Imported Upstream version 2.3
authorDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Sun, 10 Aug 2014 20:21:00 +0000 (23:21 +0300)
committerDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Sun, 10 Aug 2014 20:21:00 +0000 (23:21 +0300)
531 files changed:
CMakeLists.txt
ChangeLog.txt
FindMathGL2.cmake [new file with mode: 0644]
INSTALL
examples/fltk_example.cpp
examples/full_test.cpp
examples/glut_example.cpp
examples/mpi_test.cpp
examples/qt_example.cpp
examples/samples.cpp
examples/wnd_samples.cpp
include/config.h.in
include/mgl2/abstract.h
include/mgl2/addon.h
include/mgl2/base.h
include/mgl2/base_cf.h
include/mgl2/canvas.h
include/mgl2/canvas_cf.h
include/mgl2/canvas_wnd.h
include/mgl2/data.h
include/mgl2/data_cf.h
include/mgl2/datac.h
include/mgl2/datac_cf.h
include/mgl2/define.h
include/mgl2/eval.h
include/mgl2/evalc.h
include/mgl2/fit.h
include/mgl2/fltk.h
include/mgl2/font.h
include/mgl2/mgl.h
include/mgl2/mgl_pas.pas
include/mgl2/opengl.h
include/mgl2/other.h
include/mgl2/parser.h
include/mgl2/pde.h
include/mgl2/prim.h
include/mgl2/qmathgl.h
include/mgl2/type.h
include/xpm/accessories-calculator.png [deleted file]
include/xpm/accessories-calculator.xpm [deleted file]
include/xpm/alpha.png [deleted file]
include/xpm/alpha.xpm
include/xpm/alpha_on.xpm [deleted file]
include/xpm/arc.xpm [new file with mode: 0644]
include/xpm/axis.xpm [new file with mode: 0644]
include/xpm/axis_sh.xpm
include/xpm/barrow_a.xpm [new file with mode: 0644]
include/xpm/barrow_d.xpm [new file with mode: 0644]
include/xpm/barrow_i.xpm [new file with mode: 0644]
include/xpm/barrow_k.xpm [new file with mode: 0644]
include/xpm/barrow_n.xpm [new file with mode: 0644]
include/xpm/barrow_o.xpm [new file with mode: 0644]
include/xpm/barrow_s.xpm [new file with mode: 0644]
include/xpm/barrow_t.xpm [new file with mode: 0644]
include/xpm/barrow_v.xpm [new file with mode: 0644]
include/xpm/box.xpm
include/xpm/comment.xpm [new file with mode: 0644]
include/xpm/delete.xpm [new file with mode: 0644]
include/xpm/dialog-information.png [deleted file]
include/xpm/document-export.png [deleted file]
include/xpm/document-export.xpm [deleted file]
include/xpm/document-import.png [deleted file]
include/xpm/document-import.xpm [deleted file]
include/xpm/document-new.png [deleted file]
include/xpm/document-new.xpm [deleted file]
include/xpm/document-open.png [deleted file]
include/xpm/document-open.xpm [deleted file]
include/xpm/document-print.png [deleted file]
include/xpm/document-print.xpm [deleted file]
include/xpm/document-properties.png [deleted file]
include/xpm/document-properties.xpm [deleted file]
include/xpm/document-save.png [deleted file]
include/xpm/document-save.xpm [deleted file]
include/xpm/edit-copy.png [deleted file]
include/xpm/edit-copy.xpm [deleted file]
include/xpm/edit-cut.png [deleted file]
include/xpm/edit-cut.xpm [deleted file]
include/xpm/edit-delete.png [deleted file]
include/xpm/edit-delete.xpm [deleted file]
include/xpm/edit-find.png [deleted file]
include/xpm/edit-find.xpm [deleted file]
include/xpm/edit-paste.png [deleted file]
include/xpm/edit-paste.xpm [deleted file]
include/xpm/edit-redo.png [deleted file]
include/xpm/edit-redo.xpm [deleted file]
include/xpm/edit-select-all.png [deleted file]
include/xpm/edit-select-all.xpm [deleted file]
include/xpm/edit-undo.png [deleted file]
include/xpm/edit-undo.xpm [deleted file]
include/xpm/film-b.png [deleted file]
include/xpm/film-b.xpm [deleted file]
include/xpm/film-r.xpm [deleted file]
include/xpm/folder.png [deleted file]
include/xpm/format-indent-more.png [deleted file]
include/xpm/format-indent-more.xpm [deleted file]
include/xpm/go-down.png [deleted file]
include/xpm/go-down.xpm [deleted file]
include/xpm/go-first.png [deleted file]
include/xpm/go-first.xpm [deleted file]
include/xpm/go-last.png [deleted file]
include/xpm/go-last.xpm [deleted file]
include/xpm/go-next-b.png [deleted file]
include/xpm/go-next.png [deleted file]
include/xpm/go-next.xpm [deleted file]
include/xpm/go-previous-b.png [deleted file]
include/xpm/go-previous.png [deleted file]
include/xpm/go-previous.xpm [deleted file]
include/xpm/go-up.png [deleted file]
include/xpm/go-up.xpm [deleted file]
include/xpm/help-contents.png [deleted file]
include/xpm/help-contents.xpm [deleted file]
include/xpm/help-faq.png [deleted file]
include/xpm/help-faq.xpm [deleted file]
include/xpm/light_on.xpm [deleted file]
include/xpm/mask_a.xpm [new file with mode: 0644]
include/xpm/mask_d.xpm [new file with mode: 0644]
include/xpm/mask_d_.xpm [new file with mode: 0644]
include/xpm/mask_e.xpm [new file with mode: 0644]
include/xpm/mask_i.xpm [new file with mode: 0644]
include/xpm/mask_j.xpm [new file with mode: 0644]
include/xpm/mask_l.xpm [new file with mode: 0644]
include/xpm/mask_m.xpm [new file with mode: 0644]
include/xpm/mask_o.xpm [new file with mode: 0644]
include/xpm/mask_o_.xpm [new file with mode: 0644]
include/xpm/mask_p.xpm [new file with mode: 0644]
include/xpm/mask_r.xpm [new file with mode: 0644]
include/xpm/mask_s.xpm [new file with mode: 0644]
include/xpm/mask_s_.xpm [new file with mode: 0644]
include/xpm/mask_t.xpm [new file with mode: 0644]
include/xpm/mask_u.xpm [new file with mode: 0644]
include/xpm/media-seek-backward.png [deleted file]
include/xpm/media-seek-backward.xpm [deleted file]
include/xpm/media-seek-forward.png [deleted file]
include/xpm/media-seek-forward.xpm [deleted file]
include/xpm/object-rotate-right-on.xpm [deleted file]
include/xpm/object-rotate-right.png [deleted file]
include/xpm/object-rotate-right.xpm [deleted file]
include/xpm/other.xpm [new file with mode: 0644]
include/xpm/plot.xpm
include/xpm/polygon.xpm [new file with mode: 0644]
include/xpm/preferences-system.png [deleted file]
include/xpm/preferences-system.xpm [deleted file]
include/xpm/process-stop.png [deleted file]
include/xpm/process-stop.xpm [deleted file]
include/xpm/rotate_on.xpm [deleted file]
include/xpm/show_on.xpm [deleted file]
include/xpm/smth.xpm [deleted file]
include/xpm/stop.xpm [new file with mode: 0644]
include/xpm/sum.xpm [deleted file]
include/xpm/swap.xpm [deleted file]
include/xpm/system-file-manager.png [deleted file]
include/xpm/text-x-generic.png [deleted file]
include/xpm/tiles.xpm [new file with mode: 0644]
include/xpm/udav.png [deleted file]
include/xpm/unused/smth.xpm [new file with mode: 0644]
include/xpm/unused/sum.xpm [new file with mode: 0644]
include/xpm/unused/swap.xpm [new file with mode: 0644]
include/xpm/vect.xpm [new file with mode: 0644]
include/xpm/view-refresh.png [deleted file]
include/xpm/view-refresh.xpm [deleted file]
include/xpm/weather-clear.png [deleted file]
include/xpm/weather-clear.xpm [deleted file]
include/xpm/x-office-presentation.png [deleted file]
include/xpm/x-office-spreadsheet.png [deleted file]
include/xpm/x-office-spreadsheet.xpm [deleted file]
include/xpm/zoom-fit-best-r.xpm [deleted file]
include/xpm/zoom-fit-best.png [deleted file]
include/xpm/zoom-fit-best.xpm [deleted file]
include/xpm/zoom-in.png [deleted file]
include/xpm/zoom-in.xpm [deleted file]
include/xpm/zoom-original.png [deleted file]
include/xpm/zoom-original.xpm [deleted file]
include/xpm/zoom-out.png [deleted file]
include/xpm/zoom-out.xpm [deleted file]
include/xpm/zoom_in.xpm
include/xpm/zoom_on.xpm [deleted file]
include/xpm/zoom_out.xpm
json/main.js
json/mathgl.Graph.js
json/mathgl.View.js
lang/CMakeLists.txt
lang/data.i
lang/mgl.i
mgllab/CMakeLists.txt [deleted file]
mgllab/animate.cpp [deleted file]
mgllab/data.cpp [deleted file]
mgllab/editor.cpp [deleted file]
mgllab/grid.cpp [deleted file]
mgllab/help.cpp [deleted file]
mgllab/main.cpp [deleted file]
mgllab/mathgl.cpp [deleted file]
mgllab/option.cpp [deleted file]
mgllab/setup.cpp [deleted file]
mgllab/table.cpp [deleted file]
mgllab/udav.h [deleted file]
mgllab/udav.rc [deleted file]
mgllab/udav48.ico [deleted file]
mgllab/write.cpp [deleted file]
src/CMakeLists.txt
src/addon.cpp
src/axis.cpp
src/base.cpp
src/base_cf.cpp
src/canvas.cpp
src/canvas_cf.cpp
src/complex.cpp
src/complex_ex.cpp [new file with mode: 0644]
src/complex_io.cpp
src/cont.cpp
src/cont.hpp [new file with mode: 0644]
src/crust.cpp
src/data.cpp
src/data_ex.cpp
src/data_gr.cpp
src/data_io.cpp
src/data_png.cpp
src/eval.cpp
src/evalc.cpp
src/evalp.cpp
src/exec.cpp
src/export.cpp
src/export_2d.cpp
src/export_3d.cpp
src/fft.cpp
src/fit.cpp
src/font.cpp
src/interp.hpp
src/obj.cpp
src/opengl.cpp
src/other.cpp
src/parser.cpp
src/pde.cpp
src/pixel.cpp
src/plot.cpp
src/prc.cpp
src/prim.cpp
src/s_hull/s_hull_pro.cpp
src/s_hull/s_hull_pro.h
src/surf.cpp
src/tex_table.cpp
src/vect.cpp
src/volume.cpp
src/window.cpp
texinfo/CMakeLists.txt
texinfo/concept_en.texi
texinfo/concept_ru.texi
texinfo/core_en.texi
texinfo/core_ru.texi
texinfo/data_en.texi
texinfo/data_ru.texi
texinfo/doc_en.texi
texinfo/doc_ru.texi
texinfo/ex_mgl_en.texi
texinfo/ex_mgl_ru.texi
texinfo/example_en.texi
texinfo/example_ru.texi
texinfo/overview_en.texi
texinfo/overview_ru.texi
texinfo/parse_en.texi
texinfo/parse_ru.texi
texinfo/symbols_en.texi
texinfo/symbols_ru.texi
texinfo/time.texi
texinfo/time_big.texi
texinfo/udav/udav_anim.png [new file with mode: 0644]
texinfo/udav/udav_arg.png
texinfo/udav/udav_calc.png
texinfo/udav/udav_cmd.png
texinfo/udav/udav_data.png
texinfo/udav/udav_gen_set.png
texinfo/udav/udav_help.png
texinfo/udav/udav_inplot.png [new file with mode: 0644]
texinfo/udav/udav_light.png
texinfo/udav/udav_main.png
texinfo/udav/udav_mask.png [new file with mode: 0644]
texinfo/udav/udav_opt.png
texinfo/udav/udav_pen.png
texinfo/udav/udav_prop.png
texinfo/udav/udav_sch.png
texinfo/udav/udav_txt.png
texinfo/udav/udav_var.png
texinfo/udav_en.texi
texinfo/udav_ru.texi
texinfo/version.texi
texinfo/web_en.texi
texinfo/web_ru.texi
todo.txt
udav/CMakeLists.txt
udav/dat_pnl.cpp
udav/dat_pnl.h
udav/data_dlg.cpp
udav/help_pnl.cpp
udav/info_dlg.cpp
udav/info_dlg.h
udav/mem_pnl.cpp
udav/mem_pnl.h
udav/newcmd_dlg.cpp
udav/newcmd_dlg.h
udav/open_dlg.cpp
udav/plot_pnl.cpp
udav/plot_pnl.h
udav/png/accessories-calculator.png [new file with mode: 0644]
udav/png/alpha.png [new file with mode: 0644]
udav/png/arrow-down-double.png [new file with mode: 0644]
udav/png/arrow-down.png [new file with mode: 0644]
udav/png/arrow-left-double.png [new file with mode: 0644]
udav/png/arrow-left.png [new file with mode: 0644]
udav/png/arrow-right-double.png [new file with mode: 0644]
udav/png/arrow-right.png [new file with mode: 0644]
udav/png/arrow-up-double.png [new file with mode: 0644]
udav/png/arrow-up.png [new file with mode: 0644]
udav/png/dialog-information.png [new file with mode: 0644]
udav/png/document-export.png [new file with mode: 0644]
udav/png/document-import.png [new file with mode: 0644]
udav/png/document-new.png [new file with mode: 0644]
udav/png/document-open-folder.png [new file with mode: 0644]
udav/png/document-open.png [new file with mode: 0644]
udav/png/document-print.png [new file with mode: 0644]
udav/png/document-properties.png [new file with mode: 0644]
udav/png/document-revert.png [new file with mode: 0644]
udav/png/document-save.png [new file with mode: 0644]
udav/png/edit-clear.png [new file with mode: 0644]
udav/png/edit-copy.png [new file with mode: 0644]
udav/png/edit-cut.png [new file with mode: 0644]
udav/png/edit-delete.png [new file with mode: 0644]
udav/png/edit-find.png [new file with mode: 0644]
udav/png/edit-paste.png [new file with mode: 0644]
udav/png/edit-redo.png [new file with mode: 0644]
udav/png/edit-select-all.png [new file with mode: 0644]
udav/png/edit-undo.png [new file with mode: 0644]
udav/png/folder.png [new file with mode: 0644]
udav/png/format-indent-more.png [new file with mode: 0644]
udav/png/format-stroke-color.png [new file with mode: 0644]
udav/png/go-bottom.png [new file with mode: 0644]
udav/png/go-down.png [new file with mode: 0644]
udav/png/go-first-view.png [new file with mode: 0644]
udav/png/go-first.png [new file with mode: 0644]
udav/png/go-jump-locationbar.png [new file with mode: 0644]
udav/png/go-last-view.png [new file with mode: 0644]
udav/png/go-last.png [new file with mode: 0644]
udav/png/go-next-view-page.png [new file with mode: 0644]
udav/png/go-next-view.png [new file with mode: 0644]
udav/png/go-next.png [new file with mode: 0644]
udav/png/go-previous-view-page.png [new file with mode: 0644]
udav/png/go-previous-view.png [new file with mode: 0644]
udav/png/go-previous.png [new file with mode: 0644]
udav/png/go-top.png [new file with mode: 0644]
udav/png/go-up.png [new file with mode: 0644]
udav/png/help-contents.png [new file with mode: 0644]
udav/png/help-faq.png [new file with mode: 0644]
udav/png/layer-visible-off.png [new file with mode: 0644]
udav/png/layer-visible-on.png [new file with mode: 0644]
udav/png/list-add.png [new file with mode: 0644]
udav/png/list-remove.png [new file with mode: 0644]
udav/png/media-playback-start.png [new file with mode: 0644]
udav/png/media-seek-backward.png [new file with mode: 0644]
udav/png/media-seek-forward.png [new file with mode: 0644]
udav/png/object-group.png [new file with mode: 0644]
udav/png/object-order-lower.png [new file with mode: 0644]
udav/png/object-order-raise.png [new file with mode: 0644]
udav/png/object-rotate-down.png [new file with mode: 0644]
udav/png/object-rotate-left.png [new file with mode: 0644]
udav/png/object-rotate-right.png [new file with mode: 0644]
udav/png/object-rotate-up.png [new file with mode: 0644]
udav/png/object-ungroup.png [new file with mode: 0644]
udav/png/office-chart-bar.png [new file with mode: 0644]
udav/png/office-chart-line.png [new file with mode: 0644]
udav/png/office-chart-scatter.png [new file with mode: 0644]
udav/png/package-x-generic.png [new file with mode: 0644]
udav/png/preferences-system.png [new file with mode: 0644]
udav/png/process-stop.png [new file with mode: 0644]
udav/png/system-file-manager.png [new file with mode: 0644]
udav/png/tab-close.png [new file with mode: 0644]
udav/png/table.png [new file with mode: 0644]
udav/png/text-csv.png [new file with mode: 0644]
udav/png/text-field.png [new file with mode: 0644]
udav/png/text-plain.png [new file with mode: 0644]
udav/png/text-x-generic.png [new file with mode: 0644]
udav/png/tools-wizard.png [new file with mode: 0644]
udav/png/transform-crop.png [new file with mode: 0644]
udav/png/transform-move.png [new file with mode: 0644]
udav/png/transform-rotate.png [new file with mode: 0644]
udav/png/transform-scale.png [new file with mode: 0644]
udav/png/udav.png [new file with mode: 0644]
udav/png/view-filter.png [new file with mode: 0644]
udav/png/view-fullscreen.png [new file with mode: 0644]
udav/png/view-grid.png [new file with mode: 0644]
udav/png/view-group.png [new file with mode: 0644]
udav/png/view-refresh.png [new file with mode: 0644]
udav/png/weather-clear.png [new file with mode: 0644]
udav/png/weather-clear_old.png [new file with mode: 0644]
udav/png/weather-clouds.png [new file with mode: 0644]
udav/png/zoom-draw.png [new file with mode: 0644]
udav/png/zoom-in.png [new file with mode: 0644]
udav/png/zoom-original.png [new file with mode: 0644]
udav/png/zoom-out.png [new file with mode: 0644]
udav/prop_dlg.cpp
udav/prop_dlg.h
udav/qmglsyntax.cpp
udav/style_dlg.cpp
udav/style_dlg.h
udav/subplot_dlg.cpp [new file with mode: 0644]
udav/subplot_dlg.h [new file with mode: 0644]
udav/text_pnl.cpp
udav/text_pnl.h
udav/udav.qrc
udav/udav_wnd.cpp
udav/udav_wnd.h
udav/xpm/accessories-calculator.png [deleted file]
udav/xpm/alpha.png [deleted file]
udav/xpm/arrow_a.xpm [deleted file]
udav/xpm/arrow_d.xpm [deleted file]
udav/xpm/arrow_i.xpm [deleted file]
udav/xpm/arrow_k.xpm [deleted file]
udav/xpm/arrow_n.xpm [deleted file]
udav/xpm/arrow_o.xpm [deleted file]
udav/xpm/arrow_s.xpm [deleted file]
udav/xpm/arrow_t.xpm [deleted file]
udav/xpm/arrow_v.xpm [deleted file]
udav/xpm/cons.xpm [deleted file]
udav/xpm/crop.xpm [deleted file]
udav/xpm/dash_d.xpm [deleted file]
udav/xpm/dash_e.xpm [deleted file]
udav/xpm/dash_i.xpm [deleted file]
udav/xpm/dash_j.xpm [deleted file]
udav/xpm/dash_l.xpm [deleted file]
udav/xpm/dash_m.xpm [deleted file]
udav/xpm/dash_s.xpm [deleted file]
udav/xpm/dialog-information.png [deleted file]
udav/xpm/diff.xpm [deleted file]
udav/xpm/diff2.xpm [deleted file]
udav/xpm/document-export.png [deleted file]
udav/xpm/document-import.png [deleted file]
udav/xpm/document-new.png [deleted file]
udav/xpm/document-open.png [deleted file]
udav/xpm/document-print.png [deleted file]
udav/xpm/document-properties.png [deleted file]
udav/xpm/document-save.png [deleted file]
udav/xpm/edit-copy.png [deleted file]
udav/xpm/edit-cut.png [deleted file]
udav/xpm/edit-delete.png [deleted file]
udav/xpm/edit-find.png [deleted file]
udav/xpm/edit-paste.png [deleted file]
udav/xpm/edit-redo.png [deleted file]
udav/xpm/edit-select-all.png [deleted file]
udav/xpm/edit-undo.png [deleted file]
udav/xpm/film-b.png [deleted file]
udav/xpm/folder.png [deleted file]
udav/xpm/format-indent-more.png [deleted file]
udav/xpm/func.xpm [deleted file]
udav/xpm/go-down.png [deleted file]
udav/xpm/go-first.png [deleted file]
udav/xpm/go-last.png [deleted file]
udav/xpm/go-next-b.png [deleted file]
udav/xpm/go-next.png [deleted file]
udav/xpm/go-previous-b.png [deleted file]
udav/xpm/go-previous.png [deleted file]
udav/xpm/go-up.png [deleted file]
udav/xpm/help-contents.png [deleted file]
udav/xpm/help-faq.png [deleted file]
udav/xpm/insert.xpm [deleted file]
udav/xpm/integr.xpm [deleted file]
udav/xpm/mark_.xpm [deleted file]
udav/xpm/mark_a.xpm [deleted file]
udav/xpm/mark_cf.xpm [deleted file]
udav/xpm/mark_d.xpm [deleted file]
udav/xpm/mark_df.xpm [deleted file]
udav/xpm/mark_l.xpm [deleted file]
udav/xpm/mark_lf.xpm [deleted file]
udav/xpm/mark_n.xpm [deleted file]
udav/xpm/mark_o.xpm [deleted file]
udav/xpm/mark_of.xpm [deleted file]
udav/xpm/mark_p.xpm [deleted file]
udav/xpm/mark_pf.xpm [deleted file]
udav/xpm/mark_r.xpm [deleted file]
udav/xpm/mark_rf.xpm [deleted file]
udav/xpm/mark_s.xpm [deleted file]
udav/xpm/mark_sf.xpm [deleted file]
udav/xpm/mark_t.xpm [deleted file]
udav/xpm/mark_tf.xpm [deleted file]
udav/xpm/mark_v.xpm [deleted file]
udav/xpm/mark_vf.xpm [deleted file]
udav/xpm/mark_x.xpm [deleted file]
udav/xpm/mark_y.xpm [deleted file]
udav/xpm/media-seek-backward.png [deleted file]
udav/xpm/media-seek-forward.png [deleted file]
udav/xpm/none.xpm [deleted file]
udav/xpm/object-rotate-right.png [deleted file]
udav/xpm/oper.xpm [deleted file]
udav/xpm/oper_a.xpm [deleted file]
udav/xpm/oper_d.xpm [deleted file]
udav/xpm/oper_m.xpm [deleted file]
udav/xpm/oper_s.xpm [deleted file]
udav/xpm/option.xpm [deleted file]
udav/xpm/plot.xpm [deleted file]
udav/xpm/preferences-system.png [deleted file]
udav/xpm/preview.xpm [deleted file]
udav/xpm/process-stop.png [deleted file]
udav/xpm/size.xpm [deleted file]
udav/xpm/smth.xpm [deleted file]
udav/xpm/squize.xpm [deleted file]
udav/xpm/style.xpm [deleted file]
udav/xpm/sum.xpm [deleted file]
udav/xpm/swap.xpm [deleted file]
udav/xpm/system-file-manager.png [deleted file]
udav/xpm/table.xpm [deleted file]
udav/xpm/text-x-generic.png [deleted file]
udav/xpm/tran.xpm [deleted file]
udav/xpm/udav.png [deleted file]
udav/xpm/update.xpm [deleted file]
udav/xpm/view-refresh.png [deleted file]
udav/xpm/weather-clear.png [deleted file]
udav/xpm/window.xpm [deleted file]
udav/xpm/wire.xpm [deleted file]
udav/xpm/x-office-presentation.png [deleted file]
udav/xpm/x-office-spreadsheet.png [deleted file]
udav/xpm/zoom-fit-best.png [deleted file]
udav/xpm/zoom-in.png [deleted file]
udav/xpm/zoom-original.png [deleted file]
udav/xpm/zoom-out.png [deleted file]
utils/CMakeLists.txt
utils/make_forth.cpp
utils/make_pas.cpp
utils/mglcgi.cpp
utils/mglconv.cpp
utils/mglview.cpp
widgets/CMakeLists.txt
widgets/fltk.cpp
widgets/glut.cpp
widgets/qt.cpp
widgets/wx.cpp

index 4ae50a5ba2ce5b13e7cc8107d49ffed09cd07b6f..e465bad357b92e20a170fdea544d76d1bd7a9d49 100644 (file)
@@ -8,9 +8,9 @@ if(NOT CMAKE_BUILD_TYPE)
 endif(NOT CMAKE_BUILD_TYPE)
 
 set(CMAKE_VERBOSE_MAKEFILE ON)
-set(MathGL_VERSION_MAJOR 2)
-set(MathGL_VERSION_MINOR 2.2)
-set(MathGL_SOVERSION 7.2.0)
+#set(MathGL_VERSION_MAJOR 2)
+#set(MathGL_VERSION_MINOR 2.2)
+set(MathGL_SOVERSION 7.3.0)
 
 
 MACRO(MGL_DEPENDENT_OPTION option doc default depends1 force1 depends2 force2)
@@ -59,7 +59,6 @@ include(CMakeDependentOption)
 set(MGL_LIB_INSTALL_DIR "lib" CACHE STRING "Set library install directory")
 
 option(enable-double "Enable double precision in MathGL library" ON)
-option(enable-simple "Slightly increase drawing speed but disable mglDataA class")
 option(enable-mpi "Enable mpi")
 option(enable-opengl "Enable OpenGL support" ON)
 option(enable-all-docs "Enable all documentation building")
@@ -67,6 +66,7 @@ option(enable-all-docs "Enable all documentation building")
 option(enable-all "Enable all core features")
 option(enable-all-widgets "Enable all Widgets")
 option(enable-all-swig "Enable all SWIG based interfaces")
+option(enable-rvalue "Enable move constructor support (need C++11)" OFF)
 option(enable-pthread "Enable POSIX threads support" OFF)
 option(enable-openmp "Enable OpenMP support" ON)
 option(enable-lgpl "Enable only LGPL part of MathGL")
@@ -96,6 +96,12 @@ CMAKE_DEPENDENT_OPTION(enable-qt4 "Enable Qt4 widget" OFF "NOT enable-all-widget
 CMAKE_DEPENDENT_OPTION(enable-qt5 "Enable Qt5 widget" OFF "NOT enable-all-widgets" ON)
 CMAKE_DEPENDENT_OPTION(enable-qt5asqt "Set Qt5 as default libmgl-qt" ON "enable-qt5" OFF)
 
+if(UNIX AND enable-rvalue)
+       SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
+endif(UNIX AND enable-rvalue)
+# MSVC does not require any special flags
+
 if(enable-qt4 OR enable-qt5)
 set(enable-qt ON)
 endif(enable-qt4 OR enable-qt5)
@@ -148,6 +154,45 @@ if(HAVE_MEMRCHR)
        ADD_DEFINITIONS("-DHAVE_MEMRCHR")
 endif(HAVE_MEMRCHR)
 
+include(CheckCXXSourceCompiles)
+CHECK_CXX_SOURCE_COMPILES(
+"#include <complex>
+#include <complex.h>
+int main(int argc, char *args[])
+{std::complex<double> c(2.0, 1.0);
+double _Complex *a = reinterpret_cast<double _Complex *>(&c);
+std::complex<double> b(*a);return 0;}" MGL_HAVE_C99_COMPLEX)
+if(NOT MGL_HAVE_C99_COMPLEX)
+       set(MGL_HAVE_C99_COMPLEX 0)
+endif(NOT MGL_HAVE_C99_COMPLEX)
+CHECK_CXX_SOURCE_COMPILES(
+"#include <math.h>
+int main(){double a=NAN, b=INFINITY;return 0;}" MGL_HAVE_NAN_INF)
+if(NOT MGL_HAVE_NAN_INF)
+       set(MGL_HAVE_NAN_INF 0)
+endif(NOT MGL_HAVE_NAN_INF)
+CHECK_CXX_SOURCE_COMPILES(
+"int __attribute__((pure)) test1() {return 0;}
+int __attribute__((const)) test2(int x) {return x*x;}
+int main(int argc, char* argv[]) {return 0;}" MGL_HAVE_ATTRIBUTE)
+if(NOT MGL_HAVE_ATTRIBUTE)
+       set(MGL_HAVE_ATTRIBUTE 0)
+endif(NOT MGL_HAVE_ATTRIBUTE)
+CHECK_CXX_SOURCE_COMPILES(
+"#define mgl_isnum(a)  ({typeof (a) _a = (a); _a==_a;})
+int main(){bool a=mgl_isnum(1);return 0;}" MGL_HAVE_TYPEOF)
+if(NOT MGL_HAVE_TYPEOF)
+       set(MGL_HAVE_TYPEOF 0)
+endif(NOT MGL_HAVE_TYPEOF)
+
+#unset(MGL_HAVE_C99_COMPLEX)
+CHECK_CXX_SOURCE_COMPILES(
+"struct test { test() {} test(test&& a){} };
+int main() { test t;   return 0; }" MGL_HAVE_RVAL)
+if(NOT MGL_HAVE_RVAL)
+       set(MGL_HAVE_RVAL 0)
+endif(NOT MGL_HAVE_RVAL)
+
 if(enable-double)
        set(MGL_USE_DOUBLE 1)
 else(enable-double)
@@ -158,13 +203,6 @@ if(enable-qt4 OR enable-qt5)
        set(MGL_HAVE_QT 1)
 endif(enable-qt4 OR enable-qt5)
 
-if(enable-simple)
-       set(MGL_NO_DATA_A 1)
-message(STATUS "Class mglDataA is switched off.")
-else(enable-simple)
-       set(MGL_NO_DATA_A 0)
-endif(enable-simple)
-
 if(enable-openmp)
        find_package(OpenMP)
        if(OPENMP_FOUND)
@@ -357,66 +395,6 @@ else(enable-wx)
        set(MGL_HAVE_WX 0)
 endif(enable-wx)
 
-if(enable-python)
-       set(MGL_HAVE_SWIG 1)
-       set(MGL_HAVE_PYTHON 1)
-       set(Python_ADDITIONAL_VERSIONS 2.7)
-       FIND_PACKAGE(PythonInterp)
-       if(NOT PYTHONINTERP_FOUND)
-               message(SEND_ERROR "Couldn't find python interpreter.")
-       endif(NOT PYTHONINTERP_FOUND)
-       FIND_PACKAGE(PythonLibs)
-       if(NOT PYTHONLIBS_FOUND)
-               message(SEND_ERROR "Couldn't find python development libraries.")
-       endif(NOT PYTHONLIBS_FOUND)
-       execute_process(
-               COMMAND ${PYTHON_EXECUTABLE} -c "import numpy; print numpy.get_include()"
-               OUTPUT_VARIABLE NUMPY_INCLUDE_PATH
-               RESULT_VARIABLE NUMPY_ERR
-               OUTPUT_STRIP_TRAILING_WHITESPACE
-       )
-       if(NOT NUMPY_INCLUDE_PATH)
-               message(SEND_ERROR "Couldn't find numpy.")
-       endif(NOT NUMPY_INCLUDE_PATH)
-else(enable-python)
-       set(MGL_HAVE_PYTHON 0)
-endif(enable-python)
-
-if(enable-lua)
-       set(MGL_HAVE_SWIG 1)
-       set(MGL_HAVE_LUA 1)
-       INCLUDE(FindLua51)
-       if(NOT LUA51_FOUND)
-               message(SEND_ERROR "Couldn't find Lua 5.1 library.")
-       endif(NOT LUA51_FOUND)
-else(enable-lua)
-       set(MGL_HAVE_LUA 0)
-endif(enable-lua)
-
-
-if(enable-octave)
-       set(MGL_HAVE_SWIG 1)
-       set(MGL_HAVE_OCTAVE 1)
-       find_program(oct_prog octave-config)
-       if(NOT oct_prog)
-               message(SEND_ERROR "Couldn't find octave-config needed for octave interfaces compiling.")
-       endif(NOT oct_prog)
-       find_program(oct_exec octave)
-       if(NOT oct_exec)
-               message(SEND_ERROR "Couldn't find octave needed for octave interfaces compiling.")
-       endif(NOT oct_exec)
-       find_program(oct_mk mkoctfile)
-       if(NOT oct_mk)
-               message(SEND_ERROR "Couldn't find mkoctfile needed for octave interfaces compiling.")
-       endif(NOT oct_mk)
-       find_program(oct_tar tar)
-       if(NOT oct_tar)
-               message(SEND_ERROR "Couldn't find tar needed for octave interfaces creation.")
-       endif(NOT oct_tar)
-else(enable-octave)
-       set(MGL_HAVE_OCTAVE 0)
-endif(enable-octave)
-
 if(enable-doc-info)
        set(MGL_HAVE_DOC_INFO 1)
        find_program(findmi makeinfo)
@@ -457,7 +435,6 @@ else(enable-doc-html)
        set(MGL_HAVE_DOC_HTML 0)
 endif(enable-doc-html)
 
-
 if(enable-doc-site)
        set(MGL_HAVE_DOC_SITE 1)
 else(enable-doc-site)
@@ -499,14 +476,6 @@ else(enable-doc-prc)
        set(MGL_HAVE_DOC_PRC 0)
 endif(enable-doc-prc)
 
-if(MGL_HAVE_SWIG)
-       FIND_PACKAGE(SWIG)
-       if(NOT SWIG_FOUND)
-               message(SEND_ERROR "Couldn't find swig needed for interfaces compiling.")
-       endif(NOT SWIG_FOUND)
-       INCLUDE(${SWIG_USE_FILE})
-endif(MGL_HAVE_SWIG)
-
 if(UNIX)
        add_definitions(-DNO_COLOR_ARRAY)
 endif(UNIX)
@@ -521,8 +490,12 @@ add_subdirectory( include )
 if(NOT enable-lgpl)
        add_subdirectory( udav )
        add_subdirectory( json )
-       add_subdirectory( lang )
-       add_subdirectory( utils )
+       if(enable-python OR enable-lua OR enable-octave)
+               add_subdirectory( lang )
+       endif(enable-python OR enable-lua OR enable-octave)
+       if(NOT MSVC AND NOT BORLAND)
+               add_subdirectory( utils )
+       endif(NOT MSVC AND NOT BORLAND)
 #      add_subdirectory( mgllab )
 endif(NOT enable-lgpl)
 
index fd83c6e893d3094ce04c7fedf1bf8bd688830389..7b56ef20d2ec67f00c2aa99b60db64e1d53b9426 100644 (file)
@@ -1,3 +1,58 @@
+2.3 Released 7 August 2014
+
+* Add background image, which allow in particular semi-transparent background color. Correspondingly add function Rasterize() for saving current image as background, and function LoadBackground() for loading background image from PNG or JPEG file.
+* Add primitives to draw polygon and angle arc.
+* Allow arbitrary factor for axis ticks (like, gr->SetTicks('x',M_PI,0,NAN,"\\pi");).
+* Add function AddTick() for adding manual tick to existed ones.
+* Add new styles and symbols:
+  - arrow style 'X';
+  - color gradient (color scheme) of glyphs in text;
+  - manual dash style, like "{df090}";
+  - manual mask style, like "{s00ff00182424f800}";
+  - Add styles 'fFE0123456789+-' for printing numbers in functions Axis(), Colorbar(), Table() and Label();
+  - style '!' to disable ticks tuning in Axis() and Colorbar();
+  - special symbol '\b' which will be ignored at printing;
+  - calligraphic TeX symbols, like \calB, \calE, \calF, \calH, \calI, \calL, \calM, \calR, \ell, \scrg, \scro.
+
+* Add ODE solving functions for textual formulas
+* Add function for global cubic spline interpolation, and function to refill using global spline.
+* Add functions "random(dat)" and "gamma_inc(a,x)" to the list of known functions for formula parsing
+* Add 'inf' variable to the MGL and formula parsing
+* Allow reading JPEG files for mglData::Import().
+* Function mgl_data_subdata_ext() handle NULL argument(s). Add variants of SubData() with 1 and 2 arguments.
+* Warning messages and information are printed to stderr until call of mgl_suppress_warn(true) will disable it.
+* Add function mgl_check_version() and MGL command 'version' to check if MathGL version is valid.
+* Add move constructor(s) if compiler support C++11 rvalues.
+
+* Changes in algorithms:
+  - Greatly increase speed of formula parsing (i.e. of functions mglData::Modify(), mglData::Fill() and similar), and speeding up many other places;
+  - Improve algorithm for contours drawing and filling, taking special attention to quasi-random data.
+  - Spline() now use 5-th order polynomials to keep continuity of 2nd derivative too.
+  - Add function attributes 'pure' or 'const', which potentially can speed up drawing.
+  - Use spline instead of linear interpolation in functions Flow() and Pipe().
+  - Adjust columnplot and gridplot positions for non-zero distance between the inplots.
+  - Improve colorbar labels drawing at SetRotatedText(false)
+  - Choose new scales for perspective.
+  - Allow 'negative' angles for text rotation
+  - Use new s-hull version for triangulation.
+* Make function mgl_get_curvs() to be exported. This function is used internally to connect line segments to a set of curves (in particular, for contour lines).
+* Add ViewAsRotate() function which handle arguments of View() by the same way as Rotate() function, i.e View(tetx,tetz,tety) <=> ViewAsRotate(-tetz,-tetx,-tety)
+* Function mglWindow::Adjust() for Quality&4==0 now show image in widgets even if draw function is absent (i.e. =NULL).
+
+* improvements in UDAV:
+  - Rearrange tool buttons;
+  - Add features for manual dashing and manual mask in Style dialog;
+  - Add dialog for new dialog for new inplots (including subplot, multiplot, columnplot, stickplot, gridplot);
+  - Add option to use dots plot at image refreshing (for faster rotation etc);
+  - Add new primitives (arc,polygon,rotated text) as mouse handled ones;
+  - Add close button to data tabs;
+  - Add button to stop script drawing  and stop() slot for QMathGL;
+  - Allow to delete/hide/unhide selected plot;
+  - Allow to move selected plot between inplots;
+  - Improve NewCommand dialog -- now it replace the script command if user change arguments only;
+  - MGL commands 'perspective' and 'fog' now work correctly in UDAV;
+  - Update UDAV icons to use Oxygen ones.
+
 2.2.2.1 Released 19 March 2014
 
 * Compatibility changes for MS VisualStudio 2010 and early.
diff --git a/FindMathGL2.cmake b/FindMathGL2.cmake
new file mode 100644 (file)
index 0000000..43b8640
--- /dev/null
@@ -0,0 +1,113 @@
+# - FindMathGL2.cmake
+# This module can be used to find MathGL v.2.* and several of its optional components.
+#
+# You can specify one or more component as you call this find module.
+# Possible components are: FLTK, GLUT, Qt, WX.
+#
+# The following variables will be defined for your use:
+#
+#  MATHGL2_FOUND           = MathGL v.2 and all specified components found
+#  MATHGL2_INCLUDE_DIRS    = The MathGL v.2 include directories
+#  MATHGL2_LIBRARIES       = The libraries to link against to use MathGL v.2
+#                           and all specified components
+#  MATHGL2_VERSION_STRING  = A human-readable version of the MathGL v.2 (e.g. 2.1)
+#  MATHGL2_XXX_FOUND       = Component XXX found (replace XXX with uppercased
+#                           component name -- for example, QT or FLTK)
+#
+# The minimum required version and needed components can be specified using
+# the standard find_package()-syntax, here are some examples:
+#  find_package(MathGL 2.1 Qt REQUIRED) - 2.1 + Qt interface, required
+#  find_package(MathGL 2.1 REQUIRED)    - 2.1 (no interfaces), required
+#  find_package(MathGL 2.0 Qt WX)       - 2.0 + Qt and WX interfaces, optional
+#  find_package(MathGL 2.1)             - 2.1 (no interfaces), optional
+#
+# Typical usage could be something like this:
+#   find_package(MathGL 2.1 GLUT REQUIRED)
+#   include_directories(${MATHGL2_INCLUDE_DIRS})
+#   add_executable(myexe main.cpp)
+#   target_link_libraries(myexe ${MATHGL2_LIBRARIES})
+#
+
+#=============================================================================
+# Copyright (c) 2011 Denis Pesotsky <denis@kde.ru>, 2014 Alexey Balakin <mathgl.abalakin@gmail.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file COPYING-CMAKE-MODULES for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+FIND_PATH(MATHGL2_INCLUDE_DIR
+               NAMES mgl2/mgl.h
+               DOC "The MathGL2 v.2.* include directory")
+FIND_LIBRARY(MATHGL2_LIBRARY
+               NAMES mgl
+               PATHS ${MATHGL2_LIBRARY_DIR}
+               DOC "The MathGL v.2.* include directory")
+
+GET_FILENAME_COMPONENT(MATHGL2_LIBRARY_DIR ${MATHGL2_LIBRARY} PATH)
+
+SET(MATHGL2_LIBRARIES ${MATHGL2_LIBRARY})
+SET(MATHGL2_INCLUDE_DIRS ${MATHGL2_INCLUDE_DIR})
+
+IF(MATHGL2_INCLUDE_DIR)
+       SET(_CONFIG_FILE_PATH "${MATHGL2_INCLUDE_DIR}/mgl2/define.h")
+       SET(_VERSION_ERR "Cannot determine MathGL v.2.* version")
+       IF(EXISTS "${_CONFIG_FILE_PATH}")
+               FILE(STRINGS "${_CONFIG_FILE_PATH}"
+                       MATHGL2_VERSION_STRING REGEX "^#define MGL_VER2.*$")
+               IF(MATHGL2_VERSION_STRING)
+                       STRING(REGEX
+                               REPLACE "#define MGL_VER2" ""
+                               MATHGL2_VERSION_STRING ${MATHGL2_VERSION_STRING})
+                       STRING(REGEX
+                               REPLACE "//.*" ""
+                               MATHGL2_VERSION_STRING ${MATHGL2_VERSION_STRING})
+                       STRING(STRIP ${MATHGL2_VERSION_STRING} MATHGL2_VERSION_STRING)
+                       SET(MATHGL2_VERSION_STRING 2.${MATHGL2_VERSION_STRING})
+#                      MESSAGE(STATUS "Find MathGL version -- ${MATHGL2_VERSION_STRING}")
+               ELSE()
+                       MESSAGE(FATAL_ERROR "${_VERSION_ERR}: ${_CONFIG_FILE_PATH} parse error")
+               ENDIF()
+       ELSE()
+               MESSAGE(FATAL_ERROR "${_VERSION_ERR}: ${_CONFIG_FILE_PATH} not found")
+       ENDIF()
+ENDIF()
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(MathGL2
+               REQUIRED_VARS MATHGL2_LIBRARY MATHGL2_INCLUDE_DIR
+               VERSION_VAR MATHGL2_VERSION_STRING)
+
+FOREACH(_Component ${MathGL2_FIND_COMPONENTS})
+       STRING(TOLOWER ${_Component} _component)
+       STRING(TOUPPER ${_Component} _COMPONENT)
+       
+       SET(MathGL2_${_Component}_FIND_REQUIRED ${MathGL2_FIND_REQUIRED})
+       SET(MathGL2_${_Component}_FIND_QUIETLY true)
+       
+       FIND_PATH(MATHGL2_${_COMPONENT}_INCLUDE_DIR
+                               NAMES mgl2/${_component}.h
+                               PATHS ${MATHGL2_INCLUDE_DIR} NO_DEFAULT_PATH)
+       FIND_LIBRARY(MATHGL2_${_COMPONENT}_LIBRARY
+                               NAMES mgl-${_component}
+                               PATHS ${MATHGL2_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+       FIND_PACKAGE_HANDLE_STANDARD_ARGS(MathGL2_${_Component} DEFAULT_MSG
+                                                                               MATHGL2_${_COMPONENT}_LIBRARY
+                                                                               MATHGL2_${_COMPONENT}_INCLUDE_DIR)
+       
+       IF(MATHGL2_${_COMPONENT}_FOUND)
+               SET(MATHGL2_LIBRARIES
+                       ${MATHGL2_LIBRARIES} ${MATHGL2_${_COMPONENT}_LIBRARY})
+               SET(MATHGL2_INCLUDE_DIRS
+                       ${MATHGL2_INCLUDE_DIRS} ${MATHGL2_${_COMPONENT}_INCLUDE_DIR})
+       ENDIF()
+
+       MARK_AS_ADVANCED(MATHGL2_${_COMPONENT}_INCLUDE_DIR
+                                       MATHGL2_${_COMPONENT}_LIBRARY)
+ENDFOREACH()
+
+MARK_AS_ADVANCED(MATHGL2_INCLUDE_DIR MATHGL2_LIBRARY)
diff --git a/INSTALL b/INSTALL
index c999c40aac573bd059dba6891ef069ed63a8838f..9b5bef28965209016a3564f40f2f3fd3e45243b5 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -2,9 +2,9 @@ Installation is simple. Just execute:
 cmake .\r
 cmake .\r
 make\r
-make install\r
+sudo make install\r
 \r
-Sometimes you also need to update yours library list. To do that just execute:\r
-ldconfig\r
+Sometimes you also need to execute:\r
+sudo ldconfig\r
 \r
 See MathGL documentation for more details.\r
index 52cce1d6af23b0f88fe79d0b2b48afc691eefe7c..646373a5fdfb58f3b1da35859bb624a2ded827fc 100644 (file)
@@ -94,13 +94,17 @@ int main(int argc,char **argv)
        else    printf("You may specify argument '1', '2', '3' or 'd' for viewing examples of 1d, 2d, 3d or dual plotting\n");\r
        switch(key)\r
        {\r
-               case '1':       gr = new mglFLTK(sample_1,"1D plots");  break;\r
-               case '2':       gr = new mglFLTK(sample_2,"2D plots");  break;\r
-               case '3':       gr = new mglFLTK(sample_3,"3D plots");  break;\r
-               case 'd':       gr = new mglFLTK(sample_d,"Dual plots");        break;\r
-               case 't':       gr = new mglFLTK(test_wnd,"Testing");   break;\r
-               default:        gr = new mglFLTK(sample,"Drop and waves");      break;\r
+       case '0':       gr = new mglFLTK((mglDraw *)NULL,"1D plots");   break;\r
+       case '1':       gr = new mglFLTK(sample_1,"1D plots");  break;\r
+       case '2':       gr = new mglFLTK(sample_2,"2D plots");  break;\r
+       case '3':       gr = new mglFLTK(sample_3,"3D plots");  break;\r
+       case 'd':       gr = new mglFLTK(sample_d,"Dual plots");break;\r
+       case 't':       gr = new mglFLTK(test_wnd,"Testing");   break;\r
+       default:        gr = new mglFLTK(sample,"Drop and waves");      break;\r
        }\r
+       if(key=='0')\r
+       {       gr->Rotate(40,60);      gr->Box();      gr->Light(true);        gr->FSurf("sin(4*pi*x*y)");     gr->Update();   }\r
        gr->Run();      return 0;\r
 }\r
 #endif\r
+//-----------------------------------------------------------------------------\r
index 594a9dd05adfa90a3a0715974c388d8511a7c876..b15981e3a8f0ca926d17aa7e18fdc101b5b659e0 100644 (file)
@@ -23,7 +23,7 @@
 #if !defined(_MSC_VER) && !defined(__BORLANDC__)\r
 #include <getopt.h>\r
 #endif\r
-#include <vector>\r
+\r
 #include "mgl2/mgl.h"\r
 #include "mgl2/eval.h"\r
 //-----------------------------------------------------------------------------\r
@@ -38,7 +38,7 @@ struct mglSample      /// Structure for list of samples
 extern mglSample samp[];\r
 extern const char *mmgl_dat_prepare;\r
 //-----------------------------------------------------------------------------\r
-int mgl_cmd_smp(const void *a, const void *b)\r
+int MGL_LOCAL_PURE mgl_cmd_smp(const void *a, const void *b)\r
 {\r
        const mglSample *aa = (const mglSample *)a;\r
        const mglSample *bb = (const mglSample *)b;\r
@@ -62,53 +62,13 @@ void mgls_prepare2v(mglData *a, mglData *b);
 void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez);\r
 //-----------------------------------------------------------------------------\r
 void save(mglGraph *gr,const char *name,const char *suf);\r
-void smgl_stfa(mglGraph *gr);  // STFA sample\r
-void smgl_text(mglGraph *gr);  // text drawing\r
-void smgl_surf(mglGraph *gr);\r
-#include <mgl2/base.h>\r
-#include <mgl2/font.h>\r
 void test(mglGraph *gr)\r
 {\r
-       union {unsigned long b;double d;float f;} t;    t.b=0;\r
-       t.d = NAN;      printf("NANd: %g --> %lx\t",t.d,t.b);   t.b=0;\r
-       t.f = NAN;      printf("NANf: %g --> %lx\n",t.f,t.b);   t.b=0;\r
-       \r
-       t.d = INFINITY; printf("INFd: %g --> %lx\t",t.d,t.b);   t.b=0;\r
-       t.f = INFINITY; printf("INFf: %g --> %lx\n",t.f,t.b);   t.b=0;\r
-\r
-const unsigned long mgl_nan[2] = {0x7fffffffffffffff, 0x7fffffff};\r
-#define NANd    (*(double*)mgl_nan)\r
-#define NANf    (*(float*)(mgl_nan+1))\r
-       t.d = NANd;     printf("NANd: %g --> %lx\t",t.d,t.b);   t.b=0;\r
-       t.f = NANf;     printf("NANf: %g --> %lx\n",t.f,t.b);   t.b=0;\r
-\r
-       \r
-const unsigned long mgl_inf[2] = {0x7ff0000000000000, 0x7f800000};\r
-#define INFd    (*(double*)mgl_inf)\r
-#define INFf    (*(float*)(mgl_inf+1))\r
-       t.d = INFd;     printf("INFd: %g --> %lx\t",t.d,t.b);   t.b=0;\r
-       t.f = INFf;     printf("INFf: %g --> %lx\n",t.f,t.b);   t.b=0;\r
-\r
-       return;\r
-\r
-       mglData y(50);\r
-       y.Modify("sin(10*x) + 10");\r
-       gr->SetRange('y', y);\r
-       gr->Box();\r
-       gr->Axis();\r
-       gr->Plot(y);\r
-       y.Save("test.dat");\r
-       return;\r
-\r
-\r
+       gr->Rotate(40,60);      gr->Fog(1);     gr->Box();      return;\r
        mglParse par;\r
-       setlocale(LC_CTYPE, "");\r
-       par.Execute(gr,"new x 50 40 '0.8*sin(pi*x)*sin(pi*(y+1)/2)'\n\\r
-                                       new y 50 40 '0.8*cos(pi*x)*sin(pi*(y+1)/2)'\n\\r
-                                       new z 50 40 '0.8*cos(pi*(y+1)/2)'\nlight on\n\\r
-                                       title 'parametric form':rotate 50 60:box\n\\r
-                                       surf x y z ''\nwrite '1.tex'");\r
-//     par.Execute(gr,"light on:addlegend 'r' 'r':legend");\r
+       par.Execute(gr,"subplot 1 1 0:#rotate 40 60\nperspective 0.9:box:axis\n");\r
+//     par.Execute(gr,"subplot 1 1 0:#rotate 40 60\nperspective 1.22:box:axis\n");\r
+       return;\r
 }\r
 //-----------------------------------------------------------------------------\r
 #if !defined(_MSC_VER) && !defined(__BORLANDC__)\r
@@ -143,6 +103,7 @@ static struct option longopts[] =
        { "test",       no_argument,    &dotest,        1 },\r
        { "font",       no_argument,    &dotest,        2 },\r
        { "time",       no_argument,    &dotest,        3 },\r
+       { "fexport",no_argument,        &dotest,        4 },\r
        { "thread",     required_argument,      NULL,   't' },\r
        { "verbose",no_argument,        &verbose,       1 },\r
        { "width",      required_argument,      NULL,   'w' },\r
@@ -182,6 +143,7 @@ void usage()
                "--time         - measure execution time for all samples\n"\r
                "--font         - write current font as C++ file\n"\r
                "--quality=val  - use specified quality for plot(s)\n"\r
+               "--fexport      - test most of output formats\n"\r
        );\r
 }\r
 #endif\r
@@ -252,8 +214,166 @@ void save(mglGraph *gr,const char *name,const char *suf="")
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
+void smgl_fexport(mglGraph *gr)        // test file export\r
+{\r
+       gr->SubPlot(3,2,0);\r
+       double d,x1,x2,x0,y=0.95;\r
+       d=0.3, x0=0.2, x1=0.5, x2=0.6;\r
+       gr->Line(mglPoint(x0,1-0*d),mglPoint(x1,1-0*d),"k-");   gr->Puts(mglPoint(x2,y-0*d),"Solid '-'",":rL");\r
+       gr->Line(mglPoint(x0,1-1*d),mglPoint(x1,1-1*d),"k|");   gr->Puts(mglPoint(x2,y-1*d),"Long Dash '|'",":rL");\r
+       gr->Line(mglPoint(x0,1-2*d),mglPoint(x1,1-2*d),"k;");   gr->Puts(mglPoint(x2,y-2*d),"Dash ';'",":rL");\r
+       gr->Line(mglPoint(x0,1-3*d),mglPoint(x1,1-3*d),"k=");   gr->Puts(mglPoint(x2,y-3*d),"Small dash '='",":rL");\r
+       gr->Line(mglPoint(x0,1-4*d),mglPoint(x1,1-4*d),"kj");   gr->Puts(mglPoint(x2,y-4*d),"Dash-dot 'j'",":rL");\r
+       gr->Line(mglPoint(x0,1-5*d),mglPoint(x1,1-5*d),"ki");   gr->Puts(mglPoint(x2,y-5*d),"Small dash-dot 'i'",":rL");\r
+       gr->Line(mglPoint(x0,1-6*d),mglPoint(x1,1-6*d),"k:");   gr->Puts(mglPoint(x2,y-6*d),"Dots ':'",":rL");\r
+       gr->Line(mglPoint(x0,1-7*d),mglPoint(x1,1-7*d),"k ");   gr->Puts(mglPoint(x2,y-7*d),"None ' '",":rL");\r
+\r
+       d=0.25; x1=-1; x0=-0.8; y = -0.05;\r
+       gr->Mark(mglPoint(x1,5*d),"k.");        gr->Puts(mglPoint(x0,y+5*d),"'.'",":rL");\r
+       gr->Mark(mglPoint(x1,4*d),"k+");        gr->Puts(mglPoint(x0,y+4*d),"'+'",":rL");\r
+       gr->Mark(mglPoint(x1,3*d),"kx");        gr->Puts(mglPoint(x0,y+3*d),"'x'",":rL");\r
+       gr->Mark(mglPoint(x1,2*d),"k*");        gr->Puts(mglPoint(x0,y+2*d),"'*'",":rL");\r
+       gr->Mark(mglPoint(x1,d),"ks");          gr->Puts(mglPoint(x0,y+d),"'s'",":rL");\r
+       gr->Mark(mglPoint(x1,0),"kd");          gr->Puts(mglPoint(x0,y),"'d'",":rL");\r
+       gr->Mark(mglPoint(x1,-d,0),"ko");       gr->Puts(mglPoint(x0,y-d),"'o'",":rL");\r
+       gr->Mark(mglPoint(x1,-2*d,0),"k^");     gr->Puts(mglPoint(x0,y-2*d),"'\\^'",":rL");\r
+       gr->Mark(mglPoint(x1,-3*d,0),"kv");     gr->Puts(mglPoint(x0,y-3*d),"'v'",":rL");\r
+       gr->Mark(mglPoint(x1,-4*d,0),"k<");     gr->Puts(mglPoint(x0,y-4*d),"'<'",":rL");\r
+       gr->Mark(mglPoint(x1,-5*d,0),"k>");     gr->Puts(mglPoint(x0,y-5*d),"'>'",":rL");\r
+\r
+       d=0.25; x1=-0.5; x0=-0.3;       y = -0.05;\r
+       gr->Mark(mglPoint(x1,5*d),"k#.");       gr->Puts(mglPoint(x0,y+5*d),"'\\#.'",":rL");\r
+       gr->Mark(mglPoint(x1,4*d),"k#+");       gr->Puts(mglPoint(x0,y+4*d),"'\\#+'",":rL");\r
+       gr->Mark(mglPoint(x1,3*d),"k#x");       gr->Puts(mglPoint(x0,y+3*d),"'\\#x'",":rL");\r
+       gr->Mark(mglPoint(x1,2*d),"k#*");       gr->Puts(mglPoint(x0,y+2*d),"'\\#*'",":rL");\r
+       gr->Mark(mglPoint(x1,d),"k#s");         gr->Puts(mglPoint(x0,y+d),"'\\#s'",":rL");\r
+       gr->Mark(mglPoint(x1,0),"k#d");         gr->Puts(mglPoint(x0,y),"'\\#d'",":rL");\r
+       gr->Mark(mglPoint(x1,-d,0),"k#o");      gr->Puts(mglPoint(x0,y-d),"'\\#o'",":rL");\r
+       gr->Mark(mglPoint(x1,-2*d,0),"k#^");    gr->Puts(mglPoint(x0,y-2*d),"'\\#\\^'",":rL");\r
+       gr->Mark(mglPoint(x1,-3*d,0),"k#v");    gr->Puts(mglPoint(x0,y-3*d),"'\\#v'",":rL");\r
+       gr->Mark(mglPoint(x1,-4*d,0),"k#<");    gr->Puts(mglPoint(x0,y-4*d),"'\\#<'",":rL");\r
+       gr->Mark(mglPoint(x1,-5*d,0),"k#>");    gr->Puts(mglPoint(x0,y-5*d),"'\\#>'",":rL");\r
+\r
+       gr->SubPlot(3,2,1);\r
+       double a=0.1,b=0.4,c=0.5;\r
+       gr->Line(mglPoint(a,1),mglPoint(b,1),"k-A");            gr->Puts(mglPoint(c,1),"Style 'A' or 'A\\_'",":rL");\r
+       gr->Line(mglPoint(a,0.8),mglPoint(b,0.8),"k-V");        gr->Puts(mglPoint(c,0.8),"Style 'V' or 'V\\_'",":rL");\r
+       gr->Line(mglPoint(a,0.6),mglPoint(b,0.6),"k-K");        gr->Puts(mglPoint(c,0.6),"Style 'K' or 'K\\_'",":rL");\r
+       gr->Line(mglPoint(a,0.4),mglPoint(b,0.4),"k-I");        gr->Puts(mglPoint(c,0.4),"Style 'I' or 'I\\_'",":rL");\r
+       gr->Line(mglPoint(a,0.2),mglPoint(b,0.2),"k-D");        gr->Puts(mglPoint(c,0.2),"Style 'D' or 'D\\_'",":rL");\r
+       gr->Line(mglPoint(a,0),mglPoint(b,0),"k-S");            gr->Puts(mglPoint(c,0),"Style 'S' or 'S\\_'",":rL");\r
+       gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"k-O");      gr->Puts(mglPoint(c,-0.2),"Style 'O' or 'O\\_'",":rL");\r
+       gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"k-T");      gr->Puts(mglPoint(c,-0.4),"Style 'T' or 'T\\_'",":rL");\r
+       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-_");      gr->Puts(mglPoint(c,-0.6),"Style '\\_' or none",":rL");\r
+       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-AS");     gr->Puts(mglPoint(c,-0.8),"Style 'AS'",":rL");\r
+       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-_A");         gr->Puts(mglPoint(c,-1),"Style '\\_A'",":rL");\r
+\r
+       a=-1;   b=-0.7; c=-0.6;\r
+       gr->Line(mglPoint(a,1),mglPoint(b,1),"kAA");            gr->Puts(mglPoint(c,1),"Style 'AA'",":rL");\r
+       gr->Line(mglPoint(a,0.8),mglPoint(b,0.8),"kVV");        gr->Puts(mglPoint(c,0.8),"Style 'VV'",":rL");\r
+       gr->Line(mglPoint(a,0.6),mglPoint(b,0.6),"kKK");        gr->Puts(mglPoint(c,0.6),"Style 'KK'",":rL");\r
+       gr->Line(mglPoint(a,0.4),mglPoint(b,0.4),"kII");        gr->Puts(mglPoint(c,0.4),"Style 'II'",":rL");\r
+       gr->Line(mglPoint(a,0.2),mglPoint(b,0.2),"kDD");        gr->Puts(mglPoint(c,0.2),"Style 'DD'",":rL");\r
+       gr->Line(mglPoint(a,0),mglPoint(b,0),"kSS");            gr->Puts(mglPoint(c,0),"Style 'SS'",":rL");\r
+       gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"kOO");      gr->Puts(mglPoint(c,-0.2),"Style 'OO'",":rL");\r
+       gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"kTT");      gr->Puts(mglPoint(c,-0.4),"Style 'TT'",":rL");\r
+       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-__");     gr->Puts(mglPoint(c,-0.6),"Style '\\_\\_'",":rL");\r
+       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-VA");     gr->Puts(mglPoint(c,-0.8),"Style 'VA'",":rL");\r
+       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-AV");         gr->Puts(mglPoint(c,-1),"Style 'AV'",":rL");\r
+\r
+       gr->SubPlot(3,2,2);\r
+       //#LENUQ\r
+       gr->FaceZ(mglPoint(-1,  -1), 0.4, 0.3, "L#");   gr->Puts(mglPoint(-0.8,-0.9), "L", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.6,-1), 0.4, 0.3, "E#");   gr->Puts(mglPoint(-0.4,-0.9), "E", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.2,-1), 0.4, 0.3, "N#");   gr->Puts(mglPoint(0,  -0.9), "N", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.2, -1), 0.4, 0.3, "U#");   gr->Puts(mglPoint(0.4,-0.9), "U", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.6, -1), 0.4, 0.3, "Q#");   gr->Puts(mglPoint(0.8,-0.9), "Q", "w:C", -1.4);\r
+       //#lenuq\r
+       gr->FaceZ(mglPoint(-1,  -0.7), 0.4, 0.3, "l#"); gr->Puts(mglPoint(-0.8,-0.6), "l", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.6,-0.7), 0.4, 0.3, "e#"); gr->Puts(mglPoint(-0.4,-0.6), "e", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.2,-0.7), 0.4, 0.3, "n#"); gr->Puts(mglPoint(0,  -0.6), "n", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.2, -0.7), 0.4, 0.3, "u#"); gr->Puts(mglPoint(0.4,-0.6), "u", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.6, -0.7), 0.4, 0.3, "q#"); gr->Puts(mglPoint(0.8,-0.6), "q", "k:C", -1.4);\r
+       //#CMYkP\r
+       gr->FaceZ(mglPoint(-1,  -0.4), 0.4, 0.3, "C#"); gr->Puts(mglPoint(-0.8,-0.3), "C", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.6,-0.4), 0.4, 0.3, "M#"); gr->Puts(mglPoint(-0.4,-0.3), "M", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.2,-0.4), 0.4, 0.3, "Y#"); gr->Puts(mglPoint(0,  -0.3), "Y", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.2, -0.4), 0.4, 0.3, "k#"); gr->Puts(mglPoint(0.4,-0.3), "k", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.6, -0.4), 0.4, 0.3, "P#"); gr->Puts(mglPoint(0.8,-0.3), "P", "w:C", -1.4);\r
+       //#cmywp\r
+       gr->FaceZ(mglPoint(-1,  -0.1), 0.4, 0.3, "c#"); gr->Puts(mglPoint(-0.8, 0), "c", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.6,-0.1), 0.4, 0.3, "m#"); gr->Puts(mglPoint(-0.4, 0), "m", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.2,-0.1), 0.4, 0.3, "y#"); gr->Puts(mglPoint(0,   0), "y", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.2, -0.1), 0.4, 0.3, "w#"); gr->Puts(mglPoint(0.4, 0), "w", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.6, -0.1), 0.4, 0.3, "p#"); gr->Puts(mglPoint(0.8, 0), "p", "k:C", -1.4);\r
+       //#BGRHW\r
+       gr->FaceZ(mglPoint(-1,  0.2), 0.4, 0.3, "B#");  gr->Puts(mglPoint(-0.8, 0.3), "B", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.6,0.2), 0.4, 0.3, "G#");  gr->Puts(mglPoint(-0.4, 0.3), "G", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.2,0.2), 0.4, 0.3, "R#");  gr->Puts(mglPoint(0,   0.3), "R", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.2, 0.2), 0.4, 0.3, "H#");  gr->Puts(mglPoint(0.4, 0.3), "H", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.6, 0.2), 0.4, 0.3, "W#");  gr->Puts(mglPoint(0.8, 0.3), "W", "w:C", -1.4);\r
+       //#bgrhw\r
+       gr->FaceZ(mglPoint(-1,  0.5), 0.4, 0.3, "b#");  gr->Puts(mglPoint(-0.8, 0.6), "b", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.6,0.5), 0.4, 0.3, "g#");  gr->Puts(mglPoint(-0.4, 0.6), "g", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.2,0.5), 0.4, 0.3, "r#");  gr->Puts(mglPoint(0,   0.6), "r", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.2, 0.5), 0.4, 0.3, "h#");  gr->Puts(mglPoint(0.4, 0.6), "h", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.6, 0.5), 0.4, 0.3, "w#");  gr->Puts(mglPoint(0.8, 0.6), "w", "k:C", -1.4);\r
+       //#brighted\r
+       gr->FaceZ(mglPoint(-1,  0.8), 0.4, 0.3, "{r1}#");       gr->Puts(mglPoint(-0.8, 0.9), "\\{r1\\}", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.6,0.8), 0.4, 0.3, "{r3}#");       gr->Puts(mglPoint(-0.4, 0.9), "\\{r3\\}", "w:C", -1.4);\r
+       gr->FaceZ(mglPoint(-0.2,0.8), 0.4, 0.3, "{r5}#");       gr->Puts(mglPoint(0,   0.9), "\\{r5\\}", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.2, 0.8), 0.4, 0.3, "{r7}#");       gr->Puts(mglPoint(0.4, 0.9), "\\{r7\\}", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(0.6, 0.8), 0.4, 0.3, "{r9}#");       gr->Puts(mglPoint(0.8, 0.9), "\\{r9\\}", "k:C", -1.4);\r
+       // HEX\r
+       gr->FaceZ(mglPoint(-1, -1.3), 1, 0.3, "{xff9966}#");    gr->Puts(mglPoint(-0.5,-1.2), "\\{xff9966\\}", "k:C", -1.4);\r
+       gr->FaceZ(mglPoint(0,  -1.3), 1, 0.3, "{x83CAFF}#");    gr->Puts(mglPoint( 0.5,-1.2), "\\{x83CAFF\\}", "k:C", -1.4);\r
+\r
+       gr->SubPlot(3,2,3);\r
+       char stl[3]="r1", txt[4]="'1'";\r
+       for(int i=0;i<10;i++)\r
+       {\r
+               txt[1]=stl[1]='0'+i;\r
+               gr->Line(mglPoint(-1,0.2*i-1),mglPoint(1,0.2*i-1),stl);\r
+               gr->Puts(mglPoint(1.05,0.2*i-1),txt,":L");\r
+       }\r
+\r
+       gr->SubPlot(3,2,4);     gr->Title("TriPlot sample");    gr->Rotate(50,60);\r
+       double t[] = {0,1,2, 0,1,3, 0,2,3, 1,2,3};\r
+       double xt[] = {-1,1,0,0}, yt[] = {-1,-1,1,0}, zt[] = {-1,-1,-1,1};\r
+       mglData tt(4,3,t), uu(4,xt), vv(4,yt), ww(4,zt);\r
+       gr->TriPlot(tt,uu,vv,ww,"b");\r
+       gr->TriPlot(tt,uu,vv,ww,"k#");\r
+\r
+       gr->SubPlot(3,2,5);\r
+       mglData r(4);   r.Fill(1,4);\r
+       gr->SetRanges(1,4,1,4); gr->Axis();\r
+       gr->Mark(r,r,"s");\r
+       gr->Plot(r,"b");\r
+\r
+       gr->WriteJPEG("fexport.jpg");\r
+//     gr->WritePNG("fexport.png");\r
+       gr->WriteBMP("fexport.bmp");\r
+       gr->WriteTGA("fexport.tga");\r
+       gr->WriteEPS("fexport.eps");\r
+       gr->WriteSVG("fexport.svg");\r
+       gr->WriteGIF("fexport.gif");\r
+\r
+       gr->WriteXYZ("fexport.xyz");\r
+       gr->WriteSTL("fexport.stl");\r
+       gr->WriteOFF("fexport.off");\r
+       gr->WriteTEX("fexport.tex");\r
+       gr->WriteOBJ("fexport.obj");\r
+       gr->WritePRC("fexport.prc");\r
+       gr->WriteJSON("fexport.json");\r
+       \r
+       gr->ExportMGLD("fexport.mgld");\r
+       gr->Clf();\r
+       gr->ImportMGLD("fexport.mgld");\r
+}\r
+//-----------------------------------------------------------------------------\r
 int main(int argc,char **argv)\r
 {\r
+       mgl_suppress_warn(true);\r
        const char *suf = "";\r
        char name[256]="", *tmp;\r
        int ch;\r
@@ -298,6 +418,7 @@ int main(int argc,char **argv)
                mgl_set_test_mode(true);        test(gr);\r
                time(&en);      printf("time is %g sec\n",difftime(en,st));\r
                gr->WritePNG("test.png","",false);\r
+               gr->WriteSVG("test.svg");\r
                gr->WriteEPS("test.eps");\r
                printf("Messages:%s\n",gr->Message());\r
                printf("Global:%s\n",mglGlobalMess.c_str());\r
@@ -306,6 +427,8 @@ int main(int argc,char **argv)
        else if(dotest==2)\r
        {       mgl_create_cpp_font(gr->Self(), L"!-~,¡-ÿ,̀-̏,Α-ω,ϑ,ϕ,ϖ,ϰ,ϱ,ϵ,А-я,ℏ,ℑ,ℓ,ℜ,←-↙,∀-∯,≠-≯,⟂");\r
                delete gr;      return 0;       }\r
+       else if(dotest==4)\r
+       {       smgl_fexport(gr);       delete gr;      return 0;       }\r
        else if(dotest==3)\r
        {\r
                int qual[7]={0,1,2,4,5,6,8};\r
index 4018362e6d4e58f0597d911e53d270db2359295e..077c480b0c4b06e4adb73ce59f4745858ab77890 100644 (file)
@@ -78,15 +78,14 @@ int main(int argc,char **argv)
        char key = 0;\r
        if(argc>1)      key = argv[1][0]!='-' ? argv[1][0] : argv[1][1];\r
        else    printf("You may specify argument '1', '2', '3' or 'd' for viewing examples of 1d, 2d, 3d or dual plotting\n");\r
-       mglGLUT *gr;\r
        switch(key)\r
        {\r
-       case '1':       gr = new mglGLUT(sample_1, "1D plots"); break;\r
-       case '2':       gr = new mglGLUT(sample_2, "2D plots"); break;\r
-       case '3':       gr = new mglGLUT(sample_3, "3D plots"); break;\r
-       case 'd':       gr = new mglGLUT(sample_d, "Dual plots");       break;\r
-       case 't':       gr = new mglGLUT(test_wnd, "Testing");  break;\r
-       default:        gr = new mglGLUT(sample, "Example of molecules");       break;\r
+       case '1':       new mglGLUT(sample_1, "1D plots");      break;\r
+       case '2':       new mglGLUT(sample_2, "2D plots");      break;\r
+       case '3':       new mglGLUT(sample_3, "3D plots");      break;\r
+       case 'd':       new mglGLUT(sample_d, "Dual plots");    break;\r
+       case 't':       new mglGLUT(test_wnd, "Testing");       break;\r
+       default:        new mglGLUT(sample, "Example of molecules");    break;\r
        }\r
        return 0;\r
 }\r
index 7d32780818af1f2e0c9b20ac233f08614256deb6..74865f733902fc05a4654110dd09a54054b47eec 100644 (file)
@@ -1,7 +1,6 @@
 #include <stdio.h>
 #include <mgl2/mpi.h>
 #include <mpi.h>
-#define MCW            MPI_COMM_WORLD
 
 int main(int argc, char *argv[])
 {
index 54cfbcfa690ed35ed448431f7888250ed6183a99..58a7f9c9fabd91bb204e1a6dd4cab1d437f48e4e 100644 (file)
@@ -109,6 +109,7 @@ int main(int argc,char **argv)
        else    printf("You may specify argument '1', '2', '3' or 'd' for viewing examples of 1d, 2d, 3d or dual plotting\n");\r
        switch(key)\r
        {\r
+       case '0':       gr = new mglQT((mglDraw *)NULL,"1D plots");     break;\r
        case '1':       gr = new mglQT(sample_1,"1D plots");    break;\r
        case '2':       gr = new mglQT(sample_2,"2D plots");    break;\r
        case '3':       gr = new mglQT(sample_3,"3D plots");    break;\r
@@ -116,6 +117,8 @@ int main(int argc,char **argv)
        case 't':       gr = new mglQT(test_wnd,"Testing");     break;\r
        default:        gr = new mglQT(sample,"Drop and waves");        break;\r
        }\r
+       if(key=='0')\r
+       {       gr->Rotate(40,60);      gr->Box();      gr->Light(true);        gr->FSurf("sin(4*pi*x*y)");     gr->Update();   }\r
        gr->Run();      return 0;\r
 }\r
 #endif\r
index e3f40489a8aebeda0154acfdf4e54ee31bf9fbf0..c3a939b8c9886a9bcc10523d3a563b6db1b9ef8f 100644 (file)
@@ -54,176 +54,97 @@ define $1 pow(x*x+y*y+(z-0.3)*(z-0.3)+0.03,1.5)\n\
 define $2 pow(x*x+y*y+(z+0.3)*(z+0.3)+0.03,1.5)\n\
 new ex 10 10 10 '0.2*x/$1-0.2*x/$2'\n\
 new ey 10 10 10 '0.2*y/$1-0.2*y/$2'\n\
-new ez 10 10 10 '0.2*(z-0.3)/$1-0.2*(z+0.3)/$2'\nreturn\n";
+new ez 10 10 10 '0.2*(z-0.3)/$1-0.2*(z+0.3)/$2'\nreturn";
 //-----------------------------------------------------------------------------
 //             Sample functions (v.2.*)
 //-----------------------------------------------------------------------------
-const char *mmgl_fexport="";
-#define splot1(b) {(b).Norm(-1,1,true);gr->Rotate(70,60);gr->Box();gr->Surf3(b);}
-void smgl_fexport(mglGraph *gr)        // test file export
-{
-       gr->SubPlot(3,2,0);
-       double d,x1,x2,x0,y=0.95;
-       d=0.3, x0=0.2, x1=0.5, x2=0.6;
-       gr->Line(mglPoint(x0,1-0*d),mglPoint(x1,1-0*d),"k-");   gr->Puts(mglPoint(x2,y-0*d),"Solid '-'",":rL");
-       gr->Line(mglPoint(x0,1-1*d),mglPoint(x1,1-1*d),"k|");   gr->Puts(mglPoint(x2,y-1*d),"Long Dash '|'",":rL");
-       gr->Line(mglPoint(x0,1-2*d),mglPoint(x1,1-2*d),"k;");   gr->Puts(mglPoint(x2,y-2*d),"Dash ';'",":rL");
-       gr->Line(mglPoint(x0,1-3*d),mglPoint(x1,1-3*d),"k=");   gr->Puts(mglPoint(x2,y-3*d),"Small dash '='",":rL");
-       gr->Line(mglPoint(x0,1-4*d),mglPoint(x1,1-4*d),"kj");   gr->Puts(mglPoint(x2,y-4*d),"Dash-dot 'j'",":rL");
-       gr->Line(mglPoint(x0,1-5*d),mglPoint(x1,1-5*d),"ki");   gr->Puts(mglPoint(x2,y-5*d),"Small dash-dot 'i'",":rL");
-       gr->Line(mglPoint(x0,1-6*d),mglPoint(x1,1-6*d),"k:");   gr->Puts(mglPoint(x2,y-6*d),"Dots ':'",":rL");
-       gr->Line(mglPoint(x0,1-7*d),mglPoint(x1,1-7*d),"k ");   gr->Puts(mglPoint(x2,y-7*d),"None ' '",":rL");
-
-       d=0.25; x1=-1; x0=-0.8; y = -0.05;
-       gr->Mark(mglPoint(x1,5*d),"k.");        gr->Puts(mglPoint(x0,y+5*d),"'.'",":rL");
-       gr->Mark(mglPoint(x1,4*d),"k+");        gr->Puts(mglPoint(x0,y+4*d),"'+'",":rL");
-       gr->Mark(mglPoint(x1,3*d),"kx");        gr->Puts(mglPoint(x0,y+3*d),"'x'",":rL");
-       gr->Mark(mglPoint(x1,2*d),"k*");        gr->Puts(mglPoint(x0,y+2*d),"'*'",":rL");
-       gr->Mark(mglPoint(x1,d),"ks");          gr->Puts(mglPoint(x0,y+d),"'s'",":rL");
-       gr->Mark(mglPoint(x1,0),"kd");          gr->Puts(mglPoint(x0,y),"'d'",":rL");
-       gr->Mark(mglPoint(x1,-d,0),"ko");       gr->Puts(mglPoint(x0,y-d),"'o'",":rL");
-       gr->Mark(mglPoint(x1,-2*d,0),"k^");     gr->Puts(mglPoint(x0,y-2*d),"'\\^'",":rL");
-       gr->Mark(mglPoint(x1,-3*d,0),"kv");     gr->Puts(mglPoint(x0,y-3*d),"'v'",":rL");
-       gr->Mark(mglPoint(x1,-4*d,0),"k<");     gr->Puts(mglPoint(x0,y-4*d),"'<'",":rL");
-       gr->Mark(mglPoint(x1,-5*d,0),"k>");     gr->Puts(mglPoint(x0,y-5*d),"'>'",":rL");
-
-       d=0.25; x1=-0.5; x0=-0.3;       y = -0.05;
-       gr->Mark(mglPoint(x1,5*d),"k#.");       gr->Puts(mglPoint(x0,y+5*d),"'\\#.'",":rL");
-       gr->Mark(mglPoint(x1,4*d),"k#+");       gr->Puts(mglPoint(x0,y+4*d),"'\\#+'",":rL");
-       gr->Mark(mglPoint(x1,3*d),"k#x");       gr->Puts(mglPoint(x0,y+3*d),"'\\#x'",":rL");
-       gr->Mark(mglPoint(x1,2*d),"k#*");       gr->Puts(mglPoint(x0,y+2*d),"'\\#*'",":rL");
-       gr->Mark(mglPoint(x1,d),"k#s");         gr->Puts(mglPoint(x0,y+d),"'\\#s'",":rL");
-       gr->Mark(mglPoint(x1,0),"k#d");         gr->Puts(mglPoint(x0,y),"'\\#d'",":rL");
-       gr->Mark(mglPoint(x1,-d,0),"k#o");      gr->Puts(mglPoint(x0,y-d),"'\\#o'",":rL");
-       gr->Mark(mglPoint(x1,-2*d,0),"k#^");    gr->Puts(mglPoint(x0,y-2*d),"'\\#\\^'",":rL");
-       gr->Mark(mglPoint(x1,-3*d,0),"k#v");    gr->Puts(mglPoint(x0,y-3*d),"'\\#v'",":rL");
-       gr->Mark(mglPoint(x1,-4*d,0),"k#<");    gr->Puts(mglPoint(x0,y-4*d),"'\\#<'",":rL");
-       gr->Mark(mglPoint(x1,-5*d,0),"k#>");    gr->Puts(mglPoint(x0,y-5*d),"'\\#>'",":rL");
-
-       gr->SubPlot(3,2,1);
-       double a=0.1,b=0.4,c=0.5;
-       gr->Line(mglPoint(a,1),mglPoint(b,1),"k-A");            gr->Puts(mglPoint(c,1),"Style 'A' or 'A\\_'",":rL");
-       gr->Line(mglPoint(a,0.8),mglPoint(b,0.8),"k-V");        gr->Puts(mglPoint(c,0.8),"Style 'V' or 'V\\_'",":rL");
-       gr->Line(mglPoint(a,0.6),mglPoint(b,0.6),"k-K");        gr->Puts(mglPoint(c,0.6),"Style 'K' or 'K\\_'",":rL");
-       gr->Line(mglPoint(a,0.4),mglPoint(b,0.4),"k-I");        gr->Puts(mglPoint(c,0.4),"Style 'I' or 'I\\_'",":rL");
-       gr->Line(mglPoint(a,0.2),mglPoint(b,0.2),"k-D");        gr->Puts(mglPoint(c,0.2),"Style 'D' or 'D\\_'",":rL");
-       gr->Line(mglPoint(a,0),mglPoint(b,0),"k-S");            gr->Puts(mglPoint(c,0),"Style 'S' or 'S\\_'",":rL");
-       gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"k-O");      gr->Puts(mglPoint(c,-0.2),"Style 'O' or 'O\\_'",":rL");
-       gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"k-T");      gr->Puts(mglPoint(c,-0.4),"Style 'T' or 'T\\_'",":rL");
-       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-_");      gr->Puts(mglPoint(c,-0.6),"Style '\\_' or none",":rL");
-       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-AS");     gr->Puts(mglPoint(c,-0.8),"Style 'AS'",":rL");
-       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-_A");         gr->Puts(mglPoint(c,-1),"Style '\\_A'",":rL");
-
-       a=-1;   b=-0.7; c=-0.6;
-       gr->Line(mglPoint(a,1),mglPoint(b,1),"kAA");            gr->Puts(mglPoint(c,1),"Style 'AA'",":rL");
-       gr->Line(mglPoint(a,0.8),mglPoint(b,0.8),"kVV");        gr->Puts(mglPoint(c,0.8),"Style 'VV'",":rL");
-       gr->Line(mglPoint(a,0.6),mglPoint(b,0.6),"kKK");        gr->Puts(mglPoint(c,0.6),"Style 'KK'",":rL");
-       gr->Line(mglPoint(a,0.4),mglPoint(b,0.4),"kII");        gr->Puts(mglPoint(c,0.4),"Style 'II'",":rL");
-       gr->Line(mglPoint(a,0.2),mglPoint(b,0.2),"kDD");        gr->Puts(mglPoint(c,0.2),"Style 'DD'",":rL");
-       gr->Line(mglPoint(a,0),mglPoint(b,0),"kSS");            gr->Puts(mglPoint(c,0),"Style 'SS'",":rL");
-       gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"kOO");      gr->Puts(mglPoint(c,-0.2),"Style 'OO'",":rL");
-       gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"kTT");      gr->Puts(mglPoint(c,-0.4),"Style 'TT'",":rL");
-       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-__");     gr->Puts(mglPoint(c,-0.6),"Style '\\_\\_'",":rL");
-       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-VA");     gr->Puts(mglPoint(c,-0.8),"Style 'VA'",":rL");
-       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-AV");         gr->Puts(mglPoint(c,-1),"Style 'AV'",":rL");
-
-       gr->SubPlot(3,2,2);
-       //#LENUQ
-       gr->FaceZ(mglPoint(-1,  -1), 0.4, 0.3, "L#");   gr->Puts(mglPoint(-0.8,-0.9), "L", "w:C", -1.4);
-       gr->FaceZ(mglPoint(-0.6,-1), 0.4, 0.3, "E#");   gr->Puts(mglPoint(-0.4,-0.9), "E", "w:C", -1.4);
-       gr->FaceZ(mglPoint(-0.2,-1), 0.4, 0.3, "N#");   gr->Puts(mglPoint(0,  -0.9), "N", "w:C", -1.4);
-       gr->FaceZ(mglPoint(0.2, -1), 0.4, 0.3, "U#");   gr->Puts(mglPoint(0.4,-0.9), "U", "w:C", -1.4);
-       gr->FaceZ(mglPoint(0.6, -1), 0.4, 0.3, "Q#");   gr->Puts(mglPoint(0.8,-0.9), "Q", "w:C", -1.4);
-       //#lenuq
-       gr->FaceZ(mglPoint(-1,  -0.7), 0.4, 0.3, "l#"); gr->Puts(mglPoint(-0.8,-0.6), "l", "k:C", -1.4);
-       gr->FaceZ(mglPoint(-0.6,-0.7), 0.4, 0.3, "e#"); gr->Puts(mglPoint(-0.4,-0.6), "e", "k:C", -1.4);
-       gr->FaceZ(mglPoint(-0.2,-0.7), 0.4, 0.3, "n#"); gr->Puts(mglPoint(0,  -0.6), "n", "k:C", -1.4);
-       gr->FaceZ(mglPoint(0.2, -0.7), 0.4, 0.3, "u#"); gr->Puts(mglPoint(0.4,-0.6), "u", "k:C", -1.4);
-       gr->FaceZ(mglPoint(0.6, -0.7), 0.4, 0.3, "q#"); gr->Puts(mglPoint(0.8,-0.6), "q", "k:C", -1.4);
-       //#CMYkP
-       gr->FaceZ(mglPoint(-1,  -0.4), 0.4, 0.3, "C#"); gr->Puts(mglPoint(-0.8,-0.3), "C", "w:C", -1.4);
-       gr->FaceZ(mglPoint(-0.6,-0.4), 0.4, 0.3, "M#"); gr->Puts(mglPoint(-0.4,-0.3), "M", "w:C", -1.4);
-       gr->FaceZ(mglPoint(-0.2,-0.4), 0.4, 0.3, "Y#"); gr->Puts(mglPoint(0,  -0.3), "Y", "w:C", -1.4);
-       gr->FaceZ(mglPoint(0.2, -0.4), 0.4, 0.3, "k#"); gr->Puts(mglPoint(0.4,-0.3), "k", "w:C", -1.4);
-       gr->FaceZ(mglPoint(0.6, -0.4), 0.4, 0.3, "P#"); gr->Puts(mglPoint(0.8,-0.3), "P", "w:C", -1.4);
-       //#cmywp
-       gr->FaceZ(mglPoint(-1,  -0.1), 0.4, 0.3, "c#"); gr->Puts(mglPoint(-0.8, 0), "c", "k:C", -1.4);
-       gr->FaceZ(mglPoint(-0.6,-0.1), 0.4, 0.3, "m#"); gr->Puts(mglPoint(-0.4, 0), "m", "k:C", -1.4);
-       gr->FaceZ(mglPoint(-0.2,-0.1), 0.4, 0.3, "y#"); gr->Puts(mglPoint(0,   0), "y", "k:C", -1.4);
-       gr->FaceZ(mglPoint(0.2, -0.1), 0.4, 0.3, "w#"); gr->Puts(mglPoint(0.4, 0), "w", "k:C", -1.4);
-       gr->FaceZ(mglPoint(0.6, -0.1), 0.4, 0.3, "p#"); gr->Puts(mglPoint(0.8, 0), "p", "k:C", -1.4);
-       //#BGRHW
-       gr->FaceZ(mglPoint(-1,  0.2), 0.4, 0.3, "B#");  gr->Puts(mglPoint(-0.8, 0.3), "B", "w:C", -1.4);
-       gr->FaceZ(mglPoint(-0.6,0.2), 0.4, 0.3, "G#");  gr->Puts(mglPoint(-0.4, 0.3), "G", "w:C", -1.4);
-       gr->FaceZ(mglPoint(-0.2,0.2), 0.4, 0.3, "R#");  gr->Puts(mglPoint(0,   0.3), "R", "w:C", -1.4);
-       gr->FaceZ(mglPoint(0.2, 0.2), 0.4, 0.3, "H#");  gr->Puts(mglPoint(0.4, 0.3), "H", "w:C", -1.4);
-       gr->FaceZ(mglPoint(0.6, 0.2), 0.4, 0.3, "W#");  gr->Puts(mglPoint(0.8, 0.3), "W", "w:C", -1.4);
-       //#bgrhw
-       gr->FaceZ(mglPoint(-1,  0.5), 0.4, 0.3, "b#");  gr->Puts(mglPoint(-0.8, 0.6), "b", "k:C", -1.4);
-       gr->FaceZ(mglPoint(-0.6,0.5), 0.4, 0.3, "g#");  gr->Puts(mglPoint(-0.4, 0.6), "g", "k:C", -1.4);
-       gr->FaceZ(mglPoint(-0.2,0.5), 0.4, 0.3, "r#");  gr->Puts(mglPoint(0,   0.6), "r", "k:C", -1.4);
-       gr->FaceZ(mglPoint(0.2, 0.5), 0.4, 0.3, "h#");  gr->Puts(mglPoint(0.4, 0.6), "h", "k:C", -1.4);
-       gr->FaceZ(mglPoint(0.6, 0.5), 0.4, 0.3, "w#");  gr->Puts(mglPoint(0.8, 0.6), "w", "k:C", -1.4);
-       //#brighted
-       gr->FaceZ(mglPoint(-1,  0.8), 0.4, 0.3, "{r1}#");       gr->Puts(mglPoint(-0.8, 0.9), "\\{r1\\}", "w:C", -1.4);
-       gr->FaceZ(mglPoint(-0.6,0.8), 0.4, 0.3, "{r3}#");       gr->Puts(mglPoint(-0.4, 0.9), "\\{r3\\}", "w:C", -1.4);
-       gr->FaceZ(mglPoint(-0.2,0.8), 0.4, 0.3, "{r5}#");       gr->Puts(mglPoint(0,   0.9), "\\{r5\\}", "k:C", -1.4);
-       gr->FaceZ(mglPoint(0.2, 0.8), 0.4, 0.3, "{r7}#");       gr->Puts(mglPoint(0.4, 0.9), "\\{r7\\}", "k:C", -1.4);
-       gr->FaceZ(mglPoint(0.6, 0.8), 0.4, 0.3, "{r9}#");       gr->Puts(mglPoint(0.8, 0.9), "\\{r9\\}", "k:C", -1.4);
-       // HEX
-       gr->FaceZ(mglPoint(-1, -1.3), 1, 0.3, "{xff9966}#");    gr->Puts(mglPoint(-0.5,-1.2), "\\{xff9966\\}", "k:C", -1.4);
-       gr->FaceZ(mglPoint(0,  -1.3), 1, 0.3, "{x83CAFF}#");    gr->Puts(mglPoint( 0.5,-1.2), "\\{x83CAFF\\}", "k:C", -1.4);
-
-       gr->SubPlot(3,2,3);
-       char stl[3]="r1", txt[4]="'1'";
-       for(int i=0;i<10;i++)
-       {
-               txt[1]=stl[1]='0'+i;
-               gr->Line(mglPoint(-1,0.2*i-1),mglPoint(1,0.2*i-1),stl);
-               gr->Puts(mglPoint(1.05,0.2*i-1),txt,":L");
-       }
-
-       gr->SubPlot(3,2,4);     gr->Title("TriPlot sample");    gr->Rotate(50,60);
-       double t[] = {0,1,2, 0,1,3, 0,2,3, 1,2,3};
-       double xt[] = {-1,1,0,0}, yt[] = {-1,-1,1,0}, zt[] = {-1,-1,-1,1};
-       mglData tt(4,3,t), uu(4,xt), vv(4,yt), ww(4,zt);
-       gr->TriPlot(tt,uu,vv,ww,"b");
-       gr->TriPlot(tt,uu,vv,ww,"k#");
-
-       gr->SubPlot(3,2,5);
-       mglData r(4);   r.Fill(1,4);
-       gr->SetRanges(1,4,1,4); gr->Axis();
-       gr->Mark(r,r,"s");
-       gr->Plot(r,"b");
-
-       gr->WriteJPEG("fexport.jpg");
-       gr->WritePNG("fexport.png");
-       gr->WriteBMP("fexport.bmp");
-       gr->WriteTGA("fexport.tga");
-       gr->WriteEPS("fexport.eps");
-       gr->WriteSVG("fexport.svg");
-       gr->WriteGIF("fexport.gif");
-
-       gr->WriteXYZ("fexport.xyz");
-       gr->WriteSTL("fexport.stl");
-       gr->WriteOFF("fexport.off");
-       gr->WriteTEX("fexport.tex");
-       gr->WriteOBJ("fexport.obj");
-       gr->WritePRC("fexport.prc");
-}
-//-----------------------------------------------------------------------------
-const char *mmgl_refill="new x 10 '0.5+rnd':cumsum x 'x':norm x -1 1\n"
-"copy y sin(pi*x)/2\nsubplot 1 1 0 '<_':title 'Refill sample'\nbox:axis:plot x y 'o '\n"
-"new r 100:refill r x y\nplot r 'r'\nfplot 'sin(pi*x)/2' 'B:'";
+const char *mmgl_refill="new x 10 '0.5+rnd':cumsum x 'x':norm x -1 1\ncopy y sin(pi*x)/1.5\n"
+"subplot 2 2 0 '<_':title 'Refill sample'\nbox:axis:plot x y 'o ':fplot 'sin(pi*x)/1.5' 'B:'\n"
+"new r 100:refill r x y:plot r 'r'\n\n"
+"subplot 2 2 1 '<_':title 'Global spline'\nbox:axis:plot x y 'o ':fplot 'sin(pi*x)/1.5' 'B:'\n"
+"new r 100:gspline r x y:plot r 'r'\n\nnew y 10 '0.5+rnd':cumsum y 'x':norm y -1 1\n"
+"copy xx x:extend xx 10\ncopy yy y:extend yy 10:transpose yy\ncopy z sin(pi*xx*yy)/1.5\n"
+"alpha on:light on\n"
+"subplot 2 2 2:title '2d regular':rotate 40 60\nbox:axis:mesh xx yy z 'k'\n"
+"new rr 100 100:refill rr x y z:surf rr\n\n"
+"new xx 10 10 '(x+1)/2*cos(y*pi/2-1)':new yy 10 10 '(x+1)/2*sin(y*pi/2-1)'\ncopy z sin(pi*xx*yy)/1.5\n"
+"subplot 2 2 3:title '2d non-regular':rotate 40 60\nbox:axis:plot xx yy z 'ko '\n"
+"new rr 100 100:refill rr xx yy z:surf rr";
 void smgl_refill(mglGraph *gr)
 {
        mglData x(10), y(10), r(100);
        x.Modify("0.5+rnd");    x.CumSum("x");  x.Norm(-1,1);
-       y.Modify("sin(pi*v)/2",x);
-       if(big!=3)      {       gr->SubPlot(1,1,0,"<_");        gr->Title("Refill sample");     }
+       y.Modify("sin(pi*v)/1.5",x);
+       if(big!=3)      {       gr->SubPlot(2,2,0,"<_");        gr->Title("Refill sample");     }
        gr->Axis();     gr->Box();      gr->Plot(x,y,"o ");
        gr->Refill(r,x,y);      // or you can use r.Refill(x,y,-1,1);
-       gr->Plot(r,"r");        gr->FPlot("sin(pi*x)/2","B:");
+       gr->Plot(r,"r");        gr->FPlot("sin(pi*x)/1.5","B:");
+       if(big==3)      return;
+       gr->SubPlot(2,2,1,"<_");        gr->Title("Global spline");
+       gr->Axis();     gr->Box();      gr->Plot(x,y,"o ");
+       r.RefillGS(x,y,-1,1);   gr->Plot(r,"r");
+       gr->FPlot("sin(pi*x)/1.5","B:");
+
+       gr->Alpha(true);        gr->Light(true);
+       mglData z(10,10), xx(10,10), yy(10,10), rr(100,100);
+       y.Modify("0.5+rnd");    y.CumSum("x");  y.Norm(-1,1);
+       for(int i=0;i<10;i++)   for(int j=0;j<10;j++)
+               z.a[i+10*j] = sin(M_PI*x.a[i]*y.a[j])/1.5;
+       gr->SubPlot(2,2,2);     gr->Title("2d regular");        gr->Rotate(40,60);
+       gr->Axis();     gr->Box();      gr->Mesh(x,y,z,"k");
+       gr->Refill(rr,x,y,z);   gr->Surf(rr);
+
+       gr->Fill(xx,"(x+1)/2*cos(y*pi/2-1)");
+       gr->Fill(yy,"(x+1)/2*sin(y*pi/2-1)");
+       for(int i=0;i<10*10;i++)
+               z.a[i] = sin(M_PI*xx.a[i]*yy.a[i])/1.5;
+       gr->SubPlot(2,2,3);     gr->Title("2d non-regular");    gr->Rotate(40,60);
+       gr->Axis();     gr->Box();      gr->Plot(xx,yy,z,"ko ");
+       gr->Refill(rr,xx,yy,z); gr->Surf(rr);
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_indirect="subplot 1 1 0 '':title 'SubData vs Evaluate'\n"
+"new in 9 'x^3/1.1':plot in 'ko ':box\nnew arg 99 '4*x+4'\n"
+"evaluate e in arg:plot e 'b.'; legend 'Evaluate'\n"
+"subdata s in arg:plot s 'r.';legend 'SubData'\nlegend 2";
+void smgl_indirect(mglGraph *gr)
+{
+       gr->SubPlot(1,1,0,"");  gr->Title("SubData vs Evaluate");
+       mglData in(9), arg(99), e, s;
+       gr->Fill(in,"x^3/1.1"); gr->Fill(arg,"4*x+4");
+       gr->Plot(in,"ko ");             gr->Box();
+       e = in.Evaluate(arg);   gr->Plot(e,"b.","legend 'Evaluate'");
+       s = in.SubData(arg);    gr->Plot(s,"r.","legend 'SubData'");
+       gr->Legend(2);
+}
+//-----------------------------------------------------------------------------
+const char *mmgl_ode="subplot 2 2 0 '<_':title 'Cont':box\naxis:xlabel 'x':ylabel '\\dot{x}'\n"
+"new f 100 100 'y^2+2*x^3-x^2-0.5':cont f\n\n"
+"subplot 2 2 1 '<_':title 'Flow':box\naxis:xlabel 'x':ylabel '\\dot{x}'\n"
+"new fx 100 100 'x-3*x^2'\nnew fy 100 100 'y'\nflow fy fx 'v';value 7\n\n"
+"subplot 2 2 2 '<_':title 'ODE':box\naxis:xlabel 'x':ylabel '\\dot{x}'\n"
+"for $x -1 1 0.1\n  ode r 'y;x-3*x^2' 'xy' [$x,0]\n  plot r(0) r(1)\n"
+"  ode r '-y;-x+3*x^2' 'xy' [$x,0]\n  plot r(0) r(1)\nnext";
+void smgl_ode(mglGraph *gr)
+{
+       gr->SubPlot(2,2,0,"<_");        gr->Title("Cont");      gr->Box();
+       gr->Axis();     gr->Label('x',"x");     gr->Label('y',"\\dot{x}");
+       mglData f(100,100);     gr->Fill(f,"y^2+2*x^3-x^2-0.5");
+       gr->Cont(f);
+       gr->SubPlot(2,2,1,"<_");        gr->Title("Flow");      gr->Box();
+       gr->Axis();     gr->Label('x',"x");     gr->Label('y',"\\dot{x}");
+       mglData fx(100,100), fy(100,100);       gr->Fill(fx,"x-3*x^2"); gr->Fill(fy,"y");
+       gr->Flow(fy,fx,"v","value 7");
+       gr->SubPlot(2,2,2,"<_");        gr->Title("ODE");       gr->Box();
+       gr->Axis();     gr->Label('x',"x");     gr->Label('y',"\\dot{x}");
+       for(double x=-1;x<1;x+=0.1)
+       {
+               mglData in(2), r;       in.a[0]=x;
+               r = mglODE("y;x-3*x^2","xy",in);
+               gr->Plot(r.SubData(0), r.SubData(1));
+               r = mglODE("-y;-x+3*x^2","xy",in);
+               gr->Plot(r.SubData(0), r.SubData(1));
+       }
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_correl="new a 100 'exp(-10*x^2)'\n"
@@ -232,7 +153,7 @@ const char *mmgl_correl="new a 100 'exp(-10*x^2)'\n"
 "plot a:plot b:box:axis\n"
 "correl r a b 'x'\nnorm r 0 1:swap r 'x' # make it human readable\n"
 "subplot 1 2 1 '_':title 'Correlation of a and b'\n"
-"plot r 'r':axis:box\nline 0.5 0 0.5 1 'B|'\n";
+"plot r 'r':axis:box\nline 0.5 0 0.5 1 'B|'";
 void smgl_correl(mglGraph *gr)
 {
        mglData a(100),b(100);
@@ -268,7 +189,7 @@ const char *mmgl_mask="new a 10 10 'x'\n"
 "subplot 5 4 17 '':title '\"*\" mask':dens a '3*'\n"
 "subplot 5 4 18 '':title '\"^\" mask':dens a '3^'\n"
 "subplot 5 4 19 '':title 'manual mask'\n"
-"mask '+' 'ff00182424f80000':dens a '3+'";
+"mask '+' 'ff00182424f800':dens a '3+'";
 void smgl_mask(mglGraph *gr)
 {
        mglData a(10,10);       a.Fill(-1,1);
@@ -328,27 +249,28 @@ const char *mmgl_data1="new a 40 50 60 'exp(-x^2-4*y^2-16*z^2)'\n"
 "mirror b 'z':subplot 5 3 14:call 'splot'\n"
 "stop\nfunc splot 0\n"
 "title 'max=',b.max:norm b -1 1 on:rotate 70 60:box:surf3 b\n"
-"return\n";
-#define splot1(b) {(b).Norm(-1,1,true);gr->Rotate(70,60);gr->Box();gr->Surf3(b);}
+"return";
+inline void splot1(mglGraph *gr, mglData &b)
+{b.Norm(-1,1,true);gr->Rotate(70,60);gr->Box();gr->Surf3(b);}
 void smgl_data1(mglGraph *gr)  // basic data operations
 {
        mglData a(40,50,60),b;  gr->Fill(a,"exp(-x^2-4*y^2-16*z^2)");
        gr->Light(true);                gr->Alpha(true);
-       b.Set(a);       b.Diff("x");    gr->SubPlot(5,3,0);     splot1(b);
-       b.Set(a);       b.Diff2("x");   gr->SubPlot(5,3,1);     splot1(b);
-       b.Set(a);       b.CumSum("x");  gr->SubPlot(5,3,2);     splot1(b);
-       b.Set(a);       b.Integral("x");gr->SubPlot(5,3,3);     splot1(b);
-       b.Mirror("x");  gr->SubPlot(5,3,4);     splot1(b);
-       b.Set(a);       b.Diff("y");    gr->SubPlot(5,3,5);     splot1(b);
-       b.Set(a);       b.Diff2("y");   gr->SubPlot(5,3,6);     splot1(b);
-       b.Set(a);       b.CumSum("y");  gr->SubPlot(5,3,7);     splot1(b);
-       b.Set(a);       b.Integral("y");gr->SubPlot(5,3,8);     splot1(b);
-       b.Mirror("y");  gr->SubPlot(5,3,9);     splot1(b);
-       b.Set(a);       b.Diff("z");    gr->SubPlot(5,3,10);splot1(b);
-       b.Set(a);       b.Diff2("z");   gr->SubPlot(5,3,11);splot1(b);
-       b.Set(a);       b.CumSum("z");  gr->SubPlot(5,3,12);splot1(b);
-       b.Set(a);       b.Integral("z");gr->SubPlot(5,3,13);splot1(b);
-       b.Mirror("z");  gr->SubPlot(5,3,14);splot1(b);
+       b.Set(a);       b.Diff("x");    gr->SubPlot(5,3,0);     splot1(gr,b);
+       b.Set(a);       b.Diff2("x");   gr->SubPlot(5,3,1);     splot1(gr,b);
+       b.Set(a);       b.CumSum("x");  gr->SubPlot(5,3,2);     splot1(gr,b);
+       b.Set(a);       b.Integral("x");gr->SubPlot(5,3,3);     splot1(gr,b);
+       b.Mirror("x");  gr->SubPlot(5,3,4);     splot1(gr,b);
+       b.Set(a);       b.Diff("y");    gr->SubPlot(5,3,5);     splot1(gr,b);
+       b.Set(a);       b.Diff2("y");   gr->SubPlot(5,3,6);     splot1(gr,b);
+       b.Set(a);       b.CumSum("y");  gr->SubPlot(5,3,7);     splot1(gr,b);
+       b.Set(a);       b.Integral("y");gr->SubPlot(5,3,8);     splot1(gr,b);
+       b.Mirror("y");  gr->SubPlot(5,3,9);     splot1(gr,b);
+       b.Set(a);       b.Diff("z");    gr->SubPlot(5,3,10);splot1(gr,b);
+       b.Set(a);       b.Diff2("z");   gr->SubPlot(5,3,11);splot1(gr,b);
+       b.Set(a);       b.CumSum("z");  gr->SubPlot(5,3,12);splot1(gr,b);
+       b.Set(a);       b.Integral("z");gr->SubPlot(5,3,13);splot1(gr,b);
+       b.Mirror("z");  gr->SubPlot(5,3,14);splot1(gr,b);
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_data2="new a 40 50 60 'exp(-x^2-4*y^2-16*z^2)'\n"
@@ -370,27 +292,28 @@ const char *mmgl_data2="new a 40 50 60 'exp(-x^2-4*y^2-16*z^2)'\n"
 "copy b a:smooth b 'z':subplot 5 3 14:call 'splot'\n"
 "stop\nfunc splot 0\n"
 "title 'max=',b.max:norm b -1 1 on:rotate 70 60:box\n"
-"surf3 b 0.5:surf3 b -0.5\nreturn\n";
-#define splot2(b) {(b).Norm(-1,1,true);gr->Rotate(70,60);gr->Box();gr->Surf3(0.5,b);gr->Surf3(-0.5,b);}
+"surf3 b 0.5:surf3 b -0.5\nreturn";
+inline void splot2(mglGraph *gr, mglData &b)
+{b.Norm(-1,1,true);gr->Rotate(70,60);gr->Box();gr->Surf3(0.5,b);gr->Surf3(-0.5,b);}
 void smgl_data2(mglGraph *gr)  // data transforms
 {
        mglData a(40,50,60),b;  gr->Fill(a,"exp(-x^2-4*y^2-16*z^2)");
        gr->Light(true);                gr->Alpha(true);
-       b.Set(a);       b.SinFFT("x");  gr->SubPlot(5,3,0);     splot2(b);
-       b.Set(a);       b.CosFFT("x");  gr->SubPlot(5,3,1);     splot2(b);
-       b.Set(a);       b.Hankel("x");  gr->SubPlot(5,3,2);     splot2(b);
-       b.Set(a);       b.Swap("x");    gr->SubPlot(5,3,3);     splot2(b);
-       b.Set(a);       b.Smooth("x");  gr->SubPlot(5,3,4);     splot2(b);
-       b.Set(a);       b.SinFFT("y");  gr->SubPlot(5,3,5);     splot2(b);
-       b.Set(a);       b.CosFFT("y");  gr->SubPlot(5,3,6);     splot2(b);
-       b.Set(a);       b.Hankel("y");  gr->SubPlot(5,3,7);     splot2(b);
-       b.Set(a);       b.Swap("y");    gr->SubPlot(5,3,8);     splot2(b);
-       b.Set(a);       b.Smooth("y");  gr->SubPlot(5,3,9);     splot2(b);
-       b.Set(a);       b.SinFFT("z");  gr->SubPlot(5,3,10);splot2(b);
-       b.Set(a);       b.CosFFT("z");  gr->SubPlot(5,3,11);splot2(b);
-       b.Set(a);       b.Hankel("z");  gr->SubPlot(5,3,12);splot2(b);
-       b.Set(a);       b.Swap("z");    gr->SubPlot(5,3,13);splot2(b);
-       b.Set(a);       b.Smooth("z");  gr->SubPlot(5,3,14);splot2(b);
+       b.Set(a);       b.SinFFT("x");  gr->SubPlot(5,3,0);     splot2(gr,b);
+       b.Set(a);       b.CosFFT("x");  gr->SubPlot(5,3,1);     splot2(gr,b);
+       b.Set(a);       b.Hankel("x");  gr->SubPlot(5,3,2);     splot2(gr,b);
+       b.Set(a);       b.Swap("x");    gr->SubPlot(5,3,3);     splot2(gr,b);
+       b.Set(a);       b.Smooth("x");  gr->SubPlot(5,3,4);     splot2(gr,b);
+       b.Set(a);       b.SinFFT("y");  gr->SubPlot(5,3,5);     splot2(gr,b);
+       b.Set(a);       b.CosFFT("y");  gr->SubPlot(5,3,6);     splot2(gr,b);
+       b.Set(a);       b.Hankel("y");  gr->SubPlot(5,3,7);     splot2(gr,b);
+       b.Set(a);       b.Swap("y");    gr->SubPlot(5,3,8);     splot2(gr,b);
+       b.Set(a);       b.Smooth("y");  gr->SubPlot(5,3,9);     splot2(gr,b);
+       b.Set(a);       b.SinFFT("z");  gr->SubPlot(5,3,10);splot2(gr,b);
+       b.Set(a);       b.CosFFT("z");  gr->SubPlot(5,3,11);splot2(gr,b);
+       b.Set(a);       b.Hankel("z");  gr->SubPlot(5,3,12);splot2(gr,b);
+       b.Set(a);       b.Swap("z");    gr->SubPlot(5,3,13);splot2(gr,b);
+       b.Set(a);       b.Smooth("z");  gr->SubPlot(5,3,14);splot2(gr,b);
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_param1="new x 100 'sin(pi*x)'\nnew y 100 'cos(pi*x)'\n"
@@ -406,7 +329,7 @@ const char *mmgl_param1="new x 100 'sin(pi*x)'\nnew y 100 'cos(pi*x)'\n"
 "subplot 4 3 8:box:error x y z/10 c/10\n"
 "subplot 4 3 9:rotate 40 60:box:step x y z\n"
 "subplot 4 3 10:rotate 40 60:box:torus x z 'z';light on\n"
-"subplot 4 3 11:rotate 40 60:box:label x y z '%z'\n";
+"subplot 4 3 11:rotate 40 60:box:label x y z '%z'";
 void smgl_param1(mglGraph *gr) // 1d parametric plots
 {
        mglData x(100), y(100), z(100), c(100);
@@ -446,7 +369,7 @@ const char *mmgl_param2="new x 100 100 'sin(pi*(x+y)/2)*cos(pi*y/2)'\n"
 "subplot 4 4 12:rotate 40 60:box:belt x y z '';meshnum 10;light on\n"
 "subplot 4 4 13:rotate 40 60:box:boxs x y z '';meshnum 10;light on\n"
 "subplot 4 4 14:rotate 40 60:box:boxs x y z '#';meshnum 10;light on\n"
-"subplot 4 4 15:rotate 40 60:box:boxs x y z '@';meshnum 10;light on\n";
+"subplot 4 4 15:rotate 40 60:box:boxs x y z '@';meshnum 10;light on";
 void smgl_param2(mglGraph *gr) // 2d parametric plots
 {
        mglData x(100,100), y(100,100), z(100,100), c(100,100);
@@ -487,7 +410,7 @@ const char *mmgl_param3="new x 50 50 50 '(x+2)/3*sin(pi*y/2)'\n"
 "subplot 4 3 7:rotate 40 60:box:dots x y z c;meshnum 15\n"
 "subplot 4 3 8:rotate 40 60:box:densx c '' 0:densy c '' 0:densz c '' 0\n"
 "subplot 4 3 9:rotate 40 60:box:contx c '' 0:conty c '' 0:contz c '' 0\n"
-"subplot 4 3 10:rotate 40 60:box:contfx c '' 0:contfy c '' 0:contfz c '' 0\n";
+"subplot 4 3 10:rotate 40 60:box:contfx c '' 0:contfy c '' 0:contfz c '' 0";
 void smgl_param3(mglGraph *gr) // 3d parametric plots
 {
        mglData x(50,50,50), y(50,50,50), z(50,50,50), c(50,50,50), d(50,50,50);
@@ -523,7 +446,7 @@ const char *mmgl_paramv="new x 20 20 20 '(x+2)/3*sin(pi*y/2)'\n"
 "vect3 x y z ex ey ez:vect3 x y z ex ey ez 'x':vect3 x y z ex ey ez 'z'\n"
 "grid3 x y z z '{r9}':grid3 x y z z '{g9}x':grid3 x y z z '{b9}z'\n"
 "subplot 3 3 6:rotate 40 60:box:flow x y z ex ey ez\n"
-"subplot 3 3 7:rotate 40 60:box:pipe x y z ex ey ez\n";
+"subplot 3 3 7:rotate 40 60:box:pipe x y z ex ey ez";
 void smgl_paramv(mglGraph *gr) // parametric plots for vector field
 {
        mglData x(20,20,20), y(20,20,20), z(20,20,20), ex(20,20,20), ey(20,20,20), ez(20,20,20);
@@ -559,7 +482,7 @@ const char *mmgl_solve="zrange 0 1\nnew x 20 30 '(x+2)/3*cos(pi*y)'\n"
 "axis:box:xlabel 'i':ylabel 'j':grid2 z 'h'\n\n"
 "plot u v 'k2o':line 0.4 0.5 0.8 0.5 'kA'\n"
 "plot v1 u1 'b2^':line 0.5 0.15 0.5 0.3 'bA'\n"
-"plot v1 u2 'r2v':line 0.5 0.7 0.5 0.85 'rA'\n";
+"plot v1 u2 'r2v':line 0.5 0.7 0.5 0.85 'rA'";
 void smgl_solve(mglGraph *gr)  // solve and evaluate
 {
        gr->SetRange('z',0,1);
@@ -603,7 +526,7 @@ void smgl_solve(mglGraph *gr)       // solve and evaluate
 const char *mmgl_triangulation="new x 100 '2*rnd-1':new y 100 '2*rnd-1':copy z x^2-y^2\n"
 "new g 30 30:triangulate d x y\n"
 "title 'Triangulation'\nrotate 50 60:box:light on\n"
-"triplot d x y z:triplot d x y z '#k'\ndatagrid g x y z:mesh g 'm'\n";
+"triplot d x y z:triplot d x y z '#k'\ndatagrid g x y z:mesh g 'm'";
 void smgl_triangulation(mglGraph *gr)  // surface triangulation
 {
        mglData x(100), y(100), z(100);
@@ -620,7 +543,7 @@ void smgl_triangulation(mglGraph *gr)       // surface triangulation
 const char *mmgl_alpha="call 'prepare2d'\nsubplot 2 2 0:title 'default':rotate 50 60:box\nsurf a\n"
 "subplot 2 2 1:title 'light on':rotate 50 60:box\nlight on:surf a\n"
 "subplot 2 2 3:title 'light on; alpha on':rotate 50 60:box\nalpha on:surf a\n"
-"subplot 2 2 2:title 'alpha on':rotate 50 60:box\nlight off:surf a\n";
+"subplot 2 2 2:title 'alpha on':rotate 50 60:box\nlight off:surf a";
 void smgl_alpha(mglGraph *gr)  // alpha and lighting
 {
        mglData a;      mgls_prepare2d(&a);
@@ -637,39 +560,39 @@ void smgl_alpha(mglGraph *gr)     // alpha and lighting
 const char *mmgl_schemes="call 'sch' 0 'kw'\ncall 'sch' 1 'wk'\ncall 'sch' 2 'kHCcw'\ncall 'sch' 3 'kBbcw'\n"
 "call 'sch' 4 'kRryw'\ncall 'sch' 5 'kGgew'\ncall 'sch' 6 'BbwrR'\ncall 'sch' 7 'BbwgG'\n"
 "call 'sch' 8 'GgwmM'\ncall 'sch' 9 'UuwqR'\ncall 'sch' 10 'QqwcC'\ncall 'sch' 11 'CcwyY'\n"
-"call 'sch' 12 'bcwyr'\ncall 'sch' 13 'bwr'\ncall 'sch' 14 'BbcyrR'\ncall 'sch' 15 'UbcyqR'\n"
-"call 'sch' 16 'BbcwyrR'\ncall 'sch' 17 'bgr'\ncall 'sch' 18 'BbcyrR|'\ncall 'sch' 19 'b\\{g,0.3\\}r'\n"
+"call 'sch' 12 'bcwyr'\ncall 'sch' 13 'bwr'\ncall 'sch' 14 'wUrqy'\ncall 'sch' 15 'UbcyqR'\n"
+"call 'sch' 16 'BbcyrR'\ncall 'sch' 17 'bgr'\ncall 'sch' 18 'BbcyrR|'\ncall 'sch' 19 'b{g,0.3}r'\n"
 "stop\nfunc 'sch' 2\nsubplot 2 10 $1 '<>_^' 0.2 0:fsurf 'x' $2\n"
-"text 0.07+0.5*mod($1,2) 0.92-0.1*int($1/2) $2 'A'\nreturn\n";
+"text 0.07+0.5*mod($1,2) 0.92-0.1*int($1/2) $2 'A'\nreturn";
 void smgl_schemes(mglGraph *gr)        // Color table
 {
        mglData a(256,2);       a.Fill(-1,1);
-       gr->SubPlot(2,10,0,NULL,0.2);   gr->Dens(a,"kw");               gr->Puts(0.07, 0.92, "'kw'", "A");
-       gr->SubPlot(2,10,1,NULL,0.2);   gr->Dens(a,"wk");               gr->Puts(0.57, 0.92, "'wk'", "A");
-       gr->SubPlot(2,10,2,NULL,0.2);   gr->Dens(a,"kHCcw");    gr->Puts(0.07, 0.82, "'kHCcw'", "A");
-       gr->SubPlot(2,10,3,NULL,0.2);   gr->Dens(a,"kBbcw");    gr->Puts(0.57, 0.82, "'kBbcw'", "A");
-       gr->SubPlot(2,10,4,NULL,0.2);   gr->Dens(a,"kRryw");    gr->Puts(0.07, 0.72, "'kRryw'", "A");
-       gr->SubPlot(2,10,5,NULL,0.2);   gr->Dens(a,"kGgew");    gr->Puts(0.57, 0.72, "'kGgew'", "A");
-       gr->SubPlot(2,10,6,NULL,0.2);   gr->Dens(a,"BbwrR");    gr->Puts(0.07, 0.62, "'BbwrR'", "A");
-       gr->SubPlot(2,10,7,NULL,0.2);   gr->Dens(a,"BbwgG");    gr->Puts(0.57, 0.62, "'BbwgG'", "A");
-       gr->SubPlot(2,10,8,NULL,0.2);   gr->Dens(a,"GgwmM");    gr->Puts(0.07, 0.52, "'GgwmM'", "A");
-       gr->SubPlot(2,10,9,NULL,0.2);   gr->Dens(a,"UuwqR");    gr->Puts(0.57, 0.52, "'UuwqR'", "A");
-       gr->SubPlot(2,10,10,NULL,0.2);  gr->Dens(a,"QqwcC");    gr->Puts(0.07, 0.42, "'QqwcC'", "A");
-       gr->SubPlot(2,10,11,NULL,0.2);  gr->Dens(a,"CcwyY");    gr->Puts(0.57, 0.42, "'CcwyY'", "A");
-       gr->SubPlot(2,10,12,NULL,0.2);  gr->Dens(a,"bcwyr");    gr->Puts(0.07, 0.32, "'bcwyr'", "A");
-       gr->SubPlot(2,10,13,NULL,0.2);  gr->Dens(a,"bwr");              gr->Puts(0.57, 0.32, "'bwr'", "A");
-       gr->SubPlot(2,10,14,NULL,0.2);  gr->Dens(a,"BbcyrR");   gr->Puts(0.07, 0.22, "'BbcyrR'", "A");
-       gr->SubPlot(2,10,15,NULL,0.2);  gr->Dens(a,"UbcyqR");   gr->Puts(0.57, 0.22, "'UbcyqR'", "A");
-       gr->SubPlot(2,10,16,NULL,0.2);  gr->Dens(a,"BbcwyrR");  gr->Puts(0.07, 0.12, "'BbcwyrR'", "A");
-       gr->SubPlot(2,10,17,NULL,0.2);  gr->Dens(a,"bgr");              gr->Puts(0.57, 0.12, "'bgr'", "A");
-       gr->SubPlot(2,10,18,NULL,0.2);  gr->Dens(a,"BbcyrR|");  gr->Puts(0.07, 0.02, "'BbcyrR|'", "A");
-       gr->SubPlot(2,10,19,NULL,0.2);  gr->Dens(a,"b{g,0.3}r");                gr->Puts(0.57, 0.02, "'b\\{g,0.3\\}r'", "A");
+       gr->SubPlot(2,10,0,NULL,0.2);   gr->Dens(a,"kw");               gr->Puts(0.07, 0.92, "kw", "A");
+       gr->SubPlot(2,10,1,NULL,0.2);   gr->Dens(a,"wk");               gr->Puts(0.57, 0.92, "wk", "A");
+       gr->SubPlot(2,10,2,NULL,0.2);   gr->Dens(a,"kHCcw");    gr->Puts(0.07, 0.82, "kHCcw", "A");
+       gr->SubPlot(2,10,3,NULL,0.2);   gr->Dens(a,"kBbcw");    gr->Puts(0.57, 0.82, "kBbcw", "A");
+       gr->SubPlot(2,10,4,NULL,0.2);   gr->Dens(a,"kRryw");    gr->Puts(0.07, 0.72, "kRryw", "A");
+       gr->SubPlot(2,10,5,NULL,0.2);   gr->Dens(a,"kGgew");    gr->Puts(0.57, 0.72, "kGgew", "A");
+       gr->SubPlot(2,10,6,NULL,0.2);   gr->Dens(a,"BbwrR");    gr->Puts(0.07, 0.62, "BbwrR", "A");
+       gr->SubPlot(2,10,7,NULL,0.2);   gr->Dens(a,"BbwgG");    gr->Puts(0.57, 0.62, "BbwgG", "A");
+       gr->SubPlot(2,10,8,NULL,0.2);   gr->Dens(a,"GgwmM");    gr->Puts(0.07, 0.52, "GgwmM", "A");
+       gr->SubPlot(2,10,9,NULL,0.2);   gr->Dens(a,"UuwqR");    gr->Puts(0.57, 0.52, "UuwqR", "A");
+       gr->SubPlot(2,10,10,NULL,0.2);  gr->Dens(a,"QqwcC");    gr->Puts(0.07, 0.42, "QqwcC", "A");
+       gr->SubPlot(2,10,11,NULL,0.2);  gr->Dens(a,"CcwyY");    gr->Puts(0.57, 0.42, "CcwyY", "A");
+       gr->SubPlot(2,10,12,NULL,0.2);  gr->Dens(a,"bcwyr");    gr->Puts(0.07, 0.32, "bcwyr", "A");
+       gr->SubPlot(2,10,13,NULL,0.2);  gr->Dens(a,"bwr");              gr->Puts(0.57, 0.32, "bwr", "A");
+       gr->SubPlot(2,10,14,NULL,0.2);  gr->Dens(a,"wUrqy");    gr->Puts(0.07, 0.22, "wUrqy", "A");
+       gr->SubPlot(2,10,15,NULL,0.2);  gr->Dens(a,"UbcyqR");   gr->Puts(0.57, 0.22, "UbcyqR", "A");
+       gr->SubPlot(2,10,16,NULL,0.2);  gr->Dens(a,"BbcyrR");   gr->Puts(0.07, 0.12, "BbcyrR", "A");
+       gr->SubPlot(2,10,17,NULL,0.2);  gr->Dens(a,"bgr");              gr->Puts(0.57, 0.12, "bgr", "A");
+       gr->SubPlot(2,10,18,NULL,0.2);  gr->Dens(a,"BbcyrR|");  gr->Puts(0.07, 0.02, "BbcyrR|", "A");
+       gr->SubPlot(2,10,19,NULL,0.2);  gr->Dens(a,"b{g,0.3}r");                gr->Puts(0.57, 0.02, "b\\{g,0.3\\}r", "A");
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_curvcoor="origin -1 1 -1\nsubplot 2 2 0:title 'Cartesian':rotate 50 60:fplot '2*t-1' '0.5' '0' '2r':axis:grid\n"
 "axis 'y*sin(pi*x)' 'y*cos(pi*x)' '':subplot 2 2 1:title 'Cylindrical':rotate 50 60:fplot '2*t-1' '0.5' '0' '2r':axis:grid\n"
 "axis '2*y*x' 'y*y - x*x' '':subplot 2 2 2:title 'Parabolic':rotate 50 60:fplot '2*t-1' '0.5' '0' '2r':axis:grid\n"
-"axis 'y*sin(pi*x)' 'y*cos(pi*x)' 'x+z':subplot 2 2 3:title 'Spiral':rotate 50 60:fplot '2*t-1' '0.5' '0' '2r':axis:grid\n";
+"axis 'y*sin(pi*x)' 'y*cos(pi*x)' 'x+z':subplot 2 2 3:title 'Spiral':rotate 50 60:fplot '2*t-1' '0.5' '0' '2r':axis:grid";
 void smgl_curvcoor(mglGraph *gr)       // curvilinear coordinates
 {
        gr->SetOrigin(-1,1,-1);
@@ -699,16 +622,17 @@ const char *mmgl_style="";
 void smgl_style(mglGraph *gr)  // pen styles
 {
        gr->SubPlot(2,2,0);
-       double d,x1,x2,x0,y=0.95;
+       double d,x1,x2,x0,y=1.1, y1=1.15;
        d=0.3, x0=0.2, x1=0.5, x2=0.6;
-       gr->Line(mglPoint(x0,1-0*d),mglPoint(x1,1-0*d),"k-");   gr->Puts(mglPoint(x2,y-0*d),"Solid '-'",":rL");
-       gr->Line(mglPoint(x0,1-1*d),mglPoint(x1,1-1*d),"k|");   gr->Puts(mglPoint(x2,y-1*d),"Long Dash '|'",":rL");
-       gr->Line(mglPoint(x0,1-2*d),mglPoint(x1,1-2*d),"k;");   gr->Puts(mglPoint(x2,y-2*d),"Dash ';'",":rL");
-       gr->Line(mglPoint(x0,1-3*d),mglPoint(x1,1-3*d),"k=");   gr->Puts(mglPoint(x2,y-3*d),"Small dash '='",":rL");
-       gr->Line(mglPoint(x0,1-4*d),mglPoint(x1,1-4*d),"kj");   gr->Puts(mglPoint(x2,y-4*d),"Dash-dot 'j'",":rL");
-       gr->Line(mglPoint(x0,1-5*d),mglPoint(x1,1-5*d),"ki");   gr->Puts(mglPoint(x2,y-5*d),"Small dash-dot 'i'",":rL");
-       gr->Line(mglPoint(x0,1-6*d),mglPoint(x1,1-6*d),"k:");   gr->Puts(mglPoint(x2,y-6*d),"Dots ':'",":rL");
-       gr->Line(mglPoint(x0,1-7*d),mglPoint(x1,1-7*d),"k ");   gr->Puts(mglPoint(x2,y-7*d),"None ' '",":rL");
+       gr->Line(mglPoint(x0,y1-0*d),mglPoint(x1,y1-0*d),"k-"); gr->Puts(mglPoint(x2,y-0*d),"Solid '-'",":rL");
+       gr->Line(mglPoint(x0,y1-1*d),mglPoint(x1,y1-1*d),"k|"); gr->Puts(mglPoint(x2,y-1*d),"Long Dash '|'",":rL");
+       gr->Line(mglPoint(x0,y1-2*d),mglPoint(x1,y1-2*d),"k;"); gr->Puts(mglPoint(x2,y-2*d),"Dash ';'",":rL");
+       gr->Line(mglPoint(x0,y1-3*d),mglPoint(x1,y1-3*d),"k="); gr->Puts(mglPoint(x2,y-3*d),"Small dash '='",":rL");
+       gr->Line(mglPoint(x0,y1-4*d),mglPoint(x1,y1-4*d),"kj"); gr->Puts(mglPoint(x2,y-4*d),"Dash-dot 'j'",":rL");
+       gr->Line(mglPoint(x0,y1-5*d),mglPoint(x1,y1-5*d),"ki"); gr->Puts(mglPoint(x2,y-5*d),"Small dash-dot 'i'",":rL");
+       gr->Line(mglPoint(x0,y1-6*d),mglPoint(x1,y1-6*d),"k:"); gr->Puts(mglPoint(x2,y-6*d),"Dots ':'",":rL");
+       gr->Line(mglPoint(x0,y1-7*d),mglPoint(x1,y1-7*d),"k "); gr->Puts(mglPoint(x2,y-7*d),"None ' '",":rL");
+       gr->Line(mglPoint(x0,y1-8*d),mglPoint(x1,y1-8*d),"k{df090}");   gr->Puts(mglPoint(x2,y-8*d),"Manual '{df090}'",":rL");
 
        d=0.25; x1=-1; x0=-0.8; y = -0.05;
        gr->Mark(mglPoint(x1,5*d),"k.");                gr->Puts(mglPoint(x0,y+5*d),"'.'",":rL");
@@ -746,9 +670,10 @@ void smgl_style(mglGraph *gr)      // pen styles
        gr->Line(mglPoint(a,0),mglPoint(b,0),"k-S");            gr->Puts(mglPoint(c,0),"Style 'S' or 'S\\_'",":rL");
        gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"k-O");      gr->Puts(mglPoint(c,-0.2),"Style 'O' or 'O\\_'",":rL");
        gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"k-T");      gr->Puts(mglPoint(c,-0.4),"Style 'T' or 'T\\_'",":rL");
-       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-_");      gr->Puts(mglPoint(c,-0.6),"Style '\\_' or none",":rL");
-       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-AS");     gr->Puts(mglPoint(c,-0.8),"Style 'AS'",":rL");
-       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-_A");         gr->Puts(mglPoint(c,-1),"Style '\\_A'",":rL");
+       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-X");      gr->Puts(mglPoint(c,-0.6),"Style 'X' or 'X\\_'",":rL");
+       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-_");      gr->Puts(mglPoint(c,-0.8),"Style '\\_' or none",":rL");
+       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-AS");         gr->Puts(mglPoint(c,-1),"Style 'AS'",":rL");
+       gr->Line(mglPoint(a,-1.2),mglPoint(b,-1.2),"k-_A");     gr->Puts(mglPoint(c,-1.2),"Style '\\_A'",":rL");
 
        a=-1;   b=-0.7; c=-0.6;
        gr->Line(mglPoint(a,1),mglPoint(b,1),"kAA");            gr->Puts(mglPoint(c,1),"Style 'AA'",":rL");
@@ -759,9 +684,10 @@ void smgl_style(mglGraph *gr)      // pen styles
        gr->Line(mglPoint(a,0),mglPoint(b,0),"kSS");            gr->Puts(mglPoint(c,0),"Style 'SS'",":rL");
        gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"kOO");      gr->Puts(mglPoint(c,-0.2),"Style 'OO'",":rL");
        gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"kTT");      gr->Puts(mglPoint(c,-0.4),"Style 'TT'",":rL");
-       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-__");     gr->Puts(mglPoint(c,-0.6),"Style '\\_\\_'",":rL");
-       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-VA");     gr->Puts(mglPoint(c,-0.8),"Style 'VA'",":rL");
-       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-AV");         gr->Puts(mglPoint(c,-1),"Style 'AV'",":rL");
+       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"kXX");      gr->Puts(mglPoint(c,-0.6),"Style 'XX'",":rL");
+       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-__");     gr->Puts(mglPoint(c,-0.8),"Style '\\_\\_'",":rL");
+       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-VA");         gr->Puts(mglPoint(c,-1),"Style 'VA'",":rL");
+       gr->Line(mglPoint(a,-1.2),mglPoint(b,-1.2),"k-AV");     gr->Puts(mglPoint(c,-1.2),"Style 'AV'",":rL");
 
        gr->SubPlot(2,2,2);
        //#LENUQ
@@ -827,10 +753,11 @@ const char *mmgl_text="call 'prepare1d'\nsubplot 2 2 0 ''\ntext 0 1 'Text can be
 "text 0 -0.6 'Easy to change indexes ^{up} _{down} @{center}'\n"
 "text 0 -1 'It parse TeX: \\int \\alpha \\cdot \\\n\\sqrt3{sin(\\pi x)^2 + \\gamma_{i_k}} dx'\n"
 "subplot 2 2 1 ''\n text 0 0.5 '\\sqrt{\\frac{\\alpha^{\\gamma^2}+\\overset 1{\\big\\infty}}{\\sqrt3{2+b}}}' '@' -2\n"
-"text 0 -0.5 'Text can be printed\\n{}on several lines'\n"
+"text 0 -0.3 'Text can be printed\\n{}on several lines'\n"
+"text 0 -0.7 'or with color gradient' 'BbcyrR'\n"
 "subplot 2 2 2 '':box:plot y(:,0)\ntext y 'This is very very long string drawn along a curve' 'k'\ntext y 'Another string drawn above a curve' 'Tr'\n"
 "subplot 2 2 3 '':line -1 -1 1 -1 'rA':text 0 -1 1 -1 'Horizontal'\n"
-"line -1 -1 1 1 'rA':text 0 0 1 1 'At angle' '@'\nline -1 -1 -1 1 'rA':text -1 0 -1 1 'Vertical'\n";
+"line -1 -1 1 1 'rA':text 0 0 1 1 'At angle' '@'\nline -1 -1 -1 1 'rA':text -1 0 -1 1 'Vertical'";
 void smgl_text(mglGraph *gr)   // text drawing
 {
        if(big!=3)      gr->SubPlot(2,2,0,"");
@@ -847,13 +774,14 @@ void smgl_text(mglGraph *gr)      // text drawing
 
        gr->SubPlot(2,2,1,"");
        gr->Puts(mglPoint(0,0.5), "\\sqrt{\\frac{\\alpha^{\\gamma^2}+\\overset 1{\\big\\infty}}{\\sqrt3{2+b}}}", "@", -2);
-       gr->Puts(mglPoint(0,-0.5),"Text can be printed\non several lines");
+       gr->Puts(mglPoint(0,-0.3),"Text can be printed\non several lines");
+       gr->Puts(mglPoint(0,-0.7),"or with col\bor gradient","BbcyrR");
 
        gr->SubPlot(2,2,2,"");
        mglData y;      mgls_prepare1d(&y);
        gr->Box();      gr->Plot(y.SubData(-1,0));
        gr->Text(y,"This is very very long string drawn along a curve","k");
-       gr->Text(y,"Another string drawn above a curve","Tr");
+       gr->Text(y,"Another string drawn under a curve","Tr");
 
        gr->SubPlot(2,2,3,"");
        gr->Line(mglPoint(-1,-1),mglPoint(1,-1),"rA");  gr->Puts(mglPoint(0,-1),mglPoint(1,-1),"Horizontal");
@@ -862,33 +790,33 @@ void smgl_text(mglGraph *gr)      // text drawing
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_text2="call 'prepare1d'\n"
-"subplot 1 3 0 '':box:plot y(:,0)\ntext y 'This is very very long string drawn along a curve' 'k'\ntext y 'Another string drawn above a curve' 'Tr'\n"
-"subplot 1 3 1 '':box:plot y(:,0)\ntext y 'This is very very long string drawn along a curve' 'k:C'\ntext y 'Another string drawn above a curve' 'Tr:C'\n"
-"subplot 1 3 2 '':box:plot y(:,0)\ntext y 'This is very very long string drawn along a curve' 'k:R'\ntext y 'Another string drawn above a curve' 'Tr:R'\n";
+"subplot 1 3 0 '':box:plot y(:,0)\ntext y 'This is very very long string drawn along a curve' 'k'\ntext y 'Another string drawn under a curve' 'Tr'\n"
+"subplot 1 3 1 '':box:plot y(:,0)\ntext y 'This is very very long string drawn along a curve' 'k:C'\ntext y 'Another string drawn under a curve' 'Tr:C'\n"
+"subplot 1 3 2 '':box:plot y(:,0)\ntext y 'This is very very long string drawn along a curve' 'k:R'\ntext y 'Another string drawn under a curve' 'Tr:R'";
 void smgl_text2(mglGraph *gr)  // text drawing
 {
        mglData y;      mgls_prepare1d(&y);
        if(big!=3)      gr->SubPlot(1,3,0,"");
        gr->Box();      gr->Plot(y.SubData(-1,0));
        gr->Text(y,"This is very very long string drawn along a curve","k");
-       gr->Text(y,"Another string drawn above a curve","Tr");
+       gr->Text(y,"Another string drawn under a curve","Tr");
        if(big==3)      return;
 
        gr->SubPlot(1,3,1,"");
        gr->Box();      gr->Plot(y.SubData(-1,0));
        gr->Text(y,"This is very very long string drawn along a curve","k:C");
-       gr->Text(y,"Another string drawn above a curve","Tr:C");
+       gr->Text(y,"Another string drawn under a curve","Tr:C");
 
        gr->SubPlot(1,3,2,"");
        gr->Box();      gr->Plot(y.SubData(-1,0));
        gr->Text(y,"This is very very long string drawn along a curve","k:R");
-       gr->Text(y,"Another string drawn above a curve","Tr:R");
+       gr->Text(y,"Another string drawn under a curve","Tr:R");
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_fonts="define d 0.25\nloadfont 'STIX':text 0 1.1 'default font (STIX)'\nloadfont 'adventor':text 0 1.1-d 'adventor font'\n"
 "loadfont 'bonum':text 0 1.1-2*d 'bonum font'\nloadfont 'chorus':text 0 1.1-3*d 'chorus font'\nloadfont 'cursor':text 0 1.1-4*d 'cursor font'\n"
 "loadfont 'heros':text 0 1.1-5*d 'heros font'\nloadfont 'heroscn':text 0 1.1-6*d 'heroscn font'\nloadfont 'pagella':text 0 1.1-7*d 'pagella font'\n"
-"loadfont 'schola':text 0 1.1-8*d 'schola font'\nloadfont 'termes':text 0 1.1-9*d 'termes font'\nloadfont ''\n";
+"loadfont 'schola':text 0 1.1-8*d 'schola font'\nloadfont 'termes':text 0 1.1-9*d 'termes font'\nloadfont ''";
 void smgl_fonts(mglGraph *gr)  // font typefaces
 {
        double h=1.1, d=0.25;
@@ -909,7 +837,7 @@ const char *mmgl_bars="new ys 10 3 '0.8*sin(pi*(x+y/4+1.25))+0.2*rnd':origin 0 0
 "subplot 3 2 0 '':title 'Bars plot (default)':box:bars ys\nsubplot 3 2 1 '':title '2 colors':box:bars ys 'cbgGyr'\n"
 "subplot 3 2 4 '':title '\"\\#\" style':box:bars ys '#'\n"
 "new yc 30 'sin(pi*x)':new xc 30 'cos(pi*x)':new z 30 'x'\nsubplot 3 2 5:title '3d variant':rotate 50 60:box:bars xc yc z 'r'\n"
-"ranges -1 1 -3 3:subplot 3 2 2 '':title '\"a\" style':box:bars ys 'a'\nsubplot 3 2 3 '':title '\"f\" style':box:bars ys 'f'\n";
+"ranges -1 1 -3 3:subplot 3 2 2 '':title '\"a\" style':box:bars ys 'a'\nsubplot 3 2 3 '':title '\"f\" style':box:bars ys 'f'";
 void smgl_bars(mglGraph *gr)
 {
        mglData ys(10,3);       ys.Modify("0.8*sin(pi*(2*x+y/2))+0.2*rnd");
@@ -930,7 +858,7 @@ void smgl_bars(mglGraph *gr)
 //-----------------------------------------------------------------------------
 const char *mmgl_barh="new ys 10 3 '0.8*sin(pi*(x+y/4+1.25))+0.2*rnd':origin 0 0 0\n"
 "subplot 2 2 0 '':title 'Barh plot (default)':box:barh ys\nsubplot 2 2 1 '':title '2 colors':box:barh ys 'cbgGyr'\n"
-"ranges -3 3 -1 1:subplot 2 2 2 '':title '\"a\" style':box:barh ys 'a'\nsubplot 2 2 3 '': title '\"f\" style':box:barh ys 'f'\n";
+"ranges -3 3 -1 1:subplot 2 2 2 '':title '\"a\" style':box:barh ys 'a'\nsubplot 2 2 3 '': title '\"f\" style':box:barh ys 'f'";
 void smgl_barh(mglGraph *gr)
 {
        mglData ys(10,3);       ys.Modify("0.8*sin(pi*(2*x+y/2))+0.2*rnd");
@@ -947,7 +875,7 @@ void smgl_barh(mglGraph *gr)
 const char *mmgl_area="call 'prepare1d'\norigin 0 0 0\nsubplot 2 2 0 '':title 'Area plot (default)':box:area y\n"
 "subplot 2 2 1 '':title '2 colors':box:area y 'cbgGyr'\nsubplot 2 2 2 '':title '\"!\" style':box:area y '!'\n"
 "new yc 30 'sin(pi*x)':new xc 30 'cos(pi*x)':new z 30 'x'\nsubplot 2 2 3:title '3d variant':rotate 50 60:box\n"
-"area xc yc z 'r'\narea xc -yc z 'b#'\n";
+"area xc yc z 'r'\narea xc -yc z 'b#'";
 void smgl_area(mglGraph *gr)
 {
        mglData y;      mgls_prepare1d(&y);     gr->SetOrigin(0,0,0);
@@ -965,7 +893,7 @@ void smgl_area(mglGraph *gr)
 //-----------------------------------------------------------------------------
 const char *mmgl_plot="call 'prepare1d'\nsubplot 2 2 0 '':title 'Plot plot (default)':box:plot y\n"
 "subplot 2 2 2 '':title ''!' style; 'rgb' palette':box:plot y 'o!rgb'\nsubplot 2 2 3 '':title 'just markers':box:plot y ' +'\n"
-"new yc 30 'sin(pi*x)':new xc 30 'cos(pi*x)':new z 30 'x'\nsubplot 2 2 1:title '3d variant':rotate 50 60:box:plot xc yc z 'rs'\n";
+"new yc 30 'sin(pi*x)':new xc 30 'cos(pi*x)':new z 30 'x'\nsubplot 2 2 1:title '3d variant':rotate 50 60:box:plot xc yc z 'rs'";
 void smgl_plot(mglGraph *gr)
 {
        mglData y;      mgls_prepare1d(&y);     gr->SetOrigin(0,0,0);
@@ -983,7 +911,7 @@ void smgl_plot(mglGraph *gr)
 const char *mmgl_tens="call 'prepare1d'\nsubplot 2 2 0 '':title 'Tens plot (default)':box:tens y(:,0) y(:,1)\n"
 "subplot 2 2 2 '':title '\" \" style':box:tens y(:,0) y(:,1) 'o '\n"
 "new yc 30 'sin(pi*x)':new xc 30 'cos(pi*x)':new z 30 'x'\n"
-"subplot 2 2 1:title '3d variant':rotate 50 60:box:tens xc yc z z 's'\n";
+"subplot 2 2 1:title '3d variant':rotate 50 60:box:tens xc yc z z 's'";
 void smgl_tens(mglGraph *gr)
 {
        mglData y;      mgls_prepare1d(&y);     gr->SetOrigin(0,0,0);
@@ -1001,7 +929,7 @@ const char *mmgl_region="call 'prepare1d'\ncopy y1 y(:,1):copy y2 y(:,2)\n"
 "subplot 2 2 0 '':title 'Region plot (default)':box:region y1 y2:plot y1 'k2':plot y2 'k2'\n"
 "subplot 2 2 1 '':title '2 colors':box:region y1 y2 'yr':plot y1 'k2':plot y2 'k2'\n"
 "subplot 2 2 2 '':title '\"!\" style':box:region y1 y2 '!':plot y1 'k2':plot y2 'k2'\n"
-"subplot 2 2 3 '':title '\"i\" style':box:region y1 y2 'ir':plot y1 'k2':plot y2 'k2'\n";
+"subplot 2 2 3 '':title '\"i\" style':box:region y1 y2 'ir':plot y1 'k2':plot y2 'k2'";
 void smgl_region(mglGraph *gr)
 {
        mglData y;      mgls_prepare1d(&y);
@@ -1016,7 +944,7 @@ void smgl_region(mglGraph *gr)
 //-----------------------------------------------------------------------------
 const char *mmgl_stem="call 'prepare1d'\norigin 0 0 0:subplot 2 2 0 '':title 'Stem plot (default)':box:stem y\n"
 "new yc 30 'sin(pi*x)':new xc 30 'cos(pi*x)':new z 30 'x'\nsubplot 2 2 1:title '3d variant':rotate 50 60:box:stem xc yc z 'rx'\n"
-"subplot 2 2 2 '':title '\"!\" style':box:stem y 'o!rgb'\n";
+"subplot 2 2 2 '':title '\"!\" style':box:stem y 'o!rgb'";
 void smgl_stem(mglGraph *gr)
 {
        mglData y;      mgls_prepare1d(&y);     gr->SetOrigin(0,0,0);
@@ -1032,7 +960,7 @@ void smgl_stem(mglGraph *gr)
 //-----------------------------------------------------------------------------
 const char *mmgl_step="call 'prepare1d'\norigin 0 0 0:subplot 2 2 0 '':title 'Step plot (default)':box:step y\n"
 "new yc 30 'sin(pi*x)':new xc 30 'cos(pi*x)':new z 30 'x'\nsubplot 2 2 1:title '3d variant':rotate 50 60:box:step xc yc z 'r'\n"
-"subplot 2 2 2 '':title '\"!\" style':box:step y 's!rgb'\n";
+"subplot 2 2 2 '':title '\"!\" style':box:step y 's!rgb'";
 void smgl_step(mglGraph *gr)
 {
        mglData y;      mgls_prepare1d(&y);     gr->SetOrigin(0,0,0);
@@ -1046,7 +974,7 @@ void smgl_step(mglGraph *gr)
        gr->SubPlot(2,2,2,"");  gr->Title("'!' style"); gr->Box();      gr->Step(y,"s!rgb");
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_boxplot="new a 10 7 '(2*rnd-1)^3/2'\nsubplot 1 1 0 '':title 'Boxplot plot':box:boxplot a\n";
+const char *mmgl_boxplot="new a 10 7 '(2*rnd-1)^3/2'\nsubplot 1 1 0 '':title 'Boxplot plot':box:boxplot a";
 void smgl_boxplot(mglGraph *gr)        // flow threads and density plot
 {
        mglData a(10,7);        a.Modify("(2*rnd-1)^3/2");
@@ -1056,7 +984,7 @@ void smgl_boxplot(mglGraph *gr)    // flow threads and density plot
 //-----------------------------------------------------------------------------
 const char *mmgl_ohlc="new o 10 '0.5*sin(pi*x)'\nnew c 10 '0.5*sin(pi*(x+2/9))'\n"
 "new l 10 '0.3*rnd-0.8'\nnew h 10 '0.3*rnd+0.5'\n"
-"subplot 1 1 0 '':title 'OHLC plot':box:ohlc o h l c\n";
+"subplot 1 1 0 '':title 'OHLC plot':box:ohlc o h l c";
 void smgl_ohlc(mglGraph *gr)   // flow threads and density plot
 {
        mglData o(10), h(10), l(10), c(10);
@@ -1124,7 +1052,7 @@ const char *mmgl_molecule="alpha on:light on\n"
 "sphere 0 0 0 0.25 'b':drop 0 0 0 0.33 0.57 0 0.32 'n' 1 2\n"
 "sphere 0.33 0.57 0 0.25 'g':drop 0 0 0 0.33 -0.57 0 0.32 'n' 1 2\n"
 "sphere 0.33 -0.57 0 0.25 'g':drop 0 0 0 -0.65 0 0 0.32 'n' 1 2\n"
-"sphere -0.65 0 0 0.25 'g'\n";
+"sphere -0.65 0 0 0.25 'g'";
 void smgl_molecule(mglGraph *gr)       // example of moleculas
 {
        gr->VertexColor(false); gr->Compression(false); // per-vertex colors and compression are detrimental to transparency
@@ -1200,7 +1128,7 @@ const char *mmgl_error2="new x0 10 'rnd':new ex 10 '0.1'\nnew y0 10 'rnd':new ey
 "subplot 4 3 8 '':box:error x0 y0 ex ey 'o@'\n"
 "subplot 4 3 9 '':box:error x0 y0 ex ey '#o@'; alpha 0.5\n"
 "subplot 4 3 10 '':box:error x0 y0 ex ey '#.@'\n"
-"subplot 4 3 11 '':box:error x0 y0 ex ey; alpha 0.5\n";
+"subplot 4 3 11 '':box:error x0 y0 ex ey; alpha 0.5";
 void smgl_error2(mglGraph *gr)
 {
        mglData x0(10), y0(10), ex(10), ey(10);
@@ -1228,15 +1156,14 @@ const char *mmgl_error="call 'prepare1d'\nnew y 50 '0.7*sin(pi*x-pi) + 0.5*cos(3
 "subplot 2 2 1 '':title '\"!\" style; no e_x':box:plot y:error x0 y0 ey 'o!rgb'\n"
 "subplot 2 2 2 '':title '\"\\@\" style':alpha on:box:plot y:error x0 y0 ex ey '@'; alpha 0.5\n"
 "subplot 2 2 3:title '3d variant':rotate 50 60:axis\n"
-"for $1 0 9\n\terrbox 2*rnd-1 2*rnd-1 2*rnd-1 0.2 0.2 0.2 'bo'\nnext\n";
+"for $1 0 9\n\terrbox 2*rnd-1 2*rnd-1 2*rnd-1 0.2 0.2 0.2 'bo'\nnext";
 void smgl_error(mglGraph *gr)
 {
        mglData y;      mgls_prepare1d(&y);
        mglData x0(10), y0(10), ex0(10), ey0(10);
-       double x;
        for(int i=0;i<10;i++)
        {
-               x = i/9.;
+               double x = i/9.;
                x0.a[i] = 2*x-1 + 0.1*mgl_rnd()-0.05;
                y0.a[i] = 0.7*sin(2*M_PI*x)+0.5*cos(3*M_PI*x)+0.2*sin(M_PI*x)+0.2*mgl_rnd()-0.1;
                ey0.a[i]=0.2;   ex0.a[i]=0.1;
@@ -1260,7 +1187,7 @@ const char *mmgl_chart="new ch 7 2 'rnd+0.1':light on\n"
 "subplot 2 2 2:title 'Pie chart; \" \" color':rotate 50 60:\n"
 "axis '(y+1)/2*cos(pi*x)' '(y+1)/2*sin(pi*x)' '':box:chart ch 'bgr cmy#'\n"
 "subplot 2 2 3:title 'Ring chart; \" \" color':rotate 50 60:\n"
-"axis '(y+2)/3*cos(pi*x)' '(y+2)/3*sin(pi*x)' '':box:chart ch 'bgr cmy#'\n";
+"axis '(y+2)/3*cos(pi*x)' '(y+2)/3*sin(pi*x)' '':box:chart ch 'bgr cmy#'";
 void smgl_chart(mglGraph *gr)
 {
        mglData ch(7,2);        for(int i=0;i<7*2;i++)  ch.a[i]=mgl_rnd()+0.1;
@@ -1277,7 +1204,7 @@ void smgl_chart(mglGraph *gr)
        gr->Rotate(50,60);      gr->Box();      gr->Chart(ch,"bgr cmy#");
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_mark="call 'prepare1d'\nsubplot 1 1 0 '':title 'Mark plot (default)':box:mark y y1 's'\n";
+const char *mmgl_mark="call 'prepare1d'\nsubplot 1 1 0 '':title 'Mark plot (default)':box:mark y y1 's'";
 void smgl_mark(mglGraph *gr)
 {
        mglData y,y1;   mgls_prepare1d(&y,&y1);
@@ -1286,7 +1213,7 @@ void smgl_mark(mglGraph *gr)
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_radar="new yr 10 3 '0.4*sin(pi*(x+1.5+y/2)+0.1*rnd)'\n"
-"subplot 1 1 0 '':title 'Radar plot (with grid, \"\\#\")':radar yr '#'\n";
+"subplot 1 1 0 '':title 'Radar plot (with grid, \"\\#\")':radar yr '#'";
 void smgl_radar(mglGraph *gr)
 {
        mglData yr(10,3);       yr.Modify("0.4*sin(pi*(2*x+y))+0.1*rnd");
@@ -1294,8 +1221,8 @@ void smgl_radar(mglGraph *gr)
        gr->Radar(yr,"#");
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_candle="new y 30 'sin(pi*x/2)^2':copy y1 y/2:copy y2 (y+1)/2\n"
-"subplot 1 1 0 '':title 'Candle plot (default)'\nyrange 0 1:box:candle y y1 y2\n";
+const char *mmgl_candle="new y 30 'sin(pi*x/2)^2'\n"
+"subplot 1 1 0 '':title 'Candle plot (default)'\nyrange 0 1:box\ncandle y y/2 (y+1)/2";
 void smgl_candle(mglGraph *gr)
 {
        mglData y(30);  gr->Fill(y,"sin(pi*x/2)^2");
@@ -1305,7 +1232,7 @@ void smgl_candle(mglGraph *gr)
        gr->SetRange('y',0,1);  gr->Box();      gr->Candle(y,y1,y2);
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_textmark="call 'prepare1d'\nsubplot 1 1 0 '':title 'TextMark plot (default)':box:textmark y y1 '\\gamma' 'r'\n";
+const char *mmgl_textmark="call 'prepare1d'\nsubplot 1 1 0 '':title 'TextMark plot (default)':box:textmark y y1 '\\gamma' 'r'";
 void smgl_textmark(mglGraph *gr)
 {
        mglData y,y1;   mgls_prepare1d(&y,&y1);
@@ -1318,7 +1245,7 @@ const char *mmgl_tube="call 'prepare1d'\nlight on\n"
 "subplot 2 2 0 '':title 'Tube plot (default)':box:tube y 0.05\n"
 "subplot 2 2 1 '':title 'variable radius':box:tube y y1\n"
 "subplot 2 2 2 '':title '\"\\#\" style':box:tube y 0.05 '#'\n"
-"subplot 2 2 3:title '3d variant':rotate 50 60:box:tube xc yc z y2 'r'\n";
+"subplot 2 2 3:title '3d variant':rotate 50 60:box:tube xc yc z y2 'r'";
 void smgl_tube(mglGraph *gr)
 {
        mglData y,y1,y2;        mgls_prepare1d(&y,&y1,&y2);     y1/=20;
@@ -1339,7 +1266,7 @@ const char *mmgl_tape="call 'prepare1d'\nnew yc 50 'sin(pi*x)':new xc 50 'cos(pi
 "subplot 2 2 2:title '3d variant, x only':rotate 50 60\n"
 "box:plot xc yc z 'k':tape xc yc z 'xr':tape xc yc z 'xr#'\n"
 "subplot 2 2 3:title '3d variant, z only':rotate 50 60\n"
-"box:plot xc yc z 'k':tape xc yc z 'zg':tape xc yc z 'zg#'\n";
+"box:plot xc yc z 'k':tape xc yc z 'zg':tape xc yc z 'zg#'";
 void smgl_tape(mglGraph *gr)
 {
        mglData y;      mgls_prepare1d(&y);
@@ -1357,7 +1284,7 @@ void smgl_tape(mglGraph *gr)
        gr->Box();      gr->Plot(xc,yc,z,"k");  gr->Tape(xc,yc,z,"zg"); gr->Tape(xc,yc,z,"zg#");
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_fog="call 'prepare2d'\ntitle 'Fog sample':rotate 50 60:light on:fog 1\nbox:surf a:cont a 'y'\n";
+const char *mmgl_fog="call 'prepare2d'\ntitle 'Fog sample':rotate 50 60:light on:fog 1\nbox:surf a:cont a 'y'";
 void smgl_fog(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1369,7 +1296,7 @@ void smgl_fog(mglGraph *gr)
 const char *mmgl_map="new a 50 40 'x':new b 50 40 'y':zrange -2 2:text 0 0 '\\to'\n"
 "subplot 2 1 0:text 0 1.1 '\\{x, y\\}' '' -2:box:map a b 'brgk'\n"
 "subplot 2 1 1:text 0 1.1 '\\{\\frac{x^3+y^3}{2}, \\frac{x-y}{2}\\}' '' -2\n"
-"box:fill a '(x^3+y^3)/2':fill b '(x-y)/2':map a b 'brgk'\n";
+"box:fill a '(x^3+y^3)/2':fill b '(x-y)/2':map a b 'brgk'";
 void smgl_map(mglGraph *gr)    // example of mapping
 {
        mglData a(50, 40), b(50, 40);
@@ -1391,7 +1318,7 @@ void smgl_map(mglGraph *gr)       // example of mapping
 const char *mmgl_stfa="new a 2000:new b 2000\nfill a 'cos(50*pi*x)*(x<-.5)+cos(100*pi*x)*(x<0)*(x>-.5)+\\\n"
 "cos(200*pi*x)*(x<.5)*(x>0)+cos(400*pi*x)*(x>.5)'\n"
 "subplot 1 2 0 '<_':title 'Initial signal':plot a:axis:xlabel '\\i t'\n"
-"subplot 1 2 1 '<_':title 'STFA plot':stfa a b 64:axis:ylabel '\\omega' 0:xlabel '\\i t'\n";
+"subplot 1 2 1 '<_':title 'STFA plot':stfa a b 64:axis:ylabel '\\omega' 0:xlabel '\\i t'";
 void smgl_stfa(mglGraph *gr)   // STFA sample
 {
        mglData a(2000), b(2000);
@@ -1462,7 +1389,7 @@ void smgl_conta(mglGraph *gr)
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_contfa="call 'prepare3d'\ntitle 'Cont3 sample':rotate 50 60:box:light on\n"
-"contf3 c 'x':contf3 c:contf3 c 'z'\ncont3 c 'xk':cont3 c 'k':cont3 c 'zk'\n";
+"contf3 c 'x':contf3 c:contf3 c 'z'\ncont3 c 'xk':cont3 c 'k':cont3 c 'zk'";
 void smgl_contfa(mglGraph *gr)
 {
        mglData c;      mgls_prepare3d(&c);
@@ -1516,7 +1443,7 @@ void smgl_contf_xyz(mglGraph *gr)
 const char *mmgl_cloud="call 'prepare3d'\nsubplot 2 2 0:title 'Cloud plot':rotate 50 60:alpha on:box:cloud c 'wyrRk'\n"
 "subplot 2 2 1:title '\"i\" style':rotate 50 60:box:cloud c 'iwyrRk'\n"
 "subplot 2 2 2:title '\".\" style':rotate 50 60:box:cloud c '.wyrRk'\n"
-"subplot 2 2 3:title 'meshnum 10':rotate 50 60:box:cloud c 'wyrRk'; meshnum 10\n";
+"subplot 2 2 3:title 'meshnum 10':rotate 50 60:box:cloud c 'wyrRk'; meshnum 10";
 void smgl_cloud(mglGraph *gr)
 {
        mglData c;      mgls_prepare3d(&c);
@@ -1535,7 +1462,7 @@ void smgl_cloud(mglGraph *gr)
 const char *mmgl_cont="call 'prepare2d'\nlist v -0.5 -0.15 0 0.15 0.5\nsubplot 2 2 0:title 'Cont plot (default)':rotate 50 60:box:cont a\n"
 "subplot 2 2 1:title 'manual levels':rotate 50 60:box:cont v a\n"
 "subplot 2 2 2:title '\"\\_\" style':rotate 50 60:box:cont a '_'\n"
-"subplot 2 2 3 '':title '\"t\" style':box:cont a 't'\n";
+"subplot 2 2 3 '':title '\"t\" style':box:cont a 't'";
 void smgl_cont(mglGraph *gr)
 {
        mglData a,v(5); mgls_prepare2d(&a);     v.a[0]=-0.5;    v.a[1]=-0.15;   v.a[2]=0;       v.a[3]=0.15;    v.a[4]=0.5;
@@ -1555,7 +1482,7 @@ const char *mmgl_contf="call 'prepare2d'\nlist v -0.5 -0.15 0 0.15 0.5\n"
 "subplot 2 2 0:title 'ContF plot (default)':rotate 50 60:box:contf a\n"
 "subplot 2 2 1:title 'manual levels':rotate 50 60:box:contf v a\n"
 "subplot 2 2 2:title '\"\\_\" style':rotate 50 60:box:contf a '_'\n"
-"subplot 2 2 3:title 'several slices':rotate 50 60:box:contf a1\n";
+"subplot 2 2 3:title 'several slices':rotate 50 60:box:contf a1";
 void smgl_contf(mglGraph *gr)
 {
        mglData a,v(5),a1(30,40,3);     mgls_prepare2d(&a);     v.a[0]=-0.5;
@@ -1578,7 +1505,7 @@ const char *mmgl_contd="call 'prepare2d'\nlist v -0.5 -0.15 0 0.15 0.5\n"
 "subplot 2 2 0:title 'ContD plot (default)':rotate 50 60:box:contd a\n"
 "subplot 2 2 1:title 'manual levels':rotate 50 60:box:contd v a\n"
 "subplot 2 2 2:title '\"\\_\" style':rotate 50 60:box:contd a '_'\n"
-"subplot 2 2 3:title 'several slices':rotate 50 60:box:contd a1\n";
+"subplot 2 2 3:title 'several slices':rotate 50 60:box:contd a1";
 void smgl_contd(mglGraph *gr)
 {
        mglData a,v(5),a1(30,40,3);     mgls_prepare2d(&a);     v.a[0]=-0.5;
@@ -1600,7 +1527,7 @@ const char *mmgl_contv="call 'prepare2d'\nlist v -0.5 -0.15 0 0.15 0.5\n"
 "subplot 2 2 0:title 'ContV plot (default)':rotate 50 60:box:contv a\n"
 "subplot 2 2 1:title 'manual levels':rotate 50 60:box:contv v a\n"
 "subplot 2 2 2:title '\"\\_\" style':rotate 50 60:box:contv a '_'\n"
-"subplot 2 2 3:title 'ContV and ContF':rotate 50 60:light on:box\ncontv a:contf a:cont a 'k'\n";
+"subplot 2 2 3:title 'ContV and ContF':rotate 50 60:light on:box\ncontv a:contf a:cont a 'k'";
 void smgl_contv(mglGraph *gr)
 {
        mglData a,v(5); mgls_prepare2d(&a);     v.a[0]=-0.5;
@@ -1620,7 +1547,7 @@ void smgl_contv(mglGraph *gr)
 const char *mmgl_torus="call 'prepare1d'\nsubplot 2 2 0:title 'Torus plot (default)':light on:rotate 50 60:box:torus y1 y2\n"
 "subplot 2 2 1:title '\"x\" style':light on:rotate 50 60:box:torus y1 y2 'x'\n"
 "subplot 2 2 2:title '\"z\" style':light on:rotate 50 60:box:torus y1 y2 'z'\n"
-"subplot 2 2 3:title '\"\\#\" style':light on:rotate 50 60:box:torus y1 y2 '#'\n";
+"subplot 2 2 3:title '\"\\#\" style':light on:rotate 50 60:box:torus y1 y2 '#'";
 void smgl_torus(mglGraph *gr)
 {
        mglData y1,y2;  mgls_prepare1d(0,&y1,&y2);
@@ -1635,7 +1562,7 @@ void smgl_torus(mglGraph *gr)
 const char *mmgl_axial="call 'prepare2d'\nsubplot 2 2 0:title 'Axial plot (default)':light on:alpha on:rotate 50 60:box:axial a\n"
 "subplot 2 2 1:title '\"x\" style;\".\" style':light on:rotate 50 60:box:axial a 'x.'\n"
 "subplot 2 2 2:title '\"z\" style':light on:rotate 50 60:box:axial a 'z'\n"
-"subplot 2 2 3:title '\"\\#\" style':light on:rotate 50 60:box:axial a '#'\n";
+"subplot 2 2 3:title '\"\\#\" style':light on:rotate 50 60:box:axial a '#'";
 void smgl_axial(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1648,7 +1575,7 @@ void smgl_axial(mglGraph *gr)
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_several_light="call 'prepare2d'\ntitle 'Several light sources':rotate 50 60:light on\n"
-"light 1 0 1 0 'c':light 2 1 0 0 'y':light 3 0 -1 0 'm'\nbox:surf a 'h'\n";
+"light 1 0 1 0 'c':light 2 1 0 0 'y':light 3 0 -1 0 'm'\nbox:surf a 'h'";
 void smgl_several_light(mglGraph *gr)  // several light sources
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1666,7 +1593,7 @@ const char *mmgl_light="light on:quality 6\ncall 'prepare2d'\n"
 "line 1 0 1 -1 -1 0 'BAO'\n\n"
 "diffuse 0.5:light 0 1 0 1 -2 -1 -1 'w' 0\n"
 "subplot 2 2 3:title 'diffusive only':rotate 50 60:box:surf a\n"
-"line 1 0 1 -1 -1 0 'BAO'\n";
+"line 1 0 1 -1 -1 0 'BAO'";
 void smgl_light(mglGraph *gr)  // local light sources
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1692,7 +1619,7 @@ void smgl_light(mglGraph *gr)     // local light sources
 const char *mmgl_surf3="call 'prepare3d'\nlight on:alpha on\n"
 "subplot 2 2 0:title 'Surf3 plot (default)'\nrotate 50 60:box:surf3 c\n"
 "subplot 2 2 1:title '\"\\#\" style'\nrotate 50 60:box:surf3 c '#'\n"
-"subplot 2 2 2:title '\".\" style'\nrotate 50 60:box:surf3 c '.'\n";
+"subplot 2 2 2:title '\".\" style'\nrotate 50 60:box:surf3 c '.'";
 void smgl_surf3(mglGraph *gr)
 {
        mglData c;      mgls_prepare3d(&c);
@@ -1744,7 +1671,7 @@ void smgl_cut(mglGraph *gr)       // cutting
        gr->Box();      gr->Surf3(c);   gr->CutOff(""); // switch it off
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_traj="call 'prepare1d'\nsubplot 1 1 0 '':title 'Traj plot':box:plot x1 y:traj x1 y y1 y2\n";
+const char *mmgl_traj="call 'prepare1d'\nsubplot 1 1 0 '':title 'Traj plot':box:plot x1 y:traj x1 y y1 y2";
 void smgl_traj(mglGraph *gr)
 {
        mglData x,y,y1,y2;      mgls_prepare1d(&y,&y1,&y2,&x);
@@ -1752,7 +1679,7 @@ void smgl_traj(mglGraph *gr)
        gr->Box();      gr->Plot(x,y);  gr->Traj(x,y,y1,y2);
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_mesh="call 'prepare2d'\ntitle 'Mesh plot':rotate 50 60:box:mesh a\n";
+const char *mmgl_mesh="call 'prepare2d'\ntitle 'Mesh plot':rotate 50 60:box:mesh a";
 void smgl_mesh(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1760,7 +1687,7 @@ void smgl_mesh(mglGraph *gr)
        gr->Rotate(50,60);      gr->Box();      gr->Mesh(a);
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_fall="call 'prepare2d'\ntitle 'Fall plot':rotate 50 60:box:fall a\n";
+const char *mmgl_fall="call 'prepare2d'\ntitle 'Fall plot':rotate 50 60:box:fall a";
 void smgl_fall(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1772,7 +1699,7 @@ const char *mmgl_surf="call 'prepare2d'\nsubplot 2 2 0:title 'Surf plot (default
 "subplot 2 2 1:title '\"\\#\" style; meshnum 10':rotate 50 60:box:surf a '#'; meshnum 10\n"
 "subplot 2 2 2:title '\".\" style':rotate 50 60:box:surf a '.'\n"
 "new x 50 40 '0.8*sin(pi*x)*sin(pi*(y+1)/2)'\nnew y 50 40 '0.8*cos(pi*x)*sin(pi*(y+1)/2)'\nnew z 50 40 '0.8*cos(pi*(y+1)/2)'\n"
-"subplot 2 2 3:title 'parametric form':rotate 50 60:box:surf x y z 'BbwrR'\n";
+"subplot 2 2 3:title 'parametric form':rotate 50 60:box:surf x y z 'BbwrR'";
 void smgl_surf(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1814,7 +1741,7 @@ void smgl_parser(mglGraph *gr)    // example of MGL parsing
        delete parser;
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_belt="call 'prepare2d'\ntitle 'Belt plot':rotate 50 60:box:belt a\n";
+const char *mmgl_belt="call 'prepare2d'\ntitle 'Belt plot':rotate 50 60:box:belt a";
 void smgl_belt(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1826,7 +1753,7 @@ const char *mmgl_dens="call 'prepare2d'\nnew a1 30 40 3 '0.6*sin(2*pi*x+pi*(z+1)
 "subplot 2 2 0 '':title 'Dens plot (default)':box:dens a\n"
 "subplot 2 2 1:title '3d variant':rotate 50 60:box:dens a\n"
 "subplot 2 2 2 '':title '\"\\#\" style; meshnum 10':box:dens a '#'; meshnum 10\n"
-"subplot 2 2 3:title 'several slices':rotate 50 60:box:dens a1\n";
+"subplot 2 2 3:title 'several slices':rotate 50 60:box:dens a1";
 void smgl_dens(mglGraph *gr)
 {
        mglData a,a1(30,40,3);  mgls_prepare2d(&a);
@@ -1842,7 +1769,7 @@ void smgl_dens(mglGraph *gr)
        gr->Rotate(50,60);              gr->Box();      gr->Dens(a1);
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_surfc="call 'prepare2d'\ntitle 'SurfC plot':rotate 50 60:light on:box:surfc a b\n";
+const char *mmgl_surfc="call 'prepare2d'\ntitle 'SurfC plot':rotate 50 60:light on:box:surfc a b";
 void smgl_surfc(mglGraph *gr)
 {
        mglData a,b;    mgls_prepare2d(&a,&b);
@@ -1850,7 +1777,7 @@ void smgl_surfc(mglGraph *gr)
        gr->Light(true);        gr->Box();      gr->SurfC(a,b);
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_surfa="call 'prepare2d'\ntitle 'SurfA plot':rotate 50 60:light on:alpha on:box:surfa a b\n";
+const char *mmgl_surfa="call 'prepare2d'\ntitle 'SurfA plot':rotate 50 60:light on:alpha on:box:surfa a b";
 void smgl_surfa(mglGraph *gr)
 {
        mglData a,b;    mgls_prepare2d(&a,&b);
@@ -1858,7 +1785,7 @@ void smgl_surfa(mglGraph *gr)
        gr->Alpha(true);        gr->Light(true);        gr->Box();      gr->SurfA(a,b);
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_tile="call 'prepare2d'\ntitle 'Tile plot':rotate 50 60:box:tile a\n";
+const char *mmgl_tile="call 'prepare2d'\ntitle 'Tile plot':rotate 50 60:box:tile a";
 void smgl_tile(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1866,7 +1793,7 @@ void smgl_tile(mglGraph *gr)
        gr->Rotate(40,60);      gr->Box();      gr->Tile(a);
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_tiles="call 'prepare2d'\nsubplot 1 1 0 '':title 'Tiles plot':box:tiles a b\n";
+const char *mmgl_tiles="call 'prepare2d'\nsubplot 1 1 0 '':title 'Tiles plot':box:tiles a b";
 void smgl_tiles(mglGraph *gr)
 {
        mglData a,b;    mgls_prepare2d(&a,&b);
@@ -1877,7 +1804,7 @@ void smgl_tiles(mglGraph *gr)
 const char *mmgl_boxs="call 'prepare2d'\norigin 0 0 0\nsubplot 2 2 0:title 'Boxs plot (default)':rotate 40 60:light on:box:boxs a\n"
 "subplot 2 2 1:title '\"\\@\" style':rotate 50 60:box:boxs a '@'\n"
 "subplot 2 2 2:title '\"\\#\" style':rotate 50 60:box:boxs a '#'\n"
-"subplot 2 2 3:title 'compare with Tile':rotate 50 60:box:tile a\n";
+"subplot 2 2 3:title 'compare with Tile':rotate 50 60:box:tile a";
 void smgl_boxs(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -1895,9 +1822,9 @@ void smgl_boxs(mglGraph *gr)
 //-----------------------------------------------------------------------------
 const char *mmgl_fit="new rnd 100 '0.4*rnd+0.1+sin(2*pi*x)'\nnew in 100 '0.3+sin(2*pi*x)'\n"
 "list ini 1 1 3:fit res rnd 'a+b*sin(c*x)' 'abc' ini\n"
-"title 'Fitting sample':yrange -2 2:box:axis:plot rnd '. '\n"
+"title 'Fitting sample':yrange -2 2:box:axis:plot rnd 'k. '\n"
 "plot res 'r':plot in 'b'\ntext -0.9 -1.3 'fitted:' 'r:L'\n"
-"putsfit 0 -1.8 'y = ' 'r':text 0 2.2 'initial: y = 0.3+sin(2\\pi x)' 'b'\n";
+"putsfit 0 -1.8 'y = ' 'r':text 0 2.2 'initial: y = 0.3+sin(2\\pi x)' 'b'";
 void smgl_fit(mglGraph *gr)    // nonlinear fitting
 {
        mglData rnd(100), in(100), res;
@@ -1907,7 +1834,7 @@ void smgl_fit(mglGraph *gr)       // nonlinear fitting
        mglData Ini(3,ini);
        res = gr->Fit(rnd, "a+b*sin(c*x)", "abc", Ini);
        if(big!=3)      gr->Title("Fitting sample");
-       gr->SetRange('y',-2,2); gr->Box();      gr->Plot(rnd, ". ");
+       gr->SetRange('y',-2,2); gr->Box();      gr->Plot(rnd, "k. ");
        gr->Axis();             gr->Plot(res, "r");     gr->Plot(in, "b");
        gr->Puts(mglPoint(-0.9, -1.3), "fitted:", "r:L");
        gr->PutsFit(mglPoint(0, -1.8), "y = ", "r");
@@ -1919,7 +1846,7 @@ const char *mmgl_vecta="call 'prepare3v'\nsubplot 2 1 0:title 'Vect3 sample':rot
 "origin 0 0 0:box:axis '_xyz'\nvect3 ex ey ez 'x':vect3 ex ey ez:vect3 ex ey ez 'z'\n"
 "subplot 2 1 1:title '\"f\" style':rotate 50 60\n"
 "origin 0 0 0:box:axis '_xyz'\nvect3 ex ey ez 'fx':vect3 ex ey ez 'f':vect3 ex ey ez 'fz'\n"
-"grid3 ex 'Wx':grid3 ex 'W':grid3 ex 'Wz'\n";
+"grid3 ex 'Wx':grid3 ex 'W':grid3 ex 'Wz'";
 void smgl_vecta(mglGraph *gr)
 {
        mglData ex,ey,ez;       mgls_prepare3v(&ex,&ey,&ez);
@@ -1938,7 +1865,7 @@ const char *mmgl_vect="call 'prepare2v'\ncall 'prepare3v'\nsubplot 3 2 0 '':titl
 "subplot 3 2 2 '':title '\"f\" style':box:vect a b 'f'\n"
 "subplot 3 2 3 '':title '\">\" style':box:vect a b '>'\n"
 "subplot 3 2 4 '':title '\"<\" style':box:vect a b '<'\n"
-"subplot 3 2 5:title '3d variant':rotate 50 60:box:vect ex ey ez\n";
+"subplot 3 2 5:title '3d variant':rotate 50 60:box:vect ex ey ez";
 void smgl_vect(mglGraph *gr)
 {
        mglData a,b;    mgls_prepare2v(&a,&b);
@@ -1957,7 +1884,7 @@ void smgl_vect(mglGraph *gr)
 const char *mmgl_flow="call 'prepare2v'\ncall 'prepare3v'\nsubplot 2 2 0 '':title 'Flow plot (default)':box:flow a b\n"
 "subplot 2 2 1 '':title '\"v\" style':box:flow a b 'v'\n"
 "subplot 2 2 2 '':title 'from edges only':box:flow a b '#'\n"
-"subplot 2 2 3:title '3d variant':rotate 50 60:box:flow ex ey ez\n";
+"subplot 2 2 3:title '3d variant':rotate 50 60:box:flow ex ey ez";
 void smgl_flow(mglGraph *gr)
 {
        mglData a,b;    mgls_prepare2v(&a,&b);
@@ -1974,7 +1901,7 @@ void smgl_flow(mglGraph *gr)
 const char *mmgl_pipe="call 'prepare2v'\ncall 'prepare3v'\nsubplot 2 2 0 '':title 'Pipe plot (default)':light on:box:pipe a b\n"
 "subplot 2 2 1 '':title '\"i\" style':box:pipe a b 'i'\n"
 "subplot 2 2 2 '':title 'from edges only':box:pipe a b '#'\n"
-"subplot 2 2 3:title '3d variant':rotate 50 60:box:pipe ex ey ez '' 0.1\n";
+"subplot 2 2 3:title '3d variant':rotate 50 60:box:pipe ex ey ez '' 0.1";
 void smgl_pipe(mglGraph *gr)
 {
        mglData a,b;    mgls_prepare2v(&a,&b);
@@ -1988,7 +1915,7 @@ void smgl_pipe(mglGraph *gr)
        gr->Box();      gr->Pipe(ex,ey,ez,"",0.1);
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_dew="call 'prepare2v'\nsubplot 1 1 0 '':title 'Dew plot':light on:box:dew a b\n";
+const char *mmgl_dew="call 'prepare2v'\nsubplot 1 1 0 '':title 'Dew plot':light on:box:dew a b";
 void smgl_dew(mglGraph *gr)
 {
        mglData a,b;    mgls_prepare2v(&a,&b);
@@ -1996,7 +1923,7 @@ void smgl_dew(mglGraph *gr)
        gr->Box();      gr->Light(true);        gr->Dew(a,b);
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_grad="call 'prepare2d'\nsubplot 1 1 0 '':title 'Grad plot':box:grad a:dens a '{u8}w{q8}'\n";
+const char *mmgl_grad="call 'prepare2d'\nsubplot 1 1 0 '':title 'Grad plot':box:grad a:dens a '{u8}w{q8}'";
 void smgl_grad(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -2010,7 +1937,7 @@ const char *mmgl_cones="new ys 10 3 '0.8*sin(pi*(x+y/4+1.25))+0.2*rnd'\nlight on
 "subplot 3 2 2:title '\"\\#\" style':rotate 50 60:box:cones ys '#'\n"
 "subplot 3 2 3:title '\"a\" style':rotate 50 60:zrange -2 2:box:cones ys 'a'\n"
 "subplot 3 2 4:title '\"t\" style':rotate 50 60:box:cones ys 't'\n"
-"subplot 3 2 5:title '\"4\" style':rotate 50 60:box:cones ys '4'\n";
+"subplot 3 2 5:title '\"4\" style':rotate 50 60:box:cones ys '4'";
 void smgl_cones(mglGraph *gr)
 {
        mglData ys(10,3);       ys.Modify("0.8*sin(pi*(2*x+y/2))+0.2*rnd");
@@ -2033,7 +1960,7 @@ void smgl_cones(mglGraph *gr)
 //-----------------------------------------------------------------------------
 const char *mmgl_aspect="subplot 2 2 0:box:text -1 1.1 'Just box' ':L'\ninplot 0.2 0.5 0.7 1 off:box:text 0 1.2 'InPlot example'\n"
 "subplot 2 2 1:title 'Rotate only':rotate 50 60:box\nsubplot 2 2 2:title 'Rotate and Aspect':rotate 50 60:aspect 1 1 2:box\n"
-"subplot 2 2 3:title 'Aspect in other direction':rotate 50 60:aspect 1 2 2:box\n";
+"subplot 2 2 3:title 'Aspect in other direction':rotate 50 60:aspect 1 2 2:box";
 void smgl_aspect(mglGraph *gr) // transformation
 {
        gr->SubPlot(2,2,0);     gr->Box();
@@ -2055,7 +1982,7 @@ const char *mmgl_inplot="subplot 3 2 0:title 'StickPlot'\nstickplot 3 0 20 30:bo
 "subplot 3 2 4 '':title 'GridPlot'\ngridplot 2 2 0:box 'r':text 0 0 '0' 'r'\n"
 "gridplot 2 2 1:box 'g':text 0 0 '1' 'g'\ngridplot 2 2 2:box 'b':text 0 0 '2' 'b'\n"
 "gridplot 2 2 3:box 'm':text 0 0 '3' 'm'\nsubplot 3 2 5 '':title 'InPlot':box\n"
-"inplot 0.4 1 0.6 1 on:box 'r'\nmultiplot 3 2 1 2 1 '':title 'MultiPlot':box\n";
+"inplot 0.4 1 0.6 1 on:box 'r'\nmultiplot 3 2 1 2 1 '':title 'MultiPlot':box";
 void smgl_inplot(mglGraph *gr)
 {
        gr->SubPlot(3,2,0);     gr->Title("StickPlot");
@@ -2081,7 +2008,7 @@ const char *mmgl_combined="call 'prepare2v'\ncall 'prepare3d'\nnew v 10:fill v -
 "subplot 2 2 1 '':title 'Flow + Dens':light off:box:flow a b 'br':dens d\n"
 "subplot 2 2 2:title 'Mesh + Cont':rotate 50 60:box:mesh a:cont a '_'\n"
 "subplot 2 2 3:title 'Surf3 + ContF3':rotate 50 60:light on\n"
-"box:contf3 v c 'z' 0:contf3 v c 'x':contf3 v c\ncut 0 -1 -1 1 0 1.1\ncontf3 v c 'z' c.nz-1:surf3 c -0.5\n";
+"box:contf3 v c 'z' 0:contf3 v c 'x':contf3 v c\ncut 0 -1 -1 1 0 1.1\ncontf3 v c 'z' c.nz-1:surf3 c -0.5";
 void smgl_combined(mglGraph *gr)       // flow threads and density plot
 {
        mglData a,b,d;  mgls_prepare2v(&a,&b);  d = a;
@@ -2109,7 +2036,7 @@ const char *mmgl_axis="subplot 2 2 0:title 'Axis origin, Grid':origin 0 0:axis:g
 "inplot 0.5 1 0.5 1 on:ranges 0 10 0 2:axis\nfplot 'sqrt(x/2)':xlabel 'W' 1:ylabel 'U' 1\n"
 "inplot 0 0.5 0.5 1 on:ranges 1 0 0 2:axis 'x':fplot 'sqrt(x)+x^3':xlabel '\\tau' 1\n"
 "inplot 0.5 1 0 0.5 on:ranges 0 10 4 0:axis 'y':fplot 'x/4':ylabel 'L' -1\n"
-"inplot 0 0.5 0 0.5 on:ranges 1 0 4 0:fplot '4*x^2'\n";
+"inplot 0 0.5 0 0.5 on:ranges 1 0 4 0:fplot '4*x^2'";
 void smgl_axis(mglGraph *gr)
 {
        gr->SubPlot(2,2,0);     gr->Title("Axis origin, Grid"); gr->SetOrigin(0,0);
@@ -2136,38 +2063,54 @@ void smgl_axis(mglGraph *gr)
        gr->InPlot(0,0.5,0,0.5);        gr->SetRanges(1,0,4,0); gr->FPlot("4*x^2");
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_ticks="subplot 3 2 0:title 'Usual axis':axis\n"
-"subplot 3 2 1:title 'Too big/small range':ranges -1000 1000 0 0.001:axis\n"
-"subplot 3 2 3:title 'Too narrow range':ranges 100 100.1 10 10.01:axis\n"
-"subplot 3 2 4:title 'Disable ticks tuning':tuneticks off:axis\n"
-"subplot 3 2 2:title 'Manual ticks':ranges -pi pi 0 2:\n"
-"xtick -pi '\\pi' -pi/2 '-\\pi/2' 0 '0' 0.886 'x^*' pi/2 '\\pi/2' pi 'pi'\n"
-"# or you can use:\n#list v -pi -pi/2 0 0.886 pi/2 pi:xtick v '-\\pi\\n-\\pi/2\\n{}0\\n{}x^*\\n\\pi/2\\n\\pi'\n"
-"axis:grid:fplot '2*cos(x^2)^2' 'r2'\n"
-"subplot 3 2 5:title 'Time ticks':xrange 0 3e5:ticktime 'x':axis\n";
+const char *mmgl_ticks="subplot 3 3 0:title 'Usual axis'\naxis\n\n"
+"subplot 3 3 1:title 'Too big/small range'\nranges -1000 1000 0 0.001:axis\n\n"
+"subplot 3 3 2:title 'LaTeX-like labels'\naxis 'F!'\n\n"
+"subplot 3 3 3:title 'Too narrow range'\nranges 100 100.1 10 10.01:axis\n\n"
+"subplot 3 3 4:title 'No tuning, manual \"+\"'\naxis '+!'\n"
+"# for version <2.3 you can use\n#tuneticks off:axis\n\n"
+"subplot 3 3 5:title 'Template for ticks'\nxtick 'xxx:%g':ytick 'y:%g'\naxis\n\n"
+"xtick '':ytick '' # switch it off for other plots\n\n"
+"subplot 3 3 6:title 'No tuning, higher precision'\naxis '!4'\n\n"
+"subplot 3 3 7:title 'Manual ticks'\nranges -pi pi 0 2\n"
+"xtick pi 3 '\\pi'\nxtick 0.886 'x^*' on # note this will disable subticks drawing\n"
+"# or you can use\n#xtick -pi '\\pi' -pi/2 '-\\pi/2' 0 '0' 0.886 'x^*' pi/2 '\\pi/2' pi 'pi'\n"
+"# or you can use\n#list v -pi -pi/2 0 0.886 pi/2 pi:xtick v '-\\pi\\n-\\pi/2\\n{}0\\n{}x^*\\n\\pi/2\\n\\pi'\n"
+"axis:grid:fplot '2*cos(x^2)^2' 'r2'\n\n"
+"subplot 3 3 8:title 'Time ticks'\nxrange 0 3e5:ticktime 'x':axis";
 void smgl_ticks(mglGraph *gr)
 {
-       gr->SubPlot(3,2,0);     gr->Title("Usual axis");        gr->Axis();
-       gr->SubPlot(3,2,1);     gr->Title("Too big/small range");
+       gr->SubPlot(3,3,0);     gr->Title("Usual axis");        gr->Axis();
+       gr->SubPlot(3,3,1);     gr->Title("Too big/small range");
        gr->SetRanges(-1000,1000,0,0.001);      gr->Axis();
-       gr->SubPlot(3,2,3);     gr->Title("Too narrow range");
+       gr->SubPlot(3,3,2);     gr->Title("LaTeX-like labels");
+       gr->Axis("F!");
+       gr->SubPlot(3,3,3);     gr->Title("Too narrow range");
        gr->SetRanges(100,100.1,10,10.01);      gr->Axis();
-       gr->SubPlot(3,2,4);     gr->Title("Disable ticks tuning");
-       gr->SetTuneTicks(0);    gr->Axis();
-
-       gr->SubPlot(3,2,2);     gr->Title("Manual ticks");      gr->SetRanges(-M_PI,M_PI, 0, 2);
-       double val[]={-M_PI, -M_PI/2, 0, 0.886, M_PI/2, M_PI};
-       gr->SetTicksVal('x', mglData(6,val), "-\\pi\n-\\pi/2\n0\nx^*\n\\pi/2\n\\pi");
+       gr->SubPlot(3,3,4);     gr->Title("No tuning, manual '+'");
+       // for version<2.3 you need first call gr->SetTuneTicks(0);
+       gr->Axis("+!");
+       gr->SubPlot(3,3,5);     gr->Title("Template for ticks");
+       gr->SetTickTempl('x',"xxx:%g"); gr->SetTickTempl('y',"y:%g");
+       gr->Axis();
+       // now switch it off for other plots
+       gr->SetTickTempl('x',"");       gr->SetTickTempl('y',"");
+       gr->SubPlot(3,3,6);     gr->Title("No tuning, higher precision");
+       gr->Axis("!4");
+       gr->SubPlot(3,3,7);     gr->Title("Manual ticks");      gr->SetRanges(-M_PI,M_PI, 0, 2);
+       gr->SetTicks('x',M_PI,0,0,"\\pi");      gr->AddTick('x',0.886,"x^*");
+       // alternatively you can use following lines
+       //double val[]={-M_PI, -M_PI/2, 0, 0.886, M_PI/2, M_PI};
+       //gr->SetTicksVal('x', mglData(6,val), "-\\pi\n-\\pi/2\n0\nx^*\n\\pi/2\n\\pi");
        gr->Axis();     gr->Grid();     gr->FPlot("2*cos(x^2)^2", "r2");
-
-       gr->SubPlot(3,2,5);     gr->Title("Time ticks");        gr->SetRange('x',0,3e5);
+       gr->SubPlot(3,3,8);     gr->Title("Time ticks");        gr->SetRange('x',0,3e5);
        gr->SetTicksTime('x',0);        gr->Axis();
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_box="subplot 2 2 0:title 'Box (default)':rotate 50 60:box\n"
 "subplot 2 2 1:title 'colored':rotate 50 60:box 'r'\n"
 "subplot 2 2 2:title 'with faces':rotate 50 60:box '@'\n"
-"subplot 2 2 3:title 'both':rotate 50 60:box '@cm'\n";
+"subplot 2 2 3:title 'both':rotate 50 60:box '@cm'";
 void smgl_box(mglGraph *gr)
 {
        gr->SubPlot(2,2,0);     gr->Title("Box (default)");     gr->Rotate(50,60);      gr->Box();
@@ -2179,17 +2122,17 @@ void smgl_box(mglGraph *gr)
 const char *mmgl_loglog="subplot 2 2 0 '<_':title 'Semi-log axis':ranges 0.01 100 -1 1:axis 'lg(x)' '' ''\n"
 "axis:grid 'xy' 'g':fplot 'sin(1/x)':xlabel 'x' 0:ylabel 'y = sin 1/x' 0\n"
 "subplot 2 2 1 '<_':title 'Log-log axis':ranges 0.01 100 0.1 100:axis 'lg(x)' 'lg(y)' ''\n"
-"axis:fplot 'sqrt(1+x^2)':xlabel 'x' 0:ylabel 'y = \\sqrt{1+x^2}' 0\n"
+"axis:grid '!' 'h=':grid:fplot 'sqrt(1+x^2)'\nxlabel 'x' 0:ylabel 'y = \\sqrt{1+x^2}' 0\n"
 "subplot 2 2 2 '<_':title 'Minus-log axis':ranges -100 -0.01 -100 -0.1:axis '-lg(-x)' '-lg(-y)' ''\n"
 "axis:fplot '-sqrt(1+x^2)':xlabel 'x' 0:ylabel 'y = -\\sqrt{1+x^2}' 0\n"
 "subplot 2 2 3 '<_':title 'Log-ticks':ranges 0.01 100 0 100:axis 'sqrt(x)' '' ''\n"
-"axis:fplot 'x':xlabel 'x' 1:ylabel 'y = x' 0\n";
+"axis:fplot 'x':xlabel 'x' 1:ylabel 'y = x' 0";
 void smgl_loglog(mglGraph *gr) // log-log axis
 {
        gr->SubPlot(2,2,0,"<_");        gr->Title("Semi-log axis");     gr->SetRanges(0.01,100,-1,1);   gr->SetFunc("lg(x)","");
        gr->Axis();     gr->Grid("xy","g");     gr->FPlot("sin(1/x)");  gr->Label('x',"x",0); gr->Label('y', "y = sin 1/x",0);
        gr->SubPlot(2,2,1,"<_");        gr->Title("Log-log axis");      gr->SetRanges(0.01,100,0.1,100);        gr->SetFunc("lg(x)","lg(y)");
-       gr->Axis();     gr->FPlot("sqrt(1+x^2)");       gr->Label('x',"x",0); gr->Label('y', "y = \\sqrt{1+x^2}",0);
+       gr->Axis();     gr->Grid("!","h=");     gr->Grid();     gr->FPlot("sqrt(1+x^2)");       gr->Label('x',"x",0); gr->Label('y', "y = \\sqrt{1+x^2}",0);
        gr->SubPlot(2,2,2,"<_");        gr->Title("Minus-log axis");    gr->SetRanges(-100,-0.01,-100,-0.1);    gr->SetFunc("-lg(-x)","-lg(-y)");
        gr->Axis();     gr->FPlot("-sqrt(1+x^2)");      gr->Label('x',"x",0); gr->Label('y', "y = -\\sqrt{1+x^2}",0);
        gr->SubPlot(2,2,3,"<_");        gr->Title("Log-ticks"); gr->SetRanges(0.1,100,0,100);   gr->SetFunc("sqrt(x)","");
@@ -2197,7 +2140,7 @@ void smgl_loglog(mglGraph *gr)    // log-log axis
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_venn="list x -0.3 0 0.3:list y 0.3 -0.3 0.3:list e 0.7 0.7 0.7\n"
-"subplot 1 1 0:title 'Venn-like diagram'\ntransptype 1:alpha on:error x y e e '!rgb@#o'";
+"subplot 1 1 0:title 'Venn-like diagram'\ntransptype 1:alpha on:error x y e e '!rgb@#o';alpha 0.1";
 void smgl_venn(mglGraph *gr)
 {
        double xx[3]={-0.3,0,0.3}, yy[3]={0.3,-0.3,0.3}, ee[3]={0.7,0.7,0.7};
@@ -2206,7 +2149,7 @@ void smgl_venn(mglGraph *gr)
        gr->SetTranspType(1);   gr->Alpha(true);        gr->Error(x,y,e,e,"!rgb@#o","alpha 0.1");
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_stereo="call 'prepare2d'\nlight on\nsubplot 2 1 0:rotate 50 60+1:box:surf a\nsubplot 2 1 1:rotate 50 60-1:box:surf a\n";
+const char *mmgl_stereo="call 'prepare2d'\nlight on\nsubplot 2 1 0:rotate 50 60+1:box:surf a\nsubplot 2 1 1:rotate 50 60-1:box:surf a";
 void smgl_stereo(mglGraph *gr)
 {
        mglData a;      mgls_prepare2d(&a);
@@ -2220,7 +2163,7 @@ void smgl_stereo(mglGraph *gr)
 const char *mmgl_hist="new x 10000 '2*rnd-1':new y 10000 '2*rnd-1':copy z exp(-6*(x^2+y^2))\n"
 "hist xx x z:norm xx 0 1:hist yy y z:norm yy 0 1\nmultiplot 3 3 3 2 2 '':ranges -1 1 -1 1 0 1:box:dots x y z 'wyrRk'\n"
 "multiplot 3 3 0 2 1 '':ranges -1 1 0 1:box:bars xx\nmultiplot 3 3 5 1 2 '':ranges 0 1 -1 1:box:barh yy\n"
-"subplot 3 3 2:text 0.5 0.5 'Hist and\\n{}MultiPlot\\n{}sample' 'a' -3\n";
+"subplot 3 3 2:text 0.5 0.5 'Hist and\\n{}MultiPlot\\n{}sample' 'a' -3";
 void smgl_hist(mglGraph *gr)
 {
        mglData x(10000), y(10000), z(10000);   gr->Fill(x,"2*rnd-1");  gr->Fill(y,"2*rnd-1");  gr->Fill(z,"exp(-6*(v^2+w^2))",x,y);
@@ -2250,7 +2193,7 @@ const char *mmgl_primitives="subplot 2 2 0 '':title 'Line, Curve, Rhomb, Ellipse
 "text -0.9 -1.1 'asp=0.33':drop -0.9 -0.7 0 1 0.5 'b' 0 0.33\n"
 "text -0.3 -1.1 'asp=0.67':drop -0.3 -0.7 0 1 0.5 'b' 0 0.67\n"
 "text 0.3 -1.1 'asp=1':drop 0.3 -0.7 0 1 0.5 'b' 0 1\n"
-"text 0.9 -1.1 'asp=1.5':drop 0.9 -0.7 0 1 0.5 'b' 0 1.5\n";
+"text 0.9 -1.1 'asp=1.5':drop 0.9 -0.7 0 1 0.5 'b' 0 1.5";
 void smgl_primitives(mglGraph *gr)     // flag #
 {
        gr->SubPlot(2,2,0,"");  gr->Title("Line, Curve, Rhomb, Ellipse","",-1.5);
@@ -2303,7 +2246,7 @@ const char *mmgl_table="new ys 10 3 '0.8*sin(pi*(x+y/4+1.25))+0.2*rnd'\n"
 "subplot 2 2 1:title 'no borders, colored'\ntable ys 'y_1\\n{}y_2\\n{}y_3' 'r|'\n\n"
 "subplot 2 2 2:title 'no font decrease'\ntable ys 'y_1\\n{}y_2\\n{}y_3' '#'\n\n"
 "subplot 2 2 3:title 'manual width and position':box\n"
-"table 0.5 0.95 ys 'y_1\\n{}y_2\\n{}y_3' '#';value 0.7\n";
+"table 0.5 0.95 ys 'y_1\\n{}y_2\\n{}y_3' '#';value 0.7";
 void smgl_table(mglGraph *gr)
 {
        mglData ys(10,3);       ys.Modify("0.8*sin(pi*(2*x+y/2))+0.2*rnd");
@@ -2319,7 +2262,7 @@ void smgl_table(mglGraph *gr)
 }
 //-----------------------------------------------------------------------------
 const char *mmgl_label="new ys 10 '0.2*rnd-0.8*sin(pi*x)'\n"
-"subplot 1 1 0 '':title 'Label plot':box:plot ys ' *':label ys 'y=%y'\n";
+"subplot 1 1 0 '':title 'Label plot':box:plot ys ' *':label ys 'y=%y'";
 void smgl_label(mglGraph *gr)
 {
        mglData ys(10); ys.Modify("0.8*sin(pi*2*x)+0.2*rnd");
@@ -2336,7 +2279,7 @@ const char *mmgl_colorbar="call 'prepare2d'\nnew v 9 'x'\nsubplot 2 2 0:title 'C
 "subplot 2 2 3:title '':text -0.5 1.55 'Color positions' ':C' -2\n"
 "colorbar 'bwr>' 0.25 0:text -0.9 1.2 'Default'\n"
 "colorbar 'b{w,0.3}r>' 0.5 0:text -0.1 1.2 'Manual'\ncrange 0.01 1e3\n"
-"colorbar '>' 0.75 0:text 0.65 1.2 'Normal scale':colorbar '>':text 1.35 1.2 'Log scale'\n";
+"colorbar '>' 0.75 0:text 0.65 1.2 'Normal scale':colorbar '>':text 1.35 1.2 'Log scale'";
 void smgl_colorbar(mglGraph *gr)
 {
        gr->SubPlot(2,2,0);     gr->Title("Colorbar out of box");       gr->Box();
@@ -2367,7 +2310,7 @@ const char *mmgl_legend="addlegend 'sin(\\pi {x^2})' 'b':addlegend 'sin(\\pi x)'
 "subplot 2 2 2 '':title 'coloring':box:legend 0 'r#':legend 1 'Wb#':legend 2 'ygr#'\n"
 "subplot 2 2 3 '':title 'manual position':box\n"
 "legend 0.5 1:text 0.5 0.55 'at x=0.5, y=1' 'a'\n"
-"legend 1 '#-':text 0.75 0.25 'Horizontal legend' 'a'\n";
+"legend 1 '#-':text 0.75 0.25 'Horizontal legend' 'a'";
 void smgl_legend(mglGraph *gr)
 {
        gr->AddLegend("sin(\\pi {x^2})","b");
@@ -2393,7 +2336,7 @@ const char *mmgl_dat_diff="ranges 0 1 0 1 0 1:new a 30 40 'x*y'\n"
 "subplot 2 2 0:title 'a(x,y)':rotate 60 40:surf a:box\n"
 "subplot 2 2 1:title 'da/dx':rotate 60 40:diff a 'x':surf a:box\n"
 "subplot 2 2 2:title '\\int da/dx dxdy':rotate 60 40:integrate a 'xy':surf a:box\n"
-"subplot 2 2 3:title '\\int {d^2}a/dxdy dx':rotate 60 40:diff2 a 'y':surf a:box\n";
+"subplot 2 2 3:title '\\int {d^2}a/dxdy dx':rotate 60 40:diff2 a 'y':surf a:box";
 void smgl_dat_diff(mglGraph *gr)       // differentiate
 {
        gr->SetRanges(0,1,0,1,0,1);
@@ -2416,7 +2359,7 @@ const char *mmgl_dat_extra="subplot 2 2 0 '':title 'Envelop sample':new d1 1000
 "subplot 2 2 2:title 'Sew sample':rotate 50 60:light on:alpha on\nnew d2 100 100 'mod((y^2-(1-x)^2)/2,0.1)'\n"
 "box:surf d2 'b':sew d2 'xy' 0.1:surf d2 'r'\n"
 "subplot 2 2 3:title 'Resize sample (interpolation)'\nnew x0 10 'rnd':new v0 10 'rnd'\n"
-"resize x1 x0 100:resize v1 v0 100\nplot x0 v0 'b+ ':plot x1 v1 'r-':label x0 v0 '%n'\n";
+"resize x1 x0 100:resize v1 v0 100\nplot x0 v0 'b+ ':plot x1 v1 'r-':label x0 v0 '%n'";
 void smgl_dat_extra(mglGraph *gr)      // differentiate
 {
        gr->SubPlot(2,2,0,"");  gr->Title("Envelop sample");
@@ -2463,7 +2406,7 @@ const char *mmgl_ternary="ranges 0 1 0 1 0 1\nnew x 50 '0.25*(1+cos(2*pi*x))'\n"
 "subplot 2 2 2:title 'Quaternary axis 3D':rotate 50 60:ternary 2\nbox:axis:grid 'xyz' 'B;'\n"
 "plot x y z 'r2':surf a '#'\nxlabel 'B':ylabel 'C':tlabel 'A':zlabel 'D'\n\n"
 "subplot 2 2 3:title 'Ternary axis 3D':rotate 50 60:ternary 1\nbox:axis:grid 'xyz' 'B;'\n"
-"plot x y z 'r2':surf a '#'\nxlabel 'B':ylabel 'C':tlabel 'A':zlabel 'Z'\n";
+"plot x y z 'r2':surf a '#'\nxlabel 'B':ylabel 'C':tlabel 'A':zlabel 'Z'";
 void smgl_ternary(mglGraph *gr)        // flag #
 {
        gr->SetRanges(0,1,0,1,0,1);
@@ -2508,7 +2451,7 @@ const char *mmgl_projection="ranges 0 1 0 1 0 1\nnew x 50 '0.25*(1+cos(2*pi*x))'
 "new y 50 '0.25*(1+sin(2*pi*x))'\nnew z 50 'x'\nnew a 20 30 '30*x*y*(1-x-y)^2*(x+y<1)'\n"
 "new rx 10 'rnd':new ry 10:fill ry '(1-v)*rnd' rx\nlight on\n\n"
 "title 'Projection sample':ternary 4:rotate 50 60\nbox:axis:grid\n"
-"plot x y z 'r2':surf a '#'\nxlabel 'X':ylabel 'Y':zlabel 'Z'\n";
+"plot x y z 'r2':surf a '#'\nxlabel 'X':ylabel 'Y':zlabel 'Z'";
 void smgl_projection(mglGraph *gr)     // flag #
 {
        gr->SetRanges(0,1,0,1,0,1);
@@ -2531,7 +2474,7 @@ const char *mmgl_projection5="ranges 0 1 0 1 0 1\nnew x 50 '0.25*(1+cos(2*pi*x))
 "new y 50 '0.25*(1+sin(2*pi*x))'\nnew z 50 'x'\nnew a 20 30 '30*x*y*(1-x-y)^2*(x+y<1)'\n"
 "new rx 10 'rnd':new ry 10:fill ry '(1-v)*rnd' rx\nlight on\n\n"
 "title 'Projection sample (ternary)':ternary 5:rotate 50 60\nbox:axis:grid\n"
-"plot x y z 'r2':surf a '#'\nxlabel 'X':ylabel 'Y':zlabel 'Z'\n";
+"plot x y z 'r2':surf a '#'\nxlabel 'X':ylabel 'Y':zlabel 'Z'";
 void smgl_projection5(mglGraph *gr)    // flag #
 {
        gr->SetRanges(0,1,0,1,0,1);
@@ -2561,7 +2504,7 @@ const char *mmgl_triplot="list q 0 1 2 3 | 4 5 6 7 | 0 2 4 6 | 1 3 5 7 | 0 4 1 5
 "subplot 2 2 1:title 'TriPlot sample':rotate 50 60\n"
 "triplot t xt yt zt 'b'\ntriplot t xt yt zt '#k'\n"
 "subplot 2 2 3:title 'TriPlot coloring':rotate 50 60\n"
-"triplot t xt yt zt yt 'cb'\ntriplot t xt yt zt '#k'\ntricont t xt yt zt 'B'\n";
+"triplot t xt yt zt yt 'cb'\ntriplot t xt yt zt '#k'\ntricont t xt yt zt 'B'";
 void smgl_triplot(mglGraph *gr)
 {
        double q[] = {0,1,2,3, 4,5,6,7, 0,2,4,6, 1,3,5,7, 0,4,1,5, 2,6,3,7};
@@ -2587,22 +2530,31 @@ void smgl_triplot(mglGraph *gr)
        gr->TriCont(tt,uu,vv,ww,"B");
 }
 //-----------------------------------------------------------------------------
-const char *mmgl_dots="new t 1000 'pi*(rnd-0.5)':new f 1000 '2*pi*rnd'\n"
-"copy x 0.9*cos(t)*cos(f):copy y 0.9*cos(t)*sin(f):copy z 0.6*sin(t)\n"
-"title 'Dots sample':rotate 50 60\nbox:dots x y z\n";
+const char *mmgl_dots="new t 2000 'pi*(rnd-0.5)':new f 2000 '2*pi*rnd'\n"
+"copy x 0.9*cos(t)*cos(f):copy y 0.9*cos(t)*sin(f):copy z 0.6*sin(t):copy c cos(2*t)\n"
+"subplot 2 2 0:title 'Dots sample':rotate 50 60\nbox:dots x y z\nalpha on\n"
+"subplot 2 2 1:title 'add transparency':rotate 50 60\nbox:dots x y z c\n"
+"subplot 2 2 2:title 'add colorings':rotate 50 60\nbox:dots x y z x c\n"
+"subplot 2 2 3:title 'Only coloring':rotate 50 60\nbox:tens x y z x ' .'";
 void smgl_dots(mglGraph *gr)
 {
        int i, n=1000;
-       mglData x(n),y(n),z(n);
+       mglData x(n),y(n),z(n),c(n);
        for(i=0;i<n;i++)
        {
                double t=M_PI*(mgl_rnd()-0.5), f=2*M_PI*mgl_rnd();
                x.a[i] = 0.9*cos(t)*cos(f);
                y.a[i] = 0.9*cos(t)*sin(f);
                z.a[i] = 0.6*sin(t);
+               c.a[i] = cos(2*t);
        }
-       if(big!=3)      gr->Title("Dots sample");
+       if(big!=3)      {       gr->SubPlot(2,2,0);     gr->Title("Dots sample");       }
        gr->Rotate(50,60);      gr->Box();      gr->Dots(x,y,z);
+       if(big==3)      return;
+       gr->Alpha(true);
+       gr->SubPlot(2,2,1);     gr->Title("add transparency");          gr->Rotate(50,60);      gr->Box();      gr->Dots(x,y,z,c);
+       gr->SubPlot(2,2,2);     gr->Title("add coloring");      gr->Rotate(50,60);      gr->Box();      gr->Dots(x,y,z,x,c);
+       gr->SubPlot(2,2,3);     gr->Title("Only coloring");             gr->Rotate(50,60);      gr->Box();      gr->Tens(x,y,z,x," .");
 }
 //-----------------------------------------------------------------------------
 /*void smgl_surf3_rgbd(mglGraph *gr)
@@ -2621,7 +2573,7 @@ const char *mmgl_mirror="new a 31 41 '-pi*x*exp(-(y+1)^2-4*x^2)'\n"
 "surf a 'r';yrange 0 1; alpha 0.7:surf a 'b';yrange 0 -1; alpha 0.3\n"
 "subplot 2 2 3 '<_':title 'Option \"legend\"'\n"
 "fplot 'x^3' 'r'; legend 'y = x^3':fplot 'cos(pi*x)' 'b'; legend 'y = cos \\pi x'\n"
-"box:axis:legend 2\n";
+"box:axis:legend 2";
 void smgl_mirror(mglGraph *gr) // flag #
 {
        mglData a(31,41);
@@ -2686,13 +2638,13 @@ mglSample samp[] = {
        {"error2", smgl_error2, mmgl_error2},
        {"export", smgl_export, mmgl_export},
        {"fall", smgl_fall, mmgl_fall},
-       {"fexport", smgl_fexport, mmgl_fexport},
        {"fit", smgl_fit, mmgl_fit},
        {"flow", smgl_flow, mmgl_flow},
        {"fog", smgl_fog, mmgl_fog},
        {"fonts", smgl_fonts, mmgl_fonts},
        {"grad", smgl_grad, mmgl_grad},
        {"hist", smgl_hist, mmgl_hist},
+       {"indirect",smgl_indirect,mmgl_indirect},
        {"inplot", smgl_inplot, mmgl_inplot},
        {"label", smgl_label, mmgl_label},
        {"legend", smgl_legend, mmgl_legend },
@@ -2704,6 +2656,7 @@ mglSample samp[] = {
        {"mesh", smgl_mesh, mmgl_mesh},
        {"mirror", smgl_mirror, mmgl_mirror },
        {"molecule", smgl_molecule, mmgl_molecule },
+       {"ode", smgl_ode, mmgl_ode},
        {"ohlc", smgl_ohlc, mmgl_ohlc},
        {"param1", smgl_param1, mmgl_param1},
        {"param2", smgl_param2, mmgl_param2},
index 2839a9ba8a4a8f4c9527d2d02ab556ace2bf6639..a2a69d18c858b4b49552f3b0fae97c7ed6e4761f 100644 (file)
@@ -431,7 +431,6 @@ void mgls_prepare1d(mglData *y, mglData *y1, mglData *y2, mglData *x1, mglData *
        if(y)   y->Create(n,3);\r
        if(x1)  x1->Create(n);          if(x2)  x2->Create(n);\r
        if(y1)  y1->Create(n);          if(y2)  y2->Create(n);\r
-#pragma omp parallel for\r
        for(long i=0;i<n;i++)\r
        {\r
                double xx = i/(n-1.);\r
@@ -453,7 +452,6 @@ void mgls_prepare2d(mglData *a, mglData *b, mglData *v)
        long n=50,m=40;\r
        if(a)   a->Create(n,m);         if(b)   b->Create(n,m);\r
        if(v)   {       v->Create(9);   v->Fill(-1,1);  }\r
-#pragma omp parallel for collapse(2)\r
        for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
        {\r
                double x = i/(n-1.), y = j/(m-1.);\r
@@ -467,7 +465,6 @@ void mgls_prepare3d(mglData *a, mglData *b)
 {\r
        long n=61,m=50,l=40;\r
        if(a)   a->Create(n,m,l);               if(b)   b->Create(n,m,l);\r
-#pragma omp parallel for collapse(3)\r
        for(long k=0;k<l;k++)   for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
        {\r
                double x=2*i/(n-1.)-1, y=2*j/(m-1.)-1, z=2*k/(l-1.)-1;\r
@@ -481,7 +478,6 @@ void mgls_prepare2v(mglData *a, mglData *b)
 {\r
        long n=20,m=30;\r
        if(a)   a->Create(n,m);         if(b)   b->Create(n,m);\r
-#pragma omp parallel for collapse(2)\r
        for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
        {\r
                double x=i/(n-1.), y=j/(m-1.);\r
@@ -494,9 +490,9 @@ void mgls_prepare2v(mglData *a, mglData *b)
 void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez)\r
 {\r
        long n=10;\r
+       double z0=0.3;\r
        if(!ex || !ey || !ez)   return;\r
        ex->Create(n,n,n);      ey->Create(n,n,n);      ez->Create(n,n,n);\r
-#pragma omp parallel for collapse(3)\r
        for(long k=0;k<n;k++)   for(long j=0;j<n;j++)   for(long i=0;i<n;i++)\r
        {\r
                double x=2*i/(n-1.)-1, y=2*j/(n-1.)-1, z=2*k/(n-1.)-1;\r
@@ -508,11 +504,11 @@ void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez)
 /*             ex->a[i0]=3*z;\r
                ey->a[i0]=1;\r
                ez->a[i0]=-3*x;*/\r
-               double r1 = pow(x*x+y*y+(z-0.3)*(z-0.3)+0.03,1.5);\r
-               double r2 = pow(x*x+y*y+(z+0.3)*(z+0.3)+0.03,1.5);\r
+               double r1 = pow(x*x+y*y+(z-z0)*(z-z0)+0.03,1.5);\r
+               double r2 = pow(x*x+y*y+(z+z0)*(z+z0)+0.03,1.5);\r
                ex->a[i0]=0.2*x/r1 - 0.2*x/r2;\r
                ey->a[i0]=0.2*y/r1 - 0.2*y/r2;\r
-               ez->a[i0]=0.2*(z-0.3)/r1 - 0.2*(z+0.3)/r2;\r
+               ez->a[i0]=0.2*(z-z0)/r1 - 0.2*(z+z0)/r2;\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
index f5171a528ed8b8fb3a27ec50981d48a0310d7820..e048547e6e0b66f31ffc677ee2126fcde5ebdbbc 100644 (file)
@@ -2,21 +2,30 @@
 #define _MGL_CONFIG_H_
 
 #define MGL_USE_DOUBLE ${MGL_USE_DOUBLE}
-#define MGL_NO_DATA_A  ${MGL_NO_DATA_A}
 
 #if defined(_MSC_VER) || defined(__BORLANDC__)
+#define MGL_SYS_NAN            0
+#define MGL_HAVE_TYPEOF        0
 #define MGL_HAVE_PTHREAD       0
+#define MGL_HAVE_ATTRIBUTE     0
+#define MGL_HAVE_C99_COMPLEX   0
 #else
+#define MGL_HAVE_TYPEOF        ${MGL_HAVE_TYPEOF}
+#define MGL_SYS_NAN            ${MGL_HAVE_NAN_INF}
 #define MGL_HAVE_PTHREAD       ${MGL_HAVE_PTHREAD}
+#define MGL_HAVE_ATTRIBUTE     ${MGL_HAVE_ATTRIBUTE}
+#define MGL_HAVE_C99_COMPLEX   ${MGL_HAVE_C99_COMPLEX}
 #endif
+
+#define MGL_HAVE_RVAL  ${MGL_HAVE_RVAL}
 #define MGL_HAVE_ZLIB  ${MGL_HAVE_ZLIB}
-#define MGL_HAVE_PNG           ${MGL_HAVE_PNG}
-#define MGL_HAVE_GSL           ${MGL_HAVE_GSL}
+#define MGL_HAVE_PNG   ${MGL_HAVE_PNG}
+#define MGL_HAVE_GSL   ${MGL_HAVE_GSL}
 #define MGL_HAVE_OPENGL        ${MGL_HAVE_OPENGL}
-#define MGL_HAVE_OMP           ${MGL_HAVE_OMP}
+#define MGL_HAVE_OMP   ${MGL_HAVE_OMP}
 #define MGL_HAVE_JPEG  ${MGL_HAVE_JPEG}
-#define MGL_HAVE_GIF           ${MGL_HAVE_GIF}
-#define MGL_HAVE_PDF           ${MGL_HAVE_PDF}
+#define MGL_HAVE_GIF   ${MGL_HAVE_GIF}
+#define MGL_HAVE_PDF   ${MGL_HAVE_PDF}
 #define MGL_HAVE_HDF4  ${MGL_HAVE_HDF4}
 #define MGL_HAVE_HDF5  ${MGL_HAVE_HDF5}
 #define MGL_FONT_PATH  "${MGL_FONT_PATH}"
index 90d88088159ef7678f052548b17532ea5b206529..e9342a43db0c201c4f80539851f65e6c7a089775 100644 (file)
 #ifdef __cplusplus
 #include <string>
 #include "mgl2/type.h"
+#define MGL_TO_WCS(str,code)   if(str && *str){size_t s=mbstowcs(0,str,0); wchar_t *wcs=new wchar_t[s+1]; mbstowcs(wcs,str,s); wcs[s]=0; code; delete []wcs;}else{const wchar_t *wcs=L""; code;}
 //-----------------------------------------------------------------------------
 class mglBase;
 class mglData;
+class mglDataA;
 class mglDataC;
 class mglParser;
 class mglFormula;
@@ -39,12 +41,76 @@ typedef mglDataC* HADT;
 typedef mglParser* HMPR;
 typedef mglFormula* HMEX;
 typedef mglFormulaC* HAEX;
-//-----------------------------------------------------------------------------
-#if MGL_NO_DATA_A
-#define mglDataA mglData
-typedef const mglData* HCDT;
-#include "mgl2/data.h"
-#else
+typedef const mglDataA* HCDT;
+#ifdef __cplusplus
+extern "C" {
+#endif
+/// Set name for data variable (can be used in mgl_formula_calc() or in MGL scripts)
+void MGL_EXPORT mgl_data_set_name(mglDataA *dat, const char *name);
+void MGL_EXPORT mgl_data_set_name_(uintptr_t *dat, const char *name,int);
+void MGL_EXPORT mgl_data_set_name_w(mglDataA *dat, const wchar_t *name);
+/// Set callback function which is called at deleting variable
+void MGL_EXPORT mgl_data_set_func(mglDataA *dat, void (*func)(void *), void *par);
+
+/// Save whole data array (for ns=-1) or only ns-th slice to text file
+void MGL_EXPORT mgl_data_save(HCDT dat, const char *fname,long ns);
+void MGL_EXPORT mgl_data_save_(uintptr_t *dat, const char *fname,int *ns,int);
+/// Export data array (for ns=-1) or only ns-th slice to PNG file according color scheme
+void MGL_EXPORT mgl_data_export(HCDT dat, const char *fname, const char *scheme,mreal v1,mreal v2,long ns);
+void MGL_EXPORT mgl_data_export_(uintptr_t *dat, const char *fname, const char *scheme,mreal *v1,mreal *v2,int *ns,int,int);
+/// Save data to HDF file
+void MGL_EXPORT mgl_data_save_hdf(HCDT d,const char *fname,const char *data,int rewrite);
+void MGL_EXPORT mgl_data_save_hdf_(uintptr_t *d, const char *fname, const char *data, int *rewrite,int l,int n);
+/// Get information about the data (sizes and momentum) to string
+MGL_EXPORT const char *mgl_data_info(HCDT dat);
+int MGL_EXPORT mgl_data_info_(uintptr_t *dat, char *out, int len);
+/// Put HDF data names into buf as '\t' separated.
+int MGL_EXPORT mgl_datas_hdf(const char *fname, char *buf, long size);
+int MGL_EXPORT mgl_datas_hdf_(const char *fname, char *buf, int l, int size);
+
+/// Get maximal value of the data
+mreal MGL_EXPORT mgl_data_max(HCDT dat);
+mreal MGL_EXPORT mgl_data_max_(uintptr_t *dat);
+/// Get maximal value of the data which is less than 0
+mreal MGL_EXPORT mgl_data_neg_max(HCDT dat);
+mreal MGL_EXPORT mgl_data_neg_max_(uintptr_t *dat);
+/// Get minimal value of the data
+mreal MGL_EXPORT mgl_data_min(HCDT dat);
+mreal MGL_EXPORT mgl_data_min_(uintptr_t *dat);
+/// Get minimal value of the data which is larger than 0
+mreal MGL_EXPORT mgl_data_pos_min(HCDT dat);
+mreal MGL_EXPORT mgl_data_pos_min_(uintptr_t *dat);
+/// Find position (after specified in i,j,k) of first nonzero value of formula
+mreal MGL_EXPORT mgl_data_first(HCDT dat, const char *cond, long *i, long *j, long *k);
+mreal MGL_EXPORT mgl_data_first_(uintptr_t *dat, const char *cond, int *i, int *j, int *k, int);
+/// Find position (before specified in i,j,k) of last nonzero value of formula
+mreal MGL_EXPORT mgl_data_last(HCDT dat, const char *cond, long *i, long *j, long *k);
+mreal MGL_EXPORT mgl_data_last_(uintptr_t *dat, const char *cond, int *i, int *j, int *k, int);
+/// Find position of first in direction 'dir' nonzero value of formula
+long MGL_EXPORT mgl_data_find(HCDT dat, const char *cond, char dir, long i, long j, long k);
+int MGL_EXPORT mgl_data_find_(uintptr_t *dat, const char *cond, char *dir, int *i, int *j, int *k, int,int);
+/// Find if any nonzero value of formula
+int MGL_EXPORT mgl_data_find_any(HCDT dat, const char *cond);
+int MGL_EXPORT mgl_data_find_any_(uintptr_t *dat, const char *cond, int);
+/// Get maximal value of the data and its position
+mreal MGL_EXPORT mgl_data_max_int(HCDT dat, long *i, long *j, long *k);
+mreal MGL_EXPORT mgl_data_max_int_(uintptr_t *dat, int *i, int *j, int *k);
+/// Get maximal value of the data and its approximated position
+mreal MGL_EXPORT mgl_data_max_real(HCDT dat, mreal *x, mreal *y, mreal *z);
+mreal MGL_EXPORT mgl_data_max_real_(uintptr_t *dat, mreal *x, mreal *y, mreal *z);
+/// Get minimal value of the data and its position
+mreal MGL_EXPORT mgl_data_min_int(HCDT dat, long *i, long *j, long *k);
+mreal MGL_EXPORT mgl_data_min_int_(uintptr_t *dat, int *i, int *j, int *k);
+/// Get minimal value of the data and its approximated position
+mreal MGL_EXPORT mgl_data_min_real(HCDT dat, mreal *x, mreal *y, mreal *z);
+mreal MGL_EXPORT mgl_data_min_real_(uintptr_t *dat, mreal *x, mreal *y, mreal *z);
+/// Get "energy and find 4 momenta of data: median, width, skewness, kurtosis
+mreal MGL_EXPORT mgl_data_momentum_val(HCDT d, char dir, mreal *m, mreal *w, mreal *s, mreal *k);
+mreal MGL_EXPORT mgl_data_momentum_val_(uintptr_t *dat, char *dir, mreal *m, mreal *w, mreal *s, mreal *k,int);
+
+#ifdef __cplusplus
+}
+#endif
 //-----------------------------------------------------------------------------
 /// Callback function for asking user a question. Result shouldn't exceed 1024.
 extern MGL_EXPORT void (*mgl_ask_func)(const wchar_t *quest, wchar_t *res);
@@ -53,24 +119,85 @@ extern MGL_EXPORT void (*mgl_ask_func)(const wchar_t *quest, wchar_t *res);
 class MGL_EXPORT mglDataA
 {
 public:
-       virtual ~mglDataA()     {}
+       std::wstring s; ///< Data name
+       bool temp;              ///< This is temporary variable
+       void (*func)(void *);   ///< Callback function for destroying
+       void *o;                ///< Pointer to external object
+
+       mglDataA()      {       temp=false;     func=0; o=0;    }
+       virtual ~mglDataA()     {       if(func)        func(o);        }
+       virtual void set_v(mreal val, long i,long j=0,long k=0) {}
        virtual mreal v(long i,long j=0,long k=0) const = 0;
        virtual mreal vthr(long i) const = 0;
        virtual long GetNx() const = 0;
        virtual long GetNy() const = 0;
        virtual long GetNz() const = 0;
        inline long GetNN() const {     return GetNx()*GetNy()*GetNz(); }
-       virtual mreal Maximal() const = 0;
-       virtual mreal Minimal() const = 0;
        virtual mreal dvx(long i,long j=0,long k=0) const = 0;
 //     {       return i>0 ? (i<GetNx()-1 ? (v(i+1,j,k)-v(i-1,j,k))/2 : v(i,j,k)-v(i-1,j,k)) : v(1,j,k)-v(0,j,k);       }
        virtual mreal dvy(long i,long j=0,long k=0) const = 0;
 //     {       return j>0 ? (j<GetNy()-1 ? (v(i,j+1,k)-v(i,j-1,k))/2 : v(i,j,k)-v(i,j-1,k)) : v(i,1,k)-v(i,0,k);       }
        virtual mreal dvz(long i,long j=0,long k=0) const = 0;
 //     {       return k>0 ? (k<GetNz()-1 ? (v(i,j,k+1)-v(i,j,k-1))/2 : v(i,j,k)-v(i,j,k-1)) : v(i,j,1)-v(i,j,0);       }
+       
+       // Now some common function which applicable for most of data types
+       /// Save whole data array (for ns=-1) or only ns-th slice to text file
+       virtual void Save(const char *fname,long ns=-1) const
+       {       mgl_data_save(this,fname,ns);   }
+       /// Export data array (for ns=-1) or only ns-th slice to PNG file according color scheme
+       inline void Export(const char *fname,const char *scheme,mreal v1=0,mreal v2=0,long ns=-1) const
+       {       mgl_data_export(this,fname,scheme,v1,v2,ns);    }
+       /// Save data to HDF file
+       virtual void SaveHDF(const char *fname,const char *data,bool rewrite=false) const
+       {       mgl_data_save_hdf(this,fname,data,rewrite);     }
+       /// Put HDF data names into buf as '\t' separated.
+       inline static int DatasHDF(const char *fname, char *buf, long size)
+       {       return mgl_datas_hdf(fname,buf,size);   }
+
+       /// Get information about the data (sizes and momentum) to string
+       inline const char *PrintInfo() const    {       return mgl_data_info(this);     }
+       /// Print information about the data (sizes and momentum) to FILE (for example, stdout)
+       inline void PrintInfo(FILE *fp) const
+       {       if(fp)  {       fprintf(fp,"%s",mgl_data_info(this));   fflush(fp);     }       }
+       /// Get maximal value of the data
+       mreal Maximal() const   {       return mgl_data_max(this);      }
+       /// Get minimal value of the data
+       mreal Minimal() const   {       return mgl_data_min(this);      }
+       /// Get maximal value of the data which is less than 0
+       inline mreal MaximalNeg() const {       return mgl_data_neg_max(this);  }
+       /// Get minimal value of the data which is larger than 0
+       inline mreal MinimalPos() const {       return mgl_data_pos_min(this);  }
+       /// Get maximal value of the data and its position
+       inline mreal Maximal(long &i,long &j,long &k) const
+       {       return mgl_data_max_int(this,&i,&j,&k); }
+       /// Get minimal value of the data and its position
+       inline mreal Minimal(long &i,long &j,long &k) const
+       {       return mgl_data_min_int(this,&i,&j,&k); }
+       /// Get maximal value of the data and its approximated position
+       inline mreal Maximal(mreal &x,mreal &y,mreal &z) const
+       {       return mgl_data_max_real(this,&x,&y,&z);        }
+       /// Get minimal value of the data and its approximated position
+       inline mreal Minimal(mreal &x,mreal &y,mreal &z) const
+       {       return mgl_data_min_real(this,&x,&y,&z);        }
+       /// Get "energy" and find first (median) and second (width) momenta of data
+       inline mreal Momentum(char dir,mreal &m,mreal &w) const
+       {       return mgl_data_momentum_val(this,dir,&m,&w,0,0);       }
+       /// Get "energy and find 4 momenta of data: median, width, skewness, kurtosis
+       inline mreal Momentum(char dir,mreal &m,mreal &w,mreal &s,mreal &k) const
+       {       return mgl_data_momentum_val(this,dir,&m,&w,&s,&k);     }
+       /// Find position (after specified in i,j,k) of first nonzero value of formula
+       inline mreal Find(const char *cond, long &i, long &j, long &k) const
+       {       return mgl_data_first(this,cond,&i,&j,&k);      }
+       /// Find position (before specified in i,j,k) of last nonzero value of formula
+       inline mreal Last(const char *cond, long &i, long &j, long &k) const
+       {       return mgl_data_last(this,cond,&i,&j,&k);       }
+       /// Find position of first in direction 'dir' nonzero value of formula
+       inline long Find(const char *cond, char dir, long i=0, long j=0, long k=0) const
+       {       return mgl_data_find(this,cond,dir,i,j,k);      }
+       /// Find if any nonzero value of formula
+       inline bool FindAny(const char *cond) const
+       {       return mgl_data_find_any(this,cond);    }
 };
-#endif
-typedef const mglDataA* HCDT;
 //-----------------------------------------------------------------------------
 /// Structure for color ID
 struct MGL_EXPORT mglColorID
@@ -81,12 +208,8 @@ struct MGL_EXPORT mglColorID
 MGL_EXPORT extern mglColorID mglColorIds[31];
 MGL_EXPORT extern std::string mglGlobalMess;   ///< Buffer for receiving global messages
 //-----------------------------------------------------------------------------
-/// Brushes for mask with symbol "-+=;oOsS~<>jdD*^" correspondingly
-extern uint64_t mgl_mask_val[16];
-#define MGL_MASK_ID            "-+=;oOsS~<>jdD*^"
-#define MGL_SOLID_MASK 0xffffffffffffffff
-//-----------------------------------------------------------------------------
 #else
+#define mglDataA void
 typedef void *HMGL;
 typedef void *HMDT;
 typedef void *HADT;
@@ -96,7 +219,7 @@ typedef void *HMPR;
 typedef const void *HCDT;
 #endif
 
-#if MGL_SRC
+#ifdef MGL_SRC
 #define _Da_(d)        (*((const mglDataA *)(d)))
 #define _DA_(a)        ((const mglDataA *)*(a))
 #define _GR_   ((mglBase *)(*gr))
index aeed679d6397cac60bc8fb29ad8a683449c138b4..b083469fd365e3bbb54b5e9545ff3d18784afbf0 100644 (file)
@@ -40,16 +40,16 @@ void MGL_EXPORT mgl_fft_freq(double *freq,long nn);
 /// Remove double spaces from the string
 void MGL_EXPORT mgl_strcls(char *str);
 /// Get position of substring or return -1 if not found
-int MGL_EXPORT mgl_strpos(const char *str,char *fnd);
+int MGL_EXPORT_PURE mgl_strpos(const char *str,char *fnd);
 /// Get position of symbol or return -1 if not found
-int MGL_EXPORT mgl_chrpos(const char *str,char fnd);
+int MGL_EXPORT_PURE mgl_chrpos(const char *str,char fnd);
 
 /// Get uncommented string from file (NOTE: it is not thread safe!!!)
 MGL_EXPORT char *mgl_fgetstr(FILE *fp);
 /// Get parameters from uncommented strings of file (NOTE: it is not thread safe!!!)
 void MGL_EXPORT mgl_fgetpar(FILE *fp, const char *str, ...);
 /// Check if symbol denote true
-int MGL_EXPORT mgl_istrue(char ch);
+int MGL_EXPORT_CONST mgl_istrue(char ch);
 /// Print test message
 void MGL_EXPORT mgl_test(const char *str, ...);
 /// Print info message
index 452e2c8b8dd519c7d0664b25fb79c72ac276b940..b3779eef5c6adbc1cbb84ff52f9b43b51dbc5d46 100644 (file)
 \r
 #if MGL_HAVE_PTHREAD\r
 #include <pthread.h>\r
-#define MGL_PUSH(a,v,m)                {pthread_mutex_lock(&m);        a.push_back(v); pthread_mutex_unlock(&m);}\r
+#define MGL_PUSH(a,v,m)        {pthread_mutex_lock(&m);        a.push_back(v); pthread_mutex_unlock(&m);}\r
 #else\r
-#define MGL_PUSH(a,v,m)                a.push_back(v);\r
+#define MGL_PUSH(a,v,m)        a.push_back(v);\r
 #endif\r
-\r
-#define MGL_TO_WCS(str,code)   if(str){size_t s=mbstowcs(0,str,0); wchar_t *wcs=new wchar_t[s+1]; mbstowcs(wcs,str,s); wcs[s]=0; code; delete []wcs;}\r
 //-----------------------------------------------------------------------------\r
 inline mreal mgl_d(mreal v,mreal v1,mreal v2) { return v2!=v1?(v-v1)/(v2-v1):NAN; }\r
 //-----------------------------------------------------------------------------\r
@@ -41,6 +39,79 @@ mglPoint GetX(HCDT x, int i, int j, int k=0);
 mglPoint GetY(HCDT y, int i, int j, int k=0);\r
 mglPoint GetZ(HCDT z, int i, int j, int k=0);\r
 //-----------------------------------------------------------------------------\r
+/// Class for replacement of std::vector\r
+// NOTE memcpy is used --> no memory allocation in T\r
+template <class T> class mglStack\r
+{\r
+       T** dat;\r
+       size_t pb;      ///< size of buffer (real size is 2^pb == 1<<pb)\r
+       size_t np;      ///< allocated pointers\r
+       size_t m;       ///< used pointers (allocated size is m*nb)\r
+       size_t n;       ///< used cells\r
+       void *mutex;\r
+public:\r
+       mglStack(const mglStack<T> &st)\r
+       {\r
+               np=st.np;       dat = (T**)malloc(np*sizeof(T*));\r
+               pb=st.pb;       m=n=0;  reserve(st.n);\r
+               for(size_t i=0;i<m;i++) memcpy(dat[i],st.dat[i],(1<<pb)*sizeof(T));\r
+               n=st.n;         mutex = 0;\r
+       }\r
+       mglStack(size_t Pbuf=10)\r
+       {       np=16;  pb=Pbuf;        dat = (T**)malloc(np*sizeof(T*));\r
+               dat[0] = new T[1<<pb];  n=0;    m=1;    mutex = 0;      }\r
+       ~mglStack()     {       clear();        delete [](dat[0]);      free(dat);      }\r
+       inline void set_mutex(void *m)  {       mutex = m;      }\r
+       void reserve(size_t num)\r
+       {\r
+               num+=n;\r
+               if(num>(m<<pb))\r
+               {\r
+                       num = 1+ (num>>pb);\r
+                       if(num>np)\r
+                       {       dat = (T**)realloc(dat, num*sizeof(T*));        np=num; }\r
+                       for(size_t i=m;i<num;i++)       dat[i] = new T[1<<pb];\r
+                       m = num;\r
+               }\r
+       }\r
+       void clear()\r
+       {\r
+               if(mutex)\r
+               {\r
+#if MGL_HAVE_PTHREAD\r
+                       pthread_mutex_lock((pthread_mutex_t *)mutex);\r
+#elif MGL_HAVE_OMP\r
+                       omp_set_lock((omp_lock_t *)mutex);\r
+#endif\r
+               }\r
+               for(size_t i=0;i<m;i++) delete [](dat[i]);\r
+               dat[0] = new T[1<<pb];  n=0;    m=1;\r
+               if(mutex)\r
+               {\r
+#if MGL_HAVE_PTHREAD\r
+                       pthread_mutex_unlock((pthread_mutex_t *)mutex);\r
+#elif MGL_HAVE_OMP\r
+                       omp_unset_lock((omp_lock_t *)mutex);\r
+#endif\r
+               }\r
+       }\r
+       T &operator[](size_t i) {       register size_t d=i>>pb;        return dat[d][i-(d<<pb)];       }\r
+       const T &operator[](size_t i)   const   {       register size_t d=i>>pb;        return dat[d][i-(d<<pb)];       }\r
+       void push_back(const T &t)\r
+       {\r
+               if(n>=(m<<pb))  reserve(1);\r
+               register size_t d=n>>pb;\r
+               dat[d][n-(d<<pb)] = t;  n++;\r
+       }\r
+       size_t size()   const   {       return n;       }\r
+       const mglStack<T> &operator=(const mglStack<T> &st)\r
+       {\r
+               pb=st.pb;       clear();        reserve(st.n);\r
+               for(size_t i=0;i<st.m && i<m;i++)       memcpy(dat[i],st.dat[i],(1<<pb)*sizeof(T));\r
+               n = st.n;       return st;\r
+       }\r
+};\r
+//-----------------------------------------------------------------------------\r
 /// Structure for transformation matrix\r
 struct MGL_EXPORT mglMatrix\r
 {\r
@@ -48,16 +119,20 @@ struct MGL_EXPORT mglMatrix
        mreal x,y,z,pf;\r
        bool norot;     // flag to disable pnts rotation\r
        mglMatrix()     {       memset(this,0,sizeof(mglMatrix));       clear();        }\r
+       mglMatrix(const mglMatrix &aa) : x(aa.x),y(aa.y),z(aa.z),pf(aa.pf),norot(aa.norot)      {       memcpy(b,aa.b,9*sizeof(mreal)); }\r
+#if MGL_HAVE_RVAL\r
+       mglMatrix(mglMatrix &&aa) : x(aa.x),y(aa.y),z(aa.z),pf(aa.pf),norot(aa.norot)   {       memcpy(b,aa.b,9*sizeof(mreal)); }\r
+#endif\r
        void Rotate(mreal tetz,mreal tetx,mreal tety);\r
        void RotateN(mreal Tet,mreal x,mreal y,mreal z);\r
        inline void clear()     {       x=y=z=pf=0;     memset(b,0,9*sizeof(mreal));    b[0]=b[4]=b[8]=1;       norot=false;    }\r
-       inline mglMatrix &operator=(const mglMatrix &a)\r
-       {       x=a.x;  y=a.y;  z=a.z;  pf=a.pf;        memcpy(b,a.b,9*sizeof(mreal));  norot=false;    return *this;   }\r
+       inline const mglMatrix &operator=(const mglMatrix &a)\r
+       {       x=a.x;  y=a.y;  z=a.z;  pf=a.pf;        memcpy(b,a.b,9*sizeof(mreal));  norot=false;    return a;       }\r
 };\r
 inline bool operator==(const mglMatrix &a, const mglMatrix &b)\r
-{      return b.x==a.x&&b.y==a.y&&b.z==a.z&&b.pf==a.pf&&!memcmp(b.b,a.b,9*sizeof(mreal));}\r
+{      return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.pf-b.pf)*(a.pf-b.pf)==0)&&!memcmp(b.b,a.b,9*sizeof(mreal));}\r
 inline bool operator!=(const mglMatrix &a, const mglMatrix &b)\r
-{      return b.x!=a.x||b.y!=a.y||b.z!=a.z||b.pf!=a.pf||memcmp(b.b,a.b,9*sizeof(mreal));       }\r
+{      return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.pf-b.pf)*(a.pf-b.pf)!=0)||memcmp(b.b,a.b,9*sizeof(mreal));       }\r
 //-----------------------------------------------------------------------------\r
 /// Structure for simplest primitives\r
 struct MGL_EXPORT mglPrim      // NOTE: use float for reducing memory size\r
@@ -79,7 +154,12 @@ struct MGL_EXPORT mglPrim   // NOTE: use float for reducing memory size
                };\r
                uint64_t m;\r
        };\r
-       mglPrim(int t=0)        {       n1=n2=n3=n4=id=0;       z=s=w=p=0;      type=t; }\r
+       mglPrim(int t=0):n1(0),n2(0),n3(0),n4(0),type(t),angl(0),id(0),z(0),w(0),m(0)   {}\r
+       mglPrim(const mglPrim &aa) : n1(aa.n1),n2(aa.n2),n3(aa.n3),n4(aa.n4),type(aa.type),angl(aa.angl),id(aa.id),z(aa.z),w(aa.w),m(aa.m)      {}\r
+#if MGL_HAVE_RVAL\r
+       mglPrim(mglPrim &&aa) : n1(aa.n1),n2(aa.n2),n3(aa.n3),n4(aa.n4),type(aa.type),angl(aa.angl),id(aa.id),z(aa.z),w(aa.w),m(aa.m)   {}\r
+#endif\r
+       const mglPrim &operator=(const mglPrim &aa)     {       memcpy(this, &aa, sizeof(mglPrim));     return aa;      }\r
 };\r
 bool operator<(const mglPrim &a,const mglPrim &b);\r
 bool operator>(const mglPrim &a,const mglPrim &b);\r
@@ -90,7 +170,12 @@ struct MGL_EXPORT mglGroup
        std::vector<long> p;    ///< list of primitives (not filled!!!)\r
        int Id;                                 ///< Current list of primitives\r
        std::string Lbl;                ///< Group label\r
-       mglGroup(const char *lbl="", int id=0)  {       Lbl=lbl;        Id=id;  }\r
+       mglGroup(const char *lbl="", int id=0) : Id(id), Lbl(lbl)       {}\r
+       mglGroup(const mglGroup &aa) : p(aa.p),Id(aa.Id),Lbl(aa.Lbl)    {}\r
+#if MGL_HAVE_RVAL\r
+       mglGroup(mglGroup &&aa) : p(aa.p),Id(aa.Id),Lbl(aa.Lbl) {}\r
+#endif\r
+       inline const mglGroup &operator=(const mglGroup &aa)    {       Lbl = aa.Lbl;   Id = aa.Id;     p = aa.p;       return aa;      }\r
 };\r
 //-----------------------------------------------------------------------------\r
 /// Structure for text label\r
@@ -99,8 +184,13 @@ struct MGL_EXPORT mglText
        std::wstring text;\r
        std::string stl;\r
        mreal val;\r
-       mglText(const wchar_t *txt=L"", const char *fnt="", mreal v=0)  {       text=txt;       stl=fnt;        val=v;  }\r
-       mglText(const std::wstring &txt, mreal v=0)     {       text=txt;       val=v;  }\r
+       mglText(const wchar_t *txt=L"", const char *fnt="", mreal v=0) : text(txt), stl(fnt), val(v) {}\r
+       mglText(const std::wstring &txt, mreal v=0): text(txt), val(v)  {}\r
+       mglText(const mglText &aa) : text(aa.text),stl(aa.stl),val(aa.val)      {}\r
+#if MGL_HAVE_RVAL\r
+       mglText(mglText &&aa) : text(aa.text),stl(aa.stl),val(aa.val)   {}\r
+#endif\r
+       const mglText&operator=(const mglText &aa)      { text=aa.text; stl=aa.stl;     val=aa.val;     return aa;      }\r
 };\r
 //-----------------------------------------------------------------------------\r
 /// Structure for internal point representation\r
@@ -112,24 +202,21 @@ struct MGL_EXPORT mglPnt  // NOTE: use float for reducing memory size
        float u,v,w;    // normales\r
        float r,g,b,a;  // RGBA color\r
        short sub;              // subplot id and rotation information (later will be in subplot)\r
-       mglPnt()        {       xx=yy=zz=x=y=z=c=t=ta=u=v=w=r=g=b=a=sub=0;      }\r
+       mglPnt(float X=0, float Y=0, float Z=0, float U=0, float V=0, float W=0, float R=0, float G=0, float B=0, float A=0):xx(X),yy(Y),zz(Z),x(X),y(Y),z(Z),c(0),t(0),ta(0),u(U),v(V),w(W),r(R),g(G),b(B),a(A),sub(0) {}\r
+       mglPnt(const mglPnt &aa) : xx(aa.xx),yy(aa.yy),zz(aa.zz), x(aa.x),y(aa.y),z(aa.z), c(aa.c),t(aa.t),ta(aa.ta), u(aa.u),v(aa.v),w(aa.w), r(aa.r),g(aa.g),b(aa.b),a(aa.a), sub(aa.sub)     {}\r
+#if MGL_HAVE_RVAL\r
+       mglPnt(mglPnt &&aa) : xx(aa.xx),yy(aa.yy),zz(aa.zz), x(aa.x),y(aa.y),z(aa.z), c(aa.c),t(aa.t),ta(aa.ta), u(aa.u),v(aa.v),w(aa.w), r(aa.r),g(aa.g),b(aa.b),a(aa.a), sub(aa.sub)  {}\r
+#endif\r
+       inline const mglPnt&operator=(const mglPnt &aa) {       memcpy(this,&aa,sizeof(mglPnt));        return aa;      }\r
 };\r
 inline mglPnt operator+(const mglPnt &a, const mglPnt &b)\r
-{      mglPnt c=a;\r
-       c.x+=b.x;       c.y+=b.y;       c.z+=b.z;       c.u+=b.u;       c.v+=b.v;       c.w+=b.w;\r
-       c.r+=b.r;       c.g+=b.g;       c.b+=b.b;       c.a+=b.a;       return c;       }\r
+{      return mglPnt(a.x+b.x,a.y+b.y,a.z+b.z, a.u+b.u,a.v+b.v,a.w+b.w, a.r+b.r,a.g+b.g,a.b+b.b,a.a+b.a);       }\r
 inline mglPnt operator-(const mglPnt &a, const mglPnt &b)\r
-{      mglPnt c=a;\r
-       c.x-=b.x;       c.y-=b.y;       c.z-=b.z;       c.u-=b.u;       c.v-=b.v;       c.w-=b.w;\r
-       c.r-=b.r;       c.g-=b.g;       c.b-=b.b;       c.a-=b.a;       return c;       }\r
+{      return mglPnt(a.x-b.x,a.y-b.y,a.z-b.z, a.u-b.u,a.v-b.v,a.w-b.w, a.r-b.r,a.g-b.g,a.b-b.b,a.a-b.a);       }\r
 inline mglPnt operator*(const mglPnt &a, float b)\r
-{      mglPnt c=a;\r
-       c.x*=b; c.y*=b; c.z*=b; c.u*=b; c.v*=b; c.w*=b;\r
-       c.r*=b; c.g*=b; c.b*=b; c.a*=b; return c;       }\r
+{      return mglPnt(a.x*b,a.y*b,a.z*b, a.u*b,a.v*b,a.w*b, a.r*b,a.g*b,a.b*b,a.a*b);   }\r
 inline mglPnt operator*(float b, const mglPnt &a)\r
-{      mglPnt c=a;\r
-       c.x*=b; c.y*=b; c.z*=b; c.u*=b; c.v*=b; c.w*=b;\r
-       c.r*=b; c.g*=b; c.b*=b; c.a*=b; return c;       }\r
+{      return mglPnt(a.x*b,a.y*b,a.z*b, a.u*b,a.v*b,a.w*b, a.r*b,a.g*b,a.b*b,a.a*b);   }\r
 //-----------------------------------------------------------------------------\r
 /// Structure for glyph representation\r
 struct MGL_EXPORT mglGlyph\r
@@ -137,16 +224,20 @@ struct MGL_EXPORT mglGlyph
        long nt, nl;                    ///< number of triangles and lines\r
        short *trig, *line;     ///< vertexes of triangles and lines\r
 \r
-       mglGlyph()      {       nl=nt=0;        trig=line=0;    }\r
-       mglGlyph(const mglGlyph &a)     {       nl=nt=0;        trig=line=0;    *this=a;        }\r
-       mglGlyph(long Nt, long Nl)      {       nl=nt=0;        trig=line=0;    Create(Nt,Nl);  }\r
+       mglGlyph():nt(0),nl(0),trig(0),line(0)  {}\r
+       mglGlyph(const mglGlyph &a):nt(0),nl(0),trig(0),line(0) {       *this=a;        }\r
+       mglGlyph(long Nt, long Nl):nt(0),nl(0),trig(0),line(0)  {       Create(Nt,Nl);  }\r
+#if MGL_HAVE_RVAL\r
+       mglGlyph(mglGlyph &&aa) : nt(aa.nt),nl(aa.nl),trig(aa.trig), line(aa.line)      {       aa.trig=aa.line=0;      }\r
+#endif\r
        ~mglGlyph()     {       if(trig)        delete []trig;  if(line)        delete []line;  }\r
 \r
        void Create(long Nt, long Nl);\r
-       bool operator==(const mglGlyph &g);\r
-       inline mglGlyph &operator=(const mglGlyph &a)\r
+       bool operator==(const mglGlyph &g) MGL_FUNC_PURE;\r
+       inline bool operator!=(const mglGlyph &g)       {       return !(*this==g);     }\r
+       inline const mglGlyph &operator=(const mglGlyph &a)\r
        {       Create(a.nt, a.nl);     memcpy(trig, a.trig, 6*nt*sizeof(short));\r
-               memcpy(line, a.line, 2*nl*sizeof(short));       return *this;   }\r
+               memcpy(line, a.line, 2*nl*sizeof(short));       return a;       }\r
 };\r
 //-----------------------------------------------------------------------------\r
 #define MGL_TEXTURE_COLOURS 512\r
@@ -160,19 +251,29 @@ struct MGL_EXPORT mglTexture
        int Smooth;                     ///< Type of texture (smoothing and so on)\r
        mreal Alpha;                    ///< Transparency\r
 \r
-       mglTexture()    {       n=Smooth=0;     Alpha=1;        }\r
-       mglTexture(const char *cols, int smooth=0,mreal alpha=1)\r
-       {       n=0;    Set(cols,smooth,alpha); }\r
+       mglTexture():n(0),Smooth(0),Alpha(1)    {}\r
+       mglTexture(const char *cols, int smooth=0,mreal alpha=1):n(0)\r
+       {       Set(cols,smooth,alpha); }\r
+       mglTexture(const mglTexture &aa) : n(aa.n),Smooth(aa.Smooth),Alpha(aa.Alpha)\r
+       {       memcpy(col,aa.col,MGL_TEXTURE_COLOURS*sizeof(mglColor));        memcpy(Sch,aa.Sch,260); }\r
+#if MGL_HAVE_RVAL\r
+       mglTexture(mglTexture &&aa) : n(aa.n),Smooth(aa.Smooth),Alpha(aa.Alpha)\r
+       {       memcpy(col,aa.col,MGL_TEXTURE_COLOURS*sizeof(mglColor));        memcpy(Sch,aa.Sch,260); }\r
+#endif\r
        void Clear()    {       n=0;    }\r
        void Set(const char *cols, int smooth=0,mreal alpha=1);\r
        void Set(HCDT val, const char *cols);\r
        void GetC(mreal u,mreal v,mglPnt &p) const;\r
-       mglColor GetC(mreal u,mreal v=0) const;\r
+       mglColor GetC(mreal u,mreal v=0) const MGL_FUNC_PURE;\r
        inline bool IsSame(const mglTexture &t) const\r
        {       return n==t.n && !memcmp(col,t.col,MGL_TEXTURE_COLOURS*sizeof(mglColor));       }\r
        void GetRGBA(unsigned char *f) const;\r
        void GetRGBAPRC(unsigned char *f) const;\r
        void GetRGBAOBJ(unsigned char *f) const;        // Export repeating border colors, since OBJ by default wraps textures and we need an extra boundary to work around implementation quirks\r
+       inline const mglTexture &operator=(const mglTexture &aa)\r
+       {       n=aa.n; Smooth=aa.Smooth;       Alpha=aa.Alpha;\r
+               memcpy(col,aa.col,MGL_TEXTURE_COLOURS*sizeof(mglColor));\r
+               memcpy(Sch,aa.Sch,260); return aa;      }\r
 };\r
 //-----------------------------------------------------------------------------\r
 const mglColor NC(-1,-1,-1);\r
@@ -195,15 +296,14 @@ public:
        mglBase();\r
        virtual ~mglBase();\r
 \r
-       bool Stop;                      ///< Flag that execution should be terminated.\r
        mglPoint Min;           ///< Lower edge of bounding box for graphics.\r
        mglPoint Max;           ///< Upper edge of bounding box for graphics.\r
        mreal ZMin;                     ///< Adjusted minimal z-value 1D plots\r
        std::string Mess;       ///< Buffer for receiving messages\r
        int ObjId;                      ///< object id for mglPrim\r
        int HighId;                     ///< object id to be highlited\r
-       std::vector<mglGroup> Grp;              ///< List of groups with names -- need for export\r
-       std::vector<mglActivePos> Act;  ///< Position of active points\r
+       mglStack<mglGroup> Grp;         ///< List of groups with names -- need for export\r
+       mglStack<mglActivePos> Act;     ///< Position of active points\r
        std::string PlotId;     ///< Id of plot for saving filename (in GLUT window for example)\r
 \r
        mreal CDef;                     ///< Default (current) color in texture\r
@@ -329,13 +429,13 @@ public:
        /// Set default font size\r
        inline void SetFontSize(mreal val)      {       FontSize=val>0 ? val:-FontSize*val;     }\r
        inline mreal GetFontSize() const        {       return FontSize;        }\r
-       mreal TextWidth(const char *text, const char *font, mreal size) const;\r
-       mreal TextWidth(const wchar_t *text, const char *font, mreal size) const;\r
-       mreal TextHeight(const char *font, mreal size) const;\r
+       mreal TextWidth(const char *text, const char *font, mreal size) const MGL_FUNC_PURE;\r
+       mreal TextWidth(const wchar_t *text, const char *font, mreal size) const MGL_FUNC_PURE;\r
+       mreal TextHeight(const char *font, mreal size) const MGL_FUNC_PURE;\r
        inline mreal FontFactor() const         {       return font_factor;     }\r
-       virtual mreal GetRatio() const;\r
-       virtual int GetWidth() const;\r
-       virtual int GetHeight() const;\r
+       virtual mreal GetRatio() const MGL_FUNC_CONST;\r
+       virtual int GetWidth() const MGL_FUNC_CONST;\r
+       virtual int GetHeight() const MGL_FUNC_CONST;\r
 \r
        /// Set to use or not text rotation\r
        inline void SetRotatedText(bool val)    {       set(val,MGL_ENABLE_RTEXT);      }\r
@@ -388,7 +488,11 @@ public:
        inline long GetGlfNum() const           {       return Glf.size();      }\r
        inline const mglPnt &GetPnt(long i) const       {       return Pnt[i];          }\r
        inline long GetPntNum() const           {       return Pnt.size();      }\r
-       inline mglPrim &GetPrm(long i)          {       return Prm[i];          }\r
+//     inline mglPrim &GetPrm(long i)          {       return Prm[i];          }\r
+       inline mglPrim &GetPrm(long i, bool sort=true)\r
+       {       return (sort && PrmInd) ? Prm[PrmInd[i]]:Prm[i];        }\r
+       inline const mglPrim &GetPrm(long i, bool sort=true) const\r
+       {       return (sort && PrmInd) ? Prm[PrmInd[i]]:Prm[i];        }\r
        inline long GetPrmNum() const           {       return Prm.size();      }\r
        inline const mglText &GetPtx(long i) const      {       return Ptx[i];          }\r
        inline long GetPtxNum() const           {       return Ptx.size();      }\r
@@ -405,7 +509,7 @@ public:
        inline mreal GetC(long s,mreal z,bool scale = true) const\r
        {       return s+(scale?GetA(z):(z>0?z/MGL_FEPSILON:0));        }\r
        /// Get alpha value depending on single variable a\r
-       mreal GetA(mreal a) const;\r
+       mreal GetA(mreal a) const MGL_FUNC_PURE;\r
        /// Set pen/palette\r
        char SetPenPal(const char *stl, long *id=0, bool pal=true);\r
        /// Add texture (like color scheme) and return the position of first color\r
@@ -431,9 +535,19 @@ public:
        inline mreal mark_size()        {       return MarkSize*font_factor;    }\r
 //     inline char last_color()        {       return last_style[1];   }\r
        inline const char *last_line()  {       return last_style;      }\r
-       void resort();  ///< Resort primitives in creation order (need for export in 3D formats)\r
+       int PrmCmp(long i, long j) const MGL_FUNC_PURE; // compare 2 primitives with indexes i,j\r
+       /// Check if plot termination is asked\r
+       bool NeedStop() {       if(event_cb)    event_cb(event_par);    return Stop;    }\r
+       /// Ask to stop drawing\r
+       void AskStop(bool stop=true)    {       Stop = stop;    }\r
+       /// Set callback function for event processing\r
+       void SetEventFunc(void (*func)(void *), void *par)      {       event_cb=func;  event_par=par;  }\r
 \r
 protected:\r
+       bool Stop;                      ///< Flag that execution should be terminated.\r
+       void (*event_cb)(void *);       ///< Function to be called for event processing\r
+       void *event_par;        ///< Parameter for event processing function\r
+\r
        mglPoint OMin;          ///< Lower edge for original axis (before scaling)\r
        mglPoint OMax;          ///< Upper edge for original axis (before scaling)\r
        mglPoint AMin;          ///< Lower edge for axis scaling\r
@@ -442,16 +556,20 @@ protected:
        mglPoint FMax;          ///< Actual upper edge after transformation formulas.\r
        mglPoint Org;           ///< Center of axis cross section.\r
        int WarnCode;           ///< Warning code\r
-       std::vector<mglPnt> Pnt;        ///< Internal points\r
-       std::vector<mglPrim> Prm;       ///< Primitives (lines, triangles and so on) -- need for export\r
-       std::vector<mglPrim> Sub;       ///< InPlot regions {n1=x1,n2=x2,n3=y1,n4=y2,id}\r
+       long *PrmInd;           ///< Indexes of sorted primitives\r
+       mglStack<mglPnt> Pnt;   ///< Internal points\r
+       mglStack<mglPrim> Prm;  ///< Primitives (lines, triangles and so on) -- need for export\r
+       mglStack<mglPrim> Sub;  ///< InPlot regions {n1=x1,n2=x2,n3=y1,n4=y2,id}\r
        std::vector<mglText> Ptx;       ///< Text labels for mglPrim\r
        std::vector<mglText> Leg;       ///< Text labels for legend\r
        std::vector<mglGlyph> Glf;      ///< Glyphs data\r
-       std::vector<mglTexture> Txt;    ///< Pointer to textures\r
+       mglStack<mglTexture> Txt;       ///< Pointer to textures\r
 #if MGL_HAVE_PTHREAD\r
        pthread_mutex_t mutexPnt, mutexTxt, mutexLeg, mutexGlf, mutexAct, mutexDrw;\r
-       pthread_mutex_t mutexSub, mutexPrm, mutexPtx, mutexStk, mutexGrp;\r
+       pthread_mutex_t mutexSub, mutexPrm, mutexPtx, mutexStk, mutexGrp, mutexClf;\r
+#endif\r
+#if MGL_HAVE_OMP\r
+       omp_lock_t lockClf;\r
 #endif\r
 \r
        int TernAxis;           ///< Flag that Ternary axis is used\r
@@ -462,6 +580,7 @@ protected:
        mreal AmbBr;            ///< Default ambient light brightness\r
        mreal DifBr;            ///< Default diffusive light brightness\r
 \r
+       mreal persp;            ///< Original value for perspective\r
        mglMatrix Bp;           ///< Transformation matrix for View() and Zoom()\r
        mglMatrix B;            ///< Transformation matrix\r
        mglMatrix B1;           ///< Transformation matrix for colorbar\r
@@ -482,10 +601,11 @@ protected:
        mreal ArrowSize;        ///< The size of arrows.\r
        char last_style[64];///< Last pen style\r
        mreal font_factor;      ///< Font scaling factor\r
-       \r
+\r
        long dr_x, dr_y, dr_p;  ///< default drawing region for quality&4 mode\r
 \r
        virtual void LightScale(const mglMatrix *M)=0;                  ///< Scale positions of light sources\r
+       void ClearPrmInd();\r
 \r
        // block for SaveState()\r
        mglPoint MinS;          ///< Saved lower edge of bounding box for graphics.\r
@@ -505,6 +625,8 @@ protected:
        int DefMaskAn;  ///< Default mask rotation angle in degrees\r
 \r
 private:\r
+       mglBase(const mglBase &){}      // copying is not allowed\r
+       const mglBase &operator=(const mglBase &t){return t;}   // copying is not allowed\r
 \r
        mglPoint CutMin;        ///< Lower edge of bounding box for cut off.\r
        mglPoint CutMax;        ///< Upper edge of bounding box for cut off.\r
@@ -521,7 +643,9 @@ bool MGL_EXPORT mgl_check_dim2(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const ch
 bool MGL_EXPORT mgl_check_dim3(HMGL gr, bool both, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *name);\r
 bool MGL_EXPORT mgl_check_vec3(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *name);\r
 bool MGL_EXPORT mgl_check_trig(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *name, int d=3);\r
+bool MGL_EXPORT mgl_isnboth(HCDT x, HCDT y, HCDT z, HCDT a);\r
 bool MGL_EXPORT mgl_isboth(HCDT x, HCDT y, HCDT z, HCDT a);\r
+inline bool mgl_islog(mreal a,mreal b) {       return (a>0 && b>10*a) || (b<0 && a<10*b);      }\r
 //-----------------------------------------------------------------------------\r
 #endif\r
 #endif\r
index 76d5276c709e39c7996416a3dbdc8dd4d3c2dde6..bc850ea415d0b7bc6d5b3a7e6f85aa6ded471578 100644 (file)
 extern "C" {\r
 #endif\r
 \r
+/// Check if MathGL version is valid\r
+int MGL_EXPORT mgl_check_version(const char *ver);\r
+int MGL_EXPORT mgl_check_version_(const char *ver, int);\r
+/// Suppress printing warnings to stderr\r
+void MGL_EXPORT mgl_suppress_warn(int on);\r
+void MGL_EXPORT mgl_suppress_warn_(int *on);\r
 /// Get last warning code\r
-int MGL_EXPORT mgl_get_warn(HMGL gr);\r
-int MGL_EXPORT mgl_get_warn_(uintptr_t *gr);\r
+int MGL_EXPORT_PURE mgl_get_warn(HMGL gr);\r
+int MGL_EXPORT_PURE mgl_get_warn_(uintptr_t *gr);\r
 /// Set warning code ant fill message\r
 void MGL_EXPORT mgl_set_warn(HMGL gr, int code, const char *text);\r
 void MGL_EXPORT mgl_set_warn_(uintptr_t *gr, int *code, const char *text,int);\r
 /// Set buffer for warning messages\r
-MGL_EXPORT const char *mgl_get_mess(HMGL gr);\r
+MGL_EXPORT_PURE const char *mgl_get_mess(HMGL gr);\r
+int MGL_EXPORT mgl_get_mess_(uintptr_t *gr, char *out, int len);\r
 \r
 /// Set name of plot for saving filename\r
 void MGL_EXPORT mgl_set_plotid(HMGL gr, const char *id);\r
 void MGL_EXPORT mgl_set_plotid_(uintptr_t *gr, const char *id,int);\r
 /// Get name of plot for saving filename\r
-MGL_EXPORT const char *mgl_get_plotid(HMGL gr);\r
+MGL_EXPORT_PURE const char *mgl_get_plotid(HMGL gr);\r
+int MGL_EXPORT mgl_get_plotid_(uintptr_t *gr, char *out, int len);\r
+\r
+/// Ask to stop drawing\r
+void MGL_EXPORT mgl_ask_stop(HMGL gr, int stop);\r
+void MGL_EXPORT mgl_ask_stop_(uintptr_t *gr, int *stop);\r
+/// Check if plot termination is asked\r
+int MGL_EXPORT mgl_need_stop(HMGL gr);\r
+int MGL_EXPORT mgl_need_stop_(uintptr_t *gr);\r
+/// Set callback function for event processing\r
+void MGL_EXPORT mgl_set_event_func(HMGL gr, void (*func)(void *), void *par);\r
 \r
 /// Get plot quality\r
-int MGL_EXPORT mgl_get_quality(HMGL gr);\r
-int MGL_EXPORT mgl_get_quality_(uintptr_t *gr);\r
+int MGL_EXPORT_PURE mgl_get_quality(HMGL gr);\r
+int MGL_EXPORT_PURE mgl_get_quality_(uintptr_t *gr);\r
 /// Set plot quality\r
 void MGL_EXPORT mgl_set_quality(HMGL gr, int qual);\r
 void MGL_EXPORT mgl_set_quality_(uintptr_t *gr, int *qual);\r
@@ -50,18 +67,18 @@ void MGL_EXPORT mgl_set_quality_(uintptr_t *gr, int *qual);
 void MGL_EXPORT mgl_set_draw_reg(HMGL gr, long nx, long ny, long m);\r
 void MGL_EXPORT mgl_set_draw_reg_(uintptr_t *gr, int *nx, int *ny, int *m);\r
 \r
-/// Is frames\r
-int MGL_EXPORT mgl_is_frames(HMGL gr);\r
+/// Check if support of frames is enabled (i.e. MGL_VECT_FRAME is set and Quality&MGL_DRAW_LMEM==0)\r
+int MGL_EXPORT_PURE mgl_is_frames(HMGL gr);\r
 /// Get bit-value flag of HMGL state (for advanced users only)\r
-int MGL_EXPORT mgl_get_flag(HMGL gr, uint32_t flag);\r
-int MGL_EXPORT mgl_get_flag_(uintptr_t *gr, unsigned long *flag);\r
+int MGL_EXPORT_PURE mgl_get_flag(HMGL gr, uint32_t flag);\r
+int MGL_EXPORT_PURE mgl_get_flag_(uintptr_t *gr, unsigned long *flag);\r
 /// Set bit-value flag of HMGL state (for advanced users only)\r
 void MGL_EXPORT mgl_set_flag(HMGL gr, int val, uint32_t flag);\r
 void MGL_EXPORT mgl_set_flag_(uintptr_t *gr, int *val, unsigned long *flag);\r
 /// Change counter of HMGL uses (for advanced users only). Non-zero counter prevent automatic object removing.\r
 long MGL_EXPORT mgl_use_graph(HMGL gr, int inc);\r
 long MGL_EXPORT mgl_use_graph_(uintptr_t *gr, int *inc);\r
-void MGL_EXPORT mgl_set_rdc_acc(HMGL gr, int reduce);  // TODO\r
+void MGL_EXPORT mgl_set_rdc_acc(HMGL gr, int reduce);\r
 void MGL_EXPORT mgl_set_rdc_acc_(uintptr_t *gr, int *reduce);\r
 \r
 /// Start group of objects\r
index 8a1c084d037060ff59831fa40132ddedbb4d11bb..48d90645d7adc415e168f9bd16368f98504d0ac6 100644 (file)
@@ -26,28 +26,32 @@ struct GifFileType;
 /// Structure for drawing axis and ticks\r
 struct MGL_EXPORT mglAxis\r
 {\r
-       mglAxis()       {       dv=ds=d=v0=v1=v2=o=sh=0;        ns=f=ch=0;      pos = 't';      inv=false;      }\r
-       mglAxis(const mglAxis &aa)\r
-       {       dv=aa.dv;       ds=aa.ds;       d=aa.d;         dir=aa.dir;     sh=aa.sh;\r
-               v0=aa.v0;       v1=aa.v1;       v2=aa.v2;       o=aa.o;         pos=aa.pos;\r
-               a = aa.a;       b = aa.b;       org=aa.org;     txt=aa.txt;     inv=aa.inv;\r
-               ns=aa.ns;       f=aa.f;         ch=aa.ch;       t=aa.t; }\r
+       mglAxis() : dv(0),ds(0),d(0),ns(0),     v0(0),v1(0),v2(0),o(NAN),       f(0),   ch(0),  pos('t'),sh(0),inv(false)       {}\r
+       mglAxis(const mglAxis &aa) : dv(aa.dv),ds(aa.ds),d(aa.d),ns(aa.ns),     t(aa.t),fact(aa.fact),stl(aa.stl),      dir(aa.dir),a(aa.a),b(aa.b),org(aa.org), v0(aa.v0),v1(aa.v1),v2(aa.v2),o(aa.o), f(aa.f),txt(aa.txt),    ch(aa.ch),      pos(aa.pos),sh(aa.sh),inv(aa.inv)       {}\r
+#if MGL_HAVE_RVAL\r
+       mglAxis(mglAxis &&aa) : dv(aa.dv),ds(aa.ds),d(aa.d),ns(aa.ns),  t(aa.t),fact(aa.fact),stl(aa.stl),      dir(aa.dir),a(aa.a),b(aa.b),org(aa.org), v0(aa.v0),v1(aa.v1),v2(aa.v2),o(aa.o), f(aa.f),txt(aa.txt),    ch(aa.ch),      pos(aa.pos),sh(aa.sh),inv(aa.inv)       {}\r
+#endif\r
        inline void AddLabel(const wchar_t *lbl, mreal v)\r
        {       txt.push_back(mglText(lbl,"",v));       }\r
        inline void AddLabel(const std::wstring &lbl, mreal v)\r
        {       txt.push_back(mglText(lbl,v));  }\r
+       inline void Clear()\r
+       {       dv=ds=d=v0=v1=v2=sh=0;  o=NAN;  ns=f=0; pos = 't';      inv=false;\r
+               fact.clear();   stl.clear();    t.clear();      txt.clear();    }\r
 \r
-       mreal dv,ds;            ///< Actual step for ticks and subticks.\r
-       mreal d;                        ///< Step for axis ticks (if positive) or its number (if negative).\r
+       mreal dv,ds;    ///< Actual step for ticks and subticks.\r
+       mreal d;                ///< Step for axis ticks (if positive) or its number (if negative).\r
        int ns;                 ///< Number of axis subticks.\r
        std::wstring t; ///< Tick template (set "" to use default one ("%.2g" in simplest case))\r
+       std::wstring fact;      ///< Factor which should be placed after number (like L"\pi")\r
+       std::string stl;        ///< Tick styles (default is ""=>"3m")\r
        mglPoint dir;   ///< Axis direction\r
        mglPoint a,b;   ///< Directions of over axis\r
        mglPoint org;\r
        mreal v0;               ///< Center of axis cross section\r
        mreal v1;               ///< Minimal axis range.\r
        mreal v2;               ///< Maximal axis range.\r
-       mreal o;                        ///< Point of starting ticks numbering (if NAN then Org is used).\r
+       mreal o;                ///< Point of starting ticks numbering (if NAN then Org is used).\r
        int f;                  ///< Flag 0x1 - time, 0x2 - manual, 0x4 - fixed dv\r
        std::vector<mglText> txt;       ///< Axis labels\r
        char ch;                ///< Character of axis (like 'x','y','z','c')\r
@@ -59,7 +63,11 @@ struct MGL_EXPORT mglAxis
 /// Structure for light source\r
 struct MGL_EXPORT mglLight\r
 {\r
-       mglLight()      {       n=false;        a=b=0;  }\r
+       mglLight():n(false),a(0),b(0)   {}\r
+       mglLight(const mglLight &aa) : n(aa.n),d(aa.d),r(aa.r),q(aa.q),p(aa.p),a(aa.a),b(aa.b),c(aa.c)  {}\r
+#if MGL_HAVE_RVAL\r
+       mglLight(mglLight &&aa) : n(aa.n),d(aa.d),r(aa.r),q(aa.q),p(aa.p),a(aa.a),b(aa.b),c(aa.c)       {}\r
+#endif\r
        bool n;                 ///< Availability of light sources\r
        mglPoint d;             ///< Direction of light sources\r
        mglPoint r;             ///< Position of light sources (NAN for infinity)\r
@@ -74,6 +82,13 @@ class mglCanvas;
 /// Structure for light source\r
 struct MGL_EXPORT mglDrawReg\r
 {\r
+       mglDrawReg() {}\r
+       mglDrawReg(const mglDrawReg &aa) : PDef(aa.PDef),angle(aa.angle),ObjId(aa.ObjId),PenWidth(aa.PenWidth),pPos(aa.pPos) ,x1(aa.x1),x2(aa.x2),y1(aa.y1),y2(aa.y2)   {}\r
+#if MGL_HAVE_RVAL\r
+       mglDrawReg(mglDrawReg &&aa) : PDef(aa.PDef),angle(aa.angle),ObjId(aa.ObjId),PenWidth(aa.PenWidth),pPos(aa.pPos) ,x1(aa.x1),x2(aa.x2),y1(aa.y1),y2(aa.y2)        {}\r
+#endif\r
+       inline const mglDrawReg &operator=(const mglDrawReg &aa)\r
+       {       memcpy(this,&aa,sizeof(mglDrawReg));    return aa;      }\r
        union\r
        {\r
                uint64_t PDef;\r
@@ -89,11 +104,18 @@ struct MGL_EXPORT mglDrawReg
 /// Structure contains everything for drawing\r
 struct MGL_EXPORT mglDrawDat\r
 {\r
-       std::vector<mglPnt>  Pnt;       ///< Internal points\r
-       std::vector<mglPrim> Prm;       ///< Primitives (lines, triangles and so on) -- need for export\r
+       mglDrawDat() {}\r
+       mglDrawDat(const mglDrawDat &aa) : Pnt(aa.Pnt),Prm(aa.Prm),Ptx(aa.Ptx),Glf(aa.Glf),Txt(aa.Txt)  {}\r
+#if MGL_HAVE_RVAL\r
+       mglDrawDat(mglDrawDat &&aa) : Pnt(aa.Pnt),Prm(aa.Prm),Ptx(aa.Ptx),Glf(aa.Glf),Txt(aa.Txt)       {}\r
+#endif\r
+       inline const mglDrawDat&operator=(const mglDrawDat &aa)\r
+       {       Pnt=aa.Pnt;     Prm=aa.Prm;     Ptx=aa.Ptx;     Glf=aa.Glf;     Txt=aa.Txt;     return aa;      }\r
+       mglStack<mglPnt>  Pnt;  ///< Internal points\r
+       mglStack<mglPrim> Prm;  ///< Primitives (lines, triangles and so on) -- need for export\r
        std::vector<mglText> Ptx;       ///< Text labels for mglPrim\r
        std::vector<mglGlyph> Glf;      ///< Glyphs data\r
-       std::vector<mglTexture> Txt;    ///< Pointer to textures\r
+       mglStack<mglTexture> Txt;       ///< Pointer to textures\r
 };\r
 //-----------------------------------------------------------------------------\r
 union mglRGBA  {       uint32_t c; unsigned char r[4]; };\r
@@ -133,6 +155,7 @@ using mglBase::Light;
        inline void Pop()       {       B = stack.back(); stack.pop_back();     }\r
        /// Clear up the frame\r
        virtual void Clf(mglColor back=NC);\r
+       virtual void Clf(const char *col);\r
 \r
        /// Put further plotting in cell of stick rotated on angles tet, phi\r
        void StickPlot(int num, int i, mreal tet, mreal phi);\r
@@ -149,18 +172,21 @@ using mglBase::Light;
        /// Rotate a further plotting.\r
        void Rotate(mreal TetX,mreal TetZ,mreal TetY=0);\r
        /// Rotate a further plotting around vector {x,y,z}.\r
-       void RotateN(mreal Tet,mreal x,mreal y,mreal z) ;\r
-       /// Set perspective (in range [0,1)) for plot. Set to zero for switching off.\r
-       void Perspective(mreal a)       {       Bp.pf = fabs(a);        }\r
+       void RotateN(mreal Tet,mreal x,mreal y,mreal z);\r
+       /// Set perspective (in range [0,1)) for plot. Set to zero for switching off. Return the current perspective.\r
+       void Perspective(mreal a, bool req=true)\r
+       {       if(req) persp = Bp.pf = a;      else    Bp.pf = persp?persp:fabs(a);    }\r
 \r
        /// Set size of frame in pixels. Normally this function is called internaly.\r
-       virtual void SetSize(int w,int h);\r
+       virtual void SetSize(int w,int h,bool clf=true);\r
        /// Get ratio (mreal width)/(mreal height).\r
-       mreal GetRatio() const;\r
+       mreal GetRatio() const MGL_FUNC_PURE;\r
        /// Get bitmap data prepared for saving to file\r
        virtual unsigned char **GetRGBLines(long &w, long &h, unsigned char *&f, bool alpha=false);\r
        /// Get RGB bitmap of current state image.\r
        virtual const unsigned char *GetBits();\r
+       /// Get RGBA bitmap of background image.\r
+       const unsigned char *GetBackground()    {       return GB;      };\r
        /// Get RGBA bitmap of current state image.\r
        const unsigned char *GetRGBA()  {       Finish();       return G4;      }\r
        /// Get width of the image\r
@@ -170,11 +196,18 @@ using mglBase::Light;
        /// Combine plots from 2 canvases. Result will be saved into this.\r
        void Combine(const mglCanvas *gr);\r
 \r
+       /// Rasterize current plot and set it as background image\r
+       void Rasterize();\r
+       /// Load image for background from file\r
+       void LoadBackground(const char *fname, double alpha=1);\r
+       /// Fill background image by specified color\r
+       void FillBackground(const mglColor &cc);\r
+\r
        inline mreal GetDelay() const   {       return Delay;   }\r
        inline void SetDelay(mreal d)   {       Delay=d;        }\r
 \r
        /// Calculate 3D coordinate {x,y,z} for screen point {xs,ys}\r
-       mglPoint CalcXYZ(int xs, int ys, bool real=false) const;\r
+       mglPoint CalcXYZ(int xs, int ys, bool real=false) const MGL_FUNC_PURE;\r
        /// Calculate screen point {xs,ys} for 3D coordinate {x,y,z}\r
        void CalcScr(mglPoint p, int *xs, int *ys) const;\r
        mglPoint CalcScr(mglPoint p) const;\r
@@ -183,7 +216,7 @@ using mglBase::Light;
        /// Get object id\r
        inline int GetObjId(long xs,long ys) const      {       return OI[xs+Width*ys]; }\r
        /// Get subplot id\r
-       int GetSplId(long xs,long ys) const;\r
+       int GetSplId(long xs,long ys) const MGL_FUNC_PURE;\r
        /// Check if there is active point or primitive (n=-1)\r
        int IsActive(int xs, int ys,int &n);\r
 \r
@@ -203,6 +236,8 @@ using mglBase::Light;
        virtual void SetFrame(long i);\r
        /// Add drawing data from i-th frame to the current drawing\r
        void ShowFrame(long i);\r
+       /// Clear list of primitives for current drawing\r
+       void ClearFrame();\r
 \r
        /// Start write frames to cinema using GIF format\r
        void StartGIF(const char *fname, int ms=100);\r
@@ -237,15 +272,19 @@ using mglBase::Light;
        void SetTicksVal(char dir, const wchar_t *lbl, bool add=false);\r
        void SetTicksVal(char dir, HCDT v, const wchar_t *lbl, bool add=false);\r
        void SetTicksVal(char dir, HCDT v, const wchar_t **lbl, bool add=false);\r
+               /// Add manual tick at given position. Use "" to disable this feature.\r
+       void AddTick(char dir, double val, const char *lbl);\r
+       void AddTick(char dir, double val, const wchar_t *lbl);\r
+\r
        /// Set templates for ticks\r
        void SetTickTempl(char dir, const wchar_t *t);\r
        void SetTickTempl(char dir, const char *t);\r
        /// Set time templates for ticks\r
        void SetTickTime(char dir, mreal d=0, const char *t="");\r
        /// Set the ticks parameters\r
-       void SetTicks(char dir, mreal d=0, int ns=0, mreal org=NAN);\r
+       void SetTicks(char dir, mreal d=0, int ns=0, mreal org=NAN, const wchar_t *lbl=0);\r
        /// Auto adjust ticks\r
-       void AdjustTicks(const char *dir="xyzc", bool force=false);\r
+       void AdjustTicks(const char *dir="xyzc", bool force=false, std::string stl="");\r
        /// Tune ticks\r
        inline void SetTuneTicks(int tune, mreal pos=1.15)\r
        {       TuneTicks = tune;       FactorPos = pos;        }\r
@@ -305,14 +344,15 @@ using mglBase::Light;
        void pnt_fast(long x,long y,mreal z,const unsigned char c[4], int obj_id);\r
        /// preparing primitives for 2d export or bitmap drawing (0 default, 1 for 2d vector, 2 for 3d vector)\r
        void PreparePrim(int fast);\r
-       inline uint32_t GetPntCol(long i)       {       return pnt_col[i];      }\r
-       inline uint32_t GetPrmCol(long i)       {       return prm_col[i];      }\r
+       inline uint32_t GetPntCol(long i) const {       return pnt_col[i];      }\r
+       inline uint32_t GetPrmCol(long i, bool sort=true) const {       return GetColor(GetPrm(i, sort));       }\r
 \r
 protected:\r
        mreal Delay;            ///< Delay for animation in seconds\r
        // NOTE: Z should be float for reducing space and for compatibility reasons\r
        unsigned char *G4;      ///< Final picture in RGBA format. Prepared in Finish().\r
        unsigned char *G;       ///< Final picture in RGB format. Prepared in Finish().\r
+       unsigned char *GB;      ///< Background picture in RGBA format.\r
        std::vector<mglDrawDat> DrwDat; ///< Set of ALL drawing data for each frames\r
 \r
        int LegendMarks;        ///< Number of marks in the Legend\r
@@ -344,7 +384,7 @@ protected:
        /// Draw axis\r
        void DrawAxis(mglAxis &aa, bool text=true, char arr=0,const char *stl="",const char *opt="");\r
        /// Draw axis grid lines\r
-       void DrawGrid(mglAxis &aa);\r
+       void DrawGrid(mglAxis &aa, bool at_tick=false);\r
        /// Update axis ranges\r
        inline void UpdateAxis()\r
        {       ax.v0=Org.x;    ay.v0=Org.y;    az.v0=Org.z;    ac.v0=Org.c;\r
@@ -359,11 +399,11 @@ protected:
        /// Push drawing data (for frames only). NOTE: can be VERY large\r
        long PushDrwDat();\r
        /// Retur color for primitive depending lighting\r
-       uint32_t GetColor(const mglPrim &p);\r
+       uint32_t GetColor(const mglPrim &p) const MGL_FUNC_PURE;\r
 \r
-       mreal GetOrgX(char dir, bool inv=false) const;  ///< Get Org.x (parse NAN value)\r
-       mreal GetOrgY(char dir, bool inv=false) const;  ///< Get Org.y (parse NAN value)\r
-       mreal GetOrgZ(char dir, bool inv=false) const;  ///< Get Org.z (parse NAN value)\r
+       mreal GetOrgX(char dir, bool inv=false) const MGL_FUNC_PURE;    ///< Get Org.x (parse NAN value)\r
+       mreal GetOrgY(char dir, bool inv=false) const MGL_FUNC_PURE;    ///< Get Org.y (parse NAN value)\r
+       mreal GetOrgZ(char dir, bool inv=false) const MGL_FUNC_PURE;    ///< Get Org.z (parse NAN value)\r
 \r
        void mark_plot(long p, char type, mreal size=1);\r
        void arrow_plot(long p1, long p2, char st);\r
@@ -386,11 +426,10 @@ protected:
        bool IsSame(const mglPrim &pr,mreal wp,mglColor cp,int st);\r
 \r
        // restore normalized coordinates from screen ones\r
-       mglPoint RestorePnt(mglPoint ps, bool norm=false) const;\r
+       mglPoint RestorePnt(mglPoint ps, bool norm=false) const MGL_FUNC_PURE;\r
 \r
        // functions for multi-threading\r
        void pxl_pntcol(long id, long n, const void *);\r
-       void pxl_prmcol(long id, long n, const void *);\r
        void pxl_combine(long id, long n, const void *);\r
        void pxl_memcpy(long id, long n, const void *);\r
        void pxl_backgr(long id, long n, const void *);\r
@@ -405,7 +444,10 @@ protected:
        void PutDrawReg(mglDrawReg *d, const mglCanvas *gr);\r
 \r
 private:\r
-       std::vector<uint32_t> pnt_col, prm_col;\r
+    mglCanvas(const mglCanvas &){}     // copying is not allowed\r
+       const mglCanvas &operator=(const mglCanvas &t){return t;}       // copying is not allowed\r
+\r
+       uint32_t *pnt_col;\r
 //     mreal _tetx,_tety,_tetz;                // extra angles\r
        std::vector<mglMatrix> stack;   ///< stack for transformation matrices\r
        GifFileType *gif;\r
@@ -422,11 +464,11 @@ private:
        char GetLabelPos(mreal c, long kk, mglAxis &aa);\r
        /// Draw tick\r
        void tick_draw(mglPoint o, mglPoint d1, mglPoint d2, int f);\r
-       mreal FindOptOrg(char dir, int ind) const;\r
+       mreal FindOptOrg(char dir, int ind) const MGL_FUNC_PURE;\r
        /// Transform mreal color and alpha to bits format\r
-       unsigned char* col2int(const mglPnt &p, unsigned char *r, int obj_id);\r
+       unsigned char* col2int(const mglPnt &p, unsigned char *r, int obj_id) const;\r
        /// Combine colors in 2 plane.\r
-       void combine(unsigned char *c1, const unsigned char *c2);\r
+       void combine(unsigned char *c1, const unsigned char *c2) const;\r
        /// Fast drawing of line between 2 points\r
        void fast_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *d);\r
 \r
index de04e43f2e21d1fe2e3a36974e824c7a92696886..071f0fbc1a45566e50d3dc6d58df9c70efc96c80 100644 (file)
@@ -43,6 +43,9 @@ void MGL_EXPORT mgl_combine_gr_(uintptr_t *gr, uintptr_t *gr2);
 /// Force preparing the image. It can be useful for OpenGL mode mostly.\r
 void MGL_EXPORT mgl_finish(HMGL gr);\r
 void MGL_EXPORT mgl_finish_(uintptr_t *gr);\r
+/// Force preparing the image and save result into background one.\r
+void MGL_EXPORT mgl_rasterize(HMGL gr);\r
+void MGL_EXPORT mgl_rasterize_(uintptr_t *gr);\r
 \r
 /// Set tick length\r
 void MGL_EXPORT mgl_set_tick_len(HMGL gr, double len, double stt);\r
@@ -54,18 +57,30 @@ void MGL_EXPORT mgl_set_axis_stl_(uintptr_t *gr, const char *stl, const char *tc
 /// Auto adjust ticks\r
 void MGL_EXPORT mgl_adjust_ticks(HMGL gr, const char *dir);\r
 void MGL_EXPORT mgl_adjust_ticks_(uintptr_t *gr, const char *dir, int);\r
+/// Auto adjust ticks and set ticks format ("+E0123456789-fF")\r
+void MGL_EXPORT mgl_adjust_ticks_ext(HMGL gr, const char *dir, const char *stl);\r
+void MGL_EXPORT mgl_adjust_ticks_ext_(uintptr_t *gr, const char *dir, const char *stl, int, int);\r
 /// Set the ticks parameters\r
 void MGL_EXPORT mgl_set_ticks(HMGL gr, char dir, double d, int ns, double org);\r
 void MGL_EXPORT mgl_set_ticks_(uintptr_t *gr, char *dir, mreal *d, int *ns, mreal *org, int);\r
-/// Set ticks text (\n separated). Use "" to disable this feature.\r
+/// Set the ticks parameters and specify ticks factor string\r
+void MGL_EXPORT mgl_set_ticks_fact(HMGL gr, char dir, double d, int ns, double org, const char *fact);\r
+void MGL_EXPORT mgl_set_ticks_factw(HMGL gr, char dir, double d, int ns, double org, const wchar_t *fact);\r
+void MGL_EXPORT mgl_set_ticks_fact_(uintptr_t *gr, char *dir, double *d, int *ns, double *org, const char *fact,int,int);\r
+\r
+/// Set manual ticks text (\n separated). Use "" to disable this feature.\r
 void MGL_EXPORT mgl_set_ticks_str(HMGL gr, char dir, const char *lbl, int add);\r
 void MGL_EXPORT mgl_set_ticks_str_(uintptr_t *gr, const char *dir, const char *lbl, int *add,int,int);\r
 void MGL_EXPORT mgl_set_ticks_wcs(HMGL gr, char dir, const wchar_t *lbl, int add);\r
-/// Set ticks position and text (\n separated). Use "" to disable this feature.\r
+/// Set manual ticks position and text (\n separated). Use "" to disable this feature.\r
 void MGL_EXPORT mgl_set_ticks_val(HMGL gr, char dir, HCDT val, const char *lbl, int add);\r
 void MGL_EXPORT mgl_set_ticks_val_(uintptr_t *gr, const char *dir, uintptr_t *val, const char *lbl, int *add,int,int);\r
 void MGL_EXPORT mgl_set_ticks_valw(HMGL gr, char dir, HCDT val, const wchar_t *lbl, int add);\r
-/// Tune ticks\r
+/// Add manual tick at given position. Use "" to disable this feature.\r
+void MGL_EXPORT mgl_add_tick(HMGL gr, char dir, double val, const char *lbl);\r
+void MGL_EXPORT mgl_add_tick_(uintptr_t *gr, const char *dir, mreal *val, const char *lbl,int,int);\r
+void MGL_EXPORT mgl_add_tickw(HMGL gr, char dir, double val, const wchar_t *lbl);\r
+/// Tune ticks \r
 void MGL_EXPORT mgl_tune_ticks(HMGL gr, int tune, double fact_pos);\r
 void MGL_EXPORT mgl_tune_ticks_(uintptr_t *gr, int *tune, mreal *fact_pos);\r
 /// Set templates for ticks\r
@@ -213,12 +228,15 @@ MGL_EXPORT const unsigned char *mgl_get_rgb_(uintptr_t *gr);
 /// Get RGBA values of current bitmap\r
 MGL_EXPORT const unsigned char *mgl_get_rgba(HMGL gr);\r
 MGL_EXPORT const unsigned char *mgl_get_rgba_(uintptr_t *gr);\r
+/// Get RGB values of current bitmap\r
+MGL_EXPORT const unsigned char *mgl_get_background(HMGL gr);\r
+MGL_EXPORT const unsigned char *mgl_get_background_(uintptr_t *gr);\r
 /// Set object/subplot id\r
 void MGL_EXPORT mgl_set_obj_id(HMGL gr, int id);\r
 void MGL_EXPORT mgl_set_obj_id_(uintptr_t *gr, int *id);\r
 /// Get object id\r
-int MGL_EXPORT mgl_get_obj_id(HMGL gr, int x, int y);\r
-int MGL_EXPORT mgl_get_obj_id_(uintptr_t *gr, int *x, int *y);\r
+int MGL_EXPORT_PURE mgl_get_obj_id(HMGL gr, int x, int y);\r
+int MGL_EXPORT_PURE mgl_get_obj_id_(uintptr_t *gr, int *x, int *y);\r
 /// Get subplot id\r
 int MGL_EXPORT mgl_get_spl_id(HMGL gr, int x, int y);\r
 int MGL_EXPORT mgl_get_spl_id_(uintptr_t *gr, int *x, int *y);\r
@@ -235,8 +253,8 @@ void MGL_EXPORT mgl_calc_xyz_(uintptr_t *gr, int *xs, int *ys, mreal *x, mreal *
 void MGL_EXPORT mgl_calc_scr(HMGL gr, double x, double y, double z, int *xs, int *ys);\r
 void MGL_EXPORT mgl_calc_scr_(uintptr_t *gr, mreal *x, mreal *y, mreal *z, int *xs, int *ys);\r
 /// Check if {xs,ys} is close to active point with accuracy d, and return its position or -1\r
-long MGL_EXPORT mgl_is_active(HMGL gr, int xs, int ys, int d);\r
-long MGL_EXPORT mgl_is_active_(uintptr_t *gr, int *xs, int *ys, int *d);\r
+long MGL_EXPORT_PURE mgl_is_active(HMGL gr, int xs, int ys, int d);\r
+long MGL_EXPORT_PURE mgl_is_active_(uintptr_t *gr, int *xs, int *ys, int *d);\r
 \r
 /// Create new frame.\r
 int MGL_EXPORT mgl_new_frame(HMGL gr);\r
@@ -262,6 +280,9 @@ void MGL_EXPORT mgl_show_frame_(uintptr_t *gr, int *i);
 /// Delete primitives for i-th frame (work if MGL_VECT_FRAME is set on)\r
 void MGL_EXPORT mgl_del_frame(HMGL gr, int i);\r
 void MGL_EXPORT mgl_del_frame_(uintptr_t *gr, int *i);\r
+/// Clear list of primitives for current drawing\r
+void MGL_EXPORT mgl_clear_frame(HMGL gr);\r
+void MGL_EXPORT mgl_clear_frame_(uintptr_t *gr);\r
 \r
 /// Set the transparency type (0 - usual, 1 - glass, 2 - lamp)\r
 void MGL_EXPORT mgl_set_transp_type(HMGL gr, int kind);\r
@@ -299,12 +320,21 @@ void MGL_EXPORT mgl_mat_push_(uintptr_t *gr);
 /// Clear up the frame\r
 void MGL_EXPORT mgl_clf(HMGL gr);\r
 void MGL_EXPORT mgl_clf_(uintptr_t *gr);\r
+/// Clear up the frame but keep fog settings\r
+void MGL_EXPORT mgl_clf_nfog(HMGL gr);\r
+void MGL_EXPORT mgl_clf_nfog_(uintptr_t *gr);\r
 /// Clear up the frame and fill background by specified color\r
 void MGL_EXPORT mgl_clf_rgb(HMGL gr, double r, double g, double b);\r
 void MGL_EXPORT mgl_clf_rgb_(uintptr_t *gr, mreal *r, mreal *g, mreal *b);\r
 /// Clear up the frame and fill background by specified color\r
 void MGL_EXPORT mgl_clf_chr(HMGL gr, char col);\r
 void MGL_EXPORT mgl_clf_chr_(uintptr_t *gr, const char *col, int);\r
+/// Clear up the frame and fill background by specified color with manual transparency\r
+void MGL_EXPORT mgl_clf_str(HMGL gr, const char *col);\r
+void MGL_EXPORT mgl_clf_str_(uintptr_t *gr, const char *col, int);\r
+/// Load background image\r
+void MGL_EXPORT mgl_load_background(HMGL gr, const char *fname, double alpha);\r
+void MGL_EXPORT mgl_load_background_(uintptr_t *gr, const char *fname, mreal *alpha, int);\r
 \r
 /// Put further plotting in some region of whole frame.\r
 void MGL_EXPORT mgl_subplot(HMGL gr, int nx,int ny,int m,const char *style);\r
@@ -349,7 +379,10 @@ void MGL_EXPORT mgl_rotate_vector(HMGL gr, double Tet,double x,double y,double z
 void MGL_EXPORT mgl_rotate_vector_(uintptr_t *gr, mreal *Tet, mreal *x, mreal *y, mreal *z);\r
 /// Set perspective (in range [0,1)) for plot. Set to zero for switching off.\r
 void MGL_EXPORT mgl_perspective(HMGL gr, double val);\r
-void MGL_EXPORT mgl_perspective_(uintptr_t *gr, double val);\r
+void MGL_EXPORT mgl_perspective_(uintptr_t *gr, mreal *val);\r
+/// Ask to set perspective (in range [0,1)) for plot. Set to zero for switching off.\r
+void MGL_EXPORT mgl_ask_perspective(HMGL gr, double val);\r
+void MGL_EXPORT mgl_ask_perspective_(uintptr_t *gr, mreal *val);\r
 /// Set angle of view independently from Rotate().\r
 void MGL_EXPORT mgl_view(HMGL gr, double TetX,double TetZ,double TetY);\r
 void MGL_EXPORT mgl_view_(uintptr_t *gr, mreal *TetX, mreal *TetZ, mreal *TetY);\r
@@ -358,7 +391,9 @@ void MGL_EXPORT mgl_zoom(HMGL gr, double x1, double y1, double x2, double y2);
 void MGL_EXPORT mgl_zoom_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *x2, mreal *y2);\r
 \r
 //-----------------------------------------------------------------------------\r
+#if MGL_HAVE_PTHREAD\r
 void MGL_EXPORT mgl_draw_thr(void *);\r
+#endif\r
 /// Callback function for mouse click\r
 void MGL_EXPORT mgl_set_click_func(HMGL gr, void (*func)(void *p));\r
 \r
@@ -366,8 +401,8 @@ void MGL_EXPORT mgl_set_click_func(HMGL gr, void (*func)(void *p));
 void MGL_EXPORT mgl_wnd_set_delay(HMGL gr, double dt);\r
 void MGL_EXPORT mgl_wnd_set_delay_(uintptr_t *gr, mreal *dt);\r
 /// Get delay for animation in seconds\r
-double MGL_EXPORT mgl_wnd_get_delay(HMGL gr);\r
-double MGL_EXPORT mgl_wnd_get_delay_(uintptr_t *gr);\r
+double MGL_EXPORT_PURE mgl_wnd_get_delay(HMGL gr);\r
+double MGL_EXPORT_PURE mgl_wnd_get_delay_(uintptr_t *gr);\r
 /// Set window properties\r
 void MGL_EXPORT mgl_setup_window(HMGL gr, int clf_upd, int showpos);\r
 void MGL_EXPORT mgl_setup_window_(uintptr_t *gr, int *clf_upd, int *showpos);\r
@@ -429,9 +464,16 @@ uintptr_t MGL_EXPORT mgl_parser_add_var_(uintptr_t* p, const char *name, int);
 HMDT MGL_EXPORT mgl_parser_add_varw(HMPR p, const wchar_t *name);\r
 /// Find variable with given name or return NULL if no one\r
 /// NOTE !!! You must not delete obtained data arrays !!!\r
-HMDT MGL_EXPORT mgl_parser_find_var(HMPR p, const char *name);\r
-uintptr_t MGL_EXPORT mgl_parser_find_var_(uintptr_t* p, const char *name, int);\r
-HMDT MGL_EXPORT mgl_parser_find_varw(HMPR p, const wchar_t *name);\r
+MGL_EXPORT_PURE mglDataA *mgl_parser_find_var(HMPR p, const char *name);\r
+uintptr_t MGL_EXPORT_PURE mgl_parser_find_var_(uintptr_t* p, const char *name, int);\r
+MGL_EXPORT_PURE mglDataA *mgl_parser_find_varw(HMPR p, const wchar_t *name);\r
+/// Get variable with given id\r
+/// NOTE !!! You must not delete obtained data arrays !!!\r
+MGL_EXPORT_PURE mglDataA *mgl_parser_get_var(HMPR p, unsigned long id);\r
+uintptr_t MGL_EXPORT_PURE mgl_parser_get_var_(uintptr_t* p, unsigned long *id);\r
+/// Get number of variables\r
+long MGL_EXPORT_PURE mgl_parser_num_var(HMPR p);\r
+long MGL_EXPORT_PURE mgl_parser_num_var_(uintptr_t* p);\r
 \r
 /// Delete variable with name\r
 void MGL_EXPORT mgl_parser_del_var(HMPR p, const char *name);\r
@@ -469,16 +511,16 @@ void MGL_EXPORT mgl_parser_stop_(uintptr_t* p);
 ///            3 - setup, 4 - data handle, 5 - data create, 6 - subplot, 7 - program\r
 ///            8 - 1d plot, 9 - 2d plot, 10 - 3d plot, 11 - dd plot, 12 - vector plot\r
 ///            13 - axis, 14 - primitives, 15 - axis setup, 16 - text/legend, 17 - data transform\r
-int MGL_EXPORT mgl_parser_cmd_type(HMPR pr, const char *name);\r
-int MGL_EXPORT mgl_parser_cmd_type_(uintptr_t* p, const char *name, int);\r
+int MGL_EXPORT_PURE mgl_parser_cmd_type(HMPR pr, const char *name);\r
+int MGL_EXPORT_PURE mgl_parser_cmd_type_(uintptr_t* p, const char *name, int);\r
 /// Return description of MGL command\r
-MGL_EXPORT const char *mgl_parser_cmd_desc(HMPR pr, const char *name);\r
+MGL_EXPORT_PURE const char *mgl_parser_cmd_desc(HMPR pr, const char *name);\r
 /// Return string of command format (command name and its argument[s])\r
-MGL_EXPORT const char *mgl_parser_cmd_frmt(HMPR pr, const char *name);\r
+MGL_EXPORT_PURE const char *mgl_parser_cmd_frmt(HMPR pr, const char *name);\r
 /// Get name of command with nmber n\r
-MGL_EXPORT const char *mgl_parser_cmd_name(HMPR pr, long id);\r
+MGL_EXPORT_PURE const char *mgl_parser_cmd_name(HMPR pr, long id);\r
 /// Get number of defined commands\r
-long MGL_EXPORT mgl_parser_cmd_num(HMPR pr);\r
+long MGL_EXPORT_PURE mgl_parser_cmd_num(HMPR pr);\r
 \r
 /// Return result of formula evaluation\r
 HMDT MGL_EXPORT mgl_parser_calc(HMPR pr, const char *formula);\r
index 6000a3532387eb1b41c0dc41ad13ea78a633c532..cadfba5fdf21a1dc0f990c98b0e246c934bbce39 100644 (file)
@@ -33,7 +33,7 @@ public:
        mglCanvasWnd();\r
        virtual ~mglCanvasWnd();\r
 \r
-       void SetSize(int w,int h);\r
+       void SetSize(int w,int h,bool clf=true);\r
        void EndFrame();\r
        void SetFrame(long i);\r
        void DelFrame(long i);\r
@@ -45,7 +45,8 @@ public:
        inline mglPoint GetMousePos() const     {       return LastMousePos;}\r
        inline void SetMousePos(mglPoint p)     {       LastMousePos=p; }\r
        inline void Setup(bool clf_upd=true, bool showpos=false)\r
-       {       set(showpos,MGL_SHOW_POS);      set(clf_upd,MGL_CLF_ON_UPD);    }\r
+       {       set(showpos,MGL_SHOW_POS);      set(clf_upd,MGL_CLF_ON_UPD);\r
+               if(!clf_upd)    ResetFrames();  }\r
 \r
        virtual void ToggleAlpha()=0;   ///< Switch on/off transparency (do not overwrite user settings)\r
        virtual void ToggleLight()=0;   ///< Switch on/off lighting (do not overwrite user settings)\r
index 81aec448b846d1e87a5ac1049a01e5c359b574a7..afa1545277236021c1bd83be5a5b633953883517 100644 (file)
 #include <string>\r
 //-----------------------------------------------------------------------------\r
 /// Class for working with data array\r
-#if MGL_NO_DATA_A\r
-class MGL_EXPORT mglData\r
-#else\r
 class MGL_EXPORT mglData : public mglDataA\r
-#endif\r
 {\r
 public:\r
-\r
+using mglDataA::Momentum;\r
        long nx;                ///< number of points in 1st dimensions ('x' dimension)\r
        long ny;                ///< number of points in 2nd dimensions ('y' dimension)\r
        long nz;                ///< number of points in 3d dimensions ('z' dimension)\r
@@ -44,34 +40,43 @@ public:
        bool link;              ///< use external data (i.e. don't free it)\r
 \r
        /// Initiate by other mglData variable\r
-       inline mglData(const mglData &d)        {       a=0;    mgl_data_set(this,&d);          }       // NOTE: must be constructor for mglData& to exclude copy one\r
-       inline mglData(const mglDataA *d)       {       a=0;    mgl_data_set(this, d);          }\r
-       inline mglData(bool, mglData *d)        // NOTE: Variable d will be deleted!!!\r
+       mglData(const mglData &d)       {       a=0;    mgl_data_set(this,&d);          }       // NOTE: must be constructor for mglData& to exclude copy one\r
+#if MGL_HAVE_RVAL\r
+       mglData(mglData &&d):nx(d.nx),ny(d.ny),nz(d.nz),a(d.a),id(d.id),link(d.link)\r
+       {       s=d.s;  temp=d.temp;    func=d.func;    o=d.o;  d.a=0;  d.func=0;       }\r
+#endif\r
+       mglData(const mglDataA *d)\r
+       {       a=0;    if(d)   mgl_data_set(this, d);  else    mgl_data_create(this,1,1,1);            }\r
+       mglData(bool, mglData *d)       // NOTE: Variable d will be deleted!!!\r
        {       if(d)\r
                {       nx=d->nx;       ny=d->ny;       nz=d->nz;       a=d->a; d->a=0;\r
+                       temp=d->temp;   func=d->func;   o=d->o; s=d->s;\r
                        id=d->id;       link=d->link;   delete d;       }\r
                else    {       a=0;    Create(1);      }       }\r
        /// Initiate by flat array\r
-       inline mglData(int size, const float *d)        {       a=0;    Set(d,size);    }\r
-       inline mglData(int rows, int cols, const float *d)      {       a=0;    Set(d,cols,rows);       }\r
-       inline mglData(int size, const double *d)       {       a=0;    Set(d,size);    }\r
-       inline mglData(int rows, int cols, const double *d)     {       a=0;    Set(d,cols,rows);       }\r
-       inline mglData(const double *d, int size)       {       a=0;    Set(d,size);    }\r
-       inline mglData(const double *d, int rows, int cols)     {       a=0;    Set(d,cols,rows);       }\r
+       mglData(int size, const float *d)       {       a=0;    Set(d,size);    }\r
+       mglData(int rows, int cols, const float *d)     {       a=0;    Set(d,cols,rows);       }\r
+       mglData(int size, const double *d)      {       a=0;    Set(d,size);    }\r
+       mglData(int rows, int cols, const double *d)    {       a=0;    Set(d,cols,rows);       }\r
+       mglData(const double *d, int size)      {       a=0;    Set(d,size);    }\r
+       mglData(const double *d, int rows, int cols)    {       a=0;    Set(d,cols,rows);       }\r
+       mglData(const float *d, int size)       {       a=0;    Set(d,size);    }\r
+       mglData(const float *d, int rows, int cols)     {       a=0;    Set(d,cols,rows);       }\r
        /// Read data from file\r
-       inline mglData(const char *fname)                       {       a=0;    Read(fname);    }\r
+       mglData(const char *fname)                      {       a=0;    Read(fname);    }\r
        /// Allocate the memory for data array and initialize it zero\r
-       inline mglData(long xx=1,long yy=1,long zz=1)   {       a=0;    Create(xx,yy,zz);       }\r
+       mglData(long xx=1,long yy=1,long zz=1)  {       a=0;    Create(xx,yy,zz);       }\r
        /// Delete the array\r
        virtual ~mglData()      {       if(!link && a)  delete []a;     }\r
-       inline mreal GetVal(long i, long j=0, long k=0)\r
+\r
+       inline mreal GetVal(long i, long j=0, long k=0) const\r
        {       return mgl_data_get_value(this,i,j,k);}\r
        inline void SetVal(mreal f, long i, long j=0, long k=0)\r
        {       mgl_data_set_value(this,f,i,j,k);       }\r
        /// Get sizes\r
-       inline long GetNx() const       {       return nx;      }\r
-       inline long GetNy() const       {       return ny;      }\r
-       inline long GetNz() const       {       return nz;      }\r
+       long GetNx() const      {       return nx;      }\r
+       long GetNy() const      {       return ny;      }\r
+       long GetNz() const      {       return nz;      }\r
 \r
        /// Link external data array (don't delete it at exit)\r
        inline void Link(mreal *A, long NX, long NY=1, long NZ=1)\r
@@ -158,15 +163,18 @@ public:
        inline void Modify(const char *eq,const mglDataA &vdat)\r
        {       mgl_data_modify_vw(this,eq,&vdat,0);    }\r
        /// Modify the data by specified formula assuming x,y,z in range [r1,r2]\r
-       inline void Fill(mglBase *gr, const char *eq, const char *opt="")\r
+       inline void Fill(HMGL gr, const char *eq, const char *opt="")\r
        {       mgl_data_fill_eq(gr,this,eq,0,0,opt);   }\r
-       inline void Fill(mglBase *gr, const char *eq, const mglDataA &vdat, const char *opt="")\r
+       inline void Fill(HMGL gr, const char *eq, const mglDataA &vdat, const char *opt="")\r
        {       mgl_data_fill_eq(gr,this,eq,&vdat,0,opt);       }\r
-       inline void Fill(mglBase *gr, const char *eq, const mglDataA &vdat, const mglDataA &wdat,const char *opt="")\r
+       inline void Fill(HMGL gr, const char *eq, const mglDataA &vdat, const mglDataA &wdat,const char *opt="")\r
        {       mgl_data_fill_eq(gr,this,eq,&vdat,&wdat,opt);   }\r
        /// Equidistantly fill the data to range [x1,x2] in direction dir\r
        inline void Fill(mreal x1,mreal x2=NaN,char dir='x')\r
-       {       return mgl_data_fill(this,x1,x2,dir);   }\r
+       {       mgl_data_fill(this,x1,x2,dir);  }\r
+       /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [p1,p2] using global spline\r
+       inline void RefillGS(const mglDataA &xdat, const mglDataA &vdat, mreal x1, mreal x2,long sl=-1)\r
+       {       mgl_data_refill_gs(this,&xdat,&vdat,x1,x2,sl);  }\r
        /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [p1,p2]\r
        inline void Refill(const mglDataA &xdat, const mglDataA &vdat, mreal x1, mreal x2,long sl=-1)\r
        {       mgl_data_refill_x(this,&xdat,&vdat,x1,x2,sl);   }\r
@@ -177,14 +185,14 @@ public:
        inline void Refill(const mglDataA &xdat, const mglDataA &ydat, const mglDataA &zdat, const mglDataA &vdat, mglPoint p1, mglPoint p2)\r
        {       mgl_data_refill_xyz(this,&xdat,&ydat,&zdat,&vdat,p1.x,p2.x,p1.y,p2.y,p1.z,p2.z);        }\r
        /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range of gr\r
-       inline void Refill(mglBase *gr, const mglDataA &xdat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
+       inline void Refill(HMGL gr, const mglDataA &xdat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
        {       mgl_data_refill_gr(gr,this,&xdat,0,0,&vdat,sl,opt);     }\r
-       inline void Refill(mglBase *gr, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
+       inline void Refill(HMGL gr, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
        {       mgl_data_refill_gr(gr,this,&xdat,&ydat,0,&vdat,sl,opt); }\r
-       inline void Refill(mglBase *gr, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &zdat, const mglDataA &vdat, const char *opt="")\r
+       inline void Refill(HMGL gr, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &zdat, const mglDataA &vdat, const char *opt="")\r
        {       mgl_data_refill_gr(gr,this,&xdat,&ydat,&zdat,&vdat,-1,opt);     }\r
        /// Set the data by triangulated surface values assuming x,y,z in axis range of gr\r
-       inline void Grid(mglBase *gr, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *opt="")\r
+       inline void Grid(HMGL gr, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *opt="")\r
        {       mgl_data_grid(gr,this,&x,&y,&z,opt);    }\r
        /// Set the data by triangulated surface values assuming x,y,z in range [p1, p2]\r
        inline void Grid(const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, mglPoint p1, mglPoint p2)\r
@@ -207,12 +215,6 @@ public:
        /// Read data from text file with specifeid size\r
        inline bool Read(const char *fname,long mx,long my=1,long mz=1)\r
        {       return mgl_data_read_dim(this,fname,mx,my,mz);  }\r
-       /// Save whole data array (for ns=-1) or only ns-th slice to text file\r
-       inline void Save(const char *fname,long ns=-1) const\r
-       {       mgl_data_save(this,fname,ns);   }\r
-       /// Export data array (for ns=-1) or only ns-th slice to PNG file according color scheme\r
-       inline void Export(const char *fname,const char *scheme,mreal v1=0,mreal v2=0,long ns=-1) const\r
-       {       mgl_data_export(this,fname,scheme,v1,v2,ns);    }\r
        /// Import data array from PNG file according color scheme\r
        inline void Import(const char *fname,const char *scheme,mreal v1=0,mreal v2=1)\r
        {       mgl_data_import(this,fname,scheme,v1,v2);       }\r
@@ -228,12 +230,6 @@ public:
        /// Read data array from HDF file (parse HDF4 and HDF5 files)\r
        inline int ReadHDF(const char *fname,const char *data)\r
        {       return mgl_data_read_hdf(this,fname,data);      }\r
-       /// Save data to HDF file\r
-       inline void SaveHDF(const char *fname,const char *data,bool rewrite=false) const\r
-       {       mgl_data_save_hdf(this,fname,data,rewrite);     }\r
-       /// Put HDF data names into buf as '\t' separated.\r
-       inline static int DatasHDF(const char *fname, char *buf, long size)\r
-       {       return mgl_datas_hdf(fname,buf,size);   }\r
 \r
        /// Get column (or slice) of the data filled by formulas of named columns\r
        inline mglData Column(const char *eq) const\r
@@ -246,6 +242,10 @@ public:
        {       return mglData(true,mgl_data_subdata(this,xx,yy,zz));   }\r
        inline mglData SubData(const mglDataA &xx, const mglDataA &yy, const mglDataA &zz) const\r
        {       return mglData(true,mgl_data_subdata_ext(this,&xx,&yy,&zz));    }\r
+       inline mglData SubData(const mglDataA &xx, const mglDataA &yy) const\r
+       {       return mglData(true,mgl_data_subdata_ext(this,&xx,&yy,0));      }\r
+       inline mglData SubData(const mglDataA &xx) const\r
+       {       return mglData(true,mgl_data_subdata_ext(this,&xx,0,0));        }\r
        /// Get trace of the data array\r
        inline mglData Trace() const\r
        {       return mglData(true,mgl_data_trace(this));      }\r
@@ -337,6 +337,15 @@ public:
        inline void FillSample(const char *how)\r
        {       mgl_data_fill_sample(this,how); }\r
 \r
+       /// Return an approximated x-value (root) when dat(x) = val\r
+       inline mreal Solve(mreal val, bool use_spline=true, long i0=0) const\r
+       {       return mgl_data_solve_1d(this, val, use_spline, i0);            }\r
+       /// Return an approximated value (root) when dat(x) = val\r
+       inline mglData Solve(mreal val, char dir, bool norm=true) const\r
+       {       return mglData(true,mgl_data_solve(this, val, dir, 0, norm));   }\r
+       inline mglData Solve(mreal val, char dir, const mglData &i0, bool norm=true) const\r
+       {       return mglData(true,mgl_data_solve(this, val, dir, &i0, norm)); }\r
+\r
        /// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
        inline mreal Spline(mreal x,mreal y=0,mreal z=0) const\r
        {       return mgl_data_spline(this, x,y,z);    }\r
@@ -349,14 +358,6 @@ public:
        /// Interpolate by line the data to given point x,\a y,\a z which normalized in range [0, 1]\r
        inline mreal Linear1(mreal x,mreal y=0,mreal z=0) const\r
        {       return mgl_data_linear(this,x*(nx-1),y*(ny-1),z*(nz-1));        }\r
-       /// Return an approximated x-value (root) when dat(x) = val\r
-       inline mreal Solve(mreal val, bool use_spline=true, long i0=0) const\r
-       {       return mgl_data_solve_1d(this, val, use_spline, i0);            }\r
-       /// Return an approximated value (root) when dat(x) = val\r
-       inline mglData Solve(mreal val, char dir, bool norm=true) const\r
-       {       return mglData(true,mgl_data_solve(this, val, dir, 0, norm));   }\r
-       inline mglData Solve(mreal val, char dir, const mglData &i0, bool norm=true) const\r
-       {       return mglData(true,mgl_data_solve(this, val, dir, &i0, norm)); }\r
 \r
        /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
        inline mreal Spline(mglPoint &dif, mreal x,mreal y=0,mreal z=0) const\r
@@ -373,55 +374,13 @@ public:
        {       mreal res=mgl_data_linear_ext(this,x*(nx-1),y*(ny-1),z*(nz-1), &(dif.x),&(dif.y), &(dif.z));\r
                dif.x*=nx>1?nx-1:1;     dif.y*=ny>1?ny-1:1;     dif.z*=nz>1?nz-1:1;     return res;     }\r
 \r
-       /// Get information about the data (sizes and momentum) to string\r
-       inline const char *PrintInfo() const    {       return mgl_data_info(this);     }\r
-       /// Print information about the data (sizes and momentum) to FILE (for example, stdout)\r
-       inline void PrintInfo(FILE *fp) const\r
-       {       if(fp)  {       fprintf(fp,"%s",mgl_data_info(this));   fflush(fp);     }       }\r
-       /// Get maximal value of the data\r
-       inline mreal Maximal() const    {       return mgl_data_max(this);      }\r
-       /// Get minimal value of the data\r
-       inline mreal Minimal() const    {       return mgl_data_min(this);      }\r
-       /// Get maximal value of the data which is less than 0\r
-       inline mreal MaximalNeg() const {       return mgl_data_neg_max(this);  }\r
-       /// Get minimal value of the data which is larger than 0\r
-       inline mreal MinimalPos() const {       return mgl_data_pos_min(this);  }\r
-       /// Get maximal value of the data and its position\r
-       inline mreal Maximal(long &i,long &j,long &k) const\r
-       {       return mgl_data_max_int(this,&i,&j,&k); }\r
-       /// Get minimal value of the data and its position\r
-       inline mreal Minimal(long &i,long &j,long &k) const\r
-       {       return mgl_data_min_int(this,&i,&j,&k); }\r
-       /// Get maximal value of the data and its approximated position\r
-       inline mreal Maximal(mreal &x,mreal &y,mreal &z) const\r
-       {       return mgl_data_max_real(this,&x,&y,&z);        }\r
-       /// Get minimal value of the data and its approximated position\r
-       inline mreal Minimal(mreal &x,mreal &y,mreal &z) const\r
-       {       return mgl_data_min_real(this,&x,&y,&z);        }\r
-       /// Get "energy" and find first (median) and second (width) momenta of data\r
-       inline mreal Momentum(char dir,mreal &m,mreal &w) const\r
-       {       return mgl_data_momentum_val(this,dir,&m,&w,0,0);       }\r
-       /// Get "energy and find 4 momenta of data: median, width, skewness, kurtosis\r
-       inline mreal Momentum(char dir,mreal &m,mreal &w,mreal &s,mreal &k) const\r
-       {       return mgl_data_momentum_val(this,dir,&m,&w,&s,&k);     }\r
-       /// Find position (after specified in i,j,k) of first nonzero value of formula\r
-       inline mreal Find(const char *cond, long &i, long &j, long &k) const\r
-       {       return mgl_data_first(this,cond,&i,&j,&k);      }\r
-       /// Find position (before specified in i,j,k) of last nonzero value of formula\r
-       inline mreal Last(const char *cond, long &i, long &j, long &k) const\r
-       {       return mgl_data_last(this,cond,&i,&j,&k);       }\r
-       /// Find position of first in direction 'dir' nonzero value of formula\r
-       inline long Find(const char *cond, char dir, long i=0, long j=0, long k=0) const\r
-       {       return mgl_data_find(this,cond,dir,i,j,k);      }\r
-       /// Find if any nonzero value of formula\r
-       inline bool FindAny(const char *cond) const\r
-       {       return mgl_data_find_any(this,cond);    }\r
-\r
        /// Copy data from other mglData variable\r
-       inline mglData &operator=(const mglData &d)\r
-       {       if(this!=&d)    Set(d.a,d.nx,d.ny,d.nz);        return *this;   }\r
+       inline const mglDataA &operator=(const mglDataA &d)\r
+       {       if(this!=&d)    mgl_data_set(this,&d);  return d;       }\r
+       inline const mglData &operator=(const mglData &d)\r
+       {       if(this!=&d)    mgl_data_set(this,&d);  return d;       }\r
        inline mreal operator=(mreal val)\r
-       {       for(long i=0;i<nx*ny*nz;i++)    a[i]=val;       return val;     }\r
+       {       mgl_data_fill(this,val,val,'x');        return val;     }\r
        /// Multiply the data by other one for each element\r
        inline void operator*=(const mglDataA &d)       {       mgl_data_mul_dat(this,&d);      }\r
        /// Divide the data by other one for each element\r
@@ -443,26 +402,27 @@ public:
        inline mreal &operator[](long i)        {       return a[i];    }\r
        // NOTE see 13.10 for operator(), operator[] -- m.b. I should add it ???\r
 #endif\r
-#if MGL_NO_DATA_A\r
-       inline long GetNN() const {     return nx*ny*nz;        }\r
-#endif\r
-       /// Get the value in given cell of the data without border checking\r
-       inline mreal v(long i,long j=0,long k=0) const\r
+\r
 #ifndef DEBUG\r
-       {       return a[i+nx*(j+ny*k)];        }\r
+       /// Get the value in given cell of the data\r
+       mreal v(long i,long j=0,long k=0) const {       return a[i+nx*(j+ny*k)];        }\r
+       /// Set the value in given cell of the data\r
+       void set_v(mreal val, long i,long j=0,long k=0) {       a[i+nx*(j+ny*k)]=val;   }\r
 #else\r
-       {       if(i<0 || j<0 || k<0 || i>=nx || j>=ny || k>=nz)        printf("Wrong index in mglData");\r
-               return a[i+nx*(j+ny*k)];        }\r
+       /// Get the value in given cell of the data with border checking\r
+       mreal v(long i,long j=0,long k=0) const {       return mgl_data_get_value(this,i,j,k);  }\r
+       /// Set the value in given cell of the data\r
+       void set_v(mreal val, long i,long j=0,long k=0) {       mgl_data_set_value(this,val,i,j,k);     }\r
 #endif\r
-       inline mreal vthr(long i) const {       return a[i];    }\r
+       mreal vthr(long i) const {      return a[i];    }\r
        // add for speeding up !!!\r
-       inline mreal dvx(long i,long j=0,long k=0) const\r
+       mreal dvx(long i,long j=0,long k=0) const\r
        {   register long i0=i+nx*(j+ny*k);\r
                return i>0? (i<nx-1? (a[i0+1]-a[i0-1])/2:a[i0]-a[i0-1]) : a[i0+1]-a[i0];        }\r
-       inline mreal dvy(long i,long j=0,long k=0) const\r
+       mreal dvy(long i,long j=0,long k=0) const\r
        {   register long i0=i+nx*(j+ny*k);\r
                return j>0? (j<ny-1? (a[i0+nx]-a[i0-nx])/2:a[i0]-a[i0-nx]) : a[i0+nx]-a[i0];}\r
-       inline mreal dvz(long i,long j=0,long k=0) const\r
+       mreal dvz(long i,long j=0,long k=0) const\r
        {   register long i0=i+nx*(j+ny*k), n=nx*ny;\r
                return k>0? (k<nz-1? (a[i0+n]-a[i0-n])/2:a[i0]-a[i0-n]) : a[i0+n]-a[i0];        }\r
 };\r
@@ -491,17 +451,16 @@ inline mglData operator/(const mglDataA &b, const mglDataA &d)
 inline mglData operator/(const mglDataA &d, mreal b)\r
 {      mglData a(&d);  a/=b;   return a;       }\r
 inline bool operator==(const mglData &b, const mglData &d)\r
-{      if(b.nx!=d.nx || b.ny!=d.ny || b.ny!=d.ny)      return false;\r
+{      if(b.nx!=d.nx || b.ny!=d.ny || b.nz!=d.nz)      return false;\r
        return !memcmp(b.a,d.a,b.nx*b.ny*b.nz*sizeof(mreal));   }\r
 inline bool operator<(const mglDataA &b, const mglDataA &d)\r
 {      return b.Maximal()<d.Maximal(); }\r
 inline bool operator>(const mglDataA &b, const mglDataA &d)\r
 {      return b.Minimal()>d.Minimal(); }\r
-#endif\r
 //-----------------------------------------------------------------------------\r
-#ifndef SWIG\r
-mreal mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
-mreal mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx=0, mreal *dy=0, mreal *dz=0);\r
+mreal MGL_EXPORT_PURE mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
+mreal MGL_EXPORT_PURE mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx=0, mreal *dy=0, mreal *dz=0);\r
+mreal MGL_EXPORT_PURE mglSpline3s(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
 #endif\r
 //-----------------------------------------------------------------------------\r
 /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for amplitude and phase\r
@@ -518,7 +477,7 @@ inline mglData mglSTFA(const mglDataA &re, const mglDataA &im, long dn, char dir
 {      return mglData(true, mgl_data_stfa(&re,&im,dn,dir));    }\r
 //-----------------------------------------------------------------------------\r
 /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini\r
-inline mglData mglPDE(mglBase *gr, const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, mreal dz=0.1, mreal k0=100,const char *opt="")\r
+inline mglData mglPDE(HMGL gr, const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, mreal dz=0.1, mreal k0=100,const char *opt="")\r
 {      return mglData(true, mgl_pde_solve(gr,ham, &ini_re, &ini_im, dz, k0,opt));      }\r
 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)\r
 inline mglData mglQO2d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100)\r
@@ -533,6 +492,9 @@ inline mglData mglQO3d(const char *ham, const mglDataA &ini_re, const mglDataA &
 /// Finds ray with starting point r0, p0 (and prepares ray data for mglQO2d)\r
 inline mglData mglRay(const char *ham, mglPoint r0, mglPoint p0, mreal dt=0.1, mreal tmax=10)\r
 {      return mglData(true, mgl_ray_trace(ham, r0.x, r0.y, r0.z, p0.x, p0.y, p0.z, dt, tmax)); }\r
+/// Saves result of ODE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini\r
+inline mglData mglODE(const char *df, const char *var, const mglDataA &ini, mreal dt=0.1, mreal tmax=10)\r
+{      return mglData(true, mgl_ode_solve_str(df,var, &ini, dt, tmax));        }\r
 /// Calculate Jacobian determinant for D{x(u,v), y(u,v)} = dx/du*dy/dv-dx/dv*dy/du\r
 inline mglData mglJacobian(const mglDataA &x, const mglDataA &y)\r
 {      return mglData(true, mgl_jacobian_2d(&x, &y));  }\r
@@ -545,12 +507,34 @@ inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y, const mglD
 inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y)\r
 {      return mglData(true,mgl_triangulation_2d(&x,&y));       }\r
 //-----------------------------------------------------------------------------\r
-/// Wrapper class expression evaluating\r
+/// Get sub-array of the data with given fixed indexes\r
+inline mglData mglSubData(const mglDataA &dat, long xx, long yy=-1, long zz=-1)\r
+{      return mglData(true,mgl_data_subdata(&dat,xx,yy,zz));   }\r
+inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy, const mglDataA &zz)\r
+{      return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,&zz));    }\r
+inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy)\r
+{      return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,0));      }\r
+inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx)\r
+{      return mglData(true,mgl_data_subdata_ext(&dat,&xx,0,0));        }\r
+//-----------------------------------------------------------------------------\r
+/// Prepare coefficients for global spline interpolation\r
+inline mglData mglGSplineInit(const mglDataA &xdat, const mglDataA &ydat)\r
+{      return mglData(true,mgl_gspline_init(&xdat, &ydat));    }\r
+/// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef\r
+inline mreal mglGSpline(const mglDataA &coef, mreal dx, mreal *d1=0, mreal *d2=0)\r
+{      return mgl_gspline(&coef, dx, d1,d2);   }\r
+//-----------------------------------------------------------------------------\r
+/// Wrapper class for expression evaluating\r
 class MGL_EXPORT mglExpr\r
 {\r
        HMEX ex;\r
+       mglExpr(const mglExpr &){}      // copying is not allowed\r
+       const mglExpr &operator=(const mglExpr &t){return t;}   // copying is not allowed\r
 public:\r
        mglExpr(const char *expr)               {       ex = mgl_create_expr(expr);     }\r
+#if MGL_HAVE_RVAL\r
+       mglExpr(mglExpr &&d):ex(d.ex)   {       d.ex=0; }\r
+#endif\r
        ~mglExpr()      {       mgl_delete_expr(ex);    }\r
        /// Return value of expression for given x,y,z variables\r
        inline double Eval(double x, double y=0, double z=0)\r
@@ -568,57 +552,324 @@ public:
 #endif\r
 };\r
 //-----------------------------------------------------------------------------\r
-#ifndef SWIG\r
-/// Structure for handling named mglData (used by mglParse class).\r
-class MGL_EXPORT mglVar : public mglData\r
+/// Class which present variable as data array\r
+class MGL_EXPORT mglDataV : public mglDataA\r
 {\r
+       long nx;        ///< number of points in 1st dimensions ('x' dimension)\r
+       long ny;        ///< number of points in 2nd dimensions ('y' dimension)\r
+       long nz;        ///< number of points in 3d dimensions ('z' dimension)\r
+       mreal di, dj, dk, a0;\r
 public:\r
-       std::wstring s; ///< Data name\r
-       void *o;                ///< Pointer to external object\r
-       mglVar *next;   ///< Pointer to next instance in list\r
-       mglVar *prev;   ///< Pointer to previous instance in list\r
-       bool temp;              ///< This is temporary variable\r
-       void (*func)(void *);   ///< Callback function for destroying\r
-\r
-       mglVar(std::wstring name=L""):mglData()\r
-       {       o=0;    next=prev=0;    func=0; temp=false;     s=name; }\r
-       mglVar(mglVar **head, std::wstring name=L""):mglData()\r
-       {       o=0;    next=*head;     prev=0; *head=this;     func=0; temp=false;     s=name; }\r
-       mglVar(mglVar **head, const mglData &dat, std::wstring name):mglData(dat)\r
-       {       o=0;    next=*head;     prev=0; *head=this;     func=0; temp=false;     s=name; }\r
-       mglVar(mglVar **head, HCDT dat, std::wstring name):mglData(dat)\r
-       {       o=0;    next=*head;     prev=0; *head=this;     func=0; temp=false;     s=name; }\r
-       mglVar(mglVar *v, std::wstring name, bool link=true):mglData()  // NOTE: use carefully due to Link()!\r
-       {       if(!v)  throw mglWarnZero;\r
-               if(link)        Link(*v);       else    Set(*v);\r
-               o=0;    temp=false;     s=name; func = v->func;\r
-               prev = v;       next = v->next; v->next = this;\r
-               if(next)        next->prev = this;      }\r
-       virtual ~mglVar()\r
+       mglDataV(long xx=1,long yy=1,long zz=1,mreal x1=0,mreal x2=NaN,char dir='x'):nx(xx),ny(yy),nz(zz)\r
+       {       Fill(x1,x2,dir);        }\r
+       mglDataV(const mglDataV &d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk),a0(d.a0)      {}\r
+#if MGL_HAVE_RVAL\r
+       mglDataV(mglDataV &&d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk),a0(d.a0)\r
+       {       s=d.s;  temp=d.temp;    func=d.func;    o=d.o;  d.func=0;       }\r
+#endif\r
+       virtual ~mglDataV()     {}\r
+\r
+       /// Get sizes\r
+       long GetNx() const      {       return nx;      }\r
+       long GetNy() const      {       return ny;      }\r
+       long GetNz() const      {       return nz;      }\r
+\r
+       /// Create or recreate the array with specified size and fill it by zero\r
+       inline void Create(long mx,long my=1,long mz=1)\r
+       {       di=mx>1?di*(nx-1)/(mx-1):0;     dj=my>1?dj*(ny-1)/(my-1):0;\r
+               dk=mz>1?dk*(nz-1)/(mz-1):0;     nx=mx;  ny=my;  nz=mz;  }\r
+       /// For going throw all elements\r
+       inline void All()       {       di=dj=dk=1;     a0=0;   }\r
+       /// Equidistantly fill the data to range [x1,x2] in direction dir\r
+       inline void Fill(mreal x1,mreal x2=NaN,char dir='x')\r
        {\r
-               if(func)        func(o);\r
-               if(prev)        prev->next = next;\r
-               if(next)        next->prev = prev;\r
+               di=dj=dk=0;     a0=x1;\r
+               if(mgl_isnum(x2))\r
+               {\r
+                       if(dir=='x' && nx>1)    di=(x2-x1)/(nx-1);\r
+                       if(dir=='y' && ny>1)    dj=(x2-x1)/(ny-1);\r
+                       if(dir=='z' && nz>1)    dk=(x2-x1)/(nz-1);\r
+               }\r
        }\r
-       /// Make copy which link on the same data but have different name. NOTE: use carefully due to Link()!\r
-       inline void Duplicate(std::wstring name)\r
-       {       mglVar *v=new mglVar(name);     v->Link(*this); v->MoveAfter(this);     }\r
-       /// Move variable after var and copy func from var (if func is 0)\r
-       inline void MoveAfter(mglVar *var)\r
+       mreal Maximal() const\r
+       {       return a0+mgl_max(mgl_max(di*(nx-1),dj*(ny-1)),mgl_max(dk*(nz-1),0));   }\r
+       mreal Minimal() const\r
+       {       return a0+mgl_min(mgl_min(di*(nx-1),dj*(ny-1)),mgl_min(dk*(nz-1),0));   }\r
+\r
+       /// Copy data from other mglDataV variable\r
+       inline const mglDataV &operator=(const mglDataV &d)\r
+       {       nx=d.nx;        ny=d.ny;        nz=d.nz;        a0=d.a0;\r
+               di=d.di;        dj=d.dj;        dk=d.dk;        return d;       }\r
+       inline mreal operator=(mreal val)\r
+       {       di=dj=dk=0;     a0=val; return val;     }\r
+       /// Get the value in given cell of the data without border checking\r
+       mreal value(mreal x,mreal y,mreal z,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
+       {       if(dx)  *dx=di; if(dy)  *dy=dj; if(dz)  *dz=dk;\r
+               return a0+di*x+dj*y+dk*z;       }\r
+       mreal v(long i,long j=0,long k=0) const\r
+       {       return a0+di*i+dj*j+dk*k;       }\r
+       mreal vthr(long ii) const\r
+       {       register long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny);\r
+               return a0+di*i+dj*j+dk*k;       }\r
+       // add for speeding up !!!\r
+       mreal dvx(long ,long =0,long =0) const  {       return di;      }\r
+       mreal dvy(long ,long =0,long =0) const  {       return dj;      }\r
+       mreal dvz(long ,long =0,long =0) const  {       return dk;      }\r
+};\r
+//-----------------------------------------------------------------------------\r
+/// Class which present FFT frequency as data array\r
+class MGL_EXPORT mglDataW : public mglDataA\r
+{\r
+       long nx;        ///< number of points in 1st dimensions ('x' dimension)\r
+       long ny;        ///< number of points in 2nd dimensions ('y' dimension)\r
+       long nz;        ///< number of points in 3d dimensions ('z' dimension)\r
+       mreal di, dj, dk;\r
+public:\r
+\r
+       mglDataW(long xx=1,long yy=1,long zz=1,mreal dp=0,char dir='x'):nx(xx),ny(yy),nz(zz)\r
+       {       Freq(dp,dir);   }\r
+       mglDataW(const mglDataW &d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk)       {}\r
+#if MGL_HAVE_RVAL\r
+       mglDataW(mglDataW &&d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk)\r
+       {       s=d.s;  temp=d.temp;    func=d.func;    o=d.o;  d.func=0;       }\r
+#endif\r
+       virtual ~mglDataW()     {}\r
+\r
+       /// Get sizes\r
+       long GetNx() const      {       return nx;      }\r
+       long GetNy() const      {       return ny;      }\r
+       long GetNz() const      {       return nz;      }\r
+\r
+       /// Create or recreate the array with specified size and fill it by zero\r
+       inline void Create(long mx,long my=1,long mz=1)\r
+       {       nx=mx;  ny=my;  nz=mz;  }\r
+       /// For going throw all elements\r
+       inline void All()       {       di=dj=dk=1;     }\r
+       /// Equidistantly fill the data to range [x1,x2] in direction dir\r
+       inline void Freq(mreal dp,char dir='x')\r
+       {\r
+               di=dj=dk=0;\r
+               if(dir=='x')    di=dp;\r
+               if(dir=='y')    dj=dp;\r
+               if(dir=='z')    dk=dp;\r
+       }\r
+       mreal Maximal() const\r
+       {       return mgl_max(mgl_max(di*(nx-1),dj*(ny-1)),mgl_max(dk*(nz-1),0));      }\r
+       mreal Minimal() const\r
+       {       return mgl_min(mgl_min(di*(nx-1),dj*(ny-1)),mgl_min(dk*(nz-1),0));      }\r
+\r
+       /// Copy data from other mglDataV variable\r
+       inline const mglDataW &operator=(const mglDataW &d)\r
+       {       nx=d.nx;        ny=d.ny;        nz=d.nz;        di=d.di;        dj=d.dj;        dk=d.dk;        return d;       }\r
+       /// Get the value in given cell of the data without border checking\r
+       mreal value(mreal x,mreal y,mreal z,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
+       {       if(dx)  *dx=di; if(dy)  *dy=dj; if(dz)  *dz=dk;\r
+               return di*(x<nx/2?x:nx-x)+dj*(y<ny/2?y:ny-y)+dk*(z<nz/2?z:nz-z);        }\r
+       mreal v(long i,long j=0,long k=0) const\r
+       {       return di*(i<nx/2?i:nx-i)+dj*(j<ny/2?j:ny-j)+dk*(k<nz/2?k:nz-k);        }\r
+       mreal vthr(long ii) const\r
+       {       register long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny);\r
+               return di*(i<nx/2?i:nx-i)+dj*(j<ny/2?j:ny-j)+dk*(k<nz/2?k:nz-k);        }\r
+       // add for speeding up !!!\r
+       mreal dvx(long ,long =0,long =0) const  {       return di;      }\r
+       mreal dvy(long ,long =0,long =0) const  {       return dj;      }\r
+       mreal dvz(long ,long =0,long =0) const  {       return dk;      }\r
+};\r
+//-----------------------------------------------------------------------------\r
+/// Class which present variable as data array\r
+class MGL_EXPORT mglDataF : public mglDataA\r
+{\r
+       long nx;        ///< number of points in 1st dimensions ('x' dimension)\r
+       long ny;        ///< number of points in 2nd dimensions ('y' dimension)\r
+       long nz;        ///< number of points in 3d dimensions ('z' dimension)\r
+       std::string str;        ///< function as string\r
+       mglPoint v1, v2;        ///< ranges for coordinates\r
+       HMEX ex;                        ///< parsed variant\r
+       mreal dx,dy,dz;\r
+       inline void setD()\r
+       {\r
+               dx = nx>1?(v2.x-v1.x)/(nx-1):0;\r
+               dy = ny>1?(v2.y-v1.y)/(ny-1):0;\r
+               dz = nz>1?(v2.z-v1.z)/(nz-1):0;\r
+       }\r
+       mreal (*dfunc)(mreal i, mreal j, mreal k, void *par);\r
+       void *par;\r
+public:\r
+\r
+       mglDataF(long xx=1,long yy=1,long zz=1):nx(xx),ny(yy),nz(zz), dfunc(0),par(0)\r
+       {       ex=0;   v2=mglPoint(1,1,1);     setD(); }\r
+       mglDataF(const mglDataF &d) : nx(d.nx), ny(d.ny), nz(d.nz), str(d.str), v1(d.v1), v2(d.v2), dx(d.dx),dy(d.dy),dz(d.dz), dfunc(d.dfunc),par(d.par)\r
+       {       ex = mgl_create_expr(str.c_str());      }\r
+#if MGL_HAVE_RVAL\r
+       mglDataF(mglDataF &&d):nx(d.nx),ny(d.ny),nz(d.nz), str(d.str), v1(d.v1),v2(d.v2), ex(d.ex), dx(d.dx),dy(d.dy),dz(d.dz), dfunc(d.dfunc),par(d.par)\r
+       {       s=d.s;  temp=d.temp;    func=d.func;    o=d.o;  d.ex=0; d.func=0;       }\r
+#endif\r
+       virtual ~mglDataF()     {       mgl_delete_expr(ex);    }\r
+\r
+       /// Get sizes\r
+       long GetNx() const      {       return nx;      }\r
+       long GetNy() const      {       return ny;      }\r
+       long GetNz() const      {       return nz;      }\r
+\r
+       /// Create or recreate the array with specified size and fill it by zero\r
+       inline void Create(long mx,long my=1,long mz=1) {       nx=mx;  ny=my;  nz=mz;  setD(); }\r
+       inline void SetRanges(mglPoint p1, mglPoint p2) {       v1=p1;  v2=p2;  setD(); }\r
+       /// Set formula to be used as dfunction\r
+       inline void SetFormula(const char *eq)\r
+       {\r
+               mgl_delete_expr(ex);    dfunc=0;        par=0;\r
+               if(eq && *eq)   {       ex = mgl_create_expr(eq);       str=eq; }\r
+               else    {       ex=0;   str=""; }\r
+       }\r
+       /// Set dfunction and coordinates range [r1,r2]\r
+       inline void SetFunc(mreal (*f)(mreal,mreal,mreal,void*), void *p=NULL)\r
+       {       mgl_delete_expr(ex);    ex=0;   dfunc=f;        par=p;  }\r
+\r
+       mreal value(mreal i,mreal j=0,mreal k=0, mreal *di=0,mreal *dj=0,mreal *dk=0) const\r
        {\r
-               if(prev)        prev->next = next;\r
-               if(next)        next->prev = prev;\r
-               prev = next = 0;\r
-               if(var)\r
+               mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
+               if(di)  *di = 0;        if(dj)  *dj = 0;        if(dk)  *dk = 0;\r
+               if(dfunc)\r
                {\r
-                       prev = var;     next = var->next;\r
-                       var->next = this;\r
-                       if(func==0)     func = var->func;\r
+                       res = dfunc(x,y,z, par);\r
+                       if(di)  *di = dfunc(x+dx,y,z, par)-res;\r
+                       if(dj)  *dj = dfunc(x,y+dy,z, par)-res;\r
+                       if(dk)  *dk = dfunc(x,y,z+dz, par)-res;\r
                }\r
-               if(next)        next->prev = this;\r
+               else if(ex)\r
+               {\r
+                       if(di)  *di = mgl_expr_diff(ex,'x',x,y,z)*dx;\r
+                       if(dj)  *dj = mgl_expr_diff(ex,'y',x,y,z)*dy;\r
+                       if(dk)  *dk = mgl_expr_diff(ex,'z',x,y,z)*dz;\r
+                       res = mgl_expr_eval(ex,x,y,z);\r
+               }\r
+               return res;\r
+       }\r
+       /// Copy data from other mglDataV variable\r
+       inline const mglDataF &operator=(const mglDataF &d)\r
+       {       nx=d.nx;        ny=d.ny;        nz=d.nz;        v1=d.v1;        v2=d.v2;        setD();\r
+               str=d.str;      ex = mgl_create_expr(str.c_str());      dfunc=d.dfunc;  par=d.par;      return d;       }\r
+       /// Get the value in given cell of the data without border checking\r
+       mreal v(long i,long j=0,long k=0) const\r
+       {\r
+               mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
+               if(dfunc)       res = dfunc(x,y,z, par);\r
+               else if(ex)     res = mgl_expr_eval(ex,x,y,z);\r
+               return res;\r
+       }\r
+       mreal vthr(long i) const\r
+       {\r
+               mreal res=0, x=v1.x+dx*(i%nx), y=v1.y+dy*((i/nx)%ny), z=v1.z+dz*(i/(nx*ny));\r
+               if(dfunc)       res = dfunc(x,y,z, par);\r
+               else if(ex)     res = mgl_expr_eval(ex,x,y,z);\r
+               return res;\r
        }\r
+       // add for speeding up !!!\r
+       mreal dvx(long i,long j=0,long k=0) const\r
+       {\r
+               mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
+               if(dfunc)       res = dfunc(x+dx,y,z, par)-dfunc(x,y,z, par);\r
+               else if(ex)     res = mgl_expr_eval(ex,x+dx,y,z)-mgl_expr_eval(ex,x,y,z);\r
+               return res;\r
+       }\r
+       mreal dvy(long i,long j=0,long k=0) const\r
+       {\r
+               mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
+               if(dfunc)       res = dfunc(x,y+dy,z, par)-dfunc(x,y,z, par);\r
+               else if(ex)     res = mgl_expr_eval(ex,x,y+dy,z)-mgl_expr_eval(ex,x,y,z);\r
+               return res;\r
+       }\r
+       mreal dvz(long i,long j=0,long k=0) const\r
+       {\r
+               mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
+               if(dfunc)       res = dfunc(x,y,z+dz, par)-dfunc(x,y,z, par);\r
+               else if(ex)     res = mgl_expr_eval(ex,x,y,z+dz)-mgl_expr_eval(ex,x,y,z);\r
+               return res;\r
+       }\r
+};\r
+//-----------------------------------------------------------------------------\r
+/// Class which present variable as data array\r
+class MGL_EXPORT mglDataT : public mglDataA\r
+{\r
+       const mglDataA &dat;\r
+       long ind;\r
+public:\r
+       mglDataT(const mglDataT &d) : dat(d.dat), ind(d.ind)    {       s = d.s;        }\r
+       mglDataT(const mglDataA &d, long col=0) : dat(d), ind(col)      {}\r
+#if MGL_HAVE_RVAL\r
+       mglDataT(mglDataT &&d):dat(d.dat),ind(d.ind)\r
+       {       s=d.s;  temp=d.temp;    func=d.func;    o=d.o;  d.func=0;       }\r
+#endif\r
+       virtual ~mglDataT()     {}\r
+\r
+       /// Get sizes\r
+       long GetNx() const      {       return dat.GetNy();     }\r
+       long GetNy() const      {       return dat.GetNz();     }\r
+       long GetNz() const      {       return 1;       }\r
+\r
+       mreal Maximal() const\r
+       {       return mglSubData(dat,ind).Maximal();   }\r
+       mreal Minimal() const\r
+       {       return mglSubData(dat,ind).Minimal();   }\r
+       inline void SetInd(long i, const wchar_t *name)\r
+       {       ind = i;        s = name;       }\r
+       inline void SetInd(long i, wchar_t name)\r
+       {       ind = i;        s = name;       }\r
+\r
+       /// Get the value in given cell of the data without border checking\r
+       mreal v(long i,long j=0,long =0) const\r
+       {       return dat.v(ind,i,j);  }\r
+       mreal vthr(long i) const\r
+       {       return dat.vthr(ind+dat.GetNx()*i);     }\r
+       // add for speeding up !!!\r
+       mreal dvx(long i,long j=0,long =0) const\r
+       {       return  dat.dvy(ind,i,j);       }\r
+       mreal dvy(long i,long j=0,long =0) const\r
+       {       return dat.dvz(ind,i,j);        }\r
+       mreal dvz(long ,long =0,long =0) const\r
+       {       return 0;       }\r
 };\r
+//-----------------------------------------------------------------------------\r
+class MGL_EXPORT mglDataR : public mglDataA\r
+{\r
+       const mglDataA &dat;\r
+       long ind;\r
+public:\r
+       mglDataR(const mglDataR &d) : dat(d.dat), ind(d.ind)    {       s = d.s;        }\r
+       mglDataR(const mglDataA &d, long row=0) : dat(d), ind(row)      {}\r
+#if MGL_HAVE_RVAL\r
+       mglDataR(mglDataR &&d):dat(d.dat),ind(d.ind)\r
+       {       s=d.s;  temp=d.temp;    func=d.func;    o=d.o;  d.func=0;       }\r
 #endif\r
+       virtual ~mglDataR()     {}\r
+\r
+       /// Get sizes\r
+       long GetNx() const      {       return dat.GetNx();     }\r
+       long GetNy() const      {       return 1;       }\r
+       long GetNz() const      {       return 1;       }\r
+\r
+       mreal Maximal() const\r
+       {       return mglSubData(dat,-1,ind).Maximal();        }\r
+       mreal Minimal() const\r
+       {       return mglSubData(dat,-1,ind).Minimal();        }\r
+       inline void SetInd(long i, const wchar_t *name)\r
+       {       ind = i;        s = name;       }\r
+       inline void SetInd(long i, wchar_t name)\r
+       {       ind = i;        s = name;       }\r
+\r
+       /// Get the value in given cell of the data without border checking\r
+       mreal v(long i,long =0,long =0) const\r
+       {       return dat.v(i,ind,0);  }\r
+       mreal vthr(long i) const\r
+       {       return dat.vthr(i+dat.GetNx()*ind);     }\r
+       // add for speeding up !!!\r
+       mreal dvx(long i,long j=0,long =0) const\r
+       {       return  dat.dvx(i,ind,0);       }\r
+       mreal dvy(long i,long j=0,long =0) const\r
+       {       return 0;       }\r
+       mreal dvz(long ,long =0,long =0) const\r
+       {       return 0;       }\r
+};\r
 //-----------------------------------------------------------------------------\r
 #endif\r
 #endif\r
index 224ef768d34e0fee42d04013ce34f9117bf71132..2976bdefb9e041520ee8da9d5a8596ecc8e3fb32 100644 (file)
@@ -46,8 +46,8 @@ void MGL_EXPORT mgl_srnd_(int *seed);
 double MGL_EXPORT mgl_rnd();\r
 double MGL_EXPORT mgl_rnd_();\r
 /// Get integer power of x\r
-double MGL_EXPORT mgl_ipow(double x,int n);\r
-double MGL_EXPORT mgl_ipow_(mreal *x,int *n);\r
+double MGL_EXPORT_CONST mgl_ipow(double x,int n);\r
+double MGL_EXPORT_PURE mgl_ipow_(mreal *x,int *n);\r
 /// Get number of seconds since 1970 for given string\r
 double MGL_EXPORT mgl_get_time(const char *time, const char *fmt);\r
 double MGL_EXPORT mgl_get_time_(const char *time, const char *fmt,int,int);\r
@@ -64,8 +64,6 @@ uintptr_t MGL_EXPORT mgl_create_data_file_(const char *fname, int len);
 /// Delete HMDT object\r
 void MGL_EXPORT mgl_delete_data(HMDT dat);\r
 void MGL_EXPORT mgl_delete_data_(uintptr_t *dat);\r
-/// Get information about the data (sizes and momentum) to string\r
-MGL_EXPORT const char *mgl_data_info(HCDT dat);\r
 \r
 /// Rearange data dimensions\r
 void MGL_EXPORT mgl_data_rearrange(HMDT dat, long mx,long my,long mz);\r
@@ -113,11 +111,6 @@ void MGL_EXPORT mgl_data_set_values_(uintptr_t *d, const char *val, int *nx, int
 /// Read data array from HDF file (parse HDF4 and HDF5 files)\r
 int MGL_EXPORT mgl_data_read_hdf(HMDT d,const char *fname,const char *data);\r
 int MGL_EXPORT mgl_data_read_hdf_(uintptr_t *d, const char *fname, const char *data,int l,int n);\r
-/// Save data to HDF file\r
-void MGL_EXPORT mgl_data_save_hdf(HCDT d,const char *fname,const char *data,int rewrite);\r
-void MGL_EXPORT mgl_data_save_hdf_(uintptr_t *d, const char *fname, const char *data, int *rewrite,int l,int n);\r
-/// Put HDF data names into buf as '\t' separated.\r
-int MGL_EXPORT mgl_datas_hdf(const char *fname, char *buf, long size);\r
 /// Read data from tab-separated text file with auto determining size\r
 int MGL_EXPORT mgl_data_read(HMDT dat, const char *fname);\r
 int MGL_EXPORT mgl_data_read_(uintptr_t *d, const char *fname,int l);\r
@@ -133,12 +126,6 @@ int MGL_EXPORT mgl_data_read_range_(uintptr_t *d, const char *fname, mreal *n1,
 /// Read data from tab-separated text files with auto determining size which filenames are satisfied to template (like "t_*.dat")\r
 int MGL_EXPORT mgl_data_read_all(HMDT dat, const char *templ, int as_slice);\r
 int MGL_EXPORT mgl_data_read_all_(uintptr_t *d, const char *fname, int *as_slice,int l);\r
-/// Save whole data array (for ns=-1) or only ns-th slice to text file\r
-void MGL_EXPORT mgl_data_save(HCDT dat, const char *fname,long ns);\r
-void MGL_EXPORT mgl_data_save_(uintptr_t *dat, const char *fname,int *ns,int);\r
-/// Export data array (for ns=-1) or only ns-th slice to PNG file according color scheme\r
-void MGL_EXPORT mgl_data_export(HCDT dat, const char *fname, const char *scheme,mreal v1,mreal v2,long ns);\r
-void MGL_EXPORT mgl_data_export_(uintptr_t *dat, const char *fname, const char *scheme,mreal *v1,mreal *v2,int *ns,int,int);\r
 /// Import data array from PNG file according color scheme\r
 void MGL_EXPORT mgl_data_import(HMDT dat, const char *fname, const char *scheme,mreal v1,mreal v2);\r
 void MGL_EXPORT mgl_data_import_(uintptr_t *dat, const char *fname, const char *scheme,mreal *v1,mreal *v2,int,int);\r
@@ -173,6 +160,9 @@ void MGL_EXPORT mgl_data_fill_(uintptr_t *dat, mreal *x1,mreal *x2,const char *d
 /// Modify the data by specified formula assuming x,y,z in range [r1,r2]\r
 void MGL_EXPORT mgl_data_fill_eq(HMGL gr, HMDT dat, const char *eq, HCDT vdat, HCDT wdat,const char *opt);\r
 void MGL_EXPORT mgl_data_fill_eq_(uintptr_t *gr, uintptr_t *dat, const char *eq, uintptr_t *vdat, uintptr_t *wdat,const char *opt, int, int);\r
+/// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2] using global spline\r
+void MGL_EXPORT mgl_data_refill_gs(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl);\r
+void MGL_EXPORT mgl_data_refill_gs_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl);\r
 /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2]\r
 void MGL_EXPORT mgl_data_refill_x(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl);\r
 void MGL_EXPORT mgl_data_refill_x_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl);\r
@@ -207,22 +197,10 @@ void MGL_EXPORT mgl_data_modify_vw_(uintptr_t *dat, const char *eq, uintptr_t *v
 void MGL_EXPORT mgl_data_squeeze(HMDT dat, long rx,long ry,long rz,long smooth);\r
 void MGL_EXPORT mgl_data_squeeze_(uintptr_t *dat, int *rx,int *ry,int *rz,int *smooth);\r
 \r
-/// Get maximal value of the data\r
-mreal MGL_EXPORT mgl_data_max(HCDT dat);\r
-mreal MGL_EXPORT mgl_data_max_(uintptr_t *dat);\r
-/// Get maximal value of the data which is less than 0\r
-mreal MGL_EXPORT mgl_data_neg_max(HCDT dat);\r
-mreal MGL_EXPORT mgl_data_neg_max_(uintptr_t *dat);\r
-/// Get minimal value of the data\r
-mreal MGL_EXPORT mgl_data_min(HCDT dat);\r
-mreal MGL_EXPORT mgl_data_min_(uintptr_t *dat);\r
-/// Get minimal value of the data which is larger than 0\r
-mreal MGL_EXPORT mgl_data_pos_min(HCDT dat);\r
-mreal MGL_EXPORT mgl_data_pos_min_(uintptr_t *dat);\r
 /// Returns pointer to data element [i,j,k]\r
 MGL_EXPORT mreal *mgl_data_value(HMDT dat, long i,long j,long k);\r
 /// Returns pointer to internal data array\r
-MGL_EXPORT mreal *mgl_data_data(HMDT dat);\r
+MGL_EXPORT_PURE mreal *mgl_data_data(HMDT dat);\r
 \r
 /// Gets the x-size of the data.\r
 long MGL_EXPORT mgl_data_get_nx(HCDT d);\r
@@ -234,34 +212,6 @@ long MGL_EXPORT mgl_data_get_ny_(uintptr_t *d);
 long MGL_EXPORT mgl_data_get_nz(HCDT d);\r
 long MGL_EXPORT mgl_data_get_nz_(uintptr_t *d);\r
 \r
-/// Find position (after specified in i,j,k) of first nonzero value of formula\r
-mreal MGL_EXPORT mgl_data_first(HCDT dat, const char *cond, long *i, long *j, long *k);\r
-mreal MGL_EXPORT mgl_data_first_(uintptr_t *dat, const char *cond, int *i, int *j, int *k, int);\r
-/// Find position (before specified in i,j,k) of last nonzero value of formula\r
-mreal MGL_EXPORT mgl_data_last(HCDT dat, const char *cond, long *i, long *j, long *k);\r
-mreal MGL_EXPORT mgl_data_last_(uintptr_t *dat, const char *cond, int *i, int *j, int *k, int);\r
-/// Find position of first in direction 'dir' nonzero value of formula\r
-long MGL_EXPORT mgl_data_find(HCDT dat, const char *cond, char dir, long i, long j, long k);\r
-int MGL_EXPORT mgl_data_find_(uintptr_t *dat, const char *cond, char *dir, int *i, int *j, int *k, int,int);\r
-/// Find if any nonzero value of formula\r
-int MGL_EXPORT mgl_data_find_any(HCDT dat, const char *cond);\r
-int MGL_EXPORT mgl_data_find_any_(uintptr_t *dat, const char *cond, int);\r
-/// Get maximal value of the data and its position\r
-mreal MGL_EXPORT mgl_data_max_int(HCDT dat, long *i, long *j, long *k);\r
-mreal MGL_EXPORT mgl_data_max_int_(uintptr_t *dat, int *i, int *j, int *k);\r
-/// Get maximal value of the data and its approximated position\r
-mreal MGL_EXPORT mgl_data_max_real(HCDT dat, mreal *x, mreal *y, mreal *z);\r
-mreal MGL_EXPORT mgl_data_max_real_(uintptr_t *dat, mreal *x, mreal *y, mreal *z);\r
-/// Get minimal value of the data and its position\r
-mreal MGL_EXPORT mgl_data_min_int(HCDT dat, long *i, long *j, long *k);\r
-mreal MGL_EXPORT mgl_data_min_int_(uintptr_t *dat, int *i, int *j, int *k);\r
-/// Get minimal value of the data and its approximated position\r
-mreal MGL_EXPORT mgl_data_min_real(HCDT dat, mreal *x, mreal *y, mreal *z);\r
-mreal MGL_EXPORT mgl_data_min_real_(uintptr_t *dat, mreal *x, mreal *y, mreal *z);\r
-/// Get "energy and find 4 momenta of data: median, width, skewness, kurtosis\r
-mreal MGL_EXPORT mgl_data_momentum_val(HCDT d, char dir, mreal *m, mreal *w, mreal *s, mreal *k);\r
-mreal MGL_EXPORT mgl_data_momentum_val_(uintptr_t *dat, char *dir, mreal *m, mreal *w, mreal *s, mreal *k,int);\r
-\r
 /// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on)\r
 HMDT MGL_EXPORT mgl_data_combine(HCDT dat1, HCDT dat2);\r
 uintptr_t MGL_EXPORT mgl_data_combine_(uintptr_t *dat1, uintptr_t *dat2);\r
@@ -346,20 +296,26 @@ void MGL_EXPORT mgl_fft(double *x, long s, long n, const void *wt, void *ws, int
 void MGL_EXPORT mgl_clear_fft();\r
 \r
 /// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
-mreal MGL_EXPORT mgl_data_spline(HCDT dat, mreal x,mreal y,mreal z);\r
-mreal MGL_EXPORT mgl_data_spline_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);\r
+mreal MGL_EXPORT_PURE mgl_data_spline(HCDT dat, mreal x,mreal y,mreal z);\r
+mreal MGL_EXPORT_PURE mgl_data_spline_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);\r
 /// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
-mreal MGL_EXPORT mgl_data_linear(HCDT dat, mreal x,mreal y,mreal z);\r
-mreal MGL_EXPORT mgl_data_linear_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);\r
+mreal MGL_EXPORT_PURE mgl_data_linear(HCDT dat, mreal x,mreal y,mreal z);\r
+mreal MGL_EXPORT_PURE mgl_data_linear_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);\r
 /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
-mreal MGL_EXPORT mgl_data_spline_ext(HCDT dat, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz);\r
-mreal MGL_EXPORT mgl_data_spline_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz);\r
+mreal MGL_EXPORT_PURE mgl_data_spline_ext(HCDT dat, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz);\r
+mreal MGL_EXPORT_PURE mgl_data_spline_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz);\r
+/// Prepare coefficients for global spline interpolation\r
+HMDT MGL_EXPORT mgl_gspline_init(HCDT x, HCDT v);\r
+uintptr_t MGL_EXPORT mgl_gspline_init_(uintptr_t *x, uintptr_t *v);\r
+/// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef\r
+mreal MGL_EXPORT mgl_gspline(HCDT coef, mreal dx, mreal *d1, mreal *d2);\r
+mreal MGL_EXPORT mgl_gspline_(uintptr_t *c, mreal *dx, mreal *d1, mreal *d2);\r
 /// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
-mreal MGL_EXPORT mgl_data_linear_ext(HCDT dat, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz);\r
-mreal MGL_EXPORT mgl_data_linear_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz);\r
+mreal MGL_EXPORT_PURE mgl_data_linear_ext(HCDT dat, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz);\r
+mreal MGL_EXPORT_PURE mgl_data_linear_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz);\r
 /// Return an approximated x-value (root) when dat(x) = val\r
-mreal MGL_EXPORT mgl_data_solve_1d(HCDT dat, mreal val, int spl, long i0);\r
-mreal MGL_EXPORT mgl_data_solve_1d_(uintptr_t *dat, mreal *val, int *spl, int *i0);\r
+mreal MGL_EXPORT_PURE mgl_data_solve_1d(HCDT dat, mreal val, int spl, long i0);\r
+mreal MGL_EXPORT_PURE mgl_data_solve_1d_(uintptr_t *dat, mreal *val, int *spl, int *i0);\r
 /// Return an approximated value (root) when dat(x) = val\r
 HMDT MGL_EXPORT mgl_data_solve(HCDT dat, mreal val, char dir, HCDT i0, int norm);\r
 uintptr_t MGL_EXPORT mgl_data_solve_(uintptr_t *dat, mreal *val, const char *dir, uintptr_t *i0, int *norm,int);\r
@@ -375,13 +331,13 @@ HMDT MGL_EXPORT mgl_data_resize_box(HCDT dat, long mx,long my,long mz,mreal x1,m
 uintptr_t MGL_EXPORT mgl_data_resize_box_(uintptr_t *dat, int *mx,int *my,int *mz,mreal *x1,mreal *x2,mreal *y1,mreal *y2,mreal *z1,mreal *z2);\r
 /// Create n-th points distribution of this data values in range [v1, v2]\r
 HMDT MGL_EXPORT mgl_data_hist(HCDT dat, long n, mreal v1, mreal v2, long nsub);\r
-uintptr_t MGL_EXPORT mgl_data_momentum_(uintptr_t *dat, char *dir, const char *how, int,int);\r
+uintptr_t MGL_EXPORT mgl_data_hist_(uintptr_t *dat, int *n, mreal *v1, mreal *v2, int *nsub);\r
 /// Create n-th points distribution of this data values in range [v1, v2] with weight w\r
 HMDT MGL_EXPORT mgl_data_hist_w(HCDT dat, HCDT weight, long n, mreal v1, mreal v2, long nsub);\r
-uintptr_t MGL_EXPORT mgl_data_hist_(uintptr_t *dat, int *n, mreal *v1, mreal *v2, int *nsub);\r
+uintptr_t MGL_EXPORT mgl_data_hist_w_(uintptr_t *dat, uintptr_t *weight, int *n, mreal *v1, mreal *v2, int *nsub);\r
 /// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on.\r
 HMDT MGL_EXPORT mgl_data_momentum(HCDT dat, char dir, const char *how);\r
-uintptr_t MGL_EXPORT mgl_data_hist_w_(uintptr_t *dat, uintptr_t *weight, int *n, mreal *v1, mreal *v2, int *nsub);\r
+uintptr_t MGL_EXPORT mgl_data_momentum_(uintptr_t *dat, char *dir, const char *how, int,int);\r
 /// Get array which values is result of interpolation this for coordinates from other arrays\r
 HMDT MGL_EXPORT mgl_data_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm);\r
 uintptr_t MGL_EXPORT mgl_data_evaluate_(uintptr_t *dat, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm);\r
@@ -460,18 +416,18 @@ uintptr_t MGL_EXPORT mgl_create_expr_(const char *expr, int);
 void MGL_EXPORT mgl_delete_expr(HMEX ex);\r
 void MGL_EXPORT mgl_delete_expr_(uintptr_t *ex);\r
 /// Return value of expression for given x,y,z variables\r
-double MGL_EXPORT mgl_expr_eval(HMEX ex, double x, double y,double z);\r
+double MGL_EXPORT_PURE mgl_expr_eval(HMEX ex, double x, double y,double z);\r
 double MGL_EXPORT mgl_expr_eval_(uintptr_t *ex, mreal *x, mreal *y, mreal *z);\r
 /// Return value of expression for given variables\r
 double MGL_EXPORT mgl_expr_eval_v(HMEX ex, mreal *vars);\r
 /// Return value of expression differentiation over variable dir for given x,y,z variables\r
-double MGL_EXPORT mgl_expr_diff(HMEX ex, char dir, double x, double y,double z);\r
+double MGL_EXPORT_PURE mgl_expr_diff(HMEX ex, char dir, double x, double y,double z);\r
 double MGL_EXPORT mgl_expr_diff_(uintptr_t *ex, const char *dir, mreal *x, mreal *y, mreal *z, int);\r
 /// Return value of expression differentiation over variable dir for given variables\r
 double MGL_EXPORT mgl_expr_diff_v(HMEX ex, char dir, mreal *vars);\r
-\r
+//-----------------------------------------------------------------------------\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
-//-----------------------------------------------------------------------------\r
 #endif\r
+//-----------------------------------------------------------------------------\r
index 14218d9d9ca4c5e6830328057b806955d32aa1ee..a865c8b0d1b4321d671767e542be53699d130732 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************\r
- * data.h is part of Math Graphic Library\r
+ * datac.h is part of Math Graphic Library\r
  * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *\r
  *                                                                         *\r
  *   This program is free software; you can redistribute it and/or modify  *\r
 #define mgl3   mreal(3)\r
 #define mgl4   mreal(4)\r
 //-----------------------------------------------------------------------------\r
-/// Class for working with data array\r
+/// Class for working with complex data array\r
 class MGL_EXPORT mglDataC : public mglDataA\r
 {\r
 public:\r
-\r
+using mglDataA::Momentum;\r
        long nx;                ///< number of points in 1st dimensions ('x' dimension)\r
        long ny;                ///< number of points in 2nd dimensions ('y' dimension)\r
        long nz;                ///< number of points in 3d dimensions ('z' dimension)\r
@@ -42,35 +42,49 @@ public:
        std::string id; ///< column (or slice) names\r
        bool link;              ///< use external data (i.e. don't free it)\r
 \r
-       /// Initiate by other mglData variable\r
-       inline mglDataC(const mglDataC &d)      {       a=0;    mgl_datac_set(this,&d);         }       // NOTE: must be constructor for mglDataC& to exclude copy one\r
-       inline mglDataC(const mglDataA *d)      {       a=0;    mgl_datac_set(this, d);         }\r
-       inline mglDataC(bool, mglDataC *d)      // NOTE: Variable d will be deleted!!!\r
+       /// Initiate by other mglDataC variable\r
+       mglDataC(const mglDataC &d)     {       a=0;    mgl_datac_set(this,&d);         }       // NOTE: must be constructor for mglDataC& to exclude copy one\r
+       mglDataC(const mglDataA &d)     {       a=0;    mgl_datac_set(this,&d);         }\r
+#if MGL_HAVE_RVAL\r
+       mglDataC(mglDataC &&d):nx(d.nx),ny(d.ny),nz(d.nz),a(d.a),id(d.id),link(d.link)\r
+       {       s=d.s;  temp=d.temp;    func=d.func;    o=d.o;  d.a=0;  d.func=0;       }\r
+#endif\r
+       mglDataC(const mglDataA &re, const mglDataA &im)        {       a=0;    mgl_datac_set_ri(this,&re,&im); }\r
+       mglDataC(HCDT d)        {       a=0;    mgl_datac_set(this, d);         }\r
+       mglDataC(HCDT re, HCDT im)      {       a=0;    mgl_datac_set_ri(this, re, im);         }\r
+       mglDataC(bool, mglDataC *d)     // NOTE: Variable d will be deleted!!!\r
        {       if(d)\r
                {       nx=d->nx;       ny=d->ny;       nz=d->nz;       a=d->a; d->a=0;\r
+                       temp=d->temp;   func=d->func;   o=d->o; s=d->s;\r
                        id=d->id;       link=d->link;   delete d;       }\r
                else    {       a=0;    Create(1);      }       }\r
        /// Initiate by flat array\r
-       inline mglDataC(int size, const dual *d)        {       a=0;    Set(d,size);    }\r
-       inline mglDataC(int rows, int cols, const dual *d)      {       a=0;    Set(d,cols,rows);       }\r
-       inline mglDataC(int size, const double *d)      {       a=0;    Set(d,size);    }\r
-       inline mglDataC(int rows, int cols, const double *d)    {       a=0;    Set(d,cols,rows);       }\r
-       inline mglDataC(int size, const float *d)       {       a=0;    Set(d,size);    }\r
-       inline mglDataC(int rows, int cols, const float *d)     {       a=0;    Set(d,cols,rows);       }\r
+       mglDataC(int size, const dual *d)       {       a=0;    Set(d,size);    }\r
+       mglDataC(int rows, int cols, const dual *d)     {       a=0;    Set(d,cols,rows);       }\r
+       mglDataC(int size, const double *d)     {       a=0;    Set(d,size);    }\r
+       mglDataC(int rows, int cols, const double *d)   {       a=0;    Set(d,cols,rows);       }\r
+       mglDataC(int size, const float *d)      {       a=0;    Set(d,size);    }\r
+       mglDataC(int rows, int cols, const float *d)    {       a=0;    Set(d,cols,rows);       }\r
+       mglDataC(const dual *d, int size)       {       a=0;    Set(d,size);    }\r
+       mglDataC(const dual *d, int rows, int cols)     {       a=0;    Set(d,cols,rows);       }\r
+       mglDataC(const double *d, int size)     {       a=0;    Set(d,size);    }\r
+       mglDataC(const double *d, int rows, int cols)   {       a=0;    Set(d,cols,rows);       }\r
+       mglDataC(const float *d, int size)      {       a=0;    Set(d,size);    }\r
+       mglDataC(const float *d, int rows, int cols)    {       a=0;    Set(d,cols,rows);       }\r
        /// Read data from file\r
-       inline mglDataC(const char *fname)                      {       a=0;    Read(fname);    }\r
+       mglDataC(const char *fname)                     {       a=0;    Read(fname);    }\r
        /// Allocate the memory for data array and initialize it zero\r
-       inline mglDataC(long xx=1,long yy=1,long zz=1)  {       a=0;    Create(xx,yy,zz);       }\r
+       mglDataC(long xx=1,long yy=1,long zz=1) {       a=0;    Create(xx,yy,zz);       }\r
        /// Delete the array\r
        virtual ~mglDataC()     {       if(!link && a)  delete []a;     }\r
-       inline dual GetVal(long i, long j=0, long k=0)\r
+       inline dual GetVal(long i, long j=0, long k=0) const\r
        {       return mgl_datac_get_value(this,i,j,k);}\r
        inline void SetVal(dual f, long i, long j=0, long k=0)\r
        {       mgl_datac_set_value(this,f,i,j,k);      }\r
        /// Get sizes\r
-       inline long GetNx() const       {       return nx;      }\r
-       inline long GetNy() const       {       return ny;      }\r
-       inline long GetNz() const       {       return nz;      }\r
+       long GetNx() const      {       return nx;      }\r
+       long GetNy() const      {       return ny;      }\r
+       long GetNz() const      {       return nz;      }\r
 \r
        /// Link external data array (don't delete it at exit)\r
        inline void Link(dual *A, long NX, long NY=1, long NZ=1)\r
@@ -160,7 +174,7 @@ public:
        {       mgl_datac_fill_eq(gr,this,eq,&vdat,&wdat,opt);  }\r
        /// Equidistantly fill the data to range [x1,x2] in direction dir\r
        inline void Fill(dual x1,dual x2=NaN,char dir='x')\r
-       {       return mgl_datac_fill(this,x1,x2,dir);  }\r
+       {       mgl_datac_fill(this,x1,x2,dir); }\r
 \r
                /// Put value to data element(s)\r
        inline void Put(dual val, long i=-1, long j=-1, long k=-1)\r
@@ -182,7 +196,7 @@ public:
        inline bool Read(const char *fname,long mx,long my=1,long mz=1)\r
        {       return mgl_datac_read_dim(this,fname,mx,my,mz); }\r
        /// Save whole data array (for ns=-1) or only ns-th slice to text file\r
-       inline void Save(const char *fname,long ns=-1) const\r
+       void Save(const char *fname,long ns=-1) const\r
        {       mgl_datac_save(this,fname,ns);  }\r
        /// Read data from tab-separated text files with auto determining size which filenames are result of sprintf(fname,templ,t) where t=from:step:to\r
        inline bool ReadRange(const char *templ, double from, double to, double step=1, bool as_slice=false)\r
@@ -193,19 +207,13 @@ public:
        /// Read data from text file with size specified at beginning of the file\r
        inline bool ReadMat(const char *fname, long dim=2)\r
        {       return mgl_datac_read_mat(this,fname,dim);      }\r
-       /// Export data array (for ns=-1) or only ns-th slice to PNG file according color scheme\r
-       inline void Export(const char *fname,const char *scheme,mreal v1=0,mreal v2=0,long ns=-1) const\r
-       {       mgl_data_export(this,fname,scheme,v1,v2,ns);    }\r
 \r
                /// Read data array from HDF file (parse HDF4 and HDF5 files)\r
        inline int ReadHDF(const char *fname,const char *data)\r
        {       return mgl_datac_read_hdf(this,fname,data);     }\r
        /// Save data to HDF file\r
-       inline void SaveHDF(const char *fname,const char *data,bool rewrite=false) const\r
+       void SaveHDF(const char *fname,const char *data,bool rewrite=false) const\r
        {       mgl_datac_save_hdf(this,fname,data,rewrite);    }\r
-       /// Put HDF data names into buf as '\t' separated.\r
-       inline static int DatasHDF(const char *fname, char *buf, long size)\r
-       {       return mgl_datas_hdf(fname,buf,size);   }\r
 \r
        /// Get real part of data values\r
        inline mglData Real() const\r
@@ -219,56 +227,61 @@ public:
        /// Get argument of data values\r
        inline mglData Arg() const\r
        {       return mglData(true,mgl_datac_arg(this));       }\r
-       \r
+\r
        /// Get column (or slice) of the data filled by formulas of named columns\r
-       inline mglData Column(const char *eq) const\r
-       {       return mglData(true,mgl_data_column(this,eq));  }\r
+       inline mglDataC Column(const char *eq) const\r
+       {       return mglDataC(true,mgl_datac_column(this,eq));        }\r
        /// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on.\r
-       inline mglData Momentum(char dir, const char *how) const\r
-       {       return mglData(true,mgl_data_momentum(this,dir,how));   }\r
+       inline mglDataC Momentum(char dir, const char *how) const\r
+       {       return mglDataC(true,mgl_datac_momentum(this,dir,how)); }\r
        /// Get sub-array of the data with given fixed indexes\r
-       inline mglData SubData(long xx,long yy=-1,long zz=-1) const\r
-       {       return mglData(true,mgl_data_subdata(this,xx,yy,zz));   }\r
-       inline mglData SubData(const mglDataA &xx, const mglDataA &yy, const mglDataA &zz) const\r
-       {       return mglData(true,mgl_data_subdata_ext(this,&xx,&yy,&zz));    }\r
+       inline mglDataC SubData(long xx,long yy=-1,long zz=-1) const\r
+       {       return mglDataC(true,mgl_datac_subdata(this,xx,yy,zz)); }\r
+       inline mglDataC SubData(const mglDataA &xx, const mglDataA &yy, const mglDataA &zz) const\r
+       {       return mglDataC(true,mgl_datac_subdata_ext(this,&xx,&yy,&zz));  }\r
+       inline mglDataC SubData(const mglDataA &xx, const mglDataA &yy) const\r
+       {       return mglDataC(true,mgl_datac_subdata_ext(this,&xx,&yy,0));    }\r
+       inline mglDataC SubData(const mglDataA &xx) const\r
+       {       return mglDataC(true,mgl_datac_subdata_ext(this,&xx,0,0));      }\r
        /// Get trace of the data array\r
-       inline mglData Trace() const\r
-       {       return mglData(true,mgl_data_trace(this));      }\r
+       inline mglDataC Trace() const\r
+       {       return mglDataC(true,mgl_datac_trace(this));    }\r
+       /// Get array which is result of summation in given direction or directions\r
+       inline mglDataC Sum(const char *dir) const\r
+       {       return mglDataC(true,mgl_datac_sum(this,dir));  }\r
+       /// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on)\r
+       inline mglDataC Combine(const mglDataA &dat) const\r
+       {       return mglDataC(true,mgl_datac_combine(this,&dat));     }\r
+       /// Resize the data to new size of box [x1,x2]*[y1,y2]*[z1,z2]\r
+       inline mglDataC Resize(long mx,long my=1,long mz=1, mreal x1=0,mreal x2=1, mreal y1=0,mreal y2=1, mreal z1=0,mreal z2=1) const\r
+       {       return mglDataC(true,mgl_datac_resize_box(this,mx,my,mz,x1,x2,y1,y2,z1,z2));    }\r
+       /// Get array which values is result of interpolation this for coordinates from other arrays\r
+       inline mglDataC Evaluate(const mglData &idat, bool norm=true) const\r
+       {       return mglDataC(true,mgl_datac_evaluate(this,&idat,0,0,norm));  }\r
+       inline mglDataC Evaluate(const mglData &idat, const mglData &jdat, bool norm=true) const\r
+       {       return mglDataC(true,mgl_datac_evaluate(this,&idat,&jdat,0,norm));      }\r
+       inline mglDataC Evaluate(const mglData &idat, const mglData &jdat, const mglData &kdat, bool norm=true) const\r
+       {       return mglDataC(true,mgl_datac_evaluate(this,&idat,&jdat,&kdat,norm));  }\r
+\r
+       /// Find correlation with another data arrays\r
+       inline mglDataC Correl(const mglData &dat, const char *dir) const\r
+       {       return mglDataC(true,mgl_datac_correl(this,&dat,dir));  }\r
+       /// Find auto correlation function\r
+       inline mglDataC AutoCorrel(const char *dir) const\r
+       {       return mglDataC(true,mgl_datac_correl(this,this,dir));  }\r
+\r
        /// Create n-th points distribution of this data values in range [v1, v2]\r
        inline mglData Hist(long n,mreal v1=0,mreal v2=1, long nsub=0) const\r
        {       return mglData(true,mgl_data_hist(this,n,v1,v2,nsub));  }\r
        /// Create n-th points distribution of this data values in range [v1, v2] with weight w\r
        inline mglData Hist(const mglDataA &w, long n,mreal v1=0,mreal v2=1, long nsub=0) const\r
        {       return mglData(true,mgl_data_hist_w(this,&w,n,v1,v2,nsub));     }\r
-       /// Get array which is result of summation in given direction or directions\r
-       inline mglData Sum(const char *dir) const\r
-       {       return mglData(true,mgl_data_sum(this,dir));    }\r
        /// Get array which is result of maximal values in given direction or directions\r
        inline mglData Max(const char *dir) const\r
        {       return mglData(true,mgl_data_max_dir(this,dir));        }\r
        /// Get array which is result of minimal values in given direction or directions\r
        inline mglData Min(const char *dir) const\r
        {       return mglData(true,mgl_data_min_dir(this,dir));        }\r
-       /// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on)\r
-       inline mglData Combine(const mglDataA &dat) const\r
-       {       return mglData(true,mgl_data_combine(this,&dat));       }\r
-       /// Resize the data to new size of box [x1,x2]*[y1,y2]*[z1,z2]\r
-       inline mglData Resize(long mx,long my=1,long mz=1, mreal x1=0,mreal x2=1, mreal y1=0,mreal y2=1, mreal z1=0,mreal z2=1) const\r
-       {       return mglData(true,mgl_data_resize_box(this,mx,my,mz,x1,x2,y1,y2,z1,z2));      }\r
-       /// Get array which values is result of interpolation this for coordinates from other arrays\r
-       inline mglData Evaluate(const mglData &idat, bool norm=true) const\r
-       {       return mglData(true,mgl_data_evaluate(this,&idat,0,0,norm));    }\r
-       inline mglData Evaluate(const mglData &idat, const mglData &jdat, bool norm=true) const\r
-       {       return mglData(true,mgl_data_evaluate(this,&idat,&jdat,0,norm));        }\r
-       inline mglData Evaluate(const mglData &idat, const mglData &jdat, const mglData &kdat, bool norm=true) const\r
-       {       return mglData(true,mgl_data_evaluate(this,&idat,&jdat,&kdat,norm));    }\r
-\r
-       /// Find correlation with another data arrays\r
-       inline mglDataC Correl(const mglData &dat, const char *dir) const\r
-       {       return mglDataC(true,mgl_datac_correl(this,&dat,dir));  }\r
-       /// Find auto correlation function\r
-       inline mglDataC AutoCorrel(const char *dir) const\r
-       {       return mglDataC(true,mgl_datac_correl(this,this,dir));  }\r
 \r
        /// Cumulative summation the data in given direction or directions\r
        inline void CumSum(const char *dir)     {       mgl_datac_cumsum(this,dir);     }\r
@@ -332,66 +345,50 @@ public:
        {       return mglData(true,mgl_data_solve(this, val, dir, 0, norm));   }\r
        inline mglData Solve(mreal val, char dir, const mglData &i0, bool norm=true) const\r
        {       return mglData(true,mgl_data_solve(this, val, dir, &i0, norm)); }\r
-       \r
-       /// Print information about the data (sizes and momentum) to string\r
-       inline const char *PrintInfo() const    {       return mgl_data_info(this);     }\r
-       /// Print information about the data (sizes and momentum) to FILE (for example, stdout)\r
-       inline void PrintInfo(FILE *fp) const\r
-       {       if(fp)  {       fprintf(fp,"%s",mgl_data_info(this));   fflush(fp);     }       }\r
-       /// Get maximal value of the data\r
-       inline mreal Maximal() const    {       return mgl_data_max(this);      }\r
-       /// Get minimal value of the data\r
-       inline mreal Minimal() const    {       return mgl_data_min(this);      }\r
-       /// Get maximal value of the data and its position\r
-       inline mreal Maximal(long &i,long &j,long &k) const\r
-       {       return mgl_data_max_int(this,&i,&j,&k); }\r
-       /// Get minimal value of the data and its position\r
-       inline mreal Minimal(long &i,long &j,long &k) const\r
-       {       return mgl_data_min_int(this,&i,&j,&k); }\r
-       /// Get maximal value of the data and its approximated position\r
-       inline mreal Maximal(mreal &x,mreal &y,mreal &z) const\r
-       {       return mgl_data_max_real(this,&x,&y,&z);        }\r
-       /// Get minimal value of the data and its approximated position\r
-       inline mreal Minimal(mreal &x,mreal &y,mreal &z) const\r
-       {       return mgl_data_min_real(this,&x,&y,&z);        }\r
 \r
-       /// Copy data from other mglData variable\r
-       inline mglDataC &operator=(const mglData &d)\r
-       {       Set(&d);        return *this;   }\r
-       /// Copy data from other mglDataC variable\r
-       inline mglDataC &operator=(const mglDataC &d)\r
-       {       if(this!=&d)    Set(d.a,d.nx,d.ny,d.nz);        return *this;   }\r
+       /// Copy data from other mglDataA variable\r
+       inline const mglDataA &operator=(const mglDataA &d)\r
+       {       if(this!=&d)    Set(&d);        return d;       }\r
+       inline const mglDataC &operator=(const mglDataC &d)\r
+       {       if(this!=&d)    Set(&d);        return d;       }\r
        inline dual operator=(dual val)\r
        {       for(long i=0;i<nx*ny*nz;i++)    a[i]=val;       return val;     }\r
+       inline dual operator=(mreal val)\r
+       {       for(long i=0;i<nx*ny*nz;i++)    a[i]=val;       return val;     }\r
 #ifndef SWIG\r
        /// Direct access to the data cell\r
        inline dual &operator[](long i) {       return a[i];    }\r
 #endif\r
 \r
-       /// Get the value in given cell of the data without border checking\r
-       inline mreal v(long i,long j=0,long k=0) const\r
-#ifdef DEBUG\r
-       {       if(i<0 || j<0 || k<0 || i>=nx || j>=ny || k>=nz)        printf("Wrong index in mglData");\r
-               return abs(a[i+nx*(j+ny*k)]);   }\r
+\r
+#ifndef DEBUG\r
+       /// Get the value in given cell of the data\r
+       mreal v(long i,long j=0,long k=0) const {       return abs(a[i+nx*(j+ny*k)]);   }\r
+       /// Set the value in given cell of the data\r
+       void set_v(mreal val, long i,long j=0,long k=0) {       a[i+nx*(j+ny*k)]=val;   }\r
 #else\r
-       {       return abs(a[i+nx*(j+ny*k)]);   }\r
+       /// Get the value in given cell of the data with border checking\r
+       mreal v(long i,long j=0,long k=0) const {       return mgl_abs(mgl_datac_get_value(this,i,j,k));        }\r
+       /// Set the value in given cell of the data\r
+       void set_v(mreal val, long i,long j=0,long k=0) {       mgl_datac_set_value(this,val,i,j,k);    }\r
 #endif\r
-       inline mreal vthr(long i) const {       return abs(a[i]);       }\r
+       mreal vthr(long i) const {      return abs(a[i]);       }\r
        // add for speeding up !!!\r
-       inline mreal dvx(long i,long j=0,long k=0) const\r
+       mreal dvx(long i,long j=0,long k=0) const\r
        {   register long i0=i+nx*(j+ny*k);\r
                return i>0? abs(i<nx-1? (a[i0+1]-a[i0-1])/mgl2:a[i0]-a[i0-1]) : abs(a[i0+1]-a[i0]);     }\r
-       inline mreal dvy(long i,long j=0,long k=0) const\r
+       mreal dvy(long i,long j=0,long k=0) const\r
        {   register long i0=i+nx*(j+ny*k);\r
-       return j>0? abs(j<ny-1? (a[i0+nx]-a[i0-nx])/mgl2:a[i0]-a[i0-nx]) : abs(a[i0+nx]-a[i0]);}\r
-       inline mreal dvz(long i,long j=0,long k=0) const\r
+               return j>0? abs(j<ny-1? (a[i0+nx]-a[i0-nx])/mgl2:a[i0]-a[i0-nx]) : abs(a[i0+nx]-a[i0]);}\r
+       mreal dvz(long i,long j=0,long k=0) const\r
        {   register long i0=i+nx*(j+ny*k), n=nx*ny;\r
-       return k>0? abs(k<nz-1? (a[i0+n]-a[i0-n])/mgl2:a[i0]-a[i0-n]) : abs(a[i0+n]-a[i0]);     }\r
+               return k>0? abs(k<nz-1? (a[i0+n]-a[i0-n])/mgl2:a[i0]-a[i0-n]) : abs(a[i0+n]-a[i0]);     }\r
 };\r
 //-----------------------------------------------------------------------------\r
 #ifndef SWIG\r
-dual mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
-dual mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx=0, dual *dy=0, dual *dz=0);\r
+dual MGL_EXPORT_PURE mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
+dual MGL_EXPORT_PURE mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx=0, dual *dy=0, dual *dz=0);\r
+dual MGL_EXPORT_PURE mglSpline3Cs(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
 #endif\r
 //-----------------------------------------------------------------------------\r
 /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini\r
@@ -408,14 +405,23 @@ inline mglDataC mglQO3dc(const char *ham, const mglDataA &ini_re, const mglDataA
 inline mglDataC mglQO3dc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mglData &zz, mreal r=1, mreal k0=100)\r
 {      return mglDataC(true, mgl_qo3d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy, &zz));     }\r
 //-----------------------------------------------------------------------------\r
+/// Prepare coefficients for global spline interpolation\r
+inline mglDataC mglGSplineCInit(const mglDataA &xdat, const mglDataA &ydat)\r
+{      return mglDataC(true,mgl_gsplinec_init(&xdat, &ydat));  }\r
+/// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef\r
+inline dual mglGSplineC(const mglDataA &coef, mreal dx, dual *d1=0, dual *d2=0)\r
+{      return mgl_gsplinec(&coef, dx, d1,d2);  }\r
+//-----------------------------------------------------------------------------\r
 #define _DN_(a)        ((mglDataC *)*(a))\r
 #define _DC_           ((mglDataC *)*d)\r
 //-----------------------------------------------------------------------------\r
 #ifndef SWIG\r
-/// Wrapper class expression evaluating\r
+/// Wrapper class for complex expression evaluating\r
 class MGL_EXPORT mglExprC\r
 {\r
        HAEX ex;\r
+       mglExprC(const mglExprC &){}    // copying is not allowed\r
+       const mglExprC &operator=(const mglExprC &t){return t;} // copying is not allowed\r
 public:\r
        mglExprC(const char *expr)              {       ex = mgl_create_cexpr(expr);    }\r
        ~mglExprC()     {       mgl_delete_cexpr(ex);   }\r
index b932e4388ec63673f1610f2ef7de3b395d7a9c14..7c04af617872e10bd12eea073190f1609effc4fd 100644 (file)
@@ -43,10 +43,10 @@ void MGL_EXPORT mgl_srnd(long seed);
 /// Get random number\r
 double MGL_EXPORT mgl_rnd();\r
 /// Get integer power of x\r
-dual MGL_EXPORT mgl_ipowc(dual x,int n);\r
-dual MGL_EXPORT mgl_ipowc_(dual *x,int *n);\r
+mdual MGL_EXPORT_CONST mgl_ipowc(dual x,int n);\r
+mdual MGL_EXPORT_PURE mgl_ipowc_(dual *x,int *n);\r
 /// Get exp(i*a)\r
-dual MGL_EXPORT mgl_expi(dual a);\r
+mdual MGL_EXPORT_CONST mgl_expi(dual a);\r
 \r
 /// Create HMDT object\r
 HADT MGL_EXPORT mgl_create_datac();\r
@@ -87,14 +87,14 @@ void MGL_EXPORT mgl_datac_set_matrix(HADT dat, gsl_matrix *m);
 void MGL_EXPORT mgl_datac_set_value(HADT dat, dual v, long i, long j, long k);\r
 void MGL_EXPORT mgl_datac_set_value_(uintptr_t *d, dual *v, int *i, int *j, int *k);\r
 /// Get value of data element [i,j,k]\r
-dual MGL_EXPORT mgl_datac_get_value(HCDT dat, long i, long j, long k);\r
-dual MGL_EXPORT mgl_datac_get_value_(uintptr_t *d, int *i, int *j, int *k);\r
+mdual MGL_EXPORT mgl_datac_get_value(HCDT dat, long i, long j, long k);\r
+mdual MGL_EXPORT mgl_datac_get_value_(uintptr_t *d, int *i, int *j, int *k);\r
 /// Allocate memory and scanf the data from the string\r
 void MGL_EXPORT mgl_datac_set_values(HADT dat, const char *val, long nx, long ny, long nz);\r
 void MGL_EXPORT mgl_datac_set_values_(uintptr_t *d, const char *val, int *nx, int *ny, int *nz, int l);\r
 \r
 /// Returns pointer to internal data array\r
-MGL_EXPORT dual *mgl_datac_data(HADT dat);\r
+MGL_EXPORT_PURE dual *mgl_datac_data(HADT dat);\r
 /// Returns pointer to data element [i,j,k]\r
 MGL_EXPORT dual *mgl_datac_value(HADT dat, long i,long j,long k);\r
 \r
@@ -137,6 +137,38 @@ void MGL_EXPORT mgl_datac_create_(uintptr_t *dat, int *nx,int *ny,int *nz);
 /// Transpose dimensions of the data (generalization of Transpose)\r
 void MGL_EXPORT mgl_datac_transpose(HADT dat, const char *dim);\r
 void MGL_EXPORT mgl_datac_transpose_(uintptr_t *dat, const char *dim,int);\r
+\r
+/// Get sub-array of the data with given fixed indexes\r
+HADT MGL_EXPORT mgl_datac_subdata(HCDT dat, long xx,long yy,long zz);\r
+uintptr_t MGL_EXPORT mgl_datac_subdata_(uintptr_t *dat, int *xx,int *yy,int *zz);\r
+/// Get sub-array of the data with given fixed indexes (like indirect access)\r
+HADT MGL_EXPORT mgl_datac_subdata_ext(HCDT dat, HCDT xx, HCDT yy, HCDT zz);\r
+uintptr_t MGL_EXPORT mgl_datac_subdata_ext_(uintptr_t *dat, uintptr_t *xx,uintptr_t *yy,uintptr_t *zz);\r
+/// Get column (or slice) of the data filled by formulas of named columns\r
+HADT MGL_EXPORT mgl_datac_column(HCDT dat, const char *eq);\r
+uintptr_t MGL_EXPORT mgl_datac_column_(uintptr_t *dat, const char *eq,int l);\r
+/// Get trace of the data array\r
+HADT MGL_EXPORT mgl_datac_trace(HCDT d);\r
+uintptr_t MGL_EXPORT mgl_datac_trace_(uintptr_t *d);\r
+/// Resize the data to new sizes\r
+HADT MGL_EXPORT mgl_datac_resize(HCDT dat, long mx,long my,long mz);\r
+uintptr_t MGL_EXPORT mgl_datac_resize_(uintptr_t *dat, int *mx,int *my,int *mz);\r
+/// Resize the data to new sizes of box [x1,x2]*[y1,y2]*[z1,z2]\r
+HADT MGL_EXPORT mgl_datac_resize_box(HCDT dat, long mx,long my,long mz,mreal x1,mreal x2,mreal y1,mreal y2,mreal z1,mreal z2);\r
+uintptr_t MGL_EXPORT mgl_datac_resize_box_(uintptr_t *dat, int *mx,int *my,int *mz,mreal *x1,mreal *x2,mreal *y1,mreal *y2,mreal *z1,mreal *z2);\r
+/// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on.\r
+HADT MGL_EXPORT mgl_datac_momentum(HCDT dat, char dir, const char *how);\r
+uintptr_t MGL_EXPORT mgl_datac_momentum_(uintptr_t *dat, char *dir, const char *how, int,int);\r
+/// Get array which values is result of interpolation this for coordinates from other arrays\r
+HADT MGL_EXPORT mgl_datac_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm);\r
+uintptr_t MGL_EXPORT mgl_datac_evaluate_(uintptr_t *dat, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm);\r
+/// Get array which is result of summation in given direction or directions\r
+HADT MGL_EXPORT mgl_datac_sum(HCDT dat, const char *dir);\r
+uintptr_t MGL_EXPORT mgl_datac_sum_(uintptr_t *dat, const char *dir,int);\r
+/// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on)\r
+HADT MGL_EXPORT mgl_datac_combine(HCDT dat1, HCDT dat2);\r
+uintptr_t MGL_EXPORT mgl_datac_combine_(uintptr_t *dat1, uintptr_t *dat2);\r
+\r
 /// Set names for columns (slices)\r
 void MGL_EXPORT mgl_datac_set_id(HADT d, const char *id);\r
 void MGL_EXPORT mgl_datac_set_id_(uintptr_t *dat, const char *id,int l);\r
@@ -227,18 +259,23 @@ HMDT MGL_EXPORT mgl_datac_arg(HCDT dat);
 uintptr_t MGL_EXPORT mgl_datac_arg_(uintptr_t *dat);\r
 \r
 /// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
-dual MGL_EXPORT mgl_datac_linear(HCDT d, mreal x,mreal y,mreal z);\r
-dual MGL_EXPORT mgl_datac_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z);\r
+mdual MGL_EXPORT_PURE mgl_datac_linear(HCDT d, mreal x,mreal y,mreal z);\r
+mdual MGL_EXPORT_PURE mgl_datac_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z);\r
 /// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
-dual MGL_EXPORT mgl_datac_linear_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz);\r
-dual MGL_EXPORT mgl_datac_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz);\r
+mdual MGL_EXPORT_PURE mgl_datac_linear_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz);\r
+mdual MGL_EXPORT_PURE mgl_datac_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz);\r
 /// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
-dual MGL_EXPORT mgl_datac_spline(HCDT dat, mreal x,mreal y,mreal z);\r
-dual MGL_EXPORT mgl_datac_spline_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);\r
+mdual MGL_EXPORT_PURE mgl_datac_spline(HCDT dat, mreal x,mreal y,mreal z);\r
+mdual MGL_EXPORT_PURE mgl_datac_spline_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);\r
 /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
-dual MGL_EXPORT mgl_datac_spline_ext(HCDT dat, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz);\r
-dual MGL_EXPORT mgl_datac_spline_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz);\r
-\r
+mdual MGL_EXPORT_PURE mgl_datac_spline_ext(HCDT dat, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz);\r
+mdual MGL_EXPORT_PURE mgl_datac_spline_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz);\r
+/// Prepare coefficients for global spline interpolation\r
+HADT MGL_EXPORT mgl_gsplinec_init(HCDT x, HCDT v);\r
+uintptr_t MGL_EXPORT mgl_gspline_init_(uintptr_t *x, uintptr_t *v);\r
+/// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef\r
+mdual MGL_EXPORT mgl_gsplinec(HCDT coef, mreal dx, dual *d1, dual *d2);\r
+mdual MGL_EXPORT mgl_gsplinec_(uintptr_t *c, mreal *dx, dual *d1, dual *d2);\r
 //-----------------------------------------------------------------------------\r
 /// Create HAEX object for expression evaluating\r
 HAEX MGL_EXPORT mgl_create_cexpr(const char *expr);\r
@@ -247,10 +284,10 @@ uintptr_t MGL_EXPORT mgl_create_cexpr_(const char *expr, int);
 void MGL_EXPORT mgl_delete_cexpr(HAEX ex);\r
 void MGL_EXPORT mgl_delete_cexpr_(uintptr_t *ex);\r
 /// Return value of expression for given x,y,z variables\r
-dual MGL_EXPORT mgl_cexpr_eval(HAEX ex, dual x, dual y,dual z);\r
-dual MGL_EXPORT mgl_cexpr_eval_(uintptr_t *ex, dual *x, dual *y, dual *z);\r
+mdual MGL_EXPORT_PURE mgl_cexpr_eval(HAEX ex, dual x, dual y,dual z);\r
+mdual MGL_EXPORT mgl_cexpr_eval_(uintptr_t *ex, dual *x, dual *y, dual *z);\r
 /// Return value of expression for given variables\r
-dual MGL_EXPORT mgl_cexpr_eval_v(HAEX ex, dual *vars);\r
+mdual MGL_EXPORT mgl_cexpr_eval_v(HAEX ex, dual *vars);\r
 \r
 #ifdef __cplusplus\r
 }\r
index 554490f87ef1e909ae7ff105b2d97d923966dbea..e7ceb2190e5c4be7cbc12d82931fa1a9cc5eb6a9 100644 (file)
 #ifndef SWIG\r
 \r
 #include "mgl2/dllexport.h"\r
-#ifdef MGL_SRC\r
+#if MGL_HAVE_ATTRIBUTE\r
+#define MGL_FUNC_CONST __attribute__((const))\r
+#define MGL_FUNC_PURE  __attribute__((pure))\r
+#else\r
+#define MGL_FUNC_CONST\r
+#define MGL_FUNC_PURE\r
+#endif\r
+#define MGL_EXPORT_CONST       MGL_EXPORT MGL_FUNC_CONST\r
+#define MGL_EXPORT_PURE                MGL_EXPORT MGL_FUNC_PURE\r
+#define MGL_LOCAL_CONST                MGL_NO_EXPORT MGL_FUNC_CONST\r
+#define MGL_LOCAL_PURE         MGL_NO_EXPORT MGL_FUNC_PURE\r
+\r
+#if MGL_HAVE_RVAL      // C++11 don't support register keyword\r
+#define register\r
+#endif\r
+\r
 #if MGL_HAVE_OMP\r
 #include <omp.h>\r
 #endif\r
-#endif\r
 \r
 #endif\r
 \r
-#define MGL_VER2       2.2     // minor version of MathGL 2.* (like 1.3 for v.2.1.3)\r
+#define MGL_VER2       3.0     // minor version of MathGL 2.* (like 1.3 for v.2.1.3)\r
 //-----------------------------------------------------------------------------\r
 #ifdef WIN32 //_MSC_VER needs this before math.h\r
 #define        _USE_MATH_DEFINES\r
@@ -77,32 +91,22 @@ typedef unsigned long uintptr_t;
 #include <string.h>\r
 #include <wchar.h>\r
 \r
-#if defined(_MSC_VER) || defined(__BORLANDC__)\r
-#define fmin(a,b)      ((a)<(b))?(a):(b)\r
-#define fmax(a,b)      ((a)>(b))?(a):(b)\r
-#endif\r
-\r
 #if defined(_MSC_VER)\r
+#if (_MSC_VER<1800)\r
 #define collapse(a)    // MSVS don't support OpenMP 3.*\r
 #define strtoull _strtoui64\r
 #define hypot  _hypot\r
 #define getcwd _getcwd\r
 #define chdir  _chdir // BORLAND has chdir\r
+#endif\r
 #define snprintf _snprintf\r
 #endif\r
 \r
-#if defined(_MSC_VER) || defined(__BORLANDC__)\r
+#if !MGL_SYS_NAN\r
 #include <float.h>\r
 #include <math.h>\r
-\r
-#ifdef WIN32\r
 const unsigned long long mgl_nan[2] = {0x7fffffffffffffff, 0x7fffffff};\r
 const unsigned long long mgl_inf[2] = {0x7ff0000000000000, 0x7f800000};\r
-#else\r
-const unsigned long mgl_nan[2] = {0x7fffffffffffffff, 0x7fffffff};\r
-const unsigned long mgl_inf[2] = {0x7ff0000000000000, 0x7f800000};\r
-#endif\r
-\r
 #define NANd    (*(double*)mgl_nan)\r
 #define NANf    (*(float*)(mgl_nan+1))\r
 #define INFd    (*(double*)mgl_inf)\r
@@ -123,8 +127,7 @@ const unsigned long mgl_inf[2] = {0x7ff0000000000000, 0x7f800000};
 #define INFINITY       INFf\r
 #endif\r
 #endif\r
-\r
-#endif\r
+#endif // !MGL_SYS_NAN\r
 \r
 #ifndef M_PI\r
 #define M_PI   3.14159265358979323846  /* pi */\r
@@ -154,13 +157,23 @@ typedef float mreal;
 #define MGL_DEF_VIEWER "evince"\r
 #endif\r
 //-----------------------------------------------------------------------------\r
+#if MGL_HAVE_TYPEOF\r
+#define mgl_isbad(a)   ({typeof (a) _a = (a); _a-_a!=mreal(0.);})\r
+#define mgl_isfin(a)   ({typeof (a) _a = (a); _a-_a==mreal(0.);})\r
+#define mgl_isnum(a)   ({typeof (a) _a = (a); _a==_a;})\r
+#define mgl_isnan(a)   ({typeof (a) _a = (a); _a!=_a;})\r
+#define mgl_min(a,b)   ({typeof (a) _a = (a); typeof (b) _b = (b); _a > _b ? _b : _a;})\r
+#define mgl_max(a,b)   ({typeof (a) _a = (a); typeof (b) _b = (b); _a > _b ? _a : _b;})\r
+#define mgl_sign(a)            ({typeof (a) _a = (a); _a<0 ? -1:1;})\r
+#else\r
 #define mgl_min(a,b)   (((a)>(b)) ? (b) : (a))\r
 #define mgl_max(a,b)   (((a)>(b)) ? (a) : (b))\r
 #define mgl_isnan(a)   ((a)!=(a))\r
-//#define mgl_isnum(a) ((a)==(a) && 2*(a)!=(a))\r
 #define mgl_isnum(a)   ((a)==(a))\r
-#define mgl_isfin(a)   ((a)-(a)==0.)\r
-#define mgl_isbad(a)   ((a)-(a)!=0.)\r
+#define mgl_isfin(a)   ((a)-(a)==mreal(0.))\r
+#define mgl_isbad(a)   ((a)-(a)!=mreal(0.))\r
+#define mgl_sign(a)            ((a)<0 ? -1:1)\r
+#endif\r
 //-----------------------------------------------------------------------------\r
 #define SMOOTH_NONE            0\r
 #define SMOOTH_LINE_3  1\r
@@ -226,6 +239,11 @@ enum{      // Codes for warnings/messages
 #define MGL_DEF_SCH    "BbcyrR"        // default palette\r
 #define MGL_COLORS     "kwrgbcymhWRGBCYMHlenpquLENPQU"\r
 //-----------------------------------------------------------------------------\r
+/// Brushes for mask with symbol "-+=;oOsS~<>jdD*^" correspondingly\r
+extern uint64_t mgl_mask_val[16];\r
+#define MGL_MASK_ID            "-+=;oOsS~<>jdD*^"\r
+#define MGL_SOLID_MASK 0xffffffffffffffff\r
+//-----------------------------------------------------------------------------\r
 #define MGL_TRANSP_NORM                0x000000\r
 #define MGL_TRANSP_GLASS       0x000001\r
 #define MGL_TRANSP_LAMP                0x000002\r
@@ -250,34 +268,46 @@ enum{     // Codes for warnings/messages
 #define MGL_ONESIDED           0x080000        ///< Render only front side of surfaces if output format supports (for debugging)\r
 #define MGL_NO_ORIGIN          0x100000        ///< Don't draw tick labels at axis origin\r
 //-----------------------------------------------------------------------------\r
+#if MGL_HAVE_C99_COMPLEX\r
+#include <complex.h>\r
+#if MGL_USE_DOUBLE\r
+typedef double _Complex mdual;\r
+#else\r
+typedef float _Complex mdual;\r
+#endif\r
+#define mgl_abs(x)     cabs(x)\r
+#endif\r
 #ifdef __cplusplus\r
 //-----------------------------------------------------------------------------\r
 extern float mgl_cos[360];     ///< contain cosine with step 1 degree\r
 //-----------------------------------------------------------------------------\r
 #include <complex>\r
 typedef std::complex<mreal> dual;\r
+typedef std::complex<double> ddual;\r
+#if !MGL_HAVE_C99_COMPLEX\r
+#define mdual dual\r
+#define _Complex_I dual(0,1)\r
+#define mgl_abs(x)     abs(x)\r
+#endif\r
 //-----------------------------------------------------------------------------\r
 extern "C" {\r
 #else\r
 #include <complex.h>\r
-#if MGL_USE_DOUBLE\r
-typedef double _Complex dual;\r
-#else\r
-typedef float _Complex dual;\r
-#endif\r
+typedef double _Complex ddual;\r
+#define dual   mdual\r
 #endif\r
 /// Find length of wchar_t string (bypass standard wcslen bug)\r
-double MGL_EXPORT mgl_hypot(double x, double y);\r
+double MGL_EXPORT_CONST mgl_hypot(double x, double y);\r
 /// Find length of wchar_t string (bypass standard wcslen bug)\r
-size_t MGL_EXPORT mgl_wcslen(const wchar_t *str);\r
+size_t MGL_EXPORT_PURE mgl_wcslen(const wchar_t *str);\r
 /// Get RGB values for given color id or fill by -1 if no one found\r
 void MGL_EXPORT mgl_chrrgb(char id, float rgb[3]);\r
 /// Check if string contain color id and return its number\r
-long MGL_EXPORT mgl_have_color(const char *stl);\r
+long MGL_EXPORT_PURE mgl_have_color(const char *stl);\r
 /// Find symbol in string excluding {} and return its position or NULL\r
-const char *mglchr(const char *str, char ch);\r
+MGL_EXPORT_PURE const char *mglchr(const char *str, char ch);\r
 /// Find any symbol from chr in string excluding {} and return its position or NULL\r
-const char *mglchrs(const char *str, const char *chr);\r
+MGL_EXPORT_PURE const char *mglchrs(const char *str, const char *chr);\r
 /// Set number of thread for plotting and data handling (for pthread version only)\r
 void MGL_EXPORT mgl_set_num_thr(int n);\r
 void MGL_EXPORT mgl_set_num_thr_(int *n);\r
index 65dcb9594b3c80c424b055f6f86415f0c22b244f..9043ccf4ece58987947d3fe45e35e6a7aa57a884 100644 (file)
@@ -33,29 +33,29 @@ class MGL_EXPORT mglFormula                                 // îáúåêò äëÿ ââîäà è âû÷èñ
 {\r
 public:\r
        /// Evaluates the formula for 'x','r'=\a x, 'y','n'=\a y, 'z','t'=\a z, 'u'=\a u\r
-       mreal Calc(mreal x,mreal y=0,mreal z=0,mreal u=0) const;\r
+       mreal Calc(mreal x,mreal y=0,mreal z=0,mreal u=0) const MGL_FUNC_PURE;\r
        /// Evaluates the formula for 'x, y, z, u, v, w'\r
-       mreal Calc(mreal x,mreal y,mreal z,mreal u,mreal v,mreal w) const;\r
+       mreal Calc(mreal x,mreal y,mreal z,mreal u,mreal v,mreal w) const MGL_FUNC_PURE;\r
        /// Evaluates the formula for variables var\r
-       mreal Calc(const mreal var[MGL_VS]) const;\r
+       mreal Calc(const mreal var[MGL_VS]) const MGL_FUNC_PURE;\r
        /// Evaluates the formula for 'x','r'=\a x, 'y','n'=\a y, 'z','t'=\a z, 'u'=\a u\r
-       mreal CalcD(char diff, mreal x,mreal y=0,mreal z=0,mreal u=0) const;\r
+       mreal CalcD(char diff, mreal x,mreal y=0,mreal z=0,mreal u=0) const MGL_FUNC_PURE;\r
        /// Evaluates the formula for 'x, y, z, u, v, w'\r
-       mreal CalcD(char diff, mreal x,mreal y,mreal z,mreal u,mreal v,mreal w) const;\r
+       mreal CalcD(char diff, mreal x,mreal y,mreal z,mreal u,mreal v,mreal w) const MGL_FUNC_PURE;\r
        /// Evaluates the derivates of the formula for variables var respect to variable diff\r
-       mreal CalcD(const mreal var[MGL_VS], char diff) const;\r
+       mreal CalcD(const mreal var[MGL_VS], char diff) const MGL_FUNC_PURE;\r
        /// Return error code\r
-       int GetError() const;\r
+       inline int GetError() const     {       return Error;   }\r
        /// Parse the formula str and create formula-tree\r
        mglFormula(const char *str);\r
        /// Clean up formula-tree\r
        ~mglFormula();\r
 protected:\r
-       mreal CalcIn(const mreal *a1) const;\r
-       mreal CalcDIn(int id, const mreal *a1) const;\r
+       mreal CalcIn(const mreal *a1) const MGL_FUNC_PURE;\r
+       mreal CalcDIn(int id, const mreal *a1) const MGL_FUNC_PURE;\r
        mglFormula *Left,*Right;        // first and second argument of the function\r
        int Kod;                                        // the function ID\r
-       mreal Res;                              // the number or the variable ID\r
+       mreal Res;                                      // the number or the variable ID\r
        static int Error;\r
 };\r
 //-----------------------------------------------------------------------------\r
index 34d81151bf94f2030f4e5d42cb8b5680e98b87eb..202ca81badaa07db24838e40321e323b5ba5dfae 100644 (file)
@@ -27,21 +27,21 @@ class MGL_EXPORT mglFormulaC                                        // ������ ��� �����
 {\r
 public:\r
        /// Evaluates the formula for 'x','r'=\a x, 'y','n'=\a y, 'z','t'=\a z, 'u'=\a u\r
-       dual Calc(dual x,dual y=0,dual z=0,dual u=0) const;\r
+       dual Calc(dual x,dual y=0,dual z=0,dual u=0) const MGL_FUNC_PURE;\r
        /// Evaluates the formula for 'x, y, z, u, v, w'\r
-       dual Calc(dual x,dual y,dual z,dual u,dual v,dual w) const;\r
+       dual Calc(dual x,dual y,dual z,dual u,dual v,dual w) const MGL_FUNC_PURE;\r
        /// Evaluates the formula for variables var\r
-       dual Calc(const dual var[MGL_VS]) const;\r
+       dual Calc(const dual var[MGL_VS]) const MGL_FUNC_PURE;\r
        /// Return error code\r
-       int GetError() const;\r
+       inline int GetError() const     {       return Error;   }\r
        /// Parse the formula str and create formula-tree\r
        mglFormulaC(const char *str);\r
        /// Clean up formula-tree\r
        virtual ~mglFormulaC();\r
 protected:\r
-       dual CalcIn(const dual *a1) const;\r
+       dual CalcIn(const dual *a1) const MGL_FUNC_PURE;\r
        mglFormulaC *Left,*Right;       // first and second argument of the function\r
-       int Kod;                                                // the function ID\r
+       int Kod;                                        // the function ID\r
        dual Res;                                       // the number or the variable ID\r
        static int Error;\r
 };\r
index 1ea4598d84b9785b54de14533258914a7653433f..0b8a1a02346cf5047f1f5bac621f6d896556b46f 100644 (file)
@@ -38,7 +38,8 @@ HMDT MGL_EXPORT mgl_fit_xys(HMGL gr, HCDT x, HCDT y, HCDT s, const char *eq, con
 HMDT MGL_EXPORT mgl_fit_xyzs(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT s, const char *eq, const char *vars, HMDT ini, const char *opt);\r
 HMDT MGL_EXPORT mgl_fit_xyzas(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT s, const char *eq, const char *vars, HMDT ini, const char *opt);\r
 \r
-MGL_EXPORT const char *mgl_get_fit(HMGL gr);\r
+MGL_EXPORT_CONST const char *mgl_get_fit(HMGL gr);\r
+int MGL_EXPORT mgl_get_fit_(uintptr_t *gr, char *out, int len);\r
 \r
 HMDT MGL_EXPORT mgl_hist_x(HMGL gr, HCDT x, HCDT a, const char *opt);\r
 HMDT MGL_EXPORT mgl_hist_xy(HMGL gr, HCDT x, HCDT y, HCDT a, const char *opt);\r
index b1ba71917511779a8c15d9e8ba3476e05b5dee7a..9ddf91f466c9a3c3f2112734e76652f3fe90d246 100644 (file)
@@ -61,8 +61,8 @@ public:
 #endif\r
 \r
 #include <FL/Fl.H>\r
-#include <Fl/Fl_Window.H>\r
-#include <Fl/Fl_Scroll.H>\r
+#include <FL/Fl_Window.H>\r
+#include <FL/Fl_Scroll.H>\r
 #include <FL/Fl_Button.H>\r
 #include <FL/Fl_Counter.H>\r
 #include <FL/Fl_Menu_Bar.H>\r
@@ -76,7 +76,7 @@ public:
        Fl_Valuator     *phi_val;       ///< pointer to external phi-angle validator\r
 \r
        Fl_MathGL(int x, int y, int w, int h, const char *label=0);\r
-       ~Fl_MathGL();\r
+       virtual ~Fl_MathGL();\r
 \r
        /// Update (redraw) plot\r
        virtual void update();\r
@@ -108,6 +108,7 @@ public:
        {       popup = pmenu;  wpar = wdg;     vpar = v;       }\r
        inline void zoom_region(mreal xx1,mreal xx2,mreal yy1, mreal yy2)\r
        {       x1=xx1; y1=yy1; x2=xx2; y2=yy2; }\r
+       void stop(bool stop=true);\r
 \r
 protected:\r
        mglCanvas *gr;          ///< pointer to grapher\r
@@ -159,7 +160,7 @@ public:
        {       mgl_set_size(FMGL->get_graph(),scroll->w(),scroll->h());        FMGL->size(scroll->w(),scroll->h());    update();       }\r
 \r
        Fl_MGLView(int x, int y, int w, int h, const char *label=0);\r
-       ~Fl_MGLView();\r
+       virtual ~Fl_MGLView();\r
        void update();                  ///< Update picture by calling user drawing function\r
 protected:\r
        Fl_Button *alpha_bt, *light_bt, *rotate_bt, *anim_bt, *zoom_bt, *grid_bt;\r
index 2666c097068096f57832a74650df517e794dbfc7..2e08a018675b61cdd63bba0f8b37ad14ec12399d 100644 (file)
 #define MGL_DEF_FONT_NAME      "STIX"\r
 #endif\r
 //-----------------------------------------------------------------------------\r
+struct mglGlyphDescr\r
+{\r
+       wchar_t id;             ///< Unicode ID for glyph\r
+       int tr[4];              ///< Shift of glyph description by triangles (for solid font)\r
+       int ln[4];              ///< Shift of glyph description by lines (for wire font)\r
+       short numt[4];  ///< Number of triangles in glyph description (for solid font)\r
+       short numl[4];  ///< Number of lines in glyph description (for wire font)\r
+       short width[4]; ///< Width of glyph for wire font\r
+       mglGlyphDescr() {       memset(this,0,sizeof(mglGlyphDescr));   }\r
+};\r
+inline bool operator<(const mglGlyphDescr &a,const mglGlyphDescr &b)   {       return a.id<b.id;       }\r
+inline bool operator>(const mglGlyphDescr &a,const mglGlyphDescr &b)   {       return a.id>b.id;       }\r
+//-----------------------------------------------------------------------------\r
 struct MGL_EXPORT mglTeXsymb   {       unsigned kod;   const wchar_t *tex;     };\r
 const float mgl_fgen = 4*14;\r
 /// Get font color, style and align for internal parser\r
-char mglGetStyle(const char *how, int *font, int *align=0);\r
+bool MGL_EXPORT mglGetStyle(const char *how, int *font, int *align=0);\r
+long MGL_EXPORT_PURE mgl_internal_code(unsigned s, const std::vector<mglGlyphDescr> &glyphs);\r
 class mglBase;\r
 //-----------------------------------------------------------------------------\r
 /// Class for font typeface and text plotting procedures\r
@@ -56,7 +70,7 @@ class MGL_EXPORT mglFont
 public:\r
        mglBase *gr;    ///< mglBase class used for drawing characters\r
        mglFont(const char *name=0, const char *path=0);\r
-       ~mglFont();\r
+       virtual ~mglFont();\r
        bool parse;             ///< Parse LaTeX symbols\r
 \r
        /// Load font data to memory. Normally used by constructor.\r
@@ -68,46 +82,41 @@ public:
        /// Restore default font\r
        void Restore();\r
        /// Return true if font is loaded\r
-       inline bool Ready() const       {       return numg!=0; }\r
+       inline bool Ready() const       {       return GetNumGlyph()!=0;        }\r
 \r
        /// Get height of text\r
-       float Height(int font) const;\r
+       float Height(int font) const MGL_FUNC_PURE;\r
        /// Get height of text\r
-       float Height(const char *how) const;\r
+       float Height(const char *how) const MGL_FUNC_PURE;\r
        /// Print text string for font specified by string\r
-       float Puts(const char *str,const char *how,float col) const;\r
+       float Puts(const char *str,const char *how,float c1,float c2) const;\r
        /// Get width of text string for font specified by string\r
        float Width(const char *str,const char *how) const;\r
        /// Print text string for font specified by string\r
-       float Puts(const wchar_t *str,const char *how,float col) const;\r
+       float Puts(const wchar_t *str,const char *how,float c1,float c2) const;\r
        /// Get width of text string for font specified by string\r
        float Width(const wchar_t *str,const char *how) const;\r
 \r
        /// Get internal code for symbol\r
-       long Internal(unsigned s) const;\r
+       inline long Internal(unsigned s) const  {       return mgl_internal_code(s,glyphs);     }\r
        /// Return number of glyphs\r
-       inline unsigned GetNumGlyph() const     {       return numg;    };\r
+       inline unsigned GetNumGlyph() const     {       return glyphs.size();   };\r
        /// Return some of pointers\r
-       inline const short *GetTr(int s, long j) const  {       return Buf+tr[s][j];    }\r
-       inline const short *GetLn(int s, long j) const  {       return Buf+ln[s][j];    }\r
-       inline int GetNt(int s, long j) const   {       return numt[s][j];      }\r
-       inline int GetNl(int s, long j) const   {       return numl[s][j];      }\r
-       inline short GetWidth(int s, long j) const      {       return width[s][j];     }\r
-       inline float GetFact(int s) const               {       return fact[s]; }\r
+       inline const short *GetTr(int s, long j) const  {       return Buf+glyphs[j].tr[s];     }\r
+       inline const short *GetLn(int s, long j) const  {       return Buf+glyphs[j].ln[s];     }\r
+       inline int GetNt(int s, long j) const           {       return glyphs[j].numt[s];       }\r
+       inline int GetNl(int s, long j) const           {       return glyphs[j].numl[s];       }\r
+       inline short GetWidth(int s, long j) const      {       return glyphs[j].width[s];      }\r
+       inline float GetFact(int s) const                       {       return fact[s]; }\r
+       inline wchar_t GetUnicode(long j) const         {       return j>=0?glyphs[j].id:0;     }\r
 protected:\r
-       wchar_t *id;    ///< Unicode ID for glyph\r
-       int *tr[4];             ///< Shift of glyph description by triangles (for solid font)\r
-       int *ln[4];             ///< Shift of glyph description by lines (for wire font)\r
-       short *numt[4]; ///< Number of triangles in glyph description (for solid font)\r
-       short *numl[4]; ///< Number of lines in glyph description (for wire font)\r
-       short *width[4];///< Width of glyph for wire font\r
+       std::vector<mglGlyphDescr> glyphs;      ///< information about know glyphs\r
        float fact[4];  ///< Divider for width of glyph\r
-       unsigned numg;  ///< Number of glyphs\r
        short *Buf;             ///< Buffer for glyph descriptions\r
        long numb;              ///< Buffer size\r
 \r
        /// Print text string for font specified by integer constant\r
-       float Puts(const wchar_t *str,int font,int align, float col) const;\r
+       float Puts(const wchar_t *str,int font,int align, float c1,float c2) const;\r
        /// Get width of text string for font specified by integer constant\r
        float Width(const wchar_t *str,int font=0) const;\r
        /// Replace TeX symbols by its UTF code and add font styles\r
@@ -115,17 +124,17 @@ protected:
 \r
        /// Draw string recursively\r
        /* x,y - position, f - factor, style: 0x1 - italic, 0x2 - bold, 0x4 - overline, 0x8 - underline, 0x10 - empty (not draw) */\r
-       float Puts(const unsigned *str, float x,float y,float f,int style,float col) const;\r
+       float Puts(const unsigned *str, float x,float y,float f,int style,float c1,float c2) const;\r
        /// Parse LaTeX command\r
        unsigned Parse(const wchar_t *s) const;\r
        /// Get symbol for character ch with given font style\r
-       unsigned Symbol(char ch) const;\r
+       unsigned Symbol(char ch) const MGL_FUNC_PURE;\r
 private:\r
        float get_ptr(long &i,unsigned *str, unsigned **b1, unsigned **b2,float &w1,float &w2, float f1, float f2, int st) const;\r
-       bool read_data(const char *fname, float *ff, short *wdt, short *numl, int *posl, short *numt, int *post, std::vector<short> &buf);\r
+       bool read_data(const char *fname, int s, std::vector<short> &buf, std::vector<mglGlyphDescr> &extra);\r
        void main_copy();\r
        bool read_main(const char *fname, std::vector<short> &buf);\r
-       void mem_alloc();\r
+       inline void mem_alloc(long numg)        {       glyphs.resize(numg);    }\r
        bool read_def();\r
        void draw_ouline(int st, float x, float y, float f, float g, float ww, float ccol) const;\r
 };\r
index 8266c966e60cd7ce90268cf513e8b6d06e77b992..91530bf2fc9a37418c01a0e8f74322c563babf45 100644 (file)
@@ -49,7 +49,7 @@ public:
        {       gr = graph;             mgl_use_graph(gr,1);    }\r
        virtual ~mglGraph()\r
        {       if(mgl_use_graph(gr,-1)<1)      mgl_delete_graph(gr);   }\r
-       /// Get pointer to internal mglCanvas object\r
+       /// Get pointer to internal HMGL object\r
        inline HMGL Self()      {       return gr;      }\r
        /// Set default parameters for plotting\r
        inline void DefaultPlotParam()                  {       mgl_set_def_param(gr);  }\r
@@ -58,6 +58,14 @@ public:
        /// Get name of plot for saving filename\r
        inline const char *GetPlotId()  {       return mgl_get_plotid(gr);      }\r
 \r
+       /// Ask to stop drawing\r
+       inline void Stop(bool stop=true)        {       mgl_ask_stop(gr, stop); }\r
+       /// Check if plot termination is asked\r
+       inline bool NeedStop()  {       return mgl_need_stop(gr);       }\r
+       /// Set callback function for event processing\r
+       inline void SetEventFunc(void (*func)(void *), void *par=NULL)\r
+       {       mgl_set_event_func(gr, func, par);      }\r
+\r
        /// Set the transparency on/off.\r
        inline void Alpha(bool enable)                  {       mgl_set_alpha(gr, enable);      }\r
        /// Set default value of alpha-channel\r
@@ -216,9 +224,16 @@ public:
        {       mgl_set_ticks_val(gr,dir,&v,lbl,add);   }\r
        inline void SetTicksVal(char dir, const mglDataA &v, const wchar_t *lbl, bool add=false)\r
        {       mgl_set_ticks_valw(gr,dir,&v,lbl,add);  }\r
-       /// Set the ticks parameters\r
-       inline void SetTicks(char dir, double d=0, int ns=0, double org=NaN)\r
-       {       mgl_set_ticks(gr, dir, d, ns, org);     }\r
+       /// Add manual tick at given position. Use "" to disable this feature.\r
+       inline void AddTick(char dir, double val, const char *lbl)\r
+       {       mgl_add_tick(gr,dir,val,lbl);   }\r
+       inline void AddTick(char dir, double val, const wchar_t *lbl)\r
+       {       mgl_add_tickw(gr,dir,val,lbl);  }\r
+       /// Set the ticks parameters and string for its factor\r
+       inline void SetTicks(char dir, double d=0, int ns=0, double org=NaN, const char *factor="")\r
+       {       mgl_set_ticks_fact(gr, dir, d, ns, org, factor);        }\r
+       inline void SetTicks(char dir, double d, int ns, double org, const wchar_t *factor)\r
+       {       mgl_set_ticks_factw(gr, dir, d, ns, org, factor);       }\r
        /// Auto adjust ticks\r
        inline void Adjust(const char *dir="xyzc")\r
        {       mgl_adjust_ticks(gr, dir);      }\r
@@ -288,6 +303,9 @@ public:
        /// Set angle of view independently from Rotate().\r
        inline void View(double TetX,double TetZ=0,double TetY=0)\r
        {       mgl_view(gr, TetX, TetZ, TetY); }\r
+       /// Set angle of view independently from Rotate().\r
+       inline void ViewAsRotate(double TetZ,double TetX,double TetY=0)\r
+       {       mgl_view(gr, -TetX, -TetZ, -TetY);      }\r
        /// Zoom in/out a part of picture (use Zoom(0, 0, 1, 1) for restore default)\r
        inline void Zoom(double x1, double y1, double x2, double y2)\r
        {       mgl_zoom(gr, x1, y1, x2, y2);   }\r
@@ -388,6 +406,8 @@ public:
        inline void SetFrame(int i)     {       mgl_set_frame(gr, i);   }\r
        /// Append drawing data from i-th frame (work if MGL_VECT_FRAME is set on)\r
        inline void ShowFrame(int i){   mgl_show_frame(gr, i);  }\r
+       /// Clear list of primitives for current drawing\r
+       inline void ClearFrame()        {       mgl_clear_frame(gr);    }\r
 \r
        /// Start write frames to cinema using GIF format\r
        inline void StartGIF(const char *fname, int ms=100)\r
@@ -402,21 +422,23 @@ public:
        {       mgl_import_mgld(gr, fname, add);        }\r
 \r
        /// Copy RGB values into array which is allocated by user\r
-       inline void GetRGB(char *imgdata, int imglen)\r
+       inline bool GetRGB(char *imgdata, int imglen)\r
        {\r
                long w=mgl_get_width(gr), h=mgl_get_height(gr);\r
                if(imglen>=3*w*h)       memcpy(imgdata, mgl_get_rgb(gr),3*w*h);\r
+               return imglen>=3*w*h;\r
        }\r
        inline const unsigned char *GetRGB()            {       return mgl_get_rgb(gr); }\r
        /// Copy RGBA values into array which is allocated by user\r
-       inline void GetRGBA(char *imgdata, int imglen)\r
+       inline bool GetRGBA(char *imgdata, int imglen)\r
        {\r
                long w=mgl_get_width(gr), h=mgl_get_height(gr);\r
                if(imglen>=4*w*h)       memcpy(imgdata, mgl_get_rgba(gr),4*w*h);\r
+               return imglen>=4*w*h;\r
        }\r
        inline const unsigned char *GetRGBA()   {       return mgl_get_rgba(gr);        }\r
        /// Copy BGRN values into array which is allocated by user\r
-       inline void GetBGRN(unsigned char *imgdata, int imglen)\r
+       inline bool GetBGRN(unsigned char *imgdata, int imglen)\r
        {\r
                long w=mgl_get_width(gr), h=mgl_get_height(gr), i;\r
                const unsigned char *buf=mgl_get_rgb(gr);\r
@@ -427,7 +449,16 @@ public:
                        imgdata[4*i+2] = buf[3*i];\r
                        imgdata[4*i+3] = 255;\r
                }\r
+               return imglen>=4*w*h;\r
+       }\r
+       /// Copy RGBA values of background image into array which is allocated by user\r
+       inline bool GetBackground(char *imgdata, int imglen)\r
+       {\r
+               long w=mgl_get_width(gr), h=mgl_get_height(gr);\r
+               if(imglen>=4*w*h)       memcpy(imgdata, mgl_get_background(gr),4*w*h);\r
+               return imglen>=4*w*h;\r
        }\r
+       inline const unsigned char *GetBackground()     {       return mgl_get_background(gr);  }\r
        /// Get width of the image\r
        inline int GetWidth()   {       return mgl_get_width(gr);       }\r
        /// Get height of the image\r
@@ -460,10 +491,18 @@ public:
 \r
        /// Clear up the frame\r
        inline void Clf(double r, double g, double b)   {       mgl_clf_rgb(gr, r, g, b);       }\r
+       inline void Clf(const char *col)        {       mgl_clf_str(gr, col);   }\r
        inline void Clf(char col)       {       mgl_clf_chr(gr, col);   }\r
        inline void Clf()       {       mgl_clf(gr);    }\r
        /// Clear unused points and primitives. Useful only in combination with SetFaceNum().\r
        inline void ClearUnused()       {       mgl_clear_unused(gr);   }\r
+\r
+       /// Load background image\r
+       inline void LoadBackground(const char *fname, double alpha=1)\r
+       {       mgl_load_background(gr,fname,alpha);    }\r
+       /// Force drawing the image and use it as background one\r
+       inline void Rasterize()                 {       mgl_rasterize(gr);      }\r
+\r
        /// Draws the point (ball) at position {x,y,z} with color c\r
        inline void Ball(mglPoint p, char c='r')\r
        {       char s[3]={'.',c,0};    mgl_mark(gr, p.x, p.y, p.z, s); }\r
@@ -510,6 +549,15 @@ public:
        /// Draws the rhomb between points p1,p2 with color stl and width r\r
        inline void Rhomb(mglPoint p1, mglPoint p2, double r, const char *stl="r")\r
        {       mgl_rhomb(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, r,stl);       }\r
+       /// Draws the polygon based on points p1,p2 with color stl\r
+       inline void Polygon(mglPoint p1, mglPoint p2, int n, const char *stl="r")\r
+       {       mgl_polygon(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, n,stl);     }\r
+       /// Draws the arc around axis pr with center at p0 and starting from p1, by color stl and angle a (in degrees)\r
+       inline void Arc(mglPoint p0, mglPoint pr, mglPoint p1, double a, const char *stl="r")\r
+       {       mgl_arc_ext(gr, p0.x,p0.y,p0.z, pr.x,pr.y,pr.z, p1.x,p1.y,p1.z, a,stl); }\r
+       /// Draws the arc around axis 'z' with center at p0 and starting from p1, by color stl and angle a (in degrees)\r
+       inline void Arc(mglPoint p0, mglPoint p1, double a, const char *stl="r")\r
+       {       mgl_arc_ext(gr, p0.x,p0.y,p0.z, 0,0,1, p1.x,p1.y,p0.z, a,stl);  }\r
 \r
        /// Print text in position p with specified font\r
        inline void Putsw(mglPoint p,const wchar_t *text,const char *font=":C",double size=-1)\r
@@ -1089,6 +1137,16 @@ public:
        {       mgl_tricont_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt);  }\r
        inline void TriContV(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
        {       mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt);     }\r
+       inline void TriCont(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
+       {       mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt);     }\r
+\r
+       /// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c.\r
+       inline void TriContVt(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
+       {       mgl_tricontv_xyc(gr, &nums, &x, &y, &z, sch, opt);      }\r
+       inline void TriContVt(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
+       {       mgl_tricontv_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt); }\r
+       inline void TriContVt(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
+       {       mgl_tricontv_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt);    }\r
 \r
        /// Draw dots in points {x,y,z}.\r
        inline void Dots(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
@@ -1214,7 +1272,7 @@ public:
        mglParse(mglParse &p)   {       pr = p.pr;      mgl_use_parser(pr,1);   }\r
        mglParse(bool setsize=false)\r
        {       pr=mgl_create_parser(); mgl_parser_allow_setsize(pr, setsize);  }\r
-       ~mglParse()     {       if(mgl_use_parser(pr,-1)<1)     mgl_delete_parser(pr);  }\r
+       virtual ~mglParse()     {       if(mgl_use_parser(pr,-1)<1)     mgl_delete_parser(pr);  }\r
        /// Get pointer to internal mglParser object\r
        inline HMPR Self()      {       return pr;      }\r
        /// Parse and draw single line of the MGL script\r
@@ -1231,7 +1289,7 @@ public:
        inline void Execute(mglGraph *gr, FILE *fp, bool print=false)\r
        {       mgl_parse_file(gr->Self(), pr, fp, print);      }\r
 \r
-       /// Return type of command: 0 - not found, 1 - data plot, 2 - other plot,\r
+       /// Return type of command: 0 - not found, 1 - other data plot, 2 - func plot,\r
        ///             3 - setup, 4 - data handle, 5 - data create, 6 - subplot, 7 - program\r
        ///             8 - 1d plot, 9 - 2d plot, 10 - 3d plot, 11 - dd plot, 12 - vector plot\r
        ///             13 - axis, 14 - primitives, 15 - axis setup, 16 - text/legend, 17 - data transform\r
@@ -1272,16 +1330,23 @@ public:
 \r
        /// Find variable with given name or add a new one\r
        /// NOTE !!! You must not delete obtained data arrays !!!\r
-       inline mglVar *AddVar(const char *name)\r
-       {       return dynamic_cast<mglVar *>(mgl_parser_add_var(pr, name));    }\r
-       inline mglVar *AddVar(const wchar_t *name)\r
-       {       return dynamic_cast<mglVar *>(mgl_parser_add_varw(pr, name));   }\r
+       inline mglData *AddVar(const char *name)\r
+       {       return mgl_parser_add_var(pr, name);    }\r
+       inline mglData *AddVar(const wchar_t *name)\r
+       {       return mgl_parser_add_varw(pr, name);   }\r
        /// Find variable with given name or return NULL if no one\r
        /// NOTE !!! You must not delete obtained data arrays !!!\r
-       inline mglVar *FindVar(const char *name)\r
-       {       return dynamic_cast<mglVar *>(mgl_parser_find_var(pr, name));   }\r
-       inline mglVar *FindVar(const wchar_t *name)\r
-       {       return dynamic_cast<mglVar *>(mgl_parser_find_varw(pr, name));  }\r
+       inline mglDataA *FindVar(const char *name)\r
+       {       return mgl_parser_find_var(pr, name);   }\r
+       inline mglDataA *FindVar(const wchar_t *name)\r
+       {       return mgl_parser_find_varw(pr, name);  }\r
+       /// Get variable with given id. Can be NULL for temporary ones.\r
+       /// NOTE !!! You must not delete obtained data arrays !!!\r
+       inline mglDataA *GetVar(unsigned long id)\r
+       {       return mgl_parser_get_var(pr,id);       }\r
+       /// Get number of variables\r
+       inline long GetNumVar()\r
+       {       return mgl_parser_num_var(pr);  }\r
        /// Delete variable with name\r
        inline void DeleteVar(const char *name)         {       mgl_parser_del_var(pr, name);           }\r
        inline void DeleteVar(const wchar_t *name)      {       mgl_parser_del_varw(pr, name);          }\r
@@ -1290,4 +1355,4 @@ public:
 };\r
 //-----------------------------------------------------------------------------\r
 #endif\r
-#endif
\ No newline at end of file
+#endif\r
index 2e6537adebe412c1ab8a4b68e6bb1b740e2c97a8..85d594a3c9eed8c0df1684b4e197e80b3e4e92f8 100644 (file)
@@ -129,8 +129,65 @@ procedure mgl_fltk_run(); cdecl; external libmglfltk;
 function mgl_create_graph_qt(draw: TMglDrawFunction; const title: PChar; par: pointer): HMGL; cdecl; external libmglqt;
 procedure mgl_qt_run(); cdecl; external libmglqt;
 
-{== ../include/mgl2/base_cf.h ==}
+{== ../../include/mgl2/abstract.h ==}
 //-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+/// Set name for data variable (can be used in mgl_formula_calc() or in MGL scripts)
+procedure  mgl_data_set_name( !!! mglDataA *dat;const name: PChar); cdecl; external libmgl;
+procedure  mgl_data_set_name_w( !!! mglDataA *dat;const name: PWideChar); cdecl; external libmgl;
+/// Set callback function which is called at deleting variable
+/// Save whole data array (for ns=-1) or only ns-th slice to text file
+procedure  mgl_data_save(const dat: HMDT;const fname: PChar;ns: integer); cdecl; external libmgl;
+/// Export data array (for ns=-1) or only ns-th slice to PNG file according color scheme
+procedure  mgl_data_export(const dat: HMDT;const fname: PChar;const scheme: PChar;v1: mreal;v2: mreal;ns: integer); cdecl; external libmgl;
+/// Save data to HDF file
+procedure  mgl_data_save_hdf(const d: HMDT;const fname: PChar;const data: PChar;rewrite: integer); cdecl; external libmgl;
+/// Get information about the data (sizes and momentum) to string
+function mgl_data_info(const dat: HMDT): PChar; cdecl; external libmgl;
+/// Put HDF data names into buf as '\t' separated.
+function  mgl_datas_hdf(const fname: PChar;buf: PChar;size: integer): integer; cdecl; external libmgl;
+/// Get maximal value of the data
+function  mgl_data_max(const dat: HMDT): mreal; cdecl; external libmgl;
+/// Get maximal value of the data which is less than 0
+function  mgl_data_neg_max(const dat: HMDT): mreal; cdecl; external libmgl;
+/// Get minimal value of the data
+function  mgl_data_min(const dat: HMDT): mreal; cdecl; external libmgl;
+/// Get minimal value of the data which is larger than 0
+function  mgl_data_pos_min(const dat: HMDT): mreal; cdecl; external libmgl;
+/// Find position (after specified in i,j,k) of first nonzero value of formula
+function  mgl_data_first(const dat: HMDT;const cond: PChar;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl;
+/// Find position (before specified in i,j,k) of last nonzero value of formula
+function  mgl_data_last(const dat: HMDT;const cond: PChar;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl;
+/// Find position of first in direction 'dir' nonzero value of formula
+function  mgl_data_find(const dat: HMDT;const cond: PChar;dir: char;i: integer;j: integer;k: integer): integer; cdecl; external libmgl;
+/// Find if any nonzero value of formula
+function  mgl_data_find_any(const dat: HMDT;const cond: PChar): integer; cdecl; external libmgl;
+/// Get maximal value of the data and its position
+function  mgl_data_max_int(const dat: HMDT;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl;
+/// Get maximal value of the data and its approximated position
+function  mgl_data_max_real(const dat: HMDT;x: Pmreal;y: Pmreal;z: Pmreal): mreal; cdecl; external libmgl;
+/// Get minimal value of the data and its position
+function  mgl_data_min_int(const dat: HMDT;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl;
+/// Get minimal value of the data and its approximated position
+function  mgl_data_min_real(const dat: HMDT;x: Pmreal;y: Pmreal;z: Pmreal): mreal; cdecl; external libmgl;
+/// Get "energy and find 4 momenta of data: median, width, skewness, kurtosis
+function  mgl_data_momentum_val(const d: HMDT;dir: char;m: Pmreal;w: Pmreal;s: Pmreal;k: Pmreal): mreal; cdecl; external libmgl;
+//-----------------------------------------------------------------------------
+/// Callback function for asking user a question. Result shouldn't exceed 1024.
+//-----------------------------------------------------------------------------
+/// Abstract class for data array
+//     {       return i>0 ? (i<GetNx()-1 ? (v(i+1,j,k)-v(i-1,j,k))/2 : v(i,j,k)-v(i-1,j,k)) : v(1,j,k)-v(0,j,k)        }
+//     {       return j>0 ? (j<GetNy()-1 ? (v(i,j+1,k)-v(i,j-1,k))/2 : v(i,j,k)-v(i,j-1,k)) : v(i,1,k)-v(i,0,k)        }
+//     {       return k>0 ? (k<GetNz()-1 ? (v(i,j,k+1)-v(i,j,k-1))/2 : v(i,j,k)-v(i,j,k-1)) : v(i,j,1)-v(i,j,0)        }
+//-----------------------------------------------------------------------------
+/// Structure for color ID
+//-----------------------------------------------------------------------------
+{== ../../include/mgl2/base_cf.h ==}
+//-----------------------------------------------------------------------------
+/// Check if MathGL version is valid
+function  mgl_check_version(const ver: PChar): integer; cdecl; external libmgl;
+/// Suppress printing warnings to stderr
+procedure  mgl_suppress_warn(on: integer); cdecl; external libmgl;
 /// Get last warning code
 function  mgl_get_warn(gr: HMGL): integer; cdecl; external libmgl;
 /// Set warning code ant fill message
@@ -141,13 +198,18 @@ function mgl_get_mess(gr: HMGL): PChar; cdecl; external libmgl;
 procedure  mgl_set_plotid(gr: HMGL;const id: PChar); cdecl; external libmgl;
 /// Get name of plot for saving filename
 function mgl_get_plotid(gr: HMGL): PChar; cdecl; external libmgl;
+/// Ask to stop drawing
+procedure  mgl_ask_stop(gr: HMGL;stop: integer); cdecl; external libmgl;
+/// Check if plot termination is asked
+function  mgl_need_stop(gr: HMGL): integer; cdecl; external libmgl;
+/// Set callback function for event processing
 /// Get plot quality
 function  mgl_get_quality(gr: HMGL): integer; cdecl; external libmgl;
 /// Set plot quality
 procedure  mgl_set_quality(gr: HMGL;qual: integer); cdecl; external libmgl;
 /// Set drawing region for Quality&4
 procedure  mgl_set_draw_reg(gr: HMGL;nx: integer;ny: integer;m: integer); cdecl; external libmgl;
-/// Is frames
+/// Check if support of frames is enabled (i.e. MGL_VECT_FRAME is set and Quality&MGL_DRAW_LMEM==0)
 function  mgl_is_frames(gr: HMGL): integer; cdecl; external libmgl;
 /// Get bit-value flag of HMGL state (for advanced users only)
 function  mgl_get_flag(gr: HMGL;flag: LongWord): integer; cdecl; external libmgl;
@@ -155,6 +217,7 @@ function  mgl_get_flag(gr: HMGL;flag: LongWord): integer; cdecl; external libmgl
 procedure  mgl_set_flag(gr: HMGL;val: integer;flag: LongWord); cdecl; external libmgl;
 /// Change counter of HMGL uses (for advanced users only). Non-zero counter prevent automatic object removing.
 function  mgl_use_graph(gr: HMGL;inc: integer): integer; cdecl; external libmgl;
+procedure  mgl_set_rdc_acc(gr: HMGL;reduce: integer); cdecl; external libmgl;
 /// Start group of objects
 procedure  mgl_start_group(gr: HMGL;const name: PChar); cdecl; external libmgl;
 /// End group of objects
@@ -199,6 +262,8 @@ procedure  mgl_set_cutoff(gr: HMGL;const EqC: PChar); cdecl; external libmgl;
 procedure  mgl_set_ranges(gr: HMGL;x1: double;x2: double;y1: double;y2: double;z1: double;z2: double); cdecl; external libmgl;
 /// Set range in direction dir as [v1, v2]
 procedure  mgl_set_range_val(gr: HMGL;dir: char;v1: double;v2: double); cdecl; external libmgl;
+/// Add [v1, v2] to the current range in direction dir
+procedure  mgl_add_range_val(gr: HMGL;dir: char;v1: double;v2: double); cdecl; external libmgl;
 /// Set range in direction dir as minimal and maximal values of data a
 procedure  mgl_set_range_dat(gr: HMGL;dir: char;const a: HMDT;add: integer); cdecl; external libmgl;
 /// Set ranges for automatic variables
@@ -236,7 +301,7 @@ procedure  mgl_copy_font(gr: HMGL;gr_from: HMGL); cdecl; external libmgl;
 /// Restore font (load default font for new HMGL objects)
 procedure  mgl_restore_font(gr: HMGL); cdecl; external libmgl;
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/data_cf.h ==}
+{== ../../include/mgl2/data_cf.h ==}
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -256,8 +321,6 @@ function  mgl_create_data_size(nx: integer;ny: integer;nz: integer): HMDT; cdecl
 function  mgl_create_data_file(const fname: PChar): HMDT; cdecl; external libmgl;
 /// Delete HMDT object
 procedure  mgl_delete_data(dat: HMDT); cdecl; external libmgl;
-/// Get information about the data (sizes and momentum) to string
-function mgl_data_info(const dat: HMDT): PChar; cdecl; external libmgl;
 /// Rearange data dimensions
 procedure  mgl_data_rearrange(dat: HMDT;mx: integer;my: integer;mz: integer); cdecl; external libmgl;
 /// Link external data array (don't delete it at exit)
@@ -284,10 +347,6 @@ function  mgl_data_get_value(const dat: HMDT;i: integer;j: integer;k: integer):
 procedure  mgl_data_set_values(dat: HMDT;const val: PChar;nx: integer;ny: integer;nz: integer); cdecl; external libmgl;
 /// Read data array from HDF file (parse HDF4 and HDF5 files)
 function  mgl_data_read_hdf(d: HMDT;const fname: PChar;const data: PChar): integer; cdecl; external libmgl;
-/// Save data to HDF file
-procedure  mgl_data_save_hdf(const d: HMDT;const fname: PChar;const data: PChar;rewrite: integer); cdecl; external libmgl;
-/// Put HDF data names into buf as '\t' separated.
-function  mgl_datas_hdf(const fname: PChar;buf: PChar;size: integer): integer; cdecl; external libmgl;
 /// Read data from tab-separated text file with auto determining size
 function  mgl_data_read(dat: HMDT;const fname: PChar): integer; cdecl; external libmgl;
 /// Read data from text file with size specified at beginning of the file
@@ -298,10 +357,6 @@ function  mgl_data_read_dim(dat: HMDT;const fname: PChar;mx: integer;my: integer
 function  mgl_data_read_range(d: HMDT;const templ: PChar;n1: double;n2: double;step: double;as_slice: integer): integer; cdecl; external libmgl;
 /// Read data from tab-separated text files with auto determining size which filenames are satisfied to template (like "t_*.dat")
 function  mgl_data_read_all(dat: HMDT;const templ: PChar;as_slice: integer): integer; cdecl; external libmgl;
-/// Save whole data array (for ns=-1) or only ns-th slice to text file
-procedure  mgl_data_save(const dat: HMDT;const fname: PChar;ns: integer); cdecl; external libmgl;
-/// Export data array (for ns=-1) or only ns-th slice to PNG file according color scheme
-procedure  mgl_data_export(const dat: HMDT;const fname: PChar;const scheme: PChar;v1: mreal;v2: mreal;ns: integer); cdecl; external libmgl;
 /// Import data array from PNG file according color scheme
 procedure  mgl_data_import(dat: HMDT;const fname: PChar;const scheme: PChar;v1: mreal;v2: mreal); cdecl; external libmgl;
 /// Create or recreate the array with specified size and fill it by zero
@@ -324,6 +379,8 @@ procedure  mgl_data_set_id(d: HMDT;const id: PChar); cdecl; external libmgl;
 procedure  mgl_data_fill(dat: HMDT;x1: mreal;x2: mreal;dir: char); cdecl; external libmgl;
 /// Modify the data by specified formula assuming x,y,z in range [r1,r2]
 procedure  mgl_data_fill_eq(gr: HMGL;dat: HMDT;const eq: PChar;const vdat: HMDT;const wdat: HMDT;const opt: PChar); cdecl; external libmgl;
+/// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2] using global spline
+procedure  mgl_data_refill_gs(dat: HMDT;const xdat: HMDT;const vdat: HMDT;x1: mreal;x2: mreal;sl: integer); cdecl; external libmgl;
 /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2]
 procedure  mgl_data_refill_x(dat: HMDT;const xdat: HMDT;const vdat: HMDT;x1: mreal;x2: mreal;sl: integer); cdecl; external libmgl;
 /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in range [x1,x2]*[y1,y2]
@@ -346,10 +403,6 @@ procedure  mgl_data_modify(dat: HMDT;const eq: PChar;dim: integer); cdecl; exter
 procedure  mgl_data_modify_vw(dat: HMDT;const eq: PChar;const vdat: HMDT;const wdat: HMDT); cdecl; external libmgl;
 /// Reduce size of the data
 procedure  mgl_data_squeeze(dat: HMDT;rx: integer;ry: integer;rz: integer;smooth: integer); cdecl; external libmgl;
-/// Get maximal value of the data
-function  mgl_data_max(const dat: HMDT): mreal; cdecl; external libmgl;
-/// Get minimal value of the data
-function  mgl_data_min(const dat: HMDT): mreal; cdecl; external libmgl;
 /// Returns pointer to data element [i,j,k]
 function mgl_data_value(dat: HMDT;i: integer;j: integer;k: integer): Pmreal; cdecl; external libmgl;
 /// Returns pointer to internal data array
@@ -360,24 +413,6 @@ function  mgl_data_get_nx(const d: HMDT): integer; cdecl; external libmgl;
 function  mgl_data_get_ny(const d: HMDT): integer; cdecl; external libmgl;
 /// Gets the z-size of the data.
 function  mgl_data_get_nz(const d: HMDT): integer; cdecl; external libmgl;
-/// Find position (after specified in i,j,k) of first nonzero value of formula
-function  mgl_data_first(const dat: HMDT;const cond: PChar;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl;
-/// Find position (before specified in i,j,k) of last nonzero value of formula
-function  mgl_data_last(const dat: HMDT;const cond: PChar;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl;
-/// Find position of first in direction 'dir' nonzero value of formula
-function  mgl_data_find(const dat: HMDT;const cond: PChar;dir: char;i: integer;j: integer;k: integer): integer; cdecl; external libmgl;
-/// Find if any nonzero value of formula
-function  mgl_data_find_any(const dat: HMDT;const cond: PChar): integer; cdecl; external libmgl;
-/// Get maximal value of the data and its position
-function  mgl_data_max_int(const dat: HMDT;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl;
-/// Get maximal value of the data and its approximated position
-function  mgl_data_max_real(const dat: HMDT;x: Pmreal;y: Pmreal;z: Pmreal): mreal; cdecl; external libmgl;
-/// Get minimal value of the data and its position
-function  mgl_data_min_int(const dat: HMDT;i: Pint;j: Pint;k: Pint): mreal; cdecl; external libmgl;
-/// Get minimal value of the data and its approximated position
-function  mgl_data_min_real(const dat: HMDT;x: Pmreal;y: Pmreal;z: Pmreal): mreal; cdecl; external libmgl;
-/// Get "energy and find 4 momenta of data: median, width, skewness, kurtosis
-function  mgl_data_momentum_val(const d: HMDT;dir: char;m: Pmreal;w: Pmreal;s: Pmreal;k: Pmreal): mreal; cdecl; external libmgl;
 /// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on)
 function  mgl_data_combine(const dat1: HMDT;const dat2: HMDT): HMDT; cdecl; external libmgl;
 /// Extend data dimensions
@@ -435,6 +470,10 @@ function  mgl_data_spline(const dat: HMDT;x: mreal;y: mreal;z: mreal): mreal; cd
 function  mgl_data_linear(const dat: HMDT;x: mreal;y: mreal;z: mreal): mreal; cdecl; external libmgl;
 /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 function  mgl_data_spline_ext(const dat: HMDT;x: mreal;y: mreal;z: mreal;dx: Pmreal;dy: Pmreal;dz: Pmreal): mreal; cdecl; external libmgl;
+/// Prepare coefficients for global spline interpolation
+function  mgl_gspline_init(const x: HMDT;const v: HMDT): HMDT; cdecl; external libmgl;
+/// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef
+function  mgl_gspline(const coef: HMDT;dx: mreal;d1: Pmreal;d2: Pmreal): mreal; cdecl; external libmgl;
 /// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 function  mgl_data_linear_ext(const dat: HMDT;x: mreal;y: mreal;z: mreal;dx: Pmreal;dy: Pmreal;dz: Pmreal): mreal; cdecl; external libmgl;
 /// Return an approximated x-value (root) when dat(x) = val
@@ -497,10 +536,34 @@ function  mgl_find_root_txt(const func: PChar;ini: mreal;var_id: char): mreal; c
 /// Find roots for nonlinear equation defined by textual formula
 function  mgl_data_roots(const func: PChar;const ini: HMDT;var_id: char): HMDT; cdecl; external libmgl;
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/datac_cf.h ==}
+/// Create HMEX object for expression evaluating
+function  mgl_create_expr(const expr: PChar): HMEX; cdecl; external libmgl;
+/// Delete HMEX object
+procedure  mgl_delete_expr(ex: HMEX); cdecl; external libmgl;
+/// Return value of expression for given x,y,z variables
+function  mgl_expr_eval(ex: HMEX;x: double;y: double;z: double): double; cdecl; external libmgl;
+/// Return value of expression for given variables
+function  mgl_expr_eval_v(ex: HMEX;vars: Pmreal): double; cdecl; external libmgl;
+/// Return value of expression differentiation over variable dir for given x,y,z variables
+function  mgl_expr_diff(ex: HMEX;dir: char;x: double;y: double;z: double): double; cdecl; external libmgl;
+/// Return value of expression differentiation over variable dir for given variables
+function  mgl_expr_diff_v(ex: HMEX;dir: char;vars: Pmreal): double; cdecl; external libmgl;
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
+{== ../../include/mgl2/datac_cf.h ==}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+/// Set seed for random numbers
+procedure  mgl_srnd(seed: integer); cdecl; external libmgl;
+/// Get random number
+function  mgl_rnd(): double; cdecl; external libmgl;
+/// Get integer power of x
+function  mgl_ipowc(x: dual;n: integer): dual; cdecl; external libmgl;
+/// Get exp(i*a)
+function  mgl_expi(a: dual): dual; cdecl; external libmgl;
+overload;
 /// Create HMDT object
 function  mgl_create_datac(): HADT; cdecl; external libmgl;
 /// Create HMDT object with specified sizes
@@ -559,6 +622,26 @@ procedure  mgl_datac_save_hdf(const d: HMDT;const fname: PChar;const data: PChar
 procedure  mgl_datac_create(dat: HADT;nx: integer;ny: integer;nz: integer); cdecl; external libmgl;
 /// Transpose dimensions of the data (generalization of Transpose)
 procedure  mgl_datac_transpose(dat: HADT;const dim: PChar); cdecl; external libmgl;
+/// Get sub-array of the data with given fixed indexes
+function  mgl_datac_subdata(const dat: HMDT;xx: integer;yy: integer;zz: integer): HADT; cdecl; external libmgl;
+/// Get sub-array of the data with given fixed indexes (like indirect access)
+function  mgl_datac_subdata_ext(const dat: HMDT;const xx: HMDT;const yy: HMDT;const zz: HMDT): HADT; cdecl; external libmgl;
+/// Get column (or slice) of the data filled by formulas of named columns
+function  mgl_datac_column(const dat: HMDT;const eq: PChar): HADT; cdecl; external libmgl;
+/// Get trace of the data array
+function  mgl_datac_trace(const d: HMDT): HADT; cdecl; external libmgl;
+/// Resize the data to new sizes
+function  mgl_datac_resize(const dat: HMDT;mx: integer;my: integer;mz: integer): HADT; cdecl; external libmgl;
+/// Resize the data to new sizes of box [x1,x2]*[y1,y2]*[z1,z2]
+function  mgl_datac_resize_box(const dat: HMDT;mx: integer;my: integer;mz: integer;x1: mreal;x2: mreal;y1: mreal;y2: mreal;z1: mreal;z2: mreal): HADT; cdecl; external libmgl;
+/// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on.
+function  mgl_datac_momentum(const dat: HMDT;dir: char;const how: PChar): HADT; cdecl; external libmgl;
+/// Get array which values is result of interpolation this for coordinates from other arrays
+function  mgl_datac_evaluate(const dat: HMDT;const idat: HMDT;const jdat: HMDT;const kdat: HMDT;norm: integer): HADT; cdecl; external libmgl;
+/// Get array which is result of summation in given direction or directions
+function  mgl_datac_sum(const dat: HMDT;const dir: PChar): HADT; cdecl; external libmgl;
+/// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on)
+function  mgl_datac_combine(const dat1: HMDT;const dat2: HMDT): HADT; cdecl; external libmgl;
 /// Set names for columns (slices)
 procedure  mgl_datac_set_id(d: HADT;const id: PChar); cdecl; external libmgl;
 /// Equidistantly fill the data to range [x1,x2] in direction dir
@@ -607,6 +690,8 @@ procedure  mgl_datac_hankel(dat: HADT;const dir: PChar); cdecl; external libmgl;
 procedure  mgl_datac_fft(dat: HADT;const dir: PChar); cdecl; external libmgl;
 /// Find correlation between 2 data arrays
 function  mgl_datac_correl(const dat1: HMDT;const dat2: HMDT;const dir: PChar): HADT; cdecl; external libmgl;
+/// Calculate one step of diffraction by finite-difference method with parameter q
+procedure  mgl_datac_diffr(dat: HADT;const how: PChar;q: mreal); cdecl; external libmgl;
 function  mgl_datac_real(const dat: HMDT): HMDT; cdecl; external libmgl;
 function  mgl_datac_imag(const dat: HMDT): HMDT; cdecl; external libmgl;
 function  mgl_datac_abs(const dat: HMDT): HMDT; cdecl; external libmgl;
@@ -619,8 +704,21 @@ function  mgl_datac_linear_ext(const d: HMDT;x: mreal;y: mreal;z: mreal;dx: Pdua
 function  mgl_datac_spline(const dat: HMDT;x: mreal;y: mreal;z: mreal): dual; cdecl; external libmgl;
 /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
 function  mgl_datac_spline_ext(const dat: HMDT;x: mreal;y: mreal;z: mreal;dx: Pdual;dy: Pdual;dz: Pdual): dual; cdecl; external libmgl;
+/// Prepare coefficients for global spline interpolation
+function  mgl_gsplinec_init(const x: HMDT;const v: HMDT): HADT; cdecl; external libmgl;
+/// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef
+function  mgl_gsplinec(const coef: HMDT;dx: mreal;d1: Pdual;d2: Pdual): dual; cdecl; external libmgl;
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/cont.h ==}
+/// Create HAEX object for expression evaluating
+function  mgl_create_cexpr(const expr: PChar): HAEX; cdecl; external libmgl;
+/// Delete HAEX object
+procedure  mgl_delete_cexpr(ex: HAEX); cdecl; external libmgl;
+/// Return value of expression for given x,y,z variables
+function  mgl_cexpr_eval(ex: HAEX;x: dual;y: dual;z: dual): dual; cdecl; external libmgl;
+/// Return value of expression for given variables
+function  mgl_cexpr_eval_v(ex: HAEX;vars: Pdual): dual; cdecl; external libmgl;
+//-----------------------------------------------------------------------------
+{== ../../include/mgl2/cont.h ==}
 //-----------------------------------------------------------------------------
 /// Print text along the curve in parametric form {x,y,z}
 procedure  mgl_text_xyz(gr: HMGL;const x: HMDT;const y: HMDT;const z: HMDT;const text: PChar;const font: PChar;const opt: PChar); cdecl; external libmgl;
@@ -703,7 +801,7 @@ procedure  mgl_contf3_xyz(gr: HMGL;const x: HMDT;const y: HMDT;const z: HMDT;con
 procedure  mgl_contf3(gr: HMGL;const a: HMDT;const sch: PChar;sVal: double;const opt: PChar); cdecl; external libmgl;
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/fit.h ==}
+{== ../../include/mgl2/fit.h ==}
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 function  mgl_fit_1(gr: HMGL;const y: HMDT;const eq: PChar;const vars: PChar;ini: HMDT;const opt: PChar): HMDT; cdecl; external libmgl;
@@ -724,7 +822,7 @@ procedure  mgl_puts_fit(gr: HMGL;x: double;y: double;z: double;const prefix: PCh
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/plot.h ==}
+{== ../../include/mgl2/plot.h ==}
 //-----------------------------------------------------------------------------
 /// Draw curve for formula with x in x-axis range
 procedure  mgl_fplot(gr: HMGL;const eqY: PChar;const pen: PChar;const opt: PChar); cdecl; external libmgl;
@@ -760,6 +858,8 @@ procedure  mgl_area_xyz(graph: HMGL;const x: HMDT;const y: HMDT;const z: HMDT;co
 procedure  mgl_area_xy(graph: HMGL;const x: HMDT;const y: HMDT;const pen: PChar;const opt: PChar); cdecl; external libmgl;
 /// Fill area between curve {x,y} with x in x-axis range and axis plane
 procedure  mgl_area(graph: HMGL;const y: HMDT;const pen: PChar;const opt: PChar); cdecl; external libmgl;
+/// Fill area (draw ribbon) between curves {x1,y1,z1} and {x2,y2,z2}
+procedure  mgl_region_3d(graph: HMGL;const x1: HMDT;const y1: HMDT;const z1: HMDT;const x2: HMDT;const y2: HMDT;const z2: HMDT;const pen: PChar;const opt: PChar); cdecl; external libmgl;
 /// Fill area between curves {x,y1} and {x,y2}
 procedure  mgl_region_xy(graph: HMGL;const x: HMDT;const y1: HMDT;const y2: HMDT;const pen: PChar;const opt: PChar); cdecl; external libmgl;
 /// Fill area between curves {x,y1} and {x,y2} with x in x-axis range
@@ -823,7 +923,7 @@ procedure  mgl_candle_yv(gr: HMGL;const v1: HMDT;const v2: HMDT;const y1: HMDT;c
 /// Draw candle plot with v1=v[i], v2=v[i+1]
 procedure  mgl_candle(gr: HMGL;const v: HMDT;const y1: HMDT;const y2: HMDT;const pen: PChar;const opt: PChar); cdecl; external libmgl;
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/surf.h ==}
+{== ../../include/mgl2/surf.h ==}
 //-----------------------------------------------------------------------------
 /// Draw surface by formula with x,y in axis range
 procedure  mgl_fsurf(graph: HMGL;const fz: PChar;const stl: PChar;const opt: PChar); cdecl; external libmgl;
@@ -882,7 +982,7 @@ procedure  mgl_map_xy(graph: HMGL;const x: HMDT;const y: HMDT;const a: HMDT;cons
 /// Color map of matrix a to matrix b
 procedure  mgl_map(graph: HMGL;const a: HMDT;const b: HMDT;const sch: PChar;const opt: PChar); cdecl; external libmgl;
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/volume.h ==}
+{== ../../include/mgl2/volume.h ==}
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 /// Draw isosurface for 3d data specified parametrically
@@ -919,7 +1019,7 @@ procedure  mgl_beam_val(graph: HMGL;Val: double;const tr: HMDT;const g1: HMDT;co
 procedure  mgl_beam(graph: HMGL;const tr: HMDT;const g1: HMDT;const g2: HMDT;const a: HMDT;r: double;const stl: PChar;norm: integer;num: integer); cdecl; external libmgl;
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/vect.h ==}
+{== ../../include/mgl2/vect.h ==}
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 /// Plot vectors at position {x,y} along {ax,ay} with length/color proportional to |a|
@@ -970,7 +1070,7 @@ procedure  mgl_vect3_xyz(gr: HMGL;const x: HMDT;const y: HMDT;const z: HMDT;cons
 procedure  mgl_vect3(gr: HMGL;const ax: HMDT;const ay: HMDT;const az: HMDT;const sch: PChar;sVal: double;const opt: PChar); cdecl; external libmgl;
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/prim.h ==}
+{== ../../include/mgl2/prim.h ==}
 //-----------------------------------------------------------------------------
 /// Draws the mark at position {x,y,z}
 procedure  mgl_mark(gr: HMGL;x: double;y: double;z: double;const mark: PChar); cdecl; external libmgl;
@@ -1000,6 +1100,10 @@ procedure  mgl_cone(gr: HMGL;x1: double;y1: double;z1: double;x2: double;y2: dou
 procedure  mgl_ellipse(gr: HMGL;x1: double;y1: double;z1: double;x2: double;y2: double;z2: double;r: double;const stl: PChar); cdecl; external libmgl;
 /// Draws the rhomb between points p1,p2 with color stl and width r
 procedure  mgl_rhomb(gr: HMGL;x1: double;y1: double;z1: double;x2: double;y2: double;z2: double;r: double;const stl: PChar); cdecl; external libmgl;
+/// Draws the polygon based on points p1,p2 with color stl
+procedure  mgl_polygon(gr: HMGL;x1: double;y1: double;z1: double;x2: double;y2: double;z2: double;n: integer;const stl: PChar); cdecl; external libmgl;
+procedure  mgl_arc_ext(gr: HMGL;x0: double;y0: double;z0: double;xr: double;yr: double;zr: double;x1: double;y1: double;z1: double;a: double; !!! const char* stl); cdecl; external libmgl;
+procedure  mgl_arc(gr: HMGL;x0: double;y0: double;x1: double;y1: double;a: double; !!! const char* stl); cdecl; external libmgl;
 /// Draw cones from points {x,y,z} to axis plane
 procedure  mgl_cones_xyz(graph: HMGL;const x: HMDT;const y: HMDT;const z: HMDT;const pen: PChar;const opt: PChar); cdecl; external libmgl;
 /// Draw cones from points {x,z} to axis plane
@@ -1038,7 +1142,7 @@ procedure  mgl_labelw_y(graph: HMGL;const y: HMDT;const text: PWideChar;const fn
 procedure  mgl_table(gr: HMGL;x: double;y: double;const val: HMDT;const text: PChar;const fnt: PChar;const opt: PChar); cdecl; external libmgl;
 procedure  mgl_tablew(gr: HMGL;x: double;y: double;const val: HMDT;const text: PWideChar;const fnt: PChar;const opt: PChar); cdecl; external libmgl;
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/other.h ==}
+{== ../../include/mgl2/other.h ==}
 //-----------------------------------------------------------------------------
 /// Draw triangle mesh for points in arrays {x,y,z} with specified color c.
 procedure  mgl_triplot_xyzc(gr: HMGL;const nums: HMDT;const x: HMDT;const y: HMDT;const z: HMDT;const c: HMDT;const sch: PChar;const opt: PChar); cdecl; external libmgl;
@@ -1060,6 +1164,14 @@ procedure  mgl_tricont_xycv(gr: HMGL;const v: HMDT;const nums: HMDT;const x: HMD
 procedure  mgl_tricont_xyzc(gr: HMGL;const nums: HMDT;const x: HMDT;const y: HMDT;const z: HMDT;const c: HMDT;const sch: PChar;const opt: PChar); cdecl; external libmgl;
 /// Draw contour lines for triangle mesh for points in arrays {x,y,z}.
 procedure  mgl_tricont_xyc(gr: HMGL;const nums: HMDT;const x: HMDT;const y: HMDT;const z: HMDT;const sch: PChar;const opt: PChar); cdecl; external libmgl;
+/// Draw manual contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c.
+procedure  mgl_tricontv_xyzcv(gr: HMGL;const v: HMDT;const nums: HMDT;const x: HMDT;const y: HMDT;const z: HMDT;const c: HMDT;const sch: PChar;const opt: PChar); cdecl; external libmgl;
+/// Draw manual contour tubes for triangle mesh for points in arrays {x,y,z}.
+procedure  mgl_tricontv_xycv(gr: HMGL;const v: HMDT;const nums: HMDT;const x: HMDT;const y: HMDT;const z: HMDT;const sch: PChar;const opt: PChar); cdecl; external libmgl;
+/// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c.
+procedure  mgl_tricontv_xyzc(gr: HMGL;const nums: HMDT;const x: HMDT;const y: HMDT;const z: HMDT;const c: HMDT;const sch: PChar;const opt: PChar); cdecl; external libmgl;
+/// Draw contour tubes for triangle mesh for points in arrays {x,y,z}.
+procedure  mgl_tricontv_xyc(gr: HMGL;const nums: HMDT;const x: HMDT;const y: HMDT;const z: HMDT;const sch: PChar;const opt: PChar); cdecl; external libmgl;
 /// Draw dots in points {x,y,z}.
 procedure  mgl_dots(gr: HMGL;const x: HMDT;const y: HMDT;const z: HMDT;const sch: PChar;const opt: PChar); cdecl; external libmgl;
 /// Draw semitransparent dots in points {x,y,z} with specified alpha a.
@@ -1099,7 +1211,7 @@ procedure  mgl_contf_y_val(graph: HMGL;const v: HMDT;const a: HMDT;const stl: PC
 /// Draw manual solid contours for data at z = sVal
 procedure  mgl_contf_z_val(graph: HMGL;const v: HMDT;const a: HMDT;const stl: PChar;sVal: double;const opt: PChar); cdecl; external libmgl;
 //-----------------------------------------------------------------------------
-{== ../include/mgl2/canvas_cf.h ==}
+{== ../../include/mgl2/canvas_cf.h ==}
 //-----------------------------------------------------------------------------
 /// Create HMGL object with specified sizes
 function  mgl_create_graph(width: integer;height: integer): HMGL; cdecl; external libmgl;
@@ -1113,20 +1225,30 @@ procedure  mgl_set_def_param(gr: HMGL); cdecl; external libmgl;
 procedure  mgl_combine_gr(gr: HMGL;gr2: HMGL); cdecl; external libmgl;
 /// Force preparing the image. It can be useful for OpenGL mode mostly.
 procedure  mgl_finish(gr: HMGL); cdecl; external libmgl;
+/// Force preparing the image and save result into background one.
+procedure  mgl_rasterize(gr: HMGL); cdecl; external libmgl;
 /// Set tick length
 procedure  mgl_set_tick_len(gr: HMGL;len: double;stt: double); cdecl; external libmgl;
 /// Set axis and ticks style
 procedure  mgl_set_axis_stl(gr: HMGL;const stl: PChar;const tck: PChar;const sub: PChar); cdecl; external libmgl;
 /// Auto adjust ticks
 procedure  mgl_adjust_ticks(gr: HMGL;const dir: PChar); cdecl; external libmgl;
+/// Auto adjust ticks and set ticks format ("+E0123456789-fF")
+procedure  mgl_adjust_ticks_ext(gr: HMGL;const dir: PChar;const stl: PChar); cdecl; external libmgl;
 /// Set the ticks parameters
 procedure  mgl_set_ticks(gr: HMGL;dir: char;d: double;ns: integer;org: double); cdecl; external libmgl;
-/// Set ticks text (\n separated). Use "" to disable this feature.
+/// Set the ticks parameters and specify ticks factor string
+procedure  mgl_set_ticks_fact(gr: HMGL;dir: char;d: double;ns: integer;org: double;const fact: PChar); cdecl; external libmgl;
+procedure  mgl_set_ticks_factw(gr: HMGL;dir: char;d: double;ns: integer;org: double;const fact: PWideChar); cdecl; external libmgl;
+/// Set manual ticks text (\n separated). Use "" to disable this feature.
 procedure  mgl_set_ticks_str(gr: HMGL;dir: char;const lbl: PChar;add: integer); cdecl; external libmgl;
 procedure  mgl_set_ticks_wcs(gr: HMGL;dir: char;const lbl: PWideChar;add: integer); cdecl; external libmgl;
-/// Set ticks position and text (\n separated). Use "" to disable this feature.
+/// Set manual ticks position and text (\n separated). Use "" to disable this feature.
 procedure  mgl_set_ticks_val(gr: HMGL;dir: char;const val: HMDT;const lbl: PChar;add: integer); cdecl; external libmgl;
 procedure  mgl_set_ticks_valw(gr: HMGL;dir: char;const val: HMDT;const lbl: PWideChar;add: integer); cdecl; external libmgl;
+/// Add manual tick at given position. Use "" to disable this feature.
+procedure  mgl_add_tick(gr: HMGL;dir: char;val: double;const lbl: PChar); cdecl; external libmgl;
+procedure  mgl_add_tickw(gr: HMGL;dir: char;val: double;const lbl: PWideChar); cdecl; external libmgl;
 /// Tune ticks
 procedure  mgl_tune_ticks(gr: HMGL;tune: integer;fact_pos: double); cdecl; external libmgl;
 /// Set templates for ticks
@@ -1218,6 +1340,8 @@ function mgl_get_json(gr: HMGL): PChar; cdecl; external libmgl;
 function mgl_get_rgb(gr: HMGL): PByte; cdecl; external libmgl;
 /// Get RGBA values of current bitmap
 function mgl_get_rgba(gr: HMGL): PByte; cdecl; external libmgl;
+/// Get RGB values of current bitmap
+function mgl_get_background(gr: HMGL): PByte; cdecl; external libmgl;
 /// Set object/subplot id
 procedure  mgl_set_obj_id(gr: HMGL;id: integer); cdecl; external libmgl;
 /// Get object id
@@ -1276,6 +1400,10 @@ procedure  mgl_clf(gr: HMGL); cdecl; external libmgl;
 procedure  mgl_clf_rgb(gr: HMGL;r: double;g: double;b: double); cdecl; external libmgl;
 /// Clear up the frame and fill background by specified color
 procedure  mgl_clf_chr(gr: HMGL;col: char); cdecl; external libmgl;
+/// Clear up the frame and fill background by specified color with manual transparency
+procedure  mgl_clf_str(gr: HMGL;const col: PChar); cdecl; external libmgl;
+/// Load background image
+procedure  mgl_load_background(gr: HMGL;const fname: PChar;alpha: double); cdecl; external libmgl;
 /// Put further plotting in some region of whole frame.
 procedure  mgl_subplot(gr: HMGL;nx: integer;ny: integer;m: integer;const style: PChar); cdecl; external libmgl;
 /// Put further plotting in some region of whole frame and shift it by distance {dx,dy}.
@@ -1305,6 +1433,8 @@ procedure  mgl_rotate(gr: HMGL;TetX: double;TetZ: double;TetY: double); cdecl; e
 procedure  mgl_rotate_vector(gr: HMGL;Tet: double;x: double;y: double;z: double); cdecl; external libmgl;
 /// Set perspective (in range [0,1)) for plot. Set to zero for switching off.
 procedure  mgl_perspective(gr: HMGL;val: double); cdecl; external libmgl;
+/// Ask to set perspective (in range [0,1)) for plot. Set to zero for switching off.
+procedure  mgl_ask_perspective(gr: HMGL;val: double); cdecl; external libmgl;
 /// Set angle of view independently from Rotate().
 procedure  mgl_view(gr: HMGL;TetX: double;TetZ: double;TetY: double); cdecl; external libmgl;
 /// Zoom in/out a part of picture (use mgl_zoom(0, 0, 1, 1) for restore default)
@@ -1357,8 +1487,10 @@ function  mgl_parser_add_var(p: HMPR;const name: PChar): HMDT; cdecl; external l
 function  mgl_parser_add_varw(p: HMPR;const name: PWideChar): HMDT; cdecl; external libmgl;
 /// Find variable with given name or return NULL if no one
 /// NOTE !!! You must not delete obtained data arrays !!!
-function  mgl_parser_find_var(p: HMPR;const name: PChar): HMDT; cdecl; external libmgl;
-function  mgl_parser_find_varw(p: HMPR;const name: PWideChar): HMDT; cdecl; external libmgl;
+/// Get variable with given id
+/// NOTE !!! You must not delete obtained data arrays !!!
+/// Get number of variables
+function  mgl_parser_num_var(p: HMPR): integer; cdecl; external libmgl;
 /// Delete variable with name
 procedure  mgl_parser_del_var(p: HMPR;const name: PChar); cdecl; external libmgl;
 procedure  mgl_parser_del_varw(p: HMPR;const name: PWideChar); cdecl; external libmgl;
@@ -1396,38 +1528,15 @@ function  mgl_parser_cmd_num(pr: HMPR): integer; cdecl; external libmgl;
 function  mgl_parser_calc(pr: HMPR;const formula: PChar): HMDT; cdecl; external libmgl;
 function  mgl_parser_calcw(pr: HMPR;const formula: PWideChar): HMDT; cdecl; external libmgl;
 //-----------------------------------------------------------------------------
-/// Create HMEX object for expression evaluating
-function  mgl_create_expr(const expr: PChar): HMEX; cdecl; external libmgl;
-function  mgl_create_cexpr(const expr: PChar): HAEX; cdecl; external libmgl;
-/// Delete HMEX object
-procedure  mgl_delete_expr(ex: HMEX); cdecl; external libmgl;
-procedure  mgl_delete_cexpr(ex: HAEX); cdecl; external libmgl;
-/// Return value of expression for given x,y,z variables
-function  mgl_expr_eval(ex: HMEX;x: double;y: double;z: double): double; cdecl; external libmgl;
-function  mgl_cexpr_eval(ex: HAEX;x: dual;y: dual;z: dual): dual; cdecl; external libmgl;
-/// Return value of expression for given variables
-function  mgl_expr_eval_v(ex: HMEX;vars: Pmreal): double; cdecl; external libmgl;
-function  mgl_cexpr_eval_v(ex: HAEX;vars: Pdual): dual; cdecl; external libmgl;
-/// Return value of expression differentiation over variable dir for given x,y,z variables
-function  mgl_expr_diff(ex: HMEX;dir: char;x: double;y: double;z: double): double; cdecl; external libmgl;
-/// Return value of expression differentiation over variable dir for given variables
-function  mgl_expr_diff_v(ex: HMEX;dir: char;vars: Pmreal): double; cdecl; external libmgl;
-//-----------------------------------------------------------------------------
-{== ../include/mgl2/addon.h ==}
+{== ../../include/mgl2/addon.h ==}
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-/// Get integer power of x
-function  mgl_ipowc(x: dual;n: integer): dual; cdecl; external libmgl;
-/// Get exp(i*a)
-function  mgl_expi(a: dual): dual; cdecl; external libmgl;
-overload;
-/// Get exp(i*a)
-function  mgl_expi(a: double): dual; cdecl; external libmgl;
-overload;
 /// Explicit scheme for 1 step of axial diffraction
-function  mgl_difr_axial(a: Pdual;n: integer;q: dual;Border: integer;b: Pdual;d: Pdual;kk: integer;di: double): integer; cdecl; external libmgl;
+procedure  mgl_difr_axial(a: Pdual;n: integer;step: integer;q: dual;Border: integer;tmp: Pdual;kk: integer;di: double); cdecl; external libmgl;
+procedure  mgl_difr_axial_old(a: Pdual;n: integer;step: integer;q: dual;Border: integer;tmp1: Pdual;tmp2: Pdual;kk: integer;di: double); cdecl; external libmgl;
 /// Explicit scheme for 1 step of plane diffraction
-function  mgl_difr_grid(a: Pdual;n: integer;q: dual;Border: integer;b: Pdual;d: Pdual;kk: integer): integer; cdecl; external libmgl;
+procedure  mgl_difr_grid(a: Pdual;n: integer;step: integer;q: dual;Border: integer;tmp: Pdual;kk: integer); cdecl; external libmgl;
+procedure  mgl_difr_grid_old(a: Pdual;n: integer;step: integer;q: dual;Border: integer;tmp1: Pdual;tmp2: Pdual;kk: integer); cdecl; external libmgl;
 //-----------------------------------------------------------------------------
 /// Get random number with Gaussian distribution
 function  mgl_gauss_rnd(): double; cdecl; external libmgl;
index 37a276e0787f02f3d3967a40a1e7c4320e47cdfa..c95a310febfeeec2b16a9eb596fa9abc595ee7ba 100644 (file)
@@ -26,7 +26,7 @@ class MGL_EXPORT mglCanvasGL : public mglCanvas
 {\r
 public:\r
        mglCanvasGL();\r
-       ~mglCanvasGL();\r
+       virtual ~mglCanvasGL();\r
 \r
        void SetQuality(int =0) {       Quality=2;      }\r
        void Finish();\r
index 7b7a8d52df1fcf61d4d02516b8d45ab62b72590b..277b1ce6c12c549aa89298abb0ecbdfb4a3cb8a7 100644 (file)
@@ -58,6 +58,20 @@ void MGL_EXPORT mgl_tricont_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x,
 void MGL_EXPORT mgl_tricont_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt);\r
 void MGL_EXPORT mgl_tricont_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int, int);\r
 \r
+\r
+/// Draw manual contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c.\r
+void MGL_EXPORT mgl_tricontv_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt);\r
+void MGL_EXPORT mgl_tricontv_xyzcv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int,int);\r
+/// Draw manual contour tubes for triangle mesh for points in arrays {x,y,z}.\r
+void MGL_EXPORT mgl_tricontv_xycv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt);\r
+void MGL_EXPORT mgl_tricontv_xycv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int);\r
+/// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c.\r
+void MGL_EXPORT mgl_tricontv_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT c, const char *sch, const char *opt);\r
+void MGL_EXPORT mgl_tricontv_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int, int);\r
+/// Draw contour tubes for triangle mesh for points in arrays {x,y,z}.\r
+void MGL_EXPORT mgl_tricontv_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt);\r
+void MGL_EXPORT mgl_tricontv_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int, int);\r
+\r
 /// Draw dots in points {x,y,z}.\r
 void MGL_EXPORT mgl_dots(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt);\r
 void MGL_EXPORT mgl_dots_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int,int);\r
index 6110b98c44ef0d1f4fbab4403a65650b491e2065..039b5b1dbbddcbde9c823fd23809d5b279081b4d 100644 (file)
 struct mglArg\r
 {\r
        int type;               ///< Type of argument {0-data,1-string,2-number}\r
-       mglData *d;             ///< Pointer to data (used if type==0)\r
+       mglDataA *d;    ///< Pointer to data (used if type==0)\r
        std::wstring w; ///< String with parameters\r
        std::string s;  ///< String with parameters\r
        mreal v;                ///< Numerical value (used if type==2)\r
-       mglArg()        {       type=-1;        d=0;    v=0;    }\r
+       mglArg():type(-1),d(0),v(0)     {}\r
 };\r
 //-----------------------------------------------------------------------------\r
 /// Structure for MGL command\r
@@ -56,12 +56,7 @@ struct mglNum
 {\r
        mreal d;                ///< Number itself\r
        std::wstring s; ///< Number name\r
-       mglNum *next;   ///< Pointer to next instance in list\r
-       mglNum *prev;   ///< Pointer to prev instance in list\r
-       mglNum()        {       d=0;    next=prev=0;    }\r
-       ~mglNum();\r
-       /// Move variable after var and copy func from var (if func is 0)\r
-       void MoveAfter(mglNum *var);\r
+       mglNum(mreal val=0):d(val)      {}\r
 };\r
 //-----------------------------------------------------------------------------\r
 /// Structure for function name and position.\r
@@ -70,18 +65,17 @@ struct mglFunc
        long pos;\r
        int narg;\r
        std::wstring func;\r
-//     wchar_t func[64];\r
        mglFunc(long p, const wchar_t *f);\r
-       mglFunc(const mglFunc &f);\r
-       mglFunc()       {       pos=narg=-1;    }\r
+       mglFunc(const mglFunc &f):pos(f.pos),narg(f.narg),func(f.func)  {}\r
+       mglFunc():pos(-1),narg(-1)      {}\r
 };\r
 //-----------------------------------------------------------------------------\r
 /// Structure for stack of functions and its arguments.\r
 struct mglFnStack\r
 {\r
-       mglFnStack()    {pos=0;}\r
        long pos;\r
        std::wstring par[10];\r
+       mglFnStack():pos(0)     {}\r
 };\r
 //-----------------------------------------------------------------------------\r
 /// Function for asking question in console mode\r
@@ -92,8 +86,8 @@ class mglParser
 {\r
 friend void mgl_export(wchar_t *out, const wchar_t *in, int type);\r
 public:\r
-       mglVar *DataList;       ///< List with data and its names\r
-       mglNum *NumList;        ///< List with numbers and its names\r
+       std::vector<mglDataA*> DataList;        ///< List with data and its names\r
+       std::vector<mglNum*> NumList;   ///< List with numbers and its names\r
        bool AllowSetSize;      ///< Allow using setsize command\r
        bool AllowFileIO;       ///< Allow reading/saving files\r
        bool Stop;                      ///< Stop command was. Flag prevent further execution\r
@@ -101,10 +95,10 @@ public:
        long InUse;                     ///< Smart pointer (number of users)\r
 \r
        mglParser(bool setsize=false);\r
-       ~mglParser();\r
+       virtual ~mglParser();\r
        /// Find the command by the keyword name\r
-       mglCommand *FindCommand(const char *name);\r
-       mglCommand *FindCommand(const wchar_t *name);\r
+       const mglCommand *FindCommand(const char *name) const MGL_FUNC_PURE;\r
+       const mglCommand *FindCommand(const wchar_t *name) const MGL_FUNC_PURE;\r
        /// Parse and execute the string of MGL script\r
        inline int Parse(HMGL gr, const char *str, long pos=0)\r
        {       mglGraph GR(gr);        return Parse(&GR,str,pos);      }\r
@@ -134,14 +128,14 @@ public:
        /// Check if name is function and return its address (or 0 if no)\r
        long IsFunc(const std::wstring &name, int *narg=0);\r
        /// Find variable or return 0 if absent\r
-       mglVar *FindVar(const char *name);\r
-       mglVar *FindVar(const wchar_t *name);\r
+       mglDataA *FindVar(const char *name) MGL_FUNC_PURE;\r
+       mglDataA *FindVar(const wchar_t *name) MGL_FUNC_PURE;\r
        /// Find variable or create it if absent\r
-       mglVar *AddVar(const char *name);\r
-       mglVar *AddVar(const wchar_t *name);\r
+       mglData *AddVar(const char *name);\r
+       mglData *AddVar(const wchar_t *name);\r
        /// Find number or return 0 if absent\r
-       mglNum *FindNum(const char *name);\r
-       mglNum *FindNum(const wchar_t *name);\r
+       mglNum *FindNum(const char *name) MGL_FUNC_PURE;\r
+       mglNum *FindNum(const wchar_t *name) MGL_FUNC_PURE;\r
        /// Find number or create it if absent\r
        mglNum *AddNum(const char *name);\r
        mglNum *AddNum(const wchar_t *name);\r
@@ -152,8 +146,6 @@ public:
        void AddCommand(mglCommand *cmd, int num=0);\r
        /// Restore Once flag\r
        inline void RestoreOnce()       {       Once = true;    }\r
-       /// Delete variable\r
-       void DeleteVar(mglVar *v);\r
        /// Delete variable by its name\r
        void DeleteVar(const char *name);\r
        void DeleteVar(const wchar_t *name);\r
index 47c50be87aa8deb1d65742e72c180c9fa437a586..c7568866bbbc30038bacdc394479af6f15e998a0 100644 (file)
@@ -34,22 +34,26 @@ HMDT MGL_EXPORT mgl_pde_solve(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im
 uintptr_t MGL_EXPORT mgl_pde_solve_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0,const char *opt,int,int);
 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)
 HADT MGL_EXPORT mgl_qo2d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
-HADT MGL_EXPORT mgl_qo2d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
+HADT MGL_EXPORT mgl_qo2d_func_c(ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
 uintptr_t MGL_EXPORT mgl_qo2d_solve_c_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, int);
 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)
 HMDT MGL_EXPORT mgl_qo2d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
-HMDT MGL_EXPORT mgl_qo2d_func(dual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
+HMDT MGL_EXPORT mgl_qo2d_func(ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy);
 uintptr_t MGL_EXPORT mgl_qo2d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, int);
 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)
 HADT MGL_EXPORT mgl_qo3d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
-HADT MGL_EXPORT mgl_qo3d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
+HADT MGL_EXPORT mgl_qo3d_func_c(ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
 uintptr_t MGL_EXPORT mgl_qo3d_solve_c_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, uintptr_t* zz, int);
 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)
 HMDT MGL_EXPORT mgl_qo3d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
-HMDT MGL_EXPORT mgl_qo3d_func(dual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
+HMDT MGL_EXPORT mgl_qo3d_func(ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz);
 uintptr_t MGL_EXPORT mgl_qo3d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, uintptr_t* zz, int);
 /// Saves result of ODE solving of n equations with right part func and initial conditions x0 over time interval [0,tmax] with time step dt
-HMDT MGL_EXPORT mgl_ode_solve(void (*func)(const mreal *x, mreal *dx, void *par), int n, mreal *x0, mreal dt, mreal tmax, void *par);
+HMDT MGL_EXPORT mgl_ode_solve(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par);
+/// Saves result of ODE solving for var variables with right part func (separated by ';') and initial conditions x0 over time interval [0,tmax] with time step dt
+HMDT MGL_EXPORT mgl_ode_solve_str(const char *func, const char *var, HCDT x0, mreal dt, mreal tmax);
+/// Saves result of ODE solving of n equations with right part func and initial conditions x0 over time interval [0,tmax] with time step dt. Function bord (if not NULL) is called each time step to apply border reflection.
+HMDT MGL_EXPORT mgl_ode_solve_ex(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par, void (*bord)(mreal *x, const mreal *xp, void *par));
 /// Finds ray with starting point r0, p0 (and prepares ray data for mgl_qo2d_solve)
 HMDT MGL_EXPORT mgl_ray_trace(const char *ham, mreal x0, mreal y0, mreal z0, mreal px, mreal py, mreal pz, mreal dt, mreal tmax);
 uintptr_t MGL_EXPORT mgl_ray_trace_(const char *ham, mreal *x0, mreal *y0, mreal *z0, mreal *px, mreal *py, mreal *pz, mreal *dt, mreal *tmax,int);
index 404f1cec146f5996b4401c4da948e218185ffcf6..5da1bb967617512d3cdb00063948c67678970481 100644 (file)
@@ -71,6 +71,16 @@ void MGL_EXPORT mgl_ellipse_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mre
 /// Draws the rhomb between points p1,p2 with color stl and width r\r
 void MGL_EXPORT mgl_rhomb(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, double r, const char *stl);\r
 void MGL_EXPORT mgl_rhomb_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r, const char *stl, int);\r
+/// Draws the polygon based on points p1,p2 with color stl\r
+void MGL_EXPORT mgl_polygon(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, int n, const char *stl);\r
+void MGL_EXPORT mgl_polygon_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, int *n, const char *stl, int);\r
+       /// Draws the arc around axis pr with center at p0 and starting from p1, by color stl and angle a (in degrees)\r
+void MGL_EXPORT mgl_arc_ext(HMGL gr, double x0, double y0, double z0, double xr, double yr, double zr, double x1, double y1, double z1, double a, const char* stl);\r
+void MGL_EXPORT mgl_arc_ext_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *xr, mreal *yr, mreal *zr, mreal *x1, mreal *y1, mreal *z1, mreal *a, const char *stl, int);\r
+       /// Draws the arc around axis 'z' with center at p0 and starting from p1, by color stl and angle a (in degrees)\r
+void MGL_EXPORT mgl_arc(HMGL gr, double x0, double y0, double x1, double y1, double a, const char* stl);\r
+void MGL_EXPORT mgl_arc_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *x1, mreal *y1, mreal *a, const char *stl,int l);\r
+\r
 \r
 /// Draw cones from points {x,y,z} to axis plane\r
 void MGL_EXPORT mgl_cones_xyz(HMGL graph, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt);\r
index a9fd0853ab739c66e382f7f5a50f40b0410c66f6..e416d7d56dd3c59a2d2570a33104f09bddb5ce1f 100644 (file)
@@ -32,13 +32,13 @@ class QScrollArea;
 class QSpinBox;\r
 class QTimer;\r
 class mglCanvas;\r
+class mglTask;\r
 //-----------------------------------------------------------------------------\r
 /// Class is Qt widget which display MathGL graphics\r
 class MGL_EXPORT QMathGL : public QWidget\r
 {\r
        Q_OBJECT\r
 public:\r
-       friend void *mgl_qt_thr(void *);\r
        QString appName;        ///< Application name for message boxes\r
        bool autoResize;        ///< Allow auto resizing (default is false)\r
        bool enableMouse;       ///< Enable mouse handlers\r
@@ -62,18 +62,19 @@ public:
        inline void zoomRegion(mreal xx1,mreal xx2,mreal yy1, mreal yy2)\r
        {       x1=xx1; y1=yy1; x2=xx2; y2=yy2; }\r
 \r
-       int getPer()    {return int(per);}      ///< Get perspective value\r
-       int getPhi()    {return int(phi);}      ///< Get Phi-angle value\r
-       int getTet()    {return int(tet);}      ///< Get Theta-angle value\r
-       bool getAlpha() {return alpha;} ///< Get transparency state\r
-       bool getLight() {return light;} ///< Get lightning state\r
-       bool getZoom()  {return zoom;}  ///< Get mouse zooming state\r
-       bool getRotate(){return rotate;}        ///< Get mouse rotation state\r
-       bool getViewYZ(){return viewYZ;}        ///< Get mouse rotation axis\r
+       int getPer() const      {return int(per);}      ///< Get perspective value\r
+       int getPhi() const      {return int(phi);}      ///< Get Phi-angle value\r
+       int getTet() const      {return int(tet);}      ///< Get Theta-angle value\r
+       bool getAlpha() const   {return alpha;} ///< Get transparency state\r
+       bool getLight() const   {return light;} ///< Get lightning state\r
+       bool getZoom() const    {return zoom;}  ///< Get mouse zooming state\r
+       bool getRotate() const  {return rotate;}///< Get mouse rotation state\r
+       bool getViewYZ() const  {return viewYZ;}///< Get mouse rotation axis\r
        bool isActive(int xs,int ys);   ///< Check if active point is pressed\r
 \r
 public slots:\r
-       void refresh();\r
+       void refresh();                 ///< Redraw image with new zoom and view parameters\r
+       void refreshHQ();               ///< Redraw image with HQ (can be slower than refresh())\r
        void update();                  ///< Update picture\r
        void copy();                    ///< copy graphics to clipboard\r
        void copyClickCoor();   ///< copy click coordinates to clipboard\r
@@ -87,6 +88,7 @@ public slots:
        void setGrid(bool r);   ///< Switch on/off grid drawing\r
        void imgSize(int w, int h);     ///< Set image size\r
        void setViewYZ(bool v); ///< Switch on/off rotation around Y and Z axis\r
+       void setDotsPreview(bool d=true);       ///< Set to use dots for image preview/rotation\r
 \r
        void setCustZoom(bool a);       ///< Switch on/off using custom zoom\r
        void setCustDraw(bool a);       ///< Switch on/off using custom draw\r
@@ -127,6 +129,8 @@ public slots:
        void addCurve();                                        ///< add curve into primitives\r
        void addRhomb();                                        ///< add rhombus into primitives\r
        void addEllipse();                                      ///< add ellipse into primitives\r
+       void addArc();                                  ///< add arc into primitives\r
+       void addPolygon(int n=-1);                      ///< add polygon into primitives\r
        void addText(QString txt="");           ///< add text into primitives\r
        void setStyle(int id, QString stl);///< set style for primitive with id\r
 \r
@@ -152,7 +156,7 @@ signals:
        void frameChanged(int);         ///< Need another frame to show\r
        void showWarn(QString);         ///< Show warnings\r
        void posChanged(QString message);       ///< user click to show mouse position\r
-       void objChanged(int objId);     ///< User double-click to select object/line\r
+       void objChanged(int objId);     ///< User click to select object/line\r
        void refreshData();\r
        void doubleClick(int id);       ///< Double mouse click by object with id\r
        void askStyle(int id);          ///< Update style\r
@@ -176,8 +180,8 @@ protected:
        int (*draw_func)(mglBase *gr, void *par);\r
        mglDraw *draw;          ///< Class for drawing -- need to call directly due to inheritance mechanism\r
        QString mousePos;       ///< Last mouse position\r
-       QPixmap pic;                    ///< Pixmap for drawing (changed by update)\r
-       double tet, phi;                ///< Rotation angles\r
+       QPixmap pic;            ///< Pixmap for drawing (changed by update)\r
+       double tet, phi;        ///< Rotation angles\r
        double per;                     ///< Value of perspective ( must be in [0,1) )\r
        bool alpha;                     ///< Transparency state\r
        bool light;                     ///< Lightning state\r
@@ -185,17 +189,24 @@ protected:
        bool custDraw;          ///< Use custom draw before main drawing\r
        bool zoom;                      ///< Mouse zoom state\r
        bool grid;                      ///< Grid drawing state\r
-       bool rotate;                    ///< Mouse rotation state\r
-       bool viewYZ;                    ///< Set mouse rotation around Y and Z axis (instead of X and Z)\r
+       bool rotate;            ///< Mouse rotation state\r
+       bool viewYZ;            ///< Set mouse rotation around Y and Z axis (instead of X and Z)\r
+       bool dotsRefr;          ///< Set dots for image preview/rotation\r
        mreal x1,x2,y1,y2;      ///< Zoom in region\r
        mreal ax1,ax2,ay1,ay2;  ///< Axis range zoom\r
        bool showMessage;       ///< Flag for showing messages (enabled by each execute())\r
        QMenu *popup;           ///< Pointer to pop-up menu\r
        QTimer *timer;          ///< Timer for animation\r
+       QTimer *timerRefr;      ///< Timer for redrawing\r
+private slots:\r
+       void afterPlot();       ///< minor tuning after plot was done\r
 private:\r
        int x0, y0, xe, ye;             ///< Temporary variables for mouse\r
        uchar *grBuf;\r
-       void draw_thr();\r
+       void drawPrim();\r
+       int prevQuality;\r
+//     QThread *thread;\r
+//     mglTask *task;\r
 };\r
 //-----------------------------------------------------------------------------\r
 /// Class for drawing the MGL script\r
@@ -214,6 +225,6 @@ public:
 /// Convert bitmap from mglCanvasWnd to QPixmap\r
 void mglConvertFromGraph(QPixmap &pic, mglCanvas *gr, uchar **buf);\r
 /// Make menu, toolbars and return popup menu for MainWindow\r
-QMenu *mglMakeMenu(QMainWindow* Wnd, QMathGL* QMGL, QSpinBox*& tet, QSpinBox*& phi);\r
+MGL_EXPORT QMenu *mglMakeMenu(QMainWindow* Wnd, QMathGL* QMGL, QSpinBox*& tet, QSpinBox*& phi);\r
 //-----------------------------------------------------------------------------\r
 #endif\r
index 6fa165c5e1aab717155e3b678d99648d923dd952..85758a397daa156cb5214c4faa063c0d7051a1f9 100644 (file)
@@ -24,6 +24,7 @@
 //-----------------------------------------------------------------------------
 const mreal Pi = M_PI;
 const mreal NaN = NAN;
+const mreal Inf = INFINITY;
 const mreal mgl_min_a = 1./256;
 //-----------------------------------------------------------------------------
 #define MGL_SET_XYZ(p,xx,yy,zz)                {p.x=(xx);p.y=(yy);p.z=(zz);}
@@ -35,12 +36,18 @@ const mreal mgl_min_a = 1./256;
 struct MGL_EXPORT mglPoint
 {
        mreal x,y,z,c;
-       mglPoint(mreal X=0,mreal Y=0,mreal Z=0,mreal C=0){x=X;y=Y;z=Z;c=C;}
+       mglPoint(mreal X=0,mreal Y=0,mreal Z=0,mreal C=0):x(X),y(Y),z(Z),c(C) {}
+       mglPoint(const mglPoint &d):x(d.x),y(d.y),z(d.z),c(d.c) {}
+#if MGL_HAVE_RVAL
+       mglPoint(mglPoint &&d):x(d.x),y(d.y),z(d.z),c(d.c)      {}
+#endif
        inline bool IsNAN()             {       return (x!=x || y!=y || z!=z || c!=c);  }
        inline mreal val(int i) {       return (i<2 ? (i==0 ? x:y) : (i==2 ? z:c));     }
        inline mreal norm()             {       return sqrt(x*x+y*y+z*z);       }
        inline void Normalize() {       mreal v=norm(); x/=v;   y/=v;   z/=v;   }
 
+       inline const mglPoint &operator=(const mglPoint &p)
+       {       x=p.x;  y=p.y;  z=p.z;  c=p.c;  return p;       }
        inline void operator+=(const mglPoint &a)       {       x+=a.x; y+=a.y; z+=a.z; c+=a.c; }
        inline void operator-=(const mglPoint &a)       {       x-=a.x; y-=a.y; z-=a.z; c-=a.c; }
        inline void operator+=(mreal a) {       x+=a;   y+=a;   z+=a;   }
@@ -74,9 +81,11 @@ inline mglPoint operator^(const mglPoint &a, const mglPoint &b)
 inline mglPoint operator!(const mglPoint &a)
 {      mreal f=mgl_hypot(a.x,a.y);     return f==0?mglPoint(0.,1.,0.):mglPoint(-a.y/f, a.x/f, 0);      }
 inline bool operator==(const mglPoint &a, const mglPoint &b)
-{      return !memcmp(&a, &b, sizeof(mglPoint));       }
+{      return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.c-b.c)*(a.c-b.c)==0;      }
+//{    return !memcmp(&a, &b, sizeof(mglPoint));       }
 inline bool operator!=(const mglPoint &a, const mglPoint &b)
-{      return memcmp(&a, &b, sizeof(mglPoint));        }
+{      return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.c-b.c)*(a.c-b.c)!=0;      }
+//{    return memcmp(&a, &b, sizeof(mglPoint));        }
 inline bool operator<(const mglPoint &a, const mglPoint &b)
 {      return a.x<=b.x && a.y<=b.y && a.z<=b.z;        }
 inline bool operator>(const mglPoint &a, const mglPoint &b)
@@ -94,11 +103,16 @@ struct MGL_EXPORT mglColor
        float a;        ///< Alpha component of color
 
        /// Constructor for RGB components manualy
-       mglColor(float R,float G,float B, float A=1){   r=R;    g=G;    b=B;    a=A;    }
+       mglColor(float R,float G,float B, float A=1):r(R),g(G),b(B),a(A)        {}
        /// Constructor set default color
-       mglColor()              {       r=g=b=0;        a=1;    }
+       mglColor():r(0),g(0),b(0),a(1)  {}
        /// Constructor set color from character id
        mglColor(char c, float bright=1)                {       Set(c,bright);  }
+       /// Copy constructor
+       mglColor(const mglColor &d):r(d.r),g(d.g),b(d.b),a(d.a) {}
+#if MGL_HAVE_RVAL
+       mglColor(mglColor &&d):r(d.r),g(d.g),b(d.b),a(d.a)      {}
+#endif
        /// Set color as Red, Green, Blue values
        void Set(float R,float G,float B,float A=1)     {       r=R;    g=G;    b=B;    a=A;    }
        /// Set color as Red, Green, Blue values
@@ -123,11 +137,15 @@ struct MGL_EXPORT mglColor
                float rgb[3];   mgl_chrrgb(p,rgb);
                Set(mglColor(rgb[0],rgb[1],rgb[2]),bright);
        }
+       inline const mglColor &operator=(const mglColor &p)
+       {       r=p.r;  g=p.g;  b=p.b;  a=p.a;  return p;       }
        /// Copy color from other one
        inline bool operator==(const mglColor &c) const
-       {       return !memcmp(this, &c, sizeof(mglColor));     }
+       {       return (r-c.r)*(r-c.r)+(g-c.g)*(g-c.g)+(b-c.b)*(b-c.b)+(a-c.a)*(a-c.a)==0;      }
+//     {       return !memcmp(this, &c, sizeof(mglColor));     }
        inline bool operator!=(const mglColor &c) const
-       {       return memcmp(this, &c, sizeof(mglColor));              }
+       {       return (r-c.r)*(r-c.r)+(g-c.g)*(g-c.g)+(b-c.b)*(b-c.b)+(a-c.a)*(a-c.a)!=0;      }
+//     {       return memcmp(this, &c, sizeof(mglColor));              }
        inline bool operator<(const mglColor &c) const
        {       return memcmp(this, &c, sizeof(mglColor))<0;    }
        // transparency still the same
diff --git a/include/xpm/accessories-calculator.png b/include/xpm/accessories-calculator.png
deleted file mode 100644 (file)
index 9248971..0000000
Binary files a/include/xpm/accessories-calculator.png and /dev/null differ
diff --git a/include/xpm/accessories-calculator.xpm b/include/xpm/accessories-calculator.xpm
deleted file mode 100644 (file)
index 7a35ccb..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/* XPM */
-static const char * accessories_calculator_xpm[] = {
-"16 16 93 2",
-"      c None",
-".     c #555753",
-"+     c #B8BBB3",
-"@     c #858971",
-"#     c #787C66",
-"$     c #83876F",
-"%     c #7A7E68",
-"&     c #7D816A",
-"*     c #777B5E",
-"=     c #555843",
-"-     c #585B45",
-";     c #474938",
-">     c #393B2D",
-",     c #717559",
-"'     c #989C8A",
-")     c #969A88",
-"!     c #979B89",
-"~     c #44494A",
-"{     c #3A4041",
-"]     c #3F4446",
-"^     c #383D3F",
-"/     c #303638",
-"(     c #303537",
-"_     c #2F3537",
-":     c #313739",
-"<     c #9C9FA1",
-"[     c #5B5C5C",
-"}     c #595A5C",
-"|     c #737678",
-"1     c #5B5C5E",
-"2     c #595A5B",
-"3     c #66696B",
-"4     c #595A5A",
-"5     c #585858",
-"6     c #616365",
-"7     c #626567",
-"8     c #515354",
-"9     c #535555",
-"0     c #535455",
-"a     c #5E605C",
-"b     c #6B6D6B",
-"c     c #808080",
-"d     c #7F7F7F",
-"e     c #535353",
-"f     c #7E7E7E",
-"g     c #818181",
-"h     c #555555",
-"i     c #575757",
-"j     c #565758",
-"k     c #848484",
-"l     c #898989",
-"m     c #696A69",
-"n     c #545454",
-"o     c #555556",
-"p     c #787878",
-"q     c #545657",
-"r     c #878787",
-"s     c #888888",
-"t     c #87898A",
-"u     c #505051",
-"v     c #505152",
-"w     c #646667",
-"x     c #535354",
-"y     c #515151",
-"z     c #616364",
-"A     c #515252",
-"B     c #606365",
-"C     c #5B5B5B",
-"D     c #5A5A5A",
-"E     c #7D7D7D",
-"F     c #828282",
-"G     c #545455",
-"H     c #585859",
-"I     c #696A68",
-"J     c #858585",
-"K     c #565656",
-"L     c #838383",
-"M     c #8A8A8A",
-"N     c #8D8D8D",
-"O     c #858788",
-"P     c #646666",
-"Q     c #525353",
-"R     c #616262",
-"S     c #555757",
-"T     c #5E5F5F",
-"U     c #9B9B9B",
-"V     c #858686",
-"W     c #888989",
-"X     c #868686",
-"Y     c #878888",
-"Z     c #6C6D6B",
-"`     c #757674",
-" .    c #787977",
-". . . . . . . . . . . . . . . . ",
-". + + + + + + + + + + + + + + . ",
-". + @ @ @ @ @ @ @ # $ % & @ + . ",
-". + * * * * * * * = - ; > , + . ",
-". + ' ' ' ' ' ' ' ) ! ) ! ' + . ",
-". ~ + + + + + + + + + + + + { . ",
-". ] ^ / / ( _ _ _ _ _ _ _ _ : . ",
-". < [ } | 1 2 3 4 5 6 7 8 9 0 . ",
-"a b c d e f g h d g i j k l k . ",
-". m d f n f f o p d i q r s r . ",
-". t u v w x y z A y 6 B 5 C D . ",
-". m c d 9 E g n F k G H r s s . ",
-". I k E y c J K L J K 5 M N M . ",
-". O n G P Q K R S K T 5 M U M . ",
-". O V V W V X Y X X Y Z `  .` . ",
-". . . . . . . . . . . . . . . . "};
diff --git a/include/xpm/alpha.png b/include/xpm/alpha.png
deleted file mode 100644 (file)
index fdb8836..0000000
Binary files a/include/xpm/alpha.png and /dev/null differ
index 1c414687dcf03605811602fe26c24ef3ccd8cfc0..102c0e174a79fee5cadbcca8545f9d745902ccfc 100644 (file)
 /* XPM */
 static const char * alpha_xpm[] = {
-"16 16 7 1",
-"      c None",
-"!     c #000000",
-"#     c #0000FF",
-"$     c #000080",
-"%     c #008080",
-"&     c #FFFFFF",
-"'     c #00FFFF",
-"                ",
-"                ",
-"    #$$$$$$     ",
-"   !$!!$!!!!#   ",
-" #%%&$%''!'%'$  ",
-"#%##!#$'%#%%##! ",
-" !%%!$&%%'!!%%$ ",
-" #''%#%!$##''%  ",
-"  %''##%&&%''#  ",
-"   %'%#%&&%'#   ",
-"   #'%#%&$'%    ",
-"    $'#%&%%     ",
-"     %%%#%#     ",
-"     #!%$%      ",
-"      #!$       ",
-"       !#       "};
+"16 16 107 2",
+"      c None",
+".     c #395155",
+"+     c #3A5155",
+"@     c #384F54",
+"#     c #4C6A71",
+"$     c #68929C",
+"%     c #B8FFFF",
+"&     c #B1F9FF",
+"*     c #B7FFFF",
+"=     c #6B939C",
+"-     c #113F4A",
+";     c #7CADB9",
+">     c #B4FCFF",
+",     c #84BAC8",
+"'     c #51585B",
+")     c #78888C",
+"!     c #79898D",
+"~     c #4D4D4D",
+"{     c #17B0D6",
+"]     c #2CE0FF",
+"^     c #1D99B8",
+"/     c #1F282B",
+"(     c #A1E2F3",
+"_     c #ABF0FF",
+":     c #ACF2FF",
+"<     c #658187",
+"[     c #E1FFFF",
+"}     c #D7F8FF",
+"|     c #D7F9FF",
+"1     c #D7F7FF",
+"2     c #428494",
+"3     c #28D6FF",
+"4     c #2AD6FF",
+"5     c #26C3EA",
+"6     c #1A88A2",
+"7     c #346974",
+"8     c #7BB8C6",
+"9     c #9FDEEE",
+"0     c #97D4E3",
+"a     c #C2E2E9",
+"b     c #D6F8FF",
+"c     c #C5E6ED",
+"d     c #2DB7DA",
+"e     c #2AD1FB",
+"f     c #23BFE6",
+"g     c #0B6A81",
+"h     c #42B0CC",
+"i     c #4DB0C8",
+"j     c #3A575C",
+"k     c #7B878A",
+"l     c #7D8A8E",
+"m     c #7D8A8D",
+"n     c #3B4A4E",
+"o     c #0586A5",
+"p     c #00BEED",
+"q     c #005A70",
+"r     c #317F93",
+"s     c #56DFFF",
+"t     c #47AEC7",
+"u     c #7ADDF6",
+"v     c #81ECFF",
+"w     c #84F0FF",
+"x     c #2F7E90",
+"y     c #00DBFF",
+"z     c #0094B9",
+"A     c #3FA4BC",
+"B     c #4CC5E4",
+"C     c #72D1E7",
+"D     c #7FE4FE",
+"E     c #80E5FF",
+"F     c #78D1E8",
+"G     c #0EABD1",
+"H     c #00BBEA",
+"I     c #51D4F4",
+"J     c #3A7888",
+"K     c #85EEFF",
+"L     c #60C0D8",
+"M     c #00B7E6",
+"N     c #0096BB",
+"O     c #215764",
+"P     c #3FA7C0",
+"Q     c #70C6DC",
+"R     c #83ECFF",
+"S     c #378599",
+"T     c #00B1DE",
+"U     c #4AC5E4",
+"V     c #447B89",
+"W     c #82E8FF",
+"X     c #84E4FD",
+"Y     c #007696",
+"Z     c #00556A",
+"`     c #0A1A1E",
+" .    c #4FC5E2",
+"..    c #75D1E8",
+"+.    c #81E7FF",
+"@.    c #598B98",
+"#.    c #00B1DF",
+"$.    c #235C69",
+"%.    c #6BC4DA",
+"&.    c #82E6FF",
+"*.    c #148099",
+"=.    c #2C5B65",
+"-.    c #74D6F0",
+";.    c #074F61",
+">.    c #13353F",
+",.    c #67B8C9",
+"'.    c #0E191C",
+"            . + + @             ",
+"        # $ % & & * = -         ",
+"      ; > , ' ) ! ~ { ] ^       ",
+"  / ( _ : < [ } | 1 2 3 4 5 6   ",
+"  7 8 9 0 a b } } b c d e f g   ",
+"    h i j k l l l l m n o p q   ",
+"    r s t u v v v v w x y z     ",
+"      A B C D E E E F G H       ",
+"        I J K D E E L M N       ",
+"        O P Q E E R S T         ",
+"          U V W E X Y Z         ",
+"          `  ...+.@.#.          ",
+"            $.%.&.*.            ",
+"              =.-.;.            ",
+"              >.,.              ",
+"                '.              "};
diff --git a/include/xpm/alpha_on.xpm b/include/xpm/alpha_on.xpm
deleted file mode 100644 (file)
index 58e50f7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* XPM */
-static const char * alpha_on_xpm[] = {
-"16 16 7 1",
-"      c None",
-"!     c #000000",
-"#     c #FF0000",
-"$     c #800000",
-"%     c #808000",
-"&     c #FFFFFF",
-"'     c #FFFF00",
-"                ",
-"                ",
-"    #$$$$$$     ",
-"   !$!!$!!!!#   ",
-" #%%&$%''!'%'$  ",
-"#%##!#$'%#%%##! ",
-" !%%!$&%%'!!%%$ ",
-" #''%#%!$##''%  ",
-"  %''##%&&%''#  ",
-"   %'%#%&&%'#   ",
-"   #'%#%&$'%    ",
-"    $'#%&%%     ",
-"     %%%#%#     ",
-"     #!%$%      ",
-"      #!$       ",
-"       !#       "};
diff --git a/include/xpm/arc.xpm b/include/xpm/arc.xpm
new file mode 100644 (file)
index 0000000..28f80a1
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char * arc_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"     ......     ",
+"   ..      ..   ",
+"  .          .  ",
+"              . ",
+"              . ",
+"               .",
+"               .",
+"               .",
+"                ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/axis.xpm b/include/xpm/axis.xpm
new file mode 100644 (file)
index 0000000..65014f1
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char * axis_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+" ..             ",
+"  .             ",
+"  .             ",
+" ..             ",
+"  .             ",
+"  .             ",
+" ..             ",
+"  .             ",
+"  .             ",
+" ..             ",
+"  .             ",
+"  .             ",
+" .............. ",
+"  .   .   .   . ",
+"                "};
index eab287c3a8f20d48b20a697f9b2a2bb01b96903e..d09869f44cd9ef6751128c26032e9f548c68dedc 100644 (file)
@@ -1,5 +1,5 @@
 /* XPM */
-static char * axis_sh_xpm[] = {
+static const char * axis_sh_xpm[] = {
 "16 16 3 1",
 "      c None",
 ".     c #000000",
diff --git a/include/xpm/barrow_a.xpm b/include/xpm/barrow_a.xpm
new file mode 100644 (file)
index 0000000..8545b8f
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+const char * barrow_a_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"                ",
+"    ...         ",
+"     ....       ",
+"      .....     ",
+"       ......   ",
+"............... ",
+"       ......   ",
+"      .....     ",
+"     ....       ",
+"    ...         ",
+"                ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/barrow_d.xpm b/include/xpm/barrow_d.xpm
new file mode 100644 (file)
index 0000000..fe133de
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+const char * barrow_d_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"                ",
+"          .     ",
+"         ...    ",
+"        .....   ",
+"       .......  ",
+"............... ",
+"       .......  ",
+"        .....   ",
+"         ...    ",
+"          .     ",
+"                ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/barrow_i.xpm b/include/xpm/barrow_i.xpm
new file mode 100644 (file)
index 0000000..54e91ad
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+const char * barrow_i_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"             .. ",
+"             .. ",
+"             .. ",
+"             .. ",
+"             .. ",
+"............... ",
+"             .. ",
+"             .. ",
+"             .. ",
+"             .. ",
+"             .. ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/barrow_k.xpm b/include/xpm/barrow_k.xpm
new file mode 100644 (file)
index 0000000..be962b1
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+const char * barrow_k_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"             .. ",
+"    ...      .. ",
+"     ....    .. ",
+"      .....  .. ",
+"       ........ ",
+"............... ",
+"       ........ ",
+"      .....  .. ",
+"     ....    .. ",
+"    ...      .. ",
+"             .. ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/barrow_n.xpm b/include/xpm/barrow_n.xpm
new file mode 100644 (file)
index 0000000..7d2b54c
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+const char * barrow_n_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                ",
+"..............  ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/barrow_o.xpm b/include/xpm/barrow_o.xpm
new file mode 100644 (file)
index 0000000..a0ea264
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+const char * barrow_o_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"                ",
+"        ....    ",
+"       ......   ",
+"      ........  ",
+"      ........  ",
+"..............  ",
+"      ........  ",
+"      ........  ",
+"       .......  ",
+"        ....    ",
+"                ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/barrow_s.xpm b/include/xpm/barrow_s.xpm
new file mode 100644 (file)
index 0000000..f19c4d8
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+const char * barrow_s_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"                ",
+"      ........  ",
+"      ........  ",
+"      ........  ",
+"      ........  ",
+"..............  ",
+"      ........  ",
+"      ........  ",
+"      ........  ",
+"      ........  ",
+"                ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/barrow_t.xpm b/include/xpm/barrow_t.xpm
new file mode 100644 (file)
index 0000000..06e23d5
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+const char * barrow_t_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"                ",
+"     ..         ",
+"     ....       ",
+"     ......     ",
+"     ........   ",
+"............... ",
+"     ........   ",
+"     ......     ",
+"     ....       ",
+"     ..         ",
+"                ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/barrow_v.xpm b/include/xpm/barrow_v.xpm
new file mode 100644 (file)
index 0000000..b31d4d2
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+const char * barrow_v_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"                ",
+"           ...  ",
+"         ....   ",
+"       .....    ",
+"     ......     ",
+"...........     ",
+"     ......     ",
+"       .....    ",
+"         ....   ",
+"           ...  ",
+"                ",
+"                ",
+"                ",
+"                "};
index e2d9d122904f12c6485799ceb19b50a58869c142..23260d1a9ed42c7283823cbf0e8bb7788dbafb64 100644 (file)
@@ -1,5 +1,5 @@
 /* XPM */
-static char * box_xpm[] = {
+static const char * box_xpm[] = {
 "16 16 3 1",
 "      c None",
 ".     c #000000",
diff --git a/include/xpm/comment.xpm b/include/xpm/comment.xpm
new file mode 100644 (file)
index 0000000..1aebddd
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char * comment_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #009f00",
+"                ",
+"                ",
+"                ",
+"     .    .     ",
+"     .    .     ",
+"     .    .     ",
+"  ............  ",
+"     .    .     ",
+"     .    .     ",
+"     .    .     ",
+"     .    .     ",
+"  ............  ",
+"     .    .     ",
+"     .    .     ",
+"     .    .     ",
+"                "};
diff --git a/include/xpm/delete.xpm b/include/xpm/delete.xpm
new file mode 100644 (file)
index 0000000..a191ea2
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char * delete_xpm[] = {
+"16 16 2 1",
+"      c none",
+".     c #000000",
+"                ",
+"                ",
+"                ",
+"  ...      ...  ",
+"   ...    ...   ",
+"    ...  ...    ",
+"     ......     ",
+"      ....      ",
+"      ....      ",
+"     ......     ",
+"    ...  ...    ",
+"   ...    ...   ",
+"  ...      ...  ",
+"                ",
+"                ",
+"                "};
diff --git a/include/xpm/dialog-information.png b/include/xpm/dialog-information.png
deleted file mode 100644 (file)
index 8851b99..0000000
Binary files a/include/xpm/dialog-information.png and /dev/null differ
diff --git a/include/xpm/document-export.png b/include/xpm/document-export.png
deleted file mode 100644 (file)
index eb82440..0000000
Binary files a/include/xpm/document-export.png and /dev/null differ
diff --git a/include/xpm/document-export.xpm b/include/xpm/document-export.xpm
deleted file mode 100644 (file)
index 489a4f4..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/* XPM */
-static const char * document_export_xpm[] = {
-"16 16 147 2",
-"      c None",
-".     c #38678B",
-"+     c #3D698A",
-"@     c #4A7180",
-"#     c #58787A",
-"$     c #B1CEE6",
-"%     c #D0DFEF",
-"&     c #C5DBEC",
-"*     c #9BC2DF",
-"=     c #688BA0",
-"-     c #436E88",
-";     c #6B7F88",
-">     c #667173",
-",     c #627075",
-"'     c #4A6D85",
-")     c #41749A",
-"!     c #44789F",
-"~     c #9EBFD9",
-"{     c #C1D9EB",
-"]     c #5186AF",
-"^     c #4E6A7D",
-"/     c #6E99B6",
-"(     c #ABCBE2",
-"_     c #92B7D3",
-":     c #547D9B",
-"<     c #D5DFE5",
-"[     c #7798B0",
-"}     c #79A7CA",
-"|     c #8FB3CE",
-"1     c #3D6B8E",
-"2     c #ACBCC3",
-"3     c #5892BD",
-"4     c #EF9800",
-"5     c #ECA307",
-"6     c #BDD552",
-"7     c #98BFDC",
-"8     c #719FBF",
-"9     c #739FC0",
-"0     c #96BBD8",
-"a     c #95A9AF",
-"b     c #02ABF0",
-"c     c #0074F6",
-"d     c #F97200",
-"e     c #FE3C00",
-"f     c #FF3500",
-"g     c #CAC6AC",
-"h     c #ABC8DF",
-"i     c #92A6AC",
-"j     c #BFE6E5",
-"k     c #1CFFDF",
-"l     c #32FFCA",
-"m     c #F99A00",
-"n     c #FF7400",
-"o     c #FDA917",
-"p     c #E4E822",
-"q     c #9DE4A5",
-"r     c #37698D",
-"s     c #ACCBE3",
-"t     c #3B6B8F",
-"u     c #8BA4AF",
-"v     c #9EDEE9",
-"w     c #8CFDCB",
-"x     c #BBFF41",
-"y     c #ECEA10",
-"z     c #F2C505",
-"A     c #B2FA4B",
-"B     c #53F8BE",
-"C     c #3BC4F1",
-"D     c #328AFE",
-"E     c #AABCD1",
-"F     c #3F6C8E",
-"G     c #9AAEB4",
-"H     c #BBF8EA",
-"I     c #A0FE7E",
-"J     c #EEEEEE",
-"K     c #FAC004",
-"L     c #FDB701",
-"M     c #DDE01B",
-"N     c #49FEB4",
-"O     c #00AEFF",
-"P     c #0039FF",
-"Q     c #0024B3",
-"R     c #0029CA",
-"S     c #0057FF",
-"T     c #03BDFB",
-"U     c #28FFD3",
-"V     c #85FE79",
-"W     c #E3FF18",
-"X     c #DDFE1F",
-"Y     c #C7FF34",
-"Z     c #8BFF72",
-"`     c #F0CA07",
-" .    c #AFFA4D",
-"..    c #59FEA3",
-"+.    c #2FE6CE",
-"@.    c #21CBDE",
-"#.    c #17CDE7",
-"$.    c #13DBEB",
-"%.    c #13FFE9",
-"&.    c #16FFE5",
-"*.    c #43FABA",
-"=.    c #3DF5C0",
-"-.    c #2BECD2",
-";.    c #08D3F4",
-">.    c #009FFF",
-",.    c #F89A00",
-"'.    c #FE5F00",
-").    c #FB4D00",
-"!.    c #FC5500",
-"~.    c #FE7E00",
-"{.    c #F8C805",
-"].    c #BDFB3F",
-"^.    c #51FFAC",
-"/.    c #0BDAF2",
-"(.    c #0082FF",
-"_.    c #0045FC",
-":.    c #0037EC",
-"<.    c #003DFE",
-"[.    c #0041FF",
-"}.    c #F86B00",
-"|.    c #E60000",
-"1.    c #B60000",
-"2.    c #B30000",
-"3.    c #BB0000",
-"4.    c #EE1200",
-"5.    c #FF9A00",
-"6.    c #AAFF53",
-"7.    c #0BEBF1",
-"8.    c #006DFF",
-"9.    c #0035F2",
-"0.    c #0037E9",
-"a.    c #006CFF",
-"b.    c #0ED7F0",
-"c.    c #F88F01",
-"d.    c #F94100",
-"e.    c #E92400",
-"f.    c #E21D00",
-"g.    c #EA2400",
-"h.    c #FA4200",
-"i.    c #FF9100",
-"j.    c #F2D10B",
-"k.    c #B7F746",
-"l.    c #80F87D",
-"m.    c #6EF18E",
-"n.    c #75F389",
-"o.    c #94FB69",
-"p.    c #D2EA2B",
-"      . . . + @ #               ",
-"      $ % & * = -               ",
-"; > , ' ) ! ~ { ] ^             ",
-"          / . ( _ : <           ",
-"          [ . } | 1 2           ",
-"      . . . . } 3 . . . .       ",
-"  4 5 6 . 7 8 8 8 9 0 . a b c   ",
-"  d e f g . 7 9 9 h . i j k l   ",
-"  m n o p q r s 7 t u v w x y   ",
-"  z A B C D E F . G H I J K L   ",
-"  M N O P Q R S T U V W X Y Z   ",
-"  `  ...+.@.#.$.%.&.*.=.-.;.>.  ",
-"  ,.'.).!.~.{.].^./.(._.:.<.[.  ",
-"  }.|.1.2.3.4.5.6.7.8.9.0.a.b.  ",
-"  c.d.e.f.g.h.i.j.k.l.m.n.o.p.  ",
-"                                "};
diff --git a/include/xpm/document-import.png b/include/xpm/document-import.png
deleted file mode 100644 (file)
index 0b4e816..0000000
Binary files a/include/xpm/document-import.png and /dev/null differ
diff --git a/include/xpm/document-import.xpm b/include/xpm/document-import.xpm
deleted file mode 100644 (file)
index 39c5113..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* XPM */
-static const char * document_import_xpm[] = {
-"16 16 170 2",
-"      c None",
-".     c #FB6801",
-"+     c #FF3F00",
-"@     c #FF6200",
-"#     c #EDDE11",
-"$     c #58FFA6",
-"%     c #07C2F8",
-"&     c #0070FF",
-"*     c #0064FF",
-"=     c #0195FF",
-"-     c #0AD3F4",
-";     c #2CFFD1",
-">     c #5CFEA1",
-",     c #7A7A7A",
-"'     c #797979",
-")     c #FAA302",
-"!     c #F1B50D",
-"~     c #BFE240",
-"{     c #61F29D",
-"]     c #10BFEE",
-"^     c #0066FF",
-"/     c #0043FF",
-"(     c #0170FF",
-"_     c #0EC8F0",
-":     c #59FCA5",
-"<     c #C6FB38",
-"[     c #F5CE09",
-"}     c #787878",
-"|     c #C9C9C9",
-"1     c #C7C7C7",
-"2     c #DFE11A",
-"3     c #56FAA8",
-"4     c #08A6F7",
-"5     c #004EE6",
-"6     c #0032C9",
-"7     c #0041FF",
-"8     c #0297FD",
-"9     c #27F0D6",
-"0     c #91FF6C",
-"a     c #E1FF1B",
-"b     c #EDEC10",
-"c     c #E5E019",
-"d     c #737373",
-"e     c #C5C5C5",
-"f     c #B0B0B0",
-"g     c #DDE31D",
-"h     c #0FB6F0",
-"i     c #047CF5",
-"j     c #0374F4",
-"k     c #049DFB",
-"l     c #0FE8EF",
-"m     c #43FFBB",
-"n     c #7EFF81",
-"o     c #8CFF72",
-"p     c #65FA99",
-"q     c #2CE1D3",
-"r     c #6E6E6E",
-"s     c #C1C1C0",
-"t     c #ACACAC",
-"u     c #F9A502",
-"v     c #F5A10A",
-"w     c #E0A31C",
-"x     c #CCB833",
-"y     c #B3DD4C",
-"z     c #83FC7B",
-"A     c #2DFFD0",
-"B     c #0DDEF1",
-"C     c #059FF9",
-"D     c #0279F8",
-"E     c #0062FD",
-"F     c #004DFF",
-"G     c #6A6A6A",
-"H     c #BDBDBD",
-"I     c #A9A9A9",
-"J     c #FA6201",
-"K     c #E00600",
-"L     c #C00000",
-"M     c #C40100",
-"N     c #ED1C00",
-"O     c #FAA205",
-"P     c #85FF79",
-"Q     c #08C2F6",
-"R     c #004CFC",
-"S     c #0030BE",
-"T     c #0051EC",
-"U     c #0AA6F5",
-"V     c #656565",
-"W     c #B7B7B7",
-"X     c #A6A6A6",
-"Y     c #FB7E01",
-"Z     c #F32E00",
-"`     c #DE1A00",
-" .    c #DE1900",
-"..    c #F42F00",
-"+.    c #FF8400",
-"@.    c #E6DE18",
-"#.    c #91F96D",
-"$.    c #60EA9E",
-"%.    c #5AE5A4",
-"&.    c #73F18B",
-"*.    c #B7F047",
-"=.    c #5F5F5F",
-"-.    c #B3B3B3",
-";.    c #406CA5",
-">.    c #3868A5",
-",.    c #3768A5",
-"'.    c #3666A5",
-").    c #3566A5",
-"!.    c #3566A4",
-"~.    c #3465A4",
-"{.    c #3767A6",
-"].    c #5B5B5B",
-"^.    c #AEAEAE",
-"/.    c #C0D5EA",
-"(.    c #C1D5EA",
-"_.    c #C1D6EA",
-":.    c #BBD2E8",
-"<.    c #3465A5",
-"[.    c #565656",
-"}.    c #C3D6EA",
-"|.    c #92B5DB",
-"1.    c #95B8DC",
-"2.    c #B9D0E7",
-"3.    c #3466A4",
-"4.    c #515151",
-"5.    c #A5A5A4",
-"6.    c #3666A4",
-"7.    c #C5D7EB",
-"8.    c #98B9DD",
-"9.    c #95B7DC",
-"0.    c #B8CEE7",
-"a.    c #4C4C4C",
-"b.    c #A1A1A1",
-"c.    c #3767A5",
-"d.    c #BFD2E9",
-"e.    c #9BBADD",
-"f.    c #9ABADD",
-"g.    c #96B7DC",
-"h.    c #8FB2DA",
-"i.    c #8BB0D8",
-"j.    c #B1C9E4",
-"k.    c #484848",
-"l.    c #9B9B9B",
-"m.    c #A5C1E1",
-"n.    c #8EB2D9",
-"o.    c #8AAFD8",
-"p.    c #85ACD7",
-"q.    c #83AAD6",
-"r.    c #81A9D5",
-"s.    c #7EA7D4",
-"t.    c #79A3D3",
-"u.    c #77A2D2",
-"v.    c #7BA5D3",
-"w.    c #95B6DB",
-"x.    c #3567A6",
-"y.    c #494949",
-"z.    c #999999",
-"A.    c #3968A5",
-"B.    c #94B5DB",
-"C.    c #82AAD5",
-"D.    c #7DA6D4",
-"E.    c #7FA8D4",
-"F.    c #85ABD5",
-"G.    c #7E8896",
-"H.    c #5588BF",
-"I.    c #5689C0",
-"J.    c #4B7EB7",
-"K.    c #3667A6",
-"L.    c #454A51",
-"M.    c #3565A4",
-"      . + @ # $ % & * = - ; >   ",
-", ' ' ) ! ~ { ] ^ / ( _ : < [   ",
-"} | 1 2 3 4 5 6 7 8 9 0 a b c   ",
-"d e f g 3 h i j k l m n o p q   ",
-"r s t u v w x y z A B C D E F   ",
-"G H I J K L M N O P Q R S T U   ",
-"V W X Y Z `  ...+.@.#.$.%.&.*.  ",
-"=.-.;.>.>.,.'.'.).!.!.!.~.~.~.{.",
-"].^.)././././././.(._._._._.:.<.",
-"[.I !.}.|.|.|.|.|.|.|.|.|.1.2.3.",
-"4.5.6.7.8.8.8.8.8.8.8.8.8.9.0.).",
-"a.b.c.d.e.f.f.f.f.f.f.g.h.i.j.).",
-"k.l.>.m.n.o.p.q.r.s.t.u.u.v.w.x.",
-"y.z.A.B.C.D.D.D.D.D.D.D.D.E.F.'.",
-"k.G.A.H.I.I.I.I.I.I.I.I.I.I.J.K.",
-"L.~.~.~.~.~.~.~.~.~.~.~.~.~.M.  "};
diff --git a/include/xpm/document-new.png b/include/xpm/document-new.png
deleted file mode 100644 (file)
index 4c3efdd..0000000
Binary files a/include/xpm/document-new.png and /dev/null differ
diff --git a/include/xpm/document-new.xpm b/include/xpm/document-new.xpm
deleted file mode 100644 (file)
index 6336507..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* XPM */
-static const char * document_new_xpm[] = {
-"16 16 59 1",
-"      c None",
-".     c #9E9E9E",
-"+     c #818181",
-"@     c #8C8C7C",
-"#     c #9F9F72",
-"$     c #AFAE6A",
-"%     c #EDE436",
-"&     c #FFFFFF",
-"*     c #F2EE9B",
-"=     c #F7F069",
-"-     c #FAF24D",
-";     c #F7EF46",
-">     c #F4EB28",
-",     c #ECECEC",
-"'     c #EAEAEA",
-")     c #EBEBEB",
-"!     c #F0EDB4",
-"~     c #F7F06A",
-"{     c #FCF43A",
-"]     c #FDF668",
-"^     c #FDF66A",
-"/     c #FBF23C",
-"(     c #F9EF1E",
-"_     c #F2EE9C",
-":     c #FAF24E",
-"<     c #FDF667",
-"[     c #FEFAB5",
-"}     c #FEFAB8",
-"|     c #FDF56B",
-"1     c #FAEF22",
-"2     c #F3EF9B",
-"3     c #FEFABB",
-"4     c #FEFBBF",
-"5     c #FDF66E",
-"6     c #FAF022",
-"7     c #EDEDED",
-"8     c #F1EEB1",
-"9     c #F8F167",
-"0     c #FDF440",
-"a     c #FDF771",
-"b     c #FDF772",
-"c     c #FCF343",
-"d     c #F6EC24",
-"e     c #EFEEE0",
-"f     c #F4EF96",
-"g     c #F8F163",
-"h     c #FBF346",
-"i     c #FBF345",
-"j     c #F7EF5D",
-"k     c #EEEEEE",
-"l     c #EEEEE2",
-"m     c #F3F0B1",
-"n     c #F5F092",
-"o     c #F5F09A",
-"p     c #969677",
-"q     c #EFEFEF",
-"r     c #F0F0F0",
-"s     c #F1F1F1",
-"t     c #F2F2F2",
-".++++++++@#$%   ",
-"+&&&&&&&&*=-;>  ",
-"+&,'')))!~{]^/( ",
-"+&'')),,_:<[}|1 ",
-"+&')),,,2:^3456 ",
-"+&)),,,7890abcd ",
-"+&)),,77efghij  ",
-"+&),,77kklmnop  ",
-"+&,,77kkqqqr&+  ",
-"+&,,77kkqqrr&+  ",
-"+&,7kkqqrsss&+  ",
-"+&77kkqrrsst&+  ",
-"+&77kqqrrstt&+  ",
-"+&&&&&&&&&&&&+  ",
-".++++++++++++.  ",
-"                "};
diff --git a/include/xpm/document-open.png b/include/xpm/document-open.png
deleted file mode 100644 (file)
index ab94046..0000000
Binary files a/include/xpm/document-open.png and /dev/null differ
diff --git a/include/xpm/document-open.xpm b/include/xpm/document-open.xpm
deleted file mode 100644 (file)
index 10b148b..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/* XPM */
-static const char * document_open_xpm[] = {
-"16 16 137 2",
-"      c None",
-".     c #565854",
-"+     c #575955",
-"@     c #595B57",
-"#     c #5A5C58",
-"$     c #5F615D",
-"%     c #7A7A7A",
-"&     c #797979",
-"*     c #F7F7F7",
-"=     c #F9F9F9",
-"-     c #FAFAFA",
-";     c #FBFBFB",
-">     c #FCFCFC",
-",     c #A2A3A2",
-"'     c #5B5C58",
-")     c #787878",
-"!     c #C9C9C9",
-"~     c #C7C7C7",
-"{     c #C4C4C4",
-"]     c #555753",
-"^     c #DADADA",
-"/     c #D3D3D3",
-"(     c #D2D2D2",
-"_     c #CFCFCF",
-":     c #CDCDCD",
-"<     c #FEFEFE",
-"[     c #939392",
-"}     c #5B5E5A",
-"|     c #737373",
-"1     c #C5C5C5",
-"2     c #B0B0B0",
-"3     c #ACACAC",
-"4     c #DCDCDC",
-"5     c #9C9D9C",
-"6     c #D5D5D4",
-"7     c #FDFDFD",
-"8     c #969796",
-"9     c #5B5D59",
-"0     c #6E6E6E",
-"a     c #C1C1C0",
-"b     c #AAAAAA",
-"c     c #E2E2E2",
-"d     c #DFDFDF",
-"e     c #DEDEDE",
-"f     c #DDDDDD",
-"g     c #E0E0E0",
-"h     c #E9E9E9",
-"i     c #E5E5E5",
-"j     c #D0D0D0",
-"k     c #5D5F5B",
-"l     c #6A6A6A",
-"m     c #BDBDBD",
-"n     c #A9A9A9",
-"o     c #A5A5A5",
-"p     c #E6E6E6",
-"q     c #9FA09E",
-"r     c #9C9D9B",
-"s     c #E3E3E3",
-"t     c #D0D1D0",
-"u     c #656565",
-"v     c #B7B7B7",
-"w     c #A6A6A6",
-"x     c #A1A1A1",
-"y     c #EBEBEB",
-"z     c #EAEAEA",
-"A     c #E8E8E8",
-"B     c #E7E7E7",
-"C     c #D9D9D9",
-"D     c #5B5C59",
-"E     c #5F5F5F",
-"F     c #B3B3B3",
-"G     c #406CA5",
-"H     c #3868A5",
-"I     c #3768A5",
-"J     c #3666A5",
-"K     c #3566A5",
-"L     c #3566A4",
-"M     c #3465A4",
-"N     c #3767A6",
-"O     c #5B5B5B",
-"P     c #AEAEAE",
-"Q     c #C0D5EA",
-"R     c #C1D5EA",
-"S     c #C1D6EA",
-"T     c #BBD2E8",
-"U     c #3465A5",
-"V     c #565656",
-"W     c #C3D6EA",
-"X     c #92B5DB",
-"Y     c #95B8DC",
-"Z     c #B9D0E7",
-"`     c #3466A4",
-" .    c #515151",
-"..    c #A5A5A4",
-"+.    c #3666A4",
-"@.    c #C5D7EB",
-"#.    c #98B9DD",
-"$.    c #95B7DC",
-"%.    c #B8CEE7",
-"&.    c #4C4C4C",
-"*.    c #3767A5",
-"=.    c #BFD2E9",
-"-.    c #9BBADD",
-";.    c #9ABADD",
-">.    c #96B7DC",
-",.    c #8FB2DA",
-"'.    c #8BB0D8",
-").    c #B1C9E4",
-"!.    c #484848",
-"~.    c #9B9B9B",
-"{.    c #A5C1E1",
-"].    c #8EB2D9",
-"^.    c #8AAFD8",
-"/.    c #85ACD7",
-"(.    c #83AAD6",
-"_.    c #81A9D5",
-":.    c #7EA7D4",
-"<.    c #79A3D3",
-"[.    c #77A2D2",
-"}.    c #7BA5D3",
-"|.    c #95B6DB",
-"1.    c #3567A6",
-"2.    c #494949",
-"3.    c #999999",
-"4.    c #3968A5",
-"5.    c #94B5DB",
-"6.    c #82AAD5",
-"7.    c #7DA6D4",
-"8.    c #7FA8D4",
-"9.    c #85ABD5",
-"0.    c #7E8896",
-"a.    c #5588BF",
-"b.    c #5689C0",
-"c.    c #4B7EB7",
-"d.    c #3667A6",
-"e.    c #454A51",
-"f.    c #3565A4",
-"        . + . + + @ # $         ",
-"% & & & . * = - ; ; > , '       ",
-") ! ~ { ] ^ / / ( _ : < [ }     ",
-"| 1 2 3 ] 4 5 5 5 5 6 < 7 8 9   ",
-"0 a 3 b . c d e e f g h i j k   ",
-"l m n o . p q r r r f s s t 9   ",
-"u v w x + y z z h h A A B C D   ",
-"E F G H H I J J K L L L M M M N ",
-"O P K Q Q Q Q Q Q R S S S S T U ",
-"V n L W X X X X X X X X X Y Z ` ",
-" ...+.@.#.#.#.#.#.#.#.#.#.$.%.K ",
-"&.x *.=.-.;.;.;.;.;.;.>.,.'.).K ",
-"!.~.H {.].^./.(._.:.<.[.[.}.|.1.",
-"2.3.4.5.6.7.7.7.7.7.7.7.7.8.9.J ",
-"!.0.4.a.b.b.b.b.b.b.b.b.b.b.c.d.",
-"e.M M M M M M M M M M M M M f.  "};
diff --git a/include/xpm/document-print.png b/include/xpm/document-print.png
deleted file mode 100644 (file)
index 35c37bd..0000000
Binary files a/include/xpm/document-print.png and /dev/null differ
diff --git a/include/xpm/document-print.xpm b/include/xpm/document-print.xpm
deleted file mode 100644 (file)
index 21170e9..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* XPM */
-static const char * document_print_xpm[] = {
-"16 16 67 1",
-"      c None",
-".     c #AAABA9",
-"+     c #F9F9F9",
-"@     c #888A85",
-"#     c #F8F8F8",
-"$     c #C4C4C4",
-"%     c #F1F1F1",
-"&     c #F3F3F3",
-"*     c #F7F7F7",
-"=     c #C6C6C6",
-"-     c #C7C7C7",
-";     c #E0E0E0",
-">     c #E2E2E2",
-",     c #E3E3E3",
-"'     c #E5E5E5",
-")     c #E6E6E6",
-"!     c #E7E7E7",
-"~     c #F6F6F6",
-"{     c #F5F5F5",
-"]     c #F5F5F6",
-"^     c #7D7E7C",
-"/     c #858684",
-"(     c #ABABAB",
-"_     c #A9A9A9",
-":     c #AAAAAA",
-"<     c #FCFCFC",
-"[     c #F4F4F4",
-"}     c #E8E8E8",
-"|     c #FDFDFD",
-"1     c #D4D4D4",
-"2     c #EDEDED",
-"3     c #AEAEAE",
-"4     c #DFDFDF",
-"5     c #E1E1E1",
-"6     c #DCDCDC",
-"7     c #9F9F9F",
-"8     c #CDCCCB",
-"9     c #F0F0F0",
-"0     c #CCCBCB",
-"a     c #DDDDDD",
-"b     c #DEDEDE",
-"c     c #D9D9D9",
-"d     c #8C8B8A",
-"e     c #C5C5C5",
-"f     c #F2F2F2",
-"g     c #BEBEBE",
-"h     c #868584",
-"i     c #7A7978",
-"j     c #767574",
-"k     c #787675",
-"l     c #767472",
-"m     c #72716F",
-"n     c #747372",
-"o     c #B2B2B2",
-"p     c #BBBBBB",
-"q     c #B9B9B9",
-"r     c #B8B8B8",
-"s     c #B8B8B7",
-"t     c #B6B6B6",
-"u     c #B3B3B3",
-"v     c #B5B5B5",
-"w     c #B7B7B7",
-"x     c #ECECEC",
-"y     c #D7D7D7",
-"z     c #D8D8D8",
-"A     c #D5D5D5",
-"B     c #D6D6D6",
-"                ",
-"   ...........  ",
-"   .++++@+++#.  ",
-"   .+$$@@@$$#.  ",
-"   .+%@@@@@&*.  ",
-"   .*$$=@=--#.  ",
-"   .*;>,@')!*.  ",
-"   .~{{{{]]~*.  ",
-" ^^/(_(((((_:/^^",
-" ^<+[[[[[[[[[)}^",
-" ^|123&4,5>;678^",
-" ^90aabbb6aacde^",
-" ^fghiijklmnkoe^",
-" ^fpqqrrstuvwr-^",
-" ^xyzzyyyyyAyB1^",
-" ^^^^^^^^^^^^^^^"};
diff --git a/include/xpm/document-properties.png b/include/xpm/document-properties.png
deleted file mode 100644 (file)
index ab0e8ea..0000000
Binary files a/include/xpm/document-properties.png and /dev/null differ
diff --git a/include/xpm/document-properties.xpm b/include/xpm/document-properties.xpm
deleted file mode 100644 (file)
index e12cda1..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* XPM */
-static const char * document_properties_xpm[] = {
-"16 16 41 1",
-"      c None",
-".     c #999999",
-"+     c #818181",
-"@     c #FFFFFF",
-"#     c #ECECEC",
-"$     c #EAEAEA",
-"%     c #EBEBEB",
-"&     c #EDEDED",
-"*     c #F0F0F0",
-"=     c #C4C4C4",
-"-     c #C5C5C5",
-";     c #C6C6C6",
-">     c #C7C7C7",
-",     c #696969",
-"'     c #D2D2D2",
-")     c #EEEEEE",
-"!     c #B0B0B0",
-"~     c #585858",
-"{     c #696966",
-"]     c #6A6A6A",
-"^     c #D2D2CC",
-"/     c #D6D6D6",
-"(     c #595959",
-"_     c #626262",
-":     c #6C6C6C",
-"<     c #DCDCDC",
-"[     c #EFEFEF",
-"}     c #D4D4D4",
-"|     c #777777",
-"1     c #858585",
-"2     c #909090",
-"3     c #9D9D9D",
-"4     c #C8C8C8",
-"5     c #B5B5B5",
-"6     c #929292",
-"7     c #9E9E9E",
-"8     c #ABABAB",
-"9     c #E0E0E0",
-"0     c #ADADAD",
-"a     c #BABABA",
-"b     c #959595",
-" .++++++++++++  ",
-" +@@@@@@@@@@@@+ ",
-" +@#$$%%%##&*@+ ",
-" +@$=--;;;;>*@+ ",
-" +@$%%,,,'&)*@+ ",
-" +@%-;!~~~;>*@+ ",
-" +@%,'#',{#)*@+ ",
-" +@%~~!~]]^)*@+ ",
-" +@#,,,]]]]/*@+ ",
-" +@#!~~~~(_:<@+ ",
-" +@#&))[}|123@+ ",
-" +@&;>>445678@+ ",
-" +@&&)[[**90a@+ ",
-" +@@@@@@@@@@@@+ ",
-" b++++++++++++b ",
-"                "};
diff --git a/include/xpm/document-save.png b/include/xpm/document-save.png
deleted file mode 100644 (file)
index 22ff495..0000000
Binary files a/include/xpm/document-save.png and /dev/null differ
diff --git a/include/xpm/document-save.xpm b/include/xpm/document-save.xpm
deleted file mode 100644 (file)
index e651d91..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* XPM */
-static const char * document_save_xpm[] = {
-"16 16 107 2",
-"      c None",
-".     c #38678B",
-"+     c #3D698A",
-"@     c #4A7180",
-"#     c #58787A",
-"$     c #B1CEE6",
-"%     c #D0DFEF",
-"&     c #C5DBEC",
-"*     c #9BC2DF",
-"=     c #688BA0",
-"-     c #436E88",
-";     c #6B7F88",
-">     c #667173",
-",     c #627075",
-"'     c #4A6D85",
-")     c #41749A",
-"!     c #44789F",
-"~     c #9EBFD9",
-"{     c #C1D9EB",
-"]     c #5186AF",
-"^     c #4E6A7D",
-"/     c #6E706B",
-"(     c #6B716E",
-"_     c #E2E6DD",
-":     c #FFFFFF",
-"<     c #DDE1D6",
-"[     c #C9D6DD",
-"}     c #6E99B6",
-"|     c #ABCBE2",
-"1     c #92B7D3",
-"2     c #547D9B",
-"3     c #D5DFE5",
-"4     c #F4F4F4",
-"5     c #72756B",
-"6     c #FDFDFD",
-"7     c #EEEEEE",
-"8     c #EDEDED",
-"9     c #DFE2DE",
-"0     c #7798B0",
-"a     c #79A7CA",
-"b     c #8FB3CE",
-"c     c #3D6B8E",
-"d     c #ACBCC3",
-"e     c #EDEDEE",
-"f     c #EDEEEE",
-"g     c #EDEEED",
-"h     c #F3F4F3",
-"i     c #FCFBFC",
-"j     c #EBECEC",
-"k     c #5892BD",
-"l     c #ECECEC",
-"m     c #F3F3F3",
-"n     c #FAFAFA",
-"o     c #E9E9EA",
-"p     c #CACFC4",
-"q     c #98BFDC",
-"r     c #719FBF",
-"s     c #739FC0",
-"t     c #96BBD8",
-"u     c #95A9AF",
-"v     c #EAE9EA",
-"w     c #F2F2F2",
-"x     c #F9F9F9",
-"y     c #E4E4E4",
-"z     c #C5CBBF",
-"A     c #ABC8DF",
-"B     c #92A6AC",
-"C     c #F1F1F1",
-"D     c #ACCBE3",
-"E     c #3B6B8F",
-"F     c #F7F7F7",
-"G     c #E3E3E3",
-"H     c #CED4C8",
-"I     c #3F6C8E",
-"J     c #9AAEB4",
-"K     c #FCFCFC",
-"L     c #F0F0F0",
-"M     c #FEFEFE",
-"N     c #EBEBEB",
-"O     c #CECECE",
-"P     c #C9C9C9",
-"Q     c #C5C5C5",
-"R     c #D6D6D6",
-"S     c #9F9F9F",
-"T     c #AFAFAF",
-"U     c #BCBCBC",
-"V     c #C4C4C4",
-"W     c #C8C8C8",
-"X     c #D0D0D0",
-"Y     c #A9A9A9",
-"Z     c #D2D2D2",
-"`     c #B9B9B9",
-" .    c #CACACA",
-"..    c #CDCDCD",
-"+.    c #C3C3C3",
-"@.    c #AAAAA9",
-"#.    c #B4B4B4",
-"$.    c #C2C2C2",
-"%.    c #CBCBCB",
-"&.    c #A8A7A8",
-"*.    c #D1D1D1",
-"=.    c #A8A7A7",
-"-.    c #B7B6B6",
-";.    c #DDDDDD",
-">.    c #DCDCDC",
-",.    c #D5D5D5",
-"'.    c #CFCFCF",
-"      . . . + @ #               ",
-"      $ % & * = -               ",
-"; > , ' ) ! ~ { ] ^ / / / / / / ",
-"( _ : < [ } . | 1 2 3 : : : 4 / ",
-"5 6 7 8 9 0 . a b c d e f g h / ",
-"/ i j . . . . a k . . . . l m / ",
-"/ n o p . q r r r s t . u v w / ",
-"/ x n y z . q s s A . B y 4 C / ",
-"/ x 7 n y z . D q E B y n 7 C / ",
-"/ F G 7 n n H I . J n K 7 G L / ",
-"/ M : : : : : : : 4 4 N N G L / ",
-"/ O P P P P Q P P Q Q Q Q Q R / ",
-"/ O Q S T U V W X Y Z Y Z `  ./ ",
-"/ ..+.@.#.$.V W %.&.*.=.*.-. ./ ",
-"/ ;.>.>.>.,.,.'.'.'.'.'.'.'. ./ ",
-"/ / / / / / / / / / / / / / / / "};
diff --git a/include/xpm/edit-copy.png b/include/xpm/edit-copy.png
deleted file mode 100644 (file)
index 8dd48c4..0000000
Binary files a/include/xpm/edit-copy.png and /dev/null differ
diff --git a/include/xpm/edit-copy.xpm b/include/xpm/edit-copy.xpm
deleted file mode 100644 (file)
index 6c9d2b2..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* XPM */
-static const char * edit_copy_xpm[] = {
-"16 16 41 1",
-"      c None",
-".     c #888A85",
-"+     c #FFFFFF",
-"@     c #F0F0EF",
-"#     c #EFEFEE",
-"$     c #C8C8C7",
-"%     c #9A9B97",
-"&     c #8D8F8A",
-"*     c #8A8C87",
-"=     c #898B86",
-"-     c #C7C7C6",
-";     c #C6C6C5",
-">     c #EEEEED",
-",     c #EDEDEC",
-"'     c #FEFEFE",
-")     c #ECECEC",
-"!     c #C4C4C3",
-"~     c #FAFAFA",
-"{     c #F3F3F3",
-"]     c #F9F9F9",
-"^     c #EBEBEB",
-"/     c #EAEAEA",
-"(     c #EEEEEE",
-"_     c #F7F7F6",
-":     c #C3C4C3",
-"<     c #F3F3F2",
-"[     c #F4F4F3",
-"}     c #F2F2F2",
-"|     c #8C8E89",
-"1     c #FEFEFD",
-"2     c #989A95",
-"3     c #F8F8F7",
-"4     c #E3E4E2",
-"5     c #FAFAF9",
-"6     c #E3E3E2",
-"7     c #F4F4F4",
-"8     c #F6F6F5",
-"9     c #FCFCFB",
-"0     c #FBFBFB",
-"a     c #D4D4D4",
-"b     c #989A96",
-" ..........     ",
-" ++++++++++.    ",
-" +@#####@@+.    ",
-" +@$%..........&",
-" +@@*++++++++++.",
-" +@$=+@@@@@@@@+.",
-" +@#*+@------@+.",
-" +#;=+@@@@@@@@+.",
-" +>,*+@-----@@+.",
-" ')!=+@@@@@@@~{.",
-" ]^/*+@-----(_:.",
-" <[}*+@@@@@||||.",
-" ====1@@@@~2~34.",
-"    =5@@@~~2~6..",
-"    =7_890ab4.. ",
-"    |=........  "};
diff --git a/include/xpm/edit-cut.png b/include/xpm/edit-cut.png
deleted file mode 100644 (file)
index dc9eb9a..0000000
Binary files a/include/xpm/edit-cut.png and /dev/null differ
diff --git a/include/xpm/edit-cut.xpm b/include/xpm/edit-cut.xpm
deleted file mode 100644 (file)
index 367226c..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* XPM */
-static const char * edit_cut_xpm[] = {
-"16 16 88 1",
-"      c None",
-".     c #8B8D88",
-"+     c #939590",
-"@     c #8F918C",
-"#     c #8E908B",
-"$     c #F7F7F7",
-"%     c #90918D",
-"&     c #D2D3D0",
-"*     c #D2D4D0",
-"=     c #EFF0EF",
-"-     c #92948F",
-";     c #AAACA7",
-">     c #C6C8C3",
-",     c #8D8F8A",
-"'     c #B3B5B0",
-")     c #F7F7F6",
-"!     c #CCCEC9",
-"~     c #AEAFAB",
-"{     c #DBDCD9",
-"]     c #91938E",
-"^     c #8C8E89",
-"/     c #B6B8B3",
-"(     c #CDCECB",
-"_     c #B5B6B2",
-":     c #9FA09C",
-"<     c #B5B6B3",
-"[     c #B8BAB5",
-"}     c #E1E1DF",
-"|     c #F5F6F5",
-"1     c #9A9C97",
-"2     c #A8A9A5",
-"3     c #BABBB7",
-"4     c #E7E8E6",
-"5     c #8A8C87",
-"6     c #898984",
-"7     c #C5C6C3",
-"8     c #B3B2AF",
-"9     c #9C2F2C",
-"0     c #AE1818",
-"a     c #AB1616",
-"b     c #A60606",
-"c     c #A34A45",
-"d     c #A60202",
-"e     c #C71A19",
-"f     c #AD1717",
-"g     c #A90707",
-"h     c #D22020",
-"i     c #CE1E1E",
-"j     c #B70F0E",
-"k     c #A40502",
-"l     c #A80403",
-"m     c #C91A1A",
-"n     c #D12020",
-"o     c #CB1F1F",
-"p     c #A90A0A",
-"q     c #A80606",
-"r     c #D01F1F",
-"s     c #A80303",
-"t     c #C01514",
-"u     c #A60101",
-"v     c #CD1D1C",
-"w     c #C01513",
-"x     c #CD1D1D",
-"y     c #A70606",
-"z     c #AB1414",
-"A     c #D52323",
-"B     c #CE1D1D",
-"C     c #CA1B1A",
-"D     c #AB0D0D",
-"E     c #CF1D1D",
-"F     c #B50B0B",
-"G     c #D32121",
-"H     c #AA0C0C",
-"I     c #AA0909",
-"J     c #D62323",
-"K     c #B80D0D",
-"L     c #D11F1F",
-"M     c #AB1111",
-"N     c #AB1313",
-"O     c #DB2727",
-"P     c #A80707",
-"Q     c #AA0808",
-"R     c #D42222",
-"S     c #AA0E0E",
-"T     c #AB1010",
-"U     c #AA0D0D",
-"V     c #AA0B0B",
-"W     c #A90B0B",
-"    .+    .@    ",
-"   #$.    %&@   ",
-"   .*=-   ;>,   ",
-"   ,').  #!~.   ",
-"    .{=]^/(.    ",
-"    ,_$.:<[.    ",
-"     .}|12.     ",
-"     ,34;#5     ",
-"      6789      ",
-"    0abcdef0    ",
-"   ghijklmnop   ",
-"  qrstu  vwsxy  ",
-" zA  Bp  sC  nz ",
-" DE FGH  IJK LM ",
-" NOrBP    QREBN ",
-"  STa      UVW  "};
diff --git a/include/xpm/edit-delete.png b/include/xpm/edit-delete.png
deleted file mode 100644 (file)
index 184f762..0000000
Binary files a/include/xpm/edit-delete.png and /dev/null differ
diff --git a/include/xpm/edit-delete.xpm b/include/xpm/edit-delete.xpm
deleted file mode 100644 (file)
index 1b2b8d4..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/* XPM */
-static const char * edit_delete_xpm[] = {
-"16 16 136 2",
-"      c None",
-".     c #2E3436",
-"+     c #64696A",
-"@     c #909894",
-"#     c #E9EAE3",
-"$     c #EEEFEC",
-"%     c #EFF0EE",
-"&     c #D2D5D3",
-"*     c #BFC1C1",
-"=     c #979A9B",
-"-     c #424749",
-";     c #D9DBD6",
-">     c #C7CAC4",
-",     c #6E7672",
-"'     c #424745",
-")     c #242727",
-"!     c #313432",
-"~     c #7A837E",
-"{     c #B3B8B3",
-"]     c #CBCECB",
-"^     c #CBCFCB",
-"/     c #D6D9D3",
-"(     c #D2D5CD",
-"_     c #DADCD6",
-":     c #AEB3AD",
-"<     c #5C6362",
-"[     c #353939",
-"}     c #373A38",
-"|     c #585E5B",
-"1     c #8D948F",
-"2     c #AAAFA7",
-"3     c #D2D6D2",
-"4     c #B5BAB5",
-"5     c #E5E5E1",
-"6     c #F0F0ED",
-"7     c #ECEDE9",
-"8     c #E3E5E0",
-"9     c #DDDED9",
-"0     c #CBCEC7",
-"a     c #B6BBB3",
-"b     c #A2A8A0",
-"c     c #B3B8B0",
-"d     c #BABFB7",
-"e     c #ABB0A8",
-"f     c #CBCECD",
-"g     c #E0E2E2",
-"h     c #E6E6DD",
-"i     c #F4F4EF",
-"j     c #F4F3F1",
-"k     c #F4F4F1",
-"l     c #F3F4F0",
-"m     c #F0F0EB",
-"n     c #E5E6E0",
-"o     c #D6D9D2",
-"p     c #919894",
-"q     c #8B8F8D",
-"r     c #898D8D",
-"s     c #9A9C9C",
-"t     c #C2C5C4",
-"u     c #BCC0BF",
-"v     c #D9DBD2",
-"w     c #DFE0D8",
-"x     c #D9DBD4",
-"y     c #CCD0CF",
-"z     c #848C89",
-"A     c #969C99",
-"B     c #86898A",
-"C     c #53585A",
-"D     c #5A5F60",
-"E     c #8B8F8F",
-"F     c #ADAFB0",
-"G     c #E4E5E5",
-"H     c #E3E5E5",
-"I     c #E3E5E4",
-"J     c #A1A4A4",
-"K     c #686D6E",
-"L     c #3C4041",
-"M     c #4C5052",
-"N     c #6B7171",
-"O     c #323838",
-"P     c #2E3434",
-"Q     c #2B3132",
-"R     c #2B3133",
-"S     c #292E30",
-"T     c #282D2F",
-"U     c #272C2E",
-"V     c #393D3C",
-"W     c #939594",
-"X     c #AFB5B3",
-"Y     c #B0B6B4",
-"Z     c #69706E",
-"`     c #979F9B",
-" .    c #6A716D",
-"..    c #393E3B",
-"+.    c #5F6764",
-"@.    c #333734",
-"#.    c #616866",
-"$.    c #989B99",
-"%.    c #B7BBBB",
-"&.    c #D5D8D6",
-"*.    c #818A88",
-"=.    c #D1D4D2",
-"-.    c #7E8785",
-";.    c #515756",
-">.    c #899290",
-",.    c #434844",
-"'.    c #6E7774",
-").    c #A0A3A1",
-"!.    c #D6D9D7",
-"~.    c #858D8A",
-"{.    c #D8DBD8",
-"].    c #A2A8A3",
-"^.    c #555B59",
-"/.    c #979E9C",
-"(.    c #454B47",
-"_.    c #6F7875",
-":.    c #D4D7D5",
-"<.    c #838C89",
-"[.    c #D8DBD7",
-"}.    c #9B9D9B",
-"|.    c #AFB1B0",
-"1.    c #CCCFCF",
-"2.    c #B9BBBB",
-"3.    c #DDDFDC",
-"4.    c #A0A7A4",
-"5.    c #878B88",
-"6.    c #929595",
-"7.    c #727373",
-"8.    c #575C5E",
-"9.    c #9B9C9B",
-"0.    c #D5D8D7",
-"a.    c #CFD2D0",
-"b.    c #BFC0BF",
-"c.    c #BEC1BF",
-"d.    c #878787",
-"e.    c #54595A",
-"          . . . . . .           ",
-"      . + @ # $ % & * = .       ",
-"    - ; > , ' ) ! ~ { ] ^ .     ",
-"  . / ( _ : < [ } | 1 2 3 4 .   ",
-"  . 5 6 7 8 9 0 a b c d e f .   ",
-"  . g h i j k l m n o p q r .   ",
-"  . s t u v w x y z A B C . .   ",
-"    . D E F G H I J K L M .     ",
-"    . N O P Q R S T U V W .     ",
-"    . X Y Z `  ...+.@.#.$..     ",
-"    . %.&.*.=.-.;.>.,.'.)..     ",
-"    . %.!.~.{.].^./.(._.)..     ",
-"    . %.:.<.[.].^./.(.'.}..     ",
-"    . |.1.2.3.].^.4.5.6.7..     ",
-"      . 8.9.0.a.b.c.d.e..       ",
-"          . . . . . .           "};
diff --git a/include/xpm/edit-find.png b/include/xpm/edit-find.png
deleted file mode 100644 (file)
index d072d3c..0000000
Binary files a/include/xpm/edit-find.png and /dev/null differ
diff --git a/include/xpm/edit-find.xpm b/include/xpm/edit-find.xpm
deleted file mode 100644 (file)
index 8a8fb2e..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* XPM */
-static const char * edit_find_xpm[] = {
-"16 16 77 1",
-"      c None",
-".     c #9A9B97",
-"+     c #888A85",
-"@     c #8D8F8A",
-"#     c #8A8C87",
-"$     c #FFFFFF",
-"%     c #898B86",
-"&     c #F0F0EF",
-"*     c #C7C7C6",
-"=     c #D6D6D5",
-"-     c #818380",
-";     c #828480",
-">     c #A8A9A6",
-",     c #AEBAC8",
-"'     c #A6BCD2",
-")     c #A2BAD4",
-"!     c #A8B9CD",
-"~     c #D6D7D5",
-"{     c #A8B7C8",
-"]     c #8AACD2",
-"^     c #BFD3E7",
-"/     c #C5D7EA",
-"(     c #9CBAD9",
-"_     c #90ADCB",
-":     c #A3AEBB",
-"<     c #85A9CF",
-"[     c #DCE6F2",
-"}     c #E8EEF7",
-"|     c #E4ECF5",
-"1     c #CADAEC",
-"2     c #8EB2D8",
-"3     c #97AFCB",
-"4     c #A2B8D0",
-"5     c #A5C0DF",
-"6     c #D9E4F1",
-"7     c #E0EAF3",
-"8     c #DDE7F2",
-"9     c #C1D4E9",
-"0     c #A0BEDF",
-"a     c #81A6D0",
-"b     c #FEFEFD",
-"c     c #A9BFD6",
-"d     c #A5C1E0",
-"e     c #D0DEEE",
-"f     c #DAE5F2",
-"g     c #CDDCED",
-"h     c #C8D9EC",
-"i     c #BCD0E8",
-"j     c #80A7D1",
-"k     c #FAFAF9",
-"l     c #A7B5C3",
-"m     c #89ABD0",
-"n     c #B3CAE5",
-"o     c #C3D7EB",
-"p     c #C1D4EA",
-"q     c #CFDDEE",
-"r     c #A3BDDA",
-"s     c #93AFCE",
-"t     c #CFCFCD",
-"u     c #9FB8D1",
-"v     c #91B3D6",
-"w     c #AFC5DF",
-"x     c #B2CAE3",
-"y     c #A0BAD6",
-"z     c #97B4D3",
-"A     c #757673",
-"B     c #8C8E89",
-"C     c #7E807B",
-"D     c #B3C8DC",
-"E     c #8BACCF",
-"F     c #80A8D1",
-"G     c #99B3D0",
-"H     c #A3A4A3",
-"I     c #6C6E6A",
-"J     c #8D8E8C",
-"K     c #B8B8B7",
-"L     c #848482",
-".++++++++++@    ",
-"#$$$$$$$$$$+    ",
-"%$&&&&&&&&$+    ",
-"#$&******&$+    ",
-"%$&&&&=----;    ",
-"#$&**>-,')!-    ",
-"%$&&~-{]^/(_-   ",
-"#$&*-:<[}|123-  ",
-"#$&&-4567890a-  ",
-"%b&&-cdefghij-  ",
-"%k&&-lmnopqrs-  ",
-"%$$$t-uvwxyz-A  ",
-"B%+++C-DEFG-HHI ",
-"      I----JKHHL",
-"            JKHL",
-"             JJL"};
diff --git a/include/xpm/edit-paste.png b/include/xpm/edit-paste.png
deleted file mode 100644 (file)
index 24588a3..0000000
Binary files a/include/xpm/edit-paste.png and /dev/null differ
diff --git a/include/xpm/edit-paste.xpm b/include/xpm/edit-paste.xpm
deleted file mode 100644 (file)
index 333091c..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* XPM */
-static const char * edit_paste_xpm[] = {
-"16 16 77 1",
-"      c None",
-".     c #5F5F5E",
-"+     c #5C5C5C",
-"@     c #6D4401",
-"#     c #6C4401",
-"$     c #6B4403",
-"%     c #5C5C5B",
-"&     c #959589",
-"*     c #97978A",
-"=     c #C08424",
-"-     c #A47E3E",
-";     c #706D64",
-">     c #5E5E5E",
-",     c #7F7F7C",
-"'     c #80807D",
-")     c #7E7E7B",
-"!     c #6E6C64",
-"~     c #A17C40",
-"{     c #B97F23",
-"]     c #6C4301",
-"^     c #6F4602",
-"/     c #C68827",
-"(     c #716F64",
-"_     c #F1F1F1",
-":     c #E0E0E0",
-"<     c #BBBBBB",
-"[     c #F2F2F2",
-"}     c #6E6D64",
-"|     c #C58727",
-"1     c #6A4200",
-"2     c #666864",
-"3     c #FFFFFF",
-"4     c #F0F0EF",
-"5     c #676964",
-"6     c #C28628",
-"7     c #C58726",
-"8     c #B3B5B5",
-"9     c #EFEFEE",
-"0     c #EFEFED",
-"a     c #EDEDEB",
-"b     c #6E4602",
-"c     c #B2B4B4",
-"d     c #B1B2B2",
-"e     c #EAEAE8",
-"f     c #EDEDEC",
-"g     c #EBEBEA",
-"h     c #DBDBD9",
-"i     c #EEEEED",
-"j     c #ECECEB",
-"k     c #EBEBE9",
-"l     c #E9E9E7",
-"m     c #DADAD8",
-"n     c #CCCDCA",
-"o     c #ECECEA",
-"p     c #E8E8E6",
-"q     c #CDCECB",
-"r     c #B9BAB6",
-"s     c #B8B9B5",
-"t     c #6E4502",
-"u     c #E7E7E5",
-"v     c #D9D9D6",
-"w     c #B9B9B6",
-"x     c #E7E7E4",
-"y     c #D8D8D5",
-"z     c #C1C2BE",
-"A     c #B7B7B4",
-"B     c #706D63",
-"C     c #EDEEED",
-"D     c #FEFEFE",
-"E     c #FEFEFD",
-"F     c #BA7F23",
-"G     c #A77D3B",
-"H     c #736F64",
-"I     c #6A6C68",
-"J     c #A37C3D",
-"K     c #B37B22",
-"L     c #6B4301",
-"     .++++.     ",
-"  @#$%&**&%$##  ",
-" @=-;>,'')>!~{] ",
-" ^/(_:<<<<:[}|1 ",
-" ^/234444443561 ",
-" ^7234888893561 ",
-" ^72344440a3561 ",
-" b723488cde3561 ",
-" b72349fgeh3561 ",
-" b723ijklmn3561 ",
-" b723oepqrs3561 ",
-" t723luvw333561 ",
-" t723xyzA335|61 ",
-" t7BCDDD9E5|||1 ",
-" ]FGHIIIIIJJJKL ",
-"  ]##########L  "};
diff --git a/include/xpm/edit-redo.png b/include/xpm/edit-redo.png
deleted file mode 100644 (file)
index c3b0df0..0000000
Binary files a/include/xpm/edit-redo.png and /dev/null differ
diff --git a/include/xpm/edit-redo.xpm b/include/xpm/edit-redo.xpm
deleted file mode 100644 (file)
index c83b376..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* XPM */
-static const char * edit_redo_xpm[] = {
-"16 16 47 1",
-"      c None",
-".     c #4E9A06",
-"+     c #AEF36C",
-"@     c #8F9B0C",
-"#     c #A9DE49",
-"$     c #AEF16A",
-"%     c #AEF26B",
-"&     c #B3F573",
-"*     c #A6EF61",
-"=     c #73D216",
-"-     c #ACD945",
-";     c #AFEF67",
-">     c #A1E950",
-",     c #A0DB24",
-"'     c #A9D846",
-")     c #B1EF65",
-"!     c #A4DE24",
-"~     c #97DD2A",
-"{     c #AFD71A",
-"]     c #75D318",
-"^     c #9DC230",
-"/     c #B1ED60",
-"(     c #A5DF26",
-"_     c #C8D009",
-":     c #77D014",
-"<     c #8AE234",
-"[     c #559F0C",
-"}     c #B1E963",
-"|     c #BAE031",
-"1     c #CBD417",
-"2     c #9BD622",
-"3     c #A1DA23",
-"4     c #D9DE23",
-"5     c #529D0A",
-"6     c #B2EC64",
-"7     c #CDD624",
-"8     c #93A10B",
-"9     c #CCD41E",
-"0     c #BEE246",
-"a     c #99A605",
-"b     c #B3D937",
-"c     c #B8DD3A",
-"d     c #AFC723",
-"e     c #919D05",
-"f     c #5AA80F",
-"g     c #C0D62C",
-"h     c #9A9902",
-"         .      ",
-"         ..     ",
-"         .+.    ",
-"      ....++.   ",
-"    .@#$%&*=+.  ",
-"   .-;>,,,,==+. ",
-"  .')!~,,{===]+.",
-" .^/({{_:====<. ",
-" [}|1233334=<.  ",
-" 5678.....9<.   ",
-" .0a.    .<.    ",
-" .b.     ..     ",
-" .c.     .      ",
-" .de            ",
-"  fgh           ",
-"                "};
diff --git a/include/xpm/edit-select-all.png b/include/xpm/edit-select-all.png
deleted file mode 100644 (file)
index f4b0b19..0000000
Binary files a/include/xpm/edit-select-all.png and /dev/null differ
diff --git a/include/xpm/edit-select-all.xpm b/include/xpm/edit-select-all.xpm
deleted file mode 100644 (file)
index 08ee62a..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* XPM */
-static const char * edit_select_all_xpm[] = {
-"16 16 37 1",
-"      c None",
-".     c #8B8D89",
-"+     c #888A85",
-"@     c #8C8E89",
-"#     c #FDFDFD",
-"$     c #FEFEFE",
-"%     c #FCFCFC",
-"&     c #FBFBFB",
-"*     c #FAFAFA",
-"=     c #F9F9F9",
-"-     c #8B8D88",
-";     c #A8BED6",
-">     c #A9BFD7",
-",     c #AAC0D8",
-"'     c #ABC1D9",
-")     c #F8F8F8",
-"!     c #8197AF",
-"~     c #ACC2DA",
-"{     c #ADC3DB",
-"]     c #AEC4DC",
-"^     c #EBEBEB",
-"/     c #AFC5DD",
-"(     c #ECECEC",
-"_     c #B0C6DE",
-":     c #EEEEEE",
-"<     c #B1C7DF",
-"[     c #F0F0F0",
-"}     c #B2C8E0",
-"|     c #F2F2F2",
-"1     c #F7F7F7",
-"2     c #000000",
-"3     c #B3C9E1",
-"4     c #F4F4F4",
-"5     c #F5F5F5",
-"6     c #F6F6F6",
-"7     c #8298B0",
-"8     c #8D8F8A",
-" .++++++++++++@ ",
-" +#$$##%%&&**=- ",
-" +#;>>,,''''')- ",
-" +$>!!!!~!!!~)- ",
-" +#,!!!!{{{{{)- ",
-" +#,!!!!{]]]^)- ",
-" +%'!!!!]!!/()- ",
-" +%~~{]//___:)- ",
-" +%~{]//__<<[)- ",
-" +&~!!!!!!!}|1- ",
-" +&{]/__2}2341- ",
-" +*{]/_<}25661- ",
-" +={7777}21)11- ",
-" +={]/_<}21=)1- ",
-" +))))))2)2)))- ",
-" @++++++++++++8 "};
diff --git a/include/xpm/edit-undo.png b/include/xpm/edit-undo.png
deleted file mode 100644 (file)
index 8b0fef9..0000000
Binary files a/include/xpm/edit-undo.png and /dev/null differ
diff --git a/include/xpm/edit-undo.xpm b/include/xpm/edit-undo.xpm
deleted file mode 100644 (file)
index 3bce212..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* XPM */
-static const char * edit_undo_xpm[] = {
-"16 16 61 1",
-"      c None",
-".     c #C4A000",
-"+     c #FBF3AD",
-"@     c #FBE425",
-"#     c #BEA113",
-"$     c #BB9F15",
-"%     c #BBA11B",
-"&     c #F6E131",
-"*     c #FAE320",
-"=     c #FAEC73",
-"-     c #FAEB6F",
-";     c #F7E86E",
-">     c #F7E86C",
-",     c #BCA114",
-"'     c #C1A314",
-")     c #F6E02F",
-"!     c #F7E232",
-"~     c #F1DB29",
-"{     c #F5E02F",
-"]     c #E3CD16",
-"^     c #ECD936",
-"/     c #F6E769",
-"(     c #E3CE41",
-"_     c #C1A313",
-":     c #F8E232",
-"<     c #E8D21D",
-"[     c #E1CD40",
-"}     c #BDA116",
-"|     c #FBED79",
-"1     c #F4DF2C",
-"2     c #D6C004",
-"3     c #DFC80B",
-"4     c #F3E56A",
-"5     c #C5AB1B",
-"6     c #BCA015",
-"7     c #FBED76",
-"8     c #DAC304",
-"9     c #F9EA69",
-"0     c #F7DD05",
-"a     c #DFC80A",
-"b     c #D8C207",
-"c     c #EBDC6F",
-"d     c #BFA31B",
-"e     c #C4A901",
-"f     c #EEE16E",
-"g     c #DFC90F",
-"h     c #F2E469",
-"i     c #C0A41A",
-"j     c #F5E66D",
-"k     c #EFE276",
-"l     c #C1A319",
-"m     c #C8AC02",
-"n     c #F2E788",
-"o     c #C2A211",
-"p     c #CBAA0E",
-"q     c #E9DA5D",
-"r     c #C0A623",
-"s     c #DBC443",
-"t     c #D8C543",
-"u     c #EADB66",
-"v     c #C2A611",
-"      .         ",
-"     ..         ",
-"    .+.         ",
-"   .+@..#$%     ",
-"  .+&*=-;>,'    ",
-" .+)!~{~]^/(_   ",
-".+):!!{~<<<^[}  ",
-" .|:1222<<<3456 ",
-"  .78799990abcd ",
-"   .77....efghi ",
-"    .7.    .jkl ",
-"     ..     mno ",
-"      .     pqr ",
-"            str ",
-"            uv  ",
-"                "};
diff --git a/include/xpm/film-b.png b/include/xpm/film-b.png
deleted file mode 100644 (file)
index edccf1b..0000000
Binary files a/include/xpm/film-b.png and /dev/null differ
diff --git a/include/xpm/film-b.xpm b/include/xpm/film-b.xpm
deleted file mode 100644 (file)
index 3f50d46..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* XPM */
-static const char * film_b_xpm[] = {
-"16 16 15 1",
-"      c None",
-".     c #7474D1",
-"+     c #7171D0",
-"@     c #7070CF",
-"#     c #6F6FCF",
-"$     c #6A6ACD",
-"%     c #6868CD",
-"&     c #7373D0",
-"*     c #7979D2",
-"=     c #7C7CD3",
-"-     c #7676D1",
-";     c #7E7ED3",
-">     c #8282D5",
-",     c #8585D6",
-"'     c #8181D4",
-"                ",
-"                ",
-"  .+@#$$%$%%%   ",
-"  . &+##$#$ %   ",
-"  **..++#+##$   ",
-"  = *-..+.+ #   ",
-"  ;==**....&+   ",
-"  > ;==**** .   ",
-"  ,>>'==*=***   ",
-"  > ;==**** .   ",
-"  ;==**....&+   ",
-"  = *-..+.+ #   ",
-"  **..++#+##$   ",
-"  . &+##$#$ %   ",
-"  .+@#$$%$%%%   ",
-"                "};
diff --git a/include/xpm/film-r.xpm b/include/xpm/film-r.xpm
deleted file mode 100644 (file)
index b84f594..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* XPM */
-static const char * film_r_xpm[] = {
-"16 16 13 1",
-"      c None",
-".     c #B53C3C",
-"+     c #B23B3B",
-"@     c #AF3A3A",
-"#     c #AE3939",
-"$     c #A63737",
-"%     c #A53737",
-"&     c #BD3F3F",
-"*     c #C04141",
-"=     c #BA3E3E",
-"-     c #C14444",
-";     c #C24949",
-">     c #C44F4F",
-"                ",
-"                ",
-"  .+@#$$%$%%%   ",
-"  . .+##$#$ %   ",
-"  &&..++#+##$   ",
-"  * &=..+.+ #   ",
-"  -**&&.....+   ",
-"  ; -**&&&& .   ",
-"  >;;;**&*&&&   ",
-"  ; -**&&&& .   ",
-"  -**&&.....+   ",
-"  * &=..+.+ #   ",
-"  &&..++#+##$   ",
-"  . .+##$#$ %   ",
-"  .+@#$$%$%%%   ",
-"                "};
diff --git a/include/xpm/folder.png b/include/xpm/folder.png
deleted file mode 100644 (file)
index 65bd0bb..0000000
Binary files a/include/xpm/folder.png and /dev/null differ
diff --git a/include/xpm/format-indent-more.png b/include/xpm/format-indent-more.png
deleted file mode 100644 (file)
index 00309ea..0000000
Binary files a/include/xpm/format-indent-more.png and /dev/null differ
diff --git a/include/xpm/format-indent-more.xpm b/include/xpm/format-indent-more.xpm
deleted file mode 100644 (file)
index d2193fd..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* XPM */
-static const char * format_indent_more_xpm[] = {
-"16 16 34 1",
-"      c None",
-".     c #4E8FCC",
-"+     c #498DC7",
-"@     c #FFFFFF",
-"#     c #4B90CB",
-"$     c #FEFEFE",
-"%     c #FABFBA",
-"&     c #A22320",
-"*     c #F9B7B3",
-"=     c #921B18",
-"-     c #F9B5B1",
-";     c #FCD2D2",
-">     c #F49A9A",
-",     c #E67674",
-"'     c #D55653",
-")     c #BE3936",
-"!     c #F8B3B0",
-"~     c #F49A98",
-"{     c #D45552",
-"]     c #F8B2AE",
-"^     c #F39D99",
-"/     c #E67572",
-"(     c #F8B0AC",
-"_     c #F39B97",
-":     c #E67772",
-"<     c #D35653",
-"[     c #F8AEAA",
-"}     c #F39795",
-"|     c #E57471",
-"1     c #D35451",
-"2     c #F8AEAC",
-"3     c #F8B1AC",
-"4     c #FBCAC7",
-"5     c #4C8ECC",
-" .++++++++++++. ",
-" +@@@@@@@@@@@@# ",
-" +@@@@@@@@@@@$# ",
-" +@@@@@#####@$# ",
-" +@@@@@%@@@@@$# ",
-" +@@@@@&*@@@@@# ",
-" +@@@@@&=-@@@@# ",
-" +;>,')&==!@@@# ",
-" +;~,{)&===]@$# ",
-" +;^/{)&====($# ",
-" +;_:<)&===[@$# ",
-" +;}|1)&==2@@@# ",
-" +@@@@@&=3@@@@# ",
-" +@@@@@&3@@@@@# ",
-" +@@@@@4$$@@@@# ",
-" .############5 "};
diff --git a/include/xpm/go-down.png b/include/xpm/go-down.png
deleted file mode 100644 (file)
index 3dd7fcc..0000000
Binary files a/include/xpm/go-down.png and /dev/null differ
diff --git a/include/xpm/go-down.xpm b/include/xpm/go-down.xpm
deleted file mode 100644 (file)
index e11a2cf..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/* XPM */
-static const char * go_down_xpm[] = {
-"16 16 93 2",
-"      c None",
-".     c #3A7404",
-"+     c #3A7304",
-"@     c #C7DEB0",
-"#     c #C3DCAB",
-"$     c #BFDAA6",
-"%     c #B1D291",
-"&     c #A3CA7E",
-"*     c #C8DFB1",
-"=     c #8DBE5F",
-"-     c #86BA55",
-";     c #71AE37",
-">     c #4E9A06",
-",     c #C7DFB1",
-"'     c #78B241",
-")     c #8CBD5D",
-"!     c #85B954",
-"~     c #7CB447",
-"{     c #3B7504",
-"]     c #3B7604",
-"^     c #C5DDAD",
-"/     c #89BC59",
-"(     c #82B850",
-"_     c #6FAD34",
-":     c #568927",
-"<     c #C2DBAA",
-"[     c #C6DEAF",
-"}     c #C2DCAA",
-"|     c #88BD56",
-"1     c #82BA4D",
-"2     c #63AA1F",
-"3     c #53A208",
-"4     c #A5CE7F",
-"5     c #A4CD7E",
-"6     c #A4CC7E",
-"7     c #9FC778",
-"8     c #4B8218",
-"9     c #3B7404",
-"0     c #7AA54F",
-"a     c #B8D69B",
-"b     c #8DBE5D",
-"c     c #8AC058",
-"d     c #87C051",
-"e     c #7EBC42",
-"f     c #5AAB0C",
-"g     c #59AB0B",
-"h     c #59AA0A",
-"i     c #58A90C",
-"j     c #97C768",
-"k     c #659A34",
-"l     c #99BF75",
-"m     c #A9D183",
-"n     c #89C252",
-"o     c #87C34D",
-"p     c #69B61E",
-"q     c #5FB40D",
-"r     c #5EB30D",
-"s     c #89C54E",
-"t     c #84B755",
-"u     c #40780D",
-"v     c #B1D390",
-"w     c #98CC65",
-"x     c #7DC23B",
-"y     c #62B90F",
-"z     c #65BC0F",
-"A     c #65BD10",
-"B     c #7BC532",
-"C     c #9FCE71",
-"D     c #3F780A",
-"E     c #578C26",
-"F     c #B7DB94",
-"G     c #79C331",
-"H     c #67C011",
-"I     c #6AC512",
-"J     c #73C91F",
-"K     c #A8DB78",
-"L     c #52891E",
-"M     c #7AAA4C",
-"N     c #A0D66D",
-"O     c #69C412",
-"P     c #6ECB14",
-"Q     c #A5E06C",
-"R     c #72A83F",
-"S     c #3C7604",
-"T     c #8DBF5D",
-"U     c #8DD14C",
-"V     c #90D54E",
-"W     c #92C55F",
-"X     c #427A0E",
-"Y     c #A2D174",
-"Z     c #A3D375",
-"`     c #427B0E",
-" .    c #568B24",
-"        . + + + + + + .         ",
-"        + @ # $ % & & +         ",
-"        + * = - ; > & +         ",
-"        + , = - ' > & +         ",
-"        + @ ) ! ~ > & +         ",
-"{ + + + ] ^ / ( _ > & ] + + + { ",
-"  : < [ ^ } | 1 2 3 4 5 6 7 8   ",
-"  9 0 a b c d e f g h i j k 9   ",
-"    . l m n o p q q r s t {     ",
-"      u v w x y z A B C D       ",
-"        E F G H I J K L         ",
-"        { M N O P Q R S         ",
-"          ] T U V W S           ",
-"            X Y Z `             ",
-"               . .              ",
-"              S S               "};
diff --git a/include/xpm/go-first.png b/include/xpm/go-first.png
deleted file mode 100644 (file)
index 9c15c09..0000000
Binary files a/include/xpm/go-first.png and /dev/null differ
diff --git a/include/xpm/go-first.xpm b/include/xpm/go-first.xpm
deleted file mode 100644 (file)
index 3687e51..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* XPM */
-static const char * go_first_xpm[] = {
-"16 16 100 2",
-"      c None",
-".     c #3A7304",
-"+     c #3B7504",
-"@     c #3B7404",
-"#     c #588B28",
-"$     c #3A7404",
-"%     c #81AA58",
-"&     c #C4DCAC",
-"*     c #457C12",
-"=     c #A6C787",
-"-     c #BEDAA5",
-";     c #C6DEAF",
-">     c #629135",
-",     c #BBD6A1",
-"'     c #B0D290",
-")     c #91C064",
-"!     c #C3DDAB",
-"~     c #3B7604",
-"{     c #3B7506",
-"]     c #86AE5F",
-"^     c #BDD9A3",
-"/     c #9DC775",
-"(     c #8CBD5D",
-"_     c #8BBE5B",
-":     c #C2DDA8",
-"<     c #C0DDA5",
-"[     c #BEDBA2",
-"}     c #BBD99E",
-"|     c #B8D79A",
-"1     c #B4D496",
-"2     c #487E17",
-"3     c #A0C380",
-"4     c #B1D292",
-"5     c #8BBC5D",
-"6     c #86BA55",
-"7     c #87BD54",
-"8     c #87BF52",
-"9     c #87C04F",
-"0     c #85C04C",
-"a     c #81BE46",
-"b     c #7CBA3F",
-"c     c #76B539",
-"d     c #B4D594",
-"e     c #AECE8F",
-"f     c #9CC673",
-"g     c #7DB448",
-"h     c #7DB549",
-"i     c #80B74B",
-"j     c #83BC4B",
-"k     c #81BF46",
-"l     c #79BC37",
-"m     c #71BA2A",
-"n     c #69B51E",
-"o     c #65B31B",
-"p     c #65B01D",
-"q     c #B0D58E",
-"r     c #A1C77E",
-"s     c #68A92B",
-"t     c #62A523",
-"u     c #5FA81A",
-"v     c #5DAB11",
-"w     c #5CB00C",
-"x     c #60B50D",
-"y     c #62B80E",
-"z     c #61B80E",
-"A     c #5FB50D",
-"B     c #5CAF0C",
-"C     c #A8D280",
-"D     c #41790E",
-"E     c #85B25A",
-"F     c #8FBF62",
-"G     c #59A213",
-"H     c #55A509",
-"I     c #5AAD0B",
-"J     c #64BB0F",
-"K     c #66BF10",
-"L     c #63BB0F",
-"M     c #5FB40D",
-"N     c #A9D480",
-"O     c #6A9C3B",
-"P     c #9CC772",
-"Q     c #70B42D",
-"R     c #62B90E",
-"S     c #B0DE83",
-"T     c #B2E184",
-"U     c #ADDA82",
-"V     c #AAD681",
-"W     c #50851D",
-"X     c #99C66E",
-"Y     c #8AC74E",
-"Z     c #64BB11",
-"`     c #B1E084",
-" .    c #3F7B05",
-"..    c #3F780A",
-"+.    c #87B955",
-"@.    c #9FD56C",
-"#.    c #6AA136",
-"$.    c #ACDB7E",
-"%.    c #4E8619",
-"&.    c #3C7604",
-". .                 +           ",
-". .             @ # .           ",
-". .           $ % & .           ",
-". .         * = - ; .           ",
-". .     @ > , ' ) ! ~ . . . . $ ",
-". .   { ] ^ / ( _ : < [ } | 1 . ",
-". . 2 3 4 5 6 7 8 9 0 a b c d . ",
-". . e f g h i j k l m n o p q . ",
-". . r ( s t u v w x y z A B C . ",
-". . D E F G H I A J K K L M N . ",
-". .   $ O P Q w R S T T S U V . ",
-". .     @ W X Y Z `  .. . . . $ ",
-". .         ..+.@.` .           ",
-". .           + #.$..           ",
-". .             ~ %..           ",
-". .                 &.          "};
diff --git a/include/xpm/go-last.png b/include/xpm/go-last.png
deleted file mode 100644 (file)
index 6e904ef..0000000
Binary files a/include/xpm/go-last.png and /dev/null differ
diff --git a/include/xpm/go-last.xpm b/include/xpm/go-last.xpm
deleted file mode 100644 (file)
index 2103750..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* XPM */
-static const char * go_last_xpm[] = {
-"16 16 100 2",
-"      c None",
-".     c #3B7504",
-"+     c #3A7304",
-"@     c #568927",
-"#     c #3A7404",
-"$     c #C0DBA7",
-"%     c #7EA955",
-"&     c #C3DCAB",
-"*     c #BCD8A0",
-"=     c #A4C684",
-"-     c #447B11",
-";     c #3B7604",
-">     c #C1DBA9",
-",     c #8EBE5F",
-"'     c #AFD28D",
-")     c #BAD6A0",
-"!     c #629135",
-"~     c #3B7404",
-"{     c #B2D393",
-"]     c #B4D496",
-"^     c #B7D69A",
-"/     c #BAD79E",
-"(     c #BDD9A1",
-"_     c #C0DCA4",
-":     c #8AC058",
-"<     c #8EC25C",
-"[     c #9FCB76",
-"}     c #BFDBA4",
-"|     c #86AF60",
-"1     c #3B7506",
-"2     c #B0D190",
-"3     c #6CAB30",
-"4     c #71AE37",
-"5     c #76B23D",
-"6     c #7DB845",
-"7     c #83BE4B",
-"8     c #87C150",
-"9     c #8BC353",
-"0     c #8CC356",
-"a     c #91C560",
-"b     c #B4D694",
-"c     c #A2C581",
-"d     c #497E17",
-"e     c #ACCF8A",
-"f     c #59A016",
-"g     c #589F14",
-"h     c #5EA718",
-"i     c #6AB226",
-"j     c #76BB35",
-"k     c #83C245",
-"l     c #88C64B",
-"m     c #88C54D",
-"n     c #87C34D",
-"o     c #84BF4C",
-"p     c #B0D092",
-"q     c #A3CA7E",
-"r     c #4E9A06",
-"s     c #509E07",
-"t     c #56A609",
-"u     c #5AAD0B",
-"v     c #5EB30D",
-"w     c #61B70E",
-"x     c #66BB16",
-"y     c #6CBC1F",
-"z     c #71BC2A",
-"A     c #73B930",
-"B     c #92C560",
-"C     c #A3C97F",
-"D     c #52A108",
-"E     c #58A90A",
-"F     c #5DB10C",
-"G     c #62B80E",
-"H     c #66BE10",
-"I     c #67C011",
-"J     c #6ABB1B",
-"K     c #99CE66",
-"L     c #89B85B",
-"M     c #42790E",
-"N     c #A6CF7F",
-"O     c #A9D480",
-"P     c #ACD881",
-"Q     c #AFDC83",
-"R     c #6AC412",
-"S     c #6CC813",
-"T     c #80CC35",
-"U     c #A6D777",
-"V     c #6EA33D",
-"W     c #3D7904",
-"X     c #AFDD83",
-"Y     c #6DC815",
-"Z     c #97DC55",
-"`     c #A3D673",
-" .    c #52891E",
-"..    c #A5DC6E",
-"+.    c #8DC459",
-"@.    c #3F790A",
-"#.    c #AAD97D",
-"$.    c #6CA436",
-"%.    c #3C7604",
-"&.    c #4D8519",
-"          .                 + + ",
-"          + @ #             + + ",
-"          + $ % #           + + ",
-"          + & * = -         + + ",
-"# + + + + ; > , ' ) ! ~     + + ",
-"+ { ] ^ / ( _ : < [ } | 1   + + ",
-"+ 2 3 4 5 6 7 8 9 0 a b c d + + ",
-"+ e f g h i j k l m n o [ p + + ",
-"+ q r s t u v w x y z A B C + + ",
-"+ q r D E F G H I H J K L M + + ",
-"+ q q N O P Q R S T U V .   + + ",
-"# + + + + W X Y Z `  .;     + + ",
-"          + X ..+.@.        + + ",
-"          + #.$.%.          + + ",
-"          + &.%.            + + ",
-"          ;                 + + "};
diff --git a/include/xpm/go-next-b.png b/include/xpm/go-next-b.png
deleted file mode 100644 (file)
index 1f48daf..0000000
Binary files a/include/xpm/go-next-b.png and /dev/null differ
diff --git a/include/xpm/go-next.png b/include/xpm/go-next.png
deleted file mode 100644 (file)
index 6ef8de7..0000000
Binary files a/include/xpm/go-next.png and /dev/null differ
diff --git a/include/xpm/go-next.xpm b/include/xpm/go-next.xpm
deleted file mode 100644 (file)
index 49e0f2f..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* XPM */
-static const char * go_next_xpm[] = {
-"16 16 100 2",
-"      c None",
-".     c #3B7504",
-"+     c #3A7304",
-"@     c #598C2A",
-"#     c #3A7404",
-"$     c #CBE1B7",
-"%     c #82AB5A",
-"&     c #CEE3BB",
-"*     c #C3DCAB",
-"=     c #A4C684",
-"-     c #437A10",
-";     c #3B7604",
-">     c #CBE0B6",
-",     c #99C46F",
-"'     c #B1D291",
-")     c #B7D49C",
-"!     c #5F8F31",
-"~     c #3B7404",
-"{     c #C0DBA7",
-"]     c #C2DCAA",
-"^     c #C5DDAD",
-"/     c #C6DEAF",
-"(     c #C7DEB0",
-"_     c #91C164",
-":     c #8FC161",
-"<     c #9DC873",
-"[     c #BBD99F",
-"}     c #81AB5A",
-"|     c #3A7405",
-"1     c #BDD9A3",
-"2     c #85B954",
-"3     c #88BB58",
-"4     c #8BBC5B",
-"5     c #8BBD5C",
-"6     c #8CBE5C",
-"7     c #8DC15C",
-"8     c #8DC25A",
-"9     c #8AC255",
-"0     c #8CC358",
-"a     c #AFD48C",
-"b     c #9CC37A",
-"c     c #467C14",
-"d     c #B9D79C",
-"e     c #74AF3B",
-"f     c #6EAC33",
-"g     c #68A92B",
-"h     c #6BAC2F",
-"i     c #78B63D",
-"j     c #82BE49",
-"k     c #89C350",
-"l     c #88C44D",
-"m     c #84C249",
-"n     c #80BE44",
-"o     c #9BCA6D",
-"p     c #AACE89",
-"q     c #5E8F30",
-"r     c #A3CA7E",
-"s     c #4E9A06",
-"t     c #52A007",
-"u     c #57A709",
-"v     c #5BAE0B",
-"w     c #5FB20E",
-"x     c #66B817",
-"y     c #6CBA1F",
-"z     c #6FBA26",
-"A     c #8DC655",
-"B     c #9EC976",
-"C     c #568926",
-"D     c #4F9C06",
-"E     c #54A408",
-"F     c #5AAC0B",
-"G     c #5EB30D",
-"H     c #62B90E",
-"I     c #64BC0F",
-"J     c #6CBF1C",
-"K     c #9CD267",
-"L     c #8BBB5D",
-"M     c #427A0E",
-"N     c #A4CC7E",
-"O     c #A7D17F",
-"P     c #AAD581",
-"Q     c #61B70E",
-"R     c #66BF10",
-"S     c #7FCB34",
-"T     c #A8DA78",
-"U     c #71A63E",
-"V     c #3C7804",
-"W     c #ABD681",
-"X     c #64BA11",
-"Y     c #92D352",
-"Z     c #A5D773",
-"`     c #538B1E",
-" .    c #3C7604",
-"..    c #ABD781",
-"+.    c #A0D56C",
-"@.    c #8BC158",
-"#.    c #40790A",
-"$.    c #A6D37B",
-"%.    c #6AA136",
-"&.    c #4D8418",
-"          .                     ",
-"          + @ #                 ",
-"          + $ % #               ",
-"          + & * = -             ",
-"# + + + + ; > , ' ) ! ~         ",
-"+ { ] ^ / ( ( _ : < [ } |       ",
-"+ 1 2 3 4 5 6 7 8 9 0 a b c     ",
-"+ d e f g h i j k l m n o p q . ",
-"+ r s s s t u v w x y z A B C . ",
-"+ r s s D E F G H I J K L M     ",
-"+ r r r N O P Q R S T U ;       ",
-"# + + + + V W X Y Z `  .        ",
-"          + ..+.@.#.            ",
-"          + $.%. .              ",
-"          + &.;                 ",
-"          .                     "};
diff --git a/include/xpm/go-previous-b.png b/include/xpm/go-previous-b.png
deleted file mode 100644 (file)
index 7c8443a..0000000
Binary files a/include/xpm/go-previous-b.png and /dev/null differ
diff --git a/include/xpm/go-previous.png b/include/xpm/go-previous.png
deleted file mode 100644 (file)
index 659cd90..0000000
Binary files a/include/xpm/go-previous.png and /dev/null differ
diff --git a/include/xpm/go-previous.xpm b/include/xpm/go-previous.xpm
deleted file mode 100644 (file)
index 65984e8..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/* XPM */
-static const char * go_previous_xpm[] = {
-"16 16 98 2",
-"      c None",
-".     c #3B7504",
-"+     c #3B7404",
-"@     c #598B29",
-"#     c #3A7304",
-"$     c #3A7404",
-"%     c #7FA956",
-"&     c #C8DFB1",
-"*     c #437A10",
-"=     c #A0C37E",
-"-     c #BDD9A3",
-";     c #CAE0B5",
-">     c #5D8D2E",
-",     c #B3D296",
-"'     c #AACF88",
-")     c #91C064",
-"!     c #C7DFB1",
-"~     c #3B7604",
-"{     c #3A7405",
-"]     c #7DA855",
-"^     c #B5D497",
-"/     c #94C26A",
-"(     c #87BA57",
-"_     c #8BBD5C",
-":     c #C4DDAC",
-"<     c #C5DEAE",
-"[     c #C6DEAE",
-"}     c #C2DCAA",
-"|     c #457C13",
-"1     c #97BD72",
-"2     c #A7CD84",
-"3     c #80B64D",
-"4     c #7DB549",
-"5     c #82B74F",
-"6     c #85B954",
-"7     c #88BB58",
-"8     c #89BC59",
-"9     c #8ABC5A",
-"0     c #BFDAA6",
-"a     c #5A8C2C",
-"b     c #A5C982",
-"c     c #90BF63",
-"d     c #70AD35",
-"e     c #75B23C",
-"f     c #7BB642",
-"g     c #7FB947",
-"h     c #7AB742",
-"i     c #71B035",
-"j     c #65A827",
-"k     c #5EA31D",
-"l     c #60A420",
-"m     c #68A92B",
-"n     c #B8D69B",
-"o     c #578927",
-"p     c #9DC477",
-"q     c #87BB54",
-"r     c #66AC22",
-"s     c #66AF20",
-"t     c #62AF17",
-"u     c #5CAD0E",
-"v     c #59AC0B",
-"w     c #58A90A",
-"x     c #55A409",
-"y     c #519E07",
-"z     c #4E9A06",
-"A     c #A3CA7E",
-"B     c #41790E",
-"C     c #87B65B",
-"D     c #96CA65",
-"E     c #65B519",
-"F     c #60B50D",
-"G     c #61B70E",
-"H     c #61B60E",
-"I     c #5EB30D",
-"J     c #5AAD0B",
-"K     c #56A609",
-"L     c #6EA23D",
-"M     c #A5D576",
-"N     c #7CC833",
-"O     c #69C211",
-"P     c #67C111",
-"Q     c #AEDB82",
-"R     c #ACD881",
-"S     c #A9D480",
-"T     c #A6CF7F",
-"U     c #52891E",
-"V     c #A3D572",
-"W     c #97DA54",
-"X     c #6EC915",
-"Y     c #B0DE83",
-"Z     c #3D7904",
-"`     c #3F790A",
-" .    c #8DC459",
-"..    c #A5DC6E",
-"+.    c #3C7604",
-"@.    c #6BA236",
-"#.    c #A9D77D",
-"$.    c #4D8419",
-"                    .           ",
-"                + @ #           ",
-"              $ % & #           ",
-"            * = - ; #           ",
-"        + > , ' ) ! ~ # # # # $ ",
-"      { ] ^ / ( _ : < [ < : } # ",
-"    | 1 2 3 4 5 6 7 8 9 8 7 0 # ",
-". a b c d e f g h i j k l m n # ",
-". o p q r s t u v w x y z z A # ",
-"    B C D E F G H I J K y z A # ",
-"      . L M N O P Q R S T A A # ",
-"        ~ U V W X Y Z # # # # $ ",
-"            `  ...Y #           ",
-"              +.@.#.#           ",
-"                ~ $.#           ",
-"                    .           "};
diff --git a/include/xpm/go-up.png b/include/xpm/go-up.png
deleted file mode 100644 (file)
index fa9a7d7..0000000
Binary files a/include/xpm/go-up.png and /dev/null differ
diff --git a/include/xpm/go-up.xpm b/include/xpm/go-up.xpm
deleted file mode 100644 (file)
index d3ae19f..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* XPM */
-static const char * go_up_xpm[] = {
-"16 16 105 2",
-"      c None",
-".     c #3B7504",
-"+     c #578928",
-"@     c #568926",
-"#     c #41790F",
-"$     c #A7CA87",
-"%     c #A2C77E",
-"&     c #41790E",
-"*     c #3A7404",
-"=     c #96BD72",
-"-     c #9AC572",
-";     c #95C26A",
-">     c #86B35B",
-",     c #3B7404",
-"'     c #78A54E",
-")     c #B0D291",
-"!     c #7DB448",
-"~     c #76B13F",
-"{     c #6A9C3B",
-"]     c #578A28",
-"^     c #BBD7A0",
-"/     c #8CBD5F",
-"(     c #80B64D",
-"_     c #7AB344",
-":     c #5CA21A",
-"<     c #9AC471",
-"[     c #4F841D",
-"}     c #40780D",
-"|     c #B7D49C",
-"1     c #A0C97A",
-"2     c #8BBE5A",
-"3     c #86BC51",
-"4     c #74B438",
-"5     c #53A308",
-"6     c #6CAF2C",
-"7     c #97C36E",
-"8     c #3E770A",
-"9     c #A1C480",
-"0     c #B5D597",
-"a     c #96C569",
-"b     c #91C560",
-"c     c #8BC356",
-"d     c #66B01D",
-"e     c #59AC0B",
-"f     c #59AB0B",
-"g     c #85C14D",
-"h     c #84B455",
-"i     c #7FA956",
-"j     c #C7DFB0",
-"k     c #A0CB77",
-"l     c #9ACA6C",
-"m     c #96CA63",
-"n     c #81C143",
-"o     c #5EB30D",
-"p     c #5FB50D",
-"q     c #5FB40D",
-"r     c #5FB20F",
-"s     c #9BCE6A",
-"t     c #679C35",
-"u     c #588B28",
-"v     c #CAE0B5",
-"w     c #D0E5BC",
-"x     c #CEE5B8",
-"y     c #CBE5B3",
-"z     c #97CD63",
-"A     c #68BA19",
-"B     c #64BC0F",
-"C     c #65BE10",
-"D     c #AFDC83",
-"E     c #AEDB82",
-"F     c #ACD982",
-"G     c #A6D37B",
-"H     c #4C8418",
-"I     c #3A7304",
-"J     c #3C7804",
-"K     c #CBE6B2",
-"L     c #89C94B",
-"M     c #65BD10",
-"N     c #69C311",
-"O     c #6BC712",
-"P     c #B2E184",
-"Q     c #3E7A05",
-"R     c #CAE5B0",
-"S     c #78C331",
-"T     c #67C011",
-"U     c #6CC813",
-"V     c #71CF15",
-"W     c #B4E585",
-"X     c #C8E4AD",
-"Y     c #6DBD1F",
-"Z     c #66BF10",
-"`     c #6AC512",
-" .    c #6DC913",
-"..    c #B3E384",
-"+.    c #C5E2A9",
-"@.    c #65B616",
-"#.    c #63BA0F",
-"$.    c #66BE10",
-"%.    c #67C111",
-"&.    c #B0DE83",
-"*.    c #C1DFA5",
-"=.    c #AAD581",
-"-.    c #ABD781",
-";.    c #ADDA82",
-">.    c #ADD982",
-"              . .               ",
-"              + @               ",
-"            # $ % &             ",
-"          * = - ; > *           ",
-"        , ' ) ! ~ ; { *         ",
-"        ] ^ / ( _ : < [         ",
-"      } | 1 2 3 4 5 6 7 8       ",
-"    * 9 0 a b c d e f g h .     ",
-"  , i j k l m n o p q r s t .   ",
-"  u v w x y z A B C D E F G H   ",
-". I I I J K L M N O P Q I I I . ",
-"        I R S T U V W I         ",
-"        I X Y Z `  ...I         ",
-"        I +.@.#.$.%.&.I         ",
-"        I *.=.-.F ;.>.I         ",
-"        * I I I I I I ,         "};
diff --git a/include/xpm/help-contents.png b/include/xpm/help-contents.png
deleted file mode 100644 (file)
index b3ae2c3..0000000
Binary files a/include/xpm/help-contents.png and /dev/null differ
diff --git a/include/xpm/help-contents.xpm b/include/xpm/help-contents.xpm
deleted file mode 100644 (file)
index a307af2..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* XPM */
-static const char * help_contents_xpm[] = {
-"16 16 104 2",
-"      c None",
-".     c #8D8F8A",
-"+     c #898B86",
-"@     c #888A85",
-"#     c #8F918C",
-"$     c #FFFFFF",
-"%     c #8A8C87",
-"&     c #DEE1DB",
-"*     c #C0C3BC",
-"=     c #BABDB6",
-"-     c #C2C4BE",
-";     c #EAECE8",
-">     c #DFE2DC",
-",     c #E3E5E0",
-"'     c #E6E9E4",
-")     c #EDEEEB",
-"!     c #EFF0ED",
-"~     c #F0F1EF",
-"{     c #F0F1EE",
-"]     c #EEF0ED",
-"^     c #ECEDEA",
-"/     c #E0E3DD",
-"(     c #E4E6E1",
-"_     c #C5ABA8",
-":     c #A37A77",
-"<     c #A47E7B",
-"[     c #CAB1AE",
-"}     c #EDEFEC",
-"|     c #E1E3DE",
-"1     c #B17977",
-"2     c #A32827",
-"3     c #D69392",
-"4     c #EEEEEC",
-"5     c #EEEEED",
-"6     c #D79C9B",
-"7     c #A52927",
-"8     c #B57D7B",
-"9     c #C6ABA8",
-"0     c #F08686",
-"a     c #EB5757",
-"b     c #BAA6A2",
-"c     c #EB5C5C",
-"d     c #F09F9F",
-"e     c #A62A29",
-"f     c #D0B4B2",
-"g     c #A2837F",
-"h     c #D78F8E",
-"i     c #EC5757",
-"j     c #AB1010",
-"k     c #B99390",
-"l     c #ED5F5F",
-"m     c #DBA4A2",
-"n     c #A6827E",
-"o     c #F0F0EE",
-"p     c #BAA9A6",
-"q     c #B68885",
-"r     c #F4F5F3",
-"s     c #F8F8F7",
-"t     c #BD9896",
-"u     c #BBA6A3",
-"v     c #F2F2F1",
-"w     c #BAA8A5",
-"x     c #B79693",
-"y     c #F8F9F8",
-"z     c #BA8D8B",
-"A     c #BCAEAB",
-"B     c #F5F5F4",
-"C     c #A47F7B",
-"D     c #E09392",
-"E     c #EC8C8C",
-"F     c #A21B1B",
-"G     c #B89490",
-"H     c #BA9694",
-"I     c #A11C1B",
-"J     c #EDA7A7",
-"K     c #E39E9D",
-"L     c #A68481",
-"M     c #C6ACA8",
-"N     c #B21C1C",
-"O     c #F69090",
-"P     c #EE9897",
-"Q     c #BFAEAB",
-"R     c #C0AFAC",
-"S     c #EFB2B1",
-"T     c #F9B1B1",
-"U     c #B32020",
-"V     c #D0B5B3",
-"W     c #E2E5E0",
-"X     c #B27774",
-"Y     c #B32221",
-"Z     c #E6AAA9",
-"`     c #F8F8F8",
-" .    c #FAFAF9",
-"..    c #EAB8B7",
-"+.    c #B52626",
-"@.    c #B77B79",
-"#.    c #F2F3F0",
-"$.    c #E2E4DF",
-"%.    c #E6E8E4",
-"&.    c #C5ADA9",
-"*.    c #A47C79",
-"=.    c #A57B78",
-"-.    c #CDB3B1",
-";.    c #F1F2F0",
-"  . + @ @ @ @ @ @ @ @ @ @ + #   ",
-"  + $ $ $ $ $ $ $ $ $ $ $ $ %   ",
-"  @ $ & * = = = = = = - ; $ @   ",
-"  @ $ > , ' ; ) ! ~ { ] ^ $ @   ",
-"  @ $ / ( _ : . . < [ ~ } $ @   ",
-"  @ $ | 1 2 3 4 5 6 7 8 ! $ @   ",
-"  @ $ 9 2 0 a b b c d e f $ @   ",
-"  @ $ g h i j k k j l m n $ @   ",
-"  @ $ . o p q r s t u v . $ @   ",
-"  @ $ . v w x r y z A B . $ @   ",
-"  @ $ C D E F G H I J K L $ @   ",
-"  @ $ M N O P Q R S T U V $ @   ",
-"  @ $ W X Y Z `  ...+.@.#.$ @   ",
-"  @ $ $.%.&.*.. . =.-.r ;.$ @   ",
-"  + $ $ $ $ $ $ $ $ $ $ $ $ %   ",
-"  . + @ @ @ @ @ @ @ @ @ @ + #   "};
diff --git a/include/xpm/help-faq.png b/include/xpm/help-faq.png
deleted file mode 100644 (file)
index f6bc721..0000000
Binary files a/include/xpm/help-faq.png and /dev/null differ
diff --git a/include/xpm/help-faq.xpm b/include/xpm/help-faq.xpm
deleted file mode 100644 (file)
index 1b8b9fe..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* XPM */
-static const char * help_faq_xpm[] = {
-"16 16 73 1",
-"      c None",
-".     c #B6B8B4",
-"+     c #93938F",
-"@     c #888A85",
-"#     c #8D908A",
-"$     c #BDBEBB",
-"%     c #FCFCFC",
-"&     c #FFFFFF",
-"*     c #BBBCBB",
-"=     c #8D8F89",
-"-     c #91928E",
-";     c #93968F",
-">     c #B4B5B1",
-",     c #EEEEEB",
-"'     c #A0BDDA",
-")     c #A3BFDB",
-"!     c #91B3D5",
-"~     c #DBE2EB",
-"{     c #FCFCFB",
-"]     c #BCBDBA",
-"^     c #B8B9B7",
-"/     c #F1F1F1",
-"(     c #F2F2F1",
-"_     c #ADC6DE",
-":     c #BFD1E2",
-"<     c #FEFEFE",
-"[     c #8F918C",
-"}     c #8D8E8A",
-"|     c #F2F2F0",
-"1     c #EFEFED",
-"2     c #A1BDDA",
-"3     c #91B3D6",
-"4     c #E1E7EC",
-"5     c #92948F",
-"6     c #F5F5F4",
-"7     c #BDD0E5",
-"8     c #ACC6DF",
-"9     c #F4F5F4",
-"0     c #8F908C",
-"a     c #F1F1F0",
-"b     c #AEC6DE",
-"c     c #BFD1E3",
-"d     c #F8F8F6",
-"e     c #8AAFD5",
-"f     c #FBFBFB",
-"g     c #F8F8F7",
-"h     c #8AAFD6",
-"i     c #7AA5D3",
-"j     c #8A8C88",
-"k     c #FBFBFA",
-"l     c #90938E",
-"m     c #8E8F8B",
-"n     c #FDFDFD",
-"o     c #7AA5D2",
-"p     c #8B8D88",
-"q     c #949591",
-"r     c #F6F6F5",
-"s     c #969994",
-"t     c #C0C1BE",
-"u     c #FEFEFD",
-"v     c #90928E",
-"w     c #90938C",
-"x     c #EEEEEC",
-"y     c #8D8F8A",
-"z     c #939590",
-"A     c #979994",
-"B     c #90908C",
-"C     c #DFDFDE",
-"D     c #90928D",
-"E     c #EDEDEC",
-"F     c #8F908B",
-"G     c #DFE0DE",
-"H     c #8E908B",
-"                ",
-"       .+@@@@#  ",
-"      .$%&&&&%* ",
-" =-@@@@;>,')!~{#",
-" ]%&&&&%]^/(_:<[",
-"}%|12)34{56789<[",
-"0<||a|bc<0dedd&[",
-"[<666789<[ffff&[",
-"[&ggghgg&[<i<<&j",
-"0&kkkkkk&[&&<<%l",
-"mn<<<o<<&pqr&&s ",
-" tu&&&<<%v wx&[ ",
-" ym@zr&&A   BC[ ",
-"     DE&[    F@ ",
-"      0G[       ",
-"       H@       "};
diff --git a/include/xpm/light_on.xpm b/include/xpm/light_on.xpm
deleted file mode 100644 (file)
index 77ff8ca..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* XPM */
-static const char * light_on_xpm[] = {
-"16 16 14 1",
-"      c None",
-"!     c #000000",
-"%     c #603000",
-"'     c #804000",
-")     c #A05000",
-"*     c #201000",
-"+     c #402000",
-"-     c #E07000",
-"0     c #004000",
-"1     c #404000",
-"2     c #FF7F00",
-"3     c #C06000",
-"7     c #603000",
-"8     c #203000",
-"     '    '     ",
-"    ''%33'''    ",
-"    '2)*+3-%    ",
-"    '100001+    ",
-" ''+01322310+'' ",
-"3'211222222112''",
-" %)0322222-'0)% ",
-" 3*0222222-)0*3 ",
-" 3+0222222-)0+3 ",
-" '3032222-3703' ",
-"3'-183---3381-''",
-" '%*08'))780*%' ",
-"    '100001+    ",
-"    '2)*+3-%    ",
-"    ''%33'''    ",
-"     '    '     "};
diff --git a/include/xpm/mask_a.xpm b/include/xpm/mask_a.xpm
new file mode 100644 (file)
index 0000000..6949dd9
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_a_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"##............##",
+"##............##",
+"..##........##..",
+"..##........##..",
+"....##....##....",
+"....##....##....",
+"......####......",
+"......####......",
+"......####......",
+"......####......",
+"....##....##....",
+"....##....##....",
+"..##........##..",
+"..##........##..",
+"##............##",
+"##............##"};
diff --git a/include/xpm/mask_d.xpm b/include/xpm/mask_d.xpm
new file mode 100644 (file)
index 0000000..dc7f66d
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_d_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"........##......",
+"........##......",
+"......##..##....",
+"......##..##....",
+"....##......##..",
+"....##......##..",
+"......##..##....",
+"......##..##....",
+"........##......",
+"........##......",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_d_.xpm b/include/xpm/mask_d_.xpm
new file mode 100644 (file)
index 0000000..d3eee46
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_D_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"........##......",
+"........##......",
+"......######....",
+"......######....",
+"....##########..",
+"....##########..",
+"......######....",
+"......######....",
+"........##......",
+"........##......",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_e.xpm b/include/xpm/mask_e.xpm
new file mode 100644 (file)
index 0000000..2e6b528
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_e_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"################",
+"################",
+"................",
+"................",
+"################",
+"################",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_i.xpm b/include/xpm/mask_i.xpm
new file mode 100644 (file)
index 0000000..a24c1ca
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_i_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"..######..######",
+"..######..######",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_j.xpm b/include/xpm/mask_j.xpm
new file mode 100644 (file)
index 0000000..fcc072f
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_j_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"..##..##########",
+"..##..##########",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_l.xpm b/include/xpm/mask_l.xpm
new file mode 100644 (file)
index 0000000..a062db6
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_l_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"..........####..",
+"..........####..",
+"......####..##..",
+"......####..##..",
+"..####......##..",
+"..####......##..",
+"......####..##..",
+"......####..##..",
+"..........####..",
+"..........####..",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_m.xpm b/include/xpm/mask_m.xpm
new file mode 100644 (file)
index 0000000..e717d96
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_m_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"################",
+"################",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_o.xpm b/include/xpm/mask_o.xpm
new file mode 100644 (file)
index 0000000..3664bc4
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_o_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"......####......",
+"......####......",
+"....##....##....",
+"....##....##....",
+"....##....##....",
+"....##....##....",
+"......####......",
+"......####......",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_o_.xpm b/include/xpm/mask_o_.xpm
new file mode 100644 (file)
index 0000000..fbecff8
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_O_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"......####......",
+"......####......",
+"....########....",
+"....########....",
+"....########....",
+"....########....",
+"......####......",
+"......####......",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_p.xpm b/include/xpm/mask_p.xpm
new file mode 100644 (file)
index 0000000..d29f774
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_p_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"........##......",
+"........##......",
+"........##......",
+"........##......",
+"........##......",
+"........##......",
+"################",
+"################",
+"........##......",
+"........##......",
+"........##......",
+"........##......",
+"........##......",
+"........##......",
+"........##......",
+"........##......"};
diff --git a/include/xpm/mask_r.xpm b/include/xpm/mask_r.xpm
new file mode 100644 (file)
index 0000000..47f2aa5
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_r_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"..####..........",
+"..####..........",
+"..##..####......",
+"..##..####......",
+"..##......####..",
+"..##......####..",
+"..##..####......",
+"..##..####......",
+"..####..........",
+"..####..........",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_s.xpm b/include/xpm/mask_s.xpm
new file mode 100644 (file)
index 0000000..a5e1e82
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_s_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"....########....",
+"....########....",
+"....##....##....",
+"....##....##....",
+"....##....##....",
+"....##....##....",
+"....########....",
+"....########....",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_s_.xpm b/include/xpm/mask_s_.xpm
new file mode 100644 (file)
index 0000000..652db36
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_S_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"....########....",
+"....########....",
+"....########....",
+"....########....",
+"....########....",
+"....########....",
+"....########....",
+"....########....",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_t.xpm b/include/xpm/mask_t.xpm
new file mode 100644 (file)
index 0000000..d153fc8
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_t_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"..####..........",
+"..####..........",
+"##....##........",
+"##....##........",
+"........##....##",
+"........##....##",
+"..........####..",
+"..........####..",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/mask_u.xpm b/include/xpm/mask_u.xpm
new file mode 100644 (file)
index 0000000..61996fc
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *mask_u_xpm[]={
+"16 16 2 1",
+". c None",
+"# c #000000",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"......####......",
+"......####......",
+"....##....##....",
+"....##....##....",
+"..##........##..",
+"..##........##..",
+"................",
+"................",
+"................",
+"................"};
diff --git a/include/xpm/media-seek-backward.png b/include/xpm/media-seek-backward.png
deleted file mode 100644 (file)
index ffcac31..0000000
Binary files a/include/xpm/media-seek-backward.png and /dev/null differ
diff --git a/include/xpm/media-seek-backward.xpm b/include/xpm/media-seek-backward.xpm
deleted file mode 100644 (file)
index c211455..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/* XPM */
-static const char * media_seek_backward_xpm[] = {
-"16 16 69 1",
-"      c None",
-".     c #414140",
-"+     c #3D3F3B",
-"@     c #494A47",
-"#     c #3D3D3B",
-"$     c #4A4B48",
-"%     c #4E4F4C",
-"&     c #747571",
-"*     c #FCFCFC",
-"=     c #4E504C",
-"-     c #4C4C4A",
-";     c #696C68",
-">     c #F9F9F8",
-",     c #4D4E4B",
-"'     c #5B5E5A",
-")     c #6E6F6C",
-"!     c #EEEFEE",
-"~     c #FCFDFC",
-"{     c #FBFBFB",
-"]     c #595A57",
-"^     c #595A56",
-"/     c #646662",
-"(     c #EBEBEA",
-"_     c #575855",
-":     c #6A6B67",
-"<     c #767874",
-"[     c #EBECEA",
-"}     c #FAFAFA",
-"|     c #F2F4F1",
-"1     c #F1F1F0",
-"2     c #666763",
-"3     c #E6E7E6",
-"4     c #FAFAF9",
-"5     c #626460",
-"6     c #73756F",
-"7     c #80817C",
-"8     c #D4D6D3",
-"9     c #F1F2F0",
-"0     c #E7E9E4",
-"a     c #DFE2DD",
-"b     c #FCFCFB",
-"c     c #737470",
-"d     c #CFD1CE",
-"e     c #F2F3F0",
-"f     c #E8EAE6",
-"g     c #E0E2DD",
-"h     c #6D6E6A",
-"i     c #82837F",
-"j     c #ABAEA8",
-"k     c #F0F1EF",
-"l     c #F9FAF9",
-"m     c #FEFEFE",
-"n     c #797B75",
-"o     c #7F817C",
-"p     c #969791",
-"q     c #EEEFED",
-"r     c #767973",
-"s     c #838581",
-"t     c #91928C",
-"u     c #C9CBC6",
-"v     c #838580",
-"w     c #8D9089",
-"x     c #AFB0AC",
-"y     c #81837D",
-"z     c #90938C",
-"A     c #9C9E97",
-"B     c #9A9D97",
-"C     c #ADAFAA",
-"D     c #82837E",
-"                ",
-"                ",
-"                ",
-"        .     . ",
-"      +@@   #@$ ",
-"     %&*=  -;>, ",
-"   ')!~{]^/(~{_ ",
-" :<[}|1{234|1{5 ",
-" 67890abcdefgbh ",
-"   ijklmnopq4mr ",
-"    stulv  wxly ",
-"      zAB   CAo ",
-"        D     D ",
-"                ",
-"                ",
-"                "};
diff --git a/include/xpm/media-seek-forward.png b/include/xpm/media-seek-forward.png
deleted file mode 100644 (file)
index 4d7e2cd..0000000
Binary files a/include/xpm/media-seek-forward.png and /dev/null differ
diff --git a/include/xpm/media-seek-forward.xpm b/include/xpm/media-seek-forward.xpm
deleted file mode 100644 (file)
index e386c53..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/* XPM */
-static const char * media_seek_forward_xpm[] = {
-"16 16 69 1",
-"      c None",
-".     c #414140",
-"+     c #4A4B48",
-"@     c #494A47",
-"#     c #3D3D3B",
-"$     c #3D3F3B",
-"%     c #4D4E4B",
-"&     c #F9F9F8",
-"*     c #696C68",
-"=     c #4C4C4A",
-"-     c #4E504C",
-";     c #FCFCFC",
-">     c #747571",
-",     c #4E4F4C",
-"'     c #575855",
-")     c #FBFBFB",
-"!     c #FCFDFC",
-"~     c #EBEBEA",
-"{     c #646662",
-"]     c #595A56",
-"^     c #595A57",
-"/     c #EEEFEE",
-"(     c #6E6F6C",
-"_     c #5B5E5A",
-":     c #626460",
-"<     c #F1F1F0",
-"[     c #F2F4F1",
-"}     c #FAFAF9",
-"|     c #E6E7E6",
-"1     c #666763",
-"2     c #FAFAFA",
-"3     c #EBECEA",
-"4     c #767874",
-"5     c #6A6B67",
-"6     c #6D6E6A",
-"7     c #FCFCFB",
-"8     c #E0E2DD",
-"9     c #E8EAE6",
-"0     c #F2F3F0",
-"a     c #CFD1CE",
-"b     c #737470",
-"c     c #DFE2DD",
-"d     c #E7E9E4",
-"e     c #F1F2F0",
-"f     c #D4D6D3",
-"g     c #80817C",
-"h     c #73756F",
-"i     c #767973",
-"j     c #FEFEFE",
-"k     c #EEEFED",
-"l     c #969791",
-"m     c #7F817C",
-"n     c #797B75",
-"o     c #F9FAF9",
-"p     c #F0F1EF",
-"q     c #ABAEA8",
-"r     c #82837F",
-"s     c #81837D",
-"t     c #AFB0AC",
-"u     c #8D9089",
-"v     c #838580",
-"w     c #C9CBC6",
-"x     c #91928C",
-"y     c #838581",
-"z     c #9C9E97",
-"A     c #ADAFAA",
-"B     c #9A9D97",
-"C     c #90938C",
-"D     c #82837E",
-"                ",
-"                ",
-"                ",
-" .     .        ",
-" +@#   @@$      ",
-" %&*=  -;>,     ",
-" ')!~{]^)!/(_   ",
-" :)<[}|1)<[2345 ",
-" 67890ab7cdefgh ",
-" ij}klmnjopqr   ",
-" sotu  vowxy    ",
-" mzA   BzC      ",
-" D     D        ",
-"                ",
-"                ",
-"                "};
diff --git a/include/xpm/object-rotate-right-on.xpm b/include/xpm/object-rotate-right-on.xpm
deleted file mode 100644 (file)
index 978ad9e..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* XPM */
-static char * object_rotate_right_on_xpm[] = {
-"16 16 48 1",
-"      c None",
-".     c #7439AE",
-"+     c #6D36A3",
-"@     c #6C36A2",
-"#     c #6F37A6",
-"$     c #7339AC",
-"%     c #6E37A5",
-"&     c #F7F3FB",
-"*     c #F9F5FC",
-"=     c #F8F4FB",
-"-     c #EFE7F7",
-";     c #D4BEE9",
-">     c #8E55C6",
-",     c #7238AB",
-"'     c #DECDEE",
-")     c #DFCFEF",
-"!     c #E1D2F0",
-"~     c #EADFF4",
-"{     c #F5F0FA",
-"]     c #D3BCE9",
-"^     c #DAC7EC",
-"/     c #DCCAED",
-"(     c #E2D3F0",
-"_     c #EEE5F6",
-":     c #D8C4EB",
-"<     c #ECE2F5",
-"[     c #D5C0EA",
-"}     c #773BB2",
-"|     c #B28BD8",
-"1     c #F3ECF9",
-"2     c #F1EAF8",
-"3     c #945EC9",
-"4     c #7138A9",
-"5     c #BE9DDE",
-"6     c #D1BAE8",
-"7     c #7E3FBD",
-"8     c #CEB5E6",
-"9     c #CDB4E6",
-"0     c #CBB1E4",
-"a     c #C9AEE3",
-"b     c #C8ACE3",
-"c     c #FBF8FD",
-"d     c #C5A8E2",
-"e     c #C3A4E1",
-"f     c #C2A3E0",
-"g     c #E0D0EF",
-"h     c #C0A0DF",
-"i     c #F2EBF8",
-" .+@@#$$        ",
-" %&**=-;>,      ",
-" @='')!~{].     ",
-" @=^^^^^/-($    ",
-" %{&&{_'::<[.   ",
-" ,+@@}|1^;[23   ",
-"      45~66![.  ",
-"       7188;<,  ",
-"       @19081#  ",
-"     @@,1aba1$@@",
-"     @c1)ddd'1c@",
-"      @c!efe(c@ ",
-"       @cghgc@  ",
-"        @cic@   ",
-"         @*@    ",
-"          @     "};
diff --git a/include/xpm/object-rotate-right.png b/include/xpm/object-rotate-right.png
deleted file mode 100644 (file)
index 49e5727..0000000
Binary files a/include/xpm/object-rotate-right.png and /dev/null differ
diff --git a/include/xpm/object-rotate-right.xpm b/include/xpm/object-rotate-right.xpm
deleted file mode 100644 (file)
index c9b4357..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/* XPM */
-static const char * object_rotate_right_xpm[] = {
-"16 16 84 1",
-"      c None",
-".     c #D2650C",
-"+     c #CE5D02",
-"@     c #CE5C00",
-"#     c #CF5F03",
-"$     c #D1640B",
-"%     c #D1640C",
-"&     c #CF5D03",
-"*     c #FEF7EF",
-"=     c #FFF9F1",
-"-     c #FEF8F0",
-";     c #FCEFDF",
-">     c #F4D1AE",
-",     c #DB8138",
-"'     c #D1630A",
-")     c #FFF8EF",
-"!     c #FDDCAA",
-"~     c #FDDDAB",
-"{     c #FDE0B4",
-"]     c #FEE9CA",
-"^     c #FEF6E8",
-"/     c #F3CFAA",
-"(     c #D1650C",
-"_     c #FFF8ED",
-":     c #FDD8A2",
-"<     c #FDDAA7",
-"[     c #FEEED6",
-"}     c #F9E1C5",
-"|     c #D2640B",
-"1     c #CF5D02",
-"2     c #FEF6EA",
-"3     c #FFF7EC",
-"4     c #FFF5E7",
-"5     c #FEEDD4",
-"6     c #FDD599",
-"7     c #FEEBCE",
-"8     c #F6D1A8",
-"9     c #D2660D",
-"0     c #D2630A",
-"a     c #D1680F",
-"b     c #E8AA72",
-"c     c #FEF2E0",
-"d     c #FDD191",
-"e     c #FDD294",
-"f     c #FEF1DC",
-"g     c #DD8A40",
-"h     c #D06107",
-"i     c #EDB883",
-"j     c #FEE9CB",
-"k     c #FDCE89",
-"l     c #FEDFB3",
-"m     c #F6D1A9",
-"n     c #D2650B",
-"o     c #D5701B",
-"p     c #FFF3E3",
-"q     c #FDCA81",
-"r     c #FDEBD5",
-"s     c #D16206",
-"t     c #CE5C01",
-"u     c #FEF3E2",
-"v     c #FCC97D",
-"w     c #FCC778",
-"x     c #FCCA7F",
-"y     c #FEF3E3",
-"z     c #CF5E01",
-"A     c #D0620A",
-"B     c #FCC574",
-"C     c #FCC370",
-"D     c #FCC473",
-"E     c #FEF3E4",
-"F     c #D0640C",
-"G     c #FEFCF8",
-"H     c #FDDDAD",
-"I     c #FCC068",
-"J     c #FFFCF9",
-"K     c #FEDFB2",
-"L     c #FCBE61",
-"M     c #FCBD5F",
-"N     c #FEE0B3",
-"O     c #FEDDAD",
-"P     c #FCBA5A",
-"Q     c #FEDEAF",
-"R     c #FEF1DE",
-"S     c #FEFAF6",
-" .+@@#$%        ",
-" &*==-;>,'      ",
-" @)!!~{]^/(     ",
-" @_:::::<[}|    ",
-" 123345!66789   ",
-" 0+@@abc:defg   ",
-"      hijkklmn  ",
-"       opqqdrs  ",
-"       tuvwxyz  ",
-"     @@AcBCDEF@@",
-"     @GyHIII!yG@",
-"      @JKLMLNJ@ ",
-"       @JOPQJ@  ",
-"        @JRJ@   ",
-"         @S@    ",
-"          @     "};
diff --git a/include/xpm/other.xpm b/include/xpm/other.xpm
new file mode 100644 (file)
index 0000000..e2d7562
--- /dev/null
@@ -0,0 +1,117 @@
+/* XPM */
+static const char * other_xpm[] = {
+"16 16 98 2",
+"      c None",
+".     c #FFFFFF",
+"+     c #00CAFF",
+"@     c #00ADFF",
+"#     c #0000EB",
+"$     c #00007F",
+"%     c #0000B4",
+"&     c #0000B9",
+"*     c #00D1FF",
+"=     c #73FF8B",
+"-     c #68FF96",
+";     c #00BFFF",
+">     c #0000C3",
+",     c #0000C7",
+"'     c #01DDFD",
+")     c #0041FF",
+"!     c #0DFBF1",
+"~     c #3EFFC0",
+"{     c #00EEFF",
+"]     c #0024FF",
+"^     c #000082",
+"/     c #000083",
+"(     c #2EFFD0",
+"_     c #00E9FF",
+":     c #0001EA",
+"<     c #0074FF",
+"[     c #009CFF",
+"}     c #0058FF",
+"|     c #0000D5",
+"1     c #009FFF",
+"2     c #63FF9B",
+"3     c #0000C1",
+"4     c #00009D",
+"5     c #0000F7",
+"6     c #0042FF",
+"7     c #0030FF",
+"8     c #0000DC",
+"9     c #000080",
+"0     c #0017FE",
+"a     c #00E0FF",
+"b     c #0000F6",
+"c     c #0075FF",
+"d     c #0094FF",
+"e     c #0044FF",
+"f     c #0000BE",
+"g     c #000086",
+"h     c #000BFE",
+"i     c #004FFF",
+"j     c #0000AC",
+"k     c #006EFF",
+"l     c #10FEEE",
+"m     c #35FFC9",
+"n     c #0000C9",
+"o     c #0083FF",
+"p     c #0031FF",
+"q     c #000090",
+"r     c #0007F9",
+"s     c #0BF9F3",
+"t     c #7EFF80",
+"u     c #58FFA6",
+"v     c #007DFF",
+"w     c #000085",
+"x     c #1FFFDF",
+"y     c #000081",
+"z     c #0039FF",
+"A     c #00DBFF",
+"B     c #01BDFD",
+"C     c #0AFEF4",
+"D     c #0000AA",
+"E     c #00009A",
+"F     c #001BFC",
+"G     c #00C9FE",
+"H     c #4BFFB3",
+"I     c #0006F7",
+"J     c #008FFF",
+"K     c #6FFF8F",
+"L     c #F5FF09",
+"M     c #FFDB00",
+"N     c #F1FB0D",
+"O     c #0021FF",
+"P     c #0000EA",
+"Q     c #13FCEB",
+"R     c #F0FF0E",
+"S     c #FF8700",
+"T     c #FF5B00",
+"U     c #EDFC11",
+"V     c #12FDEC",
+"W     c #0003E9",
+"X     c #00B7FF",
+"Y     c #98FF66",
+"Z     c #FFDF00",
+"`     c #FFB300",
+" .    c #00B8FF",
+"..    c #0067FF",
+"+.    c #04E9FA",
+"@.    c #1DFCE1",
+"#.    c #00EDFF",
+"$.    c #000088",
+"            + @ # $ $ %         ",
+"      & * = - ; > $ $ , '       ",
+"  $ $ ) ! ~ { ] ^ $ $ / ( _     ",
+"  $ $ : < [ } | $ $ $ $ 1 2 3   ",
+"  $ $ 4 5 6 7 8 9 $ $ $ 0 a 7 $ ",
+"  $ $ / b c d e f $ $ g h i 8 $ ",
+"  $ $ j k l m * # $ $ n o p q $ ",
+"  $ $ r s t u v w $ $ j x 1 y $ ",
+"  $ $ z A B $ $ $ $ $ $ C ~ D $ ",
+"  $ $ $ $ E F [ G [ 0 E $ H I $ ",
+"  $ $ $ D J K L M N K J D $ O $ ",
+"    $ $ P Q R S T S U V W $ $ $ ",
+"      $ f X Y Z ` Z Y  .f $ $ $ ",
+"        $ > ..+.@.#...> $ $     ",
+"          $ $ y $.^ $           ",
+"            $ $ $               "};
index e6e79c1d4c7c126fe202afca72dbed55ccf7ba7c..acc1eeaa2459f2984754f06e44a92a330ea78be6 100644 (file)
@@ -7,17 +7,17 @@ static const char * plot_xpm[] = {
 "@     c #FF0000",
 "                ",
 " .              ",
-" ..           + ",
+"..            + ",
 " .          ++  ",
 " .         +    ",
-" ..       +     ",
+"..        +     ",
 " .       +      ",
 " .       +      ",
-" ..  @@@+       ",
+"..   @@@+       ",
 " .  @  +@     @ ",
 " .@@   + @   @  ",
-" ..   +   @@@   ",
+"..    +   @@@   ",
 " .  ++          ",
-" .++ .   .   .  ",
-" .............. ",
-"                "};
+" .++            ",
+"............... ",
+" .   .   .   .  "};
diff --git a/include/xpm/polygon.xpm b/include/xpm/polygon.xpm
new file mode 100644 (file)
index 0000000..ecbdb8f
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *polygon_xpm[]={
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"       ..       ",
+"      .  .      ",
+"    ..    ..    ",
+"   .        .   ",
+" ..          .. ",
+".              .",
+".              .",
+" .            . ",
+" .            . ",
+" .            . ",
+"  .          .  ",
+"  .          .  ",
+"  .          .  ",
+"   .        .   ",
+"   ..........   "};
diff --git a/include/xpm/preferences-system.png b/include/xpm/preferences-system.png
deleted file mode 100644 (file)
index 9460dfc..0000000
Binary files a/include/xpm/preferences-system.png and /dev/null differ
diff --git a/include/xpm/preferences-system.xpm b/include/xpm/preferences-system.xpm
deleted file mode 100644 (file)
index 1dc058b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* XPM */
-static const char * preferences_system_xpm[] = {
-"16 16 44 1",
-"      c None",
-".     c #888A85",
-"+     c #ECEBE9",
-"@     c #EFEFEE",
-"#     c #F0F0EE",
-"$     c #F0F0F0",
-"%     c #FAFAFA",
-"&     c #8A8C87",
-"*     c #F6F6F5",
-"=     c #ABACA9",
-"-     c #F7F7F7",
-";     c #E5E3E2",
-">     c #ADADAA",
-",     c #EEEEEC",
-"'     c #F3F3F3",
-")     c #F0F0EF",
-"!     c #EEEEED",
-"~     c #ECECEA",
-"{     c #BAB9B6",
-"]     c #D2D1D0",
-"^     c #A4A4A3",
-"/     c #B8B7B5",
-"(     c #B9B8B7",
-"_     c #204A87",
-":     c #7D8385",
-"<     c #CAC9C8",
-"[     c #BFBEBD",
-"}     c #ADBBCC",
-"|     c #7C93B3",
-"1     c #D4D3D3",
-"2     c #BDC8D4",
-"3     c #788DA4",
-"4     c #92A5BE",
-"5     c #E4E3E2",
-"6     c #C6C4C2",
-"7     c #748AA2",
-"8     c #7A95B4",
-"9     c #D4D3D2",
-"0     c #C4C3C2",
-"a     c #7D91A7",
-"b     c #7A95B5",
-"c     c #728BAE",
-"d     c #A0A19E",
-"e     c #869CB8",
-"                ",
-"    .        .  ",
-"   .+.      .@. ",
-"    .#.    .$.  ",
-" .  .%.    .&   ",
-".*=.-;>,  .     ",
-" .')!~{. .      ",
-"  ....]^..      ",
-"      /.(.      ",
-"   ___:><[.     ",
-"  _}}|_..1[.    ",
-" _2334_  .56..  ",
-"_}378|_   .90.  ",
-"_}abc_     .d.  ",
-"_4ee_      ...  ",
-" ___            "};
diff --git a/include/xpm/process-stop.png b/include/xpm/process-stop.png
deleted file mode 100644 (file)
index ab6808f..0000000
Binary files a/include/xpm/process-stop.png and /dev/null differ
diff --git a/include/xpm/process-stop.xpm b/include/xpm/process-stop.xpm
deleted file mode 100644 (file)
index a5a48e9..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* XPM */
-static const char * process_stop_xpm[] = {
-"16 16 133 2",
-"      c None",
-".     c #890000",
-"+     c #860000",
-"@     c #AF2222",
-"#     c #F68888",
-"$     c #F78B8B",
-"%     c #F68A8A",
-"&     c #F68787",
-"*     c #F58383",
-"=     c #B82323",
-"-     c #B12222",
-";     c #F38383",
-">     c #DC4242",
-",     c #D52F2F",
-"'     c #DB3C3C",
-")     c #F17575",
-"!     c #B41F1F",
-"~     c #B22424",
-"{     c #D53737",
-"]     c #DA3B3B",
-"^     c #F06F6F",
-"/     c #B11B1B",
-"(     c #B32626",
-"_     c #DB4141",
-":     c #D75757",
-"<     c #DACDCD",
-"[     c #D75F5F",
-"}     c #D85C5C",
-"|     c #E6D9D9",
-"1     c #DB5F5F",
-"2     c #D93B3B",
-"3     c #EF6A6A",
-"4     c #B01818",
-"5     c #880202",
-"6     c #F68989",
-"7     c #DB4040",
-"8     c #D89292",
-"9     c #DBDBDB",
-"0     c #DAD6D6",
-"a     c #D76060",
-"b     c #D85A5A",
-"c     c #E6E0E0",
-"d     c #EDEDED",
-"e     c #E5A5A5",
-"f     c #D22F2F",
-"g     c #D63B3B",
-"h     c #EE6868",
-"i     c #890303",
-"j     c #D53030",
-"k     c #D89999",
-"l     c #DFDFDF",
-"m     c #E2DEDE",
-"n     c #E6DFDF",
-"o     c #ECECEC",
-"p     c #E6ABAB",
-"q     c #D23131",
-"r     c #D02F2F",
-"s     c #CE2F2F",
-"t     c #ED6565",
-"u     c #890202",
-"v     c #DEACAC",
-"w     c #E8E8E8",
-"x     c #E8BCBC",
-"y     c #D13131",
-"z     c #CF2F2F",
-"A     c #CC2F2F",
-"B     c #EC6161",
-"C     c #D85B5B",
-"D     c #F1F1F1",
-"E     c #F3EDED",
-"F     c #DA6464",
-"G     c #C92929",
-"H     c #E94545",
-"I     c #F58585",
-"J     c #D75B5B",
-"K     c #E5DFDF",
-"L     c #E4AAAA",
-"M     c #E6A5A5",
-"N     c #F9F9F9",
-"O     c #FCF7F7",
-"P     c #DA6767",
-"Q     c #C51A1A",
-"R     c #BD0202",
-"S     c #E83737",
-"T     c #F26969",
-"U     c #D52323",
-"V     c #D21F1F",
-"W     c #DE9292",
-"X     c #CE2828",
-"Y     c #E9A5A5",
-"Z     c #FEFEFE",
-"`     c #E39696",
-" .    c #BD0000",
-"..    c #BD0303",
-"+.    c #E63434",
-"@.    c #B82424",
-"#.    c #EF5A5A",
-"$.    c #D31111",
-"%.    c #CB0101",
-"&.    c #D65858",
-"*.    c #C70303",
-"=.    c #C50000",
-"-.    c #C30000",
-";.    c #C10101",
-">.    c #D65F5F",
-",.    c #BE0404",
-"'.    c #DF2B2B",
-").    c #C71D1D",
-"!.    c #870000",
-"~.    c #B72121",
-"{.    c #ED5252",
-"].    c #D01010",
-"^.    c #C70000",
-"/.    c #C10000",
-"(.    c #BF0000",
-"_.    c #BE0505",
-":.    c #DF2C2C",
-"<.    c #C41B1B",
-"[.    c #880000",
-"}.    c #B41D1D",
-"|.    c #EB4C4C",
-"1.    c #CC0F0F",
-"2.    c #BF0505",
-"3.    c #DF2D2D",
-"4.    c #BF1919",
-"5.    c #B11A1A",
-"6.    c #EC4A4A",
-"7.    c #ED4747",
-"8.    c #EB4343",
-"9.    c #EA3F3F",
-"0.    c #E83B3B",
-"a.    c #E73737",
-"b.    c #BC1818",
-"        . + + + + + + .         ",
-"      . @ # $ $ % & * = .       ",
-"    . - ; > , , , , ' ) ! .     ",
-"  . ~ ; > { , , , , { ] ^ / .   ",
-". ( ; _ : < [ , , } | 1 2 3 4 . ",
-"5 6 7 , 8 9 0 a b c d e f g h 5 ",
-"i # , , j k l m n o p q r s t u ",
-"i # , , , j v w o x y z s A B u ",
-"i # , , , C n o D E F s A G H u ",
-"i I , , J K o L M N O P Q R S u ",
-"5 T U V W o L r X Y Z `  ...+.u ",
-". @.#.$.%.&.*.=.-.;.>.R ,.'.).!.",
-"  . ~.{.].^.=.-./.(. ._.:.<.[.  ",
-"    . }.|.1.-./.(. .2.3.4.[.    ",
-"      . 5.6.7.8.9.0.a.b.[.      ",
-"        . + + + + + + [.        "};
diff --git a/include/xpm/rotate_on.xpm b/include/xpm/rotate_on.xpm
deleted file mode 100644 (file)
index 45cfe6d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char *rotate_on_xpm[]={
-"16 16 3 1",
-". c None",
-"# c #800000",
-"a c #ff0000",
-"......#########.",
-"......#aaaaaa#..",
-".......#aaaa##..",
-"..###..#aaaaa#..",
-".#aa#..#aaa#aa#.",
-".#aa#...#a##aa#.",
-"#aa#....#a#.#aa#",
-"#aa#.....#..#aa#",
-"#aa#........#aa#",
-"#aa#........#aa#",
-".#a#........#a#.",
-".#aa#......#aa#.",
-"..#aa##..##aa#..",
-"...#aaa##aaa#...",
-"....##aaaa##....",
-"......####......"};
diff --git a/include/xpm/show_on.xpm b/include/xpm/show_on.xpm
deleted file mode 100644 (file)
index bce9067..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char * show_on_xpm[] = {
-"16 16 3 1",
-"      c None",
-".     c #000000",
-"+     c #FF3F00",
-"                ",
-"                ",
-"  ............  ",
-"  . .++++++. .  ",
-"  ...++++++...  ",
-"  . .++++++. .  ",
-"  . .++++++. .  ",
-"  ...++++++...  ",
-"  . .++++++. .  ",
-"  . .++++++. .  ",
-"  ...++++++...  ",
-"  . .++++++. .  ",
-"  . .++++++. .  ",
-"  ...++++++...  ",
-"  . .++++++. .  ",
-"  ............  "};
diff --git a/include/xpm/smth.xpm b/include/xpm/smth.xpm
deleted file mode 100644 (file)
index a2b9d46..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char * smth_xpm[] = {
-"16 16 3 1",
-"      c None",
-".     c #000000",
-"+     c #FF0000",
-"                ",
-"                ",
-"                ",
-"                ",
-"    .           ",
-"    .           ",
-"   . .    .     ",
-"   . .    ..    ",
-"  +++.   . .    ",
-" +.  ++  +++.   ",
-"  .   .++   ++  ",
-" .    . .    .+ ",
-" .    . .     . ",
-"       .        ",
-"       .        ",
-"                "};
diff --git a/include/xpm/stop.xpm b/include/xpm/stop.xpm
new file mode 100644 (file)
index 0000000..028f468
--- /dev/null
@@ -0,0 +1,23 @@
+/* XPM */
+static const char * stop_xpm[] = {
+"16 16 4 1",
+"      c None",
+".     c #770000",
+"+     c #FF0000",
+"@     c #FFFFFF",
+"                ",
+"     ......     ",
+"    .++++++.    ",
+"   .++++++++.   ",
+"  .++++++++++.  ",
+" .+++@@++@@+++. ",
+" .+++@@@@@@+++. ",
+" .++++@@@@++++. ",
+" .++++@@@@++++. ",
+" .+++@@@@@@+++. ",
+" .+++@@++@@+++. ",
+"  .++++++++++.  ",
+"   .++++++++.   ",
+"    .++++++.    ",
+"     ......     ",
+"                "};
diff --git a/include/xpm/sum.xpm b/include/xpm/sum.xpm
deleted file mode 100644 (file)
index fc017ac..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * sum_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"   ..........   ",
-"   .        .   ",
-"    .       .   ",
-"     .          ",
-"      .         ",
-"       .        ",
-"        ..      ",
-"       .        ",
-"      .         ",
-"     .          ",
-"    .       .   ",
-"   .        .   ",
-"   ..........   ",
-"                "};
diff --git a/include/xpm/swap.xpm b/include/xpm/swap.xpm
deleted file mode 100644 (file)
index 6ad367c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* XPM */
-static const char * swap_xpm[] = {
-"16 16 4 1",
-"      c None",
-".     c #0000FF",
-"+     c #000000",
-"@     c #FF0000",
-"                ",
-"  .          .. ",
-"   .        .   ",
-"    .      .    ",
-"    .      .    ",
-"     ......     ",
-"   +         +  ",
-"  +           + ",
-"  +           + ",
-"  + +       + + ",
-"   ++  @@@  ++  ",
-"  +++ @   @ +++ ",
-"     @     @    ",
-"     @     @    ",
-"  @@@       @@@ ",
-"                "};
diff --git a/include/xpm/system-file-manager.png b/include/xpm/system-file-manager.png
deleted file mode 100644 (file)
index 60cade4..0000000
Binary files a/include/xpm/system-file-manager.png and /dev/null differ
diff --git a/include/xpm/text-x-generic.png b/include/xpm/text-x-generic.png
deleted file mode 100644 (file)
index 2d7f2d6..0000000
Binary files a/include/xpm/text-x-generic.png and /dev/null differ
diff --git a/include/xpm/tiles.xpm b/include/xpm/tiles.xpm
new file mode 100644 (file)
index 0000000..505dadd
--- /dev/null
@@ -0,0 +1,132 @@
+/* XPM */
+static const char * tiles_xpm[] = {
+"16 16 113 2",
+"      c None",
+".     c #00D9FB",
+"+     c #00FEC7",
+"@     c #7DFF1E",
+"#     c #DBDF08",
+"$     c #EAC004",
+"%     c #E5D403",
+"&     c #FF5D00",
+"*     c #FC1600",
+"=     c #FC2500",
+"-     c #00EAE9",
+";     c #00E9CA",
+">     c #05F1B1",
+",     c #03F8B5",
+"'     c #00FFC7",
+")     c #00FFD6",
+"!     c #FF5900",
+"~     c #FD0600",
+"{     c #FA0000",
+"]     c #FF2600",
+"^     c #00A1FF",
+"/     c #00CEFF",
+"(     c #00FEE9",
+"_     c #00FF71",
+":     c #80FF12",
+"<     c #CFFF07",
+"[     c #FF7000",
+"}     c #FF5800",
+"|     c #FE7200",
+"1     c #F9B100",
+"2     c #00EDF2",
+"3     c #1AFF56",
+"4     c #C1FA00",
+"5     c #FDD600",
+"6     c #FFA700",
+"7     c #FF9200",
+"8     c #F3D400",
+"9     c #A0FD21",
+"0     c #21F996",
+"a     c #ECF100",
+"b     c #FFC900",
+"c     c #FF9B00",
+"d     c #FF9300",
+"e     c #FDA700",
+"f     c #AEFF05",
+"g     c #00F9C7",
+"h     c #00AAFF",
+"i     c #0052FF",
+"j     c #FDCA00",
+"k     c #E6DE00",
+"l     c #FCA900",
+"m     c #ADFF00",
+"n     c #00FCC3",
+"o     c #00C8FF",
+"p     c #0089FF",
+"q     c #0079FE",
+"r     c #0094FF",
+"s     c #00CDFF",
+"t     c #93E71F",
+"u     c #6BF55F",
+"v     c #57FA76",
+"w     c #3EFF80",
+"x     c #1BFF89",
+"y     c #00FF84",
+"z     c #00FF95",
+"A     c #F52C00",
+"B     c #F03200",
+"C     c #F23E00",
+"D     c #FB5B00",
+"E     c #F39E00",
+"F     c #D4EA00",
+"G     c #3BFF31",
+"H     c #00FCD9",
+"I     c #00C2FF",
+"J     c #FE5500",
+"K     c #E70200",
+"L     c #B30000",
+"M     c #9C0000",
+"N     c #A30000",
+"O     c #C30000",
+"P     c #F61400",
+"Q     c #FF9600",
+"R     c #99FD04",
+"S     c #01FDD5",
+"T     c #00A6FF",
+"U     c #0054FF",
+"V     c #0037FF",
+"W     c #EC0400",
+"X     c #BD0000",
+"Y     c #A20000",
+"Z     c #A00000",
+"`     c #B70000",
+" .    c #EA0100",
+"..    c #FF5600",
+"+.    c #EDE300",
+"@.    c #0CF5CC",
+"#.    c #06D2E4",
+"$.    c #09CEE0",
+"%.    c #18E5C1",
+"&.    c #4AFF6C",
+"*.    c #C1EB09",
+"=.    c #FF7200",
+"-.    c #FE4F00",
+";.    c #F73E00",
+">.    c #F03A00",
+",.    c #F03800",
+"'.    c #F63A00",
+").    c #E2BD00",
+"!.    c #D0C10A",
+"~.    c #CDC110",
+"{.    c #DFBB02",
+"].    c #F7B100",
+"^.    c #FF9C00",
+"                                ",
+"                                ",
+"            . + @ # $ %         ",
+"& * =           - ; > , ' )     ",
+"! ~ { ]             ^ / ( _ : < ",
+"[ } | 1               2 3 4 5 6 ",
+"7 8 9 0                 a b c d ",
+"e f g h i                   j k ",
+"l m n o p q r s                 ",
+"      t u v w x y z             ",
+"    A B C D E F G H I           ",
+"J K L M N O P Q R S T U V       ",
+"} W X Y Z `  ...+.  @.#.$.%.&.*.",
+"=.-.;.>.,.'.        ).!.~.{.].^.",
+"                                ",
+"                                "};
diff --git a/include/xpm/udav.png b/include/xpm/udav.png
deleted file mode 100644 (file)
index 76ba7d9..0000000
Binary files a/include/xpm/udav.png and /dev/null differ
diff --git a/include/xpm/unused/smth.xpm b/include/xpm/unused/smth.xpm
new file mode 100644 (file)
index 0000000..a2b9d46
--- /dev/null
@@ -0,0 +1,22 @@
+/* XPM */
+static const char * smth_xpm[] = {
+"16 16 3 1",
+"      c None",
+".     c #000000",
+"+     c #FF0000",
+"                ",
+"                ",
+"                ",
+"                ",
+"    .           ",
+"    .           ",
+"   . .    .     ",
+"   . .    ..    ",
+"  +++.   . .    ",
+" +.  ++  +++.   ",
+"  .   .++   ++  ",
+" .    . .    .+ ",
+" .    . .     . ",
+"       .        ",
+"       .        ",
+"                "};
diff --git a/include/xpm/unused/sum.xpm b/include/xpm/unused/sum.xpm
new file mode 100644 (file)
index 0000000..fc017ac
--- /dev/null
@@ -0,0 +1,21 @@
+/* XPM */
+static const char * sum_xpm[] = {
+"16 16 2 1",
+"      c None",
+".     c #000000",
+"                ",
+"                ",
+"   ..........   ",
+"   .        .   ",
+"    .       .   ",
+"     .          ",
+"      .         ",
+"       .        ",
+"        ..      ",
+"       .        ",
+"      .         ",
+"     .          ",
+"    .       .   ",
+"   .        .   ",
+"   ..........   ",
+"                "};
diff --git a/include/xpm/unused/swap.xpm b/include/xpm/unused/swap.xpm
new file mode 100644 (file)
index 0000000..6ad367c
--- /dev/null
@@ -0,0 +1,23 @@
+/* XPM */
+static const char * swap_xpm[] = {
+"16 16 4 1",
+"      c None",
+".     c #0000FF",
+"+     c #000000",
+"@     c #FF0000",
+"                ",
+"  .          .. ",
+"   .        .   ",
+"    .      .    ",
+"    .      .    ",
+"     ......     ",
+"   +         +  ",
+"  +           + ",
+"  +           + ",
+"  + +       + + ",
+"   ++  @@@  ++  ",
+"  +++ @   @ +++ ",
+"     @     @    ",
+"     @     @    ",
+"  @@@       @@@ ",
+"                "};
diff --git a/include/xpm/vect.xpm b/include/xpm/vect.xpm
new file mode 100644 (file)
index 0000000..7d91322
--- /dev/null
@@ -0,0 +1,60 @@
+/* XPM */
+static const char * vect_xpm[] = {
+"16 16 41 1",
+"      c None",
+".     c #B3FF00",
+"+     c #AEF900",
+"@     c #FBF400",
+"#     c #FEF700",
+"$     c #FFDA00",
+"%     c #AFFB00",
+"&     c #FDF600",
+"*     c #FDF500",
+"=     c #FD9600",
+"-     c #FD9000",
+";     c #FA8F00",
+">     c #FEAB00",
+",     c #FD9500",
+"'     c #FB9400",
+")     c #FE9100",
+"!     c #FBAA00",
+"~     c #FCA900",
+"{     c #FF9700",
+"]     c #FF9200",
+"^     c #FDA900",
+"/     c #FDAB00",
+"(     c #FB9D00",
+"_     c #FC0B00",
+":     c #FF0A00",
+"<     c #FF4400",
+"[     c #FB4200",
+"}     c #FC9E00",
+"|     c #FE9F00",
+"1     c #FD4400",
+"2     c #FC4400",
+"3     c #FFA000",
+"4     c #FB1600",
+"5     c #FCAD00",
+"6     c #D00000",
+"7     c #D20000",
+"8     c #FD1500",
+"9     c #FA1500",
+"0     c #FEAF00",
+"a     c #D10000",
+"b     c #FDAE00",
+" .+    @#     $ ",
+" %     &@     $ ",
+".      &        ",
+"      *         ",
+"  =     -;     >",
+" ,'     )     !~",
+"{      ]      ^ ",
+"      ]      /  ",
+"               (",
+" _:     <[    }|",
+" _     12     3 ",
+"      <      |  ",
+"                ",
+"         4     5",
+" 67     89    50",
+"a     8      b  "};
diff --git a/include/xpm/view-refresh.png b/include/xpm/view-refresh.png
deleted file mode 100644 (file)
index 3fd71d6..0000000
Binary files a/include/xpm/view-refresh.png and /dev/null differ
diff --git a/include/xpm/view-refresh.xpm b/include/xpm/view-refresh.xpm
deleted file mode 100644 (file)
index 32d59ea..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/* XPM */
-static const char * view_refresh_xpm[] = {
-"16 16 94 2",
-"      c None",
-".     c #3A69A7",
-"+     c #3A6AA7",
-"@     c #3667A5",
-"#     c #3969A7",
-"$     c #3868A6",
-"%     c #6890C0",
-"&     c #8FB0D3",
-"*     c #A8C2DF",
-"=     c #A8C1DE",
-"-     c #93B1D4",
-";     c #5F87B9",
-">     c #3767A5",
-",     c #3465A4",
-"'     c #3969A6",
-")     c #8CADD3",
-"!     c #9DBDDC",
-"~     c #A1BEDD",
-"{     c #B4CBE5",
-"]     c #BFD3E9",
-"^     c #CCDDEE",
-"/     c #D5E2F0",
-"(     c #BFD2E7",
-"_     c #4B77AF",
-":     c #4371AB",
-"<     c #3566A4",
-"[     c #6990C0",
-"}     c #7298C5",
-"|     c #3C6BA8",
-"1     c #5D85B7",
-"2     c #A1BBD9",
-"3     c #D8E4F1",
-"4     c #DBE6F2",
-"5     c #DDE8F3",
-"6     c #88A7CE",
-"7     c #C8D8EA",
-"8     c #4170AB",
-"9     c #3C6CA9",
-"0     c #3869A6",
-"a     c #6188B9",
-"b     c #CDDBEB",
-"c     c #E2EBF5",
-"d     c #E6EEF6",
-"e     c #3565A4",
-"f     c #6891C7",
-"g     c #C7D7E9",
-"h     c #C6D8EB",
-"i     c #E3ECF5",
-"j     c #3A6AA6",
-"k     c #8FACD0",
-"l     c #E7EEF6",
-"m     c #4774AD",
-"n     c #4C77AF",
-"o     c #4C78AF",
-"p     c #E5EDF5",
-"q     c #E5EDF6",
-"r     c #E4ECF5",
-"s     c #9CB7D7",
-"t     c #3768A6",
-"u     c #C4D7EB",
-"v     c #C9D9EA",
-"w     c #3566A5",
-"x     c #6C95C9",
-"y     c #537FB7",
-"z     c #E4EDF5",
-"A     c #C1D2E6",
-"B     c #4D79B0",
-"C     c #3C6BA9",
-"D     c #4F7CB6",
-"E     c #3768A5",
-"F     c #95B2D4",
-"G     c #E0E9F4",
-"H     c #CCDCED",
-"I     c #8FADD2",
-"J     c #4C78B0",
-"K     c #3D6DA9",
-"L     c #5B84B7",
-"M     c #4E7AB1",
-"N     c #B4CAE3",
-"O     c #C9DAEC",
-"P     c #BCD1E7",
-"Q     c #B0C9E3",
-"R     c #A0BEDE",
-"S     c #88ABD2",
-"T     c #82A5CE",
-"U     c #8EAED3",
-"V     c #3767A6",
-"W     c #5580B5",
-"X     c #84A6CE",
-"Y     c #97B6D8",
-"Z     c #99B9DB",
-"`     c #8AACD3",
-" .    c #6D94C2",
-"..    c #3B6BA7",
-"        . + @ # +               ",
-"      $ % & * = - ; >       ,   ",
-"    ' ) ! ~ { ] ^ / ( _ @ : <   ",
-"  # [ } | < + 1 2 3 4 5 6 7 +   ",
-"  $ 8 9 +       0 a b c d d +   ",
-"  e + f >           < g h i j   ",
-"  ,               $ k l 4 d j   ",
-"                , , m n n o ,   ",
-"  , , , , , , ,                 ",
-"  , p q r s t               ,   ",
-"  < d u v ,           w x y ,   ",
-"  > d i z A B 0       C D + E   ",
-"  $ 3 F G 5 H I J w ' ' K J +   ",
-"  > L @ M N O P Q R S T U $     ",
-"  , @     V W X Y Z `  .$       ",
-"  ,           + 0 < + ..        "};
diff --git a/include/xpm/weather-clear.png b/include/xpm/weather-clear.png
deleted file mode 100644 (file)
index 7dc15ea..0000000
Binary files a/include/xpm/weather-clear.png and /dev/null differ
diff --git a/include/xpm/weather-clear.xpm b/include/xpm/weather-clear.xpm
deleted file mode 100644 (file)
index 2b21ab2..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/* XPM */
-static const char * weather_clear_xpm[] = {
-"16 16 76 1",
-"      c None",
-".     c #FCB03E",
-"+     c #FCB13E",
-"@     c #FCAF3E",
-"#     c #FCB23F",
-"$     c #FDCD83",
-"%     c #FCCC82",
-"&     c #FCC470",
-"*     c #FCB953",
-"=     c #FCB23E",
-"-     c #FCC66D",
-";     c #FDE6BF",
-">     c #FEF9E7",
-",     c #FEFCF0",
-"'     c #FEF9DF",
-")     c #FDEAAD",
-"!     c #FBBA57",
-"~     c #FCB33F",
-"{     c #FDE6C1",
-"]     c #FEFEFB",
-"^     c #FEFCEF",
-"/     c #FEF8CE",
-"(     c #FDF4B0",
-"_     c #FCF4AD",
-":     c #FDF0A2",
-"<     c #FAB545",
-"[     c #FEF8E7",
-"}     c #FEFDF0",
-"|     c #FEF9CF",
-"1     c #FDF4AC",
-"2     c #FDF089",
-"3     c #FCEF87",
-"4     c #FCD964",
-"5     c #FCB33E",
-"6     c #FCCD84",
-"7     c #FEFCF1",
-"8     c #FEF8D0",
-"9     c #FEF9D0",
-"0     c #FDF6BE",
-"a     c #FDF3A1",
-"b     c #FCEF81",
-"c     c #FCEC68",
-"d     c #FCE768",
-"e     c #FBB13E",
-"f     c #FCC570",
-"g     c #FEFAE3",
-"h     c #FDF5B1",
-"i     c #FDF4AE",
-"j     c #FDF3A2",
-"k     c #FDF08C",
-"l     c #FCED71",
-"m     c #FCE959",
-"n     c #FCE459",
-"o     c #FBB13F",
-"p     c #FCBC57",
-"q     c #FDECB4",
-"r     c #FCF4AB",
-"s     c #FDF08B",
-"t     c #FCEF82",
-"u     c #FCEA5A",
-"v     c #FCEA57",
-"w     c #FBD349",
-"x     c #FBBD5B",
-"y     c #FDF1AA",
-"z     c #FCEF84",
-"A     c #FCEB65",
-"B     c #FCE956",
-"C     c #FCE34E",
-"D     c #FAB43F",
-"E     c #FCB43F",
-"F     c #FBB94A",
-"G     c #FBDB6C",
-"H     c #FCE86E",
-"I     c #FCE55D",
-"J     c #FCD549",
-"K     c #FBB43F",
-"                ",
-"       .+       ",
-"       ++       ",
-"   @# $%&* =@   ",
-"   =-;>,')!~#   ",
-"    {]^/(_:<    ",
-"   $[}}|12345   ",
-" ++67890abcde+. ",
-" .+fghijklmno++ ",
-"   pqrstluvw#   ",
-"    xyzABvCD    ",
-"   #EFGHIJK5=   ",
-"   @= #oe5 #@   ",
-"       ++       ",
-"       +.       ",
-"                "};
diff --git a/include/xpm/x-office-presentation.png b/include/xpm/x-office-presentation.png
deleted file mode 100644 (file)
index f7ea302..0000000
Binary files a/include/xpm/x-office-presentation.png and /dev/null differ
diff --git a/include/xpm/x-office-spreadsheet.png b/include/xpm/x-office-spreadsheet.png
deleted file mode 100644 (file)
index a6b1268..0000000
Binary files a/include/xpm/x-office-spreadsheet.png and /dev/null differ
diff --git a/include/xpm/x-office-spreadsheet.xpm b/include/xpm/x-office-spreadsheet.xpm
deleted file mode 100644 (file)
index 8707737..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/* XPM */
-static const char * x_office_spreadsheet_xpm[] = {
-"16 16 124 2",
-"      c None",
-".     c #999999",
-"+     c #818181",
-"@     c #FFFFFF",
-"#     c #B7B7B7",
-"$     c #B7B7B8",
-"%     c #9E9E9F",
-"&     c #B8B8B8",
-"*     c #9F9F9F",
-"=     c #B8B8B9",
-"-     c #9E9E9E",
-";     c #9F9F9E",
-">     c #B7B8B7",
-",     c #C3C3C3",
-"'     c #EEEEEE",
-")     c #C2C2C2",
-"!     c #EEEFEE",
-"~     c #EFEEEF",
-"{     c #B1B1B1",
-"]     c #B9B8B9",
-"^     c #E0E0E0",
-"/     c #E0E1E0",
-"(     c #E1E0E0",
-"_     c #E1E1E1",
-":     c #B9B8B8",
-"<     c #C4C4C4",
-"[     c #C3C4C4",
-"}     c #EEEEEF",
-"|     c #EFEFEF",
-"1     c #F0EFEF",
-"2     c #B9B9B8",
-"3     c #B9B9B9",
-"4     c #C9A6A5",
-"5     c #AE3A36",
-"6     c #A50F0C",
-"7     c #A40201",
-"8     c #A40D0A",
-"9     c #B03B37",
-"0     c #8D6969",
-"a     c #9E403D",
-"b     c #A70A07",
-"c     c #C66453",
-"d     c #CB715C",
-"e     c #C9735D",
-"f     c #C5715B",
-"g     c #BF6C59",
-"h     c #C06E61",
-"i     c #AC201D",
-"j     c #A73634",
-"k     c #B2B2B2",
-"l     c #A65C5B",
-"m     c #AF2017",
-"n     c #CB725D",
-"o     c #C7654D",
-"p     c #BB5338",
-"q     c #B65136",
-"r     c #B04E35",
-"s     c #B35D47",
-"t     c #AE5B45",
-"u     c #A95743",
-"v     c #AA2F28",
-"w     c #9F2523",
-"x     c #A51412",
-"y     c #CA6F5A",
-"z     c #BF5439",
-"A     c #BA5237",
-"B     c #B44F36",
-"C     c #AF4D34",
-"D     c #886556",
-"E     c #765F5A",
-"F     c #715B56",
-"G     c #6B5853",
-"H     c #77605B",
-"I     c #9D0D0C",
-"J     c #C76951",
-"K     c #B85137",
-"L     c #B24E36",
-"M     c #AD4C34",
-"N     c #AE653A",
-"O     c #95995D",
-"P     c #1D84A0",
-"Q     c #177F99",
-"R     c #3D91A5",
-"S     c #3B8EA0",
-"T     c #A20101",
-"U     c #9F1212",
-"V     c #CA7E6D",
-"W     c #B85F48",
-"X     c #AB4C33",
-"Y     c #A64932",
-"Z     c #B18B44",
-"`     c #B8BC50",
-" .    c #358086",
-"..    c #509CAD",
-"+.    c #278397",
-"@.    c #496E77",
-"#.    c #970909",
-"$.    c #BC7878",
-"%.    c #9C1D1A",
-"&.    c #BD7E6D",
-"*.    c #BE7F70",
-"=.    c #BD8374",
-"-.    c #CDC787",
-";.    c #CBD089",
-">.    c #B4B48A",
-",.    c #5C93A0",
-"'.    c #44656D",
-").    c #7B1618",
-"!.    c #A12F2F",
-"~.    c #959595",
-"{.    c #934040",
-"].    c #9E0605",
-"^.    c #99463D",
-"/.    c #9E624D",
-"(.    c #A6A14C",
-"_.    c #9F9B4A",
-":.    c #948845",
-"<.    c #4B3C43",
-"[.    c #9A0505",
-"}.    c #A32B2B",
-"|.    c #991C1C",
-"1.    c #A00C0C",
-"2.    c #A30201",
-"3.    c #A42525",
-". + + + + + + + + + + + +       ",
-"+ @ @ @ @ @ @ @ @ @ @ @ @ +     ",
-"+ @ # # $ % & & * = = * @ +     ",
-"+ @ - ; * * * * * * * * @ +     ",
-"+ @ > , , * ' ' ) ! ~ ) @ +     ",
-"+ @ { & ] * ^ / ) ( _ ) @ +     ",
-"+ @ : < [ * } ~ ) | 1 ) @ +     ",
-"+ @ { 2 3 * 4 5 6 7 7 8 9 0     ",
-"+ @ 3 < < a b c d e f g h i j   ",
-"+ @ k 3 l m n o p q r s t u v w ",
-"+ @ 3 < x y z A B C D E F G H I ",
-"+ @ k 3 7 J K L M N O P Q R S T ",
-"+ @ 3 < U V W X Y Z `  ...+.@.#.",
-"+ @ @ @ $.%.&.*.=.-.;.>.,.'.).!.",
-"~.+ + + + {.].^./.(._.:.<.[.}.  ",
-"              |.1.2.T 1.3.      "};
diff --git a/include/xpm/zoom-fit-best-r.xpm b/include/xpm/zoom-fit-best-r.xpm
deleted file mode 100644 (file)
index a77f7e1..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/* XPM */
-static const char * zoom_fit_best_r_xpm[] = {
-"16 16 69 1",
-"      c None",
-".     c #C34C4C",
-"+     c #C34E4E",
-"@     c #D98C8C",
-"#     c #E9BCBC",
-"$     c #F2D8D8",
-"%     c #C95C5C",
-"&     c #EAC1C1",
-"*     c #ECC7C7",
-"=     c #DC9595",
-"-     c #EBC3C3",
-";     c #CF7070",
-">     c #B33C3C",
-",     c #BD3F3F",
-"'     c #D27878",
-")     c #D07373",
-"!     c #BA3E3E",
-"~     c #FEFDFD",
-"{     c #D37E7E",
-"]     c #BE3F3F",
-"^     c #B13B3B",
-"/     c #C44F4F",
-"(     c #DA9090",
-"_     c #D27979",
-":     c #B83D3D",
-"<     c #D58282",
-"[     c #D07171",
-"}     c #E1A6A6",
-"|     c #DFA0A0",
-"1     c #CD6868",
-"2     c #CB6464",
-"3     c #D37C7C",
-"4     c #C75757",
-"5     c #C95E5E",
-"6     c #C85B5B",
-"7     c #AC3939",
-"8     c #DD9A9A",
-"9     c #C75858",
-"0     c #AE3939",
-"a     c #DE9D9D",
-"b     c #DB9393",
-"c     c #EECDCD",
-"d     c #CB6262",
-"e     c #B23B3B",
-"f     c #EFCFCF",
-"g     c #EDC8C8",
-"h     c #D47F7F",
-"i     c #B73D3D",
-"j     c #CD6A6A",
-"k     c #CE6C6C",
-"l     c #CA6060",
-"m     c #EECCCC",
-"n     c #F1D4D4",
-"o     c #E6B5B5",
-"p     c #E9BEBE",
-"q     c #F0D3D3",
-"r     c #CE6D6D",
-"s     c #903030",
-"t     c #DF9F9F",
-"u     c #F3DEDE",
-"v     c #C34B4B",
-"w     c #DC9797",
-"x     c #DE9C9C",
-"y     c #C65555",
-"z     c #822B2B",
-"A     c #DA9191",
-"B     c #852C2C",
-"C     c #7F2A2A",
-"D     c #812B2B",
-"    .+..+.      ",
-"   .@#$$#@.     ",
-"  %&*=@@=-&%    ",
-" .&;>,')!>;&.   ",
-".@->~~{]~~^-@.  ",
-"/#(,~]_):~>(#+  ",
-".$<[,[}|12%_$.  ",
-".$3452=@67+3$.  ",
-"/&87~7990~7a&/  ",
-".bc^~~>d~~efb.  ",
-" /ghi:jk::hg.   ",
-"  lmn#oopqclrs  ",
-"   /tcuuc|/vwxs ",
-"    /y//4/ z>vAB",
-"            C^;B",
-"             CD "};
diff --git a/include/xpm/zoom-fit-best.png b/include/xpm/zoom-fit-best.png
deleted file mode 100644 (file)
index eb28409..0000000
Binary files a/include/xpm/zoom-fit-best.png and /dev/null differ
diff --git a/include/xpm/zoom-fit-best.xpm b/include/xpm/zoom-fit-best.xpm
deleted file mode 100644 (file)
index c093447..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* XPM */
-static const char * zoom_fit_best_xpm[] = {
-"16 16 114 2",
-"      c None",
-".     c #878B87",
-"+     c #868C8A",
-"@     c #888B89",
-"#     c #ACB6BF",
-"$     c #CDD6DD",
-"%     c #E4E7E9",
-"&     c #929594",
-"*     c #CFD8E0",
-"=     c #D3DDE5",
-"-     c #A4BFDC",
-";     c #99B9DA",
-">     c #9AB9DA",
-",     c #A4BFDD",
-"'     c #CFDAE5",
-")     c #87A6CA",
-"!     c #547FB5",
-"~     c #5B84B8",
-"{     c #8AAAD0",
-"]     c #88A9CF",
-"^     c #5983B7",
-"/     c #537EB5",
-"(     c #527EB5",
-"_     c #FFFFFF",
-":     c #90AED2",
-"<     c #5C85B8",
-"[     c #507DB4",
-"}     c #868C8B",
-"|     c #9DBBDA",
-"1     c #5E86B8",
-"2     c #8CABD1",
-"3     c #87A8CF",
-"4     c #5982B7",
-"5     c #9EBBDA",
-"6     c #878B88",
-"7     c #8EB2D6",
-"8     c #85A7CE",
-"9     c #5A84B7",
-"0     c #86A7CE",
-"a     c #AFC8E4",
-"b     c #AAC5E2",
-"c     c #7DA1CC",
-"d     c #799FCA",
-"e     c #7199C8",
-"f     c #86ACD4",
-"g     c #89AED4",
-"h     c #6C96C6",
-"i     c #739AC8",
-"j     c #799ECA",
-"k     c #A0BEDF",
-"l     c #9AB9DC",
-"m     c #7198C7",
-"n     c #4D7AB2",
-"o     c #638FC2",
-"p     c #878C8B",
-"q     c #CFD8DE",
-"r     c #A7C1DD",
-"s     c #4D7BB3",
-"t     c #4E7BB3",
-"u     c #6E97C6",
-"v     c #4F7CB3",
-"w     c #A9C3DE",
-"x     c #D0D8DE",
-"y     c #888B87",
-"z     c #B1BAC1",
-"A     c #D9E1E8",
-"B     c #517DB4",
-"C     c #779DC9",
-"D     c #527EB4",
-"E     c #DAE2E8",
-"F     c #B2BBC1",
-"G     c #8A8C8A",
-"H     c #D7DDE2",
-"I     c #96B0CF",
-"J     c #5680B5",
-"K     c #5681B6",
-"L     c #7FA2CC",
-"M     c #80A3CC",
-"N     c #5781B6",
-"O     c #D8DEE3",
-"P     c #949895",
-"Q     c #DADFE3",
-"R     c #E1E6EA",
-"S     c #C7D7E8",
-"T     c #BDD2E6",
-"U     c #BED2E6",
-"V     c #C8D8E8",
-"W     c #DFE5EA",
-"X     c #DBE0E4",
-"Y     c #959896",
-"Z     c #9DA09B",
-"`     c #60625F",
-" .    c #8A8D8A",
-"..    c #BCC1C4",
-"+.    c #DCE0E2",
-"@.    c #E9EBEB",
-"#.    c #BDC2C5",
-"$.    c #898C88",
-"%.    c #878A84",
-"&.    c #B9BCB6",
-"*.    c #BDBFBC",
-"=.    c #61635F",
-"-.    c #8A8C88",
-";.    c #8D918D",
-">.    c #8B8D89",
-",.    c #8E918D",
-"'.    c #575955",
-").    c #7A7B78",
-"!.    c #B7B8B6",
-"~.    c #595B57",
-"{.    c #555753",
-"].    c #767873",
-"^.    c #A0A29F",
-"/.    c #565854",
-"        . + . . + .             ",
-"      @ # $ % % $ # @           ",
-"    & * = - ; > , ' * &         ",
-"  @ * ) ! ~ { ] ^ / ) * @       ",
-". # ' ( _ _ : < _ _ [ ' # .     ",
-"} $ | ~ _ 1 2 3 4 _ ! 5 $ +     ",
-"6 % 7 8 9 0 a b c d e f % .     ",
-"6 % g h i j k l m n o g % .     ",
-"p q r s _ t u u v _ t w x p     ",
-"y z A B _ _ / C _ _ D E F y     ",
-"  G H I J K L M N K I O .       ",
-"    P Q R S T U V W X Y Z `     ",
-"       ...+.@.@.+.#.$.%.&.*.=.  ",
-"        -.;.>.>.,.-.  '.).%.!.~.",
-"                        {.].^.~.",
-"                          {./.  "};
diff --git a/include/xpm/zoom-in.png b/include/xpm/zoom-in.png
deleted file mode 100644 (file)
index 31ac736..0000000
Binary files a/include/xpm/zoom-in.png and /dev/null differ
diff --git a/include/xpm/zoom-in.xpm b/include/xpm/zoom-in.xpm
deleted file mode 100644 (file)
index 22e285b..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* XPM */
-static const char * zoom_in_xpm[] = {
-"16 16 105 2",
-"      c None",
-".     c #878B87",
-"+     c #868C8A",
-"@     c #888B89",
-"#     c #ACB6BF",
-"$     c #CDD6DD",
-"%     c #E4E7E9",
-"&     c #929594",
-"*     c #CFD8E0",
-"=     c #D3DDE5",
-"-     c #A4BFDC",
-";     c #99B9DA",
-">     c #9AB9DA",
-",     c #A4BFDD",
-"'     c #CFDAE5",
-")     c #B4C9DF",
-"!     c #9DBDDD",
-"~     c #B5CDE6",
-"{     c #5C84B8",
-"]     c #5B84B8",
-"^     c #B0CAE4",
-"/     c #9ABADD",
-"(     c #98B9DC",
-"_     c #BCD1E8",
-":     c #5F87B9",
-"<     c #FFFFFF",
-"[     c #5A84B7",
-"}     c #ABC6E2",
-"|     c #91B4DA",
-"1     c #868C8B",
-"2     c #9DBBDA",
-"3     c #B6CDE6",
-"4     c #5D85B8",
-"5     c #5E86B8",
-"6     c #5982B7",
-"7     c #5781B6",
-"8     c #9FBDDE",
-"9     c #9EBBDA",
-"0     c #878B88",
-"a     c #8EB2D6",
-"b     c #5983B7",
-"c     c #507DB4",
-"d     c #86ACD4",
-"e     c #89AED4",
-"f     c #4E7BB3",
-"g     c #4A78B2",
-"h     c #878C8B",
-"i     c #CFD8DE",
-"j     c #A7C1DD",
-"k     c #86ADD6",
-"l     c #4F7CB3",
-"m     c #89AED6",
-"n     c #A9C3DE",
-"o     c #D0D8DE",
-"p     c #888B87",
-"q     c #B1BAC1",
-"r     c #D9E1E8",
-"s     c #94B6DA",
-"t     c #96B7DB",
-"u     c #527EB5",
-"v     c #537EB5",
-"w     c #97B8DB",
-"x     c #DAE2E8",
-"y     c #B2BBC1",
-"z     c #8A8C8A",
-"A     c #D7DDE2",
-"B     c #CAD8E6",
-"C     c #A4C0DF",
-"D     c #A6C2E0",
-"E     c #A7C3E1",
-"F     c #D8DEE3",
-"G     c #949895",
-"H     c #DADFE3",
-"I     c #E1E6EA",
-"J     c #C7D7E8",
-"K     c #BDD2E6",
-"L     c #BED2E6",
-"M     c #C8D8E8",
-"N     c #DFE5EA",
-"O     c #DBE0E4",
-"P     c #959896",
-"Q     c #9DA09B",
-"R     c #60625F",
-"S     c #8A8D8A",
-"T     c #BCC1C4",
-"U     c #DCE0E2",
-"V     c #E9EBEB",
-"W     c #BDC2C5",
-"X     c #898C88",
-"Y     c #878A84",
-"Z     c #B9BCB6",
-"`     c #BDBFBC",
-" .    c #61635F",
-"..    c #8A8C88",
-"+.    c #8D918D",
-"@.    c #8B8D89",
-"#.    c #8E918D",
-"$.    c #575955",
-"%.    c #7A7B78",
-"&.    c #B7B8B6",
-"*.    c #595B57",
-"=.    c #555753",
-"-.    c #767873",
-";.    c #A0A29F",
-">.    c #565854",
-"        . + . . + .             ",
-"      @ # $ % % $ # @           ",
-"    & * = - ; > , ' * &         ",
-"  @ * ) ! ~ { ] ^ / ) * @       ",
-". # ' ( _ : < < [ } | ' # .     ",
-"1 $ 2 3 4 5 < < 6 7 8 9 $ +     ",
-"0 % a b < < < < < < c d % .     ",
-"0 % e f < < < < < < g e % .     ",
-"h i j k f f < < l f m n o h     ",
-"p q r s t u < < v ( w x y p     ",
-"  z A B C D 7 7 E D B F .       ",
-"    G H I J K L M N O P Q R     ",
-"      S T U V V U W X Y Z `  .  ",
-"        ..+.@.@.#...  $.%.Y &.*.",
-"                        =.-.;.*.",
-"                          =.>.  "};
diff --git a/include/xpm/zoom-original.png b/include/xpm/zoom-original.png
deleted file mode 100644 (file)
index 8e35414..0000000
Binary files a/include/xpm/zoom-original.png and /dev/null differ
diff --git a/include/xpm/zoom-original.xpm b/include/xpm/zoom-original.xpm
deleted file mode 100644 (file)
index 6cc6b3c..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* XPM */
-static const char * zoom_original_xpm[] = {
-"16 16 111 2",
-"      c None",
-".     c #878B87",
-"+     c #868C8A",
-"@     c #888B89",
-"#     c #ACB6BF",
-"$     c #CDD6DD",
-"%     c #E4E7E9",
-"&     c #929594",
-"*     c #CFD8E0",
-"=     c #D3DDE5",
-"-     c #A4BFDC",
-";     c #99B9DA",
-">     c #9AB9DA",
-",     c #A4BFDD",
-"'     c #CFDAE5",
-")     c #B4C9DF",
-"!     c #9DBDDD",
-"~     c #B5CDE6",
-"{     c #5C84B8",
-"]     c #5B84B8",
-"^     c #B0CAE4",
-"/     c #9ABADD",
-"(     c #98B9DC",
-"_     c #BCD1E8",
-":     c #5F87B9",
-"<     c #FFFFFF",
-"[     c #5A84B7",
-"}     c #ABC6E2",
-"|     c #91B4DA",
-"1     c #868C8B",
-"2     c #9DBBDA",
-"3     c #B6CDE6",
-"4     c #5D85B8",
-"5     c #5982B7",
-"6     c #A7C3E1",
-"7     c #9FBDDE",
-"8     c #9EBBDA",
-"9     c #878B88",
-"0     c #8EB2D6",
-"a     c #5A83B7",
-"b     c #5681B6",
-"c     c #9EBDDE",
-"d     c #86ACD4",
-"e     c #89AED4",
-"f     c #8AAFD7",
-"g     c #94B6DB",
-"h     c #547FB5",
-"i     c #507DB4",
-"j     c #85ACD5",
-"k     c #7BA5D2",
-"l     c #878C8B",
-"m     c #CFD8DE",
-"n     c #A7C1DD",
-"o     c #86ADD6",
-"p     c #89AED6",
-"q     c #4E7BB3",
-"r     c #4F7CB3",
-"s     c #8BB0D7",
-"t     c #A9C3DE",
-"u     c #D0D8DE",
-"v     c #888B87",
-"w     c #B1BAC1",
-"x     c #D9E1E8",
-"y     c #94B6DA",
-"z     c #96B7DB",
-"A     c #527EB5",
-"B     c #537EB5",
-"C     c #97B8DB",
-"D     c #DAE2E8",
-"E     c #B2BBC1",
-"F     c #8A8C8A",
-"G     c #D7DDE2",
-"H     c #CAD8E6",
-"I     c #A4C0DF",
-"J     c #A6C2E0",
-"K     c #5781B6",
-"L     c #D8DEE3",
-"M     c #949895",
-"N     c #DADFE3",
-"O     c #E1E6EA",
-"P     c #C7D7E8",
-"Q     c #BDD2E6",
-"R     c #BED2E6",
-"S     c #C8D8E8",
-"T     c #DFE5EA",
-"U     c #DBE0E4",
-"V     c #959896",
-"W     c #9DA09B",
-"X     c #60625F",
-"Y     c #8A8D8A",
-"Z     c #BCC1C4",
-"`     c #DCE0E2",
-" .    c #E9EBEB",
-"..    c #BDC2C5",
-"+.    c #898C88",
-"@.    c #878A84",
-"#.    c #B9BCB6",
-"$.    c #BDBFBC",
-"%.    c #61635F",
-"&.    c #8A8C88",
-"*.    c #8D918D",
-"=.    c #8B8D89",
-"-.    c #8E918D",
-";.    c #575955",
-">.    c #7A7B78",
-",.    c #B7B8B6",
-"'.    c #595B57",
-").    c #555753",
-"!.    c #767873",
-"~.    c #A0A29F",
-"{.    c #565854",
-"        . + . . + .             ",
-"      @ # $ % % $ # @           ",
-"    & * = - ; > , ' * &         ",
-"  @ * ) ! ~ { ] ^ / ) * @       ",
-". # ' ( _ : < < [ } | ' # .     ",
-"1 $ 2 3 4 < < < 5 6 7 8 $ +     ",
-"9 % 0 ^ [ a < < b c | d % .     ",
-"9 % e f g h < < i j k e % .     ",
-"l m n o p q < < r s p t u l     ",
-"v w x y z A < < B ( C D E v     ",
-"  F G H I J K K 6 J H L .       ",
-"    M N O P Q R S T U V W X     ",
-"      Y Z `  . .` ..+.@.#.$.%.  ",
-"        &.*.=.=.-.&.  ;.>.@.,.'.",
-"                        ).!.~.'.",
-"                          ).{.  "};
diff --git a/include/xpm/zoom-out.png b/include/xpm/zoom-out.png
deleted file mode 100644 (file)
index df5be3c..0000000
Binary files a/include/xpm/zoom-out.png and /dev/null differ
diff --git a/include/xpm/zoom-out.xpm b/include/xpm/zoom-out.xpm
deleted file mode 100644 (file)
index 7bd9c37..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* XPM */
-static const char * zoom_out_xpm[] = {
-"16 16 108 2",
-"      c None",
-".     c #878B87",
-"+     c #868C8A",
-"@     c #888B89",
-"#     c #ACB6BF",
-"$     c #CDD6DD",
-"%     c #E4E7E9",
-"&     c #929594",
-"*     c #CFD8E0",
-"=     c #D3DDE5",
-"-     c #A4BFDC",
-";     c #99B9DA",
-">     c #9AB9DA",
-",     c #A4BFDD",
-"'     c #CFDAE5",
-")     c #B4C9DF",
-"!     c #9DBDDD",
-"~     c #B5CDE6",
-"{     c #B7CEE7",
-"]     c #B0CAE4",
-"^     c #9ABADD",
-"/     c #98B9DC",
-"(     c #BCD1E8",
-"_     c #C2D6EA",
-":     c #C1D4EA",
-"<     c #BAD0E7",
-"[     c #B2CBE5",
-"}     c #ABC6E2",
-"|     c #91B4DA",
-"1     c #868C8B",
-"2     c #9DBBDA",
-"3     c #B6CDE6",
-"4     c #5D85B8",
-"5     c #5E86B8",
-"6     c #5C85B8",
-"7     c #5B84B8",
-"8     c #5982B7",
-"9     c #5781B6",
-"0     c #9FBDDE",
-"a     c #9EBBDA",
-"b     c #878B88",
-"c     c #8EB2D6",
-"d     c #5983B7",
-"e     c #FFFFFF",
-"f     c #507DB4",
-"g     c #86ACD4",
-"h     c #89AED4",
-"i     c #4E7BB3",
-"j     c #4A78B2",
-"k     c #878C8B",
-"l     c #CFD8DE",
-"m     c #A7C1DD",
-"n     c #86ADD6",
-"o     c #4F7CB3",
-"p     c #89AED6",
-"q     c #A9C3DE",
-"r     c #D0D8DE",
-"s     c #888B87",
-"t     c #B1BAC1",
-"u     c #D9E1E8",
-"v     c #94B6DA",
-"w     c #96B7DB",
-"x     c #9ABADC",
-"y     c #97B8DB",
-"z     c #DAE2E8",
-"A     c #B2BBC1",
-"B     c #8A8C8A",
-"C     c #D7DDE2",
-"D     c #CAD8E6",
-"E     c #A4C0DF",
-"F     c #A6C2E0",
-"G     c #A7C3E1",
-"H     c #A8C4E1",
-"I     c #D8DEE3",
-"J     c #949895",
-"K     c #DADFE3",
-"L     c #E1E6EA",
-"M     c #C7D7E8",
-"N     c #BDD2E6",
-"O     c #BED2E6",
-"P     c #C8D8E8",
-"Q     c #DFE5EA",
-"R     c #DBE0E4",
-"S     c #959896",
-"T     c #9DA09B",
-"U     c #60625F",
-"V     c #8A8D8A",
-"W     c #BCC1C4",
-"X     c #DCE0E2",
-"Y     c #E9EBEB",
-"Z     c #BDC2C5",
-"`     c #898C88",
-" .    c #878A84",
-"..    c #B9BCB6",
-"+.    c #BDBFBC",
-"@.    c #61635F",
-"#.    c #8A8C88",
-"$.    c #8D918D",
-"%.    c #8B8D89",
-"&.    c #8E918D",
-"*.    c #575955",
-"=.    c #7A7B78",
-"-.    c #B7B8B6",
-";.    c #595B57",
-">.    c #555753",
-",.    c #767873",
-"'.    c #A0A29F",
-").    c #565854",
-"        . + . . + .             ",
-"      @ # $ % % $ # @           ",
-"    & * = - ; > , ' * &         ",
-"  @ * ) ! ~ { ~ ] ^ ) * @       ",
-". # ' / ( _ : < [ } | ' # .     ",
-"1 $ 2 3 4 5 6 7 8 9 0 a $ +     ",
-"b % c d e e e e e e f g % .     ",
-"b % h i e e e e e e j h % .     ",
-"k l m n i i o o o i p q r k     ",
-"s t u v w / x x x / y z A s     ",
-"  B C D E F G H G F D I .       ",
-"    J K L M N O P Q R S T U     ",
-"      V W X Y Y X Z `  ...+.@.  ",
-"        #.$.%.%.&.#.  *.=. .-.;.",
-"                        >.,.'.;.",
-"                          >.).  "};
index ee3ce6f290494b2c173fdd5a5581dd9bdca1ff40..22e285b149abfe4459df5a7b9cb0390dce5540a7 100644 (file)
 /* XPM */
-static const char *zoom_in_xpm[]={
-"16 16 6 1",
-"# c None",
-". c #000000",
-"a c #000080",
-"c c #804000",
-"b c #d3e4e8",
-"d c #ffff00",
-".##...##...##...",
-".####aa#########",
-".##aabbaa#######",
-"##abbbbbba#####.",
-"##abbbbbba#####.",
-".abbbbbbbba####.",
-".abbbbbbbba#####",
-".#abbbbbba######",
-"##abbbbbba#####.",
-"###aabbaaccc###.",
-".####aa##cddc##.",
-".########cdddc##",
-".#########cdddc#",
-"###########cddc.",
-"############cc#.",
-"...##...##...##."};
+static const char * zoom_in_xpm[] = {
+"16 16 105 2",
+"      c None",
+".     c #878B87",
+"+     c #868C8A",
+"@     c #888B89",
+"#     c #ACB6BF",
+"$     c #CDD6DD",
+"%     c #E4E7E9",
+"&     c #929594",
+"*     c #CFD8E0",
+"=     c #D3DDE5",
+"-     c #A4BFDC",
+";     c #99B9DA",
+">     c #9AB9DA",
+",     c #A4BFDD",
+"'     c #CFDAE5",
+")     c #B4C9DF",
+"!     c #9DBDDD",
+"~     c #B5CDE6",
+"{     c #5C84B8",
+"]     c #5B84B8",
+"^     c #B0CAE4",
+"/     c #9ABADD",
+"(     c #98B9DC",
+"_     c #BCD1E8",
+":     c #5F87B9",
+"<     c #FFFFFF",
+"[     c #5A84B7",
+"}     c #ABC6E2",
+"|     c #91B4DA",
+"1     c #868C8B",
+"2     c #9DBBDA",
+"3     c #B6CDE6",
+"4     c #5D85B8",
+"5     c #5E86B8",
+"6     c #5982B7",
+"7     c #5781B6",
+"8     c #9FBDDE",
+"9     c #9EBBDA",
+"0     c #878B88",
+"a     c #8EB2D6",
+"b     c #5983B7",
+"c     c #507DB4",
+"d     c #86ACD4",
+"e     c #89AED4",
+"f     c #4E7BB3",
+"g     c #4A78B2",
+"h     c #878C8B",
+"i     c #CFD8DE",
+"j     c #A7C1DD",
+"k     c #86ADD6",
+"l     c #4F7CB3",
+"m     c #89AED6",
+"n     c #A9C3DE",
+"o     c #D0D8DE",
+"p     c #888B87",
+"q     c #B1BAC1",
+"r     c #D9E1E8",
+"s     c #94B6DA",
+"t     c #96B7DB",
+"u     c #527EB5",
+"v     c #537EB5",
+"w     c #97B8DB",
+"x     c #DAE2E8",
+"y     c #B2BBC1",
+"z     c #8A8C8A",
+"A     c #D7DDE2",
+"B     c #CAD8E6",
+"C     c #A4C0DF",
+"D     c #A6C2E0",
+"E     c #A7C3E1",
+"F     c #D8DEE3",
+"G     c #949895",
+"H     c #DADFE3",
+"I     c #E1E6EA",
+"J     c #C7D7E8",
+"K     c #BDD2E6",
+"L     c #BED2E6",
+"M     c #C8D8E8",
+"N     c #DFE5EA",
+"O     c #DBE0E4",
+"P     c #959896",
+"Q     c #9DA09B",
+"R     c #60625F",
+"S     c #8A8D8A",
+"T     c #BCC1C4",
+"U     c #DCE0E2",
+"V     c #E9EBEB",
+"W     c #BDC2C5",
+"X     c #898C88",
+"Y     c #878A84",
+"Z     c #B9BCB6",
+"`     c #BDBFBC",
+" .    c #61635F",
+"..    c #8A8C88",
+"+.    c #8D918D",
+"@.    c #8B8D89",
+"#.    c #8E918D",
+"$.    c #575955",
+"%.    c #7A7B78",
+"&.    c #B7B8B6",
+"*.    c #595B57",
+"=.    c #555753",
+"-.    c #767873",
+";.    c #A0A29F",
+">.    c #565854",
+"        . + . . + .             ",
+"      @ # $ % % $ # @           ",
+"    & * = - ; > , ' * &         ",
+"  @ * ) ! ~ { ] ^ / ) * @       ",
+". # ' ( _ : < < [ } | ' # .     ",
+"1 $ 2 3 4 5 < < 6 7 8 9 $ +     ",
+"0 % a b < < < < < < c d % .     ",
+"0 % e f < < < < < < g e % .     ",
+"h i j k f f < < l f m n o h     ",
+"p q r s t u < < v ( w x y p     ",
+"  z A B C D 7 7 E D B F .       ",
+"    G H I J K L M N O P Q R     ",
+"      S T U V V U W X Y Z `  .  ",
+"        ..+.@.@.#...  $.%.Y &.*.",
+"                        =.-.;.*.",
+"                          =.>.  "};
diff --git a/include/xpm/zoom_on.xpm b/include/xpm/zoom_on.xpm
deleted file mode 100644 (file)
index bb19096..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* XPM */
-static const char *zoom_on_xpm[]={
-"16 16 6 1",
-"  c None",
-". c #000000",
-"a c #800000",
-"c c #804000",
-"b c #ff3f3f",
-"d c #007f7f",
-".  ...  ...  ...",
-".    aa         ",
-".  aabbaa       ",
-"  abbbbbba     .",
-"  abbbbbba     .",
-".abbbbbbbba    .",
-".abbbbbbbba     ",
-". abbbbbba      ",
-"  abbbbbba     .",
-"   aabbaaccc   .",
-".    aa  cddc  .",
-".        cdddc  ",
-".         cdddc ",
-"           cddc.",
-"            cc .",
-"...  ...  ...  ."};
index f5c3805cda230704d7e402bcb2776916b3076af5..82b040eaedb0c7417edbc0e41efc731c5fa1abe9 100644 (file)
 /* XPM */
-static const char *zoom_out_xpm[]={
-"16 16 6 1",
-". c None",
-"c c #000000",
-"# c #000080",
-"b c #804000",
-"a c #d3e4e8",
-"d c #ffff00",
-"................",
-"....##..........",
-"..##aa##........",
-".#aaaaaa#.......",
-".#aaaaaa#.......",
-"#aaaaaaaa#......",
-"#aaaaaaaa#......",
-".#aaaaaa#.......",
-".#aaaaaa#.......",
-"..##aa##bb......",
-"....##..bbbb....",
-"..c....c.bddb...",
-".cc.c.cc.bdddb..",
-"..c....c..bdddb.",
-"..c.c..c...bddb.",
-"..c....c....bb.."};
+static const char * zoom_out_xpm[] = {
+"16 16 111 2",
+"      c None",
+".     c #878B87",
+"+     c #868C8A",
+"@     c #888B89",
+"#     c #ACB6BF",
+"$     c #CDD6DD",
+"%     c #E4E7E9",
+"&     c #929594",
+"*     c #CFD8E0",
+"=     c #D3DDE5",
+"-     c #A4BFDC",
+";     c #99B9DA",
+">     c #9AB9DA",
+",     c #A4BFDD",
+"'     c #CFDAE5",
+")     c #B4C9DF",
+"!     c #9DBDDD",
+"~     c #B5CDE6",
+"{     c #5C84B8",
+"]     c #5B84B8",
+"^     c #B0CAE4",
+"/     c #9ABADD",
+"(     c #98B9DC",
+"_     c #BCD1E8",
+":     c #5F87B9",
+"<     c #FFFFFF",
+"[     c #5A84B7",
+"}     c #ABC6E2",
+"|     c #91B4DA",
+"1     c #868C8B",
+"2     c #9DBBDA",
+"3     c #B6CDE6",
+"4     c #5D85B8",
+"5     c #5982B7",
+"6     c #A7C3E1",
+"7     c #9FBDDE",
+"8     c #9EBBDA",
+"9     c #878B88",
+"0     c #8EB2D6",
+"a     c #5A83B7",
+"b     c #5681B6",
+"c     c #9EBDDE",
+"d     c #86ACD4",
+"e     c #89AED4",
+"f     c #8AAFD7",
+"g     c #94B6DB",
+"h     c #547FB5",
+"i     c #507DB4",
+"j     c #85ACD5",
+"k     c #7BA5D2",
+"l     c #878C8B",
+"m     c #CFD8DE",
+"n     c #A7C1DD",
+"o     c #86ADD6",
+"p     c #89AED6",
+"q     c #4E7BB3",
+"r     c #4F7CB3",
+"s     c #8BB0D7",
+"t     c #A9C3DE",
+"u     c #D0D8DE",
+"v     c #888B87",
+"w     c #B1BAC1",
+"x     c #D9E1E8",
+"y     c #94B6DA",
+"z     c #96B7DB",
+"A     c #527EB5",
+"B     c #537EB5",
+"C     c #97B8DB",
+"D     c #DAE2E8",
+"E     c #B2BBC1",
+"F     c #8A8C8A",
+"G     c #D7DDE2",
+"H     c #CAD8E6",
+"I     c #A4C0DF",
+"J     c #A6C2E0",
+"K     c #5781B6",
+"L     c #D8DEE3",
+"M     c #949895",
+"N     c #DADFE3",
+"O     c #E1E6EA",
+"P     c #C7D7E8",
+"Q     c #BDD2E6",
+"R     c #BED2E6",
+"S     c #C8D8E8",
+"T     c #DFE5EA",
+"U     c #DBE0E4",
+"V     c #959896",
+"W     c #9DA09B",
+"X     c #60625F",
+"Y     c #8A8D8A",
+"Z     c #BCC1C4",
+"`     c #DCE0E2",
+" .    c #E9EBEB",
+"..    c #BDC2C5",
+"+.    c #898C88",
+"@.    c #878A84",
+"#.    c #B9BCB6",
+"$.    c #BDBFBC",
+"%.    c #61635F",
+"&.    c #8A8C88",
+"*.    c #8D918D",
+"=.    c #8B8D89",
+"-.    c #8E918D",
+";.    c #575955",
+">.    c #7A7B78",
+",.    c #B7B8B6",
+"'.    c #595B57",
+").    c #555753",
+"!.    c #767873",
+"~.    c #A0A29F",
+"{.    c #565854",
+"        . + . . + .             ",
+"      @ # $ % % $ # @           ",
+"    & * = - ; > , ' * &         ",
+"  @ * ) ! ~ { ] ^ / ) * @       ",
+". # ' ( _ : < < [ } | ' # .     ",
+"1 $ 2 3 4 < < < 5 6 7 8 $ +     ",
+"9 % 0 ^ [ a < < b c | d % .     ",
+"9 % e f g h < < i j k e % .     ",
+"l m n o p q < < r s p t u l     ",
+"v w x y z A < < B ( C D E v     ",
+"  F G H I J K K 6 J H L .       ",
+"    M N O P Q R S T U V W X     ",
+"      Y Z `  . .` ..+.@.#.$.%.  ",
+"        &.*.=.=.-.&.  ;.>.@.,.'.",
+"                        ).!.~.'.",
+"                          ).{.  "};
index d13345c91f3807bde6daf8ce921b683ba6506a3d..4e88df662bc10f69d707d0b627ad7484f7d18c24 100644 (file)
@@ -24,12 +24,13 @@ var main = function() {
 //var script = "rotate 10 20: box:axis:fsurf 'sin(pi*x*y)'";
 
 var makeSampleScript = function() {
+//     var mgl = "fsurf 'x' 'rgb';value 4";
+
        var mgl = "origintick off\n";
        mgl += "title 'qqq' '@k':ranges -2 2 -2 2 -2 2:colorbar '>'\n"   // NOTE: Ranges MUST BE specified for correctly work of zoomaxis feature
        mgl += "facenum 50:";
        mgl += "origin 0 0 0:axis :xlabel 'x':ylabel 'y':zlabel 'z':"
        mgl += "box:fplot 'sin(x^2)'\n";   // This is just for testing zoomaxis features
-       mgl += "fplot 'sin(2*pi*t)' '2*t-1' 'cos(2*pi*t)' 'm2o':fsurf 'sin(pi*x*y)':";
        mgl += "text 0 0 'aaa'";
        return mgl;
 }
index fcc2153d859754de8770a505b9a152db0ae35047..5ae698496a2f051e129ab0e6e1ea0403ccc64873 100644 (file)
@@ -336,7 +336,7 @@ mathgl.Graph.prototype.__mgl_draw_prim = function(obj, ctx, prim, scl) {
 
 mathgl.Graph.prototype.__mgl_pf = function(obj, z) {
 //     return 1/obj.pf;
-       return (1-this.__fov)/obj.pf/(1-this.__fov*z/obj.depth);        // TODO: check calc coordinates!!!
+       return (1-this.__fov/1.37)/obj.pf/(1-this.__fov*z/obj.depth);   // TODO: check calc coordinates!!!
 //     return 1/(1+obj.pf*(1-z/obj.depth));
 }
 
@@ -611,39 +611,39 @@ mathgl.Graph.prototype.zoomOut = function() {
        this.zoomAxis(1./1.1);
 }
 
-mathgl.Graph.prototype.getView = function(mgl) { 
-       return this.__view; 
+mathgl.Graph.prototype.getView = function(mgl) {
+       return this.__view;
 }
 
-mathgl.Graph.prototype.reloadGeometry = function() { 
-       var mgl = this.__geometry.mgl; 
-       this.__geometry = this.__backend.geometry(mgl); 
-       this.__geometry.mgl = mgl; 
+mathgl.Graph.prototype.reloadGeometry = function() {
+       var mgl = this.__geometry.mgl;
+       this.__geometry = this.__backend.geometry(mgl);
+       this.__geometry.mgl = mgl;
 }
 
-mathgl.Graph.prototype.redraw = function() { 
-       this.__renderStart(); 
+mathgl.Graph.prototype.redraw = function() {
+       this.__renderStart();
 }
 
-mathgl.Graph.prototype.destroy = function() { 
-       this.__view.destroy(); 
+mathgl.Graph.prototype.destroy = function() {
+       this.__view.destroy();
        this.__view = null;
        this.__backend = null;
        this.__canvas = null;
        this.__geometry = null;
-} 
+}
 
-/** @param type {String} data url type (e.g. "image/png") */ 
+/** @param type {String} data url type (e.g. "image/png") */
 mathgl.Graph.prototype.toDataURL = function(type) {
        this.__canvas.toDataURL(type);
 }
 
-/** Set perspective angle of view: @param val - degree of perspective in range 0...1 (0 - use default orthogonal projection)  */ 
+/** Set perspective angle of view: @param val - degree of perspective in range 0...1 (0 - use default orthogonal projection)  */
 mathgl.Graph.prototype.setPerspective = function(val) {
-       this.__fov = val; 
+       this.__fov = val;
 }
 
-/** Set maximal number of drawable points in draft mode */ 
+/** Set maximal number of drawable points in draft mode */
 mathgl.Graph.prototype.setMaxDraftPoints = function(count) {
        this.__maxDraftPoints = count;
 }
index a2033799a1fed93a274d8d428295f2644c0cad33..e06cb4a90cd8a91f18edc496ed9daa2a58fd7cac 100644 (file)
@@ -25,6 +25,7 @@ mathgl.View = function() {
        this.__distance = 1.0;
        this.__pitch = 0;
        this.__yaw = 0;
+       this.__theta = 0;
 }
 
 
@@ -110,6 +111,8 @@ mathgl.View.prototype.viewMatrix = function() {
        var sp = Math.sin(this.__pitch);
        var cy = Math.cos(this.__yaw);
        var sy = Math.sin(this.__yaw);
+       var ct = Math.cos(this.__theta);
+       var st = Math.sin(this.__theta);
        var lh = true; // coordinate system is left handed
 
        var distanceMatrix = $M([[1, 0,  0, 0],
@@ -124,7 +127,10 @@ mathgl.View.prototype.viewMatrix = function() {
                                                [  0, 1,   0, 0],
                                                [ sy, 0,  cy, 0],
                                                [  0, 0,   0, 1]]);
-       var viewMatrix = Matrix.I(4);
+       var viewMatrix = $M([[ ct,-st, 0, 0],
+                                               [  st, ct, 0, 0],
+                                               [  0,  0,  1, 0],
+                                               [  0,  0,  0, 1]]);
        viewMatrix = viewMatrix.x(distanceMatrix);
        viewMatrix = viewMatrix.x(pitchMatrix);
        viewMatrix = viewMatrix.x(yawMatrix);
@@ -142,7 +148,10 @@ mathgl.View.prototype.__onMouseMove = function(e) {
                var x = e.offsetX;
                var y = e.offsetY;
                this.__yaw += 0.5 * (this.__mouseX - x) * Math.PI / 180;
-               this.__pitch += 0.5 * (y - this.__mouseY) * Math.PI / 180;
+//             if(Math.abs(Math.cos(this.__yaw))>0.3)
+                       this.__pitch += 0.5 * (y - this.__mouseY) * Math.PI / 180;
+//             else
+//                     this.__theta += 0.5 * (y - this.__mouseY) * Math.PI / 180;
                this.__mouseX = x;
                this.__mouseY = y;
                if(this.__pitch > 63)   this.__pitch -= 20*Math.PI;
index 6cecfe0021ea412868208d039f508fcd70f354df..68ec1179b9023b9b9bddb78bc57e557915f52651 100644 (file)
@@ -8,7 +8,32 @@ set(mgl_clean_files "")
 
 SET_SOURCE_FILES_PROPERTIES(mathgl.i numpy.i PROPERTIES CPLUSPLUS ON)
 
-if(MGL_HAVE_PYTHON)
+FIND_PACKAGE(SWIG)
+if(NOT SWIG_FOUND)
+       message(SEND_ERROR "Couldn't find swig needed for interfaces compiling.")
+endif(NOT SWIG_FOUND)
+INCLUDE(${SWIG_USE_FILE})
+
+if(enable-python)
+       set(Python_ADDITIONAL_VERSIONS 2.7)
+       FIND_PACKAGE(PythonInterp)
+       if(NOT PYTHONINTERP_FOUND)
+               message(SEND_ERROR "Couldn't find python interpreter.")
+       endif(NOT PYTHONINTERP_FOUND)
+       FIND_PACKAGE(PythonLibs)
+       if(NOT PYTHONLIBS_FOUND)
+               message(SEND_ERROR "Couldn't find python development libraries.")
+       endif(NOT PYTHONLIBS_FOUND)
+       execute_process(
+               COMMAND ${PYTHON_EXECUTABLE} -c "import numpy; print numpy.get_include()"
+               OUTPUT_VARIABLE NUMPY_INCLUDE_PATH
+               RESULT_VARIABLE NUMPY_ERR
+               OUTPUT_STRIP_TRAILING_WHITESPACE
+       )
+       if(NOT NUMPY_INCLUDE_PATH)
+               message(SEND_ERROR "Couldn't find numpy.")
+       endif(NOT NUMPY_INCLUDE_PATH)
+
        include_directories(${PYTHON_INCLUDE_DIR})
        execute_process(
                COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(prefix='${CMAKE_INSTALL_PREFIX}')"
@@ -29,9 +54,14 @@ if(MGL_HAVE_PYTHON)
        install(FILES ${MathGL_BINARY_DIR}/lang/mathgl.py ${MathGL_BINARY_DIR}/lang/mathgl.pyc DESTINATION ${MGL_PYTHON_SITE_PACKAGES})
        install (TARGETS _mathgl LIBRARY DESTINATION ${MGL_PYTHON_SITE_PACKAGES})
        set(mgl_clean_files ${mgl_clean_files} mathgl.py)
-endif(MGL_HAVE_PYTHON)
+endif(enable-python)
+
+if(enable-lua)
+       INCLUDE(FindLua51)
+       if(NOT LUA51_FOUND)
+               message(SEND_ERROR "Couldn't find Lua 5.1 library.")
+       endif(NOT LUA51_FOUND)
 
-if(MGL_HAVE_LUA)
        include_directories(${LUA_INCLUDE_DIR})
        set(SWIG_MODULE_mgl-lua_EXTRA_DEPS numpy.i ${src_imp_dep})
        SWIG_ADD_MODULE(mgl-lua lua mathgl.i)
@@ -39,9 +69,26 @@ if(MGL_HAVE_LUA)
        set_target_properties(mgl-lua PROPERTIES PREFIX "" BUILD_WITH_INSTALL_RPATH ON)
 
        install (TARGETS mgl-lua LIBRARY DESTINATION ${MGL_LIB_INSTALL_DIR})
-endif(MGL_HAVE_LUA)
+endif(enable-lua)
+
+if(enable-octave)
+       find_program(oct_prog octave-config)
+       if(NOT oct_prog)
+               message(SEND_ERROR "Couldn't find octave-config needed for octave interfaces compiling.")
+       endif(NOT oct_prog)
+       find_program(oct_exec octave)
+       if(NOT oct_exec)
+               message(SEND_ERROR "Couldn't find octave needed for octave interfaces compiling.")
+       endif(NOT oct_exec)
+       find_program(oct_mk mkoctfile)
+       if(NOT oct_mk)
+               message(SEND_ERROR "Couldn't find mkoctfile needed for octave interfaces compiling.")
+       endif(NOT oct_mk)
+       find_program(oct_tar tar)
+       if(NOT oct_tar)
+               message(SEND_ERROR "Couldn't find tar needed for octave interfaces creation.")
+       endif(NOT oct_tar)
 
-if(MGL_HAVE_OCTAVE)
        execute_process(COMMAND ${oct_prog} -p CANONICAL_HOST_TYPE
        OUTPUT_VARIABLE oct_host
        OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -82,5 +129,5 @@ message(STATUS "${oct_prog} ${oct_host} ${oct_api}")
                        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/lang )")
        endif(enable-octave-install)
        set(mgl_clean_files ${mgl_clean_files} mathgl)
-endif(MGL_HAVE_OCTAVE)
+endif(enable-octave)
 set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${mgl_clean_files}")
index 77dd22d9adfb4ea040a694871496b9031fea3a92..1435bbef41610da7a3fb87b95a91fb59191397f8 100644 (file)
@@ -31,34 +31,37 @@ public:
        bool link;              ///< use external data (i.e. don't free it)
 
        /// Initiate by other mglData variable
-       inline mglData(const mglData &d)        {       a=0;    mgl_data_set(this,&d);          }       // NOTE: must be constructor for mglData& to exclude copy one
-       inline mglData(const mglData *d)        {       a=0;    mgl_data_set(this, d);          }
-       inline mglData(bool, mglData *d)        // NOTE: Variable d will be deleted!!!
+       mglData(const mglData &d)       {       a=0;    mgl_data_set(this,&d);          }       // NOTE: must be constructor for mglData& to exclude copy one
+       mglData(const mglData *d)       {       a=0;    mgl_data_set(this, d);          }
+       mglData(bool, mglData *d)       // NOTE: Variable d will be deleted!!!
        {       if(d)
                {       nx=d->nx;       ny=d->ny;       nz=d->nz;       a=d->a; d->a=0;
                        id=d->id;       link=d->link;   delete d;       }
                else    {       a=0;    Create(1);      }       }
        /// Initiate by flat array
-       inline mglData(int size, const float *d)        {       a=0;    Set(d,size);    }
-       inline mglData(int rows, int cols, const float *d)      {       a=0;    Set(d,cols,rows);       }
-       inline mglData(int size, const double *d)       {       a=0;    Set(d,size);    }
-       inline mglData(int rows, int cols, const double *d)     {       a=0;    Set(d,cols,rows);       }
-       inline mglData(const double *d, int size)       {       a=0;    Set(d,size);    }
-       inline mglData(const double *d, int rows, int cols)     {       a=0;    Set(d,cols,rows);       }
+       mglData(int size, const float *d)       {       a=0;    Set(d,size);    }
+       mglData(int rows, int cols, const float *d)     {       a=0;    Set(d,cols,rows);       }
+       mglData(int size, const double *d)      {       a=0;    Set(d,size);    }
+       mglData(int rows, int cols, const double *d)    {       a=0;    Set(d,cols,rows);       }
+       mglData(const double *d, int size)      {       a=0;    Set(d,size);    }
+       mglData(const double *d, int rows, int cols)    {       a=0;    Set(d,cols,rows);       }
+       mglData(const float *d, int size)       {       a=0;    Set(d,size);    }
+       mglData(const float *d, int rows, int cols)     {       a=0;    Set(d,cols,rows);       }
        /// Read data from file
-       inline mglData(const char *fname)                       {       a=0;    Read(fname);    }
+       mglData(const char *fname)                      {       a=0;    Read(fname);    }
        /// Allocate the memory for data array and initialize it zero
-       inline mglData(long xx=1,long yy=1,long zz=1)   {       a=0;    Create(xx,yy,zz);       }
+       mglData(long xx=1,long yy=1,long zz=1)  {       a=0;    Create(xx,yy,zz);       }
        /// Delete the array
        virtual ~mglData()      {       if(!link && a)  delete []a;     }
-       inline mreal GetVal(long i, long j=0, long k=0)
+
+       inline mreal GetVal(long i, long j=0, long k=0) const
        {       return mgl_data_get_value(this,i,j,k);}
        inline void SetVal(mreal f, long i, long j=0, long k=0)
        {       mgl_data_set_value(this,f,i,j,k);       }
        /// Get sizes
-       inline long GetNx() const       {       return nx;      }
-       inline long GetNy() const       {       return ny;      }
-       inline long GetNz() const       {       return nz;      }
+       long GetNx() const      {       return nx;      }
+       long GetNy() const      {       return ny;      }
+       long GetNz() const      {       return nz;      }
 
        /// Link external data array (don't delete it at exit)
        inline void Link(mreal *A, long NX, long NY=1, long NZ=1)
@@ -134,15 +137,18 @@ public:
        inline void Modify(const char *eq,const mglData &vdat)
        {       mgl_data_modify_vw(this,eq,&vdat,0);    }
        /// Modify the data by specified formula assuming x,y,z in range [r1,r2]
-       inline void Fill(mglBase *gr, const char *eq, const char *opt="")
+       inline void Fill(HMGL gr, const char *eq, const char *opt="")
        {       mgl_data_fill_eq(gr,this,eq,0,0,opt);   }
-       inline void Fill(mglBase *gr, const char *eq, const mglData &vdat, const char *opt="")
+       inline void Fill(HMGL gr, const char *eq, const mglData &vdat, const char *opt="")
        {       mgl_data_fill_eq(gr,this,eq,&vdat,0,opt);       }
-       inline void Fill(mglBase *gr, const char *eq, const mglData &vdat, const mglData &wdat,const char *opt="")
+       inline void Fill(HMGL gr, const char *eq, const mglData &vdat, const mglData &wdat,const char *opt="")
        {       mgl_data_fill_eq(gr,this,eq,&vdat,&wdat,opt);   }
        /// Equidistantly fill the data to range [x1,x2] in direction dir
        inline void Fill(mreal x1,mreal x2=NaN,char dir='x')
-       {       return mgl_data_fill(this,x1,x2,dir);   }
+       {       mgl_data_fill(this,x1,x2,dir);  }
+       /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [p1,p2] using global spline
+       inline void RefillGS(const mglData &xdat, const mglData &vdat, mreal x1, mreal x2,long sl=-1)
+       {       mgl_data_refill_gs(this,&xdat,&vdat,x1,x2,sl);  }
        /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [p1,p2]
        inline void Refill(const mglData &xdat, const mglData &vdat, mreal x1, mreal x2,long sl=-1)
        {       mgl_data_refill_x(this,&xdat,&vdat,x1,x2,sl);   }
@@ -153,14 +159,14 @@ public:
        inline void Refill(const mglData &xdat, const mglData &ydat, const mglData &zdat, const mglData &vdat, mglPoint p1, mglPoint p2)
        {       mgl_data_refill_xyz(this,&xdat,&ydat,&zdat,&vdat,p1.x,p2.x,p1.y,p2.y,p1.z,p2.z);        }
        /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range of gr
-       inline void Refill(mglBase *gr, const mglData &xdat, const mglData &vdat, long sl=-1, const char *opt="")
+       inline void Refill(HMGL gr, const mglData &xdat, const mglData &vdat, long sl=-1, const char *opt="")
        {       mgl_data_refill_gr(gr,this,&xdat,0,0,&vdat,sl,opt);     }
-       inline void Refill(mglBase *gr, const mglData &xdat, const mglData &ydat, const mglData &vdat, long sl=-1, const char *opt="")
+       inline void Refill(HMGL gr, const mglData &xdat, const mglData &ydat, const mglData &vdat, long sl=-1, const char *opt="")
        {       mgl_data_refill_gr(gr,this,&xdat,&ydat,0,&vdat,sl,opt); }
-       inline void Refill(mglBase *gr, const mglData &xdat, const mglData &ydat, const mglData &zdat, const mglData &vdat, const char *opt="")
+       inline void Refill(HMGL gr, const mglData &xdat, const mglData &ydat, const mglData &zdat, const mglData &vdat, const char *opt="")
        {       mgl_data_refill_gr(gr,this,&xdat,&ydat,&zdat,&vdat,-1,opt);     }
-/// Set the data by triangulated surface values assuming x,y,z in axis range of gr
-       inline void Grid(mglBase *gr, const mglData &x, const mglData &y, const mglData &z, const char *opt="")
+       /// Set the data by triangulated surface values assuming x,y,z in axis range of gr
+       inline void Grid(HMGL gr, const mglData &x, const mglData &y, const mglData &z, const char *opt="")
        {       mgl_data_grid(gr,this,&x,&y,&z,opt);    }
        /// Set the data by triangulated surface values assuming x,y,z in range [p1, p2]
        inline void Grid(const mglData &xdat, const mglData &ydat, const mglData &vdat, mglPoint p1, mglPoint p2)
@@ -222,6 +228,10 @@ public:
        {       return mglData(true,mgl_data_subdata(this,xx,yy,zz));   }
        inline mglData SubData(const mglData &xx, const mglData &yy, const mglData &zz) const
        {       return mglData(true,mgl_data_subdata_ext(this,&xx,&yy,&zz));    }
+       inline mglData SubData(const mglData &xx, const mglData &yy) const
+       {       return mglData(true,mgl_data_subdata_ext(this,&xx,&yy,0));      }
+       inline mglData SubData(const mglData &xx) const
+       {       return mglData(true,mgl_data_subdata_ext(this,&xx,0,0));        }
        /// Get trace of the data array
        inline mglData Trace() const
        {       return mglData(true,mgl_data_trace(this));      }
@@ -313,6 +323,15 @@ public:
        inline void FillSample(const char *how)
        {       mgl_data_fill_sample(this,how); }
 
+       /// Return an approximated x-value (root) when dat(x) = val
+       inline mreal Solve(mreal val, bool use_spline=true, long i0=0) const
+       {       return mgl_data_solve_1d(this, val, use_spline, i0);            }
+       /// Return an approximated value (root) when dat(x) = val
+       inline mglData Solve(mreal val, char dir, bool norm=true) const
+       {       return mglData(true,mgl_data_solve(this, val, dir, 0, norm));   }
+       inline mglData Solve(mreal val, char dir, const mglData &i0, bool norm=true) const
+       {       return mglData(true,mgl_data_solve(this, val, dir, &i0, norm)); }
+
        /// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
        inline mreal Spline(mreal x,mreal y=0,mreal z=0) const
        {       return mgl_data_spline(this, x,y,z);    }
@@ -325,14 +344,6 @@ public:
        /// Interpolate by line the data to given point x,\a y,\a z which normalized in range [0, 1]
        inline mreal Linear1(mreal x,mreal y=0,mreal z=0) const
        {       return mgl_data_linear(this,x*(nx-1),y*(ny-1),z*(nz-1));        }
-       /// Return an approximated x-value (root) when dat(x) = val
-       inline mreal Solve(mreal val, bool use_spline=true, long i0=0) const
-       {       return mgl_data_solve_1d(this, val, use_spline, i0);            }
-       /// Return an approximated value (root) when dat(x) = val
-       inline mglData Solve(mreal val, char dir, bool norm=true) const
-       {       return mglData(true,mgl_data_solve(this, val, dir, 0, norm));   }
-       inline mglData Solve(mreal val, char dir, const mglData &i0, bool norm=true) const
-       {       return mglData(true,mgl_data_solve(this, val, dir, &i0, norm)); }
 
        /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]
        inline mreal Spline(mglPoint &dif, mreal x,mreal y=0,mreal z=0) const
@@ -358,6 +369,10 @@ public:
        inline mreal Maximal() const    {       return mgl_data_max(this);      }
        /// Get minimal value of the data
        inline mreal Minimal() const    {       return mgl_data_min(this);      }
+       /// Get maximal value of the data which is less than 0
+       inline mreal MaximalNeg() const {       return mgl_data_neg_max(this);  }
+       /// Get minimal value of the data which is larger than 0
+       inline mreal MinimalPos() const {       return mgl_data_pos_min(this);  }
        /// Get maximal value of the data and its position
        inline mreal Maximal(long &i,long &j,long &k) const
        {       return mgl_data_max_int(this,&i,&j,&k); }
@@ -390,10 +405,10 @@ public:
        {       return mgl_data_find_any(this,cond);    }
 
        /// Copy data from other mglData variable
-       inline mglData &operator=(const mglData &d)
-       {       if(this!=&d)    Set(d.a,d.nx,d.ny,d.nz);        return *this;   }
+       inline const mglData &operator=(const mglData &d)
+       {       if(this!=&d)    mgl_data_set(this,&d);  return d;       }
        inline mreal operator=(mreal val)
-       {       for(long i=0;i<nx*ny*nz;i++)    a[i]=val;       return val;     }
+       {       mgl_data_fill(this,val,val,'x');        return val;     }
        /// Multiply the data by other one for each element
        inline void operator*=(const mglData &d)        {       mgl_data_mul_dat(this,&d);      }
        /// Divide the data by other one for each element
@@ -426,7 +441,7 @@ inline mglData mglSTFA(const mglData &re, const mglData &im, long dn, char dir='
 {      return mglData(true, mgl_data_stfa(&re,&im,dn,dir));    }
 //-----------------------------------------------------------------------------
 /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini
-inline mglData mglPDE(mglBase *gr, const char *ham, const mglData &ini_re, const mglData &ini_im, mreal dz=0.1, mreal k0=100,const char *opt="")
+inline mglData mglPDE(HMGL gr, const char *ham, const mglData &ini_re, const mglData &ini_im, mreal dz=0.1, mreal k0=100,const char *opt="")
 {      return mglData(true, mgl_pde_solve(gr,ham, &ini_re, &ini_im, dz, k0,opt));      }
 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)
 inline mglData mglQO2d(const char *ham, const mglData &ini_re, const mglData &ini_im, const mglData &ray, mreal r=1, mreal k0=100)
@@ -441,6 +456,9 @@ inline mglData mglQO3d(const char *ham, const mglData &ini_re, const mglData &in
 /// Finds ray with starting point r0, p0 (and prepares ray data for mglQO2d)
 inline mglData mglRay(const char *ham, mglPoint r0, mglPoint p0, mreal dt=0.1, mreal tmax=10)
 {      return mglData(true, mgl_ray_trace(ham, r0.x, r0.y, r0.z, p0.x, p0.y, p0.z, dt, tmax)); }
+/// Saves result of ODE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini
+inline mglData mglODE(const char *df, const char *var, const mglData &ini, mreal dt=0.1, mreal tmax=10)
+{      return mglData(true, mgl_ode_solve_str(df,var, &ini, dt, tmax));        }
 /// Calculate Jacobian determinant for D{x(u,v), y(u,v)} = dx/du*dy/dv-dx/dv*dy/du
 inline mglData mglJacobian(const mglData &x, const mglData &y)
 {      return mglData(true, mgl_jacobian_2d(&x, &y));  }
@@ -453,3 +471,37 @@ inline mglData mglTriangulation(const mglData &x, const mglData &y, const mglDat
 inline mglData mglTriangulation(const mglData &x, const mglData &y)
 {      return mglData(true,mgl_triangulation_2d(&x,&y));       }
 //-----------------------------------------------------------------------------
+/// Get sub-array of the data with given fixed indexes
+inline mglData mglSubData(const mglData &dat, long xx, long yy=-1, long zz=-1)
+{      return mglData(true,mgl_data_subdata(&dat,xx,yy,zz));   }
+inline mglData mglSubData(const mglData &dat, const mglData &xx, const mglData &yy, const mglData &zz)
+{      return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,&zz));    }
+inline mglData mglSubData(const mglData &dat, const mglData &xx, const mglData &yy)
+{      return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,0));      }
+inline mglData mglSubData(const mglData &dat, const mglData &xx)
+{      return mglData(true,mgl_data_subdata_ext(&dat,&xx,0,0));        }
+//-----------------------------------------------------------------------------
+/// Prepare coefficients for global spline interpolation
+inline mglData mglGSplineInit(const mglData &xdat, const mglData &ydat)
+{      return mglData(true,mgl_gspline_init(&xdat, &ydat));    }
+/// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef
+inline mreal mglGSpline(const mglData &coef, mreal dx, mreal *d1=0, mreal *d2=0)
+{      return mgl_gspline(&coef, dx, d1,d2);   }
+//-----------------------------------------------------------------------------
+/// Wrapper class for expression evaluating
+class mglExpr
+{
+       HMEX ex;
+       mglExpr(const mglExpr &){}      // copying is not allowed
+       const mglExpr &operator=(const mglExpr &t){return t;}   // copying is not allowed
+public:
+       mglExpr(const char *expr)               {       ex = mgl_create_expr(expr);     }
+       ~mglExpr()      {       mgl_delete_expr(ex);    }
+       /// Return value of expression for given x,y,z variables
+       inline double Eval(double x, double y=0, double z=0)
+       {       return mgl_expr_eval(ex,x,y,z); }
+       /// Return value of expression differentiation over variable dir for given x,y,z variables
+       inline double Diff(char dir, double x, double y=0, double z=0)
+       {       return mgl_expr_diff(ex,dir, x,y,z);    }
+};
+//-----------------------------------------------------------------------------
index 88703baccf5de2515e64dafd1fb85e315bf2441d..168b1f9f5473fa3d564f822151223995c08aece2 100644 (file)
@@ -1,6 +1,6 @@
 /***************************************************************************
  * mgl.h is part of Math Graphic Library
- * Copyright (C) 2007-2012 Alexey Balakin <mathgl.abalakin@gmail.ru>       *
+ * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -42,7 +42,7 @@ public:
        {       gr = graph;             mgl_use_graph(gr,1);    }
        virtual ~mglGraph()
        {       if(mgl_use_graph(gr,-1)<1)      mgl_delete_graph(gr);   }
-       /// Get pointer to internal mglCanvas object
+       /// Get pointer to internal HMGL object
        inline HMGL Self()      {       return gr;      }
        /// Set default parameters for plotting
        inline void DefaultPlotParam()                  {       mgl_set_def_param(gr);  }
@@ -51,6 +51,14 @@ public:
        /// Get name of plot for saving filename
        inline const char *GetPlotId()  {       return mgl_get_plotid(gr);      }
 
+       /// Ask to stop drawing
+       inline void Stop(bool stop=true)        {       mgl_ask_stop(gr, stop); }
+       /// Check if plot termination is asked
+       inline bool NeedStop()  {       return mgl_need_stop(gr);       }
+       /// Set callback function for event processing
+       inline void SetEventFunc(void (*func)(void *), void *par=NULL)
+       {       mgl_set_event_func(gr, func, par);      }
+
        /// Set the transparency on/off.
        inline void Alpha(bool enable)                  {       mgl_set_alpha(gr, enable);      }
        /// Set default value of alpha-channel
@@ -139,6 +147,9 @@ public:
        /// Set axis range scaling -- simplified way to shift/zoom axis range -- need to replot whole image!
        inline void ZoomAxis(mglPoint p1=mglPoint(0,0,0,0), mglPoint p2=mglPoint(1,1,1,1))
        {       mgl_zoom_axis(gr, p1.x,p1.y,p1.z,p1.c, p2.x,p2.y,p2.z,p2.c);    }
+       /// Add [v1, v2] to the current range in direction dir
+       inline void AddRange(char dir, double v1, double v2)
+       {       mgl_add_range_val(gr, dir, v1, v2);     }
        /// Set range in direction dir as [v1, v2]
        inline void SetRange(char dir, double v1, double v2)
        {       mgl_set_range_val(gr, dir, v1, v2);     }
@@ -206,9 +217,16 @@ public:
        {       mgl_set_ticks_val(gr,dir,&v,lbl,add);   }
        inline void SetTicksVal(char dir, const mglData &v, const wchar_t *lbl, bool add=false)
        {       mgl_set_ticks_valw(gr,dir,&v,lbl,add);  }
-       /// Set the ticks parameters
-       inline void SetTicks(char dir, double d=0, int ns=0, double org=NaN)
-       {       mgl_set_ticks(gr, dir, d, ns, org);     }
+       /// Add manual tick at given position. Use "" to disable this feature.
+       inline void AddTick(char dir, double val, const char *lbl)
+       {       mgl_add_tick(gr,dir,val,lbl);   }
+       inline void AddTick(char dir, double val, const wchar_t *lbl)
+       {       mgl_add_tickw(gr,dir,val,lbl);  }
+       /// Set the ticks parameters and string for its factor
+       inline void SetTicks(char dir, double d=0, int ns=0, double org=NaN, const char *factor="")
+       {       mgl_set_ticks_fact(gr, dir, d, ns, org, factor);        }
+       inline void SetTicks(char dir, double d, int ns, double org, const wchar_t *factor)
+       {       mgl_set_ticks_factw(gr, dir, d, ns, org, factor);       }
        /// Auto adjust ticks
        inline void Adjust(const char *dir="xyzc")
        {       mgl_adjust_ticks(gr, dir);      }
@@ -278,6 +296,9 @@ public:
        /// Set angle of view independently from Rotate().
        inline void View(double TetX,double TetZ=0,double TetY=0)
        {       mgl_view(gr, TetX, TetZ, TetY); }
+       /// Set angle of view independently from Rotate().
+       inline void ViewAsRotate(double TetZ,double TetX,double TetY=0)
+       {       mgl_view(gr, -TetX, -TetZ, -TetY);      }
        /// Zoom in/out a part of picture (use Zoom(0, 0, 1, 1) for restore default)
        inline void Zoom(double x1, double y1, double x2, double y2)
        {       mgl_zoom(gr, x1, y1, x2, y2);   }
@@ -289,7 +310,7 @@ public:
        /// Get plot quality
        inline int GetQuality() {       return mgl_get_quality(gr);     }
        /// Set drawing region for Quality&4
-       inline void SetDrawReg(long nx, long ny, long m){       mgl_set_draw_reg(gr,nx,ny,m);   }
+       inline void SetDrawReg(long nx=1, long ny=1, long m=0)  {       mgl_set_draw_reg(gr,nx,ny,m);   }
        /// Start group of objects
        inline void StartGroup(const char *name)                {       mgl_start_group(gr, name);      }
        /// End group of objects
@@ -378,6 +399,8 @@ public:
        inline void SetFrame(int i)     {       mgl_set_frame(gr, i);   }
        /// Append drawing data from i-th frame (work if MGL_VECT_FRAME is set on)
        inline void ShowFrame(int i){   mgl_show_frame(gr, i);  }
+       /// Clear list of primitives for current drawing
+       inline void ClearFrame()        {       mgl_clear_frame(gr);    }
 
        /// Start write frames to cinema using GIF format
        inline void StartGIF(const char *fname, int ms=100)
@@ -392,21 +415,23 @@ public:
        {       mgl_import_mgld(gr, fname, add);        }
 
        /// Copy RGB values into array which is allocated by user
-       inline void GetRGB(char *imgdata, int imglen)
+       inline bool GetRGB(char *imgdata, int imglen)
        {
                long w=mgl_get_width(gr), h=mgl_get_height(gr);
                if(imglen>=3*w*h)       memcpy(imgdata, mgl_get_rgb(gr),3*w*h);
+               return imglen>=3*w*h;
        }
        inline const unsigned char *GetRGB()            {       return mgl_get_rgb(gr); }
        /// Copy RGBA values into array which is allocated by user
-       inline void GetRGBA(char *imgdata, int imglen)
+       inline bool GetRGBA(char *imgdata, int imglen)
        {
                long w=mgl_get_width(gr), h=mgl_get_height(gr);
                if(imglen>=4*w*h)       memcpy(imgdata, mgl_get_rgba(gr),4*w*h);
+               return imglen>=4*w*h;
        }
        inline const unsigned char *GetRGBA()   {       return mgl_get_rgba(gr);        }
        /// Copy BGRN values into array which is allocated by user
-       inline void GetBGRN(unsigned char *imgdata, int imglen)
+       inline bool GetBGRN(unsigned char *imgdata, int imglen)
        {
                long w=mgl_get_width(gr), h=mgl_get_height(gr), i;
                const unsigned char *buf=mgl_get_rgb(gr);
@@ -417,7 +442,16 @@ public:
                        imgdata[4*i+2] = buf[3*i];
                        imgdata[4*i+3] = 255;
                }
+               return imglen>=4*w*h;
+       }
+       /// Copy RGBA values of background image into array which is allocated by user
+       inline bool GetBackground(char *imgdata, int imglen)
+       {
+               long w=mgl_get_width(gr), h=mgl_get_height(gr);
+               if(imglen>=4*w*h)       memcpy(imgdata, mgl_get_background(gr),4*w*h);
+               return imglen>=4*w*h;
        }
+       inline const unsigned char *GetBackground()     {       return mgl_get_background(gr);  }
        /// Get width of the image
        inline int GetWidth()   {       return mgl_get_width(gr);       }
        /// Get height of the image
@@ -450,10 +484,18 @@ public:
 
        /// Clear up the frame
        inline void Clf(double r, double g, double b)   {       mgl_clf_rgb(gr, r, g, b);       }
+       inline void Clf(const char *col)        {       mgl_clf_str(gr, col);   }
        inline void Clf(char col)       {       mgl_clf_chr(gr, col);   }
        inline void Clf()       {       mgl_clf(gr);    }
        /// Clear unused points and primitives. Useful only in combination with SetFaceNum().
        inline void ClearUnused()       {       mgl_clear_unused(gr);   }
+
+       /// Load background image
+       inline void LoadBackground(const char *fname, double alpha=1)
+       {       mgl_load_background(gr,fname,alpha);    }
+       /// Force drawing the image and use it as background one
+       inline void Rasterize()                 {       mgl_rasterize(gr);      }
+
        /// Draws the point (ball) at position {x,y,z} with color c
        inline void Ball(mglPoint p, char c='r')
        {       char s[3]={'.',c,0};    mgl_mark(gr, p.x, p.y, p.z, s); }
@@ -500,6 +542,15 @@ public:
        /// Draws the rhomb between points p1,p2 with color stl and width r
        inline void Rhomb(mglPoint p1, mglPoint p2, double r, const char *stl="r")
        {       mgl_rhomb(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, r,stl);       }
+       /// Draws the polygon based on points p1,p2 with color stl
+       inline void Polygon(mglPoint p1, mglPoint p2, int n, const char *stl="r")
+       {       mgl_polygon(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, n,stl);     }
+       /// Draws the arc around axis pr with center at p0 and starting from p1, by color stl and angle a (in degrees)
+       inline void Arc(mglPoint p0, mglPoint pr, mglPoint p1, double a, const char *stl="r")
+       {       mgl_arc_ext(gr, p0.x,p0.y,p0.z, pr.x,pr.y,pr.z, p1.x,p1.y,p1.z, a,stl); }
+       /// Draws the arc around axis 'z' with center at p0 and starting from p1, by color stl and angle a (in degrees)
+       inline void Arc(mglPoint p0, mglPoint p1, double a, const char *stl="r")
+       {       mgl_arc_ext(gr, p0.x,p0.y,p0.z, 0,0,1, p1.x,p1.y,p0.z, a,stl);  }
 
        /// Print text in position p with specified font
        inline void Putsw(mglPoint p,const wchar_t *text,const char *font=":C",double size=-1)
@@ -616,6 +667,11 @@ public:
        {       mgl_region(gr, &y1, &y2, pen, opt);     }
        inline void Region(const mglData &x, const mglData &y1, const mglData &y2, const char *pen="", const char *opt="")
        {       mgl_region_xy(gr, &x, &y1, &y2, pen, opt);      }
+       /// Fill area (draw ribbon) between curves {x1,y1,z1} and {x2,y2,z2}
+       inline void Region(const mglData &x1, const mglData &y1, const mglData &z1, const mglData &x2, const mglData &y2, const mglData &z2, const char *pen="", const char *opt="")
+       {       mgl_region_3d(gr, &x1, &y1, &z1, &x2, &y2, &z2, pen, opt);      }
+       inline void Region(const mglData &x1, const mglData &y1, const mglData &x2, const mglData &y2, const char *pen="", const char *opt="")
+       {       mgl_region_3d(gr, &x1, &y1, NULL, &x2, &y2, NULL, pen, opt);    }
        /// Draw vertical lines from points {x,y,z} to axis plane
        inline void Stem(const mglData &x, const mglData &y, const mglData &z, const char *pen="", const char *opt="")
        {       mgl_stem_xyz(gr, &x, &y, &z, pen, opt); }
@@ -639,6 +695,7 @@ public:
        /// Draw chart for data a
        inline void Chart(const mglData &a, const char *colors="", const char *opt="")
        {       mgl_chart(gr, &a, colors,opt);  }
+
        /// Draw Open-High-Low-Close (OHLC) diagram
        inline void OHLC(const mglData &x, const mglData &open, const mglData &high, const mglData &low, const mglData &close, const char *pen="", const char *opt="")
        {       mgl_ohlc_x(gr, &x, &open,&high,&low,&close,pen,opt);    }
@@ -1073,6 +1130,16 @@ public:
        {       mgl_tricont_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt);  }
        inline void TriContV(const mglData &v, const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", const char *opt="")
        {       mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt);     }
+       inline void TriCont(const mglData &v, const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", const char *opt="")
+       {       mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt);     }
+
+       /// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c.
+       inline void TriContVt(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
+       {       mgl_tricontv_xyc(gr, &nums, &x, &y, &z, sch, opt);      }
+       inline void TriContVt(const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", const char *opt="")
+       {       mgl_tricontv_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt); }
+       inline void TriContVt(const mglData &v, const mglData &nums, const mglData &x, const mglData &y, const mglData &z, const mglData &a, const char *sch="", const char *opt="")
+       {       mgl_tricontv_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt);    }
 
        /// Draw dots in points {x,y,z}.
        inline void Dots(const mglData &x, const mglData &y, const mglData &z, const char *sch="", const char *opt="")
@@ -1215,7 +1282,7 @@ public:
        inline void Execute(mglGraph *gr, FILE *fp, bool print=false)
        {       mgl_parse_file(gr->Self(), pr, fp, print);      }
 
-       /// Return type of command: 0 - not found, 1 - data plot, 2 - other plot,
+       /// Return type of command: 0 - not found, 1 - other data plot, 2 - func plot,
        ///             3 - setup, 4 - data handle, 5 - data create, 6 - subplot, 7 - program
        ///             8 - 1d plot, 9 - 2d plot, 10 - 3d plot, 11 - dd plot, 12 - vector plot
        ///             13 - axis, 14 - primitives, 15 - axis setup, 16 - text/legend, 17 - data transform
@@ -1256,16 +1323,23 @@ public:
 
        /// Find variable with given name or add a new one
        /// NOTE !!! You must not delete obtained data arrays !!!
-       inline mglVar *AddVar(const char *name)
-       {       return dynamic_cast<mglVar *>(mgl_parser_add_var(pr, name));    }
-       inline mglVar *AddVar(const wchar_t *name)
-       {       return dynamic_cast<mglVar *>(mgl_parser_add_varw(pr, name));   }
+       inline mglData *AddVar(const char *name)
+       {       return mgl_parser_add_var(pr, name);    }
+       inline mglData *AddVar(const wchar_t *name)
+       {       return mgl_parser_add_varw(pr, name);   }
        /// Find variable with given name or return NULL if no one
        /// NOTE !!! You must not delete obtained data arrays !!!
-       inline mglVar *FindVar(const char *name)
-       {       return dynamic_cast<mglVar *>(mgl_parser_find_var(pr, name));   }
-       inline mglVar *FindVar(const wchar_t *name)
-       {       return dynamic_cast<mglVar *>(mgl_parser_find_varw(pr, name));  }
+       inline mglData *FindVar(const char *name)
+       {       return mgl_parser_find_var(pr, name);   }
+       inline mglData *FindVar(const wchar_t *name)
+       {       return mgl_parser_find_varw(pr, name);  }
+       /// Get variable with given id. Can be NULL for temporary ones.
+       /// NOTE !!! You must not delete obtained data arrays !!!
+       inline mglData *GetVar(unsigned long id)
+       {       return mgl_parser_get_var(pr,id);       }
+       /// Get number of variables
+       inline long GetNumVar()
+       {       return mgl_parser_num_var(pr);  }
        /// Delete variable with name
        inline void DeleteVar(const char *name)         {       mgl_parser_del_var(pr, name);           }
        inline void DeleteVar(const wchar_t *name)      {       mgl_parser_del_varw(pr, name);          }
@@ -1273,37 +1347,3 @@ public:
        void DeleteAll()        {       mgl_parser_del_all(pr); }
 };
 //-----------------------------------------------------------------------------
-/// Wrapper class expression evaluating
-class mglExpr
-{
-       HMEX ex;
-public:
-       mglExpr(const char *expr)               {       ex = mgl_create_expr(expr);     }
-       ~mglExpr()      {       mgl_delete_expr(ex);    }
-       /// Return value of expression for given x,y,z variables
-       inline double Eval(double x, double y=0, double z=0)
-       {       return mgl_expr_eval(ex,x,y,z); }
-       /// Return value of expression differentiation over variable dir for given x,y,z variables
-       inline double Diff(char dir, double x, double y=0, double z=0)
-       {       return mgl_expr_diff(ex,dir, x,y,z);    }
-};
-//-----------------------------------------------------------------------------
-/// Wrapper class expression evaluating
-class mglExprC
-{
-       HAEX ex;
-public:
-       mglExprC(const char *expr)              {       ex = mgl_create_cexpr(expr);    }
-       ~mglExprC()     {       mgl_delete_cexpr(ex);   }
-       /// Return value of expression for given x,y,z variables
-       inline dual Eval(dual x, dual y=0, dual z=0)
-       {       return mgl_cexpr_eval(ex,x,y,z);        }
-       /// Return value of expression for given x,y,z,u,v,w variables
-       inline dual Eval(dual x, dual y, dual z, dual u, dual v, dual w)
-       {
-               dual var[26];
-               var['x'-'a']=x; var['y'-'a']=y; var['z'-'a']=z;
-               var['u'-'a']=u; var['v'-'a']=v; var['w'-'a']=w;
-               return mgl_cexpr_eval_v(ex,var);        }
-};
-//-----------------------------------------------------------------------------
diff --git a/mgllab/CMakeLists.txt b/mgllab/CMakeLists.txt
deleted file mode 100644 (file)
index f64ad22..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-if(MGL_HAVE_FLTK)
-       include_directories(${FLTK_INCLUDE_DIR})
-       set(mgl_lab_src animate.cpp editor.cpp help.cpp mathgl.cpp setup.cpp write.cpp data.cpp grid.cpp main.cpp option.cpp table.cpp)
-       add_executable(mgllab ${mgl_lab_src})
-       target_link_libraries(mgllab mgl mgl-fltk ${FLTK_LIBRARIES})
-       install(
-               TARGETS mgllab
-               RUNTIME DESTINATION bin )
-endif(MGL_HAVE_FLTK)
-
diff --git a/mgllab/animate.cpp b/mgllab/animate.cpp
deleted file mode 100644 (file)
index c6de245..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/* animate.cpp is part of UDAV
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <ctype.h>
-#include <string.h>
-#include <FL/Fl_Tabs.H>
-#include <FL/Fl_Round_Button.H>
-#include <FL/Fl_Multiline_Input.H>
-#include <FL/Fl_Float_Input.H>
-#include "udav.h"
-//-----------------------------------------------------------------------------
-struct ArgumentDlg
-{
-public:
-       Fl_Window* wnd;
-       int OK;
-       Fl_Input *a[10];
-
-       ArgumentDlg()   {       memset(this,0,sizeof(ArgumentDlg));     create_dlg();   }
-       ~ArgumentDlg()  {       delete wnd;     }
-       void FillResult();
-protected:
-       void create_dlg();
-} argument_dlg;
-//-----------------------------------------------------------------------------
-void argument_dlg_cb(Fl_Widget *, void *v)
-{      argument_dlg.OK = true; ((Fl_Window *)v)->hide();       }
-//-----------------------------------------------------------------------------
-void ArgumentDlg::create_dlg()
-{
-       wnd = new Fl_Window(325, 275, gettext("Script arguments"));
-       a[1] = new Fl_Input(10, 25, 150, 25, gettext("Value for $1"));  a[1]->align(FL_ALIGN_TOP_LEFT);
-       a[2] = new Fl_Input(165, 25, 150, 25, gettext("Value for $2")); a[2]->align(FL_ALIGN_TOP_LEFT);
-       a[3] = new Fl_Input(10, 70, 150, 25, gettext("Value for $3"));  a[3]->align(FL_ALIGN_TOP_LEFT);
-       a[4] = new Fl_Input(165, 70, 150, 25, gettext("Value for $4")); a[4]->align(FL_ALIGN_TOP_LEFT);
-       a[5] = new Fl_Input(10, 115, 150, 25, gettext("Value for $5")); a[5]->align(FL_ALIGN_TOP_LEFT);
-       a[6] = new Fl_Input(165, 115, 150, 25, gettext("Value for $6"));a[6]->align(FL_ALIGN_TOP_LEFT);
-       a[7] = new Fl_Input(10, 160, 150, 25, gettext("Value for $7")); a[7]->align(FL_ALIGN_TOP_LEFT);
-       a[8] = new Fl_Input(165, 160, 150, 25, gettext("Value for $8"));a[8]->align(FL_ALIGN_TOP_LEFT);
-       a[9] = new Fl_Input(10, 205, 150, 25, gettext("Value for $9")); a[9]->align(FL_ALIGN_TOP_LEFT);
-       a[0] = new Fl_Input(165, 205, 150, 25, gettext("Value for $0"));a[0]->align(FL_ALIGN_TOP_LEFT);
-
-       Fl_Button *o;
-       o = new Fl_Button(75, 240, 75, 25, gettext("Cancel"));          o->callback(close_dlg_cb,wnd);
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);
-       o = new Fl_Return_Button(175, 240, 75, 25, gettext("OK"));      o->callback(argument_dlg_cb,wnd);
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);
-       wnd->end();
-}
-//-----------------------------------------------------------------------------
-void ArgumentDlg::FillResult()
-{
-       if(a[0]->value()[0])    Parse->AddParam(0,a[0]->value());
-       if(a[1]->value()[0])    Parse->AddParam(1,a[1]->value());
-       if(a[2]->value()[0])    Parse->AddParam(2,a[2]->value());
-       if(a[3]->value()[0])    Parse->AddParam(3,a[3]->value());
-       if(a[4]->value()[0])    Parse->AddParam(4,a[4]->value());
-       if(a[5]->value()[0])    Parse->AddParam(5,a[5]->value());
-       if(a[6]->value()[0])    Parse->AddParam(6,a[6]->value());
-       if(a[7]->value()[0])    Parse->AddParam(7,a[7]->value());
-       if(a[8]->value()[0])    Parse->AddParam(8,a[8]->value());
-       if(a[9]->value()[0])    Parse->AddParam(9,a[9]->value());
-}
-//-----------------------------------------------------------------------------
-void argument_cb(Fl_Widget *, void *)
-{
-       ArgumentDlg *s = &argument_dlg;
-       s->OK = false;
-       s->wnd->set_modal();
-       s->wnd->show();
-       while(s->wnd->shown())  Fl::wait();
-       if(s->OK)       s->FillResult();
-}
-//-----------------------------------------------------------------------------
-void argument_set(int n, const char *s)
-{
-       if(n<0 || n>9)  return;
-       Parse->AddParam(n,s);
-       argument_dlg.a[n]->value(s);
-}
-//-----------------------------------------------------------------------------
-AnimateDlg animate_dlg;
-//-----------------------------------------------------------------------------
-void animate_dlg_cb(Fl_Widget *, void *v)
-{
-       animate_dlg.swap = false;
-       if(!animate_dlg.rt->value() && !animate_dlg.rv->value())
-               fl_message(gettext("You have to select textual string or numeric cycle"));
-       else if(animate_dlg.rv->value() && animate_dlg.dx->value()==0)
-               fl_message(gettext("You have to set nonzero step in cycle"));
-       else
-       {
-               double t0=atof(animate_dlg.x0->value()), t1=atof(animate_dlg.x1->value()), dt=atof(animate_dlg.dx->value());
-               if((t1-t0)*dt<0)
-               {
-                       if(fl_ask(gettext("Order of first and last value is wrong. Swap it?")))
-                       {
-                               char s[32];     snprintf(s,32,"%g",t0);
-                               animate_dlg.x0->value(animate_dlg.x1->value());
-                               animate_dlg.x1->value(s);
-                       }
-                       else
-                       {       fl_message(gettext("Wrong boundaries"));        return; }
-               }
-               animate_dlg.OK = true;  ((Fl_Window *)v)->hide();
-       }
-}
-//-----------------------------------------------------------------------------
-void animate_rad_cb(Fl_Widget *, void *v)
-{
-       animate_dlg.rt->value(0);
-       animate_dlg.rv->value(0);
-       ((Fl_Round_Button *)v)->value(1);
-}
-//-----------------------------------------------------------------------------
-void animate_put_cb(Fl_Widget *, void *)
-{
-       if(animate_dlg.rt->value())
-       {
-               if(animate_dlg.txt->value()==0 || strlen(animate_dlg.txt->value())==0)  return;
-               char *s = new char[1+strlen(animate_dlg.txt->value())], *a=s;
-               strcpy(s, animate_dlg.txt->value());
-               for(int i=0;s[i]!=0;i++)
-               {
-                       if(s[i]=='\n')
-                       {
-                               s[i] = 0;
-                               textbuf->append("\n##a ");
-                               textbuf->append(a);
-                               a = s+i+1;
-                       }
-               }
-               if(*a)
-               {       textbuf->append("\n##a ");      textbuf->append(a);     }
-               delete []s;
-       }
-       else if(animate_dlg.rv->value())
-       {
-               char *s = new char[128];
-               snprintf(s,128,"\n##c %s %s %s",animate_dlg.x0->value(),animate_dlg.x1->value(),animate_dlg.dx->value());
-               textbuf->append(s);
-               delete []s;
-       }
-}
-//-----------------------------------------------------------------------------
-void AnimateDlg::create_dlg()
-{
-       wnd = new Fl_Window(335, 350, gettext("Animation"));
-       new Fl_Box(10, 5, 315, 25, gettext("Redraw picture for $0 equal to:"));
-       rt = new Fl_Round_Button(10, 30, 200, 25, gettext("strings in lines below"));
-       rt->callback(animate_rad_cb, rt);
-       rv = new Fl_Round_Button(220, 30, 105, 25, gettext("values"));
-       rv->callback(animate_rad_cb, rv);
-       txt = new Fl_Multiline_Input(10, 60, 200, 250);
-       x0 = new Fl_Float_Input(220, 80, 105, 25, gettext("from"));                     x0->align(FL_ALIGN_TOP_LEFT);
-       x1 = new Fl_Float_Input(220, 130, 105, 25, gettext("to"));                      x1->align(FL_ALIGN_TOP_LEFT);
-       dx = new Fl_Float_Input(220, 180, 105, 25, gettext("with step"));       dx->align(FL_ALIGN_TOP_LEFT);
-
-       Fl_Button *o;
-       o = new Fl_Button(230, 215, 80, 25, gettext("Cancel"));         o->callback(close_dlg_cb,wnd);
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);
-       o = new Fl_Return_Button(230, 250, 80, 25, gettext("OK"));      o->callback(animate_dlg_cb,wnd);
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);
-       save = new Fl_Check_Button(220, 285, 105, 25, gettext("save slides"));
-       save->tooltip(gettext("Keep slides in memory (faster animation but require more memory)"));
-       save->down_box(FL_DOWN_BOX);    save->hide();
-
-       o = new Fl_Button(10, 315, 100, 25, gettext("Put to script"));  o->callback(animate_put_cb,wnd);
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);
-       dt = new Fl_Float_Input(220, 315, 105, 25, gettext("Delay (in sec)"));//        dx->align(FL_ALIGN_TOP_LEFT);
-
-       wnd->end();
-}
-//-----------------------------------------------------------------------------
-void AnimateDlg::FillResult(Fl_MGL* e)
-{
-       e->NArgs = e->ArgCur = 0;
-       if(e->ArgBuf)   delete [](e->ArgBuf);   e->ArgBuf = 0;
-       e->AnimDelay = atof(dt->value());
-       if(rt->value())
-       {
-               char *s;
-               e->ArgBuf = new char[1+strlen(txt->value())];
-               strncpy(e->ArgBuf, txt->value(),32);
-               s = e->Args[0] = e->ArgBuf;     e->NArgs = 1;
-               for(int i=0;s[i]!=0;i++)
-                       if(s[i]=='\n')
-                       {
-                               s[i] = 0;       e->Args[e->NArgs] = s+i+1;      e->NArgs += 1;
-                       }
-               if(e->Args[e->NArgs-1][0]==0)   e->NArgs -= 1;
-       }
-       else if(rv->value() && atof(dx->value()))
-       {
-               double t0=atof(x0->value()), t1=atof(x1->value()), dt=atof(dx->value()), t;
-               if((t1-t0)/dt<1)
-               {
-                       e->ArgBuf = new char[32];       snprintf(e->ArgBuf,32,"%g",t0);
-                       e->NArgs = 1;   e->Args[0] = e->ArgBuf; return;
-               }
-               if((t1-t0)/dt>999)
-               {
-                       fl_message(gettext("Too many slides. Reduce to 1000 slides."));
-                       dt = (t1-t0)/998;
-               }
-               e->ArgBuf = new char[32*int(1+(t1-t0)/dt)];
-               for(t=t0;(dt>0&&t<=t1)||(dt<0&&t>=t1);t+=dt)
-               {
-                       snprintf(e->ArgBuf + 32*e->NArgs,32,"%g\0",t);
-                       e->Args[e->NArgs] = e->ArgBuf + 32*e->NArgs;
-                       e->NArgs += 1;
-               }
-       }
-       else    fl_message(gettext("No selection. So nothing to do"));
-}
-//-----------------------------------------------------------------------------
-void animate_cb(Fl_Widget *, void *v)
-{
-       ScriptWindow* e = (ScriptWindow*)v;
-       AnimateDlg *s = &animate_dlg;
-       s->OK = false;
-       s->wnd->set_modal();
-       s->wnd->show();
-       while(s->wnd->shown())  Fl::wait();
-       if(s->OK)       s->FillResult(e->graph);
-}
-//-----------------------------------------------------------------------------
-void cpy_arg_buf(const char *str, long *size, char **buf)
-{
-       const char *end;
-       for(end=str; *end>' '; end++);
-       if(end>=str+*size)
-       {       *size = end-str+1;      *buf = (char *)realloc(*buf,*size);     }
-       memset(*buf,0,*size);
-       strncpy(*buf,str,end-str);
-}
-//-----------------------------------------------------------------------------
-void fill_animate(const char *text)
-{
-       long size=128,i;
-       const char *str = text;
-       char *buf = (char *)malloc(size), tmp[4]="#$0";
-       for(i=0;i<10;i++)       // first read script arguments (if one)
-       {
-               tmp[2] = '0'+i;
-               if((str=strstr(text,tmp)))
-               {
-                       str+=3;
-                       while(*str>0 && *str<=' ' && *str!='\n')        str++;
-                       cpy_arg_buf(str,&size,&buf);
-                       argument_dlg.a[i]->value(buf);
-                       Parse->AddParam(i,buf);
-               }
-       }
-
-       char *a = (char *)malloc(size);
-       memset(a,0,size);       i = 0;
-       str = text;
-       while((str = strstr(str, "##")))        // now read animation parameters
-       {
-               if(str[2]=='a')
-               {
-                       str += 3;
-                       while(*str>0 && *str<=' ' && *str!='\n')        str++;
-                       if(*str==0 || *str=='\n')       return; // empty comment
-                       cpy_arg_buf(str,&size,&buf);
-                       if(i==0)        Parse->AddParam(0,buf); // put first value as $0
-                       i += strlen(buf)+1;
-                       if(i>=size)
-                       {
-                               size = (1+ (i+2)/128)*128;
-                               a = (char *)realloc(a,size);
-                       }
-                       strcat(a,buf);  strcat(a,"\n");
-               }
-               if(str[2]=='c')
-               {
-                       str += 3;
-                       register long j=0,l=strlen(str);
-                       char *s=new char[l+1],*s1=0,*s2=0,*s3=0;
-                       bool sp=true;   strcpy(s,str);
-                       for(j=0;j<l;j++)
-                       {
-                               if(isspace(s[j]))       {       s[j]=0; sp=true;        }
-                               else if(sp)
-                               {
-                                       sp=false;
-                                       if(!s1) s1=s+j; else if(!s2) s2=s+j;    else s3=s+j;
-                               }
-                               animate_dlg.x0->value(s1);
-                               animate_dlg.x1->value(s2);
-                               animate_dlg.dx->value(s3);
-                               animate_dlg.rv->value(1);
-                       }
-                       delete []s;
-               }
-       }
-       if(i)
-       {       animate_dlg.txt->value(a);      animate_dlg.rt->value(1);       }
-       free(buf);      free(a);
-}
diff --git a/mgllab/data.cpp b/mgllab/data.cpp
deleted file mode 100644 (file)
index f84d34d..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/* data.cpp is part of UDAV\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-#include <FL/Fl_Choice.H>\r
-#include <FL/Fl_Spinner.H>\r
-#include <FL/Fl_Output.H>\r
-#include <FL/Fl_Check_Button.H>\r
-#include "udav.h"\r
-//-----------------------------------------------------------------------------\r
-void option_in_cb(Fl_Widget *, void *v);\r
-void style_in_cb(Fl_Widget *, void *v);\r
-//-----------------------------------------------------------------------------\r
-struct VarDlg\r
-{\r
-       Fl_Window *wnd;\r
-       bool OK;\r
-\r
-       Fl_Choice *var;\r
-       Fl_Spinner *dim1, *dim2, *dim3;\r
-       VarDlg()        {       memset(this,0,sizeof(VarDlg));  create_dlg();   }\r
-       ~VarDlg()       {       delete wnd;     }\r
-       void create_dlg();\r
-       char *get_result();\r
-       void init();\r
-} var_dlg;\r
-//-----------------------------------------------------------------------------\r
-void VarDlg::init()\r
-{\r
-       char ss[1024];\r
-       var->clear();\r
-       mglVar *v=Parse->FindVar("");\r
-       while(v)\r
-       {\r
-               wcstombs(ss,v->s.c_str(),1024);\r
-               var->add(ss,0,0,v);\r
-               v = v->next;\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-char *VarDlg::get_result()\r
-{\r
-       static char res[64];\r
-       char a1[16]=":",a2[16]=":",a3[16]=":";\r
-       res[0]=0;\r
-       if(var->value()<0)      return res;\r
-       const Fl_Menu_Item m=var->menu()[var->value()];\r
-       if(m.text[0])\r
-       {\r
-               if(dim3->value()>=0)\r
-               {\r
-                       if(dim1->value()>=0)    snprintf(a1,16,"%g",dim1->value());\r
-                       if(dim2->value()>=0)    snprintf(a2,16,"%g",dim2->value());\r
-                       snprintf(a3,16,"%g",dim3->value());\r
-                       snprintf(res,64,"%s(%s,%s,%s)",m.text,a1,a2,a3);\r
-               }\r
-               else if(dim2->value()>=0)\r
-               {\r
-                       if(dim1->value()>=0)    snprintf(a1,16,"%g",dim1->value());\r
-                       snprintf(a2,16,"%g",dim2->value());\r
-                       snprintf(res,64,"%s(%s,%s)",m.text,a1,a2);\r
-               }\r
-               else if(dim1->value()>=0)\r
-               {\r
-                       snprintf(a1,16,"%g",dim1->value());\r
-                       snprintf(res,64,"%s(%s)",m.text,a1);\r
-               }\r
-               else    strncpy(res,m.text,64);\r
-       }\r
-       return res;\r
-}\r
-//-----------------------------------------------------------------------------\r
-void var_chg_cb(Fl_Widget *, void *)\r
-{\r
-       const Fl_Menu_Item m=var_dlg.var->menu()[var_dlg.var->value()];\r
-       if(m.text[0] && m.user_data())\r
-       {\r
-               mglVar *a = (mglVar *)m.user_data();\r
-               var_dlg.dim1->range(-1,a->nx-1);\r
-               var_dlg.dim2->range(-1,a->ny-1);\r
-               var_dlg.dim3->range(-1,a->nz-1);\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void var_in_cb(Fl_Widget *, void *v)\r
-{\r
-       Fl_Input *e = (Fl_Input*)v;\r
-       VarDlg *s = &var_dlg;\r
-       s->OK = false;\r
-       s->init();\r
-       s->wnd->set_modal();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       e->value(s->get_result());\r
-}\r
-//-----------------------------------------------------------------------------\r
-void var_dlg_cb(Fl_Widget *, void *v)\r
-{      var_dlg.OK = true;      ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void VarDlg::create_dlg()\r
-{\r
-       wnd = new Fl_Double_Window(190, 180, gettext("Variable"));\r
-       var = new Fl_Choice(100, 10, 75, 25, gettext("Variable name")); // !!!  add variables here !!!\r
-       var->callback(var_chg_cb);\r
-       dim1 = new Fl_Spinner(100, 40, 75, 25, gettext("First index"));\r
-       dim1->range(-1,0);      dim1->value(-1);        dim1->step(1);\r
-       dim1->tooltip(gettext("Value of first dimensions (-1 for all range)"));\r
-       dim2 = new Fl_Spinner(100, 70, 75, 25, gettext("Second index"));\r
-       dim2->range(-1,0);      dim2->value(-1);        dim2->step(1);\r
-       dim2->tooltip(gettext("Value of second dimensions (-1 for all range)"));\r
-       dim3 = new Fl_Spinner(100, 100, 75, 25, gettext("Third index"));\r
-       dim3->range(-1,0);      dim3->value(-1);        dim3->step(1);\r
-       dim3->tooltip(gettext("Value of third dimensions (-1 for all range)"));\r
-       Fl_Button *o;\r
-       o = new Fl_Button(15, 140, 75, 25, gettext("Cancel"));          o->callback(close_dlg_cb,wnd);\r
-       o = new Fl_Return_Button(100, 140, 75, 25, gettext("OK"));      o->callback(var_dlg_cb,wnd);\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-const char *cmds[]={\r
-"plot|area|bars|barh|boxplot|chart|error|mark|region|stem|step|tens|textmark|torus|tube",\r
-"surf|axial|belt|boxs|cont|contd|contf|dens|fall|grid2|mesh|tile|grad",\r
-"surf3|cloud|beam|cont3|conta|contf3|contfa|dens3|densa|grid3|grida",\r
-"map|stfa|surfa|surfc|tile|surf3a|surf3c",\r
-"flow|pipe|traj|vect|vectc|vectl|dew",\r
-"contx|conty|contz|contfx|contfy|contfz|densx|densy|densz|triplot|tricont|quadplot|crust|dots",\r
-"text|title|fgets|legend|addlegend|clearlegend|legendbox",\r
-"new|var|copy|delete|insert|read|readmat|readall|readhdf|save|savehdf|export|import|info|idset",\r
-"fill|fillsample|modify|put|crop|extend|rearrange|squeeze|transpose|cumsum|diff|diff2|sinfft|cosfft|hankel|envelop|integrate|mirror|norm|normsl|sew|smooth|swap|roll|addto|subto|divto|multo",\r
-"combine|evaluate|max|min|hist|jacobian|momentum|resize|sum|trace|transform|transforma|stfad|pde|qo2d|ray",\r
-"axis|box|colorbar|grid|xlabel|ylabel|zlabel|tlabel",\r
-"alpha|alphadef|transparent|transptype|ambient|light|fog|arrowsize|barwidth|linewidth|marksize|plotfactor|zoom|cut|axialdir|mesgnum|font|palette|rotatetext",\r
-"axis|ranges|caxis|crange|xrange|yrange|zrange|origin|ternary|adjust|ctick|xtick|ytick|ztick|ticklen|tickstl",\r
-"subplot|inplot|rotate|aspect|columnplot|perspective",\r
-"call|func|chdir|define|if|elseif|else|endif|for|next|once|stop|write|setsize",\r
-"fit|fits|putsfit",\r
-"fplot|fsurf|ball|cone|curve|drop|facex|facey|facez|line|rect|sphere"};\r
-const char *first[]={"plot", "surf", "surf3", "map", "flow", "contx", "text", "new", "fill", "combine", "alpha", "axis", "subplot", "call", "fit", "fplot"};\r
-const char *cmd_types="1D plots|2D plots|3D plots|Dual plots|Vector plots|Other plots|Text and legend|Create data and I-O|Data handling|Data extraction|Axis and colorbar|General setup|Axis setup|Scale and rotate|Program flow|Nonlinear fitting|Primitives";\r
-//-----------------------------------------------------------------------------\r
-void data_file(char *fn)\r
-{\r
-       static int num=0;\r
-       static char name[32], res[256];\r
-       snprintf(name,32,"mgl_%d",num); num++;\r
-       mglData *v = Parse->AddVar(name);\r
-       v->Read(fn);\r
-       if(v->nz>1)\r
-               snprintf(res,256,"#read %s '%s'\nrotate 40 60\ncrange %s\nbox\nsurf3 %s\n", name, fn, name, name);\r
-       else if(v->ny>1)\r
-               snprintf(res,256,"#read %s '%s'\nrotate 40 60\ncrange %s\nzrange %s\nbox\nsurf %s\n", name, fn, name, name, name);\r
-       else\r
-               snprintf(res,256,"#read %s '%s'\nyrange %s\nbox\nplot %s\n", name, fn, name, name);\r
-       textbuf->text(res);\r
-}\r
-//-----------------------------------------------------------------------------\r
-//\r
-//                     New Command dialog\r
-//\r
-//-----------------------------------------------------------------------------\r
-struct CmdDlg\r
-{\r
-       Fl_Window *wnd;\r
-       bool OK;\r
-\r
-       Fl_Choice *type, *cmd;\r
-       Fl_Input *var_x, *var_y, *var_z, *var_u, *var_v, *var_w;\r
-       Fl_Box *fmt, *dsc;\r
-       Fl_Input *stl, *zval, *par1, *par2, *opt;\r
-       Fl_Help_View *help;\r
-\r
-       CmdDlg()        {       memset(this,0,sizeof(CmdDlg));  create_dlg();   }\r
-       ~CmdDlg()       {       delete wnd;     }\r
-       void create_dlg();\r
-       char *get_result();\r
-} cmd_dlg;\r
-//-----------------------------------------------------------------------------\r
-void cmd_dlg_cb(Fl_Widget *, void *v)  // add variables checking\r
-{      cmd_dlg.OK = true;      ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void type_cmd_cb(Fl_Widget *, void *)\r
-{\r
-       int val = cmd_dlg.type->value();\r
-       if(val>=0 && val<16)\r
-       {\r
-               cmd_dlg.cmd->clear();   cmd_dlg.cmd->add(cmds[val]);\r
-               cmd_dlg.dsc->copy_label(Parse->CmdDesc(first[val]));\r
-               cmd_dlg.fmt->copy_label(Parse->CmdFormat(first[val]));\r
-\r
-               static char str[300];   // load help for command\r
-#ifdef WIN32\r
-               snprintf(str,300,"%s\\mgl_en.html#%s",docdir,first[val]);\r
-#else\r
-               snprintf(str,300,"%s/mgl_en.html#%s",docdir,first[val]);\r
-#endif\r
-               cmd_dlg.help->load(str);\r
-       }\r
-       cmd_dlg.cmd->value(0);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void desc_cmd_cb(Fl_Widget *, void *)\r
-{\r
-       const char *name = cmd_dlg.cmd->mvalue()->text;\r
-       cmd_dlg.dsc->copy_label(Parse->CmdDesc(name));\r
-       cmd_dlg.fmt->copy_label(Parse->CmdFormat(name));\r
-\r
-       static char str[300];   // load help for command\r
-#ifdef WIN32\r
-       snprintf(str,300,"%s\\mgl_en.html#%s",docdir,name);\r
-#else\r
-       snprintf(str,300,"%s/mgl_en.html#%s",docdir,name);\r
-#endif\r
-       cmd_dlg.help->load(str);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void CmdDlg::create_dlg()\r
-{\r
-       Fl_Button *o;\r
-       wnd = new Fl_Double_Window(500, 450, gettext("Command properties"));\r
-       type = new Fl_Choice(90, 10, 170, 25, gettext("Type of plot"));\r
-       type->tooltip(gettext("Select one of general types of plot"));\r
-       cmd = new Fl_Choice(350, 10, 100, 25, gettext("Command"));\r
-       cmd->tooltip(gettext("Select kind of plot in this group"));\r
-\r
-       fmt = new Fl_Box(0, 40, 500, 25);\r
-       fmt->box(UDAV_DOWN_BOX);\r
-       fmt->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);\r
-       fmt->tooltip(gettext("Format of command and its arguments"));\r
-       dsc = new Fl_Box(0, 70, 500, 25);\r
-       dsc->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);\r
-       dsc->tooltip(gettext("Short command description"));\r
-\r
-       type->callback(type_cmd_cb,cmd);        cmd->callback(desc_cmd_cb,0);\r
-       type->add(gettext(cmd_types));          type_cmd_cb(0,0);\r
-\r
-       var_x = new Fl_Input(15, 115, 50, 25, "X");     var_x->align(FL_ALIGN_TOP);\r
-       o = new Fl_Button(65, 115, 25, 25, "..");       o->callback(var_in_cb,var_x);\r
-       var_y = new Fl_Input(95, 115, 50, 25, "Y");     var_y->align(FL_ALIGN_TOP);\r
-       o = new Fl_Button(145, 115, 25, 25, "..");      o->callback(var_in_cb,var_y);\r
-       var_z = new Fl_Input(175, 115, 50, 25, "Z");    var_z->align(FL_ALIGN_TOP);\r
-       o = new Fl_Button(225, 115, 25, 25, "..");      o->callback(var_in_cb,var_z);\r
-       var_u = new Fl_Input(255, 115, 50, 25, gettext("Vx or A"));     var_u->align(FL_ALIGN_TOP);\r
-       o = new Fl_Button(305, 115, 25, 25, "..");      o->callback(var_in_cb,var_u);\r
-       var_v = new Fl_Input(335, 115, 50, 25, gettext("Vy or C"));     var_v->align(FL_ALIGN_TOP);\r
-       o = new Fl_Button(385, 115, 25, 25, "..");      o->callback(var_in_cb,var_v);\r
-       var_w = new Fl_Input(415, 115, 50, 25, "Vz");var_w->align(FL_ALIGN_TOP);\r
-       o = new Fl_Button(465, 115, 25, 25, "..");      o->callback(var_in_cb,var_w);\r
-\r
-       stl = new Fl_Input(15, 165, 50, 25, gettext("Style"));\r
-       stl->align(FL_ALIGN_TOP);       stl->tooltip(gettext("String argument with command style (or scheme or font)"));\r
-       o = new Fl_Button(65, 165, 25, 25, "..");       o->callback(style_in_cb, stl);\r
-\r
-       zval = new Fl_Input(95, 165, 75, 25, gettext("zVal or sVal"));\r
-       zval->align(FL_ALIGN_TOP);\r
-       zval->tooltip(gettext("Z-value or value of slice.\nKeep empty for default value"));\r
-       par1 = new Fl_Input(175, 165, 75, 25, gettext("Text or dir"));\r
-       par1->align(FL_ALIGN_TOP);\r
-       par1->tooltip(gettext("Text (in text command) or direction (in cont3, contf3, dens3)"));\r
-       par2 = new Fl_Input(255, 165, 75, 25, gettext("Number"));\r
-       par2->align(FL_ALIGN_TOP);\r
-       par2->tooltip(gettext("Number of contours in cont* commands"));\r
-\r
-       opt = new Fl_Input(15, 215, 290, 25, gettext("Options"));\r
-       opt->align(FL_ALIGN_TOP_LEFT);\r
-       opt->tooltip(gettext("Command options"));\r
-       o = new Fl_Button(305, 215, 25, 25, "..");                      o->callback(option_in_cb, opt);\r
-\r
-       o = new Fl_Button(405, 180, 75, 25, gettext("Cancel"));         o->callback(close_dlg_cb, wnd);\r
-       o = new Fl_Return_Button(405, 215, 75, 25, gettext("OK"));      o->callback(cmd_dlg_cb, wnd);\r
-\r
-       help = new Fl_Help_View(0, 250, 500, 200);\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-char *CmdDlg::get_result()\r
-{\r
-       static char res[1024],buf[128];\r
-       res[0]=0;\r
-       const char *cn = cmd->mvalue()->text;\r
-\r
-       bool sl3 = !strcmp(cn,"cont3") || !strcmp(cn,"contf3") || !strcmp(cn,"dens3");\r
-       strcpy(res,"\n");       strncat(res,cn,1022);\r
-       snprintf(buf,128,"%s%s%s%s%s%s%s%s%s%s%s%s", var_x->value()[0]?" ":"", var_x->value(),\r
-               var_y->value()[0]?" ":"", var_y->value(), var_z->value()[0]?" ":"", var_z->value(),\r
-               var_u->value()[0]?" ":"", var_u->value(), var_v->value()[0]?" ":"", var_v->value(),\r
-               var_w->value()[0]?" ":"", var_w->value());\r
-       strcat(res,buf);\r
-\r
-       if(!strcmp(cn,"text") && par1->value()[0])\r
-       {       strcat(res," '");       strcat(res,par1->value());      strcat(res,"'");        }\r
-       if(sl3 && !par1->value()[0])\r
-       {\r
-               strcat(res," 'x'");\r
-               fl_message(gettext("You should specify direction.\nDirection 'x' is selected by default"));\r
-               if(zval->value()[0])\r
-               {       snprintf(buf,128," %d",atoi(zval->value()));    strcat(res,buf);        }\r
-       }\r
-       if(sl3 && par1->value()[0])\r
-       {\r
-               strcat(res," '");       strcat(res,par1->value());      strcat(res,"'");\r
-               if(zval->value()[0])\r
-               {       snprintf(buf,128," %d",atoi(zval->value()));    strcat(res,buf);        }\r
-       }\r
-       if(stl->value()[0])\r
-       {       strcat(res," '");       strcat(res,stl->value());       strcat(res,"'");        }\r
-       if(!sl3 && zval->value()[0])\r
-       {       snprintf(buf,128," %d",atoi(zval->value()));    strcat(res,buf);        }\r
-       if(!sl3 && par2->value()[0])\r
-       {       snprintf(buf,128," %d",atoi(par2->value()));    strcat(res,buf);        }\r
-       if(opt->value()[0])     strcat(res,opt->value());\r
-//     strcat(res,"\n");\r
-       return res;\r
-}\r
-//-----------------------------------------------------------------------------\r
-void command_cb(Fl_Widget *, void *v)\r
-{\r
-       CmdDlg *s = &cmd_dlg;\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       // replace current selection\r
-       {\r
-               long i=e->editor->insert_position(), j=textbuf->line_end(i);\r
-               e->editor->insert_position(j);\r
-               e->editor->insert(s->get_result());\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void plot_dat_cb(Fl_Widget *, void *)\r
-{\r
-       CmdDlg *s = &cmd_dlg;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       // replace current selection\r
-               textbuf->insert(textbuf->length(), s->get_result());\r
-}\r
-//-----------------------------------------------------------------------------\r
diff --git a/mgllab/editor.cpp b/mgllab/editor.cpp
deleted file mode 100644 (file)
index e522eac..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-/* editor.cpp is part of UDAV\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-#include <ctype.h>\r
-#include <errno.h>\r
-#ifdef __MWERKS__\r
-# define FL_DLL\r
-#endif\r
-#include "udav.h"\r
-//-----------------------------------------------------------------------------\r
-int            changed = 0;\r
-char   filename[256] = "";\r
-Fl_Text_Buffer *textbuf = 0;\r
-void data_file(char *v);\r
-//-----------------------------------------------------------------------------\r
-// Syntax highlighting stuff...\r
-Fl_Text_Buffer  *stylebuf = 0;\r
-Fl_Text_Display::Style_Table_Entry styletable[] = {    // Style table\r
-               { FL_BLACK,             FL_COURIER,                     14, 0 },        // A - Plain\r
-               { FL_DARK_GREEN,FL_COURIER_ITALIC,      14, 0 },        // B - Line comments\r
-               { FL_BLUE,              FL_COURIER,                     14, 0 },        // C - Number\r
-               { FL_RED,               FL_COURIER,                     14, 0 },        // D - Strings\r
-               { FL_DARK_BLUE, FL_COURIER_BOLD,        14, 0 },        // E - Usual ommand\r
-               { FL_DARK_CYAN, FL_COURIER_BOLD,        14, 0 },        // F - Flow command\r
-               { FL_DARK_MAGENTA,      FL_COURIER_BOLD,14, 0 },        // G - New-data command\r
-               { FL_DARK_RED,  FL_COURIER,     14, 0 },        // H - Option\r
-               { FL_DARK_GREEN,FL_COURIER_BOLD,        14, 0 }};  // I - Inactive command\r
-//-----------------------------------------------------------------------------\r
-bool is_sfx(const char *s)     // suffix\r
-{\r
-       register long i,n=strlen(s);\r
-       for(i=0;i<n && s[i]>='a';i++);\r
-       if(i==1 && s[0]=='a')   return true;\r
-       if(i==2 && strchr("axyz",s[1]) && strchr("nmawsk",s[0]))        return true;\r
-       if(i==3 && (!strncmp("fst",s,3) || !strncmp("lst",s,3) || !strncmp("max",s,3) ||\r
-                               !strncmp("min",s,3) || !strncmp("sum",s,3)))\r
-               return true;\r
-       return false;\r
-//     char *t = new char[i+1];        memcpy(t,s,i*sizeof(char));     t[i]=0;\r
-}\r
-//-----------------------------------------------------------------------------\r
-bool is_opt(const char *s)     // option\r
-{\r
-       const char *o[]={"xrange","yrange","zrange","crange","alpha",\r
-                                       "cut","value","meshnum","size","legend"};\r
-       int l[10] = {6, 6, 6, 6, 5, 3, 5, 7, 4, 6};\r
-       register long i;\r
-       for(i=0;i<10;i++)       if(!strncmp(o[i],s,l[i]) && s[l[i]]<=' ')       return true;\r
-       return false;\r
-}\r
-//-----------------------------------------------------------------------------\r
-bool is_num(const char *s)     // number\r
-{\r
-       register long i,n=strlen(s);\r
-       if(s[0]==':' && (s[1]<=' ' || s[1]==';'))       return true;\r
-       if(n>=2 && !strncmp("pi",s,2) && (s[2]<=' ' || s[2]==';' || s[2]==':')) return true;\r
-       if(n>=2 && !strncmp("on",s,2) && (s[2]<=' ' || s[2]==';' || s[2]==':')) return true;\r
-       if(n>=3 && !strncmp("off",s,3) && (s[3]<=' ' || s[3]==';' || s[2]==':'))        return true;\r
-       if(n>=3 && !strncmp("nan",s,3) && (s[3]<=' ' || s[3]==';' || s[2]==':'))        return true;\r
-       for(i=0;i<n;i++)\r
-       {\r
-               if(s[i]<=' ' || s[i]==';')      break;\r
-               if(!strchr("+-.eE0123456789",s[i]))     return false;\r
-       }\r
-       return true;\r
-//     char *t = new char[i+1];        memcpy(t,s,i*sizeof(char));     t[i]=0;\r
-}\r
-//-----------------------------------------------------------------------------\r
-char is_cmd(const char *s)     // command\r
-{\r
-       register long i,n=strlen(s)+1;\r
-       char res=0, *w=new char[n];     strcpy(w,s);\r
-       for(i=0;i<n;i++)        if(!isalnum(s[i]))      w[i]=0;\r
-       int rts = Parse->CmdType(w);\r
-       if(rts==5)              res = 'G';\r
-       else if(rts==7) res = 'F';\r
-       else if(rts)    res = 'E';\r
-       delete []w;             return res;\r
-}\r
-//-----------------------------------------------------------------------------\r
-// Parse text and produce style data.\r
-void style_parse(const char *text, char *style, int /*length*/)\r
-{\r
-       register long i;\r
-       long n=strlen(text);\r
-       bool nl=true, arg=true;\r
-       // Style letters:\r
-       // A - Plain\r
-       // B - Line comments\r
-       // C - Number\r
-       // D - Strings\r
-       // E - Usual command\r
-       // F - Flow command\r
-       // G - New data command\r
-       // H - Option\r
-\r
-       for(i=0;i<n;i++)\r
-       {\r
-               style[i] = 'A';\r
-               if(text[i]=='#')        // comment\r
-                       for(;i<n && text[i]!='\n';i++)  style[i]='B';\r
-               if(text[i]=='\'')       // string\r
-               {\r
-                       arg = false;    style[i]='D';   i++;\r
-                       for(;i<n && text[i]!='\n' && text[i]!='\'';i++) style[i]='D';\r
-                       style[i]='D';\r
-               }\r
-               if(text[i]=='\n' || text[i]==':')       {       nl=true;        style[i]='A';   continue;       }\r
-               char r = is_cmd(text+i);\r
-               if(nl && r)     // command name\r
-               {       for(;i<n && isalnum(text[i]);i++)       style[i]=r;             i--;    }\r
-               if(text[i]<=' ' || text[i]==';')        {       arg = true;     continue;       }\r
-               if(arg && is_opt(text+i))       // option\r
-               {       for(;i<n && isalpha(text[i]);i++)       style[i]='H';   i--;    }\r
-               if(arg && is_num(text+i))       // number\r
-               {\r
-                       if(text[i]==':' && (isspace(text[i+1]) || text[i+1]==':'))\r
-                               style[i]='C';\r
-                       else for(;i<n && strchr("+-.eE0123456789pionaf",text[i]) ;i++)\r
-                               style[i]='C';\r
-                       i--;\r
-               }\r
-               if(text[i]=='.' && is_sfx(text+i+1))    // option (suffix)\r
-               {\r
-                       style[i]='H';   i++;\r
-                       for(;i<n && isalpha(text[i]);i++)       style[i]='H';\r
-               }\r
-               nl = arg = false;\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-// Initialize the style buffer...\r
-void style_init(void)\r
-{\r
-       char *style = new char[textbuf->length() + 1];\r
-       char *text = textbuf->text();\r
-       memset(style, 'A', textbuf->length());\r
-       style[textbuf->length()] = '\0';\r
-       if (!stylebuf) stylebuf = new Fl_Text_Buffer(textbuf->length());\r
-       style_parse(text, style, textbuf->length());\r
-       stylebuf->text(style);\r
-       delete[] style;\r
-       free(text);\r
-}\r
-//-----------------------------------------------------------------------------\r
-// Update unfinished styles.\r
-void style_unfinished_cb(int, void*) {}\r
-//-----------------------------------------------------------------------------\r
-// Update the style buffer...\r
-void style_update(int pos,             // Position of update\r
-                               int nInserted,  // Number of inserted chars\r
-                               int nDeleted,   // Number of deleted chars\r
-                               int     /*nRestyled*/,                  // Number of restyled chars\r
-                               const char */*deletedText*/,// Text that was deleted\r
-                               void *cbArg)    // Callback data\r
-{\r
-       long    start, end;     // Start and end of text\r
-       char last,              // Last style on line\r
-               *style,         // Style data\r
-               *text;          // Text data\r
-\r
-       // If this is just a selection change, just unselect the style buffer...\r
-       if (nInserted == 0 && nDeleted == 0) {  stylebuf->unselect();   return;  }\r
-       // Track changes in the text buffer...\r
-       if (nInserted > 0)\r
-       {\r
-               // Insert characters into the style buffer...\r
-               style = new char[nInserted + 1];\r
-               memset(style, 'A', nInserted);\r
-               style[nInserted] = '\0';\r
-\r
-               stylebuf->replace(pos, pos + nDeleted, style);\r
-               delete[] style;\r
-       }\r
-       else    // Just delete characters in the style buffer...\r
-               stylebuf->remove(pos, pos + nDeleted);\r
-\r
-       // Select the area that was just updated to avoid unnecessary callbacks...\r
-       stylebuf->select(pos, pos + nInserted - nDeleted);\r
-\r
-       // Re-parse the changed region; we do this by parsing from the\r
-       // beginning of the previous line of the changed region to the end of\r
-       // the line of the changed region...  Then we check the last\r
-       // style character and keep updating if we have a multi-line\r
-       // comment character...\r
-       start = textbuf->line_start(pos);\r
-       end   = textbuf->line_end(pos + nInserted);\r
-       text  = textbuf->text_range(start, end);\r
-       style = stylebuf->text_range(start, end);\r
-       if (start==end) last = 0;\r
-       else    last = style[end-start-1];\r
-       style_parse(text, style, end - start);\r
-       stylebuf->replace(start, end, style);\r
-       ((Fl_Text_Editor *)cbArg)->redisplay_range(start, end);\r
-\r
-       if (start==end || last != style[end-start-1])\r
-       {\r
-               // Either the user deleted some text, or the last character on\r
-               // the line changed styles, so reparse the remainder of the buffer...\r
-               free(text);     free(style);\r
-\r
-               end   = textbuf->length();\r
-               text  = textbuf->text_range(start, end);\r
-               style = stylebuf->text_range(start, end);\r
-               style_parse(text, style, end - start);\r
-               stylebuf->replace(start, end, style);\r
-               ((Fl_Text_Editor *)cbArg)->redisplay_range(start, end);\r
-       }\r
-       free(text);     free(style);\r
-}\r
-//-----------------------------------------------------------------------------\r
-ScriptWindow::ScriptWindow(int w, int h, const char* t) : Fl_Double_Window(w, h, t)\r
-{\r
-       replace_dlg = new Fl_Window(300, 105, gettext("Replace"));\r
-       replace_find = new Fl_Input(80, 10, 210, 25, gettext("Find:"));\r
-       replace_find->align(FL_ALIGN_LEFT);\r
-\r
-       replace_with = new Fl_Input(80, 40, 210, 25, gettext("Replace:"));\r
-       replace_with->align(FL_ALIGN_LEFT);\r
-\r
-       replace_all = new Fl_Button(10, 70, 90, 25, gettext("Replace All"));\r
-       replace_all->callback((Fl_Callback *)replall_cb, this);\r
-       replace_all->box(UDAV_UP_BOX);  replace_all->down_box(UDAV_DOWN_BOX);\r
-\r
-       replace_next = new Fl_Return_Button(105, 70, 120, 25, "Replace Next");\r
-       replace_next->callback((Fl_Callback *)replace2_cb, this);\r
-       replace_next->box(UDAV_UP_BOX); replace_next->down_box(UDAV_DOWN_BOX);\r
-\r
-       replace_cancel = new Fl_Button(230, 70, 60, 25, gettext("Cancel"));\r
-       replace_cancel->callback((Fl_Callback *)replcan_cb, this);\r
-       replace_cancel->box(UDAV_UP_BOX);       replace_cancel->down_box(UDAV_DOWN_BOX);\r
-\r
-       replace_dlg->end();\r
-       replace_dlg->set_non_modal();\r
-       editor = 0;             *search = 0;\r
-\r
-       setup_dlg = new SetupDlg;\r
-       setup_dlg->CreateDlg();\r
-}\r
-//-----------------------------------------------------------------------------\r
-ScriptWindow::~ScriptWindow()\r
-{\r
-       delete replace_dlg;\r
-       delete setup_dlg->wnd;\r
-}\r
-//-----------------------------------------------------------------------------\r
-int check_save(void)\r
-{\r
-  if (!changed) return 1;\r
-  int r = fl_choice(gettext("The current file has not been saved.\n"\r
-                                       "Would you like to save it now?"),\r
-                                       gettext("Cancel"), gettext("Save"), gettext("Don't Save"));\r
-  if(r==1)     {       save_cb(0,0);   return !changed;        } // Save the file...\r
-  return (r==2) ? 1 : 0;\r
-}\r
-//-----------------------------------------------------------------------------\r
-int loading = 0;\r
-void load_file(char *newfile, int ipos)\r
-{\r
-       long len = strlen(newfile);\r
-       pref.set("last_file",newfile);\r
-       if(ipos==-1 && (!strcmp(newfile+len-4,".dat") || !strcmp(newfile+len-4,".csv")))\r
-       {\r
-               data_file(newfile);\r
-               strncpy(newfile+len-4,".mgl",4);\r
-               strncpy(filename, newfile,256);\r
-       }\r
-       else\r
-       {\r
-               loading = 1;\r
-               int insert = (ipos != -1);\r
-               changed = insert;\r
-               if(!insert) *filename=0;\r
-               long r;\r
-               if(!insert)     r = textbuf->loadfile(newfile);\r
-               else r = textbuf->insertfile(newfile, ipos);\r
-\r
-               char *t = textbuf->text();\r
-#ifndef WIN32\r
-               register size_t i,l=strlen(t);\r
-               for(i=0;i<l;i++)        if(t[i]=='\r')  t[i]=' ';\r
-               textbuf->text(t);\r
-#endif\r
-               fill_animate(t);        free(t);\r
-\r
-               if (r)\r
-                       fl_alert(gettext("Error reading from file \'%s\':\n%s."), newfile, strerror(errno));\r
-               else    if(!insert)     strncpy(filename, newfile,256);\r
-               loading = 0;\r
-               textbuf->call_modify_callbacks();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void save_file(char *newfile)\r
-{\r
-       pref.set("last_file",newfile);\r
-       if (textbuf->savefile(newfile))\r
-               fl_alert(gettext("Error writing to file \'%s\':\n%s."), newfile, strerror(errno));\r
-       else\r
-               strncpy(filename, newfile,256);\r
-       changed = 0;\r
-       textbuf->call_modify_callbacks();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void copy_cb(Fl_Widget*, void* v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       Fl_Text_Editor::kf_copy(0, e->editor);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void cut_cb(Fl_Widget*, void* v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       Fl_Text_Editor::kf_cut(0, e->editor);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void delete_cb(Fl_Widget*, void*) {    textbuf->remove_selection();    }\r
-//-----------------------------------------------------------------------------\r
-void find_cb(Fl_Widget* w, void* v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       const char *val;\r
-       val = fl_input(gettext("Search String:"), e->search);\r
-       if (val != NULL) {      strncpy(e->search, val,256);    find2_cb(w, v); }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void find2_cb(Fl_Widget* w, void* v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       if (e->search[0] == '\0')       {       find_cb(w, v);  return; }\r
-\r
-       int pos = e->editor->insert_position();\r
-       long found = textbuf->search_forward(pos, e->search, &pos);\r
-       if (found) {\r
-               // Found a match; select and update the position...\r
-               textbuf->select(pos, pos+strlen(e->search));\r
-               e->editor->insert_position(pos+strlen(e->search));\r
-               e->editor->show_insert_position();\r
-       }\r
-       else fl_alert(gettext("No occurrences of \'%s\' found!"), e->search);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void changed_cb(int, int nInserted, int nDeleted,int, const char*, void* v)\r
-{\r
-       if ((nInserted || nDeleted) && !loading) changed = 1;\r
-       ScriptWindow *w = (ScriptWindow *)v;\r
-       set_title(w);\r
-       if (loading) w->editor->show_insert_position();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void insert_cb(Fl_Widget*, void *v)\r
-{\r
-       char *newfile = fl_file_chooser(gettext("Insert File?"), "*", filename);\r
-       ScriptWindow *w = (ScriptWindow *)v;\r
-       if (newfile != NULL) load_file(newfile, w->editor->insert_position());\r
-}\r
-//-----------------------------------------------------------------------------\r
-void paste_cb(Fl_Widget*, void* v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       Fl_Text_Editor::kf_paste(0, e->editor);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void replace_cb(Fl_Widget*, void* v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       e->replace_dlg->show();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void replace2_cb(Fl_Widget*, void* v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       const char *find = e->replace_find->value();\r
-       const char *replace = e->replace_with->value();\r
-       if (find[0] == '\0')    {       e->replace_dlg->show(); return; }\r
-       e->replace_dlg->hide();\r
-\r
-       int pos = e->editor->insert_position();\r
-       long found = textbuf->search_forward(pos, find, &pos);\r
-       if (found)\r
-       {\r
-               // Found a match; update the position and replace text...\r
-               textbuf->select(pos, pos+strlen(find));\r
-               textbuf->remove_selection();\r
-               textbuf->insert(pos, replace);\r
-               textbuf->select(pos, pos+strlen(replace));\r
-               e->editor->insert_position(pos+strlen(replace));\r
-               e->editor->show_insert_position();\r
-       }\r
-       else fl_alert(gettext("No occurrences of \'%s\' found!"), find);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void replall_cb(Fl_Widget*, void* v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       const char *find = e->replace_find->value();\r
-       const char *replace = e->replace_with->value();\r
-\r
-       find = e->replace_find->value();\r
-       if (find[0] == '\0')    {       e->replace_dlg->show(); return; }\r
-       e->replace_dlg->hide();\r
-       e->editor->insert_position(0);\r
-       long times = 0;\r
-\r
-       // Loop through the whole string\r
-       for (long found = 1; found;)\r
-       {\r
-               int pos = e->editor->insert_position();\r
-               found = textbuf->search_forward(pos, find, &pos);\r
-               if (found)\r
-               {\r
-                       // Found a match; update the position and replace text...\r
-                       textbuf->select(pos, pos+strlen(find));\r
-                       textbuf->remove_selection();\r
-                       textbuf->insert(pos, replace);\r
-                       e->editor->insert_position(pos+strlen(replace));\r
-                       e->editor->show_insert_position();\r
-                       times++;\r
-               }\r
-       }\r
-       if (times) fl_message(gettext("Replaced %ld occurrences."), times);\r
-       else fl_alert(gettext("No occurrences of \'%s\' found!"), find);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void replcan_cb(Fl_Widget*, void* v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       e->replace_dlg->hide();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void view_cb(Fl_Widget*, void*);\r
-//#include "xpm/window.xpm"\r
-//#include "xpm/option.xpm"\r
-//#include "xpm/table.xpm"\r
-#include "xpm/plot.xpm"\r
-#include "xpm/help-contents.xpm"\r
-#include "xpm/edit-cut.xpm"\r
-#include "xpm/edit-copy.xpm"\r
-#include "xpm/edit-paste.xpm"\r
-#include "xpm/edit-find.xpm"\r
-#include "xpm/document-open.xpm"\r
-#include "xpm/document-new.xpm"\r
-#include "xpm/document-save.xpm"\r
-Fl_Widget *add_editor(ScriptWindow *w)\r
-{\r
-       Fl_Window *w1=new Fl_Window(0,30,300,430,0);\r
-       Fl_Group *g = new Fl_Group(0,0,290,30);\r
-       Fl_Button *o;\r
-\r
-       o = new Fl_Button(0, 1, 25, 25);        o->image(new Fl_Pixmap(document_new_xpm));\r
-       o->tooltip(gettext("New script"));      o->callback(new_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(25, 1, 25, 25);       o->tooltip(gettext("Open script or data file"));\r
-       o->image(new Fl_Pixmap(document_open_xpm));     o->callback(open_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(50, 1, 25, 25);       o->tooltip(gettext("Save script to file"));\r
-       o->image(new Fl_Pixmap(document_save_xpm));     o->callback(save_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-\r
-       o = new Fl_Button(80, 1, 25, 25);       o->tooltip(gettext("Cut selection to clipboard"));\r
-       o->image(new Fl_Pixmap(edit_cut_xpm));  o->callback(cut_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(105, 1, 25, 25);      o->tooltip(gettext("Copy selection to clipboard"));\r
-       o->image(new Fl_Pixmap(edit_copy_xpm)); o->callback(copy_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(130, 1, 25, 25);      o->tooltip(gettext("Paste text from clipboard"));\r
-       o->image(new Fl_Pixmap(edit_paste_xpm));        o->callback(paste_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(155, 1, 25, 25);      o->tooltip(gettext("Find text"));\r
-       o->image(new Fl_Pixmap(edit_find_xpm)); o->callback(find_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-\r
-       o = new Fl_Button(185, 1, 25, 25);      o->tooltip(gettext("Insert MGL command"));\r
-       o->image(new Fl_Pixmap(plot_xpm));      o->callback(command_cb,w);\r
-       o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-//     o = new Fl_Button(185, 1, 25, 25);      o->tooltip(gettext("Insert command options"));\r
-//     o->image(new Fl_Pixmap(option_xpm));    o->callback(option_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-//     o = new Fl_Button(210, 1, 25, 25);      o->tooltip(gettext("Edit data array"));\r
-//     o->image(new Fl_Pixmap(table_xpm));     o->callback(table_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-//     o = new Fl_Button(235, 1, 25, 25);      o->tooltip(gettext("New view window"));\r
-//     o->image(new Fl_Pixmap(window_xpm));o->callback(view_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(210, 1, 25, 25);      o->tooltip(gettext("Show help window"));\r
-       o->image(new Fl_Pixmap(help_contents_xpm));     o->callback(help_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       g->end();       g->resizable(0);\r
-\r
-       w->editor = new Fl_Text_Editor(0, 28, 300, 400);\r
-       w->editor->buffer(textbuf);\r
-       w->editor->highlight_data(stylebuf, styletable, sizeof(styletable) / sizeof(styletable[0]), 'A', style_unfinished_cb, 0);\r
-       w->editor->textfont(FL_COURIER);\r
-\r
-       textbuf->add_modify_callback(style_update, w->editor);\r
-       textbuf->add_modify_callback(changed_cb, w);\r
-       textbuf->call_modify_callbacks();\r
-\r
-       w1->end();\r
-       w1->resizable(w->editor);       //w->graph);\r
-       return w1;\r
-}\r
-//-----------------------------------------------------------------------------\r
diff --git a/mgllab/grid.cpp b/mgllab/grid.cpp
deleted file mode 100644 (file)
index e192818..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* grid.cpp is part of UDAV
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <FL/Fl.H>
-#include <FL/Fl_Window.H>
-#include <FL/Fl_Int_Input.H>
-#include <FL/Fl_Value_Slider.H>
-#include <FL/fl_draw.H>
-#include "udav.h"
-//-----------------------------------------------------------------------------
-Fl_Callback input_cb;
-//-----------------------------------------------------------------------------
-void input_cb(Fl_Widget*, void* v)     { ((Fl_Data_Table*)v)->set_value(); }
-//-----------------------------------------------------------------------------
-Fl_Data_Table::Fl_Data_Table(int x, int y, int w, int h, const char *l) : Fl_Table(x,y,w,h,l)
-{
-       callback(&event_callback, (void*)this);
-       input = new Fl_Input(w/2,h/2,0,0);
-       input->hide();
-       input->callback(input_cb, (void*)this);
-       input->when(FL_WHEN_ENTER_KEY_ALWAYS);
-       input->maximum_size(16);
-//     (new Fl_Box(9999,9999,0,0))->hide();  // HACK: prevent flickering in Fl_Scroll
-       end();
-}
-//-----------------------------------------------------------------------------
-// Handle drawing all cells in table
-void Fl_Data_Table::draw_cell(TableContext context, int R, int C, int X, int Y, int W, int H)
-{
-       static char s[32];
-       fl_push_clip(X, Y, W, H);
-       switch ( context )
-       {
-       case CONTEXT_COL_HEADER:
-               fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color());
-               fl_font(FL_HELVETICA | FL_BOLD, 14);
-               fl_color(FL_BLACK);             snprintf(s,32,"%d",C);
-               fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER);
-               break;
-       case CONTEXT_ROW_HEADER:
-               fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color());
-               fl_font(FL_HELVETICA | FL_BOLD, 14);
-               fl_color(FL_BLACK);             snprintf(s,32,"%d",R);
-               fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER);
-               break;
-       case CONTEXT_CELL:
-           if (R == row && C == col && input->visible())       break;
-               fl_draw_box(FL_THIN_DOWN_BOX, X, Y, W, H, FL_WHITE);
-               fl_pop_clip();
-               fl_push_clip(X+3, Y+3, W-6, H-6);
-               fl_font(FL_HELVETICA, 14);
-               fl_color(FL_BLACK);
-               if(mgl_isnan(data[C+nx*R]))     strcpy(s,"nan");
-               else    snprintf(s,32,"%g",data[C+nx*R]);
-               fl_draw(s, X+3, Y+3, W-6, H-6, FL_ALIGN_RIGHT);
-               break;
-       case CONTEXT_RC_RESIZE:
-               if (!input->visible()) break;
-               find_cell(CONTEXT_TABLE, row, col, X, Y, W, H);
-               if (X!=input->x() || Y!=input->y() || W!=input->w() || H!=input->h())
-                       input->resize(X,Y,W,H);
-               break;
-       default:        break;
-       }
-       fl_pop_clip();
-}
-//-----------------------------------------------------------------------------
-void Fl_Data_Table::cell_click()
-{
-    int R = callback_row(), C = callback_col();
-    TableContext context = callback_context();
-
-    if(context==CONTEXT_CELL)
-       {
-               if (input->visible())   //input->do_callback();
-               {
-                       const char *s = input->value();
-                       data[col + nx*row] = (s[0]==0 || !strcmp(s,"nan")) ? NAN : atof(s);
-               }
-               row = R;                col = C;
-               int XX,YY,WW,HH;
-               find_cell(CONTEXT_CELL, R, C, XX, YY, WW, HH);
-               input->resize(XX,YY,WW,HH);
-               char s[32];
-               if(mgl_isnan(data[C+nx*R]))     strcpy(s,"nan");
-               else    snprintf(s,32,"%g",data[C+nx*R]);
-               input->value(s);        input->show();
-               input->take_focus();
-       }
-}
-//-----------------------------------------------------------------------------
-void Fl_Data_Table::set_value()
-{
-       const char *s = input->value();
-       data[col + nx*row] = (s[0]==0 || !strcmp(s,"nan")) ? NAN : atof(s);
-}
-//-----------------------------------------------------------------------------
diff --git a/mgllab/help.cpp b/mgllab/help.cpp
deleted file mode 100644 (file)
index 1fd19af..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/* help.cpp is part of UDAV\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-#include "udav.h"\r
-#include <ctype.h>\r
-#include <FL/Fl_Select_Browser.H>\r
-//-----------------------------------------------------------------------------\r
-void help_cb(Fl_Widget*, void*v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       long i=e->editor->insert_position(), j0=textbuf->line_start(i),j;\r
-\r
-       static char str[300];\r
-       char s[32]="", *buf = textbuf->text();\r
-       memset(s,0,32*sizeof(char));\r
-       for(j=j0;!isspace(buf[j]) && buf[j]!='#' && buf[j]!=';' && j<31+j0;j++)\r
-               s[j-j0] = buf[j];\r
-       free(buf);\r
-#ifdef WIN32\r
-       snprintf(str,300,"%s\\mgl_en.html#%s",docdir,s);\r
-#else\r
-       snprintf(str,300,"%s/mgl_en.html#%s",docdir,s);\r
-#endif\r
-       e->hd->load(str);\r
-       if(e->rtab)     e->rtab->value(e->ghelp);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void link_cb(Fl_Widget*, void*v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       static char str[300];\r
-#ifdef WIN32\r
-       snprintf(str,300,"%s\\mgl_en.html#%s",docdir,e->link_cmd->value());\r
-#else\r
-       snprintf(str,300,"%s/mgl_en.html#%s",docdir,e->link_cmd->value());\r
-#endif\r
-       e->hd->load(str);\r
-       if(e->rtab)     e->rtab->value(e->ghelp);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void example_cb(Fl_Widget*, void*v)\r
-{\r
-       static char str[300];\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-#ifdef WIN32\r
-       snprintf(str,300,"%s\\mgl_en.html\\mgl_en_2.html",docdir);\r
-#else\r
-       snprintf(str,300,"%s/mgl_en.html/mgl_en_2.html",docdir);\r
-#endif\r
-       e->hd->load(str);       e->rtab->value(e->ghelp);\r
-       if(e->rtab)     e->rtab->value(e->ghelp);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void help_in_cb(Fl_Widget*, void*v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       e->hd->textsize(e->hd->textsize()+1);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void help_out_cb(Fl_Widget*, void*v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       e->hd->textsize(e->hd->textsize()-1);\r
-}\r
-//-----------------------------------------------------------------------------\r
-#include "xpm/udav.xpm"\r
-void about_cb(Fl_Widget*, void*)\r
-{\r
-       static char s[128];\r
-       snprintf(s,128,gettext("UDAV v. 2.%g\n(c) Alexey Balakin, 2007\nhttp://udav.sf.net/"), MGL_VER2);\r
-       Fl_Double_Window* w = new Fl_Double_Window(355, 130, "About UDAV");\r
-       Fl_Box* o = new Fl_Box(10, 15, 65, 65);\r
-       o->box(FL_UP_BOX);      o->color(55);   o->image(new Fl_Pixmap(udav_xpm));\r
-       o = new Fl_Box(85, 15, 260, 65);        o->box(UDAV_DOWN_BOX);\r
-       o->label(s);\r
-       Fl_Button *b = new Fl_Return_Button(255, 90, 90, 30, "Close");\r
-       b->callback(close_dlg_cb,w);\r
-       b->box(UDAV_UP_BOX);    b->down_box(UDAV_DOWN_BOX);\r
-       w->end();       w->set_modal(); w->show();\r
-}\r
-//-----------------------------------------------------------------------------\r
-#include "xpm/zoom-out.xpm"\r
-#include "xpm/zoom-in.xpm"\r
-#include "xpm/help-faq.xpm"\r
-Fl_Widget *add_help(ScriptWindow *w)\r
-{\r
-       Fl_Window *w1=new Fl_Window(300,30,630,430,0);\r
-       Fl_Group *g = new Fl_Group(0,0,290,30);\r
-       Fl_Button *o;\r
-\r
-       w->link_cmd = new Fl_Input(0,1,150,25);\r
-       w->link_cmd->when(FL_WHEN_CHANGED);\r
-       w->link_cmd->callback(link_cb,w);\r
-\r
-       o = new Fl_Button(155, 1, 25, 25);      o->tooltip(gettext("MGL samples and hints"));\r
-       o->image(new Fl_Pixmap(help_faq_xpm));  o->callback(example_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(180, 1, 25, 25);      o->tooltip(gettext("Increase font size"));\r
-       o->image(new Fl_Pixmap(zoom_in_xpm));   o->callback(help_in_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(205, 1, 25, 25);      o->tooltip(gettext("Decrease font size"));\r
-       o->image(new Fl_Pixmap(zoom_out_xpm));  o->callback(help_out_cb,w);\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-\r
-       g->end();       g->resizable(0);\r
-\r
-       w->hd = new Fl_Help_View(0,28,630,400);\r
-       w1->end();      link_cb(w,w);\r
-       w1->resizable(w->hd);   return w1;\r
-}\r
-//-----------------------------------------------------------------------------\r
-void mem_dlg_cb0(Fl_Widget *, void *v)\r
-{      ((ScriptWindow*)v)->mem_pressed(0);     }\r
-//-----------------------------------------------------------------------------\r
-void mem_dlg_cb1(Fl_Widget *, void *v)\r
-{      ((ScriptWindow*)v)->mem_pressed(1);     }\r
-//-----------------------------------------------------------------------------\r
-void mem_dlg_cb2(Fl_Widget *, void *v)\r
-{      ((ScriptWindow*)v)->mem_pressed(2);     }\r
-//-----------------------------------------------------------------------------\r
-void mem_dlg_cb3(Fl_Widget *, void *v)\r
-{      ((ScriptWindow*)v)->mem_pressed(3);     }\r
-//-----------------------------------------------------------------------------\r
-void mem_update_cb(Fl_Widget *, void *v)\r
-{      ((ScriptWindow*)v)->mem_init(); }\r
-//-----------------------------------------------------------------------------\r
-Fl_Widget *add_mem(ScriptWindow *w)\r
-{\r
-       static int widths[] = {220,205,0};\r
-       Fl_Button *o;\r
-       Fl_Box *b;\r
-//     wnd = new Fl_Double_Window(335, 405, gettext("Data browser"));\r
-       Fl_Window *wnd = new Fl_Window(300,30,630,430,0);\r
-\r
-//     Fl_Group *g = new Fl_Group(10,10,610,395);\r
-       b = new Fl_Box(0, 10, 630, 25, gettext("Existed data arrays")); b->labeltype(FL_ENGRAVED_LABEL);\r
-       b = new Fl_Box(0, 35, 220, 25, gettext("name"));\r
-       b->box(FL_THIN_UP_BOX); b->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);\r
-       b = new Fl_Box(220, 35, 205, 25, gettext("dimensions"));\r
-       b->box(FL_THIN_UP_BOX); b->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);\r
-       b = new Fl_Box(425, 35, 205, 25, gettext("mem. usage"));\r
-       b->box(FL_THIN_UP_BOX); b->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);\r
-\r
-       w->var = new Fl_Select_Browser(0, 60, 630, 335);        w->var->column_char('\t');\r
-       w->var->align(FL_ALIGN_TOP);    w->var->column_widths(widths);\r
-       w->var->tooltip(gettext("List of available data."));\r
-//     g->end();\r
-\r
-       o = new Fl_Button(10, 400, 95, 25, gettext("Edit"));    o->callback(mem_dlg_cb0,w);\r
-       o->tooltip(gettext("Open table with selected data for editing."));\r
-       o = new Fl_Button(120, 400, 95, 25, gettext("Plot"));   o->callback(mem_dlg_cb1,w);\r
-       o->tooltip(gettext("Plot selected data."));\r
-       o = new Fl_Button(230, 400, 95, 25, gettext("Delete")); o->callback(mem_dlg_cb2,w);\r
-       o->tooltip(gettext("Delete selected data."));\r
-       o = new Fl_Button(340, 400, 95, 25, gettext("New"));    o->callback(mem_dlg_cb3,w);\r
-       o->tooltip(gettext("Open dialog for new data creation."));\r
-       o = new Fl_Button(450, 400, 95, 25, gettext("Refresh"));        o->callback(mem_update_cb,w);\r
-       o->tooltip(gettext("Refresh list of variables."));\r
-//     o = new Fl_Button(120, 335, 95, 25, gettext("Load"));   o->callback(mem_dlg_cb,(void *)4);\r
-//     o = new Fl_Button(230, 335, 95, 25, gettext("Save"));   o->callback(mem_dlg_cb,(void *)5);\r
-//     o = new Fl_Button(10, 370, 95, 25, gettext("Update"));  o->callback(mem_upd_cb,0);\r
-       wnd->end();     wnd->resizable(w->var); return wnd;\r
-}\r
-//-----------------------------------------------------------------------------\r
-void ScriptWindow::mem_init()\r
-{\r
-       char str[128];\r
-       var->clear();\r
-       mglVar *v=Parse->FindVar("");\r
-       while(v)\r
-       {\r
-               snprintf(str,128,"%ls\t%ld*%ld*%ld\t%ld\t", v->s.c_str(), v->nx, v->ny, v->nz, sizeof(mreal)*v->nx*v->ny*v->nz);\r
-               var->add(str,v);\r
-               v = v->next;\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void ScriptWindow::mem_pressed(int kind)\r
-{\r
-       TableWindow *w;\r
-       int ind = var->value();\r
-       mglVar *v = (mglVar *)var->data(ind);\r
-       static char res[128];\r
-       if(!v && kind!=3)       return;\r
-       if(kind==0)\r
-       {\r
-               w = (TableWindow *)v->o;\r
-               if(!w)\r
-               {\r
-                       char ss[1024];\r
-                       wcstombs(ss,v->s.c_str(),1024); ss[v->s.length()]=0;\r
-                       ltab->begin();\r
-                       Fl_Group *gg = new Fl_Group(0,30,300,430);\r
-                       w = new TableWindow(0,30,300,430);\r
-                       gg->label(ss);  gg->end();      ltab->end();\r
-               }\r
-               w->update(v);   ltab->value(w->parent());       w->show();\r
-       }\r
-       else if(kind==1)\r
-       {\r
-               if(v->nz>1)             snprintf(res,128,"box\nsurf3 %ls\n",v->s.c_str());\r
-               else if(v->ny>1)        snprintf(res,128,"box\nsurf %ls\n",v->s.c_str());\r
-               else                            snprintf(res,128,"box\nplot %ls\n",v->s.c_str());\r
-               textbuf->text(res);\r
-       }\r
-       else if(kind==2)\r
-               Parse->DeleteVar(v->s.c_str());\r
-       else if(kind==3)\r
-       {\r
-               const char *name = fl_input(gettext("Enter name for new variable"),"dat");\r
-               if(!name)       return;\r
-               v = Parse->AddVar(name);\r
-\r
-               ltab->begin();\r
-               Fl_Group *gg = new Fl_Group(0,30,300,430);\r
-               w = new TableWindow(0,30,300,430);\r
-               gg->label(name);        gg->end();      ltab->end();\r
-               w->update(v);   ltab->value(w->parent());       w->show();\r
-       }\r
-       mem_init();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void variables_cb(Fl_Widget *, void *v)\r
-{\r
-/*     MemDlg *s = &mem_dlg;\r
-       s->wnd->set_modal();\r
-       s->init();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();*/\r
-}\r
-//-----------------------------------------------------------------------------\r
diff --git a/mgllab/main.cpp b/mgllab/main.cpp
deleted file mode 100644 (file)
index aa7ccae..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/* main.cpp is part of UDAV\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-#include <ctype.h>\r
-#include <errno.h>\r
-#include <locale.h>\r
-#include "udav.h"\r
-//-----------------------------------------------------------------------------\r
-#ifndef MGL_DOC_DIR\r
-#ifdef WIN32\r
-#define MGL_DOC_DIR ""\r
-#else\r
-#define MGL_DOC_DIR "/usr/local/share/doc/mathgl/"\r
-#endif\r
-#endif\r
-//-----------------------------------------------------------------------------\r
-char   title[256];\r
-int num_windows = 0, auto_exec=1, plastic_scheme=1, internal_font=0;\r
-Fl_Preferences pref(Fl_Preferences::USER,"abalakin","mgllab");\r
-char *docdir=0;\r
-//-----------------------------------------------------------------------------\r
-void set_title(Fl_Window* w)\r
-{\r
-       if (filename[0] == '\0') strcpy(title, "Untitled");\r
-       else\r
-       {\r
-               char *slash;\r
-               slash = strrchr(filename, '/');\r
-#ifdef WIN32\r
-               if (slash == NULL) slash = strrchr(filename, '\\');\r
-#endif\r
-               if (slash != NULL) strncpy(title, slash + 1,256);\r
-               else strncpy(title, filename,256);\r
-       }\r
-       if (changed) strcat(title, gettext(" (modified)"));\r
-       w->label(title);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void fname_cb(Fl_Widget*, void *v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       char *file = fl_file_chooser(gettext("Insert File Name?"), gettext("All Files (*)"), 0);\r
-       if(file)\r
-       {\r
-               char *str = new char[strlen(file)+4];\r
-               snprintf(str,strlen(file)+4," '%s'",file);\r
-               e->editor->insert(str);\r
-               delete []str;\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void new_cb(Fl_Widget*, void*)\r
-{\r
-       if (!check_save()) return;\r
-       filename[0] = '\0';\r
-       textbuf->select(0, textbuf->length());\r
-       textbuf->remove_selection();\r
-       changed = 0;\r
-       textbuf->call_modify_callbacks();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void open_cb(Fl_Widget*, void *v)\r
-{\r
-       if (!check_save()) return;\r
-       char *lastname=0;\r
-       if(*filename==0)        {       pref.get("last_file",lastname,"");      strncpy(filename, lastname,256);        }\r
-       char *newfile = fl_file_chooser(gettext("Open File?"),\r
-               gettext("MGL Files (*.mgl)\tDAT Files (*.{dat,csv})\tAll Files (*)"), filename);\r
-       if(lastname)    free(lastname);\r
-       if(newfile != NULL)\r
-       {\r
-               load_file(newfile, -1);\r
-               if(auto_exec)   ((ScriptWindow*)v)->graph->update();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void close_cb(Fl_Widget*, void* v)\r
-{\r
-       Fl_Window* w = (Fl_Window*)v;\r
-       if (num_windows == 1 && !check_save())  return;\r
-\r
-       w->hide();\r
-       textbuf->remove_modify_callback(changed_cb, w);\r
-       delete w;\r
-       num_windows--;\r
-       if (!num_windows) exit(0);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void quit_cb(Fl_Widget*, void*)\r
-{\r
-       if (changed && !check_save())   return;\r
-       exit(0);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void save_cb(Fl_Widget*w, void*v)\r
-{\r
-       if (filename[0] == '\0')        {       saveas_cb(w,v); return; }       // No filename - get one!\r
-       else save_file(filename);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void saveas_cb(Fl_Widget*, void*)\r
-{\r
-       char *newfile, *fname=0;\r
-       FILE *fp=0;\r
-       while(1)\r
-       {\r
-               newfile = fl_file_chooser(gettext("Save File As?"), "*.mgl", filename);\r
-               if(!newfile || !newfile[0])     break;\r
-               if(!strchr(newfile,'.'))\r
-               {\r
-                       if(fname)       delete []fname;\r
-                       fname = new char[strlen(newfile)+5];\r
-                       strcpy(fname,newfile);  strcat(fname,".mgl");\r
-                       newfile = fname;\r
-               }\r
-               fp = fopen(newfile,"r");\r
-               if(fp)\r
-               {\r
-                       fclose(fp);\r
-                       if(fl_choice(gettext("File is exesist. Overwrite it?"),0,gettext("No"),gettext(" Yes "))==2)\r
-                               break;\r
-               }\r
-               else    break;\r
-       }\r
-       if (newfile != NULL)    save_file(newfile);\r
-       if(fname)       delete []fname;\r
-}\r
-//-----------------------------------------------------------------------------\r
-ScriptWindow *new_view();\r
-void view_cb(Fl_Widget*, void*)\r
-{      Fl_Window* w = new_view();      w->show();      }\r
-//-----------------------------------------------------------------------------\r
-void hint_cb(Fl_Widget*, void*)        {}\r
-//-----------------------------------------------------------------------------\r
-Fl_Menu_Item menuitems[] = {\r
-//     { gettext("File"), 0, 0, 0, FL_SUBMENU },\r
-       { gettext("File/New File"),                     0, new_cb },\r
-       { gettext("File/Open File..."),         FL_CTRL + 'o', open_cb },\r
-       { gettext("File/Insert File..."),       FL_CTRL + 'i', insert_cb },\r
-       { gettext("File/Save File"),                    FL_CTRL + 's', save_cb },\r
-       { gettext("File/Save File As..._"),     FL_CTRL + FL_SHIFT + 's', saveas_cb, 0, FL_MENU_DIVIDER },\r
-/*TODO { gettext("Export"), 0, 0, 0,   FL_SUBMENU },*/\r
-       { gettext("File/New View"),             FL_ALT + 'w', view_cb },\r
-       { gettext("File/Close View_"),  FL_CTRL + 'w', close_cb, 0, FL_MENU_DIVIDER },\r
-       { gettext("File/Exit"),                 FL_ALT + 'x', quit_cb },\r
-//             { 0 },\r
-       { gettext("Edit"), 0, 0, 0, FL_SUBMENU },\r
-               { gettext("Cut"),                       FL_CTRL + 'x', cut_cb },\r
-               { gettext("Copy"),                      FL_CTRL + 'c', copy_cb },\r
-               { gettext("Paste"),                     FL_CTRL + 'v', paste_cb },\r
-               { gettext("Delete"),            0, delete_cb, 0, FL_MENU_DIVIDER },\r
-               { gettext("Insert"), 0, 0, 0,   FL_SUBMENU },\r
-                       { gettext("options"),   FL_ALT + 'o', option_cb },\r
-                       { gettext("style"),             FL_ALT + 'i', style_cb },\r
-                       { gettext("filename"),  0, fname_cb },\r
-                       { gettext("command"),   FL_ALT + 'c', command_cb },\r
-                       { 0 },\r
-               { gettext("Properties"),        0, settings_cb },\r
-               { 0 },\r
-       { gettext("Search"), 0, 0, 0, FL_SUBMENU },\r
-               { gettext("Find..."),           FL_CTRL + 'f', find_cb },\r
-               { gettext("Find Again"),        FL_F + 3, find2_cb },\r
-               { gettext("Replace..."),        FL_CTRL + 'r', replace_cb },\r
-               { gettext("Replace Again"), FL_F + 4, replace2_cb },\r
-               { 0 },\r
-/*TODO{ gettext("Graphics"), 0, 0, 0, FL_SUBMENU },*/\r
-/*TODO{ gettext("Data"), 0, 0, 0, FL_SUBMENU },*/\r
-       { gettext("Help"), 0, 0, 0, FL_SUBMENU },\r
-               { gettext("MGL Help"),          FL_F + 1, help_cb },\r
-               { gettext("MGL Examples"),      0, example_cb },\r
-               { gettext("Hints and FAQ"),     0, hint_cb , 0, FL_MENU_INACTIVE},\r
-               { gettext("About UDAV"),        0, about_cb },\r
-               { 0 },\r
-       { 0 }\r
-};\r
-//-----------------------------------------------------------------------------\r
-void mem_upd_cb(Fl_Widget *, void *v)\r
-{      ((ScriptWindow*)v)->mem_init(); }\r
-//-----------------------------------------------------------------------------\r
-ScriptWindow *new_view()\r
-{\r
-       Fl_Tabs* tt;\r
-       Fl_Group *gg;\r
-       ScriptWindow *w = new ScriptWindow(930, 510, title);\r
-       w->begin();\r
-       w->menu = new Fl_Menu_Bar(0, 0, 930, 30);\r
-\r
-//     w->menu->add(gettext("File"), 0, 0, 0, FL_SUBMENU);     \r
-       w->menu->add(gettext("File/New File"), "", new_cb);\r
-       w->menu->add(gettext("File/Open File..."), "^o", open_cb, w);\r
-       w->menu->add(gettext("File/Insert File..."),    "^i", insert_cb, w);\r
-       w->menu->add(gettext("File/Save File"), "^s", save_cb, w);\r
-       w->menu->add(gettext("File/Save File As..."), 0, saveas_cb, w, FL_MENU_DIVIDER);\r
-       /*TODO  { gettext("Export"), 0, 0, 0,   FL_SUBMENU },*/\r
-       w->menu->add(gettext("File/New View"), "#w", view_cb, w);\r
-       w->menu->add(gettext("File/Close View"), "^w", close_cb, w, FL_MENU_DIVIDER);\r
-       w->menu->add(gettext("File/Exit"), "#x", quit_cb);\r
-//     w->menu->copy(menuitems, w);\r
-\r
-       Fl_Tile *t = new Fl_Tile(0,30,930,455);\r
-       tt = new Fl_Tabs(0,30,300,455,0);       tt->box(UDAV_UP_BOX);   w->ltab = tt;\r
-       gg = new Fl_Group(0,30,300,430);        gg->label(gettext("Script"));\r
-       add_editor(w);  gg->end();\r
-       tt->end();\r
-\r
-       tt = new Fl_Tabs(300,30,630,455,0);     tt->box(UDAV_UP_BOX);   w->rtab = tt;\r
-       gg = new Fl_Group(300,30,630,430,gettext("Canvas"));\r
-       w->graph = new Fl_MGL(300,30,630,430);  gg->end();\r
-       gg = new Fl_Group(300,30,630,430,gettext("Help"));\r
-       w->ghelp = gg;  add_help(w);    gg->end();\r
-       gg = new Fl_Group(300,30,630,430,gettext("Memory"));\r
-       add_mem(w);             gg->end();\r
-       tt->end();\r
-\r
-       w->status = new Fl_Box(0,485,930,25,"Ready");\r
-       w->status->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);\r
-       w->status->color(FL_BACKGROUND_COLOR);\r
-       w->status->box(FL_DOWN_BOX);\r
-       w->graph->status = w->status;\r
-\r
-       t->end();       w->end();       w->resizable(t);\r
-       tt->callback(mem_upd_cb, w);\r
-       w->callback((Fl_Callback *)close_cb, w);\r
-\r
-       num_windows++;\r
-       return w;\r
-}\r
-//-----------------------------------------------------------------------------\r
-void argument_set(int n, const char *s);\r
-int main(int argc, char **argv)\r
-{\r
-//     Fl::lock();\r
-       mgl_ask_func = mgl_ask_fltk;\r
-       char *buf, *buf2, ch;\r
-       pref.get("locale",buf,"ru_RU.cp1251");  setlocale(LC_CTYPE, buf);       free(buf);\r
-       pref.get("plastic_scheme",plastic_scheme,1);\r
-       pref.get("internal_font",internal_font,0);\r
-       pref.get("auto_exec",auto_exec,1);\r
-       pref.get("help_dir",docdir,MGL_DOC_DIR);        // docdir should be freed at exit\r
-\r
-       Fl::visual(FL_DOUBLE|FL_RGB);\r
-       if(plastic_scheme) Fl::scheme("gtk+");\r
-\r
-#ifdef USE_GETTEXT\r
-//     setlocale (LC_NUMERIC, "");\r
-//     bindtextdomain (PACKAGE, LOCALEDIR);\r
-//     textdomain (PACKAGE);\r
-#endif\r
-\r
-       textbuf = new Fl_Text_Buffer;\r
-       style_init();\r
-       ScriptWindow *w = new_view();\r
-\r
-       pref.get("font_dir",buf2,"");\r
-       pref.get("font_name",buf,"");\r
-       mgl_load_font(w->graph->FMGL->get_graph(),buf,buf2);\r
-       if(buf) free(buf);\r
-       if(buf2)        free(buf2);\r
-\r
-       buf = 0;\r
-       while(1)\r
-       {\r
-               ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:ho:L:");\r
-               if(ch>='1' && ch<='9')  argument_set(ch-'0', optarg);\r
-               else if(ch=='L')        setlocale(LC_CTYPE, optarg);\r
-               else if(ch=='h')\r
-               {\r
-                       printf("mglconv convert mgl script to bitmap png file.\nCurrent version is 2.%g\n",MGL_VER2);\r
-                       printf("Usage:\tmgllab [parameter(s)] scriptfile\n");\r
-                       printf( "\t-1 str       set str as argument $1 for script\n"\r
-                                       "\t...          ...\n"\r
-                                       "\t-9 str       set str as argument $9 for script\n"\r
-                                       "\t-L loc       set locale to loc\n"\r
-//                                     "\t-            get script from standard input\n"\r
-                                       "\t-h           print this message\n" );\r
-                       free(docdir);   return 0;\r
-               }\r
-               // NOTE: I will not parse stdin here\r
-               else if(ch==-1 && optind<argc)  buf = argv[optind];\r
-               else if(ch==-1 && optind>=argc) break;\r
-       }\r
-\r
-       w->show(1, argv);\r
-       if(buf && *buf && *buf!='-')\r
-       {\r
-               load_file(buf, -1);\r
-               if(auto_exec)   w->graph->update();\r
-       }\r
-       return Fl::run();\r
-}\r
-//-----------------------------------------------------------------------------\r
diff --git a/mgllab/mathgl.cpp b/mgllab/mathgl.cpp
deleted file mode 100644 (file)
index 15716f0..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/* mathgl.cpp is part of UDAV\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-#include "mgl2/mgl.h"\r
-#include "udav.h"\r
-//-----------------------------------------------------------------------------\r
-#include "xpm/alpha.xpm"\r
-#include "xpm/light.xpm"\r
-#include "xpm/alpha_on.xpm"\r
-#include "xpm/light_on.xpm"\r
-#include "xpm/zoom-fit-best.xpm"\r
-#include "xpm/zoom-fit-best-r.xpm"\r
-#include "xpm/film-r.xpm"\r
-#include "xpm/film-b.xpm"\r
-#include "xpm/media-seek-forward.xpm"\r
-#include "xpm/media-seek-backward.xpm"\r
-#include "xpm/go-previous.xpm"\r
-#include "xpm/go-next.xpm"\r
-#include "xpm/go-down.xpm"\r
-#include "xpm/zoom-out.xpm"\r
-#include "xpm/zoom-in.xpm"\r
-#include "xpm/go-up.xpm"\r
-#include "xpm/zoom-original.xpm"\r
-#include "xpm/view-refresh.xpm"\r
-#include "xpm/rotate.xpm"\r
-#include "xpm/rotate_on.xpm"\r
-#include "xpm/document-properties.xpm"\r
-//#include "xpm/preferences-system.xpm"\r
-#include "xpm/wire.xpm"\r
-//-----------------------------------------------------------------------------\r
-extern int internal_font;\r
-mglParse *Parse=0;\r
-//-----------------------------------------------------------------------------\r
-void udav_error(const char *Message, void *v)\r
-{      ((Fl_MGL*)v)->status->label(Message);   }\r
-mreal udav_delay(void *v)\r
-{      return ((Fl_MGL*)v)->AnimDelay; }\r
-void udav_reload(void *v)\r
-{      Parse->RestoreOnce();   ((Fl_MGL*)v)->update(); }\r
-//-----------------------------------------------------------------------------\r
-void udav_next(void *v)        {       ((Fl_MGL*)v)->next_frame();     }\r
-void Fl_MGL::next_frame()\r
-{\r
-       if(NArgs==0)\r
-       {\r
-               animate_cb(this,this);\r
-               if(NArgs==0)    return;\r
-       }\r
-       ArgCur = (ArgCur+1) % NArgs;\r
-       Parse->AddParam(0,Args[ArgCur]);\r
-       update();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void udav_prev(void *v)        {       ((Fl_MGL*)v)->prev_frame();     }\r
-void Fl_MGL::prev_frame()\r
-{\r
-       if(NArgs==0)\r
-       {\r
-               animate_cb(this,this);\r
-               if(NArgs==0)    return;\r
-       }\r
-       ArgCur = ArgCur>0 ? ArgCur-1 : NArgs-1;\r
-       Parse->AddParam(0,Args[ArgCur]);\r
-       update();\r
-}\r
-//-----------------------------------------------------------------------------\r
-Fl_MGL::Fl_MGL(int x, int y, int w, int h, const char *label) : Fl_MGLView(x,y,w,h,label)\r
-{\r
-       if(!Parse)      Parse = new mglParse;\r
-       Parse->AllowSetSize(true);\r
-       ArgBuf = 0;     NArgs = ArgCur = 0;\r
-       script = script_pre = 0;        par = this;\r
-       next = udav_next;       delay = udav_delay;\r
-       prev = udav_prev;       reload = udav_reload;\r
-/*#ifdef WIN32\r
-//     setlocale(LC_TYPE,"russian_Russia.CP1251");\r
-       char *path;\r
-       get_doc_dir(path);\r
-       if(!FMGL->GetFont()->Load("STIX",path && path[0] ? path : ".")) FMGL->GetFont()->Restore();\r
-       free(path);\r
-#endif*/\r
-}\r
-//-----------------------------------------------------------------------------\r
-Fl_MGL::~Fl_MGL()      {       clear_scripts();        if(ArgBuf)      delete []ArgBuf;        }\r
-//-----------------------------------------------------------------------------\r
-void Fl_MGL::clear_scripts()\r
-{\r
-       if(script)              free(script);\r
-       if(script_pre)  free(script_pre);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void Fl_MGL::scripts(char *scr, char *pre)\r
-{      clear_scripts();        script=scr;     script_pre=pre; }\r
-//-----------------------------------------------------------------------------\r
-int Fl_MGL::Draw(mglGraph *gr)\r
-{\r
-       Parse->Execute(gr,script_pre);\r
-       Parse->Execute(gr,script);\r
-       status->label(gr->Message());\r
-       return 0;\r
-}\r
-//-----------------------------------------------------------------------------\r
-void Fl_MGL::update()\r
-{\r
-       // NOTE: hint for old style View(). May be I should remove it!\r
-       if(!script || !strstr(script,"rotate")) mgl_rotate(FMGL->get_graph(),0,0,0);\r
-\r
-       Fl_MGLView::update();\r
-\r
-       mglVar *v = Parse->FindVar("");\r
-       while(v)\r
-       {\r
-               if(v->o)        ((TableWindow *)v->o)->update(v);\r
-               v = v->next;\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void add_suffix(char *fname, const char *ext)\r
-{\r
-       long n=strlen(fname);\r
-       if(n>4 && fname[n-4]=='.')\r
-       {       fname[n-3]=ext[0];      fname[n-2]=ext[1];      fname[n-1]=ext[2];      }\r
-       else    {       strcat(fname,".");      strcat(fname,ext);      }\r
-\r
-}\r
-//-----------------------------------------------------------------------------\r
diff --git a/mgllab/option.cpp b/mgllab/option.cpp
deleted file mode 100644 (file)
index afff0d5..0000000
+++ /dev/null
@@ -1,439 +0,0 @@
-/* option.cpp is part of UDAV\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-#include <string.h>\r
-#include <FL/Fl.H>\r
-#include <FL/Fl_Window.H>\r
-#include <FL/Fl_Box.H>\r
-#include <FL/Fl_Input.H>\r
-#include <FL/Fl_Check_Button.H>\r
-#include <FL/Fl_Round_Button.H>\r
-#include <FL/Fl_Button.H>\r
-#include <FL/Fl_Return_Button.H>\r
-#include <FL/Fl_Tabs.H>\r
-#include <FL/Fl_Group.H>\r
-#include <FL/Fl_Choice.H>\r
-#include <FL/Fl_Spinner.H>\r
-#include <FL/Fl_Output.H>\r
-#include <FL/Fl_Text_Buffer.H>\r
-#include "udav.h"\r
-//-----------------------------------------------------------------------------\r
-extern Fl_Menu_Item colors[];\r
-extern Fl_Text_Buffer  *textbuf;\r
-//-----------------------------------------------------------------------------\r
-struct OptionDlg\r
-{\r
-public:\r
-       Fl_Window* wnd;\r
-       int OK;\r
-       char result[256];\r
-       OptionDlg()     {       memset(this,0,sizeof(OptionDlg));       create_dlg();   }\r
-       ~OptionDlg()    {       delete wnd;     }\r
-       void FillResult();\r
-protected:\r
-       Fl_Input *xmin, *xmax, *ymin, *ymax, *zmin, *zmax, *cmin, *cmax;\r
-       Fl_Input *alpha, *amb, *mesh, *font;\r
-       Fl_Choice *cut;\r
-\r
-       void create_dlg();\r
-} option_dlg;\r
-//-----------------------------------------------------------------------------\r
-struct StyleDlg\r
-{\r
-public:\r
-friend void style_set_cb(Fl_Widget *, void *v);\r
-friend void style_rdo_cb(Fl_Widget *, void *v);\r
-friend void font_cb(Fl_Widget *, void *v);\r
-friend void line_cb(Fl_Widget *, void *v);\r
-friend void face_cb(Fl_Widget *, void *v);\r
-       Fl_Window* wnd;\r
-       int OK;\r
-       char result[16];\r
-       StyleDlg()      {       memset(this,0,sizeof(StyleDlg));        create_dlg();   }\r
-       ~StyleDlg()     {       delete wnd;     }\r
-protected:\r
-       Fl_Tabs *tab;\r
-       Fl_Group *ltab, *stab, *ftab;\r
-       Fl_Choice *cl, *cf, *c[7], *ae, *as;\r
-       Fl_Choice *dash, *mark, *dir, *text;\r
-       Fl_Spinner *lw;\r
-       Fl_Output *res;\r
-       Fl_Check_Button *d, *w, *sc, *rm, *it, *bf, *gt;\r
-       Fl_Round_Button *rl, *rc, *rr;\r
-\r
-       void create_dlg();\r
-} style_dlg;\r
-//-----------------------------------------------------------------------------\r
-void option_dlg_cb(Fl_Widget *, void *v)\r
-{      option_dlg.OK = true;   ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void style_dlg_cb(Fl_Widget *, void *v)\r
-{      style_dlg.OK = true;    ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void OptionDlg::create_dlg()\r
-{\r
-       Fl_Button *o;\r
-       wnd = new Fl_Window(490, 180, gettext("Command options"));\r
-       new Fl_Box(10, 15, 75, 25, gettext("X-Range"));\r
-       xmin = new Fl_Input(85, 15, 75, 25);\r
-       xmin->tooltip(gettext("Minimal value of X for cutting or for coordinate filling"));\r
-       xmax = new Fl_Input(165, 15, 75, 25);\r
-       xmax->tooltip(gettext("Maximal value of X for cutting or for coordinate filling"));\r
-       new Fl_Box(245, 15, 75, 25, gettext("Y-Range"));\r
-       ymin = new Fl_Input(320, 15, 75, 25);\r
-       ymin->tooltip(gettext("Minimal value of Y for cutting or for coordinate filling"));\r
-       ymax = new Fl_Input(400, 15, 75, 25);\r
-       ymax->tooltip(gettext("Maximal value of Y for cutting or for coordinate filling"));\r
-       new Fl_Box(10, 45, 75, 25, gettext("Z-Range"));\r
-       zmin = new Fl_Input(85, 45, 75, 25);\r
-       zmin->tooltip(gettext("Minimal value of Z for cutting or for coordinate filling"));\r
-       zmax = new Fl_Input(165, 45, 75, 25);\r
-       zmax->tooltip(gettext("Maximal value of Z for cutting or for coordinate filling"));\r
-       new Fl_Box(245, 45, 75, 25, gettext("C-Range"));\r
-       cmin = new Fl_Input(320, 45, 75, 25);\r
-       cmin->tooltip(gettext("Low border for determining color or alpha"));\r
-       cmax = new Fl_Input(400, 45, 75, 25);\r
-       cmax->tooltip(gettext("Upper border for determining color or alpha"));\r
-       {       Fl_Box *o = new Fl_Box(15, 75, 460, 5);                 o->box(FL_UP_BOX);      }\r
-       alpha = new Fl_Input(25, 105, 75, 25, "Alpha");         alpha->align(FL_ALIGN_TOP);\r
-       alpha->tooltip(gettext("Alpha value (transparency) of surface or cloud"));\r
-       amb = new Fl_Input(110, 105, 75, 25, gettext("Ambient"));       amb->align(FL_ALIGN_TOP);\r
-       amb->tooltip(gettext("Own brightness of the surface"));\r
-       mesh = new Fl_Input(195, 105, 75, 25, gettext("Mesh Num"));     mesh->align(FL_ALIGN_TOP);\r
-       mesh->tooltip(gettext("Approximate number of mesh lines in plot"));\r
-       font = new Fl_Input(280, 105, 75, 25, gettext("Font Size"));    font->align(FL_ALIGN_TOP);\r
-       font->tooltip(gettext("Act as default value for font size"));\r
-       cut = new Fl_Choice(365, 105, 75, 25, gettext("Cutting"));      cut->align(FL_ALIGN_TOP);\r
-       cut->add(gettext("on"));        cut->add(gettext("off"));\r
-       cut->tooltip(gettext("Set cutting off/on for particular plot"));\r
-\r
-       o = new Fl_Button(320, 145, 75, 25, gettext("Cancel"));         o->callback(close_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o = new Fl_Return_Button(405, 145, 75, 25, gettext("OK"));      o->callback(option_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void OptionDlg::FillResult()\r
-{\r
-       double x1=0,y1=0,z1=0,x2=0,y2=0,z2=0;\r
-       bool u1,v1,w1,u2,v2,w2;\r
-       char str[64];\r
-       result[0]=0;\r
-\r
-       u1 = xmin->value()[0];  if(u1)  x1 = atof(xmin->value());\r
-       u2 = xmax->value()[0];  if(u2)  x2 = atof(xmax->value());\r
-       v1 = ymin->value()[0];  if(v1)  y1 = atof(ymin->value());\r
-       v2 = ymin->value()[0];  if(v2)  y2 = atof(ymax->value());\r
-       w1 = zmin->value()[0];  if(w1)  z1 = atof(zmin->value());\r
-       w2 = zmin->value()[0];  if(w2)  z2 = atof(zmax->value());\r
-       if(u1 && u2)    {snprintf(str,64,"; xrange %g %g",x1,x2);       strcat(result,str);}\r
-       if(v1 && v2)    {snprintf(str,64,"; yrange %g %g",y1,y2);       strcat(result,str);}\r
-       if(w1 && w2)    {snprintf(str,64,"; zrange %g %g",z1,z2);       strcat(result,str);}\r
-\r
-       u1 = cmin->value()[0];  if(u1)  x1 = atof(cmin->value());\r
-       u2 = cmax->value()[0];  if(u2)  x2 = atof(cmax->value());\r
-       if(u1&&u2)      {snprintf(str,64,"; crange %g %g",x1,x2);       strcat(result,str);}\r
-\r
-       if(alpha->value()[0])\r
-       {       snprintf(str,64,"; alpha %g",atof(alpha->value()));     strcat(result,str);}\r
-       if(amb->value()[0])\r
-       {       snprintf(str,64,"; ambient %g",atof(amb->value()));     strcat(result,str);}\r
-       if(mesh->value()[0])\r
-       {       snprintf(str,64,"; meshnum %g",atof(mesh->value()));strcat(result,str);}\r
-       if(font->value()[0])\r
-       {       snprintf(str,64,"; fontsize '%g'",atof(font->value())); strcat(result,str);}\r
-       if(cut->value()>=0)\r
-       {snprintf(str,64,"; cut %s",cut->value()==0?"on":"off");        strcat(result,str);}\r
-}\r
-//-----------------------------------------------------------------------------\r
-void option_cb(Fl_Widget *, void *v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       OptionDlg *s = &option_dlg;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       // insert at the end of string\r
-       {\r
-               long i=e->editor->insert_position(), j=textbuf->line_end(i);\r
-               s->FillResult();\r
-               e->editor->insert_position(j);\r
-               e->editor->insert(s->result);\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void option_in_cb(Fl_Widget *, void *v)\r
-{\r
-       Fl_Input* e = (Fl_Input*)v;\r
-       OptionDlg *s = &option_dlg;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)\r
-       {\r
-               s->FillResult();\r
-               e->value(s->result);\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-Fl_Menu_Item arrows[] = {\r
-       {("none")},     //_\r
-       {("arrow")},    //A\r
-       {("back arrow")},       //V\r
-       {("stop")},     //I\r
-       {("size")},     //K\r
-       {("triangle")}, //T\r
-       {("square")},   //S\r
-       {("rhomb")},    //D\r
-       {("circle")},   //O\r
-       {0}};\r
-//-----------------------------------------------------------------------------\r
-Fl_Menu_Item dashing[] = {\r
-       {("solid")},    //-\r
-       {("dash")},     //|\r
-       {("dash dot")}, //j\r
-       {("small dash")},       //;\r
-       {("small dash dot")},   //i\r
-       {("dots")},     //:\r
-       {("none")},     //\r
-       {0}};\r
-//-----------------------------------------------------------------------------\r
-Fl_Menu_Item markers[] = {\r
-       {("none")},     //\r
-       {("circle")},   //o\r
-       {("cross")},    //+\r
-       {("skew cross")},       //x\r
-       {("square")},   //s\r
-       {("rhomb")},    //d\r
-       {("point")},    //.\r
-       {("triangle up")},      //^\r
-       {("triangle down")},    //v\r
-       {0}};\r
-//-----------------------------------------------------------------------------\r
-void style_set_cb(Fl_Widget *,void *)\r
-{\r
-       StyleDlg  *s = &style_dlg;\r
-       Fl_Widget *t = s->tab->value();\r
-       const char *cols = " wbgrcmylenuqphkWBGRCMYLENUQPH";\r
-       char *r = s->result;\r
-       long i=0,j;\r
-       if(t==s->ltab)  // line style\r
-       {\r
-               const char *aa = "_AVIKTSDO", *dd="-|j;i: ", *mm="#o+xsd.^v";\r
-               if(s->cl->value()>0)    r[i++]=cols[s->cl->value()];\r
-               if(s->dash->value()>0)  r[i++]=dd[s->dash->value()];\r
-               if(s->mark->value()>0)  r[i++]=mm[s->mark->value()];\r
-               if(s->lw->value()>1 || s->lw->value()==0)\r
-                       r[i++] = '0'+int(0.1+s->lw->value());\r
-               if(s->as->value()>0)\r
-               {       r[i++]=aa[s->ae->value()];      r[i++]=aa[s->as->value()];      }\r
-               else if(s->ae->value()>0)       r[i++]=aa[s->ae->value()];\r
-       }\r
-       else if(t==s->stab)     // surf style\r
-       {\r
-               for(j=0;j<7;j++)\r
-               {\r
-                       if(s->c[j]->value()>0)  r[i++]=cols[s->c[j]->value()];\r
-                       else break;\r
-               }\r
-               if(s->d->value())       r[i++] = 'd';\r
-               if(s->w->value())       r[i++] = '#';\r
-               if(s->dir->value()>=0)  r[i++] = 'x'+s->dir->value();\r
-               if(s->text->value()>0)  r[i++] = s->text->value()==1 ? 't':'T';\r
-       }\r
-       else if(t==s->ftab)     // text style\r
-       {\r
-               if(s->rm->value())      r[i++] = 'r';\r
-               if(s->sc->value())      r[i++] = 's';\r
-               if(s->it->value())      r[i++] = 'i';\r
-               if(s->bf->value())      r[i++] = 'b';\r
-               if(s->gt->value() && !s->rm->value())   r[i++] = 'g';\r
-               if(s->rl->value())      r[i++] = 'L';\r
-               else if(s->rc->value()) r[i++] = 'C';\r
-               else if(s->rr->value()) r[i++] = 'R';\r
-               if(s->cf->value()>0)\r
-               {       r[i++]=':';     r[i++]=cols[s->cf->value()];    }\r
-       }\r
-       r[i]=0;\r
-       s->res->value(r);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void style_rdo_cb(Fl_Widget *,void *v)\r
-{\r
-       StyleDlg  *s = &style_dlg;\r
-       s->rl->value(0);        s->rc->value(0);        s->rr->value(0);\r
-       ((Fl_Round_Button *)v)->value(1);\r
-       style_set_cb(0,0);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void StyleDlg::create_dlg()\r
-{\r
-       wnd = new Fl_Window(295, 337, gettext("String with line/surf/text style"));\r
-       tab = new Fl_Tabs(0, 0, 295, 255);      tab->callback(style_set_cb);\r
-       tab->box(UDAV_UP_BOX);\r
-\r
-       ltab = new Fl_Group(0, 25, 295, 230, gettext("Line style"));\r
-       as = new Fl_Choice(10, 50, 80, 25, gettext("Arrow at start"));\r
-       as->align(FL_ALIGN_TOP);        as->copy(arrows);       as->callback(style_set_cb);\r
-//     as->tooltip(gettext("Type of arrow at first point of line or curve"));\r
-       dash = new Fl_Choice(110, 50, 80, 25, gettext("Dashing"));\r
-       dash->align(FL_ALIGN_TOP);      dash->copy(dashing);dash->callback(style_set_cb);\r
-//     dash->tooltip(gettext("Type dashing for line or curve"));\r
-       ae = new Fl_Choice(210, 50, 80, 25, gettext("Arrow at end"));\r
-       ae->align(FL_ALIGN_TOP);        ae->copy(arrows);       ae->callback(style_set_cb);\r
-//     ae->tooltip(gettext("Type of arrow at last point of line or curve"));\r
-       cl = new Fl_Choice(110, 85, 80, 25, gettext("Color"));  cl->copy(colors);\r
-       cl->callback(style_set_cb);\r
-       mark = new Fl_Choice(110, 120, 80, 25, gettext("Marks"));\r
-       mark->copy(markers);    mark->callback(style_set_cb);\r
-//     mark->tooltip(gettext("Type of marks at positions of data points"));\r
-       lw = new Fl_Spinner(110, 155, 80, 25, gettext("Line width"));\r
-       lw->range(0,9); lw->step(1);    lw->callback(style_set_cb);\r
-//     lw->tooltip(gettext("Relative width of line or curve"));\r
-       ltab->end();\r
-\r
-       stab = new Fl_Group(0, 25, 295, 230, gettext("Color scheme"));  stab->hide();\r
-       c[0] = new Fl_Choice(15, 45, 75, 25, gettext("Color order"));\r
-       c[0]->align(FL_ALIGN_TOP);      c[0]->copy(colors);     c[0]->callback(style_set_cb);\r
-       c[1] = new Fl_Choice(15, 75, 75, 25);   c[1]->copy(colors);     c[1]->callback(style_set_cb);\r
-       c[2] = new Fl_Choice(15, 105, 75, 25);  c[2]->copy(colors);     c[2]->callback(style_set_cb);\r
-       c[3] = new Fl_Choice(15, 135, 75, 25);  c[3]->copy(colors);     c[3]->callback(style_set_cb);\r
-       c[4] = new Fl_Choice(15, 165, 75, 25);  c[4]->copy(colors);     c[4]->callback(style_set_cb);\r
-       c[5] = new Fl_Choice(15, 195, 75, 25);  c[5]->copy(colors);     c[5]->callback(style_set_cb);\r
-       c[6] = new Fl_Choice(15, 225, 75, 25);  c[6]->copy(colors);     c[6]->callback(style_set_cb);\r
-       d = new Fl_Check_Button(100, 45, 180, 25, gettext("Colors along coordinates"));\r
-//     w->tooltip(gettext("Set face color proportional to its position"));\r
-       d->callback(style_set_cb);\r
-       w = new Fl_Check_Button(100, 75, 180, 25, gettext("Wire or mesh plot"));\r
-       w->callback(style_set_cb);\r
-//     w->tooltip(gettext("Switch to draw wire isosurface or set to draw mesh on surface"));\r
-       dir = new Fl_Choice(210, 105, 75, 25, gettext("Axial direction"));\r
-       dir->add("x");  dir->add("y");  dir->add("z");  dir->callback(style_set_cb);\r
-       text = new Fl_Choice(210, 135, 75, 25, gettext("Text on contours"));\r
-//     text->tooltip("Draw contour values near contour lines"));\r
-       text->add(gettext("none"));     text->add(gettext("under"));\r
-       text->add(gettext("above"));    text->callback(style_set_cb);\r
-       stab->end();\r
-\r
-       ftab = new Fl_Group(0, 25, 295, 230, gettext("Text style"));            ftab->hide();\r
-       sc = new Fl_Check_Button(15, 40, 120, 25, gettext("Script font/style"));        sc->callback(style_set_cb);\r
-       rm = new Fl_Check_Button(15, 70, 120, 25, gettext("Roman font"));       rm->callback(style_set_cb);\r
-       gt = new Fl_Check_Button(15, 100, 120, 25, gettext("Gothic font"));     gt->callback(style_set_cb);\r
-       it = new Fl_Check_Button(15, 130, 120, 25, gettext("Italic style"));    it->callback(style_set_cb);\r
-       bf = new Fl_Check_Button(15, 160, 120, 25, gettext("Bold style"));      bf->callback(style_set_cb);\r
-       cf = new Fl_Choice(200, 40, 80, 25, gettext("Text color"));     cf->copy(colors);cf->callback(style_set_cb);\r
-       { Fl_Box* o = new Fl_Box(160, 90, 120, 90, gettext("Alignment"));\r
-               o->box(FL_DOWN_BOX);    o->align(FL_ALIGN_TOP);}\r
-       rl = new Fl_Round_Button(170, 100, 100, 25, gettext("left"));           rl->callback(style_rdo_cb,rl);\r
-       rc = new Fl_Round_Button(170, 125, 100, 25, gettext("at center"));      rc->callback(style_rdo_cb,rc);\r
-       rr = new Fl_Round_Button(170, 150, 100, 25, gettext("right"));          rr->callback(style_rdo_cb,rr);\r
-       ftab->end();\r
-\r
-       tab->end();\r
-       res = new Fl_Output(50, 265, 235, 25, gettext("Result"));\r
-//     res->tooltip(gettext("Resulting string which will be used as argument of a command"));\r
-       Fl_Button *o;\r
-       o = new Fl_Button(125, 300, 75, 25, gettext("Cancel"));         o->callback(close_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o = new Fl_Return_Button(210, 300, 75, 25, gettext("OK"));      o->callback(style_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void style_cb(Fl_Widget *, void *v)\r
-{\r
-       ScriptWindow* e = (ScriptWindow*)v;\r
-       StyleDlg *s = &style_dlg;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       // replace current selection\r
-       {\r
-               int p,q;\r
-               char str[20];\r
-               snprintf(str,20,"'%s'",s->result);\r
-               textbuf->selection_position(&p, &q);\r
-               if(p==q)        e->editor->insert(str);\r
-               else            textbuf->replace_selection(str);\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void style_in_cb(Fl_Widget *, void *v)\r
-{\r
-       Fl_Input* e = (Fl_Input*)v;\r
-       StyleDlg *s = &style_dlg;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       e->value(s->result);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void font_cb(Fl_Widget *, void *v)\r
-{\r
-       Fl_Input* e = (Fl_Input *)v;\r
-       StyleDlg *s = &style_dlg;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->tab->value(s->ftab);\r
-       s->ltab->deactivate();\r
-       s->stab->deactivate();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       // replace current selection\r
-               e->value(s->result);\r
-       s->ltab->activate();\r
-       s->stab->activate();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void line_cb(Fl_Widget *, void *v)\r
-{\r
-       Fl_Input* e = (Fl_Input *)v;\r
-       StyleDlg *s = &style_dlg;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->tab->value(s->ltab);\r
-       s->ftab->deactivate();\r
-       s->stab->deactivate();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       // replace current selection\r
-               e->value(s->result);\r
-       s->ftab->activate();\r
-       s->stab->activate();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void face_cb(Fl_Widget *, void *v)\r
-{\r
-       Fl_Input* e = (Fl_Input *)v;\r
-       StyleDlg *s = &style_dlg;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->tab->value(s->stab);\r
-       s->ltab->deactivate();\r
-       s->ftab->deactivate();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       // replace current selection\r
-               e->value(s->result);\r
-       s->ltab->activate();\r
-       s->ftab->activate();\r
-}\r
-//-----------------------------------------------------------------------------\r
diff --git a/mgllab/setup.cpp b/mgllab/setup.cpp
deleted file mode 100644 (file)
index 44309ce..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-/* setup.cpp is part of UDAV\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-#include "mgl2/mgl.h"\r
-#include <string.h>\r
-#include <FL/Fl_Tabs.H>\r
-#include <FL/Fl_Round_Button.H>\r
-#include <FL/Fl_Multiline_Input.H>\r
-#include <FL/Fl_Spinner.H>\r
-#include <locale.h>\r
-#include "udav.h"\r
-//-----------------------------------------------------------------------------\r
-extern int auto_exec, plastic_scheme, internal_font;\r
-//-----------------------------------------------------------------------------\r
-void setup_dlg_cb(Fl_Widget *, void *v)\r
-{      SetupDlg *s = (SetupDlg *)v;    s->OK = true;   s->wnd->hide(); }\r
-//-----------------------------------------------------------------------------\r
-void setup_sav_cb(Fl_Widget *, void *v)\r
-{\r
-       SetupDlg *e = (SetupDlg *)v;\r
-       char *buf = e->ToScript();\r
-       const char *fname;\r
-       if(buf[0])\r
-       {\r
-               fname = e->templ->value();\r
-               if(fname[0]==0) fname = "template.mgl";\r
-               FILE *fp = fopen(fname,"w");\r
-               fputs(buf,fp);\r
-               fclose(fp);\r
-       }\r
-       free(buf);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void close_dlg_cb(Fl_Widget *, void *v)\r
-{      ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void SetupDlg::CreateGen()\r
-{\r
-       xmin = new Fl_Input(105, 50, 75, 25);   xmax = new Fl_Input(105, 80, 75, 25);\r
-       ymin = new Fl_Input(190, 50, 75, 25);   ymax = new Fl_Input(190, 80, 75, 25);\r
-       zmin = new Fl_Input(275, 50, 75, 25);   zmax = new Fl_Input(275, 80, 75, 25);\r
-       cmin = new Fl_Input(360, 50, 75, 25);   cmax = new Fl_Input(360, 80, 75, 25);\r
-\r
-       xorg = new Fl_Input(105, 110, 75, 25);\r
-       yorg = new Fl_Input(190, 110, 75, 25);\r
-       zorg = new Fl_Input(275, 110, 75, 25);\r
-       xlab = new Fl_Input(105, 140, 75, 25);\r
-       ylab = new Fl_Input(190, 140, 75, 25);\r
-       zlab = new Fl_Input(275, 140, 75, 25);\r
-\r
-       xpos = new Fl_Choice(105, 170, 75, 25); xpos->add(gettext("at minumum"));\r
-               xpos->add("at center"); xpos->add(gettext("at maxumum"));       xpos->value(1);\r
-       ypos = new Fl_Choice(190, 170, 75, 25); ypos->add(gettext("at minumum"));\r
-               ypos->add("at center"); ypos->add(gettext("at maxumum"));       ypos->value(1);\r
-       zpos = new Fl_Choice(275, 170, 75, 25); zpos->add(gettext("at minumum"));\r
-               zpos->add("at center"); zpos->add(gettext("at maxumum"));       zpos->value(1);\r
-       xtik = new Fl_Input(105, 200, 75, 25);\r
-       ytik = new Fl_Input(190, 200, 75, 25);\r
-       ztik = new Fl_Input(275, 200, 75, 25);\r
-       xsub = new Fl_Input(105, 230, 75, 25);\r
-       ysub = new Fl_Input(190, 230, 75, 25);\r
-       zsub = new Fl_Input(275, 230, 75, 25);\r
-\r
-       { Fl_Box* o = new Fl_Box(10, 260, 470, 5);      o->box(FL_DOWN_BOX);    }\r
-       alphad = new Fl_Input(20, 285, 75, 25, gettext("AlphaDef"));    alphad->align(FL_ALIGN_TOP);\r
-       ambient = new Fl_Input(105, 285, 75, 25, gettext("Ambient"));   ambient->align(FL_ALIGN_TOP);\r
-       basew = new Fl_Input(190, 285, 75, 25, gettext("Base Width"));  basew->align(FL_ALIGN_TOP);\r
-       mesh = new Fl_Input(275, 285, 75, 25, gettext("Mesh Num"));             mesh->align(FL_ALIGN_TOP);\r
-       axial = new Fl_Choice(360, 285, 75, 25, gettext("Axial Dir"));  axial->align(FL_ALIGN_TOP);\r
-       axial->add("x");        axial->add("y");        axial->add("z");\r
-       font = new Fl_Input(20, 330, 50, 25, gettext("Font"));                  font->align(FL_ALIGN_TOP);\r
-       { Fl_Button* o = new Fl_Button(70, 330, 25, 25, "..");  o->callback(font_cb, font);\r
-               o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);     }\r
-       size = new Fl_Input(105, 330, 75, 25, gettext("Font Size"));    size->align(FL_ALIGN_TOP);\r
-       alpha = new Fl_Check_Button(190, 330, 75, 25, gettext("Alpha on"));\r
-       light = new Fl_Check_Button(275, 330, 75, 25, gettext("Light on"));\r
-       rotate = new Fl_Check_Button(360, 330, 90, 25, gettext("Rotate text"));\r
-}\r
-//-----------------------------------------------------------------------------\r
-void SetupDlg::CreateLid()\r
-{\r
-       const char *str[10]={"0:", "1:", "2:", "3:", "4:", "5:", "6:", "7:", "8:", "9:"};\r
-       int h;\r
-       for(long i=0;i<10;i++)\r
-       {\r
-               h = 55 + 30*i;\r
-               new Fl_Box(10, h, 25, 25, str[i]);\r
-               lid[i] = new Fl_Check_Button(35, h, 40, 25, gettext("on"));\r
-               xid[i] = new Fl_Input(85, h, 75, 25);\r
-               yid[i] = new Fl_Input(165, h, 75, 25);\r
-               zid[i] = new Fl_Input(245, h, 75, 25);\r
-               cid[i] = new Fl_Choice(325, h, 75, 25);\r
-               cid[i]->copy(colors);\r
-               bid[i] = new Fl_Input(405, h, 75, 25);\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void SetupDlg::CreateDlg()\r
-{\r
-       OK = false;\r
-       wnd = new Fl_Window(490, 406, gettext("Setup graphics"));\r
-       Fl_Tabs* t = new Fl_Tabs(0, 0, 490, 360);       t->box(UDAV_UP_BOX);\r
-\r
-       Fl_Group *g = new Fl_Group(0, 25, 485, 330, gettext("General"));\r
-       new Fl_Box(105, 30, 75, 20, gettext("X axis"));\r
-       new Fl_Box(190, 30, 75, 20, gettext("Y axis"));\r
-       new Fl_Box(275, 30, 75, 20, gettext("Z axis"));\r
-       new Fl_Box(360, 30, 75, 20, gettext("Color"));\r
-\r
-       new Fl_Box(25, 50, 75, 25, gettext("Minimal"));\r
-       new Fl_Box(25, 80, 75, 25, gettext("Maximal"));\r
-       new Fl_Box(25, 110, 75, 25, gettext("Origin"));\r
-       new Fl_Box(25, 140, 75, 25, gettext("Label"));\r
-       new Fl_Box(25, 170, 75, 25, gettext("Position"));\r
-       new Fl_Box(25, 200, 75, 25, gettext("Ticks"));\r
-       new Fl_Box(25, 230, 75, 25, gettext("SubTicks"));\r
-       CreateGen();\r
-       g->end();\r
-\r
-       g = new Fl_Group(0, 25, 485, 330, gettext("Light"));    g->hide();\r
-       new Fl_Box(10, 30, 25, 25, gettext("ID"));\r
-       new Fl_Box(40, 30, 40, 25, gettext("State"));\r
-       new Fl_Box(85, 30, 75, 25, gettext("X position"));\r
-       new Fl_Box(165, 30, 75, 25, gettext("Y position"));\r
-       new Fl_Box(245, 30, 75, 25, gettext("Z position"));\r
-       new Fl_Box(325, 30, 75, 25, gettext("Color"));\r
-       new Fl_Box(405, 30, 75, 25, gettext("Brightness"));\r
-       CreateLid();\r
-       g->end();\r
-\r
-       g = new Fl_Group(0, 25, 485, 330, gettext("Setup code"));       g->hide();\r
-       code = new Fl_Help_View(0, 25, 485, 330);\r
-       g->end();\r
-\r
-       t->end();       //Fl_Group::current()->resizable(t);\r
-       Fl_Button *o;\r
-       templ = new Fl_Input(120, 370, 110, 25, gettext("Template name"));\r
-       templ->value("template.mgl");\r
-       o = new Fl_Button(230, 370, 80, 25, gettext("Save"));   o->callback(setup_sav_cb, wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o->tooltip(gettext("Save settings to file template.mgl.\nYou may use it later by 'call template.mgl'"));\r
-\r
-       o = new Fl_Button(315, 370, 80, 25, gettext("Cancel")); o->callback(close_dlg_cb, wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o = new Fl_Return_Button(400, 370, 80, 25, gettext("OK"));      o->callback(setup_dlg_cb, this);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-char *SetupDlg::ToScript()\r
-{\r
-       long i;\r
-       double x1=0,y1=0,z1=0,x2=0,y2=0,z2=0;\r
-       bool u1,v1,w1,u2,v2,w2;\r
-       const char *cols = " wbgrcmylenuqphkWBGRCMYLENUQPH";\r
-       char *buf = (char *)malloc(1024*sizeof(char)), str[128];\r
-       long num = 1024, cur = 0;\r
-       buf[0]=0;\r
-       if(!OK) return buf;\r
-\r
-       for(i=0;i<10;i++)       // set light sources\r
-       {\r
-//fl_message("before %d lid:%d xid:%s yid:%s zid:%s",i,lid[i]->value(), xid[i]->value(),yid[i]->value(),zid[i]->value());\r
-               if(!lid[i]->value())    continue;\r
-               if(!xid[i]->value()[0] || !yid[i]->value()[0] || !zid[i]->value()[0])   continue;\r
-               x1=atof(xid[i]->value());       y1=atof(yid[i]->value());       z1=atof(zid[i]->value());\r
-               if(!bid[i]->value()[0])\r
-                       cur += snprintf(str,128,"light %ld %g %g %g '%c'\n",i,x1,y1,z1,\r
-                                               cols[cid[i]->value()]);\r
-               else\r
-                       cur += snprintf(str,128,"light %ld %g %g %g '%c' %g\n",i,x1,y1,z1,\r
-                                               cols[cid[i]->value()],atof(bid[i]->value()));\r
-               strcat(buf,str);\r
-       }\r
-       u1 = xmin->value()[0];  if(u1)  x1 = atof(xmin->value());\r
-       u2 = xmax->value()[0];  if(u2)  x2 = atof(xmax->value());\r
-       v1 = ymin->value()[0];  if(v1)  y1 = atof(ymin->value());\r
-       v2 = ymin->value()[0];  if(v2)  y2 = atof(ymax->value());\r
-       w1 = zmin->value()[0];  if(w1)  z1 = atof(zmin->value());\r
-       w2 = zmin->value()[0];  if(w2)  z2 = atof(zmax->value());\r
-       if(u1&&v1&&w1&&u2&&v2&&w2)\r
-       {\r
-               cur+=snprintf(str,128,"axis %g %g %g %g %g %g\n",x1,y1,z1,x2,y2,z2);\r
-               strcat(buf,str);\r
-       }\r
-       else\r
-       {\r
-               if(u1 && u2)    {cur+=snprintf(str,128,"xrange %g %g\n",x1,x2); strcat(buf,str);}\r
-               if(v1 && v2)    {cur+=snprintf(str,128,"yrange %g %g\n",y1,y2); strcat(buf,str);}\r
-               if(w1 && w2)    {cur+=snprintf(str,128,"zrange %g %g\n",z1,z2); strcat(buf,str);}\r
-       }\r
-       u1 = cmin->value()[0];  if(u1)  x1 = atof(cmin->value());\r
-       u2 = cmax->value()[0];  if(u2)  x2 = atof(cmax->value());\r
-       if(u1&&u2)      {cur+=snprintf(str,128,"crange %g %g\n",x1,x2); strcat(buf,str);}\r
-       if(cur>num-256) {       num+=512;       buf = (char *)realloc(buf,num*sizeof(char));    }\r
-\r
-       u1 = xorg->value()[0];  if(u1)  x1 = atof(xorg->value());\r
-       v1 = yorg->value()[0];  if(v1)  y1 = atof(yorg->value());\r
-       w1 = zorg->value()[0];  if(w1)  z1 = atof(zorg->value());\r
-       if(u1&&v1&&w1)  {snprintf(str,128,"origin %g %g %g\n",x1,y1,z1);        strcat(buf,str);}\r
-\r
-       u1 = xtik->value()[0];  if(u1)  x1 = atof(xtik->value());\r
-       u2 = xsub->value()[0];  if(u2)  x2 = atoi(xsub->value());\r
-       v1 = ytik->value()[0];  if(v1)  y1 = atof(ytik->value());\r
-       v2 = ysub->value()[0];  if(v2)  y2 = atoi(ysub->value());\r
-       w1 = ztik->value()[0];  if(w1)  z1 = atof(ztik->value());\r
-       w2 = zsub->value()[0];  if(w2)  z2 = atoi(zsub->value());\r
-       if(u1 && u2)    {cur+=snprintf(str,128,"xtick %g %g\n",x1,x2);  strcat(buf,str);}\r
-       if(v1 && v2)    {cur+=snprintf(str,128,"ytick %g %g\n",y1,y2);  strcat(buf,str);}\r
-       if(w1 && w2)    {cur+=snprintf(str,128,"ztick %g %g\n",z1,z2);  strcat(buf,str);}\r
-       if(u1 && !u2)   {cur+=snprintf(str,128,"xtick %g\n",x1);        strcat(buf,str);}\r
-       if(v1 && !v2)   {cur+=snprintf(str,128,"ytick %g\n",y1);        strcat(buf,str);}\r
-       if(w1 && !w2)   {cur+=snprintf(str,128,"ztick %g\n",z1);        strcat(buf,str);}\r
-\r
-       if(xlab->value()[0])\r
-       {\r
-               cur+=snprintf(str,128,"xlabel '%s' %d\n",xlab->value(), xpos->value()-1);\r
-               strcat(buf,str);\r
-       }\r
-       if(ylab->value()[0])\r
-       {\r
-               cur+=snprintf(str,128,"ylabel '%s' %d\n",ylab->value(), ypos->value()-1);\r
-               strcat(buf,str);\r
-       }\r
-       if(zlab->value()[0])\r
-       {\r
-               cur+=snprintf(str,128,"zlabel '%s' %d\n",zlab->value(), zpos->value()-1);\r
-               strcat(buf,str);\r
-       }\r
-       if(alphad->value()[0])\r
-       {\r
-               cur+=snprintf(str,128,"alphadef %g\n",atof(alphad->value()));\r
-               strcat(buf,str);\r
-       }\r
-       if(ambient->value()[0])\r
-       {\r
-               cur+=snprintf(str,128,"ambient %g\n",atof(ambient->value()));\r
-               strcat(buf,str);\r
-       }\r
-\r
-       if(basew->value()[0])\r
-       {\r
-               cur+=snprintf(str,128,"baselinewidth %g\n",atof(basew->value()));\r
-               strcat(buf,str);\r
-       }\r
-       if(mesh->value()[0])\r
-       {\r
-               cur+=snprintf(str,128,"meshnum %g\n",atof(mesh->value()));\r
-               strcat(buf,str);\r
-       }\r
-       if(axial->value()>=0)\r
-       {\r
-               cur+=snprintf(str,128,"axialdir '%c'\n",'x'+axial->value());\r
-               strcat(buf,str);\r
-       }\r
-\r
-       if(font->value()[0])\r
-       {\r
-               cur+=snprintf(str,128,"font '%s'",font->value());\r
-               strcat(buf,str);\r
-               if(size->value())       cur+=snprintf(str,128," %g\n",atof(size->value()));\r
-               else    cur+=snprintf(str,128,"\n");\r
-               strcat(buf,str);\r
-       }\r
-       if(rotate->value())     {cur+=snprintf(str,128,"rotatetext on\n");      strcat(buf,str);}\r
-\r
-       if(alpha->value())      {cur+=snprintf(str,128,"alpha on\n");   strcat(buf,str);}\r
-       if(light->value())      {cur+=snprintf(str,128,"light on\n");   strcat(buf,str);}\r
-\r
-       code->value(buf);\r
-       return buf;\r
-}\r
-//-----------------------------------------------------------------------------\r
-void setup_cb(Fl_Widget *, void *d)\r
-{\r
-       if(d==0)        return;\r
-       SetupDlg *s = ((ScriptWindow *)d)->setup_dlg;\r
-       s->OK = false;\r
-       s->wnd->set_modal();\r
-       s->wnd->show();\r
-       while(s->wnd->shown())  Fl::wait();\r
-       if(s->OK)       ((ScriptWindow *)d)->graph->update();\r
-}\r
-//-----------------------------------------------------------------------------\r
-Fl_Menu_Item colors[] = {\r
-       {"-----", 0,0,0,0,0,0,0, 0},    //\r
-       {("white"), 0,0,0,0,0,0,0, fl_rgb_color(0,0,0)},        //w\r
-       {("blue"), 0,0,0,0,0,0,0, fl_rgb_color(0,0,255)},                       //b\r
-       {("lime"), 0,0,0,0,0,0,0, fl_rgb_color(0,255,0)},                       //g\r
-       {("red"), 0,0,0,0,0,0,0, fl_rgb_color(255,0,0)},                        //r\r
-       {("cyan"), 0,0,0,0,0,0,0, fl_rgb_color(0,255,255)},             //c\r
-       {("magenta"), 0,0,0,0,0,0,0, fl_rgb_color(255,0,255)},  //m\r
-       {("yellow"), 0,0,0,0,0,0,0, fl_rgb_color(255,255,0)},           //y\r
-       {("springgreen"), 0,0,0,0,0,0,0, fl_rgb_color(0,255,127)},//l\r
-       {("lawngreen"), 0,0,0,0,0,0,0, fl_rgb_color(127,255,0)},        //e\r
-       {("skyblue"), 0,0,0,0,0,0,0, fl_rgb_color(0,127,255)},  //n\r
-       {("blueviolet"), 0,0,0,0,0,0,0, fl_rgb_color(127,0,255)},       //u\r
-       {("orange"), 0,0,0,0,0,0,0, fl_rgb_color(255,127,0)},           //q\r
-       {("deeppink"), 0,0,0,0,0,0,0, fl_rgb_color(255,0,127)}, //p\r
-       {("gray"), 0,0,0,0,0,0,0, fl_rgb_color(127,127,127)},           //h\r
-\r
-       {("black"), 0,0,0,0,0,0,0, fl_rgb_color(0,0,0)},        //k\r
-       {("lightgray"), 0,0,0,0,0,0,0, fl_rgb_color(179,179,179)},      //W\r
-       {("navy"), 0,0,0,0,0,0,0, fl_rgb_color(0,0,127)},       //B\r
-       {("green"), 0,0,0,0,0,0,0, fl_rgb_color(0,127,0)},      //G\r
-       {("maroon"), 0,0,0,0,0,0,0, fl_rgb_color(127,0,0)},     //R\r
-       {("teal"), 0,0,0,0,0,0,0, fl_rgb_color(0,127,127)},     //C\r
-       {("purple"), 0,0,0,0,0,0,0, fl_rgb_color(127,0,127)},   //M\r
-       {("olive"), 0,0,0,0,0,0,0, fl_rgb_color(127,127,0)},    //Y\r
-       {("seagreen"), 0,0,0,0,0,0,0, fl_rgb_color(0,127,77)},  //L\r
-       {("darklawn"), 0,0,0,0,0,0,0, fl_rgb_color(77,127,0)},  //E\r
-       {("darkskyblue"), 0,0,0,0,0,0,0, fl_rgb_color(0,77,127)},       //N\r
-       {("indigo"), 0,0,0,0,0,0,0, fl_rgb_color(77,0,127)},    //U\r
-       {("brown"), 0,0,0,0,0,0,0, fl_rgb_color(127,77,0)},     //Q\r
-       {("darkpink"), 0,0,0,0,0,0,0, fl_rgb_color(127,0,77)},  //P\r
-       {("darkgray"), 0,0,0,0,0,0,0, fl_rgb_color(77,77,77)},  //H\r
-{0, 0,0,0,0,0,0,0, 0}};\r
-//-----------------------------------------------------------------------------\r
-struct PropDlg\r
-{\r
-       Fl_Window *wnd;\r
-       Fl_MGL *graph;\r
-\r
-       Fl_Input *path, *locale, *font, *fpath;\r
-       Fl_Check_Button *plast, *aexec, *ifont;\r
-       PropDlg()       {       memset(this,0,sizeof(PropDlg)); create_dlg();   }\r
-       ~PropDlg()      {       delete wnd;     }\r
-       void create_dlg();\r
-       void finish();\r
-       void init();\r
-} prop_dlg;\r
-//-----------------------------------------------------------------------------\r
-void PropDlg::init()\r
-{\r
-       int a, p;\r
-       char *buf;\r
-       pref.get("plastic_scheme",p,1); plast->value(p);\r
-       pref.get("auto_exec",a,1);              aexec->value(a);\r
-       pref.get("internal_font",a,0);  ifont->value(a);\r
-       path->value(docdir);\r
-       pref.get("font_dir",buf,"");    fpath->value(buf);      free(buf);\r
-       pref.get("font_name",buf,"");   font->value(buf);       free(buf);\r
-       pref.get("locale",buf,"ru_RU.cp1251");  locale->value(buf);     free(buf);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void PropDlg::finish()\r
-{\r
-       int a, p;\r
-       p = plast->value();\r
-       if(p!=plastic_scheme)\r
-       {\r
-               plastic_scheme = p;\r
-               pref.set("plastic_scheme",p);\r
-               Fl::scheme(p?"plastic":"none");\r
-       }\r
-       a = aexec->value();\r
-       if(a!=auto_exec)\r
-       {\r
-               auto_exec = a;\r
-               pref.set("auto_exec",a);\r
-       }\r
-       a = ifont->value();\r
-       if(a!=internal_font)\r
-       {\r
-               internal_font = a;\r
-               pref.set("internal_font",a);\r
-       }\r
-       if(path->value()[0])    pref.set("help_dir",path->value());\r
-       if(locale->value()[0])\r
-       {\r
-               pref.set("locale", locale->value());\r
-               setlocale(LC_CTYPE, locale->value());\r
-       }\r
-       pref.set("font_dir",fpath->value());\r
-       pref.set("font_name",font->value());\r
-       if(graph)       mgl_load_font(graph->FMGL->get_graph(), font->value(), fpath->value());\r
-}\r
-//-----------------------------------------------------------------------------\r
-void prop_dlg_cb(Fl_Widget *, void *v)\r
-{      prop_dlg.finish();      ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void PropDlg::create_dlg()\r
-{\r
-       wnd = new Fl_Double_Window(320, 300, gettext("UDAV settings"));\r
-       path = new Fl_Input(10, 25, 305, 25, gettext("Path for help files"));   path->align(FL_ALIGN_TOP_LEFT);\r
-\r
-       font = new Fl_Input(10, 75, 305, 25, gettext("Font typeface")); font->align(FL_ALIGN_TOP_LEFT);\r
-       fpath = new Fl_Input(10, 125, 305, 25, gettext("Path for font files")); fpath->align(FL_ALIGN_TOP_LEFT);\r
-       locale = new Fl_Input(10, 175, 305, 25, gettext("Select locale"));      locale->align(FL_ALIGN_TOP_LEFT);\r
-\r
-       plast = new Fl_Check_Button(10, 210, 210, 25, gettext("Use plastic scheme"));\r
-       aexec = new Fl_Check_Button(10, 240, 210, 25, gettext("Execute after script loading"));\r
-       ifont = new Fl_Check_Button(10, 270, 210, 25, gettext("Use only internal font"));\r
-\r
-       Fl_Button *o;\r
-       o = new Fl_Button(240, 210, 75, 25, gettext("Cancel"));         o->callback(close_dlg_cb,wnd);\r
-       o = new Fl_Return_Button(240, 240, 75, 25, gettext("OK"));      o->callback(prop_dlg_cb,wnd);\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void settings_cb(Fl_Widget *, void *v)\r
-{\r
-       PropDlg *s = &prop_dlg;\r
-       s->graph = ((ScriptWindow *)v)->graph;\r
-       s->init();\r
-       s->wnd->set_modal();\r
-       s->wnd->show();\r
-}\r
-//-----------------------------------------------------------------------------\r
diff --git a/mgllab/table.cpp b/mgllab/table.cpp
deleted file mode 100644 (file)
index 313706d..0000000
+++ /dev/null
@@ -1,875 +0,0 @@
-/* table.cpp is part of UDAV\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-#include <FL/Fl_Spinner.H>\r
-#include <FL/Fl_Output.H>\r
-#include <FL/Fl_Float_Input.H>\r
-#include <FL/Fl_Value_Input.H>\r
-#include <FL/Fl_Round_Button.H>\r
-#include "udav.h"\r
-//-----------------------------------------------------------------------------\r
-void addto_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       const char *s = fl_input(gettext("Enter number for addition to data values"),0);\r
-       if(s)   {       mgl_data_add_num(e->var, atof(s));      e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void subto_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       const char *s = fl_input(gettext("Enter number for subtraction from data values"),0);\r
-       if(s)   {       mgl_data_sub_num(e->var, atof(s));      e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void multo_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       const char *s = fl_input(gettext("Enter number for multiplication of data values"),0);\r
-       if(s)   {       mgl_data_mul_num(e->var, atof(s));      e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void divto_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       const char *s = fl_input(gettext("Enter number for division of data values"),0);\r
-       if(s)   {       mgl_data_div_num(e->var, atof(s));      e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-struct XYZDlg\r
-{\r
-       Fl_Window *wnd;\r
-       bool OK;\r
-\r
-       Fl_Box *box;\r
-       Fl_Check_Button *ch;\r
-       Fl_Spinner *mx, *my, *mz;\r
-       XYZDlg()        {       memset(this,0,sizeof(XYZDlg));  create_dlg();   }\r
-       ~XYZDlg()       {       delete wnd;     }\r
-       void create_dlg();\r
-} xyz_dlg;\r
-//-----------------------------------------------------------------------------\r
-void xyz_dlg_cb(Fl_Widget *, void *v)\r
-{      xyz_dlg.OK = true;      ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void XYZDlg::create_dlg()\r
-{\r
-       wnd = new Fl_Double_Window(325, 125, gettext("Change data sizes"));\r
-       box = new Fl_Box(10, 10, 305, 40);\r
-       box->box(UDAV_THIN_UP_BOX);\r
-       box->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);\r
-\r
-       mx = new Fl_Spinner(30, 55, 75, 25, "mx");\r
-       mx->tooltip(gettext("New size of data on 1st dimension (x-direction)"));\r
-       my = new Fl_Spinner(135, 55, 75, 25, "my");\r
-       my->tooltip(gettext("New size of data on 2nd dimension (y-direction)"));\r
-       mz = new Fl_Spinner(240, 55, 75, 25, "mz");\r
-       mz->tooltip(gettext("New size of data on 3d dimension (z-direction)"));\r
-       ch = new Fl_Check_Button(15, 90, 95, 25);\r
-\r
-       Fl_Button *o;\r
-       o = new Fl_Button(125, 90, 85, 25, gettext("Cancel"));  o->callback(close_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o->tooltip(gettext("Do nothing and close this window"));\r
-       o = new Fl_Return_Button(230, 90, 85, 25, gettext("Change"));o->callback(xyz_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o->tooltip(gettext("Change (resize) data"));\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void new_dat_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       xyz_dlg.box->label(gettext("Specify new data size\nData will be zero filled"));\r
-       xyz_dlg.ch->label(gettext("not used")); xyz_dlg.OK = false;\r
-       xyz_dlg.wnd->set_modal();               xyz_dlg.wnd->show();\r
-       while(xyz_dlg.wnd->shown())     Fl::wait();\r
-       if(xyz_dlg.OK)\r
-       {\r
-               e->var->Create(int(xyz_dlg.mx->value()),\r
-                       int(xyz_dlg.my->value()), int(xyz_dlg.mz->value()));\r
-               e->refresh();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void resize_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       xyz_dlg.box->label(gettext("Specify new data size\nData will be interpolated"));\r
-       xyz_dlg.ch->label(gettext("not used")); xyz_dlg.OK = false;\r
-       xyz_dlg.wnd->set_modal();               xyz_dlg.wnd->show();\r
-       while(xyz_dlg.wnd->shown())     Fl::wait();\r
-       if(xyz_dlg.OK)\r
-       {\r
-               mglData d = e->var->Resize(int(xyz_dlg.mx->value()), int(xyz_dlg.my->value()), int(xyz_dlg.mz->value()));\r
-               mgl_data_set(e->var, &d);\r
-               e->refresh();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void squeeze_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       xyz_dlg.box->label(gettext("Specify the skiping step\nEach m-th point will be skiped"));\r
-       xyz_dlg.ch->label(gettext("smoothed")); xyz_dlg.OK = false;\r
-       xyz_dlg.wnd->set_modal();               xyz_dlg.wnd->show();\r
-       while(xyz_dlg.wnd->shown())     Fl::wait();\r
-       if(xyz_dlg.OK)\r
-       {\r
-               e->var->Squeeze(int(xyz_dlg.mx->value()), int(xyz_dlg.my->value()),\r
-                                       int(xyz_dlg.mz->value()), xyz_dlg.ch->value());\r
-               e->refresh();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-struct ChngDlg\r
-{\r
-       Fl_Window *wnd;\r
-       bool OK;\r
-\r
-       Fl_Check_Button *dx, *dy, *dz;\r
-       Fl_Choice *kind, *type;\r
-       ChngDlg()       {       memset(this,0,sizeof(ChngDlg)); create_dlg();   }\r
-       ~ChngDlg()      {       delete wnd;     }\r
-       void create_dlg();\r
-       void execute(mglData *d);\r
-} chng_dlg;\r
-//-----------------------------------------------------------------------------\r
-void chng_dlg_cb(Fl_Widget *, void *v)\r
-{      chng_dlg.OK = true;     ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void ChngDlg::execute(mglData *d)\r
-{\r
-       char r[8]="3";\r
-       if(dx->value()) strcat(r,"x");\r
-       if(dy->value()) strcat(r,"y");\r
-       if(dz->value()) strcat(r,"z");\r
-       if(!r[0])       return;\r
-       if(type->value()==1)    r[0] = '5';\r
-       if(type->value()==2)    r[0] = ' ';\r
-       switch(kind->value())\r
-       {\r
-       case 0: d->Smooth(r);           break;\r
-       case 1: d->CumSum(r);           break;\r
-       case 2: d->Integral(r); break;\r
-       case 3: d->Diff(r);             break;\r
-       case 4: d->Diff2(r);            break;\r
-       case 5: d->Swap(r);             break;\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void ChngDlg::create_dlg()\r
-{\r
-       Fl_Menu_Item k[]={{gettext("Smooth")}, {gettext("CumSum")}, { gettext("Integrate")},\r
-               { gettext("Difference")}, { gettext("Double diff.")}, { gettext("Swap parts")}, {0}};\r
-       Fl_Menu_Item t[]={{gettext("Linear *3")}, {gettext("Linear *5")}, {gettext("Parabolic *5")},{0}};\r
-       wnd = new Fl_Double_Window(165, 215, gettext("Change data"));\r
-       kind = new Fl_Choice(10, 25, 145, 25, gettext("Type of operation"));\r
-       kind->align(FL_ALIGN_TOP_LEFT); kind->copy(k);\r
-       dx = new Fl_Check_Button(10, 55, 140, 25, gettext("apply in x direction"));\r
-       dy = new Fl_Check_Button(10, 80, 140, 25, gettext("apply in y direction"));\r
-       dz = new Fl_Check_Button(10, 105, 140, 25, gettext("apply in z direction"));\r
-       type = new Fl_Choice(10, 145, 145, 25, gettext("Type of smoothing"));\r
-       type->align(FL_ALIGN_TOP_LEFT); type->copy(t);\r
-\r
-       Fl_Button *o;\r
-       o = new Fl_Button(10, 180, 65, 25, gettext("Cancel"));  o->callback(close_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o = new Fl_Return_Button(90, 180, 65, 25, gettext("Do"));o->callback(chng_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void smooth_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       chng_dlg.kind->value(0);\r
-       chng_dlg.type->activate();      chng_dlg.OK = false;\r
-       chng_dlg.wnd->set_modal();      chng_dlg.wnd->show();\r
-       while(chng_dlg.wnd->shown())    Fl::wait();\r
-       if(chng_dlg.OK)\r
-       {       chng_dlg.execute(e->var);       e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void cumsum_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       chng_dlg.kind->value(1);\r
-       chng_dlg.type->deactivate();chng_dlg.OK = false;\r
-       chng_dlg.wnd->set_modal();      chng_dlg.wnd->show();\r
-       while(chng_dlg.wnd->shown())    Fl::wait();\r
-       if(chng_dlg.OK)\r
-       {       chng_dlg.execute(e->var);       e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void integr_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       chng_dlg.kind->value(2);\r
-       chng_dlg.type->deactivate();chng_dlg.OK = false;\r
-       chng_dlg.wnd->set_modal();      chng_dlg.wnd->show();\r
-       while(chng_dlg.wnd->shown())    Fl::wait();\r
-       if(chng_dlg.OK)\r
-       {       chng_dlg.execute(e->var);       e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void diff_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       chng_dlg.kind->value(3);\r
-       chng_dlg.type->deactivate();chng_dlg.OK = false;\r
-       chng_dlg.wnd->set_modal();      chng_dlg.wnd->show();\r
-       while(chng_dlg.wnd->shown())    Fl::wait();\r
-       if(chng_dlg.OK)\r
-       {       chng_dlg.execute(e->var);       e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void diff2_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       chng_dlg.kind->value(4);\r
-       chng_dlg.type->deactivate();chng_dlg.OK = false;\r
-       chng_dlg.wnd->set_modal();      chng_dlg.wnd->show();\r
-       while(chng_dlg.wnd->shown())    Fl::wait();\r
-       if(chng_dlg.OK)\r
-       {       chng_dlg.execute(e->var);       e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void swap_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       chng_dlg.kind->value(5);\r
-       chng_dlg.type->deactivate();chng_dlg.OK = false;\r
-       chng_dlg.wnd->set_modal();      chng_dlg.wnd->show();\r
-       while(chng_dlg.wnd->shown())    Fl::wait();\r
-       if(chng_dlg.OK)\r
-       {       chng_dlg.execute(e->var);       e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-struct NwdtDlg\r
-{\r
-       Fl_Window *wnd;\r
-       bool OK;\r
-\r
-       Fl_Check_Button *dx, *dy, *dz;\r
-       Fl_Choice *kind;\r
-       Fl_Input *name;\r
-       NwdtDlg()       {       memset(this,0,sizeof(NwdtDlg)); create_dlg();   }\r
-       ~NwdtDlg()      {       delete wnd;     }\r
-       void create_dlg();\r
-} nwdt_dlg;\r
-//-----------------------------------------------------------------------------\r
-void nwdt_dlg_cb(Fl_Widget *, void *v)\r
-{      nwdt_dlg.OK = true;     ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void NwdtDlg::create_dlg()\r
-{\r
-       Fl_Menu_Item k[]={{gettext("Summation of")}, {gettext("Maximum of")}, { gettext("Minimum of")}, {0}};\r
-       wnd = new Fl_Double_Window(165, 215, gettext("Extract data"));\r
-       kind = new Fl_Choice(10, 25, 145, 25, gettext("Type of operation"));\r
-       kind->align(FL_ALIGN_TOP_LEFT); kind->copy(k);\r
-       dx = new Fl_Check_Button(10, 55, 140, 25, gettext("apply in x direction"));\r
-       dy = new Fl_Check_Button(10, 80, 140, 25, gettext("apply in y direction"));\r
-       dz = new Fl_Check_Button(10, 105, 140, 25, gettext("apply in z direction"));\r
-       name = new Fl_Input(10, 145, 145, 25, gettext("Name for output"));\r
-       name->align(FL_ALIGN_TOP_LEFT);\r
-\r
-       Fl_Button *o;\r
-       o = new Fl_Button(10, 180, 65, 25, gettext("Cancel"));  o->callback(close_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o = new Fl_Return_Button(90, 180, 65, 25, gettext("Do"));o->callback(chng_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void asum_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       nwdt_dlg.kind->value(0);        nwdt_dlg.OK = false;\r
-       nwdt_dlg.wnd->set_modal();      nwdt_dlg.wnd->show();\r
-       while(nwdt_dlg.wnd->shown())    Fl::wait();\r
-       if(nwdt_dlg.OK)\r
-       {\r
-               char r[8]="";\r
-               if(nwdt_dlg.dx->value())        strcat(r,"x");\r
-               if(nwdt_dlg.dy->value())        strcat(r,"y");\r
-               if(nwdt_dlg.dz->value())        strcat(r,"z");\r
-               if(!r[0])       return;\r
-               if(!nwdt_dlg.name->value()[0] || !strcmp(nwdt_dlg.name->value(),e->label()))\r
-                       fl_alert(gettext("Name for output variable should be differ from this name"));\r
-               else\r
-               {\r
-                       mglData d = e->var->Sum(r);\r
-                       mgl_data_set(Parse->AddVar(nwdt_dlg.name->value()), &d);\r
-               }\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void amax_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       nwdt_dlg.kind->value(0);        nwdt_dlg.OK = false;\r
-       nwdt_dlg.wnd->set_modal();      nwdt_dlg.wnd->show();\r
-       while(nwdt_dlg.wnd->shown())    Fl::wait();\r
-       if(nwdt_dlg.OK)\r
-       {\r
-               char r[8]="";\r
-               if(nwdt_dlg.dx->value())        strcat(r,"x");\r
-               if(nwdt_dlg.dy->value())        strcat(r,"y");\r
-               if(nwdt_dlg.dz->value())        strcat(r,"z");\r
-               if(!r[0])       return;\r
-               if(!nwdt_dlg.name->value()[0] || !strcmp(nwdt_dlg.name->value(),e->label()))\r
-                       fl_alert(gettext("Name for output variable should be differ from this name"));\r
-               else\r
-               {\r
-                       mglData d = e->var->Max(r);\r
-                       mgl_data_set(Parse->AddVar(nwdt_dlg.name->value()), &d);\r
-               }\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void amin_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       nwdt_dlg.kind->value(0);        nwdt_dlg.OK = false;\r
-       nwdt_dlg.wnd->set_modal();      nwdt_dlg.wnd->show();\r
-       while(nwdt_dlg.wnd->shown())    Fl::wait();\r
-       if(nwdt_dlg.OK)\r
-       {\r
-               char r[8]="";\r
-               if(nwdt_dlg.dx->value())        strcat(r,"x");\r
-               if(nwdt_dlg.dy->value())        strcat(r,"y");\r
-               if(nwdt_dlg.dz->value())        strcat(r,"z");\r
-               if(!r[0])       return;\r
-               if(!nwdt_dlg.name->value()[0] || !strcmp(nwdt_dlg.name->value(), e->label()))\r
-                       fl_alert(gettext("Name for output variable should be differ from this name"));\r
-               else\r
-               {\r
-                       mglData d = e->var->Min(r);\r
-                       mgl_data_set(Parse->AddVar(nwdt_dlg.name->value()), &d);\r
-               }\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void load_dat_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       char *newfile = fl_file_chooser(gettext("Load Data?"),\r
-               gettext("DAT Files (*.{dat,csv})\tAll Files (*)"), 0);\r
-       if(newfile != NULL)\r
-       {       e->var->Read(newfile);  e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void save_dat_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       char *newfile = fl_file_chooser(gettext("Save Data?"),\r
-               gettext("DAT Files (*.{dat,csv})\tAll Files (*)"), 0);\r
-       if(newfile != NULL)     e->var->Save(newfile);\r
-}\r
-//-----------------------------------------------------------------------------\r
-void exp_dat_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       const char *scheme, *newfile = fl_file_chooser(gettext("Export Data?"),\r
-               gettext("PNG Files (*.png)\tAll Files (*)"), 0);\r
-       if(newfile != NULL)\r
-       {\r
-               scheme = fl_input(gettext("Enter color scheme"),MGL_DEF_SCH);\r
-               if(scheme)      e->var->Export(newfile,scheme);\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void imp_dat_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       const char *scheme, *newfile = fl_file_chooser(gettext("Import Data?"),\r
-               gettext("PNG Files (*.png)\tAll Files (*)"), 0);\r
-       if (newfile != NULL)\r
-       {\r
-               scheme = fl_input(gettext("Enter color scheme"),MGL_DEF_SCH);\r
-               if(scheme)\r
-               {       e->var->Import(newfile,scheme); e->refresh();   }\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void list_dat_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       mglData *d = e->var;\r
-       if(d->nx*d->ny+d->ny>1020)\r
-       {       fl_message(gettext("Too many numbers (>1000) on slice"));       return; }\r
-       if(d->nz>1)     fl_message(gettext("Only current slice will be inserted"));\r
-       char *list = new char[16384];\r
-       strcpy(list,"list\t");\r
-       register long i,j;\r
-       char s[32];\r
-       for(j=0;j<d->ny;j++)\r
-       {\r
-               for(i=0;i<d->nx;i++)\r
-               {\r
-                       snprintf(s,32,"%g\t",d->a[i+d->nx*(j+e->get_slice()*d->ny)]);\r
-                       strcat(list,s);\r
-               }\r
-               if(j<d->ny-1)   strcat(list,"|\t");\r
-       }\r
-       textbuf->insert(0,list);\r
-       delete []list;\r
-}\r
-//-----------------------------------------------------------------------------\r
-void modify_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       const char *eq=fl_input(gettext("Enter formula for data modification\nHere x, y, z in range [0,1], u is data value"),0);\r
-       if (eq != NULL) {       e->var->Modify(eq);     e->refresh();   }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void plot_dat_cb(Fl_Widget *, void *v);\r
-//-----------------------------------------------------------------------------\r
-struct NrmDlg\r
-{\r
-       Fl_Window *wnd;\r
-       bool OK;\r
-\r
-       Fl_Value_Input *min, *max;\r
-       Fl_Choice *dir;\r
-       Fl_Check_Button *sym;\r
-       NrmDlg()        {       memset(this,0,sizeof(NrmDlg));  create_dlg();   }\r
-       ~NrmDlg()       {       delete wnd;     }\r
-       void create_dlg();\r
-} nrm_dlg;\r
-//-----------------------------------------------------------------------------\r
-void nrm_dlg_cb(Fl_Widget *, void *v)\r
-{      nrm_dlg.OK = true;      ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void NrmDlg::create_dlg()\r
-{\r
-       Fl_Menu_Item k[]={{"x"}, {"y"}, { "z"}, {0}};\r
-       wnd = new Fl_Double_Window(135, 215);\r
-       min = new Fl_Value_Input(10, 25, 115, 25, gettext("Minimal value (v1)"));\r
-       min->align(FL_ALIGN_TOP_LEFT);\r
-       min->tooltip(gettext("Minimal value for resulting data values"));\r
-       max = new Fl_Value_Input(10, 70, 115, 25, gettext("Maximal value (v2)"));\r
-       max->align(FL_ALIGN_TOP_LEFT);\r
-       max->tooltip(gettext("Maximal value for resulting data values"));\r
-       dir = new Fl_Choice(10, 115, 115, 25, gettext("Direction"));\r
-       dir->align(FL_ALIGN_TOP_LEFT);  dir->copy(k);\r
-       dir->tooltip(gettext("Direction along which data will be filled"));\r
-       sym = new Fl_Check_Button(10, 115, 115, 25, gettext("Symetrical range"));\r
-       sym->tooltip(gettext("Normalize in symmetrical range: -max(|v1|,|v2|) ... max(|v1|,|v2|)"));\r
-\r
-       Fl_Button *o;\r
-       o = new Fl_Button(25, 150, 85, 25, gettext("Cancel"));  o->callback(close_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o->tooltip(gettext("Do nothing and close this window"));\r
-       o = new Fl_Return_Button(25, 180, 85, 25, gettext("Change"));o->callback(nrm_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o->tooltip(gettext("Change data values and close this window"));\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void fill_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       nrm_dlg.OK = false;                     nrm_dlg.wnd->label(gettext("Fill in range"));\r
-       nrm_dlg.dir->show();            nrm_dlg.sym->hide();\r
-       nrm_dlg.wnd->set_modal();       nrm_dlg.wnd->show();\r
-       while(nrm_dlg.wnd->shown())     Fl::wait();\r
-       if(nrm_dlg.OK)\r
-       {\r
-               char r='x';\r
-               if(nrm_dlg.dir->value()==1)     r='y';\r
-               if(nrm_dlg.dir->value()==2)     r='z';\r
-               e->var->Fill(nrm_dlg.min->value(),nrm_dlg.max->value(),r);\r
-               e->refresh();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void normal_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       nrm_dlg.OK = false;                     nrm_dlg.wnd->label(gettext("Normalize data"));\r
-       nrm_dlg.dir->hide();            nrm_dlg.sym->show();\r
-       nrm_dlg.wnd->set_modal();       nrm_dlg.wnd->show();\r
-       while(nrm_dlg.wnd->shown())     Fl::wait();\r
-       if(nrm_dlg.OK)\r
-       {\r
-               e->var->Norm(nrm_dlg.min->value(), nrm_dlg.max->value(), nrm_dlg.sym->value());\r
-               e->refresh();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-struct CropDlg\r
-{\r
-       Fl_Window *wnd;\r
-       bool OK;\r
-\r
-       Fl_Input *x1,*x2, *y1,*y2, *z1,*z2;\r
-       CropDlg()       {       memset(this,0,sizeof(CropDlg)); create_dlg();   }\r
-       ~CropDlg()      {       delete wnd;     }\r
-       void create_dlg();\r
-} crop_dlg;\r
-//-----------------------------------------------------------------------------\r
-void crop_dlg_cb(Fl_Widget *, void *v)\r
-{      crop_dlg.OK = true;     ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void CropDlg::create_dlg()\r
-{\r
-       wnd = new Fl_Double_Window(230, 155, gettext("Crop data"));\r
-       x1 = new Fl_Input(45, 25, 80, 25, gettext("Lower bound"));      x1->align(FL_ALIGN_TOP);\r
-       x2 = new Fl_Input(140, 25, 80, 25, gettext("Upper bound"));     x2->align(FL_ALIGN_TOP);\r
-       y1 = new Fl_Input(45, 55, 80, 25);\r
-       y2 = new Fl_Input(140, 55, 80, 25);\r
-       z1 = new Fl_Input(45, 85, 80, 25);\r
-       z2 = new Fl_Input(140, 85, 80, 25);\r
-\r
-       new Fl_Box(15, 25, 25, 25, "X");\r
-       new Fl_Box(15, 55, 25, 25, "Y");\r
-       new Fl_Box(15, 85, 25, 25, "Z");\r
-       Fl_Button *o;\r
-       o = new Fl_Button(45, 120, 75, 25, gettext("Cancel"));          o->callback(close_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o->tooltip(gettext("Do nothing and close this window"));\r
-       o = new Fl_Return_Button(145, 120, 75, 25, gettext("Crop"));    o->callback(crop_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o->tooltip(gettext("Change data values and close this window"));\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void crop_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       crop_dlg.OK = false;\r
-       crop_dlg.wnd->set_modal();      crop_dlg.wnd->show();\r
-       while(crop_dlg.wnd->shown())    Fl::wait();\r
-       if(crop_dlg.OK)\r
-       {\r
-               int n1,n2;\r
-               n1 = 0; n2 = e->var->nx;\r
-               if(crop_dlg.x1->value()[0])     n1 = atoi(crop_dlg.x1->value());\r
-               if(crop_dlg.x2->value()[0])     n2 = atoi(crop_dlg.x2->value());\r
-               e->var->Crop(n1, n2, 'x');\r
-               n1 = 0; n2 = e->var->ny;\r
-               if(crop_dlg.y1->value()[0])     n1 = atoi(crop_dlg.y1->value());\r
-               if(crop_dlg.y2->value()[0])     n2 = atoi(crop_dlg.y2->value());\r
-               e->var->Crop(n1, n2, 'y');\r
-               n1 = 0; n2 = e->var->nz;\r
-               if(crop_dlg.z1->value()[0])     n1 = atoi(crop_dlg.z1->value());\r
-               if(crop_dlg.z2->value()[0])     n2 = atoi(crop_dlg.z2->value());\r
-               e->var->Crop(n1, n2, 'z');\r
-               e->refresh();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-struct TrspDlg\r
-{\r
-       Fl_Window *wnd;\r
-       bool OK;\r
-\r
-       Fl_Round_Button *xyz, *xzy, *yxz, *yzx, *zxy, *zyx;\r
-       TrspDlg()       {       memset(this,0,sizeof(TrspDlg)); create_dlg();   }\r
-       ~TrspDlg()      {       delete wnd;     }\r
-       void create_dlg();\r
-} trsp_dlg;\r
-//-----------------------------------------------------------------------------\r
-void trsp_dlg_cb(Fl_Widget *, void *v)\r
-{      trsp_dlg.OK = true;     ((Fl_Window *)v)->hide();       }\r
-//-----------------------------------------------------------------------------\r
-void trsp_rad_cb(Fl_Widget *w, void *v)\r
-{\r
-       TrspDlg* e = (TrspDlg*)v;\r
-       e->xyz->value(0);       e->xzy->value(0);\r
-       e->yxz->value(0);       e->yzx->value(0);\r
-       e->zxy->value(0);       e->zyx->value(0);\r
-       ((Fl_Round_Button *)w)->setonly();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void TrspDlg::create_dlg()\r
-{\r
-       wnd = new Fl_Double_Window(220, 170, gettext("Transpose data"));\r
-       Fl_Group *g = new Fl_Group(10, 30, 200, 90, gettext("Select new order of dimensions"));\r
-       g->box(FL_DOWN_BOX);\r
-       yxz = new Fl_Round_Button(20, 40, 75, 25, "y - x - z"); yxz->callback(trsp_rad_cb,this);\r
-       zyx = new Fl_Round_Button(20, 65, 75, 25, "z - y - x"); zyx->callback(trsp_rad_cb,this);\r
-       zxy = new Fl_Round_Button(20, 90, 75, 25, "z - x - y"); zxy->callback(trsp_rad_cb,this);\r
-       yzx = new Fl_Round_Button(100, 40, 75, 25, "y - z - x");yzx->callback(trsp_rad_cb,this);\r
-       xzy = new Fl_Round_Button(100, 65, 75, 25, "x - z - y");xzy->callback(trsp_rad_cb,this);\r
-       xyz = new Fl_Round_Button(100, 90, 75, 25, "x - y - z");xyz->callback(trsp_rad_cb,this);\r
-       g->end();\r
-\r
-       Fl_Button *o;\r
-       o = new Fl_Button(25, 130, 75, 25, gettext("Cancel"));  o->callback(close_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o->tooltip(gettext("Do nothing and close this window"));\r
-       o = new Fl_Return_Button(125, 130, 75, 25, gettext("Do"));      o->callback(trsp_dlg_cb,wnd);\r
-       o->box(UDAV_UP_BOX);    o->down_box(UDAV_DOWN_BOX);\r
-       o->tooltip(gettext("Change data values and close this window"));\r
-       wnd->end();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void transp_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       trsp_dlg.OK = false;\r
-       trsp_dlg.wnd->set_modal();      trsp_dlg.wnd->show();\r
-       while(trsp_dlg.wnd->shown())    Fl::wait();\r
-       if(trsp_dlg.OK)\r
-       {\r
-               if(trsp_dlg.xyz->value())       e->var->Transpose("xyz");\r
-               if(trsp_dlg.xzy->value())       e->var->Transpose("xzy");\r
-               if(trsp_dlg.yxz->value())       e->var->Transpose("yxz");\r
-               if(trsp_dlg.yzx->value())       e->var->Transpose("yzx");\r
-               if(trsp_dlg.zxy->value())       e->var->Transpose("zxy");\r
-               if(trsp_dlg.zyx->value())       e->var->Transpose("zyx");\r
-               e->refresh();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void first_sl_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       e->slice->value(0);\r
-       e->set_slice(0);\r
-       e->go_home();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void last_sl_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       e->slice->value(e->num_slice()-1);\r
-       e->set_slice(e->num_slice()-1);\r
-       e->go_home();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void prev_sl_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       int p = int(e->slice->value())-1;\r
-       if(p<0) p = 0;\r
-       e->slice->value(p);             e->set_slice(p);\r
-       e->go_home();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void next_sl_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       int p = int(e->slice->value())+1;\r
-       if(p>=e->num_slice())   p = e->num_slice()-1;\r
-       e->slice->value(p);             e->set_slice(p);\r
-       e->go_home();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void first_cl_cb(Fl_Widget*, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       e->go_home();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void change_sl_cb(Fl_Widget*w, void*v)\r
-{\r
-       TableWindow* e = (TableWindow*)v;\r
-       e->set_slice(long(e->slice->value()));\r
-       e->go_home();\r
-}\r
-//-----------------------------------------------------------------------------\r
-Fl_Menu_Item tablemenu[60] = {\r
-       { gettext("General"), 0, 0, 0, FL_SUBMENU },\r
-               { gettext("Load from file"),    0, load_dat_cb },\r
-               { gettext("Import from PNG"),0, imp_dat_cb },\r
-               { gettext("Save to file"),      0, save_dat_cb },\r
-               { gettext("Export to PNG"),     0, exp_dat_cb, 0, FL_MENU_DIVIDER },\r
-               { gettext("Insert as list"),    0, list_dat_cb },\r
-               { gettext("Plot data"),         0, plot_dat_cb },\r
-//             { gettext("Info for data"),     0, info_dat_cb },\r
-               { 0 },\r
-       { gettext("Sizes"), 0, 0, 0, FL_SUBMENU },\r
-               { gettext("Create new"),        0, new_dat_cb },\r
-               { gettext("Resize"),            0, resize_cb },\r
-               { gettext("Squeeze"),   0, squeeze_cb },\r
-               { gettext("Crop"),              0, crop_cb },\r
-               { gettext("Transpose"), 0, transp_cb },\r
-//             { gettext("Extend"),            0, extend_cb },\r
-               { 0 },\r
-       { gettext("Fill"), 0, 0, 0, FL_SUBMENU },\r
-               { gettext("By formula"),        0, modify_cb },\r
-               { gettext("In range"),  0, fill_cb },\r
-               { gettext("Normalize"), 0, normal_cb },\r
-               { 0 },\r
-       { gettext("Change"), 0, 0, 0, FL_SUBMENU },\r
-               { gettext("Smooth"),            0, smooth_cb },\r
-               { gettext("CumSum"),            0, cumsum_cb },\r
-               { gettext("Integrate"), 0, integr_cb },\r
-               { gettext("Difference"),        0, diff_cb },\r
-               { gettext("Double diff."),      0, diff2_cb },\r
-               { gettext("Swap parts"),        0, swap_cb },\r
-               { 0 },\r
-       { gettext("Another"), 0, 0, 0, FL_SUBMENU },\r
-//             { gettext("Histogram of"),      0, hist_cb },\r
-               { gettext("Summation of"),      0, asum_cb },\r
-               { gettext("Maximum of"),        0, amax_cb },\r
-               { gettext("Minimum of"),        0, amin_cb },\r
-               { 0 },\r
-       { gettext("Operations"), 0, 0, 0, FL_SUBMENU },\r
-               { gettext("Add to"),            0, addto_cb },\r
-               { gettext("Subtract to"),0, subto_cb },\r
-               { gettext("Multiply by"),0, multo_cb },\r
-               { gettext("Divide by"), 0, divto_cb },\r
-               { 0 },\r
-       { gettext("Navigation"), 0, 0, 0, FL_SUBMENU },\r
-               { gettext("First slice"), FL_CTRL + FL_F + 1, first_sl_cb },\r
-               { gettext("Prev slice"), FL_CTRL + FL_F + 2, prev_sl_cb },\r
-               { gettext("Next slice"), FL_CTRL + FL_F + 3, next_sl_cb },\r
-               { gettext("Last slice"),        FL_CTRL + FL_F + 4, last_sl_cb, 0, FL_MENU_DIVIDER },\r
-               { gettext("First cell"), FL_ALT + FL_F + 1, first_cl_cb },\r
-//             { gettext("Last cell"), FL_ALT + FL_F + 2, last_cl_cb },\r
-//             { gettext("Center grid"), FL_ALT + FL_F + 3, center_cl_cb },\r
-               { 0 },\r
-       { 0 }\r
-};\r
-//-----------------------------------------------------------------------------\r
-#include "xpm/document-new.xpm"\r
-#include "xpm/plot.xpm"\r
-#include "xpm/document-open.xpm"\r
-#include "xpm/document-save.xpm"\r
-#include "xpm/document-import.xpm"\r
-#include "xpm/document-export.xpm"\r
-#include "xpm/format-indent-more.xpm"\r
-#include "xpm/diff.xpm"\r
-#include "xpm/func.xpm"\r
-#include "xpm/size.xpm"\r
-#include "xpm/tran.xpm"\r
-#include "xpm/crop.xpm"\r
-#include "xpm/go-first.xpm"\r
-#include "xpm/go-last.xpm"\r
-TableWindow::TableWindow(int x, int y, int w, int h, const char* t) : Fl_Window(x, y, w, h, t)\r
-{\r
-       var = 0;\r
-//     menu = new Fl_Menu_Bar(0, 0, w, 30);\r
-//     menu->copy(tablemenu, this);\r
-       Fl_Button *o;\r
-       Fl_Group *g;\r
-\r
-\r
-       g = new Fl_Group(0,0,30,350);\r
-       o = new Fl_Button(0, 0, 25, 25);        o->image(new Fl_Pixmap(document_new_xpm));\r
-       o->callback(new_dat_cb,this);           o->tooltip(gettext("Create new data with zero filling"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(0, 25, 25, 25);       o->image(new Fl_Pixmap(document_open_xpm));\r
-       o->callback(load_dat_cb,this);          o->tooltip(gettext("Load data from file"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(0, 50, 25, 25);       o->image(new Fl_Pixmap(document_import_xpm));\r
-       o->callback(imp_dat_cb,this);           o->tooltip(gettext("Import data from PNG file"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(0, 75, 25, 25);       o->image(new Fl_Pixmap(document_save_xpm));\r
-       o->callback(save_dat_cb,this);          o->tooltip(gettext("Save data to file"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(0, 100, 25, 25);      o->image(new Fl_Pixmap(document_export_xpm));\r
-       o->callback(exp_dat_cb,this);           o->tooltip(gettext("Export data to PNG file"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-\r
-       o = new Fl_Button(0, 130, 25, 25);      o->image(new Fl_Pixmap(format_indent_more_xpm));\r
-       o->callback(list_dat_cb,this);          o->tooltip(gettext("Insert to script as 'list' command"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(0, 155, 25, 25);      o->image(new Fl_Pixmap(plot_xpm));\r
-       o->callback(plot_dat_cb,this);          o->tooltip(gettext("Plot data"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-\r
-       o = new Fl_Button(0, 185, 25, 25);      o->image(new Fl_Pixmap(diff_xpm));\r
-       o->callback(smooth_cb,this);            o->tooltip(gettext("Apply operator (smoothing, integration, difference ...) to data"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(0, 210, 25, 25);      o->image(new Fl_Pixmap(func_xpm));\r
-       o->callback(modify_cb,this);            o->tooltip(gettext("Fill data by formula"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(0, 235, 25, 25);      o->image(new Fl_Pixmap(size_xpm));\r
-       o->callback(resize_cb,this);            o->tooltip(gettext("Resize data with smoothing"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(0, 260, 25, 25);      o->image(new Fl_Pixmap(crop_xpm));\r
-       o->callback(crop_cb,this);              o->tooltip(gettext("Crop (cut off edges) data"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(0, 285, 25, 25);      o->image(new Fl_Pixmap(tran_xpm));\r
-       o->callback(transp_cb,this);            o->tooltip(gettext("Transpose data dimensions"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       g->end();       g->resizable(0);\r
-\r
-\r
-       g = new Fl_Group(30,0,200,30);\r
-       o = new Fl_Button(30, 0, 25, 25);       o->image(new Fl_Pixmap(go_first_xpm));\r
-       o->callback(first_sl_cb,this);          o->tooltip(gettext("Go to first slice (Ctrl-F1)"));\r
-//     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);\r
-       slice = new Fl_Counter(55, 0, 90, 25, 0);       slice->callback(change_sl_cb,this);\r
-       slice->lstep(10);       slice->step(1); slice->tooltip(gettext("Id of slice on third (z-) dimension"));\r
-//     slice->box(FL_PLASTIC_UP_BOX);//        slice->down_box(FL_PLASTIC_DOWN_BOX);\r
-       o = new Fl_Button(147, 0, 25, 25);      o->image(new Fl_Pixmap(go_last_xpm));\r
-       o->callback(last_sl_cb,this);           o->tooltip(gettext("Go to last slice (Ctrl-F4)"));\r
-       g->end();       g->resizable(0);\r
-\r
-       data = new Fl_Data_Table(30,30,w-30,h-30);\r
-       data->row_header(1);    data->row_header_width(70);\r
-       data->row_resize(1);    data->rows(1);\r
-       data->row_height_all(25);\r
-       data->col_header(1);    data->col_header_height(25);\r
-       data->col_resize(1);    data->cols(1);\r
-       data->col_width_all(70);\r
-\r
-       end();  resizable(data);\r
-//     callback(close_table_cb, this);\r
-}\r
-//-----------------------------------------------------------------------------\r
-TableWindow::~TableWindow()\r
-{      parent()->deactivate();\r
-       (parent()->parent())->remove(parent());\r
-       parent()->remove(this); delete parent();        }\r
-//-----------------------------------------------------------------------------\r
-void delete_cb(void *v)        {       if(v)   delete (TableWindow *)v;        }\r
-//-----------------------------------------------------------------------------\r
-void TableWindow::update(mglVar *v)\r
-{\r
-       if(v==0)        return;\r
-       char ss[1024];\r
-       wcstombs(ss,v->s.c_str(),1024);\r
-       label(ss);      v->func = delete_cb;\r
-//     if(var) var->o = 0;\r
-       var = v;        v->o = this;\r
-       refresh();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void TableWindow::refresh()\r
-{\r
-       if(var==0)      return;\r
-       deactivate();   nz = var->nz;\r
-       sl = 0; slice->range(0,nz-1);\r
-\r
-       data->rows(var->ny);    data->cols(var->nx);\r
-       data->ny = var->ny;     data->nx = var->nx;\r
-       data->data = var->a;\r
-       activate();\r
-//     show();\r
-}\r
-//-----------------------------------------------------------------------------\r
-void TableWindow::set_slice(long s)\r
-{\r
-       if(s>=0 && s<nz)\r
-       {\r
-               sl = s;\r
-               data->data = var->a + var->nx * var->ny * sl;\r
-               refresh();\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void TableWindow::go_home()\r
-{\r
-}\r
-//-----------------------------------------------------------------------------\r
diff --git a/mgllab/udav.h b/mgllab/udav.h
deleted file mode 100644 (file)
index 83788f8..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/* udav.h is part of UDAV\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-//-----------------------------------------------------------------------------\r
-#ifndef _UDAV_H_\r
-#define _UDAV_H_\r
-//-----------------------------------------------------------------------------\r
-#ifdef __MWERKS__\r
-# define FL_DLL\r
-#endif\r
-#ifdef USE_GETTEXT\r
-       #include <libintl.h>\r
-#else\r
-       #define gettext(x)      (x)\r
-#endif\r
-#include <FL/Fl.H>\r
-#include <FL/Fl_Group.H>\r
-#include <FL/Fl_Double_Window.H>\r
-#include <FL/fl_ask.H>\r
-#include <FL/Fl_File_Chooser.H>\r
-#include <FL/Fl_Menu_Bar.H>\r
-#include <FL/Fl_Input.H>\r
-#include <FL/Fl_Button.H>\r
-#include <FL/Fl_Return_Button.H>\r
-#include <FL/Fl_Text_Buffer.H>\r
-#include <FL/Fl_Text_Editor.H>\r
-#include <FL/Fl_Pixmap.H>\r
-#include <FL/Fl_Counter.H>\r
-#include <Fl/Fl_Scroll.H>\r
-#include <FL/Fl_Tabs.H>\r
-#include <FL/Fl_Help_View.H>\r
-#include <Fl/Fl_Table.H>\r
-#include <Fl/Fl_Round_Button.H>\r
-#include <Fl/Fl_Float_Input.H>\r
-#include <Fl/Fl_Multiline_Input.H>\r
-//-----------------------------------------------------------------------------\r
-#ifdef USE_PLASTIC\r
-       #define UDAV_UP_BOX                     FL_PLASTIC_UP_BOX\r
-       #define UDAV_DOWN_BOX           FL_PLASTIC_DOWN_BOX\r
-       #define UDAV_EDIT_BOX           FL_PLASTIC_THIN_DOWN_BOX\r
-       #define UDAV_THIN_UP_BOX        FL_PLASTIC_THIN_UP_BOX\r
-#else\r
-       #define UDAV_UP_BOX                     FL_GTK_UP_BOX\r
-       #define UDAV_DOWN_BOX           FL_GTK_DOWN_BOX\r
-       #define UDAV_EDIT_BOX           FL_GTK_DOWN_BOX\r
-       #define UDAV_THIN_UP_BOX        FL_GTK_THIN_UP_BOX\r
-#endif\r
-//-----------------------------------------------------------------------------\r
-#include "mgl2/fltk.h"\r
-//-----------------------------------------------------------------------------\r
-extern mglParse *Parse;\r
-extern Fl_Menu_Item colors[];\r
-extern Fl_Preferences pref;\r
-extern char *docdir;\r
-class Fl_MGL;\r
-//-----------------------------------------------------------------------------\r
-class Fl_Data_Table : public Fl_Table\r
-{\r
-private:\r
-       int row, col;\r
-       Fl_Input* input;\r
-protected:\r
-       void draw_cell(TableContext context, int R, int C, int X, int Y, int W, int H);\r
-       static void event_callback(Fl_Widget*, void*v)\r
-       {       ((Fl_Data_Table*)v)->cell_click();      }\r
-       void cell_click();\r
-\r
-public:\r
-       mreal *data;\r
-       int nx, ny;\r
-\r
-       Fl_Data_Table(int x, int y, int w, int h, const char *l=0);\r
-    ~Fl_Data_Table() { }\r
-\r
-       void set_value();\r
-    void rows(int val) { if (input->visible()) input->do_callback(); Fl_Table::rows(val); }\r
-    void cols(int val) { if (input->visible()) input->do_callback(); Fl_Table::cols(val); }\r
-    inline int rows() { return Fl_Table::rows(); }\r
-    inline int cols() { return Fl_Table::cols(); }\r
-};\r
-//-----------------------------------------------------------------------------\r
-struct AnimateDlg\r
-{\r
-       friend void animate_dlg_cb(Fl_Widget *, void *v);\r
-       friend void animate_rad_cb(Fl_Widget *, void *v);\r
-       friend void fill_animate(const char *text);\r
-       friend void animate_put_cb(Fl_Widget *, void *);\r
-public:\r
-       Fl_Window* wnd;\r
-       int OK;\r
-       AnimateDlg()    {       memset(this,0,sizeof(AnimateDlg));      create_dlg();   }\r
-       ~AnimateDlg()   {       delete wnd;     }\r
-       void FillResult(Fl_MGL* e);\r
-protected:\r
-       bool swap;\r
-       Fl_Round_Button *rt, *rv;\r
-       Fl_Multiline_Input *txt;\r
-       Fl_Float_Input *x0, *x1, *dx, *dt;\r
-       Fl_Check_Button *save;\r
-       void create_dlg();\r
-};\r
-//-----------------------------------------------------------------------------\r
-class Fl_MGL : public Fl_MGLView, public mglDraw\r
-{\r
-friend class AnimateDlg;\r
-public:\r
-       Fl_Widget *status;              ///< StatusBar for mouse coordinates\r
-       const char *AnimBuf;            ///< buffer for animation\r
-       const char **AnimS0;\r
-       int AnimNum;\r
-       mreal AnimDelay;\r
-\r
-       Fl_MGL(int x, int y, int w, int h, const char *label=0);\r
-       ~Fl_MGL();\r
-\r
-       /// Drawing itself\r
-       int Draw(mglGraph *);\r
-       /// Update (redraw) plot\r
-       void update();\r
-       /// Set main scr and optional pre scripts for execution\r
-       void scripts(char *scr, char *pre);\r
-       /// Clear scripts internally saved\r
-       void clear_scripts();\r
-       /// Show next frame\r
-       void next_frame();\r
-       /// Show prev frame\r
-       void prev_frame();\r
-\r
-protected:\r
-       char *Args[1000], *ArgBuf;\r
-       int NArgs, ArgCur;\r
-\r
-       char *script;           ///< main script\r
-       char *script_pre;       ///< script with settings\r
-};\r
-//-----------------------------------------------------------------------------\r
-struct TableWindow : public Fl_Window\r
-{\r
-public:\r
-       TableWindow(int x, int y, int w, int h, const char* t=0);\r
-       ~TableWindow();\r
-       void update(mglVar *v);\r
-       void refresh();\r
-       void set_slice(long s);\r
-       inline long get_slice() { return sl; }\r
-       inline long num_slice() {       return nz;      }\r
-       void go_home();\r
-\r
-       Fl_Data_Table *data;\r
-       Fl_Menu_Bar     *menu;\r
-//     Fl_Output *main;\r
-       Fl_Counter *slice;\r
-       mglData *var;\r
-protected:\r
-//     long nx,ny,nz;\r
-       long nz;\r
-       long sl;                // current slice\r
-       char sl_id[64]; // slice id\r
-};\r
-//-----------------------------------------------------------------------------\r
-class SetupDlg\r
-{\r
-public:\r
-       Fl_Window *wnd;\r
-       bool OK;\r
-       Fl_Input *templ;\r
-\r
-       SetupDlg()      {       memset(this,0,sizeof(SetupDlg));        }\r
-       ~SetupDlg()     {       delete wnd;     }\r
-       void CreateDlg();\r
-       char *ToScript();\r
-private:\r
-       Fl_Input *xmin, *ymin, *zmin, *cmin;\r
-       Fl_Input *xmax, *ymax, *zmax, *cmax;\r
-       Fl_Input *xorg, *yorg, *zorg;\r
-       Fl_Input *xlab, *ylab, *zlab, *font;\r
-       Fl_Choice *xpos, *ypos, *zpos, *axial, *cid[10];\r
-       Fl_Input *xtik, *ytik, *ztik;\r
-       Fl_Input *xsub, *ysub, *zsub;\r
-       Fl_Input *alphad, *ambient, *basew, *mesh, *size;\r
-       Fl_Check_Button *alpha, *light, *rotate, *lid[10];\r
-       Fl_Input *xid[10], *yid[10], *zid[10], *bid[10];\r
-       Fl_Help_View *code;\r
-\r
-       void CreateGen();\r
-       void CreateLid();\r
-};\r
-//-----------------------------------------------------------------------------\r
-class ScriptWindow : public Fl_Double_Window\r
-{\r
-public:\r
-       ScriptWindow(int w, int h, const char* t);\r
-       ~ScriptWindow();\r
-\r
-       Fl_Window       *replace_dlg;\r
-       Fl_Input        *replace_find;\r
-       Fl_Input        *replace_with;\r
-       Fl_Button       *replace_all;\r
-       Fl_Return_Button        *replace_next;\r
-       Fl_Button       *replace_cancel;\r
-       Fl_Text_Editor          *editor;\r
-       Fl_Menu_Bar     *menu;\r
-       Fl_Tabs *ltab, *rtab;\r
-       Fl_Help_View *hd;\r
-       Fl_Input *link_cmd;\r
-       Fl_Group *ghelp;\r
-       Fl_Browser *var;\r
-       Fl_Box *status;\r
-\r
-       void mem_init();\r
-       void mem_pressed(int n);\r
-       SetupDlg        *setup_dlg;\r
-       char            search[256];\r
-       Fl_MGL          *graph;\r
-};\r
-//-----------------------------------------------------------------------------\r
-// Editor window functions\r
-void find2_cb(Fl_Widget *, void *);\r
-void replall_cb(Fl_Widget *, void *);\r
-void replace2_cb(Fl_Widget *, void *);\r
-void replcan_cb(Fl_Widget *, void *);\r
-void insert_cb(Fl_Widget *, void *);\r
-void paste_cb(Fl_Widget *, void *);\r
-void replace_cb(Fl_Widget *, void *);\r
-void copy_cb(Fl_Widget *, void *);\r
-void cut_cb(Fl_Widget *, void *);\r
-void find_cb(Fl_Widget *, void *);\r
-void delete_cb(Fl_Widget *, void *);\r
-void changed_cb(int, int nInserted, int nDeleted,int, const char*, void* v);\r
-//-----------------------------------------------------------------------------\r
-// General callback functions\r
-void new_cb(Fl_Widget *, void *);\r
-void open_cb(Fl_Widget *, void *);\r
-void save_cb(Fl_Widget*, void*);\r
-void saveas_cb(Fl_Widget*, void*);\r
-void help_cb(Fl_Widget*, void*);\r
-//-----------------------------------------------------------------------------\r
-// Graphical callback functions\r
-void setup_cb(Fl_Widget *, void *);\r
-void style_cb(Fl_Widget *, void *);\r
-void option_cb(Fl_Widget *, void *);\r
-void argument_cb(Fl_Widget *, void *);\r
-void variables_cb(Fl_Widget *, void *);\r
-void settings_cb(Fl_Widget *, void *);\r
-void command_cb(Fl_Widget *, void *);\r
-//-----------------------------------------------------------------------------\r
-// Dialogs callback functions\r
-void close_dlg_cb(Fl_Widget *w, void *);\r
-void font_cb(Fl_Widget *, void *v);\r
-void line_cb(Fl_Widget *, void *v);\r
-void face_cb(Fl_Widget *, void *v);\r
-void data_cb(Fl_Widget *, void *v);\r
-//-----------------------------------------------------------------------------\r
-void style_init(void);\r
-int check_save(void);\r
-void load_file(char *newfile, int ipos);\r
-void save_file(char *newfile);\r
-Fl_Widget *add_editor(ScriptWindow *w);\r
-Fl_Widget *add_mem(ScriptWindow *w);\r
-void set_title(Fl_Window* w);\r
-//-----------------------------------------------------------------------------\r
-// Animation\r
-void animate_cb(Fl_Widget *, void *v);\r
-void fill_animate(const char *text);\r
-//-----------------------------------------------------------------------------\r
-Fl_Widget *add_help(ScriptWindow *w);\r
-void help_cb(Fl_Widget*, void*v);\r
-void example_cb(Fl_Widget*, void*v);\r
-void about_cb(Fl_Widget*, void*);\r
-//-----------------------------------------------------------------------------\r
-void newcmd_cb(Fl_Widget*,void*);\r
-//-----------------------------------------------------------------------------\r
-extern Fl_Text_Buffer  *textbuf;\r
-extern char    filename[256];\r
-extern int     changed;\r
-//-----------------------------------------------------------------------------\r
-#endif\r
-//-----------------------------------------------------------------------------\r
diff --git a/mgllab/udav.rc b/mgllab/udav.rc
deleted file mode 100644 (file)
index e557119..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* udav.rc is part of UDAV\r
- * Copyright (C) 2007 Alexey Balakin <balakin@appl.sci-nnov.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-//-----------------------------------------------------------------------------\r
-#include <windows.h>\r
-\r
-#define APPICON 1001\r
-#define APPICON48 1002\r
-\r
-APPICON ICON "udav.ico"\r
-APPICON48 ICON "udav48.ico"\r
diff --git a/mgllab/udav48.ico b/mgllab/udav48.ico
deleted file mode 100644 (file)
index a286d6d..0000000
Binary files a/mgllab/udav48.ico and /dev/null differ
diff --git a/mgllab/write.cpp b/mgllab/write.cpp
deleted file mode 100644 (file)
index ff461aa..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* write.cpp is part of Math Graphic Library\r
- * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Library General Public License\r
- * as published by the Free Software Foundation\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-//-----------------------------------------------------------------------------\r
index 73b7eeed60514b3785f53f0f4c1161b968d97dd5..95c8580bd8f7cffaccdb8aac64ab6edd6099caeb 100644 (file)
@@ -1,6 +1,6 @@
 set(mgl_src
        addon.cpp axis.cpp base_cf.cpp base.cpp canvas_cf.cpp canvas.cpp cont.cpp crust.cpp
-       complex.cpp complex_io.cpp fft.cpp data_gr.cpp
+       complex.cpp complex_ex.cpp complex_io.cpp fft.cpp data_gr.cpp
        data.cpp data_io.cpp data_ex.cpp data_png.cpp def_font.cpp
        export_2d.cpp export_3d.cpp eval.cpp evalp.cpp exec.cpp export.cpp
        fit.cpp font.cpp obj.cpp other.cpp parser.cpp pde.cpp pixel.cpp
@@ -13,7 +13,7 @@ set(mgl_hdr
        ../include/mgl2/base.h          ../include/mgl2/prim.h          ../include/mgl2/canvas_cf.h
        ../include/mgl2/font.h          ../include/mgl2/canvas.h        ../include/mgl2/surf.h
        ../include/mgl2/mgl_cf.h        ../include/mgl2/type.h          ${MathGL_BINARY_DIR}/include/mgl2/config.h
-${MathGL_BINARY_DIR}/include/mgl2/dllexport.h
+${MathGL_BINARY_DIR}/include/mgl2/dllexport.h  cont.hpp
        ../include/mgl2/cont.h          ../include/mgl2/mgl.h           ../include/mgl2/vect.h
        ../include/mgl2/data.h          ../include/mgl2/volume.h        ../include/mgl2/data_cf.h
        ../include/mgl2/define.h        ../include/mgl2/other.h         ../include/mgl2/eval.h
index ef6f932912f9ef95878e3966b7da621a44d46979..5f96413770e6f29396dd727c10e5c813a28429d0 100644 (file)
@@ -45,7 +45,7 @@ void MGL_EXPORT mgl_strcls(char *str)
        delete []tmp;
 }
 //-----------------------------------------------------------------------------
-int MGL_EXPORT mgl_strpos(const char *str,char *fnd)
+int MGL_EXPORT_PURE mgl_strpos(const char *str,char *fnd)
 {
        const char *p=strstr(str,fnd);
        int res;
@@ -54,7 +54,7 @@ int MGL_EXPORT mgl_strpos(const char *str,char *fnd)
        return res;
 }
 //-----------------------------------------------------------------------------
-int MGL_EXPORT mgl_chrpos(const char *str,char ch)
+int MGL_EXPORT_PURE mgl_chrpos(const char *str,char ch)
 {
        const char *p=str?strchr(str,ch):0;
        int res;
@@ -81,7 +81,7 @@ MGL_EXPORT char *mgl_fgetstr(FILE *fp)
 void MGL_EXPORT mgl_fgetpar(FILE *fp, const char *str, ...)
 {
        if(!str || !str[0])     return;
-       long len=strlen(str), *n;       double *v;
+       long len=strlen(str);
        char *s, *t;
        va_list lst;
        va_start(lst,str);
@@ -91,8 +91,8 @@ void MGL_EXPORT mgl_fgetpar(FILE *fp, const char *str, ...)
                if(str[i]=='%')
                {
                        if(str[i+1]=='s')       {       s = va_arg(lst, char*); strcpy(s, t);   }
-                       if(strchr("efg",str[i+1]))      {       v = va_arg(lst, double*);       *v = atof(t);   }
-                       if(strchr("ld",str[i+1]))       {       n = va_arg(lst, long*);         *n = atol(t);   }
+                       if(strchr("efg",str[i+1]))      {       double *v = va_arg(lst, double*);       *v = atof(t);   }
+                       if(strchr("ld",str[i+1]))       {       long *n = va_arg(lst, long*);   *n = atol(t);   }
                        i++;
                }
                if(str[i]==':')
@@ -104,7 +104,7 @@ void MGL_EXPORT mgl_fgetpar(FILE *fp, const char *str, ...)
        }
 }
 //-----------------------------------------------------------------------------
-int MGL_EXPORT mgl_istrue(char ch)
+int MGL_EXPORT_CONST mgl_istrue(char ch)
 {      return (ch=='1' || ch=='t' || ch=='+' || ch=='v');      }
 //-----------------------------------------------------------------------------
 void MGL_EXPORT mgl_test(const char *str, ...)
@@ -173,7 +173,6 @@ void MGL_EXPORT mgl_difr_grid_old(dual *a,int n,int step,dual q,int Border,dual
        else    for(long i=0;i<n;i++)   b[i] = a[i*step];
        for(long k=kk;k>0;k--)  // 3 iterations
        {
-//#pragma omp parallel for
                for(long i=1;i<n-1;i++)
                        d[i] = a[i*step] + adt*(b[i-1]+b[i+1]-mreal(2)*b[i])/mreal(k);
                memcpy(b,d,n*sizeof(dual));
@@ -219,7 +218,6 @@ void MGL_EXPORT mgl_difr_axial_old(dual *a,int n,int step,dual q,int Border,dual
        for(long k=kk;k>0;k--)  // kk iterations
        {
                d[ii] = a[ii] + adt*(b[ii+1]-b[ii])*(ff/k);
-//#pragma omp parallel for
                for(long i=ii+1;i<n-1;i++)
                {
                        register mreal dd = i+di;
@@ -263,11 +261,8 @@ double MGL_EXPORT mgl_gauss_rnd()
 //-----------------------------------------------------------------------------
 void MGL_EXPORT mgl_fft_freq(double *freq, long nn)
 {
-#pragma omp parallel for
-       for(long i=0;i<=nn/2;i++)
-       {
-               freq[i] = i;
-               if(i>0) freq[nn-i] = -(double)(i);
-       }
+       freq[0] = 0;
+       for(long i=1;i<=nn/2;i++)
+       {       freq[i] = i; freq[nn-i] = -i;   }
 }
 //-----------------------------------------------------------------------------
index c0a81e562a80b154852815202736c36abec0bdde..35776cea5ed322d6ff8197f34f27306796e47c54 100644 (file)
 #include "mgl2/data.h"
 #include "mgl2/canvas.h"
 #include "mgl2/prim.h"
-//-----------------------------------------------------------------------------
-#define islog(a, b) (((a)>0 && (b)>10*(a)) || ((b)<0 && (a)<10*(b)))
-// NOTE: I use <=0 for proper tick labels rotation. But this mirror labels for central origin!
-#define sign(a)        ((a)<0 ? -1:1)
-//#define sign(a)      ((a)<0 ? -1:((a)>0 ? 1:0))
+std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt);
 //-----------------------------------------------------------------------------
 MGL_NO_EXPORT inline struct tm *mgl_localtime (const time_t *clock, tm *result, bool use_utc)
 {      if (!clock || !result) return NULL;
        const tm *res = use_utc?gmtime(clock):localtime(clock);
        memcpy(result,res,sizeof(tm));  return result;  }
 //-----------------------------------------------------------------------------
-long MGL_EXPORT mgl_have_color(const char *stl)
+long MGL_EXPORT_PURE mgl_have_color(const char *stl)
 {
-       register long i,j=0;
-       if(stl) for(i=0;stl[i];i++)
+       long j=0;
+       if(stl) for(long i=0;stl[i];i++)
        {
                if(strchr(MGL_COLORS,stl[i]))   j++;
                if(stl[i]=='{' && stl[i+1]=='x')        j++;
@@ -54,7 +50,7 @@ void MGL_EXPORT mgl_wcstrim(wchar_t *str)
        str[i-k]=0;
 }
 //-----------------------------------------------------------------------------
-size_t MGL_EXPORT mgl_wcslen(const wchar_t *str)
+size_t MGL_EXPORT_PURE mgl_wcslen(const wchar_t *str)
 {
        long i=0;
        if(str) while(str[i])   i++;
@@ -76,7 +72,7 @@ void mglCanvas::SetAxisStl(const char *stl, const char *tck, const char *sub)
 void mglCanvas::SetTickLen(mreal tlen, mreal stt)
 {      TickLen = tlen?tlen:0.02;       st_t=stt>0?stt:1;       }
 //-----------------------------------------------------------------------------
-void mglCanvas::SetTicks(char dir, mreal d, int ns, mreal org)
+void mglCanvas::SetTicks(char dir, mreal d, int ns, mreal org, const wchar_t *lbl)
 {
        if(!strchr("xyzca",dir))        return;
        mglAxis &aa = (dir=='x' ? ax : (dir=='y' ? ay : (dir=='z' ? az : ac)));
@@ -84,16 +80,33 @@ void mglCanvas::SetTicks(char dir, mreal d, int ns, mreal org)
        if(aa.f==1)     aa.t.clear();
        aa.d=d; aa.f=0; aa.ns=ns;       aa.o=org;
        aa.txt.clear();
+       if(!lbl || *lbl==0)     aa.fact.clear();
+       else    aa.fact = lbl;
 }
 //-----------------------------------------------------------------------------
+void mglCanvas::AddTick(char dir, double v, const wchar_t *lbl)
+{
+       if(!strchr("xyzca",dir))        return;
+       mglAxis &aa = (dir=='x' ? ax : (dir=='y' ? ay : (dir=='z' ? az : ac)));
+       bool ff = (dir=='x' ? fx : (dir=='y' ? fy : (dir=='z' ? fz : fa)));
+
+       UpdateAxis();   AdjustTicks(aa,ff);
+       if(!v || !lbl || !lbl[0])       {       aa.f = 0;       return; }
+       aa.f = 2;       aa.ns=0;        aa.ds=0;
+       aa.AddLabel(lbl,v);
+}
+//-----------------------------------------------------------------------------
+void mglCanvas::AddTick(char dir, double v, const char *lbl)
+{      MGL_TO_WCS(lbl,AddTick(dir,v,wcs));     }
+//-----------------------------------------------------------------------------
 void mglCanvas::SetTicksVal(char dir, HCDT v, const wchar_t *lbl, bool add)
 {
        if(!strchr("xyzca",dir))        return;
        mglAxis &aa = (dir=='x' ? ax : (dir=='y' ? ay : (dir=='z' ? az : ac)));
        bool ff = (dir=='x' ? fx : (dir=='y' ? fy : (dir=='z' ? fz : fa)));
 
-       aa.txt.clear();
        if(add) {       UpdateAxis();   AdjustTicks(aa,ff);     }
+       else    aa.txt.clear();
        if(!v || !lbl || !lbl[0])       {       aa.f = 0;       return; }
        aa.f = 2;       aa.ns=0;        aa.ds=0;
        register long i,j,l=0,n=v->GetNx();
@@ -114,9 +127,7 @@ void mglCanvas::SetTicksVal(char dir, HCDT v, const wchar_t *lbl, bool add)
 }
 //-----------------------------------------------------------------------------
 void mglCanvas::SetTicksVal(char dir, HCDT v, const char *lbl, bool add)
-{
-       MGL_TO_WCS(lbl,SetTicksVal(dir,v,wcs,add));
-}
+{      MGL_TO_WCS(lbl,SetTicksVal(dir,v,wcs,add));     }
 //-----------------------------------------------------------------------------
 void mglCanvas::SetTicksVal(char dir, const wchar_t *lbl, bool add)
 {
@@ -144,8 +155,8 @@ void mglCanvas::SetTicksVal(char dir, HCDT v, const wchar_t **lbl, bool add)
        mglAxis &aa = (dir=='x' ? ax : (dir=='y' ? ay : (dir=='z' ? az : ac)));
        bool ff = (dir=='x' ? fx : (dir=='y' ? fy : (dir=='z' ? fz : fa)));
 
-       aa.txt.clear();
        if(add) {       UpdateAxis();   AdjustTicks(aa,ff);     }
+       else    aa.txt.clear();
        if(!v || !lbl)  {       aa.f = 0;       return; }
        aa.f = 2;       aa.ns=0;        aa.ds=0;
        register long i,n=v->GetNx();
@@ -171,7 +182,7 @@ void mglCanvas::SetTickTempl(char dir, const wchar_t *t)
        mglAxis &aa = (dir=='x' ? ax : (dir=='y' ? ay : (dir=='z' ? az : ac)));
 
        if(aa.f==1)     aa.f = 0;       // remove time ticks
-       if(!t aa.t.clear();   else aa.t=t;
+       if(!t || !t[0]) aa.t.clear();   else aa.t=t;
 }
 //-----------------------------------------------------------------------------
 void mglCanvas::SetTickTempl(char dir, const char *t)
@@ -253,7 +264,6 @@ void mglCanvas::SetTickTime(char dir, mreal d, const char *t)
        if(aa.ch=='y')  aa.v0 = aa.org.y;
        if(aa.ch=='z')  aa.v0 = aa.org.z;
 
-       wchar_t buf[64];
        mreal v, v0 = mgl_isnan(aa.o) ? aa.v0 : aa.o, v1;
        if(aa.v2>aa.v1)
        {       v1 = aa.v2;             v0 = v0 - aa.dv*floor((v0-aa.v1)/aa.dv+1e-3);   }
@@ -261,30 +271,31 @@ void mglCanvas::SetTickTime(char dir, mreal d, const char *t)
        {       v1 = aa.v1;             v0 = v0 - aa.dv*floor((v0-aa.v2)/aa.dv+1e-3);   }
        if(v0+aa.dv!=v0 && v1+aa.dv!=v1)        for(v=v0;v<=v1;v+=aa.dv)
        {
+               wchar_t buf[64];
                tt = v; tm tp;          mgl_localtime(&tt, &tp, get(MGL_USE_GMTIME));
                wcsftime(buf,64,aa.t.c_str(),&tp);      aa.AddLabel(buf,v);
        }
 }
 //-----------------------------------------------------------------------------
-void mglCanvas::AdjustTicks(const char *dir, bool force)
+void mglCanvas::AdjustTicks(const char *dir, bool force, std::string stl)
 {
        if(force)       SetTuneTicks(3);
        UpdateAxis();
        if(strchr(dir,'x') || strchr(dir,'X'))  // NOTE dir have to be non-NULL here !!!
-       {       if(force)       ax.d=0; AdjustTicks(ax,fx!=0);  }
+       {       if(force)       ax.d=0; ax.stl=stl;     AdjustTicks(ax,fx!=0);  }
        if(strchr(dir,'y') || strchr(dir,'Y'))
-       {       if(force)       ay.d=0; AdjustTicks(ay,fy!=0);  }
+       {       if(force)       ay.d=0; ay.stl=stl;     AdjustTicks(ay,fy!=0);  }
        if(strchr(dir,'z') || strchr(dir,'Z'))
-       {       if(force)       az.d=0; AdjustTicks(az,fz!=0);  }
+       {       if(force)       az.d=0; az.stl=stl;     AdjustTicks(az,fz!=0);  }
        if(strchr(dir,'a') || strchr(dir,'c'))
-       {       if(force)       ac.d=0; AdjustTicks(ac,fa!=0);  }
+       {       if(force)       ac.d=0; ac.stl=stl;     AdjustTicks(ac,fa!=0);  }
 }
 //-----------------------------------------------------------------------------
 void mglCanvas::AdjustTicks(mglAxis &aa, bool ff)
 {
-       double d = fabs(aa.v2-aa.v1), n;
+       double d = fabs(aa.v2-aa.v1);
        if(aa.f>0)      return;
-       if(ff && islog(aa.v1,aa.v2))
+       if(ff && mgl_islog(aa.v1,aa.v2))
        {       aa.dv = 0;      aa.ds=0;        }
        else if(aa.d>0)
        {       aa.dv = aa.d;   aa.ds = aa.d/(abs(aa.ns)+1);    }
@@ -292,7 +303,8 @@ void mglCanvas::AdjustTicks(mglAxis &aa, bool ff)
        {       aa.dv = mgl_adj_val(d,&aa.ds);  aa.o=0; }
        else
        {
-               d /= -aa.d;             n = floor(log10(d));
+               d /= -aa.d;
+               long n = floor(log10(d));
                int k = int(d*pow(10.,-n)+0.5);
                aa.dv = pow(10.,n)*k;
                aa.o=0; aa.ds = pow(10.,n);
@@ -353,32 +365,25 @@ std::wstring MGL_NO_EXPORT mgl_format(mreal v1, mreal v2, bool zero)
        return str;
 }
 //-----------------------------------------------------------------------------
-void MGL_NO_EXPORT mgl_tick_text(mreal z, mreal z0, mreal d, std::wstring fmt, mreal v, int kind, wchar_t str[64])
+std::wstring MGL_NO_EXPORT mgl_tick_text(mreal z, mreal z0, mreal d, mreal v, int kind, const std::wstring &fact, mreal step, const char *stl)
 {
+       std::wstring str;
+       bool ff = step>0 && !fact.empty();// && mgl_wcslen(str)+fact.length()<62;
+       if(ff)  z/=step;
        mreal u = fabs(z)<d ? 0:z;
        if((kind&1) && z>z0)    u = fabs(z-z0)<d ? 0:(z-z0);
        if(kind==2 || (kind==3 && z>z0))        u /= v;
-       if(kind&1)      fmt = z>z0?L"@{(+"+fmt+L")}":L"%g";
-       mglprintf(str,64,fmt.c_str(), u);
-       
-/*     mreal u = fabs(z)<d ? 0:z;
-       if((kind&1) && z>z0)    u = fabs(z-z0)<d ? 0:(z-z0);
-       if(kind==2 || (kind==3 && z>z0))        u /= v;
-       if((kind&1) && z>z0)
+       str = mgl_ftoa(u,stl?stl:"");
+       if((kind&1) && z>z0)    str = L"@{(+"+str+L")}";
+//     if(kind&1)      fmt = z>z0?L"@{(+"+fmt+L")}":L"%g";
+//     mglprintf(str,64,fmt.c_str(), u);
+       if(ff)
        {
-               size_t n1,n2;
-               mglprintf(str, 64, L"@{(+%.2g)}",u);
-               n1=mgl_wcslen(str);     mglprintf(str, 64, L"@{(+%g)}",u);      n2=mgl_wcslen(str);
-               if(n1<n2)       mglprintf(str, 64, L"@{(+%.2g)}",u);
+               if(str==L"-1" || str==L"+1" || str==L"−1")    str = str[0] + fact;
+               else if(str==L"1")      str = fact;
+               else if(str!=L"0")      str += fact;
        }
-       else
-       {
-               size_t n1,n2;
-               mglprintf(str, 64, fabs(u)<1 ? L"%.2g" : L"%.3g",u);
-               n1=mgl_wcslen(str);     mglprintf(str, 64, L"%g",u);    n2=mgl_wcslen(str);
-               if(n1<n2 && tune)       mglprintf(str, 64, fabs(u)<1 ? L"%.2g" : L"%.3g",u);
-       } 
-*/
+       return str;
 }
 //-----------------------------------------------------------------------------
 void mglCanvas::LabelTicks(mglAxis &aa)
@@ -394,6 +399,7 @@ void mglCanvas::LabelTicks(mglAxis &aa)
        int d,ds;
        if(aa.f)        return;
        aa.txt.clear();
+       bool minus = mglchr(aa.stl.c_str(),'-') && !mglchr(aa.stl.c_str(),'+');
        if(aa.dv==0 && aa.v1>0) // positive log-scale
        {
                v0 = exp(M_LN10*floor(0.1+log10(aa.v1)));
@@ -403,7 +409,8 @@ void mglCanvas::LabelTicks(mglAxis &aa)
                        d = int(floor(0.1+log10(v)));
                        if(d==0)        wcscpy(buf,L"1");
                        else if(d==1)   wcscpy(buf,L"10");
-                       else mglprintf(buf,64,L"10^{%d}",d);
+                       else if(d>0)    mglprintf(buf,64,L"10^{%d}",d);
+                       else    mglprintf(buf,64,minus?L"10^{-%d}":L"10^{−%d}",-d);
                        if(d%ds!=0)     *buf=0; //      remove too often log ticks
                        aa.AddLabel(buf,v);
                }
@@ -415,9 +422,10 @@ void mglCanvas::LabelTicks(mglAxis &aa)
                for(v=v0;v>=aa.v1*MGL_EPSILON;v*=10)    if(v*MGL_EPSILON<=aa.v2)
                {
                        d = int(floor(0.1+log10(-v)));
-                       if(d==0)        wcscpy(buf,L"-1");
-                       else if(d==1)   wcscpy(buf,L"-10");
-                       else mglprintf(buf,64,L"-10^{%d}",d);
+                       if(d==0)        wcscpy(buf,minus?L"-1":L"−1");
+                       else if(d==1)   wcscpy(buf,minus?L"-10":L"−10");
+                       else if(d>0)    mglprintf(buf,64,minus?L"-10^{%d}":L"−10^{%d}",d);
+                       else    mglprintf(buf,64,minus?L"-10^{-%d}":L"−10^{−%d}",-d);
                        if(d%ds!=0)     *buf=0; //      remove too often log ticks
                        aa.AddLabel(buf,v);
                }
@@ -426,32 +434,27 @@ void mglCanvas::LabelTicks(mglAxis &aa)
        {
                int kind=0;
                wchar_t s[32]=L"";
-               if(aa.t.empty() && TuneTicks) kind = mgl_tick_ext(aa.v2, aa.v1, s, w);
-               if((TuneTicks&1)==0 && kind==2) kind=0;
-               if((TuneTicks&2)==0 && kind!=2) kind=0;
+               if(aa.t.empty() && TuneTicks && !strchr(aa.stl.c_str(),'!'))
+                       kind = mgl_tick_ext(aa.v2, aa.v1, s, w);
+               if(((TuneTicks&1)==0 && kind==2) || ((TuneTicks&2)==0 && kind!=2))
+                       kind=0;
 
                v0 = mgl_isnan(aa.o) ? aa.v0 : aa.o;
+               if(mgl_isnan(v0))       v0=0;
                if(aa.v2>aa.v1)
                {       v1 = aa.v2;             v0 = v0 - aa.dv*floor((v0-aa.v1)/aa.dv+1e-3);   }
                else
                {       v1 = aa.v1;             v0 = v0 - aa.dv*floor((v0-aa.v2)/aa.dv+1e-3);   }
 
-               std::wstring fmt;
-               switch(kind)
-               {
-                       case 1: fmt=mgl_format(0,v1-v0,TuneTicks&4);    break;
-                       case 2: fmt=mgl_format(v0/w,v1/w,TuneTicks&4);  break;
-                       case 3: fmt=mgl_format(0,(v1-v0)/w,TuneTicks&4);break;
-                       default:fmt=mgl_format(v0,v1,TuneTicks&4);      break;
-               }
-
-               if(v0+aa.dv!=v0 && v1+aa.dv!=v1)        for(v=v0;v<=v1;v+=aa.dv)
+               if(v0+aa.dv!=v0 && v1+aa.dv!=v1)
                {
-                       if(aa.t.empty())
-                               mgl_tick_text(v,v0,aa.dv/100,fmt,w,kind,buf);
-                       else
+                       if(aa.t.empty())        for(v=v0;v<=v1;v+=aa.dv)
+                               aa.AddLabel(mgl_tick_text(v,v0,aa.dv/100,w,kind,aa.fact,aa.d,aa.stl.c_str()),v);
+                       else    for(v=v0;v<=v1;v+=aa.dv)
+                       {
                                mglprintf(buf, 64, aa.t.c_str(), fabs(v)<aa.dv/100 ? 0 : v);
-                       mgl_wcstrim(buf);       aa.AddLabel(buf,v);
+                               mgl_wcstrim(buf);       aa.AddLabel(buf,v);
+                       }
                }
                if(kind&2)      aa.AddLabel(s,FactorPos*(aa.v2-aa.v1)+aa.v1);
        }
@@ -461,10 +464,12 @@ void mglCanvas::Axis(const char *dir, const char *stl, const char *opt)
 {
        bool text = !(mglchr(dir,'_') || mglchr(dir,'~'));
        bool inv = mglchr(dir,'^');
-       bool adjust = mglchr(stl,'a');
        bool ret = get(MGL_ENABLE_RTEXT);
        if(mglchr(dir,'U'))     clr(MGL_ENABLE_RTEXT);
 
+       std::string Tstl;
+       for(const char *s="+E0123456789-fF!";*s;s++)    if(mglchr(dir,*s))      Tstl += *s;
+
        const char *ar = "AKDTVISO";
        char arr=0;
        for(size_t i=0;i<strlen(ar);i++)
@@ -472,7 +477,7 @@ void mglCanvas::Axis(const char *dir, const char *stl, const char *opt)
        if(!mglchrs(dir,"xXyYzZ"))      dir="xyz";
 
        SaveState(opt);
-       AdjustTicks(dir,adjust);
+       AdjustTicks(dir,mglchr(stl,'a'),Tstl);
        LoadState();
 
        ax.pos = strchr(dir,'X') ? 'T':'t';
@@ -509,7 +514,7 @@ void mglCanvas::DrawAxis(mglAxis &aa, bool text, char arr,const char *stl,const
        mglPoint d = aa.dir, o = aa.org, q(NAN);        // "transverse" org
        if(strchr("xyz",aa.ch)) o -= d*(o*d);
        mglPoint av=(Min+Max)/2, dv,da,db, p;
-       dv = mglPoint(sign((av.x-o.x)*(Max.x-Min.x)), sign((av.y-o.y)*(Max.y-Min.y)), sign((av.z-o.z)*(Max.z-Min.z)));
+       dv = mglPoint(mgl_sign((av.x-o.x)*(Max.x-Min.x)), mgl_sign((av.y-o.y)*(Max.y-Min.y)), mgl_sign((av.z-o.z)*(Max.z-Min.z)));
        da = aa.a*(dv*aa.a);    db = aa.b*(dv*aa.b);
        if(aa.v2<aa.v1) {       da *= -1;       db *= -1;       }
 
@@ -613,18 +618,22 @@ void mglCanvas::DrawLabels(mglAxis &aa, bool inv, const mglMatrix *M)
                if(ux==0)       uy = fabs(uy);
                qq.u = ux;      qq.v = uy;
 
-               if((!get(MGL_ENABLE_RTEXT) || tet) && nn.x!=0 && aa.ch!='c')    pos[2] = nn.x<0 ? 'L':'R';
-//             if(tet && nn.x==0)      pos[2] = 'R';
+               if((!get(MGL_ENABLE_RTEXT) || tet) && nn.x!=0)
+               {
+                       if(aa.ch!='c') pos[2] = nn.x<0 ? 'L':'R';
+                       else    pos[2] = aa.ns==1?'L':'R';//  nn.x<0 ? 'R':'L';
+               }
+//             if((!get(MGL_ENABLE_RTEXT) || tet) && nn.x!=0 && aa.ch=='c')    pos[2] = nn.x<0 ? 'R':'L';
+//             if((!get(MGL_ENABLE_RTEXT) || tet) && nn.x!=0 && aa.ch!='c')    pos[2] = nn.x<0 ? 'L':'R';
                if(aa.ch=='c' && aa.txt[i].text[0]==' ')        qq.u = qq.v = NAN;
                int ts = 1;
-               if(!get(MGL_DISABLE_SCALE))     ts = sign(qq.v*nn.x-qq.u*nn.y)*sign(aa.v2-aa.v1);
+               if(!get(MGL_DISABLE_SCALE))     ts = mgl_sign(qq.v*nn.x-qq.u*nn.y)*mgl_sign(aa.v2-aa.v1);
                if(aa.ch=='c')  ts=inv?-1:1;    // use manual settings by inv argument
-//             else if(ux==0 && uy<0)  ts *= -1;
                if(aa.ch=='T')  ts *= -1;
                if(aa.pos=='T') ts *= -1;
                pos[0] = ts>0 ? 't':'T';
                if(ts>0 && tet && nn.x==0)      pos[2]='R';
-               text_plot(kk[i], aa.txt[i].text.c_str(), pos, -1, aa.sh+0.07,CDef,tet?false:true);
+               text_plot(kk[i], aa.txt[i].text.c_str(), pos, -1, aa.sh+0.1,CDef,tet?false:true);
        }
        delete []w;     delete []kk;
 }
@@ -646,7 +655,7 @@ char mglCanvas::GetLabelPos(mreal c, long kk, mglAxis &aa)
        mglPnt &qq = Pnt[kk];
 
        if(aa.ch=='c')  qq.u = qq.v = NAN;
-       if(!get(MGL_DISABLE_SCALE))     ts = sign(qq.v*nn.x-qq.u*nn.y)*sign(aa.v2-aa.v1);
+       if(!get(MGL_DISABLE_SCALE))     ts = mgl_sign(qq.v*nn.x-qq.u*nn.y)*mgl_sign(aa.v2-aa.v1);
        if(aa.ch=='T')  ts *= -1;
        if(aa.pos=='T') ts *= -1;
        return ts>0 ? 't':'T';
@@ -672,18 +681,42 @@ void mglCanvas::tick_draw(mglPoint o, mglPoint d1, mglPoint d2, int f)
 void mglCanvas::Grid(const char *dir, const char *pen, const char *opt)
 {
        SaveState(opt);
-       if(!dir || !dir[0])     dir="xyz";
+       bool at_tick=mglchr(dir,'!');
+       if(!mglchrs(dir,"xyz")) dir="xyz";
        AdjustTicks(dir,false);
        SetPenPal(pen);
 
        static int cgid=1;      StartGroup("AxisGrid",cgid++);
-       if(strchr(dir,'x'))     DrawGrid(ax);
-       if(strchr(dir,'y'))     DrawGrid(ay);
-       if(strchr(dir,'z'))     DrawGrid(az);
+       if(strchr(dir,'x'))     DrawGrid(ax,at_tick);
+       if(strchr(dir,'y'))     DrawGrid(ay,at_tick);
+       if(strchr(dir,'z'))     DrawGrid(az,at_tick);
        EndGroup();
 }
 //-----------------------------------------------------------------------------
-void mglCanvas::DrawGrid(mglAxis &aa)
+void MGL_NO_EXPORT mgl_drw_grid(HMGL gr, double val, const mglPoint &d, const mglPoint &oa, const mglPoint &ob, const mglPoint &da1, const mglPoint &db1, const mglPoint &da2, const mglPoint &db2)
+{
+       gr->Reserve(62);
+       mglPoint q,p;
+       q = oa+d*val;   p = q+da1;      // lines along 'a'
+       long k1 = gr->AddPnt(p), k2;
+       for(long j=1;j<31;j++)
+       {
+               mreal v = j/30.;
+               p = q+da1*(1-v)+da2*v;
+               k2 = k1;        k1 = gr->AddPnt(p);
+               gr->line_plot(k2,k1);
+       }
+       q = ob+d*val;   p = q+db1;      // lines along 'b'
+       k1 = gr->AddPnt(p);
+       for(long j=1;j<31;j++)
+       {
+               mreal v = j/30.;
+               p = q+db1*(1-v)+db2*v;
+               k2 = k1;        k1 = gr->AddPnt(p);
+               gr->line_plot(k2,k1);
+       }
+}
+void mglCanvas::DrawGrid(mglAxis &aa, bool at_tick)
 {
        mglPoint pp[8]={Min,Min,Min,Min,Max,Max,Max,Max},nan=mglPoint(NAN), oo[8], org=Min;
        pp[1].x=Max.x;  pp[2].y=Max.y;  pp[3].z=Max.z;
@@ -695,37 +728,38 @@ void mglCanvas::DrawGrid(mglAxis &aa)
                ScalePoint(&B,pp[i],nan,false);
                if(pp[i].z<zm)  {       zm=pp[i].z;     org=oo[i];      }
        }
-       if(Org.x==Org.x)        org.x = Org.x;
-       if(Org.y==Org.y)        org.y = Org.y;
-       if(Org.z==Org.z)        org.z = Org.z;
+       if(mgl_isnum(Org.x))    org.x = Org.x;
+       if(mgl_isnum(Org.y))    org.y = Org.y;
+       if(mgl_isnum(Org.z))    org.z = Org.z;
        mglPoint d=aa.dir, da1,da2,db1,db2,oa,ob, p,q;
        da1 = aa.a*(aa.a*Min);  da2 = aa.a*(aa.a*Max);
        db1 = aa.b*(aa.b*Min);  db2 = aa.b*(aa.b*Max);
        oa  = aa.b*(aa.b*org);  ob  = aa.a*(aa.a*org);
 
-       register long i,j,n=aa.txt.size(),k1,k2;
-       mreal v;
-
-       Reserve(62*n);
-       if(n>0) for(i=0;i<n;i++)
+       if(at_tick && aa.ds>0 && !get(MGL_NOSUBTICKS))
        {
-               q = oa+d*aa.txt[i].val; p = q+da1;      // lines along 'a'
-               k1 = AddPnt(&B, p,CDef);
-               for(j=1;j<31;j++)
-               {
-                       v = j/30.;
-                       p = q+da1*(1-v)+da2*v;
-                       k2 = k1;        k1 = AddPnt(&B, p,CDef);
-                       line_plot(k2,k1);
-               }
-               q = ob+d*aa.txt[i].val; p = q+db1;      // lines along 'b'
-               k1 = AddPnt(&B, p,CDef);
-               for(j=1;j<31;j++)
+               mreal v0 = mgl_isnan(aa.o) ? aa.v0 : aa.o;
+               if(aa.v2>aa.v1) v0 = v0 - aa.ds*floor((v0-aa.v1)/aa.ds+1e-3);
+               else                    v0 = v0 - aa.ds*floor((v0-aa.v2)/aa.ds+1e-3);
+               if(v0+aa.ds!=v0 && aa.v2+aa.ds!=aa.v2)
+                       for(mreal v=v0;(v-aa.v2)*(v-aa.v1)<=0;v+=aa.ds)
+                               mgl_drw_grid(this, v, d, oa, ob, da1, db1, da2, db2);
+       }
+       if(aa.dv)       at_tick = false;
+       long n=aa.txt.size();
+       if(n>0) for(long i=0;i<n;i++)
+       {
+               mreal v = aa.txt[i].val;
+               mgl_drw_grid(this, v, d, oa, ob, da1, db1, da2, db2);
+               if(at_tick)
                {
-                       v = j/30.;
-                       p = q+db1*(1-v)+db2*v;
-                       k2 = k1;        k1 = AddPnt(&B, p,CDef);
-                       line_plot(k2,k1);
+                       mreal u = fabs(v);
+                       if(aa.v2>aa.v1 && fabs(u-exp(M_LN10*floor(0.1+log10(u))))<0.01*u)
+                               for(long j=2;j<10 && v*j<aa.v2;j++)
+                                       mgl_drw_grid(this, v*j, d, oa, ob, da1, db1, da2, db2);
+                       if(aa.v2<aa.v1 && fabs(u-exp(M_LN10*floor(0.1+log10(u))))<0.01*u)
+                               for(long j=2;j<10 && v*j<aa.v1;j++)
+                                       mgl_drw_grid(this, v*j, d, oa, ob, da1, db1, da2, db2);
                }
        }
 }
@@ -918,6 +952,10 @@ void mglCanvas::Colorbar(const char *sch, mreal x, mreal y, mreal w, mreal h)
        if(mglchr(sch,'_'))     where = in?2:3;
        if(mglchr(sch,'A'))     {       Push(); Identity();     }
 
+       ac.stl.clear();
+       for(const char *s="+E0123456789-fF!";*s;s++)    if(mglchr(sch,*s))      ac.stl += *s;
+       AdjustTicks("c",mglchr(sch,'a'),ac.stl.c_str());
+
        long n=256, s = AddTexture(sch);
        mglData v(n);
        if(ac.d || Min.c*Max.c<=0)      v.Fill(Min.c,Max.c);
@@ -955,6 +993,10 @@ void mglCanvas::Colorbar(HCDT v, const char *sch, mreal x, mreal y, mreal w, mre
        if(mglchr(sch,'_'))     where = in?2:3;
        if(mglchr(sch,'A'))     {       Push(); Identity();     }
 
+       ac.stl.clear();
+       for(const char *s="+E0123456789-fF!";*s;s++)    if(mglchr(sch,*s))      ac.stl += *s;
+       AdjustTicks("c",mglchr(sch,'a'),ac.stl.c_str());
+
        mreal *c=new mreal[v->GetNx()];
        if(!mgl_have_color(sch))        sch = MGL_DEF_PAL;
        long s = AddTexture(sch);
@@ -970,8 +1012,7 @@ void mglCanvas::colorbar(HCDT vv, const mreal *c, int where, mreal x, mreal y, m
 {
        static int cgid=1;      StartGroup("Colorbar",cgid++);
        long n=vv->GetNx();
-       long n1,n2,n3,n4;
-       mreal d,s3=B.pf,ss=1/s3;                // NOTE: colorbar was wider ss=0.9;
+       mreal s3=B.pf,ss=1/s3;          // NOTE: colorbar was wider ss=0.9;
        mglPoint p1,p2;
        mglMatrix M=B1; M.pf=s3;        M.norot=true;
 
@@ -980,7 +1021,7 @@ void mglCanvas::colorbar(HCDT vv, const mreal *c, int where, mreal x, mreal y, m
        mask = MGL_SOLID_MASK;
        for(long i=0;i<n-1;i++)
        {
-               d = GetA(vv->v(i))*2-1;
+               mreal d = GetA(vv->v(i))*2-1;
                p1 = p2 = mglPoint((ss*d+1)*w+x, (ss*d+1)*h+y, s3);
                switch(where)
                {
@@ -989,7 +1030,7 @@ void mglCanvas::colorbar(HCDT vv, const mreal *c, int where, mreal x, mreal y, m
                        case 3: p1.y = y;       p2.y = y+0.1*h; break;
                        default:p1.x = x-0.1*w; p2.x = x;       break;
                }
-               n1 = AddPnt(&M, p1,c[i]);       n2 = AddPnt(&M, p2,c[i]);
+               long n1 = AddPnt(&M, p1,c[i]), n2 = AddPnt(&M, p2,c[i]);
                d = GetA(vv->v(i+1))*2-1;
                p1 = p2 = mglPoint((ss*d+1)*w+x, (ss*d+1)*h+y, s3);
                switch(where)
@@ -999,17 +1040,26 @@ void mglCanvas::colorbar(HCDT vv, const mreal *c, int where, mreal x, mreal y, m
                        case 3: p1.y = y;       p2.y = y+0.1*h; break;
                        default:p1.x = x-0.1*w; p2.x = x;       break;
                }
-               n3 = AddPnt(&M, p1,c[i]);       n4 = AddPnt(&M, p2,c[i]);
-               quad_plot(n1,n2,n3,n4);
+               quad_plot(n1,n2, AddPnt(&M, p1,c[i]), AddPnt(&M, p2,c[i]));
        }
        if(n<64)
        {
-               wchar_t buf[64];        ac.txt.clear();
-               for(long i=0;i<n;i++)
+               ac.txt.clear();
+               if(ac.t.empty())
+                       for(long i=0;i<n;i++)
+                       {
+                               register mreal d = vv->v(i);
+                               ac.AddLabel(mgl_ftoa(d,ac.stl.c_str()),d);
+                       }
+               else
                {
-                       d = vv->v(i);
-                       mglprintf(buf,64,ac.t.empty()?(fabs(d)<1 ? L"%.2g" :  L"%.3g"):ac.t.c_str(),d);
-                       ac.AddLabel(buf,d);
+                       wchar_t buf[64];
+                       for(long i=0;i<n;i++)
+                       {
+                               register mreal d = vv->v(i);
+                               mglprintf(buf,64,ac.t.c_str(),d);
+                               ac.AddLabel(buf,d);
+                       }
                }
        }
        else    {       UpdateAxis();   AdjustTicks(ac,fa!=0);  }
@@ -1017,7 +1067,7 @@ void mglCanvas::colorbar(HCDT vv, const mreal *c, int where, mreal x, mreal y, m
        SetPenPal(TickStl);
        for(size_t i=0;i<ac.txt.size();i++)
        {
-               d = ac.txt[i].val = GetA(ac.txt[i].val)*2-1;
+               mreal d = ac.txt[i].val = GetA(ac.txt[i].val)*2-1;
                p1 = p2 = mglPoint((ss*d+1)*w+x, (ss*d+1)*h+y, s3);
                switch(where)
                {
@@ -1026,14 +1076,13 @@ void mglCanvas::colorbar(HCDT vv, const mreal *c, int where, mreal x, mreal y, m
                        case 3: p1.y = y;       p2.y = y+0.1*h; break;
                        default:p1.x = x-0.1*w; p2.x = x;       break;
                }
-               n1 = AddPnt(&M, p1);    n2 = AddPnt(&M, p2);
-               line_plot(n1,n2);
+               line_plot(AddPnt(&M, p1), AddPnt(&M, p2));
        }
        ac.dir = mglPoint(ss*w,ss*h,0);
        ac.org = mglPoint(w+x,h+y,s3+1);
        switch(where)
        {
-               case 1: ac.dir.x = 0;   ac.org.x = x+0.1*w;     break;
+               case 1: ac.dir.x = 0;   ac.org.x = x+0.1*w-(get(MGL_ENABLE_RTEXT)?0:0.06);      break;
                case 2: ac.dir.y = 0;   ac.org.y = y-0.1*h;     break;
                case 3: ac.dir.y = 0;   ac.org.y = y+0.1*h;     break;
                default:ac.dir.x = 0;   ac.org.x = x-0.1*w;     break;
index 06865521dafc4ddedc03d74393018b482fc6f1a7..9c5cf493fa1a534e8d13b3330625afe933a78528 100644 (file)
@@ -89,7 +89,7 @@ void MGL_EXPORT mgl_strlwr(char *str)
 //-----------------------------------------------------------------------------\r
 mglBase::mglBase()\r
 {\r
-       Flag=0; saved=false;\r
+       Flag=0; saved=false;    PrmInd=NULL;\r
 #if MGL_HAVE_PTHREAD\r
        pthread_mutex_init(&mutexPnt,0);\r
        pthread_mutex_init(&mutexTxt,0);\r
@@ -102,24 +102,40 @@ mglBase::mglBase()
        pthread_mutex_init(&mutexGlf,0);\r
        pthread_mutex_init(&mutexAct,0);\r
        pthread_mutex_init(&mutexDrw,0);\r
+       pthread_mutex_init(&mutexClf,0);\r
+       Pnt.set_mutex(&mutexClf);\r
+       Prm.set_mutex(&mutexClf);\r
+       Sub.set_mutex(&mutexClf);\r
+       Txt.set_mutex(&mutexClf);\r
+#endif\r
+#if MGL_HAVE_OMP\r
+       omp_init_lock(&lockClf);\r
+       Pnt.set_mutex(&lockClf);\r
+       Prm.set_mutex(&lockClf);\r
+       Sub.set_mutex(&lockClf);\r
+       Txt.set_mutex(&lockClf);\r
 #endif\r
        fnt=0;  *FontDef=0;     fx=fy=fz=fa=fc=0;\r
        AMin = mglPoint(0,0,0,0);       AMax = mglPoint(1,1,1,1);\r
 \r
        InUse = 1;      SetQuality();   FaceNum = 0;\r
        // Always create default palette txt[0] and default scheme txt[1]\r
-#pragma omp critical(txt)\r
-       {\r
-               mglTexture t1(MGL_DEF_PAL,-1), t2(MGL_DEF_SCH,1);\r
-               Txt.reserve(3);\r
-               MGL_PUSH(Txt,t1,mutexTxt);\r
-               MGL_PUSH(Txt,t2,mutexTxt);\r
-       }\r
-       memcpy(last_style,"{k5}-1\0",8);\r
+       mglTexture t1(MGL_DEF_PAL,-1), t2(MGL_DEF_SCH,1);\r
+       Txt.reserve(3);\r
+       MGL_PUSH(Txt,t1,mutexTxt);\r
+       MGL_PUSH(Txt,t2,mutexTxt);\r
+\r
+       strcpy(last_style,"__1 {dFFFF}k\0");\r
        MinS=mglPoint(-1,-1,-1);        MaxS=mglPoint(1,1,1);\r
        fnt = new mglFont;      fnt->gr = this; PrevState=NAN;\r
 }\r
-mglBase::~mglBase()    {       ClearEq();      delete fnt;     }\r
+mglBase::~mglBase()\r
+{\r
+       ClearEq();      ClearPrmInd();  delete fnt;\r
+#if MGL_HAVE_OMP\r
+       omp_destroy_lock(&lockClf);\r
+#endif\r
+}\r
 //-----------------------------------------------------------------------------\r
 void mglBase::RestoreFont()    {       fnt->Restore(); }\r
 void mglBase::LoadFont(const char *name, const char *path)\r
@@ -145,7 +161,7 @@ void mglBase::AddActive(long k,int n)
 }\r
 //-----------------------------------------------------------------------------\r
 mreal mglBase::GetRatio() const        {       return 1;       }\r
-int mglBase::GetWidth() const  {       return 1;       }\r
+int mglBase::GetWidth()  const {       return 1;       }\r
 int mglBase::GetHeight() const {       return 1;       }\r
 //-----------------------------------------------------------------------------\r
 void mglBase::StartGroup(const char *name, int id)\r
@@ -177,17 +193,20 @@ const char *mglWarn[mglWarnEnd] = {"data dimension(s) is incompatible",   //mglWar
                                                                "There are too long string in script",  //mglScrLong\r
                                                                "There are unbalanced ' in script"};    //mglScrStr\r
 //-----------------------------------------------------------------------------\r
+extern bool mglPrintWarn;\r
 void mglBase::SetWarn(int code, const char *who)\r
 {\r
+       std::string warn;\r
        WarnCode = code>0 ? code:0;\r
        if(code>0 && code<mglWarnEnd)\r
        {\r
-               if(who && *who) Mess = Mess+"\n"+who+": ";\r
-               else Mess += "\n";\r
-               Mess = Mess+mglWarn[code-1];\r
+               if(who && *who) warn = std::string(who)+": ";\r
+               warn = warn+mglWarn[code-1];\r
        }\r
        else if(!code)  Mess="";\r
-       else if(who && *who)    Mess = Mess+(code==-2?"":"\n")+who;\r
+       else if(who && *who)    warn = who;\r
+       if(mglPrintWarn && !warn.empty())       fprintf(stderr,"MathGL message - %s\n",warn.c_str());\r
+       if(code && !warn.empty())       Mess = Mess+(code==-2?"":"\n")+warn;\r
        LoadState();\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -197,10 +216,13 @@ void mglGlyph::Create(long Nt, long Nl)
 {\r
        if(Nt<0 || Nl<0)        return;\r
        nt=Nt;  nl=Nl;\r
-       if(trig)        delete []trig;\r
-       trig = nt>0?new short[6*nt]:0;\r
-       if(line)        delete []line;\r
-       line = nl>0?new short[2*nl]:0;\r
+#pragma omp critical(glf_create)\r
+       {\r
+               if(trig)        delete []trig;\r
+               trig = nt>0?new short[6*nt]:0;\r
+               if(line)        delete []line;\r
+               line = nl>0?new short[2*nl]:0;\r
+       }\r
 }\r
 //-----------------------------------------------------------------------------\r
 bool mglGlyph::operator==(const mglGlyph &g)\r
@@ -219,7 +241,8 @@ long mglBase::AddGlyph(int s, long j)
        memcpy(g.trig, fnt->GetTr(s,j), 6*g.nt*sizeof(short));\r
        memcpy(g.line, fnt->GetLn(s,j), 2*g.nl*sizeof(short));\r
        // now let find the similar glyph\r
-       for(size_t i=0;i<Glf.size();i++)        if(g==Glf[i])   return i;\r
+       for(size_t i=0;i<Glf.size();i++)\r
+               if(g!=Glf[i])   continue;       else    return i;\r
        // if no one then let add it\r
        long k;\r
 #pragma omp critical(glf)\r
@@ -233,7 +256,7 @@ long mglBase::AddPnt(const mglMatrix *mat, mglPoint p, mreal c, mglPoint n, mrea
        // scl=0 -- no scaling\r
        // scl&1 -- usual scaling\r
        // scl&2 -- disable NAN at scaling\r
-       // scl&4 -- ???\r
+       // scl&4 -- disable NAN for normales if no light\r
        // scl&8 -- bypass palette for enabling alpha\r
        if(mgl_isnan(c) || mgl_isnan(a))        return -1;\r
        bool norefr = mgl_isnan(n.x) && mgl_isnan(n.y) && !mgl_isnan(n.z);\r
@@ -281,7 +304,7 @@ long mglBase::CopyNtoC(long from, mreal c)
 {\r
        if(from<0)      return -1;\r
        mglPnt p=Pnt[from];\r
-       if(mgl_isnum(c))        {       p.c=c;  p.t=0;  Txt[long(c)].GetC(c,0,p);       }\r
+       if(mgl_isnum(c))        {       p.c=c;  p.t=1;  Txt[long(c)].GetC(c,0,p);       p.a=1;  }\r
        long k;\r
 #pragma omp critical(pnt)\r
        {k=Pnt.size();  MGL_PUSH(Pnt,p,mutexPnt);}      return k;\r
@@ -427,17 +450,21 @@ bool mglBase::ScalePoint(const mglMatrix *, mglPoint &p, mglPoint &n, bool use_n
                if(z2>Max.z)    {z=Max.z;       n=mglPoint(0,0,1);}\r
        }\r
 \r
-       x1=x;   y1=y;   z1=z;   x2=y2=z2=1;\r
-       if(fx)  {       x1 = fx->Calc(x,y,z);   x2 = fx->CalcD('x',x,y,z);      }\r
-       if(fy)  {       y1 = fy->Calc(x,y,z);   y2 = fy->CalcD('y',x,y,z);      }\r
-       if(fz)  {       z1 = fz->Calc(x,y,z);   z2 = fz->CalcD('z',x,y,z);      }\r
+       x1=x;   y1=y;   z1=z;\r
+       register mreal xx=1,xy=0,xz=0,yx=0,yy=1,yz=0,zx=0,zy=0,zz=1;\r
+       if(fx)  {       x1 = fx->Calc(x,y,z);   xx = fx->CalcD('x',x,y,z);      xy = fx->CalcD('y',x,y,z);      xz = fx->CalcD('z',x,y,z);      }\r
+       if(fy)  {       y1 = fy->Calc(x,y,z);   yx = fy->CalcD('x',x,y,z);      yy = fy->CalcD('y',x,y,z);      yz = fy->CalcD('z',x,y,z);      }\r
+       if(fz)  {       z1 = fz->Calc(x,y,z);   zx = fz->CalcD('x',x,y,z);      zy = fz->CalcD('y',x,y,z);      zz = fz->CalcD('z',x,y,z);      }\r
        if(mgl_isnan(x1) || mgl_isnan(y1) || mgl_isnan(z1))     {       x=NAN;  return false;   }\r
 \r
-       register mreal d;       // TODO: should I update normale for infinite light source (x=NAN)?!?\r
-       d = 1/(FMax.x - FMin.x);        x = (2*x1 - FMin.x - FMax.x)*d; x2 *= 2*d;\r
-       d = 1/(FMax.y - FMin.y);        y = (2*y1 - FMin.y - FMax.y)*d; y2 *= 2*d;\r
-       d = 1/(FMax.z - FMin.z);        z = (2*z1 - FMin.z - FMax.z)*d; z2 *= 2*d;\r
-       n.x *= y2*z2;   n.y *= x2*z2;   n.z *= x2*y2;\r
+       register mreal d;\r
+       d = 1/(FMax.x - FMin.x);        x = (2*x1 - FMin.x - FMax.x)*d; xx /= d;        xy /= d;        xz /= d;\r
+       d = 1/(FMax.y - FMin.y);        y = (2*y1 - FMin.y - FMax.y)*d; yx /= d;        yy /= d;        yz /= d;\r
+       d = 1/(FMax.z - FMin.z);        z = (2*z1 - FMin.z - FMax.z)*d; zx /= d;        zy /= d;        zz /= d;\r
+       register mreal nx=n.x, ny=n.y, nz=n.z;\r
+       n.x = nx*xx+ny*xy+nz*xz;\r
+       n.y = nx*yx+ny*yy+nz*yz;\r
+       n.z = nx*zx+ny*zy+nz*zz;\r
        if((TernAxis&3)==1)     // usual ternary axis\r
        {\r
                if(x+y>0)\r
@@ -533,8 +560,8 @@ void mglBase::CRange(mreal v1,mreal v2,bool add)
        if(v1==v2 && !add)      return;\r
        if(!add)\r
        {\r
-               if(v1==v1)      Min.c = v1;     \r
-               if(v2==v2)      Max.c = v2;             \r
+               if(mgl_isnum(v1))       Min.c = v1;\r
+               if(mgl_isnum(v2))       Max.c = v2;\r
        }\r
        else if(Min.c<Max.c)\r
        {\r
@@ -568,8 +595,8 @@ void mglBase::XRange(mreal v1,mreal v2,bool add)
        if(v1==v2 && !add)      return;\r
        if(!add)\r
        {\r
-               if(v1==v1)      Min.x = v1;     \r
-               if(v2==v2)      Max.x = v2;             \r
+               if(mgl_isnum(v1))       Min.x = v1;\r
+               if(mgl_isnum(v2))       Max.x = v2;\r
        }\r
        else if(Min.x<Max.x)\r
        {\r
@@ -603,8 +630,8 @@ void mglBase::YRange(mreal v1,mreal v2,bool add)
        if(v1==v2 && !add)      return;\r
        if(!add)\r
        {\r
-               if(v1==v1)      Min.y = v1;     \r
-               if(v2==v2)      Max.y = v2;             \r
+               if(mgl_isnum(v1))       Min.y = v1;\r
+               if(mgl_isnum(v2))       Max.y = v2;\r
        }\r
        else if(Min.y<Max.y)\r
        {\r
@@ -639,8 +666,8 @@ void mglBase::ZRange(mreal v1,mreal v2,bool add)
        if(v1==v2 && !add)      return;\r
        if(!add)\r
        {\r
-               if(v1==v1)      Min.z = v1;     \r
-               if(v2==v2)      Max.z = v2;             \r
+               if(mgl_isnum(v1))       Min.z = v1;\r
+               if(mgl_isnum(v2))       Max.z = v2;\r
        }\r
        else if(Min.z<Max.z)\r
        {\r
@@ -708,8 +735,11 @@ void mglBase::SetFunc(const char *EqX,const char *EqY,const char *EqZ,const char
 //-----------------------------------------------------------------------------\r
 void mglBase::CutOff(const char *EqC)\r
 {\r
-       if(fc)  delete fc;\r
-       if(EqC && EqC[0])       fc = new mglFormula(EqC);       else    fc = 0;\r
+#pragma omp critical(eq)\r
+       {\r
+               if(fc)  delete fc;\r
+               fc = (EqC && EqC[0])?new mglFormula(EqC):0;\r
+       }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglBase::SetCoor(int how)\r
@@ -749,9 +779,12 @@ void mglBase::SetCoor(int how)
 //-----------------------------------------------------------------------------\r
 void mglBase::ClearEq()\r
 {\r
-       if(fx)  delete fx;      if(fy)  delete fy;      if(fz)  delete fz;\r
-       if(fa)  delete fa;      if(fc)  delete fc;\r
-       fx = fy = fz = fc = fa = 0;\r
+#pragma omp critical(eq)\r
+       {\r
+               if(fx)  delete fx;      if(fy)  delete fy;      if(fz)  delete fz;\r
+               if(fa)  delete fa;      if(fc)  delete fc;\r
+               fx = fy = fz = fc = fa = 0;\r
+       }\r
        RecalcBorder();\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -795,24 +828,23 @@ void mglTexture::Set(const char *s, int smooth, mreal alpha)
        strncpy(Sch,s,259);     Smooth=smooth;  Alpha=alpha;\r
 \r
        register long i,j=0,m=0,l=strlen(s);\r
-       const char *dig = "0123456789abcdefABCDEF";\r
        bool map = smooth==2 || mglchr(s,'%'), sm = smooth>=0 && !strchr(s,'|');        // Use mapping, smoothed colors\r
-       for(i=0;i<l;i++)                // find number of colors\r
+       for(i=n=0;i<l;i++)              // find number of colors\r
        {\r
                if(smooth>=0 && s[i]==':' && j<1)       break;\r
-               if(s[i]=='[')   j++;    if(s[i]==']')   j--;\r
+               if(s[i]=='{' && strchr(MGL_COLORS"x",s[i+1]) && j<1)    n++;\r
+               if(s[i]=='[' || s[i]=='{')      j++;    if(s[i]==']' || s[i]=='}')      j--;\r
                if(strchr(MGL_COLORS,s[i]) && j<1)      n++;\r
-               if(s[i]=='x' && i>0 && s[i-1]=='{' && j<1)      n++;\r
 //             if(smooth && s[i]==':') break;  // NOTE: should use []\r
        }\r
        if(!n)\r
        {\r
-               if((strchr(s,'|') || strchr(s,'!')) && !smooth) // sharp colors\r
+               if(strchr(s,'|') && !smooth)    // sharp colors\r
                {       n=l=6;  s=MGL_DEF_SCH;  sm = false;     }\r
                else if(smooth==0)              // none colors but color scheme\r
                {       n=l=6;  s=MGL_DEF_SCH;  }\r
-               else    return;\r
        }\r
+       if(n<=0)        return;\r
        bool man=sm;\r
        mglColor *c = new mglColor[2*n];                // Colors itself\r
        mreal *val = new mreal[n];\r
@@ -826,20 +858,18 @@ void mglTexture::Set(const char *s, int smooth, mreal alpha)
                        if(m>0 && s[i+1]>'0' && s[i+1]<='9')// ext color\r
                        {       c[2*n] = mglColor(s[i],(s[i+1]-'0')/5.f);       i++;    }\r
                        else    c[2*n] = mglColor(s[i]);        // usual color\r
-                       val[n]=-1;      n++;\r
+                       val[n]=-1;      c[2*n].a = -1;  n++;\r
                }\r
                if(s[i]=='x' && i>0 && s[i-1]=='{' && j<1)      // {xRRGGBB,val} format, where val in [0,1]\r
                {\r
-                       if(strchr(dig,s[i+1]) && strchr(dig,s[i+2]) && strchr(dig,s[i+3]) && strchr(dig,s[i+4]) && strchr(dig,s[i+5]) && strchr(dig,s[i+6]))\r
-                       {\r
-                               char ss[3]="00";        c[2*n].a = 1;\r
-                               ss[0] = s[i+1]; ss[1] = s[i+2]; c[2*n].r = strtol(ss,0,16)/255.;\r
-                               ss[0] = s[i+3]; ss[1] = s[i+4]; c[2*n].g = strtol(ss,0,16)/255.;\r
-                               ss[0] = s[i+5]; ss[1] = s[i+6]; c[2*n].b = strtol(ss,0,16)/255.;\r
-                               if(strchr(dig,s[i+7]) && strchr(dig,s[i+8]))\r
-                               {       ss[0] = s[i+7]; ss[1] = s[i+8]; c[2*n].a = strtol(ss,0,16)/255.;        i+=2;   }\r
-                               val[n]=-1;      i+=6;   n++;\r
-                       }\r
+                       uint32_t id = strtoul(s+1+i,0,16);\r
+                       if(memchr(s+i+1,'}',8) || memchr(s+i+1,',',8))  c[2*n].a = -1;\r
+                       else    {       c[2*n].a = (id%256)/255.;       id /= 256;      }\r
+                       c[2*n].b = (id%256)/255.;       id /= 256;\r
+                       c[2*n].g = (id%256)/255.;       id /= 256;\r
+                       c[2*n].r = (id%256)/255.;\r
+                       while(strchr("0123456789abcdefABCDEFx",s[i]))   i++;\r
+                       val[n]=-1;      n++;    i--;\r
                }\r
                if(s[i]==',' && m>0 && j<1 && n>0)\r
                        val[n-1] = atof(s+i+1);\r
@@ -848,7 +878,11 @@ void mglTexture::Set(const char *s, int smooth, mreal alpha)
                {       man=false;      alpha = 0.1*(s[i+1]-'0');       i++;    }\r
        }\r
        for(long i=0;i<n;i++)   // default texture\r
-       {       c[2*i+1]=c[2*i];        c[2*i].a=man?0:alpha;   c[2*i+1].a=alpha;       }\r
+       {\r
+               if(c[2*i].a<0)  c[2*i].a=alpha;\r
+               c[2*i+1]=c[2*i];\r
+               if(man) c[2*i].a=0;\r
+       }\r
        if(map && sm)           // map texture\r
        {\r
                if(n==2)\r
@@ -878,13 +912,11 @@ void mglTexture::Set(const char *s, int smooth, mreal alpha)
        }\r
        // fill texture itself\r
        mreal v=sm?(n-1)/255.:n/256.;\r
-       if(!sm)\r
-//#pragma omp parallel for     // remove parallel here due to possible race conditions for v<1\r
-               for(long i=0;i<256;i++)\r
-               {\r
-                       register long j = 2*long(v*i);  //u-=j;\r
-                       col[2*i] = c[j];        col[2*i+1] = c[j+1];\r
-               }\r
+       if(!sm) for(long i=0;i<256;i++)\r
+       {\r
+               register long j = 2*long(v*i);  //u-=j;\r
+               col[2*i] = c[j];        col[2*i+1] = c[j+1];\r
+       }\r
        else    for(i=i1=0;i<256;i++)\r
        {\r
                register mreal u = v*i; j = long(u);    //u-=j;\r
@@ -906,25 +938,20 @@ mglColor mglTexture::GetC(mreal u,mreal v) const
 {\r
        u -= long(u);\r
        register long i=long(255*u);    u = u*255-i;\r
-       const mglColor *s=col+2*i;      //mglColor p;\r
+       const mglColor *s=col+2*i;\r
        return (s[0]*(1-u)+s[2]*u)*(1-v) + (s[1]*(1-u)+s[3]*u)*v;\r
-//     p.r = (s[0].r*(1-u)+s[2].r*u)*(1-v) + (s[1].r*(1-u)+s[3].r*u)*v;\r
-//     p.g = (s[0].g*(1-u)+s[2].g*u)*(1-v) + (s[1].g*(1-u)+s[3].g*u)*v;\r
-//     p.b = (s[0].b*(1-u)+s[2].b*u)*(1-v) + (s[1].b*(1-u)+s[3].b*u)*v;\r
-//     p.a = (s[0].a*(1-u)+s[2].a*u)*(1-v) + (s[1].a*(1-u)+s[3].a*u)*v;\r
-//     return p;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglTexture::GetC(mreal u,mreal v,mglPnt &p) const\r
 {\r
        u -= long(u);\r
        register long i=long(255*u);    u = u*255-i;\r
-       const mglColor *s=col+2*i;\r
-       p.r = (s[0].r*(1-u)+s[2].r*u)*(1-v) + (s[1].r*(1-u)+s[3].r*u)*v;\r
-       p.g = (s[0].g*(1-u)+s[2].g*u)*(1-v) + (s[1].g*(1-u)+s[3].g*u)*v;\r
-       p.b = (s[0].b*(1-u)+s[2].b*u)*(1-v) + (s[1].b*(1-u)+s[3].b*u)*v;\r
-       p.a = (s[0].a*(1-u)+s[2].a*u)*(1-v) + (s[1].a*(1-u)+s[3].a*u)*v;\r
-//     p.a = (s[0].a*(1-u)+s[2].a*u)*v + (s[1].a*(1-u)+s[3].a*u)*(1-v);        // for alpha use inverted\r
+       const mglColor &s0=col[2*i], &s1=col[2*i+1], &s2=col[2*i+2], &s3=col[2*i+3];\r
+       p.r = (s0.r*(1-u)+s2.r*u)*(1-v) + (s1.r*(1-u)+s3.r*u)*v;\r
+       p.g = (s0.g*(1-u)+s2.g*u)*(1-v) + (s1.g*(1-u)+s3.g*u)*v;\r
+       p.b = (s0.b*(1-u)+s2.b*u)*(1-v) + (s1.b*(1-u)+s3.b*u)*v;\r
+       p.a = (s0.a*(1-u)+s2.a*u)*(1-v) + (s1.a*(1-u)+s3.a*u)*v;\r
+//     p.a = (s0.a*(1-u)+s2.a*u)*v + (s1.a*(1-u)+s3.a*u)*(1-v);        // for alpha use inverted\r
 }\r
 //-----------------------------------------------------------------------------\r
 long mglBase::AddTexture(const char *cols, int smooth)\r
@@ -934,7 +961,8 @@ long mglBase::AddTexture(const char *cols, int smooth)
        if(t.n==0)      return smooth<0 ? 0:1;\r
        if(smooth<0)    CurrPal=0;\r
        // check if already exist\r
-       for(size_t i=0;i<Txt.size();i++)        if(t.IsSame(Txt[i]))    return i;\r
+       for(size_t i=0;i<Txt.size();i++)\r
+               if(!t.IsSame(Txt[i]))   continue;       else    return i;\r
        // create new one\r
        long k;\r
 #pragma omp critical(txt)\r
@@ -950,7 +978,6 @@ mreal mglBase::AddTexture(mglColor c)
                        return i+j/255.;\r
        // add new texture\r
        mglTexture t;\r
-#pragma omp parallel for\r
        for(long i=0;i<MGL_TEXTURE_COLOURS;i++) t.col[i]=c;\r
        long k;\r
 #pragma omp critical(txt)\r
@@ -963,23 +990,10 @@ mreal mglBase::NextColor(long &id)
 {\r
        long i=abs(id)/256, n=Txt[i].n, p=abs(id)&0xff;\r
        if(id>=0)       {       p=(p+1)%n;      id = 256*i+p;   }\r
-       mglColor c = Txt[i].col[int(MGL_TEXTURE_COLOURS*(p+0.5)/n)];\r
-       mreal dif, dmin=1;\r
-       // try to find closest color\r
-       for(long j=0;mglColorIds[j].id;j++)     for(long k=1;k<10;k++)\r
-       {\r
-               mglColor cc;    cc.Set(mglColorIds[j].col,k/5.);\r
-               dif = (c-cc).NormS();\r
-               if(dif<dmin)\r
-               {\r
-                       last_style[1] = mglColorIds[j].id;\r
-                       last_style[2] = k+'0';\r
-                       dmin=dif;\r
-               }\r
-       }\r
+       CDef = i + (n>0 ? (p+0.5)/n : 0);       CurrPal++;\r
+       sprintf(last_style+11,"{&%g}",CDef);\r
        if(!leg_str.empty())\r
        {       AddLegend(leg_str.c_str(),last_style);  leg_str.clear();        }\r
-       CDef = i + (n>0 ? (p+0.5)/n : 0);       CurrPal++;\r
        return CDef;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -987,10 +1001,12 @@ mreal mglBase::NextColor(long id, long sh)
 {\r
        long i=abs(id)/256, n=Txt[i].n, p=abs(id)&0xff;\r
        if(id>=0)       p=(p+sh)%n;\r
-       return i + (n>0 ? (p+0.5)/n : 0);\r
+       mreal cc = i + (n>0 ? (p+0.5)/n : 0);\r
+       sprintf(last_style+11,"{&%g}",cc);\r
+       return cc;\r
 }\r
 //-----------------------------------------------------------------------------\r
-const char *mglchrs(const char *str, const char *chr)\r
+MGL_EXPORT_PURE const char *mglchrs(const char *str, const char *chr)\r
 {\r
        if(!str || !str[0] || !chr || !chr[0])  return NULL;\r
        size_t l=strlen(chr);\r
@@ -1002,7 +1018,7 @@ const char *mglchrs(const char *str, const char *chr)
        return NULL;\r
 }\r
 //-----------------------------------------------------------------------------\r
-const char *mglchr(const char *str, char ch)\r
+MGL_EXPORT_PURE const char *mglchr(const char *str, char ch)\r
 {\r
        if(!str || !str[0])     return NULL;\r
        size_t l=strlen(str),k=0;\r
@@ -1020,50 +1036,67 @@ char mglBase::SetPenPal(const char *p, long *Id, bool pal)
 {\r
        char mk=0;\r
        PDef = 0xffff;  // reset to solid line\r
-       memcpy(last_style,"{k5}-1\0",8);\r
+       strcpy(last_style,"__1 {dFFFF}k\0");\r
 \r
+       const char *s;\r
        Arrow1 = Arrow2 = 0;    PenWidth = 1;\r
        if(p && *p)\r
        {\r
 //             const char *col = "wkrgbcymhRGBCYMHWlenuqpLENUQP";\r
                unsigned val[8] = {0x0000, 0xffff, 0x00ff, 0x0f0f, 0x1111, 0x087f, 0x2727, 0x3333};\r
-               const char *stl = " -|;:ji=", *s;\r
+               const char *stl = " -|;:ji=";\r
                const char *mrk = "*o+xsd.^v<>";\r
                const char *MRK = "YOPXSDCTVLR";\r
                const char *wdh = "123456789";\r
-               const char *arr = "AKDTVISO_";\r
+               const char *arr = "AKDTVISOX_";\r
                long m=0;\r
                size_t l=strlen(p);\r
                for(size_t i=0;i<l;i++)\r
                {\r
                        if(p[i]=='{')   m++;    if(p[i]=='}')   m--;\r
+                       if(m>0 && p[i]=='d')    PDef = strtol(p+i+1,0,16);\r
                        if(m>0) continue;\r
                        s = mglchr(stl,p[i]);\r
-                       if(s)   {       PDef = val[s-stl];      last_style[4]=p[i];     }\r
-                       else if(mglchr(mrk,p[i]))       mk = p[i];\r
+                       if(s)\r
+                       {       PDef = val[s-stl];      sprintf(last_style+6,"%04x",PDef);      last_style[10]='}';     }\r
+                       else if(mglchr(mrk,p[i]))\r
+                       {       mk = p[i];      last_style[3] = mk;     }\r
                        else if(mglchr(wdh,p[i]))\r
-                       {       last_style[5] = p[i];   PenWidth = p[i]-'0';    }\r
+                       {       PenWidth = p[i]-'0';    last_style[2] = p[i];   }\r
                        else if(mglchr(arr,p[i]))\r
                        {\r
                                if(!Arrow2)     Arrow2 = p[i];\r
                                else    Arrow1 = p[i];\r
                        }\r
                }\r
-               if(Arrow1=='_') Arrow1=0;       if(Arrow2=='_') Arrow2=0;\r
+               if(!Arrow1)     Arrow1='_';             if(!Arrow2)     Arrow2='_';\r
                if(mglchr(p,'#'))\r
                {\r
                        s = mglchr(mrk,mk);\r
-                       if(s)   mk = MRK[s-mrk];\r
+                       if(s)\r
+                       {       mk = MRK[s-mrk];        last_style[3] = mk;     }\r
                }\r
+               if((s=strstr(p,"{&"))!=0)\r
+               {       mk = last_style[3] = p[3];      strcpy(last_style+11,s);        }\r
+               last_style[0] = Arrow1; last_style[1] = Arrow2;\r
        }\r
        if(pal)\r
        {\r
-               last_style[6]=mk;\r
-               long tt, n;\r
-               tt = AddTexture(p,-1);  n=Txt[tt].n;\r
-               CDef = tt+((n+CurrPal-1)%n+0.5)/n;\r
-               if(Id)  *Id=long(tt)*256+(n+CurrPal-1)%n;\r
+               if((s=strstr(p,"{&"))!=0)\r
+               {\r
+                       CDef = atof(s+2);\r
+//                     if(Id)  *Id=long(tt)*256+(n+CurrPal-1)%n;\r
+               }\r
+               else\r
+               {\r
+                       long tt, n;\r
+                       tt = AddTexture(p,-1);  n=Txt[tt].n;\r
+                       CDef = tt+((n+CurrPal-1)%n+0.5)/n;\r
+                       if(Id)  *Id=long(tt)*256+(n+CurrPal-1)%n;\r
+                       sprintf(last_style+11,"{&%g}",CDef);\r
+               }\r
        }\r
+       if(Arrow1=='_') Arrow1=0;       if(Arrow2=='_') Arrow2=0;\r
        return mk;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1088,6 +1121,7 @@ void mglBase::SetMask(const char *p)
                for(long i=0;i<l;i++)\r
                {\r
                        if(p[i]=='{')   m++;    if(p[i]=='}')   m--;\r
+                       if(m>0 && p[i]=='s')    mask = strtoull(p+i+1,0,16);\r
                        if(m>0) continue;\r
                        if(p[i]==':')   break;\r
                        s = mglchr(msk, p[i]);\r
@@ -1156,7 +1190,7 @@ void mglBase::vect_plot(long p1, long p2, mreal s)
        line_plot(p1,p2);       line_plot(n1,p2);       line_plot(p2,n2);\r
 }\r
 //-----------------------------------------------------------------------------\r
-int mglFindArg(const char *str)\r
+int MGL_LOCAL_PURE mglFindArg(const char *str)\r
 {\r
        long l=0,k=0,len=strlen(str);\r
        for(long i=0;i<len;i++)\r
@@ -1185,8 +1219,7 @@ mreal mglBase::SaveState(const char *opt)
        MNS=MeshNum;    CSS=Flag;       LSS=AmbBr;\r
        MinS=Min;               MaxS=Max;       saved=true;\r
        // parse option\r
-       char *qi=mgl_strdup(opt),*q=qi, *s,*a,*b,*c;\r
-       long n;\r
+       char *qi=mgl_strdup(opt),*q=qi, *s;\r
        mgl_strtrim(q);\r
        // NOTE: not consider '#' inside legend entry !!!\r
        s=strchr(q,'#');        if(s)   *s=0;\r
@@ -1195,9 +1228,9 @@ mreal mglBase::SaveState(const char *opt)
        {\r
                s=q;    q=strchr(s,';');\r
                if(q)   {       *q=0;   q++;    }\r
-               mgl_strtrim(s);         a=s;\r
-               n=mglFindArg(s);        if(n>0) {       s[n]=0;         s=s+n+1;        }\r
-               mgl_strtrim(a);         b=s;\r
+               mgl_strtrim(s);         char *a=s;\r
+               long n=mglFindArg(s);   if(n>0) {       s[n]=0;         s=s+n+1;        }\r
+               mgl_strtrim(a);         char *b=s;\r
                n=mglFindArg(s);        if(n>0) {       s[n]=0;         s=s+n+1;        }\r
                mgl_strtrim(b);\r
 \r
@@ -1205,7 +1238,7 @@ mreal mglBase::SaveState(const char *opt)
                if(!strcmp(b,"on"))     ff=1;\r
                if(!strcmp(a+1,"range"))\r
                {\r
-                       n=mglFindArg(s);        c=s;\r
+                       n=mglFindArg(s);        char *c=s;\r
                        if(n>0) {       s[n]=0; s=s+n+1;        }\r
                        mgl_strtrim(c);         ss = atof(c);\r
                        if(a[0]=='x')           {       Min.x=ff;       Max.x=ss;       }\r
@@ -1254,7 +1287,7 @@ bool MGL_EXPORT mgl_check_dim2(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const ch
 //     if(!gr || !x || !y || !z)       return true;            // if data is absent then should be segfault!!!\r
        register long n=z->GetNx(),m=z->GetNy();\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,name);   return true;    }\r
-       if(a && n*m*z->GetNz()!=a->GetNx()*a->GetNy()*a->GetNz())\r
+       if(a && z->GetNN()!=a->GetNN())\r
        {       gr->SetWarn(mglWarnDim,name);   return true;    }\r
        if(less)\r
        {\r
@@ -1318,9 +1351,9 @@ bool MGL_EXPORT mgl_check_dim3(HMGL gr, bool both, HCDT x, HCDT y, HCDT z, HCDT
        register long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
        if(n<2 || m<2 || l<2)\r
        {       gr->SetWarn(mglWarnLow,name);   return true;    }\r
-       if(!(both || (x->GetNx()==n && y->GetNx()==m && z->GetNx()==l)))\r
+       if(!both && (x->GetNx()!=n || y->GetNx()!=m || z->GetNx()!=l))\r
        {       gr->SetWarn(mglWarnDim,name);   return true;    }\r
-       if(b && b->GetNx()*b->GetNy()*b->GetNz()!=n*m*l)\r
+       if(b && b->GetNN()!=n*m*l)\r
        {       gr->SetWarn(mglWarnDim,name);   return true;    }\r
        return false;\r
 }\r
@@ -1335,20 +1368,26 @@ bool MGL_EXPORT mgl_check_trig(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT
        return false;\r
 }\r
 //-----------------------------------------------------------------------------\r
+bool MGL_EXPORT mgl_isnboth(HCDT x, HCDT y, HCDT z, HCDT a)\r
+{\r
+       register long n=a->GetNN();\r
+       return x->GetNN()!=n || y->GetNN()!=n || z->GetNN()!=n;\r
+}\r
+//-----------------------------------------------------------------------------\r
 bool MGL_EXPORT mgl_isboth(HCDT x, HCDT y, HCDT z, HCDT a)\r
 {\r
-       register long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
-       return x->GetNx()*x->GetNy()*x->GetNz()==n*m*l && y->GetNx()*y->GetNy()*y->GetNz()==n*m*l && z->GetNx()*z->GetNy()*z->GetNz()==n*m*l;\r
+       register long n=a->GetNN();\r
+       return x->GetNN()==n && y->GetNN()==n && z->GetNN()==n;\r
 }\r
 //-----------------------------------------------------------------------------\r
 bool MGL_EXPORT mgl_check_vec3(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *name)\r
 {\r
 //     if(!gr || !x || !y || !z || !ax || !ay || !az)  return true;            // if data is absent then should be segfault!!!\r
-       register long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz();\r
-       if(n*m*l!=ay->GetNx()*ay->GetNy()*ay->GetNz() || n*m*l!=az->GetNx()*az->GetNy()*az->GetNz())\r
+       register long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz(), nn=n*m*l;\r
+       if(nn!=ay->GetNN() || nn!=az->GetNN())\r
        {       gr->SetWarn(mglWarnDim,name);   return true;    }\r
        if(n<2 || m<2 || l<2)   {       gr->SetWarn(mglWarnLow,name);   return true;    }\r
-       bool both = x->GetNx()*x->GetNy()*x->GetNz()==n*m*l && y->GetNx()*y->GetNy()*y->GetNz()==n*m*l && z->GetNx()*z->GetNy()*z->GetNz()==n*m*l;\r
+       bool both = x->GetNN()==nn && y->GetNN()==nn && z->GetNN()==nn;\r
        if(!(both || (x->GetNx()==n && y->GetNx()==m && z->GetNx()==l)))\r
        {       gr->SetWarn(mglWarnDim,name);   return true;    }\r
        return false;\r
@@ -1382,18 +1421,18 @@ void mglBase::ClearUnused()
                }\r
                // now add proper indexes\r
                l=Pnt.size();\r
-               std::vector<mglPnt> pnt;\r
+               mglStack<mglPnt> pnt;   pnt.reserve(l);\r
                for(size_t i=0;i<l;i++) if(used[i])\r
-               {       pnt.push_back(Pnt[i]);  used[i]=pnt.size();     }\r
+               {       pnt.push_back(Pnt[i]);  used[i]=pnt.size()-1;   }\r
                Pnt = pnt;      pnt.clear();\r
                // now replace point id\r
                l=Prm.size();\r
                for(size_t i=0;i<l;i++)\r
                {\r
-                       mglPrim &p=Prm[i];      p.n1=used[p.n1]-1;\r
-                       if(p.type==1 || p.type==4)      p.n2=used[p.n2]-1;\r
-                       if(p.type==2)   {       p.n2=used[p.n2]-1;      p.n3=used[p.n3]-1;      }\r
-                       if(p.type==3)   {       p.n2=used[p.n2]-1;      p.n3=used[p.n3]-1;      p.n4=used[p.n4]-1;      }\r
+                       mglPrim &p=Prm[i];      p.n1=used[p.n1];\r
+                       if(p.type==1 || p.type==4)      p.n2=used[p.n2];\r
+                       if(p.type==2)   {       p.n2=used[p.n2];        p.n3=used[p.n3];        }\r
+                       if(p.type==3)   {       p.n2=used[p.n2];        p.n3=used[p.n3];        p.n4=used[p.n4];        }\r
                }\r
                delete []used;\r
        }\r
@@ -1402,3 +1441,9 @@ void mglBase::ClearUnused()
 #endif\r
 }\r
 //-----------------------------------------------------------------------------\r
+void mglBase::ClearPrmInd()\r
+{\r
+#pragma omp critical(prmind)\r
+       {       if(PrmInd)      delete []PrmInd;        PrmInd=NULL;    }\r
+}\r
+//-----------------------------------------------------------------------------\r
index a453de251958d9c4872c210516d98e89b8d4540f..23c33a515977be5d6e556825d9f872f2e3149322 100644 (file)
 //             C interfaces\r
 //\r
 //-----------------------------------------------------------------------------\r
+bool mglPrintWarn = true;\r
+void MGL_EXPORT mgl_suppress_warn(int on)      {       mglPrintWarn = !on;     }\r
+void MGL_EXPORT mgl_suppress_warn_(int *on)    {       mgl_suppress_warn(*on); }\r
 void MGL_EXPORT mgl_set_quality(HMGL gr, int qual)     {       gr->SetQuality(qual);   }\r
 void MGL_EXPORT mgl_set_quality_(uintptr_t *gr, int *qual)     {       _GR_->SetQuality(*qual);        }\r
-int MGL_EXPORT mgl_get_quality(HMGL gr)        {       return gr->GetQuality();        }\r
-int MGL_EXPORT mgl_get_quality_(uintptr_t *gr) {       return _GR_->GetQuality();      }\r
-int MGL_EXPORT mgl_is_frames(HMGL gr)\r
+int MGL_EXPORT_PURE mgl_get_quality(HMGL gr)   {       return gr->GetQuality();        }\r
+int MGL_EXPORT_PURE mgl_get_quality_(uintptr_t *gr)    {       return _GR_->GetQuality();      }\r
+int MGL_EXPORT_PURE mgl_is_frames(HMGL gr)\r
 {      return gr->get(MGL_VECT_FRAME) && !(gr->GetQuality()&MGL_DRAW_LMEM);    }\r
 void MGL_EXPORT mgl_set_draw_reg(HMGL gr, long nx, long ny, long m)    {       gr->SetDrawReg(nx,ny,m);        }\r
 void MGL_EXPORT mgl_set_draw_reg_(uintptr_t *gr, int *nx, int *ny, int *m)     {       _GR_->SetDrawReg(*nx,*ny,*m);   }\r
 //-----------------------------------------------------------------------------\r
-int MGL_EXPORT mgl_get_flag(HMGL gr, uint32_t flag)    {       return gr->get(flag);   }\r
-int MGL_EXPORT mgl_get_flag_(uintptr_t *gr, unsigned long *flag)       {       return _GR_->get(*flag);        }\r
+int MGL_EXPORT_PURE mgl_get_flag(HMGL gr, uint32_t flag)       {       return gr->get(flag);   }\r
+int MGL_EXPORT_PURE mgl_get_flag_(uintptr_t *gr, unsigned long *flag)  {       return _GR_->get(*flag);        }\r
 void MGL_EXPORT mgl_set_flag(HMGL gr, int val, uint32_t flag)          {       gr->set(val,flag);      }\r
 void MGL_EXPORT mgl_set_flag_(uintptr_t *gr, int *val, unsigned long *flag)    {       _GR_->set(*val,*flag);  }\r
 //-----------------------------------------------------------------------------\r
@@ -55,10 +58,22 @@ void MGL_EXPORT mgl_set_plotid(HMGL gr, const char *id)     {       gr->PlotId = id;        }
 void MGL_EXPORT mgl_set_plotid_(uintptr_t *gr, const char *id,int l)\r
 {      char *s=new char[l+1];  memcpy(s,id,l); s[l]=0;\r
        _GR_->PlotId = s;       delete []s;     }\r
-MGL_EXPORT const char *mgl_get_plotid(HMGL gr) {       return gr->PlotId.c_str();      }\r
+MGL_EXPORT_PURE const char *mgl_get_plotid(HMGL gr)    {       return gr->PlotId.c_str();      }\r
+int MGL_EXPORT mgl_get_plotid_(uintptr_t *gr, char *out, int len)\r
+{\r
+       const char *res = mgl_get_plotid(_GR_);\r
+       if(out) strncpy(out,res,len);\r
+       return strlen(res);\r
+}\r
 //-----------------------------------------------------------------------------\r
-MGL_EXPORT const char *mgl_get_mess(HMGL gr)   {       return gr->Mess.c_str();        }\r
-int MGL_EXPORT mgl_get_warn(HMGL gr)   {       return gr->GetWarn();   }\r
+MGL_EXPORT_PURE const char *mgl_get_mess(HMGL gr)      {       return gr->Mess.c_str();        }\r
+int MGL_EXPORT mgl_get_mess_(uintptr_t *gr, char *out, int len)\r
+{\r
+       const char *res = mgl_get_mess(_GR_);\r
+       if(out) strncpy(out,res,len);\r
+       return strlen(res);\r
+}\r
+int MGL_EXPORT_PURE mgl_get_warn(HMGL gr)      {       return gr->GetWarn();   }\r
 void MGL_EXPORT mgl_set_warn(HMGL gr, int code, const char *txt)\r
 {      gr->SetWarn(code,txt);  }\r
 void MGL_EXPORT mgl_set_origin(HMGL gr, double x0, double y0, double z0)\r
@@ -119,7 +134,7 @@ void MGL_EXPORT mgl_set_rdc_acc_(uintptr_t *gr, int *reduce)
 void MGL_EXPORT mgl_highlight_(uintptr_t *gr, int *id) {       _GR_->Highlight(*id);   }\r
 void MGL_EXPORT mgl_set_origin_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0)\r
 {      _GR_->SetOrigin(*x0,*y0,*z0);   }\r
-int MGL_EXPORT mgl_get_warn_(uintptr_t *gr)    {       return _GR_->GetWarn(); }\r
+int MGL_EXPORT_PURE mgl_get_warn_(uintptr_t *gr)       {       return _GR_->GetWarn(); }\r
 void MGL_EXPORT mgl_set_warn_(uintptr_t *gr, int *code, const char *txt, int l)\r
 {      char *s=new char[l+1];  memcpy(s,txt,l);        s[l]=0;\r
        _GR_->SetWarn(*code, s);        delete []s;     }\r
@@ -201,6 +216,13 @@ void MGL_EXPORT mgl_def_font_(const char *name, const char *path,int l,int n)
        char *d=new char[n+1];          memcpy(d,path,n);       d[n]=0;\r
        mglDefFont.Load(name,path);     delete []s;             delete []d;     }\r
 //-----------------------------------------------------------------------------\r
+int MGL_EXPORT mgl_check_version(const char *ver)\r
+{      double v=0;     int r = sscanf(ver,"2.%lg",&v);\r
+       return r<1 || v>MGL_VER2;       }\r
+int MGL_EXPORT mgl_check_version_(const char *ver, int l)\r
+{      char *s=new char[l+1];          memcpy(s,ver,l);        s[l]=0;\r
+       int r=mgl_check_version(s);     delete []s;     return r;       }\r
+//-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_start_group(HMGL gr, const char *s)        {       gr->StartAutoGroup(s);  }\r
 void MGL_EXPORT mgl_end_group(HMGL gr) {       gr->EndGroup(); }\r
 void MGL_EXPORT mgl_start_group_(uintptr_t *gr, const char *name,int l)\r
@@ -265,3 +287,10 @@ void MGL_EXPORT mgl_set_mask_val_(const char *id, uint64_t *mask,int)
 void MGL_EXPORT mgl_set_mask_angle(HMGL gr, int angle) {       gr->SetMaskAngle(angle);        }\r
 void MGL_EXPORT mgl_set_mask_angle_(uintptr_t *gr, int *angle) {       _GR_->SetMaskAngle(*angle);     }\r
 //---------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_ask_stop(HMGL gr, int stop)                {       gr->AskStop(stop);      }\r
+void MGL_EXPORT mgl_ask_stop_(uintptr_t *gr, int *stop){       _GR_->AskStop(*stop);   }\r
+int MGL_EXPORT mgl_need_stop(HMGL gr)                  {       return gr->NeedStop();  }\r
+int MGL_EXPORT mgl_need_stop_(uintptr_t *gr)   {       return _GR_->NeedStop();}\r
+void MGL_EXPORT mgl_set_event_func(HMGL gr, void (*func)(void *), void *par)\r
+{      gr->SetEventFunc(func,par);     }\r
+//---------------------------------------------------------------------------\r
index bbe7fb2c5bd9c8e67d20cf91ffd79b39905a0467..7a7a33243970fb88d19b35aa360d4884a9db59aa 100644 (file)
@@ -27,10 +27,11 @@ mglCanvas::mglCanvas(int w, int h) : mglBase()
 {\r
        clr(MGL_DISABLE_SCALE);\r
        set(MGL_VECT_FRAME);    // NOTE: require a lot of memory!\r
-       Z=0;    C=G=G4=0;       OI=0;   gif=0;\r
+       Z=0;    C=G=G4=GB=0;    OI=0;   gif=0;\r
        CurFrameId=0;   Delay=0.5;\r
        Width=Height=Depth=0;   ObjId=-1;\r
        fscl=ftet=0;            PlotId = "frame";\r
+       pnt_col = 0;\r
 \r
        ac.ch='c';\r
        ax.dir = mglPoint(1,0,0);       ax.a = mglPoint(0,1,0); ax.b = mglPoint(0,0,1); ax.ch='x';\r
@@ -42,7 +43,8 @@ mglCanvas::mglCanvas(int w, int h) : mglBase()
 //-----------------------------------------------------------------------------\r
 mglCanvas::~mglCanvas()\r
 {\r
-       if(G)   {       delete []G;     delete []C;     delete []Z;     delete []G4;delete []OI;        }\r
+       if(G)   {       delete []G;     delete []C;     delete []Z;     delete []G4;delete []GB;delete []OI;    }\r
+       if(pnt_col)     delete []pnt_col;\r
 }\r
 //-----------------------------------------------------------------------------\r
 long mglCanvas::PushDrwDat()\r
@@ -78,7 +80,7 @@ void mglCanvas::SetFrame(long i)
 void mglCanvas::GetFrame(long k)\r
 {\r
        if(k<0 || (size_t)k>=DrwDat.size())     return;\r
-       Clf();\r
+       ClearFrame();\r
        const mglDrawDat &d=DrwDat[k];\r
 #if MGL_HAVE_PTHREAD\r
        pthread_mutex_lock(&mutexPnt);\r
@@ -88,7 +90,7 @@ void mglCanvas::GetFrame(long k)
        pthread_mutex_lock(&mutexTxt);\r
 #endif\r
 #pragma omp critical\r
-       {       Pnt=d.Pnt;      Prm=d.Prm;      Glf=d.Glf;      Ptx=d.Ptx;      Txt=d.Txt;      }\r
+       {       Pnt=d.Pnt;      Prm=d.Prm;      Glf=d.Glf;      Ptx=d.Ptx;      Txt=d.Txt;      ClearPrmInd();  }\r
 #if MGL_HAVE_PTHREAD\r
        pthread_mutex_unlock(&mutexTxt);\r
        pthread_mutex_unlock(&mutexPtx);\r
@@ -98,6 +100,44 @@ void mglCanvas::GetFrame(long k)
 #endif\r
 }\r
 //-----------------------------------------------------------------------------\r
+void mglCanvas::ClearFrame()\r
+{\r
+#if MGL_HAVE_PTHREAD\r
+       pthread_mutex_lock(&mutexPnt);\r
+       pthread_mutex_lock(&mutexPrm);\r
+       pthread_mutex_lock(&mutexGlf);\r
+       pthread_mutex_lock(&mutexPtx);\r
+       pthread_mutex_lock(&mutexTxt);\r
+       pthread_mutex_lock(&mutexSub);\r
+       pthread_mutex_lock(&mutexLeg);\r
+       pthread_mutex_lock(&mutexGrp);\r
+       pthread_mutex_lock(&mutexAct);\r
+#endif\r
+\r
+#pragma omp critical(txt)\r
+       {\r
+               StartAutoGroup(NULL);\r
+               Sub.clear();    Leg.clear();    Grp.clear();    Act.clear();\r
+               Pnt.clear();    Prm.clear();    Ptx.clear();    Glf.clear();    ClearPrmInd();\r
+               Txt.clear();    Txt.reserve(3);\r
+               mglTexture t1(MGL_DEF_PAL,-1), t2(MGL_DEF_SCH,1);\r
+               MGL_PUSH(Txt,t1,mutexTxt);\r
+               MGL_PUSH(Txt,t2,mutexTxt);\r
+       }\r
+#if MGL_HAVE_PTHREAD\r
+       pthread_mutex_unlock(&mutexAct);\r
+       pthread_mutex_unlock(&mutexGrp);\r
+       pthread_mutex_unlock(&mutexLeg);\r
+       pthread_mutex_unlock(&mutexSub);\r
+       pthread_mutex_unlock(&mutexTxt);\r
+       pthread_mutex_unlock(&mutexPtx);\r
+       pthread_mutex_unlock(&mutexGlf);\r
+       pthread_mutex_unlock(&mutexPrm);\r
+       pthread_mutex_unlock(&mutexPnt);\r
+#endif\r
+       ClfZB(true);\r
+}\r
+//-----------------------------------------------------------------------------\r
 void mglCanvas::ShowFrame(long k)\r
 {\r
        if(k<0 || (size_t)k>=DrwDat.size())     return;\r
@@ -116,7 +156,7 @@ void mglCanvas::ShowFrame(long k)
                Glf.reserve(d.Glf.size());      for(size_t i=0;i<d.Glf.size();i++)      Glf.push_back(d.Glf[i]);\r
                Ptx.reserve(d.Ptx.size());      for(size_t i=0;i<d.Ptx.size();i++)      Ptx.push_back(d.Ptx[i]);\r
                Txt.reserve(d.Pnt.size());      for(size_t i=0;i<d.Txt.size();i++)      Txt.push_back(d.Txt[i]);\r
-               Pnt.reserve(d.Pnt.size());\r
+               Pnt.reserve(d.Pnt.size());      ClearPrmInd();\r
                for(size_t i=0;i<d.Pnt.size();i++)\r
                {\r
                        mglPnt p = d.Pnt[i];    p.c += ntxt;\r
@@ -161,7 +201,7 @@ void mglCanvas::add_prim(mglPrim &a)
                a.id = ObjId;\r
 #pragma omp critical(prm)\r
                MGL_PUSH(Prm,a,mutexPrm);\r
-               clr(MGL_FINISHED);\r
+               ClearPrmInd();  clr(MGL_FINISHED);\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -177,13 +217,15 @@ int Height;                       ///< Height of the image
 int Depth;                     ///< Depth of the image\r
 int CurFrameId;                ///< Number of automaticle created frames\r
 GifFileType *gif;*/\r
-       SetDrawReg(1,1,0);\r
+       SetDrawReg(1,1,0);              Perspective(0);\r
        memcpy(mgl_mask_val, mgl_mask_def, 16*sizeof(uint64_t));        // should be > 16*8\r
+       ax.Clear();     ay.Clear();     az.Clear();     ac.Clear();\r
        mgl_clear_fft();                DefMaskAn=0;    ResetMask();\r
        SetTickRotate(true);    SetTickSkip(true);\r
        SetWarn(mglWarnNone,"");        mglGlobalMess = "";\r
        ObjId = -1;     HighId = INT_MIN;\r
-       SetFunc(0,0);   Stop=false;     CutOff(0);      Ternary(0);\r
+       SetFunc(0,0);   CutOff(0);      Ternary(0);\r
+       Stop=false;     event_cb = NULL;        event_par=NULL;\r
        SetRanges(mglPoint(-1,-1,-1,-1), mglPoint(1,1,1,1));\r
        SetOrigin(NAN,NAN,NAN,NAN);\r
        SetBarWidth(0.7);       SetMarkSize(1); SetArrowSize(1);\r
@@ -197,7 +239,6 @@ GifFileType *gif;*/
        SetDifLight(false);             SetReduceAcc(false);\r
        SetDefScheme(MGL_DEF_SCH);      SetPalette(MGL_DEF_PAL);\r
        SetPenPal("k-1");               Alpha(false);\r
-       SetTicks('x');  SetTicks('y');  SetTicks('z');  SetTicks('c');\r
        stack.clear();  Restore();      DefColor('k');\r
        SetPlotFactor(0);       InPlot(0,1,0,1,false);\r
        SetTickLen(0);  SetCut(true);\r
@@ -220,7 +261,6 @@ mreal mglCanvas::FindOptOrg(char dir, int ind) const
        if(B!=bb)\r
        {\r
                bb = B;\r
-#pragma omp parallel for\r
                for(long i=0;i<8;i++)   PostScale(&B,pp[i]);\r
                // find point with minimal y\r
                long j=0;\r
@@ -245,7 +285,7 @@ mreal mglCanvas::FindOptOrg(char dir, int ind) const
                {       if(pp[1].x>pp[2].x)     pz.y=1-pz.y;    else    pz.x=1-pz.x;    }\r
                else if(ty<tx && ty<tz) // y-axis is vertical\r
                {       if(pp[1].x>pp[3].x)     py.z=1-py.z;    else    py.x=1-py.x;    }\r
-               else if(tx<tz && tx<tz) // x-axis is vertical\r
+               else if(tx<ty && tx<tz) // x-axis is vertical\r
                {       if(pp[3].x>pp[2].x)     px.y=1-px.y;    else    px.z=1-px.z;    }\r
        }\r
        // return to normal variables\r
@@ -299,19 +339,16 @@ mreal mglCanvas::GetOrgZ(char dir, bool inv) const
 //-----------------------------------------------------------------------------\r
 //     Put primitives\r
 //-----------------------------------------------------------------------------\r
-#define MGL_MARK_PLOT  if(Quality&MGL_DRAW_LMEM)       mark_draw(Pnt[p],type,size,&d);else     \\r
-                                               {       mglPrim a;      a.w = pw;       a.s = size;     \\r
+#define MGL_MARK_PLOT  if(Quality&MGL_DRAW_LMEM)       \\r
+                                               {       mglDrawReg d;   d.set(this,dr_x,dr_y,dr_p);     d.PenWidth=pw;  \\r
+                                                       d.PDef = PDef;  d.pPos = pPos;  mark_draw(Pnt[p],type,size,&d); }\\r
+                                               else{   mglPrim a;      a.w = pw;       a.s = size;     \\r
                                                        a.n1 = p;       a.n4 = type;    a.angl=0;       add_prim(a);    }\r
 void mglCanvas::mark_plot(long p, char type, mreal size)\r
 {\r
        if(p<0 || mgl_isnan(Pnt[p].x) || mgl_isnan(size))       return;\r
        long pp=p;\r
-//     mreal pw = fabs(PenWidth)*0.15/sqrt(font_factor);\r
        mreal pw = 0.15/sqrt(font_factor);\r
-       mglDrawReg d;   d.set(this,dr_x,dr_y,dr_p);\r
-       d.PDef = PDef;  d.pPos = pPos;  d.PenWidth=pw;\r
-//     if(size>=0)     size *= MarkSize;\r
-//     if(size==0)     size = MarkSize;\r
        size = size?fabs(size):1;\r
        size *= MarkSize*0.35*font_factor;\r
        if(type=='.')   size = fabs(PenWidth)*sqrt(font_factor/400);\r
@@ -320,8 +357,10 @@ void mglCanvas::mark_plot(long p, char type, mreal size)
        else    {       MGL_MARK_PLOT   }\r
 }\r
 //-----------------------------------------------------------------------------\r
-#define MGL_LINE_PLOT  if(Quality&MGL_DRAW_LMEM)       line_draw(Pnt[p1],Pnt[p2],&dd);else     \\r
-                                               {       mglPrim a(1);   a.n3=PDef;      a.s = pPos;     \\r
+#define MGL_LINE_PLOT  if(Quality&MGL_DRAW_LMEM)       \\r
+                                               {       mglDrawReg d;   d.set(this,dr_x,dr_y,dr_p);     d.PenWidth=pw;  \\r
+                                                       d.PDef = PDef;  d.pPos = pPos;  line_draw(Pnt[p1],Pnt[p2],&d);  }\\r
+                                               else    {       mglPrim a(1);   a.n3=PDef;      a.s = pPos;     \\r
                                                        a.n1 = p1;      a.n2 = p2;      a.w = pw;       a.angl=0;       add_prim(a);    }\r
 void mglCanvas::line_plot(long p1, long p2)\r
 {\r
@@ -329,36 +368,35 @@ void mglCanvas::line_plot(long p1, long p2)
        if(p1<0 || p2<0 || mgl_isnan(Pnt[p1].x) || mgl_isnan(Pnt[p2].x))        return;\r
        if(p1>p2)       {       long kk=p1;     p1=p2;  p2=kk;  }       // rearrange start/end for proper dashing\r
        long pp1=p1,pp2=p2;\r
-       mreal pw = fabs(PenWidth)*sqrt(font_factor/400), d;\r
-       d = hypot(Pnt[p1].x-Pnt[p2].x, Pnt[p1].y-Pnt[p2].y);\r
-\r
-       mglDrawReg dd;  dd.set(this,dr_x,dr_y,dr_p);\r
-       dd.PDef = PDef; dd.pPos = pPos; dd.PenWidth=pw;\r
-\r
+       mreal pw = fabs(PenWidth)*sqrt(font_factor/400);\r
        if(TernAxis&4) for(int i=0;i<4;i++)\r
        {       p1 = ProjScale(i, pp1); p2 = ProjScale(i, pp2);\r
                MGL_LINE_PLOT   }\r
        else    {       MGL_LINE_PLOT   }\r
+       register mreal d = hypot(Pnt[p1].x-Pnt[p2].x, Pnt[p1].y-Pnt[p2].y);\r
        pPos = fmod(pPos+d/pw/1.5, 16);\r
 }\r
 //-----------------------------------------------------------------------------\r
-#define MGL_TRIG_PLOT  if(Quality&MGL_DRAW_LMEM)       trig_draw(Pnt[p1],Pnt[p2],Pnt[p3],true,&d);else \\r
-                                               {       mglPrim a(2);   a.n1 = p1;      a.n2 = p2;      a.n3 = p3;      \\r
+#define MGL_TRIG_PLOT  if(Quality&MGL_DRAW_LMEM)       \\r
+                                               {       mglDrawReg d;   d.set(this,dr_x,dr_y,dr_p);     d.PenWidth=pw;  \\r
+                                                       trig_draw(Pnt[p1],Pnt[p2],Pnt[p3],true,&d);     }\\r
+                                               else{   mglPrim a(2);   a.n1 = p1;      a.n2 = p2;      a.n3 = p3;      \\r
                                                        a.m=mask;       a.angl=MaskAn;  a.w = pw;       add_prim(a);}\r
 void mglCanvas::trig_plot(long p1, long p2, long p3)\r
 {\r
        if(p1<0 || p2<0 || p3<0 || mgl_isnan(Pnt[p1].x) || mgl_isnan(Pnt[p2].x) || mgl_isnan(Pnt[p3].x))        return;\r
        long pp1=p1,pp2=p2,pp3=p3;\r
        mreal pw = fabs(PenWidth)*sqrt(font_factor/400);\r
-       mglDrawReg d;   d.set(this,dr_x,dr_y,dr_p);     d.PenWidth=pw;\r
        if(TernAxis&4) for(int i=0;i<4;i++)\r
        {       p1 = ProjScale(i, pp1); p2 = ProjScale(i, pp2);\r
                p3 = ProjScale(i, pp3); MGL_TRIG_PLOT   }\r
        else    {       MGL_TRIG_PLOT   }\r
 }\r
 //-----------------------------------------------------------------------------\r
-#define MGL_QUAD_PLOT  if(Quality&MGL_DRAW_LMEM)       quad_draw(Pnt[p1],Pnt[p2],Pnt[p3],Pnt[p4],&d);else      \\r
-                                               {       mglPrim a(3);   a.n1 = p1;      a.n2 = p2;      a.n3 = p3;      a.n4 = p4;      \\r
+#define MGL_QUAD_PLOT  if(Quality&MGL_DRAW_LMEM)       \\r
+                                               {       mglDrawReg d;   d.set(this,dr_x,dr_y,dr_p);     d.PenWidth=pw;  \\r
+                                                       quad_draw(Pnt[p1],Pnt[p2],Pnt[p3],Pnt[p4],&d);  }\\r
+                                               else{   mglPrim a(3);   a.n1 = p1;      a.n2 = p2;      a.n3 = p3;      a.n4 = p4;      \\r
                                                        a.m=mask;       a.angl=MaskAn;  a.w = pw;       add_prim(a);    }\r
 void mglCanvas::quad_plot(long p1, long p2, long p3, long p4)\r
 {\r
@@ -368,7 +406,6 @@ void mglCanvas::quad_plot(long p1, long p2, long p3, long p4)
        if(p4<0 || mgl_isnan(Pnt[p4].x))        {       trig_plot(p1,p2,p3);    return; }\r
        long pp1=p1,pp2=p2,pp3=p3,pp4=p4;\r
        mreal pw = fabs(PenWidth)*sqrt(font_factor/400);\r
-       mglDrawReg d;   d.set(this,dr_x,dr_y,dr_p);     d.PenWidth=pw;\r
        if(TernAxis&4) for(int i=0;i<4;i++)\r
        {       p1 = ProjScale(i, pp1); p2 = ProjScale(i, pp2);\r
                p3 = ProjScale(i, pp3); p4 = ProjScale(i, pp4);\r
@@ -387,7 +424,7 @@ mreal mglCanvas::text_plot(long p,const wchar_t *text,const char *font,mreal siz
                mreal res;\r
                TernAxis = TernAxis&(~4);\r
                for(int i=0;i<4;i++)\r
-                       res = text_plot(ProjScale(i,p,true),text,font,size/2,sh,col);\r
+                       res = text_plot(ProjScale(i,p,true),text,font,size/2,sh,col,rot);\r
                TernAxis = TernAxis|4;\r
                return res;\r
        }\r
@@ -395,8 +432,8 @@ mreal mglCanvas::text_plot(long p,const wchar_t *text,const char *font,mreal siz
        mglPnt q=Pnt[p];\r
        mreal ll = q.u*q.u+q.v*q.v;\r
        bool inv=false;\r
-       if(rot && (q.u<0 || (q.u==0 && q.v<0)))\r
-       {       q.u=-q.u;       q.v=-q.v;       q.w=-q.w;       inv=true;       }\r
+//     if(rot && (q.u<0 || (q.u==0 && q.v<0)))         // NOTE this is 1st part of rotation changes (see also GetGlyphPhi())\r
+//     {       q.u=-q.u;       q.v=-q.v;       q.w=-q.w;       inv=true;       }\r
 \r
        mreal fsize=size/6.5*font_factor, h = fnt->Height(font)*fsize, w, shift = -(sh+0.02)*h;\r
        // text drawing itself\r
@@ -412,9 +449,17 @@ pthread_mutex_lock(&mutexPtx);
                shift += 0.015*h;       // Correction for glyph rotation around proper point\r
        //              shift *= h;\r
 \r
-               int align;      \r
-               char cc = mglGetStyle(font,0,&align);   align = align&3;\r
-               if(cc)  col = -cc;\r
+               int align;\r
+               mreal col1=col, col2=col;\r
+               if(mglGetStyle(font,0,&align))\r
+               {\r
+                       col1 = AddTexture(font);\r
+                       col2 = col1+1/MGL_FEPSILON;\r
+               }\r
+               else if(col<0)\r
+                       col1 = col2 = AddTexture(char(0.5-col));\r
+               align = align&3;\r
+\r
                Bt.x = q.x;     Bt.y = q.y - shift;     Bt.z = q.z;\r
                if(ll>0)\r
                {\r
@@ -429,10 +474,7 @@ pthread_mutex_lock(&mutexPtx);
 \r
                if(!(Quality&MGL_DRAW_LMEM))    // add text itself\r
                {\r
-                       char ch = mglGetStyle(font,0,0);\r
-                       mglColor mc(ch);\r
-                       if(!ch) mc = col<0 ? mglColor(char(0.5-col)):Txt[long(col)].GetC(col);\r
-\r
+                       mglColor mc = Txt[long(col1)].GetC(col1);\r
                        mglPrim a(6);   a.n1 = p;\r
                        a.n2 = int(255*mc.r) + 256*(int(255*mc.g) + 256*int(255*mc.b));\r
                        mglText txt(text,font);\r
@@ -441,9 +483,8 @@ pthread_mutex_lock(&mutexPtx);
                        add_prim(a);\r
                }\r
 \r
-               col = col<0 ? AddTexture(char(0.5-col)):col;\r
-               q.c=col;        q.t=0;  Txt[long(col)].GetC(col,0,q);\r
-               q.u = q.v = NAN;\r
+               q.c=col1;       q.t=0;  Txt[long(col1)].GetC(col1,0,q);\r
+               q.u = q.v = NAN;        q.a=q.t=q.ta=1;\r
                memset(Bt.b,0,9*sizeof(mreal));\r
                Bt.b[0] = Bt.b[4] = Bt.b[8] = fscl;\r
                register mreal opf = Bt.pf;\r
@@ -452,7 +493,6 @@ pthread_mutex_lock(&mutexPtx);
                {\r
                        long k1,k2,k3,k4;       mglPnt pt;      mglPoint pp;\r
                        w = fnt->Width(text,font);      h = fnt->Height(font);\r
-//                     int align;      mglGetStyle(font,0,&align);     align = align&3;\r
                        mreal d=-w*align/2.-h*0.2;      w+=h*0.4;\r
                        pt = q; pp = mglPoint(d,-h*0.4);                PostScale(&Bt,pp);\r
                        pt.x=pt.xx=pp.x;        pt.y=pt.yy=pp.y;\r
@@ -477,7 +517,9 @@ pthread_mutex_lock(&mutexPtx);
                        k3 = CopyNtoC(k3,bl);   k4 = CopyNtoC(k4,bl);\r
                        quad_plot(k1,k2,k3,k4);\r
                }\r
-               fsize *= fnt->Puts(text,font,col)/2;\r
+               const char *ffont = font;\r
+               while(*ffont && *ffont!=':')    ffont++;\r
+               fsize *= fnt->Puts(text,ffont,col1,col2)/2;\r
        }\r
 #if MGL_HAVE_PTHREAD\r
        pthread_mutex_unlock(&mutexPtx);\r
@@ -497,10 +539,12 @@ void mglCanvas::Glyph(mreal x, mreal y, mreal f, int s, long j, mreal col)
        a.n2 = forg;    a.n3 = s;       a.n4 = AddGlyph(s,j);\r
        if(a.n1<0)      return;\r
 \r
-       mglDrawReg d;   d.set(this,dr_x,dr_y,dr_p);\r
-       d.PDef = s;             d.pPos = a.s;   d.PenWidth=a.w;\r
-\r
-       if(Quality&MGL_DRAW_LMEM)       glyph_draw(a,&d);\r
+       if(Quality&MGL_DRAW_LMEM)\r
+       {\r
+               mglDrawReg d;   d.set(this,dr_x,dr_y,dr_p);\r
+               d.PDef = s;             d.pPos = a.s;   d.PenWidth=a.w;\r
+               glyph_draw(a,&d);\r
+       }\r
        else    add_prim(a);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -681,15 +725,14 @@ int mglCanvas::GetSplId(long x,long y) const
        return id;\r
 }\r
 //-----------------------------------------------------------------------------\r
-#define islog(a, b) (((a)>0 && (b)>10*(a)) || ((b)<0 && (a)<10*(b)))\r
 void mglCanvas::Aspect(mreal Ax,mreal Ay,mreal Az)\r
 {\r
        if(mgl_isnan(Ax))\r
        {\r
                mreal dy = (Max.y-Min.y), dx = (Max.x-Min.x), dz = (Max.z-Min.z);\r
-               if(islog(Min.x,Max.x) && fx)    dx = log10(Max.x/Min.x);\r
-               if(islog(Min.y,Max.y) && fy)    dy = log10(Max.y/Min.y);\r
-               if(islog(Min.z,Max.z) && fz)    dz = log10(Max.z/Min.z);\r
+               if(mgl_islog(Min.x,Max.x) && fx)        dx = log10(Max.x/Min.x);\r
+               if(mgl_islog(Min.y,Max.y) && fy)        dy = log10(Max.y/Min.y);\r
+               if(mgl_islog(Min.z,Max.z) && fz)        dz = log10(Max.z/Min.z);\r
                mreal fy=exp(M_LN10*floor(0.5+log10(fabs(dy/dx))));\r
                mreal fz=exp(M_LN10*floor(0.5+log10(fabs(dz/dx))));\r
                if(Ay>0)        fy*=Ay;\r
@@ -725,7 +768,7 @@ void mglCanvas::AddLight(int n, mglPoint r, mglPoint d, char col, mreal br, mrea
 //-----------------------------------------------------------------------------\r
 void mglCanvas::arrow_plot(long n1, long n2, char st)\r
 {\r
-       if(n1<0 || n2<0 || !strchr("AVKSDTIO",st))      return;\r
+       if(n1<0 || n2<0 || !strchr("AVKSDTIOX",st))     return;\r
        float ll = PenWidth*ArrowSize*0.35*font_factor;\r
        uint64_t m=mask;        int ma=MaskAn;\r
        ResetMask();\r
@@ -736,6 +779,74 @@ void mglCanvas::arrow_plot(long n1, long n2, char st)
        mask=m; MaskAn=ma;\r
 }\r
 //-----------------------------------------------------------------------------\r
+std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt)\r
+{\r
+       char se[64], sf[64], ff[8]="%.3f", ee[8]="%.3e";\r
+       int dig=3;\r
+       for(const char *s="0123456789";*s;s++)  if(mglchr(fmt,*s))      dig = *s-'0';\r
+       if(mglchr(fmt,'E'))     ee[3] = 'E';\r
+       bool plus = mglchr(fmt,'+');\r
+       bool tex = mglchr(fmt,'F');\r
+       int fdig = int(log10(v));       fdig = fdig>0?(fdig<dig?dig-fdig:0):dig;\r
+       ff[2] = fdig+'0';       ee[2] = dig+'0';\r
+       snprintf(se,64,ee,v);   snprintf(sf,64,ff,v);\r
+       long le=strlen(se), lf=strlen(sf), i;\r
+\r
+       // clear fix format\r
+       for(i=lf-1;i>=lf-fdig && sf[i]=='0';i--)        sf[i]=0;\r
+       if(sf[i]=='.')  sf[i]=0;        lf = strlen(sf);\r
+       // parse -nan numbers\r
+       if(!strcmp(sf,"-nan"))  memcpy(sf,"nan",4);\r
+\r
+       \r
+       // clear exp format\r
+       int st = se[0]=='-'?1:0;\r
+       if(plus || se[3+st+dig]=='-')   // first remove zeros after 'e'\r
+       {\r
+               for(i=(dig>0?4:3)+st+dig;i<le && se[i]=='0';i++);\r
+               memmove(se+(dig>0?4:3)+st+dig,se+i,le-i+1);\r
+       }\r
+       else\r
+       {\r
+               for(i=(dig>0?3:2)+st+dig;i<le && (se[i]=='0' || se[i]=='+');i++);\r
+               memmove(se+(dig>0?3:2)+st+dig,se+i,le-i+1);\r
+       }\r
+       le=strlen(se);\r
+       // don't allow '+' at the end\r
+       if(se[le-1]=='+')       se[--le]=0;\r
+       // remove single 'e'\r
+       if(se[le-1]=='e' || se[le-1]=='E')      se[--le]=0;\r
+       for(i=1+st+dig;i>st && se[i]=='0';i--); // remove final '0'\r
+       if(se[i]=='.')  i--;\r
+       memmove(se+i+1,se+2+st+dig,le-dig);     le=strlen(se);\r
+       // add '+' sign if required\r
+       if(plus && !strchr("-0niNI",se[0]))\r
+       {       memmove(se+1,se,le+1);  se[0]='+';\r
+               memmove(sf+1,sf,lf+1);  sf[0]='+';      }\r
+       if((lf>le && !mglchr(fmt,'f')) || !strcmp(sf,"0") || !strcmp(sf,"-0"))  strcpy(sf,se);  lf = strlen(sf);\r
+       std::wstring res;       res.reserve(lf+8);\r
+\r
+       if(mglchr(fmt,'-') && !(plus||tex))             // replace '-' by "\minus"\r
+               for(i=0;i<lf;i++)       res += sf[i];\r
+       else\r
+               for(i=0;i<lf;i++)       res += sf[i]!='-'?sf[i]:L'−';\r
+       if(tex) // TeX notation: 'e' -> "\cdot 10^{...}"\r
+       {\r
+               if(res[0]=='1' && (res[1]=='e' || res[1]=='E'))\r
+               {       res.replace(0,2,L"10^{");       res += L'}';    }\r
+               else if(wcschr(L"+-−",res[0]) && res[1]=='1' && (res[2]=='e' || res[2]=='E'))\r
+               {       res.replace(1,2,L"10^{");       res += L'}';    }\r
+               else\r
+               {\r
+                       size_t p;\r
+                       for(p=1;p<res.length();p++)     if(res[p]==L'e' || res[p]==L'E')        break;\r
+                       if(p<res.length())\r
+                       {       res.replace(p,1,L"⋅10^{");    res += L'}';    }\r
+               }\r
+       }\r
+       return res;\r
+}\r
+//-----------------------------------------------------------------------------\r
 void mglCanvas::Legend(const std::vector<mglText> &leg, mreal x, mreal y, const char *font, const char *opt)\r
 {\r
        long n=leg.size();\r
@@ -750,7 +861,8 @@ void mglCanvas::Legend(const std::vector<mglText> &leg, mreal x, mreal y, const
        // setup font and parse absolute coordinates\r
        if(!font)       font="#";\r
        char *pA, *ff = new char[strlen(font)+3];\r
-       strcpy(ff,font);        strcat(ff,":L");        Push();\r
+       const char *fmt = strchr(font,':');\r
+       strcpy(ff,fmt?fmt:"");  strcat(ff,":L");        Push();\r
        if((pA=strchr(ff,'A')))\r
        {       *pA = ' ';      InPlot(0,1,0,1,false);  iw=B1.b[0];     ih=B1.b[4];     }\r
        else    {       iw=B1.b[0]/B1.pf;       ih=B1.b[4]/B1.pf;       }\r
@@ -785,29 +897,28 @@ void mglCanvas::Legend(const std::vector<mglText> &leg, mreal x, mreal y, const
        }\r
        x += B.x-iw/2+dx;       y += B.y-ih/2+dy;\r
        // draw it\r
-       long k1=0,k2=0,k3=0,k4=0;\r
        mglPoint p,q=mglPoint(NAN,NAN,NAN);\r
 \r
-       for(i=0;ff[i] && ff[i]!=':';i++)        if(strchr(MGL_COLORS,ff[i]))\r
+       mreal cc = AddTexture(font);\r
+       mreal c1,c2;    //=AddTexture(char(k1?k1:'w')), c2=AddTexture(char(k2?k2:'k'));\r
+       if(cc<2 || Txt[long(cc+0.5)].n==0)\r
+       {       c1 = AddTexture('w');   cc = c2 = AddTexture('k');      }\r
+       else switch(Txt[long(cc+0.5)].n)\r
        {\r
-\r
-               if(k1 && k2)    {       k3=ff[i];       k4++;   }       // NOTE: keep k3 for future usage\r
-               if(k1 && !k2)   {       k2=ff[i];       k4++;   }\r
-               if(!k1) {       k1=ff[i];       k4++;   }\r
-       }\r
-       if(k4==2)       k2=0;\r
-       if(k4==1)       k1=k2=0;\r
-       mreal c1=AddTexture(char(k1?k1:'w')), c2=AddTexture(char(k2?k2:'k'));\r
-       if((Flag&3)==2) {       mreal cc=c1;    c2=c1;  c1=cc;  }\r
+       case 1: c1 = AddTexture('w');   c2 = AddTexture('k');   break;\r
+       case 2: c1 = cc;        cc+=1/MGL_FEPSILON;     c2 = AddTexture('k');   break;\r
+       default:        c1 = cc;        c2 = cc+0.5;    cc += 1/MGL_FEPSILON;   break;\r
+       }\r
+       if((Flag&3)==2) {       mreal tt=c1;    c2=c1;  c1=tt;  }\r
 \r
        mglMatrix M=B;  M.norot=true;\r
-       if(strchr(ff,'#'))      // draw bounding box\r
+       if(strchr(font,'#'))    // draw bounding box\r
        {\r
                SetPenPal("k-");\r
-               k1=AddPnt(&M,mglPoint(x,y,Depth/MGL_FEPSILON),c1,q,-1,0);\r
-               k2=AddPnt(&M,mglPoint(x+w*ncol,y,Depth/MGL_FEPSILON),c1,q,-1,0);\r
-               k3=AddPnt(&M,mglPoint(x,y+h*nrow,Depth/MGL_FEPSILON),c1,q,-1,0);\r
-               k4=AddPnt(&M,mglPoint(x+w*ncol,y+h*nrow,Depth/MGL_FEPSILON),c1,q,-1,0);\r
+               long k1=AddPnt(&M,mglPoint(x,y,Depth/MGL_FEPSILON),c1,q,1,0);\r
+               long k2=AddPnt(&M,mglPoint(x+w*ncol,y,Depth/MGL_FEPSILON),c1,q,1,0);\r
+               long k3=AddPnt(&M,mglPoint(x,y+h*nrow,Depth/MGL_FEPSILON),c1,q,1,0);\r
+               long k4=AddPnt(&M,mglPoint(x+w*ncol,y+h*nrow,Depth/MGL_FEPSILON),c1,q,1,0);\r
                quad_plot(k1,k2,k3,k4);\r
                k1=CopyNtoC(k1,c2);     k2=CopyNtoC(k2,c2);\r
                k3=CopyNtoC(k3,c2);     k4=CopyNtoC(k4,c2);\r
@@ -818,8 +929,8 @@ void mglCanvas::Legend(const std::vector<mglText> &leg, mreal x, mreal y, const
        {\r
                register long iy=nrow-(i%nrow)-1,ix=i/nrow;\r
                char m=SetPenPal(leg[i].stl.c_str());\r
-               k1=AddPnt(&M,mglPoint(x+ix*w+0.1*ll,y+iy*h+0.45*h,Depth),CDef,q,-1,0);\r
-               k2=AddPnt(&M,mglPoint(x+ix*w+0.9*ll,y+iy*h+0.45*h,Depth),CDef,q,-1,0);  pPos=0;\r
+               long k1=AddPnt(&M,mglPoint(x+ix*w+0.1*ll,y+iy*h+0.45*h,Depth),CDef,q,-1,0);\r
+               long k2=AddPnt(&M,mglPoint(x+ix*w+0.9*ll,y+iy*h+0.45*h,Depth),CDef,q,-1,0);     pPos=0;\r
                if(!leg[i].stl.empty()) line_plot(k1,k2);\r
                if(m)   for(j=0;j<LegendMarks;j++)\r
                {\r
@@ -827,7 +938,7 @@ void mglCanvas::Legend(const std::vector<mglText> &leg, mreal x, mreal y, const
                        mark_plot(AddPnt(&M,p,CDef,q,-1,0),m);\r
                }\r
                p = mglPoint(x+ix*w+((!leg[i].stl.empty())?ll:0.01*iw), y+iy*h+0.15*h, Depth);\r
-               text_plot(AddPnt(&M,p,-1,q,-1,0), leg[i].text.c_str(), ff, size);\r
+               text_plot(AddPnt(&M,p,-1,q,-1,0), leg[i].text.c_str(), ff, size,0,cc);\r
        }\r
        Pop();  EndGroup();     delete []ff;\r
 }\r
@@ -845,20 +956,19 @@ void mglCanvas::Table(mreal x, mreal y, HCDT val, const wchar_t *text, const cha
        if(x<0) x=0;    if(y<0) y=0;    if(y>1) y=1;\r
 //     if(vw>1-x)      vw=1-x;\r
 \r
-       wchar_t *buf = new wchar_t[m*32], sng[32];\r
+       char fmt[8]="3",ss[2]=" ";\r
+       for(const char *s="0123456789";*s;s++)  if(mglchr(frm,*s))      fmt[0]=*s;\r
+       for(const char *s="f+E-F";*s;s++)       if(mglchr(frm,*s))\r
+       {       ss[0] = *s;     strcat(fmt,ss); }\r
        std::vector<std::wstring> str;\r
        for(i=0;i<n;i++)                // prepare list of strings first\r
        {\r
-               *buf=0;\r
+               std::wstring buf;\r
                for(j=0;j+1<m;j++)\r
-               {\r
-                       mglprintf(sng,32,L"%.3g\n",val->v(i,j));\r
-                       wcscat(buf,sng);\r
-               }\r
-               mglprintf(sng,32,L"%.3g",val->v(i,m-1));\r
-               wcscat(buf,sng);                str.push_back(buf);\r
+                       buf += mgl_ftoa(val->v(i,j),fmt)+L'\n';\r
+               buf += mgl_ftoa(val->v(i,m-1),fmt);\r
+               str.push_back(buf);\r
        }\r
-       delete []buf;\r
 \r
        mreal sp=2*TextWidth(" ",frm,-1), w=*text ? sp+TextWidth(text,frm,-1):0, w1=0, ww, h;\r
        for(i=0;i<n;i++)                // find width for given font size\r
@@ -878,11 +988,11 @@ void mglCanvas::Table(mreal x, mreal y, HCDT val, const wchar_t *text, const cha
        y = y*(inH-h*m)+B.y-inH/2;\r
 \r
        mglPoint p,q=mglPoint(NAN,NAN);\r
-       long k1,k2;\r
        mreal xx,yy;\r
        if(grid)        // draw bounding box\r
        {\r
                SetPenPal("k-");\r
+               long k1,k2;\r
                k1=AddPnt(&B,mglPoint(x,y,Depth),-1,q,-1,0);\r
                k2=AddPnt(&B,mglPoint(x,y+m*h,Depth),-1,q,-1,0);\r
                line_plot(k1,k2);\r
@@ -908,14 +1018,14 @@ void mglCanvas::Table(mreal x, mreal y, HCDT val, const wchar_t *text, const cha
        if(*text)\r
        {\r
                ww = TextWidth(text,frm,-1)+sp;\r
-               k1=AddPnt(&B,mglPoint(x+ww*align/2.,y+h*(m-0.99),Depth),-1,q,-1,0);\r
+               long k1=AddPnt(&B,mglPoint(x+ww*align/2.,y+h*(m-0.99),Depth),-1,q,-1,0);\r
                text_plot(k1,text,frm);\r
        }\r
        else    ww = 0;\r
        for(i=0,xx=x+ww,yy=y+h*(m-0.99);i<n;i++)        // draw lines and legend\r
        {\r
                ww = eqd ? w1:(TextWidth(str[i].c_str(),frm,-1)+sp);\r
-               k1=AddPnt(&B,mglPoint(xx+ww*align/2.,yy,Depth),-1,q,-1,0);\r
+               long k1=AddPnt(&B,mglPoint(xx+ww*align/2.,yy,Depth),-1,q,-1,0);\r
                text_plot(k1,str[i].c_str(),frm);       xx += ww;\r
        }\r
        FontSize = fsize;       EndGroup();\r
@@ -932,18 +1042,18 @@ void mglCanvas::Title(const wchar_t *title,const char *stl,mreal size)
        mreal s = size>0 ? size/FontSize:-size, h=TextHeight(stl,size)*s/2;\r
        if(h>=inH)      {       SetWarn(mglWarnSpc,"Title");    return; }\r
        static int cgid=1;      StartGroup("Title",cgid++);\r
-       bool box=mglchr(stl,'#');\r
        int align;\r
-       char col = mglGetStyle(stl,0,&align);   align = align&3;\r
-       if(col==0)      col = 'k';\r
+       bool box=mglchr(stl,'#'), col = mglGetStyle(stl,0,&align);\r
+       align = align&3;\r
        mreal y=inY+inH-h;\r
        mglPoint p(inX + inW*align/2.,y,3*Depth),q(NAN,NAN,NAN);\r
        mglMatrix M=B;  M.norot=true;\r
        if(title)       text_plot(AddPnt(&M,p,-1,q,-1,0),title,stl,size);\r
        if(box) //      draw boungind box\r
        {\r
-               mreal c1=AddTexture('w'), c2=AddTexture(col);\r
-               if((Flag&3)==2) {       mreal cc=c1;    c2=c1;  c1=cc;  }\r
+               mreal c1=AddTexture('w'), c2=col?AddTexture(stl):AddTexture('k');\r
+               if((Flag&3)==2 && !col) {       mreal cc=c1;    c2=c1;  c1=cc;  }\r
+               else if((Flag&3)==2)    c1=AddTexture('k');\r
                long k1,k2,k3,k4;\r
                k1=AddPnt(&M,mglPoint(inX,y-h*0.4,3*Depth),c1,q,-1,0);\r
                k2=AddPnt(&M,mglPoint(inX+inW,y-h*0.4,3*Depth),c1,q,-1,0);\r
@@ -981,8 +1091,8 @@ void mglCanvas::EndGroup()
        LoadState();\r
        if(Quality&MGL_DRAW_LMEM)\r
        {\r
-               Pnt.clear();            Prm.clear();            Ptx.clear();\r
-               Glf.clear();            Act.clear();    Grp.clear();\r
+               Pnt.clear();    Prm.clear();    Ptx.clear();    ClearPrmInd();\r
+               Glf.clear();    Act.clear();    Grp.clear();\r
        }\r
        if(grp_counter>0)       grp_counter--;\r
 }\r
index 7cc3a29b8cc74b93e4f54e4ebc2e6d67b99c9f57..07ef15dcf8a5cfd2dd7987fedb17cfa7914f4cac 100644 (file)
@@ -29,6 +29,8 @@ MGL_EXPORT const unsigned char *mgl_get_rgb(HMGL gr)
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   return g?g->GetBits():0;        }\r
 MGL_EXPORT const unsigned char *mgl_get_rgba(HMGL gr)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   return g?g->GetRGBA():0;        }\r
+MGL_EXPORT const unsigned char* mgl_get_background(HMGL gr)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   return g?g->GetBackground():0;  }\r
 int MGL_EXPORT mgl_get_width(HMGL gr)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   return g?g->GetWidth():0;       }\r
 int MGL_EXPORT mgl_get_height(HMGL gr)\r
@@ -41,12 +43,12 @@ void MGL_EXPORT mgl_calc_scr(HMGL gr, double x, double y, double z, int *xs, int
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->CalcScr(mglPoint(x,y,z),xs,ys);      }\r
 void MGL_EXPORT mgl_set_obj_id(HMGL gr, int id)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetObjId(id);        }\r
-int MGL_EXPORT mgl_get_obj_id(HMGL gr, int x, int y)\r
+int MGL_EXPORT_PURE mgl_get_obj_id(HMGL gr, int x, int y)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   return g?g->GetObjId(x,y):-1;   }\r
-int MGL_EXPORT mgl_get_spl_id(HMGL gr, int x, int y)\r
+int MGL_EXPORT_PURE mgl_get_spl_id(HMGL gr, int x, int y)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   return g?g->GetSplId(x,y):-1;   }\r
 //-----------------------------------------------------------------------------\r
-long MGL_EXPORT mgl_is_active(HMGL gr, int xs, int ys, int d)\r
+long MGL_EXPORT_PURE mgl_is_active(HMGL gr, int xs, int ys, int d)\r
 {\r
        if(d<=0)        d=1;\r
        for(size_t i=0;i<gr->Act.size();i++)\r
@@ -56,14 +58,14 @@ long MGL_EXPORT mgl_is_active(HMGL gr, int xs, int ys, int d)
        }\r
        return -1;\r
 }\r
-long MGL_EXPORT mgl_is_active_(uintptr_t *gr, int *xs, int *ys, int *d)\r
+long MGL_EXPORT_PURE mgl_is_active_(uintptr_t *gr, int *xs, int *ys, int *d)\r
 {      return mgl_is_active(_GR_, *xs, *ys, *d);       }\r
 //-----------------------------------------------------------------------------\r
 int MGL_EXPORT mgl_new_frame(HMGL gr)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   return g?g->NewFrame():-1;      }\r
 void MGL_EXPORT mgl_end_frame(HMGL gr)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->EndFrame();  }\r
-int MGL_EXPORT mgl_get_num_frame(HMGL gr)\r
+int MGL_EXPORT_PURE mgl_get_num_frame(HMGL gr)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   return g?g->GetNumFrame():0;    }\r
 void MGL_EXPORT mgl_reset_frames(HMGL gr)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->ResetFrames();       }\r
@@ -75,6 +77,8 @@ void MGL_EXPORT mgl_show_frame(HMGL gr, int i)
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->ShowFrame(i);        }\r
 void MGL_EXPORT mgl_del_frame(HMGL gr, int i)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->DelFrame(i); }\r
+void MGL_EXPORT mgl_clear_frame(HMGL gr)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->ClearFrame();        }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_set_transp_type(HMGL gr, int type)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetTranspType(type); }\r
@@ -103,6 +107,10 @@ void MGL_EXPORT mgl_clf_chr(HMGL gr, char ch)
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->Clf(mglColor(ch));   }\r
 void MGL_EXPORT mgl_clf_rgb(HMGL gr, double r, double g, double b)\r
 {      mglCanvas *gg = dynamic_cast<mglCanvas *>(gr);  if(gg)  gg->Clf(mglColor(r,g,b));       }\r
+void MGL_EXPORT mgl_clf_str(HMGL gr, const char *col)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->Clf(col);    }\r
+void MGL_EXPORT mgl_load_background(HMGL gr, const char *fn, double alpha)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->LoadBackground(fn,alpha);    }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_subplot_d(HMGL gr, int nx,int ny,int m,const char *style,double dx,double dy)\r
 {\r
@@ -139,7 +147,7 @@ void MGL_EXPORT mgl_columnplot(HMGL gr, int num, int i, double dd)
 {\r
        register double w = 1./num;\r
        mglCanvas *g = dynamic_cast<mglCanvas *>(gr);\r
-       if(g)   g->InPlot(0,1,1-w*(i+1-dd),1-i*w,true);\r
+       if(g)   g->InPlot(0,1,1-w*(i+1-dd/2),1-(i+dd/2)*w,true);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_gridplot(HMGL gr, int nx, int ny, int i, double dd)\r
@@ -147,10 +155,8 @@ void MGL_EXPORT mgl_gridplot(HMGL gr, int nx, int ny, int i, double dd)
        register int ix=i%nx, iy=i/nx;\r
        register double wx = 1./nx, wy = 1./ny;\r
        mglCanvas *g = dynamic_cast<mglCanvas *>(gr);\r
-       if(g)   g->InPlot(ix*wx,wx*(ix+1-dd),1-wy*(iy+1-dd),1-iy*wy,true);\r
+       if(g)   g->InPlot((ix+dd/2)*wx,wx*(ix+1-dd/2),1-wy*(iy+1-dd/2),1-(iy+dd/2)*wy,true);\r
 }\r
-void MGL_EXPORT mgl_gridplot_(uintptr_t *gr, int *nx, int *ny, int *m, mreal *d)\r
-{      mgl_gridplot(_GR_,*nx,*ny,*m,*d);       }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_stickplot(HMGL gr, int num, int i, double tet, double phi)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->StickPlot(num, i, tet, phi); }\r
@@ -167,19 +173,22 @@ void MGL_EXPORT mgl_rotate_vector(HMGL gr, double Tet,double x,double y,double z
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->RotateN(Tet,x,y,z);  }\r
 void MGL_EXPORT mgl_perspective(HMGL gr, double val)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->Perspective(val);    }\r
+void MGL_EXPORT mgl_ask_perspective(HMGL gr, double val)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->Perspective(val,false);      }\r
 void MGL_EXPORT mgl_title(HMGL gr, const char *title, const char *stl, double size)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->Title(title,stl,size);       }\r
 void MGL_EXPORT mgl_titlew(HMGL gr, const wchar_t *title, const char *stl, double size)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->Title(title,stl,size);       }\r
 //-----------------------------------------------------------------------------\r
-int MGL_EXPORT mgl_new_frame_(uintptr_t *gr)           {       return _GR_->NewFrame();        }\r
-void MGL_EXPORT mgl_end_frame_(uintptr_t *gr)          {       _GR_->EndFrame();       }\r
-int MGL_EXPORT mgl_get_num_frame_(uintptr_t *gr)       {       return _GR_->GetNumFrame();     }\r
+int MGL_EXPORT mgl_new_frame_(uintptr_t *gr)   {       return _GR_->NewFrame();        }\r
+void MGL_EXPORT mgl_end_frame_(uintptr_t *gr)  {       _GR_->EndFrame();       }\r
+int MGL_EXPORT_PURE mgl_get_num_frame_(uintptr_t *gr)  {       return _GR_->GetNumFrame();     }\r
 void MGL_EXPORT mgl_reset_frames_(uintptr_t *gr)       {       _GR_->ResetFrames();    }\r
 void MGL_EXPORT mgl_get_frame_(uintptr_t *gr, int *i)  {       _GR_->GetFrame(*i);     }\r
 void MGL_EXPORT mgl_set_frame_(uintptr_t *gr, int *i)  {       _GR_->SetFrame(*i);     }\r
-void MGL_EXPORT mgl_show_frame_(uintptr_t *gr, int *i) {       _GR_->ShowFrame(*i);    }\r
+void MGL_EXPORT mgl_show_frame_(uintptr_t *gr, int *i) {       _GR_->ShowFrame(*i);}\r
 void MGL_EXPORT mgl_del_frame_(uintptr_t *gr, int *i)  {       _GR_->DelFrame(*i);     }\r
+void MGL_EXPORT mgl_clear_frame_(uintptr_t *gr)                        {       _GR_->ClearFrame();     }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_set_transp_type_(uintptr_t *gr, int *type)         {       _GR_->SetTranspType(*type);     }\r
 void MGL_EXPORT mgl_set_alpha_(uintptr_t *gr, int *enable)                     {       _GR_->Alpha(*enable);   }\r
@@ -196,12 +205,17 @@ void MGL_EXPORT mgl_add_light_loc_(uintptr_t *gr, int *n, mreal *x, mreal *y, mr
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_mat_push_(uintptr_t *gr)   {       _GR_->Push();   }\r
 void MGL_EXPORT mgl_mat_pop_(uintptr_t *gr)    {       _GR_->Pop();    }\r
-void MGL_EXPORT mgl_clf_(uintptr_t *gr)\r
-{      _GR_->Clf();    }\r
+void MGL_EXPORT mgl_clf_(uintptr_t *gr)                {       _GR_->Clf();    }\r
 void MGL_EXPORT mgl_clf_chr_(uintptr_t *gr, const char *ch, int)\r
 {      _GR_->Clf(mglColor(*ch));       }\r
 void MGL_EXPORT mgl_clf_rgb_(uintptr_t *gr, mreal *r, mreal *g, mreal *b)\r
 {      _GR_->Clf(mglColor(*r,*g,*b));  }\r
+void MGL_EXPORT mgl_clf_str_(uintptr_t *gr, const char *col, int l)\r
+{      char *s=new char[l+1];  memcpy(s,col,l);        s[l]=0;\r
+       mgl_clf_str(_GR_,s);    delete []s;     }\r
+void MGL_EXPORT mgl_load_background_(uintptr_t *gr, const char *fn, mreal *a, int l)\r
+{      char *s=new char[l+1];  memcpy(s,fn,l); s[l]=0;\r
+       mgl_load_background(_GR_,s,*a); delete []s;     }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_subplot_d_(uintptr_t *gr, int *nx,int *ny,int *m,const char *st, mreal *dx, mreal *dy,int l)\r
 {      char *s=new char[l+1];  memcpy(s,st,l); s[l]=0;\r
@@ -218,7 +232,7 @@ void MGL_EXPORT mgl_relplot_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mre
 {      _GR_->InPlot(*x1,*x2,*y1,*y2,true);     }\r
 void MGL_EXPORT mgl_columnplot_(uintptr_t *gr, int *num, int *i, mreal *d)\r
 {      mgl_columnplot(_GR_,*num,*i,*d);        }\r
-void MGL_EXPORT mgl_columnplot_d_(uintptr_t *gr, int *nx, int *ny, int *i, mreal *d)\r
+void MGL_EXPORT mgl_gridplot_(uintptr_t *gr, int *nx, int *ny, int *i, mreal *d)\r
 {      mgl_gridplot(_GR_,*nx,*ny,*i,*d);       }\r
 void MGL_EXPORT mgl_stickplot_(uintptr_t *gr, int *num, int *i, mreal *tet, mreal *phi)\r
 {      _GR_->StickPlot(*num, *i, *tet, *phi);  }\r
@@ -237,11 +251,14 @@ void MGL_EXPORT mgl_zoom_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *x2, mreal
 {      _GR_->Zoom(*x1,*y1,*x2,*y2);    }\r
 void MGL_EXPORT mgl_rotate_vector_(uintptr_t *gr, mreal *Tet, mreal *x, mreal *y, mreal *z)\r
 {      _GR_->RotateN(*Tet,*x,*y,*z);   }\r
-void MGL_EXPORT mgl_perspective_(uintptr_t *gr, double val)\r
-{      _GR_->Perspective(val); }\r
+void MGL_EXPORT mgl_perspective_(uintptr_t *gr, mreal *val)\r
+{      _GR_->Perspective(*val);        }\r
+void MGL_EXPORT mgl_ask_perspective_(uintptr_t *gr, mreal *val)\r
+{      mgl_ask_perspective(_GR_,*val); }\r
 //-----------------------------------------------------------------------------\r
 MGL_EXPORT const unsigned char *mgl_get_rgb_(uintptr_t *gr)    {       return gr ? _GR_->GetBits():0;  }\r
 MGL_EXPORT const unsigned char *mgl_get_rgba_(uintptr_t *gr){  return gr ? _GR_->GetRGBA():0;  }\r
+MGL_EXPORT const unsigned char* mgl_get_background_(uintptr_t* gr)     {       return gr ? _GR_->GetBackground():0;    }\r
 int MGL_EXPORT mgl_get_width_(uintptr_t *gr)   {       return gr ? _GR_->GetWidth():0; }\r
 int MGL_EXPORT mgl_get_height_(uintptr_t *gr)  {       return gr ? _GR_->GetHeight():0;}\r
 void MGL_EXPORT mgl_calc_xyz_(uintptr_t *gr, int *xs, int *ys, mreal *x, mreal *y, mreal *z)\r
@@ -249,8 +266,8 @@ void MGL_EXPORT mgl_calc_xyz_(uintptr_t *gr, int *xs, int *ys, mreal *x, mreal *
 void MGL_EXPORT mgl_calc_scr_(uintptr_t *gr, mreal *x, mreal *y, mreal *z, int *xs, int *ys)\r
 {      _GR_->CalcScr(mglPoint(*x,*y,*z),xs,ys);        }\r
 void MGL_EXPORT mgl_set_obj_id_(uintptr_t *gr, int *id)                {       _GR_->SetObjId(*id);    }\r
-int MGL_EXPORT mgl_get_obj_id_(uintptr_t *gr, int *x, int *y)  {       return _GR_->GetObjId(*x,*y);   }\r
-int MGL_EXPORT mgl_get_spl_id_(uintptr_t *gr, int *x, int *y)  {       return _GR_->GetSplId(*x,*y);   }\r
+int MGL_EXPORT_PURE mgl_get_obj_id_(uintptr_t *gr, int *x, int *y)     {       return _GR_->GetObjId(*x,*y);   }\r
+int MGL_EXPORT_PURE mgl_get_spl_id_(uintptr_t *gr, int *x, int *y)     {       return _GR_->GetSplId(*x,*y);   }\r
 //-----------------------------------------------------------------------------\r
 HMGL MGL_EXPORT mgl_create_graph(int width, int height)\r
 {      return new mglCanvas(width,height);     }\r
@@ -270,9 +287,15 @@ void MGL_EXPORT mgl_set_axis_stl(HMGL gr, const char *stl, const char *tck, cons
 void MGL_EXPORT mgl_tune_ticks(HMGL gr, int tune, double pos)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetTuneTicks(tune,pos);      }\r
 void MGL_EXPORT mgl_adjust_ticks(HMGL gr, const char *dir)\r
-{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->AdjustTicks(dir,true);       }\r
+{      mgl_adjust_ticks_ext(gr,dir,"");        }\r
+void MGL_EXPORT mgl_adjust_ticks_ext(HMGL gr, const char *dir, const char *stl)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->AdjustTicks(dir,true,stl);   }\r
 void MGL_EXPORT mgl_set_ticks(HMGL gr, char dir, double d, int ns, double org)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetTicks(dir,d,ns,org);      }\r
+void MGL_EXPORT mgl_set_ticks_factw(HMGL gr, char dir, double d, int ns, double org, const wchar_t *fact)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetTicks(dir,d,ns,org,fact); }\r
+void MGL_EXPORT mgl_set_ticks_fact(HMGL gr, char dir, double d, int ns, double org, const char *fact)\r
+{      MGL_TO_WCS(fact,mgl_set_ticks_factw(gr,dir,d,ns,org,wcs));      }\r
 void MGL_EXPORT mgl_set_ticks_str(HMGL gr, char dir, const char *lbl, int add)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetTicksVal(dir,lbl,add);    }\r
 void MGL_EXPORT mgl_set_ticks_wcs(HMGL gr, char dir, const wchar_t *lbl, int add)\r
@@ -281,6 +304,10 @@ void MGL_EXPORT mgl_set_ticks_val(HMGL gr, char dir, HCDT val, const char *lbl,
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetTicksVal(dir,val,lbl,add);        }\r
 void MGL_EXPORT mgl_set_ticks_valw(HMGL gr, char dir, HCDT val, const wchar_t *lbl, int add)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetTicksVal(dir,val,lbl,add);        }\r
+void MGL_EXPORT mgl_add_tick(HMGL gr, char dir, double val, const char *lbl)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->AddTick(dir,val,lbl);        }\r
+void MGL_EXPORT mgl_add_tickw(HMGL gr, char dir, double val, const wchar_t *lbl)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->AddTick(dir,val,lbl);        }\r
 void MGL_EXPORT mgl_set_tick_templ(HMGL gr, char dir, const char *templ)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetTickTempl(dir,templ);     }\r
 void MGL_EXPORT mgl_set_tick_templw(HMGL gr, char dir, const wchar_t *templ)\r
@@ -332,6 +359,9 @@ void MGL_EXPORT mgl_set_def_param_(uintptr_t *gr)   {       _GR_->DefaultPlotParam();       }
 void MGL_EXPORT mgl_combine_gr_(uintptr_t *gr, uintptr_t *in)\r
 {      _GR_->Combine((mglCanvas *)in); }\r
 //-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_set_ticks_fact_(uintptr_t *gr, char *dir, double *d, int *ns, double *org, const char *fact,int,int l)\r
+{      char *s=new char[l+1];  memcpy(s,fact,l);       s[l]=0;\r
+       mgl_set_ticks_fact(_GR_,*dir,*d,*ns,*org,s);    delete []s;     }\r
 void MGL_EXPORT mgl_set_tick_len_(uintptr_t *gr, mreal *len, mreal *stt)\r
 {      _GR_->SetTickLen(*len, *stt);   }\r
 void MGL_EXPORT mgl_set_axis_stl_(uintptr_t *gr, const char *stl, const char *tck, const char *sub, int l,int m,int n)\r
@@ -341,7 +371,11 @@ void MGL_EXPORT mgl_set_axis_stl_(uintptr_t *gr, const char *stl, const char *tc
        _GR_->SetAxisStl(a,t,s);        delete []a;     delete []s;     delete []t;     }\r
 void MGL_EXPORT mgl_adjust_ticks_(uintptr_t *gr, const char *dir, int l)\r
 {      char *s=new char[l+1];  memcpy(s,dir,l);        s[l]=0;\r
-       _GR_->AdjustTicks(s);   delete []s;     }\r
+       _GR_->AdjustTicks(s,true);      delete []s;     }\r
+void MGL_EXPORT mgl_adjust_ticks_(uintptr_t *gr, const char *dir, const char *stl, int l, int m)\r
+{      char *s=new char[l+1];  memcpy(s,dir,l);        s[l]=0;\r
+       char *f=new char[m+1];  memcpy(f,stl,m);        f[m]=0;\r
+       _GR_->AdjustTicks(s,true,f);    delete []s;     delete []f;     }\r
 void MGL_EXPORT mgl_set_ticks_(uintptr_t *gr, char *dir, mreal *d, int *ns, mreal *org, int)\r
 {      _GR_->SetTicks(*dir, *d, *ns, *org);    }\r
 void MGL_EXPORT mgl_set_ticks_str_(uintptr_t *gr, const char *dir, const char *lbl, int *add,int,int l)\r
@@ -350,6 +384,9 @@ void MGL_EXPORT mgl_set_ticks_str_(uintptr_t *gr, const char *dir, const char *l
 void MGL_EXPORT mgl_set_ticks_val_(uintptr_t *gr, const char *dir, uintptr_t *val, const char *lbl, int *add,int,int l)\r
 {      char *s=new char[l+1];  memcpy(s,lbl,l);        s[l]=0;\r
        _GR_->SetTicksVal(*dir,_DA_(val),s,*add);       delete []s;     }\r
+void MGL_EXPORT mgl_add_tick_(uintptr_t *gr, const char *dir, mreal *val, const char *lbl, int *add,int,int l)\r
+{      char *s=new char[l+1];  memcpy(s,lbl,l);        s[l]=0;\r
+       mgl_add_tick(_GR_,*dir,*val,s); delete []s;     }\r
 void MGL_EXPORT mgl_tune_ticks_(uintptr_t *gr, int *tune, mreal *fact_pos)\r
 {      _GR_->SetTuneTicks(*tune, *fact_pos);   }\r
 void MGL_EXPORT mgl_set_tick_templ_(uintptr_t *gr, const char *dir, const char *templ,int,int l)\r
@@ -409,10 +446,10 @@ void MGL_EXPORT mgl_set_legend_marks_(uintptr_t *gr, int *num)
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_wnd_set_delay(HMGL gr, double dt)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetDelay(dt);        }\r
-double MGL_EXPORT mgl_wnd_get_delay(HMGL gr)\r
+double MGL_EXPORT_PURE mgl_wnd_get_delay(HMGL gr)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   return g?g->GetDelay():0;       }\r
 void MGL_EXPORT mgl_wnd_set_delay_(uintptr_t *gr, mreal *dt)   {       _GR_->SetDelay(*dt);    }\r
-double MGL_EXPORT mgl_wnd_get_delay_(uintptr_t *gr)    {       return _GR_->GetDelay();        }\r
+double MGL_EXPORT_PURE mgl_wnd_get_delay_(uintptr_t *gr)       {       return _GR_->GetDelay();        }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_set_plotfactor(HMGL gr, double val)\r
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->SetPlotFactor(val);  }\r
@@ -435,3 +472,7 @@ void MGL_EXPORT mgl_finish(HMGL gr)
 {      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->Finish();    }\r
 void MGL_EXPORT mgl_finish_(uintptr_t *gr)     {       _GR_->Finish(); }\r
 //-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_rasterize(HMGL gr)\r
+{      mglCanvas *g = dynamic_cast<mglCanvas *>(gr);   if(g)   g->Rasterize(); }\r
+void MGL_EXPORT mgl_rasterize_(uintptr_t *gr)  {       _GR_->Rasterize();      }\r
+//-----------------------------------------------------------------------------\r
index 8b43c3c84effaf0b9d5dc255d21af47b386ddf17..46f77bbe7eef5289fc59e48712d2f4693b288f42 100644 (file)
@@ -85,7 +85,11 @@ void MGL_EXPORT mglStartThreadV(void *(*func)(void *), long n, dual *a, const vo
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_EXPORT mgl_expi(dual a)       {       return exp(dual(0,1)*a);        }\r
+mdual MGL_EXPORT_CONST mgl_expi(dual a)\r
+{\r
+       dual r = exp(dual(0,1)*dual(a));\r
+       return r.real()+r.imag()*_Complex_I;\r
+}\r
 //-----------------------------------------------------------------------------\r
 MGL_NO_EXPORT void *mgl_csmth_x(void *par)\r
 {\r
@@ -637,45 +641,49 @@ void MGL_EXPORT mgl_datac_mirror_(uintptr_t *d, const char *dir,int l)
 {      char *s=new char[l+1];  memcpy(s,dir,l);        s[l]=0;\r
        mgl_datac_mirror(_DC_,s);       delete []s;     }\r
 //-----------------------------------------------------------------------------\r
-dual mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx, dual *dy, dual *dz)\r
+dual MGL_EXPORT_PURE mglSpline3Cs(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)\r
+{      return mglSpline3st<dual>(a,nx,ny,nz,x,y,z);    }\r
+//-----------------------------------------------------------------------------\r
+dual MGL_EXPORT_PURE mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx, dual *dy, dual *dz)\r
 {      return mglSpline3t<dual>(a,nx,ny,nz,x,y,z,dx,dy,dz);    }\r
 //-----------------------------------------------------------------------------\r
-dual mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)\r
+dual MGL_EXPORT_PURE mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)\r
 {      return mglLineart<dual>(a,nx,ny,nz,x,y,z);      }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_EXPORT mgl_datac_spline(HCDT d, mreal x,mreal y,mreal z)\r
+mdual MGL_EXPORT_PURE mgl_datac_spline(HCDT d, mreal x,mreal y,mreal z)\r
 {\r
        const mglDataC *dd=dynamic_cast<const mglDataC *>(d);\r
-       if(!dd) return mgl_data_spline(d,x,y,z);\r
-       return dd->ny*dd->nz==1?mglSpline1st<dual>(dd->a,dd->nx,x):mglSpline3st<dual>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z);\r
+       dual r = dd ? mglSpline3st<dual>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z) : mgl_data_spline(d,x,y,z);\r
+       return r.real()+r.imag()*_Complex_I;\r
 }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_EXPORT mgl_datac_spline_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz)\r
+mdual MGL_EXPORT_PURE mgl_datac_spline_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz)\r
 {\r
        const mglDataC *dd=dynamic_cast<const mglDataC *>(d);\r
        if(!dd)\r
        {\r
-               mreal rx,ry,rz,res;\r
+               mreal rx=0,ry=0,rz=0,res;\r
                res=mgl_data_spline_ext(d,x,y,z,&rx,&ry,&rz);\r
                if(dx)  *dx=rx; if(dy)  *dy=ry; if(dz)  *dz=rz;\r
                return res;\r
        }\r
-       return mglSpline3t<dual>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z,dx,dy,dz);\r
+       dual r = mglSpline3t<dual>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z,dx,dy,dz);\r
+       return r.real()+r.imag()*_Complex_I;\r
 }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_EXPORT mgl_datac_spline_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
+mdual MGL_EXPORT_PURE mgl_datac_spline_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
 {      return mgl_datac_spline(_DA_(d),*x,*y,*z);      }\r
-dual MGL_EXPORT mgl_datac_spline_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz)\r
+mdual MGL_EXPORT_PURE mgl_datac_spline_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz)\r
 {      return mgl_datac_spline_ext(_DA_(d),*x,*y,*z,dx,dy,dz); }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_EXPORT mgl_datac_linear_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz)\r
+mdual MGL_EXPORT_PURE mgl_datac_linear_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz)\r
 {\r
        long kx=long(x), ky=long(y), kz=long(z);\r
        dual b0,b1;\r
        const mglDataC *dd=dynamic_cast<const mglDataC *>(d);\r
        if(!dd)\r
        {\r
-               mreal rx,ry,rz,res;\r
+               mreal rx=0,ry=0,rz=0,res;\r
                res=mgl_data_linear_ext(d,x,y,z,&rx,&ry,&rz);\r
                if(dx)  *dx=rx; if(dy)  *dy=ry; if(dz)  *dz=rz;\r
                return res;\r
@@ -710,15 +718,15 @@ dual MGL_EXPORT mgl_datac_linear_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,d
        if(dx)  *dx = kx>=0?aa[1]-aa[0]:0;\r
        if(dy)  *dy = ky>=0?aa[dn]-aa[0]:0;\r
        if(dz)  *dz = b1-b0;\r
-\r
-       return b0 + z*(b1-b0);\r
+       dual r = b0 + z*(b1-b0);\r
+       return r.real()+r.imag()*_Complex_I;\r
 }\r
-dual MGL_EXPORT mgl_datac_linear(HCDT d, mreal x,mreal y,mreal z)\r
+mdual MGL_EXPORT_PURE mgl_datac_linear(HCDT d, mreal x,mreal y,mreal z)\r
 {      return mgl_datac_linear_ext(d, x,y,z, 0,0,0);   }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_EXPORT mgl_datac_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
+mdual MGL_EXPORT_PURE mgl_datac_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
 {      return mgl_datac_linear(_DA_(d),*x,*y,*z);      }\r
-dual MGL_EXPORT mgl_datac_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz)\r
+mdual MGL_EXPORT_PURE mgl_datac_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz)\r
 {      return mgl_datac_linear_ext(_DA_(d),*x,*y,*z,dx,dy,dz); }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_datac_crop(HADT d, long n1, long n2, char dir)\r
@@ -801,7 +809,7 @@ void MGL_EXPORT mgl_datac_insert(HADT d, char dir, long at, long num)
                if(at<nz)       memcpy(b.a+nx*ny*(at+num), d->a+nx*ny*at,(nz-at)*nx*ny*sizeof(dual));\r
 #pragma omp parallel for\r
                for(long i=0;i<num;i++) memcpy(b.a+nx*ny*(at+i),d->a+nx*ny*at,nx*ny*sizeof(dual));\r
-               d->Set(b);      nz+=num;\r
+               d->Set(b);\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -840,7 +848,7 @@ void MGL_EXPORT mgl_datac_delete(HADT d, char dir, long at, long num)
                b.Create(nx,ny,nz-num);\r
                if(at>0)        memcpy(b.a, d->a,at*nx*ny*sizeof(dual));\r
                memcpy(b.a+nx*ny*at, d->a+nx*ny*(at+num),(nz-at-num)*nx*ny*sizeof(dual));\r
-               d->Set(b);      nz-=num;\r
+               d->Set(b);\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -857,17 +865,19 @@ void MGL_EXPORT mgl_datac_set_value(HADT dat, dual v, long i, long j, long k)
 void MGL_EXPORT mgl_datac_set_value_(uintptr_t *d, dual *v, int *i, int *j, int *k)\r
 {      mgl_datac_set_value(_DC_,*v,*i,*j,*k);  }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_EXPORT mgl_datac_get_value(HCDT dat, long i, long j, long k)\r
+mdual MGL_EXPORT mgl_datac_get_value(HCDT dat, long i, long j, long k)\r
 {\r
-       if(i<0 || i>=dat->GetNx() || j<0 || j>=dat->GetNy() || k<0 || k>=dat->GetNz())\r
+       register long nx=dat->GetNx(), ny=dat->GetNy(), i0=i+nx*(j+ny*k);\r
+       if(i<0 || i>=nx || j<0 || j>=ny || k<0 || k>=dat->GetNz())\r
                return NAN;\r
        const mglDataC *d = dynamic_cast<const mglDataC*>(dat);\r
-       return d ? d->a[i+d->nx*(j+d->nz*k)] : dual(dat->v(i,j,k),0);\r
+       dual r = d ? d->a[i0] : dual(dat->vthr(i0),0);\r
+       return r.real()+r.imag()*_Complex_I;\r
 }\r
-dual MGL_EXPORT mgl_datac_get_value_(uintptr_t *d, int *i, int *j, int *k)\r
+mdual MGL_EXPORT mgl_datac_get_value_(uintptr_t *d, int *i, int *j, int *k)\r
 {      return mgl_datac_get_value(_DA_(d),*i,*j,*k);   }\r
 //-----------------------------------------------------------------------------\r
-MGL_EXPORT dual *mgl_datac_data(HADT dat)      {       return dat->a;  }\r
+MGL_EXPORT_PURE dual *mgl_datac_data(HADT dat) {       return dat->a;  }\r
 //-----------------------------------------------------------------------------\r
 MGL_EXPORT dual *mgl_datac_value(HADT dat, long i,long j,long k)\r
 {      register long ii=i*dat->nx*(j+dat->ny*k);\r
@@ -1123,3 +1133,55 @@ void MGL_EXPORT mgl_datac_diffr_(uintptr_t *d, const char *how, double q,int l)
 {      char *s=new char[l+1];  memcpy(s,how,l);        s[l]=0;\r
        mgl_datac_diffr(_DC_,s,q);      delete []s;     }\r
 //-----------------------------------------------------------------------------\r
+HADT MGL_EXPORT mgl_gsplinec_init(HCDT x, HCDT v)\r
+{\r
+       long n = v->GetNx();\r
+       if(!x || x->GetNx()!=n) return 0;\r
+       mglDataC *res = new mglDataC(5*(n-1));\r
+       mreal *xx=0;\r
+       dual *vv=0;\r
+       const mglData *dx = dynamic_cast<const mglData *>(x);\r
+       if(!dx)\r
+       {\r
+               xx = new mreal[n];\r
+               for(long i=0;i<n;i++)   xx[i] = x->v(i);\r
+       }\r
+       const mglDataC *dv = dynamic_cast<const mglDataC *>(v);\r
+       if(!dv)\r
+       {\r
+               vv = new dual[n];\r
+               for(long i=0;i<n;i++)   vv[i] = v->v(i);\r
+       }\r
+       mgl_gspline_init(n,dx?dx->a:xx,dv?dv->a:vv,res->a);\r
+       if(xx)  delete []xx;\r
+       if(vv)  delete []vv;\r
+       return res;\r
+}\r
+uintptr_t MGL_EXPORT mgl_gsplinec_init_(uintptr_t *x, uintptr_t *v)\r
+{      return uintptr_t(mgl_gspline_init(_DA_(x),_DA_(v)));    }\r
+//-----------------------------------------------------------------------------\r
+mdual MGL_EXPORT mgl_gsplinec(HCDT c, mreal dx, dual *d1, dual *d2)\r
+{\r
+       long i=0, n = c->GetNx();\r
+       if(n%5) return NAN;     // not the table of coefficients\r
+       while(dx>c->v(5*i) && i<n-1)    {       dx-=c->v(5*i);  i++;    }\r
+       dual res;\r
+       const mglDataC *d = dynamic_cast<const mglDataC *>(c);\r
+       if(c)\r
+       {\r
+               const dual *a = d->a+5*i;\r
+               if(d1)  *d1 = a[2]+dx*(mreal(2)*a[3]+(3*dx)*a[4]);\r
+               if(d2)  *d2 = mreal(2)*a[3]+(6*dx)*a[4];\r
+               res = a[1]+dx*(a[2]+dx*(a[3]+dx*a[4]));\r
+       }\r
+       else\r
+       {\r
+               if(d1)  *d1 = c->v(5*i+2)+dx*(2*c->v(5*i+3)+3*dx*c->v(5*i+4));\r
+               if(d2)  *d2 = 2*c->v(5*i+3)+6*dx*c->v(5*i+4);\r
+               res = c->v(5*i+1)+dx*(c->v(5*i+2)+dx*(c->v(5*i+3)+dx*c->v(5*i+4)));\r
+       }\r
+       return res.real()+res.imag()*_Complex_I;\r
+}\r
+mdual MGL_EXPORT mgl_gsplinec_(uintptr_t *c, mreal *dx, dual *d1, dual *d2)\r
+{      return mgl_gsplinec(_DA_(c),*dx,d1,d2); }\r
+//-----------------------------------------------------------------------------\r
diff --git a/src/complex_ex.cpp b/src/complex_ex.cpp
new file mode 100644 (file)
index 0000000..16bae00
--- /dev/null
@@ -0,0 +1,480 @@
+/***************************************************************************\r
+ * data_new.cpp is part of Math Graphic Library\r
+ * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU Library General Public License as       *\r
+ *   published by the Free Software Foundation; either version 3 of the    *\r
+ *   License, or (at your option) any later version.                       *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU Library General Public     *\r
+ *   License along with this program; if not, write to the                 *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+#include <ctype.h>\r
+#include "mgl2/datac.h"\r
+#include "mgl2/evalc.h"\r
+#include "mgl2/thread.h"\r
+#include "interp.hpp"\r
+mglDataC MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector<mglDataA*> &head);\r
+//-----------------------------------------------------------------------------\r
+HADT MGL_EXPORT mgl_datac_trace(HCDT d)\r
+{\r
+       long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();\r
+       const mglDataC *dc = dynamic_cast<const mglDataC *>(d);\r
+       mglDataC *r=new mglDataC(nx);\r
+       if(dc)\r
+       {\r
+               if(ny>=nx && nz>=nx)\r
+#pragma omp parallel for\r
+                       for(long i=0;i<nx;i++)  r->a[i] = dc->a[i+nx*(i+ny*i)];\r
+               else if(ny>=nx)\r
+#pragma omp parallel for\r
+                       for(long i=0;i<nx;i++)  r->a[i] = dc->a[i+nx*i];\r
+               else\r
+#pragma omp parallel for\r
+                       for(long i=0;i<nx;i++)  r->a[i] = dc->a[i];\r
+       }\r
+       else if(ny>=nx && nz>=nx)\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx;i++)  r->a[i] = d->v(i,i,i);\r
+       else if(ny>=nx)\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx;i++)  r->a[i] = d->v(i,i);\r
+       else\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx;i++)  r->a[i] = d->v(i);\r
+       return r;\r
+}\r
+uintptr_t MGL_EXPORT mgl_datac_trace_(uintptr_t *d)\r
+{      return uintptr_t(mgl_datac_trace(_DT_));        }\r
+//-----------------------------------------------------------------------------\r
+HADT MGL_EXPORT mgl_datac_subdata_ext(HCDT d, HCDT xx, HCDT yy, HCDT zz)\r
+{\r
+       if(!xx || !yy || !zz)\r
+       {\r
+               mglData tmp;    tmp.a[0]=-1;\r
+               return mgl_datac_subdata_ext(d,xx?xx:&tmp,yy?yy:&tmp,zz?zz:&tmp);\r
+       }\r
+       \r
+       long n=0,m=0,l=0,j,k;\r
+       bool ix=false, iy=false, iz=false;\r
+       if(xx->GetNz()>1)       // 3d data\r
+       {\r
+               n = xx->GetNx();        m = xx->GetNy();        l = xx->GetNz();\r
+               j = yy->GetNN();        if(j>1 && j!=n*m*l)     return 0;       // wrong sizes\r
+               k = zz->GetNN();        if(k>1 && k!=n*m*l)     return 0;       // wrong sizes\r
+               ix = true;      iy = j>1;       iz = k>1;\r
+       }\r
+       else if(yy->GetNz()>1)\r
+       {\r
+               n = yy->GetNx();        m = yy->GetNy();        l = yy->GetNz();\r
+               j = xx->GetNN();        if(j>1 && j!=n*m*l)     return 0;       // wrong sizes\r
+               k = zz->GetNN();        if(k>1 && k!=n*m*l)     return 0;       // wrong sizes\r
+               iy = true;      ix = j>1;       iz = k>1;\r
+       }\r
+       else if(zz->GetNz()>1)\r
+       {\r
+               n = zz->GetNx();        m = zz->GetNy();        l = zz->GetNz();\r
+               j = yy->GetNN();        if(j>1 && j!=n*m*l)     return 0;       // wrong sizes\r
+               k = xx->GetNN();        if(k>1 && k!=n*m*l)     return 0;       // wrong sizes\r
+               iz = true;      iy = j>1;       ix = k>1;\r
+       }\r
+       else if(xx->GetNy()>1)  // 2d data\r
+       {\r
+               n = xx->GetNx();        m = xx->GetNy();        l = 1;\r
+               j = yy->GetNx()*yy->GetNy();    if(j>1 && j!=n*m)       return 0;       // wrong sizes\r
+               k = zz->GetNx()*zz->GetNy();    if(k>1 && k!=n*m)       return 0;       // wrong sizes\r
+               ix = true;      iy = j>1;       iz = k>1;\r
+       }\r
+       else if(yy->GetNy()>1)\r
+       {\r
+               n = yy->GetNx();        m = yy->GetNy();        l = 1;\r
+               j = xx->GetNx()*xx->GetNy();    if(j>1 && j!=n*m)       return 0;       // wrong sizes\r
+               k = zz->GetNx()*zz->GetNy();    if(k>1 && k!=n*m)       return 0;       // wrong sizes\r
+               iy = true;      ix = j>1;       iz = k>1;\r
+       }\r
+       else if(zz->GetNy()>1)\r
+       {\r
+               n = zz->GetNx();        m = zz->GetNy();        l = 1;\r
+               j = yy->GetNx()*yy->GetNy();    if(j>1 && j!=n*m)       return 0;       // wrong sizes\r
+               k = xx->GetNx()*xx->GetNy();    if(k>1 && k!=n*m)       return 0;       // wrong sizes\r
+               iz = true;      iy = j>1;       ix = k>1;\r
+       }\r
+       long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();\r
+       long vx=long(xx->v(0)), vy=long(yy->v(0)), vz=long(zz->v(0));\r
+       const mglDataC *dd = dynamic_cast<const mglDataC *>(d);\r
+       if(n*m*l>1)     // this is 2d or 3d data\r
+       {\r
+               mglDataV tx(n,m,l),ty(n,m,l),tz(n,m,l);\r
+               if(!ix) {       xx = &tx;       if(vx>=0)       tx.Fill(vx);    else tx.All();  }\r
+               if(!iy) {       yy = &ty;       if(vy>=0)       ty.Fill(vy);    else ty.All();  }\r
+               if(!iz) {       zz = &tz;       if(vz>=0)       tz.Fill(vz);    else tz.All();  }\r
+               mglDataC *r=new mglDataC(n,m,l);\r
+               if(dd)\r
+#pragma omp parallel for\r
+                       for(long i0=0;i0<n*m*l;i0++)\r
+                       {\r
+                               register long x=long(0.5+xx->vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0));\r
+                               r->a[i0] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?dd->a[x+nx*(y+ny*z)]:NAN;\r
+                       }\r
+               else\r
+#pragma omp parallel for\r
+                       for(long i0=0;i0<n*m*l;i0++)\r
+                       {\r
+                               register long x=long(0.5+xx->vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0));\r
+                               r->a[i0] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?d->v(x,y,z):NAN;\r
+                       }\r
+               return r;\r
+       }\r
+       // this is 1d data -> try as normal SubData()\r
+       mglDataV tx(nx),ty(ny),tz(nz);  tx.Fill(0,nx-1);        ty.Fill(0,ny-1);        tz.Fill(0,nz-1);\r
+       if(xx->GetNx()>1 || vx>=0)      n=xx->GetNx();  else    {       n=nx;   xx = &tx;       }\r
+       if(yy->GetNx()>1 || vy>=0)      m=yy->GetNx();  else    {       m=ny;   yy = &ty;       }\r
+       if(zz->GetNx()>1 || vz>=0)      l=zz->GetNx();  else    {       l=nz;   zz = &tz;       }\r
+       mglDataC *r=new mglDataC(n,m,l);\r
+       if(dd)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<l;k++)   for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
+               {\r
+                       register long x=long(0.5+xx->v(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k));\r
+                       r->a[i+n*(j+m*k)] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?dd->a[x+nx*(y+ny*z)]:NAN;\r
+               }\r
+       else\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<l;k++)   for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
+               {\r
+                       register long x=long(0.5+xx->v(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k));\r
+                       r->a[i+n*(j+m*k)] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?d->v(x,y,z):NAN;\r
+               }\r
+       if(m==1)        {       r->ny=r->nz;    r->nz=1;        }// "squeeze" dimensions\r
+       if(n==1)        {       r->nx=r->ny;    r->ny=r->nz;    r->nz=1;        r->NewId();}\r
+       return r;\r
+}\r
+//-----------------------------------------------------------------------------\r
+HADT MGL_EXPORT mgl_datac_subdata(HCDT d, long xx,long yy,long zz)\r
+{\r
+       long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), n=1,m=1,l=1;\r
+       int dx=0,dy=0,dz=0;\r
+       if(xx<0)        {       xx=0;   dx=1;   n=nx;   }\r
+       if(yy<0)        {       yy=0;   dy=1;   m=ny;   }\r
+       if(zz<0)        {       zz=0;   dz=1;   l=nz;   }\r
+       const mglDataC *dd = dynamic_cast<const mglDataC *>(d);\r
+       mglDataC *r=new mglDataC(n,m,l);\r
+       if(xx>=nx || yy>=ny || zz>=nz)\r
+#pragma omp parallel for\r
+               for(long i=0;i<n*m*l;i++)       r->a[i] = NAN;\r
+       else if(dd)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<l;k++)   for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
+                       r->a[i+n*(j+m*k)] = dd->a[xx+dx*i + nx*(yy+dy*j + ny*(zz+dz*k))];\r
+       else\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<l;k++)   for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
+                       r->a[i+n*(j+m*k)] = d->v(xx+dx*i, yy+dy*j, zz+dz*k);\r
+       if(m==1)        {       r->ny=r->nz;    r->nz=1;        }// "squeeze" dimensions\r
+       if(n==1)        {       r->nx=r->ny;    r->ny=r->nz;    r->nz=1;        r->NewId();}\r
+       return r;\r
+}\r
+//-----------------------------------------------------------------------------\r
+uintptr_t MGL_EXPORT mgl_datac_subdata_(uintptr_t *d, int *xx,int *yy,int *zz)\r
+{      return uintptr_t(mgl_datac_subdata(_DT_,*xx,*yy,*zz));  }\r
+uintptr_t MGL_EXPORT mgl_datac_subdata_ext_(uintptr_t *d, uintptr_t *xx, uintptr_t *yy, uintptr_t *zz)\r
+{      return uintptr_t(mgl_datac_subdata_ext(_DT_,_DA_(xx),_DA_(yy),_DA_(zz)));       }\r
+//-----------------------------------------------------------------------------\r
+MGL_NO_EXPORT void *mgl_cresize(void *par)\r
+{\r
+       mglThreadC *t=(mglThreadC *)par;\r
+       long nx=t->p[0]+0.1, ny=t->p[1]+0.1;\r
+       long n1=t->p[3]+0.1,n2=t->p[4]+0.1,n3=t->p[5]+0.1;\r
+       dual *b=t->a;\r
+       const dual *a=t->b;\r
+       const mreal *c=(const mreal *)t->v;\r
+#if !MGL_HAVE_PTHREAD\r
+#pragma omp parallel for\r
+#endif\r
+       for(long i0=t->id;i0<t->n;i0+=mglNumThr)\r
+       {\r
+               register mreal i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);\r
+               b[i0] = mglSpline3Cs(a,n1,n2,n3, c[0]+i*c[1], c[2]+j*c[3], c[4]+k*c[5]);\r
+       }\r
+       return 0;\r
+}\r
+HADT MGL_EXPORT mgl_datac_resize_box(HCDT dat, long mx,long my,long mz, mreal x1,mreal x2, mreal y1,mreal y2, mreal z1,mreal z2)\r
+{      // NOTE: only for mglDataC\r
+       const mglDataC *d=dynamic_cast<const mglDataC *>(dat);\r
+       if(!d)  return 0;\r
+       register long nx = d->nx-1, ny = d->ny-1, nz = d->nz-1;\r
+       mx = mx<1 ? nx+1:mx;    my = my<1 ? ny+1:my;    mz = mz<1 ? nz+1:mz;\r
+       mglDataC *r=new mglDataC(mx,my,mz);\r
+\r
+       mreal par[6]={nx*x1,0,ny*y1,0,nz*z1,0};\r
+       long nn[6]={mx,my,mz,nx+1,ny+1,nz+1};\r
+       if(mx>1)        par[1] = nx*(x2-x1)/(mx-1);\r
+       if(my>1)        par[3] = ny*(y2-y1)/(my-1);\r
+       if(mz>1)        par[5] = nz*(z2-z1)/(mz-1);\r
+       mglStartThreadC(mgl_cresize,0,mx*my*mz,r->a,d->a,0,nn,par);\r
+       return r;\r
+}\r
+HADT MGL_EXPORT mgl_datac_resize(HCDT d, long mx,long my,long mz)\r
+{      return mgl_datac_resize_box(d, mx,my,mz,0,1,0,1,0,1);   }\r
+uintptr_t MGL_EXPORT mgl_datac_resize_(uintptr_t *d, int *mx,int *my,int *mz)\r
+{      return uintptr_t(mgl_datac_resize(_DT_,*mx,*my,*mz));   }\r
+uintptr_t MGL_EXPORT mgl_datac_resize_box_(uintptr_t *d, int *mx,int *my,int *mz, mreal *x1,mreal *x2, mreal *y1,mreal *y2, mreal *z1,mreal *z2)\r
+{      return uintptr_t(mgl_datac_resize_box(_DT_,*mx,*my,*mz,*x1,*x2,*y1,*y2,*z1,*z2));       }\r
+//-----------------------------------------------------------------------------\r
+HADT MGL_EXPORT mgl_datac_combine(HCDT d1, HCDT d2)\r
+{\r
+       long n1=d1->GetNy(),n2=d2->GetNx(),nx=d1->GetNx();\r
+       if(d1->GetNz()>1 || (n1>1 && d2->GetNy()>1) || d2->GetNz()>1)   return 0;       // wrong dimensions\r
+       mglDataC *r=new mglDataC;\r
+       bool dim2=true;\r
+       if(n1==1)       {       n1=n2;  n2=d2->GetNy(); dim2 = false;   }\r
+       r->Create(nx,n1,n2);\r
+       if(dim2)        n1*=nx; else    {       n2*=n1; n1=nx;  }\r
+\r
+       const mglDataC *c1=dynamic_cast<const mglDataC *>(d1);\r
+       const mglDataC *c2=dynamic_cast<const mglDataC *>(d2);\r
+       if(c1 && c2)\r
+#pragma omp parallel for collapse(2)\r
+               for(long j=0;j<n2;j++)  for(long i=0;i<n1;i++)\r
+                       r->a[i+n1*j] = c1->a[i]*c2->a[j];\r
+       else if(c1)\r
+#pragma omp parallel for collapse(2)\r
+               for(long j=0;j<n2;j++)  for(long i=0;i<n1;i++)\r
+                       r->a[i+n1*j] = c1->a[i]*d2->vthr(j);\r
+       else if(c2)\r
+#pragma omp parallel for collapse(2)\r
+               for(long j=0;j<n2;j++)  for(long i=0;i<n1;i++)\r
+                       r->a[i+n1*j] = d1->vthr(i)*c2->a[j];\r
+       else\r
+#pragma omp parallel for collapse(2)\r
+               for(long j=0;j<n2;j++)  for(long i=0;i<n1;i++)\r
+                       r->a[i+n1*j] = d1->vthr(i)*d2->vthr(j);\r
+       return r;\r
+}\r
+uintptr_t MGL_EXPORT mgl_datac_combine_(uintptr_t *a, uintptr_t *b)\r
+{      return uintptr_t(mgl_datac_combine(_DA_(a),_DA_(b)));   }\r
+//-----------------------------------------------------------------------------\r
+MGL_NO_EXPORT void *mgl_sumc_z(void *par)\r
+{\r
+       mglThreadC *t=(mglThreadC *)par;\r
+       long nz=t->p[2], nn=t->n;\r
+       dual *b=t->a;\r
+       const dual *a=t->b;\r
+#if !MGL_HAVE_PTHREAD\r
+#pragma omp parallel for\r
+#endif\r
+       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       {\r
+               b[i]=0;\r
+               for(long j=0;j<nz;j++)  b[i] += a[i+nn*j];\r
+               b[i] /= nz;\r
+       }\r
+       return 0;\r
+}\r
+MGL_NO_EXPORT void *mgl_sumc_y(void *par)\r
+{\r
+       mglThreadC *t=(mglThreadC *)par;\r
+       long nx=t->p[0], ny=t->p[1], nn=t->n;\r
+       dual *b=t->a;\r
+       const dual *a=t->b;\r
+#if !MGL_HAVE_PTHREAD\r
+#pragma omp parallel for\r
+#endif\r
+       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       {\r
+               register long k = (i%nx)+nx*ny*(i/nx);  b[i]=0;\r
+               for(long j=0;j<ny;j++)  b[i] += a[k+nx*j];\r
+               b[i] /= ny;\r
+       }\r
+       return 0;\r
+}\r
+MGL_NO_EXPORT void *mgl_sumc_x(void *par)\r
+{\r
+       mglThreadC *t=(mglThreadC *)par;\r
+       long nx=t->p[0], nn=t->n;\r
+       dual *b=t->a;\r
+       const dual *a=t->b;\r
+#if !MGL_HAVE_PTHREAD\r
+#pragma omp parallel for\r
+#endif\r
+       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       {\r
+               register long k = i*nx; b[i]=0;\r
+               for(long j=0;j<nx;j++)  b[i] += a[j+k];\r
+               b[i] /= nx;\r
+       }\r
+       return 0;\r
+}\r
+HADT MGL_EXPORT mgl_datac_sum(HCDT dat, const char *dir)\r
+{\r
+       if(!dir || *dir==0)     return 0;\r
+       long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz();\r
+       long p[3]={nx,ny,nz};\r
+       dual *b = new dual[nx*ny*nz];\r
+       dual *c = new dual[nx*ny*nz];\r
+\r
+       const mglDataC *d=dynamic_cast<const mglDataC *>(dat);\r
+       if(d)   memcpy(c,d->a,nx*ny*nz*sizeof(dual));\r
+       else\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx*ny*nz;i++)    c[i]=dat->vthr(i);\r
+\r
+       if(strchr(dir,'z') && nz>1)\r
+       {\r
+               mglStartThreadC(mgl_sumc_z,0,nx*ny,b,c,0,p);\r
+               memcpy(c,b,nx*ny*sizeof(mreal));        p[2] = 1;\r
+       }\r
+       if(strchr(dir,'y') && ny>1)\r
+       {\r
+               mglStartThreadC(mgl_sumc_y,0,nx*p[2],b,c,0,p);\r
+               memcpy(c,b,nx*p[2]*sizeof(mreal));      p[1] = p[2];    p[2] = 1;\r
+       }\r
+       if(strchr(dir,'x') && nx>1)\r
+       {\r
+               mglStartThreadC(mgl_sumc_x,0,p[1]*p[2],b,c,0,p);\r
+               p[0] = p[1];    p[1] = p[2];    p[2] = 1;\r
+       }\r
+       mglDataC *r=new mglDataC(p[0],p[1],p[2]);\r
+       memcpy(r->a,b,p[0]*p[1]*p[2]*sizeof(dual));\r
+       delete []b;     delete []c;     return r;\r
+}\r
+uintptr_t MGL_EXPORT mgl_datac_sum_(uintptr_t *d, const char *dir,int l)\r
+{      char *s=new char[l+1];  memcpy(s,dir,l);        s[l]=0;\r
+       uintptr_t r=uintptr_t(mgl_datac_sum(_DT_,s));   delete []s;     return r;       }\r
+//-----------------------------------------------------------------------------\r
+HADT MGL_EXPORT mgl_datac_momentum(HCDT dat, char dir, const char *how)\r
+{\r
+       if(!how || !(*how) || !strchr("xyz",dir))       return 0;\r
+       long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz();\r
+       mglDataV x(nx,ny,nz, 0,1,'x');  x.s=L"x";\r
+       mglDataV y(nx,ny,nz, 0,1,'y');  y.s=L"y";\r
+       mglDataV z(nx,ny,nz, 0,1,'z');  z.s=L"z";\r
+       mglDataC u(dat);        u.s=L"u";       // NOTE slow !!!\r
+       std::vector<mglDataA*> list;\r
+       list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(&u);\r
+       mglDataC res=mglFormulaCalcC(how,list);\r
+\r
+       mglDataC *b=0;\r
+       if(dir=='x')\r
+       {\r
+               b=new mglDataC(nx);\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx;i++)\r
+               {\r
+                       register dual i1=0,i0=0;\r
+                       for(long j=0;j<ny*nz;j++)\r
+                       {\r
+                               register dual u=dat->vthr(i+nx*j);\r
+                               i0 += u;        i1 += u*res.a[i+nx*j];\r
+                       }\r
+                       b->a[i] = i0!=mreal(0) ? i1/i0 : 0;\r
+               }\r
+       }\r
+       if(dir=='y')\r
+       {\r
+               b=new mglDataC(ny);\r
+#pragma omp parallel for\r
+               for(long i=0;i<ny;i++)\r
+               {\r
+                       register dual i1=0,i0=0;\r
+                       for(long k=0;k<nz;k++)  for(long j=0;j<nx;j++)\r
+                       {\r
+                               register dual u=dat->v(j,i,k);\r
+                               i0 += u;        i1 += u*res.a[j+nx*(i+ny*k)];\r
+                       }\r
+                       b->a[i] = i0!=mreal(0) ? i1/i0 : 0;\r
+               }\r
+       }\r
+       if(dir=='z')\r
+       {\r
+               long nn=nx*ny;\r
+               b=new mglDataC(nz);\r
+#pragma omp parallel for\r
+               for(long i=0;i<nz;i++)\r
+               {\r
+                       register dual i1=0,i0=0;\r
+                       for(long j=0;j<nn;j++)\r
+                       {\r
+                               register dual u=dat->vthr(j+nn*i);\r
+                               i0 += u;        i1 += u*res.a[j+nn*i];\r
+                       }\r
+                       b->a[i] = i0!=mreal(0) ? i1/i0 : 0;\r
+               }\r
+       }\r
+       return b;\r
+}\r
+uintptr_t MGL_EXPORT mgl_datac_momentum_(uintptr_t *d, char *dir, const char *how, int,int l)\r
+{      char *s=new char[l+1];  memcpy(s,how,l);        s[l]=0;\r
+       uintptr_t r=uintptr_t(mgl_datac_momentum(_DT_,*dir, s));        delete []s;     return r;       }\r
+//-----------------------------------------------------------------------------\r
+HADT MGL_EXPORT mgl_datac_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm)\r
+{\r
+       if(!idat || (jdat && jdat->GetNN()!=idat->GetNN()) || (kdat && kdat->GetNN()!=idat->GetNN()))   return 0;\r
+       const mglData *dd=dynamic_cast<const mglData *>(dat);\r
+       const mglDataC *dc=dynamic_cast<const mglDataC *>(dat);\r
+       long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz();\r
+       mglDataC *r=new mglDataC(idat->GetNx(),idat->GetNy(),idat->GetNz());\r
+       if(dd)\r
+#pragma omp parallel for\r
+               for(long i=0;i<idat->GetNN();i++)\r
+               {\r
+                       mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0;\r
+                       r->a[i] = mgl_isnum(x*y*z)?mglSpline3st<mreal>(dd->a,nx,ny,nz, x,y,z):NAN;\r
+               }\r
+       else if(dc)\r
+#pragma omp parallel for\r
+               for(long i=0;i<idat->GetNN();i++)\r
+               {\r
+                       mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0;\r
+                       r->a[i] = mgl_isnum(x*y*z)?mglSpline3st<dual>(dc->a,nx,ny,nz, x,y,z):NAN;\r
+               }\r
+       else\r
+#pragma omp parallel for\r
+               for(long i=0;i<idat->GetNN();i++)\r
+               {\r
+                       mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0;\r
+                       r->a[i] = mgl_isnum(x*y*z)?mgl_data_linear(dat, x,y,z):NAN;;\r
+               }\r
+       return r;\r
+}\r
+uintptr_t MGL_EXPORT mgl_datac_evaluate_(uintptr_t *d, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm)\r
+{      return uintptr_t(mgl_datac_evaluate(_DT_,_DA_(idat),_DA_(jdat),_DA_(kdat),*norm));      }\r
+//-----------------------------------------------------------------------------\r
+HADT MGL_EXPORT mgl_datac_column(HCDT dat, const char *eq)\r
+{\r
+       const mglData *dd=dynamic_cast<const mglData *>(dat);\r
+       std::vector<mglDataA*> list;\r
+       if(dd && dd->id.length()>0)     for(size_t i=0;i<dd->id.length();i++)\r
+       {\r
+               mglDataT *col = new mglDataT(*dat);\r
+               col->SetInd(i,dd->id[i]);\r
+               list.push_back(col);\r
+       }\r
+       const mglDataC *dc=dynamic_cast<const mglDataC *>(dat);\r
+       if(dc && dc->id.length()>0)     for(size_t i=0;i<dc->id.length();i++)\r
+       {\r
+               mglDataT *col = new mglDataT(*dat);\r
+               col->SetInd(i,dc->id[i]);\r
+               list.push_back(col);\r
+       }\r
+       if(list.size()==0)      return 0;       // no named columns\r
+       mglDataV *t = new mglDataV(dat->GetNy(),dat->GetNz());\r
+       t->s=L"#$mgl";  list.push_back(t);\r
+       mglDataC *r = new mglDataC;\r
+       r->Set(mglFormulaCalcC(eq,list));\r
+       for(size_t i=0;i<list.size();i++)       delete list[i];\r
+       return r;\r
+}\r
+uintptr_t MGL_EXPORT mgl_datac_column_(uintptr_t *d, const char *eq,int l)\r
+{      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
+       uintptr_t r = uintptr_t(mgl_datac_column(_DT_,s));\r
+       delete []s;     return r;       }\r
+//-----------------------------------------------------------------------------\r
index cc214b8421c1adb77a63b777f2d0a3c96a83420b..76a9c301e1b98bea582f2da37d8523f66ea862a6 100644 (file)
@@ -32,8 +32,9 @@
 #include <hdf5.h>\r
 #endif\r
 \r
-#define isn(ch)                ((ch)=='\n')\r
+inline bool isn(char ch)       {return ch=='\n';}\r
 MGL_NO_EXPORT char *mgl_read_gz(gzFile fp);\r
+mglDataC MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector<mglDataA*> &head);\r
 //-----------------------------------------------------------------------------\r
 HADT MGL_EXPORT mgl_create_datac()     {       return new mglDataC;    }\r
 HADT MGL_EXPORT mgl_create_datac_size(long nx, long ny, long nz){      return new mglDataC(nx,ny,nz);  }\r
@@ -56,38 +57,52 @@ void mglFromStr(HADT d,char *buf,long NX,long NY,long NZ)   // TODO: add multithre
        mgl_datac_create(d, NX,NY,NZ);\r
        long nb = strlen(buf);\r
        register long i=0, j=0;\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        while(j<nb)\r
        {\r
-               while(buf[j]<=' ' && j<nb)      j++;\r
+               while(j<nb && buf[j]<=' ')      j++;\r
                while(buf[j]=='#')              // skip comment\r
                {\r
                        if(i>0 || buf[j+1]!='#')        // this is columns id\r
-                               while(!isn(buf[j]) && j<nb)     j++;\r
+                               while(j<nb && !isn(buf[j]))     j++;\r
                        else\r
                        {\r
-                               while(!isn(buf[j]) && j<nb)\r
+                               while(j<nb && !isn(buf[j]))\r
                                {\r
                                        if(buf[j]>='a' && buf[j]<='z')\r
                                                d->id.push_back(buf[j]);\r
                                        j++;\r
                                }\r
                        }\r
-                       while(buf[j]<=' ' && j<nb)      j++;\r
+                       while(j<nb && buf[j]<=' ')      j++;\r
                }\r
                char *s=buf+j;\r
-               while(buf[j]>=' ' && buf[j]!=';' && j<nb)       j++;\r
+               while(j<nb && buf[j]>=' ' && buf[j]!=';')       j++;\r
                buf[j]=0;\r
                double re=0,im=0;       size_t ll=strlen(s);\r
+               while(s[ll]<=' ')       ll--;\r
                if(*s=='(')             sscanf(s,"(%lg,%lg)",&re,&im);\r
                else if(*s=='[')        sscanf(s,"[%lg,%lg]",&re,&im);\r
                else if(*s=='{')        sscanf(s,"{%lg,%lg}",&re,&im);\r
-               else if(s[ll]=='i')     {       s[ll] = 0;      sscanf(s,"%lg+%lg)",&re,&im);   }\r
-               else            sscanf(s,"%lg+i%lg",&re,&im);\r
+               else if(s[ll]=='i')\r
+               {\r
+                       double a,b;     s[ll] = 0;\r
+                       int s1=sscanf(s,"%lg+%lg",&re,&im);\r
+                       int s2=sscanf(s,"%lg-%lg",&a,&b);\r
+                       if(s2==2 && s1<2)       {       re=a;   im=-b;  }\r
+\r
+               }\r
+               else\r
+               {\r
+                       double a,b;\r
+                       int s1=sscanf(s,"%lg+i%lg",&re,&im);\r
+                       int s2=sscanf(s,"%lg-i%lg",&a,&b);\r
+                       if(s2==2 && s1<2)       {       re=a;   im=-b;  }\r
+               }\r
                d->a[i] = dual(re,im);\r
                i++;    if(i>=NX*NY*NZ) break;\r
        }\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_datac_set(HADT d, HCDT a)\r
@@ -186,35 +201,40 @@ void MGL_EXPORT mgl_datac_set_id_(uintptr_t *d, const char *eq,int l)
 {      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
        mgl_datac_set_id(_DC_, s);      delete []s;     }\r
 //-----------------------------------------------------------------------------\r
+void MGL_NO_EXPORT mgl_cprint(FILE *fp, mreal re, mreal im, char ch)\r
+{\r
+       if(im>0)        fprintf(fp,"%g+i%g%c",re,im,ch);\r
+       else if(im<0)   fprintf(fp,"%g-i%g%c",re,-im,ch);\r
+       else    fprintf(fp,"%g%c",re,ch);\r
+}\r
 void MGL_EXPORT mgl_datac_save(HCDT d, const char *fname,long ns)\r
 {\r
        const mglDataC *dd = dynamic_cast<const mglDataC*>(d);\r
        if(!dd) {       mgl_data_save(d,fname,ns);      return; }\r
        FILE *fp = fopen(fname,"w");\r
        if(!fp) return;\r
-       register long i,j,k;\r
        long nx=dd->nx, ny=dd->ny, nz=dd->nz;\r
-       setlocale(LC_NUMERIC, "C");\r
-       if(ns<0 || (ns>=nz && nz>1))    for(k=0;k<nz;k++)\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
+       if(ns<0 || (ns>=nz && nz>1))    for(long k=0;k<nz;k++)\r
        {       // save whole data\r
-               for(i=0;i<ny;i++)\r
+               for(long i=0;i<ny;i++)\r
                {\r
-                       for(j=0;j<nx-1;j++)     fprintf(fp,"%g+i%g\t", real(dd->a[j+nx*(i+ny*k)]), imag(dd->a[j+nx*(i+ny*k)]));\r
-                       fprintf(fp,"%g+i%g\n", real(dd->a[nx-1+nx*(i+ny*k)]), imag(dd->a[nx-1+nx*(i+ny*k)]));\r
+                       for(long j=0;j<nx-1;j++)        mgl_cprint(fp, real(dd->a[j+nx*(i+ny*k)]), imag(dd->a[j+nx*(i+ny*k)]),'\t');\r
+                       mgl_cprint(fp, real(dd->a[nx-1+nx*(i+ny*k)]), imag(dd->a[nx-1+nx*(i+ny*k)]),'\n');\r
                }\r
                fprintf(fp,"\n");\r
        }\r
        else\r
        {       // save selected slice\r
-               if(nz>1)        for(i=0;i<ny;i++)\r
+               if(nz>1)        for(long i=0;i<ny;i++)\r
                {\r
-                       for(j=0;j<nx-1;j++)     fprintf(fp,"%g+i%g\t", real(dd->a[j+nx*(i+ny*ns)]), imag(dd->a[j+nx*(i+ny*ns)]));\r
-                       fprintf(fp,"%g+i%g\n", real(dd->a[nx-1+nx*(i+ny*ns)]), imag(dd->a[nx-1+nx*(i+ny*ns)]));\r
+                       for(long j=0;j<nx-1;j++)        mgl_cprint(fp, real(dd->a[j+nx*(i+ny*ns)]), imag(dd->a[j+nx*(i+ny*ns)]),'\t');\r
+                       mgl_cprint(fp, real(dd->a[nx-1+nx*(i+ny*ns)]), imag(dd->a[nx-1+nx*(i+ny*ns)]),'\n');\r
                }\r
-               else if(ns<ny)  for(j=0;j<nx;j++)\r
-                       fprintf(fp,"%g+i%g\t", real(dd->a[j+nx*ns]), imag(dd->a[j+nx*ns]));\r
+               else if(ns<ny)  for(long j=0;j<nx;j++)\r
+                       mgl_cprint(fp, real(dd->a[j+nx*ns]), imag(dd->a[j+nx*ns]),'\t');\r
        }\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
        fclose(fp);\r
 }\r
 void MGL_EXPORT mgl_datac_save_(uintptr_t *d, const char *fname,int *ns,int l)\r
@@ -322,24 +342,25 @@ int MGL_EXPORT mgl_datac_read_mat(HADT d, const char *fname, long dim)
        char *buf = mgl_read_gz(fp);\r
        long nb = strlen(buf);  gzclose(fp);\r
 \r
-       register long j=0,i,l;\r
+       long j=0;\r
        while(j<nb)\r
        {\r
                if(buf[j]=='#') while(!isn(buf[j]))     j++;    // skip comment\r
-               while(buf[j]<=' ' && j<nb)      j++;\r
+               while(j<nb && buf[j]<=' ')      j++;\r
                break;\r
        }\r
        if(dim==1)\r
        {\r
                sscanf(buf+j,"%ld",&nx);\r
-               while(buf[j]!='\n' && j<nb)     j++;    j++;\r
+               while(j<nb && buf[j]!='\n')     j++;    j++;\r
 //             while(buf[j]>' ')       j++;\r
        }\r
        else if(dim==2)\r
        {\r
                sscanf(buf+j,"%ld%ld",&nx,&ny);\r
-               while(buf[j]!='\n' && j<nb)     j++;    j++;\r
-               char *b=buf+j, ch;\r
+               while(j<nb && buf[j]!='\n')     j++;    j++;\r
+               char *b=buf+j;\r
+               register long i,l;\r
                for(i=l=0;b[i];i++)\r
                {\r
                        while(b[i]=='#')        {       while(!isn(b[i]) && b[i])       i++;    }\r
@@ -352,7 +373,7 @@ int MGL_EXPORT mgl_datac_read_mat(HADT d, const char *fname, long dim)
                        for(i=l=0;b[i] && !isn(b[i]);i++)       // determine nx\r
                        {\r
                                while(b[i]=='#')        {       while(!isn(b[i]) && b[i])       i++;    }\r
-                               ch = b[i];\r
+                               char ch = b[i];\r
                                if(ch>' ' && !first)    first=true;\r
                                if(first && (ch=='\t' || ch==';') && b[i+1]!='\t') nx++;\r
                        }\r
@@ -361,7 +382,7 @@ int MGL_EXPORT mgl_datac_read_mat(HADT d, const char *fname, long dim)
        else if(dim==3)\r
        {\r
                sscanf(buf+j,"%ld%ld%ld",&nx,&ny,&nz);\r
-               while(buf[j]!='\n' && j<nb)     j++;    j++;\r
+               while(j<nb && buf[j]!='\n')     j++;    j++;\r
        }\r
        mglFromStr(d,buf+j,nx,ny,nz);\r
        free(buf);      return true;\r
@@ -549,8 +570,8 @@ MGL_NO_EXPORT void *mgl_cmodify(void *par)
 void MGL_EXPORT mgl_datac_modify(HADT d, const char *eq,long dim)\r
 {\r
        long nx=d->nx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz};\r
+       if(dim<=0)      mgl_datac_modify_vw(d,eq,0,0);  // fastes variant for whole array\r
        mglFormulaC f(eq);\r
-       if(dim<0)       dim=0;\r
        if(nz>1)        // 3D array\r
        {\r
                par[2] -= dim;  if(par[2]<0)    par[2]=0;\r
@@ -566,38 +587,18 @@ void MGL_EXPORT mgl_datac_modify_(uintptr_t *d, const char *eq,int *dim,int l)
 {      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
        mgl_datac_modify(_DC_,s,*dim);  delete []s;     }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_cmodify_gen(void *par)\r
-{\r
-       mglThreadV *t=(mglThreadV *)par;\r
-       const mglFormulaC *f = (const mglFormulaC *)(t->v);\r
-       long nx=t->p[0],ny=t->p[1],nz=t->p[2];\r
-       dual *b=t->aa;\r
-       mreal dx,dy,dz;\r
-       HCDT v=(HCDT)t->b, w=(HCDT)t->c;\r
-       dx=nx>1?1/(nx-1.):0;    dy=ny>1?1/(ny-1.):0;    dz=nz>1?1/(nz-1.):0;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i0=t->id;i0<t->n;i0+=mglNumThr)\r
-       {\r
-               register long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);\r
-               b[i0] = f->Calc(i*dx, j*dy, k*dz, b[i0], v?v->vthr(i0):0, w?w->vthr(i0):0);\r
-       }\r
-       return 0;\r
-}\r
 void MGL_EXPORT mgl_datac_modify_vw(HADT d, const char *eq,HCDT vdat,HCDT wdat)\r
 {\r
-       const mglDataC *v = dynamic_cast<const mglDataC *>(vdat);\r
-       const mglDataC *w = dynamic_cast<const mglDataC *>(wdat);\r
-       long nn = d->nx*d->ny*d->nz, par[3]={d->nx,d->ny,d->nz};\r
-       if(vdat && vdat->GetNN()!=nn)   return;\r
-       if(wdat && wdat->GetNN()!=nn)   return;\r
-       mglFormulaC f(eq);\r
-       if(v && w)      mglStartThreadC(mgl_cmodify,0,nn,d->a,v->a,w->a,par,&f);\r
-       else if(vdat && wdat)   mglStartThreadV(mgl_cmodify_gen,nn,d->a,vdat,wdat,par,&f);\r
-       else if(v)      mglStartThreadC(mgl_cmodify,0,nn,d->a,v->a,0,par,&f);\r
-       else if(vdat)   mglStartThreadV(mgl_cmodify_gen,nn,d->a,vdat,0,par,&f);\r
-       else    mglStartThreadC(mgl_cmodify,0,nn,d->a,0,0,par,&f);\r
+       std::wstring s = d->s;  d->s = L"u";\r
+       mglDataV x(d->nx,d->ny,d->nz);  x.Fill(0,1,'x');        x.s=L"x";\r
+       mglDataV y(d->nx,d->ny,d->nz);  y.Fill(0,1,'y');        y.s=L"y";\r
+       mglDataV z(d->nx,d->ny,d->nz);  z.Fill(0,1,'z');        z.s=L"z";\r
+       mglDataV r(d->nx,d->ny,d->nz);  r.s=L"#$mgl";\r
+       mglData v(vdat), w(wdat);       v.s = L"v";     w.s = L"w";\r
+       std::vector<mglDataA*> list;\r
+       list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(d);\r
+       list.push_back(&v);     list.push_back(&w);     list.push_back(&r);\r
+       d->Set(mglFormulaCalcC(eq,list));       d->s = s;\r
 }\r
 void MGL_EXPORT mgl_datac_modify_vw_(uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w,int l)\r
 {      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
@@ -793,7 +794,7 @@ void MGL_EXPORT mgl_datac_set_ap_(uintptr_t *d, uintptr_t *a, uintptr_t *p)
 #if MGL_HAVE_HDF5\r
 void MGL_EXPORT mgl_datac_save_hdf(HCDT dat,const char *fname,const char *data,int rewrite)\r
 {\r
-       const mglDataC *d = dynamic_cast<const mglDataC *>(dat);        // NOTE: only for mglDataC\r
+       const mglDataC *d = dynamic_cast<const mglDataC *>(dat);\r
        if(!d)  {       mgl_data_save_hdf(dat,fname,data,rewrite);      return; }\r
        hid_t hf,hd,hs;\r
        hsize_t dims[4];\r
index 31f0e923407d50d8952c8deac036a4ea4f5c7f0c..e86454fc4fa722055088fed9b6175858e233424c 100644 (file)
@@ -25,6 +25,7 @@
 #else\r
 #include <algorithm.h>\r
 #endif\r
+#include <list>\r
 \r
 #include "mgl2/surf.h"\r
 #include "mgl2/cont.h"\r
 //-----------------------------------------------------------------------------\r
 void MGL_NO_EXPORT mgl_string_curve(mglBase *gr,long f,long ,const long *ff,const long *nn,const wchar_t *text, const char *font, mreal size)\r
 {\r
-       if(f<0 || nn[f]==-1)    return; // do nothing since there is no curve\r
+       if(f<0 || nn[f]<0)      return; // do nothing since there is no curve\r
        if(!font)       font="";\r
        int pos = strchr(font,'T') ? 1:-1, align;\r
-       char cc=mglGetStyle(font,0,&align);             align = align&3;\r
-       mreal c=cc ? -cc : gr->GetClrC(ff[f]);\r
+       bool cc=mglGetStyle(font,0,&align);             align = align&3;\r
        mreal h=gr->TextHeight(font,size)/2, tet, tt;\r
        wchar_t L[2]=L"a";\r
        register long i,j,k,m;\r
 \r
        std::vector<mglPoint> qa, qb;   // curves above and below original\r
-       mglPoint p=gr->GetPntP(ff[f]), q=p, s=gr->GetPntP(ff[nn[f]]), l=!(s-q), t=l;\r
+       if(ff[f]<0)     for(i=nn[f];i>=0 && i!=f;i=nn[i])       // find first real point\r
+               if(ff[i]>=0)    {       f=i;    break;  }\r
+       if(ff[f]<0)     return;\r
+       mreal c=cc?gr->AddTexture(font) : gr->GetClrC(ff[f]);\r
+       mglPoint p=gr->GetPntP(ff[f]), q=p, s;\r
+       for(i=nn[f];i>=0 && i!=f;i=nn[i])       // find second real point\r
+               if(ff[i]>=0)    {       s=gr->GetPntP(ff[i]);   break;  }\r
+       mglPoint l=!(s-q), t=l;\r
        qa.push_back(q+l*h);    qb.push_back(q-l*h);\r
        for(i=nn[f];i>=0 && i!=f;i=nn[i])       // construct curves\r
        {\r
-               if(gr->Stop)    return;\r
                p=q;    q=s;    l=t;\r
                if(nn[i]>=0 && ff[nn[i]]>=0)    {       s=gr->GetPntP(ff[nn[i]]);       t=!(s-q);       }\r
                tet = t.x*l.y-t.y*l.x;\r
@@ -68,13 +74,16 @@ void MGL_NO_EXPORT mgl_string_curve(mglBase *gr,long f,long ,const long *ff,cons
        if(pos>0)       qa=qb;\r
        // adjust text direction\r
        bool rev = align==2;\r
-       char *fnt = new char[strlen(font)+3];   strcpy(fnt,font);\r
+       const char *ffont=mglchr(font,':');\r
+       char *fnt = new char[strlen(font)+5];\r
+       if(ffont) strcpy(fnt,ffont);    else *fnt=0;\r
        if(qa[0].x>qa[1].x)\r
        {\r
                if(align==0){   strcat(fnt,":R");       align=2;        }\r
                else if(align==1)       rev = true;\r
                else            {       strcat(fnt,":L");       align=0;        }\r
        }\r
+       if(mglchr(font,'T'))    strcat(fnt,":T");\r
        if(rev) reverse(qa.begin(),qa.end());\r
        long len = mgl_wcslen(text);\r
        mreal *wdt=new mreal[len+1];\r
@@ -88,7 +97,6 @@ void MGL_NO_EXPORT mgl_string_curve(mglBase *gr,long f,long ,const long *ff,cons
        mreal a,b,d,w,t1,t2;\r
        for(i=j=0,tt=0;j<len;j++)\r
        {\r
-               if(gr->Stop)    {       delete []wdt;   delete []pt;    delete []fnt;   return; }\r
                w = align==1 ? wdt[j] : (wdt[j]+wdt[j+1])/2;    p = pt[j];\r
                for(k=i+1;k<m;k++)      if((p-qa[k]).norm()>w)  break;\r
                if(k>i+1 && k<m)        tt=-1;\r
@@ -102,10 +110,11 @@ void MGL_NO_EXPORT mgl_string_curve(mglBase *gr,long f,long ,const long *ff,cons
                tt=t1;  pt[j+1] = q+(s-q)*tt;\r
        }\r
        if(rev) pos=-pos;\r
+       mreal dc = (cc && len>1)?1/MGL_FEPSILON/(len-1):0;\r
        for(j=0;j<len;j++)      // draw text\r
        {\r
                L[0] = text[align!=2?j:len-1-j];        s = pt[j+1]-pt[j];      l = !s;\r
-               gr->text_plot(gr->AddPnt(pt[j]+(pos*h)*l,c,s,-1,-1),L,font,size,0.05,c);\r
+               gr->text_plot(gr->AddPnt(pt[j]+(pos*h)*l,c+dc*i,s,-1,-1),L,fnt,size,0.05,c+dc*j);\r
        }\r
        delete []wdt;   delete []pt;    delete []fnt;\r
 }\r
@@ -119,18 +128,8 @@ void MGL_EXPORT mgl_textw_xyz(HMGL gr, HCDT x, HCDT y, HCDT z,const wchar_t *tex
        static int cgid=1;      gr->StartGroup("TextC",cgid++);\r
 \r
        long *nn = new long[n], *ff = new long[n];\r
-       const mglData *mdx = dynamic_cast<const mglData *>(x);\r
-       const mglData *mdy = dynamic_cast<const mglData *>(y);\r
-       const mglData *mdz = dynamic_cast<const mglData *>(z);\r
-       if(mdx && mdy && mdz)\r
-#pragma omp parallel for\r
-               for(long i=0;i<n;i++)\r
-                       ff[i] = gr->AddPnt(mglPoint(mdx->a[i],mdy->a[i],mdz->a[i]),-1);\r
-       else\r
-#pragma omp parallel for\r
-               for(long i=0;i<n;i++)\r
-                       ff[i] = gr->AddPnt(mglPoint(x->v(i),y->v(i),z->v(i)),-1);\r
-#pragma omp parallel for\r
+       for(long i=0;i<n;i++)\r
+               ff[i] = gr->AddPnt(mglPoint(x->v(i),y->v(i),z->v(i)),-1);\r
        for(long i=1;i<n;i++)   nn[i-1] = i;\r
        nn[n-1]=-1;\r
        mgl_string_curve(gr,0,n,ff,nn,text,font,-1);\r
@@ -141,17 +140,15 @@ void MGL_EXPORT mgl_textw_xyz(HMGL gr, HCDT x, HCDT y, HCDT z,const wchar_t *tex
 void MGL_EXPORT mgl_textw_xy(HMGL gr, HCDT x, HCDT y, const wchar_t *text, const char *font, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData z(y->GetNx());\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
        mgl_textw_xyz(gr,x,y,&z,text,font,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_textw_y(HMGL gr, HCDT y, const wchar_t *text, const char *font, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(y->GetNx()), z(y->GetNx());\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV x(y->GetNx()), z(y->GetNx());\r
+       x.Fill(gr->Min.x,gr->Max.x);    z.Fill(gr->AdjustZMin());\r
        mgl_textw_xyz(gr,&x,y,&z,text,font,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -162,16 +159,14 @@ void MGL_EXPORT mgl_text_xyz(HMGL gr, HCDT x, HCDT y, HCDT z,const char *text, c
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_text_xy(HMGL gr, HCDT x, HCDT y, const char *text, const char *font, const char *opt)\r
 {\r
-       mglData z(y->GetNx());\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
        mgl_text_xyz(gr,x,y,&z,text,font,opt);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_text_y(HMGL gr, HCDT y, const char *text, const char *font, const char *opt)\r
 {\r
-       mglData x(y->GetNx()), z(y->GetNx());\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV x(y->GetNx()), z(y->GetNx());\r
+       x.Fill(gr->Min.x,gr->Max.x);    z.Fill(gr->AdjustZMin());\r
        mgl_text_xyz(gr,&x,y,&z,text,font,opt);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -199,194 +194,193 @@ mgl_text_y(_GR_, _DA_(y),s,f,o);        delete []o;     delete []s;     delete []f;     }
 //     Cont series\r
 //\r
 //-----------------------------------------------------------------------------\r
-struct mglSegment\r
-{\r
-       long next,prev;\r
-       mglPoint p1,p2;\r
-       mglSegment(mglPoint q1,mglPoint q2)     {p1=q1;p2=q2;next=prev=-1;}\r
-};\r
-// function for connecting arbitrary line segments\r
-/*void MGL_NO_EXPORT mgl_connect(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, int text,long ak)\r
+#include "cont.hpp"\r
+//-----------------------------------------------------------------------------\r
+std::vector<mglSegment> MGL_EXPORT mgl_get_lines(mreal val, HCDT a, HCDT x, HCDT y, HCDT z, long ak)\r
 {\r
        long n=a->GetNx(), m=a->GetNy();\r
-       if(n<2 || m<2 || x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m || z->GetNx()*z->GetNy()!=n*m)\r
-       {       gr->SetWarn(mglWarnDim,"ContGen");      return; }\r
-       std::vector<mglSegment> ss,cc;\r
-\r
-       register long i,j;\r
-       mreal d1,d2,d3,d4;\r
-       bool o1,o2,o3,o4;\r
-       mglPoint p1,p2,p3,p4,q1,q2,q3,q4;\r
-       for(i=0;i<n;i++)        for(j=0;j<m;j++)        // prepare segments\r
-       {\r
-               if(gr->Stop)    return;\r
-               d1 = mgl_d(val,a->v(i,j,ak),a->v(i+1,j,ak));            o1 = d1>=0 && d1<1;\r
-               d2 = mgl_d(val,a->v(i,j,ak),a->v(i,j+1,ak));            o2 = d2>=0 && d2<1;\r
-               d3 = mgl_d(val,a->v(i+1,j+1,ak),a->v(i+1,j,ak));        o3 = d3>=0 && d3<1;\r
-               d4 = mgl_d(val,a->v(i+1,j+1,ak),a->v(i,j+1,ak));        o4 = d4>=0 && d4<1;\r
-               p1 = mglPoint(x->v(i,j), y->v(i,j),z->v(i,j));\r
-               p2 = mglPoint(x->v(i+1,j), y->v(i+1,j),z->v(i+1,j));\r
-               p3 = mglPoint(x->v(i,j+1), y->v(i,j+1),z->v(i,j+1));\r
-               p4 = mglPoint(x->v(i+1,j+1), y->v(i+1,j+1),z->v(i+1,j+1));\r
-               q1 = p1*(1-d1)+p2*d1;   q2 = p1*(1-d2)+p3*d1;\r
-               q3 = p4*(1-d3)+p2*d3;   q4 = p4*(1-d4)+p3*d4;\r
-               if(o1 && o2)    {       o1 = o2 = false;        ss.push_back(mglSegment(q1,q2));        }\r
-               if(o1 && o3)    {       o1 = o3 = false;        ss.push_back(mglSegment(q1,q3));        }\r
-               if(o1 && o4)    {       o1 = o4 = false;        ss.push_back(mglSegment(q1,q4));        }\r
-               if(o2 && o3)    {       o2 = o3 = false;        ss.push_back(mglSegment(q2,q3));        }\r
-               if(o2 && o4)    {       o2 = o4 = false;        ss.push_back(mglSegment(q2,q4));        }\r
-               if(o3 && o4)    {       o3 = o4 = false;        ss.push_back(mglSegment(q3,q4));        }\r
-       }\r
-       // connect it\r
-       if(ss.size()==0)        return;\r
-       for(i=0;i<ss.size();i++)        // lets try most stupid algorithm (can be VERY slow)\r
+       std::vector<mglSegment> lines;\r
+       // first add all possible lines\r
+       for(long j=0;j<m-1;j++) for(long i=0;i<n-1;i++)\r
        {\r
-               mglSegment &s1=ss[i];\r
-               for(j=0;j<ss.size();j++)\r
+               register mreal v1=a->v(i,j,ak),v2=a->v(i+1,j,ak),v3=a->v(i,j+1,ak),v4=a->v(i+1,j+1,ak);\r
+               register mreal dl=mgl_d(val,v1,v3),dr=mgl_d(val,v2,v4),dp=mgl_d(val,v1,v2),dn=mgl_d(val,v3,v4);\r
+               bool added=false;\r
+               if(v1>val || v4>val)\r
                {\r
-                       mglSegment &s2=ss[j];\r
-                       if(s2.prev<0 && s1.p2==s2.p1)   {       s1.next = j;    s2.prev=i;      continue;       }\r
-                       if(s2.next<0 && s1.p1==s2.p2)   {       s1.prev = j;    s2.next=i;      continue;       }\r
-                       //                      if(s2.prev<0 && s1.p2==s2.p1)\r
-                       //                      {       s1.next = j;    s2.prev=i;      continue;       }\r
+                       mglSegment line;\r
+                       if(line.set(0,dl,dn,1,i,j,ak,x,y,z))    {       lines.push_back(line);  added=true;     }\r
+                       if(line.set(1,dr,dp,0,i,j,ak,x,y,z))    {       lines.push_back(line);  added=true;     }\r
+               }\r
+               else\r
+               {\r
+                       mglSegment line;\r
+                       if(line.set(0,dl,dp,0,i,j,ak,x,y,z))    {       lines.push_back(line);  added=true;     }\r
+                       if(line.set(1,dr,dn,1,i,j,ak,x,y,z))    {       lines.push_back(line);  added=true;     }\r
+               }\r
+               if(!added)      // try to add any other variants\r
+               {\r
+                       mglSegment line;\r
+                       if(line.set(0,dl,1,dr,i,j,ak,x,y,z))            lines.push_back(line);\r
+                       else if(line.set(dp,0,dn,1,i,j,ak,x,y,z))       lines.push_back(line);\r
+                       else if(line.set(0,dl,dn,1,i,j,ak,x,y,z))       lines.push_back(line);\r
+                       else if(line.set(1,dr,dp,0,i,j,ak,x,y,z))       lines.push_back(line);\r
+                       else if(line.set(0,dl,dp,0,i,j,ak,x,y,z))       lines.push_back(line);\r
+                       else if(line.set(1,dr,dn,1,i,j,ak,x,y,z))       lines.push_back(line);\r
                }\r
        }\r
-}*/\r
+       return lines;\r
+}\r
 //-----------------------------------------------------------------------------\r
-// NOTE! returned must be deleted!!!\r
-struct mglPnt2 {       mreal x,y;      mglPnt2(mreal xx=0,mreal yy=0)  {x=xx;y=yy;}    };\r
-long *mgl_cont_prep(mreal val, HCDT a,long ak, std::vector<mglPnt2> &kk)\r
+std::vector<mglSegment> MGL_EXPORT mgl_get_curvs(HMGL gr, std::vector<mglSegment> lines)\r
 {\r
-       long n=a->GetNx(), m=a->GetNy();\r
-       mreal d, r, kx, ky;\r
-       register long i,j,k, pc=0;\r
-       kk.clear();\r
-       // add intersection point of isoline and Y axis\r
-       const mglData *ma = dynamic_cast<const mglData *>(a);\r
-       if(ma)\r
+       long n = lines.size(), m = n;\r
+       const long nsl=(n>0 && n*n>100)?sqrt(double(n)):10;\r
+       mreal dxsl = nsl/((gr->Max.x-gr->Min.x)*MGL_FEPSILON), x0 = gr->Min.x;\r
+       mreal dysl = nsl/((gr->Max.y-gr->Min.y)*MGL_FEPSILON), y0 = gr->Min.y;\r
+       std::vector<long> *xsl, *ysl;\r
+       xsl = new std::vector<long>[nsl+1];\r
+       ysl = new std::vector<long>[nsl+1];\r
+       for(long i=0;i<n;i++)   // group lines by position of its x-coor\r
        {\r
-               for(j=0;j<m;j++)        for(i=0;i<n-1;i++)\r
+               register long i1 = (lines[i].p1.x-x0)*dxsl, i2 = (lines[i].p2.x-x0)*dxsl;\r
+               if(i1<0)        i1=0;   if(i1>nsl)      i1=nsl;\r
+               if(i2<0)        i2=0;   if(i2>nsl)      i2=nsl;\r
+               if(i1==i2 && i1*(i1-nsl)<=0)    xsl[i1].push_back(i);\r
+               else\r
                {\r
-                       d = mgl_d(val,ma->a[i+n*(j+m*ak)],ma->a[i+1+n*(j+m*ak)]);\r
-                       if(d>=0 && d<1) kk.push_back(mglPnt2(i+d,j));\r
+                       if(i1*(i1-nsl)<=0)      xsl[i1].push_back(i);\r
+                       if(i2*(i2-nsl)<=0)      xsl[i2].push_back(i);\r
                }\r
-               // add intersection point of isoline and X axis\r
-               for(j=0;j<m-1;j++)      for(i=0;i<n;i++)\r
+               i1 = (lines[i].p1.y-y0)*dysl;\r
+               i2 = (lines[i].p2.y-y0)*dysl;\r
+               if(i1<0)        i1=0;   if(i1>nsl)      i1=nsl;\r
+               if(i2<0)        i2=0;   if(i2>nsl)      i2=nsl;\r
+               if(i1==i2 && i1*(i1-nsl)<=0)    ysl[i1].push_back(i);\r
+               else\r
                {\r
-                       d = mgl_d(val,ma->a[i+n*(j+m*ak)],ma->a[i+n*(j+1+m*ak)]);\r
-                       if(d>=0 && d<1) kk.push_back(mglPnt2(i,j+d));\r
+                       if(i1*(i1-nsl)<=0)      ysl[i1].push_back(i);\r
+                       if(i2*(i2-nsl)<=0)      ysl[i2].push_back(i);\r
                }\r
        }\r
-       else    for(j=0;j<m-1;j++)      for(i=0;i<n-1;i++)\r
+       size_t xm=0,ym=0;\r
+       for(long i=0;i<=nsl;i++)\r
        {\r
-               register mreal vv = a->v(i,j,ak);\r
-               d = (i<n-1)?mgl_d(val,vv,a->v(i+1,j,ak)):-1;\r
-               if(d>=0 && d<1) kk.push_back(mglPnt2(i+d,j));\r
-               d = (j<m-1)?mgl_d(val,vv,a->v(i,j+1,ak)):-1;\r
-               if(d>=0 && d<1) kk.push_back(mglPnt2(i,j+d));\r
+               if(xm<xsl[i].size())    xm=xsl[i].size();\r
+               if(ym<ysl[i].size())    ym=ysl[i].size();\r
        }\r
-\r
-       pc = kk.size();\r
-       if(pc==0)       return  NULL;   // deallocate arrays and finish if no point\r
-       // allocate arrays for curve (nn - next, ff - prev)\r
-       long *nn = new long[pc], *ff = new long[pc];\r
-       // -1 is not parsed, -2 starting\r
-       for(i=0;i<pc;i++)       nn[i] = ff[i] = -1;\r
-       // connect points to line\r
-       long i11,i12,i21,i22,j11,j12,j21,j22;\r
-       j=-1;   // current point\r
-       do{\r
-               if(j>=0)\r
+       std::vector<mglSegment> curvs;\r
+       char *used = new char[n];       memset(used,0,n);\r
+       // create curves from lines\r
+       while(m>0)      // NOTE! This algorithm can be *very* slow!!!\r
+       {\r
+               mglSegment curv;\r
+               bool added = false;\r
+               for(long i=0;i<n;i++)   if(!used[i])    // find any first line segment\r
                {\r
-                       kx = kk[j].x;   ky = kk[j].y;   i = -1;\r
-                       i11 = long(kx+1e-5);    i12 = long(kx-1e-5);\r
-                       j11 = long(ky+1e-5);    j12 = long(ky-1e-5);\r
-                       r=10;\r
-                       for(k=0;k<pc;k++)       // find closest point in grid\r
-                       {\r
-                               if(k==j || k==ff[j] || ff[k]!=-1)       continue;       // point is marked\r
-                               i21 = long(kk[k].x+1e-5);       i22 = long(kk[k].x-1e-5);\r
-                               j21 = long(kk[k].y+1e-5);       j22 = long(kk[k].y-1e-5);\r
-                               // check if in the same cell\r
-                               register bool cond = (i11==i21 || i11==i22 || i12==i21 || i12==i22) &&\r
-                               (j11==j21 || j11==j22 || j12==j21 || j12==j22);\r
-                               d = hypot(kk[k].x-kx,kk[k].y-ky);       // if several then select closest\r
-                               if(cond && d<r) {       r=d;    i=k;    }\r
-                       }\r
-                       if(i<0) j = -1; // no free close points\r
-                       else                    // mark the point\r
-                       {       nn[j] = i;      ff[i] = j;      j = nn[i]<0 ? i : -1;   }\r
+                       curv.before(lines[i].p1);\r
+                       curv.after(lines[i].p2);\r
+                       used[i]=1;      m--;\r
+                       added=true;     break;\r
                }\r
-               if(j<0)\r
+               while(added && m>0)\r
                {\r
-                       for(k=0;k<pc;k++)       if(nn[k]==-1)   // first check edges\r
+                       added = false;\r
+                       register long i1, i2;\r
+                       if(xm<=ym)\r
+                       {       i1 = (curv.p1.x-x0)*dxsl;       i2 = (curv.p2.x-x0)*dxsl;       }\r
+                       else\r
+                       {       i1 = (curv.p1.y-y0)*dysl;       i2 = (curv.p2.y-y0)*dysl;       }\r
+                       if(i1<0)        i1=0;   if(i1>nsl)      i1=nsl;\r
+                       if(i2<0)        i2=0;   if(i2>nsl)      i2=nsl;\r
+                       const std::vector<long> &isl1=(xm<=ym)?xsl[i1]:ysl[i1];\r
+                       for(size_t i=0;i<isl1.size();i++)       // first find continuation of first point\r
                        {\r
-                               if(kk[k].x==0 || fabs(kk[k].x-n+1)<1e-5 || kk[k].y==0 || fabs(kk[k].y-m+1)<1e-5)\r
-                               {       nn[k]=-2;       j = k;  break;  }\r
+                               register long ii = isl1[i];\r
+                               const mglSegment &l=lines[ii];\r
+                               if(used[ii])    continue;\r
+                               if(l.p1==curv.p1)               {       curv.before(l.p2);      used[ii]=1;     m--;    added=true;     break;  }\r
+                               else if(l.p2==curv.p1)  {       curv.before(l.p1);      used[ii]=1;     m--;    added=true;     break;  }\r
+                       }\r
+                       const std::vector<long> &isl2=(xm<=ym)?xsl[i2]:ysl[i2];\r
+                       if(m>0) for(size_t i=0;i<isl2.size();i++)       // now the same for second point\r
+                       {\r
+                               register long ii = isl2[i];\r
+                               const mglSegment &l=lines[ii];\r
+                               if(used[ii])    continue;\r
+                               if(l.p1==curv.p2)               {       curv.after(l.p2);       used[ii]=1;     m--;    added=true;     break;  }\r
+                               else if(l.p2==curv.p2)  {       curv.after(l.p1);       used[ii]=1;     m--;    added=true;     break;  }\r
                        }\r
-                       if(j<0) for(k=0;k<pc;k++)       if(nn[k]==-1)   // or any points inside\r
-                       {       j = k;  nn[k]=-2;       break;  }\r
                }\r
-       }while(j>=0);\r
-       delete []ff;    return nn;\r
+               curvs.push_back(curv);\r
+       }\r
+       delete []used;  delete []xsl;   delete []ysl;\r
+       return curvs;\r
 }\r
 //-----------------------------------------------------------------------------\r
-// NOTE! All data MUST have the same size! Only first slice is used!\r
-void MGL_EXPORT mgl_cont_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, int text,long ak)\r
+void MGL_NO_EXPORT mgl_draw_curvs(HMGL gr, mreal val, mreal c, int text, const std::vector<mglSegment> &curvs)\r
 {\r
-       long n=a->GetNx(), m=a->GetNy();\r
-       if(n<2 || m<2 || x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m || z->GetNx()*z->GetNy()!=n*m)\r
-       {       gr->SetWarn(mglWarnDim,"ContGen");      return; }\r
-\r
-       std::vector<mglPnt2> kk;\r
-       long *nn = mgl_cont_prep(val, a, ak, kk), *ff;\r
-       if(!nn) return; // nothing to do\r
-       register long i, pc=kk.size();\r
-       register mreal xx, yy;\r
-       ff = new long[pc];      gr->Reserve(pc);\r
-       for(i=0;i<pc;i++)\r
+       long pc=0;\r
+       for(size_t i=0;i<curvs.size();i++)      pc += curvs[i].pp.size();\r
+       gr->Reserve(pc);\r
+       // fill arguments for other functions\r
+       long *ff = new long[pc], *nn = new long[pc], m=0;\r
+       for(size_t i=0;i<curvs.size();i++)\r
        {\r
-               xx = kk[i].x;   yy = kk[i].y;\r
-               ff[i] = gr->AddPnt(mglPoint(mgl_data_linear(x,xx,yy,ak), mgl_data_linear(y,xx,yy,ak), mgl_data_linear(z,xx,yy,ak)), c);\r
+               const std::list<mglPoint> &pp=curvs[i].pp;\r
+               for(std::list<mglPoint>::const_iterator it=pp.begin(); it != pp.end(); ++it)\r
+               {\r
+                       ff[m] = gr->AddPnt(*it, c);\r
+                       nn[m] = m+1;    m++;\r
+               }\r
+               nn[m-1]=-1;\r
        }\r
-\r
        if(text && pc>1)\r
        {\r
                wchar_t wcs[64];\r
                mglprintf(wcs,64,L"%4.3g",val);\r
-               mglPoint t;\r
                mreal del = 2*gr->TextWidth(wcs,"",-0.5);\r
                // find width and height of drawing area\r
                mreal ar=gr->GetRatio(), w=gr->FontFactor(), h;\r
                if(del<w/5)     del = w/5;\r
                if(ar<1) h=w/ar;        else {  h=w;    w*=ar;  }\r
-               m=long(2*w/del)+1;      n=long(2*h/del)+1;      // don't need data size anymore\r
+               long m=long(2*w/del)+1, n=long(2*h/del)+1;\r
                long *oo=new long[n*m];\r
                mreal *rr=new mreal[n*m];\r
-               for(i=0;i<n*m;i++)      {       oo[i]=-1;       rr[i]=del*del/4;        }\r
-\r
-               register long j,k;\r
-               for(k=0;k<pc;k++)       // print label several times if possible\r
+               for(long i=0;i<n*m;i++) {       oo[i]=-1;       rr[i]=del*del/4;        }\r
+               for(long k=0;k<pc;k++)  // print label several times if possible\r
                {\r
                        if(nn[k]<0)     continue;\r
-                       t = gr->GetPntP(ff[k]);\r
-                       i = long(t.x/del);      t.x -= i*del;\r
-                       j = long(t.y/del);      t.y -= j*del;\r
+                       mglPoint t = gr->GetPntP(ff[k]);\r
+                       long i = long(t.x/del); t.x -= i*del;\r
+                       long j = long(t.y/del); t.y -= j*del;\r
                        if(i<0 || i>=m || j<0 || j>=n)  continue;       // never should be here!\r
-                       xx = t.x*t.x+t.y*t.y;   i += m*j;\r
+                       mreal xx = t.x*t.x+t.y*t.y;     i += m*j;\r
                        if(rr[i]>xx)    {       rr[i]=xx;       oo[i]=k;        }\r
                }\r
-               for(i=0;i<n*m;i++)      if(oo[i]>=0)\r
-                       mgl_string_curve(gr,oo[i],pc,ff,nn,wcs,"t:C",-0.5);\r
+               for(long i=0;i<n*m;i++) if(oo[i]>=0)\r
+                       mgl_string_curve(gr,oo[i],pc,ff,nn,wcs,text==1?"t:C":"T:C",-0.5);\r
                delete []oo;    delete []rr;\r
        }\r
-       for(i=0;i<pc;i++)       if(nn[i]>=0)    gr->line_plot(ff[i], ff[nn[i]]);\r
+       for(long i=0;i<pc;i++)  if(nn[i]>=0)    gr->line_plot(ff[i], ff[nn[i]]);\r
        delete []nn;    delete []ff;\r
 }\r
 //-----------------------------------------------------------------------------\r
+// NOTE! All data MUST have the same size! Only first slice is used!\r
+void MGL_EXPORT mgl_cont_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, int text,long ak)\r
+{\r
+       long n=a->GetNx(), m=a->GetNy();\r
+       if(n<2 || m<2 || x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m || z->GetNx()*z->GetNy()!=n*m)\r
+       {       gr->SetWarn(mglWarnDim,"ContGen");      return; }\r
+\r
+       mgl_draw_curvs(gr,val,c,text,mgl_get_curvs(gr,mgl_get_lines(val,a,x,y,z,ak)));\r
+}\r
+//-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_cont_gen(HMGL gr, double val, HCDT a, HCDT x, HCDT y, HCDT z, const char *sch)\r
 {\r
-       bool text=(mglchr(sch,'t'));\r
+       int text=0;\r
+       if(mglchr(sch,'t'))     text=1;\r
+       if(mglchr(sch,'T'))     text=2;\r
        gr->SetPenPal(sch);\r
        mgl_cont_gen(gr,val,a,x,y,z,gr->CDef,text,0);\r
 }\r
@@ -399,7 +393,9 @@ void MGL_EXPORT mgl_cont_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const c
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("Cont",cgid++);\r
 \r
-       bool text=(mglchr(sch,'t'));\r
+       int text=0;\r
+       if(mglchr(sch,'t'))     text=1;\r
+       if(mglchr(sch,'T'))     text=2;\r
        bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z);\r
        long s=gr->AddTexture(sch);\r
        gr->SetPenPal(sch);\r
@@ -408,32 +404,22 @@ void MGL_EXPORT mgl_cont_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const c
        if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n)    // make\r
        {\r
                xx.Create(n, m);                yy.Create(n, m);\r
-               const mglData *mx = dynamic_cast<const mglData *>(x);\r
-               const mglData *my = dynamic_cast<const mglData *>(y);\r
-               if(mx && my)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long i=0;i<n;i++)   for(long j=0;j<m;j++)\r
-                       {       xx.a[i+n*j] = mx->a[i]; yy.a[i+n*j] = my->a[j]; }\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long i=0;i<n;i++)   for(long j=0;j<m;j++)\r
-                       {       xx.a[i+n*j] = x->v(i);  yy.a[i+n*j] = y->v(j);  }\r
+               for(long i=0;i<n;i++)   xx.a[i]=x->v(i);\r
+               for(long j=1;j<m;j++)   memcpy(xx.a+n*j,xx.a,n*sizeof(mreal));\r
+               for(long j=0;j<m;j++)\r
+               {       mreal t=y->v(j);        for(long i=0;i<n;i++)   yy.a[i+n*j]=t;  }\r
                x = &xx;        y = &yy;\r
        }\r
        // x, y -- have the same size z\r
-#pragma omp parallel\r
+       mglDataV zz(n, m);\r
+       for(long i=0;i<v->GetNx();i++)  for(long j=0;j<z->GetNz();j++)\r
        {\r
-               mglData zz(n, m);\r
-#pragma omp for collapse(2)\r
-               for(long j=0;j<z->GetNz();j++)  for(long i=0;i<v->GetNx();i++)\r
-               {\r
-                       if(gr->Stop)    continue;\r
-                       mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0;\r
-                       if(z->GetNz()>1)\r
-                               z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1);\r
-                       zz.Fill(z0,z0);\r
-                       mgl_cont_gen(gr,v0,z,x,y,&zz,gr->GetC(s,v0),text,j);\r
-               }\r
+               if(gr->NeedStop())      {       i = v->GetNx(); j = z->GetNz(); continue;       }\r
+               mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0;\r
+               if(z->GetNz()>1)\r
+                       z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1);\r
+               zz.Fill(z0,z0);\r
+               mgl_cont_gen(gr,v0,z,x,y,&zz,gr->GetC(s,v0),text,j);\r
        }\r
        gr->EndGroup();\r
 }\r
@@ -443,7 +429,7 @@ void MGL_EXPORT mgl_cont_val(HMGL gr, HCDT v, HCDT z, const char *sch, const cha
        register long n = z->GetNx(), m = z->GetNy();\r
        if(m<2 || n<2)  {       gr->SetWarn(mglWarnLow,"Cont"); return; }\r
        gr->SaveState(opt);\r
-       mglData x(n, m), y(n, m);\r
+       mglDataV x(n, m), y(n, m);\r
        x.Fill(gr->Min.x,gr->Max.x,'x');\r
        y.Fill(gr->Min.y,gr->Max.y,'y');\r
        mgl_cont_xy_val(gr,v,&x,&y,z,sch,0);\r
@@ -499,16 +485,15 @@ long MGL_NO_EXPORT mgl_add_pnt(HMGL gr, mreal d, HCDT x, HCDT y, HCDT z, long i1
        long res=-1;\r
        if(edge || (d>0 && d<1))\r
        {\r
-               mglPoint p,u,v;\r
-               p = mglPoint(x->v(i1,j1)*(1-d)+x->v(i2,j2)*d,\r
-                                        y->v(i1,j1)*(1-d)+y->v(i2,j2)*d,\r
-                                        z->v(i1,j1)*(1-d)+z->v(i2,j2)*d);\r
-               u = mglPoint(x->dvx(i1,j1)*(1-d)+x->dvx(i2,j2)*d,\r
-                                        y->dvx(i1,j1)*(1-d)+y->dvx(i2,j2)*d,\r
-                                        z->dvx(i1,j1)*(1-d)+z->dvx(i2,j2)*d);\r
-               v = mglPoint(x->dvy(i1,j1)*(1-d)+x->dvy(i2,j2)*d,\r
-                                        y->dvy(i1,j1)*(1-d)+y->dvy(i2,j2)*d,\r
-                                        z->dvy(i1,j1)*(1-d)+z->dvy(i2,j2)*d);\r
+               mglPoint p(x->v(i1,j1)*(1-d)+x->v(i2,j2)*d,\r
+                                       y->v(i1,j1)*(1-d)+y->v(i2,j2)*d,\r
+                                       z->v(i1,j1)*(1-d)+z->v(i2,j2)*d);\r
+               mglPoint u(x->dvx(i1,j1)*(1-d)+x->dvx(i2,j2)*d,\r
+                                       y->dvx(i1,j1)*(1-d)+y->dvx(i2,j2)*d,\r
+                                       z->dvx(i1,j1)*(1-d)+z->dvx(i2,j2)*d);\r
+               mglPoint v(x->dvy(i1,j1)*(1-d)+x->dvy(i2,j2)*d,\r
+                                       y->dvy(i1,j1)*(1-d)+y->dvy(i2,j2)*d,\r
+                                       z->dvy(i1,j1)*(1-d)+z->dvy(i2,j2)*d);\r
                res = gr->AddPnt(p,c,u^v);\r
        }\r
        return res;\r
@@ -517,25 +502,22 @@ long MGL_NO_EXPORT mgl_add_pnt(HMGL gr, mreal d, HCDT x, HCDT y, HCDT z, long i1
 void MGL_NO_EXPORT mgl_add_range(HMGL gr, HCDT a, HCDT x, HCDT y, HCDT z, long i1, long j1, long di, long dj, mreal c, long &u1, long &u2, long ak, mreal v1, mreal v2)\r
 {\r
        long i2=i1+di, j2=j1+dj;\r
-\r
        mreal f1 = a->v(i1,j1,ak),      f2 = a->v(i2,j2,ak), d1, d2;\r
        d1 = mgl_d(v1,f1,f2);\r
        u1 = mgl_add_pnt(gr,d1,x,y,z,i1,j1,i2,j2,c,false);\r
        d2 = mgl_d(v2,f1,f2);\r
        u2 = mgl_add_pnt(gr,d2,x,y,z,i1,j1,i2,j2,c,false);\r
        if(d1>d2)       {       j2=u1;  u1=u2;  u2=j2;  }\r
+       if(u1<0)        {       u1=u2;  u2=-1;  }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_NO_EXPORT mgl_add_edges(HMGL gr, HCDT a, HCDT x, HCDT y, HCDT z, long i1, long j1, long di, long dj, mreal c, long &u1, long &u2, long ak, mreal v1, mreal v2)\r
 {\r
        long i2=i1+di, j2=j1+dj;\r
        u1 = u2 = -1;\r
-\r
        mreal f1 = a->v(i1,j1,ak),      f2 = a->v(i2,j2,ak);\r
-       if(f1<=v2 && f1>=v1)\r
-               u1 = mgl_add_pnt(gr,0,x,y,z,i1,j1,i2,j2,c,true);\r
-       if(f2<=v2 && f2>=v1)\r
-               u2 = mgl_add_pnt(gr,1,x,y,z,i1,j1,i2,j2,c,true);\r
+       if(f1<=v2 && f1>=v1)    u1 = mgl_add_pnt(gr,0,x,y,z,i1,j1,i2,j2,c,true);\r
+       if(f2<=v2 && f2>=v1)    u2 = mgl_add_pnt(gr,1,x,y,z,i1,j1,i2,j2,c,true);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, long ak)\r
@@ -545,12 +527,11 @@ void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT
        {       gr->SetWarn(mglWarnDim,"ContFGen");     return; }\r
 \r
        register long i,j;\r
-       gr->Reserve(n*m);\r
+       gr->Reserve(8*n*m);\r
        long *kk = new long[4*n], l1,l2, r1,r2, t1,t2, u1,u2, b1,b2, d1,d2, p[8],num;\r
        memset(kk,-1,2*n*sizeof(long));\r
        for(i=0;i<n-1;i++)      // add intersection points for first line\r
        {\r
-               if(gr->Stop)    {       delete []kk;    return; }\r
                mgl_add_range(gr,a,x,y,z, i,0,1,0, c,u1,u2, ak,v1,v2);\r
                kk[4*i]=u1;             kk[4*i+1]=u2;\r
                mgl_add_edges(gr,a,x,y,z, i,0,1,0, c,d1,d2, ak,v1,v2);\r
@@ -561,7 +542,6 @@ void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT
                mgl_add_range(gr,a,x,y,z, 0,j-1,0,1, c,r1,r2, ak,v1,v2);\r
                for(i=0;i<n-1;i++)\r
                {\r
-                       if(gr->Stop)    {       delete []kk;    return; }\r
                        l1 = r1;                l2 = r2;        num=0;\r
                        t1 = kk[4*i];   t2 = kk[4*i+1];\r
                        b1 = kk[4*i+2]; b2 = kk[4*i+3];\r
@@ -579,7 +559,17 @@ void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT
                        if(d2>=0)       p[num++] = d2;  if(u2>=0)       p[num++] = u2;\r
                        if(u1>=0)       p[num++] = u1;  if(d1>=0)       p[num++] = d1;\r
                        if(l2>=0)       p[num++] = l2;  if(l1>=0)       p[num++] = l1;\r
+\r
+                       //      d1      u1      u2      d2\r
+                       //      l2                      r2\r
+                       //      l1                      r1\r
+                       //      b1      t1      t2      b2\r
+\r
                        // draw it\r
+                       bool b1d2 = a->v(i+1,j,ak)>v2 && a->v(i,j-1,ak)>v2;\r
+                       bool b2d1 = a->v(i,j,ak)>v2 && a->v(i+1,j-1,ak)>v2;\r
+                       mreal vv = mgl_data_linear(a,i+0.5,j-0.5,ak);\r
+                       vv = (vv-v1)*(vv-v2);\r
                        if(num<3)       continue;\r
                        if(num==4)      gr->quad_plot(p[0],p[1],p[3],p[2]);\r
                        else if(num==3) gr->trig_plot(p[0],p[1],p[2]);\r
@@ -590,8 +580,74 @@ void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT
                        }\r
                        else if(num==6)\r
                        {\r
-                               gr->quad_plot(p[0],p[1],p[3],p[2]);\r
-                               gr->quad_plot(p[0],p[3],p[5],p[4]);\r
+                               if(b1>=0 && b2>=0)\r
+                               {\r
+                                       gr->quad_plot(b1,b2,l1,r1);\r
+                                       gr->quad_plot(l1,r1,u1,u2);\r
+                               }\r
+                               else if(d1>=0 && d2>=0)\r
+                               {\r
+                                       gr->quad_plot(d1,d2,l1,r1);\r
+                                       gr->quad_plot(l1,r1,t1,t2);\r
+                               }\r
+                               else if(b1>=0 && d2>=0)\r
+                               {\r
+                                       if(b2d1)\r
+                                       {       gr->trig_plot(b1,t1,l1);        gr->trig_plot(r1,u1,d2);        }\r
+                                       else\r
+                                       {       gr->quad_plot(b1,t1,l1,r1);     gr->quad_plot(l1,r1,u1,d2);     }\r
+                               }\r
+                               else if(d1>=0 && b2>=0)\r
+                               {\r
+                                       if(b1d2)\r
+                                       {       gr->trig_plot(t1,b2,r1);        gr->trig_plot(l1,d1,u1);        }\r
+                                       else\r
+                                       {       gr->quad_plot(t1,b2,l1,r1);     gr->quad_plot(l1,r1,d1,u1);     }\r
+                               }\r
+                               else if(b1>=0 && d1>=0)\r
+                               {\r
+                                       gr->quad_plot(b1,d1,t1,u1);\r
+                                       gr->quad_plot(t1,u1,r1,r2);\r
+                               }\r
+                               else if(d2>=0 && b2>=0)\r
+                               {\r
+                                       gr->quad_plot(d2,b2,u1,t1);\r
+                                       gr->quad_plot(t1,u1,l1,l2);\r
+                               }\r
+                       }\r
+                       else if(num==7)\r
+                       {\r
+                               if(b1>=0)\r
+                               {\r
+                                       gr->trig_plot(b1,l1,t1);        gr->quad_plot(r1,r2,u1,u2);\r
+                                       if(!b2d1)       gr->quad_plot(l1,t1,u1,r1);\r
+                               }\r
+                               else if(b2>=0)\r
+                               {\r
+                                       gr->trig_plot(b2,r1,t1);        gr->quad_plot(l1,l2,u2,u1);\r
+                                       if(!b1d2)       gr->quad_plot(r1,t1,u2,l1);\r
+                               }\r
+                               else if(d2>=0)\r
+                               {\r
+                                       gr->trig_plot(d2,r1,u1);        gr->quad_plot(l1,l2,t1,t2);\r
+                                       if(!b2d1)       gr->quad_plot(r1,u1,t2,l2);\r
+                               }\r
+                               else if(d1>=0)\r
+                               {\r
+                                       gr->trig_plot(d1,l1,u1);        gr->quad_plot(r1,r2,t2,t1);\r
+                                       if(!b1d2)       gr->quad_plot(l1,u1,t1,r2);\r
+                               }\r
+                       }\r
+                       else if(num==8)\r
+                       {\r
+                               if(b2d1)\r
+                               {       if(l2<0)        {       l2=l1;  l1=b1;  }       if(r2<0)        r2=d2;\r
+                                       if(t2<0)        {       t2=t1;  t1=b1;  }       if(u2<0)        u2=d2;\r
+                                       gr->quad_plot(r1,r2,u1,u2);     gr->quad_plot(l1,l2,t1,t2);     }\r
+                               else\r
+                               {       if(l2<0)        l2=d1;  if(r2<0)        {       r2=r1;  r1=b2;  }\r
+                                       if(t2<0)        t2=b2;  if(u2<0)        {       u2=u1;  u1=d1;  }\r
+                                       gr->quad_plot(r1,r2,t2,t1);     gr->quad_plot(l1,l2,u2,u1);     }\r
                        }\r
                }\r
        }\r
@@ -618,32 +674,22 @@ void MGL_EXPORT mgl_contf_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const
        if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n)    // make\r
        {\r
                xx.Create(n, m);                yy.Create(n, m);\r
-               const mglData *mx = dynamic_cast<const mglData *>(x);\r
-               const mglData *my = dynamic_cast<const mglData *>(y);\r
-               if(mx && my)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                       {       xx.a[i+n*j] = mx->a[i]; yy.a[i+n*j] = my->a[j]; }\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                       {       xx.a[i+n*j] = x->v(i);  yy.a[i+n*j] = y->v(j);  }\r
+               for(long i=0;i<n;i++)   xx.a[i]=x->v(i);\r
+               for(long j=1;j<m;j++)   memcpy(xx.a+n*j,xx.a,n*sizeof(mreal));\r
+               for(long j=0;j<m;j++)\r
+               {       mreal t=y->v(j);        for(long i=0;i<n;i++)   yy.a[i+n*j]=t;  }\r
                x = &xx;        y = &yy;\r
        }\r
        // x, y -- have the same size z\r
-#pragma omp parallel\r
+       mglDataV zz(n, m);\r
+       for(long i=0;i<v->GetNx()-1;i++)        for(long j=0;j<z->GetNz();j++)\r
        {\r
-               mglData zz(n, m);\r
-#pragma omp for collapse(2)\r
-               for(long j=0;j<z->GetNz();j++)  for(long i=0;i<v->GetNx()-1;i++)\r
-               {\r
-                       if(gr->Stop)    continue;\r
-                       mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0;\r
-                       if(z->GetNz()>1)\r
-                               z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1);\r
-                       zz.Fill(z0,z0);\r
-                       mgl_contf_gen(gr,v0,v->v(i+1),z,x,y,&zz,gr->GetC(s,v0),j);\r
-               }\r
+               if(gr->NeedStop())      {       i = v->GetNx(); j = z->GetNz(); continue;       }\r
+               mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0;\r
+               if(z->GetNz()>1)\r
+                       z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1);\r
+               zz.Fill(z0,z0);\r
+               mgl_contf_gen(gr,v0,v->v(i+1),z,x,y,&zz,gr->GetC(s,v0),j);\r
        }\r
        gr->EndGroup();\r
 }\r
@@ -653,7 +699,7 @@ void MGL_EXPORT mgl_contf_val(HMGL gr, HCDT v, HCDT z, const char *sch, const ch
        register long n = z->GetNx(), m = z->GetNy();\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"Cont"); return; }\r
        gr->SaveState(opt);\r
-       mglData x(n, m), y(n, m);\r
+       mglDataV x(n, m), y(n, m);\r
        x.Fill(gr->Min.x,gr->Max.x,'x');\r
        y.Fill(gr->Min.y,gr->Max.y,'y');\r
        mgl_contf_xy_val(gr,v,&x,&y,z,sch,0);\r
@@ -664,7 +710,7 @@ void MGL_EXPORT mgl_contf_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, c
        mreal r = gr->SaveState(opt);\r
        long Num = mgl_isnan(r)?7:long(r+0.5);\r
        if(Num<1)       {       gr->SetWarn(mglWarnCnt,"Cont"); return; }\r
-       mglData v(Num+2);       v.Fill(gr->Min.c, gr->Max.c);\r
+       mglDataV v(Num+2);      v.Fill(gr->Min.c, gr->Max.c);\r
        mgl_contf_xy_val(gr,&v,x,y,z,sch,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -673,7 +719,7 @@ void MGL_EXPORT mgl_contf(HMGL gr, HCDT z, const char *sch, const char *opt)
        mreal r = gr->SaveState(opt);\r
        long Num = mgl_isnan(r)?7:long(r+0.5);\r
        if(Num<1)       {       gr->SetWarn(mglWarnCnt,"Cont"); return; }\r
-       mglData v(Num+2);       v.Fill(gr->Min.c, gr->Max.c);\r
+       mglDataV v(Num+2);      v.Fill(gr->Min.c, gr->Max.c);\r
        mgl_contf_val(gr,&v,z,sch,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -705,22 +751,22 @@ void MGL_EXPORT mgl_contf_(uintptr_t *gr, uintptr_t *a, const char *sch, const c
 //-----------------------------------------------------------------------------\r
 int MGL_NO_EXPORT mgl_get_ncol(const char *sch, char *res)\r
 {\r
-       register long i,j=0;\r
-       if(sch) for(i=0;sch[i]&&sch[i]!=':';i++)        if(strchr(MGL_COLORS,sch[i]))\r
+       long j=0;\r
+       if(sch) for(long i=0;sch[i]&&sch[i]!=':';i++)   if(strchr(MGL_COLORS,sch[i]))\r
        {       if(res) res[j]=sch[i];  j++;    }\r
        return j?j:strlen(MGL_DEF_PAL);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_contd_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
 {\r
-       long i,j=0,n=z->GetNx(),m=z->GetNy();\r
+       long j=0,n=z->GetNx(),m=z->GetNy();\r
        if(mgl_check_dim2(gr,x,y,z,0,"ContD"))  return;\r
 \r
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("ContD",cgid++);\r
 \r
        bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z);\r
-       if(sch) for(i=0;sch[i];i++)     if(strchr(MGL_COLORS,sch[i]))   j++;\r
+       if(sch) for(long i=0;sch[i];i++)        if(strchr(MGL_COLORS,sch[i]))   j++;\r
        if(j==0)        sch = MGL_DEF_PAL;\r
        long s = gr->AddTexture(sch,1);\r
        int nc = gr->GetNumPal(s*256);\r
@@ -728,33 +774,23 @@ void MGL_EXPORT mgl_contd_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const
        if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n)    // make\r
        {\r
                xx.Create(n, m);                yy.Create(n, m);\r
-               const mglData *mx = dynamic_cast<const mglData *>(x);\r
-               const mglData *my = dynamic_cast<const mglData *>(y);\r
-               if(mx && my)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                       {       xx.a[i+n*j] = mx->a[i]; yy.a[i+n*j] = my->a[j]; }\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                       {       xx.a[i+n*j] = x->v(i);  yy.a[i+n*j] = y->v(j);  }\r
+               for(long i=0;i<n;i++)   xx.a[i]=x->v(i);\r
+               for(long j=1;j<m;j++)   memcpy(xx.a+n*j,xx.a,n*sizeof(mreal));\r
+               for(long j=0;j<m;j++)\r
+               {       mreal t=y->v(j);        for(long i=0;i<n;i++)   yy.a[i+n*j]=t;  }\r
                x = &xx;        y = &yy;\r
        }\r
        // x, y -- have the same size z\r
        mreal dc = nc>1 ? 1/(MGL_FEPSILON*(nc-1)) : 0;\r
-#pragma omp parallel\r
+       mglDataV zz(n, m);\r
+       for(long i=0;i<v->GetNx()-1;i++)        for(long j=0;j<z->GetNz();j++)\r
        {\r
-               mglData zz(n, m);\r
-#pragma omp for collapse(2)\r
-               for(long j=0;j<z->GetNz();j++)  for(long i=0;i<v->GetNx()-1;i++)\r
-               {\r
-                       if(gr->Stop)    continue;\r
-                       mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0;\r
-                       if(z->GetNz()>1)\r
-                               z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1);\r
-                       zz.Fill(z0,z0);\r
-                       mgl_contf_gen(gr,v0,v->v(i+1),z,x,y,&zz,s+i*dc,j);\r
-               }\r
+               if(gr->NeedStop())      {       i = v->GetNx(); j = z->GetNz(); continue;       }\r
+               mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0;\r
+               if(z->GetNz()>1)\r
+                       z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1);\r
+               zz.Fill(z0,z0);\r
+               mgl_contf_gen(gr,v0,v->v(i+1),z,x,y,&zz,s+i*dc,j);\r
        }\r
        gr->EndGroup();\r
 }\r
@@ -764,7 +800,7 @@ void MGL_EXPORT mgl_contd_val(HMGL gr, HCDT v, HCDT z, const char *sch, const ch
        register long n = z->GetNx(), m = z->GetNy();\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"ContD");        return; }\r
        gr->SaveState(opt);\r
-       mglData x(n, m), y(n, m);\r
+       mglDataV x(n, m), y(n, m);\r
        x.Fill(gr->Min.x,gr->Max.x,'x');\r
        y.Fill(gr->Min.y,gr->Max.y,'y');\r
        mgl_contd_xy_val(gr,v,&x,&y,z,sch,0);\r
@@ -773,7 +809,7 @@ void MGL_EXPORT mgl_contd_val(HMGL gr, HCDT v, HCDT z, const char *sch, const ch
 void MGL_EXPORT mgl_contd_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData v(mgl_get_ncol(sch,0)+1);\r
+       mglDataV v(mgl_get_ncol(sch,0)+1);\r
        v.Fill(gr->Min.c, gr->Max.c);\r
        mgl_contd_xy_val(gr,&v,x,y,z,sch,0);\r
 }\r
@@ -781,7 +817,7 @@ void MGL_EXPORT mgl_contd_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, c
 void MGL_EXPORT mgl_contd(HMGL gr, HCDT z, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData v(mgl_get_ncol(sch,0)+1);\r
+       mglDataV v(mgl_get_ncol(sch,0)+1);\r
        v.Fill(gr->Min.c, gr->Max.c);\r
        mgl_contd_val(gr,&v,z,sch,0);\r
 }\r
@@ -818,23 +854,19 @@ void MGL_EXPORT mgl_contv_gen(HMGL gr, mreal val, mreal dval, HCDT a, HCDT x, HC
        if(n<2 || m<2 || x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m || z->GetNx()*z->GetNy()!=n*m)\r
        {       gr->SetWarn(mglWarnDim,"ContGen");      return; }\r
 \r
-       std::vector<mglPnt2> kk;\r
-       long *nn = mgl_cont_prep(val, a, ak, kk), *ff;\r
-       if(!nn) return; // nothing to do\r
-       register long i, pc=kk.size();\r
-       register mreal xx, yy;\r
-       ff = new long[2*pc];    gr->Reserve(2*pc);\r
-       mglPoint p,q;\r
-       for(i=0;i<pc;i++)\r
+       const std::vector<mglSegment> curvs = mgl_get_curvs(gr,mgl_get_lines(val,a,x,y,z,ak));\r
+       for(size_t i=0;i<curvs.size();i++)\r
        {\r
-               xx = kk[i].x;   yy = kk[i].y;\r
-               p = mglPoint(mgl_data_linear(x,xx,yy,ak), mgl_data_linear(y,xx,yy,ak), mgl_data_linear(z,xx,yy,ak));\r
-               q = mglPoint(p.y,-p.x);         ff[i] = gr->AddPnt(p, c, q);\r
-               ff[i+pc] = gr->AddPnt(mglPoint(p.x, p.y, p.z+dval), c, q);\r
+               const std::list<mglPoint> &pp=curvs[i].pp;\r
+               long f2=-1,g2=-1;\r
+               for(std::list<mglPoint>::const_iterator it=pp.begin(); it != pp.end(); ++it)\r
+               {\r
+                       mglPoint p=*it,q(p.y,-p.x);\r
+                       long f1 = f2;   f2 = gr->AddPnt(p,c,q); p.z+=dval;\r
+                       long g1 = g2;   g2 = gr->AddPnt(p,c,q);\r
+                       gr->quad_plot(f1,g1,f2,g2);\r
+               }\r
        }\r
-\r
-       for(i=0;i<pc;i++)       if(nn[i]>=0)    gr->quad_plot(ff[i], ff[nn[i]], ff[i+pc], ff[nn[i]+pc]);\r
-       delete []nn;    delete []ff;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_contv_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
@@ -852,35 +884,25 @@ void MGL_EXPORT mgl_contv_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const
        if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n)    // make\r
        {\r
                xx.Create(n, m);                yy.Create(n, m);\r
-               const mglData *mx = dynamic_cast<const mglData *>(x);\r
-               const mglData *my = dynamic_cast<const mglData *>(y);\r
-               if(mx && my)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                       {       xx.a[i+n*j] = mx->a[i]; yy.a[i+n*j] = my->a[j]; }\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                       {       xx.a[i+n*j] = x->v(i);  yy.a[i+n*j] = y->v(j);  }\r
+               for(long i=0;i<n;i++)   xx.a[i]=x->v(i);\r
+               for(long j=1;j<m;j++)   memcpy(xx.a+n*j,xx.a,n*sizeof(mreal));\r
+               for(long j=0;j<m;j++)\r
+               {       mreal t=y->v(j);        for(long i=0;i<n;i++)   yy.a[i+n*j]=t;  }\r
                x = &xx;        y = &yy;\r
        }\r
        // x, y -- have the same size z\r
-#pragma omp parallel\r
+       mglDataV zz(n, m);\r
+       for(long i=0;i<v->GetNx();i++)  for(long j=0;j<z->GetNz();j++)\r
        {\r
-               mglData zz(n, m);\r
-#pragma omp for collapse(2)\r
-               for(long j=0;j<z->GetNz();j++)  for(long i=0;i<v->GetNx();i++)\r
-               {\r
-                       if(gr->Stop)    continue;\r
-                       mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0;\r
-                       if(z->GetNz()>1)        z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1);\r
-                       zz.Fill(z0,z0);\r
-                       mreal dv = (gr->Max.c-gr->Min.c)/8;\r
-                       if(i>0) dv = v->v(i-1)-v->v(i);\r
-                       else if(i<v->GetNx()-1) dv = v->v(i)-v->v(i+1);\r
-                       if(fixed)       dv=-dv;\r
-                       mgl_contv_gen(gr,v0,dv,z,x,y,&zz,gr->GetC(s,v0),j);\r
-               }\r
+               if(gr->NeedStop())      {       i = v->GetNx(); j = z->GetNz(); continue;       }\r
+               mreal v0 = v->v(i), z0 = fixed ? gr->Min.z : v0;\r
+               if(z->GetNz()>1)        z0 = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(j)/(z->GetNz()-1);\r
+               zz.Fill(z0,z0);\r
+               mreal dv = (gr->Max.c-gr->Min.c)/8;\r
+               if(i>0) dv = v->v(i-1)-v->v(i);\r
+               else if(i<v->GetNx()-1) dv = v->v(i)-v->v(i+1);\r
+               if(fixed)       dv=-dv;\r
+               mgl_contv_gen(gr,v0,dv,z,x,y,&zz,gr->GetC(s,v0),j);\r
        }\r
        gr->EndGroup();\r
 }\r
@@ -890,7 +912,7 @@ void MGL_EXPORT mgl_contv_val(HMGL gr, HCDT v, HCDT z, const char *sch, const ch
        register long n = z->GetNx(), m = z->GetNy();\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"Cont"); return; }\r
        gr->SaveState(opt);\r
-       mglData x(n, m), y(n, m);\r
+       mglDataV x(n, m), y(n, m);\r
        x.Fill(gr->Min.x,gr->Max.x,'x');\r
        y.Fill(gr->Min.y,gr->Max.y,'y');\r
        mgl_contv_xy_val(gr,v,&x,&y,z,sch,0);\r
@@ -945,84 +967,7 @@ struct _mgl_slice  {       mglData x,y,z,a;        };
 //-----------------------------------------------------------------------------\r
 void MGL_NO_EXPORT mgl_get_slice(_mgl_slice &s, HCDT x, HCDT y, HCDT z, HCDT a, char dir, mreal d, bool both)\r
 {\r
-       register long i,j,i0,n=a->GetNx(),m=a->GetNy(),l=a->GetNz(), nx=1,ny=1,p;\r
-\r
-       if(dir=='x')    {       nx = m; ny = l; if(d<0) d = n/2.;       }\r
-       if(dir=='y')    {       nx = n; ny = l; if(d<0) d = m/2.;       }\r
-       if(dir=='z')    {       nx = n; ny = m; if(d<0) d = l/2.;       }\r
-       s.x.Create(nx,ny);      s.y.Create(nx,ny);\r
-       s.z.Create(nx,ny);      s.a.Create(nx,ny);\r
-       p = long(d);    d -= p;\r
-       if(dir=='x' && p>=n-1)  {       d+=p-n+2;       p=n-2;  }\r
-       if(dir=='y' && p>=m-1)  {       d+=p-m+2.;      p=m-2;  }\r
-       if(dir=='z' && p>=l-1)  {       d+=p-l+2;       p=l-2;  }\r
-       mreal v;\r
-\r
-       if(both)\r
-       {\r
-               if(dir=='x')    for(j=0;j<ny;j++)       for(i=0;i<nx;i++)\r
-               {\r
-                       i0 = i+nx*j;\r
-                       s.x.a[i0] = x->v(p,i,j)*(1-d) + x->v(p+1,i,j)*d;\r
-                       s.y.a[i0] = y->v(p,i,j)*(1-d) + y->v(p+1,i,j)*d;\r
-                       s.z.a[i0] = z->v(p,i,j)*(1-d) + z->v(p+1,i,j)*d;\r
-                       s.a.a[i0] = a->v(p,i,j)*(1-d) + a->v(p+1,i,j)*d;\r
-               }\r
-               if(dir=='y')    for(j=0;j<ny;j++)       for(i=0;i<nx;i++)\r
-               {\r
-                       i0 = i+nx*j;\r
-                       s.x.a[i0] = x->v(i,p,j)*(1-d) + x->v(i,p+1,j)*d;\r
-                       s.y.a[i0] = y->v(i,p,j)*(1-d) + y->v(i,p+1,j)*d;\r
-                       s.z.a[i0] = z->v(i,p,j)*(1-d) + z->v(i,p+1,j)*d;\r
-                       s.a.a[i0] = a->v(i,p,j)*(1-d) + a->v(i,p+1,j)*d;\r
-               }\r
-               if(dir=='z')    for(j=0;j<ny;j++)       for(i=0;i<nx;i++)\r
-               {\r
-                       i0 = i+nx*j;\r
-                       s.x.a[i0] = x->v(i,j,p)*(1-d) + x->v(i,j,p+1)*d;\r
-                       s.y.a[i0] = y->v(i,j,p)*(1-d) + y->v(i,j,p+1)*d;\r
-                       s.z.a[i0] = z->v(i,j,p)*(1-d) + z->v(i,j,p+1)*d;\r
-                       s.a.a[i0] = a->v(i,j,p)*(1-d) + a->v(i,j,p+1)*d;\r
-               }\r
-       }\r
-       else    // x, y, z -- vectors\r
-       {\r
-               if(dir=='x')\r
-               {\r
-                       v = x->v(p)*(1-d)+x->v(p+1)*d;\r
-                       for(j=0;j<ny;j++)       for(i=0;i<nx;i++)\r
-                       {\r
-                               i0 = i+nx*j;    s.x.a[i0] = v;\r
-                               s.y.a[i0] = y->v(i);    s.z.a[i0] = z->v(j);\r
-                               s.a.a[i0] = a->v(p,i,j)*(1-d) + a->v(p+1,i,j)*d;\r
-                       }\r
-               }\r
-               if(dir=='y')\r
-               {\r
-                       v = y->v(p)*(1-d)+y->v(p+1)*d;\r
-                       for(j=0;j<ny;j++)       for(i=0;i<nx;i++)\r
-                       {\r
-                               i0 = i+nx*j;    s.y.a[i0] = v;\r
-                               s.x.a[i0] = x->v(i);    s.z.a[i0] = z->v(j);\r
-                               s.a.a[i0] = a->v(i,p,j)*(1-d) + a->v(i,p+1,j)*d;\r
-                       }\r
-               }\r
-               if(dir=='z')\r
-               {\r
-                       v = z->v(p)*(1-d)+z->v(p+1)*d;\r
-                       for(j=0;j<ny;j++)       for(i=0;i<nx;i++)\r
-                       {\r
-                               i0 = i+nx*j;    s.z.a[i0] = v;\r
-                               s.x.a[i0] = x->v(i);    s.y.a[i0] = y->v(j);\r
-                               s.a.a[i0] = a->v(i,j,p)*(1-d) + a->v(i,j,p+1)*d;\r
-                       }\r
-               }\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void MGL_NO_EXPORT mgl_get_slice_md(_mgl_slice &s, const mglData *x, const mglData *y, const mglData *z, const mglData *a, char dir, mreal d, bool both)\r
-{\r
-       long n=a->nx,m=a->ny,l=a->nz, nx=1,ny=1,p;\r
+       register long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(), nx=1,ny=1,p;\r
 \r
        if(dir=='x')    {       nx = m; ny = l; if(d<0) d = n/2.;       }\r
        if(dir=='y')    {       nx = n; ny = l; if(d<0) d = m/2.;       }\r
@@ -1041,66 +986,66 @@ void MGL_NO_EXPORT mgl_get_slice_md(_mgl_slice &s, const mglData *x, const mglDa
 #pragma omp parallel for collapse(2)\r
                        for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        {\r
-                               register long i0 = i+nx*j, i1 = p+n*(i+m*j);\r
-                               s.x.a[i0] = x->a[i1]*(1-d) + x->a[i1+1]*d;\r
-                               s.y.a[i0] = y->a[i1]*(1-d) + y->a[i1+1]*d;\r
-                               s.z.a[i0] = z->a[i1]*(1-d) + z->a[i1+1]*d;\r
-                               s.a.a[i0] = a->a[i1]*(1-d) + a->a[i1+1]*d;\r
+                               register long i0 = i+nx*j;\r
+                               s.x.a[i0] = x->v(p,i,j)*(1-d) + x->v(p+1,i,j)*d;\r
+                               s.y.a[i0] = y->v(p,i,j)*(1-d) + y->v(p+1,i,j)*d;\r
+                               s.z.a[i0] = z->v(p,i,j)*(1-d) + z->v(p+1,i,j)*d;\r
+                               s.a.a[i0] = a->v(p,i,j)*(1-d) + a->v(p+1,i,j)*d;\r
                        }\r
                if(dir=='y')\r
 #pragma omp parallel for collapse(2)\r
                        for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        {\r
-                               register long i0 = i+nx*j, i1 = i+n*(p+m*j);\r
-                               s.x.a[i0] = x->a[i1]*(1-d) + x->a[i1+n]*d;\r
-                               s.y.a[i0] = y->a[i1]*(1-d) + y->a[i1+n]*d;\r
-                               s.z.a[i0] = z->a[i1]*(1-d) + z->a[i1+n]*d;\r
-                               s.a.a[i0] = a->a[i1]*(1-d) + a->a[i1+n]*d;\r
+                               register long i0 = i+nx*j;\r
+                               s.x.a[i0] = x->v(i,p,j)*(1-d) + x->v(i,p+1,j)*d;\r
+                               s.y.a[i0] = y->v(i,p,j)*(1-d) + y->v(i,p+1,j)*d;\r
+                               s.z.a[i0] = z->v(i,p,j)*(1-d) + z->v(i,p+1,j)*d;\r
+                               s.a.a[i0] = a->v(i,p,j)*(1-d) + a->v(i,p+1,j)*d;\r
                        }\r
                if(dir=='z')\r
 #pragma omp parallel for collapse(2)\r
                        for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        {\r
-                               register long i0 = i+nx*j, i1 = i+n*(j+m*p);\r
-                               s.x.a[i0] = x->a[i1]*(1-d) + x->a[i1+n*m]*d;\r
-                               s.y.a[i0] = y->a[i1]*(1-d) + y->a[i1+n*m]*d;\r
-                               s.z.a[i0] = z->a[i1]*(1-d) + z->a[i1+n*m]*d;\r
-                               s.a.a[i0] = a->a[i1]*(1-d) + a->a[i1+n*m]*d;\r
+                               register long i0 = i+nx*j;\r
+                               s.x.a[i0] = x->v(i,j,p)*(1-d) + x->v(i,j,p+1)*d;\r
+                               s.y.a[i0] = y->v(i,j,p)*(1-d) + y->v(i,j,p+1)*d;\r
+                               s.z.a[i0] = z->v(i,j,p)*(1-d) + z->v(i,j,p+1)*d;\r
+                               s.a.a[i0] = a->v(i,j,p)*(1-d) + a->v(i,j,p+1)*d;\r
                        }\r
        }\r
        else    // x, y, z -- vectors\r
        {\r
                if(dir=='x')\r
                {\r
-                       v = x->a[p]*(1-d)+x->a[p+1]*d;\r
+                       v = x->v(p)*(1-d)+x->v(p+1)*d;\r
 #pragma omp parallel for collapse(2)\r
                        for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        {\r
-                               register long i0 = i+nx*j, i1 = p+n*(i+m*j);\r
-                               s.x.a[i0] = v;  s.y.a[i0] = y->a[i];    s.z.a[i0] = z->a[j];\r
-                               s.a.a[i0] = a->a[i1]*(1-d) + a->a[i1+1]*d;\r
+                               register long i0 = i+nx*j;      s.x.a[i0] = v;\r
+                               s.y.a[i0] = y->v(i);    s.z.a[i0] = z->v(j);\r
+                               s.a.a[i0] = a->v(p,i,j)*(1-d) + a->v(p+1,i,j)*d;\r
                        }\r
                }\r
                if(dir=='y')\r
                {\r
-                       v = y->a[p]*(1-d)+y->a[p+1]*d;\r
+                       v = y->v(p)*(1-d)+y->v(p+1)*d;\r
 #pragma omp parallel for collapse(2)\r
                        for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        {\r
-                               register long i0 = i+nx*j, i1 = i+n*(p+m*j);\r
-                               s.x.a[i0] = x->a[i];    s.y.a[i0] = v;  s.z.a[i0] = z->a[j];\r
-                               s.a.a[i0] = a->a[i1]*(1-d) + a->a[i1+n]*d;\r
+                               register long i0 = i+nx*j;      s.y.a[i0] = v;\r
+                               s.x.a[i0] = x->v(i);    s.z.a[i0] = z->v(j);\r
+                               s.a.a[i0] = a->v(i,p,j)*(1-d) + a->v(i,p+1,j)*d;\r
                        }\r
                }\r
                if(dir=='z')\r
                {\r
-                       v = z->a[p]*(1-d)+z->a[p+1]*d;\r
+                       v = z->v(p)*(1-d)+z->v(p+1)*d;\r
 #pragma omp parallel for collapse(2)\r
                        for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        {\r
-                               register long i0 = i+nx*j, i1 = i+n*(j+m*p);\r
-                               s.x.a[i0] = x->a[i];    s.y.a[i0] = y->a[j];    s.z.a[i0] = v;\r
-                               s.a.a[i0] = a->a[i1]*(1-d) + a->a[i1+n*m]*d;\r
+                               register long i0 = i+nx*j;      s.z.a[i0] = v;\r
+                               s.x.a[i0] = x->v(i);    s.y.a[i0] = y->v(j);\r
+                               s.a.a[i0] = a->v(i,j,p)*(1-d) + a->v(i,j,p+1)*d;\r
                        }\r
                }\r
        }\r
@@ -1117,18 +1062,14 @@ void MGL_EXPORT mgl_cont3_xyz_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT
        if(mglchr(sch,'x'))     dir='x';\r
        if(mglchr(sch,'z'))     dir='z';\r
 \r
-       bool text=(mglchr(sch,'t'));\r
+       int text=0;\r
+       if(mglchr(sch,'t'))     text=1;\r
+       if(mglchr(sch,'T'))     text=2;\r
        long ss=gr->AddTexture(sch);\r
        gr->SetPenPal(sch);\r
 \r
        _mgl_slice s;\r
-       const mglData *mx = dynamic_cast<const mglData *>(x);\r
-       const mglData *my = dynamic_cast<const mglData *>(y);\r
-       const mglData *mz = dynamic_cast<const mglData *>(z);\r
-       const mglData *ma = dynamic_cast<const mglData *>(a);\r
-       if(mx&&my&&mz&&ma)      mgl_get_slice_md(s,mx,my,mz,ma,dir,sVal,both);\r
-       else mgl_get_slice(s,x,y,z,a,dir,sVal,both);\r
-#pragma omp parallel for\r
+       mgl_get_slice(s,x,y,z,a,dir,sVal,both);\r
        for(long i=0;i<v->GetNx();i++)\r
        {\r
                register mreal v0 = v->v(i);\r
@@ -1140,7 +1081,7 @@ void MGL_EXPORT mgl_cont3_xyz_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT
 void MGL_EXPORT mgl_cont3_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sVal, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -1205,12 +1146,7 @@ void MGL_EXPORT mgl_dens3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const cha
        if(mglchr(sch,'z'))     dir='z';\r
 \r
        _mgl_slice s;\r
-       const mglData *mx = dynamic_cast<const mglData *>(x);\r
-       const mglData *my = dynamic_cast<const mglData *>(y);\r
-       const mglData *mz = dynamic_cast<const mglData *>(z);\r
-       const mglData *ma = dynamic_cast<const mglData *>(a);\r
-       if(mx&&my&&mz&&ma)      mgl_get_slice_md(s,mx,my,mz,ma,dir,sVal,both);\r
-       else mgl_get_slice(s,x,y,z,a,dir,sVal,both);\r
+       mgl_get_slice(s,x,y,z,a,dir,sVal,both);\r
        mgl_surfc_xy(gr,&s.x,&s.y,&s.z,&s.a,sch,0);\r
        gr->EndGroup();\r
 }\r
@@ -1218,7 +1154,7 @@ void MGL_EXPORT mgl_dens3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const cha
 void MGL_EXPORT mgl_dens3(HMGL gr, HCDT a, const char *sch, double sVal, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -1252,12 +1188,7 @@ void MGL_EXPORT mgl_grid3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const cha
        if(mglchr(sch,'z'))     dir='z';\r
 \r
        _mgl_slice s;\r
-       const mglData *mx = dynamic_cast<const mglData *>(x);\r
-       const mglData *my = dynamic_cast<const mglData *>(y);\r
-       const mglData *mz = dynamic_cast<const mglData *>(z);\r
-       const mglData *ma = dynamic_cast<const mglData *>(a);\r
-       if(mx&&my&&mz&&ma)      mgl_get_slice_md(s,mx,my,mz,ma,dir,sVal,both);\r
-       else mgl_get_slice(s,x,y,z,a,dir,sVal,both);\r
+       mgl_get_slice(s,x,y,z,a,dir,sVal,both);\r
        mgl_mesh_xy(gr,&s.x,&s.y,&s.z,sch,0);\r
        gr->EndGroup();\r
 }\r
@@ -1265,7 +1196,7 @@ void MGL_EXPORT mgl_grid3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const cha
 void MGL_EXPORT mgl_grid3(HMGL gr, HCDT a, const char *sch, double sVal, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()), z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()), z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -1300,13 +1231,7 @@ void MGL_EXPORT mgl_contf3_xyz_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT
 \r
        long ss=gr->AddTexture(sch);\r
        _mgl_slice s;\r
-       const mglData *mx = dynamic_cast<const mglData *>(x);\r
-       const mglData *my = dynamic_cast<const mglData *>(y);\r
-       const mglData *mz = dynamic_cast<const mglData *>(z);\r
-       const mglData *ma = dynamic_cast<const mglData *>(a);\r
-       if(mx&&my&&mz&&ma)      mgl_get_slice_md(s,mx,my,mz,ma,dir,sVal,both);\r
-       else mgl_get_slice(s,x,y,z,a,dir,sVal,both);\r
-#pragma omp parallel for\r
+       mgl_get_slice(s,x,y,z,a,dir,sVal,both);\r
        for(long i=0;i<v->GetNx()-1;i++)\r
        {\r
                register mreal v0 = v->v(i);\r
@@ -1318,7 +1243,7 @@ void MGL_EXPORT mgl_contf3_xyz_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, HCDT
 void MGL_EXPORT mgl_contf3_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sVal, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -1330,7 +1255,7 @@ void MGL_EXPORT mgl_contf3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const ch
        mreal r = gr->SaveState(opt);\r
        long Num = mgl_isnan(r)?7:long(r+0.5);\r
        if(Num<1)       {       gr->SetWarn(mglWarnCnt,"ContF3");       return; }\r
-       mglData v(Num+2);       v.Fill(gr->Min.c, gr->Max.c);\r
+       mglDataV v(Num+2);      v.Fill(gr->Min.c, gr->Max.c);\r
        mgl_contf3_xyz_val(gr,&v,x,y,z,a,sch,sVal,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1339,7 +1264,7 @@ void MGL_EXPORT mgl_contf3(HMGL gr, HCDT a, const char *sch, double sVal, const
        mreal r = gr->SaveState(opt);\r
        long Num = mgl_isnan(r)?7:long(r+0.5);\r
        if(Num<1)       {       gr->SetWarn(mglWarnCnt,"ContF3");       return; }\r
-       mglData v(Num+2);       v.Fill(gr->Min.c, gr->Max.c);\r
+       mglDataV v(Num+2);      v.Fill(gr->Min.c, gr->Max.c);\r
        mgl_contf3_val(gr,&v,a,sch,sVal,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1371,7 +1296,7 @@ delete []o;       delete []s;     }
 //     Axial series\r
 //\r
 //-----------------------------------------------------------------------------\r
-long MGL_NO_EXPORT mgl_find_prev(long i, long pc, long *nn)\r
+long MGL_LOCAL_PURE mgl_find_prev(long i, long pc, long *nn)\r
 {\r
        for(long k=0;k<pc;k++)  if(nn[k]==i)    return k;\r
        return -1;\r
@@ -1383,14 +1308,12 @@ void MGL_NO_EXPORT mgl_axial_plot(mglBase *gr,long pc, mglPoint *ff, long *nn,ch
        if(dir=='y')    a = mglPoint(0,1,0);\r
        b = !a; c = a^b;\r
 \r
-       register long i,j,k;\r
        long p1,p2,p3,p4;\r
        gr->Reserve(pc*82);\r
-       for(i=0;i<pc;i++)\r
+       for(long i=0;i<pc;i++)\r
        {\r
-               if(gr->Stop)    return;\r
-               k = mgl_find_prev(i,pc,nn);\r
                if(nn[i]<0)     continue;\r
+               register long k = mgl_find_prev(i,pc,nn);\r
                q1 = k<0 ? ff[nn[i]]-ff[i]  : (ff[nn[i]]-ff[k])*0.5;\r
                q2 = nn[nn[i]]<0 ? ff[nn[i]]-ff[i]  : (ff[nn[nn[i]]]-ff[i])*0.5;\r
 \r
@@ -1401,7 +1324,7 @@ void MGL_NO_EXPORT mgl_axial_plot(mglBase *gr,long pc, mglPoint *ff, long *nn,ch
                if(wire==1)     gr->line_plot(p1,p2);\r
                else if(wire)   {       gr->mark_plot(p1,'.');  gr->mark_plot(p2,'.');  }\r
 \r
-               for(j=1;j<41;j++)\r
+               for(long j=1;j<41;j++)\r
                {\r
                        p3 = p1;        p4 = p2;\r
                        register float co = mgl_cos[(j*18)%360], si = mgl_cos[(270+j*18)%360];\r
@@ -1427,8 +1350,7 @@ void MGL_EXPORT mgl_axial_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, mreal
        {       gr->SetWarn(mglWarnDim,"ContGen");      return; }\r
 \r
        mglPoint *kk = new mglPoint[2*n*m],*pp = new mglPoint[2*n*m],p;\r
-       mreal d, kx, ky;\r
-       register long i,j,k, pc=0,i0;\r
+       long pc=0;\r
        // Usually number of points is much smaller. So, there is no reservation.\r
        //      gr->Reserve(2*n*m);\r
 \r
@@ -1436,11 +1358,10 @@ void MGL_EXPORT mgl_axial_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, mreal
        const mglData *mx = dynamic_cast<const mglData *>(x);\r
        const mglData *my = dynamic_cast<const mglData *>(y);\r
        const mglData *ma = dynamic_cast<const mglData *>(a);\r
-       if(mx&&my&&ma)  for(j=0;j<m;j++)        for(i=0;i<n;i++)\r
+       if(mx&&my&&ma)  for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
        {\r
-               if(gr->Stop)    {       delete []kk;    delete []pp;    return; }\r
-               i0 = i+n*j;\r
-               d = (i<n-1)?mgl_d(val,ma->a[i0+n*m*ak],ma->a[i0+1+n*m*ak]):-1;\r
+               register long i0 = i+n*j;\r
+               mreal d = (i<n-1)?mgl_d(val,ma->a[i0+n*m*ak],ma->a[i0+1+n*m*ak]):-1;\r
                if(d>=0 && d<1)\r
                {\r
                        pp[pc] = mglPoint(mx->a[i0]*(1-d)+mx->a[i0+1]*d, my->a[i0]*(1-d)+my->a[i0+1]*d);\r
@@ -1453,11 +1374,10 @@ void MGL_EXPORT mgl_axial_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, mreal
                        kk[pc] = mglPoint(i,j+d);       pc++;\r
                }\r
        }\r
-       else    for(j=0;j<m;j++)        for(i=0;i<n;i++)\r
+       else    for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
        {\r
-               if(gr->Stop)    {       delete []kk;    delete []pp;    return; }\r
                register mreal va=a->v(i,j,ak),vx=x->v(i,j),vy=y->v(i,j);\r
-               d = (i<n-1)?mgl_d(val,va,a->v(i+1,j,ak)):-1;\r
+               mreal d = (i<n-1)?mgl_d(val,va,a->v(i+1,j,ak)):-1;\r
                if(d>=0 && d<1)\r
                {\r
                        pp[pc] = mglPoint(vx*(1-d)+x->v(i+1,j)*d, vy*(1-d)+y->v(i+1,j)*d);\r
@@ -1474,22 +1394,20 @@ void MGL_EXPORT mgl_axial_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, mreal
        if(pc==0)       {       delete []kk;    delete []pp;    return; }\r
        // allocate arrays for curve\r
        long *nn = new long[pc], *ff = new long[pc];\r
-       for(i=0;i<pc;i++)       nn[i] = ff[i] = -1;\r
+       for(long i=0;i<pc;i++)  nn[i] = ff[i] = -1;\r
        // connect points to line\r
-       long i11,i12,i21,i22,j11,j12,j21,j22;\r
-       j=-1;   // current point\r
+       long j=-1;      // current point\r
        do{\r
-               if(gr->Stop)    {       delete []kk;    delete []pp;    delete []nn;    delete []ff;    return; }\r
                if(j>=0)\r
                {\r
-                       kx = kk[j].x;   ky = kk[j].y;   i = -1;\r
-                       i11 = long(kx+1e-5);    i12 = long(kx-1e-5);\r
-                       j11 = long(ky+1e-5);    j12 = long(ky-1e-5);\r
-                       for(k=0;k<pc;k++)       // find closest point in grid\r
+                       mreal kx = kk[j].x, ky = kk[j].y;       long i = -1;\r
+                       long i11 = long(kx+1e-5), i12 = long(kx-1e-5);\r
+                       long j11 = long(ky+1e-5), j12 = long(ky-1e-5);\r
+                       for(long k=0;k<pc;k++)  // find closest point in grid\r
                        {\r
                                if(k==j || k==ff[j] || ff[k]!=-1)       continue;       // point is marked\r
-                               i21 = long(kk[k].x+1e-5);       i22 = long(kk[k].x-1e-5);\r
-                               j21 = long(kk[k].y+1e-5);       j22 = long(kk[k].y-1e-5);\r
+                               long i21 = long(kk[k].x+1e-5), i22 = long(kk[k].x-1e-5);\r
+                               long j21 = long(kk[k].y+1e-5), j22 = long(kk[k].y-1e-5);\r
                                // check if in the same cell\r
                                register bool cond = (i11==i21 || i11==i22 || i12==i21 || i12==i22) &&\r
                                (j11==j21 || j11==j22 || j12==j21 || j12==j22);\r
@@ -1501,12 +1419,12 @@ void MGL_EXPORT mgl_axial_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, mreal
                }\r
                if(j<0)\r
                {\r
-                       for(k=0;k<pc;k++)       if(nn[k]==-1)   // first check edges\r
+                       for(long k=0;k<pc;k++)  if(nn[k]==-1)   // first check edges\r
                        {\r
                                if(kk[k].x==0 || fabs(kk[k].x-n+1)<1e-5 || kk[k].y==0 || fabs(kk[k].y-m+1)<1e-5)\r
                                {       nn[k]=-2;       j = k;  break;  }\r
                        }\r
-                       if(j<0) for(k=0;k<pc;k++)       if(nn[k]==-1)   // or any points inside\r
+                       if(j<0) for(long k=0;k<pc;k++)  if(nn[k]==-1)   // or any points inside\r
                        {       j = k;  nn[k]=-2;       break;  }\r
                }\r
        }while(j>=0);\r
@@ -1529,25 +1447,18 @@ void MGL_EXPORT mgl_axial_xy_val(HMGL gr, HCDT v, HCDT x, HCDT y, HCDT z, const
        if(x->GetNx()*x->GetNy()!=m*n || y->GetNx()*y->GetNy()!=m*n)    // make\r
        {\r
                xx.Create(n, m);                yy.Create(n, m);\r
-               const mglData *mx = dynamic_cast<const mglData *>(x);\r
-               const mglData *my = dynamic_cast<const mglData *>(y);\r
-               if(mx && my)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long i=0;i<n;i++)   for(long j=0;j<m;j++)\r
-                       {       xx.a[i+n*j] = mx->a[i]; yy.a[i+n*j] = my->a[j]; }\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long i=0;i<n;i++)   for(long j=0;j<m;j++)\r
-                       {       xx.a[i+n*j] = x->v(i);  yy.a[i+n*j] = y->v(j);  }\r
+               for(long i=0;i<n;i++)   xx.a[i]=x->v(i);\r
+               for(long j=1;j<m;j++)   memcpy(xx.a+n*j,xx.a,n*sizeof(mreal));\r
+               for(long j=0;j<m;j++)\r
+               {       mreal t=y->v(j);        for(long i=0;i<n;i++)   yy.a[i+n*j]=t;  }\r
                x = &xx;        y = &yy;\r
        }\r
        // x, y -- have the same size z\r
        int wire = mglchr(sch,'#')?1:0;\r
        if(mglchr(sch,'.'))     wire = 2;\r
-#pragma omp parallel for collapse(2)\r
-       for(long j=0;j<z->GetNz();j++)  for(long i=0;i<v->GetNx();i++)\r
+       for(long i=0;i<v->GetNx();i++)  for(long j=0;j<z->GetNz();j++)\r
        {\r
-               if(gr->Stop)    continue;\r
+               if(gr->NeedStop())      {       i = v->GetNx(); j = z->GetNz(); continue;       }\r
                register mreal v0 = v->v(i);\r
                mgl_axial_gen(gr,v0,z,x,y,gr->GetC(s,v0),dir,j,wire);\r
        }\r
@@ -1559,7 +1470,7 @@ void MGL_EXPORT mgl_axial_val(HMGL gr, HCDT v, HCDT a, const char *sch, const ch
        register long n=a->GetNx(), m=a->GetNy();\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"Axial");        return; }\r
        gr->SaveState(opt);\r
-       mglData x(n, m), y(n, m);\r
+       mglDataV x(n, m), y(n, m);\r
        if(gr->Max.x*gr->Min.x>=0)      x.Fill(gr->Min.x,gr->Max.x,'x');\r
        else    x.Fill(0,gr->Max.x,'x');\r
        y.Fill(gr->Min.y,gr->Max.y,'y');\r
diff --git a/src/cont.hpp b/src/cont.hpp
new file mode 100644 (file)
index 0000000..8315684
--- /dev/null
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * cont.cpp is part of Math Graphic Library
+ * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>       *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU Library General Public License as       *
+ *   published by the Free Software Foundation; either version 3 of the    *
+ *   License, or (at your option) any later version.                       *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU Library General Public     *
+ *   License along with this program; if not, write to the                 *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+//-----------------------------------------------------------------------------
+struct mglSegment
+{
+       mglPoint p1,p2; // edges
+       std::list<mglPoint> pp;
+       bool set(mreal u1,mreal v1,mreal u2,mreal v2,long i,long j,long k,HCDT x, HCDT y, HCDT z)
+       {
+               bool res=(v1>=0 && v1<=MGL_FEPSILON && u1>=0 && u1<=MGL_FEPSILON && v2>=0 && v2<=MGL_FEPSILON && u2>=0 && u2<=MGL_FEPSILON);
+               if(v1==v2 && u1==u2)    res=false;      // NOTE: shouldn't be here never
+               if(res)
+               {
+                       p1 = mglPoint(mgl_data_linear(x,i+u1,j+v1,k), mgl_data_linear(y,i+u1,j+v1,k), mgl_data_linear(z,i+u1,j+v1,k));
+                       p2 = mglPoint(mgl_data_linear(x,i+u2,j+v2,k), mgl_data_linear(y,i+u2,j+v2,k), mgl_data_linear(z,i+u2,j+v2,k));
+               }
+               return res;
+       }
+       void before(const mglPoint &p)  {       p1 = p; pp.push_front(p);       }
+       void after(const mglPoint &p)   {       p2 = p; pp.push_back(p);        }
+};
+//-----------------------------------------------------------------------------
+std::vector<mglSegment> MGL_EXPORT mgl_get_curvs(HMGL gr, std::vector<mglSegment> lines);
+void MGL_NO_EXPORT mgl_draw_curvs(HMGL gr, mreal val, mreal c, int text, const std::vector<mglSegment> &curvs);
+//-----------------------------------------------------------------------------
index 95f4c44d0537b9f29afedf954b901281880648b9..f97453bbf7e521df1700666508585968b891e63c 100644 (file)
@@ -18,6 +18,8 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
  ***************************************************************************/\r
 #include <float.h>\r
+#include <math.h>\r
+#include <list>\r
 #include "mgl2/other.h"\r
 #include "mgl2/data.h"\r
 #include "mgl2/thread.h"\r
@@ -35,17 +37,15 @@ void MGL_EXPORT mgl_triplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCD
        long ss=gr->AddTexture(sch);\r
        gr->SaveState(opt);     gr->SetPenPal("-");\r
        static int cgid=1;      gr->StartGroup("TriPlot",cgid++);\r
-       mglPoint p1,p2,p3,q;\r
 \r
        bool wire = mglchr(sch,'#');\r
        long nc = a->GetNx();\r
        if(nc!=n && nc>=m)      // colors per triangle\r
        {\r
+               mglPoint p1,p2,p3,q;\r
                gr->Reserve(m*3);\r
-#pragma omp parallel for private(p1,p2,p3,q)\r
                for(long i=0;i<m;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register long k1 = long(nums->v(0,i)+0.5);\r
                        p1 = mglPoint(x->v(k1), y->v(k1), z->v(k1));\r
                        register long k2 = long(nums->v(1,i)+0.5);\r
@@ -64,10 +64,8 @@ void MGL_EXPORT mgl_triplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCD
                gr->Reserve(n);\r
                long *kk = new long[n];\r
                mglPoint *pp = new mglPoint[n];\r
-#pragma omp parallel for\r
                for(long i=0;i<m;i++)   // add averaged normales\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register long k1 = long(nums->v(0,i)+0.5);\r
                        register long k2 = long(nums->v(1,i)+0.5);\r
                        register long k3 = long(nums->v(2,i)+0.5);\r
@@ -78,21 +76,14 @@ void MGL_EXPORT mgl_triplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCD
                                q.Normalize();\r
                                // try be sure that in the same direction ...\r
                                if(q.z<0)       q *= -1;\r
-#pragma omp critical(quadplot)\r
-                               {pp[k1] += q;   pp[k2] += q;    pp[k3] += q;}\r
+                               pp[k1] += q;    pp[k2] += q;    pp[k3] += q;\r
                        }\r
                        else    pp[k1]=pp[k2]=pp[k3]=mglPoint(NAN,NAN);\r
                }\r
-#pragma omp parallel for\r
                for(long i=0;i<n;i++)   // add points\r
-               {\r
-                       if(gr->Stop)    continue;\r
                        kk[i] = gr->AddPnt(mglPoint(x->v(i), y->v(i), z->v(i)), gr->GetC(ss,a->v(i)), pp[i]);\r
-               }\r
-#pragma omp parallel for\r
                for(long i=0;i<m;i++)   // draw triangles\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register long k1 = long(nums->v(0,i)+0.5);\r
                        register long k2 = long(nums->v(1,i)+0.5);\r
                        register long k3 = long(nums->v(2,i)+0.5);\r
@@ -155,10 +146,8 @@ void MGL_EXPORT mgl_quadplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HC
        if(nc!=n && nc>=m)      // colors per triangle\r
        {\r
                gr->Reserve(m*4);\r
-#pragma omp parallel for private(p1,p2,p3,p4)\r
                for(long i=0;i<m;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register long k1 = long(nums->v(0,i)+0.5);\r
                        p1 = mglPoint(x->v(k1), y->v(k1), z->v(k1));\r
                        register long k2 = long(nums->v(1,i)+0.5);\r
@@ -180,10 +169,8 @@ void MGL_EXPORT mgl_quadplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HC
                gr->Reserve(n);\r
                long *kk = new long[n];\r
                mglPoint *pp = new mglPoint[n];\r
-#pragma omp parallel for private(p1,p2,p3,p4)\r
                for(long i=0;i<m;i++)   // add averaged normales\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register long k1 = long(nums->v(0,i)+0.5);\r
                        p1 = mglPoint(x->v(k1), y->v(k1), z->v(k1));\r
                        register long k2 = long(nums->v(1,i)+0.5);\r
@@ -200,20 +187,13 @@ void MGL_EXPORT mgl_quadplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HC
                                mglPoint q2 = (p2-p4) ^ (p3-p4);        if(q2.z<0) q2*=-1;\r
                                mglPoint q3 = (p1-p2) ^ (p4-p2);        if(q3.z<0) q3*=-1;\r
                                mglPoint q4 = (p1-p4) ^ (p4-p3);        if(q4.z<0) q4*=-1;\r
-#pragma omp critical(quadplot)\r
-                               {pp[k1] += q1;  pp[k2] += q2;   pp[k3] += q3;   pp[k4] += q4;}\r
+                               pp[k1] += q1;   pp[k2] += q2;   pp[k3] += q3;   pp[k4] += q4;\r
                        }\r
                }\r
-#pragma omp parallel for\r
                for(long i=0;i<n;i++)   // add points\r
-               {\r
-                       if(gr->Stop)    continue;\r
                        kk[i] = gr->AddPnt(mglPoint(x->v(i), y->v(i), z->v(i)),gr->GetC(ss,a->v(i)), pp[i]);\r
-               }\r
-#pragma omp parallel for\r
                for(long i=0;i<m;i++)   // draw quads\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register long k1 = floor(nums->v(0,i)+0.5);\r
                        register long k2 = floor(nums->v(1,i)+0.5);\r
                        register long k3 = floor(nums->v(2,i)+0.5);\r
@@ -261,49 +241,59 @@ void MGL_EXPORT mgl_quadplot_xy_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, u
 //     TriCont series\r
 //\r
 //-----------------------------------------------------------------------------\r
-void MGL_EXPORT mgl_tricont_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
+#include "cont.hpp"\r
+//-----------------------------------------------------------------------------\r
+std::vector<mglSegment> MGL_NO_EXPORT mgl_tri_lines(mreal val, HCDT nums, HCDT a, HCDT x, HCDT y, HCDT z)\r
 {\r
        long n = x->GetNx(), m = nums->GetNy();\r
-       if(mgl_check_trig(gr,nums,x,y,z,a,"TriCont"))   return;\r
-\r
-       long ss=gr->AddTexture(sch);\r
-       gr->SaveState(opt);\r
-       static int cgid=1;      gr->StartGroup("TriCont",cgid++);\r
-       bool zVal = !(mglchr(sch,'_'));\r
-       mglPoint p1,p2,p3;\r
-#pragma omp parallel for private(p1,p2,p3) collapse(2)\r
-       for(long k=0;k<v->GetNx();k++)  for(long i=0;i<m;i++)\r
+       std::vector<mglSegment> lines;\r
+       for(long i=0;i<m;i++)\r
        {\r
-               if(gr->Stop)    continue;\r
                register long k1 = long(nums->v(0,i)+0.1);      if(k1<0 || k1>=n)       continue;\r
                register long k2 = long(nums->v(1,i)+0.1);      if(k2<0 || k2>=n)       continue;\r
                register long k3 = long(nums->v(2,i)+0.1);      if(k3<0 || k3>=n)       continue;\r
-               register mreal val = v->v(k), c = gr->GetC(ss,val), d1,d2,d3;\r
-\r
-               d1 = mgl_d(val,a->v(k1),a->v(k2));\r
-               p1 = mglPoint(x->v(k1)*(1-d1)+x->v(k2)*d1, y->v(k1)*(1-d1)+y->v(k2)*d1,\r
-                                         zVal?z->v(k1)*(1-d1)+z->v(k2)*d1:gr->Min.z);\r
-               d2 = mgl_d(val,a->v(k1),a->v(k3));\r
-               p2 = mglPoint(x->v(k1)*(1-d2)+x->v(k3)*d2, y->v(k1)*(1-d2)+y->v(k3)*d2,\r
-                                         zVal?z->v(k1)*(1-d2)+z->v(k3)*d2:gr->Min.z);\r
-               d3 = mgl_d(val,a->v(k2),a->v(k3));\r
-               p3 = mglPoint(x->v(k2)*(1-d3)+x->v(k3)*d3, y->v(k2)*(1-d3)+y->v(k3)*d3,\r
-                                         zVal?z->v(k2)*(1-d3)+z->v(k3)*d3:gr->Min.z);\r
+               register mreal v1 = a->v(k1), v2 = a->v(k2), v3 = a->v(k3);\r
+               register mreal d1 = mgl_d(val,v1,v2), d2 = mgl_d(val,v1,v3), d3 = mgl_d(val,v2,v3);\r
+               mglSegment line;\r
                if(d1>=0 && d1<=1 && d2>=0 && d2<=1)\r
                {\r
-                       k1 = gr->AddPnt(p1,c);  k2 = gr->AddPnt(p2,c);\r
-                       gr->line_plot(k1,k2);\r
+                       line.p1 = mglPoint(x->v(k1)*(1-d1)+x->v(k2)*d1, y->v(k1)*(1-d1)+y->v(k2)*d1, z->v(k1)*(1-d1)+z->v(k2)*d1);\r
+                       line.p2 = mglPoint(x->v(k1)*(1-d2)+x->v(k3)*d2, y->v(k1)*(1-d2)+y->v(k3)*d2, z->v(k1)*(1-d2)+z->v(k3)*d2);\r
                }\r
                else if(d1>=0 && d1<=1 && d3>=0 && d3<=1)\r
                {\r
-                       k1 = gr->AddPnt(p1,c);  k2 = gr->AddPnt(p3,c);\r
-                       gr->line_plot(k1,k2);\r
+                       line.p1 = mglPoint(x->v(k1)*(1-d1)+x->v(k2)*d1, y->v(k1)*(1-d1)+y->v(k2)*d1, z->v(k1)*(1-d1)+z->v(k2)*d1);\r
+                       line.p2 = mglPoint(x->v(k2)*(1-d3)+x->v(k3)*d3, y->v(k2)*(1-d3)+y->v(k3)*d3, z->v(k2)*(1-d3)+z->v(k3)*d3);\r
                }\r
                else if(d3>=0 && d3<=1 && d2>=0 && d2<=1)\r
                {\r
-                       k1 = gr->AddPnt(p3,c);  k2 = gr->AddPnt(p2,c);\r
-                       gr->line_plot(k1,k2);\r
+                       line.p1 = mglPoint(x->v(k1)*(1-d2)+x->v(k3)*d2, y->v(k1)*(1-d2)+y->v(k3)*d2, z->v(k1)*(1-d2)+z->v(k3)*d2);\r
+                       line.p2 = mglPoint(x->v(k2)*(1-d3)+x->v(k3)*d3, y->v(k2)*(1-d3)+y->v(k3)*d3, z->v(k2)*(1-d3)+z->v(k3)*d3);\r
                }\r
+               if(line.p1!=line.p2)    lines.push_back(line);\r
+       }\r
+       return lines;\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_tricont_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
+{\r
+       mglDataV zz(x->GetNx(),x->GetNy());\r
+       if(!z)  z = &zz;\r
+       if(mgl_check_trig(gr,nums,x,y,z,a,"TriCont"))   return;\r
+\r
+       gr->SaveState(opt);\r
+       static int cgid=1;      gr->StartGroup("TriCont",cgid++);\r
+       int text=0;\r
+       if(mglchr(sch,'t'))     text=1;\r
+       if(mglchr(sch,'T'))     text=2;\r
+       bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z);\r
+       long s=gr->AddTexture(sch);\r
+       gr->SetPenPal(sch);\r
+\r
+       for(long k=0;k<v->GetNx();k++)\r
+       {\r
+               mreal v0 = v->v(k);             zz.Fill(fixed ? gr->Min.z : v0);\r
+               mgl_draw_curvs(gr,v0,gr->GetC(s,v0),text,mgl_get_curvs(gr,mgl_tri_lines(v0,nums,a,x,y,fixed?&zz:z)));\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -317,10 +307,10 @@ void MGL_EXPORT mgl_tricont_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCD
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_tricont_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
-{      mgl_tricont_xyzc(gr,nums,x,y,z,z,sch,opt);      }\r
+{      mgl_tricont_xyzc(gr,nums,x,y,0,z,sch,opt);      }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_tricont_xycv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
-{      mgl_tricont_xyzcv(gr,v,nums,x,y,z,z,sch,opt);   }\r
+{      mgl_tricont_xyzcv(gr,v,nums,x,y,0,z,sch,opt);   }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_tricont_xyzcv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo)\r
 {      char *s=new char[l+1];  memcpy(s,sch,l);        s[l]=0;\r
@@ -347,6 +337,85 @@ void MGL_EXPORT mgl_tricont_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, u
        delete []o;     delete []s;     }\r
 //-----------------------------------------------------------------------------\r
 //\r
+//     TriContV series\r
+//\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_tricontv_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
+{\r
+       mglDataV zz(x->GetNx(),x->GetNy());\r
+       if(!z)  z = &zz;\r
+       if(mgl_check_trig(gr,nums,x,y,z,a,"TriContV"))  return;\r
+\r
+       gr->SaveState(opt);\r
+       static int cgid=1;      gr->StartGroup("TriContV",cgid++);\r
+       bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z);\r
+       long s=gr->AddTexture(sch);\r
+       gr->SetPenPal(sch);\r
+\r
+       for(long k=0;k<v->GetNx();k++)\r
+       {\r
+               mreal v0 = v->v(k);             zz.Fill(fixed ? gr->Min.z : v0);\r
+               mreal dv = (gr->Max.c-gr->Min.c)/8, c = gr->GetC(s,v0);\r
+               if(k>0) dv = v->v(k-1)-v->v(k);\r
+               else if(k<v->GetNx()-1) dv = v->v(k)-v->v(k+1);\r
+               if(fixed)       dv=-dv;\r
+\r
+               const std::vector<mglSegment> curvs = mgl_get_curvs(gr,mgl_tri_lines(v0,nums,a,x,y,fixed?&zz:z));\r
+               for(size_t i=0;i<curvs.size();i++)\r
+               {\r
+                       const std::list<mglPoint> &pp=curvs[i].pp;\r
+                       long f2=-1,g2=-1;\r
+                       for(std::list<mglPoint>::const_iterator it=pp.begin(); it != pp.end(); ++it)\r
+                       {\r
+                               mglPoint p=*it,q(p.y,-p.x);\r
+                               long f1 = f2;   f2 = gr->AddPnt(p,c,q); p.z+=dv;\r
+                               long g1 = g2;   g2 = gr->AddPnt(p,c,q);\r
+                               gr->quad_plot(f1,g1,f2,g2);\r
+                       }\r
+               }\r
+       }\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_tricontv_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
+{\r
+       mreal r = gr->SaveState(opt);\r
+       long n = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5);\r
+       mglData v(n);\r
+       for(long i=0;i<n;i++)   v.a[i] = gr->Min.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(n+1);\r
+       mgl_tricontv_xyzcv(gr,&v,nums,x,y,z,a,sch,0);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_tricontv_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
+{      mgl_tricontv_xyzc(gr,nums,x,y,0,z,sch,opt);     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_tricontv_xycv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
+{      mgl_tricontv_xyzcv(gr,v,nums,x,y,0,z,sch,opt);  }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_tricontv_xyzcv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo)\r
+{      char *s=new char[l+1];  memcpy(s,sch,l);        s[l]=0;\r
+       char *o=new char[lo+1]; memcpy(o,opt,lo);       o[lo]=0;\r
+       mgl_tricontv_xyzcv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o);\r
+       delete []o;     delete []s;     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_tricontv_xycv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo)\r
+{      char *s=new char[l+1];  memcpy(s,sch,l);        s[l]=0;\r
+       char *o=new char[lo+1]; memcpy(o,opt,lo);       o[lo]=0;\r
+       mgl_tricontv_xycv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o);\r
+       delete []o;     delete []s;     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_tricontv_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt, int l,int lo)\r
+{      char *s=new char[l+1];  memcpy(s,sch,l);        s[l]=0;\r
+       char *o=new char[lo+1]; memcpy(o,opt,lo);       o[lo]=0;\r
+       mgl_tricontv_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o);\r
+       delete []o;     delete []s;     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_tricontv_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt, int l,int lo)\r
+{      char *s=new char[l+1];  memcpy(s,sch,l);        s[l]=0;\r
+       char *o=new char[lo+1]; memcpy(o,opt,lo);       o[lo]=0;\r
+       mgl_tricontv_xyc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o);\r
+       delete []o;     delete []s;     }\r
+//-----------------------------------------------------------------------------\r
+//\r
 //     Dots series\r
 //\r
 //-----------------------------------------------------------------------------\r
@@ -368,10 +437,8 @@ void MGL_EXPORT mgl_dots_ca(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, con
        if(mk==0)       mk='.';\r
        gr->Reserve(n);\r
 \r
-#pragma omp parallel for\r
        for(long i=0;i<n;i+=d)\r
        {\r
-               if(gr->Stop)    continue;\r
                mglPoint p = mglPoint(x->vthr(i),y->vthr(i),z->vthr(i));\r
                long pp = gr->AddPnt(p,gr->GetC(ss,c->vthr(i)),mglPoint(NAN),a?gr->GetA(a->vthr(i)):-1);\r
                gr->mark_plot(pp, mk);\r
@@ -406,20 +473,18 @@ void MGL_EXPORT mgl_dots_ca_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_
 //-----------------------------------------------------------------------------\r
 long MGL_NO_EXPORT mgl_crust(long n,mglPoint *pp,long **nn,mreal ff);\r
 HMDT MGL_EXPORT mgl_triangulation_3d(HCDT x, HCDT y, HCDT z)\r
-{      // TODO: should be used s-hull or q-hull\r
+{\r
        mglData *nums=0;\r
        long n = x->GetNx(), m;\r
        if(y->GetNx()!=n || z->GetNx()!=n)      return nums;\r
        mglPoint *pp = new mglPoint[n];\r
        long *nn=0;\r
-#pragma omp parallel for\r
        for(long i=0;i<n;i++)   pp[i] = mglPoint(x->v(i), y->v(i), z->v(i));\r
        m = mgl_crust(n,pp,&nn,0);\r
 \r
        if(m>0)\r
        {\r
                nums=new mglData(3,m);\r
-#pragma omp parallel for\r
                for(long i=0;i<3*m;i++) nums->a[i]=nn[i];\r
        }\r
        delete []pp;    free(nn);       return nums;\r
@@ -433,18 +498,32 @@ HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y)
        if(y->GetNN()!=n)       return nums;\r
        // use s-hull here\r
        std::vector<Shx> pts;\r
-       std::vector<size_t> out;\r
+       std::vector<long> out;\r
        Shx pt;\r
 \r
+       double mx = 0, my = 0;\r
        for(long i=0;i<n;i++)\r
-       {       pt.r = x->vthr(i);      pt.c = y->vthr(i);      pt.id = i;      pts.push_back(pt);      }\r
+       {\r
+               register double t;\r
+               t = fabs(x->vthr(i));   if(t>mx)        mx=t;\r
+               t = fabs(y->vthr(i));   if(t>my)        my=t;\r
+       }\r
+       mx *= 1e-15;    my *= 1e-15;\r
+       for(long i=0;i<n;i++)\r
+       {\r
+               pt.r = x->vthr(i);      pt.c = y->vthr(i);\r
+               if(mgl_isbad(pt.r) || mgl_isbad(pt.c))  continue;\r
+               if(fabs(pt.r)<mx)       pt.r=0;\r
+               if(fabs(pt.c)<my)       pt.c=0;\r
+               pt.id = i;    pts.push_back(pt);\r
+       }\r
+\r
        std::vector<Triad> triads;\r
        if(de_duplicate(pts, out))\r
                mglGlobalMess += "There are duplicated points for triangulation.\n";\r
        s_hull_pro(pts, triads);\r
        long m = triads.size();\r
        nums=new mglData(3,m);\r
-#pragma omp parallel for\r
        for(long i=0;i<m;i++)\r
        {\r
                nums->a[3*i]   = triads[i].a;\r
@@ -468,15 +547,17 @@ MGL_NO_EXPORT void *mgl_grid_t(void *par)
        mglThreadD *t=(mglThreadD *)par;\r
        long nx=t->p[0],ny=t->p[1];\r
        mreal *b=t->a;\r
-       const mreal *x=t->b, *y=t->c, *d=t->d, *z=t->e;\r
+       const mreal *x=t->b, *y=t->c, *d=t->d;\r
+       HCDT zdat = (HCDT) t->v;\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
        for(long i0=t->id;i0<t->n;i0+=mglNumThr)\r
-       {       // TODO check if rounding needed\r
-               register long k1 = long(d[3*i0]), k2 = long(d[3*i0+1]), k3 = long(d[3*i0+2]);\r
+       {\r
+               register long k1 = long(d[3*i0]+0.5), k2 = long(d[3*i0+1]+0.5), k3 = long(d[3*i0+2]+0.5);\r
                mreal dxu,dxv,dyu,dyv;\r
-               mglPoint d1=mglPoint(x[k2]-x[k1],y[k2]-y[k1],z[k2]-z[k1]), d2=mglPoint(x[k3]-x[k1],y[k3]-y[k1],z[k3]-z[k1]), p;\r
+               mreal z1=zdat->vthr(k1), z2=zdat->vthr(k2), z3=zdat->vthr(k3);\r
+               mglPoint d1=mglPoint(x[k2]-x[k1],y[k2]-y[k1],z2-z1), d2=mglPoint(x[k3]-x[k1],y[k3]-y[k1],z3-z1), p;\r
 \r
                dxu = d2.x*d1.y - d1.x*d2.y;\r
                if(fabs(dxu)<1e-5) continue; // points lies on the same line\r
@@ -484,10 +565,10 @@ MGL_NO_EXPORT void *mgl_grid_t(void *par)
                dyu = d2.x/dxu; dxu =-d2.y/dxu;\r
 \r
                long x1,y1,x2,y2;\r
-               x1 = long(fmin(fmin(x[k1],x[k2]),x[k3])); // bounding box\r
-               y1 = long(fmin(fmin(y[k1],y[k2]),y[k3]));\r
-               x2 = long(fmax(fmax(x[k1],x[k2]),x[k3]));\r
-               y2 = long(fmax(fmax(y[k1],y[k2]),y[k3]));\r
+               x1 = long(mgl_min(mgl_min(x[k1],x[k2]),x[k3])); // bounding box\r
+               y1 = long(mgl_min(mgl_min(y[k1],y[k2]),y[k3]));\r
+               x2 = long(mgl_max(mgl_max(x[k1],x[k2]),x[k3]));\r
+               y2 = long(mgl_max(mgl_max(y[k1],y[k2]),y[k3]));\r
                x1 = x1>0 ? x1:0; x2 = x2<nx ? x2:nx-1;\r
                y1 = y1>0 ? y1:0; y2 = y2<ny ? y2:ny-1;\r
                if((x1>x2) | (y1>y2)) continue;\r
@@ -499,7 +580,7 @@ MGL_NO_EXPORT void *mgl_grid_t(void *par)
                        xx = (i-x0); yy = (j-y0);\r
                        u = dxu*xx+dyu*yy; v = dxv*xx+dyv*yy;\r
                        if((u<0) | (v<0) | (u+v>1)) continue;\r
-                       b[i+nx*j] = z[k1] + d1.z*u + d2.z*v;\r
+                       b[i+nx*j] = z1 + d1.z*u + d2.z*v;\r
                }\r
        }\r
        return 0;\r
@@ -509,25 +590,28 @@ void MGL_EXPORT mgl_data_grid_xy(HMDT d, HCDT xdat, HCDT ydat, HCDT zdat, mreal
 { // NOTE: only for mglData\r
        const mglData *x = dynamic_cast<const mglData *>(xdat);\r
        const mglData *y = dynamic_cast<const mglData *>(ydat);\r
-       const mglData *z = dynamic_cast<const mglData *>(zdat);\r
-       if(!x || !y || !z) return;\r
-       long n=x->GetNN();\r
-       if((n<3) || (y->GetNN()!=n) || (z->GetNN()!=n)) return;\r
+       long n=xdat->GetNN();\r
+       if((n<3) || (ydat->GetNN()!=n) || (zdat->GetNN()!=n))   return;\r
 \r
-       mglData *nums = mgl_triangulation_2d(x,y);\r
+       mglData *nums = mgl_triangulation_2d(xdat,ydat);\r
        if(nums->nx<3)  {       delete nums;    return; }\r
        long nn = nums->ny, par[3]={d->nx,d->ny,d->nz};\r
-       mreal xx[4]={x1,0, y1,0};\r
-       if(d->nx>1) xx[1] = (d->nx-1.)/(x2-x1);\r
-       if(d->ny>1) xx[3] = (d->ny-1.)/(y2-y1);\r
+       mreal xx[4]={x1,(d->nx-1.)/(x2-x1), y1,(d->ny-1.)/(y2-y1)};\r
 \r
        mreal *xc=new mreal[n], *yc=new mreal[n];\r
+       if(x && y)\r
+#pragma omp parallel for\r
+               for(long i=0;i<n;i++)\r
+               {       xc[i]=xx[1]*(x->a[i]-xx[0]);    yc[i]=xx[3]*(y->a[i]-xx[2]);    }\r
+       else\r
 #pragma omp parallel for\r
-       for(long i=0;i<n;i++)   {       xc[i]=xx[1]*(x->a[i]-xx[0]);    yc[i]=xx[3]*(y->a[i]-xx[2]);    }\r
+               for(long i=0;i<n;i++)\r
+               {       xc[i]=xx[1]*(xdat->vthr(i)-xx[0]);      yc[i]=xx[3]*(ydat->vthr(i)-xx[2]);      }\r
+       long tmp = d->nx*d->ny*d->nz;\r
 #pragma omp parallel for\r
-       for(long i=0;i<d->nx*d->ny*d->nz;i++) d->a[i] = NAN;\r
+       for(long i=0;i<tmp;i++) d->a[i] = NAN;\r
 \r
-       mglStartThread(mgl_grid_t,0,nn,d->a,xc,yc,par,0,nums->a,z->a);\r
+       mglStartThread(mgl_grid_t,0,nn,d->a,xc,yc,par,zdat,nums->a);\r
        delete nums;    delete []xc;    delete []yc;\r
 }\r
 void MGL_EXPORT mgl_data_grid_xy_(uintptr_t *d, uintptr_t *x, uintptr_t *y, uintptr_t *z, mreal *x1, mreal *x2, mreal *y1, mreal *y2)\r
index b886cd8c9ebfcd8dd842842bca01bd6773ba1d16..b2cdb262f82128eef3448524b1bd8810afbde572 100644 (file)
@@ -19,6 +19,7 @@
  ***************************************************************************/\r
 #include <time.h>\r
 #include "mgl2/data.h"\r
+#include "mgl2/datac.h"\r
 #include "mgl2/eval.h"\r
 #include "mgl2/thread.h"\r
 #include "interp.hpp"\r
@@ -115,13 +116,16 @@ void MGL_EXPORT mglStartThreadV(void *(*func)(void *), long n, mreal *a, const v
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
-mreal mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx, mreal *dy, mreal *dz)\r
+mreal MGL_EXPORT_PURE mglSpline3s(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)\r
+{      return mglSpline3st<mreal>(a,nx,ny,nz,x,y,z);   }\r
+//-----------------------------------------------------------------------------\r
+mreal MGL_EXPORT_PURE mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx, mreal *dy, mreal *dz)\r
 {      return mglSpline3t<mreal>(a,nx,ny,nz,x,y,z,dx,dy,dz);   }\r
 //-----------------------------------------------------------------------------\r
-mreal mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)\r
+mreal MGL_EXPORT_PURE mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)\r
 {      return mglLineart<mreal>(a,nx,ny,nz,x,y,z);     }\r
 //-----------------------------------------------------------------------------\r
-double mgl_ipow(double x,int n)\r
+double MGL_EXPORT_CONST mgl_ipow(double x,int n)\r
 {\r
        double t;\r
        if(n==2)        return x*x;\r
@@ -132,7 +136,7 @@ double mgl_ipow(double x,int n)
        if(n%2==1)      t *= x;\r
        return t;\r
 }\r
-double mgl_ipow_(mreal *x,int *n)      {       return mgl_ipow(*x,*n); }\r
+double MGL_EXPORT_PURE mgl_ipow_(mreal *x,int *n)      {       return mgl_ipow(*x,*n); }\r
 //-----------------------------------------------------------------------------\r
 double mgl_get_time(const char *time, const char *fmt)\r
 {\r
@@ -896,35 +900,37 @@ HMDT MGL_EXPORT mgl_data_solve(HCDT dat, mreal val, char dir, HCDT i0, int norm)
        const mglData *d = dynamic_cast<const mglData *>(dat);\r
        long p[4]={dat->GetNx(), dat->GetNy(), dat->GetNz(), norm};\r
        const mreal *ii=0;\r
-       mglData *r=new mglData;\r
+       mglData *r=new mglData, id0;\r
+       if(i0 && !i)    {       id0.Set(i0);    i=&id0; }       // <-- slow but should work\r
        if(dir=='x' && p[0]>1)\r
        {\r
                r->Create(p[1],p[2]);\r
-               if(i && i->nx*i->ny==p[1]*p[2]) ii = i->a;\r
+               ii = (i && i->nx*i->ny==p[1]*p[2])?i->a:0;\r
                mglStartThread(mgl_solve_x,0,p[1]*p[2],r->a,d?d->a:0,ii,p,dat,&val);\r
        }\r
        if(dir=='y' && p[1]>1)\r
        {\r
                r->Create(p[0],p[2]);\r
-               if(i && i->nx*i->ny==p[0]*p[2]) ii = i->a;\r
+               ii = (i && i->nx*i->ny==p[0]*p[2])?i->a:0;\r
                mglStartThread(mgl_solve_y,0,p[0]*p[2],r->a,d?d->a:0,ii,p,dat,&val);\r
        }\r
        if(dir=='z' && p[2]>1)\r
        {\r
                r->Create(p[0],p[1]);\r
-               if(i && i->nx*i->ny==p[0]*p[1]) ii = i->a;\r
+               ii = (i && i->nx*i->ny==p[0]*p[1])?i->a:0;\r
                mglStartThread(mgl_solve_z,0,p[0]*p[1],r->a,d?d->a:0,ii,p,dat,&val);\r
        }\r
        return r;\r
 }\r
 //-----------------------------------------------------------------------------\r
-mreal MGL_EXPORT mgl_data_solve_1d(HCDT d, mreal val, int spl, long i0)\r
+mreal MGL_EXPORT_PURE mgl_data_solve_1d(HCDT d, mreal val, int spl, long i0)\r
 {\r
        mreal x=0, y1, y2, a, a0, dx=0, da = 1e-5*(val?fabs(val):1);\r
        long nx = d->GetNx();\r
        if(i0<0 || i0>=nx)      i0=0;\r
        if(val==d->v(i0+1))     return i0+1;\r
        const mglData *dd=dynamic_cast<const mglData *>(d);\r
+       const mglDataC *dc=dynamic_cast<const mglDataC *>(d);\r
        if(dd)  for(long i=i0+1;i<nx;i++)\r
        {\r
                y1=dd->a[i-1];  y2=dd->a[i];\r
@@ -942,6 +948,25 @@ mreal MGL_EXPORT mgl_data_solve_1d(HCDT d, mreal val, int spl, long i0)
                        return x;\r
                }\r
        }\r
+       else if(dc)     for(long i=i0+1;i<nx;i++)\r
+       {\r
+               y1=abs(dc->a[i-1]);     y2=abs(dc->a[i]);\r
+               if((y1-val)*(y2-val)<=0)\r
+               {\r
+                       x = i-1 + (val-y1)/(y2-y1);\r
+                       dual cx, ca = mglSpline1t<dual>(dc->a,nx,x,&cx);\r
+                       a0 = a = abs(ca);       dx = a?(cx.real()*ca.real()+cx.imag()*ca.imag())/a:0;\r
+                       if(spl) for(unsigned k=0;fabs(a-val)>da || dx==0;)\r
+                       {\r
+                               x += (val-a)/dx;                k++;\r
+                               ca = mglSpline1t<dual>(dc->a,nx,x,&cx);\r
+                               a = abs(ca);    dx = a?(cx.real()*ca.real()+cx.imag()*ca.imag())/a:0;\r
+                               if(k>=10)\r
+                                       return fabs(a-val)<fabs(a0-val) ? x:i-1 + (val-y1)/(y2-y1);\r
+                       }\r
+                       return x;\r
+               }\r
+       }\r
        else    for(long i=i0+1;i<nx;i++)\r
        {\r
                y1=d->v(i-1);   y2=d->v(i);\r
@@ -951,8 +976,9 @@ mreal MGL_EXPORT mgl_data_solve_1d(HCDT d, mreal val, int spl, long i0)
        return NAN;\r
 }\r
 //-----------------------------------------------------------------------------\r
-mreal MGL_EXPORT mgl_data_linear_ext(HCDT d, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz)\r
+mreal MGL_EXPORT_PURE mgl_data_linear_ext(HCDT d, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz)\r
 {\r
+       if(!d)  return NAN;\r
        long kx=long(x), ky=long(y), kz=long(z);\r
        mreal b0,b1;\r
        const mglData *dd=dynamic_cast<const mglData *>(d);\r
@@ -1023,32 +1049,52 @@ mreal MGL_EXPORT mgl_data_linear_ext(HCDT d, mreal x,mreal y,mreal z, mreal *dx,
        return b0 + z*(b1-b0);\r
 }\r
 //-----------------------------------------------------------------------------\r
-mreal MGL_EXPORT mgl_data_linear(HCDT d, mreal x,mreal y,mreal z)\r
+mreal MGL_EXPORT_PURE mgl_data_linear(HCDT d, mreal x,mreal y,mreal z)\r
 {      return mgl_data_linear_ext(d, x,y,z, 0,0,0);    }\r
 //-----------------------------------------------------------------------------\r
-mreal MGL_EXPORT mgl_data_spline(HCDT d, mreal x,mreal y,mreal z)\r
+mreal MGL_EXPORT_PURE mgl_data_spline(HCDT d, mreal x,mreal y,mreal z)\r
 {\r
+       if(mgl_isbad(x) || mgl_isbad(y) || mgl_isbad(z))        return NAN;\r
        const mglData *dd=dynamic_cast<const mglData *>(d);\r
-       if(!d)  return 0;       // NOTE: don't support general arrays\r
-       return dd->ny*dd->nz==1?mglSpline1st<mreal>(dd->a,dd->nx,x):mglSpline3st<mreal>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z);\r
+       if(dd)  return dd->ny*dd->nz==1?mglSpline1st<mreal>(dd->a,dd->nx,x):mglSpline3st<mreal>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z);\r
+       const mglDataC *dc=dynamic_cast<const mglDataC *>(d);\r
+       if(dc)  return abs(dc->ny*dc->nz==1?mglSpline1st<dual>(dc->a,dc->nx,x):mglSpline3st<dual>(dc->a,dc->nx,dc->ny,dc->nz,x,y,z));\r
+       const mglDataV *dv=dynamic_cast<const mglDataV *>(d);\r
+       if(dv)  return dv->value(x,y,z);\r
+       const mglDataF *df=dynamic_cast<const mglDataF *>(d);\r
+       if(df)  return df->value(x,y,z);\r
+       return 0;       // TODO non-mglData: spline mglDataT, mglDataR\r
 }\r
 //-----------------------------------------------------------------------------\r
-mreal MGL_EXPORT mgl_data_spline_ext(HCDT d, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz)\r
+mreal MGL_EXPORT_PURE mgl_data_spline_ext(HCDT d, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz)\r
 {\r
+       if(mgl_isbad(x) || mgl_isbad(y) || mgl_isbad(z))        return NAN;\r
        const mglData *dd=dynamic_cast<const mglData *>(d);\r
-       if(!d)  return 0;       // NOTE: don't support general arrays\r
-       return mglSpline3t<mreal>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z,dx,dy,dz);\r
+       if(dd)  return mglSpline3t<mreal>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z,dx,dy,dz);\r
+       const mglDataC *dc=dynamic_cast<const mglDataC *>(d);\r
+       if(dc)\r
+       {       dual a,ax,ay,az;        mreal res;\r
+               a = mglSpline3t<dual>(dc->a,dc->nx,dc->ny,dc->nz,x,y,z,&ax,&ay,&az);    res = abs(a);\r
+               if(dx)  *dx = res?(real(a)*real(ax)+imag(a)*imag(ax))/res:0;\r
+               if(dy)  *dy = res?(real(a)*real(ay)+imag(a)*imag(ay))/res:0;\r
+               if(dz)  *dz = res?(real(a)*real(az)+imag(a)*imag(az))/res:0;\r
+               return res;     }\r
+       const mglDataV *dv=dynamic_cast<const mglDataV *>(d);\r
+       if(dv)  return dv->value(x,y,z,dx,dy,dz);\r
+       const mglDataF *df=dynamic_cast<const mglDataF *>(d);\r
+       if(df)  return df->value(x,y,z,dx,dy,dz);\r
+       return 0;       // TODO non-mglData: spline mglDataT, mglDataR\r
 }\r
 //-----------------------------------------------------------------------------\r
-mreal MGL_EXPORT mgl_data_spline_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
+mreal MGL_EXPORT_PURE mgl_data_spline_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
 {      return mgl_data_spline(_DA_(d),*x,*y,*z);       }\r
-mreal MGL_EXPORT mgl_data_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
+mreal MGL_EXPORT_PURE mgl_data_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
 {      return mgl_data_linear(_DA_(d),*x,*y,*z);       }\r
-mreal MGL_EXPORT mgl_data_spline_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz)\r
+mreal MGL_EXPORT_PURE mgl_data_spline_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz)\r
 {      return mgl_data_spline_ext(_DA_(d),*x,*y,*z,dx,dy,dz);  }\r
-mreal MGL_EXPORT mgl_data_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz)\r
+mreal MGL_EXPORT_PURE mgl_data_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz)\r
 {      return mgl_data_linear_ext(_DA_(d),*x,*y,*z,dx,dy,dz);  }\r
-mreal MGL_EXPORT mgl_data_solve_1d_(uintptr_t *d, mreal *val, int *spl, int *i0)\r
+mreal MGL_EXPORT_PURE mgl_data_solve_1d_(uintptr_t *d, mreal *val, int *spl, int *i0)\r
 {      return mgl_data_solve_1d(_DA_(d),*val, *spl, *i0);      }\r
 uintptr_t MGL_EXPORT mgl_data_solve_(uintptr_t *d, mreal *val, const char *dir, uintptr_t *i0, int *norm,int)\r
 {      return uintptr_t(mgl_data_solve(_DA_(d),*val, *dir, _DA_(i0), *norm));  }\r
@@ -1180,47 +1226,7 @@ mreal MGL_EXPORT mgl_data_momentum_val(HCDT dd, char dir, mreal *x, mreal *w, mr
 {\r
        long nx=dd->GetNx(),ny=dd->GetNy(),nz=dd->GetNz();\r
        mreal i0=0,i1=0,i2=0,i3=0,i4=0;\r
-       const mglData *md = dynamic_cast<const mglData *>(dd);\r
-       if(dd)  switch(dir)\r
-       {\r
-       case 'x':\r
-#pragma omp parallel for reduction(+:i0,i1,i2,i3,i4)\r
-               for(long i=0;i<nx*ny*nz;i++)\r
-               {\r
-                       register mreal d = i%nx, t = d*d, v = md->a[i];\r
-                       i0+= v; i1+= v*d;       i2+= v*t;\r
-                       i3+= v*d*t;             i4+= v*t*t;\r
-               }\r
-               break;\r
-       case 'y':\r
-#pragma omp parallel for reduction(+:i0,i1,i2,i3,i4)\r
-               for(long i=0;i<nx*ny*nz;i++)\r
-               {\r
-                       register mreal d = (i/nx)%ny, t = d*d, v = md->a[i];\r
-                       i0+= v; i1+= v*d;       i2+= v*t;\r
-                       i3+= v*d*t;             i4+= v*t*t;\r
-               }\r
-               break;\r
-       case 'z':\r
-#pragma omp parallel for reduction(+:i0,i1,i2,i3,i4)\r
-               for(long i=0;i<nx*ny*nz;i++)\r
-               {\r
-                       register mreal d = i/(nx*ny), t = d*d, v = md->a[i];\r
-                       i0+= v; i1+= v*d;       i2+= v*t;\r
-                       i3+= v*d*t;             i4+= v*t*t;\r
-               }\r
-               break;\r
-       default:        // "self-dispersion"\r
-               i0 = nx*ny*nz;\r
-#pragma omp parallel for reduction(+:i1,i2,i3,i4)\r
-               for(long i=0;i<nx*ny*nz;i++)\r
-               {\r
-                       register mreal v=md->a[i], t  = v*v;\r
-                       i1+= v;                 i2+= t;\r
-                       i3+= v*t;               i4+= t*t;\r
-               }\r
-       }\r
-       else    switch(dir)\r
+       switch(dir)\r
        {\r
        case 'x':\r
 #pragma omp parallel for reduction(+:i0,i1,i2,i3,i4)\r
@@ -1268,7 +1274,7 @@ mreal MGL_EXPORT mgl_data_momentum_val(HCDT dd, char dir, mreal *x, mreal *w, mr
        return i0;\r
 }\r
 mreal MGL_EXPORT mgl_data_momentum_val_(uintptr_t *d, char *dir, mreal *m, mreal *w, mreal *s, mreal *k,int)\r
-{      mreal mm,ww,ss,kk,aa;\r
+{      mreal mm=0,ww=0,ss=0,kk=0,aa=0;\r
        aa = mgl_data_momentum_val(_DT_,*dir,&mm,&ww,&ss,&kk);\r
        *m=mm;  *w=ww;  *s=ss;  *k=kk;  return aa;      }\r
 //-----------------------------------------------------------------------------\r
@@ -1368,12 +1374,18 @@ MGL_EXPORT const char *mgl_data_info(HCDT d)    // NOTE: Not thread safe function!
        snprintf(s,128,"Widths are:\nWa = %g\tWx = %g\tWy = %g\tWz = %g\n", Wa,Wx,Wy,Wz);       strcat(buf,s);\r
        return buf;\r
 }\r
+int MGL_EXPORT mgl_data_info_(uintptr_t *d, char *out, int len)\r
+{\r
+       const char *res = mgl_data_info(_DA_(d));\r
+       if(out) strncpy(out,res,len);\r
+       return strlen(res);\r
+}\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_insert(HMDT d, char dir, long at, long num)\r
 {\r
        if(num<1)       return;\r
        at = at<0 ? 0:at;\r
-       long nn, nx=d->nx, ny=d->ny, nz=d->nz;\r
+       long nn, nx=d->nx, ny=d->ny, nz=d->nz, nxy=nx*ny;\r
        mglData b;\r
        if(dir=='x')\r
        {\r
@@ -1384,7 +1396,8 @@ void MGL_EXPORT mgl_data_insert(HMDT d, char dir, long at, long num)
                {\r
                        if(at>0)        memcpy(b.a+nn*k, d->a+nx*k,at*sizeof(mreal));\r
                        if(at<nx)       memcpy(b.a+at+num+nn*k, d->a+at+nx*k,(nx-at)*sizeof(mreal));\r
-                       for(long i=0;i<num;i++) b.a[nn*k+at+i]=d->a[nx*k+at];   // copy values\r
+                       if(at<nx)       for(long i=0;i<num;i++) b.a[nn*k+at+i]=d->a[nx*k+at];   // copy values\r
+                       else            for(long i=0;i<num;i++) b.a[nn*k+at+i]=d->a[nx*k+nx-1]; // copy values\r
                }\r
                d->Set(b);      nx+=num;\r
        }\r
@@ -1395,9 +1408,12 @@ void MGL_EXPORT mgl_data_insert(HMDT d, char dir, long at, long num)
 #pragma omp parallel for\r
                for(long k=0;k<nz;k++)\r
                {\r
-                       if(at>0)        memcpy(b.a+nx*nn*k, d->a+nx*ny*k,at*nx*sizeof(mreal));\r
+                       if(at>0)        memcpy(b.a+nx*nn*k, d->a+nxy*k,at*nx*sizeof(mreal));\r
                        if(at<ny)       memcpy(b.a+nx*(at+num+nn*k), d->a+nx*(at+ny*k),(ny-at)*nx*sizeof(mreal));\r
-                       for(long i=0;i<num;i++) memcpy(b.a+nx*(nn*k+at+i),d->a+nx*(ny*k+at),nx*sizeof(mreal));\r
+                       if(at<ny)       for(long i=0;i<num;i++)\r
+                               memcpy(b.a+nx*(nn*k+at+i),d->a+nx*(ny*k+at),nx*sizeof(mreal));\r
+                       else    for(long i=0;i<num;i++)\r
+                               memcpy(b.a+nx*(nn*k+at+i),d->a+nx*(ny*k+ny-1),nx*sizeof(mreal));\r
                }\r
                d->Set(b);      ny+=num;\r
        }\r
@@ -1405,10 +1421,14 @@ void MGL_EXPORT mgl_data_insert(HMDT d, char dir, long at, long num)
        {\r
                if(at>nz)       at=nz;\r
                b.Create(nx,ny,nz+num);\r
-               if(at>0)        memcpy(b.a, d->a,at*nx*ny*sizeof(mreal));\r
-               if(at<nz)       memcpy(b.a+nx*ny*(at+num), d->a+nx*ny*at,(nz-at)*nx*ny*sizeof(mreal));\r
+               if(at>0)        memcpy(b.a, d->a,at*nxy*sizeof(mreal));\r
+               if(at<nz)       memcpy(b.a+nxy*(at+num), d->a+nxy*at,(nz-at)*nxy*sizeof(mreal));\r
+               if(at<nz)\r
 #pragma omp parallel for\r
-               for(long i=0;i<num;i++) memcpy(b.a+nx*ny*(at+i),d->a+nx*ny*at,nx*ny*sizeof(mreal));\r
+                       for(long i=0;i<num;i++) memcpy(b.a+nxy*(at+i),d->a+nxy*at,nxy*sizeof(mreal));\r
+               else\r
+#pragma omp parallel for\r
+                       for(long i=0;i<num;i++) memcpy(b.a+nxy*(at+i),d->a+nxy*(nz-1),nxy*sizeof(mreal));\r
                d->Set(b);\r
        }\r
 }\r
@@ -1457,70 +1477,14 @@ void MGL_EXPORT mgl_data_insert_(uintptr_t *d, const char *dir, int *at, int *nu
 void MGL_EXPORT mgl_data_delete_(uintptr_t *d, const char *dir, int *at, int *num, int)\r
 {      mgl_data_delete(_DT_,*dir,*at,*num);    }\r
 //-----------------------------------------------------------------------------\r
-mreal MGL_EXPORT mgl_spline5(mreal y1[5], mreal y2[5], long n1, long n2, mreal d, mreal &dy)\r
-{\r
-       mreal a1[4], a2[4], f0,d0,t0,f1,d1,t1, b[6];\r
-       a1[0] = -(3*y1[4]-16*y1[3]+36*y1[2]-48*y1[1]+25*y1[0])/12;\r
-       a1[1] = (11*y1[4]-56*y1[3]+114*y1[2]-104*y1[1]+35*y1[0])/12;\r
-       a1[2] = -(3*y1[4]-14*y1[3]+24*y1[2]-18*y1[1]+5*y1[0])/4;\r
-       a1[3] = (y1[4]-4*y1[3]+6*y1[2]-4*y1[1]+y1[0])/6;\r
-       a2[0] = -(3*y2[4]-16*y2[3]+36*y2[2]-48*y2[1]+25*y2[0])/12;\r
-       a2[1] = (11*y2[4]-56*y2[3]+114*y2[2]-104*y2[1]+35*y2[0])/12;\r
-       a2[2] = -(3*y2[4]-14*y2[3]+24*y2[2]-18*y2[1]+5*y2[0])/4;\r
-       a2[3] = (y2[4]-4*y2[3]+6*y2[2]-4*y2[1]+y2[0])/6;\r
-       n2++;\r
-       f0 = y1[n1];    d0 = a1[0]+n1*(a1[1]+n1*(a1[2]+n1*a1[3]));      t0 = a1[1]/2+a1[2]*n1+1.5*n2*n2*a2[3];\r
-       f1 = y2[n2];    d1 = a2[0]+n2*(a2[1]+n2*(a2[2]+n2*a2[3]));      t1 = a2[1]/2+a2[2]*n2+1.5*n2*n2*a2[3];\r
-       b[0] = f0;      b[1] = d0;      b[2] = t0;\r
-       b[3] = 10*(f1-f0)+t1-3*t0-4*d1-6*d0;\r
-       b[4] = 15*(f0-f1)-2*t1+3*t0+7*d1+8*d0;\r
-       b[5] = 6*(f1-f0)+t1-t0-3*d1-3*d0;\r
-       dy = b[1] + d*(2*b[2]+d*(3*b[3]+d*(4*b[4]+d*5*b[5])));\r
-       return b[0] + d*(b[1]+d*(b[2]+d*(b[3]+d*(b[4]+d*b[5]))));\r
-}\r
-//-----------------------------------------------------------------------------\r
-mreal MGL_EXPORT mgl_spline3(mreal y1[3], mreal y2[3], long n1, long n2, mreal d, mreal &dy)\r
-{\r
-       mreal a1[2], a2[2], f0,d0,d1,f1, b[4];\r
-       a1[0] = -(y1[2]-4*y1[1]+3*y1[0])/2;\r
-       a1[1] = y1[2]-2*y1[1]+y1[0];\r
-       a2[0] = -(y2[2]-4*y2[1]+3*y2[0])/2;\r
-       a2[1] = y2[2]-2*y2[1]+y2[0];\r
-       n2++;\r
-       f0 = y1[n1];    d0 = a1[0]+a1[1]*n1;\r
-       f1 = y2[n2];    d1 = a2[0]+a2[1]*n2;\r
-       b[0] = f0;      b[1] = d0;\r
-       b[2] = 3*(f1-f0)-d1-2*d0;\r
-       b[3] = 2*(f0-f1)+d1+d0;\r
-       dy = b[1] + d*(2*b[2]+d*3*b[3]);\r
-       return b[0] + d*(b[1]+d*(b[2]+d*b[3]));\r
-}\r
-//-----------------------------------------------------------------------------\r
-/*mreal mglData::Spline5(mreal x,mreal y,mreal z,mreal &dx,mreal &dy,mreal &dz) const\r
-{\r
-       mreal res=0;\r
-       if(nx<5)        return 0;       // not interpolation for points < 5 !!!\r
-       dx = dy = dz = 0;       x*=nx-1;        y*=ny-1;        z*=nz-1;\r
-       if(ny==1 && nz==1)      // 1D case\r
-       {\r
-               long n = long(x), n1 = n>1 ? 2:n, n2 = n<nx-3 ? 1:5+n-nx;\r
-               res = mgl_spline5(a+n+n1-2, a+n-n2, n1, n2, x-n, dx);\r
-       }\r
-       else if(nz==1)          // 2D case\r
-       {\r
-       }\r
-       return res;\r
-}*/\r
-//-----------------------------------------------------------------------------\r
 #define omod(x,y)      (y)*((x)>0?int((x)/(y)+0.5):int((x)/(y)-0.5))\r
 void MGL_NO_EXPORT mgl_omod(mreal *a, mreal da, int nx, int n)\r
 {\r
-       register long i,ii;\r
        bool qq=true;\r
        register mreal q;\r
-       for(i=1;i<nx;i++)\r
+       for(long i=1;i<nx;i++)\r
        {\r
-               ii = i*n;\r
+               register long ii = i*n;\r
                if(mgl_isnan(a[ii-n]))  {       qq=true;        continue;       }\r
                if(qq)\r
                {\r
@@ -1727,9 +1691,10 @@ void MGL_EXPORT mgl_data_put_dat_(uintptr_t *d, uintptr_t *val, int *i, int *j,
 MGL_NO_EXPORT void *mgl_diff_3(void *par)\r
 {\r
        mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0], ny=t->p[1], nz=t->p[2], nn=t->n;\r
+       long nx=t->p[0], ny=t->p[1], nz=t->p[2], nn=t->n, n2=nx*ny;\r
        mreal *b=t->a,au,av,aw,xu,xv,xw,yu,yv,yw,zu,zv,zw;\r
-       const mreal *a=t->b, *x=t->c, *y=t->d, *z=t->e;\r
+       HCDT x=(HCDT)(t->c),y=(HCDT)(t->d),z=(HCDT)(t->e);\r
+       const mreal *a=t->b;\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for private(au,av,aw,xu,xv,xw,yu,yv,yw,zu,zv,zw)\r
 #endif\r
@@ -1739,65 +1704,65 @@ MGL_NO_EXPORT void *mgl_diff_3(void *par)
                if(i==0)\r
                {\r
                        au = 3*a[i0]-4*a[i0+1]+a[i0+2];\r
-                       xu = 3*x[i0]-4*x[i0+1]+x[i0+2];\r
-                       yu = 3*y[i0]-4*y[i0+1]+y[i0+2];\r
-                       zu = 3*z[i0]-4*z[i0+1]+z[i0+2];\r
+                       xu = 3*x->vthr(i0)-4*x->vthr(i0+1)+x->vthr(i0+2);\r
+                       yu = 3*y->vthr(i0)-4*y->vthr(i0+1)+y->vthr(i0+2);\r
+                       zu = 3*z->vthr(i0)-4*z->vthr(i0+1)+z->vthr(i0+2);\r
                }\r
                else if(i==nx-1)\r
                {\r
                        au = 3*a[i0]-4*a[i0-1]+a[i0-2];\r
-                       xu = 3*x[i0]-4*x[i0-1]+x[i0-2];\r
-                       yu = 3*y[i0]-4*y[i0-1]+y[i0-2];\r
-                       zu = 3*z[i0]-4*z[i0-1]+z[i0-2];\r
+                       xu = 3*x->vthr(i0)-4*x->vthr(i0-1)+x->vthr(i0-2);\r
+                       yu = 3*y->vthr(i0)-4*y->vthr(i0-1)+y->vthr(i0-2);\r
+                       zu = 3*z->vthr(i0)-4*z->vthr(i0-1)+z->vthr(i0-2);\r
                }\r
                else\r
                {\r
                        au = a[i0+1]-a[i0-1];\r
-                       xu = x[i0+1]-x[i0-1];\r
-                       yu = y[i0+1]-y[i0-1];\r
-                       zu = z[i0+1]-z[i0-1];\r
+                       xu = x->vthr(i0+1)-x->vthr(i0-1);\r
+                       yu = y->vthr(i0+1)-y->vthr(i0-1);\r
+                       zu = z->vthr(i0+1)-z->vthr(i0-1);\r
                }\r
                if(j==0)\r
                {\r
                        av = 3*a[i0]-4*a[i0+nx]+a[i0+2*nx];\r
-                       xv = 3*x[i0]-4*x[i0+nx]+x[i0+2*nx];\r
-                       yv = 3*y[i0]-4*y[i0+nx]+y[i0+2*nx];\r
-                       zv = 3*z[i0]-4*z[i0+nx]+z[i0+2*nx];\r
+                       xv = 3*x->vthr(i0)-4*x->vthr(i0+nx)+x->vthr(i0+2*nx);\r
+                       yv = 3*y->vthr(i0)-4*y->vthr(i0+nx)+y->vthr(i0+2*nx);\r
+                       zv = 3*z->vthr(i0)-4*z->vthr(i0+nx)+z->vthr(i0+2*nx);\r
                }\r
                else if(j==ny-1)\r
                {\r
                        av = 3*a[i0]-4*a[i0-nx]+a[i0+(ny-3)*nx];\r
-                       xv = 3*x[i0]-4*x[i0-nx]+x[i0-2*nx];\r
-                       yv = 3*y[i0]-4*y[i0-nx]+y[i0-2*nx];\r
-                       zv = 3*z[i0]-4*z[i0-nx]+z[i0-2*nx];\r
+                       xv = 3*x->vthr(i0)-4*x->vthr(i0-nx)+x->vthr(i0-2*nx);\r
+                       yv = 3*y->vthr(i0)-4*y->vthr(i0-nx)+y->vthr(i0-2*nx);\r
+                       zv = 3*z->vthr(i0)-4*z->vthr(i0-nx)+z->vthr(i0-2*nx);\r
                }\r
                else\r
                {\r
                        av = a[i0+nx]-a[i0-nx];\r
-                       xv = x[i0+nx]-x[i0-nx];\r
-                       yv = y[i0+nx]-y[i0-nx];\r
-                       zv = z[i0+nx]-z[i0-nx];\r
+                       xv = x->vthr(i0+nx)-x->vthr(i0-nx);\r
+                       yv = y->vthr(i0+nx)-y->vthr(i0-nx);\r
+                       zv = z->vthr(i0+nx)-z->vthr(i0-nx);\r
                }\r
                if(k==0)\r
                {\r
-                       aw = 3*a[i0]-4*a[i0+nn]+a[i0+2*nn];\r
-                       xw = 3*x[i0]-4*x[i0+nn]+x[i0+2*nn];\r
-                       yw = 3*y[i0]-4*y[i0+nn]+y[i0+2*nn];\r
-                       zw = 3*z[i0]-4*z[i0+nn]+z[i0+2*nn];\r
+                       aw = 3*a[i0]-4*a[i0+n2]+a[i0+2*n2];\r
+                       xw = 3*x->vthr(i0)-4*x->vthr(i0+n2)+x->vthr(i0+2*n2);\r
+                       yw = 3*y->vthr(i0)-4*y->vthr(i0+n2)+y->vthr(i0+2*n2);\r
+                       zw = 3*z->vthr(i0)-4*z->vthr(i0+n2)+z->vthr(i0+2*n2);\r
                }\r
                else if(k==nz-1)\r
                {\r
-                       aw = 3*a[i0]-4*a[i+(nz-2)*nx*ny]+a[i-2*nn];\r
-                       xw = 3*x[i0]-4*x[i-nn]+x[i-2*nn];\r
-                       yw = 3*y[i0]-4*y[i-nn]+y[i-2*nn];\r
-                       zw = 3*z[i0]-4*z[i-nn]+z[i-2*nn];\r
+                       aw = 3*a[i0]-4*a[i0-n2]+a[i0-2*n2];\r
+                       xw = 3*x->vthr(i0)-4*x->vthr(i0-n2)+x->vthr(i0-2*n2);\r
+                       yw = 3*y->vthr(i0)-4*y->vthr(i0-n2)+y->vthr(i0-2*n2);\r
+                       zw = 3*z->vthr(i0)-4*z->vthr(i0-n2)+z->vthr(i0-2*n2);\r
                }\r
                else\r
                {\r
-                       aw = a[i0+nn]-a[i0-nn];\r
-                       xw = x[i0+nn]-x[i0-nn];\r
-                       yw = y[i0+nn]-y[i0-nn];\r
-                       zw = z[i0+nn]-z[i0-nn];\r
+                       aw = a[i0+n2]-a[i0-n2];\r
+                       xw = x->vthr(i0+n2)-x->vthr(i0-n2);\r
+                       yw = y->vthr(i0+n2)-y->vthr(i0-n2);\r
+                       zw = z->vthr(i0+n2)-z->vthr(i0-n2);\r
                }\r
                b[i0] = (au*yv*zw-av*yu*zw-au*yw*zv+aw*yu*zv+av*yw*zu-aw*yv*zu) / (xu*yv*zw-xv*yu*zw-xu*yw*zv+xw*yu*zv+xv*yw*zu-xw*yv*zu);\r
        }\r
@@ -1808,7 +1773,8 @@ MGL_NO_EXPORT void *mgl_diff_2(void *par)
        mglThreadD *t=(mglThreadD *)par;\r
        register long nx=t->p[0], ny=t->p[1], nn=t->n, same=t->p[2];\r
        mreal *b=t->a,au,av,xu,xv,yu,yv;\r
-       const mreal *a=t->b, *x=t->c, *y=t->d;\r
+       HCDT x=(HCDT)(t->c),y=(HCDT)(t->d);\r
+       const mreal *a=t->b;\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for private(au,av,xu,xv,yu,yv)\r
 #endif\r
@@ -1818,38 +1784,38 @@ MGL_NO_EXPORT void *mgl_diff_2(void *par)
                if(i==0)\r
                {\r
                        au = 3*a[i0]-4*a[i0+1]+a[i0+2];\r
-                       xu = 3*x[i1]-4*x[i1+1]+x[i1+2];\r
-                       yu = 3*y[i1]-4*y[i1+1]+y[i1+2];\r
+                       xu = 3*x->vthr(i1)-4*x->vthr(i1+1)+x->vthr(i1+2);\r
+                       yu = 3*y->vthr(i1)-4*y->vthr(i1+1)+y->vthr(i1+2);\r
                }\r
                else if(i==nx-1)\r
                {\r
                        au = 3*a[i0]-4*a[i0-1]+a[i0-2];\r
-                       xu = 3*x[i1]-4*x[i1-1]+x[i1-2];\r
-                       yu = 3*y[i1]-4*y[i1-1]+y[i1-2];\r
+                       xu = 3*x->vthr(i1)-4*x->vthr(i1-1)+x->vthr(i1-2);\r
+                       yu = 3*y->vthr(i1)-4*y->vthr(i1-1)+y->vthr(i1-2);\r
                }\r
                else\r
                {\r
                        au = a[i0+1]-a[i0-1];\r
-                       xu = x[i1+1]-x[i1-1];\r
-                       yu = y[i1+1]-y[i1-1];\r
+                       xu = x->vthr(i1+1)-x->vthr(i1-1);\r
+                       yu = y->vthr(i1+1)-y->vthr(i1-1);\r
                }\r
                if(j==0)\r
                {\r
                        av = 3*a[i0]-4*a[i0+nx]+a[i0+2*nx];\r
-                       xv = 3*x[i1]-4*x[i1+nx]+x[i1+2*nx];\r
-                       yv = 3*y[i1]-4*y[i1+nx]+y[i1+2*nx];\r
+                       xv = 3*x->vthr(i1)-4*x->vthr(i1+nx)+x->vthr(i1+2*nx);\r
+                       yv = 3*y->vthr(i1)-4*y->vthr(i1+nx)+y->vthr(i1+2*nx);\r
                }\r
                else if(j==ny-1)\r
                {\r
                        av = 3*a[i0]-4*a[i0-nx]+a[i0-2*nx];\r
-                       xv = 3*x[i1]-4*x[i1-nx]+x[i1-2*nx];\r
-                       yv = 3*y[i1]-4*y[i1-nx]+y[i1-2*nx];\r
+                       xv = 3*x->vthr(i1)-4*x->vthr(i1-nx)+x->vthr(i1-2*nx);\r
+                       yv = 3*y->vthr(i1)-4*y->vthr(i1-nx)+y->vthr(i1-2*nx);\r
                }\r
                else\r
                {\r
                        av = a[i0+nx]-a[i0-nx];\r
-                       xv = x[i1+nx]-x[i1-nx];\r
-                       yv = y[i1+nx]-y[i1-nx];\r
+                       xv = x->vthr(i1+nx)-x->vthr(i1-nx);\r
+                       yv = y->vthr(i1+nx)-y->vthr(i1-nx);\r
                }\r
                b[i0] = (av*yu-au*yv)/(xv*yu-xu*yv);\r
        }\r
@@ -1860,7 +1826,8 @@ MGL_NO_EXPORT void *mgl_diff_1(void *par)
        mglThreadD *t=(mglThreadD *)par;\r
        long nx=t->p[0], nn=t->n, same=t->p[1];\r
        mreal *b=t->a,au,xu;\r
-       const mreal *a=t->b, *x=t->c;\r
+       HCDT x=(HCDT)(t->c);\r
+       const mreal *a=t->b;\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for private(au,xu)\r
 #endif\r
@@ -1870,43 +1837,40 @@ MGL_NO_EXPORT void *mgl_diff_1(void *par)
                if(i==0)\r
                {\r
                        au = 3*a[i0]-4*a[i0+1]+a[i0+2];\r
-                       xu = 3*x[i1]-4*x[i1+1]+x[i1+2];\r
+                       xu = 3*x->vthr(i1)-4*x->vthr(i1+1)+x->vthr(i1+2);\r
                }\r
                else if(i==nx-1)\r
                {\r
                        au = 3*a[i0]-4*a[i0-1]+a[i0-2];\r
-                       xu = 3*x[i1]-4*x[i1-1]+x[i1-2];\r
+                       xu = 3*x->vthr(i1)-4*x->vthr(i1-1)+x->vthr(i1-2);\r
                }\r
                else\r
                {\r
                        au = a[i0+1]-a[i0-1];\r
-                       xu = x[i1+1]-x[i1-1];\r
+                       xu = x->vthr(i1+1)-x->vthr(i1-1);\r
                }\r
                b[i0] = au/xu;\r
        }\r
        return 0;\r
 }\r
-void MGL_EXPORT mgl_data_diff_par(HMDT d, HCDT v1, HCDT v2, HCDT v3)\r
-{      // NOTE: only for mglData!!!\r
-       const mglData *x = dynamic_cast<const mglData *>(v1);\r
-       const mglData *y = dynamic_cast<const mglData *>(v2);\r
-       const mglData *z = dynamic_cast<const mglData *>(v3);\r
-       long nx=d->nx,ny=d->ny,nz=d->nz, nn=nx*ny*nz;\r
+void MGL_EXPORT mgl_data_diff_par(HMDT d, HCDT x, HCDT y, HCDT z)\r
+{\r
+       long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), nn=nx*ny*nz;\r
        if(nx<2 || ny<2)        return;\r
        mreal *b = new mreal[nn];       memset(b,0,nn*sizeof(mreal));\r
        long p[3]={nx,ny,nz};\r
 \r
-       if(x&&y&&z && x->nx*x->ny*x->nz==nn && y->nx*y->ny*y->nz==nn && z->nx*z->ny*z->nz==nn)\r
-               mglStartThread(mgl_diff_3,0,nn,b,d->a,x->a,p,0,y->a,z->a);\r
-       else if(x&&y && x->nx*x->ny==nx*ny && y->nx*y->ny==nx*ny)\r
+       if(x&&y&&z && x->GetNN()==nn && y->GetNN()==nn && z->GetNN()==nn)\r
+               mglStartThread(mgl_diff_3,0,nn,b,d->a,(const mreal *)x,p,0,(const mreal *)y,(const mreal *)z);\r
+       else if(x&&y && x->GetNx()*x->GetNy()==nx*ny && y->GetNx()*y->GetNy()==nx*ny)\r
        {\r
-               p[2]=(x->nz==nz && y->nz==nz);\r
-               mglStartThread(mgl_diff_2,0,nn,b,d->a,x->a,p,0,y->a);\r
+               p[2]=(x->GetNz()==nz && y->GetNz()==nz);\r
+               mglStartThread(mgl_diff_2,0,nn,b,d->a,(const mreal *)x,p,0,(const mreal *)y);\r
        }\r
-       else if(x && x->nx==nx)\r
+       else if(x && x->GetNx()==nx)\r
        {\r
-               p[1]=(x->ny*x->nz==ny*nz);\r
-               mglStartThread(mgl_diff_1,0,nn,b,d->a,x->a,p,0,0);\r
+               p[1]=(x->GetNy()*x->GetNz()==ny*nz);\r
+               mglStartThread(mgl_diff_1,0,nn,b,d->a,(const mreal *)x,p,0,0);\r
        }\r
        memcpy(d->a,b,nn*sizeof(mreal));        delete []b;\r
 }\r
@@ -1919,11 +1883,12 @@ void MGL_EXPORT mgl_data_set_value_(uintptr_t *d, mreal *v, int *i, int *j, int
 {      mgl_data_set_value(_DT_,*v,*i,*j,*k);   }\r
 //-----------------------------------------------------------------------------\r
 mreal MGL_EXPORT mgl_data_get_value(HCDT dat, long i, long j, long k)\r
-{      return (i>=0 && i<dat->GetNx() && j>=0 && j<dat->GetNy() && k>=0 && k<dat->GetNz()) ? dat->v(i,j,k):NAN;        }\r
+{      register long nx = dat->GetNx(), ny = dat->GetNy();\r
+       return (i>=0 && i<nx && j>=0 && j<ny && k>=0 && k<dat->GetNz()) ? dat->vthr(i+nx*(j+ny*k)):NAN; }\r
 mreal MGL_EXPORT mgl_data_get_value_(uintptr_t *d, int *i, int *j, int *k)\r
 {      return mgl_data_get_value(_DA_(d),*i,*j,*k);    }\r
 //-----------------------------------------------------------------------------\r
-MGL_EXPORT mreal *mgl_data_data(HMDT dat)      {       return dat->a;  }\r
+MGL_EXPORT_PURE mreal *mgl_data_data(HMDT dat) {       return dat->a;  }\r
 //-----------------------------------------------------------------------------\r
 MGL_EXPORT mreal *mgl_data_value(HMDT dat, long i,long j,long k)\r
 {      register long ii=i*dat->nx*(j+dat->ny*k);\r
@@ -1984,131 +1949,126 @@ void MGL_EXPORT mgl_data_join(HMDT d, HCDT v)
 void MGL_EXPORT mgl_data_join_(uintptr_t *d, uintptr_t *val)\r
 {      mgl_data_join(_DT_,_DA_(val));  }\r
 //-----------------------------------------------------------------------------\r
-mreal MGL_NO_EXPORT mgl_index_1(mreal v, const mglData *dat, mreal acx)\r
+void MGL_EXPORT mgl_data_refill_gs(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl)\r
+{\r
+       HMDT coef = mgl_gspline_init(xdat, vdat);\r
+       if(!coef)       return; // incompatible dimensions\r
+       const long nx = dat->nx, nn=dat->ny*dat->nz;\r
+       mreal x0 = x1-xdat->v(0), dx = (x2-x1)/(nx-1);\r
+#pragma omp parallel for\r
+       for(long i=0;i<nx;i++)\r
+       {\r
+               register mreal d = mgl_gspline(coef,x0+dx*i,0,0);\r
+               if(sl<0)        for(long j=0;j<nn;j++)  dat->a[i+j*nx] = d;\r
+               else    dat->a[i+sl*nx] = d;\r
+       }\r
+       mgl_delete_data(coef);\r
+}\r
+//-----------------------------------------------------------------------------\r
+mreal MGL_NO_EXPORT mgl_index_1(mreal v, HCDT dat)\r
 {\r
-       long mx=dat->nx;\r
+       long mx=dat->GetNx();\r
        mreal d,d1=0,d2=mx-1,v1,v2;\r
-       v1 = mglSpline1t<mreal>(dat->a,mx,d1);\r
-       v2 = mglSpline1t<mreal>(dat->a,mx,d2);\r
+       v1 = mgl_data_spline(dat,d1,0,0);\r
+       v2 = mgl_data_spline(dat,d2,0,0);\r
        long count=0;\r
 \r
-       if(v1==v)       return d1;\r
-       if(v2==v)       return d2;\r
+       const mreal eps = MGL_EPSILON-1.;\r
+       if(fabs(v-v1)<eps)      return d1;\r
+       if(fabs(v-v2)<eps)      return d2;\r
        if((v1-v)*(v2-v)>0)     return NAN;\r
        do\r
        {\r
                d = count<10?(d2-d1)*(v-v1)/(v2-v1)+d1:(d1+d2)/2;       count++;\r
-               register mreal val = mglSpline1st<mreal>(dat->a,mx,d);\r
-               if(fabs(val-v)<acx)     break;\r
+               register mreal val = mgl_data_spline(dat,d,0,0);\r
+//             if(fabs(val-v)<acx)     break;\r
+               if(val==v || d2-d<eps)  break;\r
                if((v1-v)*(val-v)<0)    {       v2=val; d2=d;   }       else    {       v1=val; d1=d;   }\r
-       } while(fabs(d2-d1)>1e-3);\r
+       } while(fabs(d2-d1)>1e-5);\r
        return d;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_refill_x(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl)\r
 {\r
        long nx=dat->nx,mx=vdat->GetNx(),nn=dat->ny*dat->nz;\r
-       mreal acx=1e-6*fabs(x2-x1);\r
-       const mglData *xxd=dynamic_cast<const mglData *>(xdat);\r
-       const mglData *vvd=dynamic_cast<const mglData *>(vdat);\r
-       if(!xxd || !vvd || mx!=xxd->nx) return; // incompatible dimensions and for mglData only\r
+       if(mx!=xdat->GetNx())   return; // incompatible dimensions\r
+       mreal dx = (x2-x1)/(nx-1);\r
 #pragma omp parallel for\r
        for(long i=0;i<nx;i++)\r
        {\r
-               register mreal u = mgl_index_1(x1+(x2-x1)*i/(nx-1.),xxd,acx);\r
-               register mreal d = mglSpline1st<mreal>(vvd->a,mx,u);\r
+               register mreal u = mgl_index_1(x1+dx*i,xdat);\r
+               register mreal d = mgl_data_spline(vdat,u,0,0);\r
                if(sl<0)        for(long j=0;j<nn;j++)  dat->a[i+j*nx] = d;\r
                else    dat->a[i+sl*nx] = d;\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
-mglPoint MGL_NO_EXPORT mgl_index_2(mreal x, mreal y, const mglData *xdat, const mglData *ydat, mreal acx, mreal acy)\r
-{\r
-       long mx=xdat->nx, my=xdat->ny;\r
-       mreal u=fabs(x),u1=0,u2=mx-1, v=fabs(y),v1=0,v2=my-1;\r
-       mreal x11 = mgl_data_spline(xdat,u1,v1,0), y11 = mgl_data_spline(ydat,u1,v1,0);\r
-       mreal x21 = mgl_data_spline(xdat,u2,v1,0), y21 = mgl_data_spline(ydat,u2,v1,0);\r
-       mreal x12 = mgl_data_spline(xdat,u1,v2,0), y12 = mgl_data_spline(ydat,u1,v2,0);\r
-       mreal x22 = mgl_data_spline(xdat,u2,v2,0), y22 = mgl_data_spline(ydat,u2,v2,0);\r
-       long count=0;\r
-\r
-       if(fabs(x11-x)<acx && fabs(y11-y)<acy)  return mglPoint(u1,v1);\r
-       if(fabs(x12-x)<acx && fabs(y12-y)<acy)  return mglPoint(u1,v2);\r
-       if(fabs(x21-x)<acx && fabs(y21-y)<acy)  return mglPoint(u2,v1);\r
-       if(fabs(x22-x)<acx && fabs(y22-y)<acy)  return mglPoint(u2,v2);\r
-       if((x11-x)*(x12-x)*(x21-x)*(x22-x)>0 && (x11-x)*(x12-x)*(x21-x)>0)      return mglPoint(NAN,NAN);\r
-       if((y11-y)*(y12-y)*(y21-y)*(y22-y)>0 && (y11-y)*(y12-y)*(y21-y)>0)      return mglPoint(NAN,NAN);\r
-\r
-       do\r
-       {\r
-               if(count<10)\r
-               {\r
-                       register mreal dx0=x-x11, dx1=x21-x11, dx2=x12-x11, dx3=x22+x11-x12-x21;\r
-                       register mreal dy0=y-y11, dy1=y21-y11, dy2=y12-y11, dy3=y22+y11-y12-y21;\r
-                       register mreal t1 = dx0*dx0*dy3*dy3 + 2*dx0*dx1*dy2*dy3 + 2*dx0*dx2*dy1*dy3 - \r
-                                                               2*dx0*dx3*dy0*dy3 - 4*dx1*dx2*dy0*dy3 + dx1*dx1*dy2*dy2 - \r
-                                                               4*dx0*dx3*dy1*dy2 - 2*dx1*dx2*dy1*dy2 + 2*dx1*dx3*dy0*dy2 + \r
-                                                               dx2*dx2*dy1*dy1 + 2*dx2*dx3*dy0*dy1 + dx3*dx3*dy0*dy0, \r
-                                                       t2 = dx2*dy1+dx3*dy0-dx0*dy3-dx1*dy2, t3 = 2*(dx2*dy3-dx3*dy2);\r
-                       if(t1<0 || t3==0)       {       count=10;       continue;       }\r
-                       t1 = sqrt(t1);  v = (t2-t1)/t3;\r
-                       if(v<0 || v>1)  v = (t2+t1)/t3;\r
-                       u = (dx0-dx2*v)/(dx1+dx3*v);\r
-                       if(u<0 || v<0 || u>1 || v>1)    {       count=10;       continue;       }\r
-                       u = u1+(u2-u1)*u;       v = v1+(v2-v1)*v;       count++;\r
-               }\r
-               else    {       u = (u1+u2)/2;  v = (v1+v2)/2;  }\r
-\r
-               mreal tx  = mgl_data_spline(xdat,u,v,0),  ty  = mgl_data_spline(ydat,u,v,0);\r
-               if(fabs(tx-x)<acx && fabs(ty-y)<acy)    break;\r
-               mreal tx1 = mgl_data_spline(xdat,u1,v,0), ty1 = mgl_data_spline(ydat,u1,v,0);\r
-               if(fabs(tx1-x)<acx && fabs(ty1-y)<acy)  {u=u1;  break;}\r
-               mreal tx2 = mgl_data_spline(xdat,u2,v,0), ty2 = mgl_data_spline(ydat,u2,v,0);\r
-               if(fabs(tx2-x)<acx && fabs(ty2-y)<acy)  {u=u2;  break;}\r
-               mreal sx1 = mgl_data_spline(xdat,u,v1,0), sy1 = mgl_data_spline(ydat,u,v1,0);\r
-               if(fabs(sx1-x)<acx && fabs(sy1-y)<acy)  {v=v1;  break;}\r
-               mreal sx2 = mgl_data_spline(xdat,u,v2,0), sy2 = mgl_data_spline(ydat,u,v2,0);\r
-               if(fabs(sx2-x)<acx && fabs(sy2-y)<acy)  {v=v2;  break;}\r
-               if( ((x11-x)*(sx1-x)*(tx1-x)*(tx-x)>0 || (x11-x)*(sx1-x)*(tx1-x)>0) && ((y11-y)*(sy1-y)*(ty1-y)*(ty-y)>0 && (y11-y)*(sy1-y)*(ty1-y)>0) )\r
-               {       x12 = tx1;      y12 = ty1;      x21 = sx1;      y21 = sy1;      x22 = tx;       y22 = ty;       u2 = u; v2 = v; }\r
-               if( ((tx1-x)*(tx-x)*(x12-x)*(sx2-x)>0 || (tx1-x)*(tx-x)*(x12-x)>0) && ((ty1-y)*(ty-y)*(y12-y)*(sy2-y)>0 && (ty1-y)*(ty-y)*(y12-y)>0) )\r
-               {       x11 = tx1;      y11 = ty1;      x21 = tx;       y21 = ty;       x22 = sx2;      y22 = sy2;      u2 = u; v1 = v; }\r
-               if( ((tx-x)*(sx2-x)*(tx2-x)*(x22-x)>0 || (tx-x)*(sx2-x)*(tx2-x)>0) && ((ty-y)*(sy2-y)*(ty2-y)*(y22-y)>0 && (ty-y)*(sy2-y)*(ty2-y)>0) )\r
-               {       x11 = tx;       y11 = ty;       x12 = sx2;      y12 = sy2;      x21 = tx2;      y21 = ty2;      u1 = u; v1 = v; }\r
-               if( ((sx1-x)*(tx-x)*(x21-x)*(tx2-x)>0 || (sx1-x)*(tx-x)*(x21-x)>0) && ((sy1-y)*(ty-y)*(y21-y)*(ty2-y)>0 && (sy1-y)*(ty-y)*(y21-y)>0) )\r
-               {       x11 = sx1;      y11 = sy1;      x12 = tx;       y12 = ty;       x22 = tx2;      y22 = ty2;      u1 = u; v2 = v; }\r
-       } while(fabs(u2-u1)>1e-3 || fabs(v2-v1)>1e-3);\r
-       return mglPoint(u,v);\r
-}\r
-//-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_refill_xy(HMDT dat, HCDT xdat, HCDT ydat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, long sl)\r
 {\r
        long nx=dat->nx,ny=dat->ny,nz=dat->nz,mx=vdat->GetNx(),my=vdat->GetNy(),nn=nx*ny;\r
-       const mglData *xxd=dynamic_cast<const mglData *>(xdat);\r
-       const mglData *yyd=dynamic_cast<const mglData *>(ydat);\r
-       const mglData *vvd=dynamic_cast<const mglData *>(vdat);\r
-       if(!xxd || !vvd || !yyd)        return; // for mglData only\r
        bool both=(xdat->GetNN()==vdat->GetNN() && ydat->GetNN()==vdat->GetNN());\r
        if(!both && (xdat->GetNx()!=mx || ydat->GetNx()!=my))   return; // incompatible dimensions\r
-       mreal acx=1e-6*fabs(x2-x1), acy=1e-6*fabs(y2-y1);\r
+       mreal dx = (x2-x1)/(nx-1), dy = (y2-y1)/(ny-1);\r
        if(both)\r
-               mgl_data_grid_xy(dat,xdat,ydat,vdat,x1,x2,y1,y2);\r
-/*#pragma omp parallel for collapse(2)\r
-               for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)  // NOTE: too slow\r
+       {\r
+#pragma omp parallel for\r
+               for(long i=0;i<nn*nz;i++)       dat->a[i]=NAN;\r
+#pragma omp parallel for collapse(2)\r
+               for(long j=0;j<my-1;j++)        for(long i=0;i<mx-1;i++)\r
                {\r
-                       mglPoint p = mgl_index_2(x1+(x2-x1)*i/(nx-1.), y1+(y2-y1)*j/(ny-1.),xxd,yyd,acx,acy);\r
-                       register mreal d = mgl_isnan(p.x)?NAN:mgl_data_spline(vdat,p.x,p.y,0);\r
-                       register long i0=i+nx*j;\r
-                       if(sl<0)        for(long k=0;k<nz;k++)  dat->a[i0+k*nn] = d;\r
-                       else    dat->a[i0+sl*nn] = d;\r
-               }*/\r
+                       long i0 = i+mx*j;\r
+                       mreal vx0 = (xdat->vthr(i0)-x1)/dx, vy0 = (ydat->vthr(i0)-y1)/dy;\r
+                       mreal vx1 = (xdat->vthr(i0+1)-x1)/dx, vy1 = (ydat->vthr(i0+1)-y1)/dy;\r
+                       mreal vx2 = (xdat->vthr(i0+mx)-x1)/dx, vy2 = (ydat->vthr(i0+mx)-y1)/dy;\r
+                       mreal vx3 = (xdat->vthr(i0+mx+1)-x1)/dx, vy3 = (ydat->vthr(i0+mx+1)-y1)/dy;\r
+                       long xx1 = long(mgl_min( mgl_min(vx0,vx1), mgl_min(vx2,vx3) )); // bounding box\r
+                       long yy1 = long(mgl_min( mgl_min(vy0,vy1), mgl_min(vy2,vy3) ));\r
+                       long xx2 = long(mgl_max( mgl_max(vx0,vx1), mgl_max(vx2,vx3) ));\r
+                       long yy2 = long(mgl_max( mgl_max(vy0,vy1), mgl_max(vy2,vy3) ));\r
+                       xx1=mgl_max(xx1,0);     xx2=mgl_min(xx2,nx-1);\r
+                       yy1=mgl_max(yy1,0);     yy2=mgl_min(yy2,ny-1);\r
+                       if(xx1>xx2 || yy1>yy2)  continue;\r
+                       \r
+                       mreal d1x = vx1-vx0, d1y = vy1-vy0;\r
+                       mreal d2x = vx2-vx0, d2y = vy2-vy0;\r
+                       mreal d3x = vx3+vx0-vx1-vx2, d3y = vy3+vy0-vy1-vy2;\r
+                       mreal dd = d1x*d2y-d1y*d2x;\r
+                       mreal dsx =-4*(d2y*d3x - d2x*d3y)*d1y;\r
+                       mreal dsy = 4*(d2y*d3x - d2x*d3y)*d1x;\r
+\r
+                       for(long jj=yy1;jj<=yy2;jj++)   for(long ii=xx1;ii<=xx2;ii++)\r
+                       {\r
+                               mreal xx = (ii-vx0), yy = (jj-vy0);\r
+                               mreal s = dsx*xx + dsy*yy + (dd+d3y*xx-d3x*yy)*(dd+d3y*xx-d3x*yy);\r
+                               if(s>=0)\r
+                               {\r
+                                       s = sqrt(s);\r
+                                       mreal qu = d3x*yy - d3y*xx + dd + s;\r
+                                       mreal qv = d3y*xx - d3x*yy + dd + s;\r
+                                       mreal u = 2.f*(d2y*xx - d2x*yy)/qu;\r
+                                       mreal v = 2.f*(d1x*yy - d1y*xx)/qv;\r
+                                       if(u*(1.f-u)<0.f || v*(1.f-v)<0.f)      // first root bad\r
+                                       {\r
+                                               qu = d3x*yy - d3y*xx + dd - s;\r
+                                               qv = d3y*xx - d3x*yy + dd - s;\r
+                                               u = 2.f*(d2y*xx - d2x*yy)/qu;\r
+                                               v = 2.f*(d1x*yy - d1y*xx)/qv;\r
+                                               if(u*(1.f-u)<0.f || v*(1.f-v)<0.f)      continue;       // second root bad\r
+                                       }\r
+                                       i0 = ii+nx*jj;  s = mgl_data_spline(vdat,i+u,j+v,0);\r
+                                       if(sl<0)        for(long k=0;k<nz;k++)  dat->a[i0+k*nn] = s;\r
+                                       else    dat->a[i0+sl*nn] = s;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
        else\r
        {\r
                mglData u(nx), v(ny);\r
 #pragma omp parallel for\r
-               for(long i=0;i<nx;i++)  u.a[i] = mgl_index_1(x1+(x2-x1)*i/(nx-1.),xxd,acx);\r
+               for(long i=0;i<nx;i++)  u.a[i] = mgl_index_1(x1+dx*i,xdat);\r
 #pragma omp parallel for\r
-               for(long i=0;i<ny;i++)  v.a[i] = mgl_index_1(y1+(y2-y1)*i/(ny-1.),yyd,acy);\r
+               for(long i=0;i<ny;i++)  v.a[i] = mgl_index_1(y1+dy*i,ydat);\r
 #pragma omp parallel for collapse(2)\r
                for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                {\r
@@ -2123,14 +2083,9 @@ void MGL_EXPORT mgl_data_refill_xy(HMDT dat, HCDT xdat, HCDT ydat, HCDT vdat, mr
 void MGL_EXPORT mgl_data_refill_xyz(HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, mreal z1, mreal z2)\r
 {\r
        long nx=dat->nx,ny=dat->ny,nz=dat->nz,mx=vdat->GetNx(),my=vdat->GetNy(),mz=vdat->GetNz();\r
-       const mglData *xxd=dynamic_cast<const mglData *>(xdat);\r
-       const mglData *yyd=dynamic_cast<const mglData *>(ydat);\r
-       const mglData *zzd=dynamic_cast<const mglData *>(zdat);\r
-       const mglData *vvd=dynamic_cast<const mglData *>(vdat);\r
-       if(!xxd || !vvd || !yyd || !zzd)        return; // for mglData only\r
        bool both=(xdat->GetNN()==vdat->GetNN() && ydat->GetNN()==vdat->GetNN() && zdat->GetNN()==vdat->GetNN());\r
        if(!both && (xdat->GetNx()!=mx || ydat->GetNx()!=my || zdat->GetNx()!=mz))      return; // incompatible dimensions\r
-       mreal acx=1e-6*fabs(x2-x1), acy=1e-6*fabs(y2-y1), acz=1e-6*fabs(z2-z1);\r
+       const mreal acx=1e-6*fabs(x2-x1), acy=1e-6*fabs(y2-y1), acz=1e-6*fabs(z2-z1);\r
        if(both)\r
 #pragma omp parallel for collapse(3)\r
                for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
@@ -2158,70 +2113,83 @@ void MGL_EXPORT mgl_data_refill_xyz(HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, H
        else\r
        {\r
                mglData u(nx), v(ny), w(nz);\r
+               mreal dx = (x2-x1)/(nx-1), dy = (y2-y1)/(ny-1), dz = (z2-z1)/(nz-1);\r
 #pragma omp parallel for\r
-               for(long i=0;i<nx;i++)  u.a[i] = mgl_index_1(x1+(x2-x1)*i/(nx-1.),xxd,acx);\r
+               for(long i=0;i<nx;i++)  u.a[i] = mgl_index_1(x1+dx*i,xdat);\r
 #pragma omp parallel for\r
-               for(long i=0;i<ny;i++)  v.a[i] = mgl_index_1(y1+(y2-y1)*i/(ny-1.),yyd,acy);\r
+               for(long i=0;i<ny;i++)  v.a[i] = mgl_index_1(y1+dy*i,ydat);\r
 #pragma omp parallel for\r
-               for(long i=0;i<nz;i++)  w.a[i] = mgl_index_1(z1+(z2-z1)*i/(nz-1.),zzd,acz);\r
+               for(long i=0;i<nz;i++)  w.a[i] = mgl_index_1(z1+dz*i,zdat);\r
 #pragma omp parallel for collapse(3)\r
                for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        dat->a[i+nx*(j+ny*k)] = mgl_data_spline(vdat,u.a[i],v.a[j],w.a[k]);\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_eval(void *par)\r
+HMDT MGL_EXPORT mgl_data_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm)\r
 {\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0], ny=t->p[1], nz=t->p[2], n1=t->p[3], nn=t->n;\r
-       const mreal *a=t->b, *ii=t->c, *jj=t->d, *kk=t->e;\r
-       mreal *b=t->a;\r
-#if !MGL_HAVE_PTHREAD\r
+       if(!idat || (jdat && jdat->GetNN()!=idat->GetNN()) || (kdat && kdat->GetNN()!=idat->GetNN()))   return 0;\r
+       const mglData *dd=dynamic_cast<const mglData *>(dat);\r
+       long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz();\r
+       mglData *r=new mglData(idat->GetNx(),idat->GetNy(),idat->GetNz());\r
+       if(dd)\r
 #pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<nn;i+=mglNumThr)\r
-       {\r
-               register mreal x=ii?ii[i]:0, y=jj?jj[i]:0, z=kk?kk[i]:0;\r
-               if(n1)  {       x*=nx-1;        y*=ny-1;        z*=nz-1;        }\r
-               b[i] = x*y*z==x*y*z ? mglSpline3st<mreal>(a,nx,ny,nz,x,y,z):NAN;\r
-       }\r
-       return 0;\r
+               for(long i=0;i<idat->GetNN();i++)\r
+               {\r
+                       mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0;\r
+                       r->a[i] = mgl_isnum(x*y*z)?mglSpline3st<mreal>(dd->a,nx,ny,nz, x,y,z):NAN;\r
+               }\r
+       else\r
+#pragma omp parallel for\r
+               for(long i=0;i<idat->GetNN();i++)\r
+               {\r
+                       mreal x=idat->vthr(i), y=jdat?jdat->vthr(i):0, z=kdat?kdat->vthr(i):0;\r
+                       r->a[i] = mgl_isnum(x*y*z)?mgl_data_linear(dat, x,y,z):NAN;;\r
+               }\r
+       return r;\r
 }\r
-MGL_NO_EXPORT void *mgl_eval_s(void *par)\r
+uintptr_t MGL_EXPORT mgl_data_evaluate_(uintptr_t *d, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm)\r
+{      return uintptr_t(mgl_data_evaluate(_DT_,_DA_(idat),_DA_(jdat),_DA_(kdat),*norm));       }\r
+//-----------------------------------------------------------------------------\r
+HMDT MGL_EXPORT mgl_gspline_init(HCDT x, HCDT v)\r
 {\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0], ny=t->p[1], nz=t->p[2], n1=t->p[3], nn=t->n;\r
-       const mreal *ii=t->c, *jj=t->d, *kk=t->e;\r
-       HCDT a = (HCDT)t->v;\r
-       mreal *b=t->a;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       long n = v->GetNx();\r
+       if(!x || x->GetNx()!=n) return 0;\r
+       mglData *res = new mglData(5*(n-1));\r
+       mreal *xx=0, *vv=0;\r
+       const mglData *dx = dynamic_cast<const mglData *>(x);\r
+       if(!dx)\r
        {\r
-               register mreal x=ii?ii[i]:0, y=jj?jj[i]:0, z=kk?kk[i]:0;\r
-               if(n1)  {       x*=nx-1;        y*=ny-1;        z*=nz-1;        }\r
-               b[i] = x*y*z==x*y*z ? mgl_data_linear(a, x,y,z):NAN;\r
+               xx = new mreal[n];\r
+               for(long i=0;i<n;i++)   xx[i] = x->v(i);\r
        }\r
-       return 0;\r
+       const mglData *dv = dynamic_cast<const mglData *>(v);\r
+       if(!dv)\r
+       {\r
+               vv = new mreal[n];\r
+               for(long i=0;i<n;i++)   vv[i] = v->v(i);\r
+       }\r
+       mgl_gspline_init(n,dx?dx->a:xx,dv?dv->a:vv,res->a);\r
+       if(xx)  delete []xx;\r
+       if(vv)  delete []vv;\r
+       return res;\r
 }\r
-HMDT MGL_EXPORT mgl_data_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm)\r
+uintptr_t MGL_EXPORT mgl_gspline_init_(uintptr_t *x, uintptr_t *v)\r
+{      return uintptr_t(mgl_gspline_init(_DA_(x),_DA_(v)));    }\r
+//-----------------------------------------------------------------------------\r
+mreal MGL_EXPORT mgl_gspline(HCDT c, mreal dx, mreal *d1, mreal *d2)\r
 {\r
-       const mglData *d=dynamic_cast<const mglData *>(dat);\r
-       const mglData *i=dynamic_cast<const mglData *>(idat);\r
-       const mglData *j=dynamic_cast<const mglData *>(jdat);\r
-       const mglData *k=dynamic_cast<const mglData *>(kdat);\r
-       if(!i)  return 0;\r
-\r
-       long p[4]={dat->GetNx(), dat->GetNy(), dat->GetNz(),norm};\r
-       register long n=i->nx*i->ny*i->nz;\r
-       if(j && j->nx*j->ny*j->nz!=n)   return 0;\r
-       if(k && k->nx*k->ny*k->nz!=n)   return 0;\r
-       mglData *r=new mglData(i->nx,i->ny,i->nz);\r
-       if(d)   mglStartThread(mgl_eval,0,n,r->a,d->a,i->a,p,0,j?j->a:0,k?k->a:0);\r
-       else    mglStartThread(mgl_eval_s,0,n,r->a,0,i->a,p,dat,j?j->a:0,k?k->a:0);\r
-       return r;\r
+       long i=0, n = c->GetNx();\r
+       if(n%5 || dx<0) return NAN;     // not the table of coefficients\r
+       while(dx>c->v(5*i))\r
+       {\r
+               dx-=c->v(5*i);  i++;\r
+               if(5*i>=n)      return NAN;\r
+       }\r
+       if(d1)  *d1 = c->v(5*i+2)+dx*(2*c->v(5*i+3)+3*dx*c->v(5*i+4));\r
+       if(d2)  *d2 = 2*c->v(5*i+3)+6*dx*c->v(5*i+4);\r
+       return c->v(5*i+1)+dx*(c->v(5*i+2)+dx*(c->v(5*i+3)+dx*c->v(5*i+4)));\r
 }\r
-uintptr_t MGL_EXPORT mgl_data_evaluate_(uintptr_t *d, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm)\r
-{      return uintptr_t(mgl_data_evaluate(_DT_,_DA_(idat),_DA_(jdat),_DA_(kdat),*norm));       }\r
+mreal MGL_EXPORT mgl_gspline_(uintptr_t *c, mreal *dx, mreal *d1, mreal *d2)\r
+{      return mgl_gspline(_DA_(c),*dx,d1,d2);  }\r
 //-----------------------------------------------------------------------------\r
index d112516b678520c196c77fc0957633b43aa0367e..193b55d5cea284feafc05de8cf470a78d1040bf4 100644 (file)
@@ -21,6 +21,7 @@
 #include "mgl2/data.h"\r
 #include "mgl2/eval.h"\r
 #include "mgl2/thread.h"\r
+mglData MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector<mglDataA*> &head);\r
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_data_trace(HCDT d)\r
 {\r
@@ -42,27 +43,33 @@ uintptr_t MGL_EXPORT mgl_data_trace_(uintptr_t *d)
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_data_subdata_ext(HCDT d, HCDT xx, HCDT yy, HCDT zz)\r
 {\r
+       if(!xx || !yy || !zz)\r
+       {\r
+               mglData tmp;    tmp.a[0]=-1;\r
+               return mgl_data_subdata_ext(d,xx?xx:&tmp,yy?yy:&tmp,zz?zz:&tmp);\r
+       }\r
+       \r
        long n=0,m=0,l=0,j,k;\r
        bool ix=false, iy=false, iz=false;\r
        if(xx->GetNz()>1)       // 3d data\r
        {\r
                n = xx->GetNx();        m = xx->GetNy();        l = xx->GetNz();\r
-               j = yy->GetNx()*yy->GetNy()*yy->GetNz();        if(j>1 && j!=n*m*l)     return 0;       // wrong sizes\r
-               k = zz->GetNx()*zz->GetNy()*zz->GetNz();        if(k>1 && k!=n*m*l)     return 0;       // wrong sizes\r
+               j = yy->GetNN();        if(j>1 && j!=n*m*l)     return 0;       // wrong sizes\r
+               k = zz->GetNN();        if(k>1 && k!=n*m*l)     return 0;       // wrong sizes\r
                ix = true;      iy = j>1;       iz = k>1;\r
        }\r
        else if(yy->GetNz()>1)\r
        {\r
                n = yy->GetNx();        m = yy->GetNy();        l = yy->GetNz();\r
-               j = xx->GetNx()*xx->GetNy()*xx->GetNz();        if(j>1 && j!=n*m*l)     return 0;       // wrong sizes\r
-               k = zz->GetNx()*zz->GetNy()*zz->GetNz();        if(k>1 && k!=n*m*l)     return 0;       // wrong sizes\r
+               j = xx->GetNN();        if(j>1 && j!=n*m*l)     return 0;       // wrong sizes\r
+               k = zz->GetNN();        if(k>1 && k!=n*m*l)     return 0;       // wrong sizes\r
                iy = true;      ix = j>1;       iz = k>1;\r
        }\r
        else if(zz->GetNz()>1)\r
        {\r
                n = zz->GetNx();        m = zz->GetNy();        l = zz->GetNz();\r
-               j = yy->GetNx()*yy->GetNy()*yy->GetNz();        if(j>1 && j!=n*m*l)     return 0;       // wrong sizes\r
-               k = xx->GetNx()*xx->GetNy()*xx->GetNz();        if(k>1 && k!=n*m*l)     return 0;       // wrong sizes\r
+               j = yy->GetNN();        if(j>1 && j!=n*m*l)     return 0;       // wrong sizes\r
+               k = xx->GetNN();        if(k>1 && k!=n*m*l)     return 0;       // wrong sizes\r
                iz = true;      iy = j>1;       ix = k>1;\r
        }\r
        else if(xx->GetNy()>1)  // 2d data\r
@@ -87,34 +94,33 @@ HMDT MGL_EXPORT mgl_data_subdata_ext(HCDT d, HCDT xx, HCDT yy, HCDT zz)
                iz = true;      iy = j>1;       ix = k>1;\r
        }\r
        long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();\r
-       mreal vx=xx->v(0), vy=yy->v(0), vz=zz->v(0);\r
-       mglData *r=new mglData;\r
+       long vx=long(xx->v(0)), vy=long(yy->v(0)), vz=long(zz->v(0));\r
        if(n*m*l>1)     // this is 2d or 3d data\r
        {\r
-               r->Create(n,m,l);\r
+               mglDataV tx(n,m,l),ty(n,m,l),tz(n,m,l);\r
+               if(!ix) {       xx = &tx;       if(vx>=0)       tx.Fill(vx);    else tx.All();  }\r
+               if(!iy) {       yy = &ty;       if(vy>=0)       ty.Fill(vy);    else ty.All();  }\r
+               if(!iz) {       zz = &tz;       if(vz>=0)       tz.Fill(vz);    else tz.All();  }\r
+               mglData *r=new mglData(n,m,l);\r
 #pragma omp parallel for\r
                for(long i0=0;i0<n*m*l;i0++)\r
                {\r
-                       register mreal x = ix?xx->vthr(i0):vx;\r
-                       register mreal y = iy?yy->vthr(i0):vy;\r
-                       register mreal z = iz?zz->vthr(i0):vz;\r
-                       r->a[i0] = mgl_data_linear(d,x,y,z);\r
+                       register long x=long(0.5+xx->vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0));\r
+                       r->a[i0] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?d->v(x,y,z):NAN;\r
                }\r
                return r;\r
        }\r
        // this is 1d data -> try as normal SubData()\r
-       if(xx->GetNx()>1 || vx>=0)      {       n=xx->GetNx();  ix=true;        }\r
-       else    {       n=nx;   ix=false;       }\r
-       if(yy->GetNx()>1 || vy>=0)      {       m=yy->GetNx();  iy=true;        }\r
-       else    {       m=ny;   iy=false;       }\r
-       if(zz->GetNx()>1 || vz>=0)      {       l=zz->GetNx();  iz=true;        }\r
-       else    {       l=nz;   iz=false;       }\r
-       r->Create(n,m,l);\r
+       mglDataV tx(nx),ty(ny),tz(nz);  tx.All();       ty.All();       tz.All();\r
+       if(xx->GetNx()>1 || vx>=0)      n=xx->GetNx();  else    {       n=nx;   xx = &tx;       }\r
+       if(yy->GetNx()>1 || vy>=0)      m=yy->GetNx();  else    {       m=ny;   yy = &ty;       }\r
+       if(zz->GetNx()>1 || vz>=0)      l=zz->GetNx();  else    {       l=nz;   zz = &tz;       }\r
+       mglData *r=new mglData(n,m,l);\r
 #pragma omp parallel for collapse(3)\r
        for(long k=0;k<l;k++)   for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
        {\r
-               register mreal x = ix?xx->v(i):i, y = iy?yy->v(j):j, z = iz?zz->v(k):k;\r
-               r->a[i+n*(j+m*k)] = mgl_data_linear(d,x,y,z);\r
+               register long x=long(0.5+xx->v(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k));\r
+               r->a[i+n*(j+m*k)] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?d->v(x,y,z):NAN;\r
        }\r
        if(m==1)        {       r->ny=r->nz;    r->nz=1;        }// "squeeze" dimensions\r
        if(n==1)        {       r->nx=r->ny;    r->ny=r->nz;    r->nz=1;        r->NewId();}\r
@@ -123,9 +129,22 @@ HMDT MGL_EXPORT mgl_data_subdata_ext(HCDT d, HCDT xx, HCDT yy, HCDT zz)
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_data_subdata(HCDT d, long xx,long yy,long zz)\r
 {\r
-       mglData x,y,z;\r
-       x.a[0]=xx;      y.a[0]=yy;      z.a[0]=zz;\r
-       return mgl_data_subdata_ext(d,&x,&y,&z);\r
+       long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), n=1,m=1,l=1;\r
+       int dx=0,dy=0,dz=0;\r
+       if(xx<0)        {       xx=0;   dx=1;   n=nx;   }\r
+       if(yy<0)        {       yy=0;   dy=1;   m=ny;   }\r
+       if(zz<0)        {       zz=0;   dz=1;   l=nz;   }\r
+       mglData *r=new mglData(n,m,l);\r
+       if(xx<nx && yy<ny && zz<nz)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<l;k++)   for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
+                       r->a[i+n*(j+m*k)] = d->v(xx+dx*i, yy+dy*j, zz+dz*k);\r
+       else\r
+#pragma omp parallel for\r
+               for(long i=0;i<n*m*l;i++)       r->a[i] = NAN;\r
+       if(m==1)        {       r->ny=r->nz;    r->nz=1;        }// "squeeze" dimensions\r
+       if(n==1)        {       r->nx=r->ny;    r->ny=r->nz;    r->nz=1;        r->NewId();}\r
+       return r;\r
 }\r
 //-----------------------------------------------------------------------------\r
 uintptr_t MGL_EXPORT mgl_data_subdata_(uintptr_t *d, int *xx,int *yy,int *zz)\r
@@ -133,71 +152,35 @@ uintptr_t MGL_EXPORT mgl_data_subdata_(uintptr_t *d, int *xx,int *yy,int *zz)
 uintptr_t MGL_EXPORT mgl_data_subdata_ext_(uintptr_t *d, uintptr_t *xx, uintptr_t *yy, uintptr_t *zz)\r
 {      return uintptr_t(mgl_data_subdata_ext(_DT_,_DA_(xx),_DA_(yy),_DA_(zz)));        }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_column(void *par)\r
-{\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       const mglFormula *f = (const mglFormula *)t->v;\r
-       long nx=t->p[0];\r
-       mreal *b=t->a, var[MGL_VS];\r
-       const mreal *a=t->b;\r
-       memset(var,0,('z'-'a')*sizeof(mreal));\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<t->n;i+=mglNumThr)\r
-       {\r
-               for(long j=0;j<nx;j++)\r
-                       if(t->s[j]>='a' && t->s[j]<='z')\r
-                               var[t->s[j]-'a'] = a[j+nx*i];\r
-               b[i] = f->Calc(var);\r
-       }\r
-       return 0;\r
-}\r
-HMDT MGL_EXPORT mgl_data_column(HCDT dat, const char *eq)\r
-{      // NOTE: only for mglData (for speeding up)\r
-       long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz();\r
-       mglFormula f(eq);\r
-       mglData *r=new mglData(ny,nz);\r
-       const mglData *d=dynamic_cast<const mglData *>(dat);\r
-       if(d)   mglStartThread(mgl_column,0,ny*nz,r->a,d->a,0,&nx,&f,0,0,d->id.c_str());\r
-       return r;\r
-}\r
-uintptr_t MGL_EXPORT mgl_data_column_(uintptr_t *d, const char *eq,int l)\r
-{      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
-       uintptr_t r = uintptr_t(mgl_data_column(_DT_,s));\r
-       delete []s;     return r;       }\r
-//-----------------------------------------------------------------------------\r
 MGL_NO_EXPORT void *mgl_resize(void *par)\r
 {\r
        mglThreadD *t=(mglThreadD *)par;\r
        long nx=t->p[0]+0.1, ny=t->p[1]+0.1;\r
-       long n1=t->p[3]+0.1,n2=t->p[4]+0.1,n3=t->p[5]+0.1;\r
        mreal *b=t->a;\r
-       const mreal *a=t->b, *c=t->c;\r
+       const mreal *c=t->c;\r
+       HCDT dat = (HCDT)(t->v);\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
        for(long i0=t->id;i0<t->n;i0+=mglNumThr)\r
        {\r
                register long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);\r
-               b[i0] = mglSpline3(a,n1,n2,n3, c[0]+i*c[1], c[2]+j*c[3], c[4]+k*c[5]);\r
+               b[i0] = mgl_data_spline(dat, c[0]+i*c[1], c[2]+j*c[3], c[4]+k*c[5]);\r
        }\r
        return 0;\r
 }\r
 HMDT MGL_EXPORT mgl_data_resize_box(HCDT dat, long mx,long my,long mz, mreal x1,mreal x2, mreal y1,mreal y2, mreal z1,mreal z2)\r
-{      // NOTE: only for mglData (for speeding up)\r
-       const mglData *d=dynamic_cast<const mglData *>(dat);\r
-       if(!d)  return 0;\r
-       register long nx = d->nx-1, ny = d->ny-1, nz = d->nz-1;\r
-       mx = mx<1 ? nx+1:mx;    my = my<1 ? ny+1:my;    mz = mz<1 ? nz+1:mz;\r
+{\r
+       register long nx = dat->GetNx(), ny = dat->GetNy(), nz = dat->GetNz();\r
+       mx = mx<1 ? nx:mx;      my = my<1 ? ny:my;      mz = mz<1 ? nz:mz;\r
        mglData *r=new mglData(mx,my,mz);\r
 \r
        mreal par[6]={nx*x1,0,ny*y1,0,nz*z1,0};\r
-       long nn[6]={mx,my,mz,nx+1,ny+1,nz+1};\r
-       if(mx>1)        par[1] = nx*(x2-x1)/(mx-1);\r
-       if(my>1)        par[3] = ny*(y2-y1)/(my-1);\r
-       if(mz>1)        par[5] = nz*(z2-z1)/(mz-1);\r
-       mglStartThread(mgl_resize,0,mx*my*mz,r->a,d->a,par,nn);\r
+       long nn[6]={mx,my,mz,nx,ny,nz};\r
+       if(mx>1)        par[1] = (nx-1)*(x2-x1)/(mx-1);\r
+       if(my>1)        par[3] = (ny-1)*(y2-y1)/(my-1);\r
+       if(mz>1)        par[5] = (nz-1)*(z2-z1)/(mz-1);\r
+       mglStartThread(mgl_resize,0,mx*my*mz,r->a,0,par,nn,dat);\r
        return r;\r
 }\r
 HMDT MGL_EXPORT mgl_data_resize(HCDT d, long mx,long my,long mz)\r
@@ -207,31 +190,18 @@ uintptr_t MGL_EXPORT mgl_data_resize_(uintptr_t *d, int *mx,int *my,int *mz)
 uintptr_t MGL_EXPORT mgl_data_resize_box_(uintptr_t *d, int *mx,int *my,int *mz, mreal *x1,mreal *x2, mreal *y1,mreal *y2, mreal *z1,mreal *z2)\r
 {      return uintptr_t(mgl_data_resize_box(_DT_,*mx,*my,*mz,*x1,*x2,*y1,*y2,*z1,*z2));        }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_combine(void *par)\r
-{\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0];\r
-       mreal *b=t->a;\r
-       const mreal *c=t->b, *d=t->c;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i0=t->id;i0<t->n;i0+=mglNumThr)        b[i0] = c[i0%nx]*d[i0/nx];\r
-       return 0;\r
-}\r
 HMDT MGL_EXPORT mgl_data_combine(HCDT d1, HCDT d2)\r
-{      // NOTE: only for mglData (for speeding up)\r
-       const mglData *a=dynamic_cast<const mglData *>(d1);\r
-       const mglData *b=dynamic_cast<const mglData *>(d2);\r
-\r
-       if(!a || !b || a->nz>1 || (a->ny>1 && b->ny>1) || b->nz>1)      return 0;\r
+{\r
+       long n1=d1->GetNy(),n2=d2->GetNx(),nx=d1->GetNx();\r
+       if(d1->GetNz()>1 || (n1>1 && d2->GetNy()>1) || d2->GetNz()>1)   return 0;       // wrong dimensions\r
        mglData *r=new mglData;\r
-       long n1=a->ny,n2=b->nx;\r
        bool dim2=true;\r
-       if(a->ny==1)    {       n1=b->nx;       n2=b->ny;       dim2 = false;   }\r
-       r->Create(a->nx,n1,n2);\r
-       if(dim2)        n1=a->nx*a->ny; else    {       n1=a->nx;       n2=b->nx*b->ny; }\r
-       mglStartThread(mgl_combine,0,n1*n2,r->a,a->a,b->a,&n1);\r
+       if(n1==1)       {       n1=n2;  n2=d2->GetNy(); dim2 = false;   }\r
+       r->Create(nx,n1,n2);\r
+       if(dim2)        n1*=nx; else    {       n2*=n1; n1=nx;  }\r
+#pragma omp parallel for collapse(2)\r
+       for(long j=0;j<n2;j++)  for(long i=0;i<n1;i++)\r
+               r->a[i+n1*j] = d1->vthr(i)*d2->vthr(j);\r
        return r;\r
 }\r
 uintptr_t MGL_EXPORT mgl_data_combine_(uintptr_t *a, uintptr_t *b)\r
@@ -495,125 +465,91 @@ uintptr_t MGL_EXPORT mgl_data_min_dir_(uintptr_t *d, const char *dir,int l)
 {      char *s=new char[l+1];  memcpy(s,dir,l);        s[l]=0;\r
        uintptr_t r=uintptr_t(mgl_data_min_dir(_DT_,s));        delete []s;     return r;       }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_mom_z(void *par)\r
+HMDT MGL_EXPORT mgl_data_momentum(HCDT dat, char dir, const char *how)\r
 {\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0], ny=t->p[1], nz=t->p[2], nn=t->n;\r
-       mreal *b=t->a;\r
-       const mreal *a=t->b;\r
-       const mglFormula *eq = (const mglFormula *)t->v;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       if(!how || !(*how) || !strchr("xyz",dir))       return 0;\r
+       long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz();\r
+       mglDataV x(nx,ny,nz, 0,1,'x');  x.s=L"x";\r
+       mglDataV y(nx,ny,nz, 0,1,'y');  y.s=L"y";\r
+       mglDataV z(nx,ny,nz, 0,1,'z');  z.s=L"z";\r
+       mglData u(dat); u.s=L"u";       // NOTE slow !!!\r
+       std::vector<mglDataA*> list;\r
+       list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(&u);\r
+       mglData res=mglFormulaCalc(how,list);\r
+\r
+       mglData *b=0;\r
+       if(dir=='x')\r
        {\r
-               register mreal i0 = 0, i1 = 0;\r
-               for(long k=0;k<nx;k++)  for(long j=0;j<ny;j++)\r
+               b=new mglData(nx);\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx;i++)\r
                {\r
-                       register long ii = k+nx*(j+ny*i);\r
-                       register mreal x = k/(nx-1.), y = j/(ny-1.), z = i/(nz-1.);\r
-                       i0+= a[ii];\r
-                       i1+= a[ii]*eq->Calc(x,y,z,a[ii]);\r
+                       register mreal i1=0,i0=0;\r
+                       for(long j=0;j<ny*nz;j++)\r
+                       {\r
+                               register mreal u=dat->vthr(i+nx*j);\r
+                               i0 += u;        i1 += u*res.a[i+nx*j];\r
+                       }\r
+                       b->a[i] = i0>0 ? i1/i0 : 0;\r
                }\r
-               b[i] = i0>0 ? i1/i0 : 0;\r
        }\r
-       return 0;\r
-}\r
-MGL_NO_EXPORT void *mgl_mom_y(void *par)\r
-{\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0], ny=t->p[1], nz=t->p[2], nn=t->n;\r
-       mreal *b=t->a;\r
-       const mreal *a=t->b;\r
-       const mglFormula *eq = (const mglFormula *)t->v;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       if(dir=='y')\r
        {\r
-               register mreal i0 = 0, i1 = 0;\r
-               for(long j=0;j<nx;j++)  for(long k=0;k<nz;k++)\r
+               b=new mglData(ny);\r
+#pragma omp parallel for\r
+               for(long i=0;i<ny;i++)\r
                {\r
-                       register long ii = j+nx*(i+ny*k);\r
-                       register mreal x = k/(nx-1.), y = j/(ny-1.), z = i/(nz-1.);\r
-                       i0+= a[ii];\r
-                       i1+= a[ii]*eq->Calc(x,y,z,a[ii]);\r
+                       register mreal i1=0,i0=0;\r
+                       for(long k=0;k<nz;k++)  for(long j=0;j<nx;j++)\r
+                       {\r
+                               register mreal u=dat->v(j,i,k);\r
+                               i0 += u;        i1 += u*res.a[j+nx*(i+ny*k)];\r
+                       }\r
+                       b->a[i] = i0>0 ? i1/i0 : 0;\r
                }\r
-               b[i] = i0>0 ? i1/i0 : 0;\r
        }\r
-       return 0;\r
-}\r
-MGL_NO_EXPORT void *mgl_mom_x(void *par)\r
-{\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0], ny=t->p[1], nz=t->p[2], nn=t->n;\r
-       mreal *b=t->a;\r
-       const mreal *a=t->b;\r
-       const mglFormula *eq = (const mglFormula *)t->v;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<nn;i+=mglNumThr)\r
+       if(dir=='z')\r
        {\r
-               register mreal i0 = 0, i1 = 0;\r
-               for(long j=0;j<ny;j++)  for(long k=0;k<nz;k++)\r
+               long nn=nx*ny;\r
+               b=new mglData(nz);\r
+#pragma omp parallel for\r
+               for(long i=0;i<nz;i++)\r
                {\r
-                       register long ii = i+nx*(j+ny*k);\r
-                       register mreal x = k/(nx-1.), y = j/(ny-1.), z = i/(nz-1.);\r
-                       i0+= a[ii];\r
-                       i1+= a[ii]*eq->Calc(x,y,z,a[ii]);\r
+                       register mreal i1=0,i0=0;\r
+                       for(long j=0;j<nn;j++)\r
+                       {\r
+                               register mreal u=dat->vthr(j+nn*i);\r
+                               i0 += u;        i1 += u*res.a[j+nn*i];\r
+                       }\r
+                       b->a[i] = i0>0 ? i1/i0 : 0;\r
                }\r
-               b[i] = i0>0 ? i1/i0 : 0;\r
        }\r
-       return 0;\r
-}\r
-HMDT MGL_EXPORT mgl_data_momentum(HCDT dat, char dir, const char *how)\r
-{      // NOTE: only for mglData (for speeding up)\r
-       long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz();\r
-       const mglData *d=dynamic_cast<const mglData *>(dat);\r
-       if(!d)  return 0;\r
-       mglFormula eq(how);\r
-       long p[3]={nx,ny,nz};\r
-       mglData *b=0;\r
-       if(dir=='x')\r
-       {       b=new mglData(nx);      mglStartThread(mgl_mom_x,0,nx,b->a,d->a,0,p,&eq);       }\r
-       if(dir=='y')\r
-       {       b=new mglData(ny);      mglStartThread(mgl_mom_y,0,ny,b->a,d->a,0,p,&eq);       }\r
-       if(dir=='z')\r
-       {       b=new mglData(nz);      mglStartThread(mgl_mom_z,0,nz,b->a,d->a,0,p,&eq);       }\r
        return b;\r
 }\r
 uintptr_t MGL_EXPORT mgl_data_momentum_(uintptr_t *d, char *dir, const char *how, int,int l)\r
 {      char *s=new char[l+1];  memcpy(s,how,l);        s[l]=0;\r
-       uintptr_t r=uintptr_t(mgl_data_momentum(_DT_,*dir, s));\r
-       delete []s;     return r;       }\r
+       uintptr_t r=uintptr_t(mgl_data_momentum(_DT_,*dir, s)); delete []s;     return r;       }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_eqmul(void *par)\r
-{\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0];\r
-       mreal *b=t->a;\r
-       const mreal *a=t->b;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<t->n;i+=mglNumThr)   b[i] *= a[i%nx];\r
-       return 0;\r
-}\r
 void MGL_EXPORT mgl_data_mul_dat(HMDT d, HCDT a)\r
 {\r
-       long n, nx=d->nx, ny=d->ny, nz=d->nz;\r
-       const mglData *b = dynamic_cast<const mglData *>(a);\r
-       if(b)\r
+       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+       long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz();\r
+       if(mz==1 && my==1 && mx==1)\r
        {\r
-               if(b->nz==1 && b->ny==1 && nx==b->nx)\r
-               {       n=nx;           mglStartThread(mgl_eqmul,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
-               else if(b->nz==1 && ny==b->ny && nx==b->nx)\r
-               {       n=nx*ny;        mglStartThread(mgl_eqmul,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
-               else if(nz==b->nz && ny==b->ny && nx==b->nx)\r
-               {       n=nx*ny*nz;     mglStartThread(mgl_eqmul,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
+               mreal v=a->v(0);\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] *= v;\r
        }\r
-       else\r
+       else if(mz==1 && my==1 && nx==mx)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] *= a->v(i);\r
+       else if(mz==1 && ny==my && nx==mx)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] *= a->v(i,j);\r
+       else if(nz==mz && ny==my && nx==mx)\r
 #pragma omp parallel for collapse(3)\r
                for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        d->a[i+nx*(j+ny*k)] *= a->v(i,j,k);\r
@@ -621,36 +557,32 @@ void MGL_EXPORT mgl_data_mul_dat(HMDT d, HCDT a)
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_mul_num(HMDT d, mreal a)\r
 {\r
-       long n=1, nx=d->nx, ny=d->ny, nz=d->nz; mreal aa=a;\r
-       mglStartThread(mgl_eqmul,0,nx*ny*nz,d->a,&aa,0,&n);\r
+       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+#pragma omp parallel for collapse(3)\r
+       for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+               d->a[i+nx*(j+ny*k)] *= a;\r
 }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_eqdiv(void *par)\r
-{\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0];\r
-       mreal *b=t->a;\r
-       const mreal *a=t->b;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<t->n;i+=mglNumThr)   b[i] /= a[i%nx];\r
-       return 0;\r
-}\r
 void MGL_EXPORT mgl_data_div_dat(HMDT d, HCDT a)\r
 {\r
-       long n, nx=d->nx, ny=d->ny, nz=d->nz;\r
-       const mglData *b = dynamic_cast<const mglData *>(a);\r
-       if(b)\r
+       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+       long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz();\r
+       if(mz==1 && my==1 && mx==1)\r
        {\r
-               if(b->nz==1 && b->ny==1 && nx==b->nx)\r
-               {       n=nx;           mglStartThread(mgl_eqdiv,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
-               else if(b->nz==1 && ny==b->ny && nx==b->nx)\r
-               {       n=nx*ny;        mglStartThread(mgl_eqdiv,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
-               else if(nz==b->nz && ny==b->ny && nx==b->nx)\r
-               {       n=nx*ny*nz;     mglStartThread(mgl_eqdiv,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
+               mreal v=a->v(0);\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] /= v;\r
        }\r
-       else\r
+       else if(mz==1 && my==1 && nx==mx)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] /= a->v(i);\r
+       else if(mz==1 && ny==my && nx==mx)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] /= a->v(i,j);\r
+       else if(nz==mz && ny==my && nx==mx)\r
 #pragma omp parallel for collapse(3)\r
                for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        d->a[i+nx*(j+ny*k)] /= a->v(i,j,k);\r
@@ -658,36 +590,32 @@ void MGL_EXPORT mgl_data_div_dat(HMDT d, HCDT a)
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_div_num(HMDT d, mreal a)\r
 {\r
-       long n=1, nx=d->nx, ny=d->ny, nz=d->nz; mreal aa=a;\r
-       mglStartThread(mgl_eqdiv,0,nx*ny*nz,d->a,&aa,0,&n);\r
+       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+#pragma omp parallel for collapse(3)\r
+       for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+               d->a[i+nx*(j+ny*k)] /= a;\r
 }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_eqadd(void *par)\r
-{\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0];\r
-       mreal *b=t->a;\r
-       const mreal *a=t->b;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<t->n;i+=mglNumThr)   b[i] += a[i%nx];\r
-       return 0;\r
-}\r
 void MGL_EXPORT mgl_data_add_dat(HMDT d, HCDT a)\r
 {\r
-       long n, nx=d->nx, ny=d->ny, nz=d->nz;\r
-       const mglData *b = dynamic_cast<const mglData *>(a);\r
-       if(b)\r
+       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+       long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz();\r
+       if(mz==1 && my==1 && mx==1)\r
        {\r
-               if(b->nz==1 && b->ny==1 && nx==b->nx)\r
-               {       n=nx;           mglStartThread(mgl_eqadd,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
-               else if(b->nz==1 && ny==b->ny && nx==b->nx)\r
-               {       n=nx*ny;        mglStartThread(mgl_eqadd,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
-               else if(nz==b->nz && ny==b->ny && nx==b->nx)\r
-               {       n=nx*ny*nz;     mglStartThread(mgl_eqadd,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
+               mreal v=a->v(0);\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] += v;\r
        }\r
-       else\r
+       else if(mz==1 && my==1 && nx==mx)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] += a->v(i);\r
+       else if(mz==1 && ny==my && nx==mx)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] += a->v(i,j);\r
+       else if(nz==mz && ny==my && nx==mx)\r
 #pragma omp parallel for collapse(3)\r
                for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        d->a[i+nx*(j+ny*k)] += a->v(i,j,k);\r
@@ -695,36 +623,32 @@ void MGL_EXPORT mgl_data_add_dat(HMDT d, HCDT a)
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_add_num(HMDT d, mreal a)\r
 {\r
-       long n=1, nx=d->nx, ny=d->ny, nz=d->nz; mreal aa=a;\r
-       mglStartThread(mgl_eqadd,0,nx*ny*nz,d->a,&aa,0,&n);\r
+       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+#pragma omp parallel for collapse(3)\r
+       for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+               d->a[i+nx*(j+ny*k)] += a;\r
 }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_eqsub(void *par)\r
-{\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0];\r
-       mreal *b=t->a;\r
-       const mreal *a=t->b;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=t->id;i<t->n;i+=mglNumThr)   b[i] -= a[i%nx];\r
-       return 0;\r
-}\r
 void MGL_EXPORT mgl_data_sub_dat(HMDT d, HCDT a)\r
 {\r
-       long n, nx=d->nx, ny=d->ny, nz=d->nz;\r
-       const mglData *b = dynamic_cast<const mglData *>(a);\r
-       if(b)\r
+       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+       long mx=a->GetNx(), my=a->GetNy(), mz=a->GetNz();\r
+       if(mz==1 && my==1 && mx==1)\r
        {\r
-               if(b->nz==1 && b->ny==1 && nx==b->nx)\r
-               {       n=nx;           mglStartThread(mgl_eqsub,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
-               else if(b->nz==1 && ny==b->ny && nx==b->nx)\r
-               {       n=nx*ny;        mglStartThread(mgl_eqsub,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
-               else if(nz==b->nz && ny==b->ny && nx==b->nx)\r
-               {       n=nx*ny*nz;     mglStartThread(mgl_eqsub,0,nx*ny*nz,d->a,b->a,0,&n);    }\r
+               mreal v=a->v(0);\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] -= v;\r
        }\r
-       else\r
+       else if(mz==1 && my==1 && nx==mx)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] -= a->v(i);\r
+       else if(mz==1 && ny==my && nx==mx)\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+                       d->a[i+nx*(j+ny*k)] -= a->v(i,j);\r
+       else if(nz==mz && ny==my && nx==mx)\r
 #pragma omp parallel for collapse(3)\r
                for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
                        d->a[i+nx*(j+ny*k)] -= a->v(i,j,k);\r
@@ -732,8 +656,10 @@ void MGL_EXPORT mgl_data_sub_dat(HMDT d, HCDT a)
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_sub_num(HMDT d, mreal a)\r
 {\r
-       long n=1, nx=d->nx, ny=d->ny, nz=d->nz; mreal aa=a;\r
-       mglStartThread(mgl_eqsub,0,nx*ny*nz,d->a,&aa,0,&n);\r
+       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+#pragma omp parallel for collapse(3)\r
+       for(long k=0;k<nz;k++)  for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
+               d->a[i+nx*(j+ny*k)] -= a;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_mul_dat_(uintptr_t *d, uintptr_t *b)  {       mgl_data_mul_dat(_DT_, _DA_(b));        }\r
@@ -765,18 +691,19 @@ MGL_NO_EXPORT void *mgl_hist_1(void *par)
        long nn=t->n, n = t->p[0];\r
        mreal *b=new mreal[n];\r
        memset(b,0,n*sizeof(mreal));\r
-       const mreal *a=t->b, *c=t->c, *v=(const mreal *)t->v;\r
+       HCDT a = (HCDT)(t->b), c = (HCDT)(t->c);\r
+       const mreal *v=(const mreal *)t->v;\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
        for(long i=t->id;i<nn;i+=mglNumThr)\r
        {\r
-               register long k = long(n*(a[i]-v[0])/(v[1]-v[0]));\r
+               register long k = long(n*(a->vthr(i)-v[0])/(v[1]-v[0]));\r
                if(k>=0 && k<n)\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp critical(hist)\r
 #endif\r
-                       b[k] += c ? c[i]:1.;\r
+                       b[k] += c ? c->vthr(i):1.;\r
        }\r
        t->a = b;       return 0;\r
 }\r
@@ -784,10 +711,11 @@ MGL_NO_EXPORT void *mgl_hist_2(void *par)
 {\r
        mglThreadD *t=(mglThreadD *)par;\r
        long nn=t->n, n = t->p[0];\r
-       long ns=t->p[1], nx=t->p[2], ny=t->p[3], nz=t->p[4];\r
+       long ns=t->p[1], nx=t->p[2], ny=t->p[3];\r
        mreal *b=new mreal[n], d=1./ns;\r
        memset(b,0,n*sizeof(mreal));\r
-       const mreal *a=t->b, *c=t->c, *v=(const mreal *)t->v;\r
+       HCDT a = (HCDT)(t->b), c = (HCDT)(t->c);\r
+       const mreal *v=(const mreal *)t->v;\r
        bool sp = n>0;\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
@@ -795,8 +723,8 @@ MGL_NO_EXPORT void *mgl_hist_2(void *par)
        for(long i=t->id;i<nn;i+=mglNumThr)\r
        {\r
                register mreal x = d*(i%(nx*ns)), y = d*((i/(nx*ns))%(ny*ns)), z = d*(i/(nx*ny*ns*ns));\r
-               register mreal f = sp ? mglSpline3(a,nx,ny,nz,x,y,z) : mglLinear(a,nx,ny,nz,x,y,z), w=1;\r
-               if(c)   w = sp ? mglSpline3(c,nx,ny,nz,x,y,z) : mglLinear(c,nx,ny,nz,x,y,z);\r
+               register mreal f = sp ? mgl_data_spline(a,x,y,z) : mgl_data_linear(a,x,y,z), w=1;\r
+               if(c)   w = sp ? mgl_data_spline(c,x,y,z) : mgl_data_linear(c,x,y,z);\r
                if(mgl_isnan(f) || mgl_isnan(w))        continue;\r
                register long k = long(n*(f-v[0])/(v[1]-v[0]));\r
                if(k>=0 && k<n)\r
@@ -809,29 +737,26 @@ MGL_NO_EXPORT void *mgl_hist_2(void *par)
 }\r
 HMDT MGL_EXPORT mgl_data_hist(HCDT dat, long n, mreal v1, mreal v2, long nsub)\r
 {\r
-       const mglData *d = dynamic_cast<const mglData *>(dat);\r
-       if(n<2 || v1==v2 || !d) return 0;       // NOTE: For mglData only!\r
+       if(n<2 || v1==v2)       return 0;\r
        mglData *b=new mglData(n);\r
        mreal v[2]={v1,v2};\r
-       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+       long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz();\r
        long ns=abs(nsub)+1, p[5]={n,ns,nx,ny,nz};\r
-       if(nsub==0)     mglStartThread(mgl_hist_1,mgl_hist_p, nx*ny*nz, b->a,d->a,0,p,v);\r
-       else    mglStartThread(mgl_hist_2,mgl_hist_p, nx*ny*nz*ns*ns*ns, b->a,d->a,0,p,v);\r
+       if(nsub==0)     mglStartThread(mgl_hist_1,mgl_hist_p, nx*ny*nz, b->a,(const mreal *)dat,0,p,v);\r
+       else    mglStartThread(mgl_hist_2,mgl_hist_p, nx*ny*nz*ns*ns*ns, b->a,(const mreal *)dat,0,p,v);\r
        return b;\r
 }\r
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_data_hist_w(HCDT dat, HCDT weight, long n, mreal v1, mreal v2, long nsub)\r
 {\r
-       const mglData *d = dynamic_cast<const mglData *>(dat);\r
-       const mglData *w = dynamic_cast<const mglData *>(weight);\r
-       if(n<2 || v1==v2 || !d || !w)   return 0;       // NOTE: For mglData only!\r
+       if(n<2 || v1==v2)       return 0;\r
        mglData *b=new mglData(n);\r
        mreal v[2]={v1,v2};\r
 \r
-       long nx=d->nx, ny=d->ny, nz=d->nz;\r
+       long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz();\r
        long ns=abs(nsub)+1, p[5]={n,ns,nx,ny,nz};\r
-       if(nsub==0)     mglStartThread(mgl_hist_1,mgl_hist_p, nx*ny*nz, b->a,d->a,w->a,p,v);\r
-       else    mglStartThread(mgl_hist_2,mgl_hist_p, nx*ny*nz*ns*ns*ns, b->a,d->a,w->a,p,v);\r
+       if(nsub==0)     mglStartThread(mgl_hist_1,mgl_hist_p, nx*ny*nz, b->a,(const mreal *)dat,(const mreal *)weight,p,v);\r
+       else    mglStartThread(mgl_hist_2,mgl_hist_p, nx*ny*nz*ns*ns*ns, b->a,(const mreal *)dat,(const mreal *)weight,p,v);\r
        return b;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -841,7 +766,7 @@ uintptr_t MGL_EXPORT mgl_data_hist_w_(uintptr_t *d, uintptr_t *w, int *n, mreal
 {      return uintptr_t(mgl_data_hist_w(_DT_,_DA_(w),*n,*v1,*v2,*nsub));       }\r
 //-----------------------------------------------------------------------------\r
 long MGL_NO_EXPORT mgl_idx_var;\r
-int MGL_NO_EXPORT mgl_cmd_idx(const void *a, const void *b)\r
+int MGL_LOCAL_PURE mgl_cmd_idx(const void *a, const void *b)\r
 {\r
        mreal *aa = (mreal *)a, *bb = (mreal *)b;\r
        return (aa[mgl_idx_var]>bb[mgl_idx_var] ? 1:(aa[mgl_idx_var]<bb[mgl_idx_var]?-1:0) );\r
@@ -870,7 +795,7 @@ mreal MGL_EXPORT mgl_find_root(mreal (*func)(mreal x, void *par), mreal x0, void
        {\r
                x = x1-f1*(x1-x0)/(f1-f0);      f = func(x,par);\r
                if(fabs(f)<1e-7)        return x;\r
-/*             if(fabs(f-f1)>0.5*fmin(fabs(f),fabs(f1)))       // TODO switch to bisection if slow\r
+/*             if(fabs(f-f1)>0.5*mgl_min(fabs(f),fabs(f1)))    // TODO switch to bisection if slow\r
                {\r
                        x = (x1+x0)/2;  f = func(x,par);\r
                        if(fabs(f)<1e-7)        return x;\r
index fcdc558b8f225c1f352487c98310688c233d6596..faf12e77bce0ef89814f50cf227e4a27f8d2691d 100644 (file)
@@ -28,6 +28,9 @@
 #include "mgl2/thread.h"
 #include "mgl2/base.h"
 //-----------------------------------------------------------------------------
+mglData MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector<mglDataA*> &head);
+mglDataC MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector<mglDataA*> &head);
+//-----------------------------------------------------------------------------
 void MGL_EXPORT mgl_data_refill_gr(HMGL gr, HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, long sl, const char *opt)
 {
        if(!vdat)       return;
@@ -52,59 +55,21 @@ void MGL_EXPORT mgl_data_refill_gr_(uintptr_t *gr, uintptr_t *d, uintptr_t *xdat
 {      char *s=new char[l+1];  memcpy(s,opt,l);        s[l]=0;
        mgl_data_refill_gr(_GR_,_DT_,_DA_(xdat),_DA_(ydat),_DA_(zdat),_DA_(vdat),*sl,s);        delete []s;     }
 //-----------------------------------------------------------------------------
-MGL_NO_EXPORT void *mgl_fill_f(void *par)
-{
-       mglThreadD *t=(mglThreadD *)par;
-       const mglFormula *f = (const mglFormula *)(t->v);
-       long nx=t->p[0],ny=t->p[1];
-       mreal *b=t->a;
-       const mreal *v=t->b, *w=t->c, *x=t->d;
-#if !MGL_HAVE_PTHREAD
-#pragma omp parallel for
-#endif
-       for(long i0=t->id;i0<t->n;i0+=mglNumThr)
-       {
-               register long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);
-               b[i0] = f->Calc(x[0]+i*x[1], x[2]+j*x[3], x[4]+k*x[5], b[i0], v?v[i0]:0, w?w[i0]:0);
-       }
-       return 0;
-}
-MGL_NO_EXPORT void *mgl_fill_fgen(void *par)
-{
-       mglThreadV *t=(mglThreadV *)par;
-       const mglFormula *f = (const mglFormula *)(t->v);
-       long nx=t->p[0],ny=t->p[1];
-       mreal *b=t->a;
-       HCDT v=(HCDT)t->b, w=(HCDT)t->c;
-       const mreal *x=t->d;
-#if !MGL_HAVE_PTHREAD
-#pragma omp parallel for
-#endif
-       for(long i0=t->id;i0<t->n;i0+=mglNumThr)
-       {
-               register long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);
-               b[i0] = f->Calc(x[0]+i*x[1], x[2]+j*x[3], x[4]+k*x[5], b[i0], v?v->vthr(i0):0, w?w->vthr(i0):0);
-       }
-       return 0;
-}
 void MGL_EXPORT mgl_data_fill_eq(HMGL gr, HMDT d, const char *eq, HCDT vdat, HCDT wdat, const char *opt)
 {
-       const mglData *v = dynamic_cast<const mglData *>(vdat);
-       const mglData *w = dynamic_cast<const mglData *>(wdat);
-       long nn = d->nx*d->ny*d->nz, par[3]={d->nx,d->ny,d->nz};
-       if(vdat && vdat->GetNN()!=nn)   return;
-       if(wdat && wdat->GetNN()!=nn)   return;
+       if(vdat && vdat->GetNN()!=d->GetNN())   return; // incompatible dimesions
+       if(wdat && wdat->GetNN()!=d->GetNN())   return;
        gr->SaveState(opt);
-       mreal xx[6]={gr->Min.x,0, gr->Min.y,0, gr->Min.z,0};
-       if(d->nx>1)     xx[1] = (gr->Max.x-gr->Min.x)/(d->nx-1.);
-       if(d->ny>1)     xx[3] = (gr->Max.y-gr->Min.y)/(d->ny-1.);
-       if(d->nz>1)     xx[5] = (gr->Max.z-gr->Min.z)/(d->nz-1.);
-       mglFormula f(eq);
-       if(v && w)      mglStartThread(mgl_fill_f,0,nn,d->a,v->a,w->a,par,&f,xx);
-       else if(vdat && wdat)   mglStartThreadV(mgl_fill_fgen,nn,d->a,vdat,wdat,par,&f,xx);
-       else if(v)      mglStartThread(mgl_fill_f,0,nn,d->a,v->a,0,par,&f,xx);
-       else if(vdat)   mglStartThreadV(mgl_fill_fgen,nn,d->a,vdat,0,par,&f,xx);
-       else    mglStartThread(mgl_fill_f,0,nn,d->a,0,0,par,&f,xx);
+       std::wstring s = d->s;  d->s = L"u";
+       mglDataV x(d->nx,d->ny,d->nz, gr->Min.x,gr->Max.x,'x'); x.s=L"x";
+       mglDataV y(d->nx,d->ny,d->nz, gr->Min.y,gr->Max.y,'y'); y.s=L"y";
+       mglDataV z(d->nx,d->ny,d->nz, gr->Min.z,gr->Max.z,'z'); z.s=L"z";
+       mglDataV r(d->nx,d->ny,d->nz);  r.s=L"#$mgl";
+       mglData v(vdat), w(wdat);       v.s = L"v";     w.s = L"w";
+       std::vector<mglDataA*> list;
+       list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(&r);
+       list.push_back(d);      list.push_back(&v);     list.push_back(&w);
+       d->Set(mglFormulaCalc(eq,list));        d->s = s;
        gr->LoadState();
 }
 void MGL_EXPORT mgl_data_fill_eq_(uintptr_t *gr, uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w, const char *opt,int l,int lo)
@@ -112,62 +77,21 @@ void MGL_EXPORT mgl_data_fill_eq_(uintptr_t *gr, uintptr_t *d, const char *eq, u
        char *o=new char[lo+1]; memcpy(o,opt,lo);       o[lo]=0;
        mgl_data_fill_eq(_GR_,_DT_,s,_DA_(v),_DA_(w),o);        delete []o;     delete []s;     }
 //-----------------------------------------------------------------------------
-MGL_NO_EXPORT void *mgl_cfill_f(void *par)
-{
-       mglThreadC *t=(mglThreadC *)par;
-       const mglFormulaC *f = (const mglFormulaC *)(t->v);
-       long nx=t->p[0],ny=t->p[1];
-       dual *b=t->a;
-       const dual *v=t->b, *w=t->c, *x=t->d;
-#if !MGL_HAVE_PTHREAD
-#pragma omp parallel for
-#endif
-       for(long i0=t->id;i0<t->n;i0+=mglNumThr)
-       {
-               register long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);
-               b[i0] = f->Calc(x[0]+mreal(i)*x[1], x[2]+mreal(j)*x[3], x[4]+mreal(k)*x[5],
-                                               b[i0], v?v[i0]:dual(0,0), w?w[i0]:dual(0,0));
-       }
-       return 0;
-}
-MGL_NO_EXPORT void *mgl_cfill_fgen(void *par)
-{
-       mglThreadV *t=(mglThreadV *)par;
-       const mglFormulaC *f = (const mglFormulaC *)(t->v);
-       long nx=t->p[0],ny=t->p[1];
-       dual *b=t->aa;
-       HCDT v=(HCDT)t->b, w=(HCDT)t->c;
-       const mreal *x=t->d;
-#if !MGL_HAVE_PTHREAD
-#pragma omp parallel for
-#endif
-       for(long i0=t->id;i0<t->n;i0+=mglNumThr)
-       {
-               register long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);
-               b[i0] = f->Calc(x[0]+i*x[1], x[2]+j*x[3], x[4]+k*x[5],
-                                               b[i0], v?v->vthr(i0):0, w?w->vthr(i0):0);
-       }
-       return 0;
-}
 void MGL_EXPORT mgl_datac_fill_eq(HMGL gr, HADT d, const char *eq, HCDT vdat, HCDT wdat, const char *opt)
 {
-       const mglDataC *v = dynamic_cast<const mglDataC *>(vdat);
-       const mglDataC *w = dynamic_cast<const mglDataC *>(wdat);
-       long nn = d->nx*d->ny*d->nz, par[3]={d->nx,d->ny,d->nz};
-       if(v && v->nx*v->ny*v->nz!=nn)  return;
-       if(w && w->nx*w->ny*w->nz!=nn)  return;
+       if(vdat && vdat->GetNN()!=d->GetNN())   return; // incompatible dimesions
+       if(wdat && wdat->GetNN()!=d->GetNN())   return;
        gr->SaveState(opt);
-       mreal xx[6]={gr->Min.x,0, gr->Min.y,0, gr->Min.z,0};
-       if(d->nx>1)     xx[1] = (gr->Max.x-gr->Min.x)/(d->nx-1.);
-       if(d->ny>1)     xx[3] = (gr->Max.y-gr->Min.y)/(d->ny-1.);
-       if(d->nz>1)     xx[5] = (gr->Max.z-gr->Min.z)/(d->nz-1.);
-       dual cc[6]={xx[0],xx[1],xx[2],xx[3],xx[4],xx[5]};
-       mglFormulaC f(eq);
-       if(v && w)      mglStartThreadC(mgl_cfill_f,0,nn,d->a,v->a,w->a,par,&f,cc);
-       else if(vdat && wdat)   mglStartThreadV(mgl_cfill_fgen,nn,d->a,vdat,wdat,par,&f,xx);
-       else if(v)      mglStartThreadC(mgl_cfill_f,0,nn,d->a,v->a,0,par,&f,cc);
-       else if(vdat)   mglStartThreadV(mgl_cfill_fgen,nn,d->a,vdat,0,par,&f,xx);
-       else    mglStartThreadC(mgl_cfill_f,0,nn,d->a,0,0,par,&f,cc);
+       std::wstring s = d->s;  d->s = L"u";
+       mglDataV x(d->nx,d->ny,d->nz, gr->Min.x,gr->Max.x,'x'); x.s=L"x";
+       mglDataV y(d->nx,d->ny,d->nz, gr->Min.y,gr->Max.y,'y'); y.s=L"y";
+       mglDataV z(d->nx,d->ny,d->nz, gr->Min.z,gr->Max.z,'z'); z.s=L"z";
+       mglDataV r(d->nx,d->ny,d->nz);  r.s=L"#$mgl";
+       mglData v(vdat), w(wdat);       v.s = L"v";     w.s = L"w";
+       std::vector<mglDataA*> list;
+       list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(&r);
+       list.push_back(d);      list.push_back(&v);     list.push_back(&w);
+       d->Set(mglFormulaCalcC(eq,list));       d->s = s;
        gr->LoadState();
 }
 void MGL_EXPORT mgl_datac_fill_eq_(uintptr_t *gr, uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w, const char *opt,int l,int lo)
index 1ac3472466bff9bf55198c8fed2eb7dbcd44dab5..ff6b7b7c4bb25853112aa7ba9c7232740636bae4 100644 (file)
@@ -39,8 +39,8 @@
 #undef intf\r
 #endif\r
 \r
-//#define isn(ch)              ((ch)<' ' && (ch)!='\t')\r
-#define isn(ch)                ((ch)=='\n')\r
+inline bool isn(char ch)       {return ch=='\n';}\r
+mglData MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector<mglDataA*> &head);\r
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_create_data()      {       return new mglData;     }\r
 HMDT MGL_EXPORT mgl_create_data_size(long nx, long ny, long nz){       return new mglData(nx,ny,nz);   }\r
@@ -63,39 +63,41 @@ void mglFromStr(HMDT d,char *buf,long NX,long NY,long NZ)   // TODO: add multithre
        mgl_data_create(d, NX,NY,NZ);\r
        long nb = strlen(buf);\r
        register long i=0, j=0;\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        while(j<nb)\r
        {\r
-               while(buf[j]<=' ' && j<nb)      j++;\r
+               while(j<nb && buf[j]<=' ')      j++;\r
                while(buf[j]=='#')              // skip comment\r
                {\r
                        if(i>0 || buf[j+1]!='#')        // this is columns id\r
-                               while(!isn(buf[j]) && j<nb)     j++;\r
+                               while(j<nb && !isn(buf[j]))     j++;\r
                        else\r
                        {\r
-                               while(!isn(buf[j]) && j<nb)\r
+                               while(j<nb && !isn(buf[j]))\r
                                {\r
                                        if(buf[j]>='a' && buf[j]<='z')\r
                                                d->id.push_back(buf[j]);\r
                                        j++;\r
                                }\r
                        }\r
-                       while(buf[j]<=' ' && j<nb)      j++;\r
+                       while(j<nb && buf[j]<=' ')      j++;\r
                }\r
                char *s=buf+j;\r
-               while(buf[j]>' ' && buf[j]!=',' && buf[j]!=';' && j<nb) j++;\r
+               while(j<nb && buf[j]>' ' && buf[j]!=',' && buf[j]!=';') j++;\r
                buf[j]=0;\r
                d->a[i] = strstr(s,"NAN")?NAN:atof(s);\r
                i++;    if(i>=NX*NY*NZ) break;\r
        }\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_set(HMDT d, HCDT a)\r
 {\r
        if(!a)  return;\r
-       const mglData *dd = dynamic_cast<const mglData *>(a);   // faster for mglData\r
+//     d->temp = a->temp;      d->s = a->s;    d->func = a->func;      d->o = a->o;\r
+\r
        mgl_data_create(d, a->GetNx(), a->GetNy(), a->GetNz());\r
+       const mglData *dd = dynamic_cast<const mglData *>(a);   // faster for mglData\r
        if(dd)  // this one should be much faster\r
                memcpy(d->a, dd->a, d->nx*d->ny*d->nz*sizeof(mreal));\r
        else    // very inefficient!!!\r
@@ -253,37 +255,46 @@ void MGL_EXPORT mgl_data_set_id_(uintptr_t *d, const char *eq,int l)
 {      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
        mgl_data_set_id(_DT_, s);       delete []s;     }\r
 //-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_data_set_name_w(mglDataA *dat, const wchar_t *name)\r
+{      dat->s = name;  }\r
+void MGL_EXPORT mgl_data_set_name(mglDataA *dat, const char *name)\r
+{      MGL_TO_WCS(name,dat->s = wcs);  }\r
+void MGL_EXPORT mgl_data_set_name_(uintptr_t *d, const char *name,int l)\r
+{      char *s=new char[l+1];  memcpy(s,name,l);       s[l]=0;\r
+       mgl_data_set_name(_DT_,s);              delete []s;     }\r
+void MGL_EXPORT mgl_data_set_func(mglDataA *dat, void (*func)(void *), void *par)\r
+{      dat->func = func;       dat->o = par;   }\r
+//-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_save(HCDT d, const char *fname,long ns)\r
 {\r
        FILE *fp = fopen(fname,"w");\r
        if(!fp) return;\r
-       register long i,j,k;\r
        long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz();\r
-       setlocale(LC_NUMERIC, "C");\r
-       if(ns<0 || (ns>=nz && nz>1))    for(k=0;k<nz;k++)\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
+       if(ns<0 || (ns>=nz && nz>1))    for(long k=0;k<nz;k++)\r
        {       // save whole data\r
                const mglData *dr = dynamic_cast<const mglData *>(d);\r
                if(dr && !dr->id.empty())       fprintf(fp,"## %s\n",dr->id.c_str());\r
                const mglDataC *dc = dynamic_cast<const mglDataC *>(d);\r
                if(dc && !dc->id.empty())       fprintf(fp,"## %s\n",dc->id.c_str());\r
-               for(i=0;i<ny;i++)\r
+               for(long i=0;i<ny;i++)\r
                {\r
-                       for(j=0;j<nx-1;j++)     fprintf(fp,"%g\t",d->v(j,i,k));\r
+                       for(long j=0;j<nx-1;j++)        fprintf(fp,"%g\t",d->v(j,i,k));\r
                        fprintf(fp,"%g\n",d->v(nx-1,i,k));\r
                }\r
                fprintf(fp,"\n");\r
        }\r
        else\r
        {       // save selected slice\r
-               if(nz>1)        for(i=0;i<ny;i++)\r
+               if(nz>1)        for(long i=0;i<ny;i++)\r
                {\r
-                       for(j=0;j<nx-1;j++)     fprintf(fp,"%g\t",d->v(j,i,ns));\r
+                       for(long j=0;j<nx-1;j++)        fprintf(fp,"%g\t",d->v(j,i,ns));\r
                        fprintf(fp,"%g\n",d->v(nx-1,i,ns));\r
                }\r
-               else if(ns<ny)  for(j=0;j<nx;j++)\r
+               else if(ns<ny)  for(long j=0;j<nx;j++)\r
                        fprintf(fp,"%g\t",d->v(j,ns));\r
        }\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
        fclose(fp);\r
 }\r
 void MGL_EXPORT mgl_data_save_(uintptr_t *d, const char *fname,int *ns,int l)\r
@@ -403,24 +414,21 @@ int MGL_EXPORT mgl_data_read_mat(HMDT d, const char *fname, long dim)
        char *buf = mgl_read_gz(fp);\r
        long nb = strlen(buf);  gzclose(fp);\r
 \r
-       register long j=0,i,l;\r
-       while(j<nb)\r
-       {\r
-               if(buf[j]=='#') while(!isn(buf[j]))     j++;    // skip comment\r
-               while(buf[j]<=' ' && j<nb)      j++;\r
-               break;\r
-       }\r
+       long j=0;\r
+       if(buf[j]=='#') while(!isn(buf[j]))     j++;    // skip comment\r
+       while(j<nb && buf[j]<=' ')      j++;\r
        if(dim==1)\r
        {\r
                sscanf(buf+j,"%ld",&nx);\r
-               while(buf[j]!='\n' && j<nb)     j++;    j++;\r
+               while(j<nb && buf[j]!='\n')     j++;    j++;\r
 //             while(buf[j]>' ')       j++;\r
        }\r
        else if(dim==2)\r
        {\r
                sscanf(buf+j,"%ld%ld",&nx,&ny);\r
-               while(buf[j]!='\n' && j<nb)     j++;    j++;\r
-               char *b=buf+j, ch;\r
+               while(j<nb && buf[j]!='\n')     j++;    j++;\r
+               char *b=buf+j;\r
+               register long i,l;\r
                for(i=l=0;b[i];i++)\r
                {\r
                        while(b[i]=='#')        {       while(!isn(b[i]) && b[i])       i++;    }\r
@@ -433,7 +441,7 @@ int MGL_EXPORT mgl_data_read_mat(HMDT d, const char *fname, long dim)
                        for(i=l=0;b[i] && !isn(b[i]);i++)       // determine nx\r
                        {\r
                                while(b[i]=='#')        {       while(!isn(b[i]) && b[i])       i++;    }\r
-                               ch = b[i];\r
+                               char ch = b[i];\r
                                if(ch>' ' && !first)    first=true;\r
                                if(first && (ch==' ' || ch=='\t' || ch==',' || ch==';') && b[i+1]>' ') nx++;\r
                        }\r
@@ -442,7 +450,7 @@ int MGL_EXPORT mgl_data_read_mat(HMDT d, const char *fname, long dim)
        else if(dim==3)\r
        {\r
                sscanf(buf+j,"%ld%ld%ld",&nx,&ny,&nz);\r
-               while(buf[j]!='\n' && j<nb)     j++;    j++;\r
+               while(j<nb && buf[j]!='\n')     j++;    j++;\r
 /*             while(buf[j]>' ' && j<nb)       j++;\r
                while(buf[j]<=' ' && j<nb)      j++;\r
                while(buf[j]>' ' && j<nb)       j++;\r
@@ -460,18 +468,12 @@ mreal MGL_EXPORT mgl_data_max(HCDT d)
 {\r
        mreal m1=-INFINITY;\r
        long nn=d->GetNN();\r
-       const mglData *b = dynamic_cast<const mglData *>(d);\r
 #pragma omp parallel\r
        {\r
                register mreal m=-INFINITY, v;\r
-               if(b)\r
 #pragma omp for nowait\r
-                       for(long i=0;i<nn;i++)\r
-                       {       v = b->a[i];    m = m<v ? v:m;  }\r
-               else\r
-#pragma omp for nowait\r
-                       for(long i=0;i<nn;i++)\r
-                       {       v = d->vthr(i); m = m<v ? v:m;  }\r
+               for(long i=0;i<nn;i++)\r
+               {       v = d->vthr(i); m = m<v ? v:m;  }\r
 #pragma omp critical(max_dat)\r
                {       m1 = m1>m ? m1:m;       }\r
        }\r
@@ -483,18 +485,12 @@ mreal MGL_EXPORT mgl_data_min(HCDT d)
 {\r
        mreal m1=INFINITY;\r
        long nn=d->GetNN();\r
-       const mglData *b = dynamic_cast<const mglData *>(d);\r
 #pragma omp parallel\r
        {\r
                register mreal m=INFINITY, v;\r
-               if(b)\r
-#pragma omp for nowait\r
-                       for(long i=0;i<nn;i++)\r
-                       {       v = b->a[i];    m = m>v ? v:m;  }\r
-               else\r
 #pragma omp for nowait\r
-                       for(long i=0;i<nn;i++)\r
-                       {       v = d->vthr(i); m = m>v ? v:m;  }\r
+               for(long i=0;i<nn;i++)\r
+               {       v = d->vthr(i); m = m>v ? v:m;  }\r
 #pragma omp critical(min_dat)\r
                {       m1 = m1<m ? m1:m;       }\r
        }\r
@@ -506,19 +502,13 @@ mreal MGL_EXPORT mgl_data_neg_max(HCDT d)
 {\r
        mreal m1=0;\r
        long nn=d->GetNN();\r
-       const mglData *b = dynamic_cast<const mglData *>(d);\r
 #pragma omp parallel\r
        {\r
                register mreal m=0, v;\r
-               if(b)\r
 #pragma omp for nowait\r
-                       for(long i=0;i<nn;i++)\r
-                       {       v = b->a[i];    m = m<v && v<0 ? v:m;   }\r
-               else\r
-#pragma omp for nowait\r
-                       for(long i=0;i<nn;i++)\r
-                       {       v = d->vthr(i); m = m<v && v<0 ? v:m;   }\r
-#pragma omp critical(max_dat)\r
+               for(long i=0;i<nn;i++)\r
+               {       v = d->vthr(i); m = m<v && v<0 ? v:m;   }\r
+#pragma omp critical(nmax_dat)\r
                {       m1 = m1>m ? m1:m;       }\r
        }\r
        return m1;\r
@@ -529,19 +519,13 @@ mreal MGL_EXPORT mgl_data_pos_min(HCDT d)
 {\r
        mreal m1=INFINITY;\r
        long nn=d->GetNN();\r
-       const mglData *b = dynamic_cast<const mglData *>(d);\r
 #pragma omp parallel\r
        {\r
                register mreal m=INFINITY, v;\r
-               if(b)\r
-#pragma omp for nowait\r
-                       for(long i=0;i<nn;i++)\r
-                       {       v = b->a[i];    m = m>v && v>0 ? v:m;   }\r
-               else\r
 #pragma omp for nowait\r
-                       for(long i=0;i<nn;i++)\r
-                       {       v = d->vthr(i); m = m>v && v>0 ? v:m;   }\r
-#pragma omp critical(min_dat)\r
+               for(long i=0;i<nn;i++)\r
+               {       v = d->vthr(i); m = m>v && v>0 ? v:m;   }\r
+#pragma omp critical(pmin_dat)\r
                {       m1 = m1<m ? m1:m;       }\r
        }\r
        return m1;\r
@@ -664,39 +648,35 @@ mreal MGL_EXPORT mgl_data_min_real(HCDT d, mreal *x, mreal *y, mreal *z)
 mreal MGL_EXPORT mgl_data_min_real_(uintptr_t *d, mreal *x, mreal *y, mreal *z)\r
 {      return mgl_data_min_real(_DT_,x,y,z);   }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_fill_x(void *par)\r
-{\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       long nx=t->p[0],ny=t->p[1];\r
-       mreal *b=t->a, x1=t->b[0], dx=t->b[1];\r
-       register char dir = t->s[0];\r
-       if(dir=='x')\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-               for(long i0=t->id;i0<t->n;i0+=mglNumThr)        b[i0] = x1+dx*(i0%nx);\r
-       else if(dir=='y')\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-               for(long i0=t->id;i0<t->n;i0+=mglNumThr)        b[i0] = x1+dx*((i0/nx)%ny);\r
-       else if(dir=='z')\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-               for(long i0=t->id;i0<t->n;i0+=mglNumThr)        b[i0] = x1+dx*(i0/(nx*ny));\r
-       return 0;\r
-}\r
 void MGL_EXPORT mgl_data_fill(HMDT d, mreal x1,mreal x2,char dir)\r
 {\r
        if(mgl_isnan(x2))       x2=x1;\r
        if(dir<'x' || dir>'z')  dir='x';\r
-       long par[2]={d->nx,d->ny};\r
-       mreal b[2]={x1,x2-x1};\r
-       if(dir=='x')    b[1] *= d->nx>1 ? 1./(d->nx-1):0;\r
-       if(dir=='y')    b[1] *= d->ny>1 ? 1./(d->ny-1):0;\r
-       if(dir=='z')    b[1] *= d->nz>1 ? 1./(d->nz-1):0;\r
-       mglStartThread(mgl_fill_x,0,d->nx*d->ny*d->nz,d->a,b,0,par,0,0,0,&dir);\r
+       long nx=d->nx,ny=d->ny,nz=d->nz;\r
+       if(dir=='x')\r
+       {\r
+               mreal dx = d->nx>1 ? (x2-x1)/(d->nx-1):0;\r
+#pragma omp parallel for collapse(2)\r
+               for(long j=0;j<ny*nz;j++)       for(long i=1;i<nx;i++)  d->a[i+nx*j] = x1+dx*i;\r
+#pragma omp parallel for\r
+               for(long j=0;j<ny*nz;j++)       d->a[nx*j] = x1;\r
+       }\r
+       if(dir=='y')\r
+       {\r
+               mreal dx = d->ny>1 ? (x2-x1)/(d->ny-1):0;\r
+#pragma omp parallel for collapse(3)\r
+               for(long k=0;k<nz;k++)  for(long j=1;j<ny;j++)  for(long i=0;i<nx;i++)  d->a[i+nx*(j+ny*k)] = x1+dx*j;\r
+#pragma omp parallel for collapse(2)\r
+               for(long j=0;j<nz;j++)  for(long i=0;i<nx;i++)  d->a[i+nx*ny*j] = x1;\r
+       }\r
+       if(dir=='z')\r
+       {\r
+               mreal dx = d->nz>1 ? (x2-x1)/(d->nz-1):0;\r
+#pragma omp parallel for collapse(2)\r
+               for(long j=1;j<nz;j++)  for(long i=0;i<nx*ny;i++)       d->a[i+nx*ny*j] = x1+dx*j;\r
+#pragma omp parallel for\r
+               for(long j=0;j<nx*ny;j++)       d->a[j] = x1;\r
+       }\r
 }\r
 void MGL_EXPORT mgl_data_fill_(uintptr_t *d, mreal *x1,mreal *x2,const char *dir,int)\r
 {      mgl_data_fill(_DT_,*x1,*x2,*dir);       }\r
@@ -869,15 +849,16 @@ MGL_NO_EXPORT void *mgl_modify(void *par)
 void MGL_EXPORT mgl_data_modify(HMDT d, const char *eq,long dim)\r
 {\r
        long nx=d->nx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz};\r
-       mglFormula f(eq);\r
-       if(dim<0)       dim=0;\r
-       if(nz>1)        // 3D array\r
+       if(dim<=0)      mgl_data_modify_vw(d,eq,0,0);   // fastes variant for whole array\r
+       else if(nz>1)   // 3D array\r
        {\r
+               mglFormula f(eq);\r
                par[2] -= dim;  if(par[2]<0)    par[2]=0;\r
                mglStartThread(mgl_modify,0,nx*ny*par[2],d->a+nx*ny*dim,0,0,par,&f);\r
        }\r
        else            // 2D or 1D array\r
        {\r
+               mglFormula f(eq);\r
                par[1] -= dim;  if(par[1]<0)    par[1]=0;\r
                mglStartThread(mgl_modify,0,nx*par[1],d->a+nx*dim,0,0,par,&f);\r
        }\r
@@ -886,37 +867,18 @@ void MGL_EXPORT mgl_data_modify_(uintptr_t *d, const char *eq,int *dim,int l)
 {      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
        mgl_data_modify(_DT_,s,*dim);   delete []s;     }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT void *mgl_modify_gen(void *par)\r
-{\r
-       mglThreadV *t=(mglThreadV *)par;\r
-       const mglFormula *f = (const mglFormula *)(t->v);\r
-       register long nx=t->p[0],ny=t->p[1],nz=t->p[2];\r
-       mreal *b=t->a, dx,dy,dz;\r
-       HCDT v=(HCDT)t->b, w=(HCDT)t->c;\r
-       dx=nx>1?1/(nx-1.):0;    dy=ny>1?1/(ny-1.):0;    dz=nz>1?1/(nz-1.):0;\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i0=t->id;i0<t->n;i0+=mglNumThr)\r
-       {\r
-               register long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);\r
-               b[i0] = f->Calc(i*dx, j*dy, k*dz, b[i0], v?v->vthr(i0):0, w?w->vthr(i0):0);\r
-       }\r
-       return 0;\r
-}\r
 void MGL_EXPORT mgl_data_modify_vw(HMDT d, const char *eq,HCDT vdat,HCDT wdat)\r
 {\r
-       const mglData *v = dynamic_cast<const mglData *>(vdat);\r
-       const mglData *w = dynamic_cast<const mglData *>(wdat);\r
-       long nn = d->nx*d->ny*d->nz, par[3]={d->nx,d->ny,d->nz};\r
-       if(vdat && vdat->GetNN()!=nn)   return;\r
-       if(wdat && wdat->GetNN()!=nn)   return;\r
-       mglFormula f(eq);\r
-       if(v && w)      mglStartThread(mgl_modify,0,nn,d->a,v->a,w->a,par,&f);\r
-       else if(vdat && wdat)   mglStartThreadV(mgl_modify_gen,nn,d->a,vdat,wdat,par,&f);\r
-       else if(v)      mglStartThread(mgl_modify,0,nn,d->a,v->a,0,par,&f);\r
-       else if(vdat)   mglStartThreadV(mgl_modify_gen,nn,d->a,vdat,0,par,&f);\r
-       else    mglStartThread(mgl_modify,0,nn,d->a,0,0,par,&f);\r
+       std::wstring s = d->s;  d->s = L"u";\r
+       mglDataV x(d->nx,d->ny,d->nz, 0,1,'x'); x.s=L"x";\r
+       mglDataV y(d->nx,d->ny,d->nz, 0,1,'y'); y.s=L"y";\r
+       mglDataV z(d->nx,d->ny,d->nz, 0,1,'z'); z.s=L"z";\r
+       mglDataV r(d->nx,d->ny,d->nz);  r.s=L"#$mgl";\r
+       mglData v(vdat), w(wdat);       v.s = L"v";     w.s = L"w";\r
+       std::vector<mglDataA*> list;\r
+       list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(d);\r
+       list.push_back(&v);     list.push_back(&w);     list.push_back(&r);\r
+       d->Set(mglFormulaCalc(eq,list));        d->s = s;\r
 }\r
 void MGL_EXPORT mgl_data_modify_vw_(uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w,int l)\r
 {      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
@@ -968,7 +930,7 @@ int MGL_EXPORT mgl_data_read_hdf4(HMDT ,const char *,const char *)
 #if MGL_HAVE_HDF5\r
 void MGL_EXPORT mgl_data_save_hdf(HCDT dat,const char *fname,const char *data,int rewrite)\r
 {\r
-       const mglData *d = dynamic_cast<const mglData *>(dat);  // NOTE: only for mglData\r
+       const mglData *d = dynamic_cast<const mglData *>(dat);  // NOTE: slow for non-mglData\r
        if(!d)  {       mglData d(dat); mgl_data_save_hdf(&d,fname,data,rewrite);       return; }\r
        hid_t hf,hd,hs;\r
        hsize_t dims[3];\r
@@ -1063,6 +1025,9 @@ void MGL_EXPORT mgl_data_save_hdf_(uintptr_t *d, const char *fname, const char *
 {      char *s=new char[l+1];          memcpy(s,fname,l);      s[l]=0;\r
        char *t=new char[n+1];          memcpy(t,data,n);       t[n]=0;\r
        mgl_data_save_hdf(_DT_,s,t,*rewrite);   delete []s;     delete []t;     }\r
+int MGL_EXPORT mgl_datas_hdf_(const char *fname, char *buf, int l, int size)\r
+{      char *s=new char[l+1];          memcpy(s,fname,l);      s[l]=0;\r
+       int r = mgl_datas_hdf(s,buf,size);      delete []s;     return r;       }\r
 //-----------------------------------------------------------------------------\r
 bool MGL_EXPORT mgl_add_file(long &kx,long &ky, long &kz, mreal *&b, mglData *d,bool as_slice)\r
 {\r
@@ -1171,3 +1136,33 @@ int MGL_EXPORT mgl_data_read_all_(uintptr_t *d, const char *fname, int *as_slice
 {      char *s=new char[l+1];          memcpy(s,fname,l);      s[l]=0;\r
        int r = mgl_data_read_all(_DT_,s,*as_slice);    delete []s;     return r;       }\r
 //-----------------------------------------------------------------------------\r
+HMDT MGL_EXPORT mgl_data_column(HCDT dat, const char *eq)\r
+{\r
+       const mglData *dd=dynamic_cast<const mglData *>(dat);\r
+       std::vector<mglDataA*> list;\r
+       if(dd && dd->id.length()>0)     for(size_t i=0;i<dd->id.length();i++)\r
+       {\r
+               mglDataT *col = new mglDataT(*dat);\r
+               col->SetInd(i,dd->id[i]);\r
+               list.push_back(col);\r
+       }\r
+       const mglDataC *dc=dynamic_cast<const mglDataC *>(dat);\r
+       if(dc && dc->id.length()>0)     for(size_t i=0;i<dc->id.length();i++)\r
+       {\r
+               mglDataT *col = new mglDataT(*dat);\r
+               col->SetInd(i,dc->id[i]);\r
+               list.push_back(col);\r
+       }\r
+       if(list.size()==0)      return 0;       // no named columns\r
+       mglDataV *t = new mglDataV(dat->GetNy(),dat->GetNz());\r
+       t->s=L"#$mgl";  list.push_back(t);\r
+       mglData *r = new mglData;\r
+       r->Set(mglFormulaCalc(eq,list));\r
+       for(size_t i=0;i<list.size();i++)       delete list[i];\r
+       return r;\r
+}\r
+uintptr_t MGL_EXPORT mgl_data_column_(uintptr_t *d, const char *eq,int l)\r
+{      char *s=new char[l+1];  memcpy(s,eq,l); s[l]=0;\r
+       uintptr_t r = uintptr_t(mgl_data_column(_DT_,s));\r
+       delete []s;     return r;       }\r
+//-----------------------------------------------------------------------------\r
index 1f907f6a9f9bbb5a99717ba9444a281d722ca38a..e6710fdebc552a0928fecf63097cbc0e921e5498 100644 (file)
 #if MGL_HAVE_PNG\r
 #include <png.h>\r
 #endif\r
+#if MGL_HAVE_JPEG\r
+#include <jpeglib.h>\r
+#endif\r
 //-----------------------------------------------------------------------------\r
-size_t MGL_NO_EXPORT mgl_col_dif(unsigned char *c1,unsigned char *c2,bool sum)\r
+size_t MGL_LOCAL_PURE mgl_col_dif(unsigned char *c1,unsigned char *c2,bool sum)\r
 {\r
        size_t res,d1=abs(long(c1[0])-long(c2[0])),\r
                d2=abs(long(c1[1])-long(c2[1])),d3=abs(long(c1[2])-long(c2[2]));\r
@@ -45,10 +48,10 @@ MGL_NO_EXPORT unsigned char *mgl_create_scheme(const char *scheme,long &num)
        if(np<2)        {       delete []cc;    return 0;       }\r
        for(size_t i=0;i<np-1;i++)      nc+=mgl_col_dif(cc+3*i,cc+3*i+3,false);\r
        c = new unsigned char[3*nc+3];\r
-       size_t dd,pos=0;\r
+       size_t pos=0;\r
        for(size_t i=0;i<np-1;i++)\r
        {\r
-               dd=mgl_col_dif(cc+3*i,cc+3*i+3,false);\r
+               size_t dd=mgl_col_dif(cc+3*i,cc+3*i+3,false);\r
                for(size_t j=0;j<dd;j++)\r
                {\r
                        c1 = c+3*(pos+j);       c2 = cc+3*i;\r
@@ -64,6 +67,96 @@ MGL_NO_EXPORT unsigned char *mgl_create_scheme(const char *scheme,long &num)
        return c;\r
 }\r
 //-----------------------------------------------------------------------------\r
+bool MGL_NO_EXPORT mgl_read_image(unsigned char *g, int w, int h, const char *fname)\r
+{\r
+       const char *ext = fname+strlen(fname)-1;        // rindex(fname,'.');\r
+       while(*ext!='.' && ext!=fname)  ext--;\r
+       if(!strcmp(ext,".png"))\r
+       {\r
+#if MGL_HAVE_PNG\r
+               FILE *fp = fopen(fname, "rb");\r
+               if(!fp) return false;\r
+               png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);\r
+               if (!png_ptr)   {       fclose(fp);     return false;   }\r
+               png_infop info_ptr = png_create_info_struct(png_ptr);\r
+               if (!info_ptr)\r
+               {       png_destroy_read_struct(&png_ptr,0,0);  fclose(fp);     return false;   }\r
+               png_infop end_info = png_create_info_struct(png_ptr);\r
+               if (!end_info)\r
+               {       png_destroy_read_struct(&png_ptr,&info_ptr,0);  fclose(fp);     return false;   }\r
+\r
+               png_init_io(png_ptr, fp);\r
+               png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING|PNG_TRANSFORM_STRIP_16|PNG_TRANSFORM_EXPAND,0);\r
+               unsigned char **rows = png_get_rows(png_ptr, info_ptr);\r
+\r
+               long wi=png_get_image_width(png_ptr, info_ptr);\r
+               long hi=png_get_image_height(png_ptr, info_ptr);\r
+               int type = png_get_color_type(png_ptr, info_ptr);\r
+               if(w<wi)        wi=w;\r
+               if(h>hi)        h=hi;\r
+               if(type==PNG_COLOR_TYPE_RGB_ALPHA)\r
+#pragma omp parallel for\r
+                       for(long i=0;i<h;i++)   memcpy(g+4*w*i,rows[i],4*wi);\r
+               else if(type==PNG_COLOR_TYPE_RGB)\r
+#pragma omp parallel for collapse(2)\r
+                       for(long i=0;i<h;i++)   for(long j=0;j<wi;j++)\r
+                               memcpy(g+4*(w*i+j),rows[i]+3*j,3);\r
+               else if(type==PNG_COLOR_TYPE_GRAY)\r
+#pragma omp parallel for collapse(2)\r
+                       for(long i=0;i<h;i++)   for(long j=0;j<wi;j++)\r
+                               g[4*(w*i+j)] = g[4*(w*i+j)+1] = g[4*(w*i+j)+2] = rows[i][j];\r
+               else if(type==PNG_COLOR_TYPE_GRAY_ALPHA)\r
+#pragma omp parallel for collapse(2)\r
+                       for(long i=0;i<h;i++)   for(long j=0;j<wi;j++)\r
+                       {\r
+                               g[4*(w*i+j)] = g[4*(w*i+j)+1] = g[4*(w*i+j)+2] = rows[i][2*j];\r
+                               g[4*(w*i+j)+3] = rows[i][2*j+1];\r
+                       }\r
+               png_destroy_read_struct(&png_ptr, &info_ptr,&end_info);\r
+               fclose(fp);\r
+#else\r
+               mglGlobalMess += "PNG support was disabled. Please, enable it and rebuild MathGL.\n";\r
+#endif\r
+       }\r
+       else if(!strcmp(ext,".jpg") || !strcmp(ext,".jpeg"))\r
+       {\r
+#if MGL_HAVE_JPEG\r
+               FILE *fp = fopen(fname, "rb");\r
+               if(!fp) return false;\r
+\r
+               jpeg_decompress_struct info;\r
+               jpeg_error_mgr err;\r
+               info.err = jpeg_std_error(&err);\r
+               jpeg_create_decompress(&info);\r
+\r
+               jpeg_stdio_src(&info, fp);\r
+               jpeg_read_header(&info, TRUE);  // read jpeg file header\r
+               jpeg_start_decompress(&info);   // decompress the file\r
+\r
+               long wi = info.output_width;    //set width and height\r
+               long hi = info.output_height;\r
+               int channels = info.num_components;     // == 4 for RGBA else for RGB\r
+               unsigned char *buf = new unsigned char[(channels==4?4:3)*wi];\r
+               if(hi>h)        hi = h;\r
+               if(wi>w)        wi = w;\r
+               for(long i=0;i<hi;i++)\r
+               {\r
+                       jpeg_read_scanlines(&info, &buf, 1);\r
+                       if(channels==4)\r
+                               memcpy(g+4*i*w,buf,4*wi);\r
+                       else\r
+#pragma omp parallel for\r
+                               for(long j=0;j<wi;j++)\r
+                                       memcpy(g+4*i*w+4*j,buf+3*j,3);\r
+               }\r
+               delete []buf;\r
+#else\r
+               mglGlobalMess += "JPEG support was disabled. Please, enable it and rebuild MathGL.\n";\r
+#endif\r
+       }\r
+       return true;\r
+}\r
+//-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_import(HMDT d, const char *fname, const char *scheme,mreal v1,mreal v2)\r
 {\r
 #if MGL_HAVE_PNG\r
@@ -94,10 +187,10 @@ void MGL_EXPORT mgl_data_import(HMDT d, const char *fname, const char *scheme,mr
 #pragma omp parallel for collapse(2)\r
                for(long i=0;i<d->ny;i++)       for(long j=0;j<d->nx;j++)\r
                {\r
-                       size_t pos=0,val,mval=256;\r
+                       size_t pos=0,mval=256;\r
                        for(long k=0;k<num;k++)\r
                        {\r
-                               val = mgl_col_dif(c+3*k,rows[d->ny-i-1]+3*j,true);\r
+                               size_t val = mgl_col_dif(c+3*k,rows[d->ny-i-1]+3*j,true);\r
                                if(val==0)      {       pos=k;  break;  }\r
                                if(val<mval)    {       pos=k;  mval=val;       }\r
                        }\r
@@ -115,20 +208,13 @@ void MGL_EXPORT mgl_data_export(HCDT dd, const char *fname, const char *scheme,m
 {\r
 #if MGL_HAVE_PNG\r
        long nx=dd->GetNx(), ny=dd->GetNy(), nz=dd->GetNz();\r
-       const mglData *md = dynamic_cast<const mglData *>(dd);\r
        if(v1>v2)       return;\r
        if(ns<0 || ns>=nz)      ns=0;\r
        if(v1==v2)\r
        {\r
                v1 = INFINITY;  v2=-INFINITY;\r
-               if(md)\r
-//#pragma omp parallel for     // NOTE comparison here\r
-                       for(long i=0;i<nx*ny*nz;i++)\r
-                       {       register mreal vv = md->a[i];   if(vv<v1)       v1=vv;  if(vv>v2)       v2=vv;  }\r
-               else\r
-//#pragma omp parallel for     // NOTE comparison here\r
-                       for(long i=0;i<nx*ny*nz;i++)\r
-                       {       register mreal vv = dd->vthr(i);        if(vv<v1)       v1=vv;  if(vv>v2)       v2=vv;  }\r
+               for(long i=0;i<nx*ny*nz;i++)\r
+               {       register mreal vv = dd->vthr(i);        if(vv<v1)       v1=vv;  if(vv>v2)       v2=vv;  }\r
        }\r
        if(v1==v2)      return;\r
        long num=0;\r
@@ -139,23 +225,13 @@ void MGL_EXPORT mgl_data_export(HCDT dd, const char *fname, const char *scheme,m
        unsigned char *d = new unsigned char[3*nx*ny];\r
 #pragma omp parallel for\r
        for(long i=0;i<ny;i++)  p[i] = d+3*nx*(ny-1-i);\r
-       if(md)\r
-#pragma omp parallel for collapse(2)\r
-               for(long i=0;i<ny;i++)  for(long j=0;j<nx;j++)\r
-               {\r
-                       register mreal vv = md->a[j+nx*(i+ny*ns)];\r
-                       register long k = long(num*(vv-v1)/(v2-v1));\r
-                       if(k<0) k=0;    if(k>=num) k=num-1;\r
-                       memcpy(d+3*(j+i*nx),c+3*k,3);\r
-               }\r
-       else\r
 #pragma omp parallel for collapse(2)\r
-               for(long i=0;i<ny;i++)  for(long j=0;j<nx;j++)\r
-               {\r
-                       register long k = long(num*(dd->v(j,i,ns)-v1)/(v2-v1));\r
-                       if(k<0) k=0;    if(k>=num) k=num-1;\r
-                       memcpy(d+3*(j+i*nx),c+3*k,3);\r
-               }\r
+       for(long i=0;i<ny;i++)  for(long j=0;j<nx;j++)\r
+       {\r
+               register long k = long(num*(dd->v(j,i,ns)-v1)/(v2-v1));\r
+               if(k<0) k=0;    if(k>=num) k=num-1;\r
+               memcpy(d+3*(j+i*nx),c+3*k,3);\r
+       }\r
        delete []c;\r
 \r
        FILE *fp = fopen(fname, "wb");\r
index ee3ee8ba51db8ab4f8f6065597f13e1741b6b2e5..6da9744734f979cda4cda9cf4fb4c00042da945e 100644 (file)
@@ -27,6 +27,7 @@
 #include <gsl/gsl_sf.h>\r
 #include <gsl/gsl_rng.h>\r
 #include <gsl/gsl_errno.h>\r
+#include <sys/stat.h>\r
 #endif\r
 //-----------------------------------------------------------------------------\r
 //     constants for expression parsing\r
@@ -59,6 +60,7 @@ EQ_ELE,               // elliptic integral E(\phi,k) = \int_0^\phi dt   \sqrt((1 - k^2 \sin^2
 EQ_ELF,                // elliptic integral F(\phi,k) = \int_0^\phi dt 1/\sqrt((1 - k^2 \sin^2(t)))\r
 EQ_LP,         // Legendre polynomial P_l(x), (|x|<=1, l>=0)\r
 EQ_BETA,       // beta function B(x,y) = Gamma(x)*Gamma(y)/Gamma(x+y)\r
+EQ_GAMMA_INC,  // incomplete gamma function Gamma(a,x) = \int_x^\infty dt t^{a-1} \exp(-t) for x>=0.\r
 // normal functions of 1 argument\r
 EQ_SIN,                // sine function \sin(x).                       !!! MUST BE FIRST 1-PLACE FUNCTION\r
 EQ_COS,                // cosine function \cos(x).\r
@@ -127,8 +129,8 @@ EQ_CL               // Clausen function
 #endif\r
 //-----------------------------------------------------------------------------\r
 int mglFormula::Error=0;\r
-bool mglCheck(char *str,int n);\r
-int mglFindInText(char *str,const char *lst);\r
+bool MGL_LOCAL_PURE mglCheck(char *str,int n);\r
+int MGL_LOCAL_PURE mglFindInText(char *str,const char *lst);\r
 //-----------------------------------------------------------------------------\r
 #if MGL_HAVE_GSL\r
 MGL_NO_EXPORT gsl_rng *mgl_rng=0;      // NOTE: should be deleted by gsl_rng_free() but I don't know where :(\r
@@ -148,7 +150,7 @@ void MGL_EXPORT mgl_srnd(long seed)
 }\r
 void MGL_EXPORT mgl_srnd_(int *seed)   {       mgl_srnd(*seed);        }\r
 //-----------------------------------------------------------------------------\r
-double MGL_EXPORT mgl_hypot(double x, double y)        {       return hypot(x,y);      }\r
+double MGL_EXPORT_CONST mgl_hypot(double x, double y)  {       return hypot(x,y);      }\r
 //-----------------------------------------------------------------------------\r
 #if MGL_HAVE_PTHREAD\r
 pthread_mutex_t mutexRnd;\r
@@ -266,6 +268,7 @@ mglFormula::mglFormula(const char *string)
                {       Kod=EQ_A;       Res = str[0]-'a';       }\r
                else if(!strcmp(str,"rnd")) Kod=EQ_RND;\r
                else if(!strcmp(str,"pi")) Res=M_PI;\r
+               else if(!strcmp(str,"inf")) Res=INFINITY;\r
                else Res=atof(str);                             // this is number\r
        }\r
        else\r
@@ -376,6 +379,7 @@ mglFormula::mglFormula(const char *string)
                else if(!strcmp(name,"y"))              Kod=EQ_BESY;\r
                else if(!strcmp(name,"f"))              Kod=EQ_ELF;\r
                else if(!strcmp(name,"gamma"))  Kod=EQ_GAMMA;\r
+               else if(!strcmp(name,"gamma_inc"))      Kod=EQ_GAMMA_INC;\r
                else if(!strcmp(name,"ns"))             Kod=EQ_NS;\r
                else if(!strcmp(name,"nc"))             Kod=EQ_NC;\r
                else if(!strcmp(name,"nd"))             Kod=EQ_ND;\r
@@ -463,74 +467,75 @@ mreal mglFormula::CalcD(const mreal var[MGL_VS], char diff) const
        return CalcDIn(diff-'a', var);\r
 }\r
 //-----------------------------------------------------------------------------\r
-double MGL_NO_EXPORT cand(double a,double b)   {return a&&b?1:0;}\r
-double MGL_NO_EXPORT cor(double a,double b)    {return a||b?1:0;}\r
-double MGL_NO_EXPORT ceq(double a,double b)    {return a==b?1:0;}\r
-double MGL_NO_EXPORT clt(double a,double b)    {return a<b?1:0;}\r
-double MGL_NO_EXPORT cgt(double a,double b)    {return a>b?1:0;}\r
-double MGL_NO_EXPORT add(double a,double b)    {return a+b;}\r
-double MGL_NO_EXPORT sub(double a,double b)    {return a-b;}\r
-double MGL_NO_EXPORT mul(double a,double b)    {return a&&b?a*b:0;}\r
-double MGL_NO_EXPORT del(double a,double b)    {return b?a/b:NAN;}\r
-double MGL_NO_EXPORT ipw(double a,double b)    {return fabs(b-int(b))<1e-5 ? mgl_ipow(a,int(b)) : pow(a,b);}\r
-double MGL_NO_EXPORT llg(double a,double b)    {return log(a)/log(b);}\r
+double MGL_LOCAL_CONST cand(double a,double b) {return a&&b?1:0;}\r
+double MGL_LOCAL_CONST cor(double a,double b)  {return a||b?1:0;}\r
+double MGL_LOCAL_CONST ceq(double a,double b)  {return a==b?1:0;}\r
+double MGL_LOCAL_CONST clt(double a,double b)  {return a<b?1:0;}\r
+double MGL_LOCAL_CONST cgt(double a,double b)  {return a>b?1:0;}\r
+double MGL_LOCAL_CONST add(double a,double b)  {return a+b;}\r
+double MGL_LOCAL_CONST sub(double a,double b)  {return a-b;}\r
+double MGL_LOCAL_CONST mul(double a,double b)  {return a&&b?a*b:0;}\r
+double MGL_LOCAL_CONST del(double a,double b)  {return b?a/b:NAN;}\r
+double MGL_LOCAL_CONST ipw(double a,double b)  {return fabs(b-int(b))<1e-5 ? mgl_ipow(a,int(b)) : pow(a,b);}\r
+double MGL_LOCAL_CONST llg(double a,double b)  {return log(a)/log(b);}\r
 #if MGL_HAVE_GSL\r
-double MGL_NO_EXPORT gslEllE(double a,double b)        {return gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE);}\r
-double MGL_NO_EXPORT gslEllF(double a,double b)        {return gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE);}\r
-double MGL_NO_EXPORT gslLegP(double a,double b)        {return gsl_sf_legendre_Pl(int(a),b);}\r
-double MGL_NO_EXPORT gslEllEc(double a)        {return gsl_sf_ellint_Ecomp(a,GSL_PREC_SINGLE);}\r
-double MGL_NO_EXPORT gslEllFc(double a)        {return gsl_sf_ellint_Kcomp(a,GSL_PREC_SINGLE);}\r
-double MGL_NO_EXPORT gslAi(double a)   {return gsl_sf_airy_Ai(a,GSL_PREC_SINGLE);}\r
-double MGL_NO_EXPORT gslBi(double a)   {return gsl_sf_airy_Bi(a,GSL_PREC_SINGLE);}\r
-double MGL_NO_EXPORT gslAi_d(double a) {return gsl_sf_airy_Ai_deriv(a,GSL_PREC_SINGLE);}\r
-double MGL_NO_EXPORT gslBi_d(double a) {return gsl_sf_airy_Bi_deriv(a,GSL_PREC_SINGLE);}\r
+double MGL_LOCAL_CONST gslEllE(double a,double b)      {return gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE);}\r
+double MGL_LOCAL_CONST gslEllF(double a,double b)      {return gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE);}\r
+double MGL_LOCAL_CONST gslLegP(double a,double b)      {return gsl_sf_legendre_Pl(int(a),b);}\r
+double MGL_LOCAL_CONST gslEllEc(double a)      {return gsl_sf_ellint_Ecomp(a,GSL_PREC_SINGLE);}\r
+double MGL_LOCAL_CONST gslEllFc(double a)      {return gsl_sf_ellint_Kcomp(a,GSL_PREC_SINGLE);}\r
+double MGL_LOCAL_CONST gslAi(double a) {return gsl_sf_airy_Ai(a,GSL_PREC_SINGLE);}\r
+double MGL_LOCAL_CONST gslBi(double a) {return gsl_sf_airy_Bi(a,GSL_PREC_SINGLE);}\r
+double MGL_LOCAL_CONST gslAi_d(double a)       {return gsl_sf_airy_Ai_deriv(a,GSL_PREC_SINGLE);}\r
+double MGL_LOCAL_CONST gslBi_d(double a)       {return gsl_sf_airy_Bi_deriv(a,GSL_PREC_SINGLE);}\r
 #endif\r
-double MGL_NO_EXPORT sgn(double a)     {return a<0 ? -1:(a>0?1:0);}\r
-double MGL_NO_EXPORT stp(double a)     {return a>0 ? 1:0;}\r
-double MGL_NO_EXPORT arg(double a,double b)    {       return atan2(b,a);      }\r
-double MGL_NO_EXPORT mgz1(double)      {return 0;}\r
-double MGL_NO_EXPORT mgz2(double,double)       {return 0;}\r
+double MGL_LOCAL_CONST sgn(double a)   {return a<0 ? -1:(a>0?1:0);}\r
+double MGL_LOCAL_CONST stp(double a)   {return a>0 ? 1:0;}\r
+double MGL_LOCAL_CONST arg(double a,double b)  {       return atan2(b,a);      }\r
+double MGL_LOCAL_CONST mgz1(double)                    {return NAN;}   // NOTE I think NAN value is more correct here than 0\r
+double MGL_LOCAL_CONST mgz2(double,double)     {return NAN;}   // NOTE I think NAN value is more correct here than 0\r
 #ifdef WIN32\r
-double MGL_NO_EXPORT asinh(double x)   {       return log(x+sqrt(x*x+1.));     }\r
-double MGL_NO_EXPORT acosh(double x)   {       return x>1 ? log(x+sqrt(x*x-1.)) : NAN; }\r
-double MGL_NO_EXPORT atanh(double x)   {       return fabs(x)<1 ? log((1.+x)/(1.-x))/2 : NAN;  }\r
+double MGL_LOCAL_CONST asinh(double x) {       return log(x+sqrt(x*x+1.));     }\r
+double MGL_LOCAL_CONST acosh(double x) {       return x>1 ? log(x+sqrt(x*x-1.)) : NAN; }\r
+double MGL_LOCAL_CONST atanh(double x) {       return fabs(x)<1 ? log((1.+x)/(1.-x))/2 : NAN;  }\r
 #endif\r
 //-----------------------------------------------------------------------------\r
 typedef double (*func_1)(double);\r
 typedef double (*func_2)(double, double);\r
-// evaluation of embedded (included) expressions\r
-mreal mglFormula::CalcIn(const mreal *a1) const\r
-{\r
-       mreal z2[EQ_SIN-EQ_LT] = {3,3,3,3,0,3,3,0,0,0,0,0,NAN,0\r
+//-----------------------------------------------------------------------------\r
+static const mreal z2[EQ_SIN-EQ_LT] = {3,3,3,3,0,3,3,0,0,0,0,0,NAN,0\r
 #if MGL_HAVE_GSL\r
-                       ,3,NAN, 3,NAN, 0,0,3,1\r
+       ,3,NAN, 3,NAN, 0,0,3,1,3\r
 #else\r
-                       ,0,0,0,0,0,0,0,0\r
+       ,0,0,0,0,0,0,0,0,0\r
 #endif\r
-               };\r
-       func_2 f2[EQ_SIN-EQ_LT] = {clt,cgt,ceq,cor,cand,add,sub,mul,del,ipw,pow,fmod,llg,arg,hypot\r
+};\r
+static const func_2 f2[EQ_SIN-EQ_LT] = {clt,cgt,ceq,cor,cand,add,sub,mul,del,ipw,pow,fmod,llg,arg,hypot\r
 #if MGL_HAVE_GSL\r
-                       ,gsl_sf_bessel_Jnu,gsl_sf_bessel_Ynu,\r
-                       gsl_sf_bessel_Inu,gsl_sf_bessel_Knu,\r
-                       gslEllE,gslEllF,gslLegP,gsl_sf_beta\r
+       ,gsl_sf_bessel_Jnu,gsl_sf_bessel_Ynu,\r
+       gsl_sf_bessel_Inu,gsl_sf_bessel_Knu,\r
+       gslEllE,gslEllF,gslLegP,gsl_sf_beta,gsl_sf_gamma_inc,\r
 #else\r
-                       ,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2\r
+       ,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2\r
 #endif\r
-               };\r
-       func_1 f1[EQ_SN-EQ_SIN] = {sin,cos,tan,asin,acos,atan,sinh,cosh,tanh,\r
-                                       asinh,acosh,atanh,sqrt,exp,log,log10,sgn,stp,floor,fabs\r
+};\r
+static const func_1 f1[EQ_SN-EQ_SIN] = {sin,cos,tan,asin,acos,atan,sinh,cosh,tanh,\r
+                       asinh,acosh,atanh,sqrt,exp,log,log10,sgn,stp,floor,fabs\r
 #if MGL_HAVE_GSL\r
-                       ,gsl_sf_dilog,gslEllEc,gslEllFc,gslAi,gslBi,gsl_sf_erf,\r
-                       gsl_sf_expint_3,gsl_sf_expint_Ei,gsl_sf_expint_E1,gsl_sf_expint_E2,\r
-                       gsl_sf_Si,gsl_sf_Ci,gsl_sf_gamma,gsl_sf_psi,gsl_sf_lambert_W0,\r
-                       gsl_sf_lambert_Wm1,gsl_sf_sinc,gsl_sf_zeta,gsl_sf_eta,gslAi_d,gslBi_d,\r
-                       gsl_sf_dawson\r
+       ,gsl_sf_dilog,gslEllEc,gslEllFc,gslAi,gslBi,gsl_sf_erf,\r
+       gsl_sf_expint_3,gsl_sf_expint_Ei,gsl_sf_expint_E1,gsl_sf_expint_E2,\r
+       gsl_sf_Si,gsl_sf_Ci,gsl_sf_gamma,gsl_sf_psi,gsl_sf_lambert_W0,\r
+       gsl_sf_lambert_Wm1,gsl_sf_sinc,gsl_sf_zeta,gsl_sf_eta,gslAi_d,gslBi_d,\r
+       gsl_sf_dawson\r
 #else\r
-                       ,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,\r
-                       mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1\r
+       ,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,\r
+       mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1\r
 #endif\r
-               };\r
-//     if(Error)       return 0;\r
+};\r
+//-----------------------------------------------------------------------------\r
+// evaluation of embedded (included) expressions\r
+mreal mglFormula::CalcIn(const mreal *a1) const\r
+{\r
        if(Kod<EQ_LT)\r
        {\r
                if(Kod==EQ_RND) return mgl_rnd();\r
@@ -548,7 +553,7 @@ mreal mglFormula::CalcIn(const mreal *a1) const
                        return mgl_isfin(b) ? b : NAN;\r
                }\r
                else if(Kod<EQ_SN)\r
-               {       a = f1[Kod-EQ_SIN](a);  return mgl_isfin(a)?a:NAN;      }       \r
+               {       a = f1[Kod-EQ_SIN](a);  return mgl_isfin(a)?a:NAN;      }\r
 #if MGL_HAVE_GSL\r
                else if(Kod<=EQ_DC)\r
                {\r
@@ -576,79 +581,82 @@ mreal mglFormula::CalcIn(const mreal *a1) const
        return NAN;\r
 }\r
 //-----------------------------------------------------------------------------\r
-double MGL_NO_EXPORT mgp(double ,double )      {return 1;}\r
-double MGL_NO_EXPORT mgm(double ,double )      {return -1;}\r
-double MGL_NO_EXPORT mul1(double ,double b)    {return b;}\r
-double MGL_NO_EXPORT mul2(double a,double )    {return a;}\r
-double MGL_NO_EXPORT div1(double ,double b)    {return b?1/b:NAN;}\r
-double MGL_NO_EXPORT div2(double a,double b)   {return b?-a/(b*b):NAN;}\r
-double MGL_NO_EXPORT ipw1(double a,double b)   {return b*(fabs(b-int(b))<1e-5 ? mgl_ipow(a,int(b-1)) : pow(a,b-1));}\r
-double MGL_NO_EXPORT pow1(double a,double b)   {return b*pow(a,b-1);}\r
-double MGL_NO_EXPORT pow2(double a,double b)   {return log(a)*pow(a,b);}\r
-double MGL_NO_EXPORT llg1(double a,double b)   {return 1/(a*log(b));}\r
-double MGL_NO_EXPORT llg2(double a,double b)   {return -log(a)/(b*log(b)*log(b));}\r
-double MGL_NO_EXPORT cos_d(double a)   {return -sin(a);}\r
-double MGL_NO_EXPORT tan_d(double a)   {return 1./(cos(a)*cos(a));}\r
-double MGL_NO_EXPORT asin_d(double a)  {return 1./sqrt(1.-a*a);}\r
-double MGL_NO_EXPORT acos_d(double a)  {return -1./sqrt(1.-a*a);}\r
-double MGL_NO_EXPORT atan_d(double a)  {return 1./(1.+a*a);}\r
-double MGL_NO_EXPORT tanh_d(double a)  {return 1./(cosh(a)*cosh(a));}\r
-double MGL_NO_EXPORT atanh_d(double a){return 1./(1.-a*a);}\r
-double MGL_NO_EXPORT asinh_d(double a){return 1./sqrt(1.+a*a);}\r
-double MGL_NO_EXPORT acosh_d(double a){return 1./sqrt(a*a-1.);}\r
-double MGL_NO_EXPORT sqrt_d(double a)  {return 0.5/sqrt(a);}\r
-double MGL_NO_EXPORT log10_d(double a){return M_LN10/a;}\r
-double MGL_NO_EXPORT log_d(double a)   {return 1./a;}\r
-double MGL_NO_EXPORT erf_d(double a)   {return 2*exp(-a*a)/sqrt(M_PI);}\r
-double MGL_NO_EXPORT dilog_d(double a){return log(a)/(1.-a);}\r
-double MGL_NO_EXPORT ei_d(double a)    {return exp(a)/a;}\r
-double MGL_NO_EXPORT si_d(double a)    {return a?sin(a)/a:1;}\r
-double MGL_NO_EXPORT ci_d(double a)    {return cos(a)/a;}\r
-double MGL_NO_EXPORT exp3_d(double a)  {return exp(-a*a*a);}\r
-double MGL_NO_EXPORT e1_d(double a)    {return exp(-a)/a;}\r
-double MGL_NO_EXPORT sinc_d(double a)  {return a ? (cos(M_PI*a)/a-sin(M_PI*a)/(M_PI*a*a)) : 0;}\r
+double MGL_LOCAL_CONST mgzz(double,double)     {return 0;}\r
+double MGL_LOCAL_CONST mgp(double ,double )    {return 1;}\r
+double MGL_LOCAL_CONST mgm(double ,double )    {return -1;}\r
+double MGL_LOCAL_CONST mul1(double ,double b)  {return b;}\r
+double MGL_LOCAL_CONST mul2(double a,double )  {return a;}\r
+double MGL_LOCAL_CONST div1(double ,double b)  {return b?1/b:NAN;}\r
+double MGL_LOCAL_CONST div2(double a,double b) {return b?-a/(b*b):NAN;}\r
+double MGL_LOCAL_CONST ipw1(double a,double b) {return b*(fabs(b-int(b))<1e-5 ? mgl_ipow(a,int(b-1)) : pow(a,b-1));}\r
+double MGL_LOCAL_CONST pow1(double a,double b) {return b*pow(a,b-1);}\r
+double MGL_LOCAL_CONST pow2(double a,double b) {return log(a)*pow(a,b);}\r
+double MGL_LOCAL_CONST llg1(double a,double b) {return 1/(a*log(b));}\r
+double MGL_LOCAL_CONST llg2(double a,double b) {return -log(a)/(b*log(b)*log(b));}\r
+double MGL_LOCAL_CONST cos_d(double a) {return -sin(a);}\r
+double MGL_LOCAL_CONST tan_d(double a) {return 1./(cos(a)*cos(a));}\r
+double MGL_LOCAL_CONST asin_d(double a)        {return 1./sqrt(1.-a*a);}\r
+double MGL_LOCAL_CONST acos_d(double a)        {return -1./sqrt(1.-a*a);}\r
+double MGL_LOCAL_CONST atan_d(double a)        {return 1./(1.+a*a);}\r
+double MGL_LOCAL_CONST tanh_d(double a)        {return 1./(cosh(a)*cosh(a));}\r
+double MGL_LOCAL_CONST atanh_d(double a){return 1./(1.-a*a);}\r
+double MGL_LOCAL_CONST asinh_d(double a){return 1./sqrt(1.+a*a);}\r
+double MGL_LOCAL_CONST acosh_d(double a){return 1./sqrt(a*a-1.);}\r
+double MGL_LOCAL_CONST sqrt_d(double a)        {return 0.5/sqrt(a);}\r
+double MGL_LOCAL_CONST log10_d(double a){return M_LN10/a;}\r
+double MGL_LOCAL_CONST log_d(double a) {return 1./a;}\r
+double MGL_LOCAL_CONST erf_d(double a) {return 2*exp(-a*a)/sqrt(M_PI);}\r
+double MGL_LOCAL_CONST dilog_d(double a){return log(a)/(1.-a);}\r
+double MGL_LOCAL_CONST ei_d(double a)  {return exp(a)/a;}\r
+double MGL_LOCAL_CONST si_d(double a)  {return a?sin(a)/a:1;}\r
+double MGL_LOCAL_CONST ci_d(double a)  {return cos(a)/a;}\r
+double MGL_LOCAL_CONST exp3_d(double a)        {return exp(-a*a*a);}\r
+double MGL_LOCAL_CONST e1_d(double a)  {return exp(-a)/a;}\r
+double MGL_LOCAL_CONST sinc_d(double a)        {return a ? (cos(M_PI*a)/a-sin(M_PI*a)/(M_PI*a*a)) : 0;}\r
 #if MGL_HAVE_GSL\r
-double MGL_NO_EXPORT e2_d(double a)    {return -gsl_sf_expint_E1(a);}\r
-double MGL_NO_EXPORT gslJnuD(double a,double b)        {return 0.5*(gsl_sf_bessel_Jnu(a-1,b)-gsl_sf_bessel_Jnu(a+1,b));}\r
-double MGL_NO_EXPORT gslYnuD(double a,double b)        {return 0.5*(gsl_sf_bessel_Ynu(a-1,b)-gsl_sf_bessel_Ynu(a+1,b));}\r
-double MGL_NO_EXPORT gslKnuD(double a,double b)        {return -(a*gsl_sf_bessel_Knu(a,b)/b +gsl_sf_bessel_Knu(a-1,b));}\r
-double MGL_NO_EXPORT gslInuD(double a,double b)        {return -(a*gsl_sf_bessel_Inu(a,b)/b -gsl_sf_bessel_Inu(a-1,b));}\r
-double MGL_NO_EXPORT gslEllE1(double a,double b)       {return sqrt(1.-sin(a)*sin(a)*b);}\r
-double MGL_NO_EXPORT gslEllE2(double a,double b)       {return (gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE) - gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE))/(2.*b);}\r
-double MGL_NO_EXPORT gslEllF1(double a,double b)       {return 1./sqrt(1.-sin(a)*sin(a)*b);}\r
-double MGL_NO_EXPORT gslEllF2(double a,double b)       {return (gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE) - gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE)*(1.-b))/(2*b*(1.-b)) - sin(2.*a)/(sqrt(1.-sin(a)*sin(a)*b)*2.*(1.-b));}\r
-double MGL_NO_EXPORT gslE_d(double a)  {return (gsl_sf_ellint_Ecomp(a,GSL_PREC_SINGLE) - gsl_sf_ellint_Kcomp(a,GSL_PREC_SINGLE))/(2.*a);}\r
-double MGL_NO_EXPORT gslK_d(double a)  {return (gsl_sf_ellint_Ecomp(a,GSL_PREC_SINGLE) - (1.-a)*gsl_sf_ellint_Kcomp(a,GSL_PREC_SINGLE))/(2.*a*(1.-a));}\r
-double MGL_NO_EXPORT gamma_d(double a) {return gsl_sf_psi(a)*gsl_sf_gamma(a);}\r
+double MGL_LOCAL_CONST e2_d(double a)  {return -gsl_sf_expint_E1(a);}\r
+double MGL_LOCAL_CONST gslJnuD(double a,double b)      {return 0.5*(gsl_sf_bessel_Jnu(a-1,b)-gsl_sf_bessel_Jnu(a+1,b));}\r
+double MGL_LOCAL_CONST gslYnuD(double a,double b)      {return 0.5*(gsl_sf_bessel_Ynu(a-1,b)-gsl_sf_bessel_Ynu(a+1,b));}\r
+double MGL_LOCAL_CONST gslKnuD(double a,double b)      {return -(a*gsl_sf_bessel_Knu(a,b)/b +gsl_sf_bessel_Knu(a-1,b));}\r
+double MGL_LOCAL_CONST gslInuD(double a,double b)      {return -(a*gsl_sf_bessel_Inu(a,b)/b -gsl_sf_bessel_Inu(a-1,b));}\r
+double MGL_LOCAL_CONST gslEllE1(double a,double b)     {return sqrt(1.-sin(a)*sin(a)*b);}\r
+double MGL_LOCAL_CONST gslEllE2(double a,double b)     {return (gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE) - gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE))/(2.*b);}\r
+double MGL_LOCAL_CONST gslEllF1(double a,double b)     {return 1./sqrt(1.-sin(a)*sin(a)*b);}\r
+double MGL_LOCAL_CONST gslEllF2(double a,double b)     {return (gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE) - gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE)*(1.-b))/(2*b*(1.-b)) - sin(2.*a)/(sqrt(1.-sin(a)*sin(a)*b)*2.*(1.-b));}\r
+double MGL_LOCAL_CONST gslE_d(double a)        {return (gsl_sf_ellint_Ecomp(a,GSL_PREC_SINGLE) - gsl_sf_ellint_Kcomp(a,GSL_PREC_SINGLE))/(2.*a);}\r
+double MGL_LOCAL_CONST gslK_d(double a)        {return (gsl_sf_ellint_Ecomp(a,GSL_PREC_SINGLE) - (1.-a)*gsl_sf_ellint_Kcomp(a,GSL_PREC_SINGLE))/(2.*a*(1.-a));}\r
+double MGL_LOCAL_CONST gamma_d(double a)       {return gsl_sf_psi(a)*gsl_sf_gamma(a);}\r
 #endif\r
+double MGL_LOCAL_CONST ginc_d(double a, double x)      {return -exp(-x)*pow(x,a-1);}\r
 //-----------------------------------------------------------------------------\r
-// evaluation of derivative of embedded (included) expressions\r
-mreal mglFormula::CalcDIn(int id, const mreal *a1) const\r
-{\r
-       func_2 f21[EQ_SIN-EQ_LT] = {mgz2,mgz2,mgz2, mgz2,mgz2,mgp, mgp,mul1,div1, ipw1,pow1,mgp,llg1, mgz2\r
+static const func_2 f21[EQ_SIN-EQ_LT] = {mgzz,mgzz,mgzz, mgzz,mgzz,mgp, mgp,mul1,div1, ipw1,pow1,mgp,llg1, mgz2\r
 #if MGL_HAVE_GSL\r
-                       ,mgz2,mgz2,mgz2, mgz2,gslEllE1,gslEllF2, mgz2,mgz2\r
+       ,mgz2,mgz2,mgz2, mgz2,gslEllE1,gslEllF1, mgz2,mgz2,mgz2\r
 #else\r
-                       ,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2\r
+       ,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2\r
 #endif\r
-               };\r
-               func_2 f22[EQ_SIN-EQ_LT] = {mgz2,mgz2,mgz2,mgz2,mgz2,mgp,mgm,mul2,div2,pow2,pow2,mgz2,llg2, mgz2\r
+};\r
+static const func_2 f22[EQ_SIN-EQ_LT] = {mgzz,mgzz,mgzz,mgzz,mgzz,mgp,mgm,mul2,div2,pow2,pow2,mgz2,llg2, mgz2\r
 #if MGL_HAVE_GSL\r
-                       ,gslJnuD,gslYnuD,gslInuD,gslKnuD,gslEllE2,gslEllF2,mgz2/*gslLegP*/,mgz2\r
+       ,gslJnuD,gslYnuD,gslInuD,gslKnuD,gslEllE2,gslEllF2,mgz2/*gslLegP*/,mgz2,ginc_d\r
 #else\r
-                       ,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2\r
+       ,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2,mgz2\r
 #endif\r
-               };\r
-       func_1 f11[EQ_SN-EQ_SIN] = {cos,cos_d,tan_d,asin_d,acos_d,atan_d,cosh,sinh,tanh_d,\r
-                                       asinh_d,acosh_d,atanh_d,sqrt_d,exp,log_d,log10_d,mgz1,mgz1,mgz1,sgn\r
+};\r
+static const func_1 f11[EQ_SN-EQ_SIN] = {cos,cos_d,tan_d,asin_d,acos_d,atan_d,cosh,sinh,tanh_d,\r
+       asinh_d,acosh_d,atanh_d,sqrt_d,exp,log_d,log10_d,mgz1,mgz1,mgz1,sgn\r
 #if MGL_HAVE_GSL\r
-                       ,dilog_d,gslE_d,gslK_d,gslAi_d,gslBi_d,erf_d,exp3_d,ei_d,e1_d,e2_d,\r
-                       si_d,ci_d,gamma_d,gsl_sf_psi_1,mgz1,mgz1,sinc_d,mgz1,mgz1,mgz1,mgz1,mgz1\r
+       ,dilog_d,gslE_d,gslK_d,gslAi_d,gslBi_d,erf_d,exp3_d,ei_d,e1_d,e2_d,\r
+       si_d,ci_d,gamma_d,gsl_sf_psi_1,mgz1,mgz1,sinc_d,mgz1,mgz1,mgz1,mgz1,mgz1\r
 #else\r
-                       ,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,\r
-                       mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1\r
+       ,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,\r
+       mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1,mgz1\r
 #endif\r
-               };\r
+};\r
+//-----------------------------------------------------------------------------\r
+// evaluation of derivative of embedded (included) expressions\r
+mreal mglFormula::CalcDIn(int id, const mreal *a1) const\r
+{\r
        if(Kod<EQ_LT)   return (Kod==EQ_A && id==(int)Res)?1:0;\r
 \r
        double a = Left->CalcIn(a1), d = Left->CalcDIn(id,a1);\r
@@ -690,7 +698,7 @@ mreal mglFormula::CalcDIn(int id, const mreal *a1) const
 }\r
 //-----------------------------------------------------------------------------\r
 // Check braces correctness\r
-bool MGL_NO_EXPORT mglCheck(char *str,int n)\r
+bool MGL_LOCAL_PURE mglCheck(char *str,int n)\r
 {\r
        register long s = 0,i;\r
        for(i=0;i<n;i++)\r
@@ -703,7 +711,7 @@ bool MGL_NO_EXPORT mglCheck(char *str,int n)
 }\r
 //-----------------------------------------------------------------------------\r
 // Try to find one of symbols lst in the string str\r
-int MGL_NO_EXPORT mglFindInText(char *str,const char *lst)\r
+int MGL_LOCAL_PURE mglFindInText(char *str,const char *lst)\r
 {\r
        register long l=0,r=0,i;//,j,len=strlen(lst);\r
        for(i=strlen(str)-1;i>=0;i--)\r
@@ -716,12 +724,12 @@ int MGL_NO_EXPORT mglFindInText(char *str,const char *lst)
 }\r
 //-----------------------------------------------------------------------------\r
 HMEX MGL_EXPORT mgl_create_expr(const char *expr)      {       return new mglFormula(expr);    }\r
-void MGL_EXPORT mgl_delete_expr(HMEX ex)       {       delete ex;      }\r
-double MGL_EXPORT mgl_expr_eval(HMEX ex, double x, double y,double z)\r
+void MGL_EXPORT mgl_delete_expr(HMEX ex)       {       if(ex)  delete ex;      }\r
+double MGL_EXPORT_PURE mgl_expr_eval(HMEX ex, double x, double y,double z)\r
 {      return ex->Calc(x,y,z); }\r
 double MGL_EXPORT mgl_expr_eval_v(HMEX ex, mreal *var)\r
 {      return ex->Calc(var);   }\r
-double MGL_EXPORT mgl_expr_diff(HMEX ex, char dir, double x, double y,double z)\r
+double MGL_EXPORT_PURE mgl_expr_diff(HMEX ex, char dir, double x, double y,double z)\r
 {      return ex->CalcD(dir,x,y,z);    }\r
 double MGL_EXPORT mgl_expr_diff_v(HMEX ex, char dir, mreal *var)\r
 {      return ex->CalcD(var, dir);             }\r
index 8834f3ab7d76b69493999334f82096f3759b18e0..f8f76a6a7ead7ecbfd9f4c3558a1bc29f459fe87 100644 (file)
@@ -56,12 +56,13 @@ EQ_EXPI,            // exponential function \exp(i*x)
 EQ_LN,         // logarithm of x, ln(x)\r
 EQ_LG,         // decimal logarithm of x, lg(x) = ln(x)/ln(10)\r
 EQ_ABS,                // absolute value\r
+EQ_ARG,                // argument (or phase) of complex number\r
 EQ_LAST                // id of last entry\r
 };\r
 //-----------------------------------------------------------------------------\r
 int mglFormulaC::Error=0;\r
-bool mglCheck(char *str,int n);\r
-int mglFindInText(char *str,const char *lst);\r
+bool MGL_LOCAL_PURE mglCheck(char *str,int n);\r
+int MGL_LOCAL_PURE mglFindInText(char *str,const char *lst);\r
 //-----------------------------------------------------------------------------\r
 mglFormulaC::~mglFormulaC()\r
 {\r
@@ -126,6 +127,7 @@ mglFormulaC::mglFormulaC(const char *string)
                {       Kod=EQ_A;       Res = str[0]-'a';       }\r
                else if(!strcmp(str,"rnd")) Kod=EQ_RND;\r
                else if(!strcmp(str,"pi")) Res=M_PI;\r
+               else if(!strcmp(str,"inf")) Res=INFINITY;\r
                else if(str[0]=='i')    Res = dual(0,str[1]>' '?atof(str+1):1);\r
                else Res=atof(str);                                     // this is number\r
        }\r
@@ -155,6 +157,7 @@ mglFormulaC::mglFormulaC(const char *string)
                else if(!strcmp(name,"lg")) Kod=EQ_LG;\r
                else if(!strcmp(name,"ln")) Kod=EQ_LN;\r
                else if(!strcmp(name,"abs")) Kod=EQ_ABS;\r
+               else if(!strcmp(name,"arg")) Kod=EQ_ARG;\r
                else {  delete []str;   return; }       // unknown function\r
                n=mglFindInText(str,",");\r
                if(n>=0)\r
@@ -204,34 +207,35 @@ dual mglFormulaC::Calc(const dual var[MGL_VS]) const
        return CalcIn(var);\r
 }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_NO_EXPORT addc(dual a,dual b) {return a+b;}\r
-dual MGL_NO_EXPORT subc(dual a,dual b) {return a-b;}\r
-dual MGL_NO_EXPORT mulc(dual a,dual b) {return a*b;}\r
-dual MGL_NO_EXPORT divc(dual a,dual b) {return a/b;}\r
-dual MGL_NO_EXPORT ipwc(dual a,dual b) {return mgl_ipowc(a,int(b.real()));}\r
-dual MGL_NO_EXPORT powc(dual a,dual b) {return exp(b*log(a));  }\r
-dual MGL_NO_EXPORT llgc(dual a,dual b) {return log(a)/log(b);  }\r
-dual MGL_NO_EXPORT expi(dual a)        {       return exp(dual(0,1)*a);        }\r
-dual MGL_NO_EXPORT expi(double a)      {       return dual(cos(a),sin(a));     }\r
+dual MGL_LOCAL_CONST addc(dual a,dual b)       {return a+b;}\r
+dual MGL_LOCAL_CONST subc(dual a,dual b)       {return a-b;}\r
+dual MGL_LOCAL_CONST mulc(dual a,dual b)       {return a*b;}\r
+dual MGL_LOCAL_CONST divc(dual a,dual b)       {return a/b;}\r
+dual MGL_LOCAL_CONST ipwc(dual a,dual b)       {return mgl_ipowc(a,int(b.real()));}\r
+dual MGL_LOCAL_CONST powc(dual a,dual b)       {return exp(b*log(a));  }\r
+dual MGL_LOCAL_CONST llgc(dual a,dual b)       {return log(a)/log(b);  }\r
+dual MGL_LOCAL_CONST expi(dual a)      {       return exp(dual(0,1)*a);        }\r
+dual MGL_LOCAL_CONST expi(double a)    {       return dual(cos(a),sin(a));     }\r
 //-----------------------------------------------------------------------------\r
 dual MGL_NO_EXPORT ic = dual(0,1);\r
-dual MGL_NO_EXPORT asinhc(dual x)      {       return log(x+sqrt(x*x+mreal(1)));       }\r
-dual MGL_NO_EXPORT acoshc(dual x)      {       return log(x+sqrt(x*x-mreal(1)));       }\r
-dual MGL_NO_EXPORT atanhc(dual x)      {       return log((mreal(1)+x)/(mreal(1)-x))/mreal(2); }\r
-dual MGL_NO_EXPORT sinc(dual x)        {       return sin(x);  }\r
-dual MGL_NO_EXPORT cosc(dual x)        {       return cos(x);  }\r
-dual MGL_NO_EXPORT tanc(dual x)        {       return tan(x);  }\r
-dual MGL_NO_EXPORT sinhc(dual x)       {       return sinh(x); }\r
-dual MGL_NO_EXPORT coshc(dual x)       {       return cosh(x); }\r
-dual MGL_NO_EXPORT tanhc(dual x)       {       return tanh(x); }\r
-dual MGL_NO_EXPORT asinc(dual x)       {       return log(ic*x+sqrt(mreal(1)-x*x))/ic; }\r
-dual MGL_NO_EXPORT acosc(dual x)       {       return log(x+sqrt(x*x-mreal(1)))/ic;    }\r
-dual MGL_NO_EXPORT atanc(dual x)       {       return log((ic-x)/(ic+x))/(mreal(2)*ic);        }\r
-dual MGL_NO_EXPORT expc(dual x)        {       return exp(x);  }\r
-dual MGL_NO_EXPORT sqrtc(dual x)       {       return sqrt(x); }\r
-dual MGL_NO_EXPORT logc(dual x)        {       return log(x);  }\r
-dual MGL_NO_EXPORT absc(dual x)        {       return abs(x);  }\r
-dual MGL_NO_EXPORT lgc(dual x) {       return log10(x);}\r
+dual MGL_LOCAL_CONST asinhc(dual x)    {       return log(x+sqrt(x*x+mreal(1)));       }\r
+dual MGL_LOCAL_CONST acoshc(dual x)    {       return log(x+sqrt(x*x-mreal(1)));       }\r
+dual MGL_LOCAL_CONST atanhc(dual x)    {       return log((mreal(1)+x)/(mreal(1)-x))/mreal(2); }\r
+dual MGL_LOCAL_CONST sinc(dual x)      {       return sin(x);  }\r
+dual MGL_LOCAL_CONST cosc(dual x)      {       return cos(x);  }\r
+dual MGL_LOCAL_CONST tanc(dual x)      {       return tan(x);  }\r
+dual MGL_LOCAL_CONST sinhc(dual x)     {       return sinh(x); }\r
+dual MGL_LOCAL_CONST coshc(dual x)     {       return cosh(x); }\r
+dual MGL_LOCAL_CONST tanhc(dual x)     {       return tanh(x); }\r
+dual MGL_LOCAL_CONST asinc(dual x)     {       return log(ic*x+sqrt(mreal(1)-x*x))/ic; }\r
+dual MGL_LOCAL_CONST acosc(dual x)     {       return log(x+sqrt(x*x-mreal(1)))/ic;    }\r
+dual MGL_LOCAL_CONST atanc(dual x)     {       return log((ic-x)/(ic+x))/(mreal(2)*ic);        }\r
+dual MGL_LOCAL_CONST expc(dual x)      {       return exp(x);  }\r
+dual MGL_LOCAL_CONST sqrtc(dual x)     {       return sqrt(x); }\r
+dual MGL_LOCAL_CONST logc(dual x)      {       return log(x);  }\r
+dual MGL_LOCAL_CONST absc(dual x)      {       return abs(x);  }\r
+dual MGL_LOCAL_CONST argc(dual x)      {       return arg(x);  }\r
+dual MGL_LOCAL_CONST lgc(dual x)       {       return log10(x);}\r
 //-----------------------------------------------------------------------------\r
 typedef dual (*func_1)(dual);\r
 typedef dual (*func_2)(dual, dual);\r
@@ -261,30 +265,30 @@ dual mglFormulaC::CalcIn(const dual *a1) const
        return NAN;\r
 }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_EXPORT mgl_ipowc(dual x,int n)\r
+mdual MGL_EXPORT_CONST mgl_ipowc(dual x,int n)\r
 {\r
        dual t;\r
-       if(n==2)        return x*x;\r
-       if(n==1)        return x;\r
-       if(n<0)         return mreal(1)/mgl_ipowc(x,-n);\r
+       if(n==2)        {       t = x*x;        return t.real()+t.imag()*_Complex_I;    }\r
+       if(n==1)        return x.real()+x.imag()*_Complex_I;\r
+       if(n<0)         {       t = mreal(1)/mgl_ipowc(x,-n);   return t.real()+t.imag()*_Complex_I;    }\r
        if(n==0)        return mreal(1);\r
        t = mgl_ipowc(x,n/2);   t = t*t;\r
        if(n%2==1)      t *= x;\r
-       return t;\r
+       return t.real()+t.imag()*_Complex_I;\r
 }\r
-dual MGL_EXPORT mgl_ipowc_(dual *x,int *n)     {       return mgl_ipowc(*x,*n);        }\r
+mdual MGL_EXPORT_PURE mgl_ipowc_(dual *x,int *n)       {       return mgl_ipowc(*x,*n);        }\r
 //-----------------------------------------------------------------------------\r
 HAEX MGL_EXPORT mgl_create_cexpr(const char *expr)     {       return new mglFormulaC(expr);   }\r
 uintptr_t MGL_EXPORT mgl_create_cexpr_(const char *expr, int l)\r
 {      char *s=new char[l+1];  memcpy(s,expr,l);       s[l]=0;\r
        uintptr_t res = uintptr_t(mgl_create_cexpr(s));\r
        delete []s;     return res;     }\r
-void MGL_EXPORT mgl_delete_cexpr(HAEX ex)      {       delete ex;      }\r
+void MGL_EXPORT mgl_delete_cexpr(HAEX ex)      {       if(ex)  delete ex;      }\r
 void MGL_EXPORT mgl_delete_cexpr_(uintptr_t *ex)       {       mgl_delete_cexpr((HAEX)ex);     }\r
-dual MGL_EXPORT mgl_cexpr_eval(HAEX ex, dual x, dual y,dual z)\r
-{      return ex->Calc(x,y,z); }\r
-dual MGL_EXPORT mgl_cexpr_eval_(uintptr_t *ex, dual *x, dual *y, dual *z)\r
+mdual MGL_EXPORT_PURE mgl_cexpr_eval(HAEX ex, dual x, dual y,dual z)\r
+{      dual r = ex->Calc(x,y,z);       return r.real()+r.imag()*_Complex_I;    }\r
+mdual MGL_EXPORT mgl_cexpr_eval_(uintptr_t *ex, dual *x, dual *y, dual *z)\r
 {      return mgl_cexpr_eval((HAEX) ex, *x,*y,*z);             }\r
-dual MGL_EXPORT mgl_cexpr_eval_v(HAEX ex, dual *var)\r
-{      return ex->Calc(var);   }\r
+mdual MGL_EXPORT mgl_cexpr_eval_v(HAEX ex, dual *var)\r
+{      dual r = ex->Calc(var); return r.real()+r.imag()*_Complex_I;    }\r
 //-----------------------------------------------------------------------------\r
index 602bfcf7ea18c5e237609bc21443a7dbd2a2b5a8..5b4489f21354b48b86c7f94cfb5af90834a05f27 100644 (file)
 //-----------------------------------------------------------------------------
 std::wstring mgl_trim_ws(const std::wstring &str);
 int mglFormulaError;
-mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring string, mglParser *arg, const mglVar *head);
+mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring string, mglParser *arg, const std::vector<mglDataA*> &head);
+mglDataC MGL_NO_EXPORT mglFormulaCalcC(std::wstring string, mglParser *arg, const std::vector<mglDataA*> &head);
+//-----------------------------------------------------------------------------
+mglData MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector<mglDataA*> &head)
+{
+       std::wstring s;
+       for(long i=0;str[i];i++)        s.push_back(str[i]);
+       return mglFormulaCalc(s,0,head);
+}
+//-----------------------------------------------------------------------------
+mglDataC MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector<mglDataA*> &head)
+{
+       std::wstring s;
+       for(long i=0;str[i];i++)        s.push_back(str[i]);
+       return mglFormulaCalcC(s,0,head);
+}
 //-----------------------------------------------------------------------------
 void mglApplyFunc(mglData &d, double (*func)(double))
 {
@@ -36,11 +51,51 @@ void mglApplyFunc(mglData &d, double (*func)(double))
        for(long i=0;i<n;i++)   d.a[i] = func(d.a[i]);
 }
 //-----------------------------------------------------------------------------
-mglData mglApplyOper(std::wstring a1, std::wstring a2, mglParser *arg, const mglVar *head, double (*func)(double,double))
+mglData mglApplyOper(std::wstring a1, std::wstring a2, mglParser *arg, const std::vector<mglDataA*> &head, double (*func)(double,double))
 {
        const mglData &a = mglFormulaCalc(a1,arg,head), &b = mglFormulaCalc(a2,arg,head);
        long n = mgl_max(a.nx,b.nx), m = mgl_max(a.ny,b.ny), l = mgl_max(a.nz,b.nz);
        mglData r(n, m, l);
+       if(a.nx==b.nx && b.ny==a.ny && b.nz==a.nz)
+#pragma omp parallel for
+               for(long i=0;i<n*m*l;i++)       r.a[i] = func(a.a[i], b.a[i]);
+       else if(b.nx*b.ny*b.nz==1)
+#pragma omp parallel for
+               for(long i=0;i<a.nx*a.ny*a.nz;i++)      r.a[i] = func(a.a[i],b.a[0]);
+       else if(a.nx*a.ny*a.nz==1)
+#pragma omp parallel for
+               for(long i=0;i<b.nx*b.ny*b.nz;i++)      r.a[i] = func(a.a[0],b.a[i]);
+       else if(a.nx==b.nx && b.ny*b.nz==1)
+#pragma omp parallel for collapse(2)
+               for(long j=0;j<a.ny*a.nz;j++)   for(long i=0;i<n;i++)
+                       r.a[i+n*j] = func(a.a[i+n*j], b.a[i]);
+       else if(a.nx==b.nx && a.ny*a.nz==1)
+#pragma omp parallel for collapse(2)
+               for(long i=0;i<n;i++)   for(long j=0;j<b.ny*b.nz;j++)
+                       r.a[i+n*j] = func(a.a[i], b.a[i+n*j]);
+       else if(a.nx==b.nx && b.ny==a.ny && b.nz==1)
+#pragma omp parallel for collapse(3)
+               for(long k=0;k<a.nz;k++)        for(long j=0;j<m;j++)   for(long i=0;i<n;i++)
+                       r.a[i+n*(j+m*k)] = func(a.a[i+n*(j+m*k)], b.a[i+n*j]);
+       else if(a.nx==b.nx && b.ny==a.ny && a.nz==1)
+#pragma omp parallel for collapse(3)
+               for(long k=0;k<b.nz;k++)        for(long j=0;j<m;j++)   for(long i=0;i<n;i++)
+                       r.a[i+n*(j+m*k)] = func(a.a[i+n*j], b.a[i+n*(j+m*k)]);
+       return r;
+}
+//-----------------------------------------------------------------------------
+void mglApplyFuncC(mglDataC &d, dual (*func)(dual))
+{
+       long n = d.nx*d.ny*d.nz;
+#pragma omp parallel for
+       for(long i=0;i<n;i++)   d.a[i] = func(d.a[i]);
+}
+//-----------------------------------------------------------------------------
+mglDataC mglApplyOperC(std::wstring a1, std::wstring a2, mglParser *arg, const std::vector<mglDataA*> &head, dual (*func)(dual,dual))
+{
+       const mglDataC &a = mglFormulaCalcC(a1,arg,head), &b = mglFormulaCalcC(a2,arg,head);
+       long n = mgl_max(a.nx,b.nx), m = mgl_max(a.ny,b.ny), l = mgl_max(a.nz,b.nz);
+       mglDataC r(n, m, l);
        if(b.nx*b.ny*b.nz==1)
 #pragma omp parallel for
                for(long i=0;i<a.nx*a.ny*a.nz;i++)      r.a[i] = func(a.a[i],b.a[0]);
@@ -93,23 +148,23 @@ int mglFindInText(std::wstring str,const char *lst)
        return -1;
 }
 //-----------------------------------------------------------------------------
-double MGL_NO_EXPORT cand(double a,double b);//        {return a&&b?1:0;}
-double MGL_NO_EXPORT cor(double a,double b);// {return a||b?1:0;}
-double MGL_NO_EXPORT ceq(double a,double b);// {return a==b?1:0;}
-double MGL_NO_EXPORT clt(double a,double b);// {return a<b?1:0;}
-double MGL_NO_EXPORT cgt(double a,double b);// {return a>b?1:0;}
-double MGL_NO_EXPORT add(double a,double b);// {return a+b;}
-double MGL_NO_EXPORT sub(double a,double b);// {return a-b;}
-double MGL_NO_EXPORT mul(double a,double b);// {return a&&b?a*b:0;}
-double MGL_NO_EXPORT del(double a,double b);// {return b?a/b:NAN;}
-double MGL_NO_EXPORT ipw(double a,double b);// {return mgl_ipow(a,int(b));}
-double MGL_NO_EXPORT llg(double a,double b);// {return log(a)/log(b);}
-//double MGL_NO_EXPORT asinh(double x);//      {       return log(x+sqrt(x*x+1));      }
-//double MGL_NO_EXPORT acosh(double x);//      {       return x>1 ? log(x+sqrt(x*x-1)) : NAN;  }
-//double MGL_NO_EXPORT atanh(double x);//      {       return fabs(x)<1 ? log((1+x)/(1-x))/2 : NAN;    }
-double MGL_NO_EXPORT gslEllE(double a,double b);//     {return gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE);}
-double MGL_NO_EXPORT gslEllF(double a,double b);//     {return gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE);}
-double MGL_NO_EXPORT gslLegP(double a,double b);//     {return gsl_sf_legendre_Pl(int(a),b);}
+double MGL_LOCAL_CONST cand(double a,double b);//      {return a&&b?1:0;}
+double MGL_LOCAL_CONST cor(double a,double b);//       {return a||b?1:0;}
+double MGL_LOCAL_CONST ceq(double a,double b);//       {return a==b?1:0;}
+double MGL_LOCAL_CONST clt(double a,double b);//       {return a<b?1:0;}
+double MGL_LOCAL_CONST cgt(double a,double b);//       {return a>b?1:0;}
+double MGL_LOCAL_CONST add(double a,double b);//       {return a+b;}
+double MGL_LOCAL_CONST sub(double a,double b);//       {return a-b;}
+double MGL_LOCAL_CONST mul(double a,double b);//       {return a&&b?a*b:0;}
+double MGL_LOCAL_CONST del(double a,double b);//       {return b?a/b:NAN;}
+double MGL_LOCAL_CONST ipw(double a,double b);//       {return mgl_ipow(a,int(b));}
+double MGL_LOCAL_CONST llg(double a,double b);//       {return log(a)/log(b);}
+//double MGL_LOCAL_CONST asinh(double x);//    {       return log(x+sqrt(x*x+1));      }
+//double MGL_LOCAL_CONST acosh(double x);//    {       return x>1 ? log(x+sqrt(x*x-1)) : NAN;  }
+//double MGL_LOCAL_CONST atanh(double x);//    {       return fabs(x)<1 ? log((1+x)/(1-x))/2 : NAN;    }
+double MGL_LOCAL_CONST gslEllE(double a,double b);//   {return gsl_sf_ellint_E(a,b,GSL_PREC_SINGLE);}
+double MGL_LOCAL_CONST gslEllF(double a,double b);//   {return gsl_sf_ellint_F(a,b,GSL_PREC_SINGLE);}
+double MGL_LOCAL_CONST gslLegP(double a,double b);//   {return gsl_sf_legendre_Pl(int(a),b);}
 //-----------------------------------------------------------------------------
 // It seems that standard wcstombs() have a bug. So, I replace by my own.
 void MGL_EXPORT mgl_wcstombs(char *dst, const wchar_t *src, int size)
@@ -120,30 +175,32 @@ void MGL_EXPORT mgl_wcstombs(char *dst, const wchar_t *src, int size)
        dst[j] = 0;
 }
 //-----------------------------------------------------------------------------
-const mglVar *FindVar(const mglVar *head, std::wstring &name)
+MGL_LOCAL_PURE const mglDataA *FindVar(const std::vector<mglDataA*> &head, const std::wstring &name)
 {
-       const mglVar *v=head;
-       while(v)
-       {
-               if(v->s==name)  return v;
-               v = v->next;
-       }
+       for(size_t i=0;i<head.size();i++)
+               if(head[i] && head[i]->s==name) return head[i];
        return 0;
 }
 //-----------------------------------------------------------------------------
+void MGL_EXPORT mgl_wcslwr(wchar_t *str)
+{
+       register size_t l=mgl_wcslen(str);
+       for(size_t k=0;k<l;k++)
+               str[k] = (str[k]>='A' && str[k]<='Z') ? str[k]+'a'-'A' : str[k];
+}
+//-----------------------------------------------------------------------------
 /// Parse string and substitute the script argument
 // All numbers are presented as mglData(1). Do boundary checking.
 // NOTE: In any case where number is required the mglData::a[0] is used.
 // String flag is binary 0x1 -> 'x', 0x2 -> 'y', 0x4 -> 'z'
-// NOTE: the speed is not a goal (mglFormula is faster). It is true interpreter!
-mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const mglVar *head)
+mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const std::vector<mglDataA*> &head)
 {
 #if MGL_HAVE_GSL
        gsl_set_error_handler_off();
 #endif
        mglData res;
        if(str.empty() || mglFormulaError)      return res;     // nothing to parse
-       if(!head && arg)        head = arg->DataList;
+//     if(arg) head = arg->DataList;
        str = mgl_trim_ws(str);
        long n,len=str.length();
        if(str[0]=='(' && mglCheck(str.substr(1,len-2)))        // remove braces
@@ -260,24 +317,30 @@ mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const mgl
        for(n=0;n<len;n++)      if(str[n]=='(') break;
        if(n>=len)              // this is number or variable
        {
-               const mglVar *v = FindVar(head, str);
+               HCDT v = (str!=L"#$mgl")?FindVar(head, str):0;
                mglNum *f = arg?arg->FindNum(str.c_str()):0;
                if(v)   res = v;
                else if(f)      res.a[0] = f->d;
-               else if(!str.compare(L"rnd"))   res.a[0] = mgl_rnd();
-               else if(!str.compare(L"nan"))   res.a[0] = NAN;
-               else if(!str.compare(L"pi"))    res.a[0] = M_PI;
-               else if(!str.compare(L"on"))    res.a[0] = 1;
-               else if(!str.compare(L"off"))   res.a[0] = 0;
                else if(!str.compare(L":"))             res.a[0] = -1;
-               else res.a[0] = wcstod(str.c_str(),0);  // this is number
+               else
+               {
+                       HCDT v=FindVar(head, L"#$mgl");
+                       if(v)   res.Create(v->GetNx(),v->GetNy(),v->GetNz());
+                       if(!str.compare(L"rnd"))        for(long i=0;i<res.GetNN();i++) res.a[i] = mgl_rnd();
+                       else if(!str.compare(L"nan"))   res = NAN;
+                       else if(!str.compare(L"inf"))   res = INFINITY;
+                       else if(!str.compare(L"pi"))    res = M_PI;
+                       else if(!str.compare(L"on"))    res = 1;
+                       else if(!str.compare(L"off"))   res = 0;
+                       else res = wcstod(str.c_str(),0);       // this is number
+               }
                return res;
        }
        else
        {
                std::wstring nm = str.substr(0,n);
                str = str.substr(n+1,len-n-2);  len -= n+2;
-               const mglVar *v = FindVar(head, nm);
+               HCDT v = FindVar(head, nm);
 //             mglVar *v = arg->FindVar(nm.c_str());
                if(!v && !nm.compare(0,7,L"jacobi_"))   nm = nm.substr(7);
                if(v)   // subdata
@@ -286,17 +349,20 @@ mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const mgl
                        {
                                char *buf = new char[len];
                                mgl_wcstombs(buf, str.substr(1).c_str(), len-1);        buf[len-1]=0;
-                               res=v->Column(buf);     delete []buf;
+                               const mglData *vd = dynamic_cast<const mglData *>(v);
+                               if(vd)  res=vd->Column(buf);
+                               const mglDataC *vc = dynamic_cast<const mglDataC *>(v);
+                               if(vc)  res=vc->Column(buf);
+                               delete []buf;
                        }
                        else
                        {
-                               long m;
                                mglData a1, a2, a3;
                                a1.a[0] = a2.a[0] = a3.a[0] = -1;
                                n=mglFindInText(str,",");
                                if(n>0)
                                {
-                                       m=mglFindInText(str.substr(0,n),",");
+                                       long m=mglFindInText(str.substr(0,n),",");
                                        if(m>0)
                                        {
                                                str[m]=0;
@@ -311,7 +377,7 @@ mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const mgl
                                        }
                                }
                                else    a1 = mglFormulaCalc(str, arg, head);
-                               res = v->SubData(a1,a2,a3);
+                               res = mglSubData(*v,a1,a2,a3);
                        }
                }
                else if(nm[0]=='a')     // function
@@ -517,6 +583,9 @@ mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const mgl
                }
                else if(!nm.compare(L"int"))
                {       res=mglFormulaCalc(str, arg, head);     mglApplyFunc(res,floor);        }
+               else if(!nm.compare(L"random"))
+               {       res=mglFormulaCalc(str, arg, head);     register long n = res.GetNN(), i;
+                       for(i=0;i<n;i++)        res.a[i] = mgl_rnd();   }
 #if MGL_HAVE_GSL
                else if(!nm.compare(L"i"))
                {
@@ -556,6 +625,12 @@ mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const mgl
                }
                else if(!nm.compare(L"gamma"))
                {       res=mglFormulaCalc(str, arg, head);     mglApplyFunc(res,gsl_sf_gamma); }
+               else if(!nm.compare(L"gamma_inc"))
+               {
+                       n=mglFindInText(str,",");
+                       if(n<=0)        mglFormulaError=true;
+                       else    res = mglApplyOper(str.substr(0,n),str.substr(n+1),arg, head, gsl_sf_gamma_inc);
+               }
                else if(!nm.compare(L"w0"))
                {       res=mglFormulaCalc(str, arg, head);     mglApplyFunc(res,gsl_sf_lambert_W0);    }
                else if(!nm.compare(L"w1"))
@@ -571,10 +646,284 @@ mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const mgl
        return res;
 }
 //-----------------------------------------------------------------------------
-void MGL_EXPORT mgl_wcslwr(wchar_t *str)
+dual MGL_LOCAL_CONST ceqc(dual a,dual b)       {return a==b?1:0;}
+dual MGL_LOCAL_CONST cltc(dual a,dual b)       {return real(a-b)<0?1:0;}
+dual MGL_LOCAL_CONST cgtc(dual a,dual b)       {return real(a-b)>0?1:0;}
+dual MGL_LOCAL_CONST addc(dual a,dual b);      //{return a+b;}
+dual MGL_LOCAL_CONST subc(dual a,dual b);      //{return a-b;}
+dual MGL_LOCAL_CONST mulc(dual a,dual b);      //{return a*b;}
+dual MGL_LOCAL_CONST divc(dual a,dual b);      //{return a/b;}
+dual MGL_LOCAL_CONST ipwc(dual a,dual b);      //{return mgl_ipowc(a,int(b.real()));}
+dual MGL_LOCAL_CONST powc(dual a,dual b);      //{return exp(b*log(a));        }
+dual MGL_LOCAL_CONST llgc(dual a,dual b);      //{return log(a)/log(b);        }
+dual MGL_LOCAL_CONST expi(dual a);     //{     return exp(dual(0,1)*a);        }
+dual MGL_LOCAL_CONST expi(double a);   //{     return dual(cos(a),sin(a));     }
+//-----------------------------------------------------------------------------
+dual MGL_LOCAL_CONST asinhc(dual x);   //{     return log(x+sqrt(x*x+mreal(1)));       }
+dual MGL_LOCAL_CONST acoshc(dual x);   //{     return log(x+sqrt(x*x-mreal(1)));       }
+dual MGL_LOCAL_CONST atanhc(dual x);   //{     return log((mreal(1)+x)/(mreal(1)-x))/mreal(2); }
+dual MGL_LOCAL_CONST sinc(dual x);     //{     return sin(x);  }
+dual MGL_LOCAL_CONST cosc(dual x);     //{     return cos(x);  }
+dual MGL_LOCAL_CONST tanc(dual x);     //{     return tan(x);  }
+dual MGL_LOCAL_CONST sinhc(dual x);    //{     return sinh(x); }
+dual MGL_LOCAL_CONST coshc(dual x);    //{     return cosh(x); }
+dual MGL_LOCAL_CONST tanhc(dual x);    //{     return tanh(x); }
+dual MGL_LOCAL_CONST asinc(dual x);    //{     return log(ic*x+sqrt(mreal(1)-x*x))/ic; }
+dual MGL_LOCAL_CONST acosc(dual x);    //{     return log(x+sqrt(x*x-mreal(1)))/ic;    }
+dual MGL_LOCAL_CONST atanc(dual x);    //{     return log((ic-x)/(ic+x))/(mreal(2)*ic);        }
+dual MGL_LOCAL_CONST expc(dual x);     //{     return exp(x);  }
+dual MGL_LOCAL_CONST sqrtc(dual x);    //{     return sqrt(x); }
+dual MGL_LOCAL_CONST logc(dual x);     //{     return log(x);  }
+dual MGL_LOCAL_CONST absc(dual x);     //{     return abs(x);  }
+dual MGL_LOCAL_CONST argc(dual x);     //{     return arg(x);  }
+dual MGL_LOCAL_CONST lgc(dual x);              //{     return log10(x);}
+//-----------------------------------------------------------------------------
+/// Parse string and substitute the script argument
+// All numbers are presented as mglData(1). Do boundary checking.
+// NOTE: In any case where number is required the mglData::a[0] is used.
+// String flag is binary 0x1 -> 'x', 0x2 -> 'y', 0x4 -> 'z'
+mglDataC MGL_NO_EXPORT mglFormulaCalcC(std::wstring str, mglParser *arg, const std::vector<mglDataA*> &head)
 {
-       register size_t l=mgl_wcslen(str);
-       for(size_t k=0;k<l;k++)
-               str[k] = (str[k]>='A' && str[k]<='Z') ? str[k]+'a'-'A' : str[k];
+#if MGL_HAVE_GSL
+       gsl_set_error_handler_off();
+#endif
+       mglDataC res;
+       if(str.empty() || mglFormulaError)      return res;     // nothing to parse
+//     if(arg) head = arg->DataList;
+       str = mgl_trim_ws(str);
+       long n,len=str.length();
+       if(str[0]=='(' && mglCheck(str.substr(1,len-2)))        // remove braces
+       {       str = str.substr(1,len-2);      len-=2; }
+       if(str[0]=='[') // this is manual subdata
+       {
+               mglData a1;
+               long i, j, br=0,k;
+               bool ar=true,mt=false;
+               for(i=1,j=1;i<len-1;i++)
+               {
+                       if(str[i]=='[') br++;
+                       if(str[i]==']' && br>0) br--;
+                       if(str[i]==',' && !br)
+                       {
+                               a1=mglFormulaCalc(str.substr(j,i-j), arg, head);
+                               if(j==1)
+                               {       res = a1;       ar = (a1.nx==1);        mt = (a1.nx>1 && a1.ny==1);     }
+                               else
+                               {
+                                       if(ar)          // res 1d array
+                                       {       k = res.nx;     res.Insert('x',k);      res.Put(a1,k);  }
+                                       else if(mt)     // res 2d array
+                                       {       k = res.ny;     res.Insert('y',k);      res.Put(a1,-1,k);       }
+                                       else            // res 3d array
+                                       {       k = res.nz;     res.Insert('z',k);      res.Put(a1,-1,-1,k);    }
+                               }
+                               j=i+1;
+                       }
+               }
+               a1=mglFormulaCalc(str.substr(j,i-j), arg, head);
+               if(j==1)
+               {       res = a1;       ar = (a1.nx==1);        mt = (a1.nx>1 && a1.ny==1);     }
+               else
+               {
+                       if(ar)          // res 1d array
+                       {       k = res.nx;     res.Insert('x',k);      res.Put(a1,k);  }
+                       else if(mt)     // res 2d array
+                       {       k = res.ny;     res.Insert('y',k);      res.Put(a1,-1,k);       }
+                       else            // res 3d array
+                       {       k = res.nz;     res.Insert('z',k);      res.Put(a1,-1,-1,k);    }
+               }
+               return res;
+       }
+
+       n=mglFindInText(str,"<>=");                             // low priority -- conditions
+       if(n>=0)
+               return mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, str[n]=='<'?cltc:(str[n]=='>'?cgtc:ceqc));
+       n=mglFindInText(str,"+-");                              // normal priority -- additions
+       if(n>=0 && (n<2 || str[n-1]!='e' || (str[n-2]!='.' && !isdigit(str[n-2]))))
+               return mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, str[n]=='+'?addc:subc);
+       n=mglFindInText(str,"*/");                              // high priority -- multiplications
+       if(n>=0)
+               return mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, str[n]=='*'?mulc:divc);
+/*     n=mglFindInText(str,"@");                               // high priority -- combine     // TODO enable later
+       if(n>=0)
+               return mglFormulaCalcC(str.substr(0,n),arg, head).Combine(mglFormulaCalcC(str.substr(n+1),arg, head));*/
+       n=mglFindInText(str,"^");                               // highest priority -- power
+       if(n>=0)
+               return mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, ipwc);
+       n=mglFindInText(str,":");                               // highest priority -- array
+       if(n>=0 && str.compare(L":"))
+       {
+               const mglData &a1=mglFormulaCalc(str.substr(0,n), arg, head);
+               const mglData &a2=mglFormulaCalc(str.substr(n+1), arg, head);
+               res.Create(abs(int(a2.a[0]+0.5)-int(a1.a[0]+0.5))+1);
+               res.Fill(a1.a[0], a2.a[0]);
+               return res;
+       }
+       n=mglFindInText(str,".");                               // highest priority -- suffixes
+       if(n>=0)
+       {
+               mreal x,y,z,k;
+               dual v=NAN;
+               mglDataC d = mglFormulaCalcC(str.substr(0,n), arg, head);
+               const std::wstring &p=str.substr(n+1);
+               if(!p.compare(L"a"))                    v = d.a[0];
+               else if(!p.compare(L"fst"))     {       long i=-1,j=-1,l=-1;    v = d.Find(0,i,j,l);    }
+               else if(!p.compare(L"lst"))     {       long i=-1,j=-1,l=-1;    v = d.Last(0,i,j,l);    }
+               else if(!p.compare(L"nx"))      v=d.nx;
+               else if(!p.compare(L"ny"))      v=d.ny;
+               else if(!p.compare(L"nz"))      v=d.nz;
+               else if(!p.compare(L"max"))     v=d.Maximal();
+               else if(!p.compare(L"min"))     v=d.Minimal();
+               else if(!p.compare(L"pmax"))    {       v=d.Maximal();  }
+//             else if(!p.compare(L"pmin"))    {       v=d.MinimalPos();       }
+//             else if(!p.compare(L"nmax"))    {       v=d.MaximalNeg();       }
+               else if(!p.compare(L"nmin"))    {       v=0;    }
+               else if(!p.compare(L"sum"))     v=d.Momentum('x',x,y);
+               else if(!p.compare(L"mx"))      {       d.Maximal(x,y,z);       v=x/d.nx;       }
+               else if(!p.compare(L"my"))      {       d.Maximal(x,y,z);       v=y/d.ny;       }
+               else if(!p.compare(L"mz"))      {       d.Maximal(x,y,z);       v=z/d.nz;       }
+               else if(!p.compare(L"ax"))      {       d.Momentum('x',x,y);    v=x/d.nx;       }
+               else if(!p.compare(L"ay"))      {       d.Momentum('y',x,y);    v=x/d.ny;       }
+               else if(!p.compare(L"az"))      {       d.Momentum('z',x,y);    v=x/d.nz;       }
+               else if(!p.compare(L"wx"))      {       d.Momentum('x',x,y);    v=y/d.nx;       }
+               else if(!p.compare(L"wy"))      {       d.Momentum('y',x,y);    v=y/d.ny;       }
+               else if(!p.compare(L"wz"))      {       d.Momentum('z',x,y);    v=y/d.nz;       }
+               else if(!p.compare(L"sx"))      {       d.Momentum('x',x,y,z,k);        v=z/d.nx;       }
+               else if(!p.compare(L"sy"))      {       d.Momentum('y',x,y,z,k);        v=z/d.ny;       }
+               else if(!p.compare(L"sz"))      {       d.Momentum('z',x,y,z,k);        v=z/d.nz;       }
+               else if(!p.compare(L"kx"))      {       d.Momentum('x',x,y,z,k);        v=k/d.nx;       }
+               else if(!p.compare(L"ky"))      {       d.Momentum('y',x,y,z,k);        v=k/d.ny;       }
+               else if(!p.compare(L"kz"))      {       d.Momentum('z',x,y,z,k);        v=k/d.nz;       }
+               else if(!p.compare(L"aa"))      {       d.Momentum('a',x,y);    v=x;    }
+               else if(!p.compare(L"wa"))      {       d.Momentum('a',x,y);    v=y;    }
+               else if(!p.compare(L"sa"))      {       d.Momentum('a',x,y,z,k);v=z;    }
+               else if(!p.compare(L"ka"))      {       d.Momentum('a',x,y,z,k);v=k;    }
+               // if this is valid suffix when finish parsing (it can be mreal number)
+               if(mgl_isfin(v))        {       res.a[0] = v;   return res;     }
+       }
+       for(n=0;n<len;n++)      if(str[n]=='(') break;
+       if(n>=len)              // this is number or variable
+       {
+               HCDT v = (str!=L"#$mgl")?FindVar(head, str):0;
+               mglNum *f = arg?arg->FindNum(str.c_str()):0;
+               if(v)   res = v;
+               else if(f)      res.a[0] = f->d;
+               else if(!str.compare(L":"))             res.a[0] = -1;
+               else
+               {
+                       HCDT v=FindVar(head, L"#$mgl");
+                       if(v)   res.Create(v->GetNx(),v->GetNy(),v->GetNz());
+                       if(!str.compare(L"rnd"))        for(long i=0;i<res.GetNN();i++) res.a[i] = mgl_rnd();
+                       else if(!str.compare(L"nan"))   res = mreal(NAN);
+                       else if(!str.compare(L"inf"))   res = mreal(INFINITY);
+                       else if(!str.compare(L"pi"))    res = mreal(M_PI);
+                       else if(!str.compare(L"on"))    res = mreal(1.);
+                       else if(!str.compare(L"off"))   res = mreal(0.);
+                       else if(str[0]=='i')    // this is imaginary number
+                               res = dual(0,(str.length()>1 && str[1]>' ')?wcstod(str.c_str(),0):1);
+                       else res = mreal(wcstod(str.c_str(),0));        // this is real number
+               }
+               return res;
+       }
+       else
+       {
+               std::wstring nm = str.substr(0,n);
+               str = str.substr(n+1,len-n-2);  len -= n+2;
+               HCDT v = FindVar(head, nm);
+//             mglVar *v = arg->FindVar(nm.c_str());
+               if(!v && !nm.compare(0,7,L"jacobi_"))   nm = nm.substr(7);
+               if(v)   // subdata
+               {
+                       if(str[0]=='\'' && str[len-1]=='\'')    // this is column call
+                       {
+                               char *buf = new char[len];
+                               mgl_wcstombs(buf, str.substr(1).c_str(), len-1);        buf[len-1]=0;
+                               const mglData *vd = dynamic_cast<const mglData *>(v);
+                               if(vd)  res=vd->Column(buf);
+                               const mglDataC *vc = dynamic_cast<const mglDataC *>(v);
+                               if(vc)  res=vc->Column(buf);
+                               delete []buf;
+                       }
+                       else
+                       {
+                               mglData a1, a2, a3;
+                               a1.a[0] = a2.a[0] = a3.a[0] = -1;
+                               n=mglFindInText(str,",");
+                               if(n>0)
+                               {
+                                       long m=mglFindInText(str.substr(0,n),",");
+                                       if(m>0)
+                                       {
+                                               str[m]=0;
+                                               a1 = mglFormulaCalcC(str.substr(0,m), arg, head);
+                                               a2 = mglFormulaCalcC(str.substr(m+1,n-m-1), arg, head);
+                                               a3 = mglFormulaCalcC(str.substr(n+1), arg, head);
+                                       }
+                                       else
+                                       {
+                                               a1 = mglFormulaCalcC(str.substr(0,n), arg, head);
+                                               a2 = mglFormulaCalcC(str.substr(n+1), arg, head);
+                                       }
+                               }
+                               else    a1 = mglFormulaCalcC(str, arg, head);
+                               res = mglSubData(*v,a1,a2,a3);
+                       }
+               }
+               else if(nm[0]=='a')     // function
+               {
+                       if(!nm.compare(L"asin"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,asinc);       }
+                       else if(!nm.compare(L"acos"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,acosc);       }
+                       else if(!nm.compare(L"atan"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,atanc);       }
+                       else if(!nm.compare(L"arg"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,argc);        }
+                       else if(!nm.compare(L"abs"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,absc);        }
+               }
+               else if(nm[0]=='c')
+               {
+                       if(!nm.compare(L"cos"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,cosc);        }
+                       else if(!nm.compare(L"cosh") || !nm.compare(L"ch"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,coshc);       }
+               }
+               else if(!nm.compare(L"exp"))
+               {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,expc);        }
+               else if(nm[0]=='l')
+               {
+                       if(!nm.compare(L"log") || !nm.compare(L"ln"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,logc);        }
+                       else if(!nm.compare(L"lg"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,lgc); }
+               }
+               else if(nm[0]=='s')
+               {
+                       if(!nm.compare(L"sqrt"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,sqrtc);       }
+                       else if(!nm.compare(L"sin"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,sinc);        }
+                       else if(!nm.compare(L"sinh") || !nm.compare(L"sh"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,sinhc);       }
+               }
+               else if(nm[0]=='t')
+               {
+                       if(!nm.compare(L"tg") || !nm.compare(L"tan"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,tanc);        }
+                       else if(!nm.compare(L"tanh") || !nm.compare(L"th"))
+                       {       res=mglFormulaCalcC(str, arg, head);    mglApplyFuncC(res,tanhc);       }
+               }
+               else if(!nm.compare(L"pow"))
+               {
+                       n=mglFindInText(str,",");
+                       if(n<=0)        mglFormulaError=true;
+                       else    res = mglApplyOperC(str.substr(0,n),str.substr(n+1),arg, head, powc);
+               }
+               else if(!nm.compare(L"random"))
+               {       res=mglFormulaCalcC(str, arg, head);    register long n = res.GetNN(), i;
+                       for(i=0;i<n;i++)        res.a[i] = mgl_rnd();   }
+       }
+       return res;
 }
 //-----------------------------------------------------------------------------
index 3a3be14b63cdc31f22a3f211d9ffe7fc598c653b..b97d9b304d22a801fc0b95da08d7703ae6155816 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "mgl2/base.h"
 #include "mgl2/parser.h"
-#define iint(x)        long((x)+0.5)
+inline long iint(mreal x)      {return long(x+0.5);}
 wchar_t *mgl_str_copy(const char *s);
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_addlegend(mglGraph *gr, long , mglArg *a, const char *k, const char *)
@@ -39,16 +39,20 @@ int MGL_NO_EXPORT mgls_addlegend(mglGraph *gr, long , mglArg *a, const char *k,
 int MGL_NO_EXPORT mgls_addto(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dd"))             *(a[0].d) += *(a[1].d);
-       else if(!strcmp(k,"dn"))*(a[0].d) += a[1].v;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dd"))             *d += *(a[1].d);
+       else if(!strcmp(k,"dn"))*d += a[1].v;
        else    res = 1;        return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_sort(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dn"))     a[0].d->Sort(a[1].v, -1);
-       else if(!strcmp(k,"dnn"))       a[0].d->Sort(a[1].v, a[2].v);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dn"))     d->Sort(a[1].v, -1);
+       else if(!strcmp(k,"dnn"))       d->Sort(a[1].v, a[2].v);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -249,11 +253,24 @@ int MGL_NO_EXPORT mgls_clearlegend(mglGraph *gr, long , mglArg *, const char *k,
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_rasterize(mglGraph *gr, long , mglArg *, const char *, const char *)
+{
+       gr->Rasterize();        return 0;
+}
+//-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_background(mglGraph *gr, long , mglArg *a, const char *k, const char *)
+{
+       int res=0;
+       if(!strcmp(k,"s"))      gr->LoadBackground(a[0].s.c_str());
+       else if(!strcmp(k,"sn"))        gr->LoadBackground(a[0].s.c_str(),a[1].v);
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_clf(mglGraph *gr, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
        if(!strcmp(k,""))       gr->Clf();
-       else if(!strcmp(k,"s")) gr->Clf(a[0].s[0]);
+       else if(!strcmp(k,"s")) gr->Clf(a[0].s.c_str());
        else if(!strcmp(k,"nnn"))       gr->Clf(a[0].v,a[1].v,a[2].v);
        else res = 1;   return res;
 }
@@ -293,21 +310,27 @@ int MGL_NO_EXPORT mgls_crange(mglGraph *gr, long , mglArg *a, const char *k, con
 int MGL_NO_EXPORT mgls_crop(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dnns"))   a[0].d->Crop(iint(a[1].v),iint(a[2].v),a[3].s.c_str()[0]);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dnns"))   d->Crop(iint(a[1].v),iint(a[2].v),a[3].s.c_str()[0]);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_clean(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dn"))     a[0].d->Clean(iint(a[1].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dn"))     d->Clean(iint(a[1].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_cumsum(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->CumSum(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds"))     d->CumSum(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -375,10 +398,12 @@ int MGL_NO_EXPORT mgls_colorbar(mglGraph *gr, long , mglArg *a, const char *k, c
 int MGL_NO_EXPORT mgls_copy(mglGraph *gr, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dd"))     a[0].d->Set(*(a[1].d));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dd"))     d->Set(*(a[1].d));
        else if(!strcmp(k,"dds"))
-       {       a[0].d->Set(*(a[1].d)); gr->Fill(*(a[0].d), a[2].s.c_str());    }
-       else if(!strcmp(k,"dn"))        *(a[0].d) = a[1].v;
+       {       d->Set(*(a[1].d));      gr->Fill(*d, a[2].s.c_str());   }
+       else if(!strcmp(k,"dn"))        *d = a[1].v;
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -576,6 +601,38 @@ int MGL_NO_EXPORT mgls_rhomb(mglGraph *gr, long , mglArg *a, const char *k, cons
        else res = 1;   gr->Self()->LoadState();        return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_polygon(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
+{
+       int res=0;      gr->Self()->SaveState(opt);
+       if(!strcmp(k,"nnnnn"))
+               gr->Polygon(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), iint(a[4].v));
+       else if(!strcmp(k,"nnnnns"))
+               gr->Polygon(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), iint(a[4].v), a[5].s.c_str());
+       else if(!strcmp(k,"nnnnnnn"))
+               gr->Polygon(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), iint(a[6].v));
+       else if(!strcmp(k,"nnnnnnns"))
+               gr->Polygon(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v,a[5].v), iint(a[6].v), a[7].s.c_str());
+       else res = 1;   gr->Self()->LoadState();        return res;
+}
+//-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_arc(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
+{
+       int res=0;      gr->Self()->SaveState(opt);
+       if(!strcmp(k,"nnnnn"))
+               gr->Arc(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].v);
+       else if(!strcmp(k,"nnnnns"))
+               gr->Arc(mglPoint(a[0].v,a[1].v,NAN), mglPoint(a[2].v,a[3].v,NAN), a[4].v, a[5].s.c_str());
+       else if(!strcmp(k,"nnnnnn"))
+               gr->Arc(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v), a[5].v);
+       else if(!strcmp(k,"nnnnnns"))
+               gr->Arc(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v), a[5].v, a[6].s.c_str());
+       else if(!strcmp(k,"nnnnnnnnnn"))
+               gr->Arc(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v, a[5].v), mglPoint(a[6].v,a[7].v, a[8].v), a[9].v);
+       else if(!strcmp(k,"nnnnnnnnnns"))
+               gr->Arc(mglPoint(a[0].v,a[1].v,a[2].v), mglPoint(a[3].v,a[4].v, a[5].v), mglPoint(a[6].v,a[7].v, a[8].v), a[9].v, a[10].s.c_str());
+       else res = 1;   gr->Self()->LoadState();        return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_dens(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
@@ -628,24 +685,30 @@ int MGL_NO_EXPORT mgls_densz(mglGraph *gr, long , mglArg *a, const char *k, cons
 int MGL_NO_EXPORT mgls_divto(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dd"))             *(a[0].d) /= *(a[1].d);
-       else if(!strcmp(k,"dn"))        *(a[0].d) /= a[1].v;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dd"))             *d /= *(a[1].d);
+       else if(!strcmp(k,"dn"))        *d /= a[1].v;
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_multo(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dd"))             *(a[0].d) *= *(a[1].d);
-       else if(!strcmp(k,"dn"))        *(a[0].d) *= a[1].v;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dd"))             *d *= *(a[1].d);
+       else if(!strcmp(k,"dn"))        *d *= a[1].v;
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_subto(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dd"))             *(a[0].d) -= *(a[1].d);
-       else if(!strcmp(k,"dn"))        *(a[0].d) -= a[1].v;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dd"))             *d -= *(a[1].d);
+       else if(!strcmp(k,"dn"))        *d -= a[1].v;
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -664,16 +727,20 @@ int MGL_NO_EXPORT mgls_dots(mglGraph *gr, long , mglArg *a, const char *k, const
 int MGL_NO_EXPORT mgls_diff(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->Diff(a[1].s.c_str());
-       else if(!strcmp(k,"ddd"))       a[0].d->Diff(*(a[1].d), *(a[2].d));
-       else if(!strcmp(k,"dddd"))      a[0].d->Diff(*(a[1].d), *(a[2].d), *(a[3].d));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds"))     d->Diff(a[1].s.c_str());
+       else if(!strcmp(k,"ddd"))       d->Diff(*(a[1].d), *(a[2].d));
+       else if(!strcmp(k,"dddd"))      d->Diff(*(a[1].d), *(a[2].d), *(a[3].d));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_diff2(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->Diff2(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds"))     d->Diff2(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -807,29 +874,45 @@ int MGL_NO_EXPORT mgls_grad(mglGraph *gr, long , mglArg *a, const char *k, const
 int MGL_NO_EXPORT mgls_fill(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
-       if(!strcmp(k,"dnn"))    a[0].d->Fill(a[1].v,a[2].v);
-       else if(!strcmp(k,"dnns"))      a[0].d->Fill(a[1].v,a[2].v,a[3].s.c_str()[0]);
-       else if(!strcmp(k,"ds"))        gr->Fill(*(a[0].d),a[1].s.c_str(),opt);
-       else if(!strcmp(k,"dsd"))       gr->Fill(*(a[0].d),a[1].s.c_str(), *(a[2].d),opt);
-       else if(!strcmp(k,"dsdd"))      gr->Fill(*(a[0].d),a[1].s.c_str(), *(a[2].d), *(a[3].d),opt);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dnn"))    d->Fill(a[1].v,a[2].v);
+       else if(!strcmp(k,"dnns"))      d->Fill(a[1].v,a[2].v,a[3].s.c_str()[0]);
+       else if(!strcmp(k,"ds"))        gr->Fill(*d,a[1].s.c_str(),opt);
+       else if(!strcmp(k,"dsd"))       gr->Fill(*d,a[1].s.c_str(), *(a[2].d),opt);
+       else if(!strcmp(k,"dsdd"))      gr->Fill(*d,a[1].s.c_str(), *(a[2].d), *(a[3].d),opt);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_refill(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
-       if(!strcmp(k,"ddd"))    gr->Refill(*(a[0].d),*(a[1].d),*(a[2].d),-1,opt);
-       else if(!strcmp(k,"dddn"))      gr->Refill(*(a[0].d),*(a[1].d),*(a[2].d),iint(a[3].v),opt);
-       else if(!strcmp(k,"dddd"))      gr->Refill(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),-1,opt);
-       else if(!strcmp(k,"ddddn"))     gr->Refill(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),iint(a[4].v),opt);
-       else if(!strcmp(k,"ddddd"))     gr->Refill(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),opt);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ddd"))    gr->Refill(*d,*(a[1].d),*(a[2].d),-1,opt);
+       else if(!strcmp(k,"dddn"))      gr->Refill(*d,*(a[1].d),*(a[2].d),iint(a[3].v),opt);
+       else if(!strcmp(k,"dddd"))      gr->Refill(*d,*(a[1].d),*(a[2].d),*(a[3].d),-1,opt);
+       else if(!strcmp(k,"ddddn"))     gr->Refill(*d,*(a[1].d),*(a[2].d),*(a[3].d),iint(a[4].v),opt);
+       else if(!strcmp(k,"ddddd"))     gr->Refill(*d,*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),opt);
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_gspline(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
+{
+       int res=0;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ddd"))    d->RefillGS(*(a[1].d),*(a[2].d),gr->Self()->Min.x,gr->Self()->Max.x,-1);
+       else if(!strcmp(k,"dddn"))      d->RefillGS(*(a[1].d),*(a[2].d),gr->Self()->Min.x,gr->Self()->Max.x,iint(a[3].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_fillsample(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->FillSample(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds"))     d->FillSample(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -967,31 +1050,39 @@ int MGL_NO_EXPORT mgls_legendmarks(mglGraph *gr, long , mglArg *a, const char *k
 int MGL_NO_EXPORT mgls_modify(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->Modify(a[1].s.c_str());
-       else if(!strcmp(k,"dsn"))       a[0].d->Modify(a[1].s.c_str(), iint(a[2].v));
-       else if(!strcmp(k,"dsd"))       a[0].d->Modify(a[1].s.c_str(),*(a[2].d));
-       else if(!strcmp(k,"dsdd"))      a[0].d->Modify(a[1].s.c_str(),*(a[2].d),*(a[3].d));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds"))     d->Modify(a[1].s.c_str());
+       else if(!strcmp(k,"dsn"))       d->Modify(a[1].s.c_str(), iint(a[2].v));
+       else if(!strcmp(k,"dsd"))       d->Modify(a[1].s.c_str(),*(a[2].d));
+       else if(!strcmp(k,"dsdd"))      d->Modify(a[1].s.c_str(),*(a[2].d),*(a[3].d));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_max(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dds"))    *(a[0].d) = a[1].d->Max(a[2].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dds"))    *d = mglData(true,mgl_data_max_dir(a[1].d,a[2].s.c_str()));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_min(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dds"))    *(a[0].d) = a[1].d->Min(a[2].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dds"))    *d = mglData(true,mgl_data_min_dir(a[1].d,a[2].s.c_str()));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_sum(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dds"))    *(a[0].d) = a[1].d->Sum(a[2].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dds"))    *d = mglData(true,mgl_data_sum(a[1].d,a[2].s.c_str()));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1050,10 +1141,12 @@ int MGL_NO_EXPORT mgls_read(mglGraph *gr, long , mglArg *a, const char *k, const
 {
        int res=0;
        bool rr=true;
-       if(!strcmp(k,"ds"))     rr=a[0].d->Read(a[1].s.c_str());
-       else if(!strcmp(k,"dsn"))       rr=a[0].d->Read(a[1].s.c_str(), iint(a[2].v));
-       else if(!strcmp(k,"dsnn"))      rr=a[0].d->Read(a[1].s.c_str(), iint(a[2].v),iint(a[3].v));
-       else if(!strcmp(k,"dsnnn"))     rr=a[0].d->Read(a[1].s.c_str(), iint(a[2].v),iint(a[3].v),iint(a[4].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds"))     rr=d->Read(a[1].s.c_str());
+       else if(!strcmp(k,"dsn"))       rr=d->Read(a[1].s.c_str(), iint(a[2].v));
+       else if(!strcmp(k,"dsnn"))      rr=d->Read(a[1].s.c_str(), iint(a[2].v),iint(a[3].v));
+       else if(!strcmp(k,"dsnnn"))     rr=d->Read(a[1].s.c_str(), iint(a[2].v),iint(a[3].v),iint(a[4].v));
        if(!rr) gr->SetWarn(mglWarnFile,"Read");
        return res;
 }
@@ -1062,8 +1155,10 @@ int MGL_NO_EXPORT mgls_readmat(mglGraph *gr, long , mglArg *a, const char *k, co
 {
        int res=0;
        bool rr=true;
-       if(!strcmp(k,"ds")) rr=a[0].d->ReadMat(a[1].s.c_str());
-       else if(!strcmp(k,"dsn")) rr=a[0].d->ReadMat(a[1].s.c_str(), iint(a[2].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds")) rr=d->ReadMat(a[1].s.c_str());
+       else if(!strcmp(k,"dsn")) rr=d->ReadMat(a[1].s.c_str(), iint(a[2].v));
        else res = 1;
        if(!rr) gr->SetWarn(mglWarnFile,"ReadMat");
        return res;
@@ -1073,11 +1168,13 @@ int MGL_NO_EXPORT mgls_readall(mglGraph *gr, long , mglArg *a, const char *k, co
 {
        int res=0;
        bool rr=true;
-       if(!strcmp(k,"ds")) rr=a[0].d->ReadAll(a[1].s.c_str());
-       else if(!strcmp(k,"dsn")) rr=a[0].d->ReadAll(a[1].s.c_str(), a[2].v);
-       else if(!strcmp(k,"dsnn"))      rr=a[0].d->ReadRange(a[1].s.c_str(), a[2].v, a[3].v);
-       else if(!strcmp(k,"dsnnn"))     rr=a[0].d->ReadRange(a[1].s.c_str(), a[2].v, a[3].v, a[4].v);
-       else if(!strcmp(k,"dsnnnn"))rr=a[0].d->ReadRange(a[1].s.c_str(), a[2].v, a[3].v, a[4].v, a[5].v);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds")) rr=d->ReadAll(a[1].s.c_str());
+       else if(!strcmp(k,"dsn")) rr=d->ReadAll(a[1].s.c_str(), a[2].v);
+       else if(!strcmp(k,"dsnn"))      rr=d->ReadRange(a[1].s.c_str(), a[2].v, a[3].v);
+       else if(!strcmp(k,"dsnnn"))     rr=d->ReadRange(a[1].s.c_str(), a[2].v, a[3].v, a[4].v);
+       else if(!strcmp(k,"dsnnnn"))rr=d->ReadRange(a[1].s.c_str(), a[2].v, a[3].v, a[4].v, a[5].v);
        else res = 1;
        if(!rr) gr->SetWarn(mglWarnFile,"ReadMat");
        return res;
@@ -1086,7 +1183,9 @@ int MGL_NO_EXPORT mgls_readall(mglGraph *gr, long , mglArg *a, const char *k, co
 int MGL_NO_EXPORT mgls_readhdf(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dss"))    a[0].d->ReadHDF(a[1].s.c_str(), a[2].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dss"))    d->ReadHDF(a[1].s.c_str(), a[2].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1143,9 +1242,11 @@ int MGL_NO_EXPORT mgls_face(mglGraph *gr, long , mglArg *a, const char *k, const
 int MGL_NO_EXPORT mgls_resize(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ddn"))    *(a[0].d) = a[1].d->Resize(iint(a[2].v));
-       else if(!strcmp(k,"ddnn"))      *(a[0].d) = a[1].d->Resize(iint(a[2].v), iint(a[3].v));
-       else if(!strcmp(k,"ddnnn"))     *(a[0].d) = a[1].d->Resize(iint(a[2].v), iint(a[3].v), iint(a[4].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ddn"))    *d = mglData(true,mgl_data_resize_box(a[1].d, iint(a[2].v),0,0, 0,1, 0,1, 0,1));
+       else if(!strcmp(k,"ddnn"))      *d = mglData(true,mgl_data_resize_box(a[1].d, iint(a[2].v),iint(a[3].v),0, 0,1, 0,1, 0,1));
+       else if(!strcmp(k,"ddnnn"))     *d = mglData(true,mgl_data_resize_box(a[1].d, iint(a[2].v),iint(a[3].v),iint(a[4].v), 0,1, 0,1, 0,1));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1192,22 +1293,29 @@ int MGL_NO_EXPORT mgls_save(mglGraph *, long , mglArg *a, const char *k, const c
 int MGL_NO_EXPORT mgls_smooth(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"d"))      a[0].d->Smooth();
-       else if(!strcmp(k,"ds"))        a[0].d->Smooth(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"d"))      d->Smooth();
+       else if(!strcmp(k,"ds"))        d->Smooth(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_swap(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->Swap(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds"))     d->Swap(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_idset(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->SetColumnId(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       mglDataC *c = dynamic_cast<mglDataC *>(a[0].d);
+       if(!strcmp(k,"ds") && d)        d->SetColumnId(a[1].s.c_str());
+       else if(!strcmp(k,"ds") && c)   c->SetColumnId(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1296,20 +1404,24 @@ int MGL_NO_EXPORT mgls_radar(mglGraph *gr, long , mglArg *a, const char *k, cons
 int MGL_NO_EXPORT mgls_squeeze(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dn"))     a[0].d->Squeeze(iint(a[1].v));
-       else if(!strcmp(k,"dnn"))       a[0].d->Squeeze(iint(a[1].v), iint(a[2].v));
-       else if(!strcmp(k,"dnnn"))      a[0].d->Squeeze(iint(a[1].v), iint(a[2].v),iint(a[3].v));
-       else if(!strcmp(k,"dnnnn"))     a[0].d->Squeeze(iint(a[1].v), iint(a[2].v),iint(a[3].v), a[4].v);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dn"))     d->Squeeze(iint(a[1].v));
+       else if(!strcmp(k,"dnn"))       d->Squeeze(iint(a[1].v), iint(a[2].v));
+       else if(!strcmp(k,"dnnn"))      d->Squeeze(iint(a[1].v), iint(a[2].v),iint(a[3].v));
+       else if(!strcmp(k,"dnnnn"))     d->Squeeze(iint(a[1].v), iint(a[2].v),iint(a[3].v), a[4].v);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_stfad(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
        if(!strcmp(k,"dddn"))
-               *(a[0].d) = mglSTFA(*(a[1].d),*(a[2].d), iint(a[3].v));
+               *d = mglSTFA(*(a[1].d),*(a[2].d), iint(a[3].v));
        else if(!strcmp(k,"dddns"))
-               *(a[0].d) = mglSTFA(*(a[1].d),*(a[2].d), iint(a[3].v), a[4].s.c_str()[0]);
+               *d = mglSTFA(*(a[1].d),*(a[2].d), iint(a[3].v), a[4].s.c_str()[0]);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1410,7 +1522,7 @@ int MGL_NO_EXPORT mgls_multiplot(mglGraph *gr, long , mglArg *a, const char *k,
        if(!strcmp(k,"nnnnn"))
                gr->MultiPlot(iint(a[0].v), iint(a[1].v), iint(a[2].v), iint(a[3].v), iint(a[4].v));
        else if(!strcmp(k,"nnnnns"))
-               gr->MultiPlot(iint(a[0].v), iint(a[1].v), iint(a[2].v), iint(a[3].v), iint(a[4].v), a[3].s.c_str());
+               gr->MultiPlot(iint(a[0].v), iint(a[1].v), iint(a[2].v), iint(a[3].v), iint(a[4].v), a[5].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1426,16 +1538,23 @@ int MGL_NO_EXPORT mgls_title(mglGraph *gr, long , mglArg *a, const char *k, cons
 int MGL_NO_EXPORT mgls_column(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dds"))    *(a[0].d) = a[1].d->Column(a[2].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dds"))    *d = mglData(true,mgl_data_column(a[1].d,a[2].s.c_str()));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_subdata(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ddn"))    *(a[0].d) = a[1].d->SubData(iint(a[2].v));
-       else if(!strcmp(k,"ddnn"))      *(a[0].d) = a[1].d->SubData(iint(a[2].v), iint(a[3].v));
-       else if(!strcmp(k,"ddnnn"))     *(a[0].d) = a[1].d->SubData(iint(a[2].v), iint(a[3].v), iint(a[4].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ddn"))    *d = mglData(true,mgl_data_subdata(a[1].d, iint(a[2].v), -1, -1));
+       else if(!strcmp(k,"ddnn"))      *d = mglData(true,mgl_data_subdata(a[1].d, iint(a[2].v), iint(a[3].v), -1));
+       else if(!strcmp(k,"ddnnn"))     *d = mglData(true,mgl_data_subdata(a[1].d, iint(a[2].v), iint(a[3].v), iint(a[4].v)));
+       else if(!strcmp(k,"ddd"))       *d = mglSubData(*(a[1].d), *(a[2].d));
+       else if(!strcmp(k,"dddd"))      *d = mglSubData(*(a[1].d), *(a[2].d), *(a[3].d));
+       else if(!strcmp(k,"ddddd"))     *d = mglSubData(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d));
        else res = 1;
        return res;
 }
@@ -1443,7 +1562,9 @@ int MGL_NO_EXPORT mgls_subdata(mglGraph *, long , mglArg *a, const char *k, cons
 int MGL_NO_EXPORT mgls_trace(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dd"))     *(a[0].d) = a[1].d->Trace();
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dd"))     *d = mglData(true,mgl_data_trace(a[1].d));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1515,21 +1636,24 @@ int MGL_NO_EXPORT mgls_transptype(mglGraph *gr, long , mglArg *a, const char *k,
 int MGL_NO_EXPORT mgls_fourier(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dds"))    mglFourier(*(a[0].d),*(a[1].d),a[2].s.c_str());
+       mglData *re = dynamic_cast<mglData *>(a[0].d), *im = dynamic_cast<mglData *>(a[1].d);
+       if(!strcmp(k,"dds") && re && im)        mglFourier(*re,*im,a[2].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_transform(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dsdd"))   *(a[0].d) = mglTransform(*(a[2].d),*(a[3].d),a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"dsdd") && d)      *d = mglTransform(*(a[2].d),*(a[3].d),a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_transforma(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dsdd"))   *(a[0].d) = mglTransformA(*(a[2].d),*(a[3].d),a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"dsdd") && d)      *d = mglTransformA(*(a[2].d),*(a[3].d),a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1613,9 +1737,27 @@ int MGL_NO_EXPORT mgls_tricont(mglGraph *gr, long , mglArg *a, const char *k, co
        else if(!strcmp(k,"ddddds"))
                gr->TriContV(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.c_str(),opt);
        else if(!strcmp(k,"dddddd"))
-               gr->TriContV(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt);
+               gr->TriCont(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt);
        else if(!strcmp(k,"dddddds"))
-               gr->TriContV(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.c_str(),opt);
+               gr->TriCont(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.c_str(),opt);
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_tricontv(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
+{
+       int res=0;
+       if(!strcmp(k,"dddd"))
+               gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),"",opt);
+       else if(!strcmp(k,"dddds"))
+               gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),a[4].s.c_str(),opt);
+       else if(!strcmp(k,"ddddd"))
+               gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),"",opt);
+       else if(!strcmp(k,"ddddds"))
+               gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),a[5].s.c_str(),opt);
+       else if(!strcmp(k,"dddddd"))
+               gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),"",opt);
+       else if(!strcmp(k,"dddddds"))
+               gr->TriContVt(*(a[0].d),*(a[1].d),*(a[2].d),*(a[3].d),*(a[4].d),*(a[5].d),a[6].s.c_str(),opt);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1629,8 +1771,10 @@ int MGL_NO_EXPORT mgls_ternary(mglGraph *gr, long , mglArg *a, const char *k, co
 int MGL_NO_EXPORT mgls_transpose(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"d"))      a[0].d->Transpose();
-       else if(!strcmp(k,"ds"))        a[0].d->Transpose(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"d"))      d->Transpose();
+       else if(!strcmp(k,"ds"))        d->Transpose(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1778,12 +1922,24 @@ int MGL_NO_EXPORT mgls_zrange(mglGraph *gr, long , mglArg *a, const char *k, con
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_ctick(mglGraph *gr, long , mglArg *a, const char *k, const char *)
+{
+       int res=0;
+       if(!strcmp(k,"s"))      gr->SetTickTempl('c',a[0].w.c_str());
+       else if(!strcmp(k,"n")) gr->SetTicks('c',a[0].v,0,0);
+       else if(!strcmp(k,"ns"))        gr->SetTicks('c',a[0].v,0,0,a[1].w.c_str());
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_xtick(mglGraph *gr, long n, mglArg *a, const char *k, const char *)
 {
        int res=0;
        if(!strcmp(k,"n"))      gr->SetTicks('x', a[0].v);
+       else if(!strcmp(k,"ns"))        gr->SetTicks('x', a[0].v, 0, NAN, a[1].w.c_str());
        else if(!strcmp(k,"nn"))        gr->SetTicks('x', a[0].v, iint(a[1].v));
+       else if(!strcmp(k,"nns"))       gr->SetTicks('x', a[0].v, iint(a[1].v), NAN, a[2].w.c_str());
        else if(!strcmp(k,"nnn"))       gr->SetTicks('x', a[0].v, iint(a[1].v), a[2].v);
+       else if(!strcmp(k,"nnns"))      gr->SetTicks('x', a[0].v, iint(a[1].v), a[2].v, a[3].w.c_str());
        else if(!strcmp(k,"s"))         gr->SetTickTempl('x',a[0].w.c_str());
        else if(!strcmp(k,"ds"))        gr->SetTicksVal('x', *(a[0].d), a[1].w.c_str());
        else if(!strcmp(k,"dsn"))       gr->SetTicksVal('x', *(a[0].d), a[1].w.c_str(), a[2].v);
@@ -1796,7 +1952,7 @@ int MGL_NO_EXPORT mgls_xtick(mglGraph *gr, long n, mglArg *a, const char *k, con
                        {       v[i] = a[2*i].v;        s += a[2*i+1].w+L"\n";  }
                        else    break;
                }
-               gr->SetTicksVal('x',mglData(i,v),s.c_str());
+               gr->SetTicksVal('x',mglData(i,v),s.c_str(),a[2*i].type==2?a[2*i].v:0);
        }
        else res = 1;   return res;
 }
@@ -1805,8 +1961,11 @@ int MGL_NO_EXPORT mgls_ytick(mglGraph *gr, long n, mglArg *a, const char *k, con
 {
        int res=0;
        if(!strcmp(k,"n"))      gr->SetTicks('y', a[0].v);
+       else if(!strcmp(k,"ns"))        gr->SetTicks('y', a[0].v, 0, NAN, a[1].w.c_str());
        else if(!strcmp(k,"nn"))        gr->SetTicks('y', a[0].v, iint(a[1].v));
+       else if(!strcmp(k,"nns"))       gr->SetTicks('y', a[0].v, iint(a[1].v), NAN, a[2].w.c_str());
        else if(!strcmp(k,"nnn"))       gr->SetTicks('y', a[0].v, iint(a[1].v), a[2].v);
+       else if(!strcmp(k,"nnns"))      gr->SetTicks('y', a[0].v, iint(a[1].v), a[2].v, a[3].w.c_str());
        else if(!strcmp(k,"s"))         gr->SetTickTempl('y',a[0].w.c_str());
        else if(!strcmp(k,"ds"))        gr->SetTicksVal('y', *(a[0].d), a[1].w.c_str());
        else if(!strcmp(k,"dsn"))       gr->SetTicksVal('y', *(a[0].d), a[1].w.c_str(), a[2].v);
@@ -1828,8 +1987,11 @@ int MGL_NO_EXPORT mgls_ztick(mglGraph *gr, long n, mglArg *a, const char *k, con
 {
        int res=0;
        if(!strcmp(k,"n"))      gr->SetTicks('z', a[0].v);
+       else if(!strcmp(k,"ns"))        gr->SetTicks('z', a[0].v, 0, NAN, a[1].w.c_str());
        else if(!strcmp(k,"nn"))        gr->SetTicks('z', a[0].v, iint(a[1].v));
+       else if(!strcmp(k,"nns"))       gr->SetTicks('z', a[0].v, iint(a[1].v), NAN, a[2].w.c_str());
        else if(!strcmp(k,"nnn"))       gr->SetTicks('z', a[0].v, iint(a[1].v), a[2].v);
+       else if(!strcmp(k,"nnns"))      gr->SetTicks('z', a[0].v, iint(a[1].v), a[2].v, a[3].w.c_str());
        else if(!strcmp(k,"s"))         gr->SetTickTempl('z',a[0].w.c_str());
        else if(!strcmp(k,"ds"))        gr->SetTicksVal('z', *(a[0].d), a[1].w.c_str());
        else if(!strcmp(k,"dsn"))       gr->SetTicksVal('z', *(a[0].d), a[1].w.c_str(), a[2].v);
@@ -1862,15 +2024,18 @@ int MGL_NO_EXPORT mgls_error(mglGraph *gr, long , mglArg *a, const char *k, cons
 int MGL_NO_EXPORT mgls_extend(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dn"))     a[0].d->Extend(iint(a[1].v));
-       else if(!strcmp(k,"dnn"))       a[0].d->Extend(iint(a[1].v),iint(a[2].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dn"))     d->Extend(iint(a[1].v));
+       else if(!strcmp(k,"dnn"))       d->Extend(iint(a[1].v),iint(a[2].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_join(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dd"))     a[0].d->Join(*(a[1].d));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"dd") && d)        d->Join(*(a[1].d));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1900,7 +2065,8 @@ int MGL_NO_EXPORT mgls_info(mglGraph *gr, long , mglArg *a, const char *k, const
 int MGL_NO_EXPORT mgls_integrate(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->Integral(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"ds") && d)        d->Integral(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -1973,78 +2139,90 @@ int MGL_NO_EXPORT mgls_origin(mglGraph *gr, long , mglArg *a, const char *k, con
 int MGL_NO_EXPORT mgls_norm(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dnn"))    a[0].d->Norm(a[1].v,a[2].v);
-       else if(!strcmp(k,"dnnn"))      a[0].d->Norm(a[1].v,a[2].v,a[3].v!=0);
-       else if(!strcmp(k,"dnnnn"))     a[0].d->Norm(a[1].v,a[2].v,a[3].v!=0,iint(a[4].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dnn"))    d->Norm(a[1].v,a[2].v);
+       else if(!strcmp(k,"dnnn"))      d->Norm(a[1].v,a[2].v,a[3].v!=0);
+       else if(!strcmp(k,"dnnnn"))     d->Norm(a[1].v,a[2].v,a[3].v!=0,iint(a[4].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_hist(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
-       if(!strcmp(k,"ddd"))    *(a[0].d) = gr->Hist(*(a[1].d), *(a[2].d),opt);
-       else if(!strcmp(k,"dddd"))      *(a[0].d) = gr->Hist(*(a[1].d), *(a[2].d), *(a[3].d),opt);
-       else if(!strcmp(k,"ddddd"))     *(a[0].d) = gr->Hist(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d),opt);
-       else if(!strcmp(k,"ddnnn"))     *(a[0].d) = a[1].d->Hist(int(a[2].v+0.5), a[3].v, a[4].v);
-       else if(!strcmp(k,"ddnnnn"))    *(a[0].d) = a[1].d->Hist(int(a[2].v+0.5), a[3].v, a[4].v, int(a[5].v+0.5));
-       else if(!strcmp(k,"dddnnn"))    *(a[0].d) = a[1].d->Hist(*(a[2].d), int(a[3].v+0.5), a[4].v, a[5].v);
-       else if(!strcmp(k,"dddnnnn"))   *(a[0].d) = a[1].d->Hist(*(a[2].d), int(a[3].v+0.5), a[4].v, a[5].v, int(a[6].v+0.5));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ddd"))            *d = gr->Hist(*(a[1].d), *(a[2].d),opt);
+       else if(!strcmp(k,"dddd"))      *d = gr->Hist(*(a[1].d), *(a[2].d), *(a[3].d),opt);
+       else if(!strcmp(k,"ddddd"))     *d = gr->Hist(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d),opt);
+       else if(!strcmp(k,"ddnnn"))     *d = mglData(true,mgl_data_hist(a[1].d,int(a[2].v+0.5), a[3].v, a[4].v, 0));
+       else if(!strcmp(k,"ddnnnn"))    *d = mglData(true,mgl_data_hist(a[1].d,int(a[2].v+0.5), a[3].v, a[4].v, int(a[5].v+0.5)));
+       else if(!strcmp(k,"dddnnn"))    *d = mglData(true,mgl_data_hist_w(a[1].d,a[2].d, int(a[3].v+0.5), a[4].v, a[5].v, 0));
+       else if(!strcmp(k,"dddnnnn"))   *d = mglData(true,mgl_data_hist_w(a[1].d,a[2].d, int(a[3].v+0.5), a[4].v, a[5].v, int(a[6].v+0.5)));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_mirror(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->Mirror(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"ds") && d)        d->Mirror(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_hankel(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->Hankel(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"ds") && d)        d->Hankel(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_sinfft(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->SinFFT(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"ds") && d)        d->SinFFT(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_cosfft(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->CosFFT(a[1].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"ds") && d)        d->CosFFT(a[1].s.c_str());
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_new(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
-       if(!strcmp(k,"dn"))     a[0].d->Create(iint(a[1].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dn"))     d->Create(iint(a[1].v));
        else if(!strcmp(k,"dns"))
-       {       a[0].d->Create(iint(a[1].v));
-               a[0].d->Fill(gr->Self(),a[2].s.c_str(),opt);    }
-       else if(!strcmp(k,"dnn"))       a[0].d->Create(iint(a[1].v),iint(a[2].v));
+       {       d->Create(iint(a[1].v));
+               d->Fill(gr->Self(),a[2].s.c_str(),opt); }
+       else if(!strcmp(k,"dnn"))       d->Create(iint(a[1].v),iint(a[2].v));
        else if(!strcmp(k,"dnns"))
-       {       a[0].d->Create(iint(a[1].v),iint(a[2].v));
-               a[0].d->Fill(gr->Self(),a[3].s.c_str(),opt);    }
-       else if(!strcmp(k,"dnnn"))      a[0].d->Create(iint(a[1].v),iint(a[2].v),iint(a[3].v));
+       {       d->Create(iint(a[1].v),iint(a[2].v));
+               d->Fill(gr->Self(),a[3].s.c_str(),opt); }
+       else if(!strcmp(k,"dnnn"))      d->Create(iint(a[1].v),iint(a[2].v),iint(a[3].v));
        else if(!strcmp(k,"dnnns"))
-       {       a[0].d->Create(iint(a[1].v),iint(a[2].v),iint(a[3].v));
-               a[0].d->Fill(gr->Self(),a[4].s.c_str(),opt);    }
+       {       d->Create(iint(a[1].v),iint(a[2].v),iint(a[3].v));
+               d->Fill(gr->Self(),a[4].s.c_str(),opt); }
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_var(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);   // TODO use mglDataV here?!
+       if(!d)  return 1;
        if(!strcmp(k,"dnn"))
-       {       a[0].d->Create(iint(a[1].v));   a[0].d->Fill(a[2].v, NAN);      }
+       {       d->Create(iint(a[1].v));        d->Fill(a[2].v, NAN);   }
        else if(!strcmp(k,"dnnn"))
-       {       a[0].d->Create(iint(a[1].v));   a[0].d->Fill(a[2].v, a[3].v);   }
+       {       d->Create(iint(a[1].v));        d->Fill(a[2].v, a[3].v);        }
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2093,62 +2271,102 @@ int MGL_NO_EXPORT mgls_facez(mglGraph *gr, long , mglArg *a, const char *k, cons
 int MGL_NO_EXPORT mgls_normsl(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dnn"))    a[0].d->NormSl(a[1].v, a[2].v);
-       else if(!strcmp(k,"dnns"))      a[0].d->NormSl(a[1].v, a[2].v, a[3].s.c_str()[0]);
-       else if(!strcmp(k,"dnnsn"))     a[0].d->NormSl(a[1].v, a[2].v, a[3].s.c_str()[0],a[4].v);
-       else if(!strcmp(k,"dnnsnn"))a[0].d->NormSl(a[1].v, a[2].v, a[3].s.c_str()[0],a[4].v,a[5].v);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dnn"))    d->NormSl(a[1].v, a[2].v);
+       else if(!strcmp(k,"dnns"))      d->NormSl(a[1].v, a[2].v, a[3].s.c_str()[0]);
+       else if(!strcmp(k,"dnnsn"))     d->NormSl(a[1].v, a[2].v, a[3].s.c_str()[0],a[4].v);
+       else if(!strcmp(k,"dnnsnn"))d->NormSl(a[1].v, a[2].v, a[3].s.c_str()[0],a[4].v,a[5].v);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_momentum(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dds"))    *(a[0].d) = a[1].d->Momentum('z', a[2].s.c_str());
-       else if(!strcmp(k,"ddss"))      *(a[0].d) = a[1].d->Momentum(a[3].s.c_str()[0], a[2].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dds"))    *d = mglData(true,mgl_data_momentum(a[1].d,'z', a[2].s.c_str()));
+       else if(!strcmp(k,"ddss"))      *d = mglData(true,mgl_data_momentum(a[1].d,a[3].s.c_str()[0], a[2].s.c_str()));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_fit(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
        if(!strcmp(k,"dddddssd"))
-               *(a[0].d) = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.c_str(), a[6].s.c_str(), *(a[7].d),opt);
+       {
+               mglData *i = dynamic_cast<mglData *>(a[7].d);
+               if(i)   *d = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.c_str(), a[6].s.c_str(), *i,opt);
+               else    res = 1;
+       }
        else if(!strcmp(k,"dddddss"))
-               *(a[0].d) = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.c_str(), a[6].s.c_str(),opt);
+               *d = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.c_str(), a[6].s.c_str(),opt);
        else if(!strcmp(k,"ddddssd"))
-               *(a[0].d) = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.c_str(), a[5].s.c_str(), *(a[6].d),opt);
+       {
+               mglData *i = dynamic_cast<mglData *>(a[6].d);
+               if(i)   *d = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.c_str(), a[5].s.c_str(), *i,opt);
+               else    res = 1;
+       }
        else if(!strcmp(k,"ddddss"))
-               *(a[0].d) = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.c_str(), a[5].s.c_str(),opt);
+               *d = gr->Fit(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.c_str(), a[5].s.c_str(),opt);
        else if(!strcmp(k,"dddssd"))
-               *(a[0].d) = gr->Fit(*(a[1].d), *(a[2].d), a[3].s.c_str(), a[4].s.c_str(), *(a[5].d),opt);
+       {
+               mglData *i = dynamic_cast<mglData *>(a[5].d);
+               if(i)   *d = gr->Fit(*(a[1].d), *(a[2].d), a[3].s.c_str(), a[4].s.c_str(), *i,opt);
+               else    res = 1;
+       }
        else if(!strcmp(k,"dddss"))
-               *(a[0].d) = gr->Fit(*(a[1].d), *(a[2].d), a[3].s.c_str(), a[4].s.c_str(),opt);
+               *d = gr->Fit(*(a[1].d), *(a[2].d), a[3].s.c_str(), a[4].s.c_str(),opt);
        else if(!strcmp(k,"ddssd"))
-               *(a[0].d) = gr->Fit(*(a[1].d), a[2].s.c_str(), a[3].s.c_str(), *(a[4].d),opt);
+       {
+               mglData *i = dynamic_cast<mglData *>(a[4].d);
+               if(i)   *d = gr->Fit(*(a[1].d), a[2].s.c_str(), a[3].s.c_str(), *i,opt);
+               else    res = 1;
+       }
        else if(!strcmp(k,"ddss"))
-               *(a[0].d) = gr->Fit(*(a[1].d), a[2].s.c_str(), a[3].s.c_str(),opt);
+               *d = gr->Fit(*(a[1].d), a[2].s.c_str(), a[3].s.c_str(),opt);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_fits(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
        if(!strcmp(k,"ddddddssd"))
-               *(a[0].d) = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), *(a[5].d), a[6].s.c_str(), a[7].s.c_str(), *(a[8].d),opt);
+       {
+               mglData *i = dynamic_cast<mglData *>(a[8].d);
+               if(i)   *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), *(a[5].d), a[6].s.c_str(), a[7].s.c_str(), *i,opt);
+               else    res = 1;
+       }
        else if(!strcmp(k,"ddddddss"))
-               *(a[0].d) = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), *(a[5].d), a[6].s.c_str(), a[7].s.c_str(),opt);
+               *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), *(a[5].d), a[6].s.c_str(), a[7].s.c_str(),opt);
        else if(!strcmp(k,"dddddssd"))
-               *(a[0].d) = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.c_str(), a[6].s.c_str(), *(a[7].d),opt);
+       {
+               mglData *i = dynamic_cast<mglData *>(a[7].d);
+               if(i)   *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.c_str(), a[6].s.c_str(), *i,opt);
+               else    res = 1;
+       }
        else if(!strcmp(k,"dddddss"))
-               *(a[0].d) = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.c_str(), a[6].s.c_str(),opt);
+               *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), *(a[4].d), a[5].s.c_str(), a[6].s.c_str(),opt);
        else if(!strcmp(k,"ddddssd"))
-               *(a[0].d) = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.c_str(), a[5].s.c_str(), *(a[6].d),opt);
+       {
+               mglData *i = dynamic_cast<mglData *>(a[6].d);
+               if(i)   *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.c_str(), a[5].s.c_str(), *i,opt);
+               else    res = 1;
+       }
        else if(!strcmp(k,"ddddss"))
-               *(a[0].d) = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.c_str(), a[5].s.c_str(),opt);
+               *d = gr->FitS(*(a[1].d), *(a[2].d), *(a[3].d), a[4].s.c_str(), a[5].s.c_str(),opt);
        else if(!strcmp(k,"dddssd"))
-               *(a[0].d) = gr->FitS(*(a[1].d), *(a[2].d), a[3].s.c_str(), a[4].s.c_str(), *(a[5].d),opt);
+       {
+               mglData *i = dynamic_cast<mglData *>(a[5].d);
+               if(i)   *d = gr->FitS(*(a[1].d), *(a[2].d), a[3].s.c_str(), a[4].s.c_str(), *i,opt);
+               else    res = 1;
+       }
        else if(!strcmp(k,"dddss"))
-               *(a[0].d) = gr->FitS(*(a[1].d), *(a[2].d), a[3].s.c_str(), a[4].s.c_str(),opt);
+               *d = gr->FitS(*(a[1].d), *(a[2].d), a[3].s.c_str(), a[4].s.c_str(),opt);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2176,17 +2394,11 @@ int MGL_NO_EXPORT mgls_arrowsize(mglGraph *gr, long , mglArg *a, const char *k,
 int MGL_NO_EXPORT mgls_rearrange(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dn"))     a[0].d->Rearrange(iint(a[1].v));
-       else if(!strcmp(k,"dnn"))       a[0].d->Rearrange(iint(a[1].v), iint(a[2].v));
-       else if(!strcmp(k,"dnnn"))      a[0].d->Rearrange(iint(a[1].v), iint(a[2].v), iint(a[3].v));
-       else res = 1;   return res;
-}
-//-----------------------------------------------------------------------------
-int MGL_NO_EXPORT mgls_ctick(mglGraph *gr, long , mglArg *a, const char *k, const char *)
-{
-       int res=0;
-       if(!strcmp(k,"s"))      gr->SetTickTempl('c',a[0].w.c_str());
-       else if(!strcmp(k,"n")) gr->SetTicks('c',a[0].v);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dn"))     d->Rearrange(iint(a[1].v));
+       else if(!strcmp(k,"dnn"))       d->Rearrange(iint(a[1].v), iint(a[2].v));
+       else if(!strcmp(k,"dnnn"))      d->Rearrange(iint(a[1].v), iint(a[2].v), iint(a[3].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2261,8 +2473,10 @@ int MGL_NO_EXPORT mgls_fgets(mglGraph *gr, long , mglArg *a, const char *k, cons
 int MGL_NO_EXPORT mgls_import(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dss"))    a[0].d->Import(a[1].s.c_str(), a[2].s.c_str());
-       else if(!strcmp(k,"dssnn"))     a[0].d->Import(a[1].s.c_str(), a[2].s.c_str(), a[3].v,a[4].v);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dss"))    d->Import(a[1].s.c_str(), a[2].s.c_str());
+       else if(!strcmp(k,"dssnn"))     d->Import(a[1].s.c_str(), a[2].s.c_str(), a[3].v,a[4].v);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2279,7 +2493,7 @@ int MGL_NO_EXPORT mgls_write(mglGraph *gr, long , mglArg *a, const char *k, cons
        int res=0;
        if(!strcmp(k,""))       gr->WriteFrame("", "MathGL");
        else if(!strcmp(k,"s")) gr->WriteFrame(a[0].s.c_str(), "MathGL");
-       return res;
+       else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_region(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
@@ -2299,53 +2513,63 @@ int MGL_NO_EXPORT mgls_region(mglGraph *gr, long , mglArg *a, const char *k, con
 int MGL_NO_EXPORT mgls_envelop(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"d"))      a[0].d->Envelop();
-       else if(!strcmp(k,"ds"))        a[0].d->Envelop(a[1].s.c_str()[0]);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"d"))      d->Envelop();
+       else if(!strcmp(k,"ds"))        d->Envelop(a[1].s.c_str()[0]);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_sew(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"d"))      a[0].d->Sew();
-       else if(!strcmp(k,"ds"))        a[0].d->Sew(a[1].s.c_str());
-       else if(!strcmp(k,"dsn"))       a[0].d->Sew(a[1].s.c_str(), a[2].v);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"d"))      d->Sew();
+       else if(!strcmp(k,"ds"))        d->Sew(a[1].s.c_str());
+       else if(!strcmp(k,"dsn"))       d->Sew(a[1].s.c_str(), a[2].v);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_evaluate(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ddd"))    *(a[0].d) = a[1].d->Evaluate(*(a[2].d));
-       else if(!strcmp(k,"dddn"))      *(a[0].d) = a[1].d->Evaluate(*(a[2].d), a[3].v!=0);
-       else if(!strcmp(k,"dddd"))      *(a[0].d) = a[1].d->Evaluate(*(a[2].d), *(a[3].d));
-       else if(!strcmp(k,"ddddn"))     *(a[0].d) = a[1].d->Evaluate(*(a[2].d), *(a[3].d), a[4].v!=0);
-       else if(!strcmp(k,"ddddd"))     *(a[0].d) = a[1].d->Evaluate(*(a[2].d), *(a[3].d), *(a[4].d));
-       else if(!strcmp(k,"dddddn"))*(a[0].d) = a[1].d->Evaluate(*(a[2].d), *(a[3].d), *(a[4].d), a[5].v!=0);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ddd"))    *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,0,0,true));
+       else if(!strcmp(k,"dddn"))      *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,0,0, a[3].v!=0));
+       else if(!strcmp(k,"dddd"))      *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,a[3].d,0,true));
+       else if(!strcmp(k,"ddddn"))     *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,a[3].d,0, a[4].v!=0));
+       else if(!strcmp(k,"ddddd"))     *d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,a[3].d,a[4].d,true));
+       else if(!strcmp(k,"dddddn"))*d = mglData(true,mgl_data_evaluate(a[1].d,a[2].d,a[3].d,a[4].d, a[5].v!=0));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_solve(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ddns"))   *(a[0].d) = a[1].d->Solve(a[2].v, a[3].s[0]);
-       else if(!strcmp(k,"ddnsn"))     *(a[0].d) = a[1].d->Solve(a[2].v, a[3].s[0], a[4].v!=0);
-       else if(!strcmp(k,"ddnsd"))     *(a[0].d) = a[1].d->Solve(a[2].v, a[3].s[0], *(a[4].d));
-       else if(!strcmp(k,"ddnsdn"))*(a[0].d) = a[1].d->Solve(a[2].v, a[3].s[0], *(a[4].d), a[5].v!=0);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ddns"))   *d = mglData(true,mgl_data_solve(a[1].d, a[2].v, a[3].s[0], 0, true));
+       else if(!strcmp(k,"ddnsn"))     *d = mglData(true,mgl_data_solve(a[1].d, a[2].v, a[3].s[0], 0, a[4].v!=0));
+       else if(!strcmp(k,"ddnsd"))     *d = mglData(true,mgl_data_solve(a[1].d, a[2].v, a[3].s[0], a[4].d, true));
+       else if(!strcmp(k,"ddnsdn"))*d = mglData(true,mgl_data_solve(a[1].d, a[2].v, a[3].s[0], a[4].d, a[5].v!=0));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_put(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dn"))     a[0].d->Put(a[1].v);
-       else if(!strcmp(k,"dnn"))       a[0].d->Put(a[1].v, iint(a[2].v));
-       else if(!strcmp(k,"dnnn"))      a[0].d->Put(a[1].v, iint(a[2].v),iint(a[3].v));
-       else if(!strcmp(k,"dnnnn"))     a[0].d->Put(a[1].v, iint(a[2].v),iint(a[3].v),iint(a[4].v));
-       else if(!strcmp(k,"dd"))        a[0].d->Put(*(a[1].d));
-       else if(!strcmp(k,"ddn"))       a[0].d->Put(*(a[1].d), iint(a[2].v));
-       else if(!strcmp(k,"ddnn"))      a[0].d->Put(*(a[1].d), iint(a[2].v),iint(a[3].v));
-       else if(!strcmp(k,"ddnnn"))     a[0].d->Put(*(a[1].d), iint(a[2].v),iint(a[3].v),iint(a[4].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dn"))     d->Put(a[1].v);
+       else if(!strcmp(k,"dnn"))       d->Put(a[1].v, iint(a[2].v));
+       else if(!strcmp(k,"dnnn"))      d->Put(a[1].v, iint(a[2].v),iint(a[3].v));
+       else if(!strcmp(k,"dnnnn"))     d->Put(a[1].v, iint(a[2].v),iint(a[3].v),iint(a[4].v));
+       else if(!strcmp(k,"dd"))        d->Put(*(a[1].d));
+       else if(!strcmp(k,"ddn"))       d->Put(*(a[1].d), iint(a[2].v));
+       else if(!strcmp(k,"ddnn"))      d->Put(*(a[1].d), iint(a[2].v),iint(a[3].v));
+       else if(!strcmp(k,"ddnnn"))     d->Put(*(a[1].d), iint(a[2].v),iint(a[3].v),iint(a[4].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2359,141 +2583,145 @@ int MGL_NO_EXPORT mgls_palette(mglGraph *gr, long , mglArg *a, const char *k, co
 int MGL_NO_EXPORT mgls_combine(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ddd"))    *(a[0].d) = a[1].d->Combine(*(a[2].d));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"ddd") && d)       *d = mglData(true,mgl_data_combine(a[1].d, a[2].d));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_correl(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ddds"))   *(a[0].d) = a[1].d->Correl(*(a[2].d), a[3].s.c_str());
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"ddds") && d)      *d = mglData(true,mgl_data_correl(a[1].d, a[2].d, a[3].s.c_str()));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_roots(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dsds"))   *(a[0].d) = a[2].d->Roots(a[1].s.c_str(), a[3].s[0]);
-       else if(!strcmp(k,"dsns"))      a[0].d->a[0] = mgl_find_root_txt(a[1].s.c_str(), a[2].v, a[3].s[0]);
-       else if(!strcmp(k,"dsd"))       *(a[0].d) = a[2].d->Roots(a[1].s.c_str(), 'x');
-       else if(!strcmp(k,"dsn"))       a[0].d->a[0] = mgl_find_root_txt(a[1].s.c_str(), a[2].v, 'x');
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dsds"))   *d = mglData(true,mgl_data_roots(a[1].s.c_str(), a[2].d, a[3].s[0]));
+       else if(!strcmp(k,"dsns"))      d->a[0] = mgl_find_root_txt(a[1].s.c_str(), a[2].v, a[3].s[0]);
+       else if(!strcmp(k,"dsd"))       *d = mglData(true,mgl_data_roots(a[1].s.c_str(), a[2].d, 'x'));
+       else if(!strcmp(k,"dsn"))       d->a[0] = mgl_find_root_txt(a[1].s.c_str(), a[2].v, 'x');
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_ode(mglGraph *, long , mglArg *a, const char *k, const char *)
+{
+       int res=0;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dssd"))
+               *d = mglODE(a[1].s.c_str(), a[2].s.c_str(), *(a[3].d));
+       else if(!strcmp(k,"dssdnn"))
+               *d = mglODE(a[1].s.c_str(), a[2].s.c_str(), *(a[3].d), a[4].v, a[5].v);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_pde(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
-       if(!strcmp(k,"dsdd"))
-               *(a[0].d) = gr->PDE(a[1].s.c_str(), *(a[2].d), *(a[3].d), 0.1,100,opt);
+       mglData *d = dynamic_cast<mglData *>(a[0].d), *c = dynamic_cast<mglData *>(a[1].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"dsdd"))   // TODO mglDataC can be used here
+               *d = gr->PDE(a[1].s.c_str(), *(a[2].d), *(a[3].d), 0.1,100,opt);
        else if(!strcmp(k,"dsddn"))
-               *(a[0].d) = gr->PDE(a[1].s.c_str(), *(a[2].d), *(a[3].d), a[4].v,100,opt);
+               *d = gr->PDE(a[1].s.c_str(), *(a[2].d), *(a[3].d), a[4].v,100,opt);
        else if(!strcmp(k,"dsddnn"))
-               *(a[0].d) = gr->PDE(a[1].s.c_str(), *(a[2].d), *(a[3].d), a[4].v,a[5].v,opt);
-       else if(!strcmp(k,"ddsdd"))
-       {
-               HADT res = mgl_pde_solve_c(gr->Self(),a[2].s.c_str(), a[3].d, a[4].d, 0.1,100,opt);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
-       else if(!strcmp(k,"ddsddn"))
-       {
-               HADT res = mgl_pde_solve_c(gr->Self(),a[2].s.c_str(), a[3].d, a[4].d, a[5].v,100,opt);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
-       else if(!strcmp(k,"ddsddnn"))
-       {
-               HADT res = mgl_pde_solve_c(gr->Self(),a[2].s.c_str(), a[3].d, a[4].d, a[5].v,a[6].v,opt);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
+               *d = gr->PDE(a[1].s.c_str(), *(a[2].d), *(a[3].d), a[4].v,a[5].v,opt);
+       else if(!strcmp(k,"ddsdd") && c)
+       {       mglDataC res = mglDataC(true, mgl_pde_solve_c(gr->Self(),a[2].s.c_str(), a[3].d, a[4].d, 0.1,100,opt));
+               *d = res.Abs(); *c = res.Arg(); }
+       else if(!strcmp(k,"ddsddn") && c)
+       {       mglDataC res = mglDataC(true, mgl_pde_solve_c(gr->Self(),a[2].s.c_str(), a[3].d, a[4].d, a[5].v,100,opt));
+               *d = res.Abs(); *c = res.Arg(); }
+       else if(!strcmp(k,"ddsddnn") && c)
+       {       mglDataC res = mglDataC(true, mgl_pde_solve_c(gr->Self(),a[2].s.c_str(), a[3].d, a[4].d, a[5].v,a[6].v,opt));
+               *d = res.Abs(); *c = res.Arg(); }
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_qo2d(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
+       mglData *d = dynamic_cast<mglData *>(a[0].d), *c = dynamic_cast<mglData *>(a[1].d);
+       if(!d)  return 1;
        if(!strcmp(k,"dsddd"))
-               *(a[0].d) = mglData(true, mgl_qo2d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, 1,100, 0,0));
+               *d = mglData(true, mgl_qo2d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, 1,100, 0,0));
        else if(!strcmp(k,"dsdddn"))
-               *(a[0].d) = mglData(true, mgl_qo2d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,100, 0,0));
+               *d = mglData(true, mgl_qo2d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,100, 0,0));
        else if(!strcmp(k,"dsdddnn"))
-               *(a[0].d) = mglData(true, mgl_qo2d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, 0,0));
+               *d = mglData(true, mgl_qo2d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, 0,0));
        else if(!strcmp(k,"dsdddnndd"))
-               *(a[0].d) = mglData(true, mgl_qo2d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, a[7].d,a[8].d));
-       else if(!strcmp(k,"ddsddd"))
-       {
-               HADT res = mgl_qo2d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, 1,100, 0,0);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
-       else if(!strcmp(k,"ddsdddn"))
-       {
-               HADT res = mgl_qo2d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,100, 0,0);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
-       else if(!strcmp(k,"ddsdddnn"))
-       {
-               HADT res = mgl_qo2d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, 0,0);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
-       else if(!strcmp(k,"ddsdddnndd"))
-       {
-               HADT res = mgl_qo2d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, a[8].d,a[9].d);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
+               *d = mglData(true, mgl_qo2d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, dynamic_cast<mglData *>(a[7].d),dynamic_cast<mglData *>(a[8].d)));
+       else if(!strcmp(k,"ddsddd") && c)
+       {       mglDataC res = mglDataC(true, mgl_qo2d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, 1,100, 0,0));
+               *d = res.Abs(); *c = res.Arg(); }
+       else if(!strcmp(k,"ddsdddn") && c)
+       {       mglDataC res = mglDataC(true, mgl_qo2d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,100, 0,0));
+               *d = res.Abs(); *c = res.Arg(); }
+       else if(!strcmp(k,"ddsdddnn") && c)
+       {       mglDataC res = mglDataC(true, mgl_qo2d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, 0,0));
+               *d = res.Abs(); *c = res.Arg(); }
+       else if(!strcmp(k,"ddsdddnndd") && c)
+       {       mglDataC res = mglDataC(true, mgl_qo2d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, dynamic_cast<mglData *>(a[8].d),dynamic_cast<mglData *>(a[9].d)));
+               *d = res.Abs(); *c = res.Arg(); }
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_qo3d(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
+       mglData *d = dynamic_cast<mglData *>(a[0].d), *c = dynamic_cast<mglData *>(a[1].d);
+       if(!d)  return 1;
        if(!strcmp(k,"dsddd"))
-               *(a[0].d) = mglData(true, mgl_qo3d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, 1,100, 0,0,0));
+               *d = mglData(true, mgl_qo3d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, 1,100, 0,0,0));
        else if(!strcmp(k,"dsdddn"))
-               *(a[0].d) = mglData(true, mgl_qo3d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,100, 0,0,0));
+               *d = mglData(true, mgl_qo3d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,100, 0,0,0));
        else if(!strcmp(k,"dsdddnn"))
-               *(a[0].d) = mglData(true, mgl_qo3d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, 0,0,0));
+               *d = mglData(true, mgl_qo3d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, 0,0,0));
        else if(!strcmp(k,"dsdddnnddd"))
-               *(a[0].d) = mglData(true, mgl_qo3d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, a[7].d,a[8].d,a[9].d));
-       else if(!strcmp(k,"ddsddd"))
-       {
-               HADT res = mgl_qo3d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, 1,100, 0,0,0);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
-       else if(!strcmp(k,"ddsdddn"))
-       {
-               HADT res = mgl_qo3d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,100, 0,0,0);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
-       else if(!strcmp(k,"ddsdddnn"))
-       {
-               HADT res = mgl_qo3d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, 0,0,0);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
-       else if(!strcmp(k,"ddsdddnnddd"))
-       {
-               HADT res = mgl_qo3d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, a[8].d,a[9].d,a[10].d);
-               *(a[0].d) = res->Abs(); *(a[1].d) = res->Arg();
-       }
+               *d = mglData(true, mgl_qo3d_solve(a[1].s.c_str(), a[2].d, a[3].d, a[4].d, a[5].v,a[6].v, dynamic_cast<mglData *>(a[7].d),dynamic_cast<mglData *>(a[8].d),dynamic_cast<mglData *>(a[9].d)));
+       else if(!strcmp(k,"ddsddd") && c)
+       {       mglDataC res = mglDataC(true, mgl_qo3d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, 1,100, 0,0,0));
+               *d = res.Abs(); *c = res.Arg(); }
+       else if(!strcmp(k,"ddsdddn") && c)
+       {       mglDataC res = mglDataC(true, mgl_qo3d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,100, 0,0,0));
+               *d = res.Abs(); *c = res.Arg(); }
+       else if(!strcmp(k,"ddsdddnn") && c)
+       {       mglDataC res = mglDataC(true, mgl_qo3d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, 0,0,0));
+               *d = res.Abs(); *c = res.Arg(); }
+       else if(!strcmp(k,"ddsdddnnddd") && c)
+       {       mglDataC res = mglDataC(true, mgl_qo3d_solve_c(a[2].s.c_str(), a[3].d, a[4].d, a[5].d, a[6].v,a[7].v, dynamic_cast<mglData *>(a[8].d),dynamic_cast<mglData *>(a[9].d),dynamic_cast<mglData *>(a[10].d)));
+               *d = res.Abs(); *c = res.Arg(); }
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_ray(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
        if(!strcmp(k,"dsnnnn"))
-               *(a[0].d) = mglRay(a[1].s.c_str(), mglPoint(a[2].v, a[3].v), mglPoint(a[4].v, a[5].v));
+               *d = mglRay(a[1].s.c_str(), mglPoint(a[2].v, a[3].v), mglPoint(a[4].v, a[5].v));
        else if(!strcmp(k,"dsnnnnnn"))
-               *(a[0].d) = mglRay(a[1].s.c_str(), mglPoint(a[2].v, a[3].v, a[4].v), mglPoint(a[5].v, a[6].v, a[7].v));
+               *d = mglRay(a[1].s.c_str(), mglPoint(a[2].v, a[3].v, a[4].v), mglPoint(a[5].v, a[6].v, a[7].v));
        else if(!strcmp(k,"dsnnnnnnn"))
-               *(a[0].d) = mglRay(a[1].s.c_str(), mglPoint(a[2].v, a[3].v, a[4].v), mglPoint(a[5].v, a[6].v, a[7].v), a[8].v);
+               *d = mglRay(a[1].s.c_str(), mglPoint(a[2].v, a[3].v, a[4].v), mglPoint(a[5].v, a[6].v, a[7].v), a[8].v);
        else if(!strcmp(k,"dsnnnnnnnn"))
-               *(a[0].d) = mglRay(a[1].s.c_str(), mglPoint(a[2].v, a[3].v, a[4].v), mglPoint(a[5].v, a[6].v, a[7].v), a[8].v,a[9].v);
+               *d = mglRay(a[1].s.c_str(), mglPoint(a[2].v, a[3].v, a[4].v), mglPoint(a[5].v, a[6].v, a[7].v), a[8].v,a[9].v);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_jacobian(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ddd"))    *(a[0].d) = mglJacobian(*(a[1].d), *(a[2].d));
-       else if(!strcmp(k,"dddd"))      *(a[0].d) = mglJacobian(*(a[1].d), *(a[2].d), *(a[3].d));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ddd"))    *d = mglJacobian(*(a[1].d), *(a[2].d));
+       else if(!strcmp(k,"dddd"))      *d = mglJacobian(*(a[1].d), *(a[2].d), *(a[3].d));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2566,42 +2794,48 @@ int MGL_NO_EXPORT mgls_adjust(mglGraph *gr, long , mglArg *a, const char *k, con
 int MGL_NO_EXPORT mgls_insert(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->Insert(a[1].s.c_str()[0]);
-       else if(!strcmp(k,"dsn"))       a[0].d->Insert(a[1].s.c_str()[0], iint(a[2].v));
-       else if(!strcmp(k,"dsnn"))      a[0].d->Insert(a[1].s.c_str()[0], iint(a[2].v), iint(a[3].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds"))     d->Insert(a[1].s.c_str()[0]);
+       else if(!strcmp(k,"dsn"))       d->Insert(a[1].s.c_str()[0], iint(a[2].v));
+       else if(!strcmp(k,"dsnn"))      d->Insert(a[1].s.c_str()[0], iint(a[2].v), iint(a[3].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_delete(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ds"))     a[0].d->Delete(a[1].s.c_str()[0]);
-       else if(!strcmp(k,"dsn"))       a[0].d->Delete(a[1].s.c_str()[0], iint(a[2].v));
-       else if(!strcmp(k,"dsnn"))      a[0].d->Delete(a[1].s.c_str()[0], iint(a[2].v), iint(a[3].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ds"))     d->Delete(a[1].s.c_str()[0]);
+       else if(!strcmp(k,"dsn"))       d->Delete(a[1].s.c_str()[0], iint(a[2].v));
+       else if(!strcmp(k,"dsnn"))      d->Delete(a[1].s.c_str()[0], iint(a[2].v), iint(a[3].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_roll(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"dsn"))    a[0].d->Roll(a[1].s.c_str()[0], iint(a[2].v));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"dsn") && d)       d->Roll(a[1].s.c_str()[0], iint(a[2].v));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_datagrid(mglGraph *gr, long , mglArg *a, const char *k, const char *opt)
 {
        int res=0;
-       if(!strcmp(k,"dddd"))   gr->DataGrid(*(a[0].d), *(a[1].d), *(a[2].d), *(a[3].d),opt);
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!strcmp(k,"dddd") && d)      gr->DataGrid(*d, *(a[1].d), *(a[2].d), *(a[3].d),opt);
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
 int MGL_NO_EXPORT mgls_triangulate(mglGraph *, long , mglArg *a, const char *k, const char *)
 {
        int res=0;
-       if(!strcmp(k,"ddd"))
-               *(a[0].d) = mglTriangulation(*(a[1].d), *(a[2].d));
-       else if(!strcmp(k,"dddd"))
-               *(a[0].d) = mglTriangulation(*(a[1].d), *(a[2].d), *(a[3].d));
+       mglData *d = dynamic_cast<mglData *>(a[0].d);
+       if(!d)  return 1;
+       if(!strcmp(k,"ddd"))            *d = mglTriangulation(*(a[1].d), *(a[2].d));
+       else if(!strcmp(k,"dddd"))      *d = mglTriangulation(*(a[1].d), *(a[2].d), *(a[3].d));
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2634,7 +2868,16 @@ int MGL_NO_EXPORT mgls_drawreg(mglGraph *gr, long , mglArg *a, const char *k, co
 {
        int res=0;
        if(!strcmp(k,""))       gr->SetDrawReg();
-       if(!strcmp(k,"nnn"))    gr->SetDrawReg(iint(a[0].v), iint(a[1].v), iint(a[2].v));
+       else if(!strcmp(k,"nnn"))       gr->SetDrawReg(iint(a[0].v), iint(a[1].v), iint(a[2].v));
+       else res = 1;   return res;
+}
+//-----------------------------------------------------------------------------
+int MGL_NO_EXPORT mgls_version(mglGraph *gr, long , mglArg *a, const char *k, const char *)
+{
+       int res=0;
+       char buf[32];   sprintf(buf,"MathGL version is 2.%g",MGL_VER2);
+       if(!strcmp(k,""))       gr->SetWarn(-1,buf);
+       else if(!strcmp(k,"s")) res = mgl_check_version(a[0].s.c_str())?1:0;
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2645,6 +2888,7 @@ mglCommand mgls_base_cmd[] = {
        {"alpha","Switch on/off transparency","alpha [val]", mgls_alpha ,2},
        {"alphadef","Set default transparency","alphadef val", mgls_alphadef ,2},
        {"ambient","Set ambient light brightness","ambient val", mgls_ambient ,2},
+       {"arc","Draw angle arc","arc x0 y0 x1 y1 a ['fmt']|x0 y0 z0 x1 y1 a ['fmt']|x0 y0 z0 xr yr zr x1 y1 z1 a ['fmt']", mgls_arc ,13},
        {"area","Draw area plot for 1D data","area Ydat ['fmt']|Xdat Ydat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_area ,7},
        {"arrowsize","Set size of arrows","arrowsize val", mgls_arrowsize ,2},
        {"ask","Define parameter from user input","ask $N 'question'", 0, 6},
@@ -2652,6 +2896,7 @@ mglCommand mgls_base_cmd[] = {
        {"axial","Draw surfaces of contour lines rotation","axial Zdat ['fmt' num]|Xdat Ydat Zdat ['fmt' num]", mgls_axial ,8},
        {"axis","Setup or draw axis","axis ['dir' 'fmt']|'fx' 'fy' 'fz' ['fc']|how", mgls_axis ,12},
        {"axisstl","Set axis and tick style","axisstl 'stl' ['sub']", mgls_axisstl ,14},
+       {"background","Load image for background","background 'fname'", mgls_background ,12},
        {"ball","Draw point (ball)","ball posx posy ['fmt']|posx posy posz ['fmt']", mgls_ball ,13},
        {"barh","Draw horizontal bars for 1D data", "barh Ydat ['fmt' above]|Xdat Ydat ['fmt' above]", mgls_barh ,7},
        {"bars","Draw bars for 1D data","bars Ydat ['fmt' above]|Xdat Ydat ['fmt' above]|Xdat Ydat Zdat ['fmt' above]", mgls_bars ,7},
@@ -2696,7 +2941,7 @@ mglCommand mgls_base_cmd[] = {
        {"crange","Set color range","crange Dat [add] | c1 c2 [add]", mgls_crange ,14},
        {"crop","Crop edge of data","crop Dat n1 n2 'dir'", mgls_crop ,16},
        {"crust","Draw reconstructed surface for arbitrary data points","crust Xdat Ydat Zdat ['fmt']", mgls_crust ,0},
-       {"ctick","Set ticks for colorbar","ctick 'tmpl' | dx", mgls_ctick ,14},
+       {"ctick","Set ticks for colorbar","ctick 'tmpl' | dc ['factor']", mgls_ctick ,14},
        {"cumsum","Cumulative summation","cumsum Dat 'dir'", mgls_cumsum ,16},
        {"curve","Draw curve","curve x1 y1 dx1 dy1 x2 y2 dx2 dy2 ['fmt']|x1 y1 z1 dx1 dy1 dz1 x2 y2 z2 dx2 dy2 dz2 ['fmt']", mgls_curve ,13},
        {"cut","Setup plot points cutting","cut val|x1 y1 z1 x2 y2 z2|'cond'", mgls_cut ,2},
@@ -2755,6 +3000,7 @@ mglCommand mgls_base_cmd[] = {
        {"grid2","Draw grid for data array(s)","grid Zdat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_grid2 ,8},
        {"grid3","Draw grid at slices of 3D data","grid3 Adat 'dir' [pos 'fmt']|Xdat Ydat Zdat Adat 'dir' [pos 'fmt']", mgls_grid3 ,9},
        {"gridplot","Set position of plot inside cell of matrix", "gridplot nx ny ind [d]", mgls_gridplot ,5},
+       {"gspline","Fill data by global spline of Vdat","gspline Dat Xdat Vdat [sl]", mgls_gspline ,3},
        {"hankel","Hankel transform at some direction","hankel Dat 'dir'", mgls_hankel ,16},
        {"hist","Create histogram (distribution) of data values","hist Res Dat num v1 v2 [nsub]|Res Dat Wdat num v1 v2 [nsub]", mgls_hist ,4},
        {"idset","Set column id for data","idset Dat 'ids'", mgls_idset ,3},
@@ -2790,6 +3036,7 @@ mglCommand mgls_base_cmd[] = {
        {"next","Start next for-cycle iteration","next", 0, 6},
        {"norm","Normalize data","norm Dat v1 v2 [sym dim]", mgls_norm ,16},
        {"normsl","Normalize data slice by slice","normsl Dat v1 v2 ['dir' keep sym] ", mgls_normsl ,16},
+       {"ode","Solve ODE","ode Res 'df' 'var' Ini [dt tmax]", mgls_ode ,4},
        {"ohlc","Draw Open-High-Low-Close (OHLC) diagram","ohlc Odat Hdat Ldat Cdat ['fmt']|Xdat Odat Hdat Ldat Cdat ['fmt']", mgls_ohlc ,7},
        {"once","Start/close commands which should executed only once","once val", 0, 6},
        {"origin","Set axis origin","origin x0 y0 [z0]", mgls_origin ,14},
@@ -2800,6 +3047,7 @@ mglCommand mgls_base_cmd[] = {
        {"pipe","Draw flow pipes for vector field","pipe Udat Vdat ['fmt' rad num]|Xdat Ydat Udat Vdat ['fmt' rad num]|Udat Vdat Wdat ['fmt' rad num]|Xdat Ydat Zdat Udat Vdat Wdat ['fmt' rad num]", mgls_pipe ,11},
        {"plot","Draw usual plot for 1D data","plot Ydat ['fmt']|Xdat Ydat ['fmt']|Xdat Ydat Zdat ['fmt']", mgls_plot ,7},
        {"plotid","Set default filename","plotid 'name'", mgls_plotid ,2},
+       {"polygon","Draw polygon","polygon x1 y1 x2 y2 num ['fmt']|x1 y1 z1 x2 y2 z2 num ['fmt']", mgls_polygon ,13},
        {"put","Put value (numeric or array) to given data element","put Dat val [i j k] | Dat Val [i j k]", mgls_put ,3},
        {"putsfit","Print fitted formula","putsfit x y ['pre' 'font' size]|x y z ['pre' 'font' size]", mgls_putsfit ,15},
        {"qo2d","Solve PDE in accompanied coordinates for 2d case","qo2d Res 'ham' IniRe IniIm Ray [r k0 Xout Yout]", mgls_qo2d ,4},
@@ -2808,6 +3056,7 @@ mglCommand mgls_base_cmd[] = {
        {"quality","Set plot quality","quality [val]", mgls_quality ,2},
        {"radar","Draw radar chart","radar Rdat ['fmt']", mgls_radar ,7},
        {"ranges","Set axis ranges","ranges x1 x2 y1 y2 [z1 z2]", mgls_ranges ,14},
+       {"rasterize","Rasterize and save to background","rasterize", mgls_rasterize ,12},
        {"ray","Solve Hamiltonian ODE (find GO ray or trajectory)","ray Res 'ham' x0 y0 z0 px0 py0 pz0 [dz=0.1 tmax=10]", mgls_ray ,4},
        {"read","Read data from file","read Dat 'file' [nx ny nz]", mgls_read ,4},
        {"readall","Read and join data from several files","readall Dat 'templ' [slice]", mgls_readall ,4},
@@ -2872,25 +3121,27 @@ mglCommand mgls_base_cmd[] = {
        {"transpose","Transpose data array","transpose Dat ['dir']", mgls_transpose ,16},
        {"transptype","Set type transparency","transptype val", mgls_transptype ,2},
        {"triangulate","Find triangles of randomly placed points","triangulate Res Xdat Ydat [er]|Res Xdat Ydat Zdat [er]", mgls_triangulate ,4},
-       {"tricont","Draw contour lines for surface of triangles","tricont Vdat Idat Xdat Ydat ['fmt']|Vdat Idat Xdat Ydat Zdat ['fmt']|Vdat Idat Xdat Ydat Zdat Cdat ['fmt'] ", mgls_tricont ,0},
+       {"tricont","Draw contour lines for surface of triangles","tricont Idat Xdat Ydat Cdat ['fmt']|Idat Xdat Ydat Zdat Cdat ['fmt']|Vdat Idat Xdat Ydat Cdat ['fmt']|Vdat Idat Xdat Ydat Zdat Cdat ['fmt']", mgls_tricont ,0},
+       {"tricontv","Draw contour tubes for surface of triangles","tricontv Idat Xdat Ydat Cdat ['fmt']|Idat Xdat Ydat Zdat Cdat ['fmt']|Vdat Idat Xdat Ydat Cdat ['fmt']|Vdat Idat Xdat Ydat Zdat Cdat ['fmt']", mgls_tricontv ,0},
        {"triplot","Draw surface of triangles","triplot Idat Xdat Ydat ['fmt']|Idat Xdat Ydat Zdat ['fmt']|Idat Xdat Ydat Zdat Cdat ['fmt'] ", mgls_triplot ,0},
        {"tube","Draw curve by tube","tube Ydat Rdat ['fmt']|Ydat rval ['fmt']|Xdat Ydat Rdat ['fmt']|Xdat Ydat rval ['fmt']|Xdat Ydat Zdat Rdat ['fmt']|Xdat Ydat Zdat rval ['fmt']", mgls_tube ,7},
        {"tuneticks","Set ticks tuning","tuneticks val [fctr]", mgls_tuneticks ,14},
        {"var","Create new 1D data and fill it in range","var Dat nx x1 [x2]", mgls_var ,4},
        {"vect","Draw vector field","vect Udat Vdat ['fmt']|Xdat Ydat Udat Vdat ['fmt']|Udat Vdat Wdat ['fmt']|Xdat Ydat Zdat Udat Vdat Wdat ['fmt']", mgls_vect ,11},
        {"vect3","Draw vector field at slices of 3D data","vect Udat Vdat Wdat ['fmt' sval]|Xdat Ydat Zdat Udat Vdat Wdat ['fmt' sval]", mgls_vect3 ,11},
+       {"version","Print MathGL version or check if it is valid","version |'ver'", mgls_version, 2},
        {"view","Change view angles - use 'rotate' for plot rotation","view tetz tetx [tety]", mgls_view ,5},
-       {"write","Write current image to graphical file","write 'fname' [solid]", mgls_write ,2},
+       {"write","Write current image to graphical file","write ['fname']", mgls_write ,2},
        {"xlabel","Draw label for x-axis","xlabel 'txt' [pos]", mgls_xlabel ,12},
        {"xrange","Set range for x-axis","xrange Dat [add] | x1 x2 [add]", mgls_xrange ,14},
-       {"xtick","Set ticks for x-axis","xtick dx [sx tx] | 'tmpl' | Xdat 'lbl' [add] | v1 'lbl1' ...", mgls_xtick,14},
+       {"xtick","Set ticks for x-axis","xtick dx ['factor'] | dx sx ['factor'] | dx sx tx ['factor'] | 'tmpl' | Xdat 'lbl' [add] | v1 'lbl1' ...", mgls_xtick,14},
        {"ylabel","Draw label for y-axis","ylabel 'txt' [pos]", mgls_ylabel,12},
        {"yrange","Set range for y-axis","yrange Dat [add] | y1 y2 [add]", mgls_yrange,14},
-       {"ytick","Set ticks for y-axis","ytick dy [sy ty] | 'tmpl' | Ydat 'lbl' [add] | v1 'lbl1' ...", mgls_ytick,14},
+       {"ytick","Set ticks for y-axis","ytick dy ['factor'] | dy sy ['factor'] | dy sy ty ['factor'] | 'tmpl' | Ydat 'lbl' [add] | v1 'lbl1' ...", mgls_ytick,14},
        {"zlabel","Draw label for z-axis","zlabel 'txt' [pos]", mgls_zlabel,12},
        {"zoom","Zoom plot region","zoom x1 x2 y1 y2", mgls_zoom,5},
        {"zoomaxis","Zoom axis range","zoomaxis x1 x2|x1 x2 y1 y2|x1 x2 y1 y2 z1 z2|x1 x2 y1 y2 z1 z2 c1 c2", mgls_zoomaxis,14},
        {"zrange","Set range for z-axis","yrange Dat [add] | z1 z2 [add]", mgls_zrange ,14},
-       {"ztick","Set ticks for z-axis","ztick dz [sz tz] | 'tmpl' | Zdat 'lbl' [add] | v1 'lbl1' ...", mgls_ztick,14},
+       {"ztick","Set ticks for z-axis","ztick dz ['factor'] | dz sz ['factor'] | dz sz tz ['factor'] | 'tmpl' | Zdat 'lbl' [add] | v1 'lbl1' ...", mgls_ztick,14},
 {"","","",NULL,0}};
 //-----------------------------------------------------------------------------
index 742b70449904772d51701491fba96d90bb9b9a30..c44d53bfbfc4abfe3a96005ae48900653891c2d5 100644 (file)
@@ -255,11 +255,9 @@ int MGL_NO_EXPORT mgl_gif_save(const char *fname, int w, int h, unsigned char **
        // define colormap
        GifColorType col[256];
        memset(col,0,256*sizeof(GifColorType));
-       register long m;
-       register int i,j,k,ii;
-       for(i=0;i<6;i++)        for(j=0;j<6;j++)        for(k=0;k<6;k++)
+       for(int i=0;i<6;i++)    for(int j=0;j<6;j++)    for(int k=0;k<6;k++)
        {
-               m = i+6*(j+6*k);                // part 1
+               long m = i+6*(j+6*k);           // part 1
                col[m].Red = 51*i;
                col[m].Green=51*j;
                col[m].Blue =51*k;
@@ -277,11 +275,11 @@ int MGL_NO_EXPORT mgl_gif_save(const char *fname, int w, int h, unsigned char **
        // write frame
        EGifPutImageDesc(fg, 0, 0, w, h, 0, 0);
        GifPixelType *line = new GifPixelType[w*h];
-       for(m=0;m<w*h;m++)
+       for(long m=0;m<w*h;m++)
        {
-               ii = 3*(m%w);   k = m/w;
-               i = (l[k][ii]+25)/51;
-               j = (l[k][ii+1]+25)/51;
+               long ii = 3*(m%w), k = m/w;
+               int i = (l[k][ii]+25)/51;
+               int j = (l[k][ii+1]+25)/51;
                k = (l[k][ii+2]+25)/51;
                line[m] = i+6*(j+6*k);
        }
@@ -340,7 +338,9 @@ void mglCanvas::StartGIF(const char *fname, int ms)
 #endif
        // put animation parameters
        ms /= 10;
-       unsigned char ext1[11] = {0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30}, ext3[3] = {0x01, 0xff, 0xff}, ext2[9] = {0x08, ms%256, ms/256, 0xff};
+       unsigned char ext1[11] = {0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30};
+       unsigned char ext2[9] = {0x08, (unsigned char)(ms%256), (unsigned char)(ms/256), 0xff};
+       unsigned char ext3[3] = {0x01, 0xff, 0xff};
 #if GIFLIB_MAJOR>=5
        EGifPutExtensionLeader(gif,0xff);
        EGifPutExtensionBlock(gif,11,ext1);
@@ -385,13 +385,11 @@ void mglCanvas::EndFrame()
        if(!l)  return;
        EGifPutImageDesc(gif, 0, 0, width, height, 0, 0);
        GifPixelType *line = new GifPixelType[n];
-       register long m;
-       register int i,j,k,ii;
-       for(m=0;m<n;m++)
+       for(long m=0;m<n;m++)
        {
-               ii = 3*(m%width);       k = m/width;
-               i = (l[k][ii]+25)/51;
-               j = (l[k][ii+1]+25)/51;
+               long ii = 3*(m%width), k = m/width;
+               int i = (l[k][ii]+25)/51;
+               int j = (l[k][ii+1]+25)/51;
                k = (l[k][ii+2]+25)/51;
                line[m] = i+6*(j+6*k);
        }
@@ -407,7 +405,6 @@ void mglCanvas::DelFrame(long i)
 {
 #if MGL_HAVE_PTHREAD
        pthread_mutex_lock(&mutexDrw);
-#pragma omp critical(drw)
        if(get(MGL_VECT_FRAME)) DrwDat.erase(DrwDat.begin()+i);
        pthread_mutex_unlock(&mutexDrw);
 #else
index 0a90d9597228fd1ad87ad59e4a1f03f7508bda9e..aa0a5ff3f027c937946dd1a603fdaa855ad0f5c0 100644 (file)
 #define _Gr_   ((mglCanvas *)(gr))
 void mgl_printf(void *fp, bool gz, const char *str, ...);
 //-----------------------------------------------------------------------------
-MGL_NO_EXPORT const char *mgl_get_dash(unsigned short d, mreal w)
+MGL_NO_EXPORT const char *mgl_get_dash(unsigned short d, mreal w,char dlm)
 {
        static char b[32];
        static std::string s;
        if(d==0xffff)   return "";
-       int f=0, p=d&1, n=p?0:1, i, j;
+       int f=0, p=d&1, n=p?0:1;
        s = p ? "" : "0";
-       for(i=0;i<16;i++)
+       for(int i=0;i<16;i++)
        {
-               j = i;//15-i;
+               int j = i;//15-i;
                if(((d>>j)&1) == p)     f++;
                else
                {
-                       snprintf(b,32," %g",f*w);       s += b;
+                       snprintf(b,32," %g%c",f*w,dlm); s += b;
                        p = (d>>j)&1;   f = 1;  n++;
                }
        }
-       snprintf(b,32," %g",f*w);       s += b;
-       s += n%2 ? "" : " 0";
+       snprintf(b,32,"%g",f*w);        s += b;
+       s += (n%2) ? "" : " 0";
        return s.c_str();
 }
 //-----------------------------------------------------------------------------
-bool MGL_NO_EXPORT mgl_is_same(HMGL gr, long i, mreal wp,uint32_t cp, int st)
+bool MGL_LOCAL_PURE mgl_is_same(HMGL gr, long i, mreal wp,uint32_t cp, int st)
 {
        const mglPrim &pr=_Gr_->GetPrm(i);
        if(abs(pr.type)!=1)     return false;
@@ -153,11 +153,10 @@ void MGL_NO_EXPORT put_desc(HMGL gr, void *fp, bool gz, const char *pre, const c
                const mglGlyph &g = gr->GetGlf(q.n4);
                int nl=g.nl;
                const short *ln=g.line;
-               long ik,ii;
                bool np=true;
-               if(ln && nl>0)  for(ik=0;ik<nl;ik++)
+               if(ln && nl>0)  for(long ik=0;ik<nl;ik++)
                {
-                       ii = 2*ik;
+                       long ii = 2*ik;
                        if(ln[ii]==0x3fff && ln[ii+1]==0x3fff)  // line breakthrough
                        {       mgl_printf(fp, gz, "%s",ln3);   np=true;        continue;       }
                        else if(np)     mgl_printf(fp, gz, ln1,ln[ii],ln[ii+1]);
@@ -181,8 +180,9 @@ void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr)
        if(!strcmp(fname,"-"))  fp = stdout;            // allow to write in stdout
        else            fp = gz ? (void*)gzopen(fname,"wt") : (void*)fopen(fname,"wt");
        if(!fp)         {       gr->SetWarn(mglWarnOpen,fname); return; }
-       setlocale(LC_NUMERIC, "C");
-       mgl_printf(fp, gz, "%%!PS-Adobe-3.0 EPSF-3.0\n%%%%BoundingBox: 0 0 %d %d\n", _Gr_->GetWidth(), _Gr_->GetHeight());
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");
+       int w = _Gr_->GetWidth(), h = _Gr_->GetHeight();
+       mgl_printf(fp, gz, "%%!PS-Adobe-3.0 EPSF-3.0\n%%%%BoundingBox: 0 0 %d %d\n", w, h);
        mgl_printf(fp, gz, "%%%%Created by MathGL library\n%%%%Title: %s\n",descr ? descr : fname);
        mgl_printf(fp, gz, "%%%%CreationDate: %s\n",ctime(&now));
        mgl_printf(fp, gz, "/lw {setlinewidth} def\n/rgb {setrgbcolor} def\n");
@@ -240,6 +240,25 @@ void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr)
        //      if(m_C) mgl_printf(fp, gz, "/m_C {m_c m_o} def\n");
        mgl_printf(fp, gz, "\n");
 
+       // Write background image first
+       const unsigned char *img = mgl_get_background(gr);
+       bool same = true;
+       unsigned char white[3]={255,255,255};
+#pragma omp parallel for
+       for(long i=0;i<w*h;i++) if(memcmp(img,img+4*i,3))       same=false;
+       if(!same)
+       {
+               mgl_printf(fp, gz, "%d %d 8 [1 0 0 1 0 0] {<", w,h,1+w*h/40);
+               for(long j=h-1;j>=0;j--)        for(long i=0;i<w;i++)
+               {
+                       if((i+w*(h-j-1))%40==0 && i+j>0)        mgl_printf(fp, gz, "\n");
+                       mgl_printf(fp, gz, "%02x%02x%02x",img[4*(i+w*j)],img[4*(i+w*j)+1],img[4*(i+w*j)+2]);
+               }
+               mgl_printf(fp, gz, "\n>} false 3 colorimage\n\n");
+       }
+       else if(memcmp(img,white,3))
+               mgl_printf(fp, gz, "np 0 0 mt 0 %d ll %d %d ll %d 0 ll cp %g %g %g rgb fill\n", h, w, h, w, img[0]/255., img[1]/255., img[2]/255.);
+
        // write definition for all glyphs
        put_desc(gr,fp,gz,"/%c%c_%04x { np\n", "\t%d %d mt ", "%d %d ll ", "cp\n", "} def\n");
        // write primitives
@@ -309,7 +328,7 @@ void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr)
                        snprintf(str,256,"%.2g lw %.2g %.2g %.2g rgb ", q.w>1 ? q.w:1., cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.);
                        wp = q.w>1  ? q.w:1;    st = q.n3;
                        put_line(gr,fp,gz,i,wp,cp.c,st, "np %g %g mt ", "%g %g ll ", false, 1);
-                       const char *sd = mgl_get_dash(q.n3,q.w);
+                       const char *sd = mgl_get_dash(q.n3,q.w,' ');
                        if(sd && sd[0]) mgl_printf(fp, gz, "%s [%s] %g sd dr\n",str,sd,q.w*q.s);
                        else                    mgl_printf(fp, gz, "%s d0 dr\n",str);
                }
@@ -341,7 +360,7 @@ void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr)
        }
        mgl_printf(fp, gz, "\nshowpage\n%%%%EOF\n");
        if(strcmp(fname,"-"))   {       if(gz)  gzclose((gzFile)fp);    else    fclose((FILE *)fp);     }
-       setlocale(LC_NUMERIC, "");
+       setlocale(LC_NUMERIC, loc.c_str());
 }
 void MGL_EXPORT mgl_write_eps_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
 {      char *s=new char[l+1];  memcpy(s,fname,l);      s[l]=0;
@@ -356,22 +375,47 @@ void MGL_EXPORT mgl_write_svg(HMGL gr, const char *fname,const char *descr)
        time_t now;     time(&now);
 
        bool gz = fname[strlen(fname)-1]=='z';
-       long hh = _Gr_->GetHeight();
+       long hh = _Gr_->GetHeight(), ww = _Gr_->GetWidth();
        void *fp;
        if(!strcmp(fname,"-"))  fp = stdout;            // allow to write in stdout
        else            fp = gz ? (void*)gzopen(fname,"wt") : (void*)fopen(fname,"wt");
        if(!fp)         {       gr->SetWarn(mglWarnOpen,fname); return; }
-       setlocale(LC_NUMERIC, "C");
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");
        mgl_printf(fp, gz, "<?xml version=\"1.0\" standalone=\"no\"?>\n");
        mgl_printf(fp, gz, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20000303 Stylable//EN\" \"http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd\">\n");
-       mgl_printf(fp, gz, "<svg width=\"%d\" height=\"%d\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", _Gr_->GetWidth(), hh);
+       mgl_printf(fp, gz, "<svg width=\"%d\" height=\"%d\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", ww, hh);
 
        mgl_printf(fp, gz, "<!--Created by MathGL library-->\n");
        mgl_printf(fp, gz, "<!--Title: %s-->\n<!--CreationDate: %s-->\n\n",descr?descr:fname,ctime(&now));
 
        // write definition for all glyphs
-       put_desc(gr,fp,gz,"<symbol id=\"%c%c_%04x\"><path d=\"", "\tM %d %d ",
-                        "L %d %d ", "Z\n", "\"/></symbol>\n");
+       put_desc(gr,fp,gz,"<defs><g id=\"%c%c_%04x\"><path d=\"", "\tM %d %d ",
+                        "L %d %d ", "Z\n", "\"/></g></defs>\n");
+
+
+       // Write background image first
+       const unsigned char *img = mgl_get_background(gr);
+       bool same = true;
+       unsigned char white[3]={255,255,255};
+#pragma omp parallel for
+       for(long i=0;i<ww*hh;i++)       if(memcmp(img,img+4*i,3))       same=false;
+       if(!same)
+       {       // TODO write as <image width="100" height="100" xlink:href="data:image/png;base64,...">
+/*             mgl_printf(fp, gz, "%d %d 8 [1 0 0 1 0 0] {<", ww,hh,1+ww*hh/40);
+               for(long j=hh-1;j>=0;j--)       for(long i=0;i<ww;i++)
+               {
+                       if((i+ww*(hh-j-1))%40==0 && i+j>0)      mgl_printf(fp, gz, "\n");
+                       mgl_printf(fp, gz, "%02x%02x%02x",img[4*(i+ww*j)],img[4*(i+ww*j)+1],img[4*(i+ww*j)+2]);
+               }
+               mgl_printf(fp, gz, "\n>} false 3 colorimage\n\n");*/
+       }
+       else if(memcmp(img,white,3))
+       {
+               mgl_printf(fp, gz, "<g fill=\"#%02x%02x%02x\" opacity=\"%g\">\n", img[0], img[1], img[2], img[3]/255.);
+               mgl_printf(fp, gz, "<path d=\"M 0 0 L 0 %ld L %ld %ld L %ld 0 Z\"/> </g>\n", hh, ww, hh, ww);
+       }
+
+
        // currentColor -> inherit ???
        mgl_printf(fp, gz, "<g fill=\"none\" stroke=\"none\" stroke-width=\"0.5\">\n");
        // write primitives
@@ -449,7 +493,7 @@ void MGL_EXPORT mgl_write_svg(HMGL gr, const char *fname,const char *descr)
                        mgl_printf(fp,gz,"<g stroke=\"#%02x%02x%02x\"",int(cp.r[0]),int(cp.r[1]),int(cp.r[2]));
                        if(q.n3)
                        {
-                               mgl_printf(fp, gz, " stroke-dasharray=\"%s\"", mgl_get_dash(q.n3,q.w));
+                               mgl_printf(fp, gz, " stroke-dasharray=\"%s\"", mgl_get_dash(q.n3,q.w,','));
                                mgl_printf(fp, gz, " stroke-dashoffset=\"%g\"", q.s*q.w);
                        }
                        if(q.w>1)       mgl_printf(fp, gz, " stroke-width=\"%g\"", q.w);
@@ -501,7 +545,7 @@ void MGL_EXPORT mgl_write_svg(HMGL gr, const char *fname,const char *descr)
        {       mglPrim &q=gr->GetPrm(i);       if(q.type==-1)  q.type = 1;     }
        mgl_printf(fp, gz, "</g></svg>");
        if(strcmp(fname,"-"))   {       if(gz)  gzclose((gzFile)fp);    else    fclose((FILE *)fp);     }
-       setlocale(LC_NUMERIC, "");
+       setlocale(LC_NUMERIC, loc.c_str());
 }
 void MGL_EXPORT mgl_write_svg_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)
 {      char *s=new char[l+1];  memcpy(s,fname,l);      s[l]=0;
@@ -515,7 +559,7 @@ void MGL_EXPORT mgl_write_tex(HMGL gr, const char *fname,const char *descr)
 
        FILE *fp = fopen(fname,"wt");
        if(!fp)         {       gr->SetWarn(mglWarnOpen,fname); return; }
-       setlocale(LC_NUMERIC, "C");
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");
        fprintf(fp, "%% Created by MathGL library\n%% Title: %s\n\n",descr?descr:fname);
        // provide marks
        fprintf(fp, "\\providecommand{\\mglp}[4]{\\draw[#3] (#1-#4, #2) -- (#1+#4,#2) (#1,#2-#4) -- (#1,#2+#4);}\n");
@@ -638,7 +682,7 @@ void MGL_EXPORT mgl_write_tex(HMGL gr, const char *fname,const char *descr)
        for(long i=0;i<gr->GetPrmNum();i++)
        {       mglPrim &q=gr->GetPrm(i);       if(q.type==-1)  q.type = 1;     }
        fclose(fp);
-       setlocale(LC_NUMERIC, "");
+       setlocale(LC_NUMERIC, loc.c_str());
 
        // provide main file for viewing figure
        fp=fopen("mglmain.tex","wt");
index 4d0ac831bc337c2316b89890b233c136868458c7..6e0d624f518af4950430490f25efd67924653e60 100644 (file)
@@ -31,15 +31,13 @@ std::string MGL_NO_EXPORT mgl_sprintf(const char *str, ...);
 //-----------------------------------------------------------------------------\r
 void mglTexture::GetRGBA(unsigned char *f) const\r
 {\r
-       register long i,j,i0;\r
-       mglColor c1,c2,c;\r
-       for(i=255;i>=0;i--)\r
+       for(long i=255;i>=0;i--)\r
        {\r
-               c1 = col[2*i];  c2 = col[2*i+1];\r
-               for(j=0;j<256;j++)\r
+               mglColor c1 = col[2*i], c2 = col[2*i+1];\r
+               for(long j=0;j<256;j++)\r
                {\r
-                       i0 = 4*(j+256*i);\r
-                       c = c1 + (c2-c1)*(j/255.);\r
+                       register long i0 = 4*(j+256*i);\r
+                       mglColor c = c1 + (c2-c1)*(j/255.);\r
                        f[i0]   = int(255*c.r);\r
                        f[i0+1] = int(255*c.g);\r
                        f[i0+2] = int(255*c.b);\r
@@ -54,7 +52,7 @@ void MGL_EXPORT mgl_obj_glyph_old(HMGL gr, const mglPrim &q, const mglPnt &p, FI
        mreal c=q.s*cos(q.w*M_PI/180), s=-q.s*sin(q.w*M_PI/180);\r
        if(mgl_isnan(q.s))      c=s=0;\r
        double b[4] = {c,-s, s,c};\r
-       long i=q.n1+1, ik,il=0;\r
+       long i=q.n1+1;\r
 \r
        const mglGlyph &g = gr->GetGlf(q.n4);\r
        const mreal dd = 0.004;\r
@@ -81,7 +79,7 @@ void MGL_EXPORT mgl_obj_glyph_old(HMGL gr, const mglPrim &q, const mglPnt &p, FI
        {\r
                if(!(q.n3&4))   // glyph_fill(p,f,g, d);\r
                {\r
-                       for(ik=0;ik<g.nt;ik++)\r
+                       for(long ik=0;ik<g.nt;ik++)\r
                        {\r
                                x = dx+f*g.trig[6*ik];          y = dy+f*g.trig[6*ik+1];\r
                                fprintf(fp,"v %g %g %g\n",p.x+b[0]*x+b[1]*y,p.y+b[2]*x+b[3]*y,p.z);\r
@@ -94,8 +92,9 @@ void MGL_EXPORT mgl_obj_glyph_old(HMGL gr, const mglPrim &q, const mglPnt &p, FI
                }\r
                else    // glyph_wire(p,f,g, d);\r
                {\r
-                       for(ik=0;ik<g.nl;ik++)\r
+                       for(long ik=0;ik<g.nl;ik++)\r
                        {\r
+                               long il=0;\r
                                x = g.line[2*ik];       y = g.line[2*ik+1];\r
                                if(x==0x3fff && y==0x3fff)      // line breakthrough\r
                                {       il = ik+1;      continue;       }\r
@@ -123,8 +122,7 @@ void MGL_EXPORT mgl_obj_glyph_old(HMGL gr, const mglPrim &q, const mglPnt &p, FI
 void MGL_EXPORT mgl_obj_prim_old(HMGL gr, const mglPrim &q, const mglPnt &p, FILE *fp, mreal size)\r
 {\r
        char type = q.n4;       mreal ss=size;\r
-       register long i=q.n1+1,j;\r
-       register long n1=q.n1+1,n2=q.n2+1,n3=q.n3+1,n4=q.n4+1;\r
+       long i=q.n1+1, n1=q.n1+1,n2=q.n2+1,n3=q.n3+1,n4=q.n4+1;\r
        switch(q.type)\r
        {\r
        case 0:\r
@@ -262,16 +260,16 @@ void MGL_EXPORT mgl_obj_prim_old(HMGL gr, const mglPrim &q, const mglPnt &p, FIL
                        fprintf(fp,"l -2/%ld -1/%ld\n", i,i);\r
                        fprintf(fp,"l -1/%ld -3/%ld\n", i,i);   break;\r
                case 'O':\r
-                       for(j=0;j<=20;j++)\r
+                       for(long j=0;j<=20;j++)\r
                                fprintf(fp,"v %g %g %g\n",p.x+ss*mgl_cos[(j*36)%360],p.y+ss*mgl_cos[(270+j*36)%360],p.z);\r
-                       for(j=0;j<20;j++)\r
+                       for(long j=0;j<20;j++)\r
                                fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", j-21,i, j-20,i, i,i);\r
                        break;\r
                case 'C':       fprintf(fp,"p %ld\n", i);\r
                case 'o':\r
-                       for(j=0;j<=20;j++)\r
+                       for(long j=0;j<=20;j++)\r
                                fprintf(fp,"v %g %g %g\n",p.x+ss*mgl_cos[(j*36)%360],p.y+ss*mgl_cos[(270+j*36)%360],p.z);\r
-                       for(j=0;j<20;j++)\r
+                       for(long j=0;j<20;j++)\r
                                fprintf(fp,"l %ld/%ld %ld/%ld\n", j-21,i, j-20,i);\r
                        break;\r
                }\r
@@ -287,15 +285,15 @@ void MGL_EXPORT mgl_obj_prim_old(HMGL gr, const mglPrim &q, const mglPnt &p, FIL
 void MGL_EXPORT mgl_write_obj_old(HMGL gr, const char *fname,const char *descr, int use_png)\r
 {\r
        if(gr->GetPrmNum()==0)  return; // nothing to do\r
-       long m1=0,m2=0,m,j;\r
+       long m1=0,m2=0;\r
        for(size_t i=0;i<gr->Grp.size();i++)    // prepare array of indirect indexing\r
-       {       m = gr->Grp[i].Id;      if(m<m1) m1=m;  if(m>m2) m2=m;  }\r
+       {       register long m = gr->Grp[i].Id;        if(m<m1) m1=m;  if(m>m2) m2=m;  }\r
        long *ng = new long[m2-m1+1];\r
        for(size_t i=0;i<gr->Grp.size();i++)    ng[gr->Grp[i].Id-m1] = i;\r
        for(long i=0;i<gr->GetPrmNum();i++)     // collect data for groups\r
        // it is rather expensive (extra 4b per primitive) but need for export to 3D\r
        {\r
-               m = gr->GetPrm(i).id-m1;\r
+               register long m = gr->GetPrm(i,false).id-m1;\r
                if(m>=0 && m<m2-m1+1)   gr->Grp[ng[m]].p.push_back(i);\r
        }\r
        delete []ng;\r
@@ -304,7 +302,7 @@ void MGL_EXPORT mgl_write_obj_old(HMGL gr, const char *fname,const char *descr,
        FILE *fp=fopen(fname,"wt");\r
        if(!fp)         {       gr->SetWarn(mglWarnOpen,fname); return; }\r
        // vertices definition\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        fprintf(fp,"# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname);\r
        for(long i=0;i<gr->GetPntNum();i++)\r
        {\r
@@ -323,7 +321,7 @@ void MGL_EXPORT mgl_write_obj_old(HMGL gr, const char *fname,const char *descr,
                std::vector<long> &p = gr->Grp[i].p;\r
                for(size_t j=0;j<p.size();j++)\r
                {\r
-                       const mglPrim &q=gr->GetPrm(p[j]);\r
+                       const mglPrim &q=gr->GetPrm(p[j],false);\r
                        mgl_obj_prim_old(gr, q, gr->GetPnt(q.n1), fp, mgl_isnan(q.s)?0:q.s);\r
                }\r
                gr->Grp[i].p.clear();   // we don't need indexes anymore\r
@@ -345,7 +343,7 @@ void MGL_EXPORT mgl_write_obj_old(HMGL gr, const char *fname,const char *descr,
        fprintf(fp,"map_Ka %s\nmap_Kd %s\nmap_Ks %s\n",tname,tname,tname);\r
        fclose(fp);\r
        // prepare texture file (TGA or PNG)\r
-       j=gr->GetTxtNum();\r
+       long j=gr->GetTxtNum();\r
        unsigned char *buf = new unsigned char[4*256*256*j];\r
        unsigned char **pbuf= (unsigned char **)malloc(256*j*sizeof(unsigned char *));\r
        for(long i=0;i<256*j;i++)       pbuf[i] = buf+4*256*i;\r
@@ -353,7 +351,7 @@ void MGL_EXPORT mgl_write_obj_old(HMGL gr, const char *fname,const char *descr,
        if(use_png)     mgl_pnga_save(tname,256,256*j,pbuf);\r
        else            mgl_tga_save(tname,256,256*j,pbuf);\r
        free(pbuf);     delete []buf;   delete []tname;\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
 }\r
 void MGL_EXPORT mgl_write_obj_old_(uintptr_t *gr, const char *fname,const char *descr, int *use_png,int l,int n)\r
 {      char *s=new char[l+1];  memcpy(s,fname,l);      s[l]=0;\r
@@ -365,13 +363,12 @@ void MGL_EXPORT mgl_write_stl(HMGL gr, const char *fname,const char *descr)
        if(gr->GetPrmNum()==0)  return; // nothing to do\r
        FILE *fp = fopen(fname,"wt");\r
        if(!fp)         {       gr->SetWarn(mglWarnOpen,fname); return; }\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        fprintf(fp,"solid %s\n",(descr && *descr)?descr:"mathgl");\r
-       register long i;\r
        mglPnt pp;\r
-       for(i=0;i<gr->GetPrmNum();i++)\r
+       for(long i=0;i<gr->GetPrmNum();i++)\r
        {\r
-               const mglPrim &q=gr->GetPrm(i);\r
+               const mglPrim &q=gr->GetPrm(i,false);\r
                if(q.type==2)   //      triangles\r
                {\r
                        pp = gr->GetPnt(q.n1);\r
@@ -406,7 +403,7 @@ void MGL_EXPORT mgl_write_stl(HMGL gr, const char *fname,const char *descr)
        }\r
        fprintf(fp,"endsolid %s",(descr && *descr)?descr:"mathgl");\r
        fclose(fp);\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
 }\r
 void MGL_EXPORT mgl_write_stl_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)\r
 {      char *s=new char[l+1];  memcpy(s,fname,l);      s[l]=0;\r
@@ -417,13 +414,12 @@ void MGL_EXPORT mgl_write_xyz(HMGL gr, const char *fname,const char *descr)
 {\r
        if(gr->GetPrmNum()==0)  return; // nothing to do\r
 \r
-       register long i;\r
        FILE *fp=fopen(fname,"wt"), *ff;        // vertices definition\r
        if(!fp)         {       gr->SetWarn(mglWarnOpen,fname); return; }\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        fprintf(fp,"# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname);\r
        fprintf(fp,"# List of Vertices, with (x,y,z) coordinates.\n");\r
-       for(i=0;i<gr->GetPntNum();i++)\r
+       for(long i=0;i<gr->GetPntNum();i++)\r
        {\r
                const mglPnt &pp = gr->GetPnt(i);\r
                fprintf(fp,"%g %g %g\n",pp.x,pp.y,pp.z);\r
@@ -439,15 +435,15 @@ void MGL_EXPORT mgl_write_xyz(HMGL gr, const char *fname,const char *descr)
        fprintf(fp,"# Indices of vertices to connect for lines\n");\r
        fprintf(ff,"# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname);\r
        fprintf(ff,"# Indices of vertices to connect for faces\n");\r
-       for(i=0;i<gr->GetPrmNum();i++)\r
+       for(long i=0;i<gr->GetPrmNum();i++)\r
        {\r
-               const mglPrim &q=gr->GetPrm(i);\r
+               const mglPrim &q=gr->GetPrm(i,false);\r
                if(q.type==1)   fprintf(fp,"%ld %ld\n",q.n1+1,q.n2+1);\r
                if(q.type==2)   fprintf(ff,"%ld %ld %ld\n",q.n1+1,q.n2+1,q.n3+1);\r
                if(q.type==3)   fprintf(ff,"%ld %ld %ld\n%ld %ld %ld\n",q.n1+1,q.n2+1,q.n3+1,q.n4+1,q.n2+1,q.n3+1);\r
        }\r
        fclose(fp);     fclose(ff);     delete []tname;\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
 }\r
 void MGL_EXPORT mgl_write_xyz_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)\r
 {      char *s=new char[l+1];  memcpy(s,fname,l);      s[l]=0;\r
@@ -456,17 +452,17 @@ void MGL_EXPORT mgl_write_xyz_(uintptr_t *gr, const char *fname,const char *desc
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_write_off(HMGL gr, const char *fname,const char *descr, int colored)\r
 {\r
-       register long i,nf=0;\r
-       for(i=0;i<gr->GetPrmNum();i++)  // find number of faces\r
+       long nf=0;\r
+       for(long i=0;i<gr->GetPrmNum();i++)     // find number of faces\r
        {\r
-               const mglPrim &q=gr->GetPrm(i);\r
+               const mglPrim &q=gr->GetPrm(i,false);\r
                if(q.type==2 || q.type==3)      nf++;\r
        }\r
        if(nf<=0)       return; // nothing to do\r
 \r
        FILE *fp=fopen(fname,"wt");\r
        if(!fp)         {       gr->SetWarn(mglWarnOpen,fname); return; }\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        // vertices definition\r
        if(colored)\r
                fprintf(fp,"COFF\n# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname);\r
@@ -474,16 +470,16 @@ void MGL_EXPORT mgl_write_off(HMGL gr, const char *fname,const char *descr, int
                fprintf(fp,"OFF\n# Created by MathGL library\n# Title: %s\n",(descr && *descr) ? descr : fname);\r
        fprintf(fp,"# List of Vertices, with (x,y,z,r,g,b,a) coordinates.\n");\r
        fprintf(fp,"%ld %ld 0\n",gr->GetPntNum(), nf);\r
-       for(i=0;i<gr->GetPntNum();i++)\r
+       for(long i=0;i<gr->GetPntNum();i++)\r
        {\r
                const mglPnt &pp = gr->GetPnt(i);\r
                if(colored)\r
                        fprintf(fp,"%g %g %g %g %g %g %g\n", pp.x, pp.y, pp.z, pp.r, pp.g, pp.b, pp.a);\r
                else    fprintf(fp,"%g %g %g\n", pp.x, pp.y, pp.z);\r
        }\r
-       for(i=0;i<gr->GetPrmNum();i++)\r
+       for(long i=0;i<gr->GetPrmNum();i++)\r
        {\r
-               const mglPrim &q=gr->GetPrm(i);\r
+               const mglPrim &q=gr->GetPrm(i,false);\r
                const mglPnt &p1=gr->GetPnt(q.n1);\r
                if(colored)\r
                {\r
@@ -511,7 +507,7 @@ void MGL_EXPORT mgl_write_off(HMGL gr, const char *fname,const char *descr, int
                }\r
        }\r
        fclose(fp);\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
 }\r
 void MGL_EXPORT mgl_write_off_(uintptr_t *gr, const char *fname,const char *descr,int *colored,int l,int n)\r
 {      char *s=new char[l+1];  memcpy(s,fname,l);      s[l]=0;\r
@@ -542,28 +538,22 @@ MGL_EXPORT const char *mgl_get_json(HMGL gr)
 std::string mglCanvas::GetJSON()\r
 {\r
        ClearUnused();  // clear unused points\r
+       PreparePrim(3);\r
        std::string res, buf;\r
-       long i,ll=0,l=(long)Pnt.size();\r
+       long ll=0,l=(long)Pnt.size();\r
        long factor = Width>1?10:10000;\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        res = res + mgl_sprintf("{\n\"width\":%d,\t\"height\":%d,\t\"depth\":%d,\t\"plotid\":\"%s\",\t\"npnts\":%ld,\t\"pnts\":[\n",\r
                        factor*Width, factor*Height, factor*Depth, PlotId.c_str(), l);\r
-       std::string *tmp=new std::string[l];\r
-#pragma omp parallel for reduction(+:ll)\r
        for(long i=0;i<l;i++)\r
        {\r
                const mglPnt &q=Pnt[i];\r
-               tmp[i] = mgl_sprintf("[%ld,%ld,%ld,%d]%c\n", long(factor*q.xx), long(factor*(Height-q.yy)), long(factor*q.zz),q.sub, i+1<l?',':' ');\r
-               ll += tmp[i].length();\r
+               res += mgl_sprintf("[%ld,%ld,%ld,%d]%c\n", long(factor*q.xx), long(factor*(Height-q.yy)), long(factor*q.zz),q.sub, i+1<l?',':' ');\r
        }\r
-       res.reserve(ll);\r
-       for(i=0;i<l;i++)        res = res + tmp[i];\r
-       delete []tmp;\r
 \r
-       l = (long)Prm.size();\r
-       PreparePrim(3);\r
-       for(ll=i=0;i<l;i++)\r
-       {       mglRGBA c;      c.c = GetPrmCol(i);     if(c.r[3])      ll++;   }\r
+       l = (long)Prm.size();   ll = 0;\r
+       for(long i=0;i<l;i++)\r
+       {       mglRGBA c;      c.c = GetPrmCol(i,false);       if(c.r[3])      ll++;   }\r
 \r
        res = res + mgl_sprintf("],\t\"nprim\":%ld,\t\"prim\":[\n",ll+1);\r
 \r
@@ -572,7 +562,7 @@ std::string mglCanvas::GetJSON()
 #pragma omp parallel for private(buf)\r
        for(long i=0;i<l;i++)\r
        {\r
-               const mglPrim &p=Prm[i];        mglRGBA cp;     cp.c = GetPrmCol(i);\r
+               const mglPrim &p=Prm[i];        mglRGBA cp;     cp.c = GetPrmCol(i,false);\r
                if(p.n1<0 || (p.type==1 && p.n2<0) || (p.type==2 && (p.n2<0 || p.n3<0)) || (p.type==3 && (p.n2<0 || p.n3<0 || p.n4<0)))\r
                        continue;\r
                long n1=p.n1, n2=p.n2, n3=0, n4=(p.type==3||p.type==0)?p.n4:0;\r
@@ -600,7 +590,7 @@ std::string mglCanvas::GetJSON()
 \r
        l = (long)xy.size();\r
        res = res + mgl_sprintf("],\t\"ncoor\":%lu,\t\"coor\":[\n",(unsigned long)l);\r
-       for(i=0;i<l;i++)\r
+       for(long i=0;i<l;i++)\r
        {\r
                const mglPoint &p=xy[i];\r
                const mglPnt &q=Pnt[int(0.5+p.z)];\r
@@ -613,7 +603,7 @@ std::string mglCanvas::GetJSON()
 \r
        l = (long)Glf.size();\r
        res = res + mgl_sprintf("],\t\"nglfs\":%lu,\t\"glfs\":[\n",(unsigned long)l);\r
-       for(i=0;i<l;i++)\r
+       for(long i=0;i<l;i++)\r
        {\r
                const mglGlyph &g=Glf[i];\r
                res = res + mgl_sprintf("[%ld,\n\t[", g.nl);\r
@@ -621,7 +611,7 @@ std::string mglCanvas::GetJSON()
                res = res + mgl_sprintf("]\n]%c\n", i+1<l?',':' ');\r
        }\r
        res = res + mgl_sprintf("]\n}\n");\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
        return res;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -644,7 +634,7 @@ bool mglCanvas::ExportMGLD(const char *fname, const char *descr)
        if(Pnt.size()<1 || Prm.size()<1)        return true;\r
        FILE *fp=fopen(fname,"wt");\r
        if(!fp) return true;\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        // NOTE: I'll save Ptx. So prim type=6 is useless,and no LaTeX\r
        fprintf(fp,"MGLD %lu %lu %lu %lu %d %d\n# %s\n", (unsigned long)Pnt.size(), (unsigned long)Prm.size(), (unsigned long)Txt.size(), (unsigned long)Glf.size(), Width, Height, (descr && *descr) ? descr : fname);\r
        fprintf(fp,"# Vertexes: x y z c t ta u v w r g b a\n");\r
@@ -656,8 +646,9 @@ bool mglCanvas::ExportMGLD(const char *fname, const char *descr)
        fprintf(fp,"# Primitives: type n1 n2 n3 n4 id s w p\n");\r
        for(size_t i=0;i<Prm.size();i++)\r
        {\r
-               const mglPrim &p=Prm[i];        // TODO: check if better save p.m instead of p.s,p.p\r
-               fprintf(fp,"%d\t%ld\t%ld\t%ld\t%ld\t%d\t%g\t%g\t%g\n", p.type, p.n1, p.n2, p.n3, p.n4, p.id, p.s==p.s?p.s:0, p.w==p.w?p.w:0, p.p==p.p?p.p:0);\r
+               const mglPrim &p=Prm[i];\r
+               long long unsigned mask = p.m;\r
+               fprintf(fp,"%d\t%ld\t%ld\t%ld\t%ld\t%d\t%g\t%g\t%g\t%d\t%llu\n", p.type, p.n1, p.n2, p.n3, p.n4, p.id, p.s==p.s?p.s:0, p.w==p.w?p.w:0, p.p==p.p?p.p:0, p.angl, mask);\r
        }\r
        fprintf(fp,"# Textures: smooth alpha colors\n");\r
        for(size_t i=0;i<Txt.size();i++)\r
@@ -682,7 +673,7 @@ bool mglCanvas::ExportMGLD(const char *fname, const char *descr)
                }\r
        }\r
        fclose(fp);\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
        return false;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -700,13 +691,13 @@ bool mglCanvas::ImportMGLD(const char *fname, bool add)
        char *buf=new char[512];\r
        if(!fgets(buf,512,fp))  *buf=0;\r
        if(strncmp(buf,"MGLD",4))       {       delete []buf;   fclose(fp);     return true;    }\r
-       unsigned long i,n=0,m=0,l=0,k=0, npnt=0, nglf=0;\r
+       unsigned long n=0,m=0,l=0,k=0, npnt=0, nglf=0;\r
        int w=0,h=0,d;\r
        sscanf(buf+5,"%lu%lu%lu%lu%d%d",&n,&m,&l,&k,&w,&h);\r
        if(w<=0 || h<=0)        {       w=Width;        h=Height;       }\r
        d = long(sqrt(double(w*h)));\r
        if(n==0 || m==0 || l==0)        {       delete []buf;   fclose(fp);     return true;    }\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        if(!add)        {       Clf();  Txt.clear();    }\r
        else    {       ClfZB();        npnt=Pnt.size();        nglf=Glf.size();        }\r
 #if MGL_HAVE_PTHREAD\r
@@ -719,7 +710,7 @@ bool mglCanvas::ImportMGLD(const char *fname, bool add)
        {\r
                Pnt.reserve(n); Prm.reserve(m); Txt.reserve(l); Glf.reserve(k);\r
                mglPnt p;\r
-               for(i=0;i<n;i++)\r
+               for(unsigned long i=0;i<n;i++)\r
                {\r
                        do {    if(!fgets(buf,512,fp))  *buf=0; mgl_strtrim(buf);       } while(*buf=='#');\r
                        sscanf(buf,"%g%g%g%g%g%g%g%g%g%g%g%g%g", &p.xx, &p.yy, &p.zz, &p.c, &p.t, &p.ta, &p.u, &p.v, &p.w, &p.r, &p.g, &p.b, &p.a);\r
@@ -728,24 +719,27 @@ bool mglCanvas::ImportMGLD(const char *fname, bool add)
                        Pnt.push_back(p);\r
                }\r
                mglPrim q;\r
-               for(i=0;i<m;i++)\r
+               for(unsigned long i=0;i<m;i++)\r
                {\r
                        do {    if(!fgets(buf,512,fp))  *buf=0; mgl_strtrim(buf);       } while(*buf=='#');\r
-                       sscanf(buf,"%hd%ld%ld%ld%ld%d%g%g%g", &q.type, &q.n1, &q.n2, &q.n3, &q.n4, &q.id, &q.s, &q.w, &q.p);\r
-                       q.n1 = q.n1>=0?q.n1+npnt:-1;\r
-                       q.n2 = q.n2>=0?q.n2+npnt:-1;\r
-                       if(q.type==2 || q.type==3)\r
-                       {       q.n3 = q.n3>=0?q.n3+npnt:-1;    q.n4 = q.n4>=0?q.n4+npnt:-1;    }\r
-                       if(q.type==4)\r
-                       {       q.n4 = q.n4>=0?q.n4+nglf:-1;    q.s *= font_factor/(w<h?w:h);   }\r
-                       if(q.type<5)    Prm.push_back(q);\r
+                       long long unsigned mask=MGL_SOLID_MASK;\r
+                       sscanf(buf,"%hd%ld%ld%ld%ld%d%g%g%g%hd%llu", &q.type, &q.n1, &q.n2, &q.n3, &q.n4, &q.id, &q.s, &q.w, &q.p, &q.angl, &mask);\r
+                       q.n1 = q.n1>=0?q.n1+npnt:-1;    q.n2 = q.n2>=0?q.n2+npnt:-1;\r
+                       switch(q.type)\r
+                       {\r
+                       case 3: q.n4 = q.n4>=0?q.n4+npnt:-1;\r
+                       case 2: q.n3 = q.n3>=0?q.n3+npnt:-1;    q.m = mask;     break;\r
+                       case 4: q.s *= (Width<Height?Width:Height)/double(w<h?w:h);\r
+                                       q.n4 = q.n4>=0?q.n4+nglf:-1;    break;\r
+                       }\r
+                       Prm.push_back(q);\r
                }\r
                mglTexture t;\r
-               for(i=0;i<l;i++)\r
+               for(unsigned long i=0;i<l;i++)\r
                {\r
                        int sm=0;       float a;\r
                        do {    if(!fgets(buf,512,fp))  *buf=0; mgl_strtrim(buf);       } while(*buf=='#');\r
-                       register size_t j,k=0;\r
+                       size_t j,k=0;\r
                        for(j=0;buf[j];j++)\r
                        {\r
                                if(buf[j]<=' ' && k)    {       sm++;   k=0;    }\r
@@ -757,14 +751,13 @@ bool mglCanvas::ImportMGLD(const char *fname, bool add)
                        Txt.push_back(t);\r
                }\r
                mglGlyph g;\r
-               for(i=0;i<k;i++)\r
+               for(unsigned long i=0;i<k;i++)\r
                {\r
                        do {    if(!fgets(buf,512,fp))  *buf=0; mgl_strtrim(buf);       } while(*buf=='#' || *buf==0);\r
                        long nt=0,nl=0;\r
                        sscanf(buf,"%ld%ld", &nt, &nl); g.Create(nt,nl);\r
-                       register long j;\r
-                       for(j=0;j<6*nt;j++)     fscanf(fp,"%hd",g.trig+j);\r
-                       for(j=0;j<2*nl;j++)     fscanf(fp,"%hd",g.line+j);\r
+                       for(long j=0;j<6*nt;j++)        fscanf(fp,"%hd",g.trig+j);\r
+                       for(long j=0;j<2*nl;j++)        fscanf(fp,"%hd",g.line+j);\r
                        Glf.push_back(g);\r
                }\r
        }\r
@@ -774,7 +767,7 @@ bool mglCanvas::ImportMGLD(const char *fname, bool add)
        pthread_mutex_unlock(&mutexPrm);\r
        pthread_mutex_unlock(&mutexTxt);\r
 #endif\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
        delete []buf;   fclose(fp);     return false;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -975,7 +968,7 @@ void mglCanvas::WriteXGL(const char *fname,const char *descr)
        for(i=0;i<GetPrmNum();i++)      // collect data for groups\r
        // it is rather expensive (extra 4b per primitive) but need for export to 3D\r
        {\r
-               m = GetPrm(i).id-m1;\r
+               m = GetPrm(i,false).id-m1;\r
                if(m>=0 && m<m2-m1+1)   Grp[ng[m]].p.push_back(i);\r
        }\r
        delete []ng;\r
@@ -989,7 +982,7 @@ void mglCanvas::WriteXGL(const char *fname,const char *descr)
                fprintf(fp,"<OBJECT>\n<NAME>%s</NAME>\n<MESH>\n",Grp[i].Lbl.c_str());\r
                for(j=0;j<p.size();j++)         // collect Pnt for this object\r
                {\r
-                       const mglPrim q=GetPrm(p[j]);   pg[q.n1]=1;\r
+                       const mglPrim q=GetPrm(p[j],false);     pg[q.n1]=1;\r
                        if(q.type==3)   {       pg[q.n2]=1;     pg[q.n3]=1;     pg[q.n4]=1;     }\r
                        else if(q.type==1)      pg[q.n2]=1;\r
                        else if(q.type==2)      {       pg[q.n2]=1;     pg[q.n3]=1;     }\r
@@ -1003,7 +996,7 @@ void mglCanvas::WriteXGL(const char *fname,const char *descr)
                // TODO: add line styles\r
                for(j=0;j<p.size();j++) // now write primitives itself\r
                {\r
-                       const mglPrim q=GetPrm(p[j]);\r
+                       const mglPrim q=GetPrm(p[j],false);\r
                        mgl_xgl_prim(q, GetPnt(q.n1), fp, q.s*FontFactor());\r
                }\r
                fprintf(fp,"</MESH>\n</OBJECT>");       // finish with this object\r
@@ -1029,7 +1022,7 @@ void MGL_EXPORT mgl_x3d_mdef(HMGL gr, void *fp, bool gz)
        m_L=false,m_r=false,m_R=false,m_X=false,m_P=false;\r
        for(long i=0;i<gr->GetPrmNum();i++)\r
        {\r
-               const mglPrim q = gr->GetPrm(i);\r
+               const mglPrim q = gr->GetPrm(i,false);\r
                if(q.type>0)    continue;               if(q.n4=='+')   m_p = true;\r
                if(q.n4=='x')   m_x = true;             if(q.n4=='s')   m_s = true;\r
                if(q.n4=='d')   m_d = true;             if(q.n4=='v')   m_v = true;\r
@@ -1164,7 +1157,7 @@ void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr)
        bool gz = fname[strlen(fname)-1]=='z';\r
        void *fp = gz ? (void*)gzopen(fname,"wt") : (void*)fopen(fname,"wt");\r
        if(!fp)         {       gr->SetWarn(mglWarnOpen,fname); return; }\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        mgl_printf(fp, gz, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");\r
        mgl_printf(fp, gz, "<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n");\r
        mgl_printf(fp, gz, "<X3D profile='Immersive'>\n<head>\n<meta name='filename' content='%s'/>\n",fname);\r
@@ -1187,14 +1180,11 @@ void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr)
        for(long i=0;i<gr->GetPrmNum();i++)     // collect data for groups\r
        // it is rather expensive (extra 4b per primitive) but need for export to 3D\r
        {\r
-               m = gr->GetPrm(i).id-m1;\r
+               m = gr->GetPrm(i,false).id-m1;\r
                if(m>=0 && m<m2-m1+1)   gr->Grp[ng[m]].p.push_back(i);\r
        }\r
        delete []ng;\r
 \r
-       // resort in creation order for proper drawing of lines and faces\r
-       gr->resort();\r
-\r
        // primitive definition in groups\r
        long npnt = gr->GetPntNum(), k;\r
        long *pnt=new long[npnt];\r
@@ -1208,7 +1198,7 @@ void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr)
                long line=-1, face=-1, other=-1;        k=0;\r
                for(size_t j=0;j<p.size();j++)  // find points for this group\r
                {\r
-                       const mglPrim &q=gr->GetPrm(p[j]);\r
+                       const mglPrim &q=gr->GetPrm(p[j],false);\r
                        if(q.type==1)   line=q.n1;      // find kind of primitives in the group\r
                        if(q.type==2 || q.type==3)      face =q.n1;\r
                        if(q.type>3 || q.type==0)       other=q.n1;\r
@@ -1221,13 +1211,13 @@ void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr)
                        bool same=true; // check if there are the same colors for all line segments\r
                        for(size_t j=0;j<p.size();j++)\r
                        {\r
-                               const mglPrim &q=gr->GetPrm(p[j]);\r
+                               const mglPrim &q=gr->GetPrm(p[j],false);\r
                                if(q.type==1 && c!=gr->GetPntC(q.n1))   same=false;\r
                        }\r
                        memset(pnt,-1,npnt*sizeof(long));\r
                        for(size_t j=0,k=0;j<p.size();j++)      // rearrange points for this group\r
                        {\r
-                               const mglPrim &q=gr->GetPrm(p[j]);\r
+                               const mglPrim &q=gr->GetPrm(p[j],false);\r
                                if(q.type!=1)   continue;\r
                                if(q.n1>=0 && pnt[q.n1]<0)      {       pnt[q.n1]=k;    k++;    }\r
                                if(q.n2>=0 && pnt[q.n2]<0)      {       pnt[q.n2]=k;    k++;    }\r
@@ -1253,13 +1243,13 @@ void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr)
                        bool same=true; // check if there are the same colors for all line segments\r
                        for(size_t j=0;j<p.size();j++)\r
                        {\r
-                               const mglPrim &q=gr->GetPrm(p[j]);\r
+                               const mglPrim &q=gr->GetPrm(p[j],false);\r
                                if((q.type==2 || q.type==3) && c!=gr->GetPntC(q.n1))    same=false;\r
                        }\r
                        memset(pnt,-1,npnt*sizeof(long));\r
                        for(size_t j=0,k=0;j<p.size();j++)      // rearrange points for this group\r
                        {\r
-                               const mglPrim &q=gr->GetPrm(p[j]);\r
+                               const mglPrim &q=gr->GetPrm(p[j],false);\r
                                if(q.type!=2 && q.type!=3)      continue;\r
                                if(q.n1>=0 && pnt[q.n1]<0)      {       pnt[q.n1]=k;    k++;    }\r
                                if(q.n2>=0 && pnt[q.n2]<0)      {       pnt[q.n2]=k;    k++;    }\r
@@ -1286,7 +1276,7 @@ void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr)
 /*                     memset(pnt,-1,npnt*sizeof(long));\r
                        for(j=0,k=0;j<p.size();j++)     // rearrange points for this group\r
                        {\r
-                               const mglPrim &q=gr->GetPrm(p[j]);\r
+                               const mglPrim &q=gr->GetPrm(p[j],false);\r
                                if(q.type!=2 && q.type!=3)      continue;\r
                                if(q.n1>=0 && pnt[q.n1]<0)      {       pnt[q.n1]=k;    k++;    }\r
                                if(q.n2>=0 && pnt[q.n2]<0)      {       pnt[q.n2]=k;    k++;    }\r
@@ -1310,7 +1300,7 @@ void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr)
 \r
                for(size_t j=0;j<p.size();j++)\r
                {\r
-                       const mglPrim &q=gr->GetPrm(p[j]);      // TODO: collect by type (quads,trig,line) and draw together???\r
+                       const mglPrim &q=gr->GetPrm(p[j],false);        // TODO: collect by type (quads,trig,line) and draw together???\r
                        mgl_x3d_prim(q, gr->GetPnt(q.n1), pnt, fp,gz, q.s*gr->FontFactor());\r
                }\r
                mgl_printf(fp,gz,"</Group><!--%s-->\n",gr->Grp[i].Lbl.c_str());\r
@@ -1318,7 +1308,7 @@ void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr)
        }\r
        mgl_printf(fp, gz, "</Scene>\n");\r
        if(gz)  gzclose((gzFile)fp);    else    fclose((FILE *)fp);\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
        delete []pnt;\r
 }\r
 void MGL_EXPORT mgl_write_x3d_(uintptr_t *gr, const char *fname,const char *descr,int l,int n)\r
index c606b049d9553a663509323f21250f29b47a051f..c5a8c97440e3e1f77e7badb02916fdda899c698f 100644 (file)
@@ -127,23 +127,18 @@ void MGL_EXPORT mgl_fft(double *x, long s, long n, const void *wt, void *ws, int
        const double *c = (const double *)wt;
        double *d = (double *)ws, f = inv?1./n:1;
        memset(d,0,2*n*sizeof(double));
-       if(inv)
-//#pragma omp parallel for     // NOTE only 1st for can be used!
-               for(long i=0;i<n;i++)   for(long j=0;j<n;j++)
-               {
-                       register long ii = 2*(i+n*j), jj = 2*j*s;
-                       d[2*i]  += x[jj]*c[ii]+x[jj+1]*c[ii+1];
-                       d[2*i+1]+= x[jj+1]*c[ii]-x[jj]*c[ii+1];
-               }
-       else
-//#pragma omp parallel for     // NOTE only 1st for can be used!
-               for(long i=0;i<n;i++)   for(long j=0;j<n;j++)
-               {
-                       register long ii = 2*(i+n*j), jj = 2*j*s;
-                       d[2*i]  += x[jj]*c[ii]-x[jj+1]*c[ii+1];
-                       d[2*i+1]+= x[jj+1]*c[ii]+x[jj]*c[ii+1];
-               }
-//#pragma omp parallel for
+       if(inv) for(long i=0;i<n;i++)   for(long j=0;j<n;j++)
+       {
+               register long ii = 2*(i+n*j), jj = 2*j*s;
+               d[2*i]  += x[jj]*c[ii]+x[jj+1]*c[ii+1];
+               d[2*i+1]+= x[jj+1]*c[ii]-x[jj]*c[ii+1];
+       }
+       else    for(long i=0;i<n;i++)   for(long j=0;j<n;j++)
+       {
+               register long ii = 2*(i+n*j), jj = 2*j*s;
+               d[2*i]  += x[jj]*c[ii]-x[jj+1]*c[ii+1];
+               d[2*i+1]+= x[jj+1]*c[ii]+x[jj]*c[ii+1];
+       }
        for(long j=0;j<n;j++)
        {       register long jj = 2*j*s;       x[jj] = d[2*j]*f;       x[jj+1] = d[2*j+1]*f;   }
 #endif
@@ -168,14 +163,14 @@ MGL_NO_EXPORT void* mgl_fftx(void *par)
 MGL_NO_EXPORT void* mgl_ffty(void *par)
 {
        mglThreadT *t=(mglThreadT *)par;
-       register long i,nx=t->p[0],ny=t->p[1];
+       long nx=t->p[0],ny=t->p[1];
 #if !MGL_HAVE_PTHREAD
 #pragma omp parallel
 #endif
        {
                void *w = mgl_fft_alloc_thr(nx);
 #pragma omp for nowait
-               for(i=t->id;i<t->n;i+=mglNumThr)
+               for(long i=t->id;i<t->n;i+=mglNumThr)
                        mgl_fft(t->b+2*(i%nx)+2*nx*ny*(i/nx), nx, ny, t->v, w, t->p[3]);
                mgl_fft_free_thr(w);
        }
@@ -184,14 +179,14 @@ MGL_NO_EXPORT void* mgl_ffty(void *par)
 MGL_NO_EXPORT void* mgl_fftz(void *par)
 {
        mglThreadT *t=(mglThreadT *)par;
-       register long i,nx=t->p[0],ny=t->p[1],nz=t->p[2];
+       long nx=t->p[0],ny=t->p[1],nz=t->p[2];
 #if !MGL_HAVE_PTHREAD
 #pragma omp parallel
 #endif
        {
                void *w = mgl_fft_alloc_thr(nx);
 #pragma omp for nowait
-               for(i=t->id;i<t->n;i+=mglNumThr)
+               for(long i=t->id;i<t->n;i+=mglNumThr)
                        mgl_fft(t->b+2*i, nx*ny, nz, t->v, w, t->p[3]);
                mgl_fft_free_thr(w);
        }
@@ -632,7 +627,7 @@ MGL_NO_EXPORT void* mgl_cosx(void *par)
                        for(long j=0;j<nn;j++)  b[2*j]=(a[j+k]+a[nn-j+k])*0.5-sin(M_PI*j/nn)*(a[j+k]-a[nn-j+k]);
                        mgl_fft(b,1,nn,t->v,w,false);
                        double f1=0.5*(a[k]-a[nn+k]), s=-1;
-                       a[nn+k]=0.5*(a[k]+a[nn+k]*(nn%2?-1:1));
+                       a[nn+k]=0.5*(a[k]+a[nn+k]*((nn%2)?-1:1));
                        for(long j=1;j<nn;j++)
                        {
                                f1 += a[j+k]*cos(M_PI*j/nn);
@@ -669,7 +664,7 @@ MGL_NO_EXPORT void* mgl_cosy(void *par)
                        for(long j=0;j<nn;j++)  b[2*j]=(a[i+nx*(ny*k+j)]+a[i+nx*(ny*k+nn-j)])*0.5-sin(M_PI*j/nn)*(a[i+nx*(ny*k+j)]-a[i+nx*(ny*k+nn-j)]);
                        mgl_fft(b,1,nn,t->v,w,false);
                        double f1=0.5*(a[i+nx*ny*k]-a[i+nx*(ny*k+nn)]), s=-1;
-                       a[i+nx*(ny*k+nn)]=0.5*(a[i+nx*ny*k]+a[i+nx*(ny*k+nn)]*(nn%2?-1:1));
+                       a[i+nx*(ny*k+nn)]=0.5*(a[i+nx*ny*k]+a[i+nx*(ny*k+nn)]*((nn%2)?-1:1));
                        for(long j=1;j<nn;j++)
                        {
                                f1 += a[i+nx*(ny*k+j)]*cos(M_PI*j/nn);
@@ -706,7 +701,7 @@ MGL_NO_EXPORT void* mgl_cosz(void *par)
                        for(long j=0;j<nn;j++)  b[2*j]=(a[i+k*j]+a[i+k*(nn-j)])*0.5-sin(M_PI*j/nn)*(a[i+k*j]-a[i+k*(nn-j)]);
                        mgl_fft(b,1,nn,t->v,w,false);
                        double f1=0.5*(a[i]-a[i+k*nn]), s=-1;
-                       a[i+k*nn]=0.5*(a[i]+a[i+k*nn]*(nn%2?-1:1));
+                       a[i+k*nn]=0.5*(a[i]+a[i+k*nn]*((nn%2)?-1:1));
                        for(long j=1;j<nn;j++)
                        {
                                f1 += a[i+k*j]*cos(M_PI*j/nn);
@@ -761,21 +756,14 @@ void MGL_EXPORT mgl_data_cosfft(HMDT d, const char *dir)
 HMDT MGL_EXPORT mgl_transform_a(HCDT am, HCDT ph, const char *tr)
 {
        long nx = am->GetNx(), ny = am->GetNy(), nz = am->GetNz();
-       if(nx*ny*nz != ph->GetNx()*ph->GetNy()*ph->GetNz() || !tr || tr[0]==0)
-               return 0;
+       if(nx*ny*nz != ph->GetNN() || !tr || tr[0]==0)  return 0;
        mglData re(nx,ny,nz), im(nx,ny,nz);
-       const mglData *da=dynamic_cast<const mglData *>(am);
-       const mglData *dp=dynamic_cast<const mglData *>(ph);
-       if(da && dp)
-#pragma omp parallel for
-               for(long i=0;i<nx*ny*nz;i++)
-               {       re.a[i] = da->a[i]*cos(dp->a[i]);
-                       im.a[i] = da->a[i]*sin(dp->a[i]);       }
-       else
 #pragma omp parallel for
-               for(long i=0;i<nx*ny*nz;i++)
-               {       re.a[i] = am->vthr(i)*cos(ph->vthr(i));
-                       im.a[i] = am->vthr(i)*sin(ph->vthr(i)); }
+       for(long i=0;i<nx*ny*nz;i++)
+       {
+               register mreal a=am->vthr(i), p=ph->vthr(i);
+               re.a[i] = a*cos(p);     im.a[i] = a*sin(p);
+       }
        return mgl_transform(&re, &im, tr);
 }
 //-----------------------------------------------------------------------------
@@ -783,8 +771,7 @@ HMDT MGL_EXPORT mgl_transform(HCDT re, HCDT im, const char *tr)
 {
        if(!tr || *tr==0)       return 0;
        long nx = re->GetNx(), ny = re->GetNy(), nz = re->GetNz();
-       if(nx*ny*nz != im->GetNx()*im->GetNy()*im->GetNz() || !tr || tr[0]==0)
-               return 0;
+       if(nx*ny*nz != im->GetNN() || !tr || tr[0]==0)  return 0;
        mglData rr(re),ii(im);
        if(strchr(tr,'i') && strchr(tr,'f'))    // general case
        {
@@ -1099,12 +1086,8 @@ void MGL_EXPORT mgl_data_fill_sample(HMDT d, const char *how)
        }
        else    // Fourier
        {
-               if(xx)
-#pragma omp parallel for
-                       for(long i=0;i<n;i++)   aa[i] = mreal(2*i-n)/n;
-               else
-#pragma omp parallel for
-                       for(long i=0;i<n;i++)   aa[i] = M_PI*(i<n/2 ? i:i-n);
+               if(xx)  for(long i=0;i<n;i++)   aa[i] = mreal(2*i-n)/n;
+               else    for(long i=0;i<n;i++)   aa[i] = M_PI*(i<n/2 ? i:i-n);
        }
 #pragma omp parallel for
        for(long i=1;i<d->ny*d->nz;i++) memcpy(aa+i*n,aa,n*sizeof(mreal));
index e5f4f8268bd648fefce26a47834e54b7548d72b9..d84d6e7d2cff5215d33907a89091712c7467a99f 100644 (file)
@@ -28,6 +28,7 @@
 #include <gsl/gsl_multifit_nlin.h>\r
 #include <gsl/gsl_blas.h>\r
 #endif\r
+mglData MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector<mglDataA*> &head);\r
 //-----------------------------------------------------------------------------\r
 int mglFitPnts=100;            ///< Number of output points in fitting\r
 char mglFitRes[1024];  ///< Last fitted formula\r
@@ -53,12 +54,10 @@ void MGL_EXPORT mgl_puts_fit_(uintptr_t* gr, mreal *x, mreal *y, mreal *z, const
 struct mglFitData\r
 {\r
        long n;                         ///< number of points\r
-       mreal *x;                       ///< x values\r
-       mreal *y;                       ///< y values\r
-       mreal *z;                       ///< z values\r
+       mglDataA *x,*y,*z;      ///< x, y, z values\r
        mreal *a;                       ///< function values\r
        mreal *s;                       ///< value dispersions (sigma)\r
-       mglFormula *eq;         ///< approximation formula\r
+       const char *eq;         ///< approximation formula\r
        int m;                          ///< number of variables\r
        const char *var;        ///< variables for fitting\r
 };\r
@@ -67,46 +66,71 @@ struct mglFitData
 int    mgl_fit__f (const gsl_vector *x, void *data, gsl_vector *f)\r
 {\r
        mglFitData *fd = (mglFitData *)data;\r
-#pragma omp parallel\r
-       {\r
-               mreal val[MGL_VS];\r
-               for(long i=0;i<fd->m;i++)       val[fd->var[i]-'a'] = gsl_vector_get(x,i);\r
-#pragma omp for\r
-               for(long i=0;i<fd->n;i++)\r
-               {\r
-                       val['x'-'a'] = fd->x[i];\r
-                       val['y'-'a'] = fd->y ? fd->y[i] : 0;\r
-                       val['z'-'a'] = fd->z ? fd->z[i] : 0;\r
-                       gsl_vector_set (f, i, (fd->eq->Calc(val) - fd->a[i])/fd->s[i]);\r
-               }\r
-       }\r
+       mglDataV *var = new mglDataV[fd->m];\r
+       std::vector<mglDataA*> list;\r
+       for(long i=0;i<fd->m;i++)\r
+       {       var[i].s=fd->var[i];    var[i].Fill(gsl_vector_get(x,i));       list.push_back(var+i);  }\r
+       if(fd->x)       list.push_back(fd->x);\r
+       if(fd->y)       list.push_back(fd->y);\r
+       if(fd->z)       list.push_back(fd->z);\r
+       mglData res = mglFormulaCalc(fd->eq, list);\r
+#pragma omp parallel for\r
+       for(long i=0;i<fd->n;i++)\r
+               gsl_vector_set (f, i, (res.a[i] - fd->a[i])/fd->s[i]);\r
+       delete []var;\r
        return GSL_SUCCESS;\r
 }\r
 //-----------------------------------------------------------------------------\r
 int MGL_NO_EXPORT mgl_fit__df (const gsl_vector * x, void *data, gsl_matrix * J)\r
 {\r
        mglFitData *fd = (mglFitData *)data;\r
-#pragma omp parallel\r
+       mglDataV *var = new mglDataV[fd->m];\r
+       std::vector<mglDataA*> list;\r
+       for(long i=0;i<fd->m;i++)\r
+       {       var[i].s=fd->var[i];    var[i].Fill(gsl_vector_get(x,i));       list.push_back(var+i);  }\r
+       if(fd->x)       list.push_back(fd->x);\r
+       if(fd->y)       list.push_back(fd->y);\r
+       if(fd->z)       list.push_back(fd->z);\r
+       mglData res = mglFormulaCalc(fd->eq, list);\r
+       const mreal eps = 1e-5;\r
+       for(long j=0;j<fd->m;j++)\r
        {\r
-               mreal val[MGL_VS],s;\r
-               for(long i=0;i<fd->m;i++)       val[fd->var[i]-'a'] = gsl_vector_get(x,i);\r
-#pragma omp for\r
+               var[j].Fill(gsl_vector_get(x,j)+eps);\r
+               mglData dif = (mglFormulaCalc(fd->eq, list)-res)/eps;\r
+               var[j].Fill(gsl_vector_get(x,j));\r
+#pragma omp parallel for\r
                for(long i=0;i<fd->n;i++)\r
-               {\r
-                       val['x'-'a'] = fd->x[i];        s = fd->s[i];\r
-                       val['y'-'a'] = fd->y ? fd->y[i] : 0;\r
-                       val['z'-'a'] = fd->z ? fd->z[i] : 0;\r
-                       for(long j=0;j<fd->m;j++)\r
-                               gsl_matrix_set (J, i, j, fd->eq->CalcD(val, fd->var[j])/s);\r
-               }\r
+                       gsl_matrix_set (J, i, j, dif.a[i]/fd->s[i]);\r
        }\r
+       delete []var;\r
        return GSL_SUCCESS;\r
 }\r
 //-----------------------------------------------------------------------------\r
 int MGL_NO_EXPORT mgl_fit__fdf (const gsl_vector * x, void *data, gsl_vector * f, gsl_matrix * J)\r
 {\r
-       mgl_fit__f(x, data, f);\r
-       mgl_fit__df(x, data, J);\r
+       mglFitData *fd = (mglFitData *)data;\r
+       mglDataV *var = new mglDataV[fd->m];\r
+       std::vector<mglDataA*> list;\r
+       for(long i=0;i<fd->m;i++)\r
+       {       var[i].s=fd->var[i];    var[i].Fill(gsl_vector_get(x,i));       list.push_back(var+i);  }\r
+       if(fd->x)       list.push_back(fd->x);\r
+       if(fd->y)       list.push_back(fd->y);\r
+       if(fd->z)       list.push_back(fd->z);\r
+       mglData res = mglFormulaCalc(fd->eq, list);\r
+#pragma omp parallel for\r
+       for(long i=0;i<fd->n;i++)\r
+               gsl_vector_set (f, i, (res.a[i] - fd->a[i])/fd->s[i]);\r
+       const mreal eps = 1e-5;\r
+       for(long j=0;j<fd->m;j++)\r
+       {\r
+               var[j].Fill(gsl_vector_get(x,j)+eps);\r
+               mglData dif = (mglFormulaCalc(fd->eq, list)-res)/eps;\r
+               var[j].Fill(gsl_vector_get(x,j));\r
+#pragma omp parallel for\r
+               for(long i=0;i<fd->n;i++)\r
+                       gsl_matrix_set (J, i, j, dif.a[i]/fd->s[i]);\r
+       }\r
+       delete []var;\r
        return GSL_SUCCESS;\r
 }\r
 #endif\r
@@ -233,23 +257,17 @@ HMDT MGL_EXPORT mgl_fit_ys(HMGL gr, HCDT y, HCDT s, const char *eq, const char *
 //-----------------------------------------------------------------------------\r
 void MGL_NO_EXPORT mgl_fill_fit(HMGL gr, mglData &fit, mglData &in, mglFitData &fd, const char *var, long nx, long ny, long nz, long k)\r
 {\r
+       mglDataV *vv = new mglDataV[fd.m];\r
+       std::vector<mglDataA*> list;\r
+       for(long i=0;i<fd.m;i++)\r
+       {       vv[i].s=var[i]; vv[i].Fill(in.a[i]);    list.push_back(vv+i);   }\r
+       mglDataV x(nx,ny,nz, gr->Min.x,gr->Max.x,'x');  x.s = L"x";     list.push_back(&x);\r
+       mglDataV y(nx,ny,nz, gr->Min.y,gr->Max.y,'y');  y.s = L"y";     list.push_back(&y);\r
+       mglDataV z(nx,ny,nz, gr->Min.z,gr->Max.z,'z');  z.s = L"z";     list.push_back(&z);\r
+       mglData res = mglFormulaCalc(fd.eq, list);\r
        long nn = nx*ny*nz;\r
-       mreal dx = nx>1?(gr->Max.x-gr->Min.x)/(nx-1):0;\r
-       mreal dy = ny>1?(gr->Max.y-gr->Min.y)/(ny-1):0;\r
-       mreal dz = nz>1?(gr->Max.z-gr->Min.z)/(nz-1):0;\r
-#pragma omp parallel\r
-       {\r
-               mreal val[MGL_VS];      memset(val,0,MGL_VS*sizeof(mreal));\r
-               for(long j=0;j<fd.m;j++)        val[var[j]-'a'] = in.a[j];\r
-#pragma omp for collapse(3)\r
-               for(long jz=0;jz<nz;jz++)       for(long jy=0;jy<ny;jy++)       for(long jx=0;jx<nx;jx++)\r
-               {\r
-                       val['x'-'a'] = gr->Min.x+jx*dx;\r
-                       if(dy)  val['y'-'a'] = gr->Min.y+jy*dy;\r
-                       if(dz)  val['z'-'a'] = gr->Min.z+jz*dz;\r
-                       fit.a[jx+nx*(jy+ny*jz)+k*nn] = fd.eq->Calc(val);\r
-               }\r
-       }\r
+       memcpy(fit.a+k*nn,res.a,nn*sizeof(mreal));\r
+       delete []vv;\r
 }\r
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_fit_xys(HMGL gr, HCDT xx, HCDT yy, HCDT ss, const char *eq, const char *var, HMDT ini, const char *opt)\r
@@ -261,31 +279,31 @@ HMDT MGL_EXPORT mgl_fit_xys(HMGL gr, HCDT xx, HCDT yy, HCDT ss, const char *eq,
        {       gr->SetWarn(mglWarnDim,"Fit[S]");       return 0;       }\r
        if(m<2)\r
        {       gr->SetWarn(mglWarnLow,"Fit[S]");       return 0;       }\r
-       if(ss->GetNx()*ss->GetNy()*ss->GetNz() != m*yy->GetNy()*yy->GetNz())\r
+       if(ss->GetNN() != yy->GetNN())\r
        {       gr->SetWarn(mglWarnDim,"Fit[S]");       return 0;       }\r
        if(!var || *var==0)\r
        {       gr->SetWarn(mglWarnNull,"Fit[S]");      return 0;       }\r
 \r
-       mglData x(xx), y(yy), s(ss);\r
+       mglData x(xx), y(yy), s(ss);    x.s=L"x";\r
        mglFitData fd;\r
-       fd.n = m;       fd.x = x.a;             fd.y = 0;\r
+       fd.n = m;       fd.x = &x;              fd.y = 0;\r
        fd.z = 0;       fd.a = y.a;             fd.s = s.a;\r
-       fd.var = var;   fd.m = strlen(var);\r
-       fd.eq = new mglFormula(eq);\r
+       fd.eq = eq;     fd.var = var;   fd.m = strlen(var);\r
        mglData in(fd.m), *fit=new mglData(nn, yy->GetNy(), yy->GetNz());\r
        mreal res=-1;\r
        for(long i=0;i<yy->GetNy()*yy->GetNz();i++)\r
        {\r
                if(ini && ini->nx>=fd.m)        in.Set(ini->a,fd.m);\r
                else in.Fill(0.,0);\r
-               fd.a = y.a+i*m;         fd.x = x.a+(i%x.ny)*m;\r
+               mglDataR xc(x); xc.SetInd(i%x.ny, L"x");\r
+               fd.a = y.a+i*m;         fd.x = &xc;     //x.a+(i%x.ny)*m;\r
                fd.s = s.a+i*m;\r
                res = mgl_fit_base(fd,in.a);\r
                mgl_fill_fit(gr,*fit,in,fd,var,nn,1,1,i);\r
                if(ini && ini->nx>=fd.m)        memcpy(ini->a,in.a,fd.m*sizeof(mreal));\r
        }\r
        mglPrepareFitEq(gr,res,eq,var,in.a);\r
-       delete fd.eq;   gr->LoadState();        return fit;\r
+       gr->LoadState();        return fit;\r
 }\r
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_fit_xyzs(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT ss, const char *eq, const char *var, HMDT ini, const char *opt)\r
@@ -295,7 +313,7 @@ HMDT MGL_EXPORT mgl_fit_xyzs(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT ss, const
        long nn = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5);\r
        if(xx->GetNx()!=m)\r
        {       gr->SetWarn(mglWarnDim,"Fit[S]");       return 0;       }\r
-       if(ss->GetNx()*ss->GetNy()*ss->GetNz() != m*n*zz->GetNz())\r
+       if(ss->GetNN() != zz->GetNN())\r
        {       gr->SetWarn(mglWarnDim,"Fit[S]");       return 0;       }\r
        if(yy->GetNx()!=n && (xx->GetNy()!=n || yy->GetNx()!=m || yy->GetNy()!=n))\r
        {       gr->SetWarn(mglWarnDim,"Fit[S]");       return 0;       }\r
@@ -304,18 +322,18 @@ HMDT MGL_EXPORT mgl_fit_xyzs(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT ss, const
        if(!var || *var==0)\r
        {       gr->SetWarn(mglWarnNull,"Fit[S]");      return 0;       }\r
 \r
-       mglData x(m, n), y(m, n), z(zz), s(ss);\r
+       mglData x(m, n), y(m, n), z(zz), s(ss); x.s=L"x";       y.s=L"y";\r
 #pragma omp parallel for collapse(2)\r
-       for(long i=0;i<m;i++)   for(long j=0;j<n;j++)   // ñîçäàåì ìàññèâ òî÷åê\r
+       for(long i=0;i<m;i++)   for(long j=0;j<n;j++)\r
        {\r
                x.a[i+m*j] = GetX(xx,i,j,0).x;\r
                y.a[i+m*j] = GetY(yy,i,j,0).x;\r
        }\r
        mglFitData fd;\r
-       fd.n = m*n;             fd.x = x.a;     fd.y = y.a;\r
-       fd.z = 0;               fd.a = z.a;     fd.s = s.a;\r
-       fd.var = var;   fd.m = strlen(var);\r
-       fd.eq = new mglFormula(eq);\r
+       fd.n = m*n;     fd.x = &x;      fd.y = &y;\r
+       fd.z = 0;       fd.a = z.a;     fd.s = s.a;\r
+       fd.eq = eq;     fd.var=var;     fd.m = strlen(var);\r
+\r
        mglData in(fd.m), *fit=new mglData(nn, nn, zz->GetNz());\r
        mreal res = -1;\r
        for(long i=0;i<zz->GetNz();i++)\r
@@ -328,7 +346,7 @@ HMDT MGL_EXPORT mgl_fit_xyzs(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT ss, const
                if(ini && ini->nx>=fd.m)        memcpy(ini->a,in.a,fd.m*sizeof(mreal));\r
        }\r
        mglPrepareFitEq(gr,res, eq,var,in.a);\r
-       delete fd.eq;   gr->LoadState();        return fit;\r
+       gr->LoadState();        return fit;\r
 }\r
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_fit_xyzas(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT aa, HCDT ss, const char *eq, const char *var, HMDT ini, const char *opt)\r
@@ -338,17 +356,18 @@ HMDT MGL_EXPORT mgl_fit_xyzas(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT aa, HCDT
        long nn = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5);\r
        if(m<2 || n<2 || l<2)\r
        {       gr->SetWarn(mglWarnLow,"Fit[S]");       return 0;       }\r
-       if(ss->GetNx()*ss->GetNy()*ss->GetNz() != i)\r
+       if(ss->GetNN() != i)\r
        {       gr->SetWarn(mglWarnDim,"Fit[S]");       return 0;       }\r
-       bool both = xx->GetNx()*xx->GetNy()*xx->GetNz()==i && yy->GetNx()*yy->GetNy()*yy->GetNz()==i && zz->GetNx()*zz->GetNy()*zz->GetNz()==i;\r
+       bool both = xx->GetNN()==i && yy->GetNN()==i && zz->GetNN()==i;\r
        if(!(both || (xx->GetNx()==m && yy->GetNx()==n && zz->GetNx()==l)))\r
        {       gr->SetWarn(mglWarnDim,"Fit[S]");       return 0;       }\r
        if(!var || *var==0)\r
        {       gr->SetWarn(mglWarnNull,"Fit[S]");      return 0;       }\r
 \r
-       mglData x(aa), y(aa), z(aa), a(aa), s(ss);\r
+       mglData x(m,n,l), y(m,n,l), z(m,n,l), a(aa), s(ss);\r
+       x.s=L"x";       y.s=L"y";       z.s=L"z";\r
 #pragma omp parallel for collapse(3)\r
-       for(long i=0;i<m;i++)   for(long j=0;j<n;j++)   for(long k=0;k<l;k++)   // ñîçäàåì ìàññèâ òî÷åê\r
+       for(long i=0;i<m;i++)   for(long j=0;j<n;j++)   for(long k=0;k<l;k++)\r
        {\r
                register long i0 = i+m*(j+n*k);\r
                x.a[i0] = GetX(xx,i,j,k).x;\r
@@ -356,10 +375,9 @@ HMDT MGL_EXPORT mgl_fit_xyzas(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT aa, HCDT
                z.a[i0] = GetZ(zz,i,j,k).x;\r
        }\r
        mglFitData fd;\r
-       fd.n = m*n*l;   fd.x = x.a;     fd.y = y.a;\r
-       fd.z = z.a;             fd.a = a.a;     fd.s = s.a;\r
-       fd.var = var;   fd.m = strlen(var);\r
-       fd.eq = new mglFormula(eq);\r
+       fd.n = m*n*l;   fd.x = &x;      fd.y = &y;\r
+       fd.z = &z;              fd.a = a.a;     fd.s = s.a;\r
+       fd.eq = eq;             fd.var=var;     fd.m = strlen(var);\r
        mglData in(fd.m), *fit=new mglData(nn, nn, nn);\r
        mreal res = -1;\r
 \r
@@ -370,105 +388,64 @@ HMDT MGL_EXPORT mgl_fit_xyzas(HMGL gr, HCDT xx, HCDT yy, HCDT zz, HCDT aa, HCDT
        if(ini && ini->nx>=fd.m)        memcpy(ini->a,in.a,fd.m*sizeof(mreal));\r
 \r
        mglPrepareFitEq(gr,res, eq,var,in.a);\r
-       delete fd.eq;   gr->LoadState();        return fit;\r
+       gr->LoadState();        return fit;\r
 }\r
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_hist_x(HMGL gr, HCDT x, HCDT a, const char *opt)\r
 {\r
-       long nn=a->GetNx()*a->GetNy()*a->GetNz();\r
-       if(nn!=x->GetNx()*x->GetNy()*x->GetNz())\r
+       long nn=a->GetNN();\r
+       if(nn!=x->GetNN())\r
        {       gr->SetWarn(mglWarnDim,"Hist"); return 0;       }\r
        mreal rr = gr->SaveState(opt);\r
        long n = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5);\r
        mglData *res = new mglData(n);\r
 \r
-       const mglData *dx = dynamic_cast<const mglData *>(x);\r
-       const mglData *da = dynamic_cast<const mglData *>(a);\r
        mreal vx = n/(gr->Max.x-gr->Min.x);\r
-       if(dx && da)\r
-#pragma omp parallel for\r
-               for(long i=0;i<nn;i++)\r
-               {\r
-                       register long j1 = long((dx->a[i]-gr->Min.x)*vx);\r
-                       if(j1>=0 && j1<n)       res->a[j1] += da->a[i];\r
-               }\r
-       else\r
-#pragma omp parallel for\r
-               for(long i=0;i<nn;i++)\r
-               {\r
-                       register long j1 = long((x->vthr(i)-gr->Min.x)*vx);\r
-                       if(j1>=0 && j1<n)       res->a[j1] += a->vthr(i);\r
-               }\r
+       for(long i=0;i<nn;i++)\r
+       {\r
+               register long j1 = long((x->vthr(i)-gr->Min.x)*vx);\r
+               if(j1>=0 && j1<n)       res->a[j1] += a->vthr(i);\r
+       }\r
        gr->LoadState();        return res;\r
 }\r
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_hist_xy(HMGL gr, HCDT x, HCDT y, HCDT a, const char *opt)\r
 {\r
-       long nn=a->GetNx()*a->GetNy()*a->GetNz();\r
-       if(nn!=x->GetNx()*x->GetNy()*x->GetNz() || nn!=y->GetNx()*y->GetNy()*y->GetNz())\r
+       long nn=a->GetNN();\r
+       if(nn!=x->GetNN() || nn!=y->GetNN())\r
        {       gr->SetWarn(mglWarnDim,"Hist"); return 0;       }\r
        mreal rr = gr->SaveState(opt);\r
        long n = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5);\r
        mglData *res = new mglData(n, n);\r
-       const mglData *dx = dynamic_cast<const mglData *>(x);\r
-       const mglData *dy = dynamic_cast<const mglData *>(y);\r
-       const mglData *da = dynamic_cast<const mglData *>(a);\r
        mreal vx = n/(gr->Max.x-gr->Min.x);\r
        mreal vy = n/(gr->Max.y-gr->Min.y);\r
-       if(dx && dy && da)\r
-#pragma omp parallel for\r
-               for(long i=0;i<nn;i++)\r
-               {\r
-                       register long j1 = long((dx->a[i]-gr->Min.x)*vx);\r
-                       register long j2 = long((dy->a[i]-gr->Min.y)*vy);\r
-                       if(j1>=0 && j1<n && j2>=0 && j2<n)      res->a[j1+n*j2] += da->a[i];\r
-               }\r
-       else\r
-#pragma omp parallel for\r
-               for(long i=0;i<nn;i++)\r
-               {\r
-                       register long j1 = long((x->vthr(i)-gr->Min.x)*vx);\r
-                       register long j2 = long((y->vthr(i)-gr->Min.y)*vy);\r
-                       if(j1>=0 && j1<n && j2>=0 && j2<n)      res->a[j1+n*j2] += a->vthr(i);\r
-               }\r
+       for(long i=0;i<nn;i++)\r
+       {\r
+               register long j1 = long((x->vthr(i)-gr->Min.x)*vx);\r
+               register long j2 = long((y->vthr(i)-gr->Min.y)*vy);\r
+               if(j1>=0 && j1<n && j2>=0 && j2<n)      res->a[j1+n*j2] += a->vthr(i);\r
+       }\r
        gr->LoadState();        return res;\r
 }\r
 //-----------------------------------------------------------------------------\r
 HMDT MGL_EXPORT mgl_hist_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *opt)\r
 {\r
-       long nn=a->GetNx()*a->GetNy()*a->GetNz();\r
-       if(nn!=x->GetNx()*x->GetNy()*x->GetNz() || nn!=y->GetNx()*y->GetNy()*y->GetNz() || nn!=z->GetNx()*z->GetNy()*z->GetNz())\r
+       long nn=a->GetNN();\r
+       if(nn!=x->GetNN() || nn!=y->GetNN() || nn!=z->GetNN())\r
        {       gr->SetWarn(mglWarnDim,"Hist"); return 0;       }\r
        mreal rr = gr->SaveState(opt);\r
        long n = (mgl_isnan(rr) || rr<=0) ? mglFitPnts:long(rr+0.5);\r
        mglData *res = new mglData(n, n, n);\r
-       const mglData *dx = dynamic_cast<const mglData *>(x);\r
-       const mglData *dy = dynamic_cast<const mglData *>(y);\r
-       const mglData *dz = dynamic_cast<const mglData *>(z);\r
-       const mglData *da = dynamic_cast<const mglData *>(a);\r
        mreal vx = n/(gr->Max.x-gr->Min.x), vy = n/(gr->Max.y-gr->Min.y), vz = n/(gr->Max.z-gr->Min.z);\r
-       if(dx && dy && dz && da)\r
-#pragma omp parallel for\r
-               for(long i=0;i<nn;i++)\r
-               {\r
-                       register long j1 = long((dx->a[i]-gr->Min.x)*vx);\r
-                       register long j2 = long((dy->a[i]-gr->Min.y)*vy);\r
-                       register long j3 = long((dz->a[i]-gr->Min.z)*vz);\r
-                       if(j1>=0 && j1<n && j2>=0 && j2<n && j3>=0 && j3<n)\r
-                               res->a[j1+n*(j2+n*j3)] += da->a[i];\r
-               }\r
-       else\r
-#pragma omp parallel for\r
-               for(long i=0;i<nn;i++)\r
-               {\r
-                       if(gr->Stop)    continue;\r
-                       register long j1 = long((x->vthr(i)-gr->Min.x)*vx);\r
-                       register long j2 = long((y->vthr(i)-gr->Min.y)*vy);\r
-                       register long j3 = long((z->vthr(i)-gr->Min.z)*vz);\r
-                       if(j1>=0 && j1<n && j2>=0 && j2<n && j3>=0 && j3<n)\r
-                               res->a[j1+n*(j2+n*j3)] += a->vthr(i);\r
-               }\r
-       gr->LoadState();        return gr->Stop?0:res;\r
+       for(long i=0;i<nn;i++)\r
+       {\r
+               register long j1 = long((x->vthr(i)-gr->Min.x)*vx);\r
+               register long j2 = long((y->vthr(i)-gr->Min.y)*vy);\r
+               register long j3 = long((z->vthr(i)-gr->Min.z)*vz);\r
+               if(j1>=0 && j1<n && j2>=0 && j2<n && j3>=0 && j3<n)\r
+                       res->a[j1+n*(j2+n*j3)] += a->vthr(i);\r
+       }\r
+       gr->LoadState();        return res;\r
 }\r
 //-----------------------------------------------------------------------------\r
 uintptr_t MGL_EXPORT mgl_hist_x_(uintptr_t* gr, uintptr_t* x, uintptr_t* a, const char *opt, int lo)\r
@@ -484,7 +461,13 @@ uintptr_t MGL_EXPORT mgl_hist_xyz_(uintptr_t* gr, uintptr_t* x, uintptr_t* y, ui
        uintptr_t r = (uintptr_t)mgl_hist_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), o);\r
        delete []o;     return r;       }\r
 //-----------------------------------------------------------------------------\r
-MGL_EXPORT const char *mgl_get_fit(HMGL )      {       return mglFitRes;       }\r
+MGL_EXPORT_CONST const char *mgl_get_fit(HMGL )        {       return mglFitRes;       }\r
+int MGL_EXPORT mgl_get_fit_(uintptr_t *gr, char *out, int len)\r
+{\r
+       const char *res = mgl_get_fit(_GR_);\r
+       if(out) strncpy(out,res,len);\r
+       return strlen(res);\r
+}\r
 //-----------------------------------------------------------------------------\r
 uintptr_t MGL_EXPORT mgl_fit_1_(uintptr_t* gr, uintptr_t* y, const char *eq, const char *var, uintptr_t *ini, const char *opt, int l, int n, int lo)\r
 {\r
index 40c12a20e0454c418940a4dc2e461a97e9a8740c..85639cfb4a74ae0e360fbc56eb09f62694297285 100644 (file)
 #include <ctype.h>\r
 #include <wctype.h>\r
 \r
-// #ifdef WIN32\r
-// #include <windows.h>\r
-// #else\r
-// #include <wchar.h>\r
-// #endif\r
+#if !defined(__BORLANDC__) || (__CODEGEARC__ >=  0x0630)\r
+#include <algorithm>\r
+#else\r
+#include <algorithm.h>\r
+#endif\r
 \r
 #include "mgl2/base.h"\r
 #include "mgl2/font.h"\r
@@ -35,17 +35,36 @@ extern float mgl_fact;
 extern long mgl_gen_fnt[516][6];\r
 extern short mgl_buf_fnt[246080];\r
 extern mglTeXsymb mgl_tex_symb[];\r
+extern long mgl_tex_num;\r
 //mglFont mglDefFont("nofont");\r
 mglFont mglDefFont;\r
 //-----------------------------------------------------------------------------\r
-char mglGetStyle(const char *how, int *font, int *align)\r
+long MGL_EXPORT_PURE mgl_internal_code(unsigned s, const std::vector<mglGlyphDescr> &glyphs)\r
 {\r
-       char col=0;\r
+       register long i1=0,i2=glyphs.size()-1;\r
+       register wchar_t j = wchar_t(s & MGL_FONT_MASK);\r
+       // let suppose that id[i]<id[i+1]\r
+       while(i1<i2)\r
+       {\r
+               register long i = (i1+i2)/2;\r
+               if(j<glyphs[i].id)              i2 = i;\r
+               else if(j>glyphs[i].id) i1=i+1;\r
+               else return i;\r
+       }\r
+       return j==glyphs[i2].id ? i2 : -1;\r
+}\r
+//-----------------------------------------------------------------------------\r
+bool MGL_EXPORT mglGetStyle(const char *how, int *font, int *align)\r
+{\r
+       bool col=false;\r
        if(align)       *align = 1;     // centering text by default\r
        if(!how || *how==0)     return col;\r
        // NOTE: no brightness for text color\r
        for(;*how && *how!=':';how++)\r
-               if(strchr(MGL_COLORS,*how))     col=*how;\r
+       {\r
+               if(strchr(MGL_COLORS,*how))             col = true;\r
+               if(*how=='{' && how[1]=='x')    col = true;\r
+       }\r
        if(align)\r
        {\r
                *align = 1;\r
@@ -66,11 +85,11 @@ char mglGetStyle(const char *how, int *font, int *align)
        return col;\r
 }\r
 //-----------------------------------------------------------------------------\r
-float mglFont::Puts(const char *str,const char *how,float col) const\r
+float mglFont::Puts(const char *str,const char *how,float c1,float c2) const\r
 {\r
        int font=0, align=1;    float w=0;\r
-       char cc=mglGetStyle(how,&font,&align);\r
-       MGL_TO_WCS(str,w = Puts(wcs,font,align,cc?-cc:col));\r
+       mglGetStyle(how,&font,&align);\r
+       MGL_TO_WCS(str,w = Puts(wcs,font,align,c1,c2));\r
        return w;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -82,11 +101,11 @@ float mglFont::Width(const char *str,const char *how) const
        return w;\r
 }\r
 //-----------------------------------------------------------------------------\r
-float mglFont::Puts(const wchar_t *str,const char *how,float col) const\r
+float mglFont::Puts(const wchar_t *str,const char *how,float c1,float c2) const\r
 {\r
        int font=0, align=1;\r
-       char cc=mglGetStyle(how,&font,&align);\r
-       return Puts(str, font, align,cc?-cc:col);\r
+       mglGetStyle(how,&font,&align);\r
+       return Puts(str, font, align,c1,c2);\r
 }\r
 //-----------------------------------------------------------------------------\r
 float mglFont::Width(const wchar_t *str,const char *how) const\r
@@ -96,59 +115,58 @@ float mglFont::Width(const wchar_t *str,const char *how) const
        return Width(str, font);\r
 }\r
 //-----------------------------------------------------------------------------\r
-float mglFont::Puts(const wchar_t *str,int font,int align, float col) const\r
+float mglFont::Puts(const wchar_t *str,int font,int align, float c1,float c2) const\r
 {\r
-       if(numg==0 || !str || *str==0)  return 0;\r
+       if(GetNumGlyph()==0 || !str || *str==0) return 0;\r
        float ww=0,w=0,h = (align&4) ? 500./fact[0] : 0;\r
-       size_t size = mgl_wcslen(str)+1,i,num=0;\r
+       size_t size = mgl_wcslen(str)+1,num=0;\r
        if(parse)\r
        {\r
                unsigned *wcs = new unsigned[size], *buf=wcs;\r
                memcpy(wcs,str,size*sizeof(wchar_t));\r
                Convert(str, wcs);\r
-               for(i=0;wcs[i];i++)\r
+               for(size_t i=0;wcs[i];i++)\r
                {\r
                        if(wcs[i]=='\n')        // parse '\n' symbol\r
                        {\r
-                               wcs[i]=0;       w = Puts(buf,0,0,1.f,0x10|font,col);    // find width\r
-                               Puts(buf,-w*(align&3)/2.f,-h - 500.*num/fact[0],1.f,font,col);  // draw it really\r
+                               wcs[i]=0;       w = Puts(buf,0,0,1.f,0x10|font,c1,c2);  // find width\r
+                               Puts(buf,-w*(align&3)/2.f,-h - 500.*num/fact[0],1.f,font,c1,c2);        // draw it really\r
                                buf=wcs+i+1;    num++;  if(w>ww)        ww=w;\r
                        }\r
                        if(wcs[i]=='\\' && wcs[i+1]=='n' && (wcs[i+2]>' ' || wcschr(L"{}[]()!@#$%^&*/-?.,_=+\\\"", wcs[i+2])))  // parse '\n' symbol\r
                        {\r
-                               wcs[i]=0;       w = Puts(buf,0,0,1.f,0x10|font,col);    // find width\r
-                               Puts(buf,-w*(align&3)/2.f,-h - 500.*num/fact[0],1.f,font,col);  // draw it really\r
+                               wcs[i]=0;       w = Puts(buf,0,0,1.f,0x10|font,c1,c2);  // find width\r
+                               Puts(buf,-w*(align&3)/2.f,-h - 500.*num/fact[0],1.f,font,c1,c2);        // draw it really\r
                                buf=wcs+i+2;    num++;  if(w>ww)        ww=w;\r
                        }\r
                }\r
                // draw string itself\r
-               w = Puts(buf,0,0,1.f,0x10|font,col);    // find width\r
-               Puts(buf,-w*(align&3)/2.f,-h - 500.*num/fact[0],1.f,font,col);  // draw it really\r
+               w = Puts(buf,0,0,1.f,0x10|font,c1,c2);  // find width\r
+               Puts(buf,-w*(align&3)/2.f,-h - 500.*num/fact[0],1.f,font,c1,c2);        // draw it really\r
                if(w>ww)        ww=w;\r
                delete []wcs;\r
        }\r
        else\r
        {\r
                int s = (font/MGL_FONT_BOLD)&3;\r
-               long j;\r
                h *= fact[0]/fact[s];\r
-               for(i=0;i<size;i++)             // find width\r
+               for(size_t i=0;i<size;i++)              // find width\r
                {\r
-                       j = str[i]!=' ' ? Internal(str[i]) : Internal('!');\r
+                       long j = str[i]!=' ' ? Internal(str[i]) : Internal('!');\r
                        if(j==-1)       continue;\r
-                       w+= width[s][j]/fact[s];\r
+                       w+= GetWidth(s,j)/fact[s];\r
                }\r
                ww = w;         w *= -(align&3)/2.f;\r
-               if(gr)  for(i=0;i<size;i++)             // draw it\r
+               if(gr)  for(size_t i=0;i<size;i++)              // draw it\r
                {\r
+                       long j=0;       //Internal('!');\r
                        if(str[i]!=' ')\r
                        {\r
                                j = Internal(str[i]);\r
                                if(j==-1)       continue;\r
-                               gr->Glyph(w, -h, 1, s+(font&MGL_FONT_WIRE)?4:0, j, col);\r
+                               gr->Glyph(w, -h, 1, (s+(font&MGL_FONT_WIRE))?4:0, j, c1+i*(c2-c1)/(size-1));\r
                        }\r
-                       else    j = 0;//Internal('!');\r
-                       w+= width[s][j]/fact[s];\r
+                       w+= GetWidth(s,j)/fact[s];\r
                }\r
        }\r
        return ww;\r
@@ -156,32 +174,31 @@ float mglFont::Puts(const wchar_t *str,int font,int align, float col) const
 //-----------------------------------------------------------------------------\r
 float mglFont::Width(const wchar_t *str,int font) const\r
 {\r
-       if(numg==0 || !str || *str==0)  return 0;\r
+       if(GetNumGlyph()==0 || !str || *str==0) return 0;\r
        float ww=0,w=0;\r
-       size_t size = mgl_wcslen(str)+1,i;\r
+       size_t size = mgl_wcslen(str)+1;\r
        if(parse)\r
        {\r
                unsigned *wcs = new unsigned[size], *buf=wcs;\r
                memcpy(wcs,str,size*sizeof(wchar_t));\r
                Convert(str, wcs);\r
-               for(i=0;wcs[i];i++)     if(wcs[i]=='\n')        // parse '\n' symbol\r
+               for(size_t i=0;wcs[i];i++)      if(wcs[i]=='\n')        // parse '\n' symbol\r
                {\r
-                       wcs[i]=0;       w = Puts(buf,0,0,1.,0x10|font,'k');     // find width\r
+                       wcs[i]=0;       w = Puts(buf,0,0,1.,0x10|font,'k','k'); // find width\r
                        buf=wcs+i+1;    if(w>ww)        ww=w;\r
                }\r
-               w = Puts(buf,0,0,1.,0x10|font,'k');\r
+               w = Puts(buf,0,0,1.,0x10|font,'k','k');\r
                if(w<ww)        w=ww;\r
                delete []wcs;\r
        }\r
        else\r
        {\r
-               long j;\r
                int s = (font/MGL_FONT_BOLD)&3;\r
-               for(i=0;i<size;i++)\r
+               for(size_t i=0;i<size;i++)\r
                {\r
-                       j = str[i]!=' ' ? Internal(str[i]) : Internal('!');\r
+                       long j = str[i]!=' ' ? Internal(str[i]) : Internal('!');\r
                        if(j==-1)       continue;\r
-                       w+= width[s][j]/fact[s];\r
+                       w+= GetWidth(s,j)/fact[s];\r
                }\r
        }\r
        return w;\r
@@ -189,14 +206,14 @@ float mglFont::Width(const wchar_t *str,int font) const
 //-----------------------------------------------------------------------------\r
 float mglFont::Height(int font) const\r
 {\r
-       if(numg==0)     return 0;\r
+       if(GetNumGlyph()==0)    return 0;\r
        int s = (font/MGL_FONT_BOLD)&3;\r
        return (500.f)/fact[s];\r
 }\r
 //-----------------------------------------------------------------------------\r
 float mglFont::Height(const char *how) const\r
 {\r
-       if(numg==0)     return 0;\r
+       if(GetNumGlyph()==0)    return 0;\r
        int s=0;\r
        if(how)\r
        {\r
@@ -206,27 +223,12 @@ float mglFont::Height(const char *how) const
        return (500.f)/fact[s];\r
 }\r
 //-----------------------------------------------------------------------------\r
-long mglFont::Internal(unsigned s) const\r
-{\r
-       register long i,i1=0,i2=numg-1;\r
-       register wchar_t j = wchar_t(s & MGL_FONT_MASK);\r
-       // let suppose that id[i]<id[i+1]\r
-       while(i1<i2)\r
-       {\r
-               i = (i1+i2)/2;\r
-               if(j<id[i])                     i2 = i;\r
-               else if(j>id[i])        i1=i+1; // i is bad\r
-               else return i;\r
-       }\r
-       return j==id[i2] ? i2 : -1;\r
-}\r
-//-----------------------------------------------------------------------------\r
 /// Table of acents and its UTF8 codes\r
 MGL_NO_EXPORT mglTeXsymb mgl_act_symb[] = {\r
        {0x02c6, L"hat"}, {0x02dc, L"tilde"}, {0x02d9, L"dot"}, {0x00a8, L"ddot"}, {0x20db, L"dddot"}, {0x20dc, L"ddddot"}, {0x02ca, L"acute"}, {0x02c7, L"check"}, {0x02cb, L"grave"}, {0x20d7, L"vec"}, {0x02c9, L"bar"}, {0x02d8, L"breve"},\r
        /*end*/{0, L"\0"}};\r
 //-----------------------------------------------------------------------------\r
-int MGL_NO_EXPORT mgl_tex_symb_cmp(const void *a, const void *b)\r
+int MGL_LOCAL_PURE mgl_tex_symb_cmp(const void *a, const void *b)\r
 {\r
        const mglTeXsymb *aa = (const mglTeXsymb *)a;\r
        const mglTeXsymb *bb = (const mglTeXsymb *)b;\r
@@ -239,10 +241,10 @@ unsigned mglFont::Parse(const wchar_t *s) const
        register long k;\r
        unsigned res = unsigned(-2);            // Default is no symbol\r
        if(!s || !s[0]) return res;\r
-       for(k=0;mgl_tex_symb[k].kod;k++);       // determine the number of symbols\r
+//     for(k=0;mgl_tex_symb[k].kod;k++);       // determine the number of symbols\r
        mglTeXsymb tst, *rts;\r
        tst.tex = s;\r
-       rts = (mglTeXsymb *) bsearch(&tst, mgl_tex_symb, k, sizeof(mglTeXsymb), mgl_tex_symb_cmp);\r
+       rts = (mglTeXsymb *) bsearch(&tst, mgl_tex_symb, mgl_tex_num, sizeof(mglTeXsymb), mgl_tex_symb_cmp);\r
        if(rts) return rts->kod;\r
 \r
 //     for(k=0;mgl_tex_symb[k].kod;k++)        // special symbols\r
@@ -287,10 +289,10 @@ unsigned mglFont::Parse(const wchar_t *s) const
 void mglFont::Convert(const wchar_t *str, unsigned *res) const\r
 {\r
        register size_t r,i,j,k,i0;\r
-       wchar_t s[128]=L"", ch;         // TeX command and current char\r
+       wchar_t s[128]=L"";             // TeX command and current char\r
        for(i=j=0;str[i];i++)\r
        {\r
-               ch = str[i];\r
+               wchar_t ch = str[i];\r
                if(ch=='\\')    // It can be TeX command\r
                {\r
                        if(wcschr(L"{}_^\\@# ",str[i+1]))       // No, it is usual symbol\r
@@ -311,6 +313,7 @@ void mglFont::Convert(const wchar_t *str, unsigned *res) const
                                }\r
                        }\r
                }\r
+               else if(ch=='\b'){}\r
                else if(ch<=' ' && ch!='\n')    res[j++] = ' '; // no \t at this moment :(\r
                else if(ch=='_')        res[j++] = MGL_FONT_LOWER;\r
                else if(ch=='^')        res[j++] = MGL_FONT_UPPER;\r
@@ -318,7 +321,7 @@ void mglFont::Convert(const wchar_t *str, unsigned *res) const
                else if(ch=='{')        res[j++] = unsigned(-3);\r
                else if(ch=='}')        res[j++] = unsigned(-4);\r
                else if(ch=='#' && str[i+1]>' ')\r
-                       res[j++] = MGL_COLOR_MASK + (0xff & str[++i]);\r
+                       res[j++] = MGL_COLOR_MASK + (0xff & str[++i]);  // TODO inline colors -- stack of RGBA colors + index\r
                else    res[j++] = ch;                          // It is just symbol\r
        }\r
        res[j] = 0;\r
@@ -352,8 +355,8 @@ float mglFont::get_ptr(long &i,unsigned *str, unsigned **b1, unsigned **b2,float
        }\r
        else    {       s2[0] = str[i]; *b2 = s2;       i++;    }\r
        i--;\r
-       w1 = Puts(*b1, 0, 0, f1, 0x10|st,'k');\r
-       w2 = Puts(*b2, 0, 0, f2, 0x10|st,'k');\r
+       w1 = Puts(*b1, 0, 0, f1, 0x10|st,'k','k');\r
+       w2 = Puts(*b2, 0, 0, f2, 0x10|st,'k','k');\r
        return w1>w2 ? w1 : w2;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -365,37 +368,37 @@ void mglFont::draw_ouline(int st, float x, float y, float f, float g, float ww,
                gr->Glyph(x,y-200*f/g, ww*g, (st&MGL_FONT_WIRE)?12:8, 0, ccol);\r
 }\r
 //-----------------------------------------------------------------------------\r
-#define MGL_CLEAR_STYLE {st = style;   yy = y; ff = f; ccol=col;       a = (st/MGL_FONT_BOLD)&3;}\r
-float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,float col) const\r
+#define MGL_CLEAR_STYLE {st = style;   yy = y; ff = f; ccol=c1+dc*i;   a = (st/MGL_FONT_BOLD)&3;}\r
+float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,float c1,float c2) const\r
 {\r
-       if(numg==0)     return 0;\r
-       register long j,k;\r
-       long i;\r
-       register unsigned s,ss;\r
+       if(GetNumGlyph()==0)    return 0;\r
        float w=0;                              // string width\r
        int st = style;                 // current style\r
        unsigned *b1, *b2;              // pointer to substring\r
        unsigned *str;                  // string itself\r
        float yy=y, ff=f, ww, w1, w2;\r
-       float ccol=col;\r
        int a = (st/MGL_FONT_BOLD)&3;\r
+       long i;\r
        for(i=0;text[i];i++);\r
+       float dc=i>1?(c2-c1)/(i-1):0;\r
        str = new unsigned[i+1];\r
        memcpy(str,text,(i+1)*sizeof(unsigned));\r
 \r
-       for(i=0;str[i];i++)\r
+       float ccol = 0;\r
+       for(long i=0;str[i];i++)\r
        {\r
-               s = str[i];             ww = 0;\r
+               ccol = ccol<0?ccol:c1+dc*i;\r
+               unsigned s = str[i];            ww = 0;\r
                if(s==unsigned(-3))     // recursion call here\r
                {\r
                        i++;    b1 = str+i;\r
-                       for(k=1;k>0 && str[i];i++)\r
+                       for(long k=1;k>0 && str[i];i++)\r
                        {\r
                                if(str[i]==unsigned(-4))        k--;\r
                                if(str[i]==unsigned(-3))        k++;\r
                        }\r
                        str[i-1]=0;     i--;\r
-                       ww = Puts(b1, x, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       ww = Puts(b1, x, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        if(gr && !(style&0x10)) // add under-/over- line now\r
                                draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
                        MGL_CLEAR_STYLE\r
@@ -403,15 +406,15 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s=='\n')        // newline\r
                {\r
                        ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff, st);\r
-                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
-                       Puts(b2, x+(ww-w2)/2, yy-600*ff/fact[a], ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
+                       Puts(b2, x+(ww-w2)/2, yy-600*ff/fact[a], ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        MGL_CLEAR_STYLE\r
                }\r
                else if(s==unsigned(-9))        // underset\r
                {\r
                        ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st);\r
-                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
-                       Puts(b2, x+(ww-w2)/2, yy-150*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
+                       Puts(b2, x+(ww-w2)/2, yy-150*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        if(gr && !(style&0x10)) // add under-/over- line now\r
                                draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
                        MGL_CLEAR_STYLE\r
@@ -419,8 +422,8 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s==unsigned(-8))        // overset\r
                {\r
                        ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st);\r
-                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
-                       Puts(b2, x+(ww-w2)/2, yy+375*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
+                       Puts(b2, x+(ww-w2)/2, yy+375*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        if(gr && !(style&0x10)) // add under-/over- line now\r
                                draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
                        MGL_CLEAR_STYLE\r
@@ -428,8 +431,8 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s==unsigned(-12))       // sub\r
                {\r
                        ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st);\r
-                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
-                       Puts(b2, x+(ww-w2)/2, yy-250*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
+                       Puts(b2, x+(ww-w2)/2, yy-250*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        if(gr && !(style&0x10)) // add under-/over- line now\r
                                draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
                        MGL_CLEAR_STYLE\r
@@ -437,8 +440,8 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s==unsigned(-13))       // sup\r
                {\r
                        ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st);\r
-                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
-                       Puts(b2, x+(ww-w2)/2, yy+450*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
+                       Puts(b2, x+(ww-w2)/2, yy+450*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        if(gr && !(style&0x10)) // add under-/over- line now\r
                                draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
                        MGL_CLEAR_STYLE\r
@@ -446,8 +449,8 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s==unsigned(-11))       // stackl\r
                {\r
                        ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st);\r
-                       Puts(b1, x, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
-                       Puts(b2, x, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       Puts(b1, x, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
+                       Puts(b2, x, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        if(gr && !(style&0x10)) // add under-/over- line now\r
                                draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
                        MGL_CLEAR_STYLE\r
@@ -455,8 +458,8 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s==unsigned(-10))       // stacr\r
                {\r
                        ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st);\r
-                       Puts(b1, x+(ww-w1), yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
-                       Puts(b2, x+(ww-w2), yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       Puts(b1, x+(ww-w1), yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
+                       Puts(b2, x+(ww-w2), yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        if(gr && !(style&0x10)) // add under-/over- line now\r
                                draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
                        MGL_CLEAR_STYLE\r
@@ -464,8 +467,8 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s==unsigned(-7))        // stack\r
                {\r
                        ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st);\r
-                       Puts(b1, x+(ww-w1)/2, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
-                       Puts(b2, x+(ww-w2)/2, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       Puts(b1, x+(ww-w1)/2, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
+                       Puts(b2, x+(ww-w2)/2, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        if(gr && !(style&0x10)) // add under-/over- line now\r
                                draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
                        MGL_CLEAR_STYLE\r
@@ -473,8 +476,8 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s==unsigned(-6))        // frac\r
                {\r
                        ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st);\r
-                       Puts(b1, x+(ww-w1)/2, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
-                       Puts(b2, x+(ww-w2)/2, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol);\r
+                       Puts(b1, x+(ww-w1)/2, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
+                       Puts(b2, x+(ww-w2)/2, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
                        if(gr && !(style&0x10)) // add under-/over- line now\r
                        {\r
                                draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
@@ -485,8 +488,8 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s==unsigned(-4))        MGL_CLEAR_STYLE // should be never here but if I miss sth ...\r
                else if(s==unsigned(-14))       // script symbols\r
                {\r
-                       k=1;\r
-                       if(str[i+1]==unsigned(-3))      for(j=i+2;k>0 && str[j];j++)\r
+                       long k=1;\r
+                       if(str[i+1]==unsigned(-3))      for(long j=i+2;k>0 && str[j];j++)\r
                        {\r
                                if(str[j]==unsigned(-3))        k++;\r
                                if(str[j]==unsigned(-4))        k--;\r
@@ -499,12 +502,13 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                else if(s==unsigned(-1))        // set normal font\r
                        st = style & MGL_FONT_ROMAN;\r
                else if((s&MGL_COLOR_MASK)==MGL_COLOR_MASK)     // color specification\r
-                       ccol = -float(s & 0xff);\r
+                       ccol = -float(s & 0xff);        // TODO inline colors -- make textures\r
                else\r
                {\r
-                       ss = s&MGL_FONT_MASK;\r
+                       unsigned ss = s&MGL_FONT_MASK;\r
                        if(ss)  // draw symbol (glyph)\r
                        {\r
+                               long j = Internal('!');\r
                                if(ss>' ')\r
                                {\r
                                        j = Internal(ss);\r
@@ -516,8 +520,7 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
                                                else                                    gr->Glyph(x,yy,ff,a,j,ccol);\r
                                        }\r
                                }\r
-                               else    j = Internal('!');\r
-                               ww = ff*width[a][j]/fact[a];\r
+                               ww = ff*GetWidth(a,j)/fact[a];\r
                                if(gr && !(style&0x10)) // add under-/over- line now\r
                                        draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
                                if(s & MGL_FONT_ZEROW)  ww = 0;\r
@@ -540,116 +543,59 @@ float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,floa
        return w;\r
 }\r
 //-----------------------------------------------------------------------------\r
-void mglFont::mem_alloc()\r
-{\r
-       id = new wchar_t[numg];\r
-       width[0] = new short[numg];     width[1] = new short[numg];\r
-       width[2] = new short[numg];     width[3] = new short[numg];\r
-       tr[0] = new int[numg];  numt[0] = new short[numg];\r
-       tr[1] = new int[numg];  numt[1] = new short[numg];\r
-       tr[2] = new int[numg];  numt[2] = new short[numg];\r
-       tr[3] = new int[numg];  numt[3] = new short[numg];\r
-       ln[0] = new int[numg];  numl[0] = new short[numg];\r
-       ln[1] = new int[numg];  numl[1] = new short[numg];\r
-       ln[2] = new int[numg];  numl[2] = new short[numg];\r
-       ln[3] = new int[numg];  numl[3] = new short[numg];\r
-}\r
-//-----------------------------------------------------------------------------\r
 // copy normal style as default for other styles\r
 void mglFont::main_copy()\r
 {\r
-#pragma omp parallel sections\r
+#pragma omp parallel for\r
+       for(size_t i=0;i<glyphs.size();i++)\r
        {\r
-#pragma omp section\r
-               memcpy(numl[1],numl[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numl[2],numl[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numl[3],numl[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(ln[1],ln[0],numg*sizeof(int));\r
-#pragma omp section\r
-               memcpy(ln[2],ln[0],numg*sizeof(int));\r
-#pragma omp section\r
-               memcpy(ln[3],ln[0],numg*sizeof(int));\r
-#pragma omp section\r
-               memcpy(numt[1],numt[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numt[2],numt[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numt[3],numt[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(tr[1],tr[0],numg*sizeof(int));\r
-#pragma omp section\r
-               memcpy(tr[2],tr[0],numg*sizeof(int));\r
-#pragma omp section\r
-               memcpy(tr[3],tr[0],numg*sizeof(int));\r
-#pragma omp section\r
-               memcpy(width[1],width[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(width[2],width[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(width[3],width[0],numg*sizeof(short));\r
+               mglGlyphDescr &g = glyphs[i];\r
+               g.numl[1] = g.numl[2] = g.numl[3] = g.numl[0];\r
+               g.numt[1] = g.numt[2] = g.numt[3] = g.numt[0];\r
+               g.ln[1] = g.ln[2] = g.ln[3] = g.ln[0];\r
+               g.tr[1] = g.tr[2] = g.tr[3] = g.tr[0];\r
+               g.width[1] = g.width[2] = g.width[3] = g.width[0];\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
 bool mglFont::read_def()\r
 {\r
-       numg = mgl_numg;\r
        // copy default factor for other font styles;\r
        fact[1] = fact[2] = fact[3] = fact[0] = mgl_fact*mgl_fgen;\r
        Buf = new short[mgl_cur];       // prealocate buffer\r
        memset(Buf,0,mgl_cur*sizeof(short));\r
        // now allocate memory for all fonts\r
-       mem_alloc();\r
+       mem_alloc(mgl_numg);\r
        // and load symbols itself\r
 #ifndef WIN32  // win32 don't initialized threads before main()\r
 #pragma omp parallel for\r
 #endif\r
-       for(long i=0;i<int(numg);i++)\r
+       for(size_t i=0;i<mgl_numg;i++)\r
        {\r
-               id[i] = mgl_gen_fnt[i][0];\r
-               width[0][i] = mgl_gen_fnt[i][1];\r
-               numl[0][i] = mgl_gen_fnt[i][2];\r
-               ln[0][i] = mgl_gen_fnt[i][3];\r
-               numt[0][i] = mgl_gen_fnt[i][4];\r
-               tr[0][i] = mgl_gen_fnt[i][5];\r
+               mglGlyphDescr &g = glyphs[i];\r
+               g.id = mgl_gen_fnt[i][0];\r
+               g.width[0] = g.width[1] = g.width[2] = g.width[3] = mgl_gen_fnt[i][1];\r
+               g.numl[0] = g.numl[1] = g.numl[2] = g.numl[3] = mgl_gen_fnt[i][2];\r
+               g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = mgl_gen_fnt[i][3];\r
+               g.numt[0] = g.numt[1] = g.numt[2] = g.numt[3] = mgl_gen_fnt[i][4];\r
+               g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = mgl_gen_fnt[i][5];\r
        }\r
        memcpy(Buf, mgl_buf_fnt, mgl_cur*sizeof(short));\r
        numb = mgl_cur;\r
-#ifndef WIN32  // win32 don't initialized threads before main()\r
-       main_copy();    // copy normal style as default for other styles\r
-#else\r
-       memcpy(numl[1],numl[0],numg*sizeof(short));\r
-       memcpy(numl[2],numl[0],numg*sizeof(short));\r
-       memcpy(numl[3],numl[0],numg*sizeof(short));\r
-       memcpy(ln[1],ln[0],numg*sizeof(int));\r
-       memcpy(ln[2],ln[0],numg*sizeof(int));\r
-       memcpy(ln[3],ln[0],numg*sizeof(int));\r
-       memcpy(numt[1],numt[0],numg*sizeof(short));\r
-       memcpy(numt[2],numt[0],numg*sizeof(short));\r
-       memcpy(numt[3],numt[0],numg*sizeof(short));\r
-       memcpy(tr[1],tr[0],numg*sizeof(int));\r
-       memcpy(tr[2],tr[0],numg*sizeof(int));\r
-       memcpy(tr[3],tr[0],numg*sizeof(int));\r
-       memcpy(width[1],width[0],numg*sizeof(short));\r
-       memcpy(width[2],width[0],numg*sizeof(short));\r
-       memcpy(width[3],width[0],numg*sizeof(short));\r
-#endif\r
        return true;\r
 }\r
 //-----------------------------------------------------------------------------\r
-bool mglFont::read_data(const char *fname, float *ff, short *wdt, short *lnum, int *posl, short *tnum, int *post, std::vector<short> &buf)     // TODO add buffer for input file?!\r
+bool mglFont::read_data(const char *fname, int s, std::vector<short> &buf, std::vector<mglGlyphDescr> &extra)\r
 {\r
        gzFile fp;\r
        char str[256];\r
        int n, tmpw, tmpnl, tmpnt, retVal;\r
-       unsigned s, tmpi, tmppl, tmppt;\r
+       unsigned ss, tmpi, tmppl, tmppt;\r
        fp = gzopen(fname,"r"); if(!fp) return false;   // false if no file\r
        // first string is comment (not used), second string have information\r
        if(!gzgets(fp,str,256) || strncmp(str,"# font",6) || !gzgets(fp,str,256))\r
        {       gzclose(fp);    return false;   }\r
-       retVal = sscanf(str, "%d%f%u", &n, ff, &s);\r
+       retVal = sscanf(str, "%d%f%u", &n, fact+s, &ss);\r
        //Check sscanf read all data  (3 items)\r
        if(retVal != 3) {       gzclose(fp);    return false;   }\r
 \r
@@ -658,12 +604,26 @@ bool mglFont::read_data(const char *fname, float *ff, short *wdt, short *lnum, i
                gzgets(fp,str,256);\r
                retVal = sscanf(str,"%u%d%d%u%d%u", &tmpi, &tmpw, &tmpnl, &tmppl, &tmpnt, &tmppt);\r
                if(retVal != 6) {       gzclose(fp);    buf.clear();    return false;   }\r
-               long j=Internal(unsigned(tmpi));        if(j<0) continue;\r
-               if(wdt) wdt[j] = tmpw;\r
-               lnum[j] = tmpnl;        posl[j] = -1-tmppl;\r
-               tnum[j] = tmpnt;        post[j] = -1-tmppt;\r
+               long j=Internal(unsigned(tmpi));\r
+               if(j>=0)        // known symbol\r
+               {\r
+                       mglGlyphDescr &g = glyphs[j];   g.width[s] = tmpw;\r
+                       g.ln[s] = -1-tmppl;             g.tr[s] = -1-tmppt;\r
+                       g.numl[s] = tmpnl;              g.numt[s] = tmpnt;\r
+               }\r
+               else\r
+               {\r
+                       mglGlyphDescr g;        g.id = tmpi;\r
+                       g.width[0] = g.width[1] = g.width[2] = g.width[3] = tmpw;\r
+                       g.numl[0] = g.numl[1] = g.numl[2] = g.numl[3] = tmpnl;\r
+                       g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = -1-tmppl;\r
+                       g.numt[0] = g.numt[1] = g.numt[2] = g.numt[3] = tmpnt;\r
+                       g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = -1-tmppt;\r
+#pragma omp critical\r
+                       extra.push_back(g);\r
+               }\r
        }\r
-       for(unsigned i=0;i<s;i++)\r
+       for(unsigned i=0;i<ss;i++)\r
        {\r
                for(int j=0;j<256;j++)  if((str[j] = gzgetc(fp))<=' ')  break;\r
                buf.push_back(atoi(str));\r
@@ -672,11 +632,11 @@ bool mglFont::read_data(const char *fname, float *ff, short *wdt, short *lnum, i
        return true;\r
 }\r
 //-----------------------------------------------------------------------------\r
-bool mglFont::read_main(const char *fname, std::vector<short> &buf)    // TODO add buffer for input file?!\r
+bool mglFont::read_main(const char *fname, std::vector<short> &buf)\r
 {\r
        gzFile fp;\r
        int tmpi, tmpw, tmpnl, tmpnt;\r
-       unsigned s, tmppl, tmppt;\r
+       unsigned s, tmppl, tmppt,numg;\r
        char str[256];\r
 \r
        fp = gzopen(fname,"r"); if(!fp) return false;   // this font must be in any case\r
@@ -686,15 +646,18 @@ bool mglFont::read_main(const char *fname, std::vector<short> &buf)       // TODO add
        sscanf(str, "%u%f%u", &numg, fact, &s);\r
        fact[1] = fact[2] = fact[3] = fact[0];  // copy default factor for other font styles;\r
        // now allocate memory for all fonts\r
-       mem_alloc();\r
+       mem_alloc(numg);\r
        // and load symbols itself\r
        for(size_t i=0;i<numg;i++)\r
        {\r
                gzgets(fp,str,256);\r
                sscanf(str,"%d%d%d%u%d%u", &tmpi, &tmpw, &tmpnl, &tmppl, &tmpnt, &tmppt);\r
-               id[i] = tmpi;           width[0][i] = tmpw;\r
-               numl[0][i] = tmpnl; ln[0][i] = tmppl;\r
-               numt[0][i] = tmpnt;     tr[0][i] = tmppt;\r
+               mglGlyphDescr &g = glyphs[i];   g.id = tmpi;\r
+               g.width[0] = g.width[1] = g.width[2] = g.width[3] = tmpw;\r
+               g.numl[0] = g.numl[1] = g.numl[2] = g.numl[3] = tmpnl;\r
+               g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = tmppl;\r
+               g.numt[0] = g.numt[1] = g.numt[2] = g.numt[3] = tmpnt;\r
+               g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = tmppt;\r
        }\r
        for(unsigned i=0;i<s;i++)\r
        {\r
@@ -702,7 +665,6 @@ bool mglFont::read_main(const char *fname, std::vector<short> &buf) // TODO add
                buf.push_back(atoi(str));\r
        }\r
        gzclose(fp);    // finish wire normal font\r
-       main_copy();    // copy normal style as default for other styles\r
        return true;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -715,7 +677,7 @@ bool mglFont::Load(const char *base, const char *path)
        sep='\\';\r
 #endif\r
        char str[256];\r
-       const char *oldLocale = setlocale(LC_NUMERIC,"C");\r
+       std::string loc = setlocale(LC_NUMERIC,"C");\r
        if(!path)       path = MGL_FONT_PATH;\r
        if(base && *base)\r
        {\r
@@ -735,60 +697,119 @@ bool mglFont::Load(const char *base, const char *path)
        if(!(base && *base) || !read_main(str,norm))\r
        {\r
 //             mglGlobalMess += "Load built-in font.\n";\r
-               read_def();     setlocale(LC_NUMERIC,oldLocale);\r
+               read_def();     setlocale(LC_NUMERIC,loc.c_str());\r
                if(buf) delete []buf;   return true;\r
        }\r
        fact[1] = fact[2] = fact[3] = fact[0];\r
 \r
+       std::vector<mglGlyphDescr> ex_b,ex_i,ex_bi;\r
 #pragma omp parallel sections\r
        {\r
                //================== bold ===========================================\r
 #pragma omp section\r
                {       char str[256];  snprintf(str,256,"%s%c%s_b.vfm",path,sep,base); // this file may absent\r
-               read_data(str, fact+1, width[1], numl[1], ln[1], numt[1], tr[1], bold); }\r
+               read_data(str, 1, bold, ex_b);  }\r
 \r
                //================== italic =========================================\r
 #pragma omp section\r
                {       char str[256];  snprintf(str,256,"%s%c%s_i.vfm",path,sep,base);\r
-               read_data(str, fact+2, width[2], numl[2], ln[2], numt[2], tr[2], ital); }\r
+               read_data(str, 2, ital, ex_i);  }\r
 \r
                //================== bold-italic ====================================\r
 #pragma omp section\r
                {       char str[256];  snprintf(str,256,"%s%c%s_bi.vfm",path,sep,base);\r
-               read_data(str, fact+3, width[3], numl[3], ln[3], numt[3], tr[3], both); }\r
+               read_data(str, 3, both, ex_bi); }\r
        }\r
 \r
        // now collect data\r
        numb = norm.size()+bold.size()+ital.size()+both.size();\r
        Buf = new short[numb];\r
-#pragma omp parallel for\r
-       for(long i=0;i<long(norm.size());i++)   Buf[i]=norm[i];\r
+       memcpy(Buf,norm.data(),norm.size()*sizeof(short));\r
        long cur = norm.size(), len = long(bold.size());\r
        if(bold.size()>0)\r
+               memcpy(Buf+cur,bold.data(),bold.size()*sizeof(short));\r
 #pragma omp parallel for\r
-               for(long i=0;i<len;i++) Buf[i+cur]=bold[i];\r
+       for(long i=0;i<GetNumGlyph();i++)       if(glyphs[i].ln[1]<0)\r
+       {       glyphs[i].ln[1] = cur-1-glyphs[i].ln[1];        glyphs[i].tr[1] = cur-1-glyphs[i].tr[1];        }\r
 #pragma omp parallel for\r
-       for(long i=0;i<numg;i++)        if(ln[1][i]<0)\r
-       {       ln[1][i] = cur-1-ln[1][i];      tr[1][i] = cur-1-tr[1][i];      }\r
+       for(size_t i=0;i<ex_b.size();i++)       if(ex_b[i].ln[1]<0)\r
+       {\r
+               mglGlyphDescr &g = ex_b[i];\r
+               g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = cur-1-g.ln[1];\r
+               g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = cur-1-g.tr[1];\r
+       }\r
        cur += len;             len = long(ital.size());\r
        if(ital.size()>0)\r
+               memcpy(Buf+cur,ital.data(),ital.size()*sizeof(short));\r
 #pragma omp parallel for\r
-               for(long i=0;i<len;i++) Buf[i+cur]=ital[i];\r
+       for(long i=0;i<GetNumGlyph();i++)       if(glyphs[i].ln[2]<0)\r
+       {       glyphs[i].ln[2] = cur-1-glyphs[i].ln[2];        glyphs[i].tr[2] = cur-1-glyphs[i].tr[2];        }\r
 #pragma omp parallel for\r
-       for(long i=0;i<numg;i++)        if(ln[2][i]<0)\r
-       {       ln[2][i] = cur-1-ln[2][i];      tr[2][i] = cur-1-tr[2][i];      }\r
-       cur += len;             len = long(both.size());\r
+       for(size_t i=0;i<ex_i.size();i++)       if(ex_i[i].ln[2]<0)\r
+       {\r
+               mglGlyphDescr &g = ex_i[i];\r
+               g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = cur-1-g.ln[2];\r
+               g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = cur-1-g.tr[2];\r
+       }\r
+       cur += len;\r
        if(both.size()>0)\r
+               memcpy(Buf+cur,both.data(),both.size()*sizeof(short));\r
 #pragma omp parallel for\r
-               for(long i=0;i<len;i++) Buf[i+cur]=both[i];\r
+       for(long i=0;i<GetNumGlyph();i++)       if(glyphs[i].ln[3]<0)\r
+       {       glyphs[i].ln[3] = cur-1-glyphs[i].ln[3];        glyphs[i].tr[3] = cur-1-glyphs[i].tr[3];        }\r
 #pragma omp parallel for\r
-       for(long i=0;i<numg;i++)        if(ln[3][i]<0)\r
-       {       ln[3][i] = cur-1-ln[3][i];      tr[3][i] = cur-1-tr[3][i];      }\r
+       for(size_t i=0;i<ex_bi.size();i++)      if(ex_bi[i].ln[3]<0)\r
+       {\r
+               mglGlyphDescr &g = ex_bi[i];\r
+               g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = cur-1-g.ln[3];\r
+               g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = cur-1-g.tr[3];\r
+       }\r
+       // now add missing symbols\r
+       if(ex_b.size()==0)      ex_b = ex_i;\r
+       else\r
+       {\r
+               for(size_t i=0;i<ex_i.size();i++)       // add from ex_i\r
+               {\r
+                       long j = mgl_internal_code(ex_i[i].id, ex_b);\r
+                       if(j>=0)        // known symbol\r
+                       {\r
+                               mglGlyphDescr &g = ex_b[j], &f = ex_i[i];\r
+                               g.width[2] = f.width[2];\r
+                               g.ln[2] = f.ln[2];              g.tr[2] = f.tr[2];\r
+                               g.numl[2] = f.numl[2];  g.numt[2] = f.numt[2];\r
+                       }\r
+                       else    ex_b.push_back(ex_i[i]);\r
+               }\r
+               std::sort(ex_b.begin(),ex_b.end());\r
+       }\r
+       if(ex_b.size()==0)      ex_b = ex_bi;\r
+       else\r
+       {\r
+               for(size_t i=0;i<ex_bi.size();i++)      // add from ex_bi\r
+               {\r
+                       long j = mgl_internal_code(ex_bi[i].id, ex_b);\r
+                       if(j>=0)        // known symbol\r
+                       {\r
+                               mglGlyphDescr &g = ex_b[j], &f = ex_bi[i];\r
+                               g.width[2] = f.width[3];\r
+                               g.ln[2] = f.ln[3];              g.tr[2] = f.tr[3];\r
+                               g.numl[2] = f.numl[3];  g.numt[2] = f.numt[3];\r
+                       }\r
+                       else    ex_b.push_back(ex_bi[i]);\r
+               }\r
+               std::sort(ex_b.begin(),ex_b.end());\r
+       }\r
+       if(ex_b.size()>0)\r
+       {\r
+               glyphs.reserve(ex_b.size());    // preallocate memory\r
+               glyphs.insert(glyphs.end(), ex_b.begin(), ex_b.end());\r
+               std::sort(glyphs.begin(),glyphs.end());\r
+       }\r
 \r
        // Finally normalize all factors\r
        fact[0] *= mgl_fgen;    fact[1] *= mgl_fgen;\r
        fact[2] *= mgl_fgen;    fact[3] *= mgl_fgen;\r
-       setlocale(LC_NUMERIC,oldLocale);\r
+       setlocale(LC_NUMERIC,loc.c_str());\r
        if(buf) delete []buf;\r
        return true;\r
 }\r
@@ -811,7 +832,7 @@ void MGL_NO_EXPORT mgl_init()
 //-----------------------------------------------------------------------------\r
 mglFont::mglFont(const char *name, const char *path)\r
 {\r
-       parse = true;   numg=0; gr=0;\r
+       parse = true;   gr=0;   Buf=0;\r
 //     if(this==&mglDefFont)   Load(name, path);       else    Copy(&mglDefFont);\r
        if(name && *name)       Load(name, path);\r
        else if(this!=&mglDefFont)      Copy(&mglDefFont);\r
@@ -826,73 +847,21 @@ void mglFont::Restore()   {       Copy(&mglDefFont);      }
 //-----------------------------------------------------------------------------\r
 void mglFont::Clear()\r
 {\r
-//     if(gr)  gr->Clf();\r
-       if(numg)\r
-       {\r
-               delete []id;    delete []Buf;   numg = 0;\r
-               delete [](width[0]);    delete [](width[1]);    delete [](width[2]);    delete [](width[3]);\r
-               delete [](tr[0]);               delete [](tr[1]);               delete [](tr[2]);               delete [](tr[3]);\r
-               delete [](ln[0]);               delete [](ln[1]);               delete [](ln[2]);               delete [](ln[3]);\r
-               delete [](numt[0]);             delete [](numt[1]);             delete [](numt[2]);             delete [](numt[3]);\r
-               delete [](numl[0]);             delete [](numl[1]);             delete [](numl[2]);             delete [](numl[3]);\r
-       }\r
+#pragma omp critical(font)\r
+       {       if(Buf) delete []Buf;   Buf=0;  glyphs.clear(); }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglFont::Copy(mglFont *f)\r
 {\r
        if(!f || f==this)       return;\r
-       Clear();\r
-       numg = f->numg;         numb = f->numb;\r
-       mem_alloc();\r
-       // copy general data\r
-#pragma omp parallel sections\r
-       {\r
-#pragma omp section\r
-               memcpy(id,f->id,numg*sizeof(wchar_t));\r
-#pragma omp section\r
-               memcpy(width[0],f->width[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(width[1],f->width[1],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(width[2],f->width[2],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(width[3],f->width[3],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(tr[0],f->tr[0],numg*sizeof(unsigned));\r
-#pragma omp section\r
-               memcpy(tr[1],f->tr[1],numg*sizeof(unsigned));\r
-#pragma omp section\r
-               memcpy(tr[2],f->tr[2],numg*sizeof(unsigned));\r
-#pragma omp section\r
-               memcpy(tr[3],f->tr[3],numg*sizeof(unsigned));\r
-#pragma omp section\r
-               memcpy(numt[0],f->numt[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numt[1],f->numt[1],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numt[2],f->numt[2],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numt[3],f->numt[3],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(ln[0],f->ln[0],numg*sizeof(unsigned));\r
-#pragma omp section\r
-               memcpy(ln[1],f->ln[1],numg*sizeof(unsigned));\r
-#pragma omp section\r
-               memcpy(ln[2],f->ln[2],numg*sizeof(unsigned));\r
-#pragma omp section\r
-               memcpy(ln[3],f->ln[3],numg*sizeof(unsigned));\r
-#pragma omp section\r
-               memcpy(numl[0],f->numl[0],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numl[1],f->numl[1],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numl[2],f->numl[2],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(numl[3],f->numl[3],numg*sizeof(short));\r
-#pragma omp section\r
-               memcpy(fact,f->fact,4*sizeof(float));\r
-       }\r
-       // now copy symbols descriptions\r
-       Buf = new short[numb];  memcpy(Buf, f->Buf, numb*sizeof(short));\r
+#pragma omp critical(font)\r
+       {       if(Buf) delete []Buf;   Buf=0;  }\r
+       // copy scale factors\r
+       memcpy(fact,f->fact,4*sizeof(float));\r
+       // copy symbols descriptions\r
+       numb = f->numb; Buf = new short[numb];  memcpy(Buf, f->Buf, numb*sizeof(short));\r
+       // copy symbol parameters\r
+       glyphs.resize(f->glyphs.size());\r
+       memcpy(glyphs.data(),f->glyphs.data(),glyphs.size()*sizeof(mglGlyphDescr));\r
 }\r
 //-----------------------------------------------------------------------------\r
index daab03f9cb09257361c264bac46e7e8064aa45d7..04571576f25eb57cb00a374ed0b4fe9e56c43cb6 100644 (file)
 //-----------------------------------------------------------------------------
-template <class Treal> void mglFillP(long x,long y, const Treal *a,long nx,long ny,Treal _p[4][4])
-{
-       Treal sx[4]={0,0,0,0},sy[4]={0,0,0,0},f[4]={0,0,0,0},d[4]={0,0,0,0};
-       if(x<0 || y<0 || x>nx-2 || y>ny-2)
-       {
-               memset(_p[0],0,4*sizeof(Treal));
-               memset(_p[1],0,4*sizeof(Treal));
-               memset(_p[2],0,4*sizeof(Treal));
-               memset(_p[3],0,4*sizeof(Treal));
-               return;
-       }
-       // �������� �������
-       f[0]=a[x+nx*y];         f[1]=a[x+nx*(y+1)];
-       if(nx>1)        {       f[2]=a[x+1+nx*y];       f[3]=a[x+1+nx*(y+1)];   }
-       else            {       f[2] = f[0];    f[3] = f[1];    }
-       // ����������� �� x
-       if(nx>1)
-       {
-               if(x==0)
-               {
-                       sx[0]=a[x+1+y*nx]-a[x+nx*y];
-                       sx[1]=a[x+1+nx*(y+1)]-a[x+nx*(y+1)];
-               }
-               else
-               {
-                       sx[0]=(a[x+1+nx*y]-a[x-1+nx*y])/mreal(2);
-                       sx[1]=(a[x+1+nx*(y+1)]-a[x-1+nx*(y+1)])/mreal(2);
-               }
-       }
-       if(x==nx-2)
-       {
-               sx[2]=a[x+1+nx*y]-a[x+nx*y];
-               sx[3]=a[x+1+nx*(y+1)]-a[x+nx*(y+1)];
-       }
-       else
-       {
-               sx[2]=(a[x+2+nx*y]-a[x+nx*y])/mreal(2);
-               sx[3]=(a[x+2+nx*(y+1)]-a[x+nx*(y+1)])/mreal(2);
-       }
-       // ����������� �� y
-       if(y==0)
-       {
-               sy[0]=a[x+nx*(y+1)]-a[x+nx*y];
-               sy[2]=a[x+1+nx*(y+1)]-a[x+1+nx*y];
-       }
-       else
-       {
-               sy[0]=(a[x+nx*(y+1)]-a[x+nx*(y-1)])/mreal(2);
-               sy[2]=(a[x+1+nx*(y+1)]-a[x+1+nx*(y-1)])/mreal(2);
-       }
-       if(y==ny-2)
-       {
-               sy[1]=a[x+nx*(y+1)]-a[x+nx*y];
-               sy[3]=a[x+1+nx*(y+1)]-a[x+1+nx*y];
-       }
-       else
-       {
-               sy[1]=(a[x+nx*(y+2)]-a[x+nx*y])/mreal(2);
-               sy[3]=(a[x+1+nx*(y+2)]-a[x+1+nx*y])/mreal(2);
-       }
-       // ������������ �����������
-       if(nx>1)
-       {
-               // ������ d[0]
-               if(y==0 && x==0)
-                       d[0]=(a[x+1+nx*(y+1)]-a[x+nx*(y+1)]-a[x+1+nx*y]+a[x+nx*y]);
-               else if(y==0)
-                       d[0]=(a[x+1+nx*(y+1)]-a[x-1+nx*(y+1)]-a[x+1+nx*y]+a[x-1+nx*y])/mreal(2);
-               else if(x==0)
-                       d[0]=(a[x+1+nx*(y+1)]-a[x+nx*(y+1)]-a[x+1+nx*(y-1)]+a[x+nx*(y-1)])/mreal(2);
-               else
-                       d[0]=(a[x+1+nx*(y+1)]-a[x-1+nx*(y+1)]-a[x+1+nx*(y-1)]+a[x-1+nx*(y-1)])/mreal(4);
-               // ������ d[1]
-               if(y==ny-2 && x==0)
-                       d[1]=(a[x+1+nx*(y+1)]-a[x+nx*(y+1)]-a[x+1+nx*y]+a[x+nx*y]);
-               else if(y==ny-2)
-                       d[1]=(a[x+1+nx*(y+1)]-a[x-1+nx*(y+1)]-a[x+1+nx*y]+a[x-1+nx*y])/mreal(2);
-               else if(x==0)
-                       d[1]=(a[x+1+nx*(y+2)]-a[x+nx*(y+2)]-a[x+1+nx*y]+a[x+nx*y])/mreal(2);
-               else
-                       d[1]=(a[x+1+nx*(y+2)]-a[x-1+nx*(y+2)]-a[x+1+nx*y]+a[x-1+nx*y])/mreal(4);
-               // ������ d[2]
-               if(y==0 && x==nx-2)
-                       d[2]=(a[x+1+nx*(y+1)]-a[x+nx*(y+1)]-a[x+1+nx*y]+a[x+nx*y]);
-               else if(y==0)
-                       d[2]=(a[x+2+nx*(y+1)]-a[x+nx*(y+1)]-a[x+2+nx*y]+a[x+nx*y])/mreal(2);
-               else if(x==nx-2)
-                       d[2]=(a[x+1+nx*(y+1)]-a[x+nx*(y+1)]-a[x+1+nx*(y-1)]+a[x+nx*(y-1)])/mreal(2);
-               else
-                       d[2]=(a[x+2+nx*(y+1)]-a[x+nx*(y+1)]-a[x+2+nx*(y-1)]+a[x+nx*(y-1)])/mreal(4);
-               // ������ d[3]
-               if(y==ny-2 && x==nx-2)
-                       d[3]=(a[x+1+nx*(y+1)]-a[x+nx*(y+1)]-a[x+1+nx*y]+a[x+nx*y]);
-               else if(y==ny-2)
-                       d[3]=(a[x+2+nx*(y+1)]-a[x+nx*(y+1)]-a[x+2+nx*y]+a[x+nx*y])/mreal(2);
-               else if(x==nx-2)
-                       d[3]=(a[x+1+nx*(y+2)]-a[x+nx*(y+2)]-a[x+1+nx*y]+a[x+nx*y])/mreal(2);
-               else
-                       d[3]=(a[x+2+nx*(y+2)]-a[x+nx*(y+2)]-a[x+2+nx*y]+a[x+nx*y])/mreal(4);
-       }
-       // ��������� ������������ ��������
-       _p[0][0]=f[0];          _p[1][0]=sx[0];
-       _p[2][0]=mreal(3)*(f[2]-f[0])-mreal(2)*sx[0]-sx[2];
-       _p[3][0]=sx[0]+sx[2]+mreal(2)*(f[0]-f[2]);
-       _p[0][1]=sy[0];         _p[1][1]=d[0];
-       _p[2][1]=mreal(3)*(sy[2]-sy[0])-mreal(2)*d[0]-d[2];
-       _p[3][1]=d[0]+d[2]+mreal(2)*(sy[0]-sy[2]);
-       _p[0][2]=mreal(3)*(f[1]-f[0])-mreal(2)*sy[0]-sy[1];
-       _p[1][2]=mreal(3)*(sx[1]-sx[0])-mreal(2)*d[0]-d[1];
-       _p[2][2]=mreal(9)*(f[0]-f[1]-f[2]+f[3])+mreal(6)*(sy[0]-sy[2]+sx[0]-sx[1])+
-               mreal(3)*(sx[2]-sx[3]+sy[1]-sy[3])+mreal(2)*(d[1]+d[2])+mreal(4)*d[0]+d[3];
-       _p[3][2]=mreal(6)*(f[1]+f[2]-f[0]-f[3])+mreal(3)*(sx[1]-sx[0]+sx[3]-sx[2])+
-               mreal(4)*(sy[2]-sy[0])+mreal(2)*(sy[3]-sy[1]-d[0]-d[2])-d[1]-d[3];
-       _p[0][3]=mreal(2)*(f[0]-f[1])+sy[0]+sy[1];
-       _p[1][3]=mreal(2)*(sx[0]-sx[1])+d[0]+d[1];
-       _p[2][3]=mreal(6)*(f[1]+f[2]-f[0]-f[3])+mreal(3)*(sy[2]-sy[1]+sy[3]-sy[0])+
-               mreal(4)*(sx[1]-sx[0])+mreal(2)*(sx[3]-sx[2]-d[0]-d[1])-d[2]-d[3];
-       _p[3][3]=d[0]+d[1]+d[2]+d[3]+mreal(4)*(f[0]-f[1]-f[2]+f[3])+
-               mreal(2)*(sx[0]-sx[1]+sx[2]-sx[3]+sy[0]-sy[2]+sy[1]-sy[3]);
-}
-//-----------------------------------------------------------------------------
-template <class Treal> void mglFillP(long x, const Treal *a,long nx,Treal _p[4])
-{
-       if(x<0 || x>nx-2)
-       {
-               memset(_p,0,4*sizeof(Treal));
-               return;
-       }
-       Treal s[2],f[2];
-       // �������� �������
-       f[0]=a[x];              f[1]=a[x+1];
-       // ����������� �� x
-       if(x==0)        s[0]=a[x+1]-a[x];
-       else            s[0]=(a[x+1]-a[x-1])/mreal(2);
-       if(x==nx-2)     s[1]=a[x+1]-a[x];
-       else            s[1]=(a[x+2]-a[x])/mreal(2);
-       // ��������� ������������ ��������
-       _p[0]=f[0];             _p[1]=s[0];
-       _p[2]=mreal(3)*(f[1]-f[0])-mreal(2)*s[0]-s[1];
-       _p[3]=s[0]+s[1]+mreal(2)*(f[0]-f[1]);
-}
-//-----------------------------------------------------------------------------
 template <class Treal> Treal mglLineart(const Treal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)
 {
        if(!a || nx<1 || ny<1 || nz<1)  return 0;
        register long i0;
-       long kx,ky,kz;
        Treal b=0,dx,dy,dz,b1,b0;
        if(x<0 || y<0 || z<0 || x>nx-1 || y>ny-1 || z>nz-1)
                return 0;
        if(nz>1 && z!=floor(z))         // 3d interpolation
        {
-               kx=long(x);     ky=long(y);     kz=long(z);
+               long kx=long(x), ky=long(y), kz=long(z);
                dx = x-mreal(kx);       dy = y-mreal(ky);       dz = z-mreal(kz);
 
                i0 = kx+nx*(ky+ny*kz);
@@ -164,7 +21,7 @@ template <class Treal> Treal mglLineart(const Treal *a, long nx, long ny, long n
        }
        else if(ny>1 && y!=floor(y))    // 2d interpolation
        {
-               kx=long(x);     ky=long(y);
+               long kx=long(x), ky=long(y);
                dx = x-kx;      dy=y-ky;
                i0 = kx+nx*ky;
                b = a[i0]*(mreal(1)-dx-dy+dx*dy) + dx*(mreal(1)-dy)*a[i0+1] +
@@ -172,7 +29,7 @@ template <class Treal> Treal mglLineart(const Treal *a, long nx, long ny, long n
        }
        else if(nx>1 && x!=floor(x))    // 1d interpolation
        {
-               kx = long(x);
+               long kx = long(x);
                b = a[kx] + (x-kx)*(a[kx+1]-a[kx]);
        }
        else                                            // no interpolation
@@ -180,205 +37,218 @@ template <class Treal> Treal mglLineart(const Treal *a, long nx, long ny, long n
        return b;
 }
 //-----------------------------------------------------------------------------
-template <class Treal> Treal mglSpline3t(const Treal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z, Treal *dx=0, Treal *dy=0, Treal *dz=0)
+template <class Treal> Treal mgl_spline3t(const Treal y[4], long n, mreal dx, Treal &dy)
 {
-       if(!a || nx<1 || ny<1 || nz<1)  return 0;
-       Treal _p[4][4];
-       register long i,j;
-       Treal fx=1, fy=1;
-       long kx=long(x),ky=long(y),kz=long(z);
-       Treal b=0;
-       x = x>0 ?(x<nx-1 ? x:nx-1):0;
-       y = y>0 ?(y<ny-1 ? y:ny-1):0;
-       z = z>0 ?(z<nz-1 ? z:nz-1):0;
-       //      if(x<0 || y<0 || z<0 || x>nx-1 || y>ny-1 || z>nz-1)             return 0;
-       if(dx)  *dx=0;  if(dy)  *dy=0;  if(dz)  *dz=0;
-       if(kx>nx-2)     kx = nx-2;      if(kx<0)        kx = 0;
-       if(ky>ny-2)     ky = ny-2;      if(ky<0)        ky = 0;
-       if(kz>nz-2)     kz = nz-2;      if(kz<0)        kz = 0;
-//     if(nz>1 && z!=kz)               // 3d interpolation
-       if(nz>1)                // 3d interpolation
+       Treal d[3], t0,t1, f0,d0;
+       d[0] = -(y[2]-mreal(4)*y[1]+mreal(3)*y[0])/mreal(2);
+       d[1] = (y[2]-y[0])/mreal(2);
+       d[2] = (y[3]-y[1])/mreal(2);
+//     d[3] = (mreal(3)*y[3]-mreal(4)*y[2]+y[1])/mreal(2);
+
+       t0 = (y[2]+y[0])/mreal(2)-y[1];
+       t1 = (y[3]+y[1])/mreal(2)-y[2];
+       f0 = y[n];              d0 = d[n];
+       Treal res = 0;
+       if(n==1)
+       {
+               Treal f1 = y[2], d1 = d[2];
+               Treal b3 = mreal(10)*(f1-f0)+t1-mreal(3)*t0-mreal(4)*d1-mreal(6)*d0;
+               Treal b4 = mreal(15)*(f0-f1)-mreal(2)*t1+mreal(3)*t0+mreal(7)*d1+mreal(8)*d0;
+               Treal b5 = mreal(6)*(f1-f0)+t1-t0-mreal(3)*d1-mreal(3)*d0;
+               dy = d0 + dx*(mreal(2)*t0+dx*(mreal(3)*b3+dx*(mreal(4)*b4+dx*mreal(5)*b5)));
+//             d2y = mreal(2)*t0 + dx*(mreal(6)*b3+dx*(mreal(12)*b4+dx*mreal(20)*b5)); // 2nd derivative for future
+               res = f0 + dx*(d0+dx*(t0+dx*(b3+dx*(b4+dx*b5))));
+       }
+       else if(n<1)
+       {       res = f0 + dx*(d0+dx*t0);       dy = d0+dx*t0*mreal(2); }
+       else
+       {       res = f0 + dx*(d0+dx*t1);       dy = d0+dx*t1*mreal(2); }
+       return res;
+}
+//-----------------------------------------------------------------------------
+template <class Treal> Treal mgl_spline3st(const Treal y[4], long n, mreal dx)
+{
+       Treal d[3], t0,t1, f0,d0;
+       d[0] = -(y[2]-mreal(4)*y[1]+mreal(3)*y[0])/mreal(2);
+       d[1] = (y[2]-y[0])/mreal(2);
+       d[2] = (y[3]-y[1])/mreal(2);
+//     d[3] = (mreal(3)*y[3]-mreal(4)*y[2]+y[1])/mreal(2);
+
+       Treal res;
+       f0 = y[n];              d0 = d[n];
+       t0 = (y[2]+y[0])/mreal(2)-y[1];
+       t1 = (y[3]+y[1])/mreal(2)-y[2];
+       if(n==1)
+       {
+               Treal f1 = y[2], d1 = d[2];
+               Treal b3 = mreal(10)*(f1-f0)+t1-mreal(3)*t0-mreal(4)*d1-mreal(6)*d0;
+               Treal b4 = mreal(15)*(f0-f1)-mreal(2)*t1+mreal(3)*t0+mreal(7)*d1+mreal(8)*d0;
+               Treal b5 = mreal(6)*(f1-f0)+t1-t0-mreal(3)*d1-mreal(3)*d0;
+               res = f0 + dx*(d0+dx*(t0+dx*(b3+dx*(b4+dx*b5))));
+       }
+       else    res = f0 + dx*(d0+dx*(n<1?t0:t1));
+       return res;
+}
+//-----------------------------------------------------------------------------
+template <class Treal> Treal mglSpline1t(const Treal *a, long nx, mreal x, Treal *dx=0)
+{
+       Treal r,d;
+       if(nx>3)
        {
-               Treal b1[4]={0,0,0,0},  x1[4]={0,0,0,0},  y1[4]={0,0,0,0};
-               long kk=1;
-               if(kz==0)       {       kk=0;   }
-               else if(nz>3 && kz==nz-2)       {       kk=2;   }
-               for(long k=0;k<4;k++)
-               {
-                       if(kz+k-kk<nz && kz+k-kk>=0)
-                               mglFillP(kx, ky, a+(kz+k-kk)*nx*ny, nx, ny, _p);
-                       else
-                       {
-                               memset(_p[0],0,4*sizeof(Treal));
-                               memset(_p[1],0,4*sizeof(Treal));
-                               memset(_p[2],0,4*sizeof(Treal));
-                               memset(_p[3],0,4*sizeof(Treal));
-                       }
-                       for(i=0,fx=1;i<4;i++)
-                       {
-                               for(j=0,fy=1;j<4;j++)
-                               {       b1[k] += fy*fx*_p[i][j];        fy *= y-ky;     }
-                               for(j=1,fy=1;j<4;j++)
-                               {       y1[k] += mreal(j)*fy*fx*_p[i][j];       fy *= y-ky;     }
-                               fx *= x-kx;
-                       }
-                       for(i=1,fx=1;i<4;i++)
-                       {
-                               for(j=0,fy=1;j<4;j++)
-                               {       x1[k] += mreal(i)*fy*fx*_p[i][j];       fy *= y-ky;     }
-                               fx *= x-kx;
-                       }
-               }
-               mglFillP(kk, b1, nz>3 ? 4:3, _p[0]);
-               mglFillP(kk, x1, nz>3 ? 4:3, _p[1]);
-               mglFillP(kk, y1, nz>3 ? 4:3, _p[2]);
-               for(i=0,fx=1,b=0;i<4;i++)
-               {
-                       b += fx*_p[0][i];
-                       if(dx)  *dx += fx*_p[1][i];
-                       if(dy)  *dy += fx*_p[2][i];
-                       fx *= z-kz;
-               }
-               if(dz)  for(i=1,fx=1;i<4;i++)
-               {       *dz += mreal(i)*fx*_p[0][i];    fx *= z-kz;     }
+               register long k = long(x);
+               if(k>0 && k<nx-2)       r = mgl_spline3t<Treal>(a+k-1, 1, x-k, d);
+               else if(k<1)            r = mgl_spline3t<Treal>(a, 0, x, d);
+               else    r = mgl_spline3t<Treal>(a+nx-4, 2, x+2-nx, d);
        }
-//     else if(ny>1 && y!=ky)  // 2d interpolation
-       else if(ny>1)   // 2d interpolation
+       else if(nx<2)   {       d=0;    r = a[0];       }
+       else if(nx==2)  {       d=a[1]-a[0];    r = a[0]+(a[1]-a[0])*x; }
+       else    // nx==3
        {
-               mglFillP(kx, ky, a+kz*nx*ny, nx, ny, _p);
-               for(i=0,fx=1,b=0;i<4;i++)
-               {
-                       for(j=0,fy=1;j<4;j++)
-                       {       b += fy*fx*_p[i][j];    fy *= y-ky;     }
-                       if(dy)  for(j=1,fy=1;j<4;j++)
-                       {       *dy+= mreal(j)*fy*fx*_p[i][j];  fy *= y-ky;     }
-                       fx *= x-kx;
-               }
-               if(dx)  for(i=1,fx=1;i<4;i++)
-               {
-                       for(j=0,fy=1;j<4;j++)
-                       {       *dx+= mreal(i)*fy*fx*_p[i][j];  fy *= y-ky;     }
-                       fx *= x-kx;
-               }
+               Treal b1=-(a[2]-mreal(4)*a[1]+mreal(3)*a[0])/mreal(2), b2=(a[2]-mreal(2)*a[1]+a[0])/mreal(2);
+               d = b1+mreal(2)*b2*x;   r = a[0]+x*(b1+b2*x);
        }
-//     else if(nx>1 && x!=kx)  // 1d interpolation
-       else if(nx>1)   // 1d interpolation
+       if(dx)  *dx=d;
+       return r;
+}
+//-----------------------------------------------------------------------------
+template <class Treal> Treal mglSpline1st(const Treal *a, long nx, mreal x)
+{
+       Treal r;
+       if(nx>3)
        {
-               mglFillP(kx, a+(ky+ny*kz)*nx, nx, _p[0]);
-               for(i=0,fx=1,b=0;i<4;i++)
-               {       b += fx*_p[0][i];       fx *= x-kx;     }
-               if(dx)  for(i=1,fx=1;i<4;i++)
-               {       *dx+= mreal(i)*fx*_p[0][i];     fx *= x-kx;     }
+               register long k = long(x);
+               if(k>0 && k<nx-2)       r = mgl_spline3st<Treal>(a+k-1, 1, x-k);
+               else if(k<1)            r = mgl_spline3st<Treal>(a, 0, x);
+               else    r = mgl_spline3st<Treal>(a+nx-4, 2, x+2-nx);
        }
-       else                                    // no interpolation
-               b = a[kx+nx*(ky+ny*kz)];
-       return b;
+       else if(nx<2)   r = a[0];
+       else if(nx==2)  r = a[0]+(a[1]-a[0])*x;
+       else    // nx==3
+       {
+               Treal b1=-(a[2]-mreal(4)*a[1]+mreal(3)*a[0])/mreal(2), b2=(a[2]-mreal(2)*a[1]+a[0])/mreal(2);
+               r = a[0]+x*(b1+b2*x);
+       }
+       return r;
 }
 //-----------------------------------------------------------------------------
-template <class Treal> Treal mglSpline3st(const Treal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)
+template <class Treal> Treal mglSpline3t(const Treal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z, Treal *dx=0, Treal *dy=0, Treal *dz=0)
 {
-       if(!a || nx<1 || ny<1 || nz<1)  return 0;
-       Treal _p[4][4];
-       register long i,j;
-       Treal fx=1, fy=1;
-       long kx=long(x),ky=long(y),kz=long(z);
-       Treal b=0;
+//     if(!a || nx<1 || ny<1 || nz<1)  return 0;       // NOTE remove this line because this should already checked
+       Treal gx=0,gy=0,gz=0;
        x = x>0 ?(x<nx-1 ? x:nx-1):0;
        y = y>0 ?(y<ny-1 ? y:ny-1):0;
        z = z>0 ?(z<nz-1 ? z:nz-1):0;
-       //      if(x<0 || y<0 || z<0 || x>nx-1 || y>ny-1 || z>nz-1)             return 0;
-       if(kx>nx-2)     kx = nx-2;      if(kx<0)        kx = 0;
-       if(ky>ny-2)     ky = ny-2;      if(ky<0)        ky = 0;
-       if(kz>nz-2)     kz = nz-2;      if(kz<0)        kz = 0;
-//     if(nz>1 && z!=kz)               // 3d interpolation
+       Treal b;
        if(nz>1)                // 3d interpolation
        {
-               Treal b1[4]={0,0,0,0},  x1[4]={0,0,0,0},  y1[4]={0,0,0,0};
-               long kk=1;
-               if(kz==0)       {       kk=0;   }
-               else if(nz>3 && kz==nz-2)       {       kk=2;   }
-               for(long k=0;k<4;k++)
-               {
-                       if(kz+k-kk<nz && kz+k-kk>=0)
-                               mglFillP(kx, ky, a+(kz+k-kk)*nx*ny, nx, ny, _p);
-                       else
-                       {
-                               memset(_p[0],0,4*sizeof(Treal));
-                               memset(_p[1],0,4*sizeof(Treal));
-                               memset(_p[2],0,4*sizeof(Treal));
-                               memset(_p[3],0,4*sizeof(Treal));
-                       }
-                       for(i=0,fx=1;i<4;i++)
-                       {
-                               for(j=0,fy=1;j<4;j++)
-                               {       b1[k] += fy*fx*_p[i][j];        fy *= y-ky;     }
-                               fx *= x-kx;
-                       }
-               }
-               mglFillP(kk, b1, nz>3 ? 4:3, _p[0]);
-               mglFillP(kk, x1, nz>3 ? 4:3, _p[1]);
-               mglFillP(kk, y1, nz>3 ? 4:3, _p[2]);
-               for(i=0,fx=1,b=0;i<4;i++)
+               Treal tz[4], yz[4], xz[4];
+               long kz=long(z)-1, mz, k=long(y)-1, m;
+               if(nz>3)
+               {       mz = 4; kz = kz>=0?kz:0;
+                       if(kz>nz-4)     kz = nz-4;      }
+               else    {       mz = nz;        kz=0;   }
+               if(ny>3)
+               {       m = 4;  k = k>=0?k:0;
+                       if(k>ny-4)      k = ny-4;       }
+               else    {       m = ny; k=0;    }
+               for(long j=0;j<mz;j++)
                {
-                       b += fx*_p[0][i];
-                       fx *= z-kz;
+                       Treal t[4], d[4];
+                       for(long i=0;i<m;i++)
+                               t[i] = mglSpline1t<Treal>(a+nx*(i+k+ny*(j+kz)),nx,x,d+i);
+                       tz[j] = mglSpline1t<Treal>(t,m,y-k,yz+j);
+                       xz[j] = mglSpline1t<Treal>(d,m,y-k,0);
                }
+               b = mglSpline1t<Treal>(tz,mz,z-kz,&gz);
+               gx = mglSpline1t<Treal>(xz,mz,z-kz,0);
+               gy = mglSpline1t<Treal>(yz,mz,z-kz,0);
        }
-//     else if(ny>1 && y!=ky)  // 2d interpolation
        else if(ny>1)   // 2d interpolation
        {
-               mglFillP(kx, ky, a+kz*nx*ny, nx, ny, _p);
-               for(i=0,fx=1,b=0;i<4;i++)
-               {
-                       for(j=0,fy=1;j<4;j++)
-                       {       b += fy*fx*_p[i][j];    fy *= y-ky;     }
-                       fx *= x-kx;
-               }
-       }
-//     else if(nx>1 && x!=kx)  // 1d interpolation
-       else if(nx>1)   // 1d interpolation
-       {
-               mglFillP(kx, a+(ky+ny*kz)*nx, nx, _p[0]);
-               for(i=0,fx=1,b=0;i<4;i++)
-               {       b += fx*_p[0][i];       fx *= x-kx;     }
-       }
-       else                                    // no interpolation
-               b = a[kx+nx*(ky+ny*kz)];
+               Treal t[4], d[4];
+               long k = long(y)-1, m;
+               if(ny>3)
+               {       m = 4;  k = k>=0?k:0;   if(k>ny-4)      k = ny-4;       }
+               else    {       m = ny; k=0;    }
+               for(long i=0;i<m;i++)
+                       t[i] = mglSpline1t<Treal>(a+nx*(i+k),nx,x,d+i);
+               b = mglSpline1t<Treal>(t,m,y-k,&gy);
+               gx = mglSpline1t<Treal>(d,m,y-k,0);
+       }
+       else    // 1d interpolation
+               b = mglSpline1t<Treal>(a,nx,x,&gx);
+       if(dx)  *dx=gx; if(dy)  *dy=gy; if(dz)  *dz=gz;
        return b;
 }
 //-----------------------------------------------------------------------------
-template <class Treal> Treal mglSpline1t(const Treal *a, long nx, mreal x, Treal *dx=0)
+template <class Treal> Treal mglSpline3st(const Treal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)
 {
-       Treal _p[4];
-       long kx=long(x);
-       Treal b=0;
+//     if(!a || nx<1 || ny<1 || nz<1)  return 0;       // NOTE remove this line because this should already checked
        x = x>0 ?(x<nx-1 ? x:nx-1):0;
-       if(kx>nx-2)     kx = nx-2;      if(kx<0)        kx = 0;
-       if(nx>1)        // 1d interpolation
+       y = y>0 ?(y<ny-1 ? y:ny-1):0;
+       z = z>0 ?(z<nz-1 ? z:nz-1):0;
+       Treal b;
+       if(nz>1)                // 3d interpolation
        {
-               mglFillP(kx, a, nx, _p);
-               b = _p[0]+(x-kx)*(_p[1]+(x-kx)*(_p[2]+(x-kx)*_p[3]));
-               if(dx)  *dx = _p[1]+(x-kx)*(mreal(2)*_p[2]+mreal(3)*(x-kx)*_p[3]);
+               Treal tz[4], t[4];
+               long kz=long(z)-1, mz, k=long(y)-1, m;
+               if(nz>3)
+               {       mz = 4; kz = kz>=0?kz:0;
+                       if(kz>nz-4)     kz = nz-4;      }
+               else    {       mz = nz;        kz=0;   }
+               if(ny>3)
+               {       m = 4;  k = k>=0?k:0;
+                       if(k>ny-4)      k = ny-4;       }
+               else    {       m = ny; k=0;    }
+               for(long j=0;j<mz;j++)
+               {
+                       for(long i=0;i<m;i++)
+                               t[i] = mglSpline1st<Treal>(a+nx*(i+k+ny*(j+kz)),nx,x);
+                       tz[j] = mglSpline1st<Treal>(t,m,y-k);
+               }
+               b = mglSpline1st<Treal>(tz,mz,z-kz);
        }
-       else            // no interpolation
-       {       b = a[0];       if(dx)  *dx=0;  }
+       else if(ny>1)   // 2d interpolation
+       {
+               Treal t[4];
+               long k = long(y)-1, m;
+               if(ny>3)
+               {       m = 4;  k = k>=0?k:0;
+                       if(k>ny-4)      k = ny-4;       }
+               else    {       m = ny; k=0;    }
+               for(long i=0;i<m;i++)
+                       t[i] = mglSpline1st<Treal>(a+nx*(i+k),nx,x);
+               b = mglSpline1st<Treal>(t,m,y-k);
+       }
+       else    // 1d interpolation
+               b = mglSpline1st<Treal>(a,nx,x);
        return b;
 }
 //-----------------------------------------------------------------------------
-template <class Treal> Treal mglSpline1st(const Treal *a, long nx, mreal x)
-{
-       Treal _p[4];
-       long kx=long(x);
-       Treal b=0;
-       x = x>0 ?(x<nx-1 ? x:nx-1):0;
-       if(kx>nx-2)     kx = nx-2;      if(kx<0)        kx = 0;
-       if(nx>1)        // 1d interpolation
-       {
-               mglFillP(kx, a, nx, _p);
-               b = _p[0]+(x-kx)*(_p[1]+(x-kx)*(_p[2]+(x-kx)*_p[3]));
+template <class Treal> void mgl_gspline_init(long n, const mreal *x, const Treal *v, Treal *c)
+{      // c must have size 5*(n-1) !!!
+//     if(n<2) return; // NOTE remove this line because this should already checked
+       Treal *a = new Treal[n], *b = new Treal[n];
+       for(long i=0;i<n-1;i++) // basic coefficients
+       {       c[5*i] = x[i+1]-x[i];   c[5*i+1] = v[i];        }
+       // progonka
+       a[0] = -0.5;    b[0] = mreal(1.5)*(v[1]-v[0])/(x[1]-x[0]);
+       for(long i=1;i<n-1;i++)
+       {
+               mreal h0 = x[i]-x[i-1], h1 = x[i+1]-x[i];
+               Treal r = mreal(1)/(2/h0+2/h1 + a[i-1]/h0);
+               a[i] = - r/h1;
+               b[i] = ((3/h0/h0)*(v[i]-v[i-1]) + (1/h1/h1)*(v[i+1]-v[i]) + a[i-1]/h0)*r;
+       }
+       b[n-1] = ( (6/(x[n-1]-x[n-2]))*(v[n-1]-v[n-2]) - mreal(2)*b[n-2] )/(mreal(4)+mreal(2)*a[n-2]);
+       for(long i=n-2;i>=0;i--)        b[i] += a[i]*b[i+1];
+       // no spline coefficients
+       for(long i=0;i<n-1;i++)
+       {
+               c[5*i+2] = b[i];
+               mreal h = 1/(x[i+1]-x[i]), h2 = h*h;
+               c[5*i+3] = (3*h2)*(v[i+1]-v[i]) - (b[i+1]+b[i]+b[i])*h;
+               c[5*i+4] = (2*h2*h)*(v[i]-v[i+1]) + (b[i+1]+b[i])*h2;
        }
-       else            // no interpolation
-               b = a[0];
-       return b;
 }
 //-----------------------------------------------------------------------------
index 92f44542e31bb29eadb8ee5f28d3e0c05181f702..febde6c6b5c9a10dec70049d53c0e5f1e393f498 100644 (file)
@@ -315,26 +315,26 @@ struct ObjGroup {
   void writeLines() {\r
     for(std::map<size_t, std::deque<ObjLine> >::const_iterator pm = lines.begin(); pm != lines.end(); pm++)\r
     {\r
-      fprintf(fp,"usemtl Material%"PRIuS"\n", pm->first);\r
+      fprintf(fp,"usemtl Material%" PRIuS "\n", pm->first);\r
       for(std::deque<ObjLine>::const_iterator pl = pm->second.begin(); pl != pm->second.end(); pl++)\r
-        fprintf(fp,"l %"PRIuS" %"PRIuS"\n", pl->p1, pl->p2);\r
+        fprintf(fp,"l %" PRIuS " %" PRIuS "\n", pl->p1, pl->p2);\r
       }\r
   }\r
   void writePoints() {\r
     for(std::map<size_t, std::deque<size_t> >::const_iterator pm = points.begin(); pm != points.end(); pm++)\r
     {\r
-      fprintf(fp,"usemtl Material%"PRIuS"\n", pm->first);\r
+      fprintf(fp,"usemtl Material%" PRIuS "\n", pm->first);\r
       for(std::deque<size_t>::const_iterator pp = pm->second.begin(); pp != pm->second.end(); pp++)\r
-        fprintf(fp,"p %"PRIuS"\n", *pp);\r
+        fprintf(fp,"p %" PRIuS "\n", *pp);\r
     }\r
   }\r
   void writeTriangles() {\r
     for(std::deque<ObjTriangle>::const_iterator pt = triangles.begin(); pt != triangles.end(); pt++)\r
-      fprintf(fp,"f %"PRIuS" %"PRIuS" %"PRIuS"\n", pt->p1, pt->p2, pt->p3);\r
+      fprintf(fp,"f %" PRIuS " %" PRIuS " %" PRIuS "\n", pt->p1, pt->p2, pt->p3);\r
   }\r
   void writeTexturedTriangles() {\r
     for(std::deque<ObjTriangle>::const_iterator pt = triangles.begin(); pt != triangles.end(); pt++)\r
-      fprintf(fp,"f %"PRIuS"/%"PRIuS" %"PRIuS"/%"PRIuS" %"PRIuS"/%"PRIuS"\n", pt->p1,pt->t1, pt->p2,pt->t2, pt->p3,pt->t3);\r
+      fprintf(fp,"f %" PRIuS "/%" PRIuS " %" PRIuS "/%" PRIuS " %" PRIuS "/%" PRIuS "\n", pt->p1,pt->t1, pt->p2,pt->t2, pt->p3,pt->t3);\r
   }\r
 };\r
 \r
@@ -371,7 +371,7 @@ struct ObjMaterials {
                {\r
                        const size_t color_index = materialmap.size();\r
                        materialmap.insert(std::make_pair(color,color_index));\r
-      fprintf(fp,"newmtl Material%"PRIuS"\n", color_index);\r
+      fprintf(fp,"newmtl Material%" PRIuS "\n", color_index);\r
       fprintf(fp,"Ka 0.1 0.1 0.1\n");\r
       fprintf(fp,"Kd %g %g %g\n", color.r, color.g, color.b);\r
       fprintf(fp,"Ks 0.0 0.0 0.0\n");\r
@@ -391,17 +391,13 @@ struct ObjMaterials {
   }\r
 };\r
 \r
-\r
-static size_t power_of_two(size_t input)\r
+size_t MGL_LOCAL_CONST power_of_two(size_t input)\r
 {\r
        size_t value = 1;\r
-       while ( value < input ) {\r
-               value <<= 1;\r
-       }\r
+       while ( value < input ) value <<= 1;\r
        return value;\r
 }\r
 \r
-\r
 void MGL_EXPORT mgl_write_obj(HMGL gr, const char *fname,const char *descr, int use_png)\r
 {\r
        if(gr->GetPrmNum()==0)  return; // nothing to do\r
@@ -416,7 +412,7 @@ void MGL_EXPORT mgl_write_obj(HMGL gr, const char *fname,const char *descr, int
                for(i=0;i<size_t(gr->GetPrmNum());i++)  // collect data for groups\r
                // it is rather expensive (extra 4b per primitive) but need for export to 3D\r
                {\r
-                       m = gr->GetPrm(i).id-mmin;\r
+                       m = gr->GetPrm(i,false).id-mmin;\r
                        if(m>=0 && m<mmax-mmin+1)       gr->Grp[ng[m]].p.push_back(i);\r
                }\r
                delete []ng;\r
@@ -509,7 +505,7 @@ void MGL_EXPORT mgl_write_obj(HMGL gr, const char *fname,const char *descr, int
     ObjGroup grp(fp, vertexcoords);\r
                for(j=0;j<p.size();j++)\r
                {\r
-                       const mglPrim &q = gr->GetPrm(p[j]);\r
+                       const mglPrim &q = gr->GetPrm(p[j],false);\r
 \r
       register long n1=q.n1,n2=q.n2,n3=q.n3,n4=q.n4;\r
       switch(q.type)\r
@@ -945,7 +941,7 @@ void MGL_EXPORT mgl_write_obj(HMGL gr, const char *fname,const char *descr, int
 \r
     if (!grp.triangles.empty()) {\r
       if (grp.samecolor) {\r
-        fprintf(fp,"usemtl Material%"PRIuS"\n", materials.addColor(grp.commoncolor));\r
+        fprintf(fp,"usemtl Material%" PRIuS "\n", materials.addColor(grp.commoncolor));\r
         grp.writeTriangles();\r
       } else {\r
         fprintf(fp,"usemtl Material\n");\r
index 1da1b53e6b673dc82226cbfab1f235e0308f8dea..e35b6cacc0268f3a4e58d4c2beca9f7c92d44546 100644 (file)
@@ -23,28 +23,39 @@ mglCanvasGL::~mglCanvasGL(){}
 //-----------------------------------------------------------------------------\r
 void mglCanvasGL::Finish()\r
 {\r
+#if MGL_USE_DOUBLE\r
+#define MGL_GL_TYPE    GL_DOUBLE\r
+#else\r
+#define MGL_GL_TYPE    GL_FLOAT\r
+#endif\r
+\r
        if(Prm.size()>0)\r
        {\r
                PreparePrim(0);\r
-               glVertexPointer(3, GL_FLOAT, sizeof(mglPnt), &(Pnt[0].x));\r
-               glNormalPointer(GL_FLOAT, sizeof(mglPnt), &(Pnt[0].u));\r
-               glColorPointer(4, GL_FLOAT, sizeof(mglPnt), &(Pnt[0].r));\r
+/*             glVertexPointer(3, MGL_GL_TYPE, sizeof(mglPnt), &(Pnt[0].x));   // something wrong with arrays\r
+               glNormalPointer(MGL_GL_TYPE, sizeof(mglPnt), &(Pnt[0].u));\r
+               glColorPointer(4, MGL_GL_TYPE, sizeof(mglPnt), &(Pnt[0].r));\r
                glEnableClientState(GL_VERTEX_ARRAY);\r
                glEnableClientState(GL_NORMAL_ARRAY);\r
-               glEnableClientState(GL_COLOR_ARRAY);\r
+               glEnableClientState(GL_COLOR_ARRAY);*/\r
 \r
                int pdef=PDef;\r
                mreal ss=pPos, ww=PenWidth;\r
                mglPrim p;\r
                for(size_t i=0;i<Prm.size();i++)\r
                {\r
-                       p=Prm[i];       PDef=p.n3;      pPos=p.s;       PenWidth=p.w;\r
+                       p=GetPrm(i);    PDef=p.n3;      pPos=p.s;       PenWidth=p.w;\r
+                       register long n1=p.n1, n2=p.n2, n3=p.n3, n4=p.n4;\r
                        switch(p.type)\r
                        {\r
-                       case 0: mark_draw(Pnt[p.n1],p.n4,p.s,0);        break;\r
-                       case 1: line_draw(p.n1,p.n2);   break;\r
-                       case 2: trig_draw(p.n1,p.n2,p.n3);      break;\r
-                       case 3: quad_draw(p.n1,p.n2,p.n3,p.n4); break;\r
+/*                     case 0: mark_draw(Pnt[n1],n4,p.s,0);    break;\r
+                       case 1: line_draw(n1,n2);       break;\r
+                       case 2: trig_draw(n1,n2,n3);    break;\r
+                       case 3: quad_draw(n1,n2,n3,n4); break;*/\r
+                       case 0: mark_draw(Pnt[n1],n4,p.s,0);    break;\r
+                       case 1: line_draw(Pnt[n1],Pnt[n2],0);   break;\r
+                       case 2: trig_draw(Pnt[n1],Pnt[n2],Pnt[n3],true,0);      break;\r
+                       case 3: quad_draw(Pnt[n1],Pnt[n2],Pnt[n3],Pnt[n4],0);   break;\r
                        case 4: glyph_draw(p,0);        break;\r
                        }\r
                }\r
@@ -191,8 +202,10 @@ void mglCanvasGL::gl_clf(mglColor Back)
 \r
        glMatrixMode(GL_MODELVIEW);//GL_MODELVIEW GL_VIEWPORT GL_PROJECTION\r
        glLoadIdentity();\r
-//     glScaled(1.5,1.5,1.5);\r
-//     glTranslated(-0.5,-0.5,-0.5);\r
+//     glScaled(1.5,1.5,1.5);\r
+//     glTranslated(-0.5,-0.5,-0.5);\r
+       glScaled(2,2,2);\r
+       glTranslated(-0.5,-0.5,-0.5);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvasGL::set_pen(unsigned style,mreal width)\r
@@ -270,8 +283,8 @@ void mglCanvasGL::quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3
        glBegin(GL_QUADS);\r
        glNormal3f(p1.u,p1.v,p1.w);     glColor4f(p1.r,p1.g,p1.b,p1.a); glVertex3f(p1.x,p1.y,p1.z);\r
        glNormal3f(p2.u,p2.v,p2.w);     glColor4f(p2.r,p2.g,p2.b,p2.a); glVertex3f(p2.x,p2.y,p2.z);\r
-       glNormal3f(p3.u,p3.v,p3.w);     glColor4f(p3.r,p3.g,p3.b,p3.a); glVertex3f(p3.x,p3.y,p3.z);\r
        glNormal3f(p4.u,p4.v,p4.w);     glColor4f(p4.r,p4.g,p4.b,p4.a); glVertex3f(p4.x,p4.y,p4.z);\r
+       glNormal3f(p3.u,p3.v,p3.w);     glColor4f(p3.r,p3.g,p3.b,p3.a); glVertex3f(p3.x,p3.y,p3.z);\r
        glEnd();\r
 }\r
 //-----------------------------------------------------------------------------\r
index b5d4e00b01ae8f3ec227b7e11baba19ff8d902ca..06549af8de32cd43a6211e7f5c4c024cb0e2420f 100644 (file)
 #include "mgl2/data.h"\r
 #include "mgl2/base.h"\r
 //-----------------------------------------------------------------------------\r
-//\r
-//     DensX, DensY, DensZ series\r
-//\r
-//-----------------------------------------------------------------------------\r
-void MGL_EXPORT mgl_dens_x(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
+HCDT MGL_NO_EXPORT fill_slice_x(HMGL gr, double sv, HCDT a, mglData &xx, mglData &yy, mglData &zz, mglData &aa)\r
 {\r
        long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
-       if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
-       if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"DensX");        return; }\r
-       if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"DensX");        return; }\r
-       mglData xx,yy,zz,aa;\r
-       gr->SaveState(opt);\r
-\r
        if(l>1)\r
        {\r
                aa.Create(m,l); xx.Create(m,l); yy.Create(m,l); zz.Create(m,l);\r
@@ -44,15 +34,9 @@ void MGL_EXPORT mgl_dens_x(HMGL gr, HCDT a, const char *sch, double sv, const ch
                long k = long(d);       d = d - k;\r
                if(k>n-2)       {       k=n-2;  d=1;    }\r
                if(k<0)         {       k=0;    d=0;    }\r
-               const mglData *ma=dynamic_cast<const mglData *>(a);\r
-               if(ma)\r
 #pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<m;i++)\r
-                               aa.a[i+m*j] = ma->a[k+n*(i+m*j)]*(1-d) + d*ma->a[k+1+n*(i+m*j)];\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<m;i++)\r
-                               aa.a[i+m*j] = a->v(k,i,j)*(1-d) + d*a->v(k+1,i,j);\r
+               for(long j=0;j<l;j++)   for(long i=0;i<m;i++)\r
+                       aa.a[i+m*j] = a->v(k,i,j)*(1-d) + d*a->v(k+1,i,j);\r
                a = &aa;\r
        }\r
        else\r
@@ -60,18 +44,12 @@ void MGL_EXPORT mgl_dens_x(HMGL gr, HCDT a, const char *sch, double sv, const ch
        xx.Fill(sv, sv);\r
        yy.Fill(gr->Min.y, gr->Max.y,'x');\r
        zz.Fill(gr->Min.z, gr->Max.z,'y');\r
-       mgl_surfc_xy(gr,&xx,&yy,&zz,a,sch,0);\r
+       return a;\r
 }\r
 //-----------------------------------------------------------------------------\r
-void MGL_EXPORT mgl_dens_y(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
+HCDT MGL_NO_EXPORT fill_slice_y(HMGL gr, double sv, HCDT a, mglData &xx, mglData &yy, mglData &zz, mglData &aa)\r
 {\r
        long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
-       if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
-       if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"DensY");        return; }\r
-       if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"DensY");        return; }\r
-       mglData xx,yy,zz,aa;\r
-       gr->SaveState(opt);\r
-\r
        if(l>1)\r
        {\r
                aa.Create(n,l); xx.Create(n,l); yy.Create(n,l); zz.Create(n,l);\r
@@ -79,15 +57,9 @@ void MGL_EXPORT mgl_dens_y(HMGL gr, HCDT a, const char *sch, double sv, const ch
                long k = long(d);       d = d - k;\r
                if(k>m-2)       {       k=m-2;  d=1;    }\r
                if(k<0)         {       k=0;    d=0;    }\r
-               const mglData *ma=dynamic_cast<const mglData *>(a);\r
-               if(ma)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = ma->a[i+n*(k+m*j)]*(1-d) + d*ma->a[i+n+n*(k+m*j)];\r
-               else\r
 #pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = a->v(i,k,j)*(1-d) + d*a->v(i,k+1,j);\r
+               for(long j=0;j<l;j++)   for(long i=0;i<n;i++)\r
+                       aa.a[i+n*j] = a->v(i,k,j)*(1-d) + d*a->v(i,k+1,j);\r
                a = &aa;\r
        }\r
        else\r
@@ -95,18 +67,12 @@ void MGL_EXPORT mgl_dens_y(HMGL gr, HCDT a, const char *sch, double sv, const ch
        yy.Fill(sv, sv);\r
        xx.Fill(gr->Min.x, gr->Max.x,'x');\r
        zz.Fill(gr->Min.z, gr->Max.z,'y');\r
-       mgl_surfc_xy(gr,&xx,&yy,&zz,a,sch,0);\r
+       return a;\r
 }\r
 //-----------------------------------------------------------------------------\r
-void MGL_EXPORT mgl_dens_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
+HCDT MGL_NO_EXPORT fill_slice_z(HMGL gr, double sv, HCDT a, mglData &xx, mglData &yy, mglData &zz, mglData &aa)\r
 {\r
        long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
-       if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
-       if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"DensZ");        return; }\r
-       if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"DensZ");        return; }\r
-       mglData xx,yy,zz,aa;\r
-       gr->SaveState(opt);\r
-\r
        xx.Create(n,m); yy.Create(n,m); zz.Create(n,m);\r
        if(l>1)\r
        {\r
@@ -115,20 +81,54 @@ void MGL_EXPORT mgl_dens_z(HMGL gr, HCDT a, const char *sch, double sv, const ch
                long k = long(d);       d = d - k;\r
                if(k>l-2)       {       k=l-2;  d=1;    }\r
                if(k<0)         {       k=0;    d=0;    }\r
-               const mglData *ma=dynamic_cast<const mglData *>(a);\r
-               if(ma)\r
 #pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = ma->a[i+n*(j+m*k)]*(1-d) + d*ma->a[i+n*m+n*(j+m*k)];\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = a->v(i,j,k)*(1-d) + d*a->v(i,j,k+1);\r
+               for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
+                       aa.a[i+n*j] = a->v(i,j,k)*(1-d) + d*a->v(i,j,k+1);\r
                a = &aa;\r
        }\r
        zz.Fill(sv, sv);\r
        yy.Fill(gr->Min.y, gr->Max.y,'y');\r
        xx.Fill(gr->Min.x, gr->Max.x,'x');\r
+       return a;\r
+}\r
+//-----------------------------------------------------------------------------\r
+//\r
+//     DensX, DensY, DensZ series\r
+//\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_dens_x(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
+{\r
+       long n=a->GetNx(),m=a->GetNy();\r
+       if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
+       if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"DensX");        return; }\r
+       if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"DensX");        return; }\r
+       mglData xx,yy,zz,aa;\r
+       gr->SaveState(opt);\r
+       a = fill_slice_x(gr,sv,a,xx,yy,zz,aa);\r
+       mgl_surfc_xy(gr,&xx,&yy,&zz,a,sch,0);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_dens_y(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
+{\r
+       long n=a->GetNx(),m=a->GetNy();\r
+       if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
+       if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"DensY");        return; }\r
+       if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"DensY");        return; }\r
+       mglData xx,yy,zz,aa;\r
+       gr->SaveState(opt);\r
+       a = fill_slice_y(gr,sv,a,xx,yy,zz,aa);\r
+       mgl_surfc_xy(gr,&xx,&yy,&zz,a,sch,0);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_dens_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
+{\r
+       long n=a->GetNx(),m=a->GetNy();\r
+       if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
+       if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"DensZ");        return; }\r
+       if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"DensZ");        return; }\r
+       mglData xx,yy,zz,aa;\r
+       gr->SaveState(opt);\r
+       a = fill_slice_z(gr,sv,a,xx,yy,zz,aa);\r
        mgl_surfc_xy(gr,&xx,&yy,&zz,a,sch,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -156,7 +156,7 @@ void MGL_EXPORT mgl_dens_z_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal
 void MGL_EXPORT mgl_cont_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, int text,long ak);\r
 void MGL_EXPORT mgl_cont_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
 {\r
-       long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
+       long n=a->GetNx(),m=a->GetNy();\r
        if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"ContX");        return; }\r
        if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"ContX");        return; }\r
@@ -164,34 +164,13 @@ void MGL_EXPORT mgl_cont_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
        static int cgid=1;      gr->StartGroup("ContX",cgid++);\r
        mglData xx,yy,zz,aa;\r
 \r
-       bool text=(mglchr(sch,'t'));\r
+       int text=0;\r
+       if(mglchr(sch,'t'))     text=1;\r
+       if(mglchr(sch,'T'))     text=2;\r
        long ss=gr->AddTexture(sch);\r
        gr->SetPenPal(sch);\r
 \r
-       if(l>1)\r
-       {\r
-               aa.Create(m,l); xx.Create(m,l); yy.Create(m,l); zz.Create(m,l);\r
-               mreal d = (n-1)*(sv - gr->Min.x)/(gr->Max.x - gr->Min.x);\r
-               long k = long(d);       d = d - k;\r
-               if(k>n-2)       {       k=n-2;  d=1;    }\r
-               if(k<0)         {       k=0;    d=0;    }\r
-               const mglData *ma=dynamic_cast<const mglData *>(a);\r
-               if(ma)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<m;i++)\r
-                               aa.a[i+m*j] = ma->a[k+n*(i+m*j)]*(1-d) + d*ma->a[k+1+n*(i+m*j)];\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<m;i++)\r
-                               aa.a[i+m*j] = a->v(k,i,j)*(1-d) + d*a->v(k+1,i,j);\r
-               a = &aa;\r
-       }\r
-       else\r
-       {       xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); }\r
-       xx.Fill(sv, sv);\r
-       yy.Fill(gr->Min.y, gr->Max.y,'x');\r
-       zz.Fill(gr->Min.z, gr->Max.z,'y');\r
-#pragma omp parallel for\r
+       a = fill_slice_x(gr,sv,a,xx,yy,zz,aa);\r
        for(long i=0;i<v->GetNx();i++)\r
        {\r
                register mreal v0 = v->v(i);\r
@@ -202,7 +181,7 @@ void MGL_EXPORT mgl_cont_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_cont_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
 {\r
-       long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
+       long n=a->GetNx(),m=a->GetNy();\r
        if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"ContY");        return; }\r
        if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"ContY");        return; }\r
@@ -210,34 +189,13 @@ void MGL_EXPORT mgl_cont_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
        static int cgid=1;      gr->StartGroup("ContY",cgid++);\r
        mglData xx,yy,zz,aa;\r
 \r
-       bool text=(mglchr(sch,'t'));\r
+       int text=0;\r
+       if(mglchr(sch,'t'))     text=1;\r
+       if(mglchr(sch,'T'))     text=2;\r
        long ss=gr->AddTexture(sch);\r
        gr->SetPenPal(sch);\r
 \r
-       if(l>1)\r
-       {\r
-               aa.Create(n,l); xx.Create(n,l); yy.Create(n,l); zz.Create(n,l);\r
-               mreal d = (m-1)*(sv - gr->Min.y)/(gr->Max.y - gr->Min.y);\r
-               long k = long(d);       d = d - k;\r
-               if(k>m-2)       {       k=m-2;  d=1;    }\r
-               if(k<0)         {       k=0;    d=0;    }\r
-               const mglData *ma=dynamic_cast<const mglData *>(a);\r
-               if(ma)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = ma->a[i+n*(k+m*j)]*(1-d) + d*ma->a[i+n+n*(k+m*j)];\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = a->v(i,k,j)*(1-d) + d*a->v(i,k+1,j);\r
-               a = &aa;\r
-       }\r
-       else\r
-       {       xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); }\r
-       yy.Fill(sv, sv);\r
-       xx.Fill(gr->Min.x, gr->Max.x,'x');\r
-       zz.Fill(gr->Min.z, gr->Max.z,'y');\r
-#pragma omp parallel for\r
+       a = fill_slice_y(gr,sv,a,xx,yy,zz,aa);\r
        for(long i=0;i<v->GetNx();i++)\r
        {\r
                register mreal v0 = v->v(i);\r
@@ -248,7 +206,7 @@ void MGL_EXPORT mgl_cont_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_cont_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
 {\r
-       long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
+       long n=a->GetNx(),m=a->GetNy();\r
        if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"ContZ");        return; }\r
        if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"ContZ");        return; }\r
@@ -256,33 +214,13 @@ void MGL_EXPORT mgl_cont_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
        static int cgid=1;      gr->StartGroup("ContZ",cgid++);\r
        mglData xx,yy,zz,aa;\r
 \r
-       bool text=(mglchr(sch,'t'));\r
+       int text=0;\r
+       if(mglchr(sch,'t'))     text=1;\r
+       if(mglchr(sch,'T'))     text=2;\r
        long ss=gr->AddTexture(sch);\r
        gr->SetPenPal(sch);\r
 \r
-       xx.Create(n,m); yy.Create(n,m); zz.Create(n,m);\r
-       if(l>1)\r
-       {\r
-               aa.Create(n,m);\r
-               mreal d = (l-1)*(sv - gr->Min.z)/(gr->Max.z - gr->Min.z);\r
-               long k = long(d);       d = d - k;\r
-               if(k>l-2)       {       k=l-2;  d=1;    }\r
-               if(k<0)         {       k=0;    d=0;    }\r
-               const mglData *ma=dynamic_cast<const mglData *>(a);\r
-               if(ma)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = ma->a[i+n*(j+m*k)]*(1-d) + d*ma->a[i+n*m+n*(j+m*k)];\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = a->v(i,j,k)*(1-d) + d*a->v(i,j,k+1);\r
-               a = &aa;\r
-       }\r
-       zz.Fill(sv, sv);\r
-       yy.Fill(gr->Min.y, gr->Max.y,'y');\r
-       xx.Fill(gr->Min.x, gr->Max.x,'x');\r
-#pragma omp parallel for\r
+       a = fill_slice_z(gr,sv,a,xx,yy,zz,aa);\r
        for(long i=0;i<v->GetNx();i++)\r
        {\r
                register mreal v0 = v->v(i);\r
@@ -355,7 +293,7 @@ void MGL_EXPORT mgl_cont_z_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const
 void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, long ak);\r
 void MGL_EXPORT mgl_contf_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
 {\r
-       long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
+       long n=a->GetNx(),m=a->GetNy();\r
        if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"ContFX");       return; }\r
        if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"ContFX");       return; }\r
@@ -364,30 +302,7 @@ void MGL_EXPORT mgl_contf_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
        mglData xx,yy,zz,aa;\r
        long ss=gr->AddTexture(sch);\r
 \r
-       if(l>1)\r
-       {\r
-               aa.Create(m,l); xx.Create(m,l); yy.Create(m,l); zz.Create(m,l);\r
-               mreal d = (n-1)*(sv - gr->Min.x)/(gr->Max.x - gr->Min.x);\r
-               long k = long(d);       d = d - k;\r
-               if(k>n-2)       {       k=n-2;  d=1;    }\r
-               if(k<0)         {       k=0;    d=0;    }\r
-               const mglData *ma=dynamic_cast<const mglData *>(a);\r
-               if(ma)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<m;i++)\r
-                               aa.a[i+m*j] = ma->a[k+n*(i+m*j)]*(1-d) + d*ma->a[k+1+n*(i+m*j)];\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<m;i++)\r
-                               aa.a[i+m*j] = a->v(k,i,j)*(1-d) + d*a->v(k+1,i,j);\r
-               a = &aa;\r
-       }\r
-       else\r
-       {       xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); }\r
-       xx.Fill(sv, sv);\r
-       yy.Fill(gr->Min.y, gr->Max.y,'x');\r
-       zz.Fill(gr->Min.z, gr->Max.z,'y');\r
-#pragma omp parallel for\r
+       a = fill_slice_x(gr,sv,a,xx,yy,zz,aa);\r
        for(long i=0;i<v->GetNx()-1;i++)\r
        {\r
                register mreal v0 = v->v(i);\r
@@ -398,7 +313,7 @@ void MGL_EXPORT mgl_contf_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_contf_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
 {\r
-       long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
+       long n=a->GetNx(),m=a->GetNy();\r
        if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"ContFY");       return; }\r
        if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"ContFY");       return; }\r
@@ -407,30 +322,7 @@ void MGL_EXPORT mgl_contf_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
        mglData xx,yy,zz,aa;\r
        long ss=gr->AddTexture(sch);\r
 \r
-       if(l>1)\r
-       {\r
-               aa.Create(n,l); xx.Create(n,l); yy.Create(n,l); zz.Create(n,l);\r
-               mreal d = (m-1)*(sv - gr->Min.y)/(gr->Max.y - gr->Min.y);\r
-               long k = long(d);       d = d - k;\r
-               if(k>m-2)       {       k=m-2;  d=1;    }\r
-               if(k<0)         {       k=0;    d=0;    }\r
-               const mglData *ma=dynamic_cast<const mglData *>(a);\r
-               if(ma)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = ma->a[i+n*(k+m*j)]*(1-d) + d*ma->a[i+n+n*(k+m*j)];\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<l;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = a->v(i,k,j)*(1-d) + d*a->v(i,k+1,j);\r
-               a = &aa;\r
-       }\r
-       else\r
-       {       xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); }\r
-       yy.Fill(sv, sv);\r
-       xx.Fill(gr->Min.x, gr->Max.x,'x');\r
-       zz.Fill(gr->Min.z, gr->Max.z,'y');\r
-#pragma omp parallel for\r
+       a = fill_slice_y(gr,sv,a,xx,yy,zz,aa);\r
        for(long i=0;i<v->GetNx()-1;i++)\r
        {\r
                register mreal v0 = v->v(i);\r
@@ -441,7 +333,7 @@ void MGL_EXPORT mgl_contf_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_contf_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
 {\r
-       long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
+       long n=a->GetNx(),m=a->GetNy();\r
        if(mgl_isnan(sv))       sv = gr->GetOrgX('x');\r
        if(n<2 || m<2)  {       gr->SetWarn(mglWarnLow,"ContFZ");       return; }\r
        if(sv<gr->Min.x || sv>gr->Max.x)        {       gr->SetWarn(mglWarnSlc,"ContFZ");       return; }\r
@@ -450,29 +342,7 @@ void MGL_EXPORT mgl_contf_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double
        mglData xx,yy,zz,aa;\r
        long ss=gr->AddTexture(sch);\r
 \r
-       xx.Create(n,m); yy.Create(n,m); zz.Create(n,m);\r
-       if(l>1)\r
-       {\r
-               aa.Create(n,m);\r
-               mreal d = (l-1)*(sv - gr->Min.z)/(gr->Max.z - gr->Min.z);\r
-               long k = long(d);       d = d - k;\r
-               if(k>l-2)       {       k=l-2;  d=1;    }\r
-               if(k<0)         {       k=0;    d=0;    }\r
-               const mglData *ma=dynamic_cast<const mglData *>(a);\r
-               if(ma)\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = ma->a[i+n*(j+m*k)]*(1-d) + d*ma->a[i+n*m+n*(j+m*k)];\r
-               else\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-                               aa.a[i+n*j] = a->v(i,j,k)*(1-d) + d*a->v(i,j,k+1);\r
-               a = &aa;\r
-       }\r
-       zz.Fill(sv, sv);\r
-       yy.Fill(gr->Min.y, gr->Max.y,'y');\r
-       xx.Fill(gr->Min.x, gr->Max.x,'x');\r
-#pragma omp parallel for\r
+       a = fill_slice_z(gr,sv,a,xx,yy,zz,aa);\r
        for(long i=0;i<v->GetNx()-1;i++)\r
        {\r
                register mreal v0 = v->v(i);\r
index 2b61cda2cbaa491e8cbcd2eff36bbc0f2d279178..ac09a5a4e16a2e9266d4f19d7a44da301dc374bf 100644 (file)
@@ -33,8 +33,6 @@ MGL_EXPORT void (*mgl_ask_func)(const wchar_t *, wchar_t *)=0;
 void MGL_EXPORT mgl_ask_gets(const wchar_t *quest, wchar_t *res)
 {      printf("%ls\n",quest);  if(!fgetws(res,1024,stdin))     *res=0; }
 //-----------------------------------------------------------------------------
-mglFunc::mglFunc(const mglFunc &f)
-{      pos=f.pos;      narg=f.narg;    func=f.func;    }
 mglFunc::mglFunc(long p, const wchar_t *f)
 {
        pos = p;        func = f;
@@ -75,7 +73,7 @@ MGL_NO_EXPORT wchar_t *mgl_str_copy(const char *s)
        str[i] = 0;     return str;
 }
 //-----------------------------------------------------------------------------
-int MGL_NO_EXPORT mgl_cmd_cmp(const void *a, const void *b)
+int MGL_LOCAL_PURE mgl_cmd_cmp(const void *a, const void *b)
 {
        const mglCommand *aa = (const mglCommand *)a;
        const mglCommand *bb = (const mglCommand *)b;
@@ -87,7 +85,7 @@ bool mgl_check_for_name(const std::wstring &s)
        return !isalpha(s[0])||s.find_first_of(L".:()")!=std::wstring::npos;
 }
 //-----------------------------------------------------------------------------
-mglCommand *mglParser::FindCommand(const char *com)
+const mglCommand *mglParser::FindCommand(const char *com) const
 {
        if(!AllowFileIO && ( !strncmp(com,"read",4) || !strncmp(com,"save",4) || !strcmp(com,"fgets") || !strcmp(com,"import") || !strcmp(com,"export") ))
                return 0;
@@ -99,7 +97,7 @@ mglCommand *mglParser::FindCommand(const char *com)
        return rts;
 }
 //-----------------------------------------------------------------------------
-mglCommand *mglParser::FindCommand(const wchar_t *com)
+const mglCommand *mglParser::FindCommand(const wchar_t *com) const
 {
        size_t s = 15<mgl_wcslen(com)?15:mgl_wcslen(com);
        char cmd[16];   wcstombs(cmd,com,s+1);  cmd[s]=0;
@@ -117,17 +115,15 @@ int mglParser::Exec(mglGraph *gr, const wchar_t *com, long n, mglArg *a, const s
                k += id[a[i].type];
                size_t len = wcstombs(NULL,a[i].w.c_str(),0)+1;
                char *buf = new char[len];      memset(buf,0,len);
-               wcstombs(buf,a[i].w.c_str(),len);       
+               wcstombs(buf,a[i].w.c_str(),len);
                a[i].s = buf;   delete []buf;
        }
-       mglCommand *rts=FindCommand(com);
+       const mglCommand *rts=FindCommand(com);
        if(!rts || rts->type==6)        return 2;
        if(rts->type == 4)
        {
                if(n<1 || mgl_check_for_name(var))      return 2;
-               mglVar *v = AddVar(var.c_str());
-               v->Create(1,1,1);
-               a[0].type = 0;  a[0].d = v;
+               a[0].type = 0;  a[0].d = AddVar(var.c_str());
                a[0].w = var;   k[0] = 'd';
        }
        char *o=0;
@@ -142,26 +138,8 @@ int mglParser::Exec(mglGraph *gr, const wchar_t *com, long n, mglArg *a, const s
        return res;
 }
 //-----------------------------------------------------------------------------
-void mglNum::MoveAfter(mglNum *var)
-{
-       if(prev)        prev->next = next;
-       if(next)        next->prev = prev;
-       prev = next = 0;
-       if(var)
-       {       prev = var;     next = var->next;       var->next = this;       }
-       if(next)        next->prev = this;
-}
-//-----------------------------------------------------------------------------
-mglNum::~mglNum()
-{
-       if(prev)        prev->next = next;
-       if(next)        next->prev = prev;
-}
-//-----------------------------------------------------------------------------
 mglParser::mglParser(bool setsize)
 {
-       DataList=0;     NumList=0;
-//     wchar_t *par[40];       ///< Parameter for substituting instead of $1, ..., $9
        InUse = 1;
        Skip=Stop=for_br=false;
        memset(for_stack,0,40*sizeof(int));
@@ -184,16 +162,12 @@ mglParser::~mglParser()
 //-----------------------------------------------------------------------------
 void mglParser::DeleteAll()
 {
-       if(DataList)
-       {
-               while(DataList->next)   delete DataList->next;
-               delete DataList;        DataList = 0;
-       }
-       if(NumList)
-       {
-               while(NumList->next)    delete NumList->next;
-               delete NumList;         NumList = 0;
-       }
+       for(size_t i=0;i<DataList.size();i++)
+               if(DataList[i]) delete DataList[i];
+       DataList.clear();
+       for(size_t i=0;i<NumList.size();i++)
+               if(NumList[i])  delete NumList[i];
+       NumList.clear();
 }
 //-----------------------------------------------------------------------------
 void mglParser::AddParam(int n, const char *str)
@@ -208,17 +182,16 @@ int mglParser::Parse(mglGraph *gr, const char *str, long pos)
        return r;
 }
 //-----------------------------------------------------------------------------
-mglVar *mglParser::AddVar(const char *str)
+mglData *mglParser::AddVar(const char *str)
 {
-       mglVar *v=0;
+       mglData *v=0;
        MGL_TO_WCS(str,v = AddVar(wcs));
        return v;
 }
 //-----------------------------------------------------------------------------
-mglVar *mglParser::FindVar(const char *str)
+mglDataA *mglParser::FindVar(const char *str)
 {
-       if(!str || *str==0)     return DataList;
-       mglVar *v=DataList;
+       mglDataA *v=0;
        MGL_TO_WCS(str,v = FindVar(wcs));
        return v;
 }
@@ -243,50 +216,47 @@ void mglParser::AddParam(int n, const wchar_t *str)
        if(str && n>=0 && n<40) par[n] = str;
 }
 //-----------------------------------------------------------------------------
-mglVar *mglParser::FindVar(const wchar_t *name)
+mglDataA *mglParser::FindVar(const wchar_t *name)
 {
-       if(!name || *name==0)   return DataList;
-       mglVar *v=DataList;
-       while(v)
-       {
-               if(v->s==name)  return v;
-               v = v->next;
-       }
+       for(size_t i=0;i<DataList.size();i++)
+               if(DataList[i] && DataList[i]->s==name) return DataList[i];
        return 0;
 }
 //-----------------------------------------------------------------------------
-mglVar *mglParser::AddVar(const wchar_t *name)
-{
-       mglVar *v = FindVar(name);
-       if(v)   return v;
-       v = new mglVar; v->s = name;
-       if(DataList)    v->MoveAfter(DataList);
-       else                    DataList = v;
-       return v;
+mglData *mglParser::AddVar(const wchar_t *name)
+{      // TODO add list of forbidden names (like function names)
+       for(size_t i=0;i<DataList.size();i++)
+               if(DataList[i] && DataList[i]->s==name)
+               {
+                       delete (DataList[i]);
+                       mglData *d = new mglData;       d->s = name;
+                       DataList[i] = d;        return d;
+               }
+       mglData *d = new mglData;       d->s = name;
+       DataList.push_back(d);
+       return d;
 }
 //-----------------------------------------------------------------------------
 mglNum *mglParser::FindNum(const wchar_t *name)
 {
-       mglNum *v=NumList;
-       while(v)
-       {
-               if(v->s==name)  return v;
-               v = v->next;
-       }
+       for(size_t i=0;i<NumList.size();i++)
+               if(NumList[i] && NumList[i]->s==name)   return NumList[i];
        return 0;
 }
 //-----------------------------------------------------------------------------
 mglNum *mglParser::AddNum(const wchar_t *name)
 {
        mglNum *v = FindNum(name);
-       if(v)   return v;
-       v = new mglNum; v->s = name;
-       if(NumList)             v->MoveAfter(NumList);
-       else                    NumList = v;
+       if(!v)
+       {
+               mglNum *n=new mglNum;   n->s = name;
+               NumList.push_back(n);
+               v = NumList[NumList.size()-1];
+       }
        return v;
 }
 //-----------------------------------------------------------------------------
-int mglFindArg(const std::wstring &str)
+int MGL_LOCAL_PURE mglFindArg(const std::wstring &str)
 {
        register long l=0,k=0,i;
        for(i=0;i<long(str.length());i++)
@@ -304,13 +274,13 @@ int mglFindArg(const std::wstring &str)
 }
 //-----------------------------------------------------------------------------
 // convert substrings to arguments
-mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const mglVar *head);
+mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring string, mglParser *arg, const std::vector<mglDataA*> &head);
 void mglParser::FillArg(mglGraph *gr, int k, std::wstring *arg, mglArg *a)
 {
        register long n;
        for(n=1;n<k;n++)
        {
-               mglVar *v, *u;  mglNum *f;
+               mglDataA *v;    mglNum *f;
                a[n-1].type = -1;
                if(arg[n][0]=='|')      a[n-1].type = -1;
                else if(arg[n][0]=='\'')        // this is string (simplest case)
@@ -339,17 +309,16 @@ void mglParser::FillArg(mglGraph *gr, int k, std::wstring *arg, mglArg *a)
                }
                else if(arg[n][0]=='{')
                {       // this is temp data
-                       u=new mglVar;   u->temp=true;
+                       mglData *u=new mglData;
                        std::wstring s = arg[n].substr(1,arg[n].length()-2);
-                       a[n-1].w = L"/*"+s+L"*/";
-                       if(DataList)    u->MoveAfter(DataList);
-                       else                    DataList = u;
-                       a[n-1].type = 0;        a[n-1].d = u;
-                       ParseDat(gr, s, *u);
+                       a[n-1].w = u->s = L"/*"+s+L"*/";
+                       a[n-1].type = 0;
+                       ParseDat(gr, s, *u);    a[n-1].d = u;
+                       u->temp=true;   DataList.push_back(u);
                }
-               else if((v = FindVar(arg[n].c_str()))!=0)       // have to find normal variables (for data creation)
+               else if((v = FindVar(arg[n].c_str()))!=0)       // try to find normal variables (for data creation)
                {       a[n-1].type=0;  a[n-1].d=v;     a[n-1].w=v->s;  }
-               else if((f = FindNum(arg[n].c_str()))!=0)       // have to find normal variables (for data creation)
+               else if((f = FindNum(arg[n].c_str()))!=0)       // try to find normal number (for data creation)
                {       a[n-1].type=2;  a[n-1].d=0;     a[n-1].v=f->d;  a[n-1].w = f->s;        }
                else
                {       // parse all numbers and formulas by unified way
@@ -358,10 +327,9 @@ void mglParser::FillArg(mglGraph *gr, int k, std::wstring *arg, mglArg *a)
                        {       a[n-1].type = 2;        a[n-1].v = d.a[0];      }
                        else
                        {
-                               u=new mglVar;   u->temp=true;   u->Set(d);
+                               mglData *u=new mglData; u->Set(d);
                                a[n-1].w = L"/*"+arg[n]+L"*/";
-                               if(DataList)    u->MoveAfter(DataList);
-                               else                    DataList = u;
+                               u->temp=true;   DataList.push_back(u);
                                a[n-1].type = 0;        a[n-1].d = u;
                        }
                }
@@ -372,19 +340,15 @@ void mglParser::FillArg(mglGraph *gr, int k, std::wstring *arg, mglArg *a)
 int mglParser::PreExec(mglGraph *, long k, std::wstring *arg, mglArg *a)
 {
        long n=0;
-       mglVar *v;
        if(!arg[0].compare(L"delete") && k==2)  // parse command "delete"
-       {
-               DeleteVar(arg[1].c_str());      n=1;
-       }
+       {       DeleteVar(arg[1].c_str());      n=1;    }
        else if(!arg[0].compare(L"list"))       // parse command "list"
        {
                if(k<3 || mgl_check_for_name(arg[1]))   return 2;
                long nx=0, ny=1,j=0,i,t=0;
-               char ch;
                for(i=2;i<k;i++)
                {
-                       ch = arg[i][0];
+                       char ch = arg[i][0];
                        if(a[i-1].type==1)      return 2;
                        if(a[i-1].type==0)
                        {
@@ -398,7 +362,7 @@ int mglParser::PreExec(mglGraph *, long k, std::wstring *arg, mglArg *a)
                        }
                        if(ch=='|' && t==1)             {       nx = j>nx ? j:nx;       j=0;    ny++;   }
                }
-               v = AddVar(arg[1].c_str());
+               mglData *v = AddVar(arg[1].c_str());
                if(t==1)        nx = j>nx ? j:nx;
                if(t==1)        // list of numeric values
                {
@@ -413,7 +377,8 @@ int mglParser::PreExec(mglGraph *, long k, std::wstring *arg, mglArg *a)
                }
                if(t==2)        // list of data
                {
-                       mglData *b = a[1].d;
+                       mglData *b = dynamic_cast<mglData *>(a[1].d);
+                       if(!b)  return 1;
                        long nn = 0;
                        if(b->nz>1)     return 2;
                        if(b->ny>1)
@@ -422,10 +387,11 @@ int mglParser::PreExec(mglGraph *, long k, std::wstring *arg, mglArg *a)
                                nn = b->nx*b->ny;
                                for(i=2,j=0;i<k;i++)
                                {
-                                       b = a[i-1].d;
-                                       if(b==0 || nn!=b->nx*b->ny)     continue;
-                                       memcpy(v->a+j*nn,b->a,nn*(b->nz)*sizeof(mreal));
-                                       j+=b->nz;
+                                       if(nn!=a[i-1].d->GetNx()*a[i-1].d->GetNy())     continue;
+                                       b = dynamic_cast<mglData *>(a[i-1].d);
+                                       if(b)   memcpy(v->a+j*nn,b->a,nn*(b->nz)*sizeof(mreal));
+                                       else    for(long ii=0;ii<a[i-1].d->GetNN();ii++)        v->a[ii+j*nn] = a[i-1].d->vthr(ii);
+                                       j+=a[i-1].d->GetNz();
                                }
                        }
                        else
@@ -434,10 +400,12 @@ int mglParser::PreExec(mglGraph *, long k, std::wstring *arg, mglArg *a)
                                nn = b->nx;
                                for(i=2,j=0;i<k;i++)
                                {
-                                       b = a[i-1].d;
-                                       if(b==0 || nn!=b->nx)   continue;
-                                       memcpy(v->a+j*nn,b->a,nn*(b->ny)*sizeof(mreal));
-                                       j+=b->ny;
+                                       if(nn!=a[i-1].d->GetNx())       continue;
+                                       b = dynamic_cast<mglData *>(a[i-1].d);
+                                       long nny = a[i-1].d->GetNy();
+                                       if(b)   memcpy(v->a+j*nn,b->a,nn*nny*sizeof(mreal));
+                                       else    for(long ii=0;ii<nn*nny;ii++)   v->a[ii+j*nn] = a[i-1].d->vthr(ii);
+                                       j+=nny;
                                }
                        }
                }
@@ -513,11 +481,14 @@ int mglParser::ParseDef(std::wstring &str)
                int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1);
                if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10)
                {
-                       static wchar_t res[1024];
                        s = mgl_trim_ws(s.substr(2));
                        if(s[0]=='\'')  s=s.substr(1,s.length()-2);
                        if(mgl_ask_func)
-                       {       mgl_ask_func(s.c_str(),res);    if(*res)        AddParam(nn, res);      }
+                       {
+                               static wchar_t res[1024];
+                               mgl_ask_func(s.c_str(),res);
+                               if(*res)        AddParam(nn, res);
+                       }
                        return mgl_ask_func?1:2;
                }
                else    return 2;
@@ -533,10 +504,22 @@ int mglParser::ParseDef(std::wstring &str)
        return 0;
 }
 //-----------------------------------------------------------------------------
+/*void MGL_NO_EXPORT print_data(const char *s, std::vector<mglDataA*> h)
+{
+       printf("%s\ts=%lu:\n",s,h.size());
+       for(size_t i=0;i<h.size();i++)
+       {
+               printf("%lu - %p",i,h[i]);
+               if(h[i])        printf(",t%d,'%ls'",h[i]->temp, h[i]->s.c_str());
+               printf("\n");
+       }
+       fflush(stdout);
+}*/
+//-----------------------------------------------------------------------------
 // return values: 0 - OK, 1 - wrong arguments, 2 - wrong command, 3 - string too long, 4 -- unclosed string
 int mglParser::Parse(mglGraph *gr, std::wstring str, long pos)
 {
-       if(Stop)        return 0;
+       if(Stop || gr->NeedStop())      return 0;
        std::wstring arg[1024];
        str=mgl_trim_ws(str);
        long n,k=0,m=0,mm=0,res;
@@ -628,12 +611,11 @@ int mglParser::Parse(mglGraph *gr, std::wstring str, long pos)
                                        {
                                                register int i;
                                                mglParser *prs = new mglParser(AllowSetSize);
-                                               prs->DataList=DataList; prs->NumList=NumList;   prs->Cmd=Cmd;
+                                               prs->DataList.swap(DataList);   prs->NumList.swap(NumList);     prs->Cmd=Cmd;
                                                for(i=10;i<30;i++)      prs->AddParam(i,par[i].c_str());
                                                prs->Execute(gr,fp);
                                                for(i=10;i<30;i++)      AddParam(i,prs->par[i].c_str());
-                                               DataList=prs->DataList; prs->DataList=0;
-                                               NumList =prs->NumList;  prs->NumList=0;
+                                               DataList.swap(prs->DataList);   NumList.swap(prs->NumList);
                                                prs->Cmd=0;     delete prs;     fclose(fp);
                                        }
                                        else    n=1;
@@ -648,7 +630,7 @@ int mglParser::Parse(mglGraph *gr, std::wstring str, long pos)
                        int r = ch-'0';
                        if(ch>='a' && ch<='z')  r = 10+ch-'a';
 //                     int r = int(a[0].v);
-                       if(arg[1][1]==0 && (r>=0 && r<40))      // TODO: check this
+                       if(arg[1][1]==0 && (r>=0 && r<40))
                        {
                                if(a[1].type==0)
                                {
@@ -684,13 +666,9 @@ int mglParser::Parse(mglGraph *gr, std::wstring str, long pos)
                else    n = Exec(gr, arg[0].c_str(),k-1,a, arg[1].c_str(), opt.c_str());
                delete []a;
        }
-       mglVar *v = DataList, *u;
-       while(v)        // remove temporary data arrays
-       {
-               u = v->next;
-               if(v->temp)     {       if(DataList==v) DataList = v->next;             delete v;       }
-               v = u;
-       }
+       // delete temporary data arrays
+       for(size_t i=0;i<DataList.size();i++)   if(DataList[i] && DataList[i]->temp)
+       {       mglDataA *u=DataList[i];        DataList[i]=0;  delete u;       }
        return n;
 }
 //-----------------------------------------------------------------------------
@@ -709,7 +687,7 @@ int mglParser::ParseDat(mglGraph *gr, std::wstring str, mglData &res)
        }
        // try to find last argument
        if(!str.empty())        {       arg[k] = str;   k++;    }
-       if(k<1) n =0;
+       if(k<1) n = 0;
        else
        {       // fill arguments by its values
                mglArg *a = new mglArg[k+1];
@@ -723,7 +701,7 @@ int mglParser::ParseDat(mglGraph *gr, std::wstring str, mglData &res)
                        kk += id[a[i].type];
                        a[i].s.assign(a[i].w.begin(),a[i].w.end());
                }
-               mglCommand *rts=FindCommand(arg[0].c_str());
+               const mglCommand *rts=FindCommand(arg[0].c_str());
                if(!rts || rts->type!=4)        n = 2;
                else n = rts->exec(gr, k, a, kk.c_str(), 0);
                delete []a;
@@ -847,15 +825,15 @@ void mglParser::Execute(mglGraph *gr, FILE *fp, bool print)
 void mglParser::Execute(mglGraph *gr, int n, const wchar_t **text)
 {
        if(n<1 || text==0)      return;
-       long i, r, res=0;
+       long res=0;
        char buf[64];
        for_br=Skip=false;      if_pos=0;       ScanFunc(0);    fn_stack.clear();
-       for(i=0;i<n;i++)        ScanFunc(text[i]);
-       for(i=0;i<n;i++)
+       for(long i=0;i<n;i++)   ScanFunc(text[i]);
+       for(long i=0;i<n;i++)
        {
                gr->SetWarn(-1, "");
                gr->SetObjId(i+1);
-               r = Parse(gr,text[i],i+1);
+               long r = Parse(gr,text[i],i+1);
                if(r<0) {       i = -r-2;       continue;       }
                if(r==1)                snprintf(buf,64,"\nWrong argument(s) in line %ld\n", i+1);
                else if(r==2)   snprintf(buf,64,"\nWrong command in line %ld\n", i+1);
@@ -889,11 +867,10 @@ void mglParser::Execute(mglGraph *gr, const wchar_t *text)
                {       // if string need to be continued then I but ' ' instead of 0x0 and
                        // pointer next string to 0x0. Last one for keeping number of strings.
                        if(next)
-                       {       wcs[i]=wcs[next]=' ';   str[n] = wcs+s-1;       next=0; }
+                       {       for(size_t ii=next;ii<=i;ii++)  wcs[ii]='\b';   str[n] = wcs+s-1;       next=0; }
                        else
                        {       wcs[i]=0;       str[n] = wcs+i+1;       }
                        n++;
-
                }
        }
        Execute(gr, n, str);
@@ -902,26 +879,18 @@ void mglParser::Execute(mglGraph *gr, const wchar_t *text)
 //-----------------------------------------------------------------------------
 void mglParser::Execute(mglGraph *gr, const char *text)
 {
-       MGL_TO_WCS(text,        Execute(gr, wcs));
-}
-//-----------------------------------------------------------------------------
-void mglParser::DeleteVar(mglVar *v)
-{
-       if(!v)  return;
-       if(DataList==v) DataList = v->next;
-       delete v;
+       MGL_TO_WCS(text, Execute(gr, wcs));
 }
 //-----------------------------------------------------------------------------
 void mglParser::DeleteVar(const char *name)
 {
-       mglVar *v = FindVar(name);
-       DeleteVar(v);
+       MGL_TO_WCS(name,DeleteVar(wcs));
 }
 //-----------------------------------------------------------------------------
 void mglParser::DeleteVar(const wchar_t *name)
 {
-       mglVar *v = FindVar(name);
-       DeleteVar(v);
+       for(size_t i=0;i<DataList.size();i++)   if(DataList[i] && DataList[i]->s==name)
+       {       mglDataA *u=DataList[i];        DataList[i]=0;  delete u;       }
 }
 //-----------------------------------------------------------------------------
 void mglParser::AddCommand(mglCommand *cmd, int mc)
@@ -935,19 +904,19 @@ void mglParser::AddCommand(mglCommand *cmd, int mc)
        memcpy(buf, cmd, mc*sizeof(mglCommand));
        memcpy(buf+mc, Cmd, (mp+1)*sizeof(mglCommand));
        qsort(buf, mp+mc, sizeof(mglCommand), mgl_cmd_cmp);
-       if(Cmd!=mgls_base_cmd)   delete []Cmd;
-       Cmd = buf;
+#pragma omp critical(cmd_parser)
+       {       if(Cmd!=mgls_base_cmd)   delete []Cmd;  Cmd = buf;      }
 }
 //-----------------------------------------------------------------------------
 HMPR MGL_EXPORT mgl_create_parser()            {       return new mglParser;   }
 void MGL_EXPORT mgl_delete_parser(HMPR p)      {       delete p;       }
 void MGL_EXPORT mgl_parser_add_param(HMPR p, int id, const char *str)                  {       p->AddParam(id,str);    }
 void MGL_EXPORT mgl_parser_add_paramw(HMPR p, int id, const wchar_t *str)              {       p->AddParam(id,str);    }
-HMDT MGL_EXPORT mgl_parser_add_var(HMPR p, const char *name)   {       mglVar *v=p->AddVar(name);      return v;       }
-HMDT MGL_EXPORT mgl_parser_find_var(HMPR p, const char *name)  {       mglVar *v=p->FindVar(name);     return v;       }
+HMDT MGL_EXPORT mgl_parser_add_var(HMPR p, const char *name)   {       return p->AddVar(name); }
+MGL_EXPORT_PURE mglDataA *mgl_parser_find_var(HMPR p, const char *name)        {       return p->FindVar(name);}
 void MGL_EXPORT mgl_parser_del_var(HMPR p, const char *name)   {       p->DeleteVar(name);     }
-HMDT MGL_EXPORT mgl_parser_add_varw(HMPR p, const wchar_t *name)       {       mglVar *v=p->AddVar(name);      return v;       }
-HMDT MGL_EXPORT mgl_parser_find_varw(HMPR p, const wchar_t *name)      {       mglVar *v=p->FindVar(name);     return v;       }
+HMDT MGL_EXPORT mgl_parser_add_varw(HMPR p, const wchar_t *name)       {       return p->AddVar(name); }
+MGL_EXPORT_PURE mglDataA *mgl_parser_find_varw(HMPR p, const wchar_t *name)    {       return p->FindVar(name);}
 void MGL_EXPORT mgl_parser_del_varw(HMPR p, const wchar_t *name)       {       p->DeleteVar(name);     }
 int MGL_EXPORT mgl_parse_line(HMGL gr, HMPR p, const char *str, int pos)
 {      return p->Parse(gr, str, pos);  }
@@ -973,11 +942,11 @@ void MGL_EXPORT mgl_parser_add_param_(uintptr_t* p, int *id, const char *str, in
 /*===!!! NOTE !!! You must not delete obtained data arrays !!!===============*/
 uintptr_t MGL_EXPORT mgl_parser_add_var_(uintptr_t* p, const char *name, int l)
 {      char *s=new char[l+1];          memcpy(s,name,l);       s[l]=0;
-       mglVar *v=_PR_->AddVar(s);      delete []s;     return uintptr_t(v);    }
+       mglData *v=_PR_->AddVar(s);     delete []s;     return uintptr_t(v);    }
 /*===!!! NOTE !!! You must not delete obtained data arrays !!!===============*/
-uintptr_t MGL_EXPORT mgl_parser_find_var_(uintptr_t* p, const char *name, int l)
+uintptr_t MGL_EXPORT_PURE mgl_parser_find_var_(uintptr_t* p, const char *name, int l)
 {      char *s=new char[l+1];          memcpy(s,name,l);       s[l]=0;
-       mglVar *v=_PR_->FindVar(s);     delete []s;     return uintptr_t(v);    }
+       mglDataA *v=_PR_->FindVar(s);   delete []s;     return uintptr_t(v);    }
 void MGL_EXPORT mgl_parser_del_var_(uintptr_t* p, const char *name, int l)
 {      char *s=new char[l+1];          memcpy(s,name,l);       s[l]=0;
        _PR_->DeleteVar(s);     delete []s;     }
@@ -997,29 +966,38 @@ long MGL_EXPORT mgl_use_parser(HMPR pr, int inc)
 long MGL_EXPORT mgl_use_parser_(uintptr_t *p, int *inc)
 {      _PR_->InUse+=*inc;      return _PR_->InUse;     }
 //---------------------------------------------------------------------------
-int MGL_EXPORT mgl_parser_cmd_type(HMPR pr, const char *name)
+MGL_EXPORT_PURE mglDataA *mgl_parser_get_var(HMPR p, unsigned long id)
+{      return id<p->DataList.size()?p->DataList[id]:0; }
+uintptr_t MGL_EXPORT_PURE mgl_parser_get_var_(uintptr_t* p, unsigned long *id)
+{      return uintptr_t(mgl_parser_get_var(_PR_,*id)); }
+long MGL_EXPORT_PURE mgl_parser_num_var(HMPR p)
+{      return p->DataList.size();      }
+long MGL_EXPORT_PURE mgl_parser_num_var_(uintptr_t* p)
+{      return mgl_parser_num_var(_PR_);        }
+//---------------------------------------------------------------------------
+int MGL_EXPORT_PURE mgl_parser_cmd_type(HMPR pr, const char *name)
 {
-       mglCommand *cmd = pr->FindCommand(name);
+       const mglCommand *cmd = pr->FindCommand(name);
        return cmd ? cmd->type + 1 : 0;
 }
-int MGL_EXPORT mgl_parser_cmd_type_(uintptr_t* p, const char *str, int l)
+int MGL_EXPORT_PURE mgl_parser_cmd_type_(uintptr_t* p, const char *str, int l)
 {      char *s=new char[l+1];  memcpy(s,str,l);        s[l]=0;
        l = mgl_parser_cmd_type(_PR_, s);       delete []s;     return l;       }
 //---------------------------------------------------------------------------
-MGL_EXPORT const char *mgl_parser_cmd_desc(HMPR pr, const char *name)
+MGL_EXPORT_PURE const char *mgl_parser_cmd_desc(HMPR pr, const char *name)
 {
-       mglCommand *cmd = pr->FindCommand(name);
+       const mglCommand *cmd = pr->FindCommand(name);
        return cmd ? cmd->desc : 0;
 }
-MGL_EXPORT const char *mgl_parser_cmd_frmt(HMPR pr, const char *name)
+MGL_EXPORT_PURE const char *mgl_parser_cmd_frmt(HMPR pr, const char *name)
 {
-       mglCommand *cmd = pr->FindCommand(name);
+       const mglCommand *cmd = pr->FindCommand(name);
        return cmd ? cmd->form : 0;
 }
 //---------------------------------------------------------------------------
-MGL_EXPORT const char *mgl_parser_cmd_name(HMPR pr, long id)
+MGL_EXPORT_PURE const char *mgl_parser_cmd_name(HMPR pr, long id)
 {      return (id<mgl_parser_cmd_num(pr) && id>=0) ? pr->Cmd[id].name:"";      }
-long MGL_EXPORT mgl_parser_cmd_num(HMPR pr)
+long MGL_EXPORT_PURE mgl_parser_cmd_num(HMPR pr)
 {      register long i=0;      while(pr->Cmd[i].name[0])       i++;    return i;       }
 //---------------------------------------------------------------------------
 HMDT MGL_EXPORT mgl_parser_calc(HMPR pr, const char *formula)
index 6dc1b2ceb3cb3178da6b7f9cfd09aeab64e23ab1..a1dd08840d8db0b26d665f42cff6c64d1e992a42 100644 (file)
 #include "mgl2/eval.h"\r
 #include "mgl2/thread.h"\r
 #include "mgl2/base.h"\r
-#define GAMMA  0.1\r
+const double GAMMA=0.1;        ///< value for damping\r
+mglData MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector<mglDataA*> &head);\r
+mglDataC MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector<mglDataA*> &head);\r
 //-----------------------------------------------------------------------------\r
 struct mgl_pde_ham\r
 {\r
-       dual *a,*hxy,*hxv,*huv,*huy;\r
-       mglFormula *eqs;\r
+       ddual *a,*hxy,*hxv,*huv,*huy;\r
+       const char *eqs;\r
        long nx,ny;\r
-       mreal xx,yy,xs,ys,dx,dy,dq,dp,zz;\r
+       double xx,yy,xs,ys,dx,dy,dq,dp,zz;\r
        double dd;\r
 };\r
-MGL_NO_EXPORT void *mgl_pde_hprep(void *par)\r
+void MGL_NO_EXPORT mgl_pde_hprep(const mgl_pde_ham *f)\r
 {\r
-       mglThreadD *t=(mglThreadD *)par;\r
-       const mgl_pde_ham *f = (const mgl_pde_ham *)t->v;\r
-       mglFormula *eqs = f->eqs;\r
-       long nx=2*f->nx, ny=2*f->ny;\r
-       dual *a = f->a;\r
+       long nx = f->nx, ny = f->ny;\r
+       mglDataV x(nx,ny), y(nx,ny), z, r(nx,ny);\r
+       mglDataW p(nx,ny), q(nx,ny);\r
+       x.s = L"x";     y.s = L"y";     p.s = L"p";     q.s = L"q";     r.s=L"#$mgl";\r
+       z.s = L"z";     z.Fill(f->zz);\r
+       dual dd(0,f->dd);\r
+       mglData u(nx,ny);       u.s = L"u";\r
+#pragma omp parallel for\r
+       for(long i=0;i<nx*ny;i++)       u.a[i] = abs(f->a[i]);\r
+       std::vector<mglDataA*> list;\r
+       list.push_back(&x);     list.push_back(&y);     list.push_back(&z);\r
+       list.push_back(&p);     list.push_back(&q);     list.push_back(&u);\r
 \r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel\r
-#endif\r
+       x.Fill(f->xx,f->xx+f->dx*(nx-1),'x');   p.Freq(0,'x');\r
+       y.Fill(f->yy,f->yy+f->dy*(ny-1),'y');   q.Freq(0,'y');\r
+       mglDataC res = mglFormulaCalcC(f->eqs, list);\r
+#pragma omp parallel for\r
+       for(long i=0;i<nx*ny;i++)       f->hxy[i] = res.a[i]*dd;\r
+       if(ny>2)\r
        {\r
-               mreal var[MGL_VS];      memset(var,0,MGL_VS*sizeof(mreal));\r
-               var['z'-'a'] = f->zz;\r
-#pragma omp for nowait\r
-               for(long i0=t->id;i0<t->n;i0+=mglNumThr)\r
-               {\r
-                       register long i = i0%nx, j = i0/nx;             var['u'-'a'] = abs(a[i0]);\r
-                       var['x'-'a'] = f->xx+f->dx*i;   var['p'-'a'] = 0;\r
-                       var['y'-'a'] = f->yy+f->dy*j;   var['q'-'a'] = 0;\r
-                       f->hxy[i0] = dual(-eqs->CalcD(var,'i'), eqs->Calc(var))*f->dd;\r
-               }\r
-               if(f->ny>2)\r
-#pragma omp for nowait\r
-                       for(long i0=t->id;i0<t->n;i0+=mglNumThr)        // step 3/2\r
-                       {\r
-                               register long i = i0%nx, j = i0/nx;             var['u'-'a'] = abs(a[i0]);\r
-                               var['x'-'a'] = f->xs;                   var['p'-'a'] = f->dp*(i<nx/2 ? i:nx-i);\r
-                               var['y'-'a'] = f->yy+f->dy*j;   var['q'-'a'] = 0;\r
-                               f->huy[i0] = dual(-eqs->CalcD(var,'i'), eqs->Calc(var))*f->dd;\r
-                       }\r
-#pragma omp for nowait\r
-               for(long i0=t->id;i0<t->n;i0+=mglNumThr)        // step 2\r
-               {\r
-                       register long i = i0%nx, j = i0/nx;             var['u'-'a'] = abs(a[i0]);\r
-                       var['x'-'a'] = f->xs;                   var['p'-'a'] = f->dp*(i<nx/2 ? i:nx-i);\r
-                       var['y'-'a'] = f->ys;                   var['q'-'a'] = f->dq*(j<ny/2 ? j:ny-j);\r
-                       f->huv[i0] = dual(-eqs->CalcD(var,'i'), eqs->Calc(var))*f->dd;\r
-               }\r
-               if(f->ny>2)\r
-#pragma omp for nowait\r
-                       for(long i0=t->id;i0<t->n;i0+=mglNumThr)        // step 3/2\r
-                       {\r
-                               register long i = i0%nx, j = i0/nx;             var['u'-'a'] = abs(a[i0]);\r
-                               var['x'-'a'] = f->xx+f->dx*i;   var['p'-'a'] = 0;\r
-                               var['y'-'a'] = f->ys;                   var['q'-'a'] = f->dq*(j<ny/2 ? j:ny-j);\r
-                               f->hxv[i0] = dual(-eqs->CalcD(var,'i'), eqs->Calc(var))*f->dd;\r
-                       }\r
+               x.Fill(f->xs);  p.Freq(f->dp,'x');\r
+               res = mglFormulaCalcC(f->eqs, list);\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx*ny;i++)       f->huy[i] = res.a[i]*dd;\r
+       }\r
+       x.Fill(f->xs);  p.Freq(f->dp,'x');\r
+       y.Fill(f->ys);  q.Freq(f->dq,'y');\r
+       res = mglFormulaCalcC(f->eqs, list);\r
+#pragma omp parallel for\r
+       for(long i=0;i<nx*ny;i++)       f->huv[i] = res.a[i]*dd;\r
+       if(ny>2)\r
+       {\r
+               x.Fill(f->xx,f->xx+f->dx*(nx-1),'x');   p.Freq(0,'x');\r
+               res = mglFormulaCalcC(f->eqs, list);\r
+#pragma omp parallel for\r
+               for(long i=0;i<nx*ny;i++)       f->hxv[i] = res.a[i]*dd;\r
        }\r
-       return 0;\r
 }\r
 //-----------------------------------------------------------------------------\r
 // Solve equation dx/dz = func(p,q,x,y,z,|u|)[u] where p=d/dx, q=d/dy. At this moment simplified form of ham is supported: ham = f(p,q,z) + g(x,y,z,'u'), where variable 'u'=|u| (for allowing solve nonlinear problems). You may specify imaginary part like ham = p^2 + i*x*(x>0) but only if dependence on variable 'i' is linear (i.e. ham = hre+i*him).\r
@@ -96,15 +87,14 @@ HADT MGL_EXPORT mgl_pde_solve_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_
        {       gr->SetWarn(mglWarnDim,"PDE");  return 0;       }\r
        mglDataC *res=new mglDataC(nz, nx, ny);\r
 \r
-       mglFormula eqs(ham);\r
-       dual *a = new dual[4*nx*ny], hh0;       // Add "damping" area\r
-       dual *hxy = new dual[4*nx*ny], *hxv = new dual[4*nx*ny];\r
-       dual *huy = new dual[4*nx*ny], *huv = new dual[4*nx*ny];\r
-       dual *hx = new dual[2*nx], *hv = new dual[2*ny];\r
-       dual *hy = new dual[2*ny], *hu = new dual[2*nx];\r
-       mreal *dmp = new mreal[4*nx*ny];\r
-       memset(a,0,4*nx*ny*sizeof(dual));\r
-       memset(dmp,0,4*nx*ny*sizeof(mreal));\r
+       ddual *a = new ddual[4*nx*ny], hh0;     // Add "damping" area\r
+       ddual *hxy = new ddual[4*nx*ny], *hxv = new ddual[4*nx*ny];\r
+       ddual *huy = new ddual[4*nx*ny], *huv = new ddual[4*nx*ny];\r
+       ddual *hx = new ddual[2*nx], *hv = new ddual[2*ny];\r
+       ddual *hy = new ddual[2*ny], *hu = new ddual[2*nx];\r
+       double *dmp = new double[4*nx*ny];\r
+       memset(a,0,4*nx*ny*sizeof(ddual));\r
+       memset(dmp,0,4*nx*ny*sizeof(double));\r
 #pragma omp parallel for collapse(2)\r
        for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)  // Initial conditions\r
        {\r
@@ -124,11 +114,10 @@ HADT MGL_EXPORT mgl_pde_solve_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_
        mreal dx = (Max.x-Min.x)/(nx-1), dy = ny>1?(Max.y-Min.y)/(ny-1):0;\r
        mreal dp = M_PI/(Max.x-Min.x)/k0, dq = M_PI/(Max.y-Min.y)/k0;\r
        mreal xs=(Min.x+Max.x)/2, ys=(Min.y+Max.y)/2;\r
-//     double xx = Min.x - dx*nx/2, yy = Min.x - dy*ny/2;\r
        double dd = k0*dz;\r
 \r
-       mgl_pde_ham tmp;tmp.eqs = &eqs;\r
-       tmp.nx = nx;    tmp.ny = ny;    tmp.dd = dd;    tmp.a=a;\r
+       mgl_pde_ham tmp;tmp.eqs = ham;\r
+       tmp.nx = 2*nx;  tmp.ny = 2*ny;  tmp.dd = dd;    tmp.a=a;\r
        tmp.hxy=hxy;    tmp.hxv=hxv;    tmp.huy=huy;    tmp.huv=huv;\r
        tmp.xx = Min.x-dx*(nx/2);       tmp.xs = xs;    tmp.dx = dx;    tmp.dp = dp;\r
        tmp.yy = Min.y-dy*(ny/2);       tmp.ys = ys;    tmp.dy = dy;    tmp.dq = dq;\r
@@ -138,14 +127,12 @@ HADT MGL_EXPORT mgl_pde_solve_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_
        void *wty = mgl_fft_alloc(2*ny,0,0);\r
        for(long k=1;k<nz;k++)\r
        {\r
-               if(gr->Stop)    continue;\r
+               if(gr->NeedStop())      break;\r
                tmp.zz = Min.z+dz*k;\r
                memset(hxy,0,4*nx*ny*sizeof(dual));     memset(hxv,0,4*nx*ny*sizeof(dual));\r
                memset(huv,0,4*nx*ny*sizeof(dual));     memset(huy,0,4*nx*ny*sizeof(dual));\r
-               mglStartThread(mgl_pde_hprep,0,4*nx*ny,0,0,0,0,&tmp);\r
-#pragma omp parallel for\r
+               mgl_pde_hprep(&tmp);\r
                for(long i=0;i<2*nx;i++)        {       hx[i] = hxv[i];                 hu[i] = huv[i];         }\r
-#pragma omp parallel for\r
                for(long j=0;j<2*ny;j++)        {       hy[j] = huy[2*nx*j];    hv[j] = huv[2*nx*j];}\r
                // rearrange arrays\r
                hh0=hu[0];\r
@@ -215,10 +202,46 @@ HMDT MGL_EXPORT mgl_pde_solve(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im
        HMDT out = mgl_datac_abs(res);  delete res;     return out;\r
 }\r
 //-----------------------------------------------------------------------------\r
-HMDT MGL_EXPORT mgl_ode_solve(void (*func)(const mreal *x, mreal *dx, void *par), int n, mreal *x0, mreal dt, mreal tmax, void *par)\r
+struct mglOdeTxt       {       long n; HMEX *eq;       const char *var;        };\r
+void MGL_NO_EXPORT mgl_txt_func(const mreal *x, mreal *dx, void *par)\r
+{\r
+       mglOdeTxt *p=(mglOdeTxt *)par;\r
+       mreal vars['z'-'a'+1];\r
+       for(long i=0;i<p->n;i++)\r
+       {       char ch = p->var[i];    if(ch>='a' && ch<='z')  vars[ch-'a']=x[i];      }\r
+#pragma omp parallel for\r
+       for(long i=0;i<p->n;i++)\r
+               dx[i] = mgl_expr_eval_v(p->eq[i], vars);\r
+}\r
+HMDT MGL_EXPORT mgl_ode_solve_str(const char *func, const char *var, HCDT x0, mreal dt, mreal tmax)\r
+{\r
+       if(!var || !(*var) || !func)    return 0;\r
+       long len = strlen(func);\r
+       mglOdeTxt par;  par.var=var;\r
+       par.n = strlen(var);\r
+       par.eq = new HMEX[par.n];\r
+       char *buf = new char[len+1], *f=buf, *g=f;      memcpy(buf,func,len+1);\r
+       mreal *xx = new mreal[par.n];\r
+       for(long i=0;i<par.n;i++)\r
+       {\r
+               xx[i] = x0?x0->vthr(i):0;\r
+               for(long k=0;f[k];k++)  if(f[k]==';')\r
+               { g = f+k+1;    f[k]=0; break;  }\r
+               if(f==g)        g = f+strlen(f);\r
+               par.eq[i] = mgl_create_expr(f);\r
+               f = g;\r
+       }\r
+       HMDT res = mgl_ode_solve_ex(mgl_txt_func,par.n,xx,dt,tmax,&par,NULL);\r
+       for(long i=0;i<par.n;i++)       mgl_delete_expr(par.eq[i]);\r
+       delete []par.eq;        delete []buf;   delete []xx;\r
+       return res;\r
+}\r
+HMDT MGL_EXPORT mgl_ode_solve(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par)\r
+{      return mgl_ode_solve_ex(func,n,x0,dt,tmax,par,0);       }\r
+HMDT MGL_EXPORT mgl_ode_solve_ex(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par, void (*bord)(mreal *x, const mreal *xp, void *par))\r
 {\r
        if(tmax<dt)     return 0;       // nothing to do\r
-       int nt = int(tmax/dt)+1;\r
+       int nt = int(tmax/dt+0.5)+1;\r
        mglData *res=new mglData(n,nt);\r
        mreal *x=new mreal[n], *k1=new mreal[n], *k2=new mreal[n], *k3=new mreal[n], *v=new mreal[n], hh=dt/2;\r
        register long i,k;\r
@@ -234,7 +257,9 @@ HMDT MGL_EXPORT mgl_ode_solve(void (*func)(const mreal *x, mreal *dx, void *par)
                func(v,k3,par);\r
                for(i=0;i<n;i++)        {       v[i] = x[i]+k3[i]*dt;   k3[i] += k2[i]; }\r
                func(v,k2,par);\r
-               for(i=0;i<n;i++)        res->a[i+n*k] = x[i] += (k1[i]+k2[i]+2*k3[i])*dt/6;\r
+               for(i=0;i<n;i++)        x[i] += (k1[i]+k2[i]+2*k3[i])*dt/6;\r
+               if(bord)        bord(x,res->a+n*(k-1),par);\r
+               for(i=0;i<n;i++)        res->a[i+n*k] = x[i];\r
        }\r
        delete []x;     delete []k1;    delete []k2;    delete []k3;    delete []v;\r
        return res;\r
@@ -326,11 +351,11 @@ void MGL_NO_EXPORT mgl_init_ra(int n, int n7, const mreal *r, mgl_ap *ra) // pre
 //-----------------------------------------------------------------------------\r
 struct mgl_qo2d_ham\r
 {\r
-       dual *hx, *hu, *a, h0;\r
-       double *dmp;\r
-       mreal *r, dr, dk;\r
+       ddual *hx, *hu, *a, h0;\r
+       double *dmp, dr, dk;\r
+       mreal *r;\r
        mgl_ap *ra;\r
-       dual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par);\r
+       ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par);\r
        void *par;\r
 };\r
 //-----------------------------------------------------------------------------\r
@@ -364,7 +389,7 @@ MGL_NO_EXPORT void *mgl_qo2d_hprep(void *par)
        return 0;\r
 }\r
 //-----------------------------------------------------------------------------\r
-HADT MGL_EXPORT mgl_qo2d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy)\r
+HADT MGL_EXPORT mgl_qo2d_func_c(ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy)\r
 {\r
        const mglData *ray=dynamic_cast<const mglData *>(ray_dat);      // NOTE: Ray must be mglData!\r
        if(!ray)        return 0;\r
@@ -372,19 +397,17 @@ HADT MGL_EXPORT mgl_qo2d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal px,
        if(nx<2 || ini_im->GetNx()!=nx || nt<2) return 0;\r
        mglDataC *res=new mglDataC(nx,nt,1);\r
 \r
-       dual *a=new dual[2*nx], *hu=new dual[2*nx],  *hx=new dual[2*nx];\r
+       ddual *a=new ddual[2*nx], *hu=new ddual[2*nx],  *hx=new ddual[2*nx];\r
        double *dmp=new double[2*nx];\r
        mgl_ap *ra = new mgl_ap[nt];    mgl_init_ra(nt, n7, ray->a, ra);        // ray\r
 \r
        mreal dr = r/(nx-1), dk = M_PI*(nx-1)/(k0*r*nx);\r
        memset(dmp,0,2*nx*sizeof(double));\r
-#pragma omp parallel for\r
        for(long i=0;i<nx/2;i++)        // prepare damping\r
        {\r
                register mreal x1 = (nx/2-i)/(nx/2.);\r
                dmp[2*nx-1-i] = dmp[i] = 30*GAMMA*x1*x1/k0;\r
        }\r
-#pragma omp parallel for\r
        for(long i=0;i<nx;i++)  a[i+nx/2] = dual(ini_re->v(i),ini_im->v(i));    // init\r
        void *wsx, *wtx = mgl_fft_alloc(2*nx,&wsx,1);\r
        if(xx && yy)    {       xx->Create(nx,nt);      yy->Create(nx,nt);      }\r
@@ -395,27 +418,22 @@ HADT MGL_EXPORT mgl_qo2d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal px,
        // start calculation\r
        for(long k=0;k<nt;k++)\r
        {\r
-#pragma omp parallel for\r
                for(long i=0;i<nx;i++)  // "save"\r
                        res->a[i+k*nx]=a[i+nx/2]*sqrt(ra[0].ch/ra[k].ch);\r
-               if(xx && yy)\r
-#pragma omp parallel for\r
-                       for(long i=0;i<nx;i++)  // prepare xx, yy\r
-                       {\r
-                               register mreal x1 = (2*i-nx+1)*dr;\r
-                               xx->a[i+k*nx] = ray->a[n7*k] + ra[k].x1*x1;     // new coordinates\r
-                               yy->a[i+k*nx] = ray->a[n7*k+1] + ra[k].y1*x1;\r
-                       }\r
+               if(xx && yy)    for(long i=0;i<nx;i++)  // prepare xx, yy\r
+               {\r
+                       register mreal x1 = (2*i-nx+1)*dr;\r
+                       xx->a[i+k*nx] = ray->a[n7*k] + ra[k].x1*x1;     // new coordinates\r
+                       yy->a[i+k*nx] = ray->a[n7*k+1] + ra[k].y1*x1;\r
+               }\r
                tmp.r=ray->a+n7*k;      tmp.ra=ra+k;\r
                mreal hh = ra[k].pt*(1/sqrt(sqrt(1.041))-1);    // 0.041=0.45^4 -- minimal value of h\r
                tmp.h0 = ham(0, tmp.r[0], tmp.r[1], tmp.r[3]+ra[k].x0*hh, tmp.r[4]+ra[k].x0*hh, par);\r
                mglStartThread(mgl_qo2d_hprep,0,2*nx,0,0,0,0,&tmp);\r
                // Step for field\r
-               dual dt = dual(0, -ra[k].dt*k0);\r
-#pragma omp parallel for\r
+               ddual dt = ddual(0, -ra[k].dt*k0);\r
                for(long i=0;i<2*nx;i++)        a[i] *= exp(hx[i]*dt);\r
                mgl_fft((double *)a, 1, 2*nx, wtx, wsx, false);\r
-#pragma omp parallel for\r
                for(long i=0;i<2*nx;i++)        a[i] *= exp(hu[i]*dt);\r
                mgl_fft((double *)a, 1, 2*nx, wtx, wsx, true);\r
 \r
@@ -447,19 +465,19 @@ HADT MGL_EXPORT mgl_qo2d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal px,
        return res;\r
 }\r
 //-----------------------------------------------------------------------------\r
-HMDT MGL_EXPORT mgl_qo2d_func(dual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy)\r
+HMDT MGL_EXPORT mgl_qo2d_func(ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy)\r
 {\r
        HADT res = mgl_qo2d_func_c(ham,par,ini_re,ini_im,ray_dat,r,k0,xx,yy);\r
        HMDT out = mgl_datac_abs(res);  delete res;     return out;\r
 }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_NO_EXPORT mgl_ham2d(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)\r
+ddual MGL_NO_EXPORT mgl_ham2d(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)\r
 {\r
        mglFormula *h = (mglFormula *)par;\r
        mreal var[MGL_VS];      memset(var,0,MGL_VS*sizeof(mreal));\r
        var['x'-'a'] = x;       var['y'-'a'] = y;       var['u'-'a'] = u;\r
        var['p'-'a'] = px;      var['q'-'a'] = py;\r
-       return dual(h->Calc(var), -h->CalcD(var,'i'));\r
+       return ddual(h->Calc(var), -h->CalcD(var,'i'));\r
 }\r
 //-----------------------------------------------------------------------------\r
 HADT MGL_EXPORT mgl_qo2d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy)\r
@@ -480,12 +498,12 @@ HMDT MGL_EXPORT mgl_qo2d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT r
 //-----------------------------------------------------------------------------\r
 struct mgl_qo3d_ham\r
 {\r
-       dual *hxy, *huv, *hxv, *huy, *a;\r
-       dual *hx, *hy, *hu, *hv, h0;\r
-       mreal *dmp;\r
-       mreal *r, dr, dk;\r
+       ddual *hxy, *huv, *hxv, *huy, *a;\r
+       ddual *hx, *hy, *hu, *hv, h0;\r
+       double *dmp, dr, dk;\r
+       mreal *r;\r
        mgl_ap *ra;\r
-       dual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par);\r
+       ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par);\r
        void *par;\r
 };\r
 //-----------------------------------------------------------------------------\r
@@ -549,7 +567,7 @@ MGL_NO_EXPORT void *mgl_qo3d_post(void *par)
        return 0;\r
 }\r
 //-----------------------------------------------------------------------------\r
-HADT MGL_EXPORT mgl_qo3d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz)\r
+HADT MGL_EXPORT mgl_qo3d_func_c(ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz)\r
 {\r
        const mglData *ray=dynamic_cast<const mglData *>(ray_dat);      // NOTE: Ray must be mglData!\r
        if(!ray)        return 0;\r
@@ -557,18 +575,18 @@ HADT MGL_EXPORT mgl_qo3d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal z,
        if(nx<2 || ini_re->GetNx()!=nx || ini_im->GetNx()*ini_im->GetNy()!=nx*nx || nt<2)       return 0;\r
        mglDataC *res=new mglDataC(nx,nx,nt);\r
 \r
-       dual *a=new dual[4*nx*nx], *huv=new dual[4*nx*nx],  *hxy=new dual[4*nx*nx], *huy=new dual[4*nx*nx],  *hxv=new dual[4*nx*nx];\r
-       dual *hu=new dual[2*nx],  *hx=new dual[2*nx], *hy=new dual[2*nx],  *hv=new dual[2*nx];\r
-       mreal *dmp=new mreal[4*nx*nx];\r
+       ddual *a=new ddual[4*nx*nx], *huv=new ddual[4*nx*nx],  *hxy=new ddual[4*nx*nx], *huy=new ddual[4*nx*nx],  *hxv=new ddual[4*nx*nx];\r
+       ddual *hu=new ddual[2*nx],  *hx=new ddual[2*nx], *hy=new ddual[2*nx],  *hv=new ddual[2*nx];\r
+       double *dmp=new double[4*nx*nx];\r
        mgl_ap *ra = new mgl_ap[nt];\r
        mgl_init_ra(nt, n7, ray->a, ra);        // prepare ray\r
 \r
-       mreal dr = r/(nx-1), dk = M_PI*(nx-1)/(k0*r*nx);\r
-       memset(dmp,0,4*nx*nx*sizeof(mreal));\r
+       double dr = r/(nx-1), dk = M_PI*(nx-1)/(k0*r*nx);\r
+       memset(dmp,0,4*nx*nx*sizeof(double));\r
 #pragma omp parallel for collapse(2)\r
        for(long i=0;i<nx/2;i++)        for(long j=0;j<nx/2;j++)        // prepare damping\r
        {\r
-               register mreal x1 = (nx/2-i)/(nx/2.), x2 = (nx/2-j)/(nx/2.);\r
+               register double x1 = (nx/2-i)/(nx/2.), x2 = (nx/2-j)/(nx/2.);\r
                dmp[2*nx-1-i] = dmp[i] = 30*GAMMA*x1*x1/k0;\r
                dmp[(2*nx-1-j)*2*nx] += 30*GAMMA*x2*x2/k0;\r
                dmp[j*2*nx] += 30*GAMMA*x2*x2/k0;\r
@@ -601,7 +619,6 @@ HADT MGL_EXPORT mgl_qo3d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal z,
                        }\r
                tmp.r=ray->a+n7*k;      tmp.ra=ra+k;\r
                mglStartThread(mgl_qo3d_hprep,0,2*nx,0,0,0,0,&tmp);     tmp.h0 = huv[0];\r
-#pragma omp parallel for\r
                for(long i=0;i<2*nx;i++)        // fill intermediate arrays\r
                {\r
                        tmp.hx[i] = hxv[i];     tmp.hy[i] = huy[i*2*nx];\r
@@ -609,7 +626,7 @@ HADT MGL_EXPORT mgl_qo3d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal z,
                }\r
                mglStartThread(mgl_qo3d_post,0,2*nx,0,0,0,0,&tmp);\r
                // Step for field\r
-               dual dt = dual(0, -ra[k].dt*k0);        // TODO: this part can be paralleled\r
+               ddual dt = ddual(0, -ra[k].dt*k0);\r
 #pragma omp parallel\r
                {\r
                        void *wsx = mgl_fft_alloc_thr(2*nx);\r
@@ -666,19 +683,19 @@ HADT MGL_EXPORT mgl_qo3d_func_c(dual (*ham)(mreal u, mreal x, mreal y, mreal z,
        return res;\r
 }\r
 //-----------------------------------------------------------------------------\r
-HMDT MGL_EXPORT mgl_qo3d_func(dual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz)\r
+HMDT MGL_EXPORT mgl_qo3d_func(ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz)\r
 {\r
        HADT res = mgl_qo3d_func_c(ham,par,ini_re,ini_im,ray_dat,r,k0,xx,yy,zz);\r
        HMDT out = mgl_datac_abs(res);  delete res;     return out;\r
 }\r
 //-----------------------------------------------------------------------------\r
-dual MGL_NO_EXPORT mgl_ham3d(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)\r
+ddual MGL_NO_EXPORT mgl_ham3d(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)\r
 {\r
        mglFormula *h = (mglFormula *)par;\r
        mreal var[MGL_VS];      memset(var,0,MGL_VS*sizeof(mreal));\r
        var['x'-'a'] = x;       var['y'-'a'] = y;       var['z'-'a'] = z;       var['u'-'a'] = u;\r
        var['p'-'a'] = px;      var['q'-'a'] = py;      var['v'-'a'] = pz;\r
-       return dual(h->Calc(var), -h->CalcD(var,'i'));\r
+       return ddual(h->Calc(var), -h->CalcD(var,'i'));\r
 }\r
 //-----------------------------------------------------------------------------\r
 HADT MGL_EXPORT mgl_qo3d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz)\r
@@ -768,7 +785,7 @@ HMDT MGL_EXPORT mgl_jacobian_3d(HCDT x, HCDT y, HCDT z)
 {\r
        int nx = x->GetNx(), ny=x->GetNy(), nz=x->GetNz(), nn = nx*ny*nz;\r
        if(nx<2 || ny<2 || nz<2)        return 0;\r
-       if(nn!=y->GetNx()*y->GetNy()*y->GetNz() || nn!=z->GetNx()*z->GetNy()*z->GetNz())        return 0;\r
+       if(nn!=y->GetNN() || nn!=z->GetNN())    return 0;\r
        mglData *r=new mglData(nx,ny,nz);\r
        const mglData *xx=dynamic_cast<const mglData *>(x);\r
        const mglData *yy=dynamic_cast<const mglData *>(y);\r
index f300239f5ac80914320479ecc97d95f0e5066b6d..7903080e12faee3204f5b28fbf086d42bb318ae5 100644 (file)
 #include <algorithm>\r
 #include "mgl2/canvas.h"\r
 #include "mgl2/thread.h"\r
+\r
+inline mreal get_persp(float pf, float z, float Depth)\r
+//{    return (1-pf)/(1-pf*z/Depth);   }\r
+{      return (1-pf/1.37)/(1-pf*z/Depth);      }\r
+inline mreal get_pfact(float pf, float Depth)\r
+//{    return pf/(1-pf)/Depth; }\r
+{      return pf/(1-pf/1.37)/Depth;    }\r
 //-----------------------------------------------------------------------------\r
-void mglCanvas::SetSize(int w,int h)\r
+void mglCanvas::SetSize(int w,int h,bool clf)\r
 {\r
        if(w<=0 || h<=0)        {       SetWarn(mglWarnSize,"SetSize"); return; }\r
+       double dx = double(w)/Width, dy = double(h)/Height, dz = sqrt(double(w*h))/Depth;\r
        Width = w;      Height = h;     Depth = long(sqrt(double(w*h)));\r
-       if(G)   {       delete []G;     delete []C;     delete []Z;     delete []G4;delete []OI;        }\r
-       G = new unsigned char[w*h*3];\r
-       G4= new unsigned char[w*h*4];\r
-       C = new unsigned char[w*h*12];\r
-       Z = new float[w*h*3];   // only 3 planes\r
-       OI= new int[w*h];\r
-       InPlot(0,1,0,1,false);  Clf();\r
+       long s = long(w)*long(h);\r
+#pragma omp critical(rgb)\r
+       if(G)   {       delete []G;     delete []C;     delete []Z;     delete []G4;delete []GB;delete []OI;    G=0;    }\r
+       G = new unsigned char[s*3];\r
+       G4= new unsigned char[s*4];\r
+       GB= new unsigned char[s*4];\r
+       C = new unsigned char[s*12];\r
+       Z = new float[s*3];     // only 3 planes\r
+       OI= new int[s];\r
+#pragma omp parallel for\r
+       for(long i=0;i<s;i++)   memcpy(GB+4*i,BDef,4);\r
+       InPlot(0,1,0,1,false);\r
+       if(clf || (Quality&4))  Clf();\r
+       else\r
+       {\r
+#pragma omp parallel for\r
+               for(long i=0;i<long(Pnt.size());i++)\r
+               {\r
+                       mglPnt &q = Pnt[i];\r
+                       q.x*=dx;        q.y*=dy;        q.z*=dz;\r
+                       q.xx*=dx;       q.yy*=dy;       q.zz*=dz;\r
+                       q.u*=dx;        q.v*=dy;        q.w*=dz;\r
+               }\r
+               ClfZB();        Finish();\r
+       }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglDrawReg::set(mglCanvas *gr, int nx, int ny, int m)\r
@@ -44,36 +70,38 @@ void mglDrawReg::set(mglCanvas *gr, int nx, int ny, int m)
 //-----------------------------------------------------------------------------\r
 void mglCanvas::PutDrawReg(mglDrawReg *d, const mglCanvas *gr)\r
 {\r
-       if(!gr) return;\r
-       int dd = d->x2 - d->x1;\r
-       register long i,j;\r
-       for(j=d->y1;j<d->y2;j++)\r
+       if(gr)\r
        {\r
-               i = d->x1+Width*(Height-1-j);\r
-               memcpy(OI+i,gr->OI+i,dd*sizeof(int));\r
-               memcpy(Z+3*i,gr->Z+3*i,3*dd*sizeof(float));\r
-               memcpy(C+12*i,gr->C+12*i,12*dd);\r
+               int dd = d->x2 - d->x1;\r
+               for(long j=d->y1;j<d->y2;j++)\r
+               {\r
+                       register long i = d->x1+Width*(Height-1-j);\r
+                       memcpy(OI+i,gr->OI+i,dd*sizeof(int));\r
+                       memcpy(Z+3*i,gr->Z+3*i,3*dd*sizeof(float));\r
+                       memcpy(C+12*i,gr->C+12*i,12*dd);\r
+               }\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::PostScale(const mglMatrix *M, mglPoint &p) const\r
 {\r
-       mglPoint q=p/(2*M->pf);\r
-       p.x = M->x + q.x*M->b[0] + q.y*M->b[1] + q.z*M->b[2];\r
-       p.y = M->y + q.x*M->b[3] + q.y*M->b[4] + q.z*M->b[5];\r
-       p.z = M->z + q.x*M->b[6] + q.y*M->b[7] + q.z*M->b[8];\r
+       register mreal f = 1./(2*M->pf),x=p.x,y=p.y,z=p.z;\r
+       const mreal *b=M->b;\r
+       p.x = M->x + f*(x*b[0] + y*b[1] + z*b[2]);\r
+       p.y = M->y + f*(x*b[3] + y*b[4] + z*b[5]);\r
+       p.z = M->z + f*(x*b[6] + y*b[7] + z*b[8]);\r
 }\r
 //-----------------------------------------------------------------------------\r
 bool mglCanvas::ScalePoint(const mglMatrix *M, mglPoint &p, mglPoint &n, bool use_nan) const\r
 {\r
        bool res = get(MGL_DISABLE_SCALE) || mglBase::ScalePoint(M,p,n,use_nan);\r
-//     if(TernAxis&4)  return res;\r
        PostScale(M,p);\r
 \r
-       mglPoint y=n;\r
-       n.x = y.x*M->b[0] + y.y*M->b[1] + y.z*M->b[2];  // simpler for rotation only\r
-       n.y = y.x*M->b[3] + y.y*M->b[4] + y.z*M->b[5];\r
-       n.z = y.x*M->b[6] + y.y*M->b[7] + y.z*M->b[8];\r
+       register mreal nx=n.x, ny=n.y, nz=n.z;\r
+       const mreal *b=M->b;\r
+       n.x = nx*b[0] + ny*b[1] + nz*b[2];      // simpler for rotation only\r
+       n.y = nx*b[3] + ny*b[4] + nz*b[5];\r
+       n.z = nx*b[6] + ny*b[7] + nz*b[8];\r
        n.Normalize();\r
        return res;\r
 }\r
@@ -92,15 +120,17 @@ long mglCanvas::ProjScale(int nf, long id, bool text)
        else if(nf==2)\r
        {       p.x = xx+w + q.z*w;     p.y = yy + q.y*h;       p.z = B1.z+ q.x*d;      n = mglPoint(u.z,u.y,u.x);      }\r
        else\r
-       {       p.x = xx+w + q.x*B.b[0]/2 + q.y*B.b[1]/2 + q.z*B.b[2]/2;        n = nn;\r
-               p.y = yy+h + q.x*B.b[3]/2 + q.y*B.b[4]/2 + q.z*B.b[5]/2;\r
-               p.z = B.z + q.x*B.b[6]/2 + q.y*B.b[7]/2 + q.z*B.b[8]/2; }\r
+       {\r
+               const mreal *b=B.b;     n = nn;\r
+               p.x = xx+w + q.x*b[0]/2 + q.y*b[1]/2 + q.z*b[2]/2;\r
+               p.y = yy+h + q.x*b[3]/2 + q.y*b[4]/2 + q.z*b[5]/2;\r
+               p.z = B.z + q.x*b[6]/2 + q.y*b[7]/2 + q.z*b[8]/2;\r
+       }\r
        return CopyProj(id,p,text?n:nn);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::LightScale(const mglMatrix *M)\r
 {\r
-//#pragma omp parallel for\r
        for(long i=0;i<10;i++)\r
        {\r
                if(!light[i].n) continue;\r
@@ -117,30 +147,31 @@ mglPoint mglCanvas::RestorePnt(mglPoint ps, bool norm) const
        mglPoint p;\r
 \r
        mreal W=Width/2, H=Height/2, D=Depth/2;\r
-       mreal cx = B.z*Bp.b[2]+B.y*Bp.b[1]+B.x*Bp.b[0]-Bp.x*W-Bp.b[0]*W+W-Bp.b[1]*H-Bp.b[2]*D;\r
-       mreal c0 = B.b[6]*Bp.b[2]+B.b[3]*Bp.b[1]+B.b[0]*Bp.b[0];\r
-       mreal c1 = B.b[7]*Bp.b[2]+B.b[4]*Bp.b[1]+B.b[1]*Bp.b[0];\r
-       mreal c2 = B.b[8]*Bp.b[2]+B.b[5]*Bp.b[1]+B.b[2]*Bp.b[0];\r
-       mreal cy = B.z*Bp.b[5]+B.y*Bp.b[4]+B.x*Bp.b[3]-Bp.b[3]*W-Bp.y*H-Bp.b[4]*H+H-Bp.b[5]*D;\r
-       mreal c3 = B.b[6]*Bp.b[5]+B.b[3]*Bp.b[4]+B.b[0]*Bp.b[3];\r
-       mreal c4 = B.b[7]*Bp.b[5]+B.b[4]*Bp.b[4]+B.b[1]*Bp.b[3];\r
-       mreal c5 = B.b[8]*Bp.b[5]+B.b[5]*Bp.b[4]+B.b[2]*Bp.b[3];\r
-       mreal cz = B.z*Bp.b[8]+B.y*Bp.b[7]+B.x*Bp.b[6]-Bp.b[6]*W-Bp.b[7]*H-Bp.z*D-Bp.b[8]*D+D;\r
-       mreal c6 = B.b[6]*Bp.b[8]+B.b[3]*Bp.b[7]+B.b[0]*Bp.b[6];\r
-       mreal c7 = B.b[7]*Bp.b[8]+B.b[4]*Bp.b[7]+B.b[1]*Bp.b[6];\r
-       mreal c8 = B.b[8]*Bp.b[8]+B.b[5]*Bp.b[7]+B.b[2]*Bp.b[6];\r
+       const mreal *b=B.b,*d=Bp.b;\r
+       mreal cx = B.z*d[2]+B.y*d[1]+B.x*d[0]-Bp.x*W-d[0]*W+W-d[1]*H-d[2]*D;\r
+       mreal c0 = b[6]*d[2]+b[3]*d[1]+b[0]*d[0];\r
+       mreal c1 = b[7]*d[2]+b[4]*d[1]+b[1]*d[0];\r
+       mreal c2 = b[8]*d[2]+b[5]*d[1]+b[2]*d[0];\r
+       mreal cy = B.z*d[5]+B.y*d[4]+B.x*d[3]-d[3]*W-Bp.y*H-d[4]*H+H-d[5]*D;\r
+       mreal c3 = b[6]*d[5]+b[3]*d[4]+b[0]*d[3];\r
+       mreal c4 = b[7]*d[5]+b[4]*d[4]+b[1]*d[3];\r
+       mreal c5 = b[8]*d[5]+b[5]*d[4]+b[2]*d[3];\r
+       mreal cz = B.z*d[8]+B.y*d[7]+B.x*d[6]-d[6]*W-d[7]*H-Bp.z*D-d[8]*D+D;\r
+       mreal c6 = b[6]*d[8]+b[3]*d[7]+b[0]*d[6];\r
+       mreal c7 = b[7]*d[8]+b[4]*d[7]+b[1]*d[6];\r
+       mreal c8 = b[8]*d[8]+b[5]*d[7]+b[2]*d[6];\r
        if(norm)        cx=cy=cz=0;\r
 \r
-       if(ps.z==ps.z)  // try to take into account perspective if z-value is provided\r
+       if(mgl_isnum(ps.z))     // try to take into account perspective if z-value is provided\r
        {\r
-               register float d = (1-Bp.pf)/(1-Bp.pf*ps.z/Depth);\r
-               ps.x = Width/2 + (ps.x-Width/2)/d;\r
-               ps.y = Height/2+ (ps.y-Height/2)/d;\r
+               register float dd = get_persp(Bp.pf,ps.z,Depth);\r
+               ps.x = Width/2 + (ps.x-Width/2)/dd;\r
+               ps.y = Height/2+ (ps.y-Height/2)/dd;\r
        }\r
        mreal xx = ps.x-cx, yy = ps.y-cy, zz = ps.z-cz;\r
        mreal d1=c0*c4-c1*c3, d2=c1*c5-c2*c4, d3=c0*c5-c2*c3;\r
 \r
-       if(zz==zz)      // try to use z-values\r
+       if(mgl_isnum(zz))       // try to use z-values\r
        {\r
                // put inverse matrix here: [x,y,z]=B^(-1)[xx,yy,zz]\r
                mreal det = (-c0*c4*c8+c1*c3*c8+c0*c5*c7-c2*c3*c7-c1*c5*c6+c2*c4*c6)/s3;\r
@@ -191,28 +222,46 @@ void mglCanvas::CalcScr(mglPoint p, int *xs, int *ys) const
 mglPoint mglCanvas::CalcScr(mglPoint p) const\r
 {      int x,y;        CalcScr(p,&x,&y);       return mglPoint(x,y);   }\r
 //-----------------------------------------------------------------------------\r
-MGL_NO_EXPORT int mgl_type_prior[8]={1,2,4,5, 0,3,0, 7};\r
-bool mglCreationOrder=false;\r
-bool operator<(const mglPrim &a, const mglPrim &b)\r
+void MGL_NO_EXPORT mgl_prm_swap(mglPrim &s1,mglPrim &s2,mglPrim *buf)\r
 {\r
-       if(mglCreationOrder)    return a.n1<b.n1;\r
-       register int t1 = mgl_type_prior[a.type], t2 = mgl_type_prior[b.type];\r
-       if(a.z!=b.z)    return a.z < b.z;\r
-       if(t1!=t2)              return t1 > t2;\r
-       if(a.w!=b.w)    return a.w > b.w;\r
-       return a.n3 > b.n3;\r
+       memcpy(buf, &s1, sizeof(mglPrim));\r
+       memcpy(&s1, &s2, sizeof(mglPrim));\r
+       memcpy(&s2, buf, sizeof(mglPrim));\r
 }\r
-//-----------------------------------------------------------------------------\r
-bool operator>(const mglPrim &a, const mglPrim &b)\r
+void MGL_NO_EXPORT sort_prm_c(size_t l0, size_t r0, mglStack<mglPrim> &s, mglPrim *buf)\r
 {\r
-       if(mglCreationOrder)    return a.n1>b.n1;\r
-       register int t1 = mgl_type_prior[a.type], t2 = mgl_type_prior[b.type];\r
-       if(a.z!=b.z)    return a.z > b.z;\r
-       if(t1!=t2)              return t1 < t2;\r
-       if(a.w!=b.w)    return a.w < b.w;\r
-       return a.n3 < b.n3;\r
+       if(l0==r0)      return;\r
+       if(l0+1==r0)\r
+       {\r
+               if(s[r0].n1<s[l0].n1)   mgl_prm_swap(s[r0],s[l0],buf);\r
+               return;\r
+       }\r
+       bool del= (buf==0);\r
+       if(del) buf = (mglPrim*)malloc(sizeof(mglPrim));\r
+\r
+       size_t l=l0, r=r0;\r
+       long v = s[(l+r)/2].n1;\r
+\r
+       for(size_t i=l0;i<=r0;i++)      // first collect <0\r
+               if(s[i].n1<v)\r
+               {\r
+                       if(i>l) mgl_prm_swap(s[i],s[l],buf);\r
+                       l++;\r
+               }\r
+       r=l;\r
+       for(size_t i=l;i<=r0;i++)       // now collect =0\r
+               if(s[i].n1==v)\r
+               {\r
+                       if(i>r) mgl_prm_swap(s[i],s[r],buf);\r
+                       r++;\r
+               }\r
+\r
+       if(l>l0+1)      sort_prm_c(l0,l-1,s,buf);\r
+       if(r<r0)        sort_prm_c(r,r0,s,buf);\r
+       if(del) free(buf);\r
 }\r
 //-----------------------------------------------------------------------------\r
+MGL_NO_EXPORT int mgl_type_prior[8]={1,2,4,5, 0,3,0, 7};\r
 MGL_NO_EXPORT void *mgl_canvas_thr(void *par)\r
 {      mglThreadG *t=(mglThreadG *)par;        (t->gr->*(t->f))(t->id, t->n, t->p);    return NULL;    }\r
 void mglStartThread(void (mglCanvas::*func)(long i, long n, const void *p), mglCanvas *gr, long n, const void *p=NULL)\r
@@ -238,14 +287,16 @@ void mglStartThread(void (mglCanvas::*func)(long i, long n, const void *p), mglC
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pxl_combine(long id, long n, const void *)\r
 {\r
-       unsigned char c[4],*cc;\r
 #if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for private(c,cc)\r
+#pragma omp parallel for\r
 #endif\r
        for(long i=id;i<n;i+=mglNumThr)\r
-       {       cc = C+12*i;            memcpy(c,BDef,4);\r
+       {\r
+               unsigned char *cc = C+12*i, c[4];\r
+               memcpy(c,GB+4*i,4);     // memcpy(c,BDef,4);\r
                combine(c,cc+8);        combine(c,cc+4);\r
-               combine(c,cc);          memcpy(G4+4*i,c,4);     }\r
+               combine(c,cc);          memcpy(G4+4*i,c,4);\r
+       }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pxl_memcpy(long id, long n, const void *)\r
@@ -258,29 +309,32 @@ void mglCanvas::pxl_memcpy(long id, long n, const void *)
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pxl_backgr(long id, long n, const void *)\r
 {\r
-       unsigned char c[4];\r
 #if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for private(c)\r
+#pragma omp parallel for\r
 #endif\r
        for(long i=id;i<n;i+=mglNumThr)\r
-       {       memcpy(c,BDef,4);       combine(c,G4+4*i);      memcpy(G+3*i,c,3);      }\r
+       {       unsigned char c[4];     memcpy(c,GB+4*i,4);     combine(c,G4+4*i);      memcpy(G+3*i,c,3);      }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pxl_transform(long id, long n, const void *)\r
 {\r
+       const mreal *b = Bp.b;\r
+       mreal dx = -Bp.x*Width/2, dy = -Bp.y*Height/2, dz = Depth/2.;\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
        for(long i=id;i<n;i+=mglNumThr)\r
        {\r
                mglPnt &p=Pnt[i];\r
-               if(p.sub)       continue;\r
-               register float x = p.xx-Width/2., y = p.yy-Height/2., z = p.zz-Depth/2.;\r
-               p.x = Bp.b[0]*x + Bp.b[1]*y + Bp.b[2]*z - Bp.x*Width/2;\r
-               p.y = Bp.b[3]*x + Bp.b[4]*y + Bp.b[5]*z - Bp.y*Height/2;\r
-               p.z = Bp.b[6]*x + Bp.b[7]*y + Bp.b[8]*z + Depth/2.;\r
-               register float d = (1-Bp.pf)/(1-Bp.pf*p.z/Depth);\r
-               p.x = Width/2 + d*p.x;  p.y = Height/2 + d*p.y;\r
+               if(!p.sub)\r
+               {\r
+                       register float x = p.xx-Width/2., y = p.yy-Height/2., z = p.zz-Depth/2.;\r
+                       p.x = b[0]*x + b[1]*y + b[2]*z + dx;\r
+                       p.y = b[3]*x + b[4]*y + b[5]*z + dy;\r
+                       p.z = b[6]*x + b[7]*y + b[8]*z + dz;\r
+                       register float d = get_persp(Bp.pf,p.z,Depth);\r
+                       p.x = Width/2. + d*p.x; p.y = Height/2. + d*p.y;\r
+               }\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -292,41 +346,31 @@ void mglCanvas::pxl_setz_adv(long id, long n, const void *)
        for(long i=id;i<n;i+=mglNumThr)\r
        {\r
                mglPrim &q=Prm[i];      q.z = Pnt[q.n1].z;\r
-               if(q.type==1)   q.z = (q.z + Pnt[q.n2].z)/2;\r
-               if(q.type==2)   q.z = (q.z + Pnt[q.n2].z + Pnt[q.n3].z)/3;\r
                if(q.type==3)   q.z = (q.z + Pnt[q.n2].z + Pnt[q.n3].z + Pnt[q.n4].z)/4;\r
+               else if(q.type==2)      q.z = (q.z + Pnt[q.n2].z + Pnt[q.n3].z)/3;\r
+               else if(q.type==1)      q.z = (q.z + Pnt[q.n2].z)/2;\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
-void mglCanvas::pxl_prmcol(long id, long n, const void *)\r
-{\r
-       prm_col.resize(n);\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-       for(long i=id;i<n;i+=mglNumThr)\r
-               prm_col[i] = GetColor(Prm[i]);\r
-}\r
-//-----------------------------------------------------------------------------\r
-uint32_t mglCanvas::GetColor(const mglPrim &p)\r
+uint32_t mglCanvas::GetColor(const mglPrim &p) const\r
 {\r
        mglRGBA res, c1,c2,c3,c4;\r
        c1.c=pnt_col[p.type==1?p.n2:p.n1];\r
        unsigned r=c1.r[0], g=c1.r[1], b=c1.r[2], a=c1.r[3];\r
        switch(p.type)\r
        {\r
-       case 2:\r
-               c2.c=pnt_col[p.n2];     c3.c=pnt_col[p.n3];\r
-               res.r[0]=(r+c2.r[0]+c3.r[0])/3;\r
-               res.r[1]=(g+c2.r[1]+c3.r[1])/3;\r
-               res.r[2]=(b+c2.r[2]+c3.r[2])/3;\r
-               res.r[3]=(a+c2.r[3]+c3.r[3])/3; break;\r
        case 3:\r
                c2.c=pnt_col[p.n2];     c3.c=pnt_col[p.n3];     c4.c=pnt_col[p.n4];\r
                res.r[0]=(r+c2.r[0]+c3.r[0]+c4.r[0])/4;\r
                res.r[1]=(g+c2.r[1]+c3.r[1]+c4.r[1])/4;\r
                res.r[2]=(b+c2.r[2]+c3.r[2]+c4.r[2])/4;\r
                res.r[3]=(a+c2.r[3]+c3.r[3]+c4.r[3])/4; break;\r
+       case 2:\r
+               c2.c=pnt_col[p.n2];     c3.c=pnt_col[p.n3];\r
+               res.r[0]=(r+c2.r[0]+c3.r[0])/3;\r
+               res.r[1]=(g+c2.r[1]+c3.r[1])/3;\r
+               res.r[2]=(b+c2.r[2]+c3.r[2])/3;\r
+               res.r[3]=(a+c2.r[3]+c3.r[3])/3; break;\r
        case 6:\r
                res.r[0]=p.n2&0xff;     res.r[1]=(p.n2/256)&0xff;       res.r[2]=(p.n2/65536)&0xff;     res.r[3]=255;   break;\r
 //             res.c=p.n2;     break;\r
@@ -346,13 +390,11 @@ uint32_t mglCanvas::GetColor(const mglPrim &p)
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pxl_pntcol(long id, long n, const void *)\r
 {\r
-       mglRGBA c;\r
-       pnt_col.resize(n);\r
 #if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for private(c)\r
+#pragma omp parallel for\r
 #endif\r
        for(long i=id;i<n;i+=mglNumThr)\r
-       {       col2int(Pnt[i],c.r,-1); pnt_col[i]=c.c; }\r
+       {       mglRGBA c;      col2int(Pnt[i],c.r,-1); pnt_col[i]=c.c; }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pxl_setz(long id, long n, const void *)\r
@@ -364,6 +406,22 @@ void mglCanvas::pxl_setz(long id, long n, const void *)
        {       mglPrim &q=Prm[i];      q.z = Pnt[q.n1].z;      }\r
 }\r
 //-----------------------------------------------------------------------------\r
+HMGL mgl_qsort_gr=0;\r
+int mglBase::PrmCmp(long i, long j) const\r
+{\r
+       const mglPrim &a = Prm[i];\r
+       const mglPrim &b = Prm[j];\r
+       if(a.z!=b.z)    return int(100*(a.z - b.z));\r
+       register int t1 = mgl_type_prior[a.type], t2 = mgl_type_prior[b.type];\r
+       if(t1!=t2)              return t2 - t1;\r
+       if(a.w!=b.w)    return int(100*(b.w - a.w));\r
+       return a.n3 - b.n3;\r
+}\r
+int MGL_LOCAL_PURE mgl_prm_cmp(const void *i,const void *j)\r
+{\r
+       return mgl_qsort_gr->PrmCmp(*(const long *)i, *(const long *)j);\r
+}\r
+//-----------------------------------------------------------------------------\r
 void mglCanvas::PreparePrim(int fast)\r
 {\r
        if(fast!=2)\r
@@ -371,24 +429,21 @@ void mglCanvas::PreparePrim(int fast)
                mglStartThread(&mglCanvas::pxl_transform,this,Pnt.size());\r
                if(fast==0)     mglStartThread(&mglCanvas::pxl_setz,this,Prm.size());\r
                else    mglStartThread(&mglCanvas::pxl_setz_adv,this,Prm.size());\r
-               mglCreationOrder = false;\r
-               std::sort(Prm.begin(), Prm.end());\r
+#pragma omp critical\r
+               {\r
+                       ClearPrmInd();  mgl_qsort_gr = this;\r
+                       register size_t n = Prm.size();\r
+                       PrmInd = new long[n];\r
+                       for(size_t i=0;i<n;i++) PrmInd[i]=i;\r
+                       qsort(PrmInd,n,sizeof(long),mgl_prm_cmp);\r
+                       clr(MGL_FINISHED);\r
+               }\r
        }\r
        if(fast>0)\r
        {\r
-               mglStartThread(&mglCanvas::pxl_pntcol,this,Pnt.size());\r
-               mglStartThread(&mglCanvas::pxl_prmcol,this,Prm.size());\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
-void mglBase::resort()\r
-{\r
 #pragma omp critical\r
-       {\r
-               mglCreationOrder = true;\r
-               std::sort(Prm.begin(), Prm.end());\r
-               mglCreationOrder = false;\r
-               clr(MGL_FINISHED);\r
+               {       if(pnt_col)     delete []pnt_col;       pnt_col = new uint32_t[Pnt.size()];     }\r
+               mglStartThread(&mglCanvas::pxl_pntcol,this,Pnt.size());\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -396,30 +451,86 @@ void mglCanvas::pxl_primdr(long id, long , const void *)
 {\r
 #define Q      4       // should be >= sqrt(2*num_thr) ???\r
        int nx=Q,ny=Q;          // TODO find dependence on Q for 1, 2, 4, 8 threads. Try to select optimal\r
+       if(!(Quality&3))\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
-       for(long i=id;i<nx*ny;i+=mglNumThr)\r
-       {\r
-               mglDrawReg d;   d.set(this,nx,ny,i);\r
-               for(size_t k=0;k<Prm.size();k++)\r
+               for(long i=id;i<nx*ny;i+=mglNumThr)\r
                {\r
-                       if(Stop)        continue;\r
-                       const mglPrim &p=Prm[k];\r
-                       d.PDef = p.n3;  d.pPos = p.s;\r
-                       d.ObjId = p.id; d.PenWidth=p.w;\r
-                       d.angle = p.angl;\r
-                       if(p.type==2 || p.type==3) d.PDef = p.m;\r
-                       switch(p.type)\r
+                       mglDrawReg d;   d.set(this,nx,ny,i);\r
+                       for(size_t k=0;k<Prm.size();k++)\r
                        {\r
-                       case 0: mark_draw(Pnt[p.n1],p.n4,p.s,&d);       break;\r
-                       case 1: line_draw(Pnt[p.n1],Pnt[p.n2],&d);      break;\r
-                       case 2: trig_draw(Pnt[p.n1],Pnt[p.n2],Pnt[p.n3],true,&d);       break;\r
-                       case 3: quad_draw(Pnt[p.n1],Pnt[p.n2],Pnt[p.n3],Pnt[p.n4],&d);  break;\r
-                       case 4: glyph_draw(p,&d);       break;\r
+                               if(Stop)        break;\r
+                               const mglPrim &p=GetPrm(k);\r
+                               d.PDef = p.n3;  d.pPos = p.s;\r
+                               d.ObjId = p.id; d.PenWidth=p.w;\r
+                               d.angle = p.angl;\r
+                               if(p.type==2 || p.type==3) d.PDef = p.m;\r
+                               register long n1=p.n1, n2=p.n2, n3=p.n3, n4=p.n4;\r
+                               switch(p.type)\r
+                               {\r
+                               case 0: mark_draw(Pnt[n1],n4,p.s,&d);   break;\r
+                               case 1: fast_draw(Pnt[n1],Pnt[n2],&d);  break;\r
+                               case 2: fast_draw(Pnt[n1],Pnt[n2],&d);  fast_draw(Pnt[n1],Pnt[n3],&d);\r
+                                               fast_draw(Pnt[n2],Pnt[n3],&d);  break;\r
+                               case 3: fast_draw(Pnt[n1],Pnt[n4],&d);  fast_draw(Pnt[n2],Pnt[n3],&d);  break;\r
+                               case 4: glyph_draw(p,&d);       break;\r
+                               }\r
+                       }\r
+               }\r
+       else if(!(Quality&MGL_DRAW_NORM))\r
+#if !MGL_HAVE_PTHREAD\r
+#pragma omp parallel for\r
+#endif\r
+               for(long i=id;i<nx*ny;i+=mglNumThr)\r
+               {\r
+                       mglDrawReg d;   d.set(this,nx,ny,i);\r
+                       for(size_t k=0;k<Prm.size();k++)\r
+                       {\r
+                               if(Stop)        break;\r
+                               const mglPrim &p=GetPrm(k);\r
+                               d.PDef = p.n3;  d.pPos = p.s;\r
+                               d.ObjId = p.id; d.PenWidth=p.w;\r
+                               d.angle = p.angl;\r
+                               if(p.type==2 || p.type==3) d.PDef = p.m;\r
+                               register long n1=p.n1, n2=p.n2, n3=p.n3, n4=p.n4;\r
+                               switch(p.type)\r
+                               {\r
+                               case 0: mark_draw(Pnt[n1],n4,p.s,&d);   break;\r
+                               case 1: line_draw(Pnt[n1],Pnt[n2],&d);  break;\r
+                               case 2: trig_draw(Pnt[n1],Pnt[n2],Pnt[n3],true,&d);     break;\r
+                               case 3: trig_draw(Pnt[n1],Pnt[n2],Pnt[n4],true,&d);\r
+                                               trig_draw(Pnt[n1],Pnt[n3],Pnt[n4],true,&d);     break;\r
+                               case 4: glyph_draw(p,&d);       break;\r
+                               }\r
+                       }\r
+               }\r
+       else\r
+#if !MGL_HAVE_PTHREAD\r
+#pragma omp parallel for\r
+#endif\r
+               for(long i=id;i<nx*ny;i+=mglNumThr)\r
+               {\r
+                       mglDrawReg d;   d.set(this,nx,ny,i);\r
+                       for(size_t k=0;k<Prm.size();k++)\r
+                       {\r
+                               if(Stop)        break;\r
+                               const mglPrim &p=GetPrm(k);\r
+                               d.PDef = p.n3;  d.pPos = p.s;\r
+                               d.ObjId = p.id; d.PenWidth=p.w;\r
+                               d.angle = p.angl;\r
+                               if(p.type==2 || p.type==3) d.PDef = p.m;\r
+                               register long n1=p.n1, n2=p.n2, n3=p.n3, n4=p.n4;\r
+                               switch(p.type)\r
+                               {\r
+                               case 0: mark_draw(Pnt[n1],n4,p.s,&d);   break;\r
+                               case 1: line_draw(Pnt[n1],Pnt[n2],&d);  break;\r
+                               case 2: trig_draw(Pnt[n1],Pnt[n2],Pnt[n3],true,&d);     break;\r
+                               case 3: quad_draw(Pnt[n1],Pnt[n2],Pnt[n3],Pnt[n4],&d);  break;\r
+                               case 4: glyph_draw(p,&d);       break;\r
+                               }\r
                        }\r
                }\r
-       }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pxl_primpx(long id, long n, const void *)      // NOTE this variant is too slow ... may be later in CUDA???\r
@@ -433,8 +544,8 @@ void mglCanvas::pxl_primpx(long id, long n, const void *)   // NOTE this variant i
                register long i=ii%Width, j=ii/Width;\r
                for(size_t k=0;k<Prm.size();k++)\r
                {\r
-                       if(Stop)        continue;\r
-                       const mglPrim &p=Prm[k];\r
+                       if(Stop)        break;\r
+                       const mglPrim &p=GetPrm(k);\r
                        d.PDef = p.n3;  d.pPos = p.s;\r
                        d.ObjId = p.id; d.PenWidth=p.w;\r
                        d.angle = p.angl;\r
@@ -453,20 +564,22 @@ void mglCanvas::pxl_primpx(long id, long n, const void *) // NOTE this variant i
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pxl_dotsdr(long id, long n, const void *)\r
 {\r
-       unsigned char r[4]={0,0,0,255};\r
+       const mreal *b = Bp.b;\r
+       mreal dx = -Bp.x*Width/2, dy = -Bp.y*Height/2, dz = Depth/2.;\r
 #if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for firstprivate(r)\r
+#pragma omp parallel for\r
 #endif\r
        for(long i=id;i<n;i+=mglNumThr)\r
        {\r
+               unsigned char r[4]={0,0,0,255};\r
                const mglPnt &p=Pnt[i];\r
                if(p.sub)       continue;\r
                register float x = p.xx-Width/2., y = p.yy-Height/2., z = p.zz-Depth/2.,xx,yy,zz;\r
-               xx = Bp.b[0]*x + Bp.b[1]*y + Bp.b[2]*z - Bp.x*Width/2;\r
-               yy = Bp.b[3]*x + Bp.b[4]*y + Bp.b[5]*z - Bp.y*Height/2;\r
-               zz = Bp.b[6]*x + Bp.b[7]*y + Bp.b[8]*z + Depth/2.;\r
-               register float d = (1-Bp.pf)/(1-Bp.pf*zz/Depth);\r
-               xx = Width/2 + d*xx;    yy = Height/2 + d*yy;\r
+               xx = b[0]*x + b[1]*y + b[2]*z + dx;\r
+               yy = b[3]*x + b[4]*y + b[5]*z + dy;\r
+               zz = b[6]*x + b[7]*y + b[8]*z + dz;\r
+               register float d = get_persp(Bp.pf,zz,Depth);\r
+               xx = Width/2. + d*xx;   yy = Height/2. + d*yy;\r
 \r
                r[0] = (unsigned char)(255*p.r);\r
                r[1] = (unsigned char)(255*p.g);\r
@@ -479,36 +592,45 @@ void mglCanvas::pxl_dotsdr(long id, long n, const void *)
 //-----------------------------------------------------------------------------\r
 void mglCanvas::Finish()\r
 {\r
+       static mglMatrix bp;\r
+       if(Quality==MGL_DRAW_NONE)      return;\r
+#if MGL_HAVE_PTHREAD\r
+       pthread_mutex_lock(&mutexClf);\r
+#elif MGL_HAVE_OMP\r
+       omp_set_lock(&lockClf);\r
+#endif\r
        if(Quality==MGL_DRAW_DOTS)\r
        {\r
                mglStartThread(&mglCanvas::pxl_dotsdr,this,Pnt.size());\r
                mglStartThread(&mglCanvas::pxl_memcpy,this,Width*Height);\r
                mglStartThread(&mglCanvas::pxl_backgr,this,Width*Height);\r
-               return;\r
        }\r
-       static mglMatrix bp;\r
-       if(Quality==MGL_DRAW_NONE)      return;\r
-       if(Quality&MGL_DRAW_LMEM)       clr(MGL_FINISHED);\r
-       if(memcmp(&Bp,&bp,sizeof(mglMatrix)) && !(Quality&MGL_DRAW_LMEM) && Prm.size()>0)\r
-               clr(MGL_FINISHED);\r
-       if(get(MGL_FINISHED))   return; // nothing to do\r
-/*     static bool working=false;\r
-       if(working)     return;\r
-       working = true;*/\r
-       if(!(Quality&MGL_DRAW_LMEM) && Prm.size()>0)\r
+       else\r
        {\r
-               PreparePrim(0); bp=Bp;\r
-               clr(MGL_FINISHED);\r
-               mglStartThread(&mglCanvas::pxl_primdr,this,Prm.size());\r
+               if((Quality&MGL_DRAW_LMEM) || (memcmp(&Bp,&bp,sizeof(mglMatrix)) && !(Quality&MGL_DRAW_LMEM) && Prm.size()>0))\r
+                       clr(MGL_FINISHED);\r
+               if(!get(MGL_FINISHED))\r
+               {\r
+                       if(!(Quality&MGL_DRAW_LMEM) && Prm.size()>0)\r
+                       {\r
+                               PreparePrim(0); bp=Bp;\r
+                               clr(MGL_FINISHED);\r
+                               mglStartThread(&mglCanvas::pxl_primdr,this,Prm.size());\r
+                       }\r
+                       size_t n=Width*Height;\r
+                       BDef[3] = (Flag&3)!=2 ? 0:255;\r
+                       if(Quality&MGL_DRAW_NORM)       mglStartThread(&mglCanvas::pxl_combine,this,n);\r
+                       else                    mglStartThread(&mglCanvas::pxl_memcpy,this,n);\r
+                       BDef[3] = 255;\r
+                       mglStartThread(&mglCanvas::pxl_backgr,this,n);\r
+                       set(MGL_FINISHED);\r
+               }\r
        }\r
-       size_t n=Width*Height;\r
-       BDef[3] = (Flag&3)!=2 ? 0:255;\r
-       if(Quality&MGL_DRAW_NORM)       mglStartThread(&mglCanvas::pxl_combine,this,n);\r
-       else                    mglStartThread(&mglCanvas::pxl_memcpy,this,n);\r
-       BDef[3] = 255;\r
-       mglStartThread(&mglCanvas::pxl_backgr,this,n);\r
-       set(MGL_FINISHED);\r
-//     working = false;\r
+#if MGL_HAVE_PTHREAD\r
+       pthread_mutex_unlock(&mutexClf);\r
+#elif MGL_HAVE_OMP\r
+       omp_unset_lock(&lockClf);\r
+#endif\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::ClfZB(bool force)\r
@@ -523,30 +645,46 @@ void mglCanvas::ClfZB(bool force)
 //-----------------------------------------------------------------------------\r
 void mglCanvas::Clf(mglColor Back)\r
 {\r
-       Fog(0);         PDef = 0xffff;  pPos = 0;       StartAutoGroup(NULL);\r
-       Pnt.clear();    Prm.clear();    Ptx.clear();    Glf.clear();\r
-       Sub.clear();    Leg.clear();    Grp.clear();    Act.clear();\r
-       pnt_col.clear();        prm_col.clear();\r
-\r
-#pragma omp critical(txt)\r
-       {\r
-               Txt.clear();    Txt.reserve(3);\r
-               mglTexture t1(MGL_DEF_PAL,-1), t2(MGL_DEF_SCH,1);\r
-               MGL_PUSH(Txt,t1,mutexTxt);\r
-               MGL_PUSH(Txt,t2,mutexTxt);\r
-       }\r
-\r
-//     if(Back==NC)            Back = mglColor(1,1,1);\r
-       if((Flag&3)==2) Back = mglColor(0,0,0);\r
-       if(Back!=NC)\r
-       {       BDef[0]=Back.r*255;     BDef[1]=Back.g*255;BDef[2]=Back.b*255;  BDef[3]=0;      }\r
-       ClfZB(true);\r
+       Fog(0); PDef = 0xffff;  pPos = 0;\r
+       ClearFrame();\r
+       if((Flag&3)==2) Back = mglColor(0,0,0,0);\r
+       if(Back!=NC)    FillBackground(Back);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void mglCanvas::Clf(const char *col)\r
+{\r
+       Fog(0); PDef = 0xffff;  pPos = 0;\r
+       ClearFrame();\r
+       mglTexture txt(col,0,0);\r
+       FillBackground(txt.col[1]);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void mglCanvas::Rasterize()\r
+{\r
+       Finish();\r
+       memcpy(GB,G4,4*Width*Height);\r
+}\r
+//-----------------------------------------------------------------------------\r
+bool MGL_NO_EXPORT mgl_read_image(unsigned char *g, int w, int h, const char *fname);\r
+void mglCanvas::LoadBackground(const char *fname, double alpha)\r
+{\r
+       mgl_read_image(GB,Width,Height,fname);\r
+       if(alpha<1 && alpha>0)\r
+#pragma omp parallel for\r
+               for(long i=0;i<Width*Height;i++)        GB[4*i+3] = (unsigned char)(GB[4*i+3]*alpha);\r
+}\r
+//-----------------------------------------------------------------------------\r
+void mglCanvas::FillBackground(const mglColor &cc)\r
+{\r
+       BDef[0] = (unsigned char)(255*cc.r);    BDef[1] = (unsigned char)(255*cc.g);\r
+       BDef[2] = (unsigned char)(255*cc.b);    BDef[3] = (unsigned char)(255*cc.a);\r
+#pragma omp parallel for\r
+       for(long i=0;i<Width*Height;i++)        memcpy(GB+4*i,BDef,4);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pxl_other(long id, long n, const void *p)\r
 {\r
        const mglCanvas *gr = (const mglCanvas *)p;\r
-       if(!gr) return;\r
        if(Quality&MGL_DRAW_NORM)\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
@@ -571,57 +709,58 @@ void mglCanvas::pxl_other(long id, long n, const void *p)
 //-----------------------------------------------------------------------------\r
 void mglCanvas::Combine(const mglCanvas *gr)\r
 {\r
-       if(Width!=gr->Width || Height!=gr->Height)      return; // wrong sizes\r
+       if(Width!=gr->Width || Height!=gr->Height || !gr)       return; // wrong sizes\r
        mglStartThread(&mglCanvas::pxl_other,this,Width*Height,gr);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::pnt_plot(long x,long y,mreal z,const unsigned char ci[4], int obj_id)\r
 {\r
-       long i0=x+Width*(Height-1-y);\r
-       if(ci[3]==0)    return;\r
-       unsigned char *cc = C+12*i0, c[4];\r
-       memcpy(c,ci,4);\r
-       float *zz = Z+3*i0, zf = FogDist*(z/Depth-0.5-FogDz);\r
-       if(zf<0)        // add fog\r
-       {\r
-               int d = int(255.f-255.f*exp(5.f*zf));\r
-               unsigned char cb[4] = {BDef[0], BDef[1], BDef[2], (unsigned char)d};\r
-               if(d==255)      return;\r
-               combine(c,cb);\r
-       }\r
-       if(Quality&MGL_DRAW_NORM)\r
+       if(ci[3])\r
        {\r
-               if(z>=zz[1])    // shift point on slice down and paste new point\r
+               long i0=x+Width*(Height-1-y);\r
+               unsigned char *cc = C+12*i0, c[4];\r
+               memcpy(c,ci,4);\r
+               float *zz = Z+3*i0, zf = FogDist*(z/Depth-0.5-FogDz);\r
+               if(zf<0)        // add fog\r
+               {\r
+                       int d = int(255.f-255.f*exp(5.f*zf));\r
+                       unsigned char cb[4] = {BDef[0], BDef[1], BDef[2], (unsigned char)d};\r
+                       if(d==255)      return;\r
+                       combine(c,cb);\r
+               }\r
+               if(Quality&MGL_DRAW_NORM)\r
                {\r
-                       zz[2] = zz[1];  combine(cc+8,cc+4);\r
-                       if(z>=zz[0])\r
-                       {       zz[1] = zz[0];  zz[0] = z;      OI[i0]=obj_id;\r
-                               memcpy(cc+4,cc,4);      memcpy(cc,c,4);         }\r
-                       else    {       zz[1] = z;      memcpy(cc+4,c,4);       }\r
+                       if(z>=zz[1])    // shift point on slice down and paste new point\r
+                       {\r
+                               zz[2] = zz[1];  combine(cc+8,cc+4);\r
+                               if(z>=zz[0])\r
+                               {       zz[1] = zz[0];  zz[0] = z;      OI[i0]=obj_id;\r
+                                       memcpy(cc+4,cc,4);      memcpy(cc,c,4);         }\r
+                               else    {       zz[1] = z;      memcpy(cc+4,c,4);       }\r
+                       }\r
+                       else\r
+                       {\r
+                               if(z>=zz[2])    // shift point on slice down and paste new point\r
+                               {       zz[2] = z;      combine(cc+8,c);        }\r
+                               else            // point below the background\r
+                               {       combine(c,cc+8);        memcpy(cc+8,c,4);       }\r
+                       }\r
                }\r
                else\r
                {\r
-                       if(z>=zz[2])    // shift point on slice down and paste new point\r
-                       {       zz[2] = z;      combine(cc+8,c);        }\r
-                       else            // point below the background\r
-                       {       combine(c,cc+8);        memcpy(cc+8,c,4);       }\r
+                       if(z>=zz[0])    // point upper the background\r
+                       {       zz[0]=z;        memcpy(cc,c,4);         OI[i0]=obj_id;  }\r
                }\r
        }\r
-       else\r
-       {\r
-               if(z>=zz[0])    // point upper the background\r
-               {       zz[0]=z;        memcpy(cc,c,4);         OI[i0]=obj_id;  }\r
-       }\r
 }\r
 //-----------------------------------------------------------------------------\r
-unsigned char* mglCanvas::col2int(const mglPnt &p,unsigned char *r, int obj_id)\r
+unsigned char* mglCanvas::col2int(const mglPnt &p,unsigned char *r, int obj_id) const\r
 {\r
-       if(!r)  return r;\r
+//     if(!r)  return r;       // NOTE r must be provided!\r
        if(p.a<=0)      {       memset(r,0,4);  return r;       }\r
        register float b0=0,b1=0,b2=0, ar,ag,ab;\r
        ar = ag = ab = AmbBr;\r
 \r
-//     if(get(MGL_ENABLE_LIGHT) && mgl_isnum(p.u))\r
        if(mgl_isnum(p.u+p.v+p.w))\r
        {\r
                float d0,d1,d2,nn;\r
@@ -684,32 +823,35 @@ unsigned char* mglCanvas::col2int(const mglPnt &p,unsigned char *r, int obj_id)
 }\r
 //-----------------------------------------------------------------------------\r
 /// color mixing: color c1 is under color c2 !!!\r
-void mglCanvas::combine(unsigned char *c1, const unsigned char *c2)\r
+void mglCanvas::combine(unsigned char *c1, const unsigned char *c2) const\r
 {\r
-       if(!c2[3])      return;\r
-       register unsigned int a1=c1[3], a2=c2[3],b1=255-a2;\r
-       if(a1==0 || a2==255)    {       memcpy(c1,c2,4);        return; }\r
-       if((Flag&3)==0)\r
-       {\r
-               c1[0] = (c1[0]*b1 + c2[0]*a2)/256;\r
-               c1[1] = (c1[1]*b1 + c2[1]*a2)/256;\r
-               c1[2] = (c1[2]*b1 + c2[2]*a2)/256;\r
-               c1[3] = (unsigned char)(a2+a1*b1/255);\r
-       }\r
-       else if((Flag&3)==1)\r
-       {\r
-               c1[0] = (unsigned char)((255-a1*(255-c1[0])/256)*(255-a2*(255-c2[0])/256)/256);\r
-               c1[1] = (unsigned char)((255-a1*(255-c1[1])/256)*(255-a2*(255-c2[1])/256)/256);\r
-               c1[2] = (unsigned char)((255-a1*(255-c1[2])/256)*(255-a2*(255-c2[2])/256)/256);\r
-               c1[3] = 255;\r
-       }\r
-       else if((Flag&3)==2)\r
+       if(c2[3])\r
        {\r
-               unsigned int b2,b3;\r
-               b1 = (c1[0]*a1 + c2[0]*a2)/256;         c1[0] = b1<255 ? b1 : 255;\r
-               b2 = (c1[1]*a1 + c2[1]*a2)/256;         c1[1] = b2<255 ? b2 : 255;\r
-               b3 = (c1[2]*a1 + c2[2]*a2)/256;         c1[2] = b3<255 ? b3 : 255;\r
-               c1[3] = a1+a2>255? 255 : a1+a2;\r
+               register unsigned a1=c1[3], a2=c2[3];\r
+               if(a2==255 || a1==0)    {       memcpy(c1,c2,4);        return; }\r
+               if((Flag&3)==0)\r
+               {\r
+                       register unsigned b1=255-a2;\r
+                       c1[0] = (c1[0]*b1 + c2[0]*a2)/256;\r
+                       c1[1] = (c1[1]*b1 + c2[1]*a2)/256;\r
+                       c1[2] = (c1[2]*b1 + c2[2]*a2)/256;\r
+                       c1[3] = (unsigned char)(a2+a1*b1/255);\r
+               }\r
+               else if((Flag&3)==1)\r
+               {\r
+                       c1[0] = (unsigned char)((255-a1*(255-c1[0])/256)*(255-a2*(255-c2[0])/256)/256);\r
+                       c1[1] = (unsigned char)((255-a1*(255-c1[1])/256)*(255-a2*(255-c2[1])/256)/256);\r
+                       c1[2] = (unsigned char)((255-a1*(255-c1[2])/256)*(255-a2*(255-c2[2])/256)/256);\r
+                       c1[3] = 255;\r
+               }\r
+               else if((Flag&3)==2)\r
+               {\r
+                       register unsigned b1,b2,b3;\r
+                       b1 = (c1[0]*a1 + c2[0]*a2)/256;         c1[0] = b1<255 ? b1 : 255;\r
+                       b2 = (c1[1]*a1 + c2[1]*a2)/256;         c1[1] = b2<255 ? b2 : 255;\r
+                       b3 = (c1[2]*a1 + c2[2]*a2)/256;         c1[2] = b3<255 ? b3 : 255;\r
+                       c1[3] = a1+a2>255? 255 : a1+a2;\r
+               }\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -720,17 +862,17 @@ unsigned char **mglCanvas::GetRGBLines(long &w, long &h, unsigned char *&f, bool
        p = (unsigned char **)malloc(Height * sizeof(unsigned char *));\r
        long d = (alpha ? 4:3)*Width;\r
        unsigned char *gg = (alpha?G4:G);\r
-#pragma omp parallel for\r
        for(long i=0;i<Height;i++)      p[i] = gg + d*i;\r
        w = Width;      h = Height;             f = 0;\r
        return p;\r
 }\r
 //-----------------------------------------------------------------------------\r
-bool visible(long i, long j, const unsigned char m[8], mreal pw, int a)        // Check if pixel visible\r
+bool MGL_LOCAL_PURE visible(long i, long j, const unsigned char m[8], mreal pw, int a) // Check if pixel visible\r
 {\r
        register float c = mgl_cos[(a+360)%360], s = mgl_cos[(a+450)%360];\r
-       register int ii = long(0.5+(i*c+j*s)/pw)%8, jj = long(0.5+(j*c-i*s)/pw)%8;\r
-       if(ii<0)        ii+=8;  if(jj<0)        jj+=8;\r
+//     register int ii = int(0.5+(i*c+j*s)/pw)%8, jj = int(0.5+(j*c-i*s)/pw)%8;\r
+//     if(ii<0)        ii+=8;  if(jj<0)        jj+=8;\r
+       register int ii = int(0.5+(i*c+j*s)/pw)&7, jj = int(0.5+(j*c-i*s)/pw)&7;\r
        return m[jj] & (1<<ii);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -739,68 +881,68 @@ bool visible(long i, long j, const unsigned char m[8], mreal pw, int a)   // Check
        for each point (x,y) and selected one pair which 0<u<1 and 0<v<1.*/\r
 void mglCanvas::quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, const mglDrawReg *d)\r
 {\r
-       if(!(Quality&3))\r
+       if(Quality&MGL_DRAW_LMEM)\r
        {\r
-//             fast_draw(p1,p2,d);     fast_draw(p1,p3,d);\r
-//             fast_draw(p4,p2,d);     fast_draw(p4,p3,d);\r
-               fast_draw(p1,p4,d);     fast_draw(p2,p3,d);\r
-               return;\r
+               if(!(Quality&3))\r
+               {       fast_draw(p1,p4,d);     fast_draw(p2,p3,d);     return; }\r
+               if(!(Quality&MGL_DRAW_NORM))\r
+               {       trig_draw(p1,p2,p4,true,d);     trig_draw(p1,p3,p4,true,d);     return; }\r
        }\r
        unsigned char r[4];\r
        long y1,x1,y2,x2;\r
        float dd,dsx,dsy;\r
        mglPnt d1=p2-p1, d2=p3-p1, d3=p4+p1-p2-p3, p;\r
 \r
-       x1 = long(fmin(p1.x<p2.x?p1.x:p2.x, p3.x<p4.x?p3.x:p4.x));      // bounding box\r
-       y1 = long(fmin(p1.y<p2.y?p1.y:p2.y, p3.y<p4.y?p3.y:p4.y));\r
-       x2 = long(fmax(p1.x>p2.x?p1.x:p2.x, p3.x>p4.x?p3.x:p4.x));\r
-       y2 = long(fmax(p1.y>p2.y?p1.y:p2.y, p3.y>p4.y?p3.y:p4.y));\r
-       x1=x1>d->x1?x1:d->x1;   x2=x2<d->x2?x2:d->x2;\r
-       y1=y1>d->y1?y1:d->y1;   y2=y2<d->y2?y2:d->y2;\r
-       if(x1>x2 || y1>y2)      return;\r
+       if((d1.x==0 && d1.y==0) || (d2.x==0 && d2.y==0))\r
+       {       trig_draw(p1,p2,p4,true,d);     trig_draw(p1,p3,p4,true,d);     return; }\r
+\r
+       x1 = long(mgl_min(mgl_min(p1.x,p2.x), mgl_min(p3.x,p4.x)));     // bounding box\r
+       y1 = long(mgl_min(mgl_min(p1.y,p2.y), mgl_min(p3.y,p4.y)));\r
+       x2 = long(mgl_max(mgl_max(p1.x,p2.x), mgl_max(p3.x,p4.x)));\r
+       y2 = long(mgl_max(mgl_max(p1.y,p2.y), mgl_max(p3.y,p4.y)));\r
+       x1=mgl_max(x1,d->x1);   x2=mgl_min(x2,d->x2);\r
+       y1=mgl_max(y1,d->y1);   y2=mgl_min(y2,d->y2);\r
+//     if(x1>x2 || y1>y2)      return;\r
 \r
        dd = d1.x*d2.y-d1.y*d2.x;\r
        dsx =-4*(d2.y*d3.x - d2.x*d3.y)*d1.y;\r
        dsy = 4*(d2.y*d3.x - d2.x*d3.y)*d1.x;\r
 \r
-       if((d1.x==0 && d1.y==0) || (d2.x==0 && d2.y==0) || !(Quality&MGL_DRAW_NORM))\r
-       {       trig_draw(p1,p2,p4,true,d);     trig_draw(p1,p3,p4,true,d);     return; }\r
-\r
        mglPoint n1 = mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z);\r
        mglPoint n2 = mglPoint(p2.x-p4.x,p2.y-p4.y,p2.z-p4.z)^mglPoint(p3.x-p4.x,p3.y-p4.y,p3.z-p4.z);\r
        mglPoint nr = (n1+n2)*0.5;\r
 \r
        float x0 = p1.x, y0 = p1.y;\r
-       for(long i=x1;i<=x2;i++)        for(long j=y1;j<=y2;j++)\r
+       int oi = d->ObjId, ang=d->angle;\r
+       mreal pw = d->PenWidth;\r
+       uint64_t pd = d->PDef;\r
+       for(long j=y1;j<=y2;j++)        for(long i=x1;i<=x2;i++)\r
        {\r
-               if(!visible(i,j,d->m, d->PenWidth,d->angle))    continue;\r
-               register float xx = (i-x0), yy = (j-y0), s;\r
-               s = dsx*xx + dsy*yy + (dd+d3.y*xx-d3.x*yy)*(dd+d3.y*xx-d3.x*yy);\r
-               if(s<0) continue;       // no solution\r
-               s = sqrt(s);\r
-               register float qu = d3.x*yy - d3.y*xx + dd + s, u=-1;\r
-               register float qv = d3.y*xx - d3.x*yy + dd + s, v=-1;\r
-//             if(qu && qv)\r
-               {\r
-                       u = 2.f*(d2.y*xx - d2.x*yy)/qu;\r
-                       v = 2.f*(d1.x*yy - d1.y*xx)/qv;\r
-               }\r
-               if(u*(1.f-u)<0.f || v*(1.f-v)<0.f)      // first root bad\r
+               if(pd==MGL_SOLID_MASK || visible(i,j,d->m, pw,ang))\r
                {\r
-                       qu = d3.x*yy - d3.y*xx + dd - s;\r
-                       qv = d3.y*xx - d3.x*yy + dd - s;\r
-                       u = v = -1.f;\r
-//                     if(qu && qv)\r
+                       register float xx = (i-x0), yy = (j-y0), s;\r
+                       s = dsx*xx + dsy*yy + (dd+d3.y*xx-d3.x*yy)*(dd+d3.y*xx-d3.x*yy);\r
+                       if(s>=0)\r
                        {\r
-                               u = 2.f*(d2.y*xx - d2.x*yy)/qu;\r
-                               v = 2.f*(d1.x*yy - d1.y*xx)/qv;\r
+                               s = sqrt(s);\r
+                               register float qu = d3.x*yy - d3.y*xx + dd + s;\r
+                               register float qv = d3.y*xx - d3.x*yy + dd + s;\r
+                               register float u = 2.f*(d2.y*xx - d2.x*yy)/qu;  \r
+                               register float v = 2.f*(d1.x*yy - d1.y*xx)/qv;\r
+                               if(u*(1.f-u)<0.f || v*(1.f-v)<0.f)      // first root bad\r
+                               {\r
+                                       qu = d3.x*yy - d3.y*xx + dd - s;\r
+                                       qv = d3.y*xx - d3.x*yy + dd - s;\r
+//                                     u = v = -1.f;\r
+                                       u = 2.f*(d2.y*xx - d2.x*yy)/qu; v = 2.f*(d1.x*yy - d1.y*xx)/qv;\r
+                                       if(u*(1.f-u)<0.f || v*(1.f-v)<0.f)      continue;       // second root bad\r
+                               }\r
+                               p = p1+d1*u+d2*v+d3*(u*v);\r
+                               if(mgl_isnan(p.u) && mgl_isnum(p.v))\r
+                               {       p.u = nr.x;     p.v = nr.y;     p.w = nr.z;     }\r
+                               pnt_plot(i,j,p.z,col2int(p,r,oi),oi);\r
                        }\r
-                       if(u*(1.f-u)<0.f || v*(1.f-v)<0.f)      continue;       // second root bad\r
                }\r
-               p = p1+d1*u+d2*v+d3*(u*v);\r
-               if(mgl_isnan(p.u) && mgl_isnum(p.v))\r
-               {       p.u = nr.x;     p.v = nr.y;     p.w = nr.z;     }\r
-               pnt_plot(i,j,p.z,col2int(p,r,d->ObjId),d->ObjId);\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -853,10 +995,7 @@ void mglCanvas::quad_pix(long i, long j, const mglPnt &p1, const mglPnt &p2, con
 void mglCanvas::trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, const mglDrawReg *d)\r
 {\r
        if(!(Quality&3) && anorm)\r
-       {\r
-               fast_draw(p1,p2,d);     fast_draw(p1,p3,d);\r
-               fast_draw(p2,p3,d);     return;\r
-       }\r
+       {       fast_draw(p1,p2,d);     fast_draw(p1,p3,d);     fast_draw(p2,p3,d);     return; }\r
        unsigned char r[4];\r
        long y1,x1,y2,x2;\r
        float dxu,dxv,dyu,dyv;\r
@@ -867,34 +1006,48 @@ void mglCanvas::trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3,
        dyv =-d1.x/dxu; dxv = d1.y/dxu;\r
        dyu = d2.x/dxu; dxu =-d2.y/dxu;\r
 \r
-       x1 = long(fmin(p1.x<p2.x?p1.x:p2.x, p3.x));     // bounding box\r
-       y1 = long(fmin(p1.y<p2.y?p1.y:p2.y, p3.y));\r
-       x2 = long(fmax(p1.x>p2.x?p1.x:p2.x, p3.x));\r
-       y2 = long(fmax(p1.y>p2.y?p1.y:p2.y, p3.y));\r
+       x1 = long(mgl_min(p1.x<p2.x?p1.x:p2.x, p3.x));  // bounding box\r
+       y1 = long(mgl_min(p1.y<p2.y?p1.y:p2.y, p3.y));\r
+       x2 = long(mgl_max(p1.x>p2.x?p1.x:p2.x, p3.x));\r
+       y2 = long(mgl_max(p1.y>p2.y?p1.y:p2.y, p3.y));\r
        x1=x1>d->x1?x1:d->x1;   x2=x2<d->x2?x2:d->x2;\r
        y1=y1>d->y1?y1:d->y1;   y2=y2<d->y2?y2:d->y2;\r
-       if(x1>x2 || y1>y2)      return;\r
+//     if(x1>x2 || y1>y2)      return;\r
        // default normale\r
        mglPoint nr = mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z);\r
        float x0 = p1.x, y0 = p1.y;\r
-       if(Quality&MGL_DRAW_NORM)       for(long i=x1;i<=x2;i++)        for(long j=y1;j<=y2;j++)\r
+       float dz = Width>2 ? 1 : 1e-5*Width;    // provide additional height to be well visible on the surfaces\r
+       if(anorm)       dz=0;\r
+       int oi = d->ObjId, ang=d->angle;\r
+       mreal pw = d->PenWidth;\r
+       uint64_t pd = d->PDef;\r
+       if(Quality&MGL_DRAW_NORM)       for(long j=y1;j<=y2;j++)        for(long i=x1;i<=x2;i++)\r
        {\r
-               if(!visible(i,j,d->m, d->PenWidth,d->angle))    continue;\r
-               register float xx = (i-x0), yy = (j-y0);\r
-               register float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;\r
-               if(u<0 || v<0 || u+v>1) continue;\r
-               p = p1+d1*u+d2*v;\r
-               if(mgl_isnan(p.u) && mgl_isnum(p.v) && anorm)\r
-               {       p.u = nr.x;     p.v = nr.y;     p.w = nr.z;     }\r
-               pnt_plot(i,j,p.z,col2int(p,r,d->ObjId),d->ObjId);\r
+               if(pd==MGL_SOLID_MASK || visible(i,j,d->m, pw,ang))\r
+               {\r
+                       register float xx = (i-x0), yy = (j-y0);\r
+                       register float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;\r
+                       if(u<0 || v<0 || u+v>1) continue;\r
+                       p = p1+d1*u+d2*v;\r
+                       if(mgl_isnan(p.u) && mgl_isnum(p.v) && anorm)\r
+                       {       p.u = nr.x;     p.v = nr.y;     p.w = nr.z;     }\r
+                       pnt_plot(i,j,p.z+dz,col2int(p,r,oi),oi);\r
+               }\r
        }\r
-       else    for(long i=x1;i<=x2;i++)        for(long j=y1;j<=y2;j++)\r
+       else\r
        {\r
-               if(!visible(i,j,d->m, d->PenWidth,d->angle))    continue;\r
-               register float xx = (i-x0), yy = (j-y0);\r
-               register float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;\r
-               if(u<0 || v<0 || u+v>1) continue;\r
-               pnt_plot(i,j,p1.z,col2int(p1,r,d->ObjId),d->ObjId);\r
+               col2int(p1,r,oi);\r
+               float zz = p1.z+dz;\r
+               for(long j=y1;j<=y2;j++)        for(long i=x1;i<=x2;i++)\r
+               {\r
+                       if(pd==MGL_SOLID_MASK || visible(i,j,d->m, pw,ang))\r
+                       {\r
+                               register float xx = (i-x0), yy = (j-y0);\r
+                               register float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;\r
+                               if(u<0 || v<0 || u+v>1) continue;\r
+                               pnt_plot(i,j,zz,r,oi);\r
+                       }\r
+               }\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -916,7 +1069,6 @@ void mglCanvas::trig_pix(long i, long j, const mglPnt &p1, const mglPnt &p2, con
        pnt_plot(i,j,p.z,col2int(p,r,d->ObjId),d->ObjId);\r
 }\r
 //-----------------------------------------------------------------------------\r
-//#define mgl_sline(c,x)       (unsigned char)((c)/cosh(x))\r
 inline unsigned char mgl_sline(unsigned char c,float x)\r
 {      x*=x/2; return (unsigned char)((c)/(1+x+x*x/5));        }\r
 void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *dr)\r
@@ -927,8 +1079,9 @@ void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
 \r
        float pw=dr->PenWidth, dxu,dxv,dyu,dyv,dd,dpw=3;\r
        float dz = Width>2 ? 1 : 1e-5*Width;            // provide additional height to be well visible on the surfaces\r
+       int oi = dr->ObjId;\r
 \r
-       if(dr->ObjId==HighId)   {       pw *= 2;        dpw=2;  }\r
+       if(oi==HighId)  {       pw *= 2;        dpw=2;  }\r
        mglPnt d=p2-p1, p;\r
        bool hor = fabs(d.x)>fabs(d.y);\r
 \r
@@ -939,11 +1092,14 @@ void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
        x1=x1>dr->x1?x1:dr->x1; x2=x2<dr->x2?x2:dr->x2;\r
        y1=y1>dr->y1?y1:dr->y1; y2=y2<dr->y2?y2:dr->y2;\r
        dd = hypot(d.x, d.y);\r
-       if(x1>x2 || y1>y2 || dd<1e-5)   return;\r
+//     if(x1>x2 || y1>y2 || dd<1e-5)   return;\r
+       if(dd<1e-5)     return;\r
 \r
        dxv = d.y/dd;   dyv =-d.x/dd;\r
        dxu = d.x/dd;   dyu = d.y/dd;\r
 \r
+       uint64_t pd = dr->PDef;\r
+       mreal pp = dr->pPos;\r
        if(hor) for(long i=x1;i<=x2;i++)\r
        {\r
                y1 = int(p1.y+d.y*(i-p1.x)/d.x - pw - 3.5);\r
@@ -957,10 +1113,10 @@ void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
                        if(u<0)                 v += u*u;\r
                        else if(u>dd)   v += (u-dd)*(u-dd);\r
                        if(v>pw*pw)             continue;\r
-                       if(!(dr->PDef & ( 1<<long(fmod(dr->pPos+u/pw/1.5, 16)) ) ))     continue;\r
-                       p = p1+d*(u/dd);        col2int(p,r,dr->ObjId);\r
+                       if(!(pd & ( 1<<long(fmod(pp+u/pw/1.5, 16)) ) )) continue;\r
+                       p = p1+d*(u/dd);        col2int(p,r,oi);\r
                        r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
-                       pnt_plot(i,j,p.z+dz,r,dr->ObjId);\r
+                       pnt_plot(i,j,p.z+dz,r,oi);\r
                }\r
        }\r
        else    for(long j=y1;j<=y2;j++)\r
@@ -977,10 +1133,10 @@ void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
                        if(u<0)                 v += u*u;\r
                        else if(u>dd)   v += (u-dd)*(u-dd);\r
                        if(v>pw*pw)             continue;\r
-                       if(!(dr->PDef & (1<<long(fmod(dr->pPos+u/pw/1.5, 16)))))                continue;\r
-                       p = p1+d*(u/dd);        col2int(p,r,dr->ObjId);\r
+                       if(!(pd & (1<<long(fmod(pp+u/pw/1.5, 16)))))            continue;\r
+                       p = p1+d*(u/dd);        col2int(p,r,oi);\r
                        r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
-                       pnt_plot(i,j,p.z+dz,r,dr->ObjId);\r
+                       pnt_plot(i,j,p.z+dz,r,oi);\r
                }\r
        }\r
 }\r
@@ -996,7 +1152,8 @@ void mglCanvas::fast_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
 {\r
        if(p1.x==p2.x && p1.y==p2.y) return;\r
        mglPnt d=p2-p1;\r
-       unsigned char r[4];     col2int(p1,r,dr->ObjId);\r
+       int oi = dr->ObjId;\r
+       unsigned char r[4];     col2int(p1,r,oi);\r
        long y1,x1,y2,x2;\r
 \r
        bool hor = fabs(d.x)>fabs(d.y);\r
@@ -1012,13 +1169,13 @@ void mglCanvas::fast_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
        {\r
                register long c = long(p1.y+d.y*(i-p1.x)/d.x);\r
                if(c>=y1 && c<=y2)\r
-                       pnt_fast(i, c, p1.z+d.z*(i-p1.x)/d.x+dz, r,dr->ObjId);\r
+                       pnt_fast(i, c, p1.z+d.z*(i-p1.x)/d.x+dz, r,oi);\r
        }\r
        else    for(long i=y1;i<=y2;i++)\r
        {\r
                register long c = long(p1.x+d.x*(i-p1.y)/d.y);\r
                if(c>=x1 && c<=x2)\r
-                       pnt_fast(c, i, p1.z+d.z*(i-p1.y)/d.y+dz, r,dr->ObjId);\r
+                       pnt_fast(c, i, p1.z+d.z*(i-p1.y)/d.y+dz, r,oi);\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1046,23 +1203,24 @@ void mglCanvas::pnt_draw(const mglPnt &p, const mglDrawReg *dr)
 {\r
 //     if(k<0 || !dr)  return;\r
        float pw=3*dr->PenWidth,dpw=3;\r
-       if(dr->ObjId==HighId)   {       pw *= 2;        dpw=2;  }\r
+       int oi = dr->ObjId;\r
+       if(oi==HighId)  {       pw *= 2;        dpw=2;  }\r
        unsigned char cs[4], cc;\r
-       col2int(p,cs,dr->ObjId);        cc = cs[3];\r
+       col2int(p,cs,oi);       cc = cs[3];\r
        if(cc==0)       return;\r
        long s = long(5.5+fabs(pw));\r
-       long i1=fmax(-s,dr->x1-p.x),i2=fmin(s,dr->x2-p.x), j1=fmax(-s,dr->y1-p.y),j2=fmin(s,dr->y2-p.y);\r
+       long i1=mgl_max(-s,dr->x1-p.x),i2=mgl_min(s,dr->x2-p.x), j1=mgl_max(-s,dr->y1-p.y),j2=mgl_min(s,dr->y2-p.y);\r
        if(!(Quality&3))        for(long j=j1;j<=j2;j++)        for(long i=i1;i<=i2;i++)        // fast draw\r
        {\r
                register float v = i*i+j*j;\r
                if(v>1+(pw-1)*(pw-1)/4) continue;\r
-               pnt_plot(p.x+i,p.y+j,p.z,cs,dr->ObjId);\r
+               pnt_plot(p.x+i,p.y+j,p.z,cs,oi);\r
        }\r
        else    for(long j=j1;j<=j2;j++)        for(long i=i1;i<=i2;i++)\r
        {\r
                register float v = i*i+j*j;\r
                cs[3] = v<(pw-1)*(pw-1)/4 ? cc : mgl_sline(cc,dpw*(sqrt(v)+(1-pw)/2));\r
-               pnt_plot(p.x+i,p.y+j,p.z,cs,dr->ObjId);\r
+               pnt_plot(p.x+i,p.y+j,p.z,cs,oi);\r
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1080,7 +1238,8 @@ void mglCanvas::pnt_pix(long i, long j, const mglPnt &p, const mglDrawReg *dr)
 //-----------------------------------------------------------------------------\r
 void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)\r
 {\r
-       unsigned char cs[4], ca;        col2int(q,cs,d->ObjId); ca = cs[3];// = size>0 ? 255 : 255*q.t;\r
+       int oi = d->ObjId;\r
+       unsigned char cs[4], ca;        col2int(q,cs,oi);       ca = cs[3];// = size>0 ? 255 : 255*q.t;\r
        mreal ss=fabs(size), pw=1,dpw=3;\r
 \r
        if(type=='.' || ss==0)\r
@@ -1093,13 +1252,13 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                y1=y1>d->y1?y1:d->y1;   y2=y2<d->y2?y2:d->y2;\r
                if(x1>x2 || y1>y2)      return;\r
 \r
-               if(d->ObjId==HighId)    {       pw *= 2;        dpw=2;  }\r
+               if(oi==HighId)  {       pw *= 2;        dpw=2;  }\r
                for(long j=y1;j<=y2;j++)        for(long i=x1;i<=x2;i++)\r
                {\r
                        register float dx=i-q.x, dy=j-q.y, v=dx*dx+dy*dy;\r
                        register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                        cs[3] = ca*sum/255;\r
-                       pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                       pnt_plot(i,j,q.z+1,cs,oi);\r
                }\r
        }\r
        else\r
@@ -1107,11 +1266,11 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                if(d)\r
                {\r
                        d->PDef = MGL_SOLID_MASK;       d->angle = 0;\r
-                       pw = d->PenWidth*fabs(50*size);\r
+                       pw = d->PenWidth*sqrt(fabs(50*size));\r
                        if(pw<1)        pw=1;\r
                }\r
                if(!strchr("xsSoO",type))       ss *= 1.1;\r
-               if(d->ObjId==HighId)    {       pw *= 2;        dpw=2;  }\r
+               if(oi==HighId)  {       pw *= 2;        dpw=2;  }\r
 \r
                register mreal dd = ss+pw+3.5;\r
                long x1 = long(q.x-dd), y1 = long(q.y-dd);      // bounding box\r
@@ -1140,7 +1299,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(dx)-ss;        v = dy*dy+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case '+':\r
@@ -1153,7 +1312,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(dx)-ss;        v = dy*dy+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'X':\r
@@ -1176,7 +1335,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
 \r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'x':\r
@@ -1189,7 +1348,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(dx-dy)-2*ss;   v = dx+dy;      v = v*v+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'S':\r
@@ -1200,7 +1359,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                v = fabs(dx)-ss;        if(v<0) v=0;    v = u*u+v*v;\r
                                register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 's':\r
@@ -1217,7 +1376,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(dx)-ss;        v = (dy+ss)*(dy+ss)+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'D':\r
@@ -1228,7 +1387,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                v = fabs(dx+dy)-ss;     if(v<0) v=0;    v = u*u+v*v;\r
                                register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'd':\r
@@ -1245,7 +1404,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(dx-dy)-ss;     v = (dx+dy+ss)*(dx+dy+ss)+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'Y':\r
@@ -1260,7 +1419,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(-0.87*dx+0.5*dy-ss/2)-ss/2;    v = (0.5*dx+0.87*dy)*(0.5*dx+0.87*dy)+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case '*':\r
@@ -1275,7 +1434,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(-0.87*dx+0.5*dy)-ss;   v = (0.5*dx+0.87*dy)*(0.5*dx+0.87*dy)+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'T':\r
@@ -1295,7 +1454,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                        sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                        sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
                                }\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case '^':\r
@@ -1310,7 +1469,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(0.55*dx-0.83*dy)-0.9*ss;       v = 0.83*dx+0.55*dy-0.55*ss;    v = v*v+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'V':\r
@@ -1330,7 +1489,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                        sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                        sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
                                }\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'v':\r
@@ -1345,7 +1504,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(0.55*dx-0.83*dy)-0.9*ss;       v = 0.83*dx+0.55*dy+0.55*ss;    v = v*v+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'L':\r
@@ -1365,7 +1524,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                        sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                        sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
                                }\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case '<':\r
@@ -1380,7 +1539,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(0.55*dy-0.83*dx)-0.9*ss;       v = 0.83*dy+0.55*dx+0.55*ss;    v = v*v+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'R':\r
@@ -1400,7 +1559,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                        sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                        sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
                                }\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case '>':\r
@@ -1415,7 +1574,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                u = fabs(0.55*dy-0.83*dx)-0.9*ss;       v = 0.83*dy+0.55*dx-0.55*ss;    v = v*v+(u<0?0:u*u);\r
                                sum += v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'O':\r
@@ -1425,7 +1584,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                v = hypot(dx,dy)-ss;    v=v<0?0:v*v;\r
                                register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'o':\r
@@ -1435,7 +1594,7 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                v = hypot(dx,dy)-ss;    v=v*v;\r
                                register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                case 'C':\r
@@ -1446,8 +1605,8 @@ void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
                                register int sum = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                                v = dx*dx+dy*dy;\r
                                sum += v<(2*pw-1)*(2*pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-2*pw)/2));\r
-                               sum = sum>255?255:sum;  cs[3] = ca*sum/255;             cs[3] = ca*sum/255;\r
-                               pnt_plot(i,j,q.z+1,cs,d->ObjId);\r
+                               sum = sum>255?255:sum;  cs[3] = ca*sum/255;\r
+                               pnt_plot(i,j,q.z+1,cs,oi);\r
                        }\r
                        break;\r
                }\r
@@ -1576,15 +1735,14 @@ void mglCanvas::mark_pix(long i, long j, const mglPnt &q, char type, mreal size,
                                register float xx = (i-q.x), yy = (j-q.y);\r
                                register float dz = Width>2 ? 1 : 1e-5*Width;           // provide additional height to be well visible on the surfaces\r
                                if(xx*xx+yy*yy<ss*ss)   pnt_plot(i,j,q.z+dz,cs,d->ObjId);\r
-                               // TODO add edge smoothing here?\r
                        }\r
                case 'o':\r
                        {\r
-                               register float pw=d->PenWidth, dpw=2;\r
+                               register float pw=d->PenWidth;\r
                                register float xx = (i-q.x), yy = (j-q.y), v = hypot(xx,yy);\r
                                v = (v-ss)*(v-ss);\r
                                if(v>pw*pw)     return;\r
-                               if(v>(pw-1)*(pw-1)/4)   cs[3] = mgl_sline(cs[3],dpw*(sqrt(v)+(1-pw)/2));\r
+                               if(v>(pw-1)*(pw-1)/4)   cs[3] = mgl_sline(cs[3],2*(sqrt(v)+(1-pw)/2));\r
                                register float dz = Width>2 ? 1 : 1e-5*Width;           // provide additional height to be well visible on the surfaces\r
                                pnt_plot(i,j,q.z+dz,cs,d->ObjId);\r
                        }\r
@@ -1592,11 +1750,11 @@ void mglCanvas::mark_pix(long i, long j, const mglPnt &q, char type, mreal size,
                case 'C':\r
                        pnt_pix(i,j,q,d);\r
                        {\r
-                               register float pw=d->PenWidth, dpw=2;\r
+                               register float pw=d->PenWidth;\r
                                register float xx = (i-q.x), yy = (j-q.y), v = hypot(xx,yy);\r
                                v = (v-ss)*(v-ss);\r
                                if(v>pw*pw)     return;\r
-                               if(v>(pw-1)*(pw-1)/4)   cs[3] = mgl_sline(cs[3],dpw*(sqrt(v)+(1-pw)/2));\r
+                               if(v>(pw-1)*(pw-1)/4)   cs[3] = mgl_sline(cs[3],2*(sqrt(v)+(1-pw)/2));\r
                                register float dz = Width>2 ? 1 : 1e-5*Width;           // provide additional height to be well visible on the surfaces\r
                                pnt_plot(i,j,q.z+dz,cs,d->ObjId);\r
                        }\r
@@ -1617,8 +1775,8 @@ float mglCanvas::GetGlyphPhi(const mglPnt &q, float phi)
                y = Bp.b[3]*q.u + Bp.b[4]*q.v + Bp.b[5]*q.w;\r
                z = Bp.b[6]*q.u + Bp.b[7]*q.v + Bp.b[8]*q.w;\r
 \r
-               register float dv = (1-Bp.pf)/(1-Bp.pf*q.z/Depth);\r
-               register float c=Bp.pf/(1-Bp.pf)/Depth;\r
+               register float dv= get_persp(Bp.pf,q.z,Depth);\r
+               register float c = get_pfact(Bp.pf,Depth);\r
                x += (q.x-Width/2)*z*c*dv;\r
                y += (q.y-Height/2)*z*c*dv;\r
        }\r
@@ -1627,7 +1785,7 @@ float mglCanvas::GetGlyphPhi(const mglPnt &q, float phi)
        if(ll==ll && phi<1e4)\r
        {\r
                phi = -atan2(y,x)*180/M_PI;\r
-               if(fabs(phi)>90)        phi+=180;\r
+//             if(fabs(phi)>90)        phi+=180;       // NOTE this is 2nd part of rotation changes (see also text_plot())\r
        }\r
        else phi=0;\r
        return phi;\r
@@ -1641,7 +1799,8 @@ void mglCanvas::glyph_draw(const mglPrim &P, mglDrawReg *d)
        if(d)   {       d->PDef = MGL_SOLID_MASK;       d->angle = 0;   d->PenWidth=0.6;        }\r
        mglPnt p=Pnt[P.n1];\r
        // NOTE check this later for mglInPlot\r
-       mreal pf=p.sub<0?1:sqrt((Bp.b[0]*Bp.b[0]+Bp.b[1]*Bp.b[1]+Bp.b[3]*Bp.b[3]+Bp.b[4]*Bp.b[4])/2), f = P.p*pf;\r
+       mreal fact = get_persp(Bp.pf,p.z,Depth);\r
+       mreal pf=(p.sub<0?1:sqrt((Bp.b[0]*Bp.b[0]+Bp.b[1]*Bp.b[1]+Bp.b[3]*Bp.b[3]+Bp.b[4]*Bp.b[4])/2))*fact, f = P.p*pf;\r
 \r
        mglMatrix M;\r
        M.b[0] = M.b[4] = M.b[8] = P.s;\r
@@ -1686,7 +1845,6 @@ void mglCanvas::glyph_wire(const mglMatrix *M, const mglPnt &pp, mreal f, const
        long il=0;\r
        mglPnt q0=pp, q1=pp;    q0.u=q0.v=q1.u=q1.v=NAN;\r
        mglPoint p1,p2;\r
-//#pragma omp parallel for firstprivate(q0,q1,i1) private(p1,p2)\r
        for(long ik=0;ik<g.nl;ik++)\r
        {\r
                register long ii = 2*ik;\r
@@ -1786,7 +1944,6 @@ void mglCanvas::glyph_wpix(long i, long j, const mglMatrix *M, const mglPnt &pp,
        long il=0;\r
        mglPnt q0=pp, q1=pp;    q0.u=q0.v=q1.u=q1.v=NAN;\r
        mglPoint p1,p2;\r
-//#pragma omp parallel for firstprivate(q0,q1,i1) private(p1,p2)       // mostly useless here\r
        for(long ik=0;ik<g.nl;ik++)\r
        {\r
                register long ii = 2*ik;\r
@@ -1868,6 +2025,10 @@ void mglCanvas::arrow_draw(long n1, long n2, char st, float ll)
                        k1=setPp(q,p0+kl+kt);   k2=setPp(q,p0+kl-kt);\r
                        k3=setPp(q,p0-kl-kt);   k4=setPp(q,p0-kl+kt);\r
                        quad_plot(k1,k2,k4,k3); break;\r
+               case 'X':\r
+                       k1=setPp(q,p0+kl+kt);   k2=setPp(q,p0+kl-kt);\r
+                       k3=setPp(q,p0-kl-kt);   k4=setPp(q,p0-kl+kt);\r
+                       line_plot(k1,k3);       line_plot(k2,k4);       break;\r
                case 'T':\r
                        k1=setPp(q,p0-kl+kt);   k2=setPp(q,p0-kl-kt);   k3=setPp(q,p0+kl);\r
                        trig_plot(k1,k2,k3);    break;\r
@@ -1923,6 +2084,10 @@ void mglCanvas::arrow_plot_3d(long n1, long n2, char st, float ll)
                        k5=setPp(q,p0-kl+kt);   k6=setPp(q,p0-kl+kz);   k7=setPp(q,p0-kl-kt);   k8=setPp(q,p0-kl-kz);\r
                        quad_plot(k1,k2,k4,k3); quad_plot(k1,k2,k5,k6); quad_plot(k3,k2,k7,k6);\r
                        quad_plot(k1,k4,k5,k8); quad_plot(k3,k4,k7,k8); quad_plot(k5,k6,k8,k7); break;\r
+               case 'X':\r
+                       k1=setPp(q,p0+kl+kt);   k2=setPp(q,p0+kl+kz);   k3=setPp(q,p0+kl-kt);   k4=setPp(q,p0+kl-kz);\r
+                       k5=setPp(q,p0-kl+kt);   k6=setPp(q,p0-kl+kz);   k7=setPp(q,p0-kl-kt);   k8=setPp(q,p0-kl-kz);\r
+                       line_plot(k1,k7);       line_plot(k2,k8);       line_plot(k3,k5);       line_plot(k4,k6);       break;\r
                case 'T':\r
                        k1=setPp(q,p0-kl+kt);   k2=setPp(q,p0-kl+kz);   k3=setPp(q,p0-kl-kt);\r
                        k4=setPp(q,p0-kl-kz);   k5=setPp(q,p0+kl);\r
index c9ee24a69b4c1c437e13da661479ed630e165cad..592655b16ab862f339cf18b1dd20aed3d8509cfe 100644 (file)
@@ -37,33 +37,30 @@ void MGL_EXPORT mgl_fplot(HMGL gr, const char *eqY, const char *pen, const char
        mreal *y = (mreal *)malloc(n*sizeof(mreal));\r
        mglFormula *eq = new mglFormula(eqY);\r
        mreal xs, ys, yr, ym=fabs(gr->Max.y - gr->Min.y)/nd;\r
-#define islog(a, b) (((a)>0 && (b)>10*(a)) || ((b)<0 && (a)<10*(b)))\r
        // initial data filling\r
        if(gr->Min.x>0 && gr->Max.x>100*gr->Min.x)\r
        {\r
                mreal d = log(2*gr->Max.x/gr->Min.x)/(n-1);\r
-#pragma omp parallel for\r
                for(long i=0;i<n;i++)\r
                {       x[i]=2*gr->Max.x*exp(d*i)/(2*gr->Max.x/gr->Min.x+exp(d*i));     y[i]=eq->Calc(x[i]);    }\r
        }\r
        else if(gr->Max.x<0 && gr->Min.x<100*gr->Max.x)\r
        {\r
                mreal d = log(2*gr->Min.x/gr->Max.x)/(n-1);\r
-#pragma omp parallel for\r
                for(long i=0;i<n;i++)\r
                {       x[i]=2*gr->Min.x*exp(d*i)/(2*gr->Min.x/gr->Max.x+exp(d*i));     y[i]=eq->Calc(x[i]);    }\r
        }\r
        else\r
        {\r
                mreal d = (gr->Max.x - gr->Min.x)/(n-1.);\r
-#pragma omp parallel for\r
                for(long i=0;i<n;i++)\r
                {       x[i]=gr->Min.x + i*d;   y[i]=eq->Calc(x[i]);    }\r
        }\r
 \r
        for(long i=0;i<n-1 && n<nm;)\r
        {\r
-               if(gr->Stop)    {       free(x);        free(y);        delete eq;      return; }\r
+               if((i&0xfff)==0 && gr->NeedStop())\r
+               {       free(x);        free(y);        delete eq;      return; }\r
                xs=(x[i]+x[i+1])/2;\r
                ys=(y[i]+y[i+1])/2;     yr=eq->Calc(xs);\r
                if(fabs(yr-ys)>ym)      // bad approximation here\r
@@ -78,9 +75,8 @@ void MGL_EXPORT mgl_fplot(HMGL gr, const char *eqY, const char *pen, const char
        }\r
 \r
        delete eq;\r
-       mglData yy,xx;\r
-       xx.Set(x,n);    free(x);\r
-       yy.Set(y,n);    free(y);\r
+       mglData yy(y,n),xx(x,n);\r
+       free(x);        free(y);\r
        mgl_plot_xy(gr,&xx,&yy,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -98,10 +94,8 @@ void MGL_EXPORT mgl_fplot_xyz(HMGL gr, const char *eqX, const char *eqY, const c
        ey = new mglFormula(eqY ? eqY : "0");\r
        ez = new mglFormula(eqZ ? eqZ : "0");\r
        mreal ts, xs, ys, zs, xr, yr, zr, xm=fabs(gr->Max.x - gr->Min.x)/1000, ym=fabs(gr->Max.y - gr->Min.y)/1000, zm=fabs(gr->Max.z - gr->Min.z)/1000;\r
-#pragma omp parallel for\r
        for(long i=0;i<n;i++)   // initial data filling\r
        {\r
-               if(gr->Stop)    continue;\r
                t[i] = i/(n-1.);\r
                x[i] = ex->Calc(0,0,t[i]);\r
                y[i] = ey->Calc(0,0,t[i]);\r
@@ -110,7 +104,7 @@ void MGL_EXPORT mgl_fplot_xyz(HMGL gr, const char *eqX, const char *eqY, const c
 \r
        for(long i=0;i<n-1 && n<10000;)\r
        {\r
-               if(gr->Stop)\r
+               if((i&0xfff)==0 && gr->NeedStop())\r
                {\r
                        free(x);        free(y);        free(z);        free(t);\r
                        delete ex;      delete ey;      delete ez;      return;\r
@@ -135,8 +129,7 @@ void MGL_EXPORT mgl_fplot_xyz(HMGL gr, const char *eqX, const char *eqY, const c
        }\r
        delete ex;      delete ey;      delete ez;\r
 \r
-       mglData xx,yy,zz;\r
-       xx.Set(x,n);    yy.Set(y,n);    zz.Set(z,n);\r
+       mglData xx(x,n),yy(y,n),zz(z,n);\r
        free(x);        free(y);        free(z);        free(t);\r
        mgl_plot_xyz(gr,&xx,&yy,&zz,pen,0);\r
 }\r
@@ -169,11 +162,9 @@ void MGL_EXPORT mgl_radar(HMGL gr, HCDT a, const char *pen, const char *opt)
        mreal m=a->Minimal(), r=gr->SaveState(opt);\r
        if(mgl_isnan(r) || r<0) r = m<0 ? -m:0;\r
        mreal *co=new mreal[2*n];\r
-#pragma omp parallel for\r
        for(long i=0;i<n;i++)   {       co[i]=cos(2*i*M_PI/n);  co[i+n]=sin(2*i*M_PI/n);        }\r
        for(long j=0;j<ny;j++)\r
        {\r
-#pragma omp parallel for\r
                for(long i=0;i<n;i++)\r
                {\r
                        register mreal v = a->v(i,j);\r
@@ -195,7 +186,6 @@ void MGL_EXPORT mgl_radar(HMGL gr, HCDT a, const char *pen, const char *opt)
                if(r>0)\r
                {\r
                        x.Create(101);  y.Create(101);\r
-#pragma omp parallel for\r
                        for(long i=0;i<91;i++)\r
                        {       x.a[i]=r*mgl_cos[(4*i)%360];    y.a[i]=r*mgl_cos[(270+4*i)%360];        }\r
                        mgl_plot_xy(gr,&x,&y,"k",0);\r
@@ -233,10 +223,8 @@ void MGL_EXPORT mgl_candle_xyv(HMGL gr, HCDT x, HCDT v1, HCDT v2, HCDT y1, HCDT
        if(mglchr(pen,'^'))     dv = 0;\r
        if(mglchr(pen,'>'))     dv = -1;\r
        mreal zm = gr->AdjustZMin();\r
-#pragma omp parallel for\r
        for(long i=0;i<n;i++)\r
        {\r
-               if(gr->Stop)    continue;\r
                mreal m1=v1->v(i),      m2 = v2->v(i),  xx = x->v(i);\r
                mreal d = i<nx-1 ? x->v(i+1)-xx : xx-x->v(i-1);\r
                mreal x1 = xx + d/2*(dv-gr->BarWidth);\r
@@ -264,7 +252,7 @@ void MGL_EXPORT mgl_candle_xyv(HMGL gr, HCDT x, HCDT v1, HCDT v2, HCDT y1, HCDT
 void MGL_EXPORT mgl_candle_yv(HMGL gr, HCDT v1, HCDT v2, HCDT y1, HCDT y2, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(v1->GetNx()+1);\r
+       mglDataV x(v1->GetNx()+1);\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        mgl_candle_xyv(gr,&x,v1,v2,y1,y2,pen,0);\r
 }\r
@@ -296,29 +284,42 @@ void MGL_EXPORT mgl_candle_(uintptr_t *gr, uintptr_t *y, uintptr_t *y1, uintptr_
 //     Plot series\r
 //\r
 //-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_mark(HMGL gr, double x, double y, double z,const char *mark);\r
 void MGL_EXPORT mgl_plot_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
 {\r
-       long j,m,mx,my,mz,n=y->GetNx(),pal;\r
+       static int cgid=1;\r
+       long n=y->GetNx(),pal;\r
+       if(n<2 && !mgl_check_dim0(gr,x,y,z,0,"Plot"))\r
+       {\r
+               gr->StartGroup("Plot",cgid++);\r
+               gr->SaveState(opt);\r
+\r
+               char mk = gr->SetPenPal(pen);\r
+               if(mk)\r
+               {\r
+                       long k = gr->AddPnt(mglPoint(x->v(0),y->v(0),z->v(0)),gr->CDef,mglPoint(NAN),-1,3);\r
+                       gr->mark_plot(k,mk,gr->GetPenWidth());  gr->AddActive(k);\r
+               }\r
+               gr->EndGroup(); return;\r
+       }\r
        if(mgl_check_dim1(gr,x,y,z,0,"Plot"))   return;\r
 \r
-       static int cgid=1;      gr->StartGroup("Plot",cgid++);\r
+       gr->StartGroup("Plot",cgid++);\r
        gr->SaveState(opt);\r
-       m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();  m = z->GetNy() > m ? z->GetNy() : m;\r
+       long m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();     m = z->GetNy() > m ? z->GetNy() : m;\r
        char mk=gr->SetPenPal(pen,&pal);        gr->Reserve(2*n*m);\r
-       bool t1,t2,t3;\r
        mglPoint p1,nn,p2,pt;\r
        long n1=-1,n2=-1,n3=-1;\r
        bool sh = mglchr(pen,'!');\r
 \r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
-               mz = j<z->GetNy() ? j:0;        gr->NextColor(pal);\r
-               t1 = t2 = false;\r
-               register long i;\r
-               for(i=0;i<n;i++)\r
+               if(gr->NeedStop())      break;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
+               gr->NextColor(pal);\r
+               bool t1 = false, t2 = false;\r
+               for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
                        if(i>0) {       n2=n1;  p2 = p1;        t2=t1;  }\r
                        p1 = mglPoint(x->v(i,mx), y->v(i,my), z->v(i,mz));\r
                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
@@ -340,7 +341,7 @@ void MGL_EXPORT mgl_plot_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
                                        pt.x = p1.x*ii+p2.x*(1-ii);\r
                                        pt.y = p1.y*ii+p2.y*(1-ii);\r
                                        pt.z = p1.z*ii+p2.z*(1-ii);     p=pt;\r
-                                       t3 = gr->ScalePoint(gr->GetB(),p,q,false);\r
+                                       bool t3 = gr->ScalePoint(gr->GetB(),p,q,false);\r
                                        if((t1 && t3) || (t2 && !t3))   i2 = ii;\r
                                        else    i1 = ii;\r
                                } while(fabs(i2-i1)>1e-3);\r
@@ -356,8 +357,7 @@ void MGL_EXPORT mgl_plot_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
 void MGL_EXPORT mgl_plot_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData z(y->GetNx());\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
        mgl_plot_xyz(gr,x,y,&z,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -366,9 +366,8 @@ void MGL_EXPORT mgl_plot(HMGL gr, HCDT y, const char *pen, const char *opt)
        register long n=y->GetNx();\r
        if(n<2) {       gr->SetWarn(mglWarnLow,"Plot"); return; }\r
        gr->SaveState(opt);\r
-       mglData x(n), z(n);\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV x(n), z(n);\r
+       x.Fill(gr->Min.x,gr->Max.x);    z.Fill(gr->AdjustZMin());\r
        mgl_plot_xyz(gr,&x,y,&z,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -393,7 +392,7 @@ void MGL_EXPORT mgl_plot_(uintptr_t *gr, uintptr_t *y,      const char *pen, const ch
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_tens_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char *pen, const char *opt)\r
 {\r
-       long j,m,mx,my,mz,mc,n=y->GetNx(), pal;\r
+       long m,n=y->GetNx(), pal;\r
        if(mgl_check_dim1(gr,x,y,z,0,"Tens"))   return;\r
 \r
        gr->SaveState(opt);\r
@@ -401,19 +400,18 @@ void MGL_EXPORT mgl_tens_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char
        m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();  m = z->GetNy() > m ? z->GetNy() : m;\r
        char mk=gr->SetPenPal(pen, &pal);       gr->Reserve(2*n*m);\r
        long ss=gr->AddTexture(pen);\r
-       bool t1,t2,t3;\r
        mglPoint p1,p2,pt,nn;\r
        long n1=-1,n2=-1,n3=-1;\r
 \r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
-               mz = j<z->GetNy() ? j:0;        mc = j<c->GetNy() ? j:0;\r
+               if(gr->NeedStop())      break;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
+               long mz = j<z->GetNy() ? j:0, mc = j<c->GetNy() ? j:0;\r
                register long i;\r
-               t1 = t2 = false;\r
+               bool t1 = false, t2 = false;\r
                for(i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
                        if(i>0) {       n2=n1;  p2=p1;  t2=t1;  }\r
                        p1 = mglPoint(x->v(i,mx), y->v(i,my), z->v(i,mz), c->v(i,mc));\r
                        n1 = gr->AddPnt(p1,gr->GetC(ss,p1.c));  t1 = n1>=0;\r
@@ -435,7 +433,7 @@ void MGL_EXPORT mgl_tens_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char
                                        pt.y = p1.y*ii+p2.y*(1-ii);\r
                                        pt.z = p1.z*ii+p2.z*(1-ii);     p=pt;\r
                                        pt.c = p1.c*ii+p2.c*(1-ii);\r
-                                       t3 = gr->ScalePoint(gr->GetB(),p,q,false);\r
+                                       bool t3 = gr->ScalePoint(gr->GetB(),p,q,false);\r
                                        if((t1 && t3) || (t2 && !t3))   i2 = ii;\r
                                        else    i1 = ii;\r
                                } while(fabs(i2-i1)>1e-3);\r
@@ -451,8 +449,7 @@ void MGL_EXPORT mgl_tens_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char
 void MGL_EXPORT mgl_tens_xy(HMGL gr, HCDT x, HCDT y, HCDT c, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData z(y->GetNx());\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
        mgl_tens_xyz(gr,x,y,&z,c,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -461,9 +458,8 @@ void MGL_EXPORT mgl_tens(HMGL gr, HCDT y, HCDT c, const char *pen, const char *o
        register long n=y->GetNx();\r
        if(n<2) {       gr->SetWarn(mglWarnLow,"Tens"); return; }\r
        gr->SaveState(opt);\r
-       mglData x(n), z(n);\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV x(n), z(n);\r
+       x.Fill(gr->Min.x,gr->Max.x);    z.Fill(gr->AdjustZMin());\r
        mgl_tens_xyz(gr,&x,y,&z,c,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -488,7 +484,7 @@ void MGL_EXPORT mgl_tens_(uintptr_t *gr, uintptr_t *y, uintptr_t *c, const char
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_area_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
 {\r
-       long i,j,n=y->GetNx(),m,mx,my,mz,pal;\r
+       long n=y->GetNx(),m,pal;\r
        if(mgl_check_dim1(gr,x,y,z,0,"Area"))   return;\r
 \r
        gr->SaveState(opt);\r
@@ -500,22 +496,21 @@ void MGL_EXPORT mgl_area_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
        mreal z0=gr->GetOrgZ('x');\r
        mreal c1,c2;\r
        mglPoint p1,p2,p3,p4,nn;\r
-       long n1,n2,n3,n4;\r
        gr->SetPenPal(pen,&pal);        gr->Reserve(2*n*m);\r
-//     long s=gr->AddTexture(pen,1);\r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                c2=c1=gr->NextColor(pal);\r
                if(gr->GetNumPal(pal)==2*m && !sh)      c2 = gr->NextColor(pal);\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;        mz = j<z->GetNy() ? j:0;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
 \r
                nn = mglPoint(-y->dvx(0,my),x->dvx(0,mx));\r
                mglPoint p = mglPoint(x->v(0,mx),y->v(0,my),z->v(0,mz));\r
-               n1 = gr->AddPnt(p,c1,nn,-1,11); p.z = z0;       n2 = gr->AddPnt(p,c2,nn,-1,11);\r
-               for(i=1;i<n;i++)\r
+               long n1 = gr->AddPnt(p,c1,nn,-1,11);    p.z = z0;\r
+               long n2 = gr->AddPnt(p,c2,nn,-1,11);\r
+               for(long i=1;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
-                       n3=n1;  n4=n2;\r
+                       long n3=n1, n4=n2;\r
                        nn = mglPoint(-y->dvx(i,my),x->dvx(i,mx));\r
                        p = mglPoint(x->v(i,mx),y->v(i,my),z->v(i,mz));\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
@@ -533,34 +528,34 @@ void MGL_EXPORT mgl_area_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_area_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
 {\r
-       long i,j,n=y->GetNx(),m=y->GetNy(),mx,my,pal;\r
+       long n=y->GetNx(),m=y->GetNy(),pal;\r
        if(mgl_check_dim1(gr,x,y,0,0,"Area"))   return;\r
 \r
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("Curve",cgid++);\r
        mreal zm = gr->AdjustZMin();\r
-       mreal y0=gr->GetOrgY('x'), z0;\r
+       mreal y0=gr->GetOrgY('x');\r
        mreal c1,c2;\r
        mglPoint nn=mglPoint(0,0,1);\r
-       long n1,n2,n3,n4;\r
        bool sh = mglchr(pen,'!');\r
        bool wire = mglchr(pen,'#');\r
 \r
        gr->SetPenPal(pen,&pal);        gr->Reserve(2*n*m);\r
 //     long s=gr->AddTexture(pen,1);\r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                c2=c1=gr->NextColor(pal);\r
                if(gr->GetNumPal(pal)==2*m && !sh)      c2=gr->NextColor(pal);\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
-               z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
+               mreal z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
 \r
                mglPoint p = mglPoint(x->v(0,mx),y->v(0,my),z0);\r
-               n1 = gr->AddPnt(p,c1,nn,-1,11); p.y = y0;       n2 = gr->AddPnt(p,c2,nn,-1,11);\r
-               for(i=1;i<n;i++)\r
+               long n1 = gr->AddPnt(p,c1,nn,-1,11);    p.y = y0;\r
+               long n2 = gr->AddPnt(p,c2,nn,-1,11);\r
+               for(long i=1;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
-                       n3=n1;  n4=n2;\r
+                       long n3=n1, n4=n2;\r
                        p = mglPoint(x->v(i,mx),y->v(i,my),z0);\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
                        n1 = gr->AddPnt(p,c1,nn,-1,11); p.y = y0;       n2 = gr->AddPnt(p,c2,nn,-1,11);\r
@@ -578,8 +573,7 @@ void MGL_EXPORT mgl_area_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char
 void MGL_EXPORT mgl_area(HMGL gr, HCDT y, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(y->GetNx());\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
+       mglDataV x(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x);\r
        mgl_area_xy(gr,&x,y,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -604,7 +598,7 @@ void MGL_EXPORT mgl_area_(uintptr_t *gr, uintptr_t *y, const char *pen, const ch
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_region_3d(HMGL gr, HCDT x1, HCDT y1, HCDT z1, HCDT x2, HCDT y2, HCDT z2, const char *pen, const char *opt)\r
 {\r
-       long i,j, n=y1->GetNx(), m, mx, my, mz, pal;\r
+       long n=y1->GetNx(), m, pal;\r
        if(mgl_check_dim1(gr,x1,y1,z1,0,"Region"))      return;\r
        if(mgl_check_dim1(gr,x1,x2,y2,z2,"Region"))     return;\r
        m = x1->GetNy() > y1->GetNy() ? x1->GetNy() : y1->GetNy();      m = z1->GetNy() > m ? z1->GetNy() : m;\r
@@ -618,28 +612,25 @@ void MGL_EXPORT mgl_region_3d(HMGL gr, HCDT x1, HCDT y1, HCDT z1, HCDT x2, HCDT
        static int cgid=1;      gr->StartGroup("Region",cgid++);\r
        mreal c1,c2;\r
        mglPoint nn=mglPoint(0,0,1);\r
-       long n1,n2,n3,n4;\r
        mreal zm = gr->AdjustZMin();\r
 //     bool inside = (mglchr(pen,'i'));        // NOTE: check if 'i' is free (used here for inside flag)\r
        bool sh = mglchr(pen,'!');\r
 \r
        gr->SetPenPal(pen,&pal);        gr->Reserve(2*n*m);\r
-//     long s=gr->AddTexture(pen,1);\r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                c2=c1=gr->NextColor(pal);\r
                if(gr->GetNumPal(pal)==2*m && !sh)      c2=gr->NextColor(pal);\r
-               mx = j<x1->GetNy() ? j:0;\r
-               my = j<y1->GetNy() ? j:0;\r
-               mz = (zhave && j<z1->GetNy()) ? j:0;\r
+               long mx = j<x1->GetNy() ? j:0, my = j<y1->GetNy() ? j:0;\r
+               long mz = (zhave && j<z1->GetNy()) ? j:0;\r
                mreal z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
 \r
-               n1 = gr->AddPnt(mglPoint(x1->v(0,mx),y1->v(0,my),zhave?z1->v(0,mz):z0),c1,nn,-1,11);\r
-               n2 = gr->AddPnt(mglPoint(x2->v(0,mx),y2->v(0,my),zhave?z2->v(0,mz):z0),c2,nn,-1,11);\r
-               for(i=1;i<n;i++)\r
+               long n1 = gr->AddPnt(mglPoint(x1->v(0,mx),y1->v(0,my),zhave?z1->v(0,mz):z0),c1,nn,-1,11);\r
+               long n2 = gr->AddPnt(mglPoint(x2->v(0,mx),y2->v(0,my),zhave?z2->v(0,mz):z0),c2,nn,-1,11);\r
+               for(long i=1;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
-                       n3=n1;  n4=n2;\r
+                       long n3=n1, n4=n2;\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
                        n1 = gr->AddPnt(mglPoint(x1->v(i,mx),y1->v(i,my),zhave?z1->v(i,mz):z0),c1,nn,-1,11);\r
                        n2 = gr->AddPnt(mglPoint(x2->v(i,mx),y2->v(i,my),zhave?z2->v(i,mz):z0),c2,nn,-1,11);\r
@@ -651,7 +642,7 @@ void MGL_EXPORT mgl_region_3d(HMGL gr, HCDT x1, HCDT y1, HCDT z1, HCDT x2, HCDT
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_region_xy(HMGL gr, HCDT x, HCDT y1, HCDT y2, const char *pen, const char *opt)\r
 {\r
-       long i,j, n=y1->GetNx(), m=y1->GetNy(), mx, pal;\r
+       long n=y1->GetNx(), m=y1->GetNy(), pal;\r
        if(mgl_check_dim1(gr,x,y1,y2,0,"Region"))       return;\r
        if(y2->GetNy()!=m)      {       gr->SetWarn(mglWarnDim,"Region");       return; }\r
 \r
@@ -659,28 +650,27 @@ void MGL_EXPORT mgl_region_xy(HMGL gr, HCDT x, HCDT y1, HCDT y2, const char *pen
        static int cgid=1;      gr->StartGroup("Region",cgid++);\r
        mreal c1,c2;\r
        mglPoint nn=mglPoint(0,0,1);\r
-       long n1,n2,n3,n4;\r
-       mreal xx,f1,f2,f3,f4;\r
        mreal zm = gr->AdjustZMin();\r
        bool inside = (mglchr(pen,'i'));        // NOTE: check if 'i' is free (used here for inside flag)\r
        bool sh = mglchr(pen,'!');\r
 \r
        gr->SetPenPal(pen,&pal);        gr->Reserve(2*n*m);\r
 //     long s=gr->AddTexture(pen,1);\r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                c2=c1=gr->NextColor(pal);\r
                if(gr->GetNumPal(pal)==2*m && !sh)      c2=gr->NextColor(pal);\r
-               mx = j<x->GetNy() ? j:0;\r
+               long mx = j<x->GetNy() ? j:0;\r
                mreal z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
 \r
-               f1 = y1->v(0,j);        f2 = y2->v(0,j);        xx = x->v(0,mx);\r
-               n1 = gr->AddPnt(mglPoint(xx,f1,z0),c1,nn,-1,11);\r
-               n2 = gr->AddPnt(mglPoint(xx,f2,z0),c2,nn,-1,11);\r
-               for(i=1;i<n;i++)\r
+               mreal f1 = y1->v(0,j), f2 = y2->v(0,j), xx = x->v(0,mx);\r
+               long n1 = gr->AddPnt(mglPoint(xx,f1,z0),c1,nn,-1,11);\r
+               long n2 = gr->AddPnt(mglPoint(xx,f2,z0),c2,nn,-1,11);\r
+               for(long i=1;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
-                       n3=n1;  n4=n2;  f3=f1;  f4=f2;\r
+                       long n3=n1, n4=n2;\r
+                       mreal f3=f1, f4=f2;\r
                        f1 = y1->v(i,j);        f2 = y2->v(i,j);        xx = x->v(i,mx);\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
                        n1 = gr->AddPnt(mglPoint(xx,f1,z0),c1,nn,-1,11);\r
@@ -694,8 +684,7 @@ void MGL_EXPORT mgl_region_xy(HMGL gr, HCDT x, HCDT y1, HCDT y2, const char *pen
 void MGL_EXPORT mgl_region(HMGL gr, HCDT y1, HCDT y2, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(y1->GetNx());\r
-       x.Fill(gr->Min.x, gr->Max.x);\r
+       mglDataV x(y1->GetNx());        x.Fill(gr->Min.x, gr->Max.x);\r
        mgl_region_xy(gr,&x,y1,y2,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -720,7 +709,7 @@ void MGL_EXPORT mgl_region_(uintptr_t *gr, uintptr_t *y1, uintptr_t *y2, const c
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_step_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
 {\r
-       long i,j,m,mx,my,mz,n=y->GetNx(), pal;\r
+       long m,n=y->GetNx(), pal;\r
        if(mgl_check_dim1(gr,x,y,z,0,"Step"))   return;\r
 \r
        gr->SaveState(opt);\r
@@ -729,18 +718,17 @@ void MGL_EXPORT mgl_step_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
        bool sh = mglchr(pen,'!');\r
 \r
        char mk=gr->SetPenPal(pen,&pal);        gr->Reserve(2*n*m);\r
-       long n1,n2;\r
        mglPoint p;\r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
-               mz = j<z->GetNy() ? j:0;        gr->NextColor(pal);\r
-               n1 = gr->AddPnt(mglPoint(x->v(0,mx), y->v(0,my), z->v(0,mz)));\r
+               if(gr->NeedStop())      break;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
+               gr->NextColor(pal);\r
+               long n1 = gr->AddPnt(mglPoint(x->v(0,mx), y->v(0,my), z->v(0,mz)));\r
                if(mk)  gr->mark_plot(n1,mk);\r
-               for(i=1;i<n;i++)\r
+               for(long i=1;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
-                       n2 = n1;        // horizontal\r
+                       long n2 = n1;   // horizontal\r
                        p = mglPoint(x->v(i,mx), y->v(i,my), z->v(i-1,mz));\r
                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
                        n1 = gr->AddPnt(p,c);   gr->line_plot(n1,n2);\r
@@ -758,7 +746,7 @@ void MGL_EXPORT mgl_step_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_step_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
 {\r
-       long i,j,m,mx,my,n=y->GetNx(), pal;\r
+       long m,n=y->GetNx(), pal;\r
        if(mgl_check_dim1(gr,x,y,0,0,"Step"))   return;\r
 \r
        gr->SaveState(opt);\r
@@ -768,18 +756,17 @@ void MGL_EXPORT mgl_step_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char
 \r
        mreal zVal =gr->AdjustZMin();\r
        char mk=gr->SetPenPal(pen,&pal);        gr->Reserve(2*n*m);\r
-       long n1,n2;\r
        mglPoint p;\r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
+               if(gr->NeedStop())      break;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
                gr->NextColor(pal);\r
-               n1 = gr->AddPnt(mglPoint(x->v(0,mx), y->v(0,my), zVal));\r
+               long n1 = gr->AddPnt(mglPoint(x->v(0,mx), y->v(0,my), zVal));\r
                if(mk)  gr->mark_plot(n1,mk);\r
-               for(i=1;i<n;i++)\r
+               for(long i=1;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
-                       n2 = n1;        // horizontal\r
+                       long n2 = n1;   // horizontal\r
                        p = mglPoint(x->v(i,mx), y->v(i-1,my), zVal);\r
                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
                        n1 = gr->AddPnt(p,c);   gr->line_plot(n1,n2);\r
@@ -798,8 +785,7 @@ void MGL_EXPORT mgl_step_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char
 void MGL_EXPORT mgl_step(HMGL gr, HCDT y,      const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(y->GetNx());\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
+       mglDataV x(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x);\r
        mgl_step_xy(gr,&x,y,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -824,7 +810,7 @@ void MGL_EXPORT mgl_step_(uintptr_t *gr, uintptr_t *y,      const char *pen, const ch
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_stem_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
 {\r
-       long m,mx,my,mz,n=y->GetNx(), pal;\r
+       long m,n=y->GetNx(), pal;\r
        if(mgl_check_dim0(gr,x,y,z,0,"Stem"))   return;\r
 \r
        gr->SaveState(opt);\r
@@ -836,12 +822,11 @@ void MGL_EXPORT mgl_stem_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
        char mk=gr->SetPenPal(pen,&pal);        gr->Reserve(2*n*m);\r
        for(long j=0;j<m;j++)\r
        {\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
-               mz = j<z->GetNy() ? j:0;        gr->NextColor(pal);\r
-#pragma omp parallel for\r
+               if(gr->NeedStop())      break;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
+               gr->NextColor(pal);\r
                for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
                        long n1 = gr->AddPnt(mglPoint(x->v(i,mx), y->v(i,my), z->v(i,mz)),c);\r
                        if(mk)  gr->mark_plot(n1,mk);\r
@@ -854,7 +839,7 @@ void MGL_EXPORT mgl_stem_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_stem_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
 {\r
-       long m,mx,my,n=y->GetNx(), pal;\r
+       long m,n=y->GetNx(), pal;\r
        if(mgl_check_dim0(gr,x,y,0,0,"Stem"))   return;\r
 \r
        gr->SaveState(opt);\r
@@ -866,12 +851,11 @@ void MGL_EXPORT mgl_stem_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char
        char mk=gr->SetPenPal(pen,&pal);        gr->Reserve(2*n*m);\r
        for(long j=0;j<m;j++)\r
        {\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
+               if(gr->NeedStop())      break;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
                gr->NextColor(pal);\r
-#pragma omp parallel for\r
                for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        mreal vv = x->v(i,mx);\r
                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
                        long n1 = gr->AddPnt(mglPoint(vv, y->v(i,my), zVal),c);\r
@@ -886,8 +870,7 @@ void MGL_EXPORT mgl_stem_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char
 void MGL_EXPORT mgl_stem(HMGL gr, HCDT y,      const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(y->GetNx());\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
+       mglDataV x(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x);\r
        mgl_stem_xy(gr,&x,y,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -912,7 +895,7 @@ void MGL_EXPORT mgl_stem_(uintptr_t *gr, uintptr_t *y,      const char *pen, const ch
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_bars_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
 {\r
-       long m,mx,my,mz,n=z->GetNx(), pal,nx=x->GetNx(),ny=y->GetNx();\r
+       long m,n=z->GetNx(), pal,nx=x->GetNx(),ny=y->GetNx();\r
        if(mgl_check_dim1(gr,x,z,y,0,"Bars",true))      return;\r
 \r
        gr->SaveState(opt);\r
@@ -935,14 +918,13 @@ void MGL_EXPORT mgl_bars_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
        gr->Reserve(4*n*m);\r
        for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                c2=c1=gr->NextColor(pal);\r
                if(gr->GetNumPal(pal)==2*m && !sh)      c2 = gr->NextColor(pal);\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;        mz = j<z->GetNy() ? j:0;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
                zp = z0 = gr->GetOrgZ('x');\r
-#pragma omp parallel for ordered\r
                for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
                        mreal vv = x->v(i,mx), d = i<nx-1 ? x->v(i+1,mx)-vv : vv-x->v(i-1,mx), zz;\r
                        mreal x1 = vv + d/2*(dv-gr->BarWidth), x2 = x1 + gr->BarWidth*d;\r
@@ -955,11 +937,8 @@ void MGL_EXPORT mgl_bars_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
                                y2 = (y2-y1)/m;         y1 += j*y2;             y2 += y1;\r
                        }\r
                        else\r
-#pragma omp ordered\r
                        {       z0 = gr->GetOrgZ('x') + dd[i];  dd[i] += zz;    zz += z0;       }\r
-                       if(fall)\r
-#pragma omp ordered\r
-                       {       z0 = zp;        zz += z0;       zp = zz;        }\r
+                       if(fall)        {       z0 = zp;        zz += z0;       zp = zz;        }\r
 \r
                        mreal c = vv<0 ? c1 : c2;\r
                        mglPoint nn = mglPoint(-y->dvx(i,my),x->dvx(i,mx));\r
@@ -980,7 +959,7 @@ void MGL_EXPORT mgl_bars_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_bars_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
 {\r
-       long m,mx,my,n=y->GetNx(),nx=x->GetNx(),pal;\r
+       long m,n=y->GetNx(),nx=x->GetNx(),pal;\r
        if(mgl_check_dim1(gr,x,y,0,0,"Bars",true))      return;\r
 \r
        gr->SaveState(opt);\r
@@ -1003,14 +982,13 @@ void MGL_EXPORT mgl_bars_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char
        gr->Reserve(4*n*m);\r
        for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                c2=c1=gr->NextColor(pal);\r
                if(gr->GetNumPal(pal)==2*m && !sh)      c2 = gr->NextColor(pal);\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
                yp = y0 = gr->GetOrgY('x');\r
-#pragma omp parallel for ordered\r
                for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
                        mreal vv = x->v(i,mx), d = i<nx-1 ? x->v(i+1,mx)-vv : vv-x->v(i-1,mx), yy;\r
                        mreal x1 = vv + d/2*(dv-gr->BarWidth), x2 = x1 + gr->BarWidth*d;\r
@@ -1018,11 +996,8 @@ void MGL_EXPORT mgl_bars_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char
                        if(!above)\r
                        {       x2 = (x2-x1)/m;         x1 += j*x2;             x2 += x1;       }\r
                        else\r
-#pragma omp ordered\r
                        {       y0 = gr->GetOrgY('x') + dd[i];  dd[i] += yy;    yy += y0;       }\r
-                       if(fall)\r
-#pragma omp ordered\r
-                       {       y0 = yp;        yy += y0;       yp = yy;        }\r
+                       if(fall)        {       y0 = yp;        yy += y0;       yp = yy;        }\r
 \r
                        mreal c = vv<0 ? c1 : c2;\r
                        long n1 = gr->AddPnt(mglPoint(x1,yy,zm),c);\r
@@ -1043,8 +1018,7 @@ void MGL_EXPORT mgl_bars_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char
 void MGL_EXPORT mgl_bars(HMGL gr, HCDT y, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(y->GetNx()+1);\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
+       mglDataV x(y->GetNx()+1);       x.Fill(gr->Min.x,gr->Max.x);\r
        mgl_bars_xy(gr,&x,y,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1069,7 +1043,7 @@ void MGL_EXPORT mgl_bars_(uintptr_t *gr, uintptr_t *y,    const char *pen, const ch
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_barh_yx(HMGL gr, HCDT y, HCDT v, const char *pen, const char *opt)\r
 {\r
-       long m,mx,my,n=v->GetNx(),ny=y->GetNx(),pal;\r
+       long m,n=v->GetNx(),ny=y->GetNx(),pal;\r
        if(mgl_check_dim1(gr,y,v,0,0,"Barh",true))      return;\r
 \r
        gr->SaveState(opt);\r
@@ -1092,14 +1066,13 @@ void MGL_EXPORT mgl_barh_yx(HMGL gr, HCDT y, HCDT v, const char *pen, const char
        gr->Reserve(4*n*m);\r
        for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                c2=c1=gr->NextColor(pal);\r
                if(gr->GetNumPal(pal)==2*m && !sh)      c2 = gr->NextColor(pal);\r
-               mx = j<v->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
+               long mx = j<v->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
                xp = x0 = gr->GetOrgX('y');\r
-#pragma omp parallel for ordered\r
                for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        if(sh)  c2=c1=gr->NextColor(pal,i);\r
                        mreal vv = y->v(i,my), d = i<ny-1 ? y->v(i+1,my)-vv : vv-y->v(i-1,my), xx;\r
                        mreal y1 = vv + d/2*(dv-gr->BarWidth), y2 = y1 + gr->BarWidth*d;\r
@@ -1107,11 +1080,8 @@ void MGL_EXPORT mgl_barh_yx(HMGL gr, HCDT y, HCDT v, const char *pen, const char
                        if(!above)\r
                        {       y2 = (y2-y1)/m;         y1 += j*y2;             y2 += y1;       }\r
                        else\r
-#pragma omp ordered\r
                        {       x0 = gr->GetOrgX('y') + dd[i];  dd[i] += xx;    xx += x0;       }\r
-                       if(fall)\r
-#pragma omp ordered\r
-                       {       x0 = xp;        xx += x0;       xp = xx;        }\r
+                       if(fall)        {       x0 = xp;        xx += x0;       xp = xx;        }\r
 \r
                        mreal c = vv<0 ? c1 : c2;\r
                        long n1 = gr->AddPnt(mglPoint(xx,y1,zm),c);\r
@@ -1132,8 +1102,7 @@ void MGL_EXPORT mgl_barh_yx(HMGL gr, HCDT y, HCDT v, const char *pen, const char
 void MGL_EXPORT mgl_barh(HMGL gr, HCDT v,      const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData y(v->GetNx()+1);\r
-       y.Fill(gr->Min.y,gr->Max.y);\r
+       mglDataV y(v->GetNx()+1);       y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_barh_yx(gr,&y,v,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1169,12 +1138,11 @@ void MGL_EXPORT mgl_ohlc_x(HMGL gr, HCDT x, HCDT open, HCDT high, HCDT low, HCDT
        gr->SetPenPal(pen,&pal);        gr->Reserve(6*n*m);\r
        for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                cc=gr->NextColor(pal);\r
                mx = j<x->GetNy() ? j:0;\r
-#pragma omp parallel for private(vv,dd,x1,x2)\r
                for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        vv = x->v(i,mx);        dd = i<nx-1 ? x->v(i+1)-vv : vv-x->v(i-1);\r
                        x1 = vv + dd/2*(dv-gr->BarWidth);       x2 = x1 + gr->BarWidth*dd;\r
                        x2 = (x2-x1)/m;         x1 += j*x2;             x2 += x1;       vv = (x2+x1)/2;\r
@@ -1200,8 +1168,7 @@ void MGL_EXPORT mgl_ohlc_x(HMGL gr, HCDT x, HCDT open, HCDT high, HCDT low, HCDT
 void MGL_EXPORT mgl_ohlc(HMGL gr, HCDT open, HCDT high, HCDT low, HCDT close, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(open->GetNx()+1);\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
+       mglDataV x(open->GetNx()+1);    x.Fill(gr->Min.x,gr->Max.x);\r
        mgl_ohlc_x(gr,&x,open,high,low,close,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1239,42 +1206,35 @@ void MGL_EXPORT mgl_boxplot_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const c
        if(mglchr(pen,'>'))     dv = -1;\r
        mreal zVal = gr->AdjustZMin(), vv;\r
        bool sh = mglchr(pen,'!');\r
-#pragma omp parallel\r
+       mreal *d = new mreal[m];\r
+       for(long i=0;i<n;i++)   // find quartiles by itself\r
        {\r
-               mreal *d = new mreal[m];\r
-#pragma omp for\r
-               for(long i=0;i<n;i++)   // find quartiles by itself\r
+               register long mm,k,j;\r
+               for(mm=j=0;j<m;j++)\r
                {\r
-                       if(gr->Stop)    continue;\r
-                       register long mm,k,j;\r
-                       for(mm=j=0;j<m;j++)\r
-                       {\r
-                               mreal vv = y->v(i,j);\r
-                               if(mgl_isnum(vv))       {       d[mm]=vv;       mm++;   }\r
-                       }\r
-//                     if(m==0)        {       b[i]=NAN;       break;  }\r
-                       qsort(d, mm, sizeof(mreal), mgl_cmp_flt);\r
-                       b[i] = d[0];    b[i+4*n] = d[mm-1];             k = mm/4;\r
-                       b[i+n] = (mm%4) ? d[k] : (d[k]+d[k-1])/2.;\r
-                       b[i+2*n] = (mm%2) ? d[mm/2] : (d[mm/2]+d[mm/2-1])/2.;\r
-                       b[i+3*n] = (mm%4) ? d[mm-k-1] : (d[mm-k-1]+d[mm-k])/2.;\r
+                       mreal vv = y->v(i,j);\r
+                       if(mgl_isnum(vv))       {       d[mm]=vv;       mm++;   }\r
                }\r
-               delete []d;\r
+//                     if(m==0)        {       b[i]=NAN;       break;  }\r
+               qsort(d, mm, sizeof(mreal), mgl_cmp_flt);\r
+               b[i] = d[0];    b[i+4*n] = d[mm-1];             k = mm/4;\r
+               b[i+n] = (mm%4) ? d[k] : (d[k]+d[k-1])/2.;\r
+               b[i+2*n] = (mm%2) ? d[mm/2] : (d[mm/2]+d[mm/2-1])/2.;\r
+               b[i+3*n] = (mm%4) ? d[mm-k-1] : (d[mm-k-1]+d[mm-k])/2.;\r
        }\r
+       delete []d;\r
 \r
        long pal;\r
        gr->SetPenPal(pen,&pal);        gr->NextColor(pal);     gr->Reserve(18*n);\r
-#pragma omp parallel for private(vv,dd,x1,x2)\r
        for(long i=0;i<n;i++)\r
        {\r
-               if(gr->Stop)    continue;\r
                vv = x->v(i);\r
                dd = i<nx-1 ? x->v(i+1)-vv : vv-x->v(i-1);\r
                x1 = vv + dd/2*(dv-gr->BarWidth);\r
                x2 = x1 + gr->BarWidth*dd;\r
                mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
                register long n1,n2;\r
-               // TODO why boxplot fail if I use for()\r
+\r
                n1=gr->AddPnt(mglPoint(x1,b[i],zVal),c);        // horizontal lines\r
                n2=gr->AddPnt(mglPoint(x2,b[i],zVal),c);\r
                gr->line_plot(n1,n2);\r
@@ -1311,8 +1271,7 @@ void MGL_EXPORT mgl_boxplot_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const c
 void MGL_EXPORT mgl_boxplot(HMGL gr, HCDT y, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(y->GetNx()+1);\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
+       mglDataV x(y->GetNx()+1);       x.Fill(gr->Min.x,gr->Max.x);\r
        mgl_boxplot_xy(gr,&x,y,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1332,7 +1291,7 @@ void MGL_EXPORT mgl_boxplot_(uintptr_t *gr, uintptr_t *y, const char *pen, const
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const char *pen, const char *opt)\r
 {\r
-       long m,mx,my,m1,m2,n=ey->GetNx(),pal;\r
+       long m,n=ey->GetNx(),pal;\r
        if(mgl_check_dim0(gr,x,y,ey,ex,"Error"))        return;\r
 \r
        gr->SaveState(opt);\r
@@ -1351,57 +1310,50 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
        mglPoint q(NAN,NAN);\r
        for(long j=0;j<m;j++)\r
        {\r
-               if(gr->Stop)    return;\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
-               m1 = j<ex->GetNy() ? j:0;       m2 = j<ey->GetNy() ? j:0;\r
+               if(gr->NeedStop())      break;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
+               long m1 = j<ex->GetNy() ? j:0,m2 = j<ey->GetNy() ? j:0;\r
                gr->NextColor(pal);\r
                if(ma)\r
                {\r
-                       if(strchr("PXsS",mk))\r
-#pragma omp parallel for\r
-                               for(long i=0;i<n;i++)   // boundary of square\r
-                               {\r
-                                       mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
-                                       mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                                       long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,11);\r
-                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,11);\r
-                                       long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,11);\r
-                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,11);\r
-                                       gr->line_plot(n1,n2);   gr->line_plot(n1,n3);\r
-                                       gr->line_plot(n4,n2);   gr->line_plot(n4,n3);\r
-                               }\r
-                       if(strchr("dD",mk))\r
-#pragma omp parallel for\r
-                               for(long i=0;i<n;i++)   // boundary of rhomb\r
+                       if(strchr("PXsS",mk))   for(long i=0;i<n;i++)   // boundary of square\r
+                       {\r
+                               mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
+                               mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
+                               long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,11);\r
+                               long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,11);\r
+                               long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,11);\r
+                               long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,11);\r
+                               gr->line_plot(n1,n2);   gr->line_plot(n1,n3);\r
+                               gr->line_plot(n4,n2);   gr->line_plot(n4,n3);\r
+                       }\r
+                       if(strchr("dD",mk))     for(long i=0;i<n;i++)   // boundary of rhomb\r
+                       {\r
+                               mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
+                               mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
+                               long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,11);\r
+                               long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,11);\r
+                               long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,11);\r
+                               long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,11);\r
+                               gr->line_plot(n1,n2);   gr->line_plot(n2,n3);\r
+                               gr->line_plot(n3,n4);   gr->line_plot(n4,n1);\r
+                       }\r
+                       if(strchr("oOC",mk))    for(long i=0;i<n;i++)   // circle\r
+                       {\r
+                               mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
+                               mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
+                               long n1,n2,k;\r
+                               for(k=0,n2=-1;k<=40;k++)\r
                                {\r
-                                       mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
-                                       mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                                       long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,11);\r
-                                       long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,11);\r
-                                       long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,11);\r
-                                       long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,11);\r
-                                       gr->line_plot(n1,n2);   gr->line_plot(n2,n3);\r
-                                       gr->line_plot(n3,n4);   gr->line_plot(n4,n1);\r
-                               }\r
-                       if(strchr("oOC",mk))\r
-#pragma omp parallel for\r
-                               for(long i=0;i<n;i++)   // circle\r
-                               {\r
-                                       mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
-                                       mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                                       long n1,n2,k;\r
-                                       for(k=0,n2=-1;k<=40;k++)\r
-                                       {\r
-                                               n1 = n2;\r
-                                               n2 = gr->AddPnt(mglPoint(vx+ve*mgl_cos[(18*k)%360],\r
-                                                               vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,11);\r
-                                               if(k>0) gr->line_plot(n1,n2);\r
-                                       }\r
+                                       n1 = n2;\r
+                                       n2 = gr->AddPnt(mglPoint(vx+ve*mgl_cos[(18*k)%360],\r
+                                                       vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,11);\r
+                                       if(k>0) gr->line_plot(n1,n2);\r
                                }\r
+                       }\r
                        switch(mk)\r
                        {\r
                        case 'P':       case '+':\r
-#pragma omp parallel for\r
                                for(long i=0;i<n;i++)\r
                                {\r
                                        mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
@@ -1413,7 +1365,6 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                        gr->line_plot(n1,n3);   gr->line_plot(n2,n4);\r
                                }       break;\r
                        case 'X':       case 'x':\r
-#pragma omp parallel for\r
                                for(long i=0;i<n;i++)\r
                                {\r
                                        mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
@@ -1425,7 +1376,6 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                        gr->line_plot(n1,n4);   gr->line_plot(n2,n3);\r
                                }       break;\r
                        case 'S':\r
-#pragma omp parallel for\r
                                for(long i=0;i<n;i++)\r
                                {\r
                                        mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
@@ -1437,7 +1387,6 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                        gr->quad_plot(n1,n2,n3,n4);\r
                                }       break;\r
                        case 'D':\r
-#pragma omp parallel for\r
                                for(long i=0;i<n;i++)\r
                                {\r
                                        mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
@@ -1449,7 +1398,6 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                        gr->quad_plot(n1,n4,n2,n3);\r
                                }       break;\r
                        case 'O':\r
-#pragma omp parallel for\r
                                for(long i=0;i<n;i++)\r
                                {\r
                                        mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
@@ -1471,22 +1419,20 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
                                }\r
                        }\r
                }\r
-               else\r
-#pragma omp parallel for\r
-                       for(long i=0;i<n;i++)\r
-                       {\r
-                               mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
-                               mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
-                               if(mk)  gr->mark_plot(gr->AddPnt(mglPoint(vx,vy,zVal),c), mk);\r
+               else    for(long i=0;i<n;i++)\r
+               {\r
+                       mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
+                       mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
+                       if(mk)  gr->mark_plot(gr->AddPnt(mglPoint(vx,vy,zVal),c), mk);\r
 \r
-                               long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,11);\r
-                               long n2 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,11);\r
-                               gr->line_plot(n1,n2);   gr->arrow_plot(n1,n2,'I');      gr->arrow_plot(n2,n1,'I');\r
+                       long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,11);\r
+                       long n2 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,11);\r
+                       gr->line_plot(n1,n2);   gr->arrow_plot(n1,n2,'I');      gr->arrow_plot(n2,n1,'I');\r
 \r
-                               n1 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),-1,q,c,11);\r
-                               n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),-1,q,c,11);\r
-                               gr->line_plot(n1,n2);   gr->arrow_plot(n1,n2,'I');      gr->arrow_plot(n2,n1,'I');\r
-                       }\r
+                       n1 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),-1,q,c,11);\r
+                       n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),-1,q,c,11);\r
+                       gr->line_plot(n1,n2);   gr->arrow_plot(n1,n2,'I');      gr->arrow_plot(n2,n1,'I');\r
+               }\r
        }\r
        gr->EndGroup();\r
 }\r
@@ -1494,17 +1440,16 @@ void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const c
 void MGL_EXPORT mgl_error_xy(HMGL gr, HCDT x, HCDT y, HCDT ey, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData ex(y->GetNx());\r
-       ex.Fill(NAN,NAN);\r
+       mglDataV ex(y->GetNx());        ex.Fill(NAN);\r
        mgl_error_exy(gr,x,y,&ex,ey,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_error(HMGL gr, HCDT y, HCDT ey, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(y->GetNx());\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
-       mgl_error_xy(gr,&x,y,ey,pen,0);\r
+       mglDataV x(y->GetNx()), ex(y->GetNx());\r
+       x.Fill(gr->Min.x,gr->Max.x);    ex.Fill(NAN);\r
+       mgl_error_exy(gr,&x,y,&ex,ey,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_error_(uintptr_t *gr, uintptr_t *y, uintptr_t *ey, const char *pen, const char *opt,int l,int lo)\r
@@ -1534,10 +1479,8 @@ void face_plot(mglBase *gr, mglPoint o, mglPoint d1, mglPoint d2, mreal c, bool
        d1 = d1/num;    d2 = d2/num;\r
        long n=num+1, *id=new long[n*n];\r
        gr->Reserve(n*n);\r
-#pragma omp parallel for collapse(2)\r
        for(long j=0;j<n;j++)   for(long i=0;i<n;i++)\r
                id[i+n*j] = gr->AddPnt(o+d1*i+d2*j,c,nn);\r
-#pragma omp parallel for collapse(2)\r
        for(long j=0;j<num;j++) for(long i=0;i<num;i++)\r
        {\r
                long *ii = id+i+n*j;\r
@@ -1587,12 +1530,12 @@ void MGL_EXPORT mgl_chart(HMGL gr, HCDT a, const char *cols, const char *opt)
 \r
        for(j=0;j<a->GetNy();j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                y1 = gr->Min.y + dy*j;\r
                for(i=0,ss=0;i<n;i++)   ss += a->v(i,j);\r
                if(ss==0)       continue;\r
                for(cs=0,i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    {       delete []c;     return; }\r
                        vv = a->v(i,j); dx = vv/ss;     cc = c[i%nc];\r
                        if(dx==0)       continue;\r
                        x1 = gr->Min.x + (gr->Max.x-gr->Min.x)*cs/ss;   dx *= (gr->Max.x-gr->Min.x);\r
@@ -1623,7 +1566,7 @@ void MGL_EXPORT mgl_chart_(uintptr_t *gr, uintptr_t *a, const char *col, const c
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_mark_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt)\r
 {\r
-       long j,m,mx,my,mz,mr,n=y->GetNx(),pal;\r
+       long m,n=y->GetNx(),pal;\r
        if(mgl_check_dim0(gr,x,y,z,r,"Mark"))   return;\r
 \r
        gr->SaveState(opt);\r
@@ -1634,14 +1577,14 @@ void MGL_EXPORT mgl_mark_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char
        if(mk==0)       return;\r
        bool sh = mglchr(pen,'!');\r
 \r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                gr->NextColor(pal);\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
-               mz = j<z->GetNy() ? j:0;        mr = j<r->GetNy() ? j:0;\r
-               for(int i=0;i<n;i++)\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
+               long mz = j<z->GetNy() ? j:0, mr = j<r->GetNy() ? j:0;\r
+               for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
                        gr->mark_plot(gr->AddPnt(mglPoint(x->v(i,mx),y->v(i,my),z->v(i,mz)),c), mk, fabs(r->v(i,mr)));\r
                }\r
@@ -1652,8 +1595,7 @@ void MGL_EXPORT mgl_mark_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char
 void MGL_EXPORT mgl_mark_xy(HMGL gr, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData z(y->GetNx());\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
        mgl_mark_xyz(gr,x,y,&z,r,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1661,9 +1603,8 @@ void MGL_EXPORT mgl_mark_y(HMGL gr, HCDT y, HCDT r, const char *pen, const char
 {\r
        register long n=y->GetNx();\r
        gr->SaveState(opt);\r
-       mglData x(n), z(n);\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV x(n), z(n);\r
+       x.Fill(gr->Min.x,gr->Max.x);    z.Fill(gr->AdjustZMin());\r
        mgl_mark_xyz(gr,&x,y,&z,r,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1689,7 +1630,7 @@ void MGL_EXPORT mgl_mark_y_(uintptr_t *gr, uintptr_t *y, uintptr_t *r, const cha
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_tube_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt)\r
 {\r
-       long j,m,mx,my,mz,mr,n=y->GetNx(),pal;\r
+       long m,n=y->GetNx(),pal;\r
        if(mgl_check_dim1(gr,x,y,z,r,"Tube"))   return;\r
 \r
        gr->SaveState(opt);\r
@@ -1706,11 +1647,12 @@ void MGL_EXPORT mgl_tube_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const cha
        mglPoint p,l,t,u,q,d;\r
        long *nn=new long[2*num];\r
        memset(nn,-1,2*num*sizeof(long));\r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                gr->NextColor(pal);\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
-               mz = j<z->GetNy() ? j:0;        mr = j<r->GetNy() ? j:0;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
+               long mz = j<z->GetNy() ? j:0, mr = j<r->GetNy() ? j:0;\r
                for(long i=0;i<n;i++)\r
                {\r
                        l = mglPoint(x->dvx(i,mx),y->dvx(i,my),z->dvx(i,mz));\r
@@ -1720,7 +1662,6 @@ void MGL_EXPORT mgl_tube_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const cha
                        mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
                        for(long k=0;k<num;k++)\r
                        {\r
-                               if(gr->Stop)    {       delete []nn;    return; }\r
                                register int kk = k*360/(num-1);\r
                                register float  co = mgl_cos[(kk)%360], si = mgl_cos[(270+kk)%360];\r
                                p = q + t*(rr*co) + u*(rr*si);\r
@@ -1738,8 +1679,7 @@ void MGL_EXPORT mgl_tube_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const cha
 void MGL_EXPORT mgl_tube_xyr(HMGL gr, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData z(y->GetNx());\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
        mgl_tube_xyzr(gr,x,y,&z,r,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1748,9 +1688,8 @@ void MGL_EXPORT mgl_tube_r(HMGL gr, HCDT y, HCDT r, const char *pen, const char
        register long n=y->GetNx();\r
        if(n<2) {       gr->SetWarn(mglWarnLow,"Tube"); return; }\r
        gr->SaveState(opt);\r
-       mglData x(n), z(n);\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV x(n), z(n);\r
+       x.Fill(gr->Min.x,gr->Max.x);    z.Fill(gr->AdjustZMin());\r
        mgl_tube_xyzr(gr,&x,y,&z,r,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1759,10 +1698,9 @@ void MGL_EXPORT mgl_tube(HMGL gr, HCDT y, double rr, const char *pen, const char
        register long n=y->GetNx();\r
        if(n<2) {       gr->SetWarn(mglWarnLow,"Tube"); return; }\r
        gr->SaveState(opt);\r
-       mglData x(n), r(n), z(n);\r
+       mglDataV x(n), r(n), z(n);\r
        x.Fill(gr->Min.x,gr->Max.x);\r
-       r.Fill(rr,rr);\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       r.Fill(rr);     z.Fill(gr->AdjustZMin());\r
        mgl_tube_xyzr(gr,&x,y,&z,&r,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1771,17 +1709,15 @@ void MGL_EXPORT mgl_tube_xy(HMGL gr, HCDT x, HCDT y, double rr, const char *pen,
        register long n=y->GetNx();\r
        if(n<2) {       gr->SetWarn(mglWarnLow,"Tube"); return; }\r
        gr->SaveState(opt);\r
-       mglData r(n), z(n);\r
-       r.Fill(rr,rr);\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV r(n), z(n);\r
+       r.Fill(rr);     z.Fill(gr->AdjustZMin());\r
        mgl_tube_xyzr(gr,x,y,&z,&r,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_tube_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, double rr, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData r(y->GetNx());\r
-       r.Fill(rr,rr);\r
+       mglDataV r(y->GetNx()); r.Fill(rr);\r
        mgl_tube_xyzr(gr,x,y,z,&r,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1823,7 +1759,7 @@ void MGL_EXPORT mgl_tube_(uintptr_t *gr, uintptr_t *y, mreal *r, const char *pen
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_tape_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
 {\r
-       long j,m,mx,my,mz,n=y->GetNx(),pal;\r
+       long m,n=y->GetNx(),pal;\r
        if(mgl_check_dim1(gr,x,y,z,0,"Tape"))   return;\r
 \r
        static int cgid=1;      gr->StartGroup("Tape",cgid++);\r
@@ -1837,11 +1773,12 @@ void MGL_EXPORT mgl_tape_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
        if(!xo && !zo)  xo = zo = true;\r
        mreal c1,c2;\r
 \r
-       for(j=0;j<m;j++)\r
+       for(long j=0;j<m;j++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                c2=c1=gr->NextColor(pal);\r
                if(gr->GetNumPal(pal)==2*m && !sh)      c2 = gr->NextColor(pal);\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;        mz = j<z->GetNy() ? j:0;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
                // initial values for normales\r
                p2 = mglPoint(x->v(0,mx), y->v(0,my), z->v(0,mz));\r
                l = mglPoint(x->v(1,mx), y->v(1,my), z->v(1,mz)) - p2;  l /= mgl_norm(l);\r
@@ -1857,7 +1794,6 @@ void MGL_EXPORT mgl_tape_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
                register long i;\r
                for(i=1;i<n;i++)\r
                {\r
-                       if(gr->Stop)    return;\r
                        p1 = p2;        p2 = mglPoint(x->v(i,mx), y->v(i,my), z->v(i,mz));\r
                        l = p2-p1;              l /= mgl_norm(l);\r
                        q1 -= l*(l*q1); q1/= mgl_norm(q1);      q2 = (q1^l);\r
@@ -1888,8 +1824,7 @@ void MGL_EXPORT mgl_tape_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, c
 void MGL_EXPORT mgl_tape_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData z(y->GetNx());\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
        mgl_tape_xyz(gr,x,y,&z,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -1898,9 +1833,8 @@ void MGL_EXPORT mgl_tape(HMGL gr, HCDT y, const char *pen, const char *opt)
        register long n=y->GetNx();\r
        if(n<2) {       gr->SetWarn(mglWarnLow,"Plot"); return; }\r
        gr->SaveState(opt);\r
-       mglData x(n), z(n);\r
-       x.Fill(gr->Min.x,gr->Max.x);\r
-       mreal zm = gr->AdjustZMin();    z.Fill(zm,zm);\r
+       mglDataV x(n), z(n);\r
+       x.Fill(gr->Min.x,gr->Max.x);    z.Fill(gr->AdjustZMin());\r
        mgl_tape_xyz(gr,&x,y,&z,pen,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
index 74c7fde0fcfd9e439765f3c0d2b2c05a731d8227..f2d256391d25eb38e5b7d3fe927fb1c741abb4e2 100644 (file)
@@ -256,7 +256,7 @@ void MGL_EXPORT mgl_write_prc(HMGL gr, const char *fname,const char* /*descr*/,
                for(size_t i=0;i<size_t(gr->GetPrmNum());i++)   // collect data for groups\r
                // it is rather expensive (extra 4b per primitive) but need for export to 3D\r
                {\r
-                       m = gr->GetPrm(i).id-mmin;\r
+                       m = gr->GetPrm(i,false).id-mmin;\r
                        if(m>=0 && m<mmax-mmin+1)       gr->Grp[ng[m]].p.push_back(i);\r
                }\r
                delete []ng;\r
@@ -373,7 +373,7 @@ void MGL_EXPORT mgl_write_prc(HMGL gr, const char *fname,const char* /*descr*/,
                file.begingroup(grp.Lbl.c_str(),&grpopt);\r
                for(size_t j=0;j<prm.size();j++)\r
                {\r
-                       const mglPrim &q=gr->GetPrm(prm[j]);\r
+                       const mglPrim &q=gr->GetPrm(prm[j],false);\r
                        const double w = (q.w>1)?(q.w*sqrt(gr->FontFactor()/400.)):1;\r
 \r
                        const mglPnt p = gr->GetPnt(q.n1) - p0;\r
@@ -921,7 +921,7 @@ void MGL_EXPORT mgl_write_prc(HMGL gr, const char *fname,const char* /*descr*/,
 //             const HPDF_REAL height = dynamic_cast<mglCanvas *>(gr)->GetHeight();\r
 //             const HPDF_REAL depth  = sqrt(width*height);\r
 \r
-               const HPDF_Rect rect = {0, 0, width, height};\r
+               const HPDF_Rect rect = {0, 0, HPDF_REAL(width), HPDF_REAL(height)};\r
 \r
                HPDF_Doc        pdf;\r
                HPDF_Page page;\r
index 20f97e5da5d75142e02fc3d77b523ca02828ebbc..f9f1481551ee5d0c84ae4ad344254039325795ea 100644 (file)
@@ -20,6 +20,7 @@
 #include "mgl2/canvas.h"\r
 #include "mgl2/prim.h"\r
 #include "mgl2/data.h"\r
+std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt);\r
 //-----------------------------------------------------------------------------\r
 //\r
 //     Mark & Curve series\r
@@ -60,14 +61,12 @@ void MGL_EXPORT mgl_line(HMGL gr, double x1, double y1, double z1, double x2, do
        gr->SetPenPal(pen);\r
        n = (n<2) ? 2 : n;\r
 \r
-       register long i,k1,k2;\r
-       register mreal s;\r
        gr->Reserve(n);\r
-       k1 = gr->AddPnt(p,gr->CDef,nn,-1,3);    gr->AddActive(k1);\r
-       for(i=1;i<n;i++)\r
+       long k1 = gr->AddPnt(p,gr->CDef,nn,-1,3);       gr->AddActive(k1);\r
+       for(long i=1;i<n;i++)\r
        {\r
-               if(gr->Stop)    return;\r
-               s = i/mreal(n-1);       p = p1*(1-s)+p2*s;      k2 = k1;\r
+               mreal s = i/mreal(n-1); p = p1*(1-s)+p2*s;\r
+               long k2 = k1;\r
                k1 = gr->AddPnt(p,gr->CDef,nn,-1,3);\r
                gr->line_plot(k2,k1);\r
                if(i==1)        gr->arrow_plot(k2,k1,gr->Arrow1);\r
@@ -89,14 +88,12 @@ void MGL_EXPORT mgl_curve(HMGL gr, double x1, double y1, double z1, double dx1,
        n = (n<2) ? 2 : n;\r
        gr->SetPenPal(pen);\r
 \r
-       register long i,k1,k2;\r
-       register mreal s;\r
        gr->Reserve(n);\r
-       k1=gr->AddPnt(p,gr->CDef,nn,-1,3);      gr->AddActive(k1);\r
-       for(i=1;i<n;i++)\r
+       long k1=gr->AddPnt(p,gr->CDef,nn,-1,3); gr->AddActive(k1);\r
+       for(long i=1;i<n;i++)\r
        {\r
-               if(gr->Stop)    return;\r
-               s = i/(n-1.);   p = p1+s*(d1+s*(a+s*b));        k2 = k1;\r
+               mreal s = i/(n-1.);     p = p1+s*(d1+s*(a+s*b));\r
+               long k2 = k1;\r
                k1 = gr->AddPnt(p,gr->CDef,nn,-1,3);\r
                gr->line_plot(k2,k1);\r
                if(i==1)        gr->arrow_plot(k2,k1,gr->Arrow1);\r
@@ -215,8 +212,15 @@ void MGL_EXPORT mgl_cone(HMGL gr, double x1, double y1, double z1, double x2, do
        static int cgid=1;      gr->StartGroup("Cone",cgid++);\r
        mglPoint p1(x1,y1,z1), p2(x2,y2,z2), p,q(NAN,NAN),t(NAN,NAN), d=p2-p1,a,b;\r
        a=!d;   a.Normalize();          b=d^a;  b.Normalize();\r
-       long ss=gr->AddTexture(stl);\r
-       mreal c1=gr->GetC(ss,p1.z), c2=gr->GetC(ss,p2.z), dr=r2-r1;\r
+       mreal c1,c2,dr=r2-r1;\r
+       const char *s;\r
+       if((s=strstr(stl,"{&"))!=0)     c1 = c2 = atof(s+2);\r
+       else\r
+       {\r
+               register long ss=gr->AddTexture(stl);\r
+               c1=gr->GetC(ss,p1.z);\r
+               c2=gr->GetC(ss,p2.z);\r
+       }\r
        long *kk=new long[164],k1=-1,k2=-1;\r
        bool edge = mglchr(stl,'@');\r
        bool wire = mglchr(stl,'#');\r
@@ -233,10 +237,8 @@ void MGL_EXPORT mgl_cone(HMGL gr, double x1, double y1, double z1, double x2, do
        bool refr = n>6;\r
        if(refr)        t=d;\r
 \r
-#pragma omp parallel for firstprivate(p,q)\r
        for(long i=0;i<2*n+1;i++)\r
        {\r
-               if(gr->Stop)    continue;\r
                register int f = n!=4?(2*i+1)*90/n:45*i;\r
                register mreal co = mgl_cos[f%360], si = mgl_cos[(f+270)%360];\r
                p = p1+(r1*co)*a+(r1*si)*b;\r
@@ -247,26 +249,22 @@ void MGL_EXPORT mgl_cone(HMGL gr, double x1, double y1, double z1, double x2, do
                kk[i+2*n+1] = gr->AddPnt(p,c2,q,-1,3);\r
                if(edge && !wire)       kk[i+123] = gr->AddPnt(p,c2,t,-1,3);\r
        }\r
-       if(wire)\r
-//#pragma omp parallel for             // useless\r
-               for(long i=0;i<2*n;i++)\r
-               {\r
-                       gr->line_plot(kk[i],kk[i+1]);\r
-                       gr->line_plot(kk[i],kk[i+2*n+1]);\r
-                       gr->line_plot(kk[i+2*n+2],kk[i+1]);\r
-                       gr->line_plot(kk[i+2*n+2],kk[i+2*n+1]);\r
-               }\r
-       else\r
-#pragma omp parallel for\r
-               for(long i=0;i<2*n;i++)\r
+       if(wire)        for(long i=0;i<2*n;i++)\r
+       {\r
+               gr->line_plot(kk[i],kk[i+1]);\r
+               gr->line_plot(kk[i],kk[i+2*n+1]);\r
+               gr->line_plot(kk[i+2*n+2],kk[i+1]);\r
+               gr->line_plot(kk[i+2*n+2],kk[i+2*n+1]);\r
+       }\r
+       else    for(long i=0;i<2*n;i++)\r
+       {\r
+               gr->quad_plot(kk[i],kk[i+1],kk[i+2*n+1],kk[i+2*n+2]);\r
+               if(edge)\r
                {\r
-                       gr->quad_plot(kk[i],kk[i+1],kk[i+2*n+1],kk[i+2*n+2]);\r
-                       if(edge)\r
-                       {\r
-                               gr->trig_plot(k1,kk[i+82],kk[i+83]);\r
-                               gr->trig_plot(k2,kk[i+123],kk[i+124]);\r
-                       }\r
+                       gr->trig_plot(k1,kk[i+82],kk[i+83]);\r
+                       gr->trig_plot(k2,kk[i+123],kk[i+124]);\r
                }\r
+       }\r
        gr->EndGroup(); delete []kk;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -280,7 +278,7 @@ void MGL_EXPORT mgl_cone_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_cones_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
 {\r
-       long i=5,j,m,mx,my,mz,n=z->GetNx(),nx=x->GetNx(), nz=z->GetNy(), pal;\r
+       long m,n=z->GetNx(),nx=x->GetNx(), nz=z->GetNy(), pal;\r
        if(mgl_check_dim1(gr,x,z,y,0,"Cones",true))     return;\r
 \r
        gr->SaveState(opt);\r
@@ -296,39 +294,40 @@ void MGL_EXPORT mgl_cones_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen,
        if(mglchr(pen,'>'))     dv = -1;\r
 \r
        gr->SetPenPal(pen,&pal);\r
-       char c1[8];     memset(c1,0,8); c1[0] ='@';\r
-       char c2[8];     memset(c2,0,8); c2[0] ='@';\r
-       if(wire)        {       c1[5]=c2[5]='#';        i++;    }\r
-       if(mglchr(pen,'&'))     c1[i]=c2[i]='4';\r
-       else if(mglchr(pen,'4'))        c1[i]=c2[i]='4';\r
-       else if(mglchr(pen,'6'))        c1[i]=c2[i]='6';\r
-       else if(mglchr(pen,'8'))        c1[i]=c2[i]='8';\r
+       std::string cb="@";\r
+       if(wire)        cb += '#';\r
+       if(mglchr(pen,'4'))     cb+='4';\r
+       else if(mglchr(pen,'6'))        cb+='6';\r
+       else if(mglchr(pen,'8'))        cb+='8';\r
+\r
        memset(dd,0,2*n*sizeof(mreal));\r
        z0 = gr->GetOrgZ('x');\r
-       for(i=0;i<n;i++)        for(j=0;j<m;j++)        dd[i] += z->v(i, j<nz ? j:0);\r
-       for(j=0;j<m;j++)\r
+       for(long i=0;i<n;i++)   for(long j=0;j<m;j++)   dd[i] += z->v(i, j<nz ? j:0);\r
+\r
+       char buf[64];\r
+       for(long j=0;j<m;j++)\r
        {\r
-               gr->NextColor(pal);             memcpy(c1+1,gr->last_line(),4);\r
+               if(gr->NeedStop())      break;\r
+               sprintf(buf,"{&%g}",gr->NextColor(pal));\r
+               std::string c1=cb+buf, c2=c1;\r
                if(gr->GetNumPal(pal)==2*m)\r
-               {       gr->NextColor(pal);     memcpy(c2+1,gr->last_line(),4); }\r
-               else    memcpy(c2,c1,8);\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;        mz = j<nz ? j:0;\r
-               for(i=0;i<n;i++)\r
+               {       sprintf(buf,"{&%g}",gr->NextColor(pal));        c2 = cb+buf;    }\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<nz ? j:0;\r
+               for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    {       delete []dd;    return; }\r
                        vx=x->v(i,mx);  vy=y->v(i,my);  vz=z->v(i,mz);\r
                        v0=y->v(i,0);   v1=i<nx-1 ? x->v(i+1,mx):x->v(i-1,mx);\r
                        d = i<nx-1 ? v1-vx : vx-v1;\r
-                       x1 = vx + d/2*(dv-0.*gr->BarWidth);     // TODO\r
+                       x1 = vx + d/2*(dv-0.*gr->BarWidth);\r
                        d *= 0.7*gr->BarWidth;\r
                        if(above)\r
                        {\r
                                zz = j>0?dd[i+n]:z0;    dd[i+n] += vz;\r
                                mgl_cone(gr, x1,v0,zz, x1,v0,dd[i+n],\r
                                                 tube?d:d*(dd[i]-zz)/(dd[i]-z0),\r
-                                                tube?d:d*(dd[i]-dd[i+n])/(dd[i]-z0), c1);\r
+                                                tube?d:d*(dd[i]-dd[i+n])/(dd[i]-z0), c1.c_str());\r
                        }\r
-                       else    mgl_cone(gr, x1,vy,z0, x1,vy,vz, d,tube?d:0, vz<0?c1:c2);\r
+                       else    mgl_cone(gr, x1,vy,z0, x1,vy,vz, d,tube?d:0, vz<0?c1.c_str():c2.c_str());\r
                }\r
        }\r
        gr->EndGroup(); delete []dd;\r
@@ -369,10 +368,88 @@ void MGL_EXPORT mgl_cones_(uintptr_t *gr, uintptr_t *y,   const char *pen, const c
 //     Ellipse & Rhomb\r
 //\r
 //-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_polygon(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, int n, const char *stl)\r
+{\r
+       if(n<3) return;\r
+       long pal=0, n0,n1,n2,np,k1=-1,kp=-1;\r
+       static int cgid=1;      gr->StartGroup("Polygon",cgid++);\r
+       gr->SetPenPal(stl,&pal);\r
+       mreal c=gr->NextColor(pal);\r
+       mreal k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k');\r
+       bool fill = !mglchr(stl,'#'), box = mglchr(stl,'@') || !fill;\r
+       if(!fill)       k=c;\r
+       gr->Reserve(box?2*n+1:n+1);\r
+       if(mgl_isnan(z1) || mgl_isnan(z2))      z1=z2=2*gr->Max.z-gr->Min.z;\r
+       mglPoint p1(x1,y1,z1), p2(x2,y2,z2), d=p2-p1, u=!d, p,qq;\r
+       n0 = gr->AddPnt(p1,c,qq,-1,11);\r
+       u = (d.norm()/u.norm())*u;\r
+       n1 = np = gr->AddPnt(p2,c,qq,-1,11);\r
+       gr->AddActive(n0,0);    gr->AddActive(n1,1);\r
+       if(box) k1 = kp = gr->CopyNtoC(n1,k);\r
+       for(long i=1;i<n;i++)\r
+       {\r
+               p = p1+d*cos(2*M_PI*i/n)+u*sin(2*M_PI*i/n);\r
+               n2 = gr->AddPnt(p,c,qq,-1,11);\r
+               if(fill)        gr->trig_plot(n0,n1,n2);\r
+               if(box)\r
+               {\r
+                       long kk = gr->CopyNtoC(n2,k);\r
+                       gr->line_plot(k1, kk);  k1 = kk;\r
+               }\r
+               n1 = n2;\r
+       }\r
+       if(fill)        gr->trig_plot(n0,n2,np);\r
+       if(box)         gr->line_plot(k1, kp);\r
+       gr->EndGroup();\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_arc_ext(HMGL gr, double x0, double y0, double z0, double xr, double yr, double zr, double x1, double y1, double z1, double a, const char* stl)\r
+{\r
+       long pal=0, n = long(fabs(a)/9+1.5);    a *= M_PI/180;\r
+       static int cgid=1;      gr->StartGroup("Arc",cgid++);\r
+       gr->SetPenPal(stl,&pal);\r
+       mreal c=gr->NextColor(pal);\r
+       gr->Reserve(n+2);\r
+       if(mgl_isnan(z0) || mgl_isnan(z1))      z0=z1=2*gr->Max.z-gr->Min.z;\r
+       mglPoint p0(x0,y0,z0), p1(x1,y1,z1), d=p1-p0, u=mglPoint(xr,yr,zr)^d, p,qq;\r
+       if(u.norm()==0) return; // wrong vector orientation\r
+       u = (d.norm()/u.norm())*u;\r
+       gr->AddActive(gr->AddPnt(p0,gr->CDef,qq,-1,3),0);\r
+       long n1 = gr->AddPnt(p1,c,qq,-1,11);    gr->AddActive(n1,1);\r
+       for(long i=1;i<n;i++)\r
+       {\r
+               p = p0+d*cos(a*i/(n-1))+u*sin(a*i/(n-1));\r
+               long n2 = gr->AddPnt(p,c,qq,-1,11);\r
+               if(i==1)        gr->arrow_plot(n1,n2,gr->Arrow1);\r
+               if(i==n-1)      {       gr->arrow_plot(n2,n1,gr->Arrow2);       gr->AddActive(n2,2);    }\r
+               gr->line_plot(n1,n2);   n1 = n2;\r
+       }\r
+       gr->EndGroup();\r
+}\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_arc(HMGL gr, double x0, double y0, double x1, double y1, double a, const char* stl)\r
+{      mgl_arc_ext(gr,x0,y0,NAN,0,0,1,x1,y1,NAN,a,stl);        }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_polygon_(uintptr_t* gr, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, int *n, const char *stl,int l)\r
+{      char *s=new char[l+1];  memcpy(s,stl,l);        s[l]=0;\r
+       mgl_polygon(_GR_,*x1,*y1,*z1,*x2,*y2,*z2,*n,s); delete []s;     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_arc_ext_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *z0, mreal *x1, mreal *y1, mreal *z1, mreal *x2, mreal *y2, mreal *z2, mreal *r, const char *stl,int l)\r
+{      char *s=new char[l+1];  memcpy(s,stl,l);        s[l]=0;\r
+       mgl_arc_ext(_GR_,*x0,*y0,*z0,*x1,*y1,*z1,*x2,*y2,*z2,*r,s);     delete []s;     }\r
+//-----------------------------------------------------------------------------\r
+void MGL_EXPORT mgl_arc_(uintptr_t* gr, mreal *x0, mreal *y0, mreal *x1, mreal *y1, mreal *a, const char *stl,int l)\r
+{      char *s=new char[l+1];  memcpy(s,stl,l);        s[l]=0;\r
+       mgl_arc(_GR_,*x0,*y0,*x1,*y1,*a,s);     delete []s;     }\r
+//-----------------------------------------------------------------------------\r
+//\r
+//     Ellipse & Rhomb\r
+//\r
+//-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_ellipse(HMGL gr, double x1, double y1, double z1, double x2, double y2, double z2, double r, const char *stl)\r
 {\r
        const int n = 41;\r
-       long pal=0,n0,n1=-1,n2,m1=-1,m2;\r
+       long pal=0,n0,n1=-1,m1=-1;\r
        static int cgid=1;      gr->StartGroup("Ellipse",cgid++);\r
        gr->SetPenPal(stl,&pal);\r
        mreal c=gr->NextColor(pal), d;\r
@@ -392,12 +469,11 @@ void MGL_EXPORT mgl_ellipse(HMGL gr, double x1, double y1, double z1, double x2,
        gr->AddActive(gr->AddPnt(p2,c,q,-1,11),1);\r
        for(long i=0;i<n;i++)\r
        {\r
-               if(gr->Stop)    return;\r
                register int t=i*360/(n-1);\r
                p = s+v*mgl_cos[t%360]+u*mgl_cos[(270+t)%360];\r
-               n2 = n1;        n1 = gr->AddPnt(p,c,q,-1,11);\r
+               long n2 = n1;   n1 = gr->AddPnt(p,c,q,-1,11);\r
                if(i==n/4)      gr->AddActive(n1,2);\r
-               m2 = m1;        m1 = gr->CopyNtoC(n1,k);\r
+               long m2 = m1;   m1 = gr->CopyNtoC(n1,k);\r
                if(i>0)\r
                {\r
                        if(fill)        gr->trig_plot(n0,n1,n2);\r
@@ -419,12 +495,12 @@ void MGL_EXPORT mgl_rhomb(HMGL gr, double x1, double y1, double z1, double x2, d
        if(!fill)       k=c;\r
        gr->Reserve(8);\r
        if(mgl_isnan(z1) || mgl_isnan(z2))      z1=z2=2*gr->Max.z-gr->Min.z;\r
-       mglPoint p1(x1,y1,z1), p2(x2,y2,z2), u=mglPoint(0,0,1)^(p1-p2), q=u^(p1-p2), p, s,qq;\r
+       mglPoint p1(x1,y1,z1), p2(x2,y2,z2), u=!(p1-p2), p, s,qq;\r
        u = (r/u.norm())*u;     s = (p1+p2)/2.;\r
-       p = p1; q = qq; n1 = gr->AddPnt(p,c,qq,-1,11);\r
-       p = s+u;q = qq; n2 = gr->AddPnt(p,b==c?c:k,qq,-1,11);\r
-       p = p2; q = qq; n3 = gr->AddPnt(p,b,qq,-1,11);\r
-       p = s-u;q = qq; n4 = gr->AddPnt(p,b==c?c:k,qq,-1,11);\r
+       p = p1;         n1 = gr->AddPnt(p,c,qq,-1,11);\r
+       p = s+u;        n2 = gr->AddPnt(p,b==c?c:k,qq,-1,11);\r
+       p = p2;         n3 = gr->AddPnt(p,b,qq,-1,11);\r
+       p = s-u;        n4 = gr->AddPnt(p,b==c?c:k,qq,-1,11);\r
        gr->AddActive(n1,0);    gr->AddActive(n2,2);    gr->AddActive(n3,1);\r
        if(fill)        gr->quad_plot(n1,n2,n4,n3);\r
        n1 = gr->CopyNtoC(n1,k);        n2 = gr->CopyNtoC(n2,k);\r
@@ -471,7 +547,6 @@ void MGL_EXPORT mgl_drop(HMGL gr, mglPoint p, mglPoint q, double r, double c, do
 \r
        for(long i=0;i<=m;i++)  for(long j=0;j<n;j++)   // NOTE use prev.points => not for omp\r
        {\r
-               if(gr->Stop)    continue;\r
                if(i>0 && i<m)\r
                {\r
                        register int u=i*180/m, v=180*j/m+202;\r
@@ -521,27 +596,19 @@ void MGL_EXPORT mgl_dew_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char
        if(gr->MeshNum>1)       {       tx=(n-1)/(gr->MeshNum-1);       ty=(m-1)/(gr->MeshNum-1);       }\r
        if(tx<1)        tx=1;   if(ty<1)        ty=1;\r
 \r
-#pragma omp parallel\r
+       for(long k=0;k<ax->GetNz();k++) for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
        {\r
-               register mreal xm1=0,ym;\r
-#pragma omp for nowait collapse(3)\r
-               for(long k=0;k<ax->GetNz();k++) for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-               {\r
-                       ym = sqrt(ax->v(i,j,k)*ax->v(i,j,k)+ay->v(i,j,k)*ay->v(i,j,k));\r
-                       xm1 = xm1>ym ? xm1 : ym;\r
-               }\r
-#pragma omp critical(max_vec)\r
-               {xm = xm>xm1 ? xm:xm1;}\r
+               register mreal ym = sqrt(ax->v(i,j,k)*ax->v(i,j,k)+ay->v(i,j,k)*ay->v(i,j,k));\r
+               xm = xm>ym ? xm : ym;\r
        }\r
        xm = 1./MGL_FEPSILON/(xm==0 ? 1:xm);\r
 \r
        for(long k=0;k<ax->GetNz();k++)\r
        {\r
                if(ax->GetNz()>1)       zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1);\r
-//#pragma omp parallel for collapse(2) // gain looks negligible?!?\r
                for(long i=0;i<n;i+=tx) for(long j=0;j<m;j+=ty)\r
                {\r
-                       if(gr->Stop)    continue;\r
+                       if(gr->NeedStop())      {       gr->EndGroup(); return; }\r
                        register mreal xx=GetX(x,i,j,k).x, yy=GetY(y,i,j,k).x, dd;\r
                        register mreal dx = i<n-1 ? (GetX(x,i+1,j,k).x-xx) : (xx-GetX(x,i-1,j,k).x);\r
                        register mreal dy = j<m-1 ? (GetY(y,i,j+1,k).x-yy) : (yy-GetY(y,i,j-1,k).x);\r
@@ -629,7 +696,7 @@ void MGL_EXPORT mgl_puts_dir_(uintptr_t *gr, mreal *x, mreal *y, mreal *z, mreal
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_textmarkw_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const wchar_t *text, const char *fnt, const char *opt)\r
 {\r
-       long m,mx,my,mz,mr,n=y->GetNx();\r
+       long m,n=y->GetNx();\r
        if(mgl_check_dim0(gr,x,y,z,r,"TextMark"))       return;\r
 \r
        gr->SaveState(opt);\r
@@ -642,12 +709,11 @@ void MGL_EXPORT mgl_textmarkw_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, cons
        mglPoint p,q(NAN);\r
        for(long j=0;j<m;j++)\r
        {\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
-               mz = j<z->GetNy() ? j:0;        mr = j<r->GetNy() ? j:0;\r
-#pragma omp parallel for private(p)    // NOTE this should be useless ?!?\r
+               if(gr->NeedStop())      break;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
+               long mz = j<z->GetNy() ? j:0, mr = j<r->GetNy() ? j:0;\r
                for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        p = mglPoint(x->v(i,mx), y->v(i,my), z->v(i,mz));\r
                        register long k = gr->AddPnt(p,-1,q);\r
                        gr->text_plot(k, text, fnt, -0.5*fabs(r->v(i,mr)));\r
@@ -726,22 +792,26 @@ void MGL_EXPORT mgl_textmark_(uintptr_t *gr, uintptr_t *y, const char *text, con
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_labelw_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const wchar_t *text, const char *fnt, const char *opt)\r
 {\r
-       long m,mx,my,mz,n=y->GetNx();\r
-       if(mgl_check_dim1(gr,x,y,z,0,"Label"))  return;\r
+       long m,n=y->GetNx();\r
+       if(mgl_check_dim0(gr,x,y,z,0,"Label"))  return;\r
 \r
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("Label",cgid++);\r
        m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();  m = z->GetNy() > m ? z->GetNy() : m;\r
 \r
        mglPoint q(NAN);\r
-       wchar_t tmp[32];\r
+\r
+       char fmt[8]="2",ss[2]=" ";\r
+       std::string Tstl;\r
+       for(const char *s="0123456789";*s;s++)  if(mglchr(fnt,*s))      fmt[0] = *s;\r
+       for(const char *s="f+E-F";*s;s++)       if(mglchr(fnt,*s))\r
+       {       ss[0] = *s;     strcat(fmt,ss); }\r
        for(long j=0;j<m;j++)\r
        {\r
-               mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;        mz = j<z->GetNy() ? j:0;\r
-#pragma omp parallel for private(tmp)\r
+               if(gr->NeedStop())      break;\r
+               long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
                for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        mreal xx=x->v(i,mx), yy=y->v(i,my), zz=z->v(i,mz);\r
                        register long kk = gr->AddPnt(mglPoint(xx,yy,zz),-1,q),k,l;\r
                        std::wstring buf;\r
@@ -749,13 +819,13 @@ void MGL_EXPORT mgl_labelw_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const wchar_t *t
                        {\r
                                if(text[k]!='%' || (k>0 && text[k-1]=='\\'))\r
                                {       buf += text[k]; continue;       }\r
-                               else if(text[k+1]=='%') {       buf+='%';       k++;    continue;       }\r
-                               else if(text[k+1]=='n') mglprintf(tmp,32,L"%ld",i);\r
-                               else if(text[k+1]=='x') mglprintf(tmp,32,L"%.2g",xx);\r
-                               else if(text[k+1]=='y') mglprintf(tmp,32,L"%.2g",yy);\r
-                               else if(text[k+1]=='z') mglprintf(tmp,32,L"%.2g",zz);\r
-                               else {  buf+='%';       continue;       }\r
-                               buf += tmp;     k++;\r
+                               else if(text[k+1]=='%') buf+=L"%";\r
+                               else if(text[k+1]=='n') {       wchar_t tmp[32];        mglprintf(tmp,32,L"%ld",i);     buf += tmp;     }\r
+                               else if(text[k+1]=='x') buf += mgl_ftoa(xx,fmt);\r
+                               else if(text[k+1]=='y') buf += mgl_ftoa(yy,fmt);\r
+                               else if(text[k+1]=='z') buf += mgl_ftoa(zz,fmt);\r
+                               else {  buf+=L"%";      continue;       }\r
+                               k++;\r
                        }\r
                        gr->text_plot(kk, buf.c_str(), fnt, -0.7, 0.05);\r
                }\r
index 4a11f51ae5e8a47dbbcf3afbe109000d1858cd21..2ff4236fb4377177dab35bd77a61ac1bc1fba095 100644 (file)
@@ -25,11 +25,11 @@ using namespace std;
  */
 
 
-// Global replace int->long by A.Balakin 7 August 2012 -- 64bit version can handle huge data arrays
+// Global replace int->long by A.Balakin 21 April 2014 -- 64bit version can handle huge data arrays
 
 
-void circle_cent2(float r1,float c1, float r2,float c2, float r3,float c3,
-                                 float &r,float &c, float &ro2)
+void circle_cent2(double r1,double c1, double r2,double c2, double r3,double c3,
+                                 double &r,double &c, double &ro2)
 {
        /*
         *  function to return the center of a circle and its radius
@@ -37,28 +37,28 @@ void circle_cent2(float r1,float c1, float r2,float c2, float r3,float c3,
         * but will return r0 = -1 if it is.
         */
 
-       float v1 = 2*(r2-r1), v2 = 2*(c2-c1), v3 = r2*r2 - r1*r1 + c2*c2 - c1*c1;
-       float v4 = 2*(r3-r1),
-                 v5 = 2*(c3-c1),
-                 v6 = r3*r3 - r1*r1 + c3*c3 - c1*c1,
+       double a1 = (r1+r2)/2.0;
+       double a2 = (c1+c2)/2.0;
+       double b1 = (r3+r2)/2.0;
+       double b2 = (c3+c2)/2.0;
 
-                 v7 =  v2*v4 - v1*v5;
-       if( v7 == 0 )
-       {
-               r=0;
-               c=0;
-               ro2 = -1;
-               return;
-       }
+       double e2 = r1-r2;
+       double e1 = -c1+c2;
 
-       c = (v4*v3 - v1*v6)/v7;
-       if( v1 != 0 )
-               r = (v3 - c*v2)/v1;
-       else
-               r = (v6 - c*v5)/v4;
+       double q2 = r3-r2;
+       double q1 = -c3+c2;
 
-       ro2 = ( (r-r1)*(r-r1) + (c-c1)*(c-c1) );
+       r=0;
+       c=0;
+       ro2=-1;
+       if( e1*-q2 + e2*q1 == 0 ) return;
 
+       double beta = (-e2*(b1-a1) + e1*(b2-a2))/( e2*q1-e1*q2);
+
+       r = b1 + q1*beta;
+       c = b2 + q2*beta;
+
+       ro2 = (r1-r)*(r1-r) + (c1-c)*(c1-c);
        return;
 }
 
@@ -78,7 +78,7 @@ long read_Shx(std::vector<Shx> &pts, char * fname)
 {
        char s0[513];
        long nump =0;
-       float p1,p2;
+       double p1,p2;
 
        Shx pt;
 
@@ -105,9 +105,8 @@ long read_Shx(std::vector<Shx> &pts, char * fname)
                                {
                                        copy( line.begin(), line.end(), s0);
                                        s0[line.length()] = 0;
-                                       long v = sscanf( s0, "%g %g", &p1,&p2);
-                                       if( v>0 )
-                                       {
+                                       long v = sscanf( s0, "%lg %lg", &p1,&p2);
+                                       if( v>0 ) {
                                                pt.id = nump;
                                                nump++;
                                                pt.r = p1;
@@ -123,7 +122,7 @@ long read_Shx(std::vector<Shx> &pts, char * fname)
                        {
                                copy( line.begin(), line.end(), s0);
                                s0[line.length()] = 0;
-                               long v = sscanf( s0, "%g %g", &p1,&p2);
+                               long v = sscanf( s0, "%lg %lg", &p1,&p2);
                                if( v>0 )
                                {
                                        pt.id = nump;
@@ -141,7 +140,7 @@ long read_Shx(std::vector<Shx> &pts, char * fname)
                                {
                                        copy( line.begin(), line.end(), s0);
                                        s0[line.length()] = 0;
-                                       long v = sscanf( s0, "%g %g", &p1,&p2);
+                                       long v = sscanf( s0, "%lg %lg", &p1,&p2);
                                        if( v>0 )
                                        {
                                                pt.id = nump;
@@ -222,18 +221,18 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
 
        if( nump < 3 )
        {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //             cerr << "less than 3 points, aborting " << endl;
                return(-1);
        }
 
 
-       float r = pts[0].r;
-       float c = pts[0].c;
+       double r = pts[0].r;
+       double c = pts[0].c;
        for( long k=0; k<nump; k++)
        {
-               float dr = pts[k].r-r;
-               float dc = pts[k].c-c;
+               double dr = pts[k].r-r;
+               double dc = pts[k].c-c;
 
                pts[k].ro = dr*dr + dc*dc;
 
@@ -242,13 +241,13 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
        sort( pts.begin(), pts.end() );
 
 
-       float r1 = pts[0].r;
-       float c1 = pts[0].c;
+       double r1 = pts[0].r;
+       double c1 = pts[0].c;
 
-       float r2 = pts[1].r;
-       float c2 = pts[1].c;
+       double r2 = pts[1].r;
+       double c2 = pts[1].c;
        long mid = -1;
-       float romin2 = 100000000.0, ro2, R=0,C=0;       // added by A.Balakin 6 July 2012 -- uninitialised variable
+       double romin2 =  9.0e20, ro2, R=0,C=0;  // added by A.Balakin 21 April 2014 -- uninitialised variable
 
        long k=2;
        while (k<nump)
@@ -271,7 +270,7 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
 
        if( mid < 0 )
        {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //             cerr << "linear structure, aborting " << endl;
                return(-2);
        }
@@ -287,8 +286,8 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
 
        for( long k=0; k<nump-3; k++)
        {
-               float dr = pts[k].r-R;
-               float dc = pts[k].c-C;
+               double dr = pts[k].r-R;
+               double dc = pts[k].c-C;
 
                pts[k].ro = dr*dr + dc*dc;
 
@@ -300,8 +299,6 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
        pts.insert(pts.begin(), pt1);
        pts.insert(pts.begin(), pt0);
 
-       //  long slump [nump];
-//  long * slump  = new long [nump];
        std::vector<long> slump;
        slump.resize(nump);
 
@@ -325,13 +322,13 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
        std::vector<Shx> hull;
 
 
-       r = (pts[0].r + pts[1].r + pts[2].r )/(float) 3.0;
-       c = (pts[0].c + pts[1].c + pts[2].c )/(float) 3.0;
+       r = (pts[0].r + pts[1].r + pts[2].r )/(double) 3.0;
+       c = (pts[0].c + pts[1].c + pts[2].c )/(double) 3.0;
 
-       float dr0 = pts[0].r - r,  dc0 = pts[0].c - c;
-       float tr01 =  pts[1].r - pts[0].r, tc01 =  pts[1].c - pts[0].c;
+       double dr0 = pts[0].r - r,  dc0 = pts[0].c - c;
+       double tr01 =  pts[1].r - pts[0].r, tc01 =  pts[1].c - pts[0].c;
 
-       float df = -tr01* dc0 + tc01*dr0;
+       double df = -tr01* dc0 + tc01*dr0;
        if( df < 0 )    // [ 0 1 2 ]
        {
                pt0.tr = pt1.r-pt0.r;
@@ -386,9 +383,9 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
        // and creating triangles....
        // that will need to be flipped.
 
-       float dr, dc, rx,cx;
+       double dr, dc, rx,cx;
        Shx  ptx;
-       long numt=0;    // added by A.Balakin 6 July 2012 -- uninitialised variable
+       long numt=0;    // added by A.Balakin 21 April 2014 -- uninitialised variable
 
        for( long k=3; k<nump; k++)
        {
@@ -398,7 +395,7 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
                ptx.c = cx;
                ptx.id = pts[k].id;
 
-               long numh = (long) hull.size()/*, numh_old = numh*/;    // commented by A.Balakin 6 July 2012 -- unused variable
+               long numh = (long) hull.size()/*, numh_old = numh*/;    // commented by A.Balakin 21 April 2014 -- unused variable
                dr = rx- hull[0].r;
                dc = cx- hull[0].c;  // outwards pointing from hull[0] to pt.
 
@@ -406,10 +403,10 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
                long hidx;  // new hull point location within hull.....
 
 
-               float df = -dc* hull[0].tr + dr*hull[0].tc;    // visibility test vector.
+               double df = -dc* hull[0].tr + dr*hull[0].tc;    // visibility test vector.
                if( df < 0 )   // starting with a visible hull facet !!!
                {
-//                     long e1 = 1, e2 = numh; // commented by A.Balakin 6 July 2012 -- unused variable
+//                     long e1 = 1, e2 = numh; // commented by A.Balakin 21 April 2014 -- unused variable
                        hidx = 0;
 
                        // check to see if segment numh is also visible
@@ -678,17 +675,17 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
 
        }
 
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //     cerr << "of triangles " << triads.size() << " to be flipped. "<< endl;
 
        //  write_Triads(triads, "tris0.mat");
 
-       std::set<long> ids, ids2;
+       std::set<long> ids;
 
        long tf = T_flip_pro( pts, triads, slump, numt, 0, ids);
        if( tf < 0 )
        {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //             cerr << "cannot triangualte this set " << endl;
                return(-3);
        }
@@ -704,7 +701,25 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
                nit ++;
                if( tf < 0 )
                {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
+//                     cerr << "cannot triangualte this set " << endl;
+                       return(-4);
+               }
+       }
+
+       ids.clear();
+       nits = T_flip_edge( pts, triads, slump, numt, 0, ids);
+       nit=0;
+
+       while(  nits > 0 && nit < 100) {
+
+               tf = T_flip_pro_idx( pts, triads, slump, ids);
+               nits = (long) ids.size();
+               //      cerr << "flipping cycle  " << nit << "   active triangles " << nits << endl;
+               nit ++;
+               if( tf < 0 )
+               {
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //                     cerr << "cannot triangualte this set " << endl;
                        return(-4);
                }
@@ -713,8 +728,8 @@ long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads)
 }
 
 
-void circle_cent4(float r1,float c1, float r2,float c2, float r3,float c3,
-                                 float &r,float &c, float &ro2)
+void circle_cent4(double r1,double c1, double r2,double c2, double r3,double c3,
+                                 double &r,double &c, double &ro2)
 {
        /*
         *  function to return the center of a circle and its radius
@@ -743,9 +758,9 @@ void circle_cent4(float r1,float c1, float r2,float c2, float r3,float c3,
        else
                rd = (v6 - c*v5)/v4;
 
-       ro2 = (float)  ( (rd-r1)*(rd-r1) + (cd-c1)*(cd-c1) );
-       r = (float) rd;
-       c = (float) cd;
+       ro2 = (double)  ( (rd-r1)*(rd-r1) + (cd-c1)*(cd-c1) );
+       r = (double) rd;
+       c = (double) cd;
 
        return;
 }
@@ -756,16 +771,13 @@ void circle_cent4(float r1,float c1, float r2,float c2, float r3,float c3,
    erase duplicate points, do not change point ids.
 
 */
-// Change return type to size_t to be 64 bit compatible -- by A.Balakin 7 August 2012
 
-size_t de_duplicate( std::vector<Shx> &pts, std::vector<size_t> &outx )
-{
+long de_duplicate( std::vector<Shx> &pts, std::vector<long> &outx ) {
 
-       size_t nump = pts.size();
+       long nump = (long) pts.size();
        std::vector<Dupex> dpx;
        Dupex d;
-       for( size_t k=0; k<nump; k++)
-       {
+       for( long k=0; k<nump; k++) {
                d.r = pts[k].r;
                d.c = pts[k].c;
                d.id = k;
@@ -774,11 +786,10 @@ size_t de_duplicate( std::vector<Shx> &pts, std::vector<size_t> &outx )
 
        sort(dpx.begin(), dpx.end());
 
-       for( size_t k=0; k<nump-1; k++)
-       {
+       for( long k=0; k<nump-1; k++) {
                if( dpx[k].r == dpx[k+1].r && dpx[k].c == dpx[k+1].c )
                {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //                     cerr << "duplicate-point ids " << dpx[k].id << "  " << dpx[k+1].id << "   at  ("  << pts[dpx[k+1].id].r << "," << pts[dpx[k+1].id].c << ")" << endl;
                        outx.push_back( dpx[k+1].id);
                }
@@ -789,10 +800,9 @@ size_t de_duplicate( std::vector<Shx> &pts, std::vector<size_t> &outx )
 
        sort(outx.begin(), outx.end());
 
-       size_t nx = outx.size();
-       for( size_t k=nx; k>0; k--)
-       {
-               pts.erase(pts.begin()+outx[k-1]);
+       long nx = (long) outx.size();
+       for( long k=nx-1; k>=0; k--) {
+               pts.erase(pts.begin()+outx[k]);
        }
 
        return(nx);
@@ -814,7 +824,7 @@ size_t de_duplicate( std::vector<Shx> &pts, std::vector<size_t> &outx )
 long T_flip_pro( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<long> &slump, long numt, long start, std::set<long> &ids)
 {
 
-       float r3,c3;
+       double r3,c3;
        long pa,pb,pc, pd, D, L1, L2, L3, L4, T2;
 
        Triad tx, tx2;
@@ -888,11 +898,16 @@ long T_flip_pro( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<
                        }
                        else
                        {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //                             cerr << "triangle flipping error. " << t << endl;
                                return(-5);
                        }
 
+
+// Commented by A.Balakin 21 April 2014 -- unused variable
+//                     if( pd < 0 || pd > 100)
+//                             long dfx = 9;
+
                        r3 = pts[pd].r;
                        c3 = pts[pd].c;
 
@@ -1014,7 +1029,7 @@ long T_flip_pro( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<
                        }
                        else
                        {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //                             cerr << "triangle flipping error. " << t << endl;
                                return(-5);
                        }
@@ -1143,7 +1158,7 @@ long T_flip_pro( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<
                        }
                        else
                        {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //                             cerr << "triangle flipping error. " << t << endl;
                                return(-5);
                        }
@@ -1217,38 +1232,38 @@ long T_flip_pro( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<
 /* minimum angle cnatraint for circum circle test.
    due to Cline & Renka
 
-   A   --    B
+   A   --      B
 
-   |    /    |
+   |   /       |
 
-   C   --    D
+   C   --      D
 
 
  */
 
-long Cline_Renka_test(float &Ax, float &Ay,
-                                        float &Bx, float &By,
-                                        float &Cx, float &Cy,
-                                        float &Dx, float &Dy)
+long Cline_Renka_test(double &Ax, double &Ay,
+                                        double &Bx, double &By,
+                                        double &Cx, double &Cy,
+                                        double &Dx, double &Dy)
 {
 
-       float v1x = Bx-Ax, v1y = By-Ay,    v2x = Cx-Ax, v2y = Cy-Ay,
-                 v3x = Bx-Dx, v3y = By-Dy,    v4x = Cx-Dx, v4y = Cy-Dy;
-       float cosA = v1x*v2x + v1y*v2y;
-       float cosD = v3x*v4x + v3y*v4y;
+       double v1x = Bx-Ax, v1y = By-Ay,        v2x = Cx-Ax, v2y = Cy-Ay,
+                 v3x = Bx-Dx, v3y = By-Dy,     v4x = Cx-Dx, v4y = Cy-Dy;
+       double cosA = v1x*v2x + v1y*v2y;
+       double cosD = v3x*v4x + v3y*v4y;
 
        if( cosA < 0 && cosD < 0 ) // two obtuse angles
                return(-1);
 
-//     float ADX = Ax-Dx, ADy = Ay-Dy; // commented by A.Balakin 6 July 2012 -- unused variable
+//     double ADX = Ax-Dx, ADy = Ay-Dy;        // commented by A.Balakin 21 April 2014 -- unused variable
 
 
        if( cosA > 0 && cosD > 0 )  // two acute angles
                return(1);
 
 
-       float sinA = fabs(v1x*v2y - v1y*v2x);
-       float sinD = fabs(v3x*v4y - v3y*v4x);
+       double sinA = fabs(v1x*v2y - v1y*v2x);
+       double sinD = fabs(v3x*v4y - v3y*v4x);
 
        if( cosA*sinD + sinA*cosD < 0 )
                return(-1);
@@ -1266,7 +1281,7 @@ long Cline_Renka_test(float &Ax, float &Ay,
 long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<long> &slump, std::set<long> &ids)
 {
 
-       float  r3,c3;
+       double  r3,c3;
        long pa,pb,pc, pd,  D, L1, L2, L3, L4, T2;
 
        Triad tx, tx2;
@@ -1346,7 +1361,7 @@ long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vec
                        }
                        else
                        {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //                             cerr << "triangle flipping error. " << t << "  T2: " <<  T2<<  endl;
                                return(-6);
                        }
@@ -1473,7 +1488,7 @@ long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vec
                        }
                        else
                        {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //                             cerr << "triangle flipping error. " << t <<  endl;
                                return(-6);
                        }
@@ -1599,7 +1614,7 @@ long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vec
                        }
                        else
                        {
-// Commented by A.Balakin 2 July 2012 -- library shouldn't print anything
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
 //                             cerr << "triangle flipping error. " << t << endl;
                                return(-6);
                        }
@@ -1616,8 +1631,6 @@ long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vec
                                L2 = tri.bc;
                                if( L1 != L3 && L2 != L4 )   // need this check for stability.
                                {
-
-
                                        tx.a = tri.b;
                                        tx.b = tri.a;
                                        tx.c = D;
@@ -1626,19 +1639,15 @@ long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vec
                                        tx.ac = T2;
                                        tx.bc = L3;
 
-
                                        // triangle 2;
                                        tx2.a = tri.b;
                                        tx2.b = tri.c;
                                        tx2.c = D;
 
-
-
                                        tx2.ab = L2;
                                        tx2.ac = t;
                                        tx2.bc = L4;
 
-
                                        ids2.insert(t);
                                        ids2.insert(T2);
 
@@ -1666,8 +1675,6 @@ long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vec
                                }
                        }
                }
-
-
        }
 
        ids.clear();
@@ -1676,3 +1683,462 @@ long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vec
        return(1);
 }
 
+/* test the seed configuration to see if the center
+   of the circum circle lies inside the seed triangle.
+
+   if not issue a warning.
+*/
+
+
+long  test_center(Shx &pt0, Shx &pt1,Shx &pt2)
+{
+       double r01 = pt1.r - pt0.r;
+       double c01 = pt1.c - pt0.c;
+
+       double r02 = pt2.r - pt0.r;
+       double c02 = pt2.c - pt0.c;
+
+       double r21 = pt1.r - pt2.r;
+       double c21 = pt1.c - pt2.c;
+
+       double v = r01*r02 + c01*c02;
+       if( v < 0 ) return(-1);
+
+       v = r21*r02 + c21*c02;
+       if( v > 0 ) return(-1);
+
+       v = r01*r21 + c01*c21;
+       if( v < 0 ) return(-1);
+
+       return(1);
+}
+
+long de_duplicateX( std::vector<Shx> &pts, std::vector<long> &outx,std::vector<Shx> &pts2 )
+{
+       long nump = (long) pts.size();
+       std::vector<Dupex> dpx;
+       Dupex d;
+       for( long k=0; k<nump; k++)
+       {
+               d.r = pts[k].r;
+               d.c = pts[k].c;
+               d.id = k;
+               dpx.push_back(d);
+       }
+
+       sort(dpx.begin(), dpx.end());
+
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
+//     cerr << "de-duplicating ";
+       pts2.clear();
+       pts2.push_back(pts[dpx[0].id]);
+       pts2[0].id = 0;
+       long cnt = 1;
+
+       for( long k=0; k<nump-1; k++)
+       {
+               if( dpx[k].r == dpx[k+1].r && dpx[k].c == dpx[k+1].c )
+               {
+                       //cerr << "duplicate-point ids " << dpx[k].id << "  " << dpx[k+1].id << "   at  ("  << pts[dpx[k+1].id].r << "," << pts[dpx[k+1].id].c << ")" << endl;
+                       //cerr << dpx[k+1].id << " ";
+
+                       outx.push_back( dpx[k+1].id);
+               }
+               else
+               {
+                       pts[dpx[k+1].id].id = cnt;
+                       pts2.push_back(pts[dpx[k+1].id]);
+                       cnt++;
+               }
+       }
+
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
+//     cerr << "removed  " << outx.size() << endl;
+
+       return(outx.size());
+}
+
+
+
+long T_flip_edge( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<long> &slump, long numt, long start, std::set<long> &ids)
+{
+       double r3,c3;
+       long pa,pb,pc, pd, D, L1, L2, L3, L4, T2;
+
+       Triad tx, tx2;
+
+
+       for( long t=start; t<numt; t++)
+       {
+               Triad &tri = triads[t];
+               // test all 3 neighbours of tri
+
+               long flipped = 0;
+
+               if( tri.bc >= 0  && (tri.ac < 0 || tri.ab < 0) )
+               {
+                       pa = slump[tri.a];
+                       pb = slump[tri.b];
+                       pc = slump[tri.c];
+
+                       T2 = tri.bc;
+                       Triad &t2 = triads[T2];
+                       // find relative orientation (shared limb).
+                       if( t2.ab == t )
+                       {
+                               D = t2.c;
+                               pd = slump[t2.c];
+
+                               if( tri.b == t2.a)
+                               {
+                                       L3 = t2.ac;
+                                       L4 = t2.bc;
+                               }
+                               else {
+                                       L3 = t2.bc;
+                                       L4 = t2.ac;
+                               }
+                       }
+                       else if(  t2.ac == t )
+                       {
+                               D = t2.b;
+                               pd = slump[t2.b];
+
+                               if( tri.b == t2.a)
+                               {
+                                       L3 = t2.ab;
+                                       L4 = t2.bc;
+                               }
+                               else
+                               {
+                                       L3 = t2.bc;
+                                       L4 = t2.ab;
+                               }
+                       }
+                       else if(  t2.bc == t )
+                       {
+                               D = t2.a;
+                               pd = slump[t2.a];
+
+                               if( tri.b == t2.b)
+                               {
+                                       L3 = t2.ab;
+                                       L4 = t2.ac;
+                               }
+                               else
+                               {
+                                       L3 = t2.ac;
+                                       L4 = t2.ab;
+                               }
+                       }
+                       else
+                       {
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
+//                             cerr << "triangle flipping error. " << t << endl;
+                               return(-5);
+                       }
+
+
+// Commented by A.Balakin 21 April 2014 -- unused variable
+//                     if( pd < 0 || pd > 100)
+//                             long dfx = 9;
+
+                       r3 = pts[pd].r;
+                       c3 = pts[pd].c;
+
+                       long XX = Cline_Renka_test( pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c,
+                                                                          pts[pc].r, pts[pc].c, r3, c3 );
+
+                       if( XX < 0 ) {
+
+                               L1 = tri.ab;
+                               L2 = tri.ac;
+                               //      if( L1 != L3 && L2 != L4 ){  // need this check for stability.
+
+                               tx.a = tri.a;
+                               tx.b = tri.b;
+                               tx.c = D;
+
+                               tx.ab = L1;
+                               tx.ac = T2;
+                               tx.bc = L3;
+
+
+                               // triangle 2;
+                               tx2.a = tri.a;
+                               tx2.b = tri.c;
+                               tx2.c = D;
+
+                               tx2.ab = L2;
+                               tx2.ac = t;
+                               tx2.bc = L4;
+
+
+                               ids.insert(t);
+                               ids.insert(T2);
+
+                               t2 = tx2;
+                               tri = tx;
+                               flipped = 1;
+
+                               // change knock on triangle labels.
+                               if( L3 >= 0 )
+                               {
+                                       Triad &t3 = triads[L3];
+                                       if( t3.ab == T2 ) t3.ab = t;
+                                       else if( t3.bc == T2 ) t3.bc = t;
+                                       else if( t3.ac == T2 ) t3.ac = t;
+                               }
+
+                               if(L2 >= 0 )
+                               {
+                                       Triad &t4 = triads[L2];
+                                       if( t4.ab == t ) t4.ab = T2;
+                                       else if( t4.bc == t ) t4.bc = T2;
+                                       else if( t4.ac == t ) t4.ac = T2;
+                               }
+                               //      }
+                       }
+               }
+
+
+               if(  flipped == 0 && tri.ab >= 0  && (tri.ac < 0 || tri.bc < 0))
+               {
+                       pc = slump[tri.c];
+                       pb = slump[tri.b];
+                       pa = slump[tri.a];
+
+                       T2 = tri.ab;
+                       Triad &t2 = triads[T2];
+                       // find relative orientation (shared limb).
+                       if( t2.ab == t )
+                       {
+                               D = t2.c;
+                               pd = slump[t2.c];
+
+                               if( tri.a == t2.a)
+                               {
+                                       L3 = t2.ac;
+                                       L4 = t2.bc;
+                               }
+                               else
+                               {
+                                       L3 = t2.bc;
+                                       L4 = t2.ac;
+                               }
+                       }
+                       else if(  t2.ac == t )
+                       {
+                               D = t2.b;
+                               pd = slump[t2.b];
+
+                               if( tri.a == t2.a)
+                               {
+                                       L3 = t2.ab;
+                                       L4 = t2.bc;
+                               }
+                               else
+                               {
+                                       L3 = t2.bc;
+                                       L4 = t2.ab;
+                               }
+                       }
+                       else if(  t2.bc == t )
+                       {
+                               D = t2.a;
+                               pd = slump[t2.a];
+
+                               if( tri.a == t2.b)
+                               {
+                                       L3 = t2.ab;
+                                       L4 = t2.ac;
+                               }
+                               else
+                               {
+                                       L3 = t2.ac;
+                                       L4 = t2.ab;
+                               }
+                       }
+                       else {
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
+//                             cerr << "triangle flipping error. " << t << endl;
+                               return(-5);
+                       }
+
+                       r3 = pts[pd].r;
+                       c3 = pts[pd].c;
+
+                       long XX = Cline_Renka_test( pts[pc].r, pts[pc].c, pts[pb].r, pts[pb].c,
+                                                                          pts[pa].r, pts[pa].c,r3, c3);
+
+                       if( XX < 0)
+                       {
+                               L1 = tri.ac;
+                               L2 = tri.bc;
+                               //      if( L1 != L3 && L2 != L4 ){  // need this check for stability.
+
+                               tx.a = tri.c;
+                               tx.b = tri.a;
+                               tx.c = D;
+
+                               tx.ab = L1;
+                               tx.ac = T2;
+                               tx.bc = L3;
+
+                               // triangle 2;
+                               tx2.a = tri.c;
+                               tx2.b = tri.b;
+                               tx2.c = D;
+
+                               tx2.ab = L2;
+                               tx2.ac = t;
+                               tx2.bc = L4;
+
+                               ids.insert(t);
+                               ids.insert(T2);
+
+                               t2 = tx2;
+                               tri = tx;
+                               flipped = 1;
+
+                               // change knock on triangle labels.
+                               if( L3 >= 0 )
+                               {
+                                       Triad &t3 = triads[L3];
+                                       if( t3.ab == T2 ) t3.ab = t;
+                                       else if( t3.bc == T2 ) t3.bc = t;
+                                       else if( t3.ac == T2 ) t3.ac = t;
+                               }
+
+                               if(L2 >= 0 )
+                               {
+                                       Triad &t4 = triads[L2];
+                                       if( t4.ab == t ) t4.ab = T2;
+                                       else if( t4.bc == t ) t4.bc = T2;
+                                       else if( t4.ac == t ) t4.ac = T2;
+                               }
+                       }
+               }
+
+
+               if( flipped == 0 && tri.ac >= 0  && (tri.bc < 0 || tri.ab < 0) )
+               {
+                       pc = slump[tri.c];
+                       pb = slump[tri.b];
+                       pa = slump[tri.a];
+
+                       T2 = tri.ac;
+                       Triad &t2 = triads[T2];
+                       // find relative orientation (shared limb).
+                       if( t2.ab == t )
+                       {
+                               D = t2.c;
+                               pd = slump[t2.c];
+
+                               if( tri.a == t2.a)
+                               {
+                                       L3 = t2.ac;
+                                       L4 = t2.bc;
+                               }
+                               else
+                               {
+                                       L3 = t2.bc;
+                                       L4 = t2.ac;
+                               }
+                       }
+                       else if(  t2.ac == t )
+                       {
+                               D = t2.b;
+                               pd = slump[t2.b];
+
+                               if( tri.a == t2.a)
+                               {
+                                       L3 = t2.ab;
+                                       L4 = t2.bc;
+                               }
+                               else {
+                                       L3 = t2.bc;
+                                       L4 = t2.ab;
+                               }
+                       }
+                       else if(  t2.bc == t )
+                       {
+                               D = t2.a;
+                               pd = slump[t2.a];
+
+                               if( tri.a == t2.b)
+                               {
+                                       L3 = t2.ab;
+                                       L4 = t2.ac;
+                               }
+                               else
+                               {
+                                       L3 = t2.ac;
+                                       L4 = t2.ab;
+                               }
+                       }
+                       else
+                       {
+// Commented by A.Balakin 21 April 2014 -- library shouldn't print anything
+//                             cerr << "triangle flipping error. " << t << endl;
+                               return(-5);
+                       }
+
+                       r3 = pts[pd].r;
+                       c3 = pts[pd].c;
+
+                       long XX = Cline_Renka_test( pts[pb].r, pts[pb].c, pts[pa].r, pts[pa].c,
+                                                                          pts[pc].r, pts[pc].c,r3, c3);
+
+                       if( XX < 0 )
+                       {
+                               L1 = tri.ab;   // .ac shared limb
+                               L2 = tri.bc;
+                               //      if( L1 != L3 && L2 != L4 ){  // need this check for stability.
+
+                               tx.a = tri.b;
+                               tx.b = tri.a;
+                               tx.c = D;
+
+                               tx.ab = L1;
+                               tx.ac = T2;
+                               tx.bc = L3;
+
+
+                               // triangle 2;
+                               tx2.a = tri.b;
+                               tx2.b = tri.c;
+                               tx2.c = D;
+
+                               tx2.ab = L2;
+                               tx2.ac = t;
+                               tx2.bc = L4;
+
+                               ids.insert(t);
+                               ids.insert(T2);
+
+                               t2 = tx2;
+                               tri = tx;
+
+                               // change knock on triangle labels.
+                               if( L3 >= 0 )
+                               {
+                                       Triad &t3 = triads[L3];
+                                       if( t3.ab == T2 ) t3.ab = t;
+                                       else if( t3.bc == T2 ) t3.bc = t;
+                                       else if( t3.ac == T2 ) t3.ac = t;
+                               }
+
+                               if(L2 >= 0 )
+                               {
+                                       Triad &t4 = triads[L2];
+                                       if( t4.ab == t ) t4.ab = T2;
+                                       else if( t4.bc == t ) t4.bc = T2;
+                                       else if( t4.ac == t ) t4.ac = T2;
+                               }
+                       }
+               }
+       }
+       return(1);
+}
+
index 7d4979aebb07dea2bf8300a1b0acfcd34e0d6c16..ceb81b0a58cdb0a70839b190277962499e83e29b 100644 (file)
@@ -1,38 +1,31 @@
 #ifndef _structures_h
 #define _structures_h
 
-
-
-
 // for FILE
 
 #include <stdlib.h>
 #include <vector>
 #include <set>
 
-
-
 /*
-   for use in s_hull_pro.cpp
-
-S-hull-pro, Copyright (c) 2012
-Dr David SInclair
-Cambridge, UK
-
-email david@s-hull.org
+       for use in s_hull_pro.cpp
 
+       S-hull-pro, Copyright (c) 2012
+       Dr David SInclair
+       Cambridge, UK
 
+       email david@s-hull.org
 */
 
-// Global replace int->long by A.Balakin 7 August 2012 -- 64bit version can handle huge data arrays
+// Global replace int->long by A.Balakin 21 April 2014 -- 64bit version can handle huge data arrays
 
 struct Triad
 {
        long a,b, c;
        long ab, bc, ac;  // adjacent edges index to neighbouring triangle.
-       float ro, R,C;
+       double ro, R,C;
        //std::set<long> idx;
-       Triad() {a=b=c=ab=bc=ac=0;      ro=R=C=0;}      // added by A.Balakin 6 July 2012 -- uninitialised variable
+       Triad() {a=b=c=0;       ab=bc=ac=-1;    ro=-1;  R=C=0;} // added by A.Balakin 21 April 2014 -- uninitialised variable
        Triad(long x, long y) : a(x), b(y),c(0), ab(-1), bc(-1), ac(-1), ro(-1), R(0), C(0) {}
        Triad(long x, long y, long z) : a(x), b(y), c(z),  ab(-1), bc(-1), ac(-1), ro(-1), R(0), C(0) {}
        Triad(const Triad &p) : a(p.a), b(p.b), c(p.c), ab(p.ab), bc(p.bc), ac(p.ac), ro(p.ro), R(p.R), C(p.C) {}
@@ -65,13 +58,12 @@ struct Triad
 struct Shx
 {
        long id, trid;
-       float r,c, tr,tc ;
-       float ro;
-       Shx() {r=c=tr=tc=ro=0;  id=trid=0;}     // added by A.Balakin 6 July 2012 -- uninitialised variable
-       Shx(float a, float b) : id(-1), r(a), c(b), tr(0.0), tc(0.0), ro(0.0)
-       {       trid=0; }               // added by A.Balakin 6 July 2012 -- uninitialised variable
-       Shx(float a, float b, float x) : id(-1), r(a), c(b), tr(0), tc(0), ro(x)
-       {       trid=0; }       // added by A.Balakin 6 July 2012 -- uninitialised variable
+       double r,c, tr,tc, ro;
+       Shx() {r=c=tr=tc=ro=0;  id=-1;  trid=0;}        // added by A.Balakin 21 April 2014 -- uninitialised variable
+       Shx(double a, double b) : r(a), c(b)
+       {       trid=0; ro=tr=tc=0;     id=-1;  }                       // added by A.Balakin 21 April 2014 -- uninitialised variable
+       Shx(double a, double b, double x) : r(a), c(b), ro(x)
+       {       trid=0; tr=tc=0;        id=-1;  }                       // added by A.Balakin 21 April 2014 -- uninitialised variable
        Shx(const Shx &p) : id(p.id), trid(p.trid), r(p.r), c(p.c), tr(p.tr), tc(p.tc), ro(p.ro) {}
 
        Shx &operator=(const Shx &p)
@@ -85,27 +77,30 @@ struct Shx
                ro = p.ro;
                return *this;
        }
-
 };
 
 
 // sort into descending order (for use in corner responce ranking).
 inline bool operator<(const Shx &a, const Shx &b)
 {
-       if( a.ro == b.ro)
+       if( a.ro == b.ro) {
+               if( a.r == b.r ) {
+                       return a.c < b.c;
+               }
                return a.r < b.r;
+       }
        return a.ro <  b.ro;
-}
+};
 
 
 struct Dupex
 {
        long id;
-       float r,c;
+       double r,c;
 
-       Dupex() {}
-       Dupex(float a, float b) : id(-1), r(a), c(b) {}
-       Dupex(float a, float b, long x) : id(x), r(a), c(b) {}
+       Dupex() {       r=c=0;  id=-1;  }       // added by A.Balakin 21 April 2014 -- uninitialised variable
+       Dupex(double a, double b) : id(-1), r(a), c(b) {}
+       Dupex(double a, double b, long x) : id(x), r(a), c(b) {}
        Dupex(const Dupex &p) : id(p.id),  r(p.r), c(p.c) {}
 
        Dupex &operator=(const Dupex &p)
@@ -125,27 +120,28 @@ inline bool operator<(const Dupex &a, const Dupex &b)
        if( a.r == b.r)
                return a.c < b.c;
        return a.r <  b.r;
-}
+};
 
 
 
 
 
 // from s_hull.C
-
-
 long s_hull_pro( std::vector<Shx> &pts, std::vector<Triad> &triads);
-void circle_cent2(float r1,float c1, float r2,float c2, float r3,float c3,float &r,float &c, float &ro2);
-void circle_cent4(float r1,float c1, float r2,float c2, float r3,float c3,float &r,float &c, float &ro2);
+void circle_cent2(double r1,double c1, double r2,double c2, double r3,double c3,double &r,double &c, double &ro2);
+void circle_cent4(double r1,double c1, double r2,double c2, double r3,double c3,double &r,double &c, double &ro2);
 void write_Shx(std::vector<Shx> &pts, char * fname);
 void write_Triads(std::vector<Triad> &ts, char * fname);
-long Cline_Renka_test(float &Ax, float &Ay, float &Bx, float &By, float &Cx, float &Cy, float &Dx, float &Dy);
+long Cline_Renka_test(double &Ax, double &Ay, double &Bx, double &By, double &Cx, double &Cy, double &Dx, double &Dy);
 long T_flip_pro( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<long> &slump, long numt, long start, std::set<long> &ids);
 long T_flip_pro_idx( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<long> &slump, std::set<long> &ids);
 
 long read_Shx(std::vector<Shx> &pts, char * fname);
+long de_duplicate( std::vector<Shx> &pts,  std::vector<long> &outx );
+long de_duplicateX( std::vector<Shx> &pts, std::vector<long> &outx,std::vector<Shx> &pts2 );
+long  test_center(Shx &pt0, Shx &pt1,Shx &pt2);
 
+long T_flip_edge( std::vector<Shx> &pts, std::vector<Triad> &triads, std::vector<long> &slump, long numt, long start, std::set<long> &ids);
 
-size_t de_duplicate( std::vector<Shx> &pts,  std::vector<size_t> &outx );
 
 #endif
index f84765748a832645a67e712ed443f7b87eb1cf4a..0890e990149cfd86c2481d452f557d60793aceef 100644 (file)
@@ -27,27 +27,23 @@ void MGL_NO_EXPORT mgl_mesh_plot(mglBase *gr, long *pos, long n, long m, int how
 {\r
        int d = gr->MeshNum>0 ? gr->MeshNum+1 : n*m, dx = n>d?n/d:1, dy = m>d?m/d:1;\r
        // NOTE: number of lines in each direction can be reduced too\r
-       if(how&1)\r
-#pragma omp parallel for\r
-               for(long j=0;j<m;j+=dy)\r
-               {\r
-                       register long s,i;\r
-                       for(s=i=0;i<n-1;i++)    if(pos[n*j+i]>=0 && pos[n*j+i+1]>=0)    s++;\r
-                       d = gr->FaceNum>0 ? gr->FaceNum+1 : n;  s = s>d?s/d:1;\r
-                       for(i=0;i<n-s;i+=s)\r
-                               gr->line_plot(pos[n*j+i],pos[n*j+i+s]);\r
+       if(how&1)       for(long j=0;j<m;j+=dy)\r
+       {\r
+               register long s,i;\r
+               for(s=i=0;i<n-1;i++)    if(pos[n*j+i]>=0 && pos[n*j+i+1]>=0)    s++;\r
+               d = gr->FaceNum>0 ? gr->FaceNum+1 : n;  s = s>d?s/d:1;\r
+               for(i=0;i<n-s;i+=s)\r
+                       gr->line_plot(pos[n*j+i],pos[n*j+i+s]);\r
 \r
-               }\r
-       if(how&2)\r
-#pragma omp parallel for\r
-               for(long i=0;i<n;i+=dx)\r
-               {\r
-                       register long s,j;\r
-                       for(s=j=0;j<m-1;j++)    if(pos[n*j+i]>=0 && pos[n*j+i+n]>=0)    s++;\r
-                       d = gr->FaceNum>0 ? gr->FaceNum+1 : n;  s = s>d?s/d:1;\r
-                       for(j=0;j<m-s;j+=s)\r
-                               gr->line_plot(pos[n*j+i],pos[n*j+i+s*n]);\r
-               }\r
+       }\r
+       if(how&2)       for(long i=0;i<n;i+=dx)\r
+       {\r
+               register long s,j;\r
+               for(s=j=0;j<m-1;j++)    if(pos[n*j+i]>=0 && pos[n*j+i+n]>=0)    s++;\r
+               d = gr->FaceNum>0 ? gr->FaceNum+1 : n;  s = s>d?s/d:1;\r
+               for(j=0;j<m-s;j+=s)\r
+                       gr->line_plot(pos[n*j+i],pos[n*j+i+s*n]);\r
+       }\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_NO_EXPORT mgl_surf_plot(mglBase *gr, long *pos, long n, long m)\r
@@ -62,7 +58,6 @@ void MGL_NO_EXPORT mgl_surf_plot(mglBase *gr, long *pos, long n, long m)
                int d = gr->FaceNum+1,ns=n*s/((n-1)*(m-1)),ms=m*s/((n-1)*(m-1));\r
                dx = ns>d?ns/d:1;               dy = ms>d?ms/d:1;\r
        }\r
-#pragma omp parallel for collapse(2)\r
        for(long j=0;j<m-dy;j+=dy)      for(long i=0;i<n-dx;i+=dx)\r
                gr->quad_plot(pos[n*j+i],pos[n*j+i+dx],pos[n*j+i+n*dy],pos[n*j+i+n*dy+dx]);\r
 }\r
@@ -71,46 +66,42 @@ void MGL_NO_EXPORT mgl_surf_plot(mglBase *gr, long *pos, long n, long m)
 //     Plot by formulas series\r
 //\r
 //-----------------------------------------------------------------------------\r
+mglData MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector<mglDataA*> &head);\r
+//-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_fsurf(HMGL gr, const char *eqZ, const char *sch, const char *opt)\r
-{      // TODO: Add strong function variation analysis ???\r
+{      // NOTE Strong function variation analysis can be added here\r
        if(eqZ==0 || eqZ[0]==0) return;         // nothing to plot\r
        mreal r = gr->SaveState(opt);\r
        long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5);\r
-       mglData z(n,n);\r
-       mglFormula *eq = new mglFormula(eqZ);\r
-       mreal dx = (gr->Max.x - gr->Min.x)/(n-1.), dy = (gr->Max.y - gr->Min.y)/(n-1.);\r
-#pragma omp parallel for collapse(2)\r
-       for(long j=0;j<n;j++)   for(long i=0;i<n;i++)\r
-       {\r
-               if(gr->Stop)    continue;\r
-               z.a[i+n*j] = eq->Calc(gr->Min.x+i*dx, gr->Min.y+j*dy);\r
-       }\r
+       mglData z(n,n),res;\r
+       mglDataV x(n,n);        x.Fill(gr->Min.x,gr->Max.x,'x');        x.s=L"x";\r
+       mglDataV y(n,n);        y.Fill(gr->Min.y,gr->Max.y,'y');        y.s=L"y";\r
+       mglDataV t(n,n);        t.s=L"#$mgl";\r
+       std::vector<mglDataA*> list;\r
+       list.push_back(&x);     list.push_back(&y);     list.push_back(&t);\r
+       res.Set(mglFormulaCalc(eqZ,list));\r
+       if(res.nx==1 && res.ny==1)      z = res.a[0];   else    z = res;\r
        mgl_surf(gr, &z, sch,0);\r
-       delete eq;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_fsurf_xyz(HMGL gr, const char *eqX, const char *eqY, const char *eqZ, const char *sch, const char *opt)\r
-{      // TODO: Add strong function variation analisys ???\r
+{      // NOTE Strong function variation analysis can be added here\r
        if(eqZ==0 || eqZ[0]==0) return;         // nothing to plot\r
        mreal r = gr->SaveState(opt);\r
        long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5);\r
-       mglData x(n,n), y(n,n), z(n,n);\r
-       if(n<=0)        n=100;\r
-       mglFormula *ex, *ey, *ez;\r
-       ex = new mglFormula(eqX ? eqX : "u");\r
-       ey = new mglFormula(eqY ? eqY : "v");\r
-       ez = new mglFormula(eqZ);\r
-#pragma omp parallel for collapse(2)\r
-       for(long j=0;j<n;j++)   for(long i=0;i<n;i++)\r
-       {\r
-               if(gr->Stop)    continue;\r
-               register mreal u = j/(n-1.), v = i/(n-1.);\r
-               x.a[i+n*j] = ex->Calc(0,v,0,u);\r
-               y.a[i+n*j] = ey->Calc(0,v,0,u);\r
-               z.a[i+n*j] = ez->Calc(0,v,0,u);\r
-       }\r
+       mglData z(n,n), x(n,n), y(n,n), res;\r
+       mglDataV u(n,n);        u.Fill(0,1,'x');        u.s=L"u";\r
+       mglDataV v(n,n);        v.Fill(0,1,'y');        v.s=L"v";\r
+       mglDataV t(n,n);        t.s=L"#$mgl";\r
+       std::vector<mglDataA*> list;\r
+       list.push_back(&u);     list.push_back(&v);     list.push_back(&t);\r
+       res.Set(mglFormulaCalc(eqX,list));\r
+       if(res.nx==1 && res.ny==1)      x = res.a[0];   else    x = res;\r
+       res.Set(mglFormulaCalc(eqY,list));\r
+       if(res.nx==1 && res.ny==1)      y = res.a[0];   else    y = res;\r
+       res.Set(mglFormulaCalc(eqZ,list));\r
+       if(res.nx==1 && res.ny==1)      z = res.a[0];   else    z = res;\r
        mgl_surf_xy(gr,&x,&y,&z,sch,0);\r
-       delete ex;      delete ey;      delete ez;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_fsurf_(uintptr_t *gr, const char *fy, const char *stl, const char *opt, int ly, int ls, int lo)\r
@@ -148,10 +139,9 @@ void MGL_EXPORT mgl_mesh_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 \r
        for(long k=0;k<z->GetNz();k++)\r
        {\r
-#pragma omp parallel for collapse(2)\r
+               if(gr->NeedStop())      break;\r
                for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register mreal zz = z->v(i,j,k);\r
                        pos[i+n*j] = gr->AddPnt(mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, zz),gr->GetC(ss,zz));\r
                }\r
@@ -163,7 +153,7 @@ void MGL_EXPORT mgl_mesh_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 void MGL_EXPORT mgl_mesh(HMGL gr, HCDT z, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()), y(z->GetNy());\r
+       mglDataV x(z->GetNx()), y(z->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_mesh_xy(gr,&x,&y,z,sch,0);\r
@@ -197,10 +187,9 @@ void MGL_EXPORT mgl_fall_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 \r
        for(long k=0;k<z->GetNz();k++)\r
        {\r
-#pragma omp parallel for collapse(2)\r
+               if(gr->NeedStop())      break;\r
                for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register mreal zz = z->v(i,j,k);\r
                        pos[i+n*j] = gr->AddPnt(mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, zz),gr->GetC(ss,zz));\r
                }\r
@@ -212,7 +201,7 @@ void MGL_EXPORT mgl_fall_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 void MGL_EXPORT mgl_fall(HMGL gr, HCDT z, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()), y(z->GetNy());\r
+       mglDataV x(z->GetNx()), y(z->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_fall_xy(gr,&x,&y,z,sch,0);\r
@@ -246,13 +235,10 @@ void MGL_EXPORT mgl_grid_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 \r
        for(long k=0;k<z->GetNz();k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                if(z->GetNz()>1)        zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(z->GetNz()-1);\r
-#pragma omp parallel for collapse(2)\r
                for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
-               {\r
-                       if(gr->Stop)    continue;\r
                        pos[i+n*j] = gr->AddPnt(mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, zVal),gr->CDef);\r
-               }\r
                mgl_mesh_plot(gr,pos,n,m,3);\r
        }\r
        delete []pos;   gr->EndGroup();\r
@@ -261,7 +247,7 @@ void MGL_EXPORT mgl_grid_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 void MGL_EXPORT mgl_grid(HMGL gr, HCDT z,const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()), y(z->GetNy());\r
+       mglDataV x(z->GetNx()), y(z->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_grid_xy(gr,&x,&y,z,sch,0);\r
@@ -296,10 +282,9 @@ void MGL_EXPORT mgl_surf_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
        mglPoint p,q,s,xx,yy;\r
        for(long k=0;k<z->GetNz();k++)\r
        {\r
-#pragma omp parallel for private(p,q,s,xx,yy) collapse(2)\r
+               if(gr->NeedStop())      break;\r
                for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        xx = GetX(x,i,j,k);             yy = GetY(y,i,j,k);\r
                        p = mglPoint(xx.x, yy.x, z->v(i,j,k));\r
                        q = mglPoint(xx.y, yy.y, z->dvx(i,j,k));\r
@@ -307,13 +292,11 @@ void MGL_EXPORT mgl_surf_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
                        pos[i+n*j] = gr->AddPnt(p,gr->GetC(ss,p.z),q^s);\r
                }\r
                if(sch && mglchr(sch,'.'))\r
-#pragma omp parallel for\r
                        for(long i=0;i<n*m;i++) gr->mark_plot(pos[i],'.');\r
                else    mgl_surf_plot(gr,pos,n,m);\r
-               if(wire && !gr->Stop)\r
+               if(wire)\r
                {\r
                        gr->SetPenPal("k-");\r
-#pragma omp parallel for\r
                        for(long i=0;i<n*m;i++) pos[i] = gr->CopyNtoC(pos[i],gr->CDef);\r
                        mgl_mesh_plot(gr,pos,n,m,3);\r
                }\r
@@ -324,7 +307,7 @@ void MGL_EXPORT mgl_surf_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 void MGL_EXPORT mgl_surf(HMGL gr, HCDT z, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()), y(z->GetNy());\r
+       mglDataV x(z->GetNx()), y(z->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_surf_xy(gr,&x,&y,z,sch,0);\r
@@ -360,12 +343,11 @@ void MGL_EXPORT mgl_belt_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
        mglPoint p1,p2,q,s,xx,yy;\r
        for(long k=0;k<z->GetNz();k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                if(how) for(long i=0;i<n-dx;i+=dx)\r
                {\r
-#pragma omp parallel for private(p1,p2,xx,yy,q,s)\r
                        for(long j=0;j<m;j++)\r
                        {\r
-                               if(gr->Stop)    continue;\r
                                xx = GetX(x,i,j,k);             yy = GetY(y,i,j,k);\r
                                p1 = mglPoint(xx.x, yy.x, z->v(i,j,k));\r
                                s = mglPoint(xx.z, yy.z, z->dvy(i,j,k));\r
@@ -379,10 +361,8 @@ void MGL_EXPORT mgl_belt_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
                }\r
                else    for(long j=0;j<m-dy;j+=dy)\r
                {\r
-#pragma omp parallel for private(p1,p2,xx,yy,q,s)\r
                        for(long i=0;i<n;i++)   // ñîçäàåì ìàññèâ òî÷åê\r
                        {\r
-                               if(gr->Stop)    continue;\r
                                xx = GetX(x,i,j,k);             yy = GetY(y,i,j,k);\r
                                p1 = mglPoint(xx.x, yy.x, z->v(i,j,k));\r
                                q = mglPoint(xx.y, yy.y, z->dvx(i,j,k));\r
@@ -401,7 +381,7 @@ void MGL_EXPORT mgl_belt_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 void MGL_EXPORT mgl_belt(HMGL gr, HCDT z, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()), y(z->GetNy());\r
+       mglDataV x(z->GetNx()), y(z->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_belt_xy(gr,&x,&y,z,sch,0);\r
@@ -439,25 +419,22 @@ void MGL_EXPORT mgl_dens_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
        mreal zz, c;\r
        for(long k=0;k<z->GetNz();k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                if(z->GetNz()>1)\r
                        zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(z->GetNz()-1);\r
-#pragma omp parallel for private(p,c,zz) collapse(2)\r
                for(long j=0;j<m;j++)   for(long i=0;i<n;i++)   // ñîçäàåì ìàññèâ òî÷åê\r
                {\r
-                       if(gr->Stop)    continue;\r
                        p = mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, zVal);\r
                        zz = z->v(i,j,k);       c = gr->GetC(ss,zz);\r
                        if(mgl_isnan(zz))       p.x = NAN;\r
                        pos[i+n*j] = gr->AddPnt(p,c,s);\r
                }\r
                if(sch && mglchr(sch,'.'))\r
-#pragma omp parallel for\r
                        for(long i=0;i<n*m;i++) gr->mark_plot(pos[i],'.');\r
                else    mgl_surf_plot(gr,pos,n,m);\r
-               if(wire && !gr->Stop)\r
+               if(wire)\r
                {\r
                        gr->SetPenPal("k-");\r
-#pragma omp parallel for\r
                        for(long i=0;i<n*m;i++) pos[i] = gr->CopyNtoC(pos[i],gr->CDef);\r
                        mgl_mesh_plot(gr,pos,n,m,3);\r
                }\r
@@ -468,7 +445,7 @@ void MGL_EXPORT mgl_dens_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 void MGL_EXPORT mgl_dens(HMGL gr, HCDT z, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()), y(z->GetNy());\r
+       mglDataV x(z->GetNx()), y(z->GetNy());\r
        x.Fill(gr->Min.x, gr->Max.x);\r
        y.Fill(gr->Min.y, gr->Max.y);\r
        mgl_dens_xy(gr,&x,&y,z,sch,0);\r
@@ -523,10 +500,9 @@ void MGL_EXPORT mgl_surfc_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char
        mglPoint p,q,s,xx,yy;\r
        for(long k=0;k<z->GetNz();k++)\r
        {\r
-#pragma omp parallel for private(p,xx,yy,q,s) collapse(2)\r
+               if(gr->NeedStop())      break;\r
                for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        xx = GetX(x,i,j,k);             yy = GetY(y,i,j,k);\r
                        p = mglPoint(xx.x, yy.x, z->v(i,j,k));\r
                        q = mglPoint(xx.y, yy.y, z->dvx(i,j,k));\r
@@ -534,13 +510,11 @@ void MGL_EXPORT mgl_surfc_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char
                        pos[i+n*j] = gr->AddPnt(p,gr->GetC(ss,c->v(i,j,k)),q^s);\r
                }\r
                if(sch && mglchr(sch,'.'))\r
-#pragma omp parallel for\r
                        for(long i=0;i<n*m;i++) gr->mark_plot(pos[i],'.');\r
                else    mgl_surf_plot(gr,pos,n,m);\r
-               if(wire && !gr->Stop)\r
+               if(wire)\r
                {\r
                        gr->SetPenPal("k-");\r
-#pragma omp parallel for\r
                        for(long i=0;i<n*m;i++) pos[i] = gr->CopyNtoC(pos[i],gr->CDef);\r
                        mgl_mesh_plot(gr,pos,n,m,3);\r
                }\r
@@ -551,7 +525,7 @@ void MGL_EXPORT mgl_surfc_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char
 void MGL_EXPORT mgl_surfc(HMGL gr, HCDT z, HCDT c, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()), y(z->GetNy());\r
+       mglDataV x(z->GetNx()), y(z->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_surfc_xy(gr,&x,&y,z,c,sch,0);\r
@@ -586,10 +560,9 @@ void MGL_EXPORT mgl_surfa_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char
        mglPoint p,q,s,xx,yy;\r
        for(k=0;k<z->GetNz();k++)\r
        {\r
-#pragma omp parallel for private(p,xx,yy,q,s) collapse(2)\r
+               if(gr->NeedStop())      break;\r
                for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        xx = GetX(x,i,j,k);             yy = GetY(y,i,j,k);\r
                        mreal vv = z->v(i,j,k); p = mglPoint(xx.x, yy.x, vv);\r
                        q = mglPoint(xx.y, yy.y, z->dvx(i,j,k));\r
@@ -597,13 +570,11 @@ void MGL_EXPORT mgl_surfa_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char
                        pos[i+n*j] = gr->AddPnt(p,gr->GetC(ss,vv),q^s,gr->GetA(c->v(i,j,k)));\r
                }\r
                if(sch && mglchr(sch,'.'))\r
-#pragma omp parallel for\r
                        for(long i=0;i<n*m;i++) gr->mark_plot(pos[i],'.');\r
                else    mgl_surf_plot(gr,pos,n,m);\r
-               if(wire && !gr->Stop)\r
+               if(wire)\r
                {\r
                        gr->SetPenPal("k-");\r
-#pragma omp parallel for\r
                        for(long i=0;i<n*m;i++) pos[i] = gr->CopyNtoC(pos[i],gr->CDef);\r
                        mgl_mesh_plot(gr,pos,n,m,3);\r
                }\r
@@ -614,7 +585,7 @@ void MGL_EXPORT mgl_surfa_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char
 void MGL_EXPORT mgl_surfa(HMGL gr, HCDT z, HCDT c, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()), y(z->GetNy());\r
+       mglDataV x(z->GetNx()), y(z->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_surfa_xy(gr,&x,&y,z,c,sch,0);\r
@@ -654,9 +625,9 @@ void MGL_EXPORT mgl_boxs_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
        long k1,k2,k3,k4,k5,k6,k7,k8;\r
        for(k=0;k<z->GetNz();k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                for(i=0;i<n;i+=dx)      for(j=0;j<m;j+=dy)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        zz = z->v(i,j,k);               c  = gr->GetC(ss,zz);\r
                        xx = GetX(x,i,j,k);             yy = GetY(y,i,j,k);\r
                        x1 = i<lx-dx ? GetX(x,i+dx,j,k).x:NAN;\r
@@ -721,7 +692,7 @@ void MGL_EXPORT mgl_boxs_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 void MGL_EXPORT mgl_boxs(HMGL gr, HCDT z, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()+1), y(z->GetNy()+1);\r
+       mglDataV x(z->GetNx()+1), y(z->GetNy()+1);\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_boxs_xy(gr,&x,&y,z,sch,0);\r
@@ -757,10 +728,9 @@ void MGL_EXPORT mgl_tile_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
        mglPoint s=mglPoint(0,0,1);\r
        for(long k=0;k<z->GetNz();k++)\r
        {\r
-#pragma omp parallel for collapse(2)\r
+               if(gr->NeedStop())      break;\r
                for(long j=0;j<m;j+=dx) for(long i=0;i<n;i+=dy)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register mreal zz = z->v(i,j,k), c = gr->GetC(ss,zz);\r
                        register mreal xx = GetX(x,i,j,k).x, yy = GetY(y,i,j,k).x;\r
                        register long k1 = gr->AddPnt(mglPoint(xx,yy,zz),c,s);\r
@@ -782,7 +752,7 @@ void MGL_EXPORT mgl_tile_xy(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, co
 void MGL_EXPORT mgl_tile(HMGL gr, HCDT z, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()+1), y(z->GetNy()+1);\r
+       mglDataV x(z->GetNx()+1), y(z->GetNy()+1);\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_tile_xy(gr,&x,&y,z,sch,0);\r
@@ -819,10 +789,9 @@ void MGL_EXPORT mgl_tiles_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT s, const char
        mreal x1,x2,x3,x4,y1,y2,y3,y4;\r
        for(long k=0;k<z->GetNz();k++)\r
        {\r
-#pragma omp parallel for private(x1,x2,x3,x4,y1,y2,y3,y4) collapse(2)\r
+               if(gr->NeedStop())      break;\r
                for(long j=0;j<m;j+=dx) for(long i=0;i<n;i+=dy)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register mreal zz = z->v(i,j,k), c = gr->GetC(cc,zz);\r
                        register mreal ss = (1-gr->GetA(s->v(i,j,k)))/2, sm = 1-ss;\r
 \r
@@ -849,7 +818,7 @@ void MGL_EXPORT mgl_tiles_xy(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT s, const char
 void MGL_EXPORT mgl_tiles(HMGL gr, HCDT z, HCDT s, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(z->GetNx()+1), y(z->GetNy()+1);\r
+       mglDataV x(z->GetNx()+1), y(z->GetNy()+1);\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_tiles_xy(gr,&x,&y,z,s,sch,0);\r
@@ -874,12 +843,12 @@ void MGL_EXPORT mgl_map_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char
        long n=ax->GetNx(),m=ax->GetNy();\r
        if(mgl_check_dim2(gr,x,y,ax,ay,"Map"))  return;\r
 \r
-       bool both = x->GetNx()==n && y->GetNx()==n && x->GetNy()==m && y->GetNy()==m;\r
+       bool nboth = !(x->GetNx()==n && y->GetNx()==n && x->GetNy()==m && y->GetNy()==m);\r
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("Map",cgid++);\r
 \r
        long ss = gr->AddTexture(mgl_have_color(sch)?sch:"rgb",2);\r
-       long s = both ? n:1;\r
+       long s = nboth ?1:n;\r
 \r
        mglPoint t=mglPoint(NAN);\r
        long *pos = new long[n*m];\r
@@ -888,7 +857,6 @@ void MGL_EXPORT mgl_map_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char
 #pragma omp parallel for collapse(2)\r
        for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
        {\r
-               if(gr->Stop)    continue;\r
                register long s1 = i>0 ? 1:0, s2 = i<n-1 ? 1:0;\r
                register mreal xdx = (ax->v(i+s2,j)-ax->v(i-s1,j))/(GetX(x,i+s2,j).x-GetX(x,i-s1,j).x);\r
                register mreal ydx = (ay->v(i+s2,j)-ay->v(i-s1,j))/(GetX(x,i+s2,j).x-GetX(x,i-s1,j).x);\r
@@ -898,22 +866,21 @@ void MGL_EXPORT mgl_map_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char
                xdx = xdx*ydy - xdy*ydx;        // Jacobian\r
                register mreal xx,yy;\r
 \r
-               if(both)\r
+               if(nboth)\r
                {\r
-                       xx = (x->v(i,j) - gr->Min.x)/(gr->Max.x - gr->Min.x);\r
-                       yy = (y->v(i,j) - gr->Min.y)/(gr->Max.y - gr->Min.y);\r
+                       xx = (x->v(i) - gr->Min.x)/(gr->Max.x - gr->Min.x);\r
+                       yy = (y->v(j) - gr->Min.y)/(gr->Max.y - gr->Min.y);\r
                }\r
                else\r
                {\r
-                       xx = (x->v(i) - gr->Min.x)/(gr->Max.x - gr->Min.x);\r
-                       yy = (y->v(j) - gr->Min.y)/(gr->Max.y - gr->Min.y);\r
+                       xx = (x->v(i,j) - gr->Min.x)/(gr->Max.x - gr->Min.x);\r
+                       yy = (y->v(i,j) - gr->Min.y)/(gr->Max.y - gr->Min.y);\r
                }\r
                if(xx<0)        xx=0;   if(xx>=1)       xx=1/MGL_FEPSILON;\r
                if(yy<0)        yy=0;   if(yy>=1)       yy=1/MGL_FEPSILON;\r
                pos[i+n*j] = gr->AddPnt(mglPoint(ax->v(i,j), ay->v(i,j), xdx),gr->GetC(ss,xx,false),t,yy);\r
        }\r
        if(sch && mglchr(sch,'.'))\r
-#pragma omp parallel for\r
                for(long i=0;i<n*m;i++) gr->mark_plot(pos[i],'.');\r
        else    mgl_surf_plot(gr,pos,n,m);\r
        delete []pos;   gr->EndGroup();\r
@@ -922,7 +889,7 @@ void MGL_EXPORT mgl_map_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char
 void MGL_EXPORT mgl_map(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_map_xy(gr,&x,&y,ax,ay,sch,0);\r
index 40483f5177d8506737961d80b27dc7214d076da7..e8297d976b72de57c2e76fbe273b1331dc042667 100644 (file)
@@ -20,6 +20,7 @@
 #include "mgl2/font.h"
 
 /// Table of LaTeX symbols and its UTF8 codes. This array MUST BE sorted!!!
+MGL_EXPORT long mgl_tex_num=1881-24;
 MGL_EXPORT mglTeXsymb mgl_tex_symb[] = {
        {0x23, L"#"},
        {0x25, L"%"},
@@ -349,6 +350,8 @@ MGL_EXPORT mglTeXsymb mgl_tex_symb[] = {
        {0x2130, L"calE"},
        {0x2131, L"calF"},
        {0x210b, L"calH"},
+       {0x2110, L"calI"},
+       {0x2112, L"calL"},
        {0x2133, L"calM"},
        {0x211b, L"calR"},
        {0x2229, L"cap"},
index 5b46c572402cb2818c77f0410492976c61de44b6..66034f26c063727bbc7aaa434b44fbd3cc5112bc 100644 (file)
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_traj_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
 {\r
-       long m,mx,my,mz,nx,ny,nz,n=ax->GetNx(),pal;\r
+       long n=ax->GetNx(),pal;\r
        if(mgl_check_dim1(gr,x,z,y,ax,"Traj"))  return;\r
        if(mgl_check_dim1(gr,ax,az,ay,0,"Traj"))        return;\r
 \r
        mreal len=gr->SaveState(opt);   if(mgl_isnan(len))      len = 0;\r
        static int cgid=1;      gr->StartGroup("Traj",cgid++);\r
 \r
-       register long i, j;\r
        // find maximum\r
-       i = ax->GetNy()>ay->GetNy() ? ax->GetNy():ay->GetNy();  j = z->GetNy()>az->GetNy() ? z->GetNy():az->GetNy();\r
-       m = x->GetNy()>y->GetNy() ? x->GetNy():y->GetNy();              if(i>m) m=i;    if(j>m) m=j;\r
+       long m = x->GetNy()>y->GetNy() ? x->GetNy():y->GetNy();\r
+       long i = ax->GetNy()>ay->GetNy() ? ax->GetNy():ay->GetNy();\r
+       long j = z->GetNy()>az->GetNy() ? z->GetNy():az->GetNy();\r
+       if(i>m) m=i;    if(j>m) m=j;\r
        gr->SetPenPal(sch,&pal);        gr->Reserve(4*n*m);\r
 \r
        mglPoint p1,p2;\r
@@ -49,15 +50,14 @@ void MGL_EXPORT mgl_traj_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
                xm = xm>da ? xm : da;\r
        }\r
        xm = 1./(xm ? sqrt(xm):1);*/\r
-       for(j=0;j<m;j++) // start prepare arrows\r
+       for(long j=0;j<m;j++) // start prepare arrows\r
        {\r
+               if(gr->NeedStop())      break;\r
                gr->NextColor(pal);\r
-               nx = j<x->GetNy() ? j:0;        ny = j<y->GetNy() ? j:0;        nz = j<z->GetNy() ? j:0;\r
-               mx = j<ax->GetNy() ? j:0;       my = j<ay->GetNy() ? j:0;       mz = j<az->GetNy() ? j:0;\r
-#pragma omp parallel for private(p1,p2)\r
+               long nx = j<x->GetNy() ? j:0, ny = j<y->GetNy() ? j:0, nz = j<z->GetNy() ? j:0;\r
+               long mx = j<ax->GetNy() ? j:0,my = j<ay->GetNy() ? j:0,mz = j<az->GetNy() ? j:0;\r
                for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        p1 = mglPoint(x->v(i,nx), y->v(i,ny), z->v(i,nz));\r
                        p2 = mglPoint(ax->v(i,mx),ay->v(i,my),az->v(i,mz));\r
                        mreal dd = p2.norm();\r
@@ -80,7 +80,7 @@ void MGL_EXPORT mgl_traj_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
 void MGL_EXPORT mgl_traj_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData z(x->GetNx()), az(x->GetNx());  z.Fill(gr->Min.z,gr->Min.z);\r
+       mglDataV z(x->GetNx()), az(x->GetNx()); z.Fill(gr->AdjustZMin());\r
        mgl_traj_xyz(gr,x,y,&z,ax,ay,&az,sch,0);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -148,11 +148,10 @@ void MGL_EXPORT mgl_vect_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const cha
 \r
        for(long k=0;k<l;k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                if(ax->GetNz()>1)       zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1);\r
-#pragma omp parallel for private(d,v,p1,p2) collapse(2)\r
                for(long j=0;j<m;j+=ty) for(long i=0;i<n;i+=tx)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        d = mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, zVal);\r
                        v = mglPoint(ax->v(i,j,k),ay->v(i,j,k));\r
                        mreal dd = v.norm(), c1, c2;\r
@@ -177,7 +176,7 @@ void MGL_EXPORT mgl_vect_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const cha
 void MGL_EXPORT mgl_vect_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_vect_xy(gr,&x,&y,ax,ay,sch,0);\r
@@ -247,26 +246,28 @@ void MGL_EXPORT mgl_vect_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
        ca /= (n*m*l)/(tx*ty*tz);\r
        xm = xm?1./xm:0;        cm = cm?1./cm:0;\r
 \r
-#pragma omp parallel for private(d,v,p1,p2) collapse(3)\r
-       for(long k=0;k<l;k+=tz) for(long i=0;i<n;i+=tx) for(long j=0;j<m;j+=ty)\r
+       for(long k=0;k<l;k+=tz)\r
        {\r
-               if(gr->Stop)    continue;\r
-               d=mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, GetZ(z,i,j,k).x);\r
-               v = mglPoint(ax->v(i,j,k),ay->v(i,j,k),az->v(i,j,k));\r
-               mreal dd = v.norm(),c1,c2;\r
-               v *= cm*(fix?(dd>dm ? 1./dd : 0) : xm);\r
+               if(gr->NeedStop())      break;\r
+               for(long i=0;i<n;i+=tx) for(long j=0;j<m;j+=ty)\r
+               {\r
+                       d=mglPoint(GetX(x,i,j,k).x, GetY(y,i,j,k).x, GetZ(z,i,j,k).x);\r
+                       v = mglPoint(ax->v(i,j,k),ay->v(i,j,k),az->v(i,j,k));\r
+                       mreal dd = v.norm(),c1,c2;\r
+                       v *= cm*(fix?(dd>dm ? 1./dd : 0) : xm);\r
 \r
-               if(end)         {       p1 = d-v;       p2 = d; }\r
-               else if(beg)    {       p1 = d; p2 = d+v;       }\r
-               else            {       p1=d-v/2.;      p2=d+v/2.;      }\r
-               if(grd) {       c1=gr->GetC(ss,dd*xm-0.5,false);        c2=gr->GetC(ss,dd*xm,false);    }\r
-               else    c1 = c2 = gr->GetC(ss,dd*xm,false);\r
-               long n1=gr->AddPnt(p1,c1),      n2=gr->AddPnt(p2,c2);\r
-               // allow vectors outside bounding box\r
-               if(n1<0 && n2>=0)       n1=gr->AddPnt(p1,c1,mglPoint(NAN),-1,2);\r
-               if(n2<0 && n1>=0)       n2=gr->AddPnt(p2,c2,mglPoint(NAN),-1,2);\r
-               if(dot) {       gr->line_plot(n1,n2);   gr->mark_plot(n1,'.');  }\r
-               else    gr->vect_plot(n1,n2);\r
+                       if(end)         {       p1 = d-v;       p2 = d; }\r
+                       else if(beg)    {       p1 = d; p2 = d+v;       }\r
+                       else            {       p1=d-v/2.;      p2=d+v/2.;      }\r
+                       if(grd) {       c1=gr->GetC(ss,dd*xm-0.5,false);        c2=gr->GetC(ss,dd*xm,false);    }\r
+                       else    c1 = c2 = gr->GetC(ss,dd*xm,false);\r
+                       long n1=gr->AddPnt(p1,c1),      n2=gr->AddPnt(p2,c2);\r
+                       // allow vectors outside bounding box\r
+                       if(n1<0 && n2>=0)       n1=gr->AddPnt(p1,c1,mglPoint(NAN),-1,2);\r
+                       if(n2<0 && n1>=0)       n2=gr->AddPnt(p2,c2,mglPoint(NAN),-1,2);\r
+                       if(dot) {       gr->line_plot(n1,n2);   gr->mark_plot(n1,'.');  }\r
+                       else    gr->vect_plot(n1,n2);\r
+               }\r
        }\r
        gr->EndGroup();\r
 }\r
@@ -274,7 +275,7 @@ void MGL_EXPORT mgl_vect_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
 void MGL_EXPORT mgl_vect_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -395,103 +396,6 @@ void MGL_NO_EXPORT mgl_get_slice(_mgl_vec_slice &s, HCDT x, HCDT y, HCDT z, HCDT
        }\r
 }\r
 //-----------------------------------------------------------------------------\r
-void MGL_NO_EXPORT mgl_get_slice_md(_mgl_vec_slice &s, const mglData *x, const mglData *y, const mglData *z, const mglData *ax, const mglData *ay, const mglData *az, char dir, mreal d, bool both)\r
-{\r
-       long n=ax->nx,m=ax->ny,l=ax->nz, nx=1,ny=1,p;\r
-\r
-       if(dir=='x')    {       nx = m; ny = l; if(d<0) d = n/2.;       }\r
-       if(dir=='y')    {       nx = n; ny = l; if(d<0) d = m/2.;       }\r
-       if(dir=='z')    {       nx = n; ny = m; if(d<0) d = l/2.;       }\r
-       s.x.Create(nx,ny);      s.y.Create(nx,ny);      s.z.Create(nx,ny);\r
-       s.ax.Create(nx,ny);     s.ay.Create(nx,ny);     s.az.Create(nx,ny);\r
-       p = long(d);    d -= p;\r
-       if(dir=='x' && p>=n-1)  {       d+=p-n+2;       p=n-2;  }\r
-       if(dir=='y' && p>=m-1)  {       d+=p-m+2.;      p=m-2;  }\r
-       if(dir=='z' && p>=l-1)  {       d+=p-l+2;       p=l-2;  }\r
-\r
-       if(both)\r
-       {\r
-               if(dir=='x')\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
-                       {\r
-                               register long i0 = i+nx*j, i1 = p+n*(i+m*j);\r
-                               s.x.a[i0] = x->a[i1]*(1-d) + x->a[i1+1]*d;\r
-                               s.y.a[i0] = y->a[i1]*(1-d) + y->a[i1+1]*d;\r
-                               s.z.a[i0] = z->a[i1]*(1-d) + z->a[i1+1]*d;\r
-                               s.ax.a[i0] = ax->a[i1]*(1-d) + ax->a[i1+1]*d;\r
-                               s.ay.a[i0] = ay->a[i1]*(1-d) + ay->a[i1+1]*d;\r
-                               s.az.a[i0] = az->a[i1]*(1-d) + az->a[i1+1]*d;\r
-                       }\r
-               if(dir=='y')\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
-                       {\r
-                               register long i0 = i+nx*j, i1 = i+n*(p+m*j);\r
-                               s.x.a[i0] = x->a[i1]*(1-d) + x->a[i1+n]*d;\r
-                               s.y.a[i0] = y->a[i1]*(1-d) + y->a[i1+n]*d;\r
-                               s.z.a[i0] = z->a[i1]*(1-d) + z->a[i1+n]*d;\r
-                               s.ax.a[i0] = ax->a[i1]*(1-d) + ax->a[i1+n]*d;\r
-                               s.ay.a[i0] = ay->a[i1]*(1-d) + ay->a[i1+n]*d;\r
-                               s.az.a[i0] = az->a[i1]*(1-d) + az->a[i1+n]*d;\r
-                       }\r
-               if(dir=='z')\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
-                       {\r
-                               register long i0 = i+nx*j, i1 = i+n*(j+m*p);\r
-                               s.x.a[i0] = x->a[i1]*(1-d) + x->a[i1+n*m]*d;\r
-                               s.y.a[i0] = y->a[i1]*(1-d) + y->a[i1+n*m]*d;\r
-                               s.z.a[i0] = z->a[i1]*(1-d) + z->a[i1+n*m]*d;\r
-                               s.ax.a[i0] = ax->a[i1]*(1-d) + ax->a[i1+n*m]*d;\r
-                               s.ay.a[i0] = ay->a[i1]*(1-d) + ay->a[i1+n*m]*d;\r
-                               s.az.a[i0] = az->a[i1]*(1-d) + az->a[i1+n*m]*d;\r
-                       }\r
-       }\r
-       else    // x, y, z -- vectors\r
-       {\r
-               if(dir=='x')\r
-               {\r
-                       mreal v = x->a[p]*(1-d)+x->a[p+1]*d;\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
-                       {\r
-                               register long i0 = i+nx*j, i1 = p+n*(i+m*j);    s.x.a[i0] = v;\r
-                               s.y.a[i0] = y->a[i];    s.z.a[i0] = z->a[j];\r
-                               s.ax.a[i0] = ax->a[i1]*(1-d) + ax->a[i1+1]*d;\r
-                               s.ay.a[i0] = ay->a[i1]*(1-d) + ay->a[i1+1]*d;\r
-                               s.az.a[i0] = az->a[i1]*(1-d) + az->a[i1+1]*d;\r
-                       }\r
-               }\r
-               if(dir=='y')\r
-               {\r
-                       mreal v = y->a[p]*(1-d)+y->a[p+1]*d;\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
-                       {\r
-                               register long i0 = i+nx*j, i1 = i+n*(p+m*j);    s.y.a[i0] = v;\r
-                               s.x.a[i0] = x->a[i];    s.z.a[i0] = z->a[j];\r
-                               s.ax.a[i0] = ax->a[i1]*(1-d) + ax->a[i1+n]*d;\r
-                               s.ay.a[i0] = ay->a[i1]*(1-d) + ay->a[i1+n]*d;\r
-                               s.az.a[i0] = az->a[i1]*(1-d) + az->a[i1+n]*d;\r
-                       }\r
-               }\r
-               if(dir=='z')\r
-               {\r
-                       mreal v = z->a[p]*(1-d)+z->a[p+1]*d;\r
-#pragma omp parallel for collapse(2)\r
-                       for(long j=0;j<ny;j++)  for(long i=0;i<nx;i++)\r
-                       {\r
-                               register long i0 = i+nx*j, i1 = i+n*(j+m*p);    s.z.a[i0] = v;\r
-                               s.x.a[i0] = x->a[i];    s.y.a[i0] = y->a[j];\r
-                               s.ax.a[i0] = ax->a[i1]*(1-d) + ax->a[i1+n*m]*d;\r
-                               s.ay.a[i0] = ay->a[i1]*(1-d) + ay->a[i1+n*m]*d;\r
-                               s.az.a[i0] = az->a[i1]*(1-d) + az->a[i1+n*m]*d;\r
-                       }\r
-               }\r
-       }\r
-}\r
-//-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_vect3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt)\r
 {\r
        bool both = mgl_isboth(x,y,z,ax);\r
@@ -511,16 +415,7 @@ void MGL_EXPORT mgl_vect3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
        long ss = gr->AddTexture(sch);\r
 \r
        _mgl_vec_slice s;\r
-       const mglData *mx = dynamic_cast<const mglData *>(x);\r
-       const mglData *my = dynamic_cast<const mglData *>(y);\r
-       const mglData *mz = dynamic_cast<const mglData *>(z);\r
-       const mglData *max = dynamic_cast<const mglData *>(ax);\r
-       const mglData *may = dynamic_cast<const mglData *>(ay);\r
-       const mglData *maz = dynamic_cast<const mglData *>(az);\r
-       if(mx&&my&&mz&&max&&may&&maz)\r
-               mgl_get_slice_md(s,mx,my,mz,max,may,maz,dir,sVal,both);\r
-       else\r
-               mgl_get_slice(s,x,y,z,ax,ay,az,dir,sVal,both);\r
+       mgl_get_slice(s,x,y,z,ax,ay,az,dir,sVal,both);\r
 \r
        long n=s.ax.nx,m=s.ax.ny, tx=1,ty=1;\r
        if(gr->MeshNum>1)       {       tx=(n-1)/(gr->MeshNum-1);       ty=(m-1)/(gr->MeshNum-1);       }\r
@@ -555,10 +450,8 @@ void MGL_EXPORT mgl_vect3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
        ca /= (n*m)/(tx*ty);\r
        xm = xm?1./xm:0;        cm = cm?1./cm:0;\r
 \r
-#pragma omp parallel for private(d,v,p1,p2) collapse(2)\r
        for(long i=0;i<n;i+=tx) for(long j=0;j<m;j+=ty)\r
        {\r
-               if(gr->Stop)    continue;\r
                register long i0 = i+n*j;\r
                d = mglPoint(s.x.a[i0], s.y.a[i0], s.z.a[i0]);\r
                v = mglPoint(s.ax.a[i0], s.ay.a[i0], s.az.a[i0]);\r
@@ -583,7 +476,7 @@ void MGL_EXPORT mgl_vect3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
 void MGL_EXPORT mgl_vect3(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy()),z(ax->GetNz());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy()),z(ax->GetNz()); // NOTE mglDataV here is useless\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -608,10 +501,9 @@ void MGL_EXPORT mgl_vect3_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_
 void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, long ss, bool vv)\r
 {\r
        long n=10*(ax.nx+ax.ny);\r
-       bool both = x.nx==ax.nx && y.nx==ax.nx && x.ny==ax.ny && y.ny==ax.ny;\r
+       bool nboth = x.nx*x.ny!=ax.nx*ax.ny || y.nx*y.ny!=ax.nx*ax.ny;\r
 \r
        mglPoint *pp = new mglPoint[n], dp;\r
-       mreal *cc = new mreal[n];\r
        mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
 \r
        mreal dt = 0.5/(ax.nx > ax.ny ? ax.nx : ax.ny),e,f,g,ff[4],gg[4],h,s=1;\r
@@ -619,26 +511,25 @@ void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, const mglD
        register long k=0,m;\r
        bool end = false;\r
        do{\r
-               if(gr->Stop)    {       delete []pp;    delete []cc;    return; }\r
-               pp[k].x = both ? x.Spline1(u,v,0):x.Spline1(u,0,0);\r
-               pp[k].y = both ? y.Spline1(u,v,0):y.Spline1(v,0,0);\r
+               pp[k].x = nboth ? x.Spline1(u,0,0):x.Spline1(u,v,0);\r
+               pp[k].y = nboth ? y.Spline1(v,0,0):y.Spline1(u,v,0);\r
                pp[k].z = zVal;\r
                for(m=0;m<k-1;m++)      // determines encircle\r
                        if(mgl_norm((pp[k]-pp[m])/dx)<dt/10.)   {       end = true;     break;  }\r
-               f = ax.Linear1(u,v,0);  g = ay.Linear1(u,v,0);\r
-               h = hypot(f,g); cc[k] = gr->GetC(ss,s*h);\r
+               f = ax.Spline1(u,v,0);  g = ay.Spline1(u,v,0);\r
+               h = hypot(f,g); pp[k].c = gr->GetC(ss,s*h);\r
                if(h<1e-5)      break;  // stationary point\r
                k++;\r
                // find next point by midpoint method\r
                h+=1;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                e = u+ff[0]/2;  h = v+gg[0]/2;\r
-               f = ax.Linear1(e,h,0);  g = ay.Linear1(e,h,0);\r
+               f = ax.Spline1(e,h,0);  g = ay.Spline1(e,h,0);\r
                h = 1+hypot(f,g);       ff[1]=f*dt/h;   gg[1]=g*dt/h;\r
                e = u+ff[1]/2;  h = v+gg[1]/2;\r
-               f = ax.Linear1(e,h,0);  g = ay.Linear1(e,h,0);\r
+               f = ax.Spline1(e,h,0);  g = ay.Spline1(e,h,0);\r
                h = 1+hypot(f,g);       ff[2]=f*dt/h;   gg[2]=g*dt/h;\r
                e = u+ff[2];    h = v+gg[2];\r
-               f = ax.Linear1(e,h,0);  g = ay.Linear1(e,h,0);\r
+               f = ax.Spline1(e,h,0);  g = ay.Spline1(e,h,0);\r
                h = 1+hypot(f,g);       ff[3]=f*dt/h;   gg[3]=g*dt/h;\r
                u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
                v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
@@ -647,11 +538,11 @@ void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, const mglD
        } while(!end);\r
        if(k>1)\r
        {\r
-               long i,j,jj,a=long(1./fabs(dt));\r
-               gr->Reserve(k);         j = gr->AddPnt(pp[0],cc[0]);\r
-               for(i=1;i<k;i++)\r
+               long j,a=long(1./fabs(dt));\r
+               gr->Reserve(k);         j = gr->AddPnt(pp[0],pp[0].c);\r
+               for(long i=1;i<k;i++)\r
                {\r
-                       jj=j;   j = gr->AddPnt(pp[i],cc[i]);\r
+                       long jj=j;      j = gr->AddPnt(pp[i],pp[i].c);\r
                        if(vv && i%a==0)\r
                        {\r
                                if(dt<0)        gr->vect_plot(j,jj,a/5);\r
@@ -660,12 +551,11 @@ void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, const mglD
                        else    gr->line_plot(jj,j);\r
                }\r
        }\r
-       delete []pp;    delete []cc;\r
+       delete []pp;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_flow_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
 {\r
-       mreal u,v;\r
        if(mgl_check_dim2(gr,x,y,ax,ay,"Flow")) return;\r
 \r
        mreal r = gr->SaveState(opt);\r
@@ -681,11 +571,13 @@ void MGL_EXPORT mgl_flow_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const cha
 \r
        for(long k=0;k<ax->GetNz();k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                if(ax->GetNz()>1)       zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1);\r
-#pragma omp parallel for private(u,v) collapse(2)\r
+//#pragma omp parallel for collapse(2)\r
                for(long i=0;i<num;i++) for(int s=-1;s<=1;s+=2)\r
                {\r
-                       if(gr->Stop)    continue;\r
+                       mreal u,v;\r
+                       if(gr->NeedStop())      {       i=num;  s=2;    continue;       }\r
                        u = 0;  v = (i+1.)/(num+1.);\r
                        flow(gr, zVal, s*u, s*v, xx, yy, bx, by,ss,vv);\r
                        u = 1;  v = (i+1.)/(num+1.);\r
@@ -709,7 +601,7 @@ void MGL_EXPORT mgl_flow_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const cha
 void MGL_EXPORT mgl_flow_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy());        // NOTE mglDataV here is useless\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_flow_xy(gr,&x,&y,ax,ay,sch,0);\r
@@ -726,10 +618,10 @@ void MGL_EXPORT mgl_flow_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_flowp_xy(HMGL gr, double x0, double y0, double z0, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
 {\r
-       mglPoint p(x0,y0,z0);\r
+       if(mgl_isnan(z0))       z0 = gr->Min.z;\r
        mreal u,v;\r
        long n=ax->GetNx(), m=ax->GetNy();\r
-       bool both = x->GetNx()==n && y->GetNx()==n && x->GetNy()==m && y->GetNy()==m;\r
+       bool nboth = x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m;\r
        if(mgl_check_dim2(gr,x,y,ax,ay,"FlowP"))        return;\r
 \r
        gr->SaveState(opt);\r
@@ -743,38 +635,38 @@ void MGL_EXPORT mgl_flowp_xy(HMGL gr, double x0, double y0, double z0, HCDT x, H
        long i0=0,j0=0;\r
        for(i=0;i<n;i++)        for(j=0;j<m;j++)        // first find closest\r
        {\r
-               d = both ? hypot(x->v(i,j)-p.x,y->v(i,j)-p.y) : hypot(x->v(i)-p.x,y->v(j)-p.y);\r
+               d = nboth ? hypot(x->v(i)-x0,y->v(j)-y0) : hypot(x->v(i,j)-x0,y->v(i,j)-y0);\r
                if(d<dm)        {       i0=i;   j0=j;   dm=d;   }\r
        }\r
        if(dm==0)       {       u = i0/mreal(n);        v = j0/mreal(m);        }       // we find it\r
        else\r
        {\r
                mreal dxu,dxv,dyu,dyv, dx, dy;\r
-               if(both)\r
+               if(nboth)\r
                {\r
-                       dx = x->v(i0,j0)-p.x;   dy = y->v(i0,j0)-p.y;\r
+                       dx = x->v(i0)-x0;       dy = y->v(j0)-y0;\r
+                       dxu= x->dvx(i0);        dyv= y->dvx(j0);\r
+                       u = (i0+dx/dxu)/n;      v = (j0+dy/dyv)/m;\r
+               }\r
+               else\r
+               {\r
+                       dx = x->v(i0,j0)-x0;    dy = y->v(i0,j0)-y0;\r
                        dxu= x->dvx(i0,j0);             dyu= y->dvx(i0,j0);\r
                        dxv= x->dvy(i0,j0);             dyv= y->dvy(i0,j0);\r
                        d = dxv*dyu-dxu*dyv;\r
                        u = (i0+(dxv*dy-dx*dyv)/d)/n;\r
                        v = (j0-(dxu*dy-dx*dyu)/d)/m;\r
                }\r
-               else\r
-               {\r
-                       dx = x->v(i0)-p.x;      dy = y->v(j0)-p.y;\r
-                       dxu= x->dvx(i0);        dyv= y->dvx(j0);\r
-                       u = (i0+dx/dxu)/n;      v = (j0+dy/dyv)/m;\r
-               }\r
        }\r
        mglData xx(x), yy(y), bx(ax), by(ay);\r
-       flow(gr, p.z, u, v, xx, yy, bx, by,ss,vv);\r
+       flow(gr, z0, u, v, xx, yy, bx, by,ss,vv);\r
        gr->EndGroup();\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_flowp_2d(HMGL gr, double x0, double y0, double z0, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_flowp_xy(gr,x0,y0,z0,&x,&y,ax,ay,sch,0);\r
@@ -798,9 +690,8 @@ void flow(mglBase *gr, double u, double v, double w, const mglData &x, const mgl
 {\r
        static long n=10*(ax.nx+ax.ny);\r
        long nn = ax.nx*ax.ny*ax.nz;\r
-       bool both = x.nx*x.ny*x.nz==nn && y.nx*y.ny*y.nz==nn && z.nx*z.ny*z.nz==nn;\r
+       bool nboth = x.nx*x.ny*x.nz!=nn || y.nx*y.ny*y.nz!=nn || z.nx*z.ny*z.nz!=nn;\r
        mglPoint *pp = new mglPoint[n], dp;\r
-       mreal *cc = new mreal[n];\r
        mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
 \r
        nn = (ax.nx > ax.ny ? ax.nx : ax.ny);\r
@@ -811,29 +702,28 @@ void flow(mglBase *gr, double u, double v, double w, const mglData &x, const mgl
        register long k=0,m;\r
        bool end = false;\r
        do{\r
-               if(gr->Stop)    {       delete []pp;    delete []cc;    return; }\r
-               pp[k].x = both ? x.Spline1(u,v,w):x.Spline1(u,0,0);\r
-               pp[k].y = both ? y.Spline1(u,v,w):y.Spline1(v,0,0);\r
-               pp[k].z = both ? z.Spline1(u,v,w):z.Spline1(w,0,0);\r
+               pp[k].x = nboth ? x.Spline1(u,0,0):x.Spline1(u,v,w);\r
+               pp[k].y = nboth ? y.Spline1(v,0,0):y.Spline1(u,v,w);\r
+               pp[k].z = nboth ? z.Spline1(w,0,0):z.Spline1(u,v,w);\r
                for(m=0;m<k-1;m++)      // determines encircle\r
                        if(mgl_norm((pp[k]-pp[m])/dx)<dt/10.)   {       end = true;     break;  }\r
-               e = ax.Linear1(u,v,w);  f = ay.Linear1(u,v,w);  g = az.Linear1(u,v,w);\r
-               h = sqrt(e*e+f*f+g*g);  cc[k] = gr->GetC(ss,s*h);\r
+               e = ax.Spline1(u,v,w);  f = ay.Spline1(u,v,w);  g = az.Spline1(u,v,w);\r
+               h = sqrt(e*e+f*f+g*g);  pp[k].c = gr->GetC(ss,s*h);\r
                if(h<1e-5)      break;  // stationary point\r
                k++;\r
                // find next point by midpoint method\r
                h+=1;   ee[0]=e*dt/h;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
-               e = ax.Linear1(u1,v1,w1);       f = ay.Linear1(u1,v1,w1);\r
-               g = az.Linear1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
+               e = ax.Spline1(u1,v1,w1);       f = ay.Spline1(u1,v1,w1);\r
+               g = az.Spline1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
                ee[1]=e*dt/h;   ff[1]=f*dt/h;   gg[1]=g*dt/h;\r
                u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2;\r
-               e = ax.Linear1(u1,v1,w1);       f = ay.Linear1(u1,v1,w1);\r
-               g = az.Linear1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
+               e = ax.Spline1(u1,v1,w1);       f = ay.Spline1(u1,v1,w1);\r
+               g = az.Spline1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
                ee[2]=e*dt/h;   ff[2]=f*dt/h;   gg[2]=g*dt/h;\r
                u1 = u+ee[2];   v1 = v+ff[2];   w1 = w+gg[2];\r
-               e = ax.Linear1(u1,v1,w1);       f = ay.Linear1(u1,v1,w1);\r
-               g = az.Linear1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
+               e = ax.Spline1(u1,v1,w1);       f = ay.Spline1(u1,v1,w1);\r
+               g = az.Spline1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
                ee[3]=e*dt/h;   ff[3]=f*dt/h;   gg[3]=g*dt/h;\r
                u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6;\r
                v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
@@ -843,21 +733,21 @@ void flow(mglBase *gr, double u, double v, double w, const mglData &x, const mgl
        } while(!end);\r
        if(k>1)\r
        {\r
-               long i,j,jj,a=long(1./fabs(dt));\r
+               long j,a=long(1./fabs(dt));\r
                mreal rr = mgl_norm(gr->Max-gr->Min)*gr->BarWidth/25, ll;\r
                mglPoint q1,q2,l;\r
-               long n1=-1,n2=-1,n3=-1,n4=-1, m1=-1,m2=-1,m3=-1,m4=-1;\r
+               long n1=-1,n2=-1,n3=-1,n4=-1;\r
 \r
-               gr->Reserve(4*k);       j = gr->AddPnt(pp[0],cc[0]);\r
+               gr->Reserve(4*k);       j = gr->AddPnt(pp[0],pp[0].c);\r
                l = pp[1] - pp[0];      l /= mgl_norm(l);\r
                q1 = mglPoint(l.y,-l.x,0);      ll = mgl_norm(q1);\r
                if(ll)  q1 /= ll;       else    q1 = mglPoint(0,1,0);\r
                q2 = q1^l;\r
                if(xo)  {       n1 = gr->AddPnt(pp[0],-1,q2);   n2 = gr->AddPnt(pp[0]+rr*q1,-1,q2);     }\r
                if(zo)  {       n3 = gr->AddPnt(pp[0],-1,q1);   n4 = gr->AddPnt(pp[0]+rr*q2,-1,q1);     }\r
-               for(i=1;i<k;i++)\r
+               for(long i=1;i<k;i++)\r
                {\r
-                       jj=j;   j = gr->AddPnt(pp[i],cc[i]);\r
+                       long jj=j;      j = gr->AddPnt(pp[i],pp[i].c);\r
                        if(vv && i%a==0)\r
                        {\r
                                if(dt<0)        gr->vect_plot(j,jj,a/5);\r
@@ -866,19 +756,18 @@ void flow(mglBase *gr, double u, double v, double w, const mglData &x, const mgl
                        else    gr->line_plot(jj,j);\r
                        l = pp[i]-pp[i-1];              l /= mgl_norm(l);\r
                        q1 -= l*(l*q1); q1/= mgl_norm(q1);      q2 = q1^l;\r
-                       m1 = n1;        m2 = n2;        m3 = n3;        m4 = n4;\r
+                       long m1 = n1, m2 = n2, m3 = n3, m4 = n4;\r
                        if(xo)\r
                        {       n1 = gr->AddPnt(pp[i],-1,q2);   n2 = gr->AddPnt(pp[i]+rr*q1,-1,q2);     gr->quad_plot(n1,n2,m1,m2);     }\r
                        if(zo)\r
                        {       n3 = gr->AddPnt(pp[i],-1,q1);   n4 = gr->AddPnt(pp[i]+rr*q2,-1,q1);     gr->quad_plot(n3,n4,m3,m4);     }\r
                }\r
        }\r
-       delete []pp;    delete []cc;\r
+       delete []pp;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_flow_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
 {\r
-       mreal u,v,w;\r
        if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Flow3"))   return;\r
 \r
        mreal r = gr->SaveState(opt);\r
@@ -889,10 +778,11 @@ void MGL_EXPORT mgl_flow_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
        bool vv = mglchr(sch,'v'), xo = mglchr(sch,'x'), zo = mglchr(sch,'z');\r
 \r
        mglData xx(x), yy(y), zz(z), bx(ax), by(ay), bz(az);\r
-#pragma omp parallel for private(u,v,w) collapse(3)\r
+//#pragma omp parallel for collapse(3)\r
        for(long i=0;i<num;i++) for(long j=0;j<num;j++) for(int s=-1;s<=1;s+=2)\r
        {\r
-               if(gr->Stop)    continue;\r
+               mreal u,v,w;\r
+               if(gr->NeedStop())      {       i=j=num;        s=2;    continue;       }\r
                u = (i+1.)/(num+1.);    v = (j+1.)/(num+1.);    w = 0;\r
                flow(gr, s*u, s*v, s*w, xx, yy, zz, bx, by, bz,ss,vv,xo,zo);\r
                u = (i+1.)/(num+1.);    v = (j+1.)/(num+1.);    w = 1;\r
@@ -921,7 +811,7 @@ void MGL_EXPORT mgl_flow_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
 void MGL_EXPORT mgl_flow_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz());        // NOTE mglDataV here is useless\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -942,7 +832,7 @@ void MGL_EXPORT mgl_flowp_xyz(HMGL gr, double x0, double y0, double z0, HCDT x,
        mglPoint p(x0,y0,z0);\r
        mreal u,v,w;\r
        long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz();\r
-       bool both = x->GetNx()*x->GetNy()*x->GetNz()==n*m*l && y->GetNx()*y->GetNy()*y->GetNz()==n*m*l && z->GetNx()*z->GetNy()*z->GetNz()==n*m*l;\r
+       bool nboth = !(x->GetNN()==n*m*l && y->GetNN()==n*m*l && z->GetNN()==n*m*l);\r
        if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"FlowP3"))  return;\r
 \r
        gr->SaveState(opt);\r
@@ -957,10 +847,10 @@ void MGL_EXPORT mgl_flowp_xyz(HMGL gr, double x0, double y0, double z0, HCDT x,
        mreal dx,dy,dz;\r
        for(i=0;i<n;i++)        for(j=0;j<m;j++)        for(k=0;k<l;k++)        // first find closest\r
        {\r
-               if(both)\r
-               {       dx = x->v(i,j,k)-p.x;   dy = y->v(i,j,k)-p.y;   dz = x->v(i,j,k)-p.z;   }\r
-               else\r
+               if(nboth)\r
                {       dx = x->v(i)-p.x;       dy = y->v(j)-p.y;       dz = x->v(k)-p.z;       }\r
+               else\r
+               {       dx = x->v(i,j,k)-p.x;   dy = y->v(i,j,k)-p.y;   dz = x->v(i,j,k)-p.z;   }\r
                d = sqrt(dx*dx+dy*dy+dz*dz);\r
                if(d<dm)        {       i0=i;   j0=j;   k0=k;   dm=d;   }\r
        }\r
@@ -969,7 +859,13 @@ void MGL_EXPORT mgl_flowp_xyz(HMGL gr, double x0, double y0, double z0, HCDT x,
        else\r
        {\r
                mreal dxu,dxv,dxw,dyu,dyv,dyw,dzu,dzv,dzw;\r
-               if(both)\r
+               if(nboth)\r
+               {\r
+                       dx = x->v(i0)-p.x;      dy = y->v(j0)-p.y;      dz = z->v(k0)-p.z;\r
+                       dxu= x->dvx(i0);        dyv= y->dvx(j0);        dzw= z->dvx(k0);\r
+                       u = (i0+dx/dxu)/n;      v = (j0+dy/dyv)/m;      w = (k0+dz/dzw)/m;\r
+               }\r
+               else\r
                {\r
                        dx = x->v(i0,j0,k0)-p.x;        dy = y->v(i0,j0,k0)-p.y;        dz = z->v(i0,j0,k0)-p.z;\r
                        dxu= x->dvx(i0,j0,k0);          dyu= y->dvx(i0,j0,k0);          dzu= z->dvx(i0,j0,k0);\r
@@ -980,12 +876,6 @@ void MGL_EXPORT mgl_flowp_xyz(HMGL gr, double x0, double y0, double z0, HCDT x,
                        v = (j0-(dx*(dyw*dzu-dyu*dzw)+dxu*(dy*dzw-dyw*dz)+dxw*(dyu*dz-dy*dzu))/d)/m;\r
                        w = (i0+(dx*(dyv*dzu-dyu*dzv)+dxu*(dy*dzv-dyv*dz)+dxv*(dyu*dz-dy*dzu))/d)/l;\r
                }\r
-               else\r
-               {\r
-                       dx = x->v(i0)-p.x;      dy = y->v(j0)-p.y;      dz = z->v(k0)-p.z;\r
-                       dxu= x->dvx(i0);        dyv= y->dvx(j0);        dzw= z->dvx(k0);\r
-                       u = (i0+dx/dxu)/n;      v = (j0+dy/dyv)/m;      w = (k0+dz/dzw)/m;\r
-               }\r
        }\r
        mglData xx(x), yy(y), zz(z), bx(ax), by(ay), bz(az);\r
        flow(gr, u, v, w, xx, yy, zz, bx, by, bz,ss,vv,xo,zo);\r
@@ -995,7 +885,7 @@ void MGL_EXPORT mgl_flowp_xyz(HMGL gr, double x0, double y0, double z0, HCDT x,
 void MGL_EXPORT mgl_flowp_3d(HMGL gr, double x0, double y0, double z0, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz());        // NOTE mglDataV here is useless\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -1021,7 +911,7 @@ void MGL_EXPORT mgl_grad_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT phi, const ch
        mglData ax(phi), ay,az,xx,yy,zz;\r
        ay.Set(ax);     az.Set(ax);     xx.Set(ax);     yy.Set(ax);     zz.Set(ax);\r
        long n=xx.nx, m=xx.ny, l=xx.nz, nn = n*m*l;\r
-       if(x->GetNx()*x->GetNy()*x->GetNz()==nn && y->GetNx()*y->GetNy()*y->GetNz()==nn && z->GetNx()*z->GetNy()*z->GetNz()==nn)\r
+       if(x->GetNN()==nn && y->GetNN()==nn && z->GetNN()==nn)\r
        {       xx.Set(x);      yy.Set(y);      zz.Set(z);      }       // nothing to do\r
        else if(x->GetNx()==n && y->GetNx()==m && z->GetNx()==l)\r
 #pragma omp parallel for collapse(3)\r
@@ -1052,7 +942,7 @@ void MGL_EXPORT mgl_grad_xy(HMGL gr, HCDT x, HCDT y, HCDT phi, const char *sch,
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_grad(HMGL gr, HCDT phi, const char *sch, const char *opt)\r
 {\r
-       mglData x(phi->GetNx()), y(phi->GetNy()), z(phi->GetNz());\r
+       mglDataV x(phi->GetNx()), y(phi->GetNy()), z(phi->GetNz());\r
        gr->SaveState(opt);\r
        x.Fill(gr->Min.x,gr->Max.x);    y.Fill(gr->Min.y,gr->Max.y);    z.Fill(gr->Min.z,gr->Max.z);\r
        if(phi->GetNz()==1)     mgl_grad_xy(gr,&x,&y,phi,sch,0);\r
@@ -1081,7 +971,7 @@ void MGL_EXPORT mgl_grad_(uintptr_t *gr, uintptr_t *ph, const char *sch, const c
 void MGL_NO_EXPORT flowr(mglBase *gr, double zVal, double u, double v, const mglData &x, const mglData &y, const mglData &ax, const mglData &ay, double r0,long sc)\r
 {\r
        long n=10*(ax.nx+ax.ny);\r
-       bool both = x.nx==ax.nx && y.nx==ax.nx && x.ny==ax.ny && y.ny==ax.ny;\r
+       bool nboth = x.nx*x.ny!=ax.nx*ax.ny || y.nx*y.ny!=ax.nx*ax.ny;\r
 \r
        mglPoint *pp = new mglPoint[n], dp;\r
        mreal *cc = new mreal[n];\r
@@ -1093,13 +983,12 @@ void MGL_NO_EXPORT flowr(mglBase *gr, double zVal, double u, double v, const mgl
        register long k=0,m;\r
        bool end = false;\r
        do{\r
-               if(gr->Stop)    {       delete []pp;    delete []cc;    return; }\r
-               pp[k].x = both ? x.Spline1(u,v,0):x.Spline1(u,0,0);\r
-               pp[k].y = both ? y.Spline1(u,v,0):y.Spline1(v,0,0);\r
+               pp[k].x = nboth ? x.Spline1(u,0,0):x.Spline1(u,v,0);\r
+               pp[k].y = nboth ? y.Spline1(v,0,0):y.Spline1(u,v,0);\r
                pp[k].z = zVal;\r
                for(m=0;m<k-1;m++)      // determines encircle\r
                        if(mgl_norm((pp[k]-pp[m])/dx)<dt/10.)   {       end = true;     break;  }\r
-               f = ax.Linear1(u,v,0);  g = ay.Linear1(u,v,0);\r
+               f = ax.Spline1(u,v,0);  g = ay.Spline1(u,v,0);\r
                h = hypot(f,g); cc[k] = gr->GetC(sc,s*h);\r
                pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
                if(h<1e-5)      break;  // stationary point\r
@@ -1107,13 +996,13 @@ void MGL_NO_EXPORT flowr(mglBase *gr, double zVal, double u, double v, const mgl
                // find next point by midpoint method\r
                h+=1;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                e = u+ff[0]/2;  h = v+gg[0]/2;\r
-               f = ax.Linear1(e,h,0);  g = ay.Linear1(e,h,0);  h = 1+hypot(f,g);\r
+               f = ax.Spline1(e,h,0);  g = ay.Spline1(e,h,0);  h = 1+hypot(f,g);\r
                ff[1]=f*dt/h;   gg[1]=g*dt/h;\r
                e = u+ff[1]/2;  h = v+gg[1]/2;\r
-               f = ax.Linear1(e,h,0);  g = ay.Linear1(e,h,0);  h = 1+hypot(f,g);\r
+               f = ax.Spline1(e,h,0);  g = ay.Spline1(e,h,0);  h = 1+hypot(f,g);\r
                ff[2]=f*dt/h;   gg[2]=g*dt/h;\r
                e = u+ff[2];    h = v+gg[2];\r
-               f = ax.Linear1(e,h,0);  g = ay.Linear1(e,h,0);  h = 1+hypot(f,g);\r
+               f = ax.Spline1(e,h,0);  g = ay.Spline1(e,h,0);  h = 1+hypot(f,g);\r
                ff[3]=f*dt/h;   gg[3]=g*dt/h;\r
                u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
                v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
@@ -1161,7 +1050,6 @@ void MGL_NO_EXPORT flowr(mglBase *gr, double zVal, double u, double v, const mgl
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_pipe_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, double r0, const char *opt)\r
 {\r
-       mreal u,v;\r
        if(mgl_check_dim2(gr,x,y,ax,ay,"Pipe")) return;\r
 \r
        mreal r = gr->SaveState(opt);\r
@@ -1177,11 +1065,13 @@ void MGL_EXPORT mgl_pipe_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const cha
        mglData xx(x), yy(y), bx(ax), by(ay);\r
        for(long k=0;k<ax->GetNz();k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                if(ax->GetNz()>1)       zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1);\r
-#pragma omp parallel for private(u,v) collapse(2)\r
+//#pragma omp parallel for collapse(2)\r
                for(long i=0;i<num;i++) for(int s=-1;s<=1;s+=2)\r
                {\r
-                       if(gr->Stop)    continue;\r
+                       mreal u,v;\r
+                       if(gr->NeedStop())      {       i=num;  s=2;    continue;       }\r
                        u = 0;  v = (i+1.)/(num+1.);\r
                        flowr(gr, zVal, s*u, s*v, xx, yy, bx, by,r0,ss);\r
                        u = 1;  v = (i+1.)/(num+1.);\r
@@ -1205,7 +1095,7 @@ void MGL_EXPORT mgl_pipe_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const cha
 void MGL_EXPORT mgl_pipe_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, double r0, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy());        // NOTE mglDataV here is useless\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        mgl_pipe_xy(gr,&x,&y,ax,ay,sch,r0,0);\r
@@ -1228,7 +1118,7 @@ void flowr(mglBase *gr, double u, double v, double w, const mglData &x, const mg
 {\r
        static long n=10*(ax.nx+ax.ny);\r
        long nn = ax.nx*ax.ny*ax.nz;\r
-       bool both = x.nx*x.ny*x.nz==nn && y.nx*y.ny*y.nz==nn && z.nx*z.ny*z.nz==nn;\r
+       bool nboth = x.nx*x.ny*x.nz!=nn || y.nx*y.ny*y.nz!=nn || z.nx*z.ny*z.nz!=nn;\r
        mglPoint *pp = new mglPoint[n], dp;\r
        mreal *cc = new mreal[n];\r
        mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
@@ -1243,13 +1133,12 @@ void flowr(mglBase *gr, double u, double v, double w, const mglData &x, const mg
        register long k=0,m;\r
        bool end = false;\r
        do{\r
-               if(gr->Stop)    {       delete []pp;    delete []cc;    return; }\r
-               pp[k].x = both ? x.Spline1(u,v,w):x.Spline1(u,0,0);\r
-               pp[k].y = both ? y.Spline1(u,v,w):y.Spline1(v,0,0);\r
-               pp[k].z = both ? z.Spline1(u,v,w):z.Spline1(w,0,0);\r
+               pp[k].x = nboth ? x.Spline1(u,0,0):x.Spline1(u,v,w);\r
+               pp[k].y = nboth ? y.Spline1(v,0,0):y.Spline1(u,v,w);\r
+               pp[k].z = nboth ? z.Spline1(w,0,0):z.Spline1(u,v,w);\r
                for(m=0;m<k-1;m++)      // determines encircle\r
                        if(mgl_norm((pp[k]-pp[m])/dx)<dt/10.)   {       end = true;     break;  }\r
-               e = ax.Linear1(u,v,w);  f = ay.Linear1(u,v,w);  g = az.Linear1(u,v,w);\r
+               e = ax.Spline1(u,v,w);  f = ay.Spline1(u,v,w);  g = az.Spline1(u,v,w);\r
                h = sqrt(e*e+f*f+g*g);  cc[k] = gr->GetC(sc,s*h);\r
                pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
                if(h<1e-5)      break;  // stationary point\r
@@ -1257,16 +1146,16 @@ void flowr(mglBase *gr, double u, double v, double w, const mglData &x, const mg
                // find next point by midpoint method\r
                h+=1;   ee[0]=e*dt/h;   ff[0]=f*dt/h;   gg[0]=g*dt/h;\r
                u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
-               e = ax.Linear1(u1,v1,w1);       f = ay.Linear1(u1,v1,w1);\r
-               g = az.Linear1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
+               e = ax.Spline1(u1,v1,w1);       f = ay.Spline1(u1,v1,w1);\r
+               g = az.Spline1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
                ee[1]=e*dt/h;   ff[1]=f*dt/h;   gg[1]=g*dt/h;\r
                u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2;\r
-               e = ax.Linear1(u1,v1,w1);       f = ay.Linear1(u1,v1,w1);\r
-               g = az.Linear1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
+               e = ax.Spline1(u1,v1,w1);       f = ay.Spline1(u1,v1,w1);\r
+               g = az.Spline1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
                ee[2]=e*dt/h;   ff[2]=f*dt/h;   gg[2]=g*dt/h;\r
                u1 = u+ee[2];   v1 = v+ff[2];   w1 = w+gg[2];\r
-               e = ax.Linear1(u1,v1,w1);       f = ay.Linear1(u1,v1,w1);\r
-               g = az.Linear1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
+               e = ax.Spline1(u1,v1,w1);       f = ay.Spline1(u1,v1,w1);\r
+               g = az.Spline1(u1,v1,w1);       h = 1+sqrt(e*e+f*f+g*g);\r
                ee[3]=e*dt/h;   ff[3]=f*dt/h;   gg[3]=g*dt/h;\r
                u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6;\r
                v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
@@ -1315,7 +1204,6 @@ void flowr(mglBase *gr, double u, double v, double w, const mglData &x, const mg
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_pipe_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double r0, const char *opt)\r
 {\r
-       mreal u,v,w;\r
        if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Vect"))    return;\r
 \r
        mreal r = gr->SaveState(opt);\r
@@ -1327,10 +1215,11 @@ void MGL_EXPORT mgl_pipe_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
        bool cnt=!mglchr(sch,'#');\r
 \r
        mglData xx(x), yy(y), zz(z), bx(ax), by(ay), bz(az);\r
-#pragma omp parallel for private(u,v,w) collapse(3)\r
+//#pragma omp parallel for collapse(3)\r
        for(long i=0;i<num;i++) for(long j=0;j<num;j++) for(int s=-1;s<=1;s+=2)\r
        {\r
-               if(gr->Stop)    continue;\r
+               mreal u,v,w;\r
+               if(gr->NeedStop())      {       i=j=num;        s=2;    continue;       }\r
                u = (i+1.)/(num+1.);    v = (j+1.)/(num+1.);    w = 0;\r
                flowr(gr, s*u, s*v, s*w, xx, yy, zz, bx, by, bz,r0,ss);\r
                u = (i+1.)/(num+1.);    v = (j+1.)/(num+1.);    w = 1;\r
@@ -1359,7 +1248,7 @@ void MGL_EXPORT mgl_pipe_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay,
 void MGL_EXPORT mgl_pipe_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double r0, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz());\r
+       mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz());        // NOTE mglDataV here is useless\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
index 2a8303132e269551e43fa4fa26b5b676d07c22c9..c4bf96eda78becd4f3e64be933853fed10f86083 100644 (file)
@@ -32,8 +32,8 @@ void MGL_EXPORT mgl_cloud_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const cha
 {\r
        if(!(gr->GetQuality()&3))       return; // do nothing in fast_draw\r
        long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
-       bool both = mgl_isboth(x,y,z,a);\r
-       if(mgl_check_dim3(gr,both,x,y,z,a,0,"Cloud"))   return;\r
+       bool nboth = mgl_isnboth(x,y,z,a);\r
+       if(mgl_check_dim3(gr,!nboth,x,y,z,a,0,"Cloud")) return;\r
 \r
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("Cloud",cgid++);\r
@@ -58,35 +58,36 @@ void MGL_EXPORT mgl_cloud_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const cha
        long *pos=new long[n*m*l];\r
        gr->Reserve(n*m*l);\r
        mglPoint q=mglPoint(NAN);\r
-#pragma omp parallel for collapse(3)\r
-       for(long k=0;k<l;k++)   for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
+       for(long k=0;k<l;k++)\r
        {\r
-               if(gr->Stop)    continue;\r
-               mglPoint p = both ? mglPoint(x->v(i*tx,j*ty,k*tz),y->v(i*tx,j*ty,k*tz),z->v(i*tx,j*ty,k*tz)) : mglPoint(x->v(i*tx),y->v(j*ty),z->v(k*tz));\r
-               mreal aa = gr->GetA(a->v(i*tx,j*ty,k*tz));\r
-               mreal bb = inv ? (1-aa)*(1-aa)*alpha : aa*aa*alpha;\r
-               pos[i+n*(j+m*k)] = gr->AddPnt(p,gr->GetC(ss,aa,false),q,bb);\r
+               if(gr->NeedStop())      break;\r
+               for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
+               {\r
+                       mglPoint p = nboth ? mglPoint(x->v(i*tx),y->v(j*ty),z->v(k*tz)) : mglPoint(x->v(i*tx,j*ty,k*tz),y->v(i*tx,j*ty,k*tz),z->v(i*tx,j*ty,k*tz));\r
+                       mreal aa = gr->GetA(a->v(i*tx,j*ty,k*tz));\r
+                       mreal bb = inv ? (1-aa)*(1-aa)*alpha : aa*aa*alpha;\r
+                       pos[i+n*(j+m*k)] = gr->AddPnt(p,gr->GetC(ss,aa,false),q,bb);\r
+               }\r
        }\r
-       if(dot)\r
-#pragma omp parallel for\r
-               for(long i=0;i<n*m*l;i++)       gr->mark_plot(pos[i],'.');\r
-       else\r
-#pragma omp parallel for collapse(3)\r
-               for(long k=0;k<l;k++)   for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
+       if(dot) for(long i=0;i<n*m*l;i++)       gr->mark_plot(pos[i],'.');\r
+       else    for(long k=0;k<l;k++)\r
+       {\r
+               if(gr->NeedStop())      break;\r
+               for(long j=0;j<m;j++)   for(long i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        register long i0 = i+n*(j+m*k);\r
                        if(i<n-1 && j<m-1)      gr->quad_plot(pos[i0],pos[i0+1],pos[i0+n],pos[i0+n+1]);\r
                        if(i<n-1 && k<l-1)      gr->quad_plot(pos[i0],pos[i0+1],pos[i0+n*m],pos[i0+n*m+1]);\r
                        if(k<l-1 && j<m-1)      gr->quad_plot(pos[i0],pos[i0+n],pos[i0+n*m],pos[i0+n+n*m]);\r
                }\r
+       }\r
        delete []pos;   gr->EndGroup();\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_cloud(HMGL gr, HCDT a, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -130,21 +131,21 @@ mreal MGL_NO_EXPORT mgl_normal_1d(HCDT a, mreal x, bool inv, long n)
        return inv ? nx : -nx;\r
 }\r
 //-----------------------------------------------------------------------------\r
-mglPoint MGL_NO_EXPORT mgl_find_norm(bool both, HCDT x, HCDT y, HCDT z, HCDT a, mglPoint u, bool inv, long n,long m,long l)\r
+mglPoint MGL_NO_EXPORT mgl_find_norm(bool nboth, HCDT x, HCDT y, HCDT z, HCDT a, mglPoint u, bool inv, long n,long m,long l)\r
 {\r
        mglPoint s = mgl_normal_3d(a,u,inv,n,m,l), t, q;\r
-       if(both)\r
-       {\r
-               t = mgl_normal_3d(x,u,true,n,m,l);      q.x = (s*t)/(t*t);\r
-               t = mgl_normal_3d(y,u,true,n,m,l);      q.y = (s*t)/(t*t);\r
-               t = mgl_normal_3d(z,u,true,n,m,l);      q.z = (s*t)/(t*t);\r
-       }\r
-       else\r
+       if(nboth)\r
        {\r
                q.x = s.x/mgl_normal_1d(x,u.x,true,n);\r
                q.y = s.y/mgl_normal_1d(y,u.y,true,m);\r
                q.z = s.z/mgl_normal_1d(z,u.z,true,l);\r
        }\r
+       else\r
+       {\r
+               t = mgl_normal_3d(x,u,true,n,m,l);      q.x = (s*t)/(t*t);\r
+               t = mgl_normal_3d(y,u,true,n,m,l);      q.y = (s*t)/(t*t);\r
+               t = mgl_normal_3d(z,u,true,n,m,l);      q.z = (s*t)/(t*t);\r
+       }\r
        return q;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -157,17 +158,15 @@ inline mreal MGL_NO_EXPORT mgl_cos_pp(const mglPoint *kk,long i0,long i1,long i2
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_surf3_plot(HMGL gr, long n,long m,long *kx1,long *kx2,long *ky1,long *ky2, long *kz, std::vector<mglPoint> kk, int wire)\r
 {\r
-       long id[12],us[12],pd[12],ni;\r
+       long id[12],us[12],pd[12];\r
        mglPoint pp[12];\r
-       mreal d,d0;\r
 \r
-#pragma omp parallel for private(id,us,pd,pp,ni,d,d0) collapse(2)\r
+#pragma omp parallel for private(id,us,pd,pp) collapse(2)\r
        for(long j=0;j<m-1;j++) for(long i=0;i<n-1;i++)\r
        {\r
-               if(gr->Stop)    continue;\r
                register long i0 = i+n*j,ii,jj,k;\r
                // find ID of points of Surf3 intersection with cell i0\r
-               memset(id,-1,12*sizeof(long));  ni = 0;\r
+               memset(id,-1,12*sizeof(long));  long ni = 0;\r
                if(kx1[i0]>=0)          id[ni++] = kx1[i0];\r
                if(ky1[i0]>=0)          id[ni++] = ky1[i0];\r
                if(kx1[i0+n]>=0)        id[ni++] = kx1[i0+n];\r
@@ -187,7 +186,7 @@ void MGL_EXPORT mgl_surf3_plot(HMGL gr, long n,long m,long *kx1,long *kx2,long *
                // remove points which is too close to first one\r
                for(jj=1;jj<ni;)\r
                {\r
-                       d = mgl_norm(pp[jj] - pp[0]);\r
+                       register mreal d = mgl_norm(pp[jj] - pp[0]);\r
                        if(d>1e-5)      jj++;\r
                        else\r
                        {       ni--;   for(ii=jj;ii<ni;ii++)   id[ii]=id[ii+1];        }\r
@@ -196,9 +195,10 @@ void MGL_EXPORT mgl_surf3_plot(HMGL gr, long n,long m,long *kx1,long *kx2,long *
                if(ni<3)        continue;\r
                memset(us,0,12*sizeof(long));\r
                // firstly let find most outstanding point\r
-               for(jj=1,ii=2,d0=2;ii<ni;ii++)\r
+               mreal d0=2;\r
+               for(jj=1,ii=2;ii<ni;ii++)\r
                {\r
-                       d = mgl_cos_pp(pp,0,ii,1);\r
+                       register mreal d = mgl_cos_pp(pp,0,ii,1);\r
                        if(d<d0)        {       d0=d;   jj=ii;  }\r
                }\r
                // copy first 2 points as base\r
@@ -212,7 +212,7 @@ void MGL_EXPORT mgl_surf3_plot(HMGL gr, long n,long m,long *kx1,long *kx2,long *
                        for(i0=-1,ii=1,d0=-2;ii<ni;ii++)\r
                        {\r
                                if(us[ii])      continue;\r
-                               d = mgl_cos_pp(pp,0,ii,jj);\r
+                               register mreal d = mgl_cos_pp(pp,0,ii,jj);\r
                                if(d>d0)        {       d0=d;   i0=ii;  }\r
                        }\r
                        if(i0<0)        break;  // no more triangles. NOTE: should be never here\r
@@ -239,11 +239,11 @@ void MGL_EXPORT mgl_surf3_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, H
 {\r
        long i,j,k,i1,n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
        long *kx1,*kx2,*ky1,*ky2,*kz;\r
-       bool both = mgl_isboth(x,y,z,a);\r
+       bool nboth = !mgl_isboth(x,y,z,a);\r
        int wire = mglchr(sch,'#')?1:0;\r
        if(mglchr(sch,'.'))     wire = 2;\r
        mreal d;\r
-       if(mgl_check_dim3(gr,both,x,y,z,a,0,"Surf3"))   return;\r
+       if(mgl_check_dim3(gr,!nboth,x,y,z,a,0,"Surf3")) return;\r
 \r
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("Surf3",cgid++);\r
@@ -262,27 +262,24 @@ void MGL_EXPORT mgl_surf3_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, H
        mreal a0;\r
        for(k=0;k<l;k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                memcpy(kx1,kx2,n*m*sizeof(long));       memset(kx2,-1,n*m*sizeof(long));\r
                memcpy(ky1,ky2,n*m*sizeof(long));       memset(ky2,-1,n*m*sizeof(long));\r
                memset(kz ,-1,n*m*sizeof(long));\r
                gr->Reserve(n*m);       gr->Reserve(n*m);\r
-//#pragma omp parallel for collapse(2) // NOTE: this part require a lot of memory for OpenMP. Omit it.\r
                for(j=0;j<m;j++)        for(i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    continue;\r
                        i1 = i+n*j;             a0 = a->v(i,j,k);\r
-                       p0 = both?mglPoint(x->v(i,j,k), y->v(i,j,k), z->v(i,j,k)) : mglPoint(x->v(i), y->v(j), z->v(k));\r
+                       p0 = nboth? mglPoint(x->v(i), y->v(j), z->v(k)) : mglPoint(x->v(i,j,k), y->v(i,j,k), z->v(i,j,k));\r
                        if(i<n-1)\r
                        {\r
                                d = mgl_d(val,a0,a->v(i+1,j,k));\r
                                if(d>=0 && d<1)\r
                                {\r
-                                       if(both)        p = mglPoint(p0.x*(1-d)+x->v(i+1,j,k)*d,\r
-                                                                       p0.y*(1-d)+y->v(i+1,j,k)*d,\r
-                                                                       p0.z*(1-d)+z->v(i+1,j,k)*d);\r
-                                       else    p = mglPoint(p0.x*(1-d)+x->v(i+1)*d, p0.y, p0.z);\r
+                                       if(nboth)       p = mglPoint(p0.x*(1-d)+x->v(i+1)*d, p0.y, p0.z);\r
+                                       else    p = mglPoint(p0.x*(1-d)+x->v(i+1,j,k)*d, p0.y*(1-d)+y->v(i+1,j,k)*d, p0.z*(1-d)+z->v(i+1,j,k)*d);\r
                                        u = mglPoint(i+d,j,k);\r
-                                       q = mgl_find_norm(both, x,y,z,a, u, inv,n,m,l);\r
+                                       q = mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l);\r
                                        pos = gr->AddPnt(p,c,q);        u.c=pos;\r
                                        if(pos<0)       continue;\r
                                        kx2[i1] = kk.size();    kk.push_back(u);\r
@@ -293,12 +290,10 @@ void MGL_EXPORT mgl_surf3_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, H
                                d = mgl_d(val,a0,a->v(i,j+1,k));\r
                                if(d>=0 && d<1)\r
                                {\r
-                                       if(both)        p = mglPoint(p0.x*(1-d)+x->v(i,j+1,k)*d,\r
-                                                                       p0.y*(1-d)+y->v(i,j+1,k)*d,\r
-                                                                       p0.z*(1-d)+z->v(i,j+1,k)*d);\r
-                                       else    p = mglPoint(p0.x, p0.y*(1-d)+y->v(j+1)*d, p0.z);\r
+                                       if(nboth)       p = mglPoint(p0.x, p0.y*(1-d)+y->v(j+1)*d, p0.z);\r
+                                       else    p = mglPoint(p0.x*(1-d)+x->v(i,j+1,k)*d, p0.y*(1-d)+y->v(i,j+1,k)*d, p0.z*(1-d)+z->v(i,j+1,k)*d);\r
                                        u = mglPoint(i,j+d,k);\r
-                                       q = mgl_find_norm(both, x,y,z,a, u, inv,n,m,l);\r
+                                       q = mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l);\r
                                        pos = gr->AddPnt(p,c,q);        u.c=pos;\r
                                        if(pos<0)       continue;\r
                                        ky2[i1] = kk.size();    kk.push_back(u);\r
@@ -309,12 +304,10 @@ void MGL_EXPORT mgl_surf3_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, H
                                d = mgl_d(val,a->v(i,j,k-1),a0);\r
                                if(d>=0 && d<1)\r
                                {\r
-                                       if(both)        p = mglPoint(x->v(i,j,k-1)*(1-d)+p0.x*d,\r
-                                                                       y->v(i,j,k-1)*(1-d)+p0.y*d,\r
-                                                                       z->v(i,j,k-1)*(1-d)+p0.z*d);\r
-                                       else    p = mglPoint(p0.x, p0.y, z->v(k-1)*(1-d)+p0.z*d);\r
+                                       if(nboth)       p = mglPoint(p0.x, p0.y, z->v(k-1)*(1-d)+p0.z*d);\r
+                                       else    p = mglPoint(x->v(i,j,k-1)*(1-d)+p0.x*d, y->v(i,j,k-1)*(1-d)+p0.y*d, z->v(i,j,k-1)*(1-d)+p0.z*d);\r
                                        u = mglPoint(i,j,k+d-1);\r
-                                       q = mgl_find_norm(both, x,y,z,a, u, inv,n,m,l);\r
+                                       q = mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l);\r
                                        pos = gr->AddPnt(p,c,q);        u.c=pos;\r
                                        if(pos<0)       continue;\r
                                        kz[i1] = kk.size();     kk.push_back(u);\r
@@ -331,7 +324,7 @@ void MGL_EXPORT mgl_surf3_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, H
 void MGL_EXPORT mgl_surf3_val(HMGL gr, double val, HCDT a, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()), z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()), z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -352,7 +345,7 @@ void MGL_EXPORT mgl_surf3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const cha
 void MGL_EXPORT mgl_surf3(HMGL gr, HCDT a, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()), z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()), z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -387,11 +380,11 @@ void MGL_EXPORT mgl_surf3a_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
 {\r
        long i,j,k,i1,n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
        long *kx1,*kx2,*ky1,*ky2,*kz;\r
-       bool both = mgl_isboth(x,y,z,a);\r
+       bool nboth = mgl_isnboth(x,y,z,a);\r
        int wire = mglchr(sch,'#')?1:0;\r
        if(mglchr(sch,'.'))     wire = 2;\r
        mreal d;\r
-       if(mgl_check_dim3(gr,both,x,y,z,a,b,"Surf3A"))  return;\r
+       if(mgl_check_dim3(gr,!nboth,x,y,z,a,b,"Surf3A"))        return;\r
 \r
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("Surf3A",cgid++);\r
@@ -410,30 +403,26 @@ void MGL_EXPORT mgl_surf3a_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
        mreal a0,b0;\r
        for(k=0;k<l;k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                memcpy(kx1,kx2,n*m*sizeof(long));       memset(kx2,-1,n*m*sizeof(long));\r
                memcpy(ky1,ky2,n*m*sizeof(long));       memset(ky2,-1,n*m*sizeof(long));\r
                memset(kz ,-1,n*m*sizeof(long));\r
                gr->Reserve(n*m);       gr->Reserve(n*m);\r
-//#pragma omp parallel for collapse(2) // NOTE: this part require a lot of memory for OpenMP. Omit it.\r
                for(j=0;j<m;j++)        for(i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    {       delete []kx1;   delete []kx2;   delete []ky1;\r
-                                                               delete []ky2;   delete []kz;    return; }\r
                        i1 = i+n*j;\r
                        a0 = a->v(i,j,k);       b0 = b->v(i,j,k);\r
-                       p0 = both?mglPoint(x->v(i,j,k), y->v(i,j,k), z->v(i,j,k)) : mglPoint(x->v(i), y->v(j), z->v(k));\r
+                       p0 = nboth? mglPoint(x->v(i), y->v(j), z->v(k)) : mglPoint(x->v(i,j,k), y->v(i,j,k), z->v(i,j,k));\r
                        if(i<n-1)\r
                        {\r
                                d = mgl_d(val,a0,a->v(i+1,j,k));\r
                                if(d>=0 && d<1)\r
                                {\r
-                                       if(both)        p = mglPoint(p0.x*(1-d)+x->v(i+1,j,k)*d,\r
-                                                                       p0.y*(1-d)+y->v(i+1,j,k)*d,\r
-                                                                       p0.z*(1-d)+z->v(i+1,j,k)*d);\r
-                                       else    p = mglPoint(p0.x*(1-d)+x->v(i+1)*d, p0.y, p0.z);\r
+                                       if(nboth)       p = mglPoint(p0.x*(1-d)+x->v(i+1)*d, p0.y, p0.z);\r
+                                       else    p = mglPoint(p0.x*(1-d)+x->v(i+1,j,k)*d, p0.y*(1-d)+y->v(i+1,j,k)*d, p0.z*(1-d)+z->v(i+1,j,k)*d);\r
                                        aa = gr->GetA(b0*(1-d)+b->v(i+1,j,k)*d);\r
                                        u = mglPoint(i+d,j,k);\r
-                                       q = mgl_find_norm(both, x,y,z,a, u, inv,n,m,l);\r
+                                       q = mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l);\r
                                        pos = gr->AddPnt(p,c,q,aa);     u.c=pos;\r
                                        if(pos<0)       continue;\r
                                        kx2[i1] = kk.size();    kk.push_back(u);\r
@@ -444,13 +433,11 @@ void MGL_EXPORT mgl_surf3a_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
                                d = mgl_d(val,a0,a->v(i,j+1,k));\r
                                if(d>=0 && d<1)\r
                                {\r
-                                       if(both)        p = mglPoint(p0.x*(1-d)+x->v(i,j+1,k)*d,\r
-                                                                       p0.y*(1-d)+y->v(i,j+1,k)*d,\r
-                                                                       p0.z*(1-d)+z->v(i,j+1,k)*d);\r
-                                       else    p = mglPoint(p0.x, p0.y*(1-d)+y->v(j+1)*d, p0.z);\r
+                                       if(nboth)       p = mglPoint(p0.x, p0.y*(1-d)+y->v(j+1)*d, p0.z);\r
+                                       else    p = mglPoint(p0.x*(1-d)+x->v(i,j+1,k)*d, p0.y*(1-d)+y->v(i,j+1,k)*d, p0.z*(1-d)+z->v(i,j+1,k)*d);\r
                                        aa = gr->GetA(b0*(1-d)+b->v(i,j+1,k)*d);\r
                                        u = mglPoint(i,j+d,k);\r
-                                       q = mgl_find_norm(both, x,y,z,a, u, inv,n,m,l);\r
+                                       q = mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l);\r
                                        pos = gr->AddPnt(p,c,q,aa);     u.c=pos;\r
                                        if(pos<0)       continue;\r
                                        ky2[i1] = kk.size();    kk.push_back(u);\r
@@ -461,13 +448,11 @@ void MGL_EXPORT mgl_surf3a_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
                                d = mgl_d(val,a->v(i,j,k-1),a0);\r
                                if(d>=0 && d<1)\r
                                {\r
-                                       if(both)        p = mglPoint(x->v(i,j,k-1)*(1-d)+p0.x*d,\r
-                                                                       y->v(i,j,k-1)*(1-d)+p0.y*d,\r
-                                                                       z->v(i,j,k-1)*(1-d)+p0.z*d);\r
-                                       else    p = mglPoint(p0.x, p0.y, z->v(k-1)*(1-d)+p0.z*d);\r
+                                       if(nboth)       p = mglPoint(p0.x, p0.y, z->v(k-1)*(1-d)+p0.z*d);\r
+                                       else    p = mglPoint(x->v(i,j,k-1)*(1-d)+p0.x*d, y->v(i,j,k-1)*(1-d)+p0.y*d, z->v(i,j,k-1)*(1-d)+p0.z*d);\r
                                        aa = gr->GetA(b->v(i,j,k-1)*(1-d)+b0*d);\r
                                        u = mglPoint(i,j,k+d-1);\r
-                                       q = mgl_find_norm(both, x,y,z,a, u, inv,n,m,l);\r
+                                       q = mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l);\r
                                        pos = gr->AddPnt(p,c,q,aa);     u.c=pos;\r
                                        if(pos<0)       continue;\r
                                        kz[i1] = kk.size();     kk.push_back(u);\r
@@ -484,7 +469,7 @@ void MGL_EXPORT mgl_surf3a_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
 void MGL_EXPORT mgl_surf3a_val(HMGL gr, double val, HCDT a, HCDT b, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -517,7 +502,7 @@ void MGL_EXPORT mgl_surf3a_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b,
 void MGL_EXPORT mgl_surf3a(HMGL gr, HCDT a, HCDT b, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -554,11 +539,11 @@ void MGL_EXPORT mgl_surf3c_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
 {\r
        long i,j,k,i1,n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
        long *kx1,*kx2,*ky1,*ky2,*kz;\r
-       bool both = mgl_isboth(x,y,z,a);\r
+       bool nboth = mgl_isnboth(x,y,z,a);\r
        int wire = mglchr(sch,'#')?1:0;\r
        if(mglchr(sch,'.'))     wire = 2;\r
        mreal d;\r
-       if(mgl_check_dim3(gr,both,x,y,z,a,b,"Surf3C"))  return;\r
+       if(mgl_check_dim3(gr,!nboth,x,y,z,a,b,"Surf3C"))        return;\r
 \r
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("Surf3C",cgid++);\r
@@ -577,30 +562,26 @@ void MGL_EXPORT mgl_surf3c_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
        mreal a0,b0;\r
        for(k=0;k<l;k++)\r
        {\r
+               if(gr->NeedStop())      break;\r
                memcpy(kx1,kx2,n*m*sizeof(long));       memset(kx2,-1,n*m*sizeof(long));\r
                memcpy(ky1,ky2,n*m*sizeof(long));       memset(ky2,-1,n*m*sizeof(long));\r
                memset(kz ,-1,n*m*sizeof(long));\r
                gr->Reserve(n*m);       gr->Reserve(n*m);\r
-//#pragma omp parallel for collapse(2) // NOTE: this part require a lot of memory for OpenMP. Omit it.\r
                for(j=0;j<m;j++)        for(i=0;i<n;i++)\r
                {\r
-                       if(gr->Stop)    {       delete []kx1;   delete []kx2;   delete []ky1;\r
-                                                               delete []ky2;   delete []kz;    return; }\r
                        i1 = i+n*j;\r
                        a0 = a->v(i,j,k);       b0 = b->v(i,j,k);\r
-                       p0 = both?mglPoint(x->v(i,j,k), y->v(i,j,k), z->v(i,j,k)) : mglPoint(x->v(i), y->v(j), z->v(k));\r
+                       p0 = nboth? mglPoint(x->v(i), y->v(j), z->v(k)) : mglPoint(x->v(i,j,k), y->v(i,j,k), z->v(i,j,k));\r
                        if(i<n-1)\r
                        {\r
                                d = mgl_d(val,a0,a->v(i+1,j,k));\r
                                if(d>=0 && d<1)\r
                                {\r
-                                       if(both)        p = mglPoint(p0.x*(1-d)+x->v(i+1,j,k)*d,\r
-                                                                       p0.y*(1-d)+y->v(i+1,j,k)*d,\r
-                                                                       p0.z*(1-d)+z->v(i+1,j,k)*d);\r
-                                       else    p = mglPoint(p0.x*(1-d)+x->v(i+1)*d, p0.y, p0.z);\r
+                                       if(nboth)       p = mglPoint(p0.x*(1-d)+x->v(i+1)*d, p0.y, p0.z);\r
+                                       else    p = mglPoint(p0.x*(1-d)+x->v(i+1,j,k)*d, p0.y*(1-d)+y->v(i+1,j,k)*d, p0.z*(1-d)+z->v(i+1,j,k)*d);\r
                                        c = gr->GetC(ss,b0*(1-d)+b->v(i+1,j,k)*d);\r
                                        u = mglPoint(i+d,j,k);\r
-                                       q = mgl_find_norm(both, x,y,z,a, u, inv,n,m,l);\r
+                                       q = mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l);\r
                                        pos = gr->AddPnt(p,c,q);        u.c=pos;\r
                                        if(pos<0)       continue;\r
                                        kx2[i1] = kk.size();    kk.push_back(u);\r
@@ -611,13 +592,11 @@ void MGL_EXPORT mgl_surf3c_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
                                d = mgl_d(val,a0,a->v(i,j+1,k));\r
                                if(d>=0 && d<1)\r
                                {\r
-                                       if(both)        p = mglPoint(p0.x*(1-d)+x->v(i,j+1,k)*d,\r
-                                                                       p0.y*(1-d)+y->v(i,j+1,k)*d,\r
-                                                                       p0.z*(1-d)+z->v(i,j+1,k)*d);\r
-                                       else    p = mglPoint(p0.x, p0.y*(1-d)+y->v(j+1)*d, p0.z);\r
+                                       if(nboth)       p = mglPoint(p0.x, p0.y*(1-d)+y->v(j+1)*d, p0.z);\r
+                                       else    p = mglPoint(p0.x*(1-d)+x->v(i,j+1,k)*d, p0.y*(1-d)+y->v(i,j+1,k)*d, p0.z*(1-d)+z->v(i,j+1,k)*d);\r
                                        c = gr->GetC(ss,b0*(1-d)+b->v(i,j+1,k)*d);\r
                                        u = mglPoint(i,j+d,k);\r
-                                       q = mgl_find_norm(both, x,y,z,a, u, inv,n,m,l);\r
+                                       q = mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l);\r
                                        pos = gr->AddPnt(p,c,q);        u.c=pos;\r
                                        if(pos<0)       continue;\r
                                        ky2[i1] = kk.size();    kk.push_back(u);\r
@@ -628,13 +607,11 @@ void MGL_EXPORT mgl_surf3c_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
                                d = mgl_d(val,a->v(i,j,k-1),a0);\r
                                if(d>=0 && d<1)\r
                                {\r
-                                       if(both)        p = mglPoint(x->v(i,j,k-1)*(1-d)+p0.x*d,\r
-                                                                       y->v(i,j,k-1)*(1-d)+p0.y*d,\r
-                                                                       z->v(i,j,k-1)*(1-d)+p0.z*d);\r
-                                       else    p = mglPoint(p0.x, p0.y, z->v(k-1)*(1-d)+p0.z*d);\r
+                                       if(nboth)       p = mglPoint(p0.x, p0.y, z->v(k-1)*(1-d)+p0.z*d);\r
+                                       else    p = mglPoint(x->v(i,j,k-1)*(1-d)+p0.x*d, y->v(i,j,k-1)*(1-d)+p0.y*d, z->v(i,j,k-1)*(1-d)+p0.z*d);\r
                                        c = gr->GetC(ss,b->v(i,j,k-1)*(1-d)+b0*d);\r
                                        u = mglPoint(i,j,k+d-1);\r
-                                       q = mgl_find_norm(both, x,y,z,a, u, inv,n,m,l);\r
+                                       q = mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l);\r
                                        pos = gr->AddPnt(p,c,q);        u.c=pos;\r
                                        if(pos<0)       continue;\r
                                        kz[i1] = kk.size();     kk.push_back(u);\r
@@ -651,7 +628,7 @@ void MGL_EXPORT mgl_surf3c_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z,
 void MGL_EXPORT mgl_surf3c_val(HMGL gr, double val, HCDT a, HCDT b, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -673,7 +650,7 @@ void MGL_EXPORT mgl_surf3c_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b,
 void MGL_EXPORT mgl_surf3c(HMGL gr, HCDT a, HCDT b, const char *sch, const char *opt)\r
 {\r
        gr->SaveState(opt);\r
-       mglData x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
+       mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
        x.Fill(gr->Min.x,gr->Max.x);\r
        y.Fill(gr->Min.y,gr->Max.y);\r
        z.Fill(gr->Min.z,gr->Max.z);\r
@@ -709,68 +686,8 @@ void MGL_EXPORT mgl_surf3c_(uintptr_t *gr, uintptr_t *a, uintptr_t *b, const cha
 // flag & 0x1  --      accompanied coordinates\r
 // flag & 0x2  --      project to r*z\r
 // flag & 0x4  --      normalize field\r
-void MGL_NO_EXPORT mgl_beam_md(HMGL gr, double val, const mglData *tr, const mglData *g1, const mglData *g2, const mglData *a, double r, const char *stl, int flag)\r
-{\r
-       long n = a->nz,m=a->nx,l=a->ny;\r
-       if(n<2 || m<2 || l<2)   {       gr->SetWarn(mglWarnLow,"Beam"); return; }\r
-       if(a->Minimal()<0)              {       gr->SetWarn(mglWarnNeg,"Beam"); return; }\r
-       if(tr->nx<3 || tr->ny<n || g1->nx<3 || g1->ny<n || g2->nx<3 || g2->ny<n)\r
-       {       gr->SetWarn(mglWarnDim,"Beam"); return; }\r
-       mglData x(a),y(a),z(a),b(a);\r
-       mreal asum=1, asum0=0, amax, aa;\r
-       r = fabs(r);\r
-       if(flag & 4)\r
-#pragma omp parallel for reduction(+:asum0)\r
-               for(long j=0;j<m*l;j++) asum0 += a->a[j]*a->a[j];\r
-       if(asum0==0)    {       gr->SetWarn(mglWarnZero,"Beam");        return; }\r
-       for(long i=0;i<n;i++)\r
-       {\r
-               asum=amax=0;\r
-               if(flag & 4)\r
-               {\r
-                       for(long j=0;j<m*l;j++)\r
-                       {\r
-                               aa = a->a[j+m*l*i];\r
-                               asum += aa*aa;\r
-                               amax = amax>aa ? amax : aa;\r
-                       }\r
-                       if(amax==0)     {       asum=0; amax=1; }\r
-#pragma omp parallel for\r
-                       for(long j=0;j<m*l;j++) b.a[j+m*l*i] = b.a[j+m*l*i]*sqrt(asum/asum0)/amax;\r
-               }\r
-#pragma omp parallel for collapse(2)\r
-               for(long k=0;k<l;k++)   for(long j=0;j<m;j++)\r
-               {\r
-                       if(gr->Stop)    continue;\r
-                       register long i0 = j+m*(k+l*i);\r
-                       if(flag & 1)\r
-                       {\r
-                               x.a[i0] = 2*j/(m-1.)-1;\r
-                               y.a[i0] = 2*k/(l-1.)-1;\r
-                               z.a[i0] = gr->Max.z*i/(n-1.);\r
-                       }\r
-                       else\r
-                       {\r
-                               x.a[i0] = tr->a[3*i] + g1->a[3*i]*(2*j/(m-1.)-1)*r + g2->a[3*i]*(2*k/(l-1.)-1)*r;\r
-                               y.a[i0] = tr->a[3*i+1] + g1->a[3*i+1]*(2*j/(m-1.)-1)*r + g2->a[3*i+1]*(2*k/(l-1.)-1)*r;\r
-                               z.a[i0] = tr->a[3*i+2] + g1->a[3*i+2]*(2*j/(m-1.)-1)*r + g2->a[3*i+2]*(2*k/(l-1.)-1)*r;\r
-                       }\r
-                       if(flag & 2)    x.a[i0] = hypot(x.a[i0],y.a[i0]);\r
-               }\r
-       }\r
-       mgl_surf3_xyz_val(gr,val,&x,&y,&z,&b,stl,0);\r
-}\r
-//-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_beam_val(HMGL gr, double val, HCDT tr, HCDT g1, HCDT g2, HCDT a, double r, const char *stl, int flag)\r
 {\r
-\r
-       const mglData *dtr=dynamic_cast<const mglData *>(tr);\r
-       const mglData *dg2=dynamic_cast<const mglData *>(g1);\r
-       const mglData *dg1=dynamic_cast<const mglData *>(g2);\r
-       const mglData *da=dynamic_cast<const mglData *>(a);\r
-       if(dtr&&dg1&&dg2&&da)\r
-       {       mgl_beam_md(gr,val,dtr,dg1,dg2,da,r,stl,flag);  return; }\r
-\r
        long n = a->GetNz(),m=a->GetNx(),l=a->GetNy();\r
        if(n<2 || m<2 || l<2)   {       gr->SetWarn(mglWarnLow,"Beam"); return; }\r
        if(a->Minimal()<0)              {       gr->SetWarn(mglWarnNeg,"Beam"); return; }\r
@@ -778,42 +695,45 @@ void MGL_EXPORT mgl_beam_val(HMGL gr, double val, HCDT tr, HCDT g1, HCDT g2, HCD
        {       gr->SetWarn(mglWarnDim,"Beam"); return; }\r
        mglData x(a),y(a),z(a),b(a);\r
        register long i,j,k,i0;\r
-       mreal asum=1, asum0=1, amax, aa;\r
-       r = fabs(r);\r
+       mreal asum0=1;  r = fabs(r);\r
        if(flag & 4)    for(j=0;j<m*l;j++)      asum0 += a->vthr(j)*a->vthr(j);\r
        if(asum0==0)    {       gr->SetWarn(mglWarnZero,"Beam");        return; }\r
        for(i=0;i<n;i++)\r
        {\r
-               asum=amax=0;\r
+               if(gr->NeedStop())      break;\r
                if(flag & 4)\r
                {\r
+                       mreal asum=0, amax=0;\r
                        for(j=0;j<m*l;j++)\r
                        {\r
-                               aa = a->vthr(j+m*l*i);\r
-                               asum += aa*aa;\r
-                               amax = amax>aa ? amax : aa;\r
+                               register mreal aa = a->vthr(j+m*l*i);\r
+                               asum += aa*aa;  amax = amax>aa ? amax : aa;\r
                        }\r
-                       if(amax==0)     {       asum=0; amax=1; }\r
-                       for(j=0;j<m*l;j++)      b.a[j+m*l*i] = b.a[j+m*l*i]*sqrt(asum/asum0)/amax;\r
+                       amax = amax?sqrt(asum/asum0)/amax:0;\r
+#pragma omp parallel for\r
+                       for(j=0;j<m*l;j++)      b.a[j+m*l*i] = b.a[j+m*l*i]*amax;\r
                }\r
-               for(j=0;j<m;j++)        for(k=0;k<l;k++)\r
-               {\r
-                       if(gr->Stop)    return;\r
-                       i0 = j+m*(k+l*i);\r
-                       if(flag & 1)\r
+               if(flag & 1)\r
+#pragma omp parallel for collapse(2)\r
+                       for(j=0;j<m;j++)        for(k=0;k<l;k++)\r
                        {\r
+                               i0 = j+m*(k+l*i);\r
                                x.a[i0] = 2*j/(m-1.)-1;\r
                                y.a[i0] = 2*k/(l-1.)-1;\r
                                z.a[i0] = gr->Max.z*i/(n-1.);\r
                        }\r
-                       else\r
+               else\r
+#pragma omp parallel for collapse(2)\r
+                       for(j=0;j<m;j++)        for(k=0;k<l;k++)\r
                        {\r
+                               i0 = j+m*(k+l*i);\r
                                x.a[i0] = tr->v(0,i) + g1->v(0,i)*(2*j/(m-1.)-1)*r + g2->v(0,i)*(2*k/(l-1.)-1)*r;\r
                                y.a[i0] = tr->v(1,i) + g1->v(1,i)*(2*j/(m-1.)-1)*r + g2->v(1,i)*(2*k/(l-1.)-1)*r;\r
                                z.a[i0] = tr->v(2,i) + g1->v(2,i)*(2*j/(m-1.)-1)*r + g2->v(2,i)*(2*k/(l-1.)-1)*r;\r
                        }\r
-                       if(flag & 2)    x.a[i0] = hypot(x.a[i0],y.a[i0]);\r
-               }\r
+               if(flag & 2)\r
+#pragma omp parallel for collapse(2)\r
+                       for(j=0;j<m;j++)        for(k=0;k<l;k++)        x.a[i0] = hypot(x.a[i0],y.a[i0]);\r
        }\r
        mgl_surf3_xyz_val(gr,val,&x,&y,&z,&b,stl,0);\r
 }\r
index 5ad274038c6ea873cdcd030720dfecb627327663..9f5512c6b1b9eede36fc611aaf1b333189304fa0 100644 (file)
@@ -41,10 +41,10 @@ void mglCanvasWnd::ResetFrames()
        mglCanvas::ResetFrames();\r
 }\r
 //-----------------------------------------------------------------------------\r
-void mglCanvasWnd::SetSize(int w,int h)\r
+void mglCanvasWnd::SetSize(int w,int h,bool)\r
 {\r
        if(DrawFunc)    ResetFrames();\r
-       mglCanvas::SetSize(w,h);\r
+       mglCanvas::SetSize(w,h,false);\r
 //     if(Wnd) Wnd->size(w,h);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -85,7 +85,7 @@ void mglCanvasWnd::SetDrawFunc(int (*draw)(mglBase *gr, void *p), void *par, voi
 {\r
        ResetFrames();\r
        if(get(MGL_CLF_ON_UPD)) DefaultPlotParam();\r
-       setlocale(LC_NUMERIC, "C");\r
+       const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
        // use frames for quickly redrawing while adding/changing primitives\r
        if(mgl_is_frames(this)) NewFrame();\r
 \r
@@ -96,7 +96,7 @@ void mglCanvasWnd::SetDrawFunc(int (*draw)(mglBase *gr, void *p), void *par, voi
 \r
        if(mgl_is_frames(this)) EndFrame();\r
        if(n>=0)        SetCurFig(0);\r
-       setlocale(LC_NUMERIC, "");\r
+       setlocale(LC_NUMERIC, loc.c_str());\r
 }\r
 //-----------------------------------------------------------------------------\r
 const unsigned char *mglCanvasWnd::GetBits()\r
@@ -114,7 +114,7 @@ void mglCanvasWnd::ReLoad()
                LoadFunc(FuncPar);\r
                // update number of slides\r
                ResetFrames();\r
-               setlocale(LC_NUMERIC, "C");\r
+               const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
                // use frames for quickly redrawing while adding/changing primitives\r
                if(mgl_is_frames(this)) NewFrame();\r
                \r
@@ -122,7 +122,7 @@ void mglCanvasWnd::ReLoad()
                if(n<NumFig && n>=0)    NumFig = n;\r
                \r
                if(mgl_is_frames(this)) EndFrame();\r
-               setlocale(LC_NUMERIC, "");\r
+               setlocale(LC_NUMERIC, loc.c_str());\r
                Update();\r
        }\r
 }\r
@@ -213,11 +213,11 @@ void MGL_EXPORT mgl_reload_class(void *p) // so stupid way to save mglDraw class
 void MGL_EXPORT mgl_click_class(void *p)       // so stupid way to save mglDraw class inheritance :(\r
 {      mglWindow *w = (mglWindow *)p;  if(w && w->dr)  w->dr->Click(); }*/\r
 int MGL_EXPORT mgl_draw_class(HMGL gr, void *p)\r
-{      mglGraph g(gr); mglDraw *dr = (mglDraw *)p;     return dr->Draw(&g);    }\r
+{      mglGraph g(gr); mglDraw *dr = (mglDraw *)p;     return dr?dr->Draw(&g):0;       }\r
 void MGL_EXPORT mgl_reload_class(void *p)\r
-{      mglDraw *dr = (mglDraw *)p;     dr->Reload();   }\r
+{      mglDraw *dr = (mglDraw *)p;     if(dr)  dr->Reload();   }\r
 void MGL_EXPORT mgl_click_class(void *p)\r
-{      mglDraw *dr = (mglDraw *)p;     dr->Click();            }\r
+{      mglDraw *dr = (mglDraw *)p;     if(dr)  dr->Click();            }\r
 //-----------------------------------------------------------------------------\r
 typedef int (*draw_func)(mglGraph *gr);\r
 int MGL_EXPORT mgl_draw_graph(HMGL gr, void *p)\r
@@ -227,21 +227,18 @@ int MGL_EXPORT mgl_draw_graph(HMGL gr, void *p)
        return func ? func(&g) : 0;\r
 }\r
 //-----------------------------------------------------------------------------\r
+#if MGL_HAVE_PTHREAD\r
 MGL_NO_EXPORT void *mgl_draw_calc(void *p)\r
 {\r
-#if MGL_HAVE_PTHREAD\r
-       ((mglDraw *)p)->Calc();\r
-#endif\r
-       return 0;\r
+       ((mglDraw *)p)->Calc(); return 0;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_draw_thr(void *p)\r
 {\r
-#if MGL_HAVE_PTHREAD\r
        mglDraw *d = (mglDraw *)p;\r
        if(!d || d->running)    return;\r
        pthread_create(&(d->thr),0,mgl_draw_calc,d);\r
        pthread_detach(d->thr);\r
-#endif\r
 }\r
+#endif\r
 //-----------------------------------------------------------------------------\r
index 20ad882b49b16af4671ce5cbb222e60584ec052d..a57e11260ba54b7f571cd843731b8893b0aacee3 100644 (file)
@@ -8,7 +8,7 @@
                several_light solve stem step stereo stfa style surf3a surf3c surf3
                surfa surfc surf table tape tens ternary textmark text ticks tile tiles
                torus traj triangulation triplot tube type0 type1 type2 vect vecta venn
-               projection5 mask correl refill ohlc )
+               projection5 mask correl refill ohlc ode indirect)
        set(MGL_PNG_N )
        set(MGL_PNG_S )
        set(MGL_PNG_J )
@@ -24,8 +24,8 @@
        file(COPY ${MGL_TEX}/qt.png ${MGL_TEX}/fltk.png ${MGL_TEX}/classes.png ${MGL_TEX}/emblem_sm.png ${MGL_TEX}/datadvance.png DESTINATION ${MGL_OUT})
        file(COPY ${MGL_TEX}/index.html ${MGL_TEX}/json.html ${MGL_TEX}/mathgl.js DESTINATION ${MGL_OUT})
 
-       set(UDAV_IMG udav_arg.png udav_calc.png udav_cmd.png udav_data.png
-               udav_gen_set.png udav_help.png udav_light.png udav_main.png udav_opt.png
+       set(UDAV_IMG udav_arg.png udav_calc.png udav_cmd.png udav_data.png udav_mask.png
+               udav_gen_set.png udav_help.png udav_light.png udav_main.png udav_opt.png udav_inplot.png
                udav_pen.png udav_prop.png udav_sch.png udav_txt.png udav_var.png)
        foreach(SAMPLE ${UDAV_IMG})
                file(COPY ${MGL_TEX}/udav/${SAMPLE} DESTINATION ${MGL_OUT}/udav/)
@@ -34,7 +34,7 @@
        foreach(SAMPLE ${MGL_PNG})
                set(MGL_PNG_N ${MGL_PNG_N} ${MGL_OUT}/png/${SAMPLE}.png)
                add_custom_command(OUTPUT ${MGL_OUT}/png/${SAMPLE}.png
-                       COMMAND mgl_example -kind=${SAMPLE} -web
+                       COMMAND mgl_example -kind=${SAMPLE}
                        DEPENDS mgl_example
                        WORKING_DIRECTORY ${MGL_OUT}/png )
                set(MGL_PNG_S ${MGL_PNG_S} ${MGL_OUT}/small/${SAMPLE}-sm.png)
@@ -46,7 +46,6 @@ if(MGL_HAVE_DOC_JSON)
                set(MGL_PNG_J ${MGL_PNG_J} ${MGL_OUT}/json/${SAMPLE}.json)
                add_custom_command(OUTPUT ${MGL_OUT}/json/${SAMPLE}.json
                        COMMAND mgl_example -json -kind=${SAMPLE}
-#                      COMMAND ${CMAKE_BINARY_DIR}/examples/mgl_example -json -kind=${SAMPLE}
                        DEPENDS mgl_example
                        WORKING_DIRECTORY ${MGL_OUT}/json )
 endif(MGL_HAVE_DOC_JSON)
@@ -62,7 +61,7 @@ endif(MGL_HAVE_DOC_PRC)
        foreach(SAMPLE ${MGL_EXTRA})
                set(MGL_PNG_N ${MGL_PNG_N} ${MGL_OUT}/png/${SAMPLE}.png)
                add_custom_command(OUTPUT ${MGL_OUT}/png/${SAMPLE}.png
-                       COMMAND mgl_example -kind=${SAMPLE} -web
+                       COMMAND mgl_example -kind=${SAMPLE}
                        DEPENDS mgl_example
                        WORKING_DIRECTORY ${MGL_OUT}/png )
                set(MGL_PNG_S ${MGL_PNG_S} ${MGL_OUT}/small/${SAMPLE}-sm.png)
@@ -156,7 +155,7 @@ endif(MGL_HAVE_DOC_PRC)
 # TODO: try to install all mathgl*.info* in future!!!
                install(FILES ${MGL_OUT}/mathgl_en.info ${MGL_OUT}/mathgl_en.info-1 ${MGL_OUT}/mathgl_en.info-2 ${MGL_OUT}/mathgl_en.info-3 DESTINATION ${MGL_INFO_PATH})
        endif(MGL_HAVE_DOC_INFO)
-       
+
        if(MGL_HAVE_DOC_HTML)
                add_custom_target(doc_html ALL
                DEPENDS ${MGL_OUT}/mgl_en.html
@@ -182,9 +181,9 @@ endif(MGL_HAVE_DOC_PRC)
                        DEPENDS ${MGL_OUT}/mgl_en.pdf
                        DEPENDS ${MGL_OUT}/mathgl_en.pdf
                )
-               install(FILES ${MGL_OUT}/mathgl_en.pdf DESTINATION ${MGL_DOC_PATH})
+               install(FILES ${MGL_OUT}/mathgl_en.pdf ${MGL_OUT}/mgl_en.pdf DESTINATION ${MGL_DOC_PATH})
        endif(MGL_HAVE_DOC_PDF_EN)
-       
+
        if(MGL_HAVE_DOC_PDF_RU)
                add_custom_target(doc_ru ALL
 #                      DEPENDS ${MGL_OUT}/mgl_ru.pdf
index 455d49b638f4104be4cea766b467c292f7fb8f3a..202b454ef23e394826a41a091b7526b6ec14ef47 100644 (file)
@@ -40,11 +40,11 @@ In addition to the general concepts I want to comment on some non-trivial or les
 @section Coordinate axes
 @nav{}
 
-Two axis representations are used in MathGL. The first one consists of normalizing coordinates of data points in a box @var{Min}x@var{Max} (see @ref{Axis settings}). If @code{SetCut()} is @code{true} then the outlier points are omitted, otherwise they are projected to the bounding box (see @ref{Cutting}). Also, the point will be omitted if it lies inside the box defined by @code{SetCutBox()} or if the value of formula @code{CutOff()} is nonzero for its coordinates. After that, transformation formulas defined by @code{SetFunc()} or @code{SetCoor()} are applied to the data point (see @ref{Curved coordinates}). Finally, the data point is plotted by one of the functions.
+Two axis representations are used in MathGL. The first one consists of normalizing coordinates of data points in axis range (see @ref{Axis settings}). If @code{SetCut()} is @code{true} then the outlier points are omitted, otherwise they are projected to the bounding box (see @ref{Cutting}). Also, the point will be omitted if it lies inside the box defined by @code{SetCutBox()} or if the value of formula @code{CutOff()} is nonzero for its coordinates. After that, transformation formulas defined by @code{SetFunc()} or @code{SetCoor()} are applied to the data point (see @ref{Curved coordinates}). Finally, the data point is plotted by one of the functions.
 
 The range of @emph{x, y, z}-axis can be specified by @code{SetRange()} or @code{SetRanges()} functions. Its origin is specified by @code{SetOrigin()} function. At this you can you can use @code{NAN} values for selecting axis origin automatically.
 
-There is 4-th axis @emph{c} (color axis or colorbar) in addition to the usual axes @emph{x, y, z}. It sets the range of values for the surface coloring. Its borders are automatically set to values of Min.z, Max.z during the call of @code{SetRanges()} function. Also, one can directly set it by call @code{SetRange('c', ...)}. Use @code{Colorbar()} function for drawing the colorbar.
+There is 4-th axis @emph{c} (color axis or colorbar) in addition to the usual axes @emph{x, y, z}. It sets the range of values for the surface coloring. Its borders are automatically set to values of z-range during the call of @code{SetRanges()} function. Also, one can directly set it by call @code{SetRange('c', ...)}. Use @code{Colorbar()} function for drawing the colorbar.
 
 The form (appearence) of tick labels is controlled by @code{SetTicks()} function (@pxref{Ticks}). Function @var{SetTuneTicks} switches on/off tick enhancing by factoring out acommon multiplier (for small coordinate values, like 0.001 to 0.002, or large, like from 1000 to 2000) or common component (for narrow range, like from 0.999 to 1.000). Finally, you may use functions @code{SetTickTempl()} for setting templates for tick labels (it supports TeX symbols). Also, there is a possibility to print arbitrary text as tick labels the by help of @code{SetTicksVal()} function.
 
@@ -91,18 +91,18 @@ The line style is defined by the string which may contain specifications for col
 @html
 By default palette contain following colors: <span style="color: rgb(76, 76, 76);">dark gray</span> &lsquo;<samp>H</samp>&rsquo;, <span style="color: rgb(0, 0, 255);">blue</span> &lsquo;<samp>b</samp>&rsquo;, <span style="color: rgb(0, 255, 0);">green</span> &lsquo;<samp>g</samp>&rsquo;, <span style="color: rgb(255, 0, 0);">red</span> &lsquo;<samp>r</samp>&rsquo;, <span style="color: rgb(0, 255, 255);">cyan</span> &lsquo;<samp>c</samp>&rsquo;, <span style="color: rgb(255, 0, 255);">magenta</span> &lsquo;<samp>m</samp>&rsquo;, <span style="color: rgb(255, 255, 0);">yellow</span> &lsquo;<samp>y</samp>&rsquo;, <span style="color: rgb(127, 127, 127);">gray</span> &lsquo;<samp>h</samp>&rsquo;, <span style="color: rgb(0, 255, 127);">green-blue</span> &lsquo;<samp>l</samp>&rsquo;, <span style="color: rgb(0, 127, 255);">sky-blue</span> &lsquo;<samp>n</samp>&rsquo;, <span style="color: rgb(255, 127, 0);">orange</span> &lsquo;<samp>q</samp>&rsquo;, <span style="color: rgb(127, 255, 0);">green-yellow</span> &lsquo;<samp>e</samp>&rsquo;, <span style="color: rgb(127, 0, 255);">blue-violet</span> &lsquo;<samp>u</samp>&rsquo;, <span style="color: rgb(255, 0, 127);">purple</span> &lsquo;<samp>p</samp>&rsquo;.
 
-<p>Dashing style has the following meaning: space &ndash; no line (usable for plotting only marks), &lsquo;<samp>-</samp>&rsquo; &ndash; solid line (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;), &lsquo;<samp>|</samp>&rsquo; &ndash; long dashed line (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>;</samp>&rsquo; &ndash; dashed line (&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>=</samp>&rsquo; &ndash; small dashed line (&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;), &lsquo;<samp>:</samp>&rsquo; &ndash; dotted line (&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;), &lsquo;<samp>j</samp>&rsquo; &ndash; dash-dotted line (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>i</samp>&rsquo; &ndash; small dash-dotted line (&#9632;&#9632;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;&#9632;&#9632;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;).</p>
+<p>Dashing style has the following meaning: space &ndash; no line (usable for plotting only marks), &lsquo;<samp>-</samp>&rsquo; &ndash; solid line (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;), &lsquo;<samp>|</samp>&rsquo; &ndash; long dashed line (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>;</samp>&rsquo; &ndash; dashed line (&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>=</samp>&rsquo; &ndash; small dashed line (&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;), &lsquo;<samp>:</samp>&rsquo; &ndash; dotted line (&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;), &lsquo;<samp>j</samp>&rsquo; &ndash; dash-dotted line (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>i</samp>&rsquo; &ndash; small dash-dotted line (&#9632;&#9632;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;&#9632;&#9632;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;), &lsquo;<samp>{dNNNN}</samp>&rsquo; &ndash; manual mask style (for v.2.3 and later, like &lsquo;<samp>{df090}</samp>&rsquo; for (&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9633;)).</p>
 @end html
 @end ifhtml
 @ifnothtml
 By default palette contain following colors: dark gray @samp{H}, blue @samp{b}, green @samp{g}, red @samp{r}, cyan @samp{c}, magenta @samp{m}, yellow @samp{y}, gray @samp{h}, blue-green @samp{l}, sky-blue @samp{n}, orange @samp{q}, yellow-green @samp{e}, blue-violet @samp{u}, purple @samp{p}.
 
-Dashing style has the following meaning: space -- no line (usable for plotting only marks), @samp{-} -- solid line (################), @samp{|} -- long dashed line (########________), @samp{;} -- dashed line (####____####____), @samp{=} -- small dashed line (##__##__##__##__), @samp{:} -- dotted line (#___#___#___#___), @samp{j} -- dash-dotted line (#######____#____), @samp{i} -- small dash-dotted line (###__#__###__#__).
+Dashing style has the following meaning: space -- no line (usable for plotting only marks), @samp{-} -- solid line (################), @samp{|} -- long dashed line (########________), @samp{;} -- dashed line (####____####____), @samp{=} -- small dashed line (##__##__##__##__), @samp{:} -- dotted line (#___#___#___#___), @samp{j} -- dash-dotted line (#######____#____), @samp{i} -- small dash-dotted line (###__#__###__#__), @samp{@{dNNNN@}} -- manual mask style (for v.2.3 and later, like @samp{@{df090@}} for (####____#__#____)).
 @end ifnothtml
 
 Marker types are: @samp{o} -- circle, @samp{+} -- cross, @samp{x} -- skew cross, @samp{s} - square, @samp{d} - rhomb (or diamond), @samp{.} -- dot (point), @samp{^} -- triangle up, @samp{v} -- triangle down, @samp{<} -- triangle left, @samp{>} -- triangle right, @samp{#*} -- Y sign, @samp{#+} -- squared cross, @samp{#x} -- squared skew cross, @samp{#.} -- circled dot. If string contain symbol @samp{#} then the solid versions of markers are used.
 
-One may specify to draw a special symbol (an arrow) at the beginning and at the end of line. This is done if the specification string contains one of the following symbols: @samp{A} -- outer arrow, @samp{V} -- inner arrow, @samp{I} -- transverse hatches, @samp{K} -- arrow with hatches, @samp{T} -- triangle, @samp{S} -- square, @samp{D} -- rhombus, @samp{O} -- circle, @samp{_} -- nothing (the default). The following rule applies: the first symbol specifies the arrow at the end of line, the second specifies the arrow at the beginning of the line. For example, @samp{r-A} defines a red solid line with usual arrow at the end, @samp{b|AI} defines a blue dash line with an arrow at the end and with hatches at the beginning, @samp{_O} defines a line with the current style and with a circle at the beginning. These styles are applicable during the graphics plotting as well (for example, @ref{1D plotting}).
+One may specify to draw a special symbol (an arrow) at the beginning and at the end of line. This is done if the specification string contains one of the following symbols: @samp{A} -- outer arrow, @samp{V} -- inner arrow, @samp{I} -- transverse hatches, @samp{K} -- arrow with hatches, @samp{T} -- triangle, @samp{S} -- square, @samp{D} -- rhombus, @samp{O} -- circle, @samp{X} -- skew cross, @samp{_} -- nothing (the default). The following rule applies: the first symbol specifies the arrow at the end of line, the second specifies the arrow at the beginning of the line. For example, @samp{r-A} defines a red solid line with usual arrow at the end, @samp{b|AI} defines a blue dash line with an arrow at the end and with hatches at the beginning, @samp{_O} defines a line with the current style and with a circle at the beginning. These styles are applicable during the graphics plotting as well (for example, @ref{1D plotting}).
 
 @pfig{style, Color and line styles.}
 
@@ -116,7 +116,7 @@ One may specify to draw a special symbol (an arrow) at the beginning and at the
 
 The color scheme is used for determining the color of surfaces, isolines, isosurfaces and so on. The color scheme is defined by the string, which may contain several characters that are color id (@pxref{Line styles}) or characters @samp{#:|}. Symbol @samp{#} switches to mesh drawing or to a wire plot. Symbol @samp{|} disables color interpolation in color scheme, which can be useful, for example, for sharp colors during matrix plotting. Symbol @samp{:} terminate the color scheme parsing. Following it, the user may put styles for the text, rotation axis for curves/isocontours, and so on. Color scheme may contain up to 32 color values.
 
-The final color is a linear interpolation of color array. The color array is constructed from the string ids (including ``bright'' colors, see @ref{Color styles}). The argument is the amplitude normalized between @var{Cmin} -- @var{Cmax} (see @ref{Axis settings}). For example, string containing 4 characters @samp{bcyr} corresponds to a colorbar from blue (lowest value) through cyan (next value) through yellow (next value) to the red (highest value). String @samp{kw} corresponds to a colorbar from black (lowest value) to white (highest value). String @samp{m} corresponds to a simple magenta color.
+The final color is a linear interpolation of color array. The color array is constructed from the string ids (including ``bright'' colors, see @ref{Color styles}). The argument is the amplitude normalized in color range (see @ref{Axis settings}). For example, string containing 4 characters @samp{bcyr} corresponds to a colorbar from blue (lowest value) through cyan (next value) through yellow (next value) to the red (highest value). String @samp{kw} corresponds to a colorbar from black (lowest value) to white (highest value). String @samp{m} corresponds to a simple magenta color.
 
 There are several useful combinations. String @samp{kw} corresponds to the simplest gray color scheme where higher values are brighter. String @samp{wk} presents the inverse gray color scheme where higher value is darker. Strings @samp{kRryw}, @samp{kGgw}, @samp{kBbcw} present the well-known @emph{hot}, @emph{summer} and @emph{winter} color schemes. Strings @samp{BbwrR} and @samp{bBkRr} allow to view bi-color figure on white or black background, where negative values are blue and positive values are red. String @samp{BbcyrR} gives a color scheme similar to the well-known @emph{jet} color scheme.
 
@@ -133,10 +133,14 @@ Additionally, MathGL can apply mask to face filling at bitmap rendering. The kin
 
 However, you can redefine mask for one symbol by specifying new matrix of size 8*8 as second argument for @ref{mask} command. For example, the right-down subplot on the figure above is produced by code@*
 @ifclear UDAV
-@code{gr->SetMask('+', "ff00182424f80000");    gr->Dens(a,"3+");}
+@code{gr->SetMask('+', "ff00182424f800");      gr->Dens(a,"3+");}@*
+or just use manual mask style (for v.2.3 and later)@*
+@code{gr->Dens(a,"3@{s00ff00182424f800@}");}
 @end ifclear
 @ifset UDAV
-@code{mask '+' 'ff00182424f80000':dens a '3+'}
+@code{mask '+' 'ff00182424f800':dens a '3+'}@*
+or just use manual mask style (for v.2.3 and later)@*
+@code{dens a '3@{s00ff00182424f800@}'}
 @end ifset
 
 @c ------------------------------------------------------------------
@@ -147,7 +151,7 @@ However, you can redefine mask for one symbol by specifying new matrix of size 8
 
 @cindex Font styles
 
-Text style is specified by the string which may contain: color id characters @samp{wkrgbcymhRGBCYMHW} (see @ref{Color styles}), and font style (@samp{ribwou}) and/or alignment (@samp{LRC}) specifications. At this, font style and alignment begin after the separator @samp{:}. For example, @samp{r:iCb} sets the bold (@samp{b}) italic (@samp{i}) font text aligned at the center (@samp{C}) and with red color (@samp{r}).
+Text style is specified by the string which may contain: color id characters @samp{wkrgbcymhRGBCYMHW} (see @ref{Color styles}), and font style (@samp{ribwou}) and/or alignment (@samp{LRC}) specifications. At this, font style and alignment begin after the separator @samp{:}. For example, @samp{r:iCb} sets the bold (@samp{b}) italic (@samp{i}) font text aligned at the center (@samp{C}) and with red color (@samp{r}). Starting from MathGL v.2.3, you can set not single color for whole text, but use color gradient for printed text (see @ref{Color scheme}).
 
 The font styles are: @samp{r} -- roman (or regular) font, @samp{i} -- italic style, @samp{b} -- bold style. By default roman roman font is used. The align types are: @samp{L} -- align left (default), @samp{C} -- align center, @samp{R} -- align right. Additional font effects are: @samp{w} -- wired, @samp{o} -- over-lined, @samp{u} -- underlined.
 
@@ -194,7 +198,7 @@ MathGL have the fast variant of textual formula evaluation
 @end ifclear
 . There are a lot of functions and operators available. The operators are: @samp{+} -- addition, @samp{-} -- subtraction, @samp{*} -- multiplication, @samp{/} -- division, @samp{^} -- integer power. Also there are logical ``operators'': @samp{<} -- true if x<y, @samp{>} -- true if x>y, @samp{=} -- true if x=y, @samp{&} -- true if x and y both nonzero, @samp{|} -- true if x or y nonzero. These logical operators have lowest priority and return 1 if true or 0 if false.
 
-The basic functions are: @samp{sqrt(x)} -- square root of @var{x}, @samp{pow(x,y)} -- power @var{x} in @var{y}, @samp{ln(x)} -- natural logarithm of @var{x}, @samp{lg(x)} -- decimal logarithm of @var{x}, @samp{log(a,x)} -- logarithm base @var{a} of @var{x}, @samp{abs(x)} -- absolute value of @var{x}, @samp{sign(x)} -- sign of @var{x}, @samp{mod(x,y)} -- x modulo y, @samp{step(x)} -- step function, @samp{int(x)} -- integer part of @var{x}, @samp{rnd} -- random number, @samp{pi} -- number
+The basic functions are: @samp{sqrt(x)} -- square root of @var{x}, @samp{pow(x,y)} -- power @var{x} in @var{y}, @samp{ln(x)} -- natural logarithm of @var{x}, @samp{lg(x)} -- decimal logarithm of @var{x}, @samp{log(a,x)} -- logarithm base @var{a} of @var{x}, @samp{abs(x)} -- absolute value of @var{x}, @samp{sign(x)} -- sign of @var{x}, @samp{mod(x,y)} -- @var{x} modulo @var{y}, @samp{step(x)} -- step function, @samp{int(x)} -- integer part of @var{x}, @samp{rnd} -- random number, @samp{random(x)} -- random data of size as in @var{x}, @samp{pi} -- number
 @ifhtml
 @html
 &pi; = 3.1415926&hellip;
@@ -208,7 +212,7 @@ Trigonometric functions are: @samp{sin(x)}, @samp{cos(x)}, @samp{tan(x)} (or @sa
 
 @ifhtml
 @html
-<p>There are a set of special functions: &lsquo;<samp>gamma(x)</samp>&rsquo; &ndash; Gamma function &Gamma;(x) = &int;<sub>0</sub><sup>&infin;</sup> t<sup>x-1</sup> exp(-t) dt, &lsquo;<samp>psi(x)</samp>&rsquo; &ndash; digamma function &psi;(x) = &Gamma;&prime;(x)/&Gamma;(x) for x&ne;0, &lsquo;<samp>ai(x)</samp>&rsquo; &ndash; Airy function Ai(x), &lsquo;<samp>bi(x)</samp>&rsquo; &ndash; Airy function Bi(x), &lsquo;<samp>cl(x)</samp>&rsquo; &ndash; Clausen function, &lsquo;<samp>li2(x)</samp>&rsquo; (or &lsquo;<samp>dilog(x)</samp>&rsquo;) &ndash; dilogarithm Li<sub>2</sub>(x) = -&real;&int;<sub>0</sub><sup>x</sup>ds log(1-s)/s, &lsquo;<samp>sinc(x)</samp>&rsquo; &ndash; compute sinc(x) = sin(&pi;x)/(&pi;x) for any value of x, &lsquo;<samp>zeta(x)</samp>&rsquo; &ndash; Riemann zeta function &zeta;(s) = &sum;<sub>k=1</sub><sup>&infin;</sup>k<sup>-s</sup> for arbitrary s&ne;1, &lsquo;<samp>eta(x)</samp>&rsquo; &ndash; eta function &eta;(s) = (1 - 2<sup>1-s</sup>)&zeta;(s) for arbitrary s, &lsquo;<samp>lp(l,x)</samp>&rsquo; &ndash; Legendre polynomial P<sub>l</sub>(x), (|x|&le;1, l&ge;0), &lsquo;<samp>w0(x)</samp>&rsquo; &ndash; principal branch of the Lambert W function, &lsquo;<samp>w1(x)</samp>&rsquo; &ndash; principal branch of the Lambert W function. Function W(x) is defined to be solution of the equation: W exp(W) = x. </p>
+<p>There are a set of special functions: &lsquo;<samp>gamma(x)</samp>&rsquo; &ndash; Gamma function &Gamma;(x) = &int;<sub>0</sub><sup>&infin;</sup> t<sup>x-1</sup> exp(-t) dt, &lsquo;<samp>gamma_inc(x,y)</samp>&rsquo; &ndash; incomplete Gamma function &Gamma;(x,y) = &int;<sub>y</sub><sup>&infin;</sup> t<sup>x-1</sup> exp(-t) dt, &lsquo;<samp>psi(x)</samp>&rsquo; &ndash; digamma function &psi;(x) = &Gamma;&prime;(x)/&Gamma;(x) for x&ne;0, &lsquo;<samp>ai(x)</samp>&rsquo; &ndash; Airy function Ai(x), &lsquo;<samp>bi(x)</samp>&rsquo; &ndash; Airy function Bi(x), &lsquo;<samp>cl(x)</samp>&rsquo; &ndash; Clausen function, &lsquo;<samp>li2(x)</samp>&rsquo; (or &lsquo;<samp>dilog(x)</samp>&rsquo;) &ndash; dilogarithm Li<sub>2</sub>(x) = -&real;&int;<sub>0</sub><sup>x</sup>ds log(1-s)/s, &lsquo;<samp>sinc(x)</samp>&rsquo; &ndash; compute sinc(x) = sin(&pi;x)/(&pi;x) for any value of x, &lsquo;<samp>zeta(x)</samp>&rsquo; &ndash; Riemann zeta function &zeta;(s) = &sum;<sub>k=1</sub><sup>&infin;</sup>k<sup>-s</sup> for arbitrary s&ne;1, &lsquo;<samp>eta(x)</samp>&rsquo; &ndash; eta function &eta;(s) = (1 - 2<sup>1-s</sup>)&zeta;(s) for arbitrary s, &lsquo;<samp>lp(l,x)</samp>&rsquo; &ndash; Legendre polynomial P<sub>l</sub>(x), (|x|&le;1, l&ge;0), &lsquo;<samp>w0(x)</samp>&rsquo; &ndash; principal branch of the Lambert W function, &lsquo;<samp>w1(x)</samp>&rsquo; &ndash; principal branch of the Lambert W function. Function W(x) is defined to be solution of the equation: W exp(W) = x. </p>
 
 <p>The exponent integrals are: &lsquo;<samp>ci(x)</samp>&rsquo; &ndash; Cosine integral Ci(x) = &int;<sub>0</sub><sup>x</sup>dt cos(t)/t, &lsquo;<samp>si(x)</samp>&rsquo; &ndash; Sine integral Si(x) = &int;<sub>0</sub><sup>x</sup>dt sin(t)/t, &lsquo;<samp>erf(x)</samp>&rsquo; &ndash; error function erf(x) = (2/&radic;&pi;) &int;<sub>0</sub><sup>x</sup>dt exp(-t<sup>2</sup>) , &lsquo;<samp>ei(x)</samp>&rsquo; &ndash; exponential integral Ei(x) = -PV(&int;<sub>-x</sub><sup>&infin;</sup>dt exp(-t)/t) (where PV denotes the principal value of the integral), &lsquo;<samp>e1(x)</samp>&rsquo; &ndash; exponential integral E<sub>1</sub>(x) = &real;&int;<sub>1</sub><sup>&infin;</sup>dt exp(-xt)/t, &lsquo;<samp>e2(x)</samp>&rsquo; &ndash; exponential integral E<sub>2</sub>(x) = &real;&int;<sub>1</sub>&infin;</sup>dt exp(-xt)/t<sup>2</sup>, &lsquo;<samp>ei3(x)</samp>&rsquo; &ndash; exponential integral Ei<sub>3</sub>(x) = &int;<sub>0</sub><sup>x</sup>dt exp(-t<sup>3</sup>) for x&ge;0. </p>
 
@@ -218,7 +222,7 @@ Trigonometric functions are: @samp{sin(x)}, @samp{cos(x)}, @samp{tan(x)} (or @sa
 @end html
 @end ifhtml
 @ifnothtml
-There are a set of special functions: @samp{gamma(x)} -- Gamma function @math{\Gamma(x) = \int_0^\infty dt t^@{x-1@} \exp(-t)} , @samp{psi(x)} -- digamma function @math{\psi(x) = \Gamma'(x)/\Gamma(x)} for x!=0, @samp{ai(x)} -- Airy function Ai(x), @samp{bi(x)} -- Airy function Bi(x), @samp{cl(x)} -- Clausen function, @samp{li2(x)} (or @samp{dilog(x)}) -- dilogarithm @math{Li_2(x) = - \Re \int_0^x ds \log(1-s)/s}, @samp{sinc(x)} -- compute @math{sinc(x) = \sin(\pi x) / (\pi x)} for any value of x, @samp{zeta(x)} -- Riemann zeta function @math{\zeta(s) = \sum_@{k=1@}^\infty k^@{-s@}} for arbitrary s!=1, @samp{eta(x)} -- eta function @math{\eta(s) = (1-2^@{1-s@}) \zeta(s)} for arbitrary s, @samp{lp(l,x)} -- Legendre polynomial @math{P_l(x)}, (|x|<=1, l>=0), @samp{w0(x)}, @samp{w1(x)} -- principal branch of the Lambert @var{W} functions. Function W(x) is defined to be solution of the equation @math{W \exp(W) = x}.
+There are a set of special functions: @samp{gamma(x)} -- Gamma function @math{\Gamma(x) = \int_0^\infty dt t^@{x-1@} exp(-t)}, @samp{gamma_inc(x,y)} -- incomplete Gamma function @math{\Gamma(x,y) = \int_y^\infty dt t^@{x-1@} exp(-t)}, @samp{psi(x)} -- digamma function @math{\psi(x) = \Gamma'(x)/\Gamma(x)} for x!=0, @samp{ai(x)} -- Airy function Ai(x), @samp{bi(x)} -- Airy function Bi(x), @samp{cl(x)} -- Clausen function, @samp{li2(x)} (or @samp{dilog(x)}) -- dilogarithm @math{Li_2(x) = - \Re \int_0^x ds \log(1-s)/s}, @samp{sinc(x)} -- compute @math{sinc(x) = \sin(\pi x) / (\pi x)} for any value of x, @samp{zeta(x)} -- Riemann zeta function @math{\zeta(s) = \sum_@{k=1@}^\infty k^@{-s@}} for arbitrary s!=1, @samp{eta(x)} -- eta function @math{\eta(s) = (1-2^@{1-s@}) \zeta(s)} for arbitrary s, @samp{lp(l,x)} -- Legendre polynomial @math{P_l(x)}, (|x|<=1, l>=0), @samp{w0(x)}, @samp{w1(x)} -- principal branch of the Lambert @var{W} functions. Function W(x) is defined to be solution of the equation @math{W \exp(W) = x}.
 
 The exponent integrals are: @samp{ci(x)} -- Cosine integral @math{Ci(x) = \int_0^x dt \cos(t)/t}, @samp{si(x)} -- Sine integral @math{Si(x) = \int_0^x dt \sin(t)/t}, @samp{erf(x)} -- error function @math{erf(x) = (2/\sqrt(\pi)) \int_0^x dt \exp(-t^2)}, @samp{ei(x)} -- exponential integral @math{Ei(x) := - PV(\int_@{-x@}^\infty dt \exp(-t)/t)} (where PV denotes the principal value of the integral), @samp{e1(x)} -- exponential integral @math{E_1(x) := Re \int_1^\infty dt \exp(-xt)/t} , @samp{e2(x)} -- exponential integral @math{E_2(x) := Re \int_1^\infty dt \exp(-xt)/t^2}, @samp{ei3(x)} -- exponential integral @math{Ei_3(x) = \int_0^x dt \exp(-t^3)} for x>=0.
 
index 0e815507fe945cf64a797b73cceae86f590000e0..01c8ed513aaa917b63d25c921103e59c46fa9952 100644 (file)
 @section Оси координат
 @nav{}
 
\9fÑ\80едÑ\81Ñ\82авление Ñ\81иÑ\81Ñ\82емÑ\8b ÐºÐ¾Ð¾Ñ\80динаÑ\82 Ð² MathGL Ñ\81оÑ\81Ñ\82оиÑ\82 Ð¸Ð· Ð´Ð²Ñ\83Ñ\85 Ñ\87аÑ\81Ñ\82ей. Ð\92наÑ\87але ÐºÐ¾Ð¾Ñ\80динаÑ\82Ñ\8b Ð½Ð¾Ñ\80миÑ\80Ñ\83Ñ\8eÑ\82Ñ\81Ñ\8f Ð² Ð¸Ð½Ñ\82еÑ\80вал @var{Min}x@var{Max} (@pxref{Axis settings}). Если флаг @code{SetCut()} установлен, то точки вне интервала отбрасываются, в противном случае, они проецируются на ограничивающий параллелепипед (см. @ref{Cutting}). Кроме того, отбрасываются точки внутри границ, определенных переменными @var{CutMin}x@var{CutMax} и точки, для которых значение функции @code{CutOff}() не равно нулю. После этого формулы перехода в криволинейную систему координат @code{SetFunc()}применяются к каждой точке. Наконец, точка данных отображается с помощью одной из графических функций.
\9fÑ\80едÑ\81Ñ\82авление Ñ\81иÑ\81Ñ\82емÑ\8b ÐºÐ¾Ð¾Ñ\80динаÑ\82 Ð² MathGL Ñ\81оÑ\81Ñ\82оиÑ\82 Ð¸Ð· Ð´Ð²Ñ\83Ñ\85 Ñ\87аÑ\81Ñ\82ей. Ð\92наÑ\87але ÐºÐ¾Ð¾Ñ\80динаÑ\82Ñ\8b Ð½Ð¾Ñ\80миÑ\80Ñ\83Ñ\8eÑ\82Ñ\81Ñ\8f Ð² Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ\8f Ð¾Ñ\81ей ÐºÐ¾Ð¾Ñ\80динаÑ\82 (@pxref{Axis settings}). Если флаг @code{SetCut()} установлен, то точки вне интервала отбрасываются, в противном случае, они проецируются на ограничивающий параллелепипед (см. @ref{Cutting}). Кроме того, отбрасываются точки внутри границ, определенных переменными @var{CutMin}x@var{CutMax} и точки, для которых значение функции @code{CutOff}() не равно нулю. После этого формулы перехода в криволинейную систему координат @code{SetFunc()}применяются к каждой точке. Наконец, точка данных отображается с помощью одной из графических функций.
 
 Диапазон изменения @emph{x, y, z}-координат задается функциями @code{SetRange()} или @code{SetRanges()}. Точка пересечения осей координат задается функцией @code{SetOrigin()}. При этом можно использовать NAN значения для автоматического выбора положения оси.
 
-Кроме привычных осей @emph{x, y, z} есть еще одна ось -- цветовая шкала -- ось @emph{c}. Она используется при окрашивании поверхностей и задает границы изменения функции при окрашивании. Ее границы автоматически устанавливаются равными Min.z и Max.z при вызове @code{SetRanges()}. Возможно и ручное изменение границ цветового интервала посредством вызова @code{SetRange('c', ...)}. Используйте @code{Colorbar()} для отображения цветовой шкалы.
+Кроме привычных осей @emph{x, y, z} есть еще одна ось -- цветовая шкала -- ось @emph{c}. Она используется при окрашивании поверхностей и задает границы изменения функции при окрашивании. Ее границы автоматически устанавливаются равными диапазону z-оси при вызове @code{SetRanges()}. Возможно и ручное изменение границ цветового интервала посредством вызова @code{SetRange('c', ...)}. Используйте @code{Colorbar()} для отображения цветовой шкалы.
 
 Вид меток по осям определяется функцией @code{SetTicks()} (@pxref{Ticks}). Функция @var{SetTuneTicks} включает/выключает выделение общего множителя (большого или малого факторов в диапазоне) для меток осей координат. Наконец, если стандартный вид меток не устраивает пользователя, то их шаблон можно задать явно (можно использовать и ТеХ символы), воспользовавшись функцией  @code{SetTickTempl()}. Кроме того, в качестве меток можно вывести произвольный текст использовав функцию @code{SetTicksVal()}.
 
@@ -89,18 +89,18 @@ Base colors are defined by one of symbol @samp{wkrgbcymhRGBCYMHWlenupqLENUPQ}.
 @html
 По умолчанию палитры содержит следующие цвета: <span style="color: rgb(76, 76, 76);">темно серый</span> &lsquo;<samp>H</samp>&rsquo;, <span style="color: rgb(0, 0, 255);">синий</span> &lsquo;<samp>b</samp>&rsquo;, <span style="color: rgb(0, 255, 0);">зеленый</span> &lsquo;<samp>g</samp>&rsquo;, <span style="color: rgb(255, 0, 0);">красный</span> &lsquo;<samp>r</samp>&rsquo;, <span style="color: rgb(0, 255, 255);">голубой</span> &lsquo;<samp>c</samp>&rsquo;, <span style="color: rgb(255, 0, 255);">пурпурный</span> &lsquo;<samp>m</samp>&rsquo;, <span style="color: rgb(255, 255, 0);">yellow</span> &lsquo;<samp>y</samp>&rsquo;, <span style="color: rgb(127, 127, 127);">серый</span> &lsquo;<samp>h</samp>&rsquo;, <span style="color: rgb(0, 255, 127);">сине-зеленый</span> &lsquo;<samp>l</samp>&rsquo;, <span style="color: rgb(0, 127, 255);">небесно-синий</span> &lsquo;<samp>n</samp>&rsquo;, <span style="color: rgb(255, 127, 0);">оранжевый</span> &lsquo;<samp>q</samp>&rsquo;, <span style="color: rgb(127, 255, 0);">желто-зеленый</span> &lsquo;<samp>e</samp>&rsquo;, <span style="color: rgb(127, 0, 255);">сине-фиолетовый</span> &lsquo;<samp>u</samp>&rsquo;, <span style="color: rgb(255, 0, 127);">фиолетовый</span> &lsquo;<samp>p</samp>&rsquo;.
 
-<p>Тип пунктира: пробел &ndash; нет линии (для рисования только маркеров), &lsquo;<samp>-</samp>&rsquo; &ndash; сплошная линия (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;), &lsquo;<samp>|</samp>&rsquo; &ndash; длинный пунктир (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>;</samp>&rsquo; &ndash; пунктир (&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>=</samp>&rsquo; &ndash; короткий пунктир (&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;), &lsquo;<samp>:</samp>&rsquo; &ndash; точки (&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;), &lsquo;<samp>j</samp>&rsquo; &ndash; пунктир с точками  (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>i</samp>&rsquo; &ndash; мелкий пунктир с точками (&#9632;&#9632;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;&#9632;&#9632;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;).</p>
+<p>Тип пунктира: пробел &ndash; нет линии (для рисования только маркеров), &lsquo;<samp>-</samp>&rsquo; &ndash; сплошная линия (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;), &lsquo;<samp>|</samp>&rsquo; &ndash; длинный пунктир (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>;</samp>&rsquo; &ndash; пунктир (&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>=</samp>&rsquo; &ndash; короткий пунктир (&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;&#9632;&#9632;&#9633;&#9633;), &lsquo;<samp>:</samp>&rsquo; &ndash; точки (&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;), &lsquo;<samp>j</samp>&rsquo; &ndash; пунктир с точками  (&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9633;), &lsquo;<samp>i</samp>&rsquo; &ndash; мелкий пунктир с точками (&#9632;&#9632;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;&#9632;&#9632;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;), &lsquo;<samp>{dNNNN}</samp>&rsquo; &ndash; заданный вручную стиль (для v.2.3 и поздних, например &lsquo;<samp>{df090}</samp>&rsquo; для (&#9632;&#9632;&#9632;&#9632;&#9633;&#9633;&#9633;&#9633;&#9632;&#9633;&#9633;&#9632;&#9633;&#9633;&#9633;&#9633;)).</p>
 @end html
 @end ifhtml
 @ifnothtml
 По умолчанию палитра содержит следующие цвета: темно серый @samp{H}, синий @samp{b}, зеленый @samp{g}, красный @samp{r}, голубой @samp{c}, пурпурный @samp{m}, yellow @samp{y}, серый @samp{h}, сине-зеленый @samp{l}, небесно-синий @samp{n}, оранжевый @samp{q}, желто-зеленый @samp{e}, сине-фиолетовый @samp{u}, фиолетовый @samp{p}.
 
-Тип пунктира: пробел -- нет линии (для рисования только маркеров), @samp{-} -- сплошная линия (################), @samp{|} -- длинный пунктир (########________), @samp{;} -- пунктир (####____####____), @samp{=} -- короткий пунктир (##__##__##__##__), @samp{:} -- точки (#___#___#___#___), @samp{j} -- пунктир с точками  (#######____#____), @samp{i} -- мелкий пунктир с точками (###__#__###__#__).
+Тип пунктира: пробел -- нет линии (для рисования только маркеров), @samp{-} -- сплошная линия (################), @samp{|} -- длинный пунктир (########________), @samp{;} -- пунктир (####____####____), @samp{=} -- короткий пунктир (##__##__##__##__), @samp{:} -- точки (#___#___#___#___), @samp{j} -- пунктир с точками  (#######____#____), @samp{i} -- мелкий пунктир с точками (###__#__###__#__), @samp{@{dNNNN@}} -- заданный вручную стиль (для v.2.3 и поздних, например @samp{@{df090@}} для (####____#__#____)).
 @end ifnothtml
 
 Типы маркеров: @samp{o} -- окружность, @samp{+} -- крест, @samp{x} -- косой крест, @samp{s} -- квадрат, @samp{d} - ромб, @samp{.} -- точка, @samp{^} -- треугольник вверх, @samp{v} -- треугольник вниз, @samp{<} -- треугольник влево, @samp{>} -- треугольник вправо, @samp{#*} -- знак Y, @samp{#+} -- крест в квадрате, @samp{#x} -- косой крест в квадрате, @samp{#.} -- точка в окружности. Если в строке присутствует символ @samp{#}, то используются символы с заполнением.
 
-На конце и в начале линии можно выводить специальный символ (стрелку), если в строке указать один из символов: @samp{A} -- стрелка наружу, @samp{V} -- стрелка внутрь, @samp{I} -- поперечная черта, @samp{K} -- стрелка с чертой, @samp{T} -- треугольник, @samp{S} -- квадрат, @samp{D} -- ромб, @samp{O} -- круг, @samp{_} -- нет стрелки (по умолчанию). При этом действует следующее правило: первый символ определяет стрелку на конце линии, второй символ -- стрелку в начале линии. Например, @samp{r-A} -- красная сплошная линия со стрелкой на конце, @samp{b|AI} -- синий пунктир со стрелкой на конце и чертой вначале, @samp{_O} -- линия с текущим стилем и кружком вначале. Эти стили действуют и при построении графиков (например, @ref{1D plotting}).
+На конце и в начале линии можно выводить специальный символ (стрелку), если в строке указать один из символов: @samp{A} -- стрелка наружу, @samp{V} -- стрелка внутрь, @samp{I} -- поперечная черта, @samp{K} -- стрелка с чертой, @samp{T} -- треугольник, @samp{S} -- квадрат, @samp{D} -- ромб, @samp{O} -- круг, @samp{X} -- косой крест, @samp{_} -- нет стрелки (по умолчанию). При этом действует следующее правило: первый символ определяет стрелку на конце линии, второй символ -- стрелку в начале линии. Например, @samp{r-A} -- красная сплошная линия со стрелкой на конце, @samp{b|AI} -- синий пунктир со стрелкой на конце и чертой вначале, @samp{_O} -- линия с текущим стилем и кружком вначале. Эти стили действуют и при построении графиков (например, @ref{1D plotting}).
 
 @pfig{style, Color and line styles.}
 
@@ -114,7 +114,7 @@ Base colors are defined by one of symbol @samp{wkrgbcymhRGBCYMHWlenupqLENUPQ}.
 
 Цветовая схема используется для определения цвета поверхностей, линий уровня и пр. Цветовая схема задается строкой @emph{s}, которая содержит символы цвета (@pxref{Line styles}) или символы @samp{#:|}. Символ @samp{#} переключает рисование поверхности на сетчатое (для трехмерных поверхностей) или включает рисование сетки на поверхности. Символ @samp{|} отключает интерполяцию цвета в цветовой схеме. Это может быть полезно для ``резких'' цветов, например, при рисовании матриц. Если в строке встречается символ @samp{:}, то он принудительно заканчивает разбор строки для стиля поверхности. После этого символа могут идти описание стиля текста или оси вращения кривой/линий уровня. Цветовая схема может содержать до 32 значений цвета.
 
\9fÑ\80и Ð¾Ð¿Ñ\80еделении Ñ\86веÑ\82а Ð¿Ð¾ @emph{амплиÑ\82Ñ\83де} (наиболее Ñ\87аÑ\81Ñ\82о Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f) Ð¾ÐºÐ¾Ð½Ñ\87аÑ\82елÑ\8cнÑ\8bй Ñ\86веÑ\82 Ð¾Ð¿Ñ\80еделÑ\8fеÑ\82Ñ\81Ñ\8f Ð¿Ñ\83Ñ\82ем Ð»Ð¸Ð½ÐµÐ¹Ð½Ð¾Ð¹ Ð¸Ð½Ñ\82еÑ\80полÑ\8fÑ\86ии Ð¼Ð°Ñ\81Ñ\81ива Ñ\86веÑ\82ов. Ð\9cаÑ\81Ñ\81ив Ñ\86веÑ\82ов Ñ\84оÑ\80миÑ\80Ñ\83еÑ\82Ñ\81Ñ\8f Ð¸Ð· Ñ\86веÑ\82ов, Ñ\83казаннÑ\8bÑ\85 Ð² Ñ\81Ñ\82Ñ\80оке Ñ\81пеÑ\86иÑ\84икаÑ\86ии. Ð\90Ñ\80гÑ\83менÑ\82 -- Ð°Ð¼Ð¿Ð»Ð¸Ñ\82Ñ\83да, Ð½Ð¾Ñ\80миÑ\80ованнаÑ\8f Ð¼ÐµÐ¶Ð´Ñ\83 @var{Cmin} -- @var{Cmax} (см. @ref{Axis settings}). Например, строка из 4 символов @samp{bcyr} соответствует изменению цвета от синего (минимальное значение) через голубой и желтый (промежуточные значения) к красному (максимальное значение). Строка @samp{kw} соответствует изменению цвета от черного (минимальное значение) к белому (максимальное значение). Строка из одного символа (например, @samp{g}) соответствует однотонному цвету (в данному случае зеленому).
\9fÑ\80и Ð¾Ð¿Ñ\80еделении Ñ\86веÑ\82а Ð¿Ð¾ @emph{амплиÑ\82Ñ\83де} (наиболее Ñ\87аÑ\81Ñ\82о Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f) Ð¾ÐºÐ¾Ð½Ñ\87аÑ\82елÑ\8cнÑ\8bй Ñ\86веÑ\82 Ð¾Ð¿Ñ\80еделÑ\8fеÑ\82Ñ\81Ñ\8f Ð¿Ñ\83Ñ\82ем Ð»Ð¸Ð½ÐµÐ¹Ð½Ð¾Ð¹ Ð¸Ð½Ñ\82еÑ\80полÑ\8fÑ\86ии Ð¼Ð°Ñ\81Ñ\81ива Ñ\86веÑ\82ов. Ð\9cаÑ\81Ñ\81ив Ñ\86веÑ\82ов Ñ\84оÑ\80миÑ\80Ñ\83еÑ\82Ñ\81Ñ\8f Ð¸Ð· Ñ\86веÑ\82ов, Ñ\83казаннÑ\8bÑ\85 Ð² Ñ\81Ñ\82Ñ\80оке Ñ\81пеÑ\86иÑ\84икаÑ\86ии. Ð\90Ñ\80гÑ\83менÑ\82 -- Ð°Ð¼Ð¿Ð»Ð¸Ñ\82Ñ\83да, Ð½Ð¾Ñ\80миÑ\80ованнаÑ\8f Ð½Ð° Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ\8f Ñ\86веÑ\82а (см. @ref{Axis settings}). Например, строка из 4 символов @samp{bcyr} соответствует изменению цвета от синего (минимальное значение) через голубой и желтый (промежуточные значения) к красному (максимальное значение). Строка @samp{kw} соответствует изменению цвета от черного (минимальное значение) к белому (максимальное значение). Строка из одного символа (например, @samp{g}) соответствует однотонному цвету (в данному случае зеленому).
 
 Есть несколько полезных цветовых схем. Строка @samp{kw} дает обычную серую (черно-белую) схему, когда большие значения светлее. Строка @samp{wk} представляет обратную серую схему, когда большие значения темнее. Строки @samp{kRryw}, @samp{kGgw}, @samp{kBbcw} представляют собой хорошо известные схемы @emph{hot}, @emph{summer} и @emph{winter}. Строки @samp{BbwrR} и @samp{bBkRr} позволяют рисовать двухцветные фигуры на белом или черном фоне, когда отрицательные значения показаны синим цветом, а положительные -- красным. Строка @samp{BbcyrR} дает цветовую схему, близкую к хорошо известной схеме @emph{jet}.
 
@@ -122,7 +122,7 @@ Base colors are defined by one of symbol @samp{wkrgbcymhRGBCYMHWlenupqLENUPQ}.
 
 @pfig{schemes, Most popular color schemes.}
 
\9fÑ\80и Ð¾Ð¿Ñ\80еделении Ñ\86веÑ\82а Ð¿Ð¾ @emph{положениÑ\8e Ñ\82оÑ\87ки Ð² Ð¿Ñ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82ве} (иÑ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f Ð² @ref{map}) Ð¾ÐºÐ¾Ð½Ñ\87аÑ\82елÑ\8cнÑ\8bй Ñ\86веÑ\82 Ð¾Ð¿Ñ\80еделÑ\8fеÑ\82Ñ\81Ñ\8f Ð¿Ð¾ Ñ\84оÑ\80мÑ\83ле c=x*c[1] + y*c[2]. Ð\97деÑ\81Ñ\8c c[1], c[2] -- Ð¿ÐµÑ\80вÑ\8bе Ñ\82Ñ\80и Ñ\86веÑ\82а Ð² Ñ\86веÑ\82овом Ð¼Ð°Ñ\81Ñ\81иве; x, y -- ÐºÐ¾Ð¾Ñ\80динаÑ\82Ñ\8b Ñ\82оÑ\87ки, Ð½Ð¾Ñ\80миÑ\80ованнÑ\8bе Ð½Ð° @var{Min}x@var{Max}.
\9fÑ\80и Ð¾Ð¿Ñ\80еделении Ñ\86веÑ\82а Ð¿Ð¾ @emph{положениÑ\8e Ñ\82оÑ\87ки Ð² Ð¿Ñ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82ве} (иÑ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f Ð² @ref{map}) Ð¾ÐºÐ¾Ð½Ñ\87аÑ\82елÑ\8cнÑ\8bй Ñ\86веÑ\82 Ð¾Ð¿Ñ\80еделÑ\8fеÑ\82Ñ\81Ñ\8f Ð¿Ð¾ Ñ\84оÑ\80мÑ\83ле c=x*c[1] + y*c[2]. Ð\97деÑ\81Ñ\8c c[1], c[2] -- Ð¿ÐµÑ\80вÑ\8bе Ñ\82Ñ\80и Ñ\86веÑ\82а Ð² Ñ\86веÑ\82овом Ð¼Ð°Ñ\81Ñ\81иве; x, y -- ÐºÐ¾Ð¾Ñ\80динаÑ\82Ñ\8b Ñ\82оÑ\87ки, Ð½Ð¾Ñ\80миÑ\80ованнÑ\8bе Ð² Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ\8f Ð¾Ñ\81ей ÐºÐ¾Ð¾Ñ\80динаÑ\82.
 @c Такой тип определения цвета полезен, например, при построении поверхностей уровня, когда цвет дает представление о положении точки в пространстве.
 
 
@@ -132,10 +132,14 @@ Base colors are defined by one of symbol @samp{wkrgbcymhRGBCYMHWlenupqLENUPQ}.
 
 Однако, вы можете задать собственную маску (как матрицу 8*8) для любого из этих символов, используя второй аргумент команды @ref{mask}. Например, маска на правом нижнем подрисунке получается кодом@*
 @ifclear UDAV
-@code{gr->SetMask('+', "ff00182424f80000");    gr->Dens(a,"3+");}
+@code{gr->SetMask('+', "ff00182424f80000");    gr->Dens(a,"3+");}@*
+или использовать явное задание маски (для v.2.3 и более поздних)@*
+@code{gr->Dens(a,"3@{s00ff00182424f800@}");}
 @end ifclear
 @ifset UDAV
-@code{mask '+' 'ff00182424f80000':dens a '3+'}
+@code{mask '+' 'ff00182424f80000':dens a '3+'}@*
+или использовать явное задание маски (для v.2.3 и более поздних)@*
+@code{dens a '3@{s00ff00182424f800@}'}
 @end ifset
 
 @c ------------------------------------------------------------------
@@ -146,7 +150,7 @@ Base colors are defined by one of symbol @samp{wkrgbcymhRGBCYMHWlenupqLENUPQ}.
 
 @cindex Стиль текста
 
-Стиль текста задается строкой, которая может содержать цвет текста @samp{wkrgbcymhRGBCYMHW} (см. @ref{Color styles}), а также тип шрифта (@samp{ribwou}) и/или выравнивания (@samp{LRC}) после символа @samp{:}. Например, @samp{r:iCb} соответствует жирному (@samp{b}) курсиву (@samp{i}) с выравниванием по центру (@samp{C} красного цвета (@samp{r}).
+Стиль текста задается строкой, которая может содержать цвет текста @samp{wkrgbcymhRGBCYMHW} (см. @ref{Color styles}), а также тип шрифта (@samp{ribwou}) и/или выравнивания (@samp{LRC}) после символа @samp{:}. Например, @samp{r:iCb} соответствует жирному (@samp{b}) курсиву (@samp{i}) с выравниванием по центру (@samp{C} красного цвета (@samp{r}). Начиная с MathGL версии 2.3, вы можете использовать не только один цвет для всего текста, но и задать цветовой градиент для выводимой строки (см. @ref{Color scheme}).
 
 Начертания шрифта: @samp{r} -- прямой шрифт, @samp{i} -- курсив, @samp{b} -- жирный. По умолчанию используется прямой шрифт. Типы выравнивания текста: @samp{L} -- по левому краю (по умолчанию), @samp{C} -- по центру, @samp{R} -- по правому краю. Дополнительные эффекты шрифта: @samp{w} -- контурный, @samp{o} -- надчеркнутый, @samp{u} -- подчеркнутый.
 
@@ -192,7 +196,7 @@ MathGL имеет быстрый парсер текстовых формул
 @end ifclear
 , понимающий большое число функций и операций. Базовые операции: @samp{+} -- сложение, @samp{-} -- вычитание, @samp{*} -- умножение, @samp{/} -- деление, @samp{^} -- возведение в целосичленную степень. Также есть логические операции: @samp{<} -- истина если if x<y, @samp{>} -- истина если x>y, @samp{=} -- истина если x=y, @samp{&} -- истина если x и y оба не равны нулю, @samp{|} -- истина если x или y не нуль. Логические операции имеют наинизший приоритет и возвращают 1 если истина или 0 если ложно.
 
-Базовые функции: @samp{sqrt(x)} -- квадратный корень из @var{x}, @samp{pow(x,y)} -- @var{x} в степени @var{y}, @samp{ln(x)} -- натуральный логарифм @var{x}, @samp{lg(x)} -- десятичный логарифм @var{x}, @samp{log(a,x)} -- логарифм по основанию @var{a} от @var{x}, @samp{abs(x)} -- модуль @var{x}, @samp{sign(x)} -- знак @var{x}, @samp{mod(x,y)} -- остаток от деления x на y, @samp{step(x)} -- ступенчатая функция, @samp{int(x)} -- целая часть @var{x}, @samp{rnd} -- случайное число, @samp{pi} -- число
+Базовые функции: @samp{sqrt(x)} -- квадратный корень из @var{x}, @samp{pow(x,y)} -- @var{x} в степени @var{y}, @samp{ln(x)} -- натуральный логарифм @var{x}, @samp{lg(x)} -- десятичный логарифм @var{x}, @samp{log(a,x)} -- логарифм по основанию @var{a} от @var{x}, @samp{abs(x)} -- модуль @var{x}, @samp{sign(x)} -- знак @var{x}, @samp{mod(x,y)} -- остаток от деления @var{x} на @var{y}, @samp{step(x)} -- ступенчатая функция, @samp{int(x)} -- целая часть @var{x}, @samp{rnd} -- случайное число, @samp{random(x)} -- матрица случайный чисел размером как @var{x}, @samp{pi} -- число
 @ifhtml
 @html
 &pi; = 3.1415926&hellip;
@@ -206,7 +210,7 @@ MathGL имеет быстрый парсер текстовых формул
 
 @ifhtml
 @html
-<p>Специальные функции: &lsquo;<samp>gamma(x)</samp>&rsquo; &ndash; гамма функция &Gamma;(x) = &int;<sub>0</sub><sup>&infin;</sup> t<sup>x-1</sup> exp(-t) dt, &lsquo;<samp>psi(x)</samp>&rsquo; &ndash; дигамма функция &psi;(x) = &Gamma;&prime;(x)/&Gamma;(x) для x&ne;0, &lsquo;<samp>ai(x)</samp>&rsquo; &ndash; Эйри функция Ai(x), &lsquo;<samp>bi(x)</samp>&rsquo; &ndash; Эйри функция Bi(x), &lsquo;<samp>cl(x)</samp>&rsquo; &ndash; функция Клаузена, &lsquo;<samp>li2(x)</samp>&rsquo; (или &lsquo;<samp>dilog(x)</samp>&rsquo;) &ndash; дилогарифм Li<sub>2</sub>(x) = -&real;&int;<sub>0</sub><sup>x</sup>ds log(1-s)/s, &lsquo;<samp>sinc(x)</samp>&rsquo; &ndash; функция sinc(x) = sin(&pi;x)/(&pi;x) для любых x, &lsquo;<samp>zeta(x)</samp>&rsquo; &ndash; зета функция Римана &zeta;(s) = &sum;<sub>k=1</sub><sup>&infin;</sup>k<sup>-s</sup> для s&ne;1, &lsquo;<samp>eta(x)</samp>&rsquo; &ndash; эта функция &eta;(s) = (1 - 2<sup>1-s</sup>)&zeta;(s) для произвольного s, &lsquo;<samp>lp(l,x)</samp>&rsquo; &ndash; полином Лежандра P<sub>l</sub>(x), (|x|&le;1, l&ge;0), &lsquo;<samp>w0(x)</samp>&rsquo;, &lsquo;<samp>w1(x)</samp>&rsquo; &ndash; функции Ламберта W. Функции W(x) определены как решение уравнения: W exp(W) = x. </p>
+<p>Специальные функции: &lsquo;<samp>gamma(x)</samp>&rsquo; &ndash; гамма функция &Gamma;(x) = &int;<sub>0</sub><sup>&infin;</sup> t<sup>x-1</sup> exp(-t) dt, &lsquo;<samp>gamma_inc(x,y)</samp>&rsquo; &ndash; неполная гамма функция &Gamma;(x,y) = &int;<sub>y</sub><sup>&infin;</sup> t<sup>x-1</sup> exp(-t) dt, &lsquo;<samp>psi(x)</samp>&rsquo; &ndash; дигамма функция &psi;(x) = &Gamma;&prime;(x)/&Gamma;(x) для x&ne;0, &lsquo;<samp>ai(x)</samp>&rsquo; &ndash; Эйри функция Ai(x), &lsquo;<samp>bi(x)</samp>&rsquo; &ndash; Эйри функция Bi(x), &lsquo;<samp>cl(x)</samp>&rsquo; &ndash; функция Клаузена, &lsquo;<samp>li2(x)</samp>&rsquo; (или &lsquo;<samp>dilog(x)</samp>&rsquo;) &ndash; дилогарифм Li<sub>2</sub>(x) = -&real;&int;<sub>0</sub><sup>x</sup>ds log(1-s)/s, &lsquo;<samp>sinc(x)</samp>&rsquo; &ndash; функция sinc(x) = sin(&pi;x)/(&pi;x) для любых x, &lsquo;<samp>zeta(x)</samp>&rsquo; &ndash; зета функция Римана &zeta;(s) = &sum;<sub>k=1</sub><sup>&infin;</sup>k<sup>-s</sup> для s&ne;1, &lsquo;<samp>eta(x)</samp>&rsquo; &ndash; эта функция &eta;(s) = (1 - 2<sup>1-s</sup>)&zeta;(s) для произвольного s, &lsquo;<samp>lp(l,x)</samp>&rsquo; &ndash; полином Лежандра P<sub>l</sub>(x), (|x|&le;1, l&ge;0), &lsquo;<samp>w0(x)</samp>&rsquo;, &lsquo;<samp>w1(x)</samp>&rsquo; &ndash; функции Ламберта W. Функции W(x) определены как решение уравнения: W exp(W) = x. </p>
 
 <p>Экспоненциальные интегралы: &lsquo;<samp>ci(x)</samp>&rsquo; &ndash; cos-интеграл Ci(x) = &int;<sub>0</sub><sup>x</sup>dt cos(t)/t, &lsquo;<samp>si(x)</samp>&rsquo; &ndash; sin-интеграл Si(x) = &int;<sub>0</sub><sup>x</sup>dt sin(t)/t, &lsquo;<samp>erf(x)</samp>&rsquo; &ndash; функция ошибки erf(x) = (2/&radic;&pi;) &int;<sub>0</sub><sup>x</sup>dt exp(-t<sup>2</sup>) , &lsquo;<samp>ei(x)</samp>&rsquo; &ndash; интеграл Ei(x) = -PV(&int;<sub>-x</sub><sup>&infin;</sup>dt exp(-t)/t) (где PV обозначает главное значение), &lsquo;<samp>e1(x)</samp>&rsquo; &ndash; интеграл E<sub>1</sub>(x) = &real;&int;<sub>1</sub><sup>&infin;</sup>dt exp(-xt)/t, &lsquo;<samp>e2(x)</samp>&rsquo; &ndash; интеграл E<sub>2</sub>(x) = &real;&int;<sub>1</sub>&infin;</sup>dt exp(-xt)/t<sup>2</sup>, &lsquo;<samp>ei3(x)</samp>&rsquo; &ndash; интеграл Ei<sub>3</sub>(x) = &int;<sub>0</sub><sup>x</sup>dt exp(-t<sup>3</sup>) для x&ge;0. </p>
 
@@ -216,7 +220,7 @@ MathGL имеет быстрый парсер текстовых формул
 @end html
 @end ifhtml
 @ifnothtml
-Специальные функции: @samp{gamma(x)} -- гамма функция @math{\Gamma(x) = \int_0^\infty dt t^@{x-1@} \exp(-t)} , @samp{psi(x)} -- дигамма функция @math{\psi(x) = \Gamma'(x)/\Gamma(x)} для x!=0, @samp{ai(x)} -- Эйри функция Ai(x), @samp{bi(x)} -- Эйри функция Bi(x), @samp{cl(x)} -- функция Клаузена, @samp{li2(x)} (или @samp{dilog(x)}) -- дилогарифм @math{Li_2(x) = - \Re \int_0^x ds \log(1-s)/s}, @samp{sinc(x)} -- функция @math{sinc(x) = \sin(\pi x) / (\pi x)} для любых x, @samp{zeta(x)} -- зета функция Римана @math{\zeta(s) = \sum_@{k=1@}^\infty k^@{-s@}} для s!=1, @samp{eta(x)} -- эта функция @math{\eta(s) = (1-2^@{1-s@}) \zeta(s)} для произвольного s, @samp{lp(l,x)} -- полином Лежандра @math{P_l(x)}, (|x|<=1, l>=0), @samp{w0(x)}, @samp{w1(x)} -- функции Ламберта @var{W}. Функции W(x) определены как решение уравнения @math{W \exp(W) = x}.
+Специальные функции: @samp{gamma(x)} -- гамма функция @math{\Gamma(x) = \int_0^\infty dt t^@{x-1@} \exp(-t)}, @samp{gamma_inc(x,y)} -- неполная гамма функция @math{\Gamma(x,y) = \int_y^\infty dt t^@{x-1@} exp(-t)}, @samp{psi(x)} -- дигамма функция @math{\psi(x) = \Gamma'(x)/\Gamma(x)} для x!=0, @samp{ai(x)} -- Эйри функция Ai(x), @samp{bi(x)} -- Эйри функция Bi(x), @samp{cl(x)} -- функция Клаузена, @samp{li2(x)} (или @samp{dilog(x)}) -- дилогарифм @math{Li_2(x) = - \Re \int_0^x ds \log(1-s)/s}, @samp{sinc(x)} -- функция @math{sinc(x) = \sin(\pi x) / (\pi x)} для любых x, @samp{zeta(x)} -- зета функция Римана @math{\zeta(s) = \sum_@{k=1@}^\infty k^@{-s@}} для s!=1, @samp{eta(x)} -- эта функция @math{\eta(s) = (1-2^@{1-s@}) \zeta(s)} для произвольного s, @samp{lp(l,x)} -- полином Лежандра @math{P_l(x)}, (|x|<=1, l>=0), @samp{w0(x)}, @samp{w1(x)} -- функции Ламберта @var{W}. Функции W(x) определены как решение уравнения @math{W \exp(W) = x}.
 
 Экспоненциальные интегралы: @samp{ci(x)} -- cos-интеграл @math{Ci(x) = \int_0^x dt \cos(t)/t}, @samp{si(x)} -- sin-интеграл @math{Si(x) = \int_0^x dt \sin(t)/t}, @samp{erf(x)} -- функция ошибки @math{erf(x) = (2/\sqrt(\pi)) \int_0^x dt \exp(-t^2)}, @samp{ei(x)} -- интеграл @math{Ei(x) := - PV(\int_@{-x@}^\infty dt \exp(-t)/t)} (где PV обозначает главное значение), @samp{e1(x)} -- интеграл @math{E_1(x) := Re \int_1^\infty dt \exp(-xt)/t} , @samp{e2(x)} -- интеграл @math{E_2(x) := Re \int_1^\infty dt \exp(-xt)/t^2}, @samp{ei3(x)} -- интеграл @math{Ei_3(x) = \int_0^x dt \exp(-t^3)} для x>=0.
 
index 80a6e74f22efcf760f0525949eada01b5b661032..5b3ded0cbb67ae117b9426c8004eeedcc04b0739 100644 (file)
@@ -11,12 +11,22 @@ This chapter contains a lot of plotting commands for 1D, 2D and 3D data. It also
 The core of MathGL is @strong{mglGraph} class defined in @code{#include <mgl2/mgl.h>}. It contains a lot of plotting functions for 1D, 2D and 3D data. It also encapsulates parameters for axes drawing. Moreover an arbitrary coordinate transformation can be used for each axis. All plotting functions use data encapsulated in mglData class (see @ref{Data processing}) that allows to check sizes of used arrays easily. Also it have many functions for data handling: modify it by formulas, find momentums and distribution (histogram), apply operator (differentiate, integrate, transpose, Fourier and so on), change data sizes (interpolate, squeeze, crop and so on). Additional information about colors, fonts, formula parsing can be found in @ref{General concepts} and @ref{Other classes}.
 @end ifclear
 
+Some of MathGL features will appear only in novel versions. To test used MathGL version you can use following function.
+@anchor{version}
+@deftypefn {MGL command} {} version 'ver'
+@ifclear UDAV
+@deftypefnx {C function} @code{int} mgl_check_version (@code{const char *}ver)
+@end ifclear
+Return nonzero if MathGL version is appropriate for required by @var{ver}, i.e. if major version is the same and minor version is greater or equal to one in @var{ver}.
+@end deftypefn
+
 @menu
 * Constructor::
 * Graphics setup::
 * Axis settings::
 * Subplots and rotation::
 * Export picture::
+* Background::
 * Primitives::
 * Text printing::
 * Axis and Colorbar::
@@ -87,6 +97,7 @@ Restore initial values for all of parameters.
 * Palette and colors::
 * Masks::
 * Error handling::
+* Stop drawing::
 @end menu
 
 @c ==================================================================
@@ -270,7 +281,7 @@ Sets size of arrows for @ref{1D plotting}, lines and curves (see @ref{Primitives
 @deftypefnx {Method on @code{mglGraph}} @code{void} SetMeshNum (@code{int} val)
 @deftypefnx {C function} @code{void} mgl_set_meshnum (@code{HMGL} gr, @code{int} num)
 @end ifclear
-Sets approximate number of lines in @ref{mesh}, @ref{fall}, @ref{grid} and also the number of hachures in @ref{vect}, @ref{dew} and the number of cells in @ref{cloud}. By default (=0) it draws all lines/hachures/cells.
+Sets approximate number of lines in @ref{mesh}, @ref{fall}, @ref{grid2} and also the number of hachures in @ref{vect}, @ref{dew} and the number of cells in @ref{cloud}. By default (=0) it draws all lines/hachures/cells.
 @end deftypefn
 
 @anchor{facenum}
@@ -293,7 +304,8 @@ Sets default name @var{id} as filename for saving (in FLTK window for example).
 
 @ifclear UDAV
 @deftypefn {Method on @code{mglGraph}} @code{const char *} GetPlotId ()
-@deftypefnx {C function} @code{const char *} mgl_get_plotid (@code{HMGL} gr)
+@deftypefnx {C function only} @code{const char *} mgl_get_plotid (@code{HMGL} gr)
+@deftypefnx {Fortran subroutine} @code{} mgl_get_plotid (@code{long} gr, @code{char *}out, @code{int} len)
 Gets default name @var{id} as filename for saving (in FLTK window for example).
 @end deftypefn
 @end ifclear
@@ -483,15 +495,18 @@ Sets the default rotation angle (in degrees) for masks. Note, you can use symbol
 
 @c ==================================================================
 @external{}
-@node Error handling, , Masks, Graphics setup
+@node Error handling, Stop drawing, Masks, Graphics setup
 @subsection Error handling
 @nav{}
+@ifset UDAV
+All warnings will be displayed automatically in special tool-window or in console.
+@end ifset
 @ifclear UDAV
 @cindex Message
 @cindex SetWarn
 @cindex GetWarn
 
-Normally user should set it to zero by @code{SetWarn(0);} before plotting and check if @code{GetWarn()} or @code{Message()} return non zero after plotting. Only last warning will be saved. All warnings/errors produced by MathGL is not critical -- the plot just will not be drawn.
+Normally user should set it to zero by @code{SetWarn(0);} before plotting and check if @code{GetWarn()} or @code{Message()} return non zero after plotting. Only last warning will be saved. All warnings/errors produced by MathGL is not critical -- the plot just will not be drawn. By default, all warnings are printed in stderr. You can disable it by using @code{mgl_suppress_warn(true);}.
 
 @deftypefn {Method on @code{mglGraph}} @code{void} SetWarn (@code{int} code, @code{const char *}info=@code{""})
 @deftypefnx {C function} @code{void} mgl_set_warn (@code{HMGL} gr, @code{int} code, @code{const char *}info)
@@ -499,7 +514,8 @@ Set warning code. Normally you should call this function only for clearing the w
 @end deftypefn
 
 @deftypefn {Method on @code{mglGraph}} @code{const char *}Message ()
-@deftypefnx {C function} @code{const char *}mgl_get_mess (@code{HMGL} gr)
+@deftypefnx {C function only} @code{const char *}mgl_get_mess (@code{HMGL} gr)
+@deftypefnx {Fortran subroutine} @code{} mgl_get_mess (@code{long} gr, @code{char *}out, @code{int} len)
 Return messages about matters why some plot are not drawn. If returned string is empty then there are no messages.
 @end deftypefn
 
@@ -551,6 +567,42 @@ Too long line in MGL script
 Unbalanced ' in MGL script
 @end table
 @end deftypefn
+
+@deftypefn {C function} @code{void} mgl_suppress_warn (@code{int} state)
+Disable printing warnings to @code{stderr} if @var{state} is nonzero.
+@end deftypefn
+
+@end ifclear
+
+
+@c ==================================================================
+@external{}
+@node Stop drawing, , Error handling, Graphics setup
+@subsection Stop drawing
+@nav{}
+@ifset UDAV
+You can use @ref{stop} command or press corresponding toolbutton to stop drawing and script execution.
+@end ifset
+@ifclear UDAV
+@cindex Stop
+@cindex NeedStop
+@cindex SetEventFunc
+
+@deftypefn {Method on @code{mglGraph}} @code{void} Stop (@code{bool} stop=@code{true})
+@deftypefnx {C function only} @code{void} mgl_ask_stop (@code{HMGL} gr, @code{int} stop)
+Ask to stop drawing if @var{stop} is non-zero, otherwise reset stop flag.
+@end deftypefn
+
+@deftypefn {Method on @code{mglGraph}} @code{bool} NeedStop ()
+@deftypefnx {C function only} @code{void} mgl_need_stop (@code{HMGL} gr)
+Return @code{true} if drawing should be terminated. Also it process all events in GUI. User should call this function from time to time inside a long calculation to allow processing events for GUI.
+@end deftypefn
+
+@deftypefn {Method on @code{mglGraph}} @code{bool} SetEventFunc (@code{void (*}func@code{)(void *)}, @code{void *}par=@code{NULL})
+@deftypefnx {C function only} @code{void} mgl_set_event_func (@code{HMGL} gr, @code{void (*}func@code{)(void *)}, @code{void *}par)
+Set callback function which will be called to process events of GUI library.
+@end deftypefn
+
 @end ifclear
 
 @c ==================================================================
@@ -686,7 +738,7 @@ Sets transformation formulas for curvilinear coordinate. Each string should cont
 @deftypefnx {Method on @code{mglGraph}} @code{void} SetCoor (@code{int} how)
 @deftypefnx {C function} @code{void} mgl_set_coor (@code{HMGL} gr, @code{int} how)
 @end ifclear
-Sets one of the predefined transformation formulas for curvilinear coordinate. Paramater @var{how} define the coordinates: @code{mglCartesian=0} -- Cartesian coordinates (no transformation); @code{mglPolar=1} -- Polar coordinates @math{x_n=x*cos(y),y_n=x*sin(y), z_n=z}; @code{mglSpherical=2} -- Sperical coordinates @math{x_n=x*sin(y)*cos(z), y_n=x*sin(y)*sin(z), z_n=x*cos(y)}; @code{mglParabolic=3} -- Parabolic coordinates @math{x_n=x*y, y_n=(x*x-y*y)/2, z_n=z}; @code{mglParaboloidal=4} -- Paraboloidal coordinates @math{x_n=(x*x-y*y)*cos(z)/2, y_n=(x*x-y*y)*sin(z)/2, z_n=x*y}; @code{mglOblate=5} -- Oblate coordinates @math{x_n=cosh(x)*cos(y)*cos(z), y_n=cosh(x)*cos(y)*sin(z), z_n=sinh(x)*sin(y)}; @code{mglProlate=6} -- Prolate coordinates @math{x_n=sinh(x)*sin(y)*cos(z), y_n=sinh(x)*sin(y)*sin(z), z_n=cosh(x)*cos(y)}; @code{mglElliptic=7} -- Elliptic coordinates @math{x_n=cosh(x)*cos(y), y_n=sinh(x)*sin(y), z_n=z}; @code{mglToroidal=8} -- Toroidal coordinates @math{x_n=sinh(x)*cos(z)/(cosh(x)-cos(y)), y_n=sinh(x)*sin(z)/(cosh(x)-cos(y)), z_n=sin(y)/(cosh(x)-cos(y))}; @code{mglBispherical=9} -- Bispherical coordinates @math{x_n=sin(y)*cos(z)/(cosh(x)-cos(y)), y_n=sin(y)*sin(z)/(cosh(x)-cos(y)), z_n=sinh(x)/(cosh(x)-cos(y))}; @code{mglBipolar=10} -- Bipolar coordinates @math{x_n=sinh(x)/(cosh(x)-cos(y)), y_n=sin(y)/(cosh(x)-cos(y)), z_n=z}; @code{mglLogLog=11} -- log-log coordinates @math{x_n=lg(x), y_n=lg(y), z_n=lg(z)}; @code{mglLogX=12} -- log-x coordinates @math{x_n=lg(x), y_n=y, z_n=z}; @code{mglLogY=13} -- log-y coordinates @math{x_n=x, y_n=lg(y), z_n=z}.
+Sets one of the predefined transformation formulas for curvilinear coordinate. Parameter @var{how} define the coordinates: @code{mglCartesian=0} -- Cartesian coordinates (no transformation); @code{mglPolar=1} -- Polar coordinates @math{x_n=x*cos(y),y_n=x*sin(y), z_n=z}; @code{mglSpherical=2} -- Sperical coordinates @math{x_n=x*sin(y)*cos(z), y_n=x*sin(y)*sin(z), z_n=x*cos(y)}; @code{mglParabolic=3} -- Parabolic coordinates @math{x_n=x*y, y_n=(x*x-y*y)/2, z_n=z}; @code{mglParaboloidal=4} -- Paraboloidal coordinates @math{x_n=(x*x-y*y)*cos(z)/2, y_n=(x*x-y*y)*sin(z)/2, z_n=x*y}; @code{mglOblate=5} -- Oblate coordinates @math{x_n=cosh(x)*cos(y)*cos(z), y_n=cosh(x)*cos(y)*sin(z), z_n=sinh(x)*sin(y)}; @code{mglProlate=6} -- Prolate coordinates @math{x_n=sinh(x)*sin(y)*cos(z), y_n=sinh(x)*sin(y)*sin(z), z_n=cosh(x)*cos(y)}; @code{mglElliptic=7} -- Elliptic coordinates @math{x_n=cosh(x)*cos(y), y_n=sinh(x)*sin(y), z_n=z}; @code{mglToroidal=8} -- Toroidal coordinates @math{x_n=sinh(x)*cos(z)/(cosh(x)-cos(y)), y_n=sinh(x)*sin(z)/(cosh(x)-cos(y)), z_n=sin(y)/(cosh(x)-cos(y))}; @code{mglBispherical=9} -- Bispherical coordinates @math{x_n=sin(y)*cos(z)/(cosh(x)-cos(y)), y_n=sin(y)*sin(z)/(cosh(x)-cos(y)), z_n=sinh(x)/(cosh(x)-cos(y))}; @code{mglBipolar=10} -- Bipolar coordinates @math{x_n=sinh(x)/(cosh(x)-cos(y)), y_n=sin(y)/(cosh(x)-cos(y)), z_n=z}; @code{mglLogLog=11} -- log-log coordinates @math{x_n=lg(x), y_n=lg(y), z_n=lg(z)}; @code{mglLogX=12} -- log-x coordinates @math{x_n=lg(x), y_n=y, z_n=z}; @code{mglLogY=13} -- log-y coordinates @math{x_n=x, y_n=lg(y), z_n=z}.
 @end deftypefn
 
 @anchor{ternary}
@@ -729,6 +781,7 @@ Use @code{Ternary(0)} for returning to usual axis. @sref{Ternary axis} @sref{Axi
 @cindex SetTickRotate
 @cindex SetTickSkip
 @cindex SetOriginTick
+@cindex AddTick
 @end ifclear
 
 @anchor{adjust}
@@ -749,15 +802,21 @@ Set the ticks step, number of sub-ticks and initial ticks position to be the mos
 @deftypefnx {MGL command} {} ztick @code{val [sub=0 org=nan]}
 @deftypefnx {MGL command} {} ctick @code{val [sub=0 org=nan]}
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d=@code{0}, @code{int} ns=@code{0}, @code{mreal} org=@code{NAN})
+@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d=@code{0}, @code{int} ns=@code{0}, @code{mreal} org=@code{NAN}, @code{const char *}fact=@code{""})
+@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const wchar_t *}fact)
 @deftypefnx {C function} @code{void} mgl_set_ticks (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org)
+@deftypefnx {C function} @code{void} mgl_set_ticks_fact (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const char *}fact)
+@deftypefnx {C function} @code{void} mgl_set_ticks_factw (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const wchar_t *}fact)
 @end ifclear
-Set the ticks step @var{d}, number of sub-ticks @var{ns} (used for positive @var{d}) and initial ticks position @var{org} for the axis along direction @var{dir} (use 'c' for colorbar ticks). Variable @var{d} set step for axis ticks (if positive) or it's number on the axis range (if negative). Zero value set automatic ticks. If @var{org} value is NAN then axis origin is used.
+Set the ticks step @var{d}, number of sub-ticks @var{ns} (used for positive @var{d}) and initial ticks position @var{org} for the axis along direction @var{dir} (use 'c' for colorbar ticks). Variable @var{d} set step for axis ticks (if positive) or it's number on the axis range (if negative). Zero value set automatic ticks. If @var{org} value is NAN then axis origin is used. Parameter @var{fact} set text which will be printed after tick label (like "\pi" for @var{d}=M_PI).
 @end deftypefn
 
 @deftypefn {MGL command} {} xtick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
 @deftypefnx {MGL command} {} ytick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
 @deftypefnx {MGL command} {} ztick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
+@deftypefnx {MGL command} {} xtick vdat 'lbls' [@code{add=off}]
+@deftypefnx {MGL command} {} ytick vdat 'lbls' [@code{add=off}]
+@deftypefnx {MGL command} {} ztick vdat 'lbls' [@code{add=off}]
 @ifclear UDAV
 @deftypefnx {Method on @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const char *}lbl, @code{bool} add=@code{false})
 @deftypefnx {Method on @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const wchar_t *}lbl, @code{bool} add=@code{false})
@@ -768,9 +827,18 @@ Set the ticks step @var{d}, number of sub-ticks @var{ns} (used for positive @var
 @deftypefnx {C function} @code{void} mgl_set_ticks_val (@code{HMGL} gr, @code{char} dir, @code{HCDT} val, @code{const char *}lbl, @code{bool} add)
 @deftypefnx {C function} @code{void} mgl_set_ticks_valw (@code{HMGL} gr, @code{char} dir, @code{HCDT} val, @code{const wchar_t *}lbl, @code{bool} add)
 @end ifclear
-Set the manual positions @var{val} and its labels @var{lbl} for ticks along axis @var{dir}. If array @var{val} is absent then values equidistantly distributed in interval [@var{Min}.x, @var{Max}.x] are used. Labels are separated by @samp{\n} symbol. Use @code{SetTicks()} to restore automatic ticks.
+Set the manual positions @var{val} and its labels @var{lbl} for ticks along axis @var{dir}. If array @var{val} is absent then values equidistantly distributed in x-axis range are used. Labels are separated by @samp{\n} symbol. Use @code{SetTicks()} to restore automatic ticks.
 @end deftypefn
 
+@ifclear UDAV
+@deftypefn {Method on @code{mglGraph}} @code{void} AddTick (@code{char} dir, @code{double} val, @code{const char *}lbl)
+@deftypefnx {Method on @code{mglGraph}} @code{void} AddTick (@code{char} dir, @code{double} val, @code{const wchar_t *}lbl)
+@deftypefnx {C function} @code{void} mgl_add_tick (@code{HMGL} gr, @code{char} dir, @code{double} val, @code{const char *}lbl)
+@deftypefnx {C function} @code{void} mgl_set_tickw (@code{HMGL} gr, @code{char} dir, @code{double} val, @code{const wchar_t *}lbl)
+The same as previous but add single tick label @var{lbl} at position @var{val} to the lest of existed ones.
+@end deftypefn
+@end ifclear
+
 @deftypefn {MGL command} {} xtick 'templ'
 @deftypefnx {MGL command} {} ytick 'templ'
 @deftypefnx {MGL command} {} ztick 'templ'
@@ -900,9 +968,9 @@ Puts further plotting in a @var{m}-th cell of @var{nx}*@var{ny} grid of the whol
 @item
 @samp{U} or @samp{_} -- at bottom side,
 @item
-@samp{#} -- reserve none space (use whole region for axis range).
+@samp{#} -- reserve none space (use whole region for axis range) -- axis and tick labels will be invisible by default.
 @end itemize
-From the aesthetical point of view it is not recommended to use this function with different matrices in the same frame. The position of the cell can be shifted from its default position by relative size @var{dx}, @var{dy}.
+From the aesthetical point of view it is not recommended to use this function with different matrices in the same frame. The position of the cell can be shifted from its default position by relative size @var{dx}, @var{dy}. Note, colorbar can be invisible (be out of image borders) if you set empty style @samp{}.
 @end deftypefn
 
 @anchor{multiplot}
@@ -971,7 +1039,7 @@ Puts further plotting in @var{ind}-th cell of stick with @var{num} cells. At thi
 @deftypefnx {C function} @code{void} mgl_title (@code{HMGL} gr, @code{const char *}txt, @code{const char *}stl, @code{mreal} size)
 @deftypefnx {C function} @code{void} mgl_titlew (@code{HMGL} gr, @code{const wchar_t *}txt, @code{const char *}stl, @code{mreal} size)
 @end ifclear
-Add text @var{title} for current subplot/inplot. Paramater @var{stl} can contain:
+Add text @var{title} for current subplot/inplot. Parameter @var{stl} can contain:
 @itemize @bullet
 @item
 font style (see, @ref{Font styles});
@@ -1057,7 +1125,7 @@ The function changes the scale of graphics that correspond to zoom in/out of the
 
 @c ##################################################################
 @external{}
-@node Export picture, Primitives, Subplots and rotation, MathGL core
+@node Export picture, Background, Subplots and rotation, MathGL core
 @section Export picture
 @nav{}
 @cindex SetSize
@@ -1090,7 +1158,7 @@ Gets quality of the plot: @code{MGL_DRAW_WIRE=0} -- no face drawing (fastest), @
 
 @deftypefn {Method on @code{mglGraph}} @code{void} StartGroup (const char *name)
 @deftypefnx {C function} @code{void} mgl_start_group (@code{HMGL} gr, @code{const char *}name)
-Starts group definition. Groups contain objects and other groups, they are used to select a part of a model to zoom to or to make invizible or to make semitransparent and so on.
+Starts group definition. Groups contain objects and other groups, they are used to select a part of a model to zoom to or to make invisible or to make semitransparent and so on.
 @end deftypefn
 
 @deftypefn {Method on @code{mglGraph}} @code{void} EndGroup ()
@@ -1171,7 +1239,7 @@ Exports current frame to TGA file. Parameter @var{fname} specifies the file name
 
 @deftypefn {Method on @code{mglGraph}} @code{void} WriteEPS (@code{const char *}fname, @code{const char *}descr=@code{""})
 @deftypefnx {C function} @code{void} mgl_write_eps (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
-Exports current frame to EPS file using vector representation. So it is not recommended for the export of large data plot. It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file. By default there is no description added. If file name is terminated by @samp{z} (for example, @samp{fname.eps.gz}) then file will be compressed in gzip format.
+Exports current frame to EPS file using vector representation. So it is not recommended for the export of large data plot. It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file. By default there is no description added. If file name is terminated by @samp{z} (for example, @samp{fname.eps.gz}) then file will be compressed in gzip format. Note, that EPS format don't support color interpolation, and the resulting plot will look as you use @ref{quality}=1 for plotting.
 @end deftypefn
 
 @deftypefn {Method on @code{mglGraph}} @code{void} WriteBPS (@code{const char *}fname, @code{const char *}descr=@code{""})
@@ -1181,7 +1249,7 @@ Exports current frame to EPS file using bitmap representation. Parameter @var{fn
 
 @deftypefn {Method on @code{mglGraph}} @code{void} WriteSVG (@code{const char *}fname, @code{const char *}descr=@code{""})
 @deftypefnx {C function} @code{void} mgl_write_svg (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
-Exports current frame to SVG (Scalable Vector Graphics) file using vector representation. In difference of EPS format, SVG format support transparency that allows to correctly draw semitransparent plot (like @ref{surfa}, @ref{surf3a} or @ref{cloud}). Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name). If file name is terminated by @samp{z} (for example, @samp{fname.svgz}) then file will be compressed in gzip format.
+Exports current frame to SVG (Scalable Vector Graphics) file using vector representation. In difference of EPS format, SVG format support transparency that allows to correctly draw semitransparent plot (like @ref{surfa}, @ref{surf3a} or @ref{cloud}). Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name). If file name is terminated by @samp{z} (for example, @samp{fname.svgz}) then file will be compressed in gzip format. Note, that SVG format don't support color interpolation, and the resulting plot will look as you use @ref{quality}=1 for plotting.
 @end deftypefn
 
 @deftypefn {Method on @code{mglGraph}} @code{void} WriteTEX (@code{const char *}fname, @code{const char *}descr=@code{""})
@@ -1309,6 +1377,11 @@ Deletes drawing data for frame @var{i} and shift all later frame indexes. Functi
 Reset frames counter (start it from zero).
 @end deftypefn
 
+@deftypefn {Method on @code{mglGraph}} @code{void} ClearFrame (@code{int} i)
+@deftypefnx {C function} @code{void} mgl_clear_frame (@code{HMGL} gr, @code{int} i)
+Clear list of primitives for current drawing.
+@end deftypefn
+
 @deftypefn {Method on @code{mglGraph}} @code{void} StartGIF (@code{const char *}fname, @code{int} ms=@code{100})
 @deftypefnx {C function} @code{void} mgl_start_gif (@code{HMGL} gr, @code{const char *}fname, @code{int} ms)
 Start writing frames into animated GIF file @var{fname}. Parameter @var{ms} set the delay between frames in milliseconds. You @strong{should not} change the picture size during writing the cinema. Use @code{CloseGIF()} to finalize writing. Note, that this function is disabled in OpenGL mode.
@@ -1438,11 +1511,56 @@ Receive graphical information from node @var{id} using MPI. The width and height
 
 @c ##################################################################
 @external{}
-@node Primitives, Text printing, Export picture, MathGL core
+@node Background, Primitives, Export picture, MathGL core
+@section Background
+@nav{}
+@cindex LoadBackground
+@cindex Clf
+@cindex Rasterize
+
+These functions change background image.
+
+@anchor{clf}
+@deftypefn {MGL command} {} clf ['col']
+@ifclear UDAV
+@deftypefnx {Method on @code{mglGraph}} @code{void} Clf ()
+@deftypefnx {Method on @code{mglGraph}} @code{void} Clf (@code{const char *} col)
+@deftypefnx {Method on @code{mglGraph}} @code{void} Clf (@code{char} col)
+@deftypefnx {Method on @code{mglGraph}} @code{void} Clf (@code{mreal} r, @code{mreal} g, @code{mreal} b)
+@deftypefnx {C function} @code{void} mgl_clf (@code{HMGL} gr)
+@deftypefnx {C function} @code{void} mgl_clf_str (@code{HMGL} gr, @code{const char *} col)
+@deftypefnx {C function} @code{void} mgl_clf_chr (@code{HMGL} gr, @code{char} col)
+@deftypefnx {C function} @code{void} mgl_clf_rgb (@code{HMGL} gr, @code{mreal} r, @code{mreal} g, @code{mreal} b)
+@end ifclear
+Clear the picture and fill background by specified color.
+@end deftypefn
+
+@anchor{rasterize}
+@deftypefn {MGL command} {} rasterize
+@ifclear UDAV
+@deftypefnx {Method on @code{mglGraph}} @code{void} Rasterize ()
+@deftypefnx {C function} @code{void} mgl_rasterize (@code{HMGL} gr)
+@end ifclear
+Force drawing the plot and use it as background. After it, function clear the list of primitives, like @ref{clf}. This function is useful if you want save part of plot as bitmap one (for example, large surfaces, isosurfaces or vector fields) and keep some parts as vector one (like annotation, curves, axis and so on).
+@end deftypefn
+
+@anchor{background}
+@deftypefn {MGL command} {} background 'fname' [@code{alpha=1}]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglGraph}} @code{void} LoadBackground (@code{const char *} fname, @code{double} alpha=@code{1})
+@deftypefnx {C function} @code{void} mgl_load_background (@code{HMGL} gr, @code{const char *} fname, @code{double} alpha)
+@end ifclear
+Load PNG or JPEG file @var{fname} as background for the plot. Parameter @var{alpha} manually set transparency of the background.
+@end deftypefn
+
+
+
+@c ##################################################################
+@external{}
+@node Primitives, Text printing, Background, MathGL core
 @section Primitives
 @nav{}
 @cindex Ball
-@cindex Clf
 @cindex Line
 @cindex Curve
 @cindex Glyph
@@ -1461,19 +1579,6 @@ Receive graphical information from node @var{id} using MPI. The width and height
 
 These functions draw some simple objects like line, point, sphere, drop, cone and so on. @sref{Using primitives}
 
-@anchor{clf}
-@deftypefn {MGL command} {} clf ['col']
-@ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Clf ()
-@deftypefnx {Method on @code{mglGraph}} @code{void} Clf (@code{char} col)
-@deftypefnx {Method on @code{mglGraph}} @code{void} Clf (@code{mreal} r, @code{mreal} g, @code{mreal} b)
-@deftypefnx {C function} @code{void} mgl_clf (@code{HMGL} gr)
-@deftypefnx {C function} @code{void} mgl_clf_chr (@code{HMGL} gr, @code{char} col)
-@deftypefnx {C function} @code{void} mgl_clf_rgb (@code{HMGL} gr, @code{mreal} r, @code{mreal} g, @code{mreal} b)
-@end ifclear
-Clear the picture and fill it by specified color.
-@end deftypefn
-
 @anchor{ball}
 @deftypefn {MGL command} {} ball @code{x y} ['col'='r.']
 @deftypefnx {MGL command} {} ball @code{x y z} ['col'='r.']
@@ -1640,6 +1745,37 @@ colors for filling and boundary (second one if style @samp{@@} is used, black co
 @end itemize
 @end deftypefn
 
+@anchor{arc}
+@deftypefn {MGL command} {} arc @code{x0 y0 x1 y1 a} ['col'='r']
+@deftypefnx {MGL command} {} arc @code{x0 y0 z0 x1 y1 a} ['col'='r']
+@deftypefnx {MGL command} {} arc @code{x0 y0 z0 xa ya za x1 y1 z1 a} ['col'='r']
+@ifclear UDAV
+@deftypefnx {Method on @code{mglGraph}} @code{void} Arc (@code{mglPoint} p0, @code{mglPoint} p1, @code{mreal} a, @code{const char *}col=@code{"r"})
+@deftypefnx {Method on @code{mglGraph}} @code{void} Arc (@code{mglPoint} p0, @code{mglPoint} pa, @code{mglPoint} p1, @code{mreal} a, @code{const char *}col=@code{"r"})
+@deftypefnx {C function} @code{void} mgl_arc (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} x1, @code{mreal} y1, @code{mreal} a, @code{const char *}col)
+@deftypefnx {C function} @code{void} mgl_arc_ext (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} xa, @code{mreal} ya, @code{mreal} za, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} a, @code{const char *}col)
+@end ifclear
+Draw the arc around axis @var{pa} (default is z-axis @var{pa}=@{0,0,1@}) with center at @var{p0} and starting from point @var{p1}. Parameter @var{a} set the angle of arc in degree. Parameter @var{col} may contain color of the arc and arrow style for arc edges.
+@end deftypefn
+
+@anchor{polygon}
+@deftypefn {MGL command} {} polygon @code{x0 y0 x1 y1 num} ['col'='r']
+@deftypefnx {MGL command} {} polygon @code{x0 y0 z0 x1 y1 z1 num} ['col'='r']
+@ifclear UDAV
+@deftypefnx {Method on @code{mglGraph}} @code{void} Polygon (@code{mglPoint} p0, @code{mglPoint} p1, @code{int} num, @code{const char *}col=@code{"r"})
+@deftypefnx {C function} @code{void} mgl_polygon (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{int} num, @code{const char *}col)
+@end ifclear
+Draw the polygon with @var{num} edges starting from @var{p1}. The center of polygon is located in @var{p0}. Parameter @var{col} may contain
+@itemize @bullet
+@item
+colors for filling and boundary (second one if style @samp{@@} is used, black color is used by default);
+@item
+@samp{#} for wire figure (boundary only);
+@item
+@samp{@@} for filling and boundary.
+@end itemize
+@end deftypefn
+
 @c ##################################################################
 @external{}
 @node Text printing, Axis and Colorbar, Primitives, MathGL core
@@ -1655,7 +1791,7 @@ colors for filling and boundary (second one if style @samp{@@} is used, black co
 
 These functions draw the text. There are functions for drawing text in arbitrary place, in arbitrary direction and along arbitrary curve. MathGL can use arbitrary font-faces and parse many TeX commands (for more details see @ref{Font styles}). All these functions have 2 variant: for printing 8-bit text (@code{char *}) and for printing Unicode text (@code{wchar_t *}). In first case the conversion into the current locale is used. So sometimes you need to specify it by @code{setlocale()} function. The @var{size} argument control the size of text: if positive it give the value, if negative it give the value relative to @code{SetFontSize()}. The font type (STIX, arial, courier, times and so on) can be selected by function LoadFont(). @xref{Font settings}.
 
-The font parameters are described by string. This string may set the text color @samp{wkrgbcymhRGBCYMHW} (see @ref{Color styles}). Also,  after delimiter symbol @samp{:}, it can contain characters of font type (@samp{rbiwou}) and/or align (@samp{LRC}) specification. The font types are: @samp{r} -- roman (or regular) font, @samp{i} -- italic style, @samp{b} -- bold style, @samp{w} -- wired style, @samp{o} -- over-lined text, @samp{u} -- underlined text. By default roman font is used. The align types are: @samp{L} -- align left (default), @samp{C} -- align center, @samp{R} -- align right. For example, string @samp{b:iC} correspond to italic font style for centered text which printed by blue color.
+The font parameters are described by string. This string may set the text color @samp{wkrgbcymhRGBCYMHW} (see @ref{Color styles}). Starting from MathGL v.2.3, you can set color gradient for text (see @ref{Color scheme}). Also,  after delimiter symbol @samp{:}, it can contain characters of font type (@samp{rbiwou}) and/or align (@samp{LRCT}) specification. The font types are: @samp{r} -- roman (or regular) font, @samp{i} -- italic style, @samp{b} -- bold style, @samp{w} -- wired style, @samp{o} -- over-lined text, @samp{u} -- underlined text. By default roman font is used. The align types are: @samp{L} -- align left (default), @samp{C} -- align center, @samp{R} -- align right. Style @samp{T} will position text under the specified point (like align top). For example, string @samp{b:iC} correspond to italic font style for centered text which printed by blue color.
 
 If string contains symbols @samp{aA} then text is printed at absolute position @{@var{x}, @var{y}@} (supposed to be in range [0,1]) of picture (for @samp{A}) or subplot/inplot (for @samp{a}). If string contains symbol @samp{@@} then box around text is drawn.
 
@@ -1683,7 +1819,7 @@ The function plots the string @var{text} at position @var{p} with fonts specifyi
 @deftypefnx {C function} @code{void} mgl_puts_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const char *}text, @code{const char *}fnt, @code{mreal} size)
 @deftypefnx {C function} @code{void} mgl_putsw_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const wchar_t *}text, @code{const char *}fnt, @code{mreal} size)
 @end ifclear
-The function plots the string @var{text} at position @var{p} along direction @var{d} with specified @var{size}. Parameter @var{fnt} set text style and text position: above (@samp{T}) or under (@samp{t}) the line.
+The function plots the string @var{text} at position @var{p} along direction @var{d} with specified @var{size}. Parameter @var{fnt} set text style and text position: under (@samp{T}) or above (@samp{t}) the line.
 @end deftypefn
 
 @anchor{fgets}
@@ -1709,7 +1845,7 @@ Draws unrotated @var{n}-th line of file @var{fname} at position @{@var{x},@var{y
 @deftypefnx {C function} @code{void} mgl_text_xyz (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}text, @code{const char *}fnt, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_textw_xyz (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}text, @code{const char *}fnt, @code{const char *}opt)
 @end ifclear
-The function draws @var{text} along the curve between points @{@var{x}[i], @var{y}[i], @var{z}[i]@} by font style @var{fnt}. The string @var{fnt} may contain symbols @samp{t} for printing the text under the curve (default), or @samp{T} for printing the text above the curve. The sizes of 1st dimension must be equal for all arrays @code{x.nx=y.nx=z.nx}. If array @var{x} is not specified then its an automatic array is used with values equidistantly distributed in interval [@var{Min}.x, @var{Max}.x] (see @ref{Ranges (bounding box)}). If array @var{z} is not specified then @var{z}[i] = @var{Min}.z is used. String @var{opt} contain command options (see @ref{Command options}).
+The function draws @var{text} along the curve between points @{@var{x}[i], @var{y}[i], @var{z}[i]@} by font style @var{fnt}. The string @var{fnt} may contain symbols @samp{t} for printing the text under the curve (default), or @samp{T} for printing the text under the curve. The sizes of 1st dimension must be equal for all arrays @code{x.nx=y.nx=z.nx}. If array @var{x} is not specified then its an automatic array is used with values equidistantly distributed in x-axis range (see @ref{Ranges (bounding box)}). If array @var{z} is not specified then @var{z}[i] equal to minimal z-axis value is used. String @var{opt} contain command options (see @ref{Command options}).
 @end deftypefn
 
 @c ##################################################################
@@ -1733,20 +1869,20 @@ These functions draw the ``things for measuring'', like axis with ticks, colorba
 @end ifclear
 Draws axes with ticks (see @ref{Axis settings}). Parameter @var{dir} may contain:
 @itemize @bullet
-@item
-@samp{xyz} for drawing axis in corresponding direction;
-@item
-@samp{XYZ} for drawing axis in corresponding direction but with inverted positions of labels;
-@item
-@samp{~} or @samp{_} for disabling tick labels;
-@item
-@samp{U} for disabling rotation of tick labels;
-@item
-@samp{^} for inverting default axis origin;
-@item
-@samp{AKDTVISO} for drawing arrow at the end of axis;
-@item
-@samp{a} for forced adjusting of axis ticks.
+@item @samp{xyz} for drawing axis in corresponding direction;
+@item @samp{XYZ} for drawing axis in corresponding direction but with inverted positions of labels;
+@item @samp{~} or @samp{_} for disabling tick labels;
+@item @samp{U} for disabling rotation of tick labels;
+@item @samp{^} for inverting default axis origin;
+@item @samp{!} for disabling ticks tuning (see @ref{tuneticks});
+@item @samp{AKDTVISO} for drawing arrow at the end of axis;
+@item @samp{a} for forced adjusting of axis ticks;
+@item @samp{f} for printing ticks labels in fixed format;
+@item @samp{E} for using @samp{E} instead of @samp{e} in ticks labels;
+@item @samp{F} for printing ticks labels in LaTeX format;
+@item @samp{+} for printing @samp{+} for positive ticks;
+@item @samp{-} for printing usual @samp{-} in ticks labels;
+@item @samp{0123456789} for precision at printing ticks labels.
 @end itemize
 Styles of ticks and axis can be overrided by using @var{stl} string. @sref{Axis and ticks}
 @end deftypefn
@@ -1761,14 +1897,17 @@ Draws colorbar. Parameter @var{sch} may contain:
 @itemize @bullet
 @item
 color scheme (see @ref{Color scheme});
-@item
-@samp{<>^_} for positioning at left, at right, at top or at bottom correspondingly;
-@item
-@samp{I} for positioning near bounding (by default, is positioned at edges of subplot);
-@item
-@samp{A} for using absolute coordinates;
-@item
-@samp{~} for disabling tick labels.
+@item @samp{<>^_} for positioning at left, at right, at top or at bottom correspondingly;
+@item @samp{I} for positioning near bounding (by default, is positioned at edges of subplot);
+@item @samp{A} for using absolute coordinates;
+@item @samp{~} for disabling tick labels.
+@item @samp{!} for disabling ticks tuning (see @ref{tuneticks});
+@item @samp{f} for printing ticks labels in fixed format;
+@item @samp{E} for using @samp{E} instead of @samp{e} in ticks labels;
+@item @samp{F} for printing ticks labels in LaTeX format;
+@item @samp{+} for printing @samp{+} for positive ticks;
+@item @samp{-} for printing usual @samp{-} in ticks labels;
+@item @samp{0123456789} for precision at printing ticks labels.
 @end itemize
 @sref{Colorbars}
 @end deftypefn
@@ -1803,7 +1942,7 @@ The same as previous but with sharp colors @var{sch} (current palette if @code{s
 @deftypefnx {Method on @code{mglGraph}} @code{void} Grid (@code{const char *}dir=@code{"xyz"}, @code{const char *}pen=@code{"B"}, @code{const char *}opt=@code{""})
 @deftypefnx {C function} @code{void} mgl_axis_grid (@code{HMGL} gr, @code{const char *}dir, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-Draws grid lines perpendicular to direction determined by string parameter @var{dir}. The step of grid lines is the same as tick step for @ref{axis}. The style of lines is determined by @var{pen} parameter (default value is dark blue solid line @samp{B-}).
+Draws grid lines perpendicular to direction determined by string parameter @var{dir}. If @var{dir} contain @samp{!} then grid lines will be drawn at coordinates of subticks also. The step of grid lines is the same as tick step for @ref{axis}. The style of lines is determined by @var{pen} parameter (default value is dark blue solid line @samp{B-}).
 @end deftypefn
 
 @anchor{box}
@@ -1931,7 +2070,7 @@ Set the number of marks in the legend. By default 1 mark is used.
 @cindex Label
 @cindex Cones
 
-These functions perform plotting of 1D data. 1D means that data depended from only 1 parameter like parametric curve @{x[i],y[i],z[i]@}, i=1...n. By default (if absent) values of @var{x}[i] are equidistantly distributed in axis range, and @var{z}[i]=@var{Min}.z. The plots are drawn for each row if one of the data is the matrix. By any case the sizes of 1st dimension @strong{must be equal} for all arrays @code{x.nx=y.nx=z.nx}.
+These functions perform plotting of 1D data. 1D means that data depended from only 1 parameter like parametric curve @{x[i],y[i],z[i]@}, i=1...n. By default (if absent) values of @var{x}[i] are equidistantly distributed in axis range, and @var{z}[i] equal to minimal z-axis value. The plots are drawn for each row if one of the data is the matrix. By any case the sizes of 1st dimension @strong{must be equal} for all arrays @code{x.nx=y.nx=z.nx}.
 
 String @var{pen} specifies the color and style of line and marks (see @ref{Line styles}). By default (@code{pen=""}) solid line with color from palette is used (see @ref{Palette and colors}). Symbol @samp{!} set to use new color from palette for each point (not for each curve, as default). String @var{opt} contain command options (see @ref{Command options}). @sref{1D samples}
 
@@ -2033,7 +2172,7 @@ These functions draw continuous lines between points and fills it to axis plane.
 @deftypefnx {C function} @code{void} mgl_region_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_region_3d (@code{HMGL} gr, @code{HCDT} x1, @code{HCDT} y1, @code{HCDT} z1, @code{HCDT} x2, @code{HCDT} y2, @code{HCDT} z2, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-These functions fill area between 2 curves. Dimensions of arrays @var{y1} and @var{y2} must be equal. Also you can use gradient filling if number of specified colors is equal to 2*number of curves. If @var{pen} contain symbol @samp{i} then only area with y1<y<y2 will be filled else the area with y2<y<y1 will be filled too. See also @ref{area}, @ref{bars}, @ref{stem}. @sref{Region sample}
+These functions fill area between 2 curves. Dimensions of arrays @var{y1} and @var{y2} must be equal. Also you can use gradient filling if number of specified colors is equal to 2*number of curves. If for 2D version @var{pen} contain symbol @samp{i} then only area with y1<y<y2 will be filled else the area with y2<y<y1 will be filled too. See also @ref{area}, @ref{bars}, @ref{stem}. @sref{Region sample}
 @end deftypefn
 
 @anchor{stem}
@@ -2099,7 +2238,7 @@ These functions draw cones from points to axis plane. If string contain symbol @
 @item
 @samp{t} for drawing tubes/cylinders instead of cones/prisms;
 @item
-@samp{4}, @samp{6}, @samp{8}, @samp{t} for drawing square, hex- or octo-prism instead of cones;
+@samp{4}, @samp{6}, @samp{8} for drawing square, hex- or octo-prism instead of cones;
 @item
 @samp{<}, @samp{^} or @samp{>} for aligning boxes left, right or centering them at its x-coordinates.
 @end itemize
@@ -2235,7 +2374,17 @@ These functions draw string @var{txt} as marks with size proportional to @var{r}
 @deftypefnx {C function} @code{void} mgl_label_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_labelw_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
 @end ifclear
-These functions draw string @var{txt} at points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. If string @var{txt} contain @samp{%x}, @samp{%y}, @samp{%z} or @samp{%n} then it will be replaced by the value of x-,y-,z-coordinate of the point or its index. See also @ref{plot}, @ref{mark}, @ref{textmark}, @ref{table}. @sref{Label sample}
+These functions draw string @var{txt} at points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. If string @var{txt} contain @samp{%x}, @samp{%y}, @samp{%z} or @samp{%n} then it will be replaced by the value of x-,y-,z-coordinate of the point or its index. String @var{fnt} may contain:
+@itemize
+@item @ref{Font styles};
+@item @samp{f} for fixed format of printed numbers;
+@item @samp{E} for using @samp{E} instead of @samp{e};
+@item @samp{F} for printing in LaTeX format;
+@item @samp{+} for printing @samp{+} for positive numbers;
+@item @samp{-} for printing usual @samp{-};
+@item @samp{0123456789} for precision at printing numbers.
+@end itemize
+See also @ref{plot}, @ref{mark}, @ref{textmark}, @ref{table}. @sref{Label sample}
 @end deftypefn
 
 @anchor{table}
@@ -2249,7 +2398,20 @@ These functions draw string @var{txt} at points @{@var{x}[i], @var{y}[i], @var{z
 @deftypefnx {C function} @code{void} mgl_table (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{HCDT} val, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_tablew (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{HCDT} val, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
 @end ifclear
-These functions draw table with values of @var{val} and captions from string @var{txt} (separated by newline symbol @samp{\n}) at points @{@var{x}, @var{y}@} (default at @{0,0@}) related to current subplot. If string @var{fnt} contain @samp{#} then cell border will be drawn. If string @var{fnt} contain @samp{|} then table width is limited by subplot width (equivalent option @samp{value 1}). If string @var{fnt} contain @samp{=} then widths of all cells are the same. Option @code{value} set the width of the table (default is 1). See also @ref{plot}, @ref{label}. @sref{Table sample}
+These functions draw table with values of @var{val} and captions from string @var{txt} (separated by newline symbol @samp{\n}) at points @{@var{x}, @var{y}@} (default at @{0,0@}) related to current subplot. String @var{fnt} may contain:
+@itemize
+@item @ref{Font styles};
+@item @samp{#} for drawing cell borders;
+@item @samp{|} for limiting table widh by subplot one (equal to option @samp{value 1});
+@item @samp{=} for equal width of all cells;
+@item @samp{f} for fixed format of printed numbers;
+@item @samp{E} for using @samp{E} instead of @samp{e};
+@item @samp{F} for printing in LaTeX format;
+@item @samp{+} for printing @samp{+} for positive numbers;
+@item @samp{-} for printing usual @samp{-};
+@item @samp{0123456789} for precision at printing numbers.
+@end itemize
+Option @code{value} set the width of the table (default is 1). See also @ref{plot}, @ref{label}. @sref{Table sample}
 @end deftypefn
 
 @anchor{tube}
@@ -2387,7 +2549,7 @@ The function draws horizontal tiles for surface specified parametrically @{@var{
 @deftypefnx {C function} @code{void} mgl_dens (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_dens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws density plot for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z} = @var{Min}.z. If string @var{sch} have symbol @samp{#} then grid lines are drawn. If string @var{sch} have symbol @samp{.} then plot by dots is produced. See also @ref{surf}, @ref{cont}, @ref{contf}, @ref{boxs}, @ref{tile}, @code{dens[xyz]}. @sref{Dens sample}
+The function draws density plot for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z} equal to minimal z-axis value. If string @var{sch} have symbol @samp{#} then grid lines are drawn. If string @var{sch} have symbol @samp{.} then plot by dots is produced. See also @ref{surf}, @ref{cont}, @ref{contf}, @ref{boxs}, @ref{tile}, @code{dens[xyz]}. @sref{Dens sample}
 @end deftypefn
 
 @anchor{cont}
@@ -2399,7 +2561,7 @@ The function draws density plot for surface specified parametrically @{@var{x}[i
 @deftypefnx {C function} @code{void} mgl_cont__val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_cont_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k] or at @var{z} = @var{Min}.z if @var{sch} contain symbol @samp{_}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. If string @var{sch} have symbol @samp{t} or @samp{T} then contour labels @var{v}[k] will be drawn below (or above) the contours. See also @ref{dens}, @ref{contf}, @ref{contd}, @ref{axial}, @code{cont[xyz]}. @sref{Cont sample}
+The function draws contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k], or at @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. If string @var{sch} have symbol @samp{t} or @samp{T} then contour labels @var{v}[k] will be drawn below (or above) the contours. See also @ref{dens}, @ref{contf}, @ref{contd}, @ref{axial}, @code{cont[xyz]}. @sref{Cont sample}
 @end deftypefn
 
 @deftypefn {MGL command} {} cont zdat ['sch'='']
@@ -2422,7 +2584,7 @@ The same as previous with vector @var{v} of @var{num}-th elements equidistantly
 @deftypefnx {C function} @code{void} mgl_contf_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_contf_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws solid (or filled) contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k] or at @var{z} = @var{Min}.z if @var{sch} contain symbol @samp{_}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v} (must be @code{v.nx>2}). See also @ref{dens}, @ref{cont}, @ref{contd}, @code{contf[xyz]}. @sref{ContF sample}
+The function draws solid (or filled) contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k], or at @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v} (must be @code{v.nx>2}). See also @ref{dens}, @ref{cont}, @ref{contd}, @code{contf[xyz]}. @sref{ContF sample}
 @end deftypefn
 
 @deftypefn {MGL command} {} contf zdat ['sch'='']
@@ -2445,7 +2607,7 @@ The same as previous with vector @var{v} of @var{num}-th elements equidistantly
 @deftypefnx {C function} @code{void} mgl_contd_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_contd_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws solid (or filled) contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k] (or at @var{z} = @var{Min}.z if @var{sch} contain symbol @samp{_}) with manual colors. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v} (must be @code{v.nx>2}). String @var{sch} sets the contour colors: the color of k-th contour is determined by character @code{sch[k%strlen(sch)]}. See also @ref{dens}, @ref{cont}, @ref{contf}. @sref{ContD sample}
+The function draws solid (or filled) contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k] (or at @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}) with manual colors. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v} (must be @code{v.nx>2}). String @var{sch} sets the contour colors: the color of k-th contour is determined by character @code{sch[k%strlen(sch)]}. See also @ref{dens}, @ref{cont}, @ref{contf}. @sref{ContD sample}
 @end deftypefn
 
 @deftypefn {MGL command} {} contd zdat ['sch'='']
@@ -2468,7 +2630,7 @@ The same as previous with vector @var{v} of @var{num}-th elements equidistantly
 @deftypefnx {C function} @code{void} mgl_contv_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_contv_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws vertical cylinder (tube) at contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k] or at @var{z} = @var{Min}.z if @var{sch} contain symbol @samp{_}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. See also @ref{cont}, @ref{contf}. @sref{ContV sample}
+The function draws vertical cylinder (tube) at contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k], or at @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. See also @ref{cont}, @ref{contf}. @sref{ContV sample}
 @end deftypefn
 
 @deftypefn {MGL command} {} contv zdat ['sch'='']
@@ -2514,7 +2676,7 @@ The same as previous with vector @var{v} of @var{num}-th elements equidistantly
 @deftypefnx {C function} @code{void} mgl_grid (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_grid_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws grid lines for density plot of surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z} = @var{Min}.z. See also @ref{dens}, @ref{cont}, @ref{contf}, @ref{meshnum}.
+The function draws grid lines for density plot of surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z} equal to minimal z-axis value. See also @ref{dens}, @ref{cont}, @ref{contf}, @ref{grid3}, @ref{meshnum}.
 @end deftypefn
 
 
@@ -2769,7 +2931,7 @@ The function draws mapping plot for matrices @{@var{ax}, @var{ay} @} which param
 @deftypefnx {C function} @code{void} mgl_stfa (@code{HMGL} gr, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_stfa_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Draws spectrogram of complex array @var{re}+i*@var{im} for Fourier size of @var{dn} points at plane @var{z}=@var{Min}.z. For example in 1D case, result is density plot of data @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} with size @{int(nx/dn), dn, ny@}. At this array @var{re}, @var{im} parametrically depend on coordinates @var{x}, @var{y}. The size of @var{re} and @var{im} must be the same. The minor dimensions of arrays @var{x}, @var{y}, @var{re} should be equal. Arrays @var{x}, @var{y} can be vectors (not matrix as @var{re}).  @sref{STFA sample}
+Draws spectrogram of complex array @var{re}+i*@var{im} for Fourier size of @var{dn} points at plane @var{z} equal to minimal z-axis value. For example in 1D case, result is density plot of data @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} with size @{int(nx/dn), dn, ny@}. At this array @var{re}, @var{im} parametrically depend on coordinates @var{x}, @var{y}. The size of @var{re} and @var{im} must be the same. The minor dimensions of arrays @var{x}, @var{y}, @var{re} should be equal. Arrays @var{x}, @var{y} can be vectors (not matrix as @var{re}).  @sref{STFA sample}
 @end deftypefn
 
 
@@ -2808,7 +2970,7 @@ The function draws vectors @{@var{ax}, @var{ay}, @var{az}@} along a curve @{@var
 @deftypefnx {C function} @code{void} mgl_vect_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_vect_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws plane vector field plot for the field @{@var{ax}, @var{ay}@} depending parametrically on coordinates @var{x}, @var{y} at level @var{z}=@var{Min}.z. The length and color of arrows are proportional to @math{\sqrt@{ax^2+ay^2@}}. The number of arrows depend on @ref{meshnum}. The appearance of the hachures (arrows) can be changed by symbols:
+The function draws plane vector field plot for the field @{@var{ax}, @var{ay}@} depending parametrically on coordinates @var{x}, @var{y} at level @var{z} equal to minimal z-axis value. The length and color of arrows are proportional to @math{\sqrt@{ax^2+ay^2@}}. The number of arrows depend on @ref{meshnum}. The appearance of the hachures (arrows) can be changed by symbols:
 @itemize @bullet
 @item
 @samp{f} for drawing arrows with fixed lengths,
@@ -2865,7 +3027,7 @@ See also @ref{vect}, @ref{flow}, @ref{dew}. @sref{Vect3 sample}
 @deftypefnx {C function} @code{void} mgl_dew (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_dew_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws dew-drops for plane vector field @{@var{ax}, @var{ay}@} depending parametrically on coordinates @var{x}, @var{y} at level @var{z}=@var{Min}.z. Note that this is very expensive plot in memory usage and creation time! The color of drops is proportional to @math{\sqrt@{ax^2+ay^2@}}. The number of drops depend on @ref{meshnum}. See also @ref{vect}. @sref{Dew sample}
+The function draws dew-drops for plane vector field @{@var{ax}, @var{ay}@} depending parametrically on coordinates @var{x}, @var{y} at level @var{z} equal to minimal z-axis value. Note that this is very expensive plot in memory usage and creation time! The color of drops is proportional to @math{\sqrt@{ax^2+ay^2@}}. The number of drops depend on @ref{meshnum}. See also @ref{vect}. @sref{Dew sample}
 @end deftypefn
 
 @anchor{flow}
@@ -2877,7 +3039,7 @@ The function draws dew-drops for plane vector field @{@var{ax}, @var{ay}@} depen
 @deftypefnx {C function} @code{void} mgl_flow_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_flow_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws flow threads for the plane vector field @{@var{ax}, @var{ay}@} parametrically depending on coordinates @var{x}, @var{y} at level @var{z} = @var{Min}.z. Number of threads is proportional to @code{value} option (default is 5). String @var{sch} may contain:
+The function draws flow threads for the plane vector field @{@var{ax}, @var{ay}@} parametrically depending on coordinates @var{x}, @var{y} at level @var{z} equal to minimal z-axis value. Number of threads is proportional to @code{value} option (default is 5). String @var{sch} may contain:
 @itemize @bullet
 @item
 color scheme -- up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
@@ -2948,7 +3110,7 @@ The function draws gradient lines for scalar field @var{phi}[i,j] (or @var{phi}[
 @deftypefnx {C function} @code{void} mgl_pipe_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_pipe_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
 @end ifclear
-The function draws flow pipes for the plane vector field @{@var{ax}, @var{ay}@} parametrically depending on coordinates @var{x}, @var{y} at level @var{z} = @var{Min}.z. Number of pipes is proportional to @code{value} option (default is 5). If @samp{#} symbol is specified then pipes start only from edges of axis range. The color of lines is proportional to @math{\sqrt@{ax^2+ay^2@}}. Warm color corresponds to normal flow (like attractor). Cold one corresponds to inverse flow (like source). Parameter @var{r0} set the base pipe radius. If @var{r0}<0 or symbol @samp{i} is specified then pipe radius is inverse proportional to amplitude. The vector field is plotted for each z slice of @var{ax}, @var{ay}. See also @ref{flow}, @ref{vect}. @sref{Pipe sample}
+The function draws flow pipes for the plane vector field @{@var{ax}, @var{ay}@} parametrically depending on coordinates @var{x}, @var{y} at level @var{z} equal to minimal z-axis value. Number of pipes is proportional to @code{value} option (default is 5). If @samp{#} symbol is specified then pipes start only from edges of axis range. The color of lines is proportional to @math{\sqrt@{ax^2+ay^2@}}. Warm color corresponds to normal flow (like attractor). Cold one corresponds to inverse flow (like source). Parameter @var{r0} set the base pipe radius. If @var{r0}<0 or symbol @samp{i} is specified then pipe radius is inverse proportional to amplitude. The vector field is plotted for each z slice of @var{ax}, @var{ay}. See also @ref{flow}, @ref{vect}. @sref{Pipe sample}
 @end deftypefn
 
 @deftypefn {MGL command} {} pipe udat vdat wdat ['sch'='' @code{r0=0.05}]
@@ -3054,7 +3216,7 @@ The same as previous with manual contour levels.
 @deftypefnx {Method on @code{mglGraph}} @code{void} FPlot (@code{const char *}eqY, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
 @deftypefnx {C function} @code{void} mgl_fplot (@code{HMGL} gr, @code{const char *}eqY, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-Draws command function @samp{y(x)} at plane @var{z}=@var{Min}.z where @samp{x} variable is changed in @code{xrange}. You do not need to create the data arrays to plot it. Option @code{value} set initial number of points.  See also @ref{plot}.
+Draws command function @samp{y(x)} at plane @var{z} equal to minimal z-axis value, where @samp{x} variable is changed in @code{xrange}. You do not need to create the data arrays to plot it. Option @code{value} set initial number of points.  See also @ref{plot}.
 @end deftypefn
 
 @deftypefn {MGL command} {} fplot 'x(t)' 'y(t)' 'z(t)' ['pen'='']
@@ -3111,7 +3273,7 @@ The function draws the surface of triangles. Triangle vertexes are set by indexe
 @deftypefnx {C function} @code{void} mgl_tricont_xyzcv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_tricont_xyzv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws contour lines for surface of triangles at @var{z}=@var{v}[k] (or at  @var{z} = @var{Min}.z if @var{sch} contain symbol @samp{_}). Triangle vertexes are set by indexes @var{id} of data points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. If @var{v} is absent then arrays of option @code{value} elements  equidistantly distributed in color range is used. String @var{sch} sets the color scheme. Array @var{c} (if specified) is used for contour coloring. First dimensions of @var{id} must be 3 or greater. Arrays @var{x}, @var{y}, @var{z} must have equal sizes. Parameter @var{c} set the colors of triangles (if @var{id}.ny=@var{c}.nx) or colors of vertexes (if @var{x}.nx=@var{c}.nx). See also @ref{triplot}, @ref{cont}, @ref{triangulation}.
+The function draws contour lines for surface of triangles at @var{z}=@var{v}[k] (or at  @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}). Triangle vertexes are set by indexes @var{id} of data points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. If @var{v} is absent then arrays of option @code{value} elements  equidistantly distributed in color range is used. String @var{sch} sets the color scheme. Array @var{c} (if specified) is used for contour coloring. First dimensions of @var{id} must be 3 or greater. Arrays @var{x}, @var{y}, @var{z} must have equal sizes. Parameter @var{c} set the colors of triangles (if @var{id}.ny=@var{c}.nx) or colors of vertexes (if @var{x}.nx=@var{c}.nx). See also @ref{triplot}, @ref{cont}, @ref{triangulation}.
 @end deftypefn
 
 @anchor{quadplot}
@@ -3220,7 +3382,7 @@ Fit data along x-, y- and z-directions for array specified parametrically @var{a
 @deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit3 (@code{mglData &}fit, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
 @deftypefnx {C function} @code{HMDT} mgl_fit_2 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
 @deftypefnx {C function} @code{HMDT} mgl_fit_3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
-Fit data along all directions for 2d or 3d arrays @var{a} with @var{s}=1 and @var{x}, @var{y}, @var{z} equidistantly distributed in interval [@var{Min}, @var{Max}].
+Fit data along all directions for 2d or 3d arrays @var{a} with @var{s}=1 and @var{x}, @var{y}, @var{z} equidistantly distributed in axis range.
 @end deftypefn
 @end ifclear
 
@@ -3235,7 +3397,8 @@ Print last fitted formula with found coefficients (as numbers) at position @var{
 
 @ifclear UDAV
 @deftypefn {Method on @code{mglGraph}} @code{const char *}GetFit ()
-@deftypefnx {C function} @code{const char *} mgl_get_fit (@code{HMGL} gr)
+@deftypefnx {C function only} @code{const char *} mgl_get_fit (@code{HMGL} gr)
+@deftypefnx {Fortran subroutine} @code{} mgl_get_fit (@code{long} gr, @code{char *}out, @code{int} len)
 Get last fitted formula with found coefficients (as numbers).
 @end deftypefn
 @end ifclear
index 6405d92b5155c1b36b9495f7ba4192fa1d11491a..cb5adc05872ceb52bc81fb9e19e75c0009ae665e 100644 (file)
 Основным классом MathGL является класс @strong{mglGraph}, определённый в @code{#include <mgl2/mgl.h>}. Он включает в себя множество функций для построения графиков от 1D, 2D и 3D массивов. Он также содержит функции вывода текста и построения осей координат. Есть возможность построения в произвольной системе координат, которая  задается строковыми формулами. Все графические функции используют класс mglData (см. @ref{Data processing}) для хранения массивов данных. Это позволяет легко контролировать размеры, работу с памятью и производить обработку данных. Дополнительная информация о цветах, шрифтах, вычисления формул может быть найдена в @ref{General concepts} и @ref{Other classes}.
 @end ifclear
 
+Некоторые возможности MathGL доступны только в новых версиях библиотеки. Для проверки текущей версии MathGL можно использовать следующую функцию.
+@anchor{version}
+@deftypefn {MGL command} {} version 'ver'
+@ifclear UDAV
+@deftypefnx {C function} @code{int} mgl_check_version (@code{const char *}ver)
+@end ifclear
+Возвращает ненулевое значение если версия MathGL подходит для требуемой в @var{ver}, т.е. если номер основной версии совпадает и "подверсия" больше или равна указанной в @var{ver}.
+@end deftypefn
+
 @menu
 * Constructor::
 * Graphics setup::
 * Axis settings::
 * Subplots and rotation::
 * Export picture::
+* Background::
 * Primitives::
 * Text printing::
 * Axis and Colorbar::
@@ -87,6 +97,7 @@ MGL не требует создания данного типа объекто
 * Palette and colors::
 * Masks::
 * Error handling::
+* Stop drawing::
 @end menu
 
 @c ==================================================================
@@ -261,7 +272,7 @@ MGL не требует создания данного типа объекто
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetMeshNum (@code{int} val)
 @deftypefnx {Функция С} @code{void} mgl_set_meshnum (@code{HMGL} gr, @code{int} num)
 @end ifclear
-Задает ориентировочное число линий в @ref{mesh}, @ref{fall}, @ref{grid} и число стрелок (штрихов) в @ref{vect}, @ref{dew} и число ячеек в @ref{cloud}. По умолчанию (=0) рисуются все линии, стрелки, ячейки.
+Задает ориентировочное число линий в @ref{mesh}, @ref{fall} и число стрелок (штрихов) в @ref{vect}, @ref{dew} и число ячеек в @ref{cloud}. По умолчанию (=0) рисуются все линии, стрелки, ячейки.
 @end deftypefn
 
 @anchor{facenum}
@@ -285,6 +296,7 @@ MGL не требует создания данного типа объекто
 @ifclear UDAV
 @deftypefn {Метод класса @code{mglGraph}} @code{const char *} GetPlotId ()
 @deftypefnx {Функция С} @code{const char *} mgl_get_plotid (@code{HMGL} gr)
+@deftypefnx {Fortran процедура} @code{} mgl_get_plotid (@code{long} gr, @code{char *}out, @code{int} len)
 Возвращает имя графика для сохранения в файл (например, в окне FLTK).
 @end deftypefn
 @end ifclear
@@ -467,15 +479,18 @@ MGL не требует создания данного типа объекто
 
 @c ==================================================================
 @external{}
-@node Error handling, , Masks, Graphics setup
+@node Error handling, Stop drawing , Masks, Graphics setup
 @subsection Обработка ошибок
 @nav{}
+@ifset UDAV
+Все сообщения будут выведены автоматически в специальном окне или в консоли.
+@end ifset
 @ifclear UDAV
 @cindex Message
 @cindex SetWarn
 @cindex GetWarn
 
-Обычно вы должны сбросить признак ошибки с помощью @code{SetWarn(0);} перед построением и проверить @code{GetWarnCode()} или @code{Message()} на наличие ошибок после построения. Только последнее предупреждение сохраняется. Замечу, что все предупреждения/ошибки в MathGL не являются критичными -- в худшем из вариантов соответствующий график просто не будет построен.
+Обычно вы должны сбросить признак ошибки с помощью @code{SetWarn(0);} перед построением и проверить @code{GetWarnCode()} или @code{Message()} на наличие ошибок после построения. Только последнее предупреждение сохраняется. Замечу, что все предупреждения/ошибки в MathGL не являются критичными -- в худшем из вариантов соответствующий график просто не будет построен. По умолчанию, все предупреждения выводятся в @code{stderr}. Этот вывод можно выключить вызовом @code{mgl_suppress_warn(true);}.
 
 @deftypefn {Метод класса @code{mglGraph}} @code{void} SetWarn (@code{int} code, @code{const char *}info=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_set_warn (@code{HMGL} gr, @code{int} code, @code{const char *}info)
@@ -484,6 +499,7 @@ MGL не требует создания данного типа объекто
 
 @deftypefn {Метод класса @code{mglGraph}} @code{const char *}Message ()
 @deftypefnx {Функция С} @code{const char *}mgl_get_mess (@code{HMGL} gr)
+@deftypefnx {Fortran процедура} @code{} mgl_get_mess (@code{long} gr, @code{char *}out, @code{int} len)
 Возвращает текст предупреждений о причине отсутствия графика. Если возвращаемая строка пустая, то сообщений нет.
 @end deftypefn
 
@@ -535,6 +551,42 @@ Setsize: размер(ы) равны нулю или отрицательны
 Одиночная ' в скрипте MGL
 @end table
 @end deftypefn
+
+@deftypefn {Функция С} @code{void} mgl_suppress_warn (@code{int} state)
+Выключает вывод предупреждений в @code{stderr} если @var{state} не ноль.
+@end deftypefn
+
+
+@end ifclear
+
+@c ==================================================================
+@external{}
+@node Stop drawing, , Error handling, Graphics setup
+@subsection Остановка рисования
+@nav{}
+@ifset UDAV
+Вы можете использовать команду @ref{stop} или соответствующую кнопку панели инструментов для остановки рисования и выполнения скрипта.
+@end ifset
+@ifclear UDAV
+@cindex Stop
+@cindex NeedStop
+@cindex SetEventFunc
+
+@deftypefn {Метод класса @code{mglGraph}} @code{void} Stop (@code{bool} stop=@code{true})
+@deftypefnx {C function only} @code{void} mgl_ask_stop (@code{HMGL} gr, @code{int} stop)
+Просит остановить рисование если @var{stop} не ноль, иначе сбрасывает флаг остановки.
+@end deftypefn
+
+@deftypefn {Метод класса @code{mglGraph}} @code{bool} NeedStop ()
+@deftypefnx {C function only} @code{void} mgl_need_stop (@code{HMGL} gr)
+Возвращает @code{true} если рисование должно быть остановлено. Также запускает обработку всех отложенных событий в GUI. Пользователь должен вызывать эту функцию время от времени внутри долгих вычислений для плавности отклика GUI.
+@end deftypefn
+
+@deftypefn {Метод класса @code{mglGraph}} @code{bool} SetEventFunc (@code{void (*}func@code{)(void *)}, @code{void *}par=@code{NULL})
+@deftypefnx {C function only} @code{void} mgl_set_event_func (@code{HMGL} gr, @code{void (*}func@code{)(void *)}, @code{void *}par)
+Задает функцию, которая будет вызвана для обработки событий в GUI библиотеке.
+@end deftypefn
+
 @end ifclear
 
 
@@ -712,6 +764,7 @@ Ternary -- специальный тип графика для 3 зависим
 @cindex SetTickRotate
 @cindex SetTickSkip
 @cindex SetOriginTick
+@cindex AddTick
 @end ifclear
 
 @anchor{adjust}
@@ -732,15 +785,21 @@ Ternary -- специальный тип графика для 3 зависим
 @deftypefnx {Команда MGL} {} ztick @code{val [sub=0 org=nan]}
 @deftypefnx {Команда MGL} {} ctick @code{val [sub=0 org=nan]}
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d=@code{0}, @code{int} ns=@code{0}, @code{mreal} org=@code{NAN})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d=@code{0}, @code{int} ns=@code{0}, @code{mreal} org=@code{NAN}, @code{const char *}fact=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d=@code{0}, @code{int} ns=@code{0}, @code{mreal} org=@code{NAN}, @code{const wchar_t *}fact)
 @deftypefnx {Функция С} @code{void} mgl_set_ticks (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org)
+@deftypefnx {Функция С} @code{void} mgl_set_ticks_fact (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const char *}fact)
+@deftypefnx {Функция С} @code{void} mgl_set_ticks_factw (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const wchar_t *} fact)
 @end ifclear
-Задает шаг меток осей @var{d}, число подметок @var{ns} и начальное положение меток @var{org} для оси вдоль направления @var{dir} (используйте 'c' для меток colorbar). Переменная @var{d} задает шаг меток (если положительна) или их число на оси (если отрицательна). Нулевое значение задает автоматическую расстановку меток. Если @var{org}=@code{NAN}, то используется значение из переменной @var{Org}.
+Задает шаг меток осей @var{d}, число подметок @var{ns} и начальное положение меток @var{org} для оси вдоль направления @var{dir} (используйте 'c' для меток colorbar). Переменная @var{d} задает шаг меток (если положительна) или их число на оси (если отрицательна). Нулевое значение задает автоматическую расстановку меток. Если @var{org}=@code{NAN}, то используется значение из переменной @var{Org}. Параметр @var{fact} задает текст, которые будет напечатан после метки оси (например, "\pi" для @var{d}=M_PI).
 @end deftypefn
 
 @deftypefn {Команда MGL} {} xtick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
 @deftypefnx {Команда MGL} {} ytick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
 @deftypefnx {Команда MGL} {} ztick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
+@deftypefnx {Команда MGL} {} xtick vdat 'lbls' [@code{add=off}]
+@deftypefnx {Команда MGL} {} ytick vdat 'lbls' [@code{add=off}]
+@deftypefnx {Команда MGL} {} ztick vdat 'lbls' [@code{add=off}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const char *}lbl, @code{bool} add=@code{false})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const wchar_t *}lbl, @code{bool} add=@code{false})
@@ -751,9 +810,18 @@ Ternary -- специальный тип графика для 3 зависим
 @deftypefnx {Функция С} @code{void} mgl_set_ticks_val (@code{HMGL} gr, @code{char} dir, @code{HCDT} val, @code{const char *}lbl, @code{bool} add)
 @deftypefnx {Функция С} @code{void} mgl_set_ticks_valw (@code{HMGL} gr, @code{char} dir, @code{HCDT} val, @code{const wchar_t *}lbl, @code{bool} add)
 @end ifclear
\97адаеÑ\82 Ñ\8fвное Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ @var{val} Ð¸ Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и @var{lbl} Ð´Ð»Ñ\8f Ð¼ÐµÑ\82ок Ð²Ð´Ð¾Ð»Ñ\8c Ð¾Ñ\81и @var{dir}. Ð\95Ñ\81ли Ð¼Ð°Ñ\81Ñ\81ив @var{val} Ð½Ðµ Ñ\83казан, Ñ\82о Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8eÑ\82Ñ\81Ñ\8f Ð·Ð½Ð°Ñ\87ениÑ\8f Ñ\80авно Ñ\80аÑ\81пÑ\80еделÑ\91ннÑ\8bе Ð² Ð¸Ð½Ñ\82еÑ\80вале [@var{Min}.x, @var{Max}.x]. Метки разделяются символом @samp{\n}. Используйте @code{SetTicks()} для восстановления автоматических меток.
\97адаеÑ\82 Ñ\8fвное Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ @var{val} Ð¸ Ð¿Ð¾Ð´Ð¿Ð¸Ñ\81и @var{lbl} Ð´Ð»Ñ\8f Ð¼ÐµÑ\82ок Ð²Ð´Ð¾Ð»Ñ\8c Ð¾Ñ\81и @var{dir}. Ð\95Ñ\81ли Ð¼Ð°Ñ\81Ñ\81ив @var{val} Ð½Ðµ Ñ\83казан, Ñ\82о Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8eÑ\82Ñ\81Ñ\8f Ð·Ð½Ð°Ñ\87ениÑ\8f Ñ\80авно Ñ\80аÑ\81пÑ\80еделÑ\91ннÑ\8bе Ð² Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ðµ Ð¾Ñ\81ей ÐºÐ¾Ð¾Ñ\80динаÑ\82. Метки разделяются символом @samp{\n}. Используйте @code{SetTicks()} для восстановления автоматических меток.
 @end deftypefn
 
+@ifclear UDAV
+@deftypefn {Метод класса @code{mglGraph}} @code{void} AddTick (@code{char} dir, @code{double} val, @code{const char *}lbl)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} AddTick (@code{char} dir, @code{double} val, @code{const wchar_t *}lbl)
+@deftypefnx {Функция С} @code{void} mgl_add_tick (@code{HMGL} gr, @code{char} dir, @code{double} val, @code{const char *}lbl)
+@deftypefnx {Функция С} @code{void} mgl_set_tickw (@code{HMGL} gr, @code{char} dir, @code{double} val, @code{const wchar_t *}lbl)
+Аналогично предыдущему, но добавляет одну метку оси к списку существующих меток.
+@end deftypefn
+@end ifclear
+
 @deftypefn {Команда MGL} {} xtick 'templ'
 @deftypefnx {Команда MGL} {} ytick 'templ'
 @deftypefnx {Команда MGL} {} ztick 'templ'
@@ -871,7 +939,7 @@ Ternary -- специальный тип графика для 3 зависим
 @deftypefnx {Функция С} @code{void} mgl_subplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl)
 @deftypefnx {Функция С} @code{void} mgl_subplot_d (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl, @code{mreal} dx, @code{mreal} dy)
 @end ifclear
-Помещает последующий вывод в @var{m}-ую ячейку сетки размером @var{nx}*@var{ny} от всего рисунка. Функция сбрасывает матрицу трансформации (повороты и сжатие графика) и должна вызываться первой для создания "подграфика". С эстетической точки зрения не рекомендуется вызывать эту функцию с различными (или не кратными) размерами сетки. Место для осей/colorbar резервируется только если строка @var{stl} содержит: @samp{L} или @samp{<} -- с левого края, @samp{R} или @samp{>} -- с правого края, @samp{A} или @samp{^} -- с верхнего края, @samp{U} или @samp{_} -- с нижнего края. Если строка @var{stl} содержит @samp{#}, то оси координат будут занимать все доступное пространство (место резервироваться не будет). Ячейка может быть дополнительно сдвинута относительно своего обычного положения на относительный размер @var{dx}, @var{dy}.
+Помещает последующий вывод в @var{m}-ую ячейку сетки размером @var{nx}*@var{ny} от всего рисунка. Функция сбрасывает матрицу трансформации (повороты и сжатие графика) и должна вызываться первой для создания "подграфика". С эстетической точки зрения не рекомендуется вызывать эту функцию с различными (или не кратными) размерами сетки. Место для осей/colorbar резервируется только если строка @var{stl} содержит: @samp{L} или @samp{<} -- с левого края, @samp{R} или @samp{>} -- с правого края, @samp{A} или @samp{^} -- с верхнего края, @samp{U} или @samp{_} -- с нижнего края. Если строка @var{stl} содержит @samp{#}, то оси координат будут занимать все доступное пространство (место резервироваться не будет). Ячейка может быть дополнительно сдвинута относительно своего обычного положения на относительный размер @var{dx}, @var{dy}. Отмечу, что colorbar может находиться за пределами рисунка если выбран пустой стиль @samp{}.
 @end deftypefn
 
 @anchor{multiplot}
@@ -1010,7 +1078,7 @@ Ternary -- специальный тип графика для 3 зависим
 
 @c ##################################################################
 @external{}
-@node Export picture, Primitives, Subplots and rotation, MathGL core
+@node Export picture, Background, Subplots and rotation, MathGL core
 @section Экспорт рисунка
 @nav{}
 @cindex SetSize
@@ -1124,7 +1192,7 @@ Ternary -- специальный тип графика для 3 зависим
 
 @deftypefn {Метод класса @code{mglGraph}} @code{void} WriteEPS (@code{const char *}fname, @code{const char *}descr=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_write_eps (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
-Экспортирует текущий кадр в EPS файл, используя векторное представление графика. Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если имя файла оканчивается на @samp{z} (например, @samp{fname.eps.gz}), то файл автоматически архивируется в формате gzip.
+Экспортирует текущий кадр в EPS файл, используя векторное представление графика. Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если имя файла оканчивается на @samp{z} (например, @samp{fname.eps.gz}), то файл автоматически архивируется в формате gzip. Отмечу, что формат EPS не поддерживает интерполяцию цвета, и картинка будет выглядеть как при использовании @ref{quality}=1.
 @end deftypefn
 
 @deftypefn {Метод класса @code{mglGraph}} @code{void} WriteBPS (@code{const char *}fname, @code{const char *}descr=@code{""})
@@ -1134,7 +1202,7 @@ Ternary -- специальный тип графика для 3 зависим
 
 @deftypefn {Метод класса @code{mglGraph}} @code{void} WriteSVG (@code{const char *}fname, @code{const char *}descr=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_write_svg (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
-Экспортирует текущий кадр в SVG файл, используя векторное представление графика. Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если имя файла оканчивается на @samp{z} (например, @samp{fname.svgz}), то файл автоматически архивируется в формате gzip.
+Экспортирует текущий кадр в SVG файл, используя векторное представление графика. Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если имя файла оканчивается на @samp{z} (например, @samp{fname.svgz}), то файл автоматически архивируется в формате gzip. Отмечу, что формат SVG не поддерживает интерполяцию цвета, и картинка будет выглядеть как при использовании @ref{quality}=1.
 @end deftypefn
 
 @deftypefn {Метод класса @code{mglGraph}} @code{void} WriteTEX (@code{const char *}fname, @code{const char *}descr=@code{""})
@@ -1264,6 +1332,11 @@ Ternary -- специальный тип графика для 3 зависим
 Сбрасывает счетчик кадров в 0.
 @end deftypefn
 
+@deftypefn {Метод класса @code{mglGraph}} @code{void} ClearFrame (@code{int} i)
+@deftypefnx {Функция С} @code{void} mgl_clear_frame (@code{HMGL} gr, @code{int} i)
+Очищает текущий список объектов.
+@end deftypefn
+
 @deftypefn {Метод класса @code{mglGraph}} @code{void} StartGIF (@code{const char *}fname, @code{int} ms=@code{100})
 @deftypefnx {Функция С} @code{void} mgl_start_gif (@code{HMGL} gr, @code{const char *}fname, @code{int} ms)
 Начинает запись кадров в анимированный GIF файл @var{fname}. Параметр @var{ms} задает задержку между кадрами в миллисекундах. Вы @strong{не должны} менять размер рисунка во время создания кино. Используйте CloseGIF() для завершения записи. Эта функция не работает в режиме OpenGL.
@@ -1390,13 +1463,57 @@ gr.GetBGRN(bits, len(bits));
 @end ifclear
 
 
+@c ##################################################################
+@external{}
+@node Background, Primitives, Export picture, MathGL core
+@section Фоновое изображение
+@nav{}
+@cindex LoadBackground
+@cindex Clf
+@cindex Rasterize
+
+These functions change background image.
+
+@anchor{clf}
+@deftypefn {Команда MGL} {} clf ['col']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf ()
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf (@code{const char *} col)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf (@code{char} col)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf (@code{mreal} r, @code{mreal} g, @code{mreal} b)
+@deftypefnx {Функция С} @code{void} mgl_clf (@code{HMGL} gr)
+@deftypefnx {Функция С} @code{void} mgl_clf_str (@code{HMGL} gr, @code{const char *} col)
+@deftypefnx {Функция С} @code{void} mgl_clf_chr (@code{HMGL} gr, @code{char} col)
+@deftypefnx {Функция С} @code{void} mgl_clf_rgb (@code{HMGL} gr, @code{mreal} r, @code{mreal} g, @code{mreal} b)
+@end ifclear
+Очищает рисунок и заполняет фон заданным цветом.
+@end deftypefn
+
+@anchor{rasterize}
+@deftypefn {Команда MGL} {} rasterize
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Rasterize ()
+@deftypefnx {Функция С} @code{void} mgl_rasterize (@code{HMGL} gr)
+@end ifclear
+Завершает рисование графика и помещает результат в качестве фона. После этого, очищает список примитивов (как @ref{clf}). Функция полезна для сохранения части графика (например, поверхностей или векторных полей) в растровом виде, а другой части (кривых, осей и пр.) в векторном.
+@end deftypefn
+
+@anchor{background}
+@deftypefn {Команда MGL} {} background 'fname' [@code{alpha=1}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} LoadBackground (@code{const char *} fname, @code{double} alpha=@code{1})
+@deftypefnx {Функция С} @code{void} mgl_load_background (@code{HMGL} gr, @code{const char *} fname, @code{double} alpha)
+@end ifclear
+Загружает PNG или JPEG файл @var{fname} в качестве фона для графика. Параметр @var{alpha} задает прозрачность фона вручную.
+@end deftypefn
+
+
 @c ##################################################################
 @external{}
 @node Primitives, Text printing, Export picture, MathGL core
 @section Рисование примитивов
 @nav{}
 @cindex Ball
-@cindex Clf
 @cindex Line
 @cindex Curve
 @cindex Glyph
@@ -1415,19 +1532,6 @@ gr.GetBGRN(bits, len(bits));
 
 Эти функции рисуют рисуют простые объекты типа линий, точек, сфер, капель, конусов, и т.д.
 
-@anchor{clf}
-@deftypefn {Команда MGL} {} clf ['col']
-@ifclear UDAV
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf ()
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf (@code{char} col)
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf (@code{mreal} r, @code{mreal} g, @code{mreal} b)
-@deftypefnx {Функция С} @code{void} mgl_clf (@code{HMGL} gr)
-@deftypefnx {Функция С} @code{void} mgl_clf_chr (@code{HMGL} gr, @code{char} col)
-@deftypefnx {Функция С} @code{void} mgl_clf_rgb (@code{HMGL} gr, @code{mreal} r, @code{mreal} g, @code{mreal} b)
-@end ifclear
-Очищает рисунок и заполняет его заданным цветом.
-@end deftypefn
-
 @anchor{ball}
 @deftypefn {Команда MGL} {} ball @code{x y} ['col'='r.']
 @deftypefnx {Команда MGL} {} ball @code{x y z} ['col'='r.']
@@ -1571,6 +1675,30 @@ gr.GetBGRN(bits, len(bits));
 Рисует ромб ширины @var{r} с вершинами в точках @var{p1}, @var{p2} цветом @var{stl}. Если @var{col} содержит: @samp{#} то рисуется только граница, @samp{@@} то рисуется граница (вторым цветом из @var{col} или черными). Если @var{col} содержит 3 цвета, то используется градиентная заливка.
 @end deftypefn
 
+@anchor{arc}
+@deftypefn {MGL command} {} arc @code{x0 y0 x1 y1 a} ['col'='r']
+@deftypefnx {MGL command} {} arc @code{x0 y0 z0 x1 y1 a} ['col'='r']
+@deftypefnx {MGL command} {} arc @code{x0 y0 z0 xa ya za x1 y1 z1 a} ['col'='r']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Arc (@code{mglPoint} p0, @code{mglPoint} p1, @code{mreal} a, @code{const char *}col=@code{"r"})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Arc (@code{mglPoint} p0, @code{mglPoint} pa, @code{mglPoint} p1, @code{mreal} a, @code{const char *}col=@code{"r"})
+@deftypefnx {C function} @code{void} mgl_arc (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} x1, @code{mreal} y1, @code{mreal} a, @code{const char *}col)
+@deftypefnx {C function} @code{void} mgl_arc_ext (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} xa, @code{mreal} ya, @code{mreal} za, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} a, @code{const char *}col)
+@end ifclear
+Рисует дугу вокруг оси @var{pa} (по умолчанию вокруг оси z @var{pa}=@{0,0,1@}) с центром в @var{p0}, начиная с точки @var{p1}. Параметр @var{a} задает угол дуги в градусах. Строка @var{col} задает цвет дуги и тип стрелок на краях.
+@end deftypefn
+
+@anchor{polygon}
+@deftypefn {MGL command} {} polygon @code{x0 y0 x1 y1 num} ['col'='r']
+@deftypefnx {MGL command} {} polygon @code{x0 y0 z0 x1 y1 z1 num} ['col'='r']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Polygon (@code{mglPoint} p0, @code{mglPoint} p1, @code{int} num, @code{const char *}col=@code{"r"})
+@deftypefnx {C function} @code{void} mgl_polygon (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{int} num, @code{const char *}col)
+@end ifclear
+Рисует правильный @var{num}-угольник с центром в @var{p0} с первой вершиной в @var{p1} цветом @var{col}. Если @var{col} содержит: @samp{#} то рисуется только граница, @samp{@@} то рисуется граница (вторым цветом из @var{col} или черными).
+@c Если @var{col} содержит 3 цвета, то используется градиентная заливка.
+@end deftypefn
+
 @c ##################################################################
 @external{}
 @node Text printing, Axis and Colorbar, Primitives, MathGL core
@@ -1585,7 +1713,7 @@ gr.GetBGRN(bits, len(bits));
 
 Функции для вывода текста позволяют вывести строку текста в произвольном месте рисунка, в произвольном направлении и вдоль произвольной кривой. MathGL позволяет использовать произвольное начертание шрифта и многие ТеХ-ие команды (детальнее см. @ref{Font styles}). Все функции вывода текста имеют варианты для 8-bit строк (@code{char *}) и для Unicode строк (@code{wchar_t *}). В первом случае используется конверсия из текущей локали, т.е. иногда вам требуется явно указать локаль с помощью функции @code{setlocale()}. Аргумент @var{size} определяет размер текста: размер шрифта если положителен или относительный размер (=-@var{size}*@code{SetFontSize()}) если отрицателен. Начертание шрифта (STIX, arial, courier, times и др.) можно изменить с помощью функции LoadFont(). @xref{Font settings}.
 
-Параметры шрифта задаются строкой, которая может содержать символы цвета @samp{wkrgbcymhRGBCYMHW} (см. @ref{Color styles}). Также после символа @samp{:} можно указать  символы стиля (@samp{rbiwou}) и/или выравнивания (@samp{LRC}). Стили шрифта: @samp{r} -- прямой, @samp{i} -- курсив, @samp{b} -- жирный, @samp{w} -- контурный, @samp{o} -- надчеркнутый, @samp{u} -- подчеркнутый. По умолчанию используется прямой шрифт. Типы выравнивания: @samp{L} -- по левому краю (по умолчанию), @samp{C} -- по центру, @samp{R} -- по правому краю. Например, строка @samp{b:iC} соответствует курсиву синего цвета с выравниванием по центру.
+Параметры шрифта задаются строкой, которая может содержать символы цвета @samp{wkrgbcymhRGBCYMHW} (см. @ref{Color styles}). Также после символа @samp{:} можно указать  символы стиля (@samp{rbiwou}) и/или выравнивания (@samp{LRCT}). Стили шрифта: @samp{r} -- прямой, @samp{i} -- курсив, @samp{b} -- жирный, @samp{w} -- контурный, @samp{o} -- надчеркнутый, @samp{u} -- подчеркнутый. По умолчанию используется прямой шрифт. Типы выравнивания: @samp{L} -- по левому краю (по умолчанию), @samp{C} -- по центру, @samp{R} -- по правому краю.  Стиль @samp{T} выведет текст под указанной точкой (как "выравнивание по верху"). Например, строка @samp{b:iC} соответствует курсиву синего цвета с выравниванием по центру. Начиная с MathGL версии 2.3, вы можете задать цветовой градиент для выводимой строки (см. @ref{Color scheme}).
 
 Если строка содержит символы @samp{aA}, то текст выводится в абсолютных координатах (полагаются в диапазоне [0,1]). При этом используются координаты относительно рисунка (если указано @samp{A}) или относительно последнего subplot/inplot (если указано @samp{a}). Если строка содержит символ @samp{@@}, то вокруг текста рисуется прямоугольник.
 
@@ -1613,7 +1741,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_puts_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const char *}text, @code{const char *}fnt, @code{mreal} size)
 @deftypefnx {Функция С} @code{void} mgl_putsw_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const wchar_t *}text, @code{const char *}fnt, @code{mreal} size)
 @end ifclear
\92Ñ\8bводиÑ\82 Ñ\81Ñ\82Ñ\80окÑ\83 @var{text} Ð¾Ñ\82 Ñ\82оÑ\87ки @var{p} Ð²Ð´Ð¾Ð»Ñ\8c Ð½Ð°Ð¿Ñ\80авлениÑ\8f @var{d}. Ð\9fаÑ\80амеÑ\82Ñ\80 @var{fnt} Ð·Ð°Ð´Ð°ÐµÑ\82 Ñ\81Ñ\82илÑ\8c Ñ\82екÑ\81Ñ\82а Ð¸ Ñ\83казÑ\8bваеÑ\82 Ð²Ñ\8bводиÑ\82Ñ\8c Ñ\82екÑ\81Ñ\82 Ð½Ð°Ð´ Ð»Ð¸Ð½Ð¸ÐµÐ¹ (@samp{T}) Ð¸Ð»Ð¸ Ð¿Ð¾д ней (@samp{t}).
\92Ñ\8bводиÑ\82 Ñ\81Ñ\82Ñ\80окÑ\83 @var{text} Ð¾Ñ\82 Ñ\82оÑ\87ки @var{p} Ð²Ð´Ð¾Ð»Ñ\8c Ð½Ð°Ð¿Ñ\80авлениÑ\8f @var{d}. Ð\9fаÑ\80амеÑ\82Ñ\80 @var{fnt} Ð·Ð°Ð´Ð°ÐµÑ\82 Ñ\81Ñ\82илÑ\8c Ñ\82екÑ\81Ñ\82а Ð¸ Ñ\83казÑ\8bваеÑ\82 Ð²Ñ\8bводиÑ\82Ñ\8c Ñ\82екÑ\81Ñ\82 Ð¿Ð¾Ð´ Ð»Ð¸Ð½Ð¸ÐµÐ¹ (@samp{T}) Ð¸Ð»Ð¸ Ð½Ð°д ней (@samp{t}).
 @end deftypefn
 
 @anchor{fgets}
@@ -1639,7 +1767,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_text_xyz (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}text, @code{const char *}fnt, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_textw_xyz (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}text, @code{const char *}fnt, @code{const char *}opt)
 @end ifclear
\92Ñ\8bводиÑ\82 Ñ\81Ñ\82Ñ\80окÑ\83 @var{text} Ð²Ð´Ð¾Ð»Ñ\8c ÐºÑ\80ивой @{@var{x}[i], @var{y}[i], @var{z}[i]@} Ñ\88Ñ\80иÑ\84Ñ\82ом @var{fnt}. Ð¡Ñ\82Ñ\80ока @var{fnt} Ð¼Ð¾Ð¶ÐµÑ\82 Ñ\81одеÑ\80жаÑ\82Ñ\8c Ñ\81имволÑ\8b: @samp{t} Ð´Ð»Ñ\8f Ð²Ñ\8bвода Ñ\82екÑ\81Ñ\82а Ð¿Ð¾Ð´ ÐºÑ\80ивой (по Ñ\83молÑ\87аниÑ\8e), Ð¸Ð»Ð¸ @samp{T} Ð´Ð»Ñ\8f Ð²Ñ\8bвода Ñ\82екÑ\81Ñ\82а Ð½Ð°Ð´ ÐºÑ\80ивой. Ð Ð°Ð·Ð¼ÐµÑ\80Ñ\8b Ð¿Ð¾ 1-ой Ñ\80азмеÑ\80ноÑ\81Ñ\82и Ð´Ð¾Ð»Ð¶Ð½Ñ\8b Ð±Ñ\8bÑ\82Ñ\8c Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ\8b Ð´Ð»Ñ\8f Ð²Ñ\81еÑ\85 Ð¼Ð°Ñ\81Ñ\81ивов @code{x.nx=y.nx=z.nx}. Ð\95Ñ\81ли Ð¼Ð°Ñ\81Ñ\81ив @var{x} Ð½Ðµ Ñ\83казан, Ñ\82о Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f "авÑ\82омаÑ\82иÑ\87еÑ\81кий" Ð¼Ð°Ñ\81Ñ\81ив Ñ\81о Ð·Ð½Ð°Ñ\87ениÑ\8fми Ð² Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ðµ [@var{Min}.x, @var{Max}.x] (Ñ\81м. @ref{Ranges (bounding box)}). Ð\95Ñ\81ли Ð¼Ð°Ñ\81Ñ\81ив @var{z} Ð½Ðµ Ñ\83казан, Ñ\82о Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f @var{z}[i] = @var{Min}.z. Строка @var{opt} содержит опции команды (см. @ref{Command options}).
\92Ñ\8bводиÑ\82 Ñ\81Ñ\82Ñ\80окÑ\83 @var{text} Ð²Ð´Ð¾Ð»Ñ\8c ÐºÑ\80ивой @{@var{x}[i], @var{y}[i], @var{z}[i]@} Ñ\88Ñ\80иÑ\84Ñ\82ом @var{fnt}. Ð¡Ñ\82Ñ\80ока @var{fnt} Ð¼Ð¾Ð¶ÐµÑ\82 Ñ\81одеÑ\80жаÑ\82Ñ\8c Ñ\81имволÑ\8b: @samp{t} Ð´Ð»Ñ\8f Ð²Ñ\8bвода Ñ\82екÑ\81Ñ\82а Ð¿Ð¾Ð´ ÐºÑ\80ивой (по Ñ\83молÑ\87аниÑ\8e), Ð¸Ð»Ð¸ @samp{T} Ð´Ð»Ñ\8f Ð²Ñ\8bвода Ñ\82екÑ\81Ñ\82а Ð¿Ð¾Ð´ ÐºÑ\80ивой. Ð Ð°Ð·Ð¼ÐµÑ\80Ñ\8b Ð¿Ð¾ 1-ой Ñ\80азмеÑ\80ноÑ\81Ñ\82и Ð´Ð¾Ð»Ð¶Ð½Ñ\8b Ð±Ñ\8bÑ\82Ñ\8c Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ\8b Ð´Ð»Ñ\8f Ð²Ñ\81еÑ\85 Ð¼Ð°Ñ\81Ñ\81ивов @code{x.nx=y.nx=z.nx}. Ð\95Ñ\81ли Ð¼Ð°Ñ\81Ñ\81ив @var{x} Ð½Ðµ Ñ\83казан, Ñ\82о Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f "авÑ\82омаÑ\82иÑ\87еÑ\81кий" Ð¼Ð°Ñ\81Ñ\81ив Ñ\81о Ð·Ð½Ð°Ñ\87ениÑ\8fми Ð² Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ðµ Ð¾Ñ\81ей ÐºÐ¾Ð¾Ñ\80динаÑ\82 (Ñ\81м. @ref{Ranges (bounding box)}). Ð\95Ñ\81ли Ð¼Ð°Ñ\81Ñ\81ив @var{z} Ð½Ðµ Ñ\83казан, Ñ\82о Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»Ñ\8cное Ð·Ð½Ð°Ñ\87ение Ð¾Ñ\81и z. Строка @var{opt} содержит опции команды (см. @ref{Command options}).
 @end deftypefn
 
 @c ##################################################################
@@ -1661,7 +1789,24 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Axis (@code{const char *}dir=@code{"xyz"}, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_axis (@code{HMGL} gr, @code{const char *}dir, @code{const char *}stl, @code{const char *}opt)
 @end ifclear
-Рисует оси координат и метки на них (см. @ref{Axis settings}) в направлениях @samp{xyz}, указанных строкой @var{dir}. Заглавные буквы @samp{XYZ} приведут к расположению меток с другой стороны от оси. Если строка содержит символ @samp{~} или @samp{_}, то подписи меток отображаться не будут. Если строка содержит символ @samp{^}, то инвертируется положение осей по умолчанию. Если строка содержит символ @samp{AKDTVISO}, то будет нарисована соответствующая стрелка на конце оси. Стиль меток и оси(ей) задается строкой @var{stl}. @sref{Axis and ticks}
+Рисует оси координат и метки на них (см. @ref{Axis settings}) в направлениях @samp{xyz}, указанных строкой @var{dir}. Строка @var{dir} может содержать:
+@itemize
+@item @samp{xyz} для рисования соответствующих осей;
+@item @samp{XYZ} для рисования соответствующих осей с метками с другой стороны;
+@item @samp{~} или @samp{_} для осей без подписей;
+@item @samp{U} для невращаемых подписей;
+@item @samp{^} для инвертирования положения по умолчанию;
+@item @samp{!} для отключения улучшения вида меток (см. @ref{tuneticks});
+@item @samp{AKDTVISO} для вывода стрелки на конце оси;
+@item @samp{a} для принудительной автоматической расстановки меток;
+@item @samp{f} для вывода чисел в фиксированном формате;
+@item @samp{E} для вывода @samp{E} вместо @samp{e};
+@item @samp{F} для вывода в формате LaTeX;
+@item @samp{+} для вывода @samp{+} для положительных чисел;
+@item @samp{-} для вывода обычного @samp{-};
+@item @samp{0123456789} для задания точности при выводе чисел.
+@end itemize
+Стиль меток и оси(ей) задается строкой @var{stl}. @sref{Axis and ticks}
 @end deftypefn
 
 @anchor{colorbar}
@@ -1670,7 +1815,22 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Colorbar (@code{const char *}sch=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_colorbar (@code{HMGL} gr, @code{const char *}sch)
 @end ifclear
-Рисует полосу соответствия цвета и числовых значений (colorbar) для цветовой схемы @var{sch} (используется текущая для @code{sch=""}) с краю от графика. Если строка @var{sch} содержит @samp{<>^_}, то положение выбирается: @samp{>} -- справа, @samp{<} -- слева, @samp{^} -- сверху, @samp{_} -- снизу. Если строка содержит @samp{A}, то используются абсолютные координаты (относительно рисунка). Если строка содержит @samp{~}, то подписи меток не рисуются. @sref{Colorbars}
+Рисует полосу соответствия цвета и числовых значений (colorbar) для цветовой схемы @var{sch} (используется текущая для @code{sch=""}) с краю от графика. Строка @var{sch} также может содержать:
+@itemize
+@item @samp{<>^_} для расположения слева, справа, сверху или снизу соответственно;
+@item @samp{I} для расположения около осей (по умолчанию, на краях subplot);
+@item @samp{A} для использования абсолютных координат (относительно рисунка);
+@item @samp{~} для colorbar без подписей;
+@item @samp{!} для отключения улучшения вида меток (см. @ref{tuneticks});
+@item @samp{a} для принудительной автоматической расстановки меток;
+@item @samp{f} для вывода чисел в фиксированном формате;
+@item @samp{E} для вывода @samp{E} вместо @samp{e};
+@item @samp{F} для вывода в формате LaTeX;
+@item @samp{+} для вывода @samp{+} для положительных чисел;
+@item @samp{-} для вывода обычного @samp{-};
+@item @samp{0123456789} для задания точности при выводе чисел.
+@end itemize
+@sref{Colorbars}
 @end deftypefn
 
 @deftypefn {Команда MGL} {} colorbar vdat ['sch'='']
@@ -1703,7 +1863,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid (@code{const char *}dir=@code{"xyz"}, @code{const char *}pen=@code{"B"}, @code{const char *}opt=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_axis_grid (@code{HMGL} gr, @code{const char *}dir, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-Рисует линии сетки в направлениях перпендикулярным @var{dir}. Шаг сетки такой же как у меток осей координат. Стиль линий задается параметром @var{pen} (по умолчанию -- сплошная темно синяя линия @samp{B-}).
+РиÑ\81Ñ\83еÑ\82 Ð»Ð¸Ð½Ð¸Ð¸ Ñ\81еÑ\82ки Ð² Ð½Ð°Ð¿Ñ\80авлениÑ\8fÑ\85 Ð¿ÐµÑ\80пендикÑ\83лÑ\8fÑ\80нÑ\8bм @var{dir}. Ð\95Ñ\81ли @var{dir} Ñ\81одеÑ\80жиÑ\82 @samp{!}, Ñ\82о Ð»Ð¸Ð½Ð¸Ð¸ Ñ\80иÑ\81Ñ\83Ñ\8eÑ\82Ñ\81Ñ\8f Ñ\82акже Ð¸ Ð´Ð»Ñ\8f ÐºÐ¾Ð¾Ñ\80динаÑ\82 Ð¿Ð¾Ð´-меÑ\82ок. Ð¨Ð°Ð³ Ñ\81еÑ\82ки Ñ\82акой Ð¶Ðµ ÐºÐ°Ðº Ñ\83 Ð¼ÐµÑ\82ок Ð¾Ñ\81ей ÐºÐ¾Ð¾Ñ\80динаÑ\82. Ð¡Ñ\82илÑ\8c Ð»Ð¸Ð½Ð¸Ð¹ Ð·Ð°Ð´Ð°ÐµÑ\82Ñ\81Ñ\8f Ð¿Ð°Ñ\80амеÑ\82Ñ\80ом @var{pen} (по Ñ\83молÑ\87аниÑ\8e -- Ñ\81плоÑ\88наÑ\8f Ñ\82емно Ñ\81инÑ\8fÑ\8f Ð»Ð¸Ð½Ð¸Ñ\8f @samp{B-}).
 @end deftypefn
 
 @anchor{box}
@@ -1818,7 +1978,7 @@ gr.GetBGRN(bits, len(bits));
 @cindex Label
 @cindex Cones
 
-Эти функции строят графики для одномерных (1D) массивов. Одномерными считаются массивы, зависящие только от одного параметра (индекса) подобно кривой в параметрической форме @{x(i),y(i),z(i)@}, i=1...n. По умолчанию (если отсутствуют) значения @var{x}[i] равно распределены в диапазоне оси х, и @var{z}[i]=@var{Min}.z. Графики рисуются для каждой строки массива данных если он двумерный. Размер по 1-ой координате @strong{должен быть одинаков} для всех массивов @code{x.nx=y.nx=z.nx}.
+Эти функции строят графики для одномерных (1D) массивов. Одномерными считаются массивы, зависящие только от одного параметра (индекса) подобно кривой в параметрической форме @{x(i),y(i),z(i)@}, i=1...n. По умолчанию (если отсутствуют) значения @var{x}[i] равно распределены в диапазоне оси х, и @var{z}[i] равно минимальному значению оси z. Графики рисуются для каждой строки массива данных если он двумерный. Размер по 1-ой координате @strong{должен быть одинаков} для всех массивов @code{x.nx=y.nx=z.nx}.
 
 Строка @var{pen} задает цвет и стиль линии и маркеров (см. @ref{Line styles}). По умолчанию (@code{pen=""}) рисуется сплошная линия с текущим цветом из палитры (см. @ref{Palette and colors}). Символ @samp{!} в строке задает использование нового цвета из палитры для каждой точки данных (не для всей кривой, как по умолчанию). Строка @var{opt} задает опции графика (см. @ref{Command options}). @sref{1D samples}
 
@@ -1920,7 +2080,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_region_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_region_3d (@code{HMGL} gr, @code{HCDT} x1, @code{HCDT} y1, @code{HCDT} z1, @code{HCDT} x2, @code{HCDT} y2, @code{HCDT} z2, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-Функции закрашивают область между 2 кривыми. Градиентная заливка используется если число цветов равно удвоенному число кривых. Если @var{pen} содержит @samp{i}, то закрашивается только область y1<y<y2, в противном случае будет закрашена и область y2<y<y1. См. также @ref{area}, @ref{bars}, @ref{stem}. @sref{Region sample}
+Функции закрашивают область между 2 кривыми. Градиентная заливка используется если число цветов равно удвоенному число кривых. Если в 2d версии @var{pen} содержит @samp{i}, то закрашивается только область y1<y<y2, в противном случае будет закрашена и область y2<y<y1. См. также @ref{area}, @ref{bars}, @ref{stem}. @sref{Region sample}
 @end deftypefn
 
 @anchor{stem}
@@ -1986,7 +2146,7 @@ gr.GetBGRN(bits, len(bits));
 @item
 @samp{t} для рисования цилиндра вместо конуса/призмы;
 @item
-@samp{4}, @samp{6}, @samp{8}, @samp{t} для рисования квадратной, шестиугольной или восьмиугольной призмы вместо конуса;
+@samp{4}, @samp{6}, @samp{8} для рисования квадратной, шестиугольной или восьмиугольной призмы вместо конуса;
 @item
 @samp{<}, @samp{^} или @samp{>} для выравнивания конусов влево, вправо или по центру относительно их координат.
 @end itemize
@@ -2013,7 +2173,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_boxplot (@code{HMGL} gr, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_boxplot_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-Функции рисуют boxplot (называемый также как box-and-whisker diagram или как "ящик с усами") в точках @var{x}[i] на плоскости @var{z} = @var{zVal} (по умолчанию @var{z}=@var{Min.z}). Это график, компактно изображающий распределение вероятностей @var{a}[i,j] (минимум, нижний квартиль (Q1), медиана (Q2), верхний квартиль (Q3) и максимум) вдоль второго (j-го) направления. Если @var{pen} содержит @samp{<}, @samp{^} или @samp{>}, то полоски будут выровнены влево, вправо или центрированы относительно их координат. См. также @ref{plot}, @ref{error}, @ref{bars}, @ref{barwidth}. @sref{BoxPlot sample}
+Функции рисуют boxplot (называемый также как box-and-whisker diagram или как "ящик с усами") в точках @var{x}[i] на плоскости @var{z} = @var{zVal} (по умолчанию @var{z} равно минимальному значению оси z). Это график, компактно изображающий распределение вероятностей @var{a}[i,j] (минимум, нижний квартиль (Q1), медиана (Q2), верхний квартиль (Q3) и максимум) вдоль второго (j-го) направления. Если @var{pen} содержит @samp{<}, @samp{^} или @samp{>}, то полоски будут выровнены влево, вправо или центрированы относительно их координат. См. также @ref{plot}, @ref{error}, @ref{bars}, @ref{barwidth}. @sref{BoxPlot sample}
 @end deftypefn
 
 @anchor{candle}
@@ -2060,7 +2220,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_error_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_error_exy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ex, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-Функции рисуют размер ошибки @{@var{ex}[i], @var{ey}[i]@} в точках @{@var{x}[i], @var{y}[i]@} на плоскости @var{z} = @var{zVal} (по умолчанию @var{z}=@var{Min.z}). Такой график полезен для отображения ошибки эксперимента, вычислений и пр. Если @var{pen} содержит @samp{@@}, то будут использованы большие полупрозрачные маркеры. См. также @ref{plot}, @ref{mark}. @sref{Error sample}
+Функции рисуют размер ошибки @{@var{ex}[i], @var{ey}[i]@} в точках @{@var{x}[i], @var{y}[i]@} на плоскости @var{z} = @var{zVal} (по умолчанию @var{z} равно минимальному значению оси z). Такой график полезен для отображения ошибки эксперимента, вычислений и пр. Если @var{pen} содержит @samp{@@}, то будут использованы большие полупрозрачные маркеры. См. также @ref{plot}, @ref{mark}. @sref{Error sample}
 @end deftypefn
 
 @anchor{mark}
@@ -2122,7 +2282,17 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_label_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_labelw_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
 @end ifclear
-Функции выводят текстовую строку @var{txt} в точках @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Если строка @var{txt} содержит @samp{%x}, @samp{%y}, @samp{%z} или @samp{%n}, то они будут заменены на значения соответствующих координат или на номер точки. См. также @ref{plot}, @ref{mark}, @ref{textmark}, @ref{table}. @sref{Label sample}
+Функции выводят текстовую строку @var{txt} в точках @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Если строка @var{txt} содержит @samp{%x}, @samp{%y}, @samp{%z} или @samp{%n}, то они будут заменены на значения соответствующих координат или на номер точки. Строка @var{fnt} может содержать:
+@itemize
+@item @ref{Font styles};
+@item @samp{f} для вывода чисел в фиксированном формате;
+@item @samp{E} для вывода @samp{E} вместо @samp{e};
+@item @samp{F} для вывода в формате LaTeX;
+@item @samp{+} для вывода @samp{+} для положительных чисел;
+@item @samp{-} для вывода обычного @samp{-};
+@item @samp{0123456789} для задания точности при выводе чисел.
+@end itemize
+См. также @ref{plot}, @ref{mark}, @ref{textmark}, @ref{table}. @sref{Label sample}
 @end deftypefn
 
 @anchor{table}
@@ -2136,7 +2306,20 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_table (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{HCDT} val, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_tablew (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{HCDT} val, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
 @end ifclear
-Рисует таблицу значений массива @var{val} с заголовками @var{txt} (разделенными символом новой строки @samp{\n}) в точке @{@var{x}, @var{y}@} (по умолчанию @{0,0@}) относительно текущего subplot. Если строка @var{fnt} содержит @samp{#}, то рисуются границы ячеек. Если строка @var{fnt} содержит @samp{=}, то ширина всех ячеек одинакова. Если строка @var{fnt} содержит @samp{|}, то ширина таблицы ограничена шириной subplot (эквивалентно опции @samp{value 1}). Опция @code{value} задает ширину таблицы (по умолчанию 1). См. также @ref{label}. @sref{Table sample}
+Рисует таблицу значений массива @var{val} с заголовками @var{txt} (разделенными символом новой строки @samp{\n}) в точке @{@var{x}, @var{y}@} (по умолчанию @{0,0@}) относительно текущего subplot. Строка @var{fnt} может содержать:
+@itemize
+@item @ref{Font styles};
+@item @samp{#} для рисования границ ячеек;
+@item @samp{=} для одинаковой ширины всех ячеек;
+@item @samp{|} для ограничения ширины таблицы шириной subplot (эквивалентно опции @samp{value 1});
+@item @samp{f} для вывода чисел в фиксированном формате;
+@item @samp{E} для вывода @samp{E} вместо @samp{e};
+@item @samp{F} для вывода в формате LaTeX;
+@item @samp{+} для вывода @samp{+} для положительных чисел;
+@item @samp{-} для вывода обычного @samp{-};
+@item @samp{0123456789} для задания точности при выводе чисел.
+@end itemize
+Опция @code{value} задает ширину таблицы (по умолчанию 1). См. также @ref{label}. @sref{Table sample}
 @end deftypefn
 
 @anchor{tube}
@@ -2277,7 +2460,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_dens (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_dens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует график плотности для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z} = @var{Min}.z. Если @var{sch} содержит @samp{#}, то рисуется сетка. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. См. также @ref{surf}, @ref{cont}, @ref{contf}, @ref{boxs}, @ref{tile}, @code{dens[xyz]}. @sref{Dens sample}
+Рисует график плотности для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z} равном минимальному значению оси z. Если @var{sch} содержит @samp{#}, то рисуется сетка. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. См. также @ref{surf}, @ref{cont}, @ref{contf}, @ref{boxs}, @ref{tile}, @code{dens[xyz]}. @sref{Dens sample}
 @end deftypefn
 
 @anchor{cont}
@@ -2289,7 +2472,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_cont__val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_cont_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует линии уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Если @var{sch} содержит @samp{t} или @samp{T}, то значения @var{v}[k] будут выведены вдоль контуров над (или под) кривой. См. также @ref{dens}, @ref{contf}, @ref{contd}, @ref{axial}, @code{cont[xyz]}. @sref{Cont sample}
+Рисует линии уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z}  равном минимальному значению оси z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Если @var{sch} содержит @samp{t} или @samp{T}, то значения @var{v}[k] будут выведены вдоль контуров над (или под) кривой. См. также @ref{dens}, @ref{contf}, @ref{contd}, @ref{axial}, @code{cont[xyz]}. @sref{Cont sample}
 @end deftypefn
 
 @deftypefn {Команда MGL} {} cont zdat ['sch'='']
@@ -2312,7 +2495,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_contf_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_contf_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует закрашенные линии (контуры) уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. См. также @ref{dens}, @ref{cont}, @ref{contd}, @code{contf[xyz]}. @sref{ContF sample}
+Рисует закрашенные линии (контуры) уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z}  равном минимальному значению оси z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. См. также @ref{dens}, @ref{cont}, @ref{contd}, @code{contf[xyz]}. @sref{ContF sample}
 @end deftypefn
 
 @deftypefn {Команда MGL} {} contf zdat ['sch'='']
@@ -2335,7 +2518,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_contd_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_contd_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует закрашенные линии (контуры) уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Строка @var{sch} задает цвета контуров: цвет k-го контура определяется как k-ый цвет строки. См. также @ref{dens}, @ref{cont}, @ref{contf}. @sref{ContD sample}
+Рисует закрашенные линии (контуры) уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z}  равном минимальному значению оси z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Строка @var{sch} задает цвета контуров: цвет k-го контура определяется как k-ый цвет строки. См. также @ref{dens}, @ref{cont}, @ref{contf}. @sref{ContD sample}
 @end deftypefn
 
 @deftypefn {Команда MGL} {} contd zdat ['sch'='']
@@ -2358,7 +2541,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_contv_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_contv_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует вертикальные цилиндры от линий уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z}=@var{v}[k] или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. См. также @ref{cont}, @ref{contf}. @sref{ContV sample}
+Рисует вертикальные цилиндры от линий уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z}=@var{v}[k] или при @var{z}  равном минимальному значению оси z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. См. также @ref{cont}, @ref{contf}. @sref{ContV sample}
 @end deftypefn
 
 @deftypefn {Команда MGL} {} contv zdat ['sch'='']
@@ -2404,7 +2587,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_grid (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_grid_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует плоскую сету для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z} = @var{Min}.z. См. также @ref{dens}, @ref{cont}, @ref{contf}, @ref{meshnum}.
+Рисует плоскую сету для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z} равном минимальному значению оси z. См. также @ref{dens}, @ref{cont}, @ref{contf}, @ref{grid3}, @ref{meshnum}.
 @end deftypefn
 
 
@@ -2661,7 +2844,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_stfa (@code{HMGL} gr, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_stfa_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует спектрограмму комплексного массива @var{re}+i*@var{im} для Фурье размером @var{dn} точек в плоскости @var{z}=@var{Min}.z. Параметр @var{dn} -- любое чётное число. Например в 1D случае, результатом будет график плотности от массива @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} размером @{int(nx/dn), dn, ny@}. Массивы @var{re}, @var{im} параметрически зависят от координат @var{x}, @var{y}. Все размеры массивов @var{re} и @var{im} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y}, @var{re} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{re}). @sref{STFA sample}
+Рисует спектрограмму комплексного массива @var{re}+i*@var{im} для Фурье размером @var{dn} точек в плоскости @var{z} равно минимальному значению оси z. Параметр @var{dn} -- любое чётное число. Например в 1D случае, результатом будет график плотности от массива @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} размером @{int(nx/dn), dn, ny@}. Массивы @var{re}, @var{im} параметрически зависят от координат @var{x}, @var{y}. Все размеры массивов @var{re} и @var{im} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y}, @var{re} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{re}). @sref{STFA sample}
 @end deftypefn
 
 
@@ -2700,7 +2883,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_vect_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_vect_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует векторное поле @{@var{ax}, @var{ay}@} параметрически зависящее от координат @var{x}, @var{y} на плоскости при @var{z}=@var{Min}.z. Длина и цвет векторов пропорциональна @math{\sqrt@{ax^2+ay^2@}}. Число рисуемых векторов зависит от @ref{meshnum}. Вид стрелок/штрихов может быть изменён символами:
+Рисует векторное поле @{@var{ax}, @var{ay}@} параметрически зависящее от координат @var{x}, @var{y} на плоскости при @var{z} равном минимальному значению оси z. Длина и цвет векторов пропорциональна @math{\sqrt@{ax^2+ay^2@}}. Число рисуемых векторов зависит от @ref{meshnum}. Вид стрелок/штрихов может быть изменён символами:
 @itemize @bullet
 @item
 @samp{f} для стрелок одинаковой длины,
@@ -2757,7 +2940,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_dew (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_dew_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует капли для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} при @var{z}=@var{Min}.z. Замечу, что график требует много памяти и процессорного времени для своего создания! Цвет капель пропорционален @math{\sqrt@{ax^2+ay^2@}}. Число капель определяется @ref{meshnum}. См. также @ref{vect}. @sref{Dew sample}
+Рисует капли для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} при @var{z} равном минимальному значению оси z. Замечу, что график требует много памяти и процессорного времени для своего создания! Цвет капель пропорционален @math{\sqrt@{ax^2+ay^2@}}. Число капель определяется @ref{meshnum}. См. также @ref{vect}. @sref{Dew sample}
 @end deftypefn
 
 @anchor{flow}
@@ -2769,7 +2952,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_flow_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_flow_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует нити тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при @var{z} = @var{Min}.z. Число нитей пропорционально значению опции @code{value} (по умолчанию 5). Цвет нитей пропорционален @math{\sqrt@{ax^2+ay^2@}}. Строка @var{sch} может содержать
+Рисует нити тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при @var{z} равном минимальному значению оси z. Число нитей пропорционально значению опции @code{value} (по умолчанию 5). Цвет нитей пропорционален @math{\sqrt@{ax^2+ay^2@}}. Строка @var{sch} может содержать
 @itemize @bullet
 @item
 цветовую схему -- тёплые цвета соответствуют нормальному току (типа стока), холодные цвета соответствуют обратному току (типа источника);
@@ -2840,7 +3023,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_pipe_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_pipe_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
 @end ifclear
-Рисует трубки тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при @var{z} = @var{Min}.z. Число трубок пропорционально значению опции @code{value}. Цвет и радиус трубок пропорционален @math{\sqrt@{ax^2+ay^2@}}. Тёплые цвета соответствуют нормальному току (типа стока). Холодные цвета соответствуют обратному току (типа источника). Параметр @var{r0} задает радиус трубок. При @var{r0}<0 радиус трубок обратно пропорционален их амплитуде. См. также @ref{flow}, @ref{vect}. @sref{Pipe sample}
+Рисует трубки тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при @var{z} равном минимальному значению оси z. Число трубок пропорционально значению опции @code{value}. Цвет и радиус трубок пропорционален @math{\sqrt@{ax^2+ay^2@}}. Тёплые цвета соответствуют нормальному току (типа стока). Холодные цвета соответствуют обратному току (типа источника). Параметр @var{r0} задает радиус трубок. При @var{r0}<0 радиус трубок обратно пропорционален их амплитуде. См. также @ref{flow}, @ref{vect}. @sref{Pipe sample}
 @end deftypefn
 
 @deftypefn {Команда MGL} {} pipe udat vdat wdat ['sch'='' @code{r0=0.05}]
@@ -2946,7 +3129,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} FPlot (@code{const char *}eqY, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_fplot (@code{HMGL} gr, @code{const char *}eqY, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-Рисует функцию @samp{eqY(x)} в плоскости @var{z}=@var{Min}.z с координатой @samp{x} в диапазоне [@var{Min}.x, @var{Max}.x]. Опция @code{value} задает начальное число точек. См. также @ref{plot}.
+Рисует функцию @samp{eqY(x)} в плоскости @var{z} равно минимальному значению оси z с координатой @samp{x} в диапазоне осей координат. Опция @code{value} задает начальное число точек. См. также @ref{plot}.
 @end deftypefn
 
 @deftypefn {Команда MGL} {} fplot 'x(t)' 'y(t)' 'z(t)' ['pen'='']
@@ -3003,7 +3186,7 @@ gr.GetBGRN(bits, len(bits));
 @deftypefnx {Функция С} @code{void} mgl_tricont_xyzcv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_tricont_xyzv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Рисует линии уровня поверхности из треугольников при @var{z}=@var{v}[k] (или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}). Вершины треугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Если аргуент @var{v} не задан, то используется массив из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @code{value} в опциях @var{opt} (по умолчанию 7). Строка @var{sch} задает цветовую схему. Размер по 1-му индексу массива @var{id} должен быть 3 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет треугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{triplot}, @ref{cont}, @ref{triangulation}.
+Рисует линии уровня поверхности из треугольников при @var{z}=@var{v}[k] (или при @var{z} равном минимальному значению оси z если @var{sch} содержит @samp{_}). Вершины треугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Если аргуент @var{v} не задан, то используется массив из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @code{value} в опциях @var{opt} (по умолчанию 7). Строка @var{sch} задает цветовую схему. Размер по 1-му индексу массива @var{id} должен быть 3 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет треугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{triplot}, @ref{cont}, @ref{triangulation}.
 @end deftypefn
 
 @anchor{quadplot}
@@ -3058,7 +3241,7 @@ gr.GetBGRN(bits, len(bits));
 
 Эти функции подбирают параметры функции для наилучшей аппроксимации данных, т.е. минимизируют сумму @math{\sum_i (f(x_i, y_i, z_i) - a_i)^2/s_i^2}. При этом аппроксимирующая функция @samp{f} может зависеть от одного аргумента @samp{x} (1D случай), от двух аргументов @samp{x,y} (2D случай) или от трех аргументов @samp{x,y,z} (3D случай). Функция @samp{f} также может зависеть от параметров. Список параметров задается строкой @var{var} (например, @samp{abcd}). Обычно пользователь должен предоставить начальные значения параметров в переменной @var{ini}. Однако, при его отсутствии используются нулевые значения. Параметр @var{print}=@code{true} включает вывод найденной формулы в @var{Message} (см. @ref{Error handling}).
 
-ФÑ\83нкÑ\86ии Fit() Ð¸ FitS() Ð½Ðµ Ñ\80иÑ\81Ñ\83Ñ\8eÑ\82 Ð¿Ð¾Ð»Ñ\83Ñ\87еннÑ\8bе Ð¼Ð°Ñ\81Ñ\81ивÑ\8b. Ð\9eни Ð·Ð°Ð¿Ð¾Ð»Ð½Ñ\8fÑ\8eÑ\82 Ð¼Ð°Ñ\81Ñ\81ив @var{fit} Ð¿Ð¾ Ñ\84оÑ\80мÑ\83ле @samp{f} Ñ\81 Ð½Ð°Ð¹Ð´ÐµÐ½Ð½Ñ\8bми ÐºÐ¾Ñ\8dÑ\84Ñ\84иÑ\86иенÑ\82ами Ð¸ Ð²Ð¾Ð·Ð²Ñ\80аÑ\89аÑ\8eÑ\82 @math{\chi^2} Ð¾Ñ\88ибкÑ\83 Ð°Ð¿Ð¿Ñ\80окÑ\81имаÑ\86ии. Ð\9fÑ\80и Ñ\8dÑ\82ом, ÐºÐ¾Ð¾Ñ\80динаÑ\82Ñ\8b @samp{x,y,z} Ñ\80авно Ñ\80аÑ\81пÑ\80еделенÑ\8b Ð² Ð¸Ð½Ñ\82еÑ\80вале @var{Min}--@var{Max}. Число точек в @var{fit} определяется опцией @code{value} (по умолчанию @var{mglFitPnts}=100). Функции используют библиотеку GSL. @sref{Nonlinear fitting hints}
+ФÑ\83нкÑ\86ии Fit() Ð¸ FitS() Ð½Ðµ Ñ\80иÑ\81Ñ\83Ñ\8eÑ\82 Ð¿Ð¾Ð»Ñ\83Ñ\87еннÑ\8bе Ð¼Ð°Ñ\81Ñ\81ивÑ\8b. Ð\9eни Ð·Ð°Ð¿Ð¾Ð»Ð½Ñ\8fÑ\8eÑ\82 Ð¼Ð°Ñ\81Ñ\81ив @var{fit} Ð¿Ð¾ Ñ\84оÑ\80мÑ\83ле @samp{f} Ñ\81 Ð½Ð°Ð¹Ð´ÐµÐ½Ð½Ñ\8bми ÐºÐ¾Ñ\8dÑ\84Ñ\84иÑ\86иенÑ\82ами Ð¸ Ð²Ð¾Ð·Ð²Ñ\80аÑ\89аÑ\8eÑ\82 @math{\chi^2} Ð¾Ñ\88ибкÑ\83 Ð°Ð¿Ð¿Ñ\80окÑ\81имаÑ\86ии. Ð\9fÑ\80и Ñ\8dÑ\82ом, ÐºÐ¾Ð¾Ñ\80динаÑ\82Ñ\8b @samp{x,y,z} Ñ\80авно Ñ\80аÑ\81пÑ\80еделенÑ\8b Ð² Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ðµ Ð¾Ñ\81ей ÐºÐ¾Ð¾Ñ\80динаÑ\82. Число точек в @var{fit} определяется опцией @code{value} (по умолчанию @var{mglFitPnts}=100). Функции используют библиотеку GSL. @sref{Nonlinear fitting hints}
 
 @anchor{fits}
 @deftypefn {Команда MGL} {} fits res adat sdat 'func' 'var' [ini=0]
@@ -3128,6 +3311,7 @@ gr.GetBGRN(bits, len(bits));
 @ifclear UDAV
 @deftypefn {Метод класса @code{mglGraph}} @code{const char *}GetFit ()
 @deftypefnx {Функция С} @code{const char *} mgl_get_fit (@code{HMGL} gr)
+@deftypefnx {Fortran процедура} @code{} mgl_get_fit (@code{long} gr, @code{char *}out, @code{int} len)
 Возвращает последнюю подобранную формулу с найденными коэффициентами.
 @end deftypefn
 @end ifclear
index 0a4db63e5b2d99bdf15bc8f6748880e822214e27..884753781e432740047cbd83cd2404f43a9b62db 100644 (file)
@@ -23,7 +23,7 @@ This chapter describe classes @code{mglData} and @code{mglDataC} for working wit
 * Operators::
 * Global functions::
 * Evaluate expression::
-* MGL variables::
+* Special data classes::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -62,6 +62,20 @@ Names of column (or slice if nz>1)  -- one character per column.
 Flag to use external data, i.e. don't delete it.
 @end deftypecv
 
+@deftypecv {Variable} mglDataA @code{std::wstring} s
+Name of data. It is used in parsing of MGL scripts.
+@end deftypecv
+@deftypecv {Variable} mglDataA @code{bool} temp
+Flag of temporary variable, which should be deleted.
+@end deftypecv
+@deftypecv {Variable} mglDataA @code{void (*)(void *)} func
+Pointer to callback function which will be called at destroying.
+@end deftypecv
+@deftypecv {Variable} mglDataA @code{void *} o
+Pointer to object for callback function.
+@end deftypecv
+
+
 @deftypefn {Method on @code{mglData}} @code{mreal} GetVal (@code{long} i)
 @deftypefnx {Method on @code{mglDataC}} @code{mreal} GetVal (@code{long} i)
 @deftypefnx {Method on @code{mglData}} @code{void} SetVal (@code{mreal} val, @code{long} i)
@@ -69,12 +83,9 @@ Flag to use external data, i.e. don't delete it.
 Gets or sets the value in by "flat" index @var{i} without border checking. Index @var{i} should be in range [0, nx*ny*nz-1].
 @end deftypefn
 
-@deftypefn {Method on @code{mglData}} @code{long} GetNx ()
-@deftypefnx {Method on @code{mglDataC}} @code{long} GetNx ()
-@deftypefnx {Method on @code{mglData}} @code{long} GetNy ()
-@deftypefnx {Method on @code{mglDataC}} @code{long} GetNy ()
-@deftypefnx {Method on @code{mglData}} @code{long} GetNz ()
-@deftypefnx {Method on @code{mglDataC}} @code{long} GetNz ()
+@deftypefn {Method on @code{mglDataA}} @code{long} GetNx ()
+@deftypefnx {Method on @code{mglDataA}} @code{long} GetNy ()
+@deftypefnx {Method on @code{mglDataA}} @code{long} GetNz ()
 @deftypefnx {C function} @code{long} mgl_data_get_nx (@code{HCDT} dat)
 @deftypefnx {C function} @code{long} mgl_data_get_ny (@code{HCDT} dat)
 @deftypefnx {C function} @code{long} mgl_data_get_nz (@code{HCDT} dat)
@@ -93,6 +104,16 @@ Gets or sets the value in specified cell of the data with border checking.
 @deftypefnx {C function} @code{const dual *} mgl_datac_data (@code{HCDT} dat)
 Returns pointer to internal data array.
 @end deftypefn
+
+@deftypefn {C function only} @code{void} mgl_data_set_func (@code{mglDataA *}dat, @code{void (*}func@code{)(void *)}, @code{void *}par)
+Set pointer to callback function which will be called at destroying.
+@end deftypefn
+
+@deftypefn {C function} @code{void} mgl_data_set_name (@code{mglDataA *}dat, @code{const char *}name)
+@deftypefnx {C function} @code{void} mgl_data_set_name_w (@code{mglDataA *}dat, @code{const wchar_t *}name)
+Set name of data, which used in parsing of MGL scripts.
+@end deftypefn
+
 @end ifclear
 
 @c ------------------------------------------------------------------
@@ -531,6 +552,15 @@ Copies value(s) from array @var{v} to the range of original array. Negative inde
 Fills by interpolated values of array @var{v} at the point @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i], Y[j], Z[k]}@} (or @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i,j,k], Y[i,j,k], Z[i,j,k]}@} if @var{x}, @var{y}, @var{z} are not 1d arrays), where @code{X,Y,Z} are equidistantly distributed in range [@var{x1},@var{x2}]*[@var{y1},@var{y2}]*[@var{z1},@var{z2}] and have the same sizes as this array. If parameter @var{sl} is 0 or positive then changes will be applied only for slice @var{sl}.
 @end deftypefn
 
+@anchor{gspline}
+@deftypefn {MGL command} {} gspline dat xdat vdat [sl=-1]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} RefillGS (@code{const mglDataA &}x, @code{const mglDataA &}v, @code{mreal} x1, @code{mreal} x2, @code{long} sl=@code{-1})
+@deftypefnx {C function} @code{void} mgl_data_refill_gs (@code{HMDT} a, @code{HCDT} x, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{long} sl)
+@end ifclear
+Fills by global cubic spline values of array @var{v} at the point @var{x}=@code{X[i]}, where @code{X} are equidistantly distributed in range [@var{x1},@var{x2}] and have the same sizes as this array. If parameter @var{sl} is 0 or positive then changes will be applied only for slice @var{sl}.
+@end deftypefn
+
 @anchor{idset}
 @deftypefn {MGL command} {} idset dat 'ids'
 @ifclear UDAV
@@ -614,8 +644,7 @@ Join data arrays from several text files which filenames satisfied the template
 @anchor{save}
 @deftypefn {MGL command} {} save dat 'fname'
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
 @deftypefnx {C function} @code{void} mgl_data_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
 @deftypefnx {C function} @code{void} mgl_datac_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
 @end ifclear
@@ -636,8 +665,7 @@ Reads data array named @var{dname} from HDF5 or HDF4 file. This function does no
 @anchor{savehdf}
 @deftypefn {MGL command} {} savehdf dat 'fname' 'dname'
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
 @deftypefnx {C function} @code{void} mgl_data_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
 @deftypefnx {C function} @code{void} mgl_datac_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
 @end ifclear
@@ -647,8 +675,7 @@ Saves data array named @var{dname} to HDF5 file. This function does nothing if H
 @anchor{datas}
 @deftypefn {MGL command} {} datas 'fname'
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{int} DatasHDF (@code{const char *}fname, @code{char *}buf, @code{long} size) @code{static}
-@deftypefnx {Method on @code{mglDataC}} @code{int} DatasHDF (@code{const char *}fname, @code{char *}buf, @code{long} size) @code{static}
+@deftypefnx {Method on @code{mglDataA}} @code{int} DatasHDF (@code{const char *}fname, @code{char *}buf, @code{long} size) @code{static}
 @deftypefnx {C function} @code{int} mgl_datas_hdf (@code{const char *}fname, @code{char *}buf, @code{long} size)
 @end ifclear
 Put data names from HDF5 file @var{fname} into @var{buf} as '\t' separated fields. In MGL version the list of data names will be printed as message. This function does nothing if HDF5 was disabled during library compilation.
@@ -666,7 +693,7 @@ Reads data from bitmap file (now support only PNG format). The RGB values of bit
 @anchor{export}
 @deftypefn {MGL command} {} export dat 'fname' 'sch' [@code{v1=0 v2=0}]
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{void} Export (@code{const char *}fname, @code{const char *}scheme, @code{mreal} v1=@code{0}, mreal v2=@code{0}, @code{int} ns=@code{-1}) const
+@deftypefnx {Method on @code{mglDataA}} @code{void} Export (@code{const char *}fname, @code{const char *}scheme, @code{mreal} v1=@code{0}, mreal v2=@code{0}, @code{int} ns=@code{-1}) const
 @deftypefnx {C function} @code{void} mgl_data_export (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{mreal} v1, mreal v2, @code{int} ns) const
 @end ifclear
 Saves data matrix (or @code{ns}-th slice for 3d data) to bitmap file (now support only PNG format). The data values are transformed from range [@var{v1}, @var{v2}] to RGB pixels of bitmap using color scheme @var{scheme} (@pxref{Color scheme}). If @var{v1}>=@var{v2} then the values of @var{v1}, @var{v2} are automatically determined as minimal and maximal value of the data array.
@@ -707,9 +734,14 @@ Extracts sub-array data from the original data array keeping fixed positive inde
 @ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz) @code{const}
 @deftypefnx {Method on @code{mglDataC}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz) @code{const}
+@deftypefnx {Method on @code{mglData}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy) @code{const}
+@deftypefnx {Method on @code{mglDataC}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy) @code{const}
+@deftypefnx {Method on @code{mglData}} @code{mglData} SubData (@code{const mglDataA &}xx) @code{const}
+@deftypefnx {Method on @code{mglDataC}} @code{mglData} SubData (@code{const mglDataA &}xx) @code{const}
 @deftypefnx {C function} @code{HMDT} mgl_data_subdata_ext (@code{HCDT} dat, @code{HCDT} xx, @code{HCDT} yy, @code{HCDT} zz)
+@deftypefnx {C function} @code{HADT} mgl_datac_subdata_ext (@code{HCDT} dat, @code{HCDT} xx, @code{HCDT} yy, @code{HCDT} zz)
 @end ifclear
-Extracts sub-array data from the original data array for indexes specified by arrays @var{xx}, @var{yy}, @var{zz} (indirect access). This function work like previous one for 1D arguments or numbers, and resulting array dimensions are equal dimensions of 1D arrays for corresponding direction. For 2D and 3D arrays in arguments, the resulting array have the same dimensions as input arrays. The dimensions of all argument must be the same (or to be scalar 1*1*1) if they are 2D or 3D arrays. In MGL version this command usually is used as inline one @code{dat(xx,yy,zz)}. Function return NULL or create empty data if data cannot be created for given arguments.
+Extracts sub-array data from the original data array for indexes specified by arrays @var{xx}, @var{yy}, @var{zz} (indirect access). This function work like previous one for 1D arguments or numbers, and resulting array dimensions are equal dimensions of 1D arrays for corresponding direction. For 2D and 3D arrays in arguments, the resulting array have the same dimensions as input arrays. The dimensions of all argument must be the same (or to be scalar 1*1*1) if they are 2D or 3D arrays. In MGL version this command usually is used as inline one @code{dat(xx,yy,zz)}. Function return NULL or create empty data if data cannot be created for given arguments. In C function some of @var{xx}, @var{yy}, @var{zz} can be NULL.
 @end deftypefn
 
 @anchor{column}
@@ -1087,7 +1119,7 @@ Normalizes data slice-by-slice along direction @var{dir} the data in slices to r
 @section Interpolation
 @nav{}
 
-MGL scripts can use linear interpolation by @ref{subdata} command, or spline interpolation by @ref{evaluate} command. Also you can use @ref{resize} for obtaining a data array with new sizes.
+MGL scripts can use spline interpolation by @ref{evaluate} or @ref{refill} commands. Also you can use @ref{resize} for obtaining a data array with new sizes.
 
 @ifclear UDAV
 
@@ -1156,11 +1188,10 @@ There are a set of functions for obtaining data properties in MGL language. Howe
 @anchor{info}
 @deftypefn {MGL command} {} info dat
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{const char *} PrintInfo () @code{const}
-@deftypefnx {Method on @code{mglData}} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{const char *} PrintInfo () @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
-@deftypefnx {C function} @code{const char *} mgl_data_info (@code{HCDT} dat)
+@deftypefnx {Method on @code{mglDataA}} @code{const char *} PrintInfo () @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
+@deftypefnx {C function only} @code{const char *} mgl_data_info (@code{HCDT} dat)
+@deftypefnx {Fortran subroutine} @code{} mgl_data_info (@code{long} dat, @code{char *}out, @code{int} len)
 @end ifclear
 Gets or prints to file @var{fp} or as message (in MGL) information about the data (sizes, maximum/minimum, momentums and so on).
 @end deftypefn
@@ -1181,12 +1212,9 @@ Prints value of number @var{val} as message.
 @deftypefnx {MGL suffix} {(dat)} .ny
 @deftypefnx {MGL suffix} {(dat)} .nz
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{long} GetNx ()
-@deftypefnx {Method on @code{mglData}} @code{long} GetNy ()
-@deftypefnx {Method on @code{mglData}} @code{long} GetNz ()
-@deftypefnx {Method on @code{mglDataC}} @code{long} GetNx ()
-@deftypefnx {Method on @code{mglDataC}} @code{long} GetNy ()
-@deftypefnx {Method on @code{mglDataC}} @code{long} GetNz ()
+@deftypefnx {Method on @code{mglDataA}} @code{long} GetNx ()
+@deftypefnx {Method on @code{mglDataA}} @code{long} GetNy ()
+@deftypefnx {Method on @code{mglDataA}} @code{long} GetNz ()
 @deftypefnx {C function} @code{long} mgl_data_get_nx (@code{HCDT} dat)
 @deftypefnx {C function} @code{long} mgl_data_get_ny (@code{HCDT} dat)
 @deftypefnx {C function} @code{long} mgl_data_get_nz (@code{HCDT} dat)
@@ -1200,8 +1228,7 @@ Gets the x-, y-, z-size of the data.
 @anchor{.max}
 @deftypefn {MGL suffix} {(dat)} .max
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{mreal} Maximal () @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{mreal} Maximal () @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{mreal} Maximal () @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_max (@code{HCDT} dat)
 @end ifclear
 Gets maximal value of the data.
@@ -1211,26 +1238,22 @@ Gets maximal value of the data.
 @anchor{.min}
 @deftypefn {MGL suffix} {(dat)} .min
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{mreal} Minimal () @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{mreal} Minimal () @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{mreal} Minimal () @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_min (@code{HMDT} dat) @code{const}
 @end ifclear
 Gets minimal value of the data.
 @end deftypefn
 
 @ifclear UDAV
-@deftypefn {Method on @code{mglData}} @code{mreal} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{mreal} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefn {Method on @code{mglDataA}} @code{mreal} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_min_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
 Gets position of minimum to variables @var{i}, @var{j}, @var{k} and returns the minimal value.
 @end deftypefn
-@deftypefn {Method on @code{mglData}} @code{mreal} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{mreal} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefn {Method on @code{mglDataA}} @code{mreal} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_max_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
 Gets position of maximum to variables @var{i}, @var{j}, @var{k} and returns the maximal value.
 @end deftypefn
-@deftypefn {Method on @code{mglData}} @code{mreal} Minimal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{mreal} Minimal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
+@deftypefn {Method on @code{mglDataA}} @code{mreal} Minimal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_min_real (@code{HCDT} dat, @code{mreal} *x, @code{mreal} *y, @code{mreal} *z)
 Gets approximated (interpolated) position of minimum to variables @var{x}, @var{y}, @var{z} and returns the minimal value.
 @end deftypefn
@@ -1241,8 +1264,7 @@ Gets approximated (interpolated) position of minimum to variables @var{x}, @var{
 @deftypefnx {MGL suffix} {(dat)} .my
 @deftypefnx {MGL suffix} {(dat)} .mz
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{mreal} Maximal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
-@deftypefnx {Method on @code{mglDataC}} @code{mreal} Maximal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{mreal} Maximal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_max_real (@code{HCDT} dat, @code{mreal} *x, @code{mreal} *y, @code{mreal} *z)
 @end ifclear
 Gets approximated (interpolated) position of maximum to variables @var{x}, @var{y}, @var{z} and returns the maximal value.
@@ -1272,8 +1294,8 @@ Gets approximated (interpolated) position of maximum to variables @var{x}, @var{
 @deftypefnx {MGL suffix} {(dat)} .kz
 @deftypefnx {MGL suffix} {(dat)} .ka
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &a, @code{mreal} &w) @code{const}
-@deftypefnx {Method on @code{mglData}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &m, @code{mreal} &w, @code{mreal} &s, @code{mreal} &k) @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &a, @code{mreal} &w) @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &m, @code{mreal} &w, @code{mreal} &s, @code{mreal} &k) @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_momentum_val (@code{HCDT} dat, @code{char} dir, @code{mreal} *a, @code{mreal} *w, @code{mreal} *s, @code{mreal} *k)
 @end ifclear
 Gets zero-momentum (energy, @math{I=\sum dat_i}) and write first momentum (median, @math{a = \sum \xi_i dat_i/I}), second momentum (width, @math{w^2 = \sum (\xi_i-a)^2 dat_i/I}), third momentum (skewness, @math{s = \sum (\xi_i-a)^3 dat_i/ I w^3}) and fourth momentum (kurtosis, @math{k = \sum (\xi_i-a)^4 dat_i / 3 I w^4}) to variables. Here @math{\xi} is corresponding coordinate if @var{dir} is @samp{'x'}, @samp{'y'} or @samp{'z'}. Otherwise median is @math{a = \sum dat_i/N}, width is @math{w^2 = \sum (dat_i-a)^2/N} and so on.
@@ -1283,7 +1305,7 @@ Gets zero-momentum (energy, @math{I=\sum dat_i}) and write first momentum (media
 @deftypefn {MGL suffix} {(dat)} .fst
 @ifclear UDAV
 @cindex Find
-@deftypefnx {Method on @code{mglData}} @code{mreal} Find (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{mreal} Find (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_first (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
 @end ifclear
 Find position (after specified in @var{i}, @var{j}, @var{k}) of first nonzero value of formula @var{cond}. Function return the data value at found position.
@@ -1293,19 +1315,19 @@ Find position (after specified in @var{i}, @var{j}, @var{k}) of first nonzero va
 @deftypefn {MGL suffix} {(dat)} .lst
 @ifclear UDAV
 @cindex Last
-@deftypefnx {Method on @code{mglData}} @code{mreal} Last (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefnx {Method on @code{mglDataA}} @code{mreal} Last (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_last (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
 @end ifclear
 Find position (before specified in @var{i}, @var{j}, @var{k}) of last nonzero value of formula @var{cond}. Function return the data value at found position.
 @end deftypefn
 
 @ifclear UDAV
-@deftypefn {Method on @code{mglData}} @code{int} Find (@code{const char *}cond, @code{char} dir, @code{int} i=@code{0}, @code{int} j=@code{0}, @code{int} k=@code{0}) @code{const}
+@deftypefn {Method on @code{mglDataA}} @code{int} Find (@code{const char *}cond, @code{char} dir, @code{int} i=@code{0}, @code{int} j=@code{0}, @code{int} k=@code{0}) @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_find (@code{HCDT} dat, @code{const char *}cond, @code{int} i, @code{int} j, @code{int} k)
 Return position of first in direction @var{dir} nonzero value of formula @var{cond}. The search is started from point @{i,j,k@}.
 @end deftypefn
 @cindex FindAny
-@deftypefn {Method on @code{mglData}} @code{bool} FindAny (@code{const char *}cond) @code{const}
+@deftypefn {Method on @code{mglDataA}} @code{bool} FindAny (@code{const char *}cond) @code{const}
 @deftypefnx {C function} @code{mreal} mgl_data_find_any (@code{HCDT} dat, @code{const char *}cond)
 Determines if any nonzero value of formula in the data array.
 @end deftypefn
@@ -1460,9 +1482,11 @@ Short time Fourier transformation for real and imaginary parts. Output  is ampli
 @deftypefn {MGL command} {} pde @sc{res} 'ham' ini_re ini_im [@code{dz=0.1 k0=100}]
 @ifclear UDAV
 @deftypefnx {Global function} @code{mglData} mglPDE (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
+@deftypefnx {Global function} @code{mglDataC} mglPDEc (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
 @deftypefnx {C function} @code{HMDT} mgl_pde_solve (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
+@deftypefnx {C function} @code{HADT} mgl_pde_solve_c (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
 @end ifclear
-Solves equation du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy are pseudo-differential operators. Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{Min}, @var{Max} set the bounding box for the solution. Note, that really this ranges are increased by factor 3/2 for purpose of reducing reflection from boundaries. Parameter @var{dz} set the step along evolutionary coordinate z. At this moment, simplified form of function @var{ham} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this function is effectively @math{ham = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed. Here variable @samp{u} is used for field amplitude |u|. This allow one solve nonlinear problems -- for example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. You may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}, but only if dependence on variable @samp{i} is linear (i.e. @math{ham = hre+i*him}). @sref{PDE solving hints}
+Solves equation du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy are pseudo-differential operators. Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{Min}, @var{Max} set the bounding box for the solution. Note, that really this ranges are increased by factor 3/2 for purpose of reducing reflection from boundaries. Parameter @var{dz} set the step along evolutionary coordinate z. At this moment, simplified form of function @var{ham} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this function is effectively @math{ham = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed. Here variable @samp{u} is used for field amplitude |u|. This allow one solve nonlinear problems -- for example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. You may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}, but only if dependence on variable @samp{i} is linear (i.e. @math{ham = hre+i*him}). See also @ref{qo2d}, @ref{qo3d}. @sref{PDE solving hints}
 @end deftypefn
 
 @anchor{ray}
@@ -1474,16 +1498,49 @@ Solves equation du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], where p=-i/k0*d/dx, q=
 Solves GO ray equation like dr/dt = d @var{ham}/dp, dp/dt = -d @var{ham}/dr. This is Hamiltonian equations for particle trajectory in 3D case. Here @var{ham} is Hamiltonian which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, momentums @samp{p}=px, @samp{q}=py, @samp{v}=pz and time @samp{t}: @math{ham = H(x,y,z,p,q,v,t)}. The starting point (at @code{t=0}) is defined by variables @var{r0}, @var{p0}. Parameters @var{dt} and @var{tmax} specify the integration step and maximal time for ray tracing. Result is array of @{x,y,z,p,q,v,t@} with dimensions @{7 * int(@var{tmax}/@var{dt}+1) @}.
 @end deftypefn
 
+@anchor{ode}
+@deftypefn {MGL command} {} ode @sc{res} 'df' 'var' ini [@code{dt=0.1 tmax=10}]
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglODE (@code{const char *}df, @code{const char *}var, @code{const mglDataA &}ini, @code{mreal} dt=@code{0.1}, @code{mreal} tmax=@code{10})
+@deftypefnx {C function} @code{HMDT} mgl_ode_solve_str (@code{const char *}df, @code{const char *}var, @code{HCDT} ini, @code{mreal} dt, @code{mreal} tmax)
+@deftypefnx {C function} @code{HMDT} mgl_ode_solve (@code{void (*}df@code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax)
+@deftypefnx {C function} @code{HMDT} mgl_ode_solve_ex (@code{void (*}df@code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax, @code{void (*}bord@code{)(mreal *x, const mreal *xprev, void *par)})
+@end ifclear
+Solves ODE equations dx/dt = df(x). The functions @var{df} can be specified as string of ';'-separated textual formulas (argument @var{var} set the character ids of variables x[i]) or as callback function, which fill @code{dx} array for give @code{x}'s. Parameters @var{ini}, @var{dt}, @var{tmax} set initial values, time step and maximal time of the calculation. Result is data array with dimensions @{@var{n} * int(@var{tmax}/@var{dt}+1)@}.
+@end deftypefn
+
 @anchor{qo2d}
 @deftypefn {MGL command} {} qo2d @sc{res} 'ham' ini_re ini_im ray [@code{r=1 k0=100} xx yy]
 @ifclear UDAV
-@deftypefnx {Global function} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100}, @code{mglData *}xx=@code{0}, @code{mglData *}yy=@code{0})
+@deftypefnx {Global function} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
 @deftypefnx {Global function} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglDataC} mglQO2dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglDataC} mglQO2dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
 @deftypefnx {C function} @code{HMDT} mgl_qo2d_solve (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
+@deftypefnx {C function} @code{HADT} mgl_qo2d_solve_c (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
+@deftypefnx {C function} @code{HMDT} mgl_qo2d_func (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
+@deftypefnx {C function} @code{HADT} mgl_qo2d_func_c (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
+@end ifclear
+Solves equation du/dt = i*k0*@var{ham}(p,q,x,y,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy are pseudo-differential operators (see @code{mglPDE()} for details). Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{ray} set the reference ray, i.e. the ray around which the accompanied coordinate system will be maked. You may use, for example, the array created by @ref{ray} function. Note, that the reference ray @strong{must be} smooth enough to make accompanied coodrinates unambiguity. Otherwise errors in the solution may appear. If @var{xx} and @var{yy} are non-zero then Cartesian coordinates for each point will be written into them. See also @ref{pde}, @ref{qo3d}. @sref{PDE solving hints}
+@end deftypefn
+
+
+@anchor{qo3d}
+@deftypefn {MGL command} {} qo3d @sc{res} 'ham' ini_re ini_im ray [@code{r=1 k0=100} xx yy zz]
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglQO3d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglData} mglQO3d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mglData &}zz, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglDataC} mglQO3dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglDataC} mglQO3dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mglData &}zz, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {C function} @code{HMDT} mgl_qo3d_solve (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
+@deftypefnx {C function} @code{HADT} mgl_qo3d_solve_c (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
+@deftypefnx {C function} @code{HMDT} mgl_qo3d_func (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
+@deftypefnx {C function} @code{HADT} mgl_qo3d_func_c (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
 @end ifclear
-Solves equation du/dt = i*k0*@var{ham}(p,q,x,y,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy are pseudo-differential operators (see @code{mglPDE()} for details). Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{ray} set the reference ray, i.e. the ray around which the accompanied coordinate system will be maked. You may use, for example, the array created by @code{mglRay()} function. Note, that the reference ray @strong{must be} smooth enough to make accompanied coodrinates unambiguity. Otherwise errors in the solution may appear. If @var{xx} and @var{yy} are non-zero then Cartesian coordinates for each point will be written into them. See also @code{mglPDE()}. @sref{PDE solving hints}
+Solves equation du/dt = i*k0*@var{ham}(p,q,v,x,y,z,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy, v=-i/k0*d/dz are pseudo-differential operators (see @code{mglPDE()} for details). Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{ray} set the reference ray, i.e. the ray around which the accompanied coordinate system will be maked. You may use, for example, the array created by @ref{ray} function. Note, that the reference ray @strong{must be} smooth enough to make accompanied coodrinates unambiguity. Otherwise errors in the solution may appear. If @var{xx} and @var{yy} and @var{zz} are non-zero then Cartesian coordinates for each point will be written into them. See also @ref{pde}, @ref{qo2d}. @sref{PDE solving hints}
 @end deftypefn
 
+
 @anchor{jacobian}
 @deftypefn {MGL command} {} jacobian @sc{res} xdat ydat [zdat]
 @ifclear UDAV
@@ -1507,10 +1564,27 @@ Computes the Jacobian for transformation @{i,j,k@} to @{@var{x},@var{y},@var{z}@
 Computes triangulation for arbitrary placed points with coordinates @{@var{x},@var{y}@} (i.e. finds triangles which connect points). MathGL use @uref{http://www.s-hull.org/,s-hull} code for triangulation. The sizes of 1st dimension @strong{must be equal} for all arrays @code{x.nx=y.nx}. Resulting array can be used in @ref{triplot} or @ref{tricont} functions for visualization of reconstructed surface. @sref{Making regular data}
 @end deftypefn
 
+@ifclear UDAV
+
+@deftypefn {Global function} @code{mglData} mglGSplineInit (@code{const mglDataA &}x, @code{const mglDataA &}y)
+@deftypefnx {Global function} @code{mglDataC} mglGSplineCInit (@code{const mglDataA &}x, @code{const mglDataA &}y)
+@deftypefnx {C function} @code{HMDT} mgl_gspline_init (@code{HCDT} x, @code{HCDT} y)
+@deftypefnx {C function} @code{HADT} mgl_gsplinec_init (@code{HCDT} x, @code{HCDT} y)
+Prepare coefficients for global cubic spline interpolation.
+@end deftypefn
+
+@deftypefn {Global function} @code{mreal} mglGSpline (@code{const mglDataA &}coef, @code{mreal} dx, @code{mreal *}d1=@code{0}, @code{mreal *}d2=@code{0})
+@deftypefnx {Global function} @code{dual} mglGSplineC (@code{const mglDataA &}coef, @code{mreal} dx, @code{dual *}d1=@code{0}, @code{dual *}d2=@code{0})
+@deftypefnx {C function} @code{mreal} mgl_gspline (@code{HCDT} coef, @code{mreal} dx, @code{mreal *}d1, @code{mreal *}d2)
+@deftypefnx {C function} @code{dual} mgl_gsplinec (@code{HCDT} coef, @code{mreal} dx, @code{dual *}d1, @code{dual *}d2)
+Evaluate global cubic spline (and its 1st and 2nd derivatives @var{d1}, @var{d2} if they are not @code{NULL}) using prepared coefficients @var{coef} at point @var{dx}+@var{x0} (where @var{x0} is 1st element of data @var{x} provided to @code{mglGSpline*Init()} function). 
+@end deftypefn
+
+@end ifclear
 
 @c ------------------------------------------------------------------
 @external{}
-@node Evaluate expression, MGL variables, Global functions, Data processing
+@node Evaluate expression, Special data classes, Global functions, Data processing
 @section Evaluate expression
 @nav{}
 
@@ -1567,49 +1641,82 @@ Evaluates the formula derivation respect to @var{dir} for variables in array @va
 
 @c ------------------------------------------------------------------
 @external{}
-@node MGL variables, , Evaluate expression, Data processing
-@section MGL variables
+@node Special data classes, , Evaluate expression, Data processing
+@section Special data classes
 @nav{}
 
+
 @ifset UDAV
-For information about MGL variables see @ref{MGL definition}.
+MGL use these special classes automatically.
 @end ifset
 
 @ifclear UDAV
+This section describe special data classes @code{mglDataV}, @code{mglDataF}, @code{mglDataT} and @code{mglDataR} which sometime can noticeable speed up drawing or data handling. These classes are defined in @code{#include <mgl2/data.h>}. Note, that all plotting and data handling routines can be done using usual @code{mglData} or @code{mglDataC} classes. Also these special classes are usable in C++ code only.
 
-Class mglVar represent MGL variables. It is needed for parsing MGL scripts (see @ref{mglParse class}). This class is derived from @code{mglData} and is defined in @code{#include <mgl2/mgl.h>}.
-
-@deftypecv {Variable} mglVar @code{std::wstring} s
-Name of variable.
-@end deftypecv
-
-@deftypecv {Variable} mglVar @code{mglVar *} next
-@deftypecvx {Variable} mglVar @code{mglVar *} prev
-Next and previous variable in the list.
-@end deftypecv
+@heading Class @code{mglDataV}
+represent variable with values equidistantly distributed in given range.
+@deftypefn {Constructor on @code{mglDataV}} @code{} mglDataV (@code{const mglDataV &} d)
+Copy constructor.
+@end deftypefn
+@deftypefn {Constructor on @code{mglDataV}} @code{} mglDataV (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1}, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{NaN}, @code{char} dir=@code{'x'})
+Create variable with "sizes" @var{nx}x@var{ny}x@var{nz} which changes from @var{v1} to @var{v2} (or is constant if @var{v2}=@code{NaN}) along @var{dir} direction.
+@end deftypefn
+@deftypefn {Method on @code{mglDataV}} @code{void} Create (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
+Set "sizes" @var{nx}x@var{ny}x@var{nz}.
+@end deftypefn
+@deftypefn {Method on @code{mglDataV}} @code{void} Fill (@code{mreal} x1, @code{mreal} x2=@code{NaN}, @code{char} dir=@code{'x'})
+Set ranges of the variable.
+@end deftypefn
+@deftypefn {Method on @code{mglDataV}} @code{void} Freq (@code{mreal} dp, @code{char} dir=@code{'x'})
+Set as frequency variable with increment @var{dp}.
+@end deftypefn
 
-@deftypecv {Variable} mglVar @code{bool} temp
-Flag of the temporary variable. If @code{true} the this variable will be removed after script execution.
-@end deftypecv
+@heading Class @code{mglDataF}
+represent function which values are evaluated (instead of access to data array as in @code{mglData}).
+@deftypefn {Constructor on @code{mglDataF}} @code{} mglDataF (@code{const mglDataF &} d)
+Copy constructor.
+@end deftypefn
+@deftypefn {Constructor on @code{mglDataF}} @code{} mglDataF (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
+Create variable with "sizes" @var{nx}x@var{ny}x@var{nz} with zero function.
+@end deftypefn
+@deftypefn {Method on @code{mglDataF}} @code{void} Create (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
+Set "sizes" @var{nx}x@var{ny}x@var{nz}.
+@end deftypefn
+@deftypefn {Method on @code{mglDataF}} @code{void} SetRanges (@code{mglPoint} p1, @code{mglPoint} p2)
+Set ranges for internal x,y,z variables.
+@end deftypefn
+@deftypefn {Method on @code{mglDataF}} @code{void} SetFormula (@code{const char *}func)
+Set string which will be evaluated at function calls. Note this variant is about 10 times slower than @code{SetFunc}() one.
+@end deftypefn
+@deftypefn {Method on @code{mglDataF}} @code{void} SetFunc (@code{mreal (*}f@code{)(mreal x,mreal y,mreal z,void *p)}, @code{void *}p=@code{NULL})
+Set pointer to function which will be used for data.
+@end deftypefn
 
-@deftypecv {Variable} mglVar @code{void} @code{void (*}func@code{)(void *)}
-Callback function, which will be called at variable destroying.
-@end deftypecv
+@heading Class @code{mglDataT}
+represent named reference to column of another data array.
+@deftypefn {Constructor on @code{mglDataT}} @code{} mglDataT (@code{const mglDataT &} d)
+Copy constructor.
+@end deftypefn
+@deftypefn {Constructor on @code{mglDataT}} @code{} mglDataT (@code{const mglDataA &} d, @code{long} col=@code{0})
+Create variable which reference @var{col}-th column of data @var{d}.
+@end deftypefn
+@deftypefn {Method on @code{mglDataT}} @code{void} SetInd (@code{long} col, @code{wchar_t} name)
+@deftypefnx {Method on @code{mglDataT}} @code{void} SetInd (@code{long} col, @code{const wchar_t *} name)
+Set reference to another column of the same data and its name.
+@end deftypefn
 
-@deftypecv {Variable} mglVar @code{void *} o
-Pointer to external object for callback function.
-@end deftypecv
 
-@deftypefn {Constructor on @code{mglVar}} @code{} mglVar ()
-Create variable with size 1*1*1.
+@heading Class @code{mglDataR}
+represent named reference to row of another data array.
+@deftypefn {Constructor on @code{mglDataR}} @code{} mglDataR (@code{const mglDataR &} d)
+Copy constructor.
 @end deftypefn
-
-@deftypefn {Destructor on @code{mglVar}} @code{} ~mglVar ()
-Deletes the instance of class mglVar.
+@deftypefn {Constructor on @code{mglDataR}} @code{} mglDataR (@code{const mglDataA &} d, @code{long} row=@code{0})
+Create variable which reference @var{row}-th row of data @var{d}.
 @end deftypefn
-
-@deftypefn {Method on @code{mglVar}} @code{void} MoveAfter (@code{mglVar *}var)
-Move variable after @var{var} in the list.
+@deftypefn {Method on @code{mglDataR}} @code{void} SetInd (@code{long} row, @code{wchar_t} name)
+@deftypefnx {Method on @code{mglDataR}} @code{void} SetInd (@code{long} row, @code{const wchar_t *} name)
+Set reference to another row of the same data and its name.
 @end deftypefn
 
 @end ifclear
index a5c82caa0148a2131ab028fd7449fb25e41eb489..01afc69d8077197a9fb4b154996b0dbbcdabb229 100644 (file)
@@ -23,7 +23,7 @@
 * Operators::
 * Global functions::
 * Evaluate expression::
-* MGL variables::
+* Special data classes::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -62,6 +62,19 @@ MGL не поддерживает прямой доступ к элемента
 Флаг использования указателя на внешние данные, включает запрет на удаление массива данных.
 @end deftypecv
 
+@deftypecv {Variable} mglDataA @code{std::wstring} s
+Имя массива данных, использующееся при разборе MGL скриптов.
+@end deftypecv
+@deftypecv {Variable} mglDataA @code{bool} temp
+Флаг временной переменной, которая может быть удалена в любой момент.
+@end deftypecv
+@deftypecv {Variable} mglDataA @code{void (*)(void *)} func
+Указатель на callback функцию, которая будет вызвана при удлалении данных.
+@end deftypecv
+@deftypecv {Variable} mglDataA @code{void *} o
+Указатель для callback функции.
+@end deftypecv
+
 @deftypefn {Метод класса @code{mglData}} @code{mreal} GetVal (@code{long} i)
 @deftypefnx {Метод класса @code{mglDataC}} @code{mreal} GetVal (@code{long} i)
 @deftypefnx {Метод класса @code{mglData}} @code{void} SetVal (@code{mreal} val, @code{long} i)
@@ -69,12 +82,9 @@ MGL не поддерживает прямой доступ к элемента
 Присваивает или возвращает значение используя "непрерывную" индексацию без проверки выхода за границы массива. Индекс @var{i} должен быть в диапазоне [0, nx*ny*nz-1].
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData}} @code{long} GetNx ()
-@deftypefnx {Метод класса @code{mglDataC}} @code{long} GetNx ()
-@deftypefnx {Метод класса @code{mglData}} @code{long} GetNy ()
-@deftypefnx {Метод класса @code{mglDataC}} @code{long} GetNy ()
-@deftypefnx {Метод класса @code{mglData}} @code{long} GetNz ()
-@deftypefnx {Метод класса @code{mglDataC}} @code{long} GetNz ()
+@deftypefn {Метод класса @code{mglDataA}} @code{long} GetNx ()
+@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNy ()
+@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNz ()
 @deftypefnx {Функция С} @code{long} mgl_data_get_nx (@code{HCDT} dat)
 @deftypefnx {Функция С} @code{long} mgl_data_get_ny (@code{HCDT} dat)
 @deftypefnx {Функция С} @code{long} mgl_data_get_nz (@code{HCDT} dat)
@@ -92,6 +102,16 @@ MGL не поддерживает прямой доступ к элемента
 @deftypefn {Функция С} @code{const mreal *} mgl_data_data (@code{HCDT} dat)
 Возвращает указатель на внутренний массив данных.
 @end deftypefn
+
+@deftypefn {Функция С} @code{void} mgl_data_set_func (@code{mglDataA *}dat, @code{void (*}func@code{)(void *)}, @code{void *}par)
+Задает указатель на callback функцию, которая будет вызвана при удлалении данных.
+@end deftypefn
+
+@deftypefn {Функция С} @code{void} mgl_data_set_name (@code{mglDataA *}dat, @code{const char *}name)
+@deftypefnx {Функция С} @code{void} mgl_data_set_name_w (@code{mglDataA *}dat, @code{const wchar_t *}name)
+Задает имя массива данных, использующееся при разборе MGL скриптов.
+@end deftypefn
+
 @end ifclear
 
 @c ------------------------------------------------------------------
@@ -528,6 +548,15 @@ a_ij^new = a_i^old where j=0...@var{n1}. Соответственно, для @v
 Заполняет значениями интерполяции массива @var{v} в точках @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i], Y[j], Z[k]}@} (или @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i,j,k], Y[i,j,k], Z[i,j,k]}@} если @var{x}, @var{y}, @var{z} не 1d массивы), где @code{X,Y,Z} равномерно распределены в диапазоне [@var{x1},@var{x2}]*[@var{y1},@var{y2}]*[@var{z1},@var{z2}] и имеют такой же размер как и заполняемый массив. Если параметр @var{sl} равен 0 или положительный, то изменятся будет только @var{sl}-ый срез.
 @end deftypefn
 
+@anchor{gspline}
+@deftypefn {MGL command} {} gspline dat xdat vdat [sl=-1]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} RefillGS (@code{const mglDataA &}x, @code{const mglDataA &}v, @code{mreal} x1, @code{mreal} x2, @code{long} sl=@code{-1})
+@deftypefnx {C function} @code{void} mgl_data_refill_gs (@code{HMDT} a, @code{HCDT} x, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{long} sl)
+@end ifclear
+Заполняет значениями глобального кубического сплайна для массива @var{v} в точках @var{x}=@code{X[i]}, где @code{X} равномерно распределен в диапазоне [@var{x1},@var{x2}] и имеет такой же размер как и заполняемый массив. Если параметр @var{sl} равен 0 или положительный, то изменятся будет только @var{sl}-ый срез.
+@end deftypefn
+
 @anchor{idset}
 @deftypefn {Команда MGL} {} idset dat 'ids'
 @ifclear UDAV
@@ -611,8 +640,7 @@ a_ij^new = a_i^old where j=0...@var{n1}. Соответственно, для @v
 @anchor{save}
 @deftypefn {Команда MGL} {} save dat 'fname'
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
 @deftypefnx {Функция С} @code{void} mgl_data_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
 @deftypefnx {Функция С} @code{void} mgl_datac_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
 @end ifclear
@@ -633,8 +661,7 @@ a_ij^new = a_i^old where j=0...@var{n1}. Соответственно, для @v
 @anchor{savehdf}
 @deftypefn {Команда MGL} {} savehdf dat 'fname' 'dname'
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
 @deftypefnx {Функция С} @code{void} mgl_data_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
 @deftypefnx {Функция С} @code{void} mgl_datac_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
 @end ifclear
@@ -644,8 +671,7 @@ a_ij^new = a_i^old where j=0...@var{n1}. Соответственно, для @v
 @anchor{datas}
 @deftypefn {Команда MGL} {} datas 'fname'
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{void} DatasHDF (@code{const char *}fname, @code{char *}buf, @code{long} size) @code{static}
-@deftypefnx {Метод класса @code{mglDataC}} @code{int} DatasHDF (@code{const char *}fname, @code{char *}buf, @code{long} size) @code{static}
+@deftypefnx {Метод класса @code{mglDataA}} @code{int} DatasHDF (@code{const char *}fname, @code{char *}buf, @code{long} size) @code{static}
 @deftypefnx {Функция С} @code{void} mgl_datas_hdf (@code{const char *}fname, @code{char *}buf, @code{long} size)
 @end ifclear
 Помещает имена массивов данных в HDF5 файле @var{fname} в строку @var{buf} разделёнными символом табуляции '\t'. В версии MGL имена массивов будут выведены как сообщение. Функция ничего не делает если библиотека была собрана без поддержки HDF5.
@@ -663,7 +689,7 @@ a_ij^new = a_i^old where j=0...@var{n1}. Соответственно, для @v
 @anchor{export}
 @deftypefn {Команда MGL} {} export dat 'fname' 'sch' [@code{v1=0 v2=0}]
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{void} Export (@code{const char *}fname, @code{const char *}scheme, @code{mreal} v1=@code{0}, mreal v2=@code{0}, @code{int} ns=@code{-1}) const
+@deftypefnx {Метод класса @code{mglDataA}} @code{void} Export (@code{const char *}fname, @code{const char *}scheme, @code{mreal} v1=@code{0}, mreal v2=@code{0}, @code{int} ns=@code{-1}) const
 @deftypefnx {Функция С} @code{void} mgl_data_export (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{mreal} v1, mreal v2, @code{int} ns) const
 @end ifclear
 Сохраняет данные в растровый файл. Числовые значения, нормированные в диапазон [@var{v1}, @var{v2}], преобразуются в RGB значения пикселов, используя цветовую схему @var{sch} (@pxref{Color scheme}). Если @var{v1}>=@var{v2}, то значения @var{v1}, @var{v2} определяются автоматически как минимальное и максимальное значение данных.
@@ -1083,7 +1109,7 @@ These functions change the data in some direction like differentiations, integra
 @section Интерполяция
 @nav{}
 
-СкÑ\80ипÑ\82Ñ\8b MGL Ð¼Ð¾Ð³Ñ\83Ñ\82 Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ð»Ð¸Ð½ÐµÐ¹Ð½Ñ\83Ñ\8e Ð¸Ð½Ñ\82еÑ\80полÑ\8fÑ\86иÑ\8e Ñ\81 Ð¿Ð¾Ð¼Ð¾Ñ\89Ñ\8cÑ\8e ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\8b @ref{subdata}, Ð¸Ð»Ð¸ ÐºÑ\83биÑ\87еÑ\81кие Ñ\81плайнÑ\8b Ð¿Ñ\80и Ð¸Ñ\81полÑ\8cзовании ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\8b @ref{evaluate}. Также можно использовать @ref{resize} для массива с новыми размерами.
+СкÑ\80ипÑ\82Ñ\8b MGL Ð¼Ð¾Ð³Ñ\83Ñ\82 Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ð¸Ð½Ñ\82еÑ\80полÑ\8fÑ\86иÑ\8e ÐºÑ\83биÑ\87еÑ\81кими Ñ\81плайнами Ñ\81 Ð¿Ð¾Ð¼Ð¾Ñ\89Ñ\8cÑ\8e ÐºÐ¾Ð¼Ð°Ð½Ð´ @ref{evaluate} Ð¸Ð»Ð¸ @ref{refill}. Также можно использовать @ref{resize} для массива с новыми размерами.
 
 @ifclear UDAV
 
@@ -1153,11 +1179,10 @@ These functions change the data in some direction like differentiations, integra
 @anchor{info}
 @deftypefn {Команда MGL} {} info dat
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{const char *} PrintInfo () @code{const}
-@deftypefnx {Метод класса @code{mglData}} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{const char *} PrintInfo () @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{const char *} PrintInfo () @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
 @deftypefnx {Функция С} @code{const char *} mgl_data_info (@code{HCDT} dat)
+@deftypefnx {Fortran процедура} @code{} mgl_data_info (@code{long} dat, @code{char *}out, @code{int} len)
 @end ifclear
 Возвращает строку с информацией о данных (размеры, моменты и пр.) или пишет её в файл. В MGL скрипте печатает её как сообщение.
 @end deftypefn
@@ -1178,12 +1203,9 @@ These functions change the data in some direction like differentiations, integra
 @deftypefnx {MGL suffix} {(dat)} .ny
 @deftypefnx {MGL suffix} {(dat)} .nz
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{long} GetNx ()
-@deftypefnx {Метод класса @code{mglData}} @code{long} GetNy ()
-@deftypefnx {Метод класса @code{mglData}} @code{long} GetNz ()
-@deftypefnx {Метод класса @code{mglDataC}} @code{long} GetNx ()
-@deftypefnx {Метод класса @code{mglDataC}} @code{long} GetNy ()
-@deftypefnx {Метод класса @code{mglDataC}} @code{long} GetNz ()
+@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNx ()
+@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNy ()
+@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNz ()
 @deftypefnx {Функция С} @code{long} mgl_data_get_nx (@code{HCDT} dat)
 @deftypefnx {Функция С} @code{long} mgl_data_get_ny (@code{HCDT} dat)
 @deftypefnx {Функция С} @code{long} mgl_data_get_nz (@code{HCDT} dat)
@@ -1197,8 +1219,7 @@ These functions change the data in some direction like differentiations, integra
 @anchor{.max}
 @deftypefn {MGL suffix} {(dat)} .max
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{mreal} Maximal () @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{mreal} Maximal () @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Maximal () @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_max (@code{HCDT} dat)
 @end ifclear
 Возвращает максимальное значение массива данных.
@@ -1208,26 +1229,22 @@ These functions change the data in some direction like differentiations, integra
 @anchor{.min}
 @deftypefn {MGL suffix} {(dat)} .min
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{mreal} Minimal () @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{mreal} Minimal () @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Minimal () @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_min (@code{HMDT} dat) @code{const}
 @end ifclear
 Возвращает минимальное значение массива данных.
 @end deftypefn
 
 @ifclear UDAV
-@deftypefn {Метод класса @code{mglData}} @code{mreal} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{mreal} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefn {Метод класса @code{mglDataA}} @code{mreal} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_min_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
 Возвращает максимальное значение массива данных и сохраняет его положение в переменные @var{i}, @var{j}, @var{k}.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData}} @code{mreal} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{mreal} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefn {Метод класса @code{mglDataA}} @code{mreal} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_max_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
 Возвращает минимальное значение массива данных и сохраняет его положение в переменные @var{i}, @var{j}, @var{k}.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData}} @code{mreal} Minimal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{mreal} Minimal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
+@deftypefn {Метод класса @code{mglDataA}} @code{mreal} Minimal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_min_real (@code{HCDT} dat, @code{mreal} *x, @code{mreal} *y, @code{mreal} *z)
 Возвращает максимальное значение массива данных и его приближенное (интерполированное) положение в переменные @var{x}, @var{y}, @var{z}.
 @end deftypefn
@@ -1238,8 +1255,7 @@ These functions change the data in some direction like differentiations, integra
 @deftypefnx {MGL suffix} {(dat)} .my
 @deftypefnx {MGL suffix} {(dat)} .mz
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{mreal} Maximal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
-@deftypefnx {Метод класса @code{mglDataC}} @code{mreal} Maximal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Maximal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_max_real (@code{HCDT} dat, @code{mreal} *x, @code{mreal} *y, @code{mreal} *z)
 @end ifclear
 Возвращает минимальное значение массива данных и его приближенное (интерполированное) положение в переменные @var{x}, @var{y}, @var{z}.
@@ -1269,8 +1285,8 @@ These functions change the data in some direction like differentiations, integra
 @deftypefnx {MGL suffix} {(dat)} .kz
 @deftypefnx {MGL suffix} {(dat)} .ka
 @ifclear UDAV
-@deftypefnx {Метод класса @code{mglData}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &a, @code{mreal} &w) @code{const}
-@deftypefnx {Метод класса @code{mglData}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &m, @code{mreal} &w, @code{mreal} &s, @code{mreal} &k) @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &a, @code{mreal} &w) @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &m, @code{mreal} &w, @code{mreal} &s, @code{mreal} &k) @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_momentum_val (@code{HCDT} dat, @code{char} dir, @code{mreal} *a, @code{mreal} *w, @code{mreal} *s, @code{mreal} *k)
 @end ifclear
 Возвращает нулевой момент (энергию, @math{I=\sum a_i}) и записывает первый (среднее, @math{m = \sum \xi_i a_i/I}), второй (ширину, @math{w^2 = \sum (\xi_i-m)^2 a_i/I}), третий (асимметрия, @math{s = \sum (\xi_i-m)^3 a_i/ I w^3}) и четвёртый моменты (эксцесс, @math{k = \sum (\xi_i-m)^4 a_i / 3 I w^4})). Здесь @math{\xi} -- соответствующая координата если @var{dir} равно @samp{'x'}, @samp{'y'}, @samp{'z'}. В противном случае среднее, ширина, асимметрия, эксцесс равны @math{m = \sum a_i/N}, @math{w^2 = \sum (a_i-m)^2/N} и т.д.
@@ -1280,7 +1296,7 @@ These functions change the data in some direction like differentiations, integra
 @deftypefn {MGL suffix} {(dat)} .fst
 @ifclear UDAV
 @cindex Find
-@deftypefnx {Метод класса @code{mglData}} @code{mreal} Find (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Find (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_first (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
 @end ifclear
 Находит положение (после заданного в @var{i}, @var{j}, @var{k}) первого не нулевого значения формулы @var{cond}. Функция возвращает найденное значение и записывает его положение в @var{i}, @var{j}, @var{k}.
@@ -1290,19 +1306,19 @@ These functions change the data in some direction like differentiations, integra
 @deftypefn {MGL suffix} {(dat)} .lst
 @ifclear UDAV
 @cindex Last
-@deftypefnx {Метод класса @code{mglData}} @code{mreal} Last (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Last (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_last (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
 @end ifclear
 Находит положение (перед заданного в @var{i}, @var{j}, @var{k}) последнего не нулевого значения формулы @var{cond}. Функция возвращает найденное значение и записывает его положение в @var{i}, @var{j}, @var{k}.
 @end deftypefn
 
 @ifclear UDAV
-@deftypefn {Метод класса @code{mglData}} @code{int} Find (@code{const char *}cond, @code{char} dir, @code{int} i=@code{0}, @code{int} j=@code{0}, @code{int} k=@code{0}) @code{const}
+@deftypefn {Метод класса @code{mglDataA}} @code{int} Find (@code{const char *}cond, @code{char} dir, @code{int} i=@code{0}, @code{int} j=@code{0}, @code{int} k=@code{0}) @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_find (@code{HCDT} dat, @code{const char *}cond, @code{int} i, @code{int} j, @code{int} k)
 Возвращает положение первого в направлении @var{dir} не нулевого значения формулы @var{cond}. Поиск начинается с точки @{i,j,k@}.
 @end deftypefn
 @cindex FindAny
-@deftypefn {Метод класса @code{mglData}} @code{bool} FindAny (@code{const char *}cond) @code{const}
+@deftypefn {Метод класса @code{mglDataA}} @code{bool} FindAny (@code{const char *}cond) @code{const}
 @deftypefnx {Функция С} @code{mreal} mgl_data_find_any (@code{HCDT} dat, @code{const char *}cond)
 Определяет есть ли хоть одно значение массива, удовлетворяющее условию @var{cond}.
 @end deftypefn
@@ -1471,14 +1487,45 @@ These functions change the data in some direction like differentiations, integra
 Решает систему геометрооптических уравнений d@emph{r}/dt = d @var{ham}/d@emph{p}, d@emph{p}/dt = -d @var{ham}/d@emph{r}. Это гамильтоновы уравнения для траектории частицы в 3D случае. Гамильтониан @var{ham} может зависеть от координат @samp{x}, @samp{y}, @samp{z}, импульсов @samp{p}=px, @samp{q}=py, @samp{v}=pz и времени @samp{t}: @math{ham = H(x,y,z,p,q,v,t)}. Начальная точка (при @code{t=0}) задается переменными @{@var{x0}, @var{y0}, @var{z0}, @var{p0}, @var{q0}, @var{v0}@}. Параметры @var{dt} и @var{tmax} задают шаг и максимальное время интегрирования. Результат -- массив @{x,y,z,p,q,v,t@} с размером @{7 * int(@var{tmax}/@var{dt}+1) @}.
 @end deftypefn
 
+@anchor{ode}
+@deftypefn {MGL command} {} ode @sc{res} 'df' 'var' ini [@code{dt=0.1 tmax=10}]
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglODE (@code{const char *}df, @code{const char *}var, @code{const mglDataA &}ini, @code{mreal} dt=@code{0.1}, @code{mreal} tmax=@code{10})
+@deftypefnx {C function} @code{HMDT} mgl_ode_solve_str (@code{const char *}df, @code{const char *}var, @code{HCDT} ini, @code{mreal} dt, @code{mreal} tmax)
+@deftypefnx {C function} @code{HMDT} mgl_ode_solve (@code{void (*}df@code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax)
+@deftypefnx {C function} @code{HMDT} mgl_ode_solve_ex (@code{void (*}df@code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax, @code{void (*}bord@code{)(mreal *x, const mreal *xprev, void *par)})
+@end ifclear
+Решает систему обыкновенных дифференциальных уравнений dx/dt = df(x). Функции @var{df} могут быть заданны строкой с разделенными ';' формулами (аргумент @var{var} задает символы для переменных x[i]) или указателем на функцию, которая заполняет @code{dx} по заданным значениям @code{x}. Параметры @var{ini}, @var{dt}, @var{tmax} задают начальные значения, шаг и максимальное время интегрирования. Результат -- массив с размером @{@var{n} * int(@var{tmax}/@var{dt}+1)@}.
+@end deftypefn
+
 @anchor{qo2d}
 @deftypefn {Команда MGL} {} qo2d @sc{res} 'ham' ini_re ini_im ray [@code{r=1 k0=100} xx yy]
 @ifclear UDAV
 @deftypefnx {Global function} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100}, @code{mglData *}xx=@code{0}, @code{mglData *}yy=@code{0})
 @deftypefnx {Global function} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglDataC} mglQO2dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglDataC} mglQO2dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
 @deftypefnx {Функция С} @code{HMDT} mgl_qo2d_solve (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
+@deftypefnx {Функция С} @code{HADT} mgl_qo2d_solve_c (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
+@deftypefnx {Функция С} @code{HMDT} mgl_qo2d_func (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
+@deftypefnx {Функция С} @code{HADT} mgl_qo2d_func_c (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
 @end ifclear
-Решает уравнение в частных производных du/dt = i*k0*@var{ham}(p,q,x,y,|u|)[u] в сопровождающей системе координат, где p=-i/k0*d/dx, q=-i/k0*d/dy -- псевдо-дифференциальные операторы. Параметры @var{ini_re}, @var{ini_im} задают начальное распределение поля. Параметр @var{ray} задает опорный луч для сопровождающей системы координат. Можно использовать луч найденный с помощью @code{mglRay()}. Опорный луч должен быть достаточно гладкий, чтобы система координат была однозначной и для исключения ошибок интегрирования. Если массивы @var{xx} и @var{yy} указаны, то в них записываются декартовы координаты для каждой точки найденного решения. См. также @code{mglPDE()}. @sref{PDE solving hints}
+Решает уравнение в частных производных du/dt = i*k0*@var{ham}(p,q,x,y,|u|)[u] в сопровождающей системе координат, где p=-i/k0*d/dx, q=-i/k0*d/dy -- псевдо-дифференциальные операторы. Параметры @var{ini_re}, @var{ini_im} задают начальное распределение поля. Параметр @var{ray} задает опорный луч для сопровождающей системы координат. Можно использовать луч найденный с помощью @ref{ray}. Опорный луч должен быть достаточно гладкий, чтобы система координат была однозначной и для исключения ошибок интегрирования. Если массивы @var{xx} и @var{yy} указаны, то в них записываются декартовы координаты для каждой точки найденного решения. См. также @ref{pde}, @ref{qo3d}. @sref{PDE solving hints}
+@end deftypefn
+
+@anchor{qo3d}
+@deftypefn {Команда MGL} {} qo3d @sc{res} 'ham' ini_re ini_im ray [@code{r=1 k0=100} xx yy zz]
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglQO3d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglData} mglQO3d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mglData &}zz, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglDataC} mglQO3dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Global function} @code{mglDataC} mglQO3dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mglData &}zz, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
+@deftypefnx {Функция С} @code{HMDT} mgl_qo3d_solve (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
+@deftypefnx {Функция С} @code{HADT} mgl_qo3d_solve_c (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
+@deftypefnx {Функция С} @code{HMDT} mgl_qo3d_func (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
+@deftypefnx {Функция С} @code{HADT} mgl_qo3d_func_c (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
+@end ifclear
+Решает уравнение в частных производных du/dt = i*k0*@var{ham}(p,q,v,x,y,z,|u|)[u] в сопровождающей системе координат, где p=-i/k0*d/dx, q=-i/k0*d/dy, v=-i/k0*d/dz -- псевдо-дифференциальные операторы. Параметры @var{ini_re}, @var{ini_im} задают начальное распределение поля. Параметр @var{ray} задает опорный луч для сопровождающей системы координат. Можно использовать луч найденный с помощью @ref{ray}. Опорный луч должен быть достаточно гладкий, чтобы система координат была однозначной и для исключения ошибок интегрирования. Если массивы @var{xx}, @var{yy} и @var{zz} указаны, то в них записываются декартовы координаты для каждой точки найденного решения. См. также @ref{pde}, @ref{qo2d}.
 @end deftypefn
 
 @anchor{jacobian}
@@ -1505,9 +1552,27 @@ These functions change the data in some direction like differentiations, integra
 @end deftypefn
 
 
+@ifclear UDAV
+
+@deftypefn {Global function} @code{mglData} mglGSplineInit (@code{const mglDataA &}x, @code{const mglDataA &}y)
+@deftypefnx {Global function} @code{mglDataC} mglGSplineCInit (@code{const mglDataA &}x, @code{const mglDataA &}y)
+@deftypefnx {Функция С} @code{HMDT} mgl_gspline_init (@code{HCDT} x, @code{HCDT} y)
+@deftypefnx {Функция С} @code{HADT} mgl_gsplinec_init (@code{HCDT} x, @code{HCDT} y)
+Подготавливает коэффициенты для глобального кубического сплайна.
+@end deftypefn
+
+@deftypefn {Global function} @code{mreal} mglGSpline (@code{const mglDataA &}coef, @code{mreal} dx, @code{mreal *}d1=@code{0}, @code{mreal *}d2=@code{0})
+@deftypefnx {Global function} @code{dual} mglGSplineC (@code{const mglDataA &}coef, @code{mreal} dx, @code{dual *}d1=@code{0}, @code{dual *}d2=@code{0})
+@deftypefnx {Функция С} @code{mreal} mgl_gspline (@code{HCDT} coef, @code{mreal} dx, @code{mreal *}d1, @code{mreal *}d2)
+@deftypefnx {Функция С} @code{dual} mgl_gsplinec (@code{HCDT} coef, @code{mreal} dx, @code{dual *}d1, @code{dual *}d2)
+Вычисляет глобальный кубический сплайн (а также 1ую и 2ую производные @var{d1}, @var{d2} если они не @code{NULL}), используя коэффициенты @var{coef} в точке @var{dx}+@var{x0} (здесь @var{x0} -- 1ый элемент массива @var{x} в функции @code{mglGSpline*Init()}).
+@end deftypefn
+
+@end ifclear
+
 @c ------------------------------------------------------------------
 @external{}
-@node Evaluate expression, MGL variables, Global functions, Data processing
+@node Evaluate expression, Special data classes, Global functions, Data processing
 @section Вычисление выражений
 @nav{}
 
@@ -1561,49 +1626,81 @@ These functions change the data in some direction like differentiations, integra
 
 @c ------------------------------------------------------------------
 @external{}
-@node MGL variables, , Evaluate expression, Data processing
-@section Переменные MGL
+@node Special data classes, , Evaluate expression, Data processing
+@section Special data classes
 @nav{}
 
 @ifset UDAV
-Для информации о переменных MGL см. @ref{MGL definition}.
+MGL использует специальные классы автоматически.
 @end ifset
 
 @ifclear UDAV
+Раздел описывает специальные классы данных @code{mglDataV}, @code{mglDataF}, @code{mglDataT} и @code{mglDataR}, которые могут заметно ускорить рисование и обработку данных. Классы определены в @code{#include <mgl2/data.h>}. Отмечу, что все функции рисования и обработки данных можно выполнить используя только основные классы @code{mglData} и/или @code{mglDataC}. Также специальные классы доступны только в коде на С++.
 
-Класс mglVar содержит переменную/массив скрипта MGL и используется при разборе MGL скриптов (см. @ref{mglParse class}). Это класс наследник @code{mglData} и определен в @code{#include <mgl2/mgl.h>}.
-
-@deftypecv {Variable} mglVar @code{std::wstring} s
-Имя переменной в скрипте.
-@end deftypecv
-
-@deftypecv {Variable} mglVar @code{mglVar *} next
-@deftypecvx {Variable} mglVar @code{mglVar *} prev
-Следующая и предыдущая переменная в списке.
-@end deftypecv
+@heading Класс @code{mglDataV}
+представляет переменную со значениями равнораспределенными в заданном интервале.
+@deftypefn {Конструктор @code{mglDataV}} @code{} mglDataV (@code{const mglDataV &} d)
+Конструктор копирования.
+@end deftypefn
+@deftypefn {Конструктор @code{mglDataV}} @code{} mglDataV (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1}, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{NaN}, @code{char} dir=@code{'x'})
+Создает переменную "размером" @var{nx}x@var{ny}x@var{nz}, изменяющуюся от @var{v1} до @var{v2} (или постоянную при @var{v2}=@code{NaN}) вдоль направления @var{dir}.
+@end deftypefn
+@deftypefn {Метод класса @code{mglDataV}} @code{void} Create (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
+Задает "размеры" переменной @var{nx}x@var{ny}x@var{nz}.
+@end deftypefn
+@deftypefn {Метод класса @code{mglDataV}} @code{void} Fill (@code{mreal} x1, @code{mreal} x2=@code{NaN}, @code{char} dir=@code{'x'})
+Задает диапазон изменения переменной.
+@end deftypefn
+@deftypefn {Метод класса @code{mglDataV}} @code{void} Freq (@code{mreal} dp, @code{char} dir=@code{'x'})
+Задает переменную для частоты с шагом @var{dp}.
+@end deftypefn
 
-@deftypecv {Variable} mglVar @code{bool} temp
-Флаг временной переменной. Если @code{true}, то переменная будет удалена после выполнения скрипта.
-@end deftypecv
+@heading Класс @code{mglDataF}
+представляет функцию, которая будет вызываться вместо обращения к элементам массива (как в классе @code{mglData}).
+@deftypefn {Конструктор @code{mglDataF}} @code{} mglDataF (@code{const mglDataF &} d)
+Конструктор копирования.
+@end deftypefn
+@deftypefn {Конструктор @code{mglDataF}} @code{} mglDataF (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
+Создает данные "размером" @var{nx}x@var{ny}x@var{nz} с нулевой функцией.
+@end deftypefn
+@deftypefn {Метод класса @code{mglDataF}} @code{void} Create (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
+Задает "размеры" данных @var{nx}x@var{ny}x@var{nz}.
+@end deftypefn
+@deftypefn {Метод класса @code{mglDataF}} @code{void} SetRanges (@code{mglPoint} p1, @code{mglPoint} p2)
+Задает диапазоны изменения внутренних переменных x,y,z.
+@end deftypefn
+@deftypefn {Метод класса @code{mglDataF}} @code{void} SetFormula (@code{const char *}func)
+Задает строку, которая будет разобрана в функцию. Это вариант более чем 10 раз медленнее в сравнении с @code{SetFunc}().
+@end deftypefn
+@deftypefn {Метод класса @code{mglDataF}} @code{void} SetFunc (@code{mreal (*}f@code{)(mreal x,mreal y,mreal z,void *p)}, @code{void *}p=@code{NULL})
+Задает указатель на функцию, которая будет использована вместо доступа к элементам массива.
+@end deftypefn
 
-@deftypecv {Variable} mglVar @code{void (*}func@code{)(void *)}
-Callback функция, вызываемая при удалении переменной.
-@end deftypecv
+@heading Класс @code{mglDataT}
+представляет именнованную ссылку на столбец в другом массиве данных.
+@deftypefn {Конструктор @code{mglDataT}} @code{} mglDataT (@code{const mglDataT &} d)
+Конструктор копирования.
+@end deftypefn
+@deftypefn {Конструктор @code{mglDataT}} @code{} mglDataT (@code{const mglDataA &} d, @code{long} col=@code{0})
+Создает ссылку на @var{col}-ый столбец данных @var{d}.
+@end deftypefn
+@deftypefn {Метод класса @code{mglDataT}} @code{void} SetInd (@code{long} col, @code{wchar_t} name)
+@deftypefnx {Метод класса @code{mglDataT}} @code{void} SetInd (@code{long} col, @code{const wchar_t *} name)
+Задает ссылку на другой столбец того же массива данных.
+@end deftypefn
 
-@deftypecv {Variable} mglVar @code{void *} o
-Указатель на внешний объект, передаваемый callback функции.
-@end deftypecv
 
-@deftypefn {Constructor on @code{mglVar}} @code{} mglVar ()
-Создает переменную с размерами 1*1*1.
+@heading Класс @code{mglDataR}
+представляет именнованную ссылку на строку в другом массиве данных.
+@deftypefn {Конструктор @code{mglDataR}} @code{} mglDataR (@code{const mglDataR &} d)
+Конструктор копирования.
 @end deftypefn
-
-@deftypefn {Destructor on @code{mglVar}} @code{} ~mglVar ()
-Удаляет переменную mglVar.
+@deftypefn {Конструктор @code{mglDataR}} @code{} mglDataR (@code{const mglDataA &} d, @code{long} row=@code{0})
+Создает ссылку на @var{row}-ую строку данных @var{d}.
 @end deftypefn
-
-@deftypefn {Метод класса @code{mglVar}} @code{void} MoveAfter (@code{mglVar *}var)
\9fеÑ\80емеÑ\89аеÑ\82 Ð¿ÐµÑ\80еменнÑ\83Ñ\8e Ð¿Ð¾Ñ\81ле @var{var} Ð² Ñ\81пиÑ\81ке Ð¿ÐµÑ\80еменных.
+@deftypefn {Метод класса @code{mglDataR}} @code{void} SetInd (@code{long} row, @code{wchar_t} name)
+@deftypefnx {Метод класса @code{mglDataR}} @code{void} SetInd (@code{long} row, @code{const wchar_t *} name)
\97адаеÑ\82 Ñ\81Ñ\81Ñ\8bлкÑ\83 Ð½Ð° Ð´Ñ\80Ñ\83гой Ñ\81Ñ\82олбеÑ\86 Ñ\82ого Ð¶Ðµ Ð¼Ð°Ñ\81Ñ\81ива Ð´Ð°нных.
 @end deftypefn
 
 @end ifclear
index 3dcd007ff79a4463cf60a4027c630fa500738d62..1e46da6a067ffbbefff6fe979bf25e3b4ac6f79d 100644 (file)
@@ -72,44 +72,45 @@ This file documents the Mathematical Graphic Library (MathGL), a collection of c
 <tr><td style="padding-left: 5px;font-size: 110%"> <a target=_blank href="http://groups.google.com/group/mathgl"><b>MathGL</b></a> </td></tr>
 </table>
 
-<hr style="width: 100%; height: 1px;">
-<script type="text/javascript"><!--
-google_ad_client = "ca-pub-1128070552722622";
-/* Vertical small */
-google_ad_slot = "5501954624";
-google_ad_width = 120;
-google_ad_height = 240;
-//-->
-</script>
-<script type="text/javascript"
-src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-</script></nav>
+@comment  <hr style="width: 100%; height: 1px;">
+@comment  <script type="text/javascript"><!--
+@comment  google_ad_client = "ca-pub-1128070552722622";
+@comment  /* Vertical small */
+@comment  google_ad_slot = "5501954624";
+@comment  google_ad_width = 120;
+@comment  google_ad_height = 240;
+@comment  //-->
+@comment  </script>
+@comment  <script type="text/javascript"
+@comment  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+@comment  </script>
+</nav>
 @end html
 @end macro
 
 @macro external {}
 @html
-<br><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
-<!-- Ref 728x15 -->
-<ins class="adsbygoogle"
-style="display:inline-block;width:728px;height:15px"
-data-ad-client="ca-pub-1128070552722622"
-data-ad-slot="7008431385"></ins>
-<script>
-(adsbygoogle = window.adsbygoogle || []).push({});
-</script><br>
-
-<script type="text/javascript"><!--
-google_ad_client = "ca-pub-1128070552722622";
-/* 728x90, создано 23.12.09 */
-google_ad_slot = "9958083480";
-google_ad_width = 728;
-google_ad_height = 90;
-//-->
-</script>
-<script type="text/javascript"
-src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-</script><br/>
+@comment  <br><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
+@comment  <!-- Ref 728x15 -->
+@comment  <ins class="adsbygoogle"
+@comment  style="display:inline-block;width:728px;height:15px"
+@comment  data-ad-client="ca-pub-1128070552722622"
+@comment  data-ad-slot="7008431385"></ins>
+@comment  <script>
+@comment  (adsbygoogle = window.adsbygoogle || []).push({});
+@comment  </script><br>
+@comment
+@comment  <script type="text/javascript"><!--
+@comment  google_ad_client = "ca-pub-1128070552722622";
+@comment  /* 728x90, создано 23.12.09 */
+@comment  google_ad_slot = "9958083480";
+@comment  google_ad_width = 728;
+@comment  google_ad_height = 90;
+@comment  //-->
+@comment  </script>
+@comment  <script type="text/javascript"
+@comment  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+@comment  </script><br/>
 <footer>
 <!--LiveInternet counter--><script type="text/javascript"><!--
 document.write("<a href='http://www.liveinternet.ru/click' "+
index 0dac42ff80ec51d32358db37be16cd8a0d37ebc7..37c95d303258d7cbe069a066a3eddacf2914a3f7 100644 (file)
@@ -75,44 +75,46 @@ This file documents the Mathematical Graphic Library (MathGL), a collection of c
 <tr><td style="padding-left: 5px;font-size: 110%"> <a target=_blank href="http://groups.google.com/group/mathgl"><b>MathGL</b></a> </td></tr>
 </table>
 
-<hr style="width: 100%; height: 1px;">
-<script type="text/javascript"><!--
-google_ad_client = "ca-pub-1128070552722622";
-/* Vertical small */
-google_ad_slot = "5501954624";
-google_ad_width = 120;
-google_ad_height = 240;
-//-->
-</script>
-<script type="text/javascript"
-src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-</script></nav>
+@comment  <hr style="width: 100%; height: 1px;">
+@comment  <script type="text/javascript"><!--
+@comment  google_ad_client = "ca-pub-1128070552722622";
+@comment  /* Vertical small */
+@comment  google_ad_slot = "5501954624";
+@comment  google_ad_width = 120;
+@comment  google_ad_height = 240;
+@comment  //-->
+@comment  </script>
+@comment  <script type="text/javascript"
+@comment  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+@comment  </script>
+</nav>
 @end html
 @end macro
 
 @macro external {}
 @html
-<br><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
-<!-- Ref 728x15 -->
-<ins class="adsbygoogle"
-style="display:inline-block;width:728px;height:15px"
-data-ad-client="ca-pub-1128070552722622"
-data-ad-slot="7008431385"></ins>
-<script>
-(adsbygoogle = window.adsbygoogle || []).push({});
-</script><br>
-
-<script type="text/javascript"><!--
-google_ad_client = "ca-pub-1128070552722622";
-/* 728x90, создано 23.12.09 */
-google_ad_slot = "9958083480";
-google_ad_width = 728;
-google_ad_height = 90;
-//-->
-</script>
-<script type="text/javascript"
-src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-</script><br/>
+@comment  <br><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
+@comment  <!-- Ref 728x15 -->
+@comment  <ins class="adsbygoogle"
+@comment  style="display:inline-block;width:728px;height:15px"
+@comment  data-ad-client="ca-pub-1128070552722622"
+@comment  data-ad-slot="7008431385"></ins>
+@comment  <script>
+@comment  (adsbygoogle = window.adsbygoogle || []).push({});
+@comment  </script><br>
+@comment
+@comment  <script type="text/javascript"><!--
+@comment  google_ad_client = "ca-pub-1128070552722622";
+@comment  /* 728x90, создано 23.12.09 */
+@comment  google_ad_slot = "9958083480";
+@comment  google_ad_width = 728;
+@comment  google_ad_height = 90;
+@comment  //-->
+@comment  </script>
+@comment  <script type="text/javascript"
+@comment  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+@comment  </script><br/>
+<footer>
 <!--LiveInternet counter--><script type="text/javascript"><!--
 document.write("<a href='http://www.liveinternet.ru/click' "+
 "target=_blank><img src='http://counter.yadro.ru/hit?t12.2;r"+
@@ -129,6 +131,7 @@ screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+
 <a target=_blank href="http://www.thefreecountry.com/"> <img src="http://www.thefreecountry.com/images/tfc88x31green.gif" alt="thefreecountry.com: Free Programmers' Resources, Free Webmasters' Resources, Free Security Resources, Free Software" border="0" height="31" width="88"></a>
 
 <a target=_blank href="http://sourceforge.net/donate/index.php?group_id=152187"><img src="http://images.sourceforge.net/images/project-support.jpg" width="88" height="32" border="0" alt="Support This Project" /> </a>
+</footer>
 @end html
 @end macro
 
index c97475d3a974807678bfe16e60f610ccbba8db08..40fad8106052de514c496adb6963c4cf41d4e36c 100644 (file)
@@ -224,26 +224,43 @@ Also, one can specify its own ticks with arbitrary labels by help of @code{SetTi
 
 The sample code, demonstrated ticks feature is
 @verbatim
-subplot 3 2 0:title 'Usual axis'
+subplot 3 3 0:title 'Usual axis'
 axis
 
-subplot 3 2 1:title 'Too big/small range'
+subplot 3 3 1:title 'Too big/small range'
 ranges -1000 1000 0 0.001:axis
 
-subplot 3 2 3:title 'Too narrow range'
+subplot 3 3 2:title 'LaTeX-like labels'
+axis 'F!'
+
+subplot 3 3 3:title 'Too narrow range'
 ranges 100 100.1 10 10.01:axis
 
-subplot 3 2 4:title 'Disable ticks tuning'
-tuneticks off:axis
+subplot 3 3 4:title 'No tuning, manual "+"'
+axis '+!'
+# for version <2.3 you can use
+#tuneticks off:axis
+
+subplot 3 3 5:title 'Template for ticks'
+xtick 'xxx:%g':ytick 'y:%g'
+axis
+
+xtick '':ytick '' # switch it off for other plots
+
+subplot 3 3 6:title 'No tuning, higher precision'
+axis '!4'
 
-subplot 3 2 2:title 'Manual ticks'
+subplot 3 3 7:title 'Manual ticks'
 ranges -pi pi 0 2
-xtick -pi '\pi' -pi/2 '-\pi/2' 0 '0' 0.886 'x^*' pi/2 '\pi/2' pi 'pi'
-# or you can use:
+xtick pi 3 '\pi'
+xtick 0.886 'x^*' on # note this will disable subticks drawing
+# or you can use
+#xtick -pi '\pi' -pi/2 '-\pi/2' 0 '0' 0.886 'x^*' pi/2 '\pi/2' pi 'pi'
+# or you can use
 #list v -pi -pi/2 0 0.886 pi/2 pi:xtick v '-\pi\n-\pi/2\n{}0\n{}x^*\n\pi/2\n\pi'
 axis:grid:fplot '2*cos(x^2)^2' 'r2'
 
-subplot 3 2 5:title 'Time ticks'
+subplot 3 3 8:title 'Time ticks'
 xrange 0 3e5:ticktime 'x':axis
 @end verbatim
 
@@ -258,7 +275,7 @@ xlabel 'x' 0:ylabel 'y = sin 1/x' 0
 
 subplot 2 2 1 '<_':title 'Log-log axis'
 ranges 0.01 100 0.1 100:axis 'lg(x)' 'lg(y)' ''
-axis:fplot 'sqrt(1+x^2)'
+axis:grid '!' 'h=':grid:fplot 'sqrt(1+x^2)'
 xlabel 'x' 0:ylabel 'y = \sqrt{1+x^2}' 0
 
 subplot 2 2 2 '<_':title 'Minus-log axis'
@@ -429,7 +446,7 @@ text 0 -0.5 'Text can be printed\n{}on several lines'
 
 subplot 2 2 2 '':box:plot y(:,0)
 text y 'This is very very long string drawn along a curve' 'k'
-text y 'Another string drawn above a curve' 'Tr'
+text y 'Another string drawn under a curve' 'Tr'
 
 subplot 2 2 3 '':line -1 -1 1 -1 'rA':text 0 -1 1 -1 'Horizontal'
 line -1 -1 1 1 'rA':text 0 0 1 1 'At angle' '@'
@@ -789,7 +806,7 @@ Now I shall show the example of a surface drawing. At first let us switch lightn
 @verbatim
 light on
 @end verbatim
-and draw the surface, considering coordinates x,y to be uniformly distributed in interval @var{Min}*@var{Max}
+and draw the surface, considering coordinates x,y to be uniformly distributed in axis range
 @verbatim
 new a0 50 40 '0.6*sin(pi*(x+1))*sin(1.5*pi*(y+1))+0.4*cos(0.75*pi*(x+1)*(y+1))'
 subplot 2 2 0:rotate 60 40
@@ -1997,12 +2014,17 @@ tricont t xt yt zt 'B'
 
 Command @ref{dots} is another way to draw irregular points. @code{Dots} use color scheme for coloring (see @ref{Color scheme}). The sample code is:
 @verbatim
-new t 1000 'pi*(rnd-0.5)':new f 1000 '2*pi*rnd'
-copy x 0.9*cos(t)*cos(f)
-copy y 0.9*cos(t)*sin(f)
-copy z 0.6*sin(t)
-title 'Dots sample':rotate 50 60:box
-dots x y z
+new t 2000 'pi*(rnd-0.5)':new f 2000 '2*pi*rnd'
+copy x 0.9*cos(t)*cos(f):copy y 0.9*cos(t)*sin(f):copy z 0.6*sin(t):copy c cos(2*t)
+subplot 2 2 0:title 'Dots sample':rotate 50 60
+box:dots x y z
+alpha on
+subplot 2 2 1:title 'add transparency':rotate 50 60
+box:dots x y z c
+subplot 2 2 2:title 'add colorings':rotate 50 60
+box:dots x y z x c
+subplot 2 2 3:title 'Only coloring':rotate 50 60
+box:tens x y z x ' .'
 @end verbatim
 
 @pfig{dots, Example of Dots()}
@@ -2196,10 +2218,12 @@ In this section I've included some small hints and advices for the improving of
 * Using primitives::
 * STFA sample::
 * Mapping visualization::
+* Data interpolation::
 * Making regular data::
 * Making histogram::
 * Nonlinear fitting hints::
 * PDE solving hints::
+* Drawing phase plain::
 * MGL parser using::
 * Using options::
 * ``Templates''::
@@ -2351,7 +2375,7 @@ MathGL can add a fog to the image. Its switching on is rather simple -- just use
 call 'prepare2d'
 title 'Fog sample':rotate 50 60:light on
 fog 1
-box:surf a
+box:surf a:cont a 'y'
 @end verbatim
 
 @pfig{fog, Example of @code{Fog()}.}
@@ -2500,7 +2524,7 @@ stfa a b 64:axis:ylabel '\omega' 0:xlabel '\i t'
 
 @c ------------------------------------------------------------------
 @external{}
-@node Mapping visualization, Making regular data, STFA sample, Hints
+@node Mapping visualization, Data interpolation, STFA sample, Hints
 @subsection Mapping visualization
 @nav{}
 
@@ -2523,7 +2547,65 @@ fill a '(x^3+y^3)/2':fill b '(x-y)/2':map a b 'brgk'
 
 @c ------------------------------------------------------------------
 @external{}
-@node Making regular data, Making histogram, Mapping visualization, Hints
+@node Data interpolation, Making regular data, Mapping visualization, Hints
+@subsection Data interpolation
+@nav{}
+
+There are many functions to get interpolated values of a data array. Basically all of them can be divided by 3 categories:
+@enumerate
+@item functions which return single value at given point (see @ref{Interpolation} and @code{mglGSpline()} in @ref{Global functions});
+@item functions @ref{subdata} and @ref{evaluate} for indirect access to data elements;
+@item functions @ref{refill}, @ref{gspline} and @ref{datagrid} which fill regular (rectangular) data array by interpolated values.
+@end enumerate
+
+The usage of first category is rather straightforward and don't need any special comments.
+
+There is difference in indirect access functions. Function @ref{subdata} use use step-like interpolation to handle correctly single @code{nan} values in the data array. Contrary, function @ref{evaluate} use local spline interpolation, which give smoother output but spread @code{nan} values. So, @ref{subdata} should be used for specific data elements (for example, for given column), and @ref{evaluate} should be used for distributed elements (i.e. consider data array as some field). Following sample illustrates this difference:
+@verbatim
+subplot 1 1 0 '':title 'SubData vs Evaluate'
+new in 9 'x^3/1.1':plot in 'ko ':box
+new arg 99 '4*x+4'
+evaluate e in arg:plot e 'b.'; legend 'Evaluate'
+subdata s in arg:plot s 'r.';legend 'SubData'
+legend 2
+@end verbatim
+
+@pfig{indirect, Example of indirect data access.}
+
+Example of @ref{datagrid} usage is done in @ref{Making regular data}. Here I want to show the peculiarities of @ref{refill} and @ref{gspline} functions. Both functions require argument(s) which provide coordinates of the data values, and return rectangular data array which equidistantly distributed in axis range. So, in opposite to @ref{evaluate} function, @ref{refill} and @ref{gspline} can interpolate non-equidistantly distributed data. At this both functions @ref{refill} and @ref{gspline} provide continuity of 2nd derivatives along coordinate(s). However, @ref{refill} is slower but give better (from human point of view) result than global spline @ref{gspline} due to more advanced algorithm. Following sample illustrates this difference:
+@verbatim
+new x 10 '0.5+rnd':cumsum x 'x':norm x -1 1
+copy y sin(pi*x)/1.5
+subplot 2 2 0 '<_':title 'Refill sample'
+box:axis:plot x y 'o ':fplot 'sin(pi*x)/1.5' 'B:'
+new r 100:refill r x y:plot r 'r'
+
+subplot 2 2 1 '<_':title 'Global spline'
+box:axis:plot x y 'o ':fplot 'sin(pi*x)/1.5' 'B:'
+new r 100:gspline r x y:plot r 'r'
+
+new y 10 '0.5+rnd':cumsum y 'x':norm y -1 1
+copy xx x:extend xx 10
+copy yy y:extend yy 10:transpose yy
+copy z sin(pi*xx*yy)/1.5
+alpha on:light on
+subplot 2 2 2:title '2d regular':rotate 40 60
+box:axis:mesh xx yy z 'k'
+new rr 100 100:refill rr x y z:surf rr
+
+new xx 10 10 '(x+1)/2*cos(y*pi/2-1)'
+new yy 10 10 '(x+1)/2*sin(y*pi/2-1)'
+copy z sin(pi*xx*yy)/1.5
+subplot 2 2 3:title '2d non-regular':rotate 40 60
+box:axis:plot xx yy z 'ko '
+new rr 100 100:refill rr xx yy z:surf rr
+@end verbatim
+
+@pfig{refill, Example of non-equidistant data interpolation.}
+
+@c ------------------------------------------------------------------
+@external{}
+@node Making regular data, Making histogram, Data interpolation, Hints
 @subsection Making regular data
 @nav{}
 
@@ -2575,7 +2657,7 @@ new in 100 '0.3+sin(2*pi*x)'
 @end verbatim
 and plot it to see that data we will fit
 @verbatim
-title 'Fitting sample':yrange -2 2:box:axis:plot rnd '. '
+title 'Fitting sample':yrange -2 2:box:axis:plot rnd 'k. '
 @end verbatim
 
 The next step is the fitting itself. For that let me specify an initial values @var{ini} for coefficients @samp{abc} and do the fitting for approximation formula @samp{a+b*sin(c*x)}
@@ -2597,7 +2679,7 @@ The full sample code for nonlinear fitting is:
 new rnd 100 '0.4*rnd+0.1+sin(2*pi*x)'
 new in 100 '0.3+sin(2*pi*x)'
 list ini 1 1 3:fit res rnd 'a+b*sin(c*x)' 'abc' ini
-title 'Fitting sample':yrange -2 2:box:axis:plot rnd '. '
+title 'Fitting sample':yrange -2 2:box:axis:plot rnd 'k. '
 plot res 'r':plot in 'b'
 text -0.9 -1.3 'fitted:' 'r:L'
 putsfit 0 -1.8 'y = ' 'r'
@@ -2608,26 +2690,26 @@ text 0 2.2 'initial: y = 0.3+sin(2\pi x)' 'b'
 
 @c ------------------------------------------------------------------
 @external{}
-@node PDE solving hints, MGL parser using, Nonlinear fitting hints, Hints
+@node PDE solving hints, Drawing phase plain, Nonlinear fitting hints, Hints
 @subsection PDE solving hints
 @nav{}
 
-Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @code{mglRay()} for ray tracing, @code{mglPDE()} for PDE solving, @code{mglQO2d()} for beam tracing in 2D case (see @ref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
+Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @ref{ray} for ray tracing, @ref{pde} for PDE solving, @ref{qo2d} for beam tracing in 2D case (see @ref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
 
-The ray tracing can be done by @code{mglRay()} function. Really ray tracing equation is Hamiltonian equation for 3D space. So, the function can be also used for finding a particle trajectory (i.e. solve Hamiltonian ODE) for 1D, 2D or 3D cases. The function have a set of arguments. First of all, it is Hamiltonian which defined the media (or the equation) you are planning to use. The Hamiltonian is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, time @samp{t} (for particle dynamics) and momentums @samp{p}=@math{p_x}, @samp{q}=@math{p_y}, @samp{v}=@math{p_z}. Next, you have to define the initial conditions for coordinates and momentums at @samp{t}=0 and set the integrations step (default is 0.1) and its duration (default is 10). The Runge-Kutta method of 4-th order is used for integration.
+The ray tracing can be done by @ref{ray} function. Really ray tracing equation is Hamiltonian equation for 3D space. So, the function can be also used for finding a particle trajectory (i.e. solve Hamiltonian ODE) for 1D, 2D or 3D cases. The function have a set of arguments. First of all, it is Hamiltonian which defined the media (or the equation) you are planning to use. The Hamiltonian is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, time @samp{t} (for particle dynamics) and momentums @samp{p}=@math{p_x}, @samp{q}=@math{p_y}, @samp{v}=@math{p_z}. Next, you have to define the initial conditions for coordinates and momentums at @samp{t}=0 and set the integrations step (default is 0.1) and its duration (default is 10). The Runge-Kutta method of 4-th order is used for integration.
 @verbatim
   const char *ham = "p^2+q^2-x-1+i*0.5*(y+x)*(y>-x)";
   mglData r = mglRay(ham, mglPoint(-0.7, -1), mglPoint(0, 0.5), 0.02, 2);
 @end verbatim
 This example calculate the reflection from linear layer (media with Hamiltonian @samp{p^2+q^2-x-1}=@math{p_x^2+p_y^2-x-1}). This is parabolic curve. The resulting array have 7 columns which contain data for @{x,y,z,p,q,v,t@}.
 
-The solution of PDE is a bit more complicated. As previous you have to specify the equation as pseudo-differential operator @math{\hat H(x, \nabla)} which is called sometime as ``Hamiltonian'' (for example, in beam tracing). As previously, it is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z} (but not time!), momentums @samp{p}=@math{(d/dx)/i k_0}, @samp{q}=@math{(d/dy)/i k_0} and field amplitude @samp{u}=@math{|u|}. The evolutionary coordinate is @samp{z} in all cases. So that, the equation look like @math{du/dz = ik_0 H(x,y,\hat p, \hat q, |u|)[u]}. Dependence on field amplitude @samp{u}=@math{|u|} allows one to solve nonlinear problems too. For example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. Also you may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}, but only if dependence on variable @samp{i} is linear (i.e. @math{H = Hre+i*Him}).
+The solution of PDE is a bit more complicated. As previous you have to specify the equation as pseudo-differential operator @math{\hat H(x, \nabla)} which is called sometime as ``Hamiltonian'' (for example, in beam tracing). As previously, it is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z} (but not time!), momentums @samp{p}=@math{(d/dx)/i k_0}, @samp{q}=@math{(d/dy)/i k_0} and field amplitude @samp{u}=@math{|u|}. The evolutionary coordinate is @samp{z} in all cases. So that, the equation look like @math{du/dz = ik_0 H(x,y,\hat p, \hat q, |u|)[u]}. Dependence on field amplitude @samp{u}=@math{|u|} allows one to solve nonlinear problems too. For example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. Also you may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"} or @code{ham = "p^2 + i1*x*(x>0)"}.
 
-Next step is specifying the initial conditions at @samp{z}=@code{Min.z}. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified range [Min, Max]. So, the data arrays should have corresponding scales. Finally, you may set the integration step and parameter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
+Next step is specifying the initial conditions at @samp{z} equal to minimal z-axis value. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified axis range. So, the data arrays should have corresponding scales. Finally, you may set the integration step and parameter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
 
 Final comment is concerning the possible form of pseudo-differential operator @math{H}. At this moment, simplified form of operator @math{H} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this operator is effectively @math{H = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed for 3D case.
 
-So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{ik_0 \partial_z u + \Delta u + x \cdot u + i (x+z)/2 \cdot u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this:
+So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{1/ik_0 * du/dz + d^2 u/dx^2 + d^2 u/dy^2 + x * u + i (x+z)/2 * u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this:
 @verbatim
 new re 128 'exp(-48*(x+0.7)^2)':new im 128
 pde a 'p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)' re im 0.01 30
@@ -2642,7 +2724,7 @@ text 0 0.95 'Equation: ik_0\partial_zu + \Delta u + x\cdot u +\
 
 @pfig{pde, Example of PDE solving.}
 
-The last example is example of beam tracing. Beam tracing equation is special kind of PDE equation written in coordinates accompanied to a ray. Generally this is the same parameters and limitation as for PDE solving but the coordinates are defined by the ray and by parameter of grid width @var{w} in direction transverse the ray. So, you don't need to specify the range of coordinates. @strong{BUT} there is limitation. The accompanied coordinates are well defined only for smooth enough rays, i.e. then the ray curvature @math{K} (which is defined as @math{1/K^2 = (|\ddot r|^2 |\dot r|^2 - (\ddot r, \dot r)^2)/|\dot r|^6}) is much large then the grid width: @math{K>>w}. So, you may receive incorrect results if this condition will be broken.
+The last example is example of beam tracing. Beam tracing equation is special kind of PDE equation written in coordinates accompanied to a ray. Generally this is the same parameters and limitation as for PDE solving but the coordinates are defined by the ray and by parameter of grid width @var{w} in direction transverse the ray. So, you don't need to specify the range of coordinates. @strong{BUT} there is limitation. The accompanied coordinates are well defined only for smooth enough rays, i.e. then the ray curvature @math{K} (which is defined as @math{1/K^2 = (|r''|^2 |r'|^2 - (r'', r'')^2)/|r'|^6}) is much large then the grid width: @math{K>>w}. So, you may receive incorrect results if this condition will be broken.
 
 You may use following code for obtaining the same solution as in previous example:
 @verbatim
@@ -2663,7 +2745,44 @@ text 0.7 -0.05 'central ray'
 
 @c ------------------------------------------------------------------
 @external{}
-@node MGL parser using, Using options, PDE solving hints, Hints
+@node Drawing phase plain, MGL parser using, PDE solving hints, Hints
+@subsection Drawing phase plain
+@nav{}
+
+Here I want say a few words of plotting phase plains. Phase plain is name for system of coordinates @math{x}, @math{x'}, i.e. a variable and its time derivative. Plot in phase plain is very useful for qualitative analysis of an ODE, because such plot is rude (it topologically the same for a range of ODE parameters). Most often the phase plain @{@math{x}, @math{x'}@} is used (due to its simplicity), that allows to analyze up to the 2nd order ODE (i.e. @math{x''+f(x,x')=0}).
+
+The simplest way to draw phase plain in MathGL is using @ref{flow} function(s), which automatically select several points and draw flow threads. If the ODE have an integral of motion (like Hamiltonian @math{H(x,x')=const} for dissipation-free case) then you can use @ref{cont} function for plotting isolines (contours). In fact. isolines are the same as flow threads, but without arrows on it. Finally, you can directly solve ODE using @ref{ode} function and plot its numerical solution.
+
+Let demonstrate this for ODE equation @math{x''-x+3*x^2=0}. This is nonlinear oscillator with square nonlinearity. It has integral @math{H=y^2+2*x^3-x^2=Const}. Also it have 2 typical stationary points: saddle at @{x=0, y=0@} and center at @{x=1/3, y=0@}. Motion at vicinity of center is just simple oscillations, and is stable to small variation of parameters. In opposite, motion around saddle point is non-stable to small variation of parameters, and is very slow. So, calculation around saddle points are more difficult, but more important. Saddle points are responsible for solitons, stochasticity and so on.
+
+So, let draw this phase plain by 3 different methods. First, draw isolines for @math{H=y^2+2*x^3-x^2=Const} -- this is simplest for ODE without dissipation. Next, draw flow threads -- this is straightforward way, but the automatic choice of starting points is not always optimal. Finally, use @ref{ode} to check the above plots. At this we need to run @ref{ode} in both direction of time (in future and in the past) to draw whole plain. Alternatively, one can put starting points far from (or at the bounding box as done in @ref{flow}) the plot, but this is a more complicated. The sample code is:
+@verbatim
+subplot 2 2 0 '<_':title 'Cont':box
+axis:xlabel 'x':ylabel '\dot{x}'
+new f 100 100 'y^2+2*x^3-x^2-0.5':cont f
+
+subplot 2 2 1 '<_':title 'Flow':box
+axis:xlabel 'x':ylabel '\dot{x}'
+new fx 100 100 'x-3*x^2'
+new fy 100 100 'y'
+flow fy fx 'v';value 7
+
+subplot 2 2 2 '<_':title 'ODE':box
+axis:xlabel 'x':ylabel '\dot{x}'
+for $x -1 1 0.1
+  ode r 'y;x-3*x^2' 'xy' [$x,0]
+  plot r(0) r(1)
+  ode r '-y;-x+3*x^2' 'xy' [$x,0]
+  plot r(0) r(1)
+next
+@end verbatim
+
+@pfig{ode, Example of ODE solving and phase plain drawing.}
+
+
+@c ------------------------------------------------------------------
+@external{}
+@node MGL parser using, Using options, Drawing phase plain, Hints
 @subsection MGL parser using
 @nav{}
 
@@ -2829,6 +2948,21 @@ Just use @code{rotatetext off}. Also you can use axis style @samp{U} for disable
 @item How can I draw equal axis range even for rectangular image?
 Just use @code{aspect nan nan} for each subplot, or at the beginning of the drawing.
 
+@item How I can set transparent background?
+Just use code like @code{clf 'r@{A5@}'} or prepare PNG file and set it as background image by call @code{background 'fname.png'}.
+
+@item How I can reduce "white" edges around bounding box?
+The simplest way is to use @ref{subplot} style. However, you should be careful if you plan to add @ref{colorbar} or rotate plot -- part of plot can be invisible if you will use non-default @ref{subplot} style.
+
+@item Can I combine bitmap and vector output in EPS?
+Yes. Sometimes you may have huge surface and a small set of curves and/or text on the plot. You can use function @ref{rasterize} just after making surface plot. This will put all plot to bitmap background. At this later plotting will be in vector format. For example, you can do something like following:
+@verbatim
+surf x y z
+rasterize # make surface as bitmap
+axis
+write 'fname.eps'
+@end verbatim
+
 @end table
 
 @external{}
index c97475d3a974807678bfe16e60f610ccbba8db08..57dbe35fad23af6c70670bb017a7812b1ac5080a 100644 (file)
@@ -224,26 +224,43 @@ Also, one can specify its own ticks with arbitrary labels by help of @code{SetTi
 
 The sample code, demonstrated ticks feature is
 @verbatim
-subplot 3 2 0:title 'Usual axis'
+subplot 3 3 0:title 'Usual axis'
 axis
 
-subplot 3 2 1:title 'Too big/small range'
+subplot 3 3 1:title 'Too big/small range'
 ranges -1000 1000 0 0.001:axis
 
-subplot 3 2 3:title 'Too narrow range'
+subplot 3 3 2:title 'LaTeX-like labels'
+axis 'F!'
+
+subplot 3 3 3:title 'Too narrow range'
 ranges 100 100.1 10 10.01:axis
 
-subplot 3 2 4:title 'Disable ticks tuning'
-tuneticks off:axis
+subplot 3 3 4:title 'No tuning, manual "+"'
+axis '+!'
+# for version <2.3 you can use
+#tuneticks off:axis
+
+subplot 3 3 5:title 'Template for ticks'
+xtick 'xxx:%g':ytick 'y:%g'
+axis
+
+xtick '':ytick '' # switch it off for other plots
+
+subplot 3 3 6:title 'No tuning, higher precision'
+axis '!4'
 
-subplot 3 2 2:title 'Manual ticks'
+subplot 3 3 7:title 'Manual ticks'
 ranges -pi pi 0 2
-xtick -pi '\pi' -pi/2 '-\pi/2' 0 '0' 0.886 'x^*' pi/2 '\pi/2' pi 'pi'
-# or you can use:
+xtick pi 3 '\pi'
+xtick 0.886 'x^*' on # note this will disable subticks drawing
+# or you can use
+#xtick -pi '\pi' -pi/2 '-\pi/2' 0 '0' 0.886 'x^*' pi/2 '\pi/2' pi 'pi'
+# or you can use
 #list v -pi -pi/2 0 0.886 pi/2 pi:xtick v '-\pi\n-\pi/2\n{}0\n{}x^*\n\pi/2\n\pi'
 axis:grid:fplot '2*cos(x^2)^2' 'r2'
 
-subplot 3 2 5:title 'Time ticks'
+subplot 3 3 8:title 'Time ticks'
 xrange 0 3e5:ticktime 'x':axis
 @end verbatim
 
@@ -258,7 +275,7 @@ xlabel 'x' 0:ylabel 'y = sin 1/x' 0
 
 subplot 2 2 1 '<_':title 'Log-log axis'
 ranges 0.01 100 0.1 100:axis 'lg(x)' 'lg(y)' ''
-axis:fplot 'sqrt(1+x^2)'
+axis:grid '!' 'h=':grid:fplot 'sqrt(1+x^2)'
 xlabel 'x' 0:ylabel 'y = \sqrt{1+x^2}' 0
 
 subplot 2 2 2 '<_':title 'Minus-log axis'
@@ -429,7 +446,7 @@ text 0 -0.5 'Text can be printed\n{}on several lines'
 
 subplot 2 2 2 '':box:plot y(:,0)
 text y 'This is very very long string drawn along a curve' 'k'
-text y 'Another string drawn above a curve' 'Tr'
+text y 'Another string drawn under a curve' 'Tr'
 
 subplot 2 2 3 '':line -1 -1 1 -1 'rA':text 0 -1 1 -1 'Horizontal'
 line -1 -1 1 1 'rA':text 0 0 1 1 'At angle' '@'
@@ -789,7 +806,7 @@ Now I shall show the example of a surface drawing. At first let us switch lightn
 @verbatim
 light on
 @end verbatim
-and draw the surface, considering coordinates x,y to be uniformly distributed in interval @var{Min}*@var{Max}
+and draw the surface, considering coordinates x,y to be uniformly distributed in axis range
 @verbatim
 new a0 50 40 '0.6*sin(pi*(x+1))*sin(1.5*pi*(y+1))+0.4*cos(0.75*pi*(x+1)*(y+1))'
 subplot 2 2 0:rotate 60 40
@@ -1997,12 +2014,17 @@ tricont t xt yt zt 'B'
 
 Command @ref{dots} is another way to draw irregular points. @code{Dots} use color scheme for coloring (see @ref{Color scheme}). The sample code is:
 @verbatim
-new t 1000 'pi*(rnd-0.5)':new f 1000 '2*pi*rnd'
-copy x 0.9*cos(t)*cos(f)
-copy y 0.9*cos(t)*sin(f)
-copy z 0.6*sin(t)
-title 'Dots sample':rotate 50 60:box
-dots x y z
+new t 2000 'pi*(rnd-0.5)':new f 2000 '2*pi*rnd'
+copy x 0.9*cos(t)*cos(f):copy y 0.9*cos(t)*sin(f):copy z 0.6*sin(t):copy c cos(2*t)
+subplot 2 2 0:title 'Dots sample':rotate 50 60
+box:dots x y z
+alpha on
+subplot 2 2 1:title 'add transparency':rotate 50 60
+box:dots x y z c
+subplot 2 2 2:title 'add colorings':rotate 50 60
+box:dots x y z x c
+subplot 2 2 3:title 'Only coloring':rotate 50 60
+box:tens x y z x ' .'
 @end verbatim
 
 @pfig{dots, Example of Dots()}
@@ -2196,10 +2218,12 @@ In this section I've included some small hints and advices for the improving of
 * Using primitives::
 * STFA sample::
 * Mapping visualization::
+* Data interpolation::
 * Making regular data::
 * Making histogram::
 * Nonlinear fitting hints::
 * PDE solving hints::
+* Drawing phase plain::
 * MGL parser using::
 * Using options::
 * ``Templates''::
@@ -2351,7 +2375,7 @@ MathGL can add a fog to the image. Its switching on is rather simple -- just use
 call 'prepare2d'
 title 'Fog sample':rotate 50 60:light on
 fog 1
-box:surf a
+box:surf a:cont a 'y'
 @end verbatim
 
 @pfig{fog, Example of @code{Fog()}.}
@@ -2500,7 +2524,7 @@ stfa a b 64:axis:ylabel '\omega' 0:xlabel '\i t'
 
 @c ------------------------------------------------------------------
 @external{}
-@node Mapping visualization, Making regular data, STFA sample, Hints
+@node Mapping visualization, Data interpolation, STFA sample, Hints
 @subsection Mapping visualization
 @nav{}
 
@@ -2523,7 +2547,65 @@ fill a '(x^3+y^3)/2':fill b '(x-y)/2':map a b 'brgk'
 
 @c ------------------------------------------------------------------
 @external{}
-@node Making regular data, Making histogram, Mapping visualization, Hints
+@node Data interpolation, Making regular data, Mapping visualization, Hints
+@subsection Data interpolation
+@nav{}
+
+There are many functions to get interpolated values of a data array. Basically all of them can be divided by 3 categories:
+@enumerate
+@item functions which return single value at given point (see @ref{Interpolation} and @code{mglGSpline()} in @ref{Global functions});
+@item functions @ref{subdata} and @ref{evaluate} for indirect access to data elements;
+@item functions @ref{refill}, @ref{gspline} and @ref{datagrid} which fill regular (rectangular) data array by interpolated values.
+@end enumerate
+
+The usage of first category is rather straightforward and don't need any special comments.
+
+There is difference in indirect access functions. Function @ref{subdata} use use step-like interpolation to handle correctly single @code{nan} values in the data array. Contrary, function @ref{evaluate} use local spline interpolation, which give smoother output but spread @code{nan} values. So, @ref{subdata} should be used for specific data elements (for example, for given column), and @ref{evaluate} should be used for distributed elements (i.e. consider data array as some field). Following sample illustrates this difference:
+@verbatim
+subplot 1 1 0 '':title 'SubData vs Evaluate'
+new in 9 'x^3/1.1':plot in 'ko ':box
+new arg 99 '4*x+4'
+evaluate e in arg:plot e 'b.'; legend 'Evaluate'
+subdata s in arg:plot s 'r.';legend 'SubData'
+legend 2
+@end verbatim
+
+@pfig{indirect, Example of indirect data access.}
+
+Example of @ref{datagrid} usage is done in @ref{Making regular data}. Here I want to show the peculiarities of @ref{refill} and @ref{gspline} functions. Both functions require argument(s) which provide coordinates of the data values, and return rectangular data array which equidistantly distributed in axis range. So, in opposite to @ref{evaluate} function, @ref{refill} and @ref{gspline} can interpolate non-equidistantly distributed data. At this both functions @ref{refill} and @ref{gspline} provide continuity of 2nd derivatives along coordinate(s). However, @ref{refill} is slower but give better (from human point of view) result than global spline @ref{gspline} due to more advanced algorithm. Following sample illustrates this difference:
+@verbatim
+new x 10 '0.5+rnd':cumsum x 'x':norm x -1 1
+copy y sin(pi*x)/1.5
+subplot 2 2 0 '<_':title 'Refill sample'
+box:axis:plot x y 'o ':fplot 'sin(pi*x)/1.5' 'B:'
+new r 100:refill r x y:plot r 'r'
+
+subplot 2 2 1 '<_':title 'Global spline'
+box:axis:plot x y 'o ':fplot 'sin(pi*x)/1.5' 'B:'
+new r 100:gspline r x y:plot r 'r'
+
+new y 10 '0.5+rnd':cumsum y 'x':norm y -1 1
+copy xx x:extend xx 10
+copy yy y:extend yy 10:transpose yy
+copy z sin(pi*xx*yy)/1.5
+alpha on:light on
+subplot 2 2 2:title '2d regular':rotate 40 60
+box:axis:mesh xx yy z 'k'
+new rr 100 100:refill rr x y z:surf rr
+
+new xx 10 10 '(x+1)/2*cos(y*pi/2-1)'
+new yy 10 10 '(x+1)/2*sin(y*pi/2-1)'
+copy z sin(pi*xx*yy)/1.5
+subplot 2 2 3:title '2d non-regular':rotate 40 60
+box:axis:plot xx yy z 'ko '
+new rr 100 100:refill rr xx yy z:surf rr
+@end verbatim
+
+@pfig{refill, Example of non-equidistant data interpolation.}
+
+@c ------------------------------------------------------------------
+@external{}
+@node Making regular data, Making histogram, Data interpolation, Hints
 @subsection Making regular data
 @nav{}
 
@@ -2575,7 +2657,7 @@ new in 100 '0.3+sin(2*pi*x)'
 @end verbatim
 and plot it to see that data we will fit
 @verbatim
-title 'Fitting sample':yrange -2 2:box:axis:plot rnd '. '
+title 'Fitting sample':yrange -2 2:box:axis:plot rnd 'k. '
 @end verbatim
 
 The next step is the fitting itself. For that let me specify an initial values @var{ini} for coefficients @samp{abc} and do the fitting for approximation formula @samp{a+b*sin(c*x)}
@@ -2597,7 +2679,7 @@ The full sample code for nonlinear fitting is:
 new rnd 100 '0.4*rnd+0.1+sin(2*pi*x)'
 new in 100 '0.3+sin(2*pi*x)'
 list ini 1 1 3:fit res rnd 'a+b*sin(c*x)' 'abc' ini
-title 'Fitting sample':yrange -2 2:box:axis:plot rnd '. '
+title 'Fitting sample':yrange -2 2:box:axis:plot rnd 'k. '
 plot res 'r':plot in 'b'
 text -0.9 -1.3 'fitted:' 'r:L'
 putsfit 0 -1.8 'y = ' 'r'
@@ -2608,26 +2690,26 @@ text 0 2.2 'initial: y = 0.3+sin(2\pi x)' 'b'
 
 @c ------------------------------------------------------------------
 @external{}
-@node PDE solving hints, MGL parser using, Nonlinear fitting hints, Hints
+@node PDE solving hints, Drawing phase plain, Nonlinear fitting hints, Hints
 @subsection PDE solving hints
 @nav{}
 
-Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @code{mglRay()} for ray tracing, @code{mglPDE()} for PDE solving, @code{mglQO2d()} for beam tracing in 2D case (see @ref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
+Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @ref{ray} for ray tracing, @ref{pde} for PDE solving, @ref{qo2d} for beam tracing in 2D case (see @ref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
 
-The ray tracing can be done by @code{mglRay()} function. Really ray tracing equation is Hamiltonian equation for 3D space. So, the function can be also used for finding a particle trajectory (i.e. solve Hamiltonian ODE) for 1D, 2D or 3D cases. The function have a set of arguments. First of all, it is Hamiltonian which defined the media (or the equation) you are planning to use. The Hamiltonian is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, time @samp{t} (for particle dynamics) and momentums @samp{p}=@math{p_x}, @samp{q}=@math{p_y}, @samp{v}=@math{p_z}. Next, you have to define the initial conditions for coordinates and momentums at @samp{t}=0 and set the integrations step (default is 0.1) and its duration (default is 10). The Runge-Kutta method of 4-th order is used for integration.
+The ray tracing can be done by @ref{ray} function. Really ray tracing equation is Hamiltonian equation for 3D space. So, the function can be also used for finding a particle trajectory (i.e. solve Hamiltonian ODE) for 1D, 2D or 3D cases. The function have a set of arguments. First of all, it is Hamiltonian which defined the media (or the equation) you are planning to use. The Hamiltonian is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, time @samp{t} (for particle dynamics) and momentums @samp{p}=@math{p_x}, @samp{q}=@math{p_y}, @samp{v}=@math{p_z}. Next, you have to define the initial conditions for coordinates and momentums at @samp{t}=0 and set the integrations step (default is 0.1) and its duration (default is 10). The Runge-Kutta method of 4-th order is used for integration.
 @verbatim
   const char *ham = "p^2+q^2-x-1+i*0.5*(y+x)*(y>-x)";
   mglData r = mglRay(ham, mglPoint(-0.7, -1), mglPoint(0, 0.5), 0.02, 2);
 @end verbatim
 This example calculate the reflection from linear layer (media with Hamiltonian @samp{p^2+q^2-x-1}=@math{p_x^2+p_y^2-x-1}). This is parabolic curve. The resulting array have 7 columns which contain data for @{x,y,z,p,q,v,t@}.
 
-The solution of PDE is a bit more complicated. As previous you have to specify the equation as pseudo-differential operator @math{\hat H(x, \nabla)} which is called sometime as ``Hamiltonian'' (for example, in beam tracing). As previously, it is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z} (but not time!), momentums @samp{p}=@math{(d/dx)/i k_0}, @samp{q}=@math{(d/dy)/i k_0} and field amplitude @samp{u}=@math{|u|}. The evolutionary coordinate is @samp{z} in all cases. So that, the equation look like @math{du/dz = ik_0 H(x,y,\hat p, \hat q, |u|)[u]}. Dependence on field amplitude @samp{u}=@math{|u|} allows one to solve nonlinear problems too. For example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. Also you may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}, but only if dependence on variable @samp{i} is linear (i.e. @math{H = Hre+i*Him}).
+The solution of PDE is a bit more complicated. As previous you have to specify the equation as pseudo-differential operator @math{\hat H(x, \nabla)} which is called sometime as ``Hamiltonian'' (for example, in beam tracing). As previously, it is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z} (but not time!), momentums @samp{p}=@math{(d/dx)/i k_0}, @samp{q}=@math{(d/dy)/i k_0} and field amplitude @samp{u}=@math{|u|}. The evolutionary coordinate is @samp{z} in all cases. So that, the equation look like @math{du/dz = ik_0 H(x,y,\hat p, \hat q, |u|)[u]}. Dependence on field amplitude @samp{u}=@math{|u|} allows one to solve nonlinear problems too. For example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. Also you may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"} or @code{ham = "p^2 + i1*x*(x>0)"}.
 
-Next step is specifying the initial conditions at @samp{z}=@code{Min.z}. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified range [Min, Max]. So, the data arrays should have corresponding scales. Finally, you may set the integration step and parameter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
+Next step is specifying the initial conditions at @samp{z} equal to minimal z-axis value. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified axis range. So, the data arrays should have corresponding scales. Finally, you may set the integration step and parameter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
 
 Final comment is concerning the possible form of pseudo-differential operator @math{H}. At this moment, simplified form of operator @math{H} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this operator is effectively @math{H = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed for 3D case.
 
-So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{ik_0 \partial_z u + \Delta u + x \cdot u + i (x+z)/2 \cdot u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this:
+So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{1/ik_0 * du/dz + d^2 u/dx^2 + d^2 u/dy^2 + x * u + i (x+z)/2 * u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this:
 @verbatim
 new re 128 'exp(-48*(x+0.7)^2)':new im 128
 pde a 'p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)' re im 0.01 30
@@ -2642,7 +2724,7 @@ text 0 0.95 'Equation: ik_0\partial_zu + \Delta u + x\cdot u +\
 
 @pfig{pde, Example of PDE solving.}
 
-The last example is example of beam tracing. Beam tracing equation is special kind of PDE equation written in coordinates accompanied to a ray. Generally this is the same parameters and limitation as for PDE solving but the coordinates are defined by the ray and by parameter of grid width @var{w} in direction transverse the ray. So, you don't need to specify the range of coordinates. @strong{BUT} there is limitation. The accompanied coordinates are well defined only for smooth enough rays, i.e. then the ray curvature @math{K} (which is defined as @math{1/K^2 = (|\ddot r|^2 |\dot r|^2 - (\ddot r, \dot r)^2)/|\dot r|^6}) is much large then the grid width: @math{K>>w}. So, you may receive incorrect results if this condition will be broken.
+The last example is example of beam tracing. Beam tracing equation is special kind of PDE equation written in coordinates accompanied to a ray. Generally this is the same parameters and limitation as for PDE solving but the coordinates are defined by the ray and by parameter of grid width @var{w} in direction transverse the ray. So, you don't need to specify the range of coordinates. @strong{BUT} there is limitation. The accompanied coordinates are well defined only for smooth enough rays, i.e. then the ray curvature @math{K} (which is defined as @math{1/K^2 = (|r''|^2 |r'|^2 - (r'', r'')^2)/|r'|^6}) is much large then the grid width: @math{K>>w}. So, you may receive incorrect results if this condition will be broken.
 
 You may use following code for obtaining the same solution as in previous example:
 @verbatim
@@ -2663,7 +2745,44 @@ text 0.7 -0.05 'central ray'
 
 @c ------------------------------------------------------------------
 @external{}
-@node MGL parser using, Using options, PDE solving hints, Hints
+@node Drawing phase plain, MGL parser using, PDE solving hints, Hints
+@subsection Drawing phase plain
+@nav{}
+
+Here I want say a few words of plotting phase plains. Phase plain is name for system of coordinates @math{x}, @math{x'}, i.e. a variable and its time derivative. Plot in phase plain is very useful for qualitative analysis of an ODE, because such plot is rude (it topologically the same for a range of ODE parameters). Most often the phase plain @{@math{x}, @math{x'}@} is used (due to its simplicity), that allows to analyze up to the 2nd order ODE (i.e. @math{x''+f(x,x')=0}).
+
+The simplest way to draw phase plain in MathGL is using @ref{flow} function(s), which automatically select several points and draw flow threads. If the ODE have an integral of motion (like Hamiltonian @math{H(x,x')=const} for dissipation-free case) then you can use @ref{cont} function for plotting isolines (contours). In fact. isolines are the same as flow threads, but without arrows on it. Finally, you can directly solve ODE using @ref{ode} function and plot its numerical solution.
+
+Let demonstrate this for ODE equation @math{x''-x+3*x^2=0}. This is nonlinear oscillator with square nonlinearity. It has integral @math{H=y^2+2*x^3-x^2=Const}. Also it have 2 typical stationary points: saddle at @{x=0, y=0@} and center at @{x=1/3, y=0@}. Motion at vicinity of center is just simple oscillations, and is stable to small variation of parameters. In opposite, motion around saddle point is non-stable to small variation of parameters, and is very slow. So, calculation around saddle points are more difficult, but more important. Saddle points are responsible for solitons, stochasticity and so on.
+
+So, let draw this phase plain by 3 different methods. First, draw isolines for @math{H=y^2+2*x^3-x^2=Const} -- this is simplest for ODE without dissipation. Next, draw flow threads -- this is straightforward way, but the automatic choice of starting points is not always optimal. Finally, use @ref{ode} to check the above plots. At this we need to run @ref{ode} in both direction of time (in future and in the past) to draw whole plain. Alternatively, one can put starting points far from (or at the bounding box as done in @ref{flow}) the plot, but this is a more complicated. The sample code is:
+@verbatim
+subplot 2 2 0 '<_':title 'Cont':box
+axis:xlabel 'x':ylabel '\dot{x}'
+new f 100 100 'y^2+2*x^3-x^2-0.5':cont f
+
+subplot 2 2 1 '<_':title 'Flow':box
+axis:xlabel 'x':ylabel '\dot{x}'
+new fx 100 100 'x-3*x^2'
+new fy 100 100 'y'
+flow fy fx 'v';value 7
+
+subplot 2 2 2 '<_':title 'ODE':box
+axis:xlabel 'x':ylabel '\dot{x}'
+for $x -1 1 0.1
+  ode r 'y;x-3*x^2' 'xy' [$x,0]
+  plot r(0) r(1)
+  ode r '-y;-x+3*x^2' 'xy' [$x,0]
+  plot r(0) r(1)
+next
+@end verbatim
+
+@pfig{ode, Example of ODE solving and phase plain drawing.}
+
+
+@c ------------------------------------------------------------------
+@external{}
+@node MGL parser using, Using options, Drawing phase plain, Hints
 @subsection MGL parser using
 @nav{}
 
@@ -2829,6 +2948,21 @@ Just use @code{rotatetext off}. Also you can use axis style @samp{U} for disable
 @item How can I draw equal axis range even for rectangular image?
 Just use @code{aspect nan nan} for each subplot, or at the beginning of the drawing.
 
+@item Как задать полупрозрачный фон?
+Просто используйте код типа @code{clf 'r@{A5@}'} или подготовьте PNG файл и задайте его в качестве фона рисунка @code{background 'fname.png'}.
+
+@item Как уменьшить поля вокруг графика?
+Простейший путь состоит в использовании стилей @ref{subplot}. Однако, вы должны быть осторожны в изменении стиля @ref{subplot} если вы планируете добавлять @ref{colorbar} или вращать график -- часть графика может стать невидимой.
+
+@item Can I combine bitmap and vector output in EPS?
+Yes. Sometimes you may have huge surface and a small set of curves and/or text on the plot. You can use function @ref{rasterize} just after making surface plot. This will put all plot to bitmap background. At this later plotting will be in vector format. For example, you can do something like following:
+@verbatim
+surf x y z
+rasterize # make surface as bitmap
+axis
+write 'fname.eps'
+@end verbatim
+
 @end table
 
 @external{}
index a5dca99bd6439ec1f46486dd46cd7f9080ea56f0..9dcad68e961096a79e87baec4822ad47c338e2e4 100644 (file)
@@ -790,22 +790,31 @@ The sample code, demonstrated ticks feature is
 @verbatim
 int sample(mglGraph *gr)
 {
-  gr->SubPlot(3,2,0); gr->Title("Usual axis");  gr->Axis();
-  gr->SubPlot(3,2,1); gr->Title("Too big/small range");
+  gr->SubPlot(3,3,0); gr->Title("Usual axis");  gr->Axis();
+  gr->SubPlot(3,3,1); gr->Title("Too big/small range");
   gr->SetRanges(-1000,1000,0,0.001);  gr->Axis();
-  gr->SubPlot(3,2,3); gr->Title("Too narrow range");
+  gr->SubPlot(3,3,2); gr->Title("LaTeX-like labels");
+  gr->Axis("F!");
+  gr->SubPlot(3,3,3); gr->Title("Too narrow range");
   gr->SetRanges(100,100.1,10,10.01);  gr->Axis();
-  gr->SubPlot(3,2,4); gr->Title("Disable ticks tuning");
-  gr->SetTuneTicks(0);  gr->Axis();
-
-  gr->SubPlot(3,2,2); gr->Title("Manual ticks");  gr->SetRanges(-M_PI,M_PI, 0, 2);
-  mreal val[]={-M_PI, -M_PI/2, 0, 0.886, M_PI/2, M_PI};
-  gr->SetTicksVal('x', mglData(6,val), "-\\pi\n-\\pi/2\n0\nx^*\n\\pi/2\n\\pi");
-  gr->Axis(); gr->Grid(); gr->FPlot("2*cos(x^2)^2", "r2");
-
-  gr->SubPlot(3,2,5); gr->Title("Time ticks");  gr->SetRange('x',0,3e5);
+  gr->SubPlot(3,3,4); gr->Title("No tuning, manual '+'");
+  // for version<2.3 you need first call gr->SetTuneTicks(0);
+  gr->Axis("+!");
+  gr->SubPlot(3,3,5); gr->Title("Template for ticks");
+  gr->SetTickTempl('x',"xxx:%g"); gr->SetTickTempl('y',"y:%g");
+  gr->Axis();
+  // now switch it off for other plots
+  gr->SetTickTempl('x',"");   gr->SetTickTempl('y',"");
+  gr->SubPlot(3,3,6); gr->Title("No tuning, higher precision");
+  gr->Axis("!4");
+  gr->SubPlot(3,3,7); gr->Title("Manual ticks");  gr->SetRanges(-M_PI,M_PI, 0, 2);
+  gr->SetTicks('x',M_PI,0,0,"\\pi");  gr->AddTick('x',0.886,"x^*");
+  // alternatively you can use following lines
+  //double val[]={-M_PI, -M_PI/2, 0, 0.886, M_PI/2, M_PI};
+  //gr->SetTicksVal('x', mglData(6,val), "-\\pi\n-\\pi/2\n0\nx^*\n\\pi/2\n\\pi");
+  gr->Axis();  gr->Grid();  gr->FPlot("2*cos(x^2)^2", "r2");
+  gr->SubPlot(3,3,8); gr->Title("Time ticks");  gr->SetRange('x',0,3e5);
   gr->SetTicksTime('x',0);  gr->Axis();
-  return 0;
 }
 @end verbatim
 
@@ -822,7 +831,8 @@ int sample(mglGraph *gr)
 
   gr->SubPlot(2,2,1,"<_");  gr->Title("Log-log axis");
   gr->SetRanges(0.01,100,0.1,100);  gr->SetFunc("lg(x)","lg(y)");
-  gr->Axis(); gr->FPlot("sqrt(1+x^2)"); gr->Label('x',"x",0);
+  gr->Axis(); gr->Grid("!","h=");   gr->Grid();
+  gr->FPlot("sqrt(1+x^2)"); gr->Label('x',"x",0);
   gr->Label('y', "y = \\sqrt{1+x^2}",0);
 
   gr->SubPlot(2,2,2,"<_");  gr->Title("Minus-log axis");
@@ -1035,7 +1045,7 @@ int sample(mglGraph *gr)
   mglData y;  mgls_prepare1d(&y);
   gr->Box();  gr->Plot(y.SubData(-1,0));
   gr->Text(y,"This is very very long string drawn along a curve",":k");
-  gr->Text(y,"Another string drawn above a curve","T:r");
+  gr->Text(y,"Another string drawn under a curve","T:r");
 
   gr->SubPlot(2,2,3,"");
   gr->Line(mglPoint(-1,-1),mglPoint(1,-1),"rA");
@@ -1462,7 +1472,7 @@ int sample(mglGraph *gr)
 {
   gr->Light(true);     gr->Light(0,mglPoint(0,0,1));
 @end verbatim
-and draw the surface, considering coordinates x,y to be uniformly distributed in interval @var{Min}*@var{Max}
+and draw the surface, considering coordinates x,y to be uniformly distributed in axis range
 @verbatim
   mglData a0(50,40);
   a0.Modify("0.6*sin(2*pi*x)*sin(3*pi*y)+0.4*cos(3*pi*(x*y))");
@@ -3011,17 +3021,25 @@ Function @ref{dots} is another way to draw irregular points. @code{Dots} use col
 @verbatim
 int sample(mglGraph *gr)
 {
-  int i, n=1000;
-  mglData x(n),y(n),z(n);
+  int i, n=2000;
+  mglData x(n),y(n),z(n),c(n);
   for(i=0;i<n;i++)
   {
     mreal t=M_PI*(mgl_rnd()-0.5), f=2*M_PI*mgl_rnd();
     x.a[i] = 0.9*cos(t)*cos(f);
     y.a[i] = 0.9*cos(t)*sin(f);
     z.a[i] = 0.6*sin(t);
+    c.a[i] = cos(2*t);
   }
-  gr->Title("Dots sample"); gr->Rotate(50,60);
+  gr->SubPlot(2,2,0); gr->Title("Dots sample");  gr->Rotate(50,60);
   gr->Box();  gr->Dots(x,y,z);
+  gr->Alpha(true);
+  gr->SubPlot(2,2,1); gr->Title("add transparency"); gr->Rotate(50,60);
+  gr->Box();  gr->Dots(x,y,z,c);
+  gr->SubPlot(2,2,2); gr->Title("add coloring"); gr->Rotate(50,60);
+  gr->Box();  gr->Dots(x,y,z,x,c);
+  gr->SubPlot(2,2,3); gr->Title("Only coloring");gr->Rotate(50,60);
+  gr->Box();  gr->Tens(x,y,z,x," .");
   return 0;
 }
 @end verbatim
@@ -3290,10 +3308,12 @@ In this section I've included some small hints and advices for the improving of
 * Using primitives::
 * STFA sample::
 * Mapping visualization::
+* Data interpolation::
 * Making regular data::
 * Making histogram::
 * Nonlinear fitting hints::
 * PDE solving hints::
+* Drawing phase plain::
 * MGL parser using::
 * Using options::
 * ``Templates''::
@@ -3468,7 +3488,7 @@ int sample(mglGraph *gr)
   mglData a;  mgls_prepare2d(&a);
   gr->Title("Fog sample");
   gr->Light(true);  gr->Rotate(50,60);  gr->Fog(1); gr->Box();
-  gr->Surf(a);
+  gr->Surf(a);  gr->Cont(a,"y");
   return 0;
 }
 @end verbatim
@@ -3664,7 +3684,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
-@node Mapping visualization, Making regular data, STFA sample, Hints
+@node Mapping visualization, Data interpolation, STFA sample, Hints
 @subsection Mapping visualization
 @nav{}
 
@@ -3696,9 +3716,80 @@ int sample(mglGraph *gr)
 
 @pfig{map, Example of Map().}
 
+
+
+@c ------------------------------------------------------------------
+@external{}
+@node Data interpolation, Making regular data, Mapping visualization, Hints
+@subsection Data interpolation
+@nav{}
+
+There are many functions to get interpolated values of a data array. Basically all of them can be divided by 3 categories:
+@enumerate
+@item functions which return single value at given point (see @ref{Interpolation} and @code{mglGSpline()} in @ref{Global functions});
+@item functions @ref{subdata} and @ref{evaluate} for indirect access to data elements;
+@item functions @ref{refill}, @ref{gspline} and @ref{datagrid} which fill regular (rectangular) data array by interpolated values.
+@end enumerate
+
+The usage of first category is rather straightforward and don't need any special comments.
+
+There is difference in indirect access functions. Function @ref{subdata} use use step-like interpolation to handle correctly single @code{nan} values in the data array. Contrary, function @ref{evaluate} use local spline interpolation, which give smoother output but spread @code{nan} values. So, @ref{subdata} should be used for specific data elements (for example, for given column), and @ref{evaluate} should be used for distributed elements (i.e. consider data array as some field). Following sample illustrates this difference:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"");  gr->Title("SubData vs Evaluate");
+  mglData in(9), arg(99), e, s;
+  gr->Fill(in,"x^3/1.1"); gr->Fill(arg,"4*x+4");
+  gr->Plot(in,"ko ");     gr->Box();
+  e = in.Evaluate(arg);   gr->Plot(e,"b.","legend 'Evaluate'");
+  s = in.SubData(arg);    gr->Plot(s,"r.","legend 'SubData'");
+  gr->Legend(2);
+}
+@end verbatim
+
+@pfig{indirect, Example of indirect data access.}
+
+Example of @ref{datagrid} usage is done in @ref{Making regular data}. Here I want to show the peculiarities of @ref{refill} and @ref{gspline} functions. Both functions require argument(s) which provide coordinates of the data values, and return rectangular data array which equidistantly distributed in axis range. So, in opposite to @ref{evaluate} function, @ref{refill} and @ref{gspline} can interpolate non-equidistantly distributed data. At this both functions @ref{refill} and @ref{gspline} provide continuity of 2nd derivatives along coordinate(s). However, @ref{refill} is slower but give better (from human point of view) result than global spline @ref{gspline} due to more advanced algorithm. Following sample illustrates this difference:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData x(10), y(10), r(100);
+  x.Modify("0.5+rnd");  x.CumSum("x");  x.Norm(-1,1);
+  y.Modify("sin(pi*v)/1.5",x);
+  gr->SubPlot(2,2,0,"<_");  gr->Title("Refill sample");
+  gr->Axis();  gr->Box(); gr->Plot(x,y,"o ");
+  gr->Refill(r,x,y);  // or you can use r.Refill(x,y,-1,1);
+  gr->Plot(r,"r");  gr->FPlot("sin(pi*x)/1.5","B:");
+  gr->SubPlot(2,2,1,"<_");gr->Title("Global spline");
+  gr->Axis();  gr->Box(); gr->Plot(x,y,"o ");
+  r.RefillGS(x,y,-1,1);   gr->Plot(r,"r");
+  gr->FPlot("sin(pi*x)/1.5","B:");
+
+  gr->Alpha(true);  gr->Light(true);
+  mglData z(10,10), xx(10,10), yy(10,10), rr(100,100);
+  y.Modify("0.5+rnd");  y.CumSum("x");  y.Norm(-1,1);
+  for(int i=0;i<10;i++) for(int j=0;j<10;j++)
+    z.a[i+10*j] = sin(M_PI*x.a[i]*y.a[j])/1.5;
+  gr->SubPlot(2,2,2); gr->Title("2d regular");  gr->Rotate(40,60);
+  gr->Axis();  gr->Box(); gr->Mesh(x,y,z,"k");
+  gr->Refill(rr,x,y,z); gr->Surf(rr);
+
+  gr->Fill(xx,"(x+1)/2*cos(y*pi/2-1)");
+  gr->Fill(yy,"(x+1)/2*sin(y*pi/2-1)");
+  for(int i=0;i<10*10;i++)
+    z.a[i] = sin(M_PI*xx.a[i]*yy.a[i])/1.5;
+  gr->SubPlot(2,2,3); gr->Title("2d non-regular");  gr->Rotate(40,60);
+  gr->Axis();  gr->Box();  gr->Plot(xx,yy,z,"ko ");
+  gr->Refill(rr,xx,yy,z);  gr->Surf(rr);
+}
+@end verbatim
+
+@pfig{refill, Example of non-equidistant data interpolation.}
+
+
 @c ------------------------------------------------------------------
 @external{}
-@node Making regular data, Making histogram, Mapping visualization, Hints
+@node Making regular data, Making histogram, Data interpolation, Hints
 @subsection Making regular data
 @nav{}
 
@@ -3767,7 +3858,7 @@ Nonlinear fitting is rather simple. All that you need is the data to fit, the ap
 and plot it to see that data we will fit
 @verbatim
   gr->Title("Fitting sample");
-  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, ". ");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, "k. ");
   gr->Axis(); gr->Plot(in, "b");
   gr->Puts(mglPoint(0, 2.2), "initial: y = 0.3+sin(2\\pi x)", "b");
 @end verbatim
@@ -3800,7 +3891,7 @@ int sample(mglGraph *gr)
   mglData res = gr->Fit(rnd, "a+b*sin(c*x)", "abc", Ini);
 
   gr->Title("Fitting sample");
-  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, ". ");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, "k. ");
   gr->Axis();   gr->Plot(res, "r"); gr->Plot(in, "b");
   gr->Puts(mglPoint(-0.9, -1.3), "fitted:", "r:L");
   gr->PutsFit(mglPoint(0, -1.8), "y = ", "r");
@@ -3813,26 +3904,26 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
-@node PDE solving hints, MGL parser using, Nonlinear fitting hints, Hints
+@node PDE solving hints, Drawing phase plain, Nonlinear fitting hints, Hints
 @subsection PDE solving hints
 @nav{}
 
-Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @code{mglRay()} for ray tracing, @code{mglPDE()} for PDE solving, @code{mglQO2d()} for beam tracing in 2D case (see @ref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
+Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @ref{ray} for ray tracing, @ref{pde} for PDE solving, @ref{qo2d} for beam tracing in 2D case (see @ref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
 
-The ray tracing can be done by @code{mglRay()} function. Really ray tracing equation is Hamiltonian equation for 3D space. So, the function can be also used for finding a particle trajectory (i.e. solve Hamiltonian ODE) for 1D, 2D or 3D cases. The function have a set of arguments. First of all, it is Hamiltonian which defined the media (or the equation) you are planning to use. The Hamiltonian is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, time @samp{t} (for particle dynamics) and momentums @samp{p}=@math{p_x}, @samp{q}=@math{p_y}, @samp{v}=@math{p_z}. Next, you have to define the initial conditions for coordinates and momentums at @samp{t}=0 and set the integrations step (default is 0.1) and its duration (default is 10). The Runge-Kutta method of 4-th order is used for integration.
+The ray tracing can be done by @ref{ray} function. Really ray tracing equation is Hamiltonian equation for 3D space. So, the function can be also used for finding a particle trajectory (i.e. solve Hamiltonian ODE) for 1D, 2D or 3D cases. The function have a set of arguments. First of all, it is Hamiltonian which defined the media (or the equation) you are planning to use. The Hamiltonian is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, time @samp{t} (for particle dynamics) and momentums @samp{p}=@math{p_x}, @samp{q}=@math{p_y}, @samp{v}=@math{p_z}. Next, you have to define the initial conditions for coordinates and momentums at @samp{t}=0 and set the integrations step (default is 0.1) and its duration (default is 10). The Runge-Kutta method of 4-th order is used for integration.
 @verbatim
   const char *ham = "p^2+q^2-x-1+i*0.5*(y+x)*(y>-x)";
   mglData r = mglRay(ham, mglPoint(-0.7, -1), mglPoint(0, 0.5), 0.02, 2);
 @end verbatim
 This example calculate the reflection from linear layer (media with Hamiltonian @samp{p^2+q^2-x-1}=@math{p_x^2+p_y^2-x-1}). This is parabolic curve. The resulting array have 7 columns which contain data for @{x,y,z,p,q,v,t@}.
 
-The solution of PDE is a bit more complicated. As previous you have to specify the equation as pseudo-differential operator @math{\hat H(x, \nabla)} which is called sometime as ``Hamiltonian'' (for example, in beam tracing). As previously, it is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z} (but not time!), momentums @samp{p}=@math{(d/dx)/i k_0}, @samp{q}=@math{(d/dy)/i k_0} and field amplitude @samp{u}=@math{|u|}. The evolutionary coordinate is @samp{z} in all cases. So that, the equation look like @math{du/dz = ik_0 H(x,y,\hat p, \hat q, |u|)[u]}. Dependence on field amplitude @samp{u}=@math{|u|} allows one to solve nonlinear problems too. For example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. Also you may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}, but only if dependence on variable @samp{i} is linear (i.e. @math{H = Hre+i*Him}).
+The solution of PDE is a bit more complicated. As previous you have to specify the equation as pseudo-differential operator @math{\hat H(x, \nabla)} which is called sometime as ``Hamiltonian'' (for example, in beam tracing). As previously, it is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z} (but not time!), momentums @samp{p}=@math{(d/dx)/i k_0}, @samp{q}=@math{(d/dy)/i k_0} and field amplitude @samp{u}=@math{|u|}. The evolutionary coordinate is @samp{z} in all cases. So that, the equation look like @math{du/dz = ik_0 H(x,y,\hat p, \hat q, |u|)[u]}. Dependence on field amplitude @samp{u}=@math{|u|} allows one to solve nonlinear problems too. For example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. Also you may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"} or @code{ham = "p^2 + i1*x*(x>0)"}.
 
-Next step is specifying the initial conditions at @samp{z}=@code{Min.z}. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified range [Min, Max]. So, the data arrays should have corresponding scales. Finally, you may set the integration step and parameter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
+Next step is specifying the initial conditions at @samp{z} equal to minimal z-axis value. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified axis range. So, the data arrays should have corresponding scales. Finally, you may set the integration step and parameter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
 
 Final comment is concerning the possible form of pseudo-differential operator @math{H}. At this moment, simplified form of operator @math{H} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this operator is effectively @math{H = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed for 3D case.
 
-So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{ik_0 \partial_z u + \Delta u + x \cdot u + i (x+z)/2 \cdot u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this:
+So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{1/ik_0 * du/dz + d^2 u/dx^2 + d^2 u/dy^2 + x * u + i (x+z)/2 * u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this:
 @verbatim
 int sample(mglGraph *gr)
 {
@@ -3852,7 +3943,7 @@ int sample(mglGraph *gr)
 
 @pfig{pde, Example of PDE solving.}
 
-The last example is example of beam tracing. Beam tracing equation is special kind of PDE equation written in coordinates accompanied to a ray. Generally this is the same parameters and limitation as for PDE solving but the coordinates are defined by the ray and by parameter of grid width @var{w} in direction transverse the ray. So, you don't need to specify the range of coordinates. @strong{BUT} there is limitation. The accompanied coordinates are well defined only for smooth enough rays, i.e. then the ray curvature @math{K} (which is defined as @math{1/K^2 = (|\ddot r|^2 |\dot r|^2 - (\ddot r, \dot r)^2)/|\dot r|^6}) is much large then the grid width: @math{K>>w}. So, you may receive incorrect results if this condition will be broken.
+The last example is example of beam tracing. Beam tracing equation is special kind of PDE equation written in coordinates accompanied to a ray. Generally this is the same parameters and limitation as for PDE solving but the coordinates are defined by the ray and by parameter of grid width @var{w} in direction transverse the ray. So, you don't need to specify the range of coordinates. @strong{BUT} there is limitation. The accompanied coordinates are well defined only for smooth enough rays, i.e. then the ray curvature @math{K} (which is defined as @math{1/K^2 = (|r''|^2 |r'|^2 - (r'', r'')^2)/|r'|^6}) is much large then the grid width: @math{K>>w}. So, you may receive incorrect results if this condition will be broken.
 
 You may use following code for obtaining the same solution as in previous example:
 @verbatim
@@ -3882,7 +3973,48 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
-@node MGL parser using, Using options, PDE solving hints, Hints
+@node Drawing phase plain, MGL parser using, PDE solving hints, Hints
+@subsection Drawing phase plain
+@nav{}
+
+Here I want say a few words of plotting phase plains. Phase plain is name for system of coordinates @math{x}, @math{x'}, i.e. a variable and its time derivative. Plot in phase plain is very useful for qualitative analysis of an ODE, because such plot is rude (it topologically the same for a range of ODE parameters). Most often the phase plain @{@math{x}, @math{x'}@} is used (due to its simplicity), that allows to analyze up to the 2nd order ODE (i.e. @math{x''+f(x,x')=0}).
+
+The simplest way to draw phase plain in MathGL is using @ref{flow} function(s), which automatically select several points and draw flow threads. If the ODE have an integral of motion (like Hamiltonian @math{H(x,x')=const} for dissipation-free case) then you can use @ref{cont} function for plotting isolines (contours). In fact. isolines are the same as flow threads, but without arrows on it. Finally, you can directly solve ODE using @ref{ode} function and plot its numerical solution.
+
+Let demonstrate this for ODE equation @math{x''-x+3*x^2=0}. This is nonlinear oscillator with square nonlinearity. It has integral @math{H=y^2+2*x^3-x^2=Const}. Also it have 2 typical stationary points: saddle at @{x=0, y=0@} and center at @{x=1/3, y=0@}. Motion at vicinity of center is just simple oscillations, and is stable to small variation of parameters. In opposite, motion around saddle point is non-stable to small variation of parameters, and is very slow. So, calculation around saddle points are more difficult, but more important. Saddle points are responsible for solitons, stochasticity and so on.
+
+So, let draw this phase plain by 3 different methods. First, draw isolines for @math{H=y^2+2*x^3-x^2=Const} -- this is simplest for ODE without dissipation. Next, draw flow threads -- this is straightforward way, but the automatic choice of starting points is not always optimal. Finally, use @ref{ode} to check the above plots. At this we need to run @ref{ode} in both direction of time (in future and in the past) to draw whole plain. Alternatively, one can put starting points far from (or at the bounding box as done in @ref{flow}) the plot, but this is a more complicated. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0,"<_");  gr->Title("Cont");  gr->Box();
+  gr->Axis();  gr->Label('x',"x");  gr->Label('y',"\\dot{x}");
+  mglData f(100,100);   gr->Fill(f,"y^2+2*x^3-x^2-0.5");
+  gr->Cont(f);
+  gr->SubPlot(2,2,1,"<_");  gr->Title("Flow");  gr->Box();
+  gr->Axis();  gr->Label('x',"x");  gr->Label('y',"\\dot{x}");
+  mglData fx(100,100), fy(100,100);
+  gr->Fill(fx,"x-3*x^2");  gr->Fill(fy,"y");
+  gr->Flow(fy,fx,"v","value 7");
+  gr->SubPlot(2,2,2,"<_");  gr->Title("ODE");   gr->Box();
+  gr->Axis();  gr->Label('x',"x");  gr->Label('y',"\\dot{x}");
+  for(double x=-1;x<1;x+=0.1)
+  {
+    mglData in(2), r;   in.a[0]=x;
+    r = mglODE("y;x-3*x^2","xy",in);
+    gr->Plot(r.SubData(0), r.SubData(1));
+    r = mglODE("-y;-x+3*x^2","xy",in);
+    gr->Plot(r.SubData(0), r.SubData(1));
+  }
+}
+@end verbatim
+
+@pfig{ode, Example of ODE solving and phase plain drawing.}
+
+
+@c ------------------------------------------------------------------
+@external{}
+@node MGL parser using, Using options, Drawing phase plain, Hints
 @subsection MGL parser using
 @nav{}
 
@@ -4132,6 +4264,20 @@ They are standard GNU tools. There is special FAQ about its usage under Windows
 @item How can I draw equal axis range even for rectangular image?
 Just use @code{Aspect(NAN,NAN)} for each subplot, or at the beginning of the drawing.
 
+@item How I can set transparent background?
+Just use code like @code{Clf("r@{A5@}");} or prepare PNG file and set it as background image by call @code{LoadBackground("fname.png");}.
+
+@item How I can reduce "white" edges around bounding box?
+The simplest way is to use @ref{subplot} style. However, you should be careful if you plan to add @ref{colorbar} or rotate plot -- part of plot can be invisible if you will use non-default @ref{subplot} style.
+
+@item Can I combine bitmap and vector output in EPS?
+Yes. Sometimes you may have huge surface and a small set of curves and/or text on the plot. You can use function @ref{rasterize} just after making surface plot. This will put all plot to bitmap background. At this later plotting will be in vector format. For example, you can do something like following:
+@verbatim
+gr->Surf(x, y, z);
+gr->Rasterize(); // make surface as bitmap
+gr->Axis();
+gr->WriteFrame("fname.eps");
+@end verbatim
 
 @end table
 
index f6001f171c94139dbb5450054ba731c889057f76..a318c2c388b87e4b698c6a2782534e7e480c0ea1 100644 (file)
@@ -822,7 +822,8 @@ int sample(mglGraph *gr)
 
   gr->SubPlot(2,2,1,"<_");  gr->Title("Log-log axis");
   gr->SetRanges(0.01,100,0.1,100);  gr->SetFunc("lg(x)","lg(y)");
-  gr->Axis(); gr->FPlot("sqrt(1+x^2)"); gr->Label('x',"x",0);
+  gr->Axis(); gr->Grid("!","h=");   gr->Grid();
+  gr->FPlot("sqrt(1+x^2)"); gr->Label('x',"x",0);
   gr->Label('y', "y = \\sqrt{1+x^2}",0);
 
   gr->SubPlot(2,2,2,"<_");  gr->Title("Minus-log axis");
@@ -1035,7 +1036,7 @@ int sample(mglGraph *gr)
   mglData y;  mgls_prepare1d(&y);
   gr->Box();  gr->Plot(y.SubData(-1,0));
   gr->Text(y,"This is very very long string drawn along a curve",":k");
-  gr->Text(y,"Another string drawn above a curve","T:r");
+  gr->Text(y,"Another string drawn under a curve","T:r");
 
   gr->SubPlot(2,2,3,"");
   gr->Line(mglPoint(-1,-1),mglPoint(1,-1),"rA");
@@ -1461,7 +1462,7 @@ int sample(mglGraph *gr)
 {
   gr->Light(true);     gr->Light(0,mglPoint(0,0,1));
 @end verbatim
-and draw the surface, considering coordinates x,y to be uniformly distributed in interval @var{Min}*@var{Max}
+and draw the surface, considering coordinates x,y to be uniformly distributed in axis range
 @verbatim
   mglData a0(50,40);
   a0.Modify("0.6*sin(2*pi*x)*sin(3*pi*y)+0.4*cos(3*pi*(x*y))");
@@ -3009,17 +3010,25 @@ Function @ref{dots} is another way to draw irregular points. @code{Dots} use col
 @verbatim
 int sample(mglGraph *gr)
 {
-  int i, n=1000;
-  mglData x(n),y(n),z(n);
+  int i, n=2000;
+  mglData x(n),y(n),z(n),c(n);
   for(i=0;i<n;i++)
   {
     mreal t=M_PI*(mgl_rnd()-0.5), f=2*M_PI*mgl_rnd();
     x.a[i] = 0.9*cos(t)*cos(f);
     y.a[i] = 0.9*cos(t)*sin(f);
     z.a[i] = 0.6*sin(t);
+    c.a[i] = cos(2*t);
   }
-  gr->Title("Dots sample"); gr->Rotate(50,60);
+  gr->SubPlot(2,2,0); gr->Title("Dots sample");  gr->Rotate(50,60);
   gr->Box();  gr->Dots(x,y,z);
+  gr->Alpha(true);
+  gr->SubPlot(2,2,1); gr->Title("add transparency"); gr->Rotate(50,60);
+  gr->Box();  gr->Dots(x,y,z,c);
+  gr->SubPlot(2,2,2); gr->Title("add coloring"); gr->Rotate(50,60);
+  gr->Box();  gr->Dots(x,y,z,x,c);
+  gr->SubPlot(2,2,3); gr->Title("Only coloring");gr->Rotate(50,60);
+  gr->Box();  gr->Tens(x,y,z,x," .");
   return 0;
 }
 @end verbatim
@@ -3288,10 +3297,12 @@ In this section I've included some small hints and advices for the improving of
 * Using primitives::
 * STFA sample::
 * Mapping visualization::
+* Data interpolation::
 * Making regular data::
 * Making histogram::
 * Nonlinear fitting hints::
 * PDE solving hints::
+* Drawing phase plain::
 * MGL parser using::
 * Using options::
 * ``Templates''::
@@ -3466,7 +3477,7 @@ int sample(mglGraph *gr)
   mglData a;  mgls_prepare2d(&a);
   gr->Title("Fog sample");
   gr->Light(true);  gr->Rotate(50,60);  gr->Fog(1); gr->Box();
-  gr->Surf(a);
+  gr->Surf(a);  gr->Cont(a,"y");
   return 0;
 }
 @end verbatim
@@ -3662,7 +3673,7 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
-@node Mapping visualization, Making regular data, STFA sample, Hints
+@node Mapping visualization, Data interpolation, STFA sample, Hints
 @subsection Mapping visualization
 @nav{}
 
@@ -3696,7 +3707,76 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
-@node Making regular data, Making histogram, Mapping visualization, Hints
+@node Data interpolation, Making regular data, Mapping visualization, Hints
+@subsection Data interpolation
+@nav{}
+
+There are many functions to get interpolated values of a data array. Basically all of them can be divided by 3 categories:
+@enumerate
+@item functions which return single value at given point (see @ref{Interpolation} and @code{mglGSpline()} in @ref{Global functions});
+@item functions @ref{subdata} and @ref{evaluate} for indirect access to data elements;
+@item functions @ref{refill}, @ref{gspline} and @ref{datagrid} which fill regular (rectangular) data array by interpolated values.
+@end enumerate
+
+The usage of first category is rather straightforward and don't need any special comments.
+
+There is difference in indirect access functions. Function @ref{subdata} use use step-like interpolation to handle correctly single @code{nan} values in the data array. Contrary, function @ref{evaluate} use local spline interpolation, which give smoother output but spread @code{nan} values. So, @ref{subdata} should be used for specific data elements (for example, for given column), and @ref{evaluate} should be used for distributed elements (i.e. consider data array as some field). Following sample illustrates this difference:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(1,1,0,"");  gr->Title("SubData vs Evaluate");
+  mglData in(9), arg(99), e, s;
+  gr->Fill(in,"x^3/1.1"); gr->Fill(arg,"4*x+4");
+  gr->Plot(in,"ko ");     gr->Box();
+  e = in.Evaluate(arg);   gr->Plot(e,"b.","legend 'Evaluate'");
+  s = in.SubData(arg);    gr->Plot(s,"r.","legend 'SubData'");
+  gr->Legend(2);
+}
+@end verbatim
+
+@pfig{indirect, Example of indirect data access.}
+
+Example of @ref{datagrid} usage is done in @ref{Making regular data}. Here I want to show the peculiarities of @ref{refill} and @ref{gspline} functions. Both functions require argument(s) which provide coordinates of the data values, and return rectangular data array which equidistantly distributed in axis range. So, in opposite to @ref{evaluate} function, @ref{refill} and @ref{gspline} can interpolate non-equidistantly distributed data. At this both functions @ref{refill} and @ref{gspline} provide continuity of 2nd derivatives along coordinate(s). However, @ref{refill} is slower but give better (from human point of view) result than global spline @ref{gspline} due to more advanced algorithm. Following sample illustrates this difference:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData x(10), y(10), r(100);
+  x.Modify("0.5+rnd");  x.CumSum("x");  x.Norm(-1,1);
+  y.Modify("sin(pi*v)/1.5",x);
+  gr->SubPlot(2,2,0,"<_");  gr->Title("Refill sample");
+  gr->Axis();  gr->Box(); gr->Plot(x,y,"o ");
+  gr->Refill(r,x,y);  // or you can use r.Refill(x,y,-1,1);
+  gr->Plot(r,"r");  gr->FPlot("sin(pi*x)/1.5","B:");
+  gr->SubPlot(2,2,1,"<_");gr->Title("Global spline");
+  gr->Axis();  gr->Box(); gr->Plot(x,y,"o ");
+  r.RefillGS(x,y,-1,1);   gr->Plot(r,"r");
+  gr->FPlot("sin(pi*x)/1.5","B:");
+
+  gr->Alpha(true);  gr->Light(true);
+  mglData z(10,10), xx(10,10), yy(10,10), rr(100,100);
+  y.Modify("0.5+rnd");  y.CumSum("x");  y.Norm(-1,1);
+  for(int i=0;i<10;i++) for(int j=0;j<10;j++)
+    z.a[i+10*j] = sin(M_PI*x.a[i]*y.a[j])/1.5;
+  gr->SubPlot(2,2,2); gr->Title("2d regular");  gr->Rotate(40,60);
+  gr->Axis();  gr->Box(); gr->Mesh(x,y,z,"k");
+  gr->Refill(rr,x,y,z); gr->Surf(rr);
+
+  gr->Fill(xx,"(x+1)/2*cos(y*pi/2-1)");
+  gr->Fill(yy,"(x+1)/2*sin(y*pi/2-1)");
+  for(int i=0;i<10*10;i++)
+    z.a[i] = sin(M_PI*xx.a[i]*yy.a[i])/1.5;
+  gr->SubPlot(2,2,3); gr->Title("2d non-regular");  gr->Rotate(40,60);
+  gr->Axis();  gr->Box();  gr->Plot(xx,yy,z,"ko ");
+  gr->Refill(rr,xx,yy,z);  gr->Surf(rr);
+}
+@end verbatim
+
+@pfig{refill, Example of non-equidistant data interpolation.}
+
+
+@c ------------------------------------------------------------------
+@external{}
+@node Making regular data, Making histogram, Data interpolation, Hints
 @subsection Making regular data
 @nav{}
 
@@ -3765,7 +3845,7 @@ Nonlinear fitting is rather simple. All that you need is the data to fit, the ap
 and plot it to see that data we will fit
 @verbatim
   gr->Title("Fitting sample");
-  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, ". ");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, "k. ");
   gr->Axis(); gr->Plot(in, "b");
   gr->Puts(mglPoint(0, 2.2), "initial: y = 0.3+sin(2\\pi x)", "b");
 @end verbatim
@@ -3798,7 +3878,7 @@ int sample(mglGraph *gr)
   mglData res = gr->Fit(rnd, "a+b*sin(c*x)", "abc", Ini);
 
   gr->Title("Fitting sample");
-  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, ". ");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, "k. ");
   gr->Axis();   gr->Plot(res, "r"); gr->Plot(in, "b");
   gr->Puts(mglPoint(-0.9, -1.3), "fitted:", "r:L");
   gr->PutsFit(mglPoint(0, -1.8), "y = ", "r");
@@ -3811,26 +3891,26 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
-@node PDE solving hints, MGL parser using, Nonlinear fitting hints, Hints
+@node PDE solving hints, Drawing phase plain, Nonlinear fitting hints, Hints
 @subsection PDE solving hints
 @nav{}
 
-Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @code{mglRay()} for ray tracing, @code{mglPDE()} for PDE solving, @code{mglQO2d()} for beam tracing in 2D case (see @ref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
+Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @ref{ray} for ray tracing, @ref{pde} for PDE solving, @ref{qo2d} for beam tracing in 2D case (see @ref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
 
-The ray tracing can be done by @code{mglRay()} function. Really ray tracing equation is Hamiltonian equation for 3D space. So, the function can be also used for finding a particle trajectory (i.e. solve Hamiltonian ODE) for 1D, 2D or 3D cases. The function have a set of arguments. First of all, it is Hamiltonian which defined the media (or the equation) you are planning to use. The Hamiltonian is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, time @samp{t} (for particle dynamics) and momentums @samp{p}=@math{p_x}, @samp{q}=@math{p_y}, @samp{v}=@math{p_z}. Next, you have to define the initial conditions for coordinates and momentums at @samp{t}=0 and set the integrations step (default is 0.1) and its duration (default is 10). The Runge-Kutta method of 4-th order is used for integration.
+The ray tracing can be done by @ref{ray} function. Really ray tracing equation is Hamiltonian equation for 3D space. So, the function can be also used for finding a particle trajectory (i.e. solve Hamiltonian ODE) for 1D, 2D or 3D cases. The function have a set of arguments. First of all, it is Hamiltonian which defined the media (or the equation) you are planning to use. The Hamiltonian is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, time @samp{t} (for particle dynamics) and momentums @samp{p}=@math{p_x}, @samp{q}=@math{p_y}, @samp{v}=@math{p_z}. Next, you have to define the initial conditions for coordinates and momentums at @samp{t}=0 and set the integrations step (default is 0.1) and its duration (default is 10). The Runge-Kutta method of 4-th order is used for integration.
 @verbatim
   const char *ham = "p^2+q^2-x-1+i*0.5*(y+x)*(y>-x)";
   mglData r = mglRay(ham, mglPoint(-0.7, -1), mglPoint(0, 0.5), 0.02, 2);
 @end verbatim
 This example calculate the reflection from linear layer (media with Hamiltonian @samp{p^2+q^2-x-1}=@math{p_x^2+p_y^2-x-1}). This is parabolic curve. The resulting array have 7 columns which contain data for @{x,y,z,p,q,v,t@}.
 
-The solution of PDE is a bit more complicated. As previous you have to specify the equation as pseudo-differential operator @math{\hat H(x, \nabla)} which is called sometime as ``Hamiltonian'' (for example, in beam tracing). As previously, it is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z} (but not time!), momentums @samp{p}=@math{(d/dx)/i k_0}, @samp{q}=@math{(d/dy)/i k_0} and field amplitude @samp{u}=@math{|u|}. The evolutionary coordinate is @samp{z} in all cases. So that, the equation look like @math{du/dz = ik_0 H(x,y,\hat p, \hat q, |u|)[u]}. Dependence on field amplitude @samp{u}=@math{|u|} allows one to solve nonlinear problems too. For example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. Also you may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}, but only if dependence on variable @samp{i} is linear (i.e. @math{H = Hre+i*Him}).
+The solution of PDE is a bit more complicated. As previous you have to specify the equation as pseudo-differential operator @math{\hat H(x, \nabla)} which is called sometime as ``Hamiltonian'' (for example, in beam tracing). As previously, it is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z} (but not time!), momentums @samp{p}=@math{(d/dx)/i k_0}, @samp{q}=@math{(d/dy)/i k_0} and field amplitude @samp{u}=@math{|u|}. The evolutionary coordinate is @samp{z} in all cases. So that, the equation look like @math{du/dz = ik_0 H(x,y,\hat p, \hat q, |u|)[u]}. Dependence on field amplitude @samp{u}=@math{|u|} allows one to solve nonlinear problems too. For example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. Also you may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"} or @code{ham = "p^2 + i1*x*(x>0)"}.
 
-Next step is specifying the initial conditions at @samp{z}=@code{Min.z}. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified range [Min, Max]. So, the data arrays should have corresponding scales. Finally, you may set the integration step and parameter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
+Next step is specifying the initial conditions at @samp{z} equal to minimal z-axis value. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified axis range. So, the data arrays should have corresponding scales. Finally, you may set the integration step and parameter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
 
 Final comment is concerning the possible form of pseudo-differential operator @math{H}. At this moment, simplified form of operator @math{H} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this operator is effectively @math{H = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed for 3D case.
 
-So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{ik_0 \partial_z u + \Delta u + x \cdot u + i (x+z)/2 \cdot u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this:
+So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{1/ik_0 * du/dz + d^2 u/dx^2 + d^2 u/dy^2 + x * u + i (x+z)/2 * u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this:
 @verbatim
 int sample(mglGraph *gr)
 {
@@ -3850,7 +3930,7 @@ int sample(mglGraph *gr)
 
 @pfig{pde, Example of PDE solving.}
 
-The last example is example of beam tracing. Beam tracing equation is special kind of PDE equation written in coordinates accompanied to a ray. Generally this is the same parameters and limitation as for PDE solving but the coordinates are defined by the ray and by parameter of grid width @var{w} in direction transverse the ray. So, you don't need to specify the range of coordinates. @strong{BUT} there is limitation. The accompanied coordinates are well defined only for smooth enough rays, i.e. then the ray curvature @math{K} (which is defined as @math{1/K^2 = (|\ddot r|^2 |\dot r|^2 - (\ddot r, \dot r)^2)/|\dot r|^6}) is much large then the grid width: @math{K>>w}. So, you may receive incorrect results if this condition will be broken.
+The last example is example of beam tracing. Beam tracing equation is special kind of PDE equation written in coordinates accompanied to a ray. Generally this is the same parameters and limitation as for PDE solving but the coordinates are defined by the ray and by parameter of grid width @var{w} in direction transverse the ray. So, you don't need to specify the range of coordinates. @strong{BUT} there is limitation. The accompanied coordinates are well defined only for smooth enough rays, i.e. then the ray curvature @math{K} (which is defined as @math{1/K^2 = (|r''|^2 |r'|^2 - (r'', r'')^2)/|r'|^6}) is much large then the grid width: @math{K>>w}. So, you may receive incorrect results if this condition will be broken.
 
 You may use following code for obtaining the same solution as in previous example:
 @verbatim
@@ -3880,7 +3960,48 @@ int sample(mglGraph *gr)
 
 @c ------------------------------------------------------------------
 @external{}
-@node MGL parser using, Using options, PDE solving hints, Hints
+@node Drawing phase plain, MGL parser using, PDE solving hints, Hints
+@subsection Drawing phase plain
+@nav{}
+
+Here I want say a few words of plotting phase plains. Phase plain is name for system of coordinates @math{x}, @math{x'}, i.e. a variable and its time derivative. Plot in phase plain is very useful for qualitative analysis of an ODE, because such plot is rude (it topologically the same for a range of ODE parameters). Most often the phase plain @{@math{x}, @math{x'}@} is used (due to its simplicity), that allows to analyze up to the 2nd order ODE (i.e. @math{x''+f(x,x')=0}).
+
+The simplest way to draw phase plain in MathGL is using @ref{flow} function(s), which automatically select several points and draw flow threads. If the ODE have an integral of motion (like Hamiltonian @math{H(x,x')=const} for dissipation-free case) then you can use @ref{cont} function for plotting isolines (contours). In fact. isolines are the same as flow threads, but without arrows on it. Finally, you can directly solve ODE using @ref{ode} function and plot its numerical solution.
+
+Let demonstrate this for ODE equation @math{x''-x+3*x^2=0}. This is nonlinear oscillator with square nonlinearity. It has integral @math{H=y^2+2*x^3-x^2=Const}. Also it have 2 typical stationary points: saddle at @{x=0, y=0@} and center at @{x=1/3, y=0@}. Motion at vicinity of center is just simple oscillations, and is stable to small variation of parameters. In opposite, motion around saddle point is non-stable to small variation of parameters, and is very slow. So, calculation around saddle points are more difficult, but more important. Saddle points are responsible for solitons, stochasticity and so on.
+
+So, let draw this phase plain by 3 different methods. First, draw isolines for @math{H=y^2+2*x^3-x^2=Const} -- this is simplest for ODE without dissipation. Next, draw flow threads -- this is straightforward way, but the automatic choice of starting points is not always optimal. Finally, use @ref{ode} to check the above plots. At this we need to run @ref{ode} in both direction of time (in future and in the past) to draw whole plain. Alternatively, one can put starting points far from (or at the bounding box as done in @ref{flow}) the plot, but this is a more complicated. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0,"<_");  gr->Title("Cont");  gr->Box();
+  gr->Axis();  gr->Label('x',"x");  gr->Label('y',"\\dot{x}");
+  mglData f(100,100);   gr->Fill(f,"y^2+2*x^3-x^2-0.5");
+  gr->Cont(f);
+  gr->SubPlot(2,2,1,"<_");  gr->Title("Flow");  gr->Box();
+  gr->Axis();  gr->Label('x',"x");  gr->Label('y',"\\dot{x}");
+  mglData fx(100,100), fy(100,100);
+  gr->Fill(fx,"x-3*x^2");  gr->Fill(fy,"y");
+  gr->Flow(fy,fx,"v","value 7");
+  gr->SubPlot(2,2,2,"<_");  gr->Title("ODE");   gr->Box();
+  gr->Axis();  gr->Label('x',"x");  gr->Label('y',"\\dot{x}");
+  for(double x=-1;x<1;x+=0.1)
+  {
+    mglData in(2), r;   in.a[0]=x;
+    r = mglODE("y;x-3*x^2","xy",in);
+    gr->Plot(r.SubData(0), r.SubData(1));
+    r = mglODE("-y;-x+3*x^2","xy",in);
+    gr->Plot(r.SubData(0), r.SubData(1));
+  }
+}
+@end verbatim
+
+@pfig{ode, Example of ODE solving and phase plain drawing.}
+
+
+@c ------------------------------------------------------------------
+@external{}
+@node MGL parser using, Using options, Drawing phase plain, Hints
 @subsection MGL parser using
 @nav{}
 
@@ -4133,6 +4254,21 @@ gr->Window(argc,argv,foo_draw,"Title",this);
 @item Как нарисовать одинаковые оси координат для прямоугольного (не квадратного) рисунка?
 Просто используйте @code{Aspect(NAN,NAN)} для каждого подграфика, или в начале рисования.
 
+@item Как задать полупрозрачный фон?
+Просто используйте код типа @code{Clf("r@{A5@}");} или подготовьте PNG файл и задайте его в качестве фона рисунка @code{LoadBackground("fname.png");}.
+
+@item Как уменьшить поля вокруг графика?
+Простейший путь состоит в использовании стилей @ref{subplot}. Однако, вы должны быть осторожны в изменении стиля @ref{subplot} если вы планируете добавлять @ref{colorbar} или вращать график -- часть графика может стать невидимой.
+
+@item Can I combine bitmap and vector output in EPS?
+Yes. Sometimes you may have huge surface and a small set of curves and/or text on the plot. You can use function @ref{rasterize} just after making surface plot. This will put all plot to bitmap background. At this later plotting will be in vector format. For example, you can do something like following:
+@verbatim
+gr->Surf(x, y, z);
+gr->Rasterize(); // make surface as bitmap
+gr->Axis();
+gr->WriteFrame("fname.eps");
+@end verbatim
+
 @end table
 
 @external{}
index ca0e512ca61398727c6a9d08d65c5971b41b509a..dede3b2ab98d1edaacc6519bd849cbd6086e94a7 100644 (file)
@@ -93,6 +93,9 @@ Note, you can download the latest sources (which can be not stable) from sourcef
 svn checkout http://svn.code.sf.net/p/mathgl/code/mathgl-2x mathgl-code
 @end verbatim
 
+@strong{IMPORTANT!} MathGL use a set of defines, which were determined at configure stage and may differ if used with non-default compiler (like using MathGL binaries compiled by MinGW in VisualStudio). There are @code{MGL_SYS_NAN, MGL_HAVE_TYPEOF, MGL_HAVE_PTHREAD, MGL_HAVE_ATTRIBUTE, MGL_HAVE_C99_COMPLEX, MGL_HAVE_RVAL}. I specially set them to @code{0} for Borland and Microsoft compilers due to compatibility reasons. Also default setting are good for GNU (gcc, mingw) and clang compilers. However, for another compiler you may need to manually set this defines to @code{0} in file @code{include/mgl2/config.h} if you are using precompiled binaries.
+
+
 @c ------------------------------------------------------------------
 @external{}
 @node  Quick guide, Changes from v.1, Installation, Overview
index 8d86cbae8f330f68b20b86609c9722387119b37e..3570dbbb739e2d2fed100a2644e771457fea9539 100644 (file)
@@ -93,6 +93,9 @@ MathGL это ...
 svn checkout http://svn.code.sf.net/p/mathgl/code/mathgl-2x mathgl-code
 @end verbatim
 
+@strong{ВАЖНО!} MathGL использует набор defines, определяемых на этапе конфигурирования библиотеки. Это @code{MGL_SYS_NAN, MGL_HAVE_TYPEOF, MGL_HAVE_PTHREAD, MGL_HAVE_ATTRIBUTE, MGL_HAVE_C99_COMPLEX, MGL_HAVE_RVAL}. Они могут отличаться при использовании бинарников скомпилированных другим компилятором (например при использовании скомпилированных MinGW бинарников в VisualStudio). Я специально устанавливаю их в @code{0} для компиляторов Borland и Microsoft из соображений совместимости. Кроме того, настройки по умолчанию подходят для компиляторов GNU (gcc, mingw) и clang. Однако, для прочих компиляторов может потребоваться ручная установка defines в @code{0} в файле @code{include/mgl2/config.h} если вы используете предварительно скомпилированные файлы.
+
+
 @c TODO Translate it!
 
 @c ------------------------------------------------------------------
index 21b0e7b7ce3e1a3b8aea7f61af920dbd9d87006b..356086ce437292c0b74b45cbaf96e57084e35559 100644 (file)
@@ -188,7 +188,7 @@ Terminate execution.
 
 Class for parsing and executing MGL script. This class is defined in @code{#include <mgl2/mgl.h>}.
 
-The main function of mglParse class is @code{Execute()}. Exactly this function parses and executes the script string-by-string. Also there are subservient functions for the finding and creation of a variable (object derived from @code{mglData} class, see @ref{MGL variables}). These functions can be useful for displaying values of variables (arrays) in some external object (like, window) or for providing access to internal data. Function @code{AllowSetSize()} allows one to prevent changing the size of the  picture inside the script (forbids the MGL command @code{setsize}).
+The main function of mglParse class is @code{Execute()}. Exactly this function parses and executes the script string-by-string. Also there are subservient functions for the finding and creation of a variable (object derived from @code{mglDataA}). These functions can be useful for displaying values of variables (arrays) in some external object (like, window) or for providing access to internal data. Function @code{AllowSetSize()} allows one to prevent changing the size of the  picture inside the script (forbids the MGL command @code{setsize}).
 
 @c Note an important feature -- if user defines function @var{func} in variable then it will be called before the destroying of this variable (@pxref{mglVar class}).
 
@@ -224,7 +224,7 @@ The same as previous but read script from the file @var{fp}. If @var{print}=@cod
 @deftypefnx {Method on @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const wchar_t *}str, @code{long} pos=@code{0})
 @deftypefnx {C function} @code{int} mgl_parse_line (@code{HMGL} gr, @code{HMPR} p, @code{const char *}str, @code{int} pos)
 @deftypefnx {C function} @code{int} mgl_parse_linew (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}str, @code{int} pos)
-Function parses the string @var{str} and executes it by  using @var{gr} as a graphics plotter. Returns the value depending on an error presence in the string @var{str}: 0 -- no error, 1 -- wrong command argument(s), 2 -- unknown command, 3 -- string is too long. Optional argument @var{pos} allows to save the string position in the document (or file) for using @code{for|next} command.
+Function parses the string @var{str} and executes it by  using @var{gr} as a graphics plotter. Returns the value depending on an error presence in the string @var{str}: 0 -- no error, 1 -- wrong command argument(s), 2 -- unknown command, 3 -- string is too long, 4 -- strings is not closed. Optional argument @var{pos} allows to save the string position in the document (or file) for using @code{for|next} command.
 @end deftypefn
 
 @deftypefn {Method on @code{mglParse}} @code{mglData} Calc (@code{const char *}formula)
index 52769c962db8e843eb14822ba01f253e9eb59106..532c925e52fd2f382047fd94aa9e34ea57b8a633 100644 (file)
@@ -192,7 +192,7 @@ MathGL имеет встроенный скриптовый язык MGL для
 
 Класс разбирает и выполняет скрипты MGL. Он определен в @code{#include <mgl2/mgl.h>}.
 
-Основная функция класса mglParse -- @code{Execute()}, выполняющая построчный разбор скрипта. Также есть вспомогательные функции для поиска и создания переменных MGL (объектов, производных от @code{mglData}, см. @ref{MGL variables}). Эти функции полезны для отображения значений массивов во внешних объектах (например, в отдельном окне) или для предоставления доступа к внутренним массивам. Функция @code{AllowSetSize()} позволяет запретить изменение размера картинки (запрещает команду @code{setsize}). Функция @code{AllowFileIO()} позволяет запретить доступ к файлам на диске.
+Основная функция класса mglParse -- @code{Execute()}, выполняющая построчный разбор скрипта. Также есть вспомогательные функции для поиска и создания переменных MGL (объектов, производных от @code{mglDataA}). Эти функции полезны для отображения значений массивов во внешних объектах (например, в отдельном окне) или для предоставления доступа к внутренним массивам. Функция @code{AllowSetSize()} позволяет запретить изменение размера картинки (запрещает команду @code{setsize}). Функция @code{AllowFileIO()} позволяет запретить доступ к файлам на диске.
 
 @c Note an important feature -- if user defines function @var{func} in variable then it will be called before the destroying of this variable (@pxref{mglVar class}).
 
@@ -228,7 +228,7 @@ MathGL имеет встроенный скриптовый язык MGL для
 @deftypefnx {Метод класса @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const wchar_t *}str, @code{long} pos=@code{0})
 @deftypefnx {Функция С} @code{int} mgl_parse_line (@code{HMGL} gr, @code{HMPR} p, @code{const char *}str, @code{int} pos)
 @deftypefnx {Функция С} @code{int} mgl_parse_linew (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}str, @code{int} pos)
-Выполняет строку @var{str} с выводом графики на @var{gr}. Возвращает код ошибки: 0 -- нет ошибок, 1 -- неправильные аргументы, 2 -- неизвестная команда, 3 -- строка слишком длинная. Аргумент @var{pos} задает позицию строки в документе/файле для использования в команде @ref{for}.
+Выполняет строку @var{str} с выводом графики на @var{gr}. Возвращает код ошибки: 0 -- нет ошибок, 1 -- неправильные аргументы, 2 -- неизвестная команда, 3 -- строка слишком длинная, 4 -- нет закрывающей скобки или @samp{'}. Аргумент @var{pos} задает позицию строки в документе/файле для использования в команде @ref{for}.
 @end deftypefn
 
 @deftypefn {Метод класса @code{mglParse}} @code{mglData} Calc (@code{const char *}formula)
index 6b440b0ca55a0e45facfcb3ee359633f25253328..a71c3481effac04568aa4705858f217d44e6b812 100644 (file)
@@ -23,7 +23,11 @@ empty line style (see @ref{Line styles});
 empty color in @ref{chart}.
 
 @item !
-set to use new color from palette for each point (not for each curve, as default) in @ref{1D plotting}.
+set to use new color from palette for each point (not for each curve, as default) in @ref{1D plotting};
+
+set to disable ticks tuning in @ref{axis} and @ref{colorbar};
+
+set to draw @ref{grid} lines at subticks coordinates too.
 
 @item #
 set to use solid marks (see @ref{Line styles}) or solid @ref{error} boxes;
@@ -65,6 +69,8 @@ one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
 
 one of mask for face filling (see @ref{Color scheme});
 
+set to print @samp{+} for positive numbers in @ref{axis}, @ref{label}, @ref{table};
+
 operation in @ref{Textual formulas}.
 
 @item ,
@@ -77,6 +83,8 @@ one of mask for face filling (see @ref{Color scheme});
 
 place entries horizontally in @ref{legend};
 
+set to use usual @samp{-} for negative numbers in @ref{axis}, @ref{label}, @ref{table};
+
 operation in @ref{Textual formulas}.
 
 @item .
@@ -198,7 +206,7 @@ switch to lower index inside a string (see @ref{Font styles}).
 contain symbols excluded from color scheme parsing (see @ref{Color scheme}).
 
 @item @{@}
-contain extended color specification (see @ref{Color styles});
+contain extended specification of color (see @ref{Color styles}), dashing (see @ref{Line styles}) or mask (see @ref{Color scheme});
 
 denote special operation in @ref{MGL scripts};
 
@@ -228,12 +236,14 @@ line width (see @ref{Line styles});
 
 brightness of a color (see @ref{Color styles});
 
+precision of numbers in @ref{axis}, @ref{label}, @ref{table};
+
 kind of smoothing (for digits 1,3,5) in @ref{smooth};
 
 digits for a value.
 
 @item 4,6,8
-draw square, hex- or octo-pyramids instead of cones in @ref{cone}, @ref{cones}.
+set to draw square, hex- or octo-pyramids instead of cones in @ref{cone}, @ref{cones}.
 
 @item A,B,C,D,E,F,a,b,c,d,e,f
 can be hex-digit for color specification if placed inside @{@} (see @ref{Color styles}).
@@ -276,7 +286,9 @@ one of mask for face filling (see @ref{Color scheme}).
 @item d
 one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
 
-one of mask for face filling (see @ref{Color scheme}).
+one of mask for face filling (see @ref{Color scheme});
+
+start hex-dash description if placed inside @{@} (see @ref{Line styles}).
 
 @item E
 dark green-yellow color (see @ref{Color styles}).
@@ -284,11 +296,17 @@ dark green-yellow color (see @ref{Color styles}).
 @item e
 green-yellow color (see @ref{Color styles}).
 
+@item F
+
+set LaTeX-like format for numbers in @ref{axis}, @ref{label}, @ref{table}.
+
 @item f
 style of @ref{bars}, @ref{barh};
 
 style of @ref{vect}, @ref{vect3};
 
+set fixed format for numbers in @ref{axis}, @ref{label}, @ref{table};
+
 Fourier transform for @ref{transform}.
 
 @item G
@@ -394,6 +412,8 @@ one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
 
 one of mask for face filling (see @ref{Color scheme});
 
+start hex-mask description if placed inside @{@} (see @ref{Color scheme});
+
 sine transform for @ref{transform}.
 
 @item t
@@ -443,12 +463,15 @@ wired text if placed after @samp{:} (see @ref{Font styles});
 
 name of w-axis (one of ternary axis);
 
+@item X
+arrow style (see @ref{Line styles}).
+
 @item x
 one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
 
 name of x-axis or x-direction or 1st dimension of a data array;
 
-start hex-color described if placed inside @{@} (see @ref{Color styles});
+start hex-color description if placed inside @{@} (see @ref{Color styles});
 
 style of @ref{tape}.
 
@@ -498,6 +521,9 @@ style of @ref{tape}.
 @item @key{F6}
 @tab Change canvas size to fill whole region.
 
+@item @key{F7}
+@tab Stop drawing and script execution.
+
 @item @key{Ctrl-F5}
 @tab Run slideshow. If no parameter specified then the dialog with slideshow options will appear.
 
@@ -657,7 +683,10 @@ style of @ref{tape}.
 @tab Change canvas size to fill whole region.
 
 @item @key{F7}
-@tab Stop script execution.
+@tab Stop script execution and drawing.
+
+@item @key{F8}
+@tab Show/hide tool window with list of hidden plots.
 
 @item @key{F9}
 @tab Restore status for 'once' command and reload data.
@@ -729,4 +758,4 @@ style of @ref{tape}.
 
 @end multitable
 
-@external{}
\ No newline at end of file
+@external{}
index 6b440b0ca55a0e45facfcb3ee359633f25253328..a71c3481effac04568aa4705858f217d44e6b812 100644 (file)
@@ -23,7 +23,11 @@ empty line style (see @ref{Line styles});
 empty color in @ref{chart}.
 
 @item !
-set to use new color from palette for each point (not for each curve, as default) in @ref{1D plotting}.
+set to use new color from palette for each point (not for each curve, as default) in @ref{1D plotting};
+
+set to disable ticks tuning in @ref{axis} and @ref{colorbar};
+
+set to draw @ref{grid} lines at subticks coordinates too.
 
 @item #
 set to use solid marks (see @ref{Line styles}) or solid @ref{error} boxes;
@@ -65,6 +69,8 @@ one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
 
 one of mask for face filling (see @ref{Color scheme});
 
+set to print @samp{+} for positive numbers in @ref{axis}, @ref{label}, @ref{table};
+
 operation in @ref{Textual formulas}.
 
 @item ,
@@ -77,6 +83,8 @@ one of mask for face filling (see @ref{Color scheme});
 
 place entries horizontally in @ref{legend};
 
+set to use usual @samp{-} for negative numbers in @ref{axis}, @ref{label}, @ref{table};
+
 operation in @ref{Textual formulas}.
 
 @item .
@@ -198,7 +206,7 @@ switch to lower index inside a string (see @ref{Font styles}).
 contain symbols excluded from color scheme parsing (see @ref{Color scheme}).
 
 @item @{@}
-contain extended color specification (see @ref{Color styles});
+contain extended specification of color (see @ref{Color styles}), dashing (see @ref{Line styles}) or mask (see @ref{Color scheme});
 
 denote special operation in @ref{MGL scripts};
 
@@ -228,12 +236,14 @@ line width (see @ref{Line styles});
 
 brightness of a color (see @ref{Color styles});
 
+precision of numbers in @ref{axis}, @ref{label}, @ref{table};
+
 kind of smoothing (for digits 1,3,5) in @ref{smooth};
 
 digits for a value.
 
 @item 4,6,8
-draw square, hex- or octo-pyramids instead of cones in @ref{cone}, @ref{cones}.
+set to draw square, hex- or octo-pyramids instead of cones in @ref{cone}, @ref{cones}.
 
 @item A,B,C,D,E,F,a,b,c,d,e,f
 can be hex-digit for color specification if placed inside @{@} (see @ref{Color styles}).
@@ -276,7 +286,9 @@ one of mask for face filling (see @ref{Color scheme}).
 @item d
 one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
 
-one of mask for face filling (see @ref{Color scheme}).
+one of mask for face filling (see @ref{Color scheme});
+
+start hex-dash description if placed inside @{@} (see @ref{Line styles}).
 
 @item E
 dark green-yellow color (see @ref{Color styles}).
@@ -284,11 +296,17 @@ dark green-yellow color (see @ref{Color styles}).
 @item e
 green-yellow color (see @ref{Color styles}).
 
+@item F
+
+set LaTeX-like format for numbers in @ref{axis}, @ref{label}, @ref{table}.
+
 @item f
 style of @ref{bars}, @ref{barh};
 
 style of @ref{vect}, @ref{vect3};
 
+set fixed format for numbers in @ref{axis}, @ref{label}, @ref{table};
+
 Fourier transform for @ref{transform}.
 
 @item G
@@ -394,6 +412,8 @@ one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
 
 one of mask for face filling (see @ref{Color scheme});
 
+start hex-mask description if placed inside @{@} (see @ref{Color scheme});
+
 sine transform for @ref{transform}.
 
 @item t
@@ -443,12 +463,15 @@ wired text if placed after @samp{:} (see @ref{Font styles});
 
 name of w-axis (one of ternary axis);
 
+@item X
+arrow style (see @ref{Line styles}).
+
 @item x
 one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
 
 name of x-axis or x-direction or 1st dimension of a data array;
 
-start hex-color described if placed inside @{@} (see @ref{Color styles});
+start hex-color description if placed inside @{@} (see @ref{Color styles});
 
 style of @ref{tape}.
 
@@ -498,6 +521,9 @@ style of @ref{tape}.
 @item @key{F6}
 @tab Change canvas size to fill whole region.
 
+@item @key{F7}
+@tab Stop drawing and script execution.
+
 @item @key{Ctrl-F5}
 @tab Run slideshow. If no parameter specified then the dialog with slideshow options will appear.
 
@@ -657,7 +683,10 @@ style of @ref{tape}.
 @tab Change canvas size to fill whole region.
 
 @item @key{F7}
-@tab Stop script execution.
+@tab Stop script execution and drawing.
+
+@item @key{F8}
+@tab Show/hide tool window with list of hidden plots.
 
 @item @key{F9}
 @tab Restore status for 'once' command and reload data.
@@ -729,4 +758,4 @@ style of @ref{tape}.
 
 @end multitable
 
-@external{}
\ No newline at end of file
+@external{}
index a6e03831d3cf8509c0d9529be69aa955196190c9..648031cfe617083eeeaa464f94743f54e50aa880 100644 (file)
 @multitable @columnfractions .16 .12 .12 .12 .12 .12 .12 .12
 @headitem Name @tab q=0 @tab q=1 @tab q=2 @tab q=4 @tab q=5 @tab q=6 @tab q=8
-@item alpha @tab 0.09 @tab 0.1 @tab 0.12 @tab 0.03 @tab 0.08 @tab 0.11 @tab 0.02
-@item area @tab 0.04 @tab 0.07 @tab 0.1 @tab 0.05 @tab 0.07 @tab 0.11 @tab 0.02
-@item aspect @tab 0.05 @tab 0.04 @tab 0.07 @tab 0.03 @tab 0.02 @tab 0.08 @tab 0.02
-@item axial @tab 0.7 @tab 0.76 @tab 1.05 @tab 0.3 @tab 0.43 @tab 0.64 @tab 0.1
-@item axis @tab 0.09 @tab 0.1 @tab 0.14 @tab 0.06 @tab 0.05 @tab 0.15 @tab 0.02
-@item barh @tab 0.04 @tab 0.04 @tab 0.07 @tab 0.03 @tab 0.04 @tab 0.09 @tab 0.02
-@item bars @tab 0.05 @tab 0.06 @tab 0.09 @tab 0.04 @tab 0.06 @tab 0.12 @tab 0.02
-@item belt @tab 0.03 @tab 0.05 @tab 0.07 @tab 0.02 @tab 0.04 @tab 0.08 @tab 0.01
-@item box @tab 0.03 @tab 0.05 @tab 0.08 @tab 0.03 @tab 0.08 @tab 0.12 @tab 0.01
-@item boxplot @tab 0.02 @tab 0.02 @tab 0.04 @tab 0.02 @tab 0.02 @tab 0.04 @tab 0.01
-@item boxs @tab 0.25 @tab 0.28 @tab 0.41 @tab 0.08 @tab 0.13 @tab 0.22 @tab 0.06
-@item candle @tab 0.02 @tab 0.03 @tab 0.05 @tab 0.02 @tab 0.03 @tab 0.05 @tab 0.01
-@item chart @tab 0.62 @tab 0.82 @tab 0.93 @tab 0.29 @tab 0.69 @tab 0.97 @tab 0.26
-@item cloud @tab 0.04 @tab 6.14 @tab 6.24 @tab 0.03 @tab 3.1 @tab 3.37 @tab 0.03
-@item colorbar @tab 0.17 @tab 0.2 @tab 0.25 @tab 0.1 @tab 0.17 @tab 0.3 @tab 0.05
-@item combined @tab 0.47 @tab 0.36 @tab 0.42 @tab 0.23 @tab 0.28 @tab 0.37 @tab 0.2
-@item cones @tab 0.21 @tab 0.16 @tab 0.21 @tab 0.07 @tab 0.11 @tab 0.23 @tab 0.05
-@item cont @tab 0.1 @tab 0.11 @tab 0.16 @tab 0.08 @tab 0.07 @tab 0.16 @tab 0.06
-@item cont_xyz @tab 0.06 @tab 0.05 @tab 0.08 @tab 0.05 @tab 0.05 @tab 0.08 @tab 0.05
-@item conta @tab 0.05 @tab 0.05 @tab 0.07 @tab 0.04 @tab 0.05 @tab 0.08 @tab 0.03
-@item contd @tab 0.23 @tab 0.24 @tab 0.27 @tab 0.14 @tab 0.17 @tab 0.23 @tab 0.12
-@item contf @tab 0.18 @tab 0.2 @tab 0.24 @tab 0.1 @tab 0.14 @tab 0.21 @tab 0.09
-@item contf_xyz @tab 0.09 @tab 0.11 @tab 0.15 @tab 0.08 @tab 0.1 @tab 0.11 @tab 0.05
-@item contfa @tab 0.17 @tab 0.16 @tab 0.18 @tab 0.08 @tab 0.14 @tab 0.18 @tab 0.07
-@item contv @tab 0.14 @tab 0.16 @tab 0.18 @tab 0.1 @tab 0.12 @tab 0.19 @tab 0.08
-@item correl @tab 0.04 @tab 0.05 @tab 0.07 @tab 0.03 @tab 0.03 @tab 0.09 @tab 0.02
-@item curvcoor @tab 0.15 @tab 0.15 @tab 0.2 @tab 0.1 @tab 0.11 @tab 0.18 @tab 0.09
-@item cut @tab 1.01 @tab 0.61 @tab 0.65 @tab 0.49 @tab 0.54 @tab 0.61 @tab 0.42
-@item dat_diff @tab 0.06 @tab 0.08 @tab 0.12 @tab 0.03 @tab 0.06 @tab 0.12 @tab 0.03
-@item dat_extra @tab 0.28 @tab 0.19 @tab 0.24 @tab 0.1 @tab 0.11 @tab 0.2 @tab 0.06
-@item data1 @tab 3.66 @tab 2.43 @tab 2.49 @tab 2.22 @tab 2.15 @tab 2.23 @tab 2.07
-@item data2 @tab 2.47 @tab 2.13 @tab 2.14 @tab 2.1 @tab 2.05 @tab 2.12 @tab 2
-@item dens @tab 0.11 @tab 0.17 @tab 0.2 @tab 0.07 @tab 0.11 @tab 0.19 @tab 0.05
-@item dens_xyz @tab 0.07 @tab 0.1 @tab 0.13 @tab 0.05 @tab 0.09 @tab 0.12 @tab 0.03
-@item densa @tab 0.07 @tab 0.09 @tab 0.12 @tab 0.03 @tab 0.07 @tab 0.12 @tab 0.03
-@item dew @tab 1.67 @tab 0.74 @tab 0.73 @tab 0.14 @tab 0.14 @tab 0.15 @tab 0.07
-@item dots @tab 0.04 @tab 0.04 @tab 0.05 @tab 0.03 @tab 0.04 @tab 0.05 @tab 0.01
-@item error @tab 0.05 @tab 0.05 @tab 0.08 @tab 0.04 @tab 0.04 @tab 0.1 @tab 0.02
-@item error2 @tab 0.05 @tab 0.06 @tab 0.1 @tab 0.04 @tab 0.05 @tab 0.1 @tab 0.04
-@item export @tab 0.17 @tab 0.25 @tab 0.27 @tab 0.13 @tab 0.18 @tab 0.21 @tab 0.12
-@item fall @tab 0.03 @tab 0.02 @tab 0.05 @tab 0.02 @tab 0.01 @tab 0.05 @tab 0.01
-@item fexport @tab 2.34 @tab 2.31 @tab 2.72 @tab 0.5 @tab 0.5 @tab 0.85 @tab 1.59
-@item fit @tab 0.05 @tab 0.05 @tab 0.08 @tab 0.04 @tab 0.04 @tab 0.07 @tab 0.02
-@item flow @tab 0.3 @tab 0.32 @tab 0.42 @tab 0.23 @tab 0.24 @tab 0.36 @tab 0.23
-@item fog @tab 0.04 @tab 0.07 @tab 0.09 @tab 0.02 @tab 0.07 @tab 0.11 @tab 0.01
-@item fonts @tab 2.44 @tab 2.75 @tab 2.19 @tab 2.16 @tab 2.2 @tab 2.23 @tab 2.35
-@item grad @tab 0.06 @tab 0.11 @tab 0.16 @tab 0.05 @tab 0.1 @tab 0.15 @tab 0.05
-@item hist @tab 0.18 @tab 0.19 @tab 0.22 @tab 0.19 @tab 0.2 @tab 0.25 @tab 0.05
-@item inplot @tab 0.06 @tab 0.06 @tab 0.1 @tab 0.04 @tab 0.04 @tab 0.11 @tab 0.04
-@item label @tab 0.04 @tab 0.04 @tab 0.06 @tab 0.03 @tab 0.03 @tab 0.08 @tab 0.01
-@item legend @tab 0.17 @tab 0.18 @tab 0.26 @tab 0.1 @tab 0.12 @tab 0.26 @tab 0.03
-@item light @tab 0.15 @tab 0.15 @tab 0.16 @tab 0.15 @tab 0.15 @tab 0.16 @tab 0.15
-@item loglog @tab 0.13 @tab 0.13 @tab 0.18 @tab 0.1 @tab 0.09 @tab 0.15 @tab 0.08
-@item map @tab 0.04 @tab 0.08 @tab 0.1 @tab 0.03 @tab 0.06 @tab 0.1 @tab 0.02
-@item mark @tab 0.03 @tab 0.03 @tab 0.04 @tab 0.03 @tab 0.04 @tab 0.05 @tab 0.01
-@item mask @tab 0.07 @tab 0.12 @tab 0.14 @tab 0.05 @tab 0.08 @tab 0.15 @tab 0.02
-@item mesh @tab 0.03 @tab 0.03 @tab 0.08 @tab 0.02 @tab 0.02 @tab 0.07 @tab 0.01
-@item mirror @tab 0.12 @tab 0.13 @tab 0.17 @tab 0.06 @tab 0.08 @tab 0.16 @tab 0.04
-@item molecule @tab 0.1 @tab 0.11 @tab 0.13 @tab 0.03 @tab 0.06 @tab 0.06 @tab 0.02
-@item param1 @tab 0.27 @tab 0.28 @tab 0.37 @tab 0.11 @tab 0.15 @tab 0.37 @tab 0.07
-@item param2 @tab 0.64 @tab 0.61 @tab 0.62 @tab 0.24 @tab 0.35 @tab 0.42 @tab 0.22
-@item param3 @tab 3.05 @tab 3.34 @tab 3.41 @tab 1.63 @tab 2.05 @tab 2.08 @tab 1.51
-@item paramv @tab 4.94 @tab 4.78 @tab 4.92 @tab 1.26 @tab 1.49 @tab 1.45 @tab 1.25
-@item parser @tab 0.04 @tab 0.05 @tab 0.06 @tab 0.05 @tab 0.04 @tab 0.09 @tab 0.03
-@item pde @tab 2.12 @tab 2.18 @tab 2.22 @tab 2.05 @tab 2.12 @tab 2.13 @tab 2.02
-@item pipe @tab 4.73 @tab 3.13 @tab 2.99 @tab 0.81 @tab 1.05 @tab 0.99 @tab 0.64
-@item plot @tab 0.06 @tab 0.06 @tab 0.1 @tab 0.06 @tab 0.05 @tab 0.1 @tab 0.02
-@item primitives @tab 0.11 @tab 0.15 @tab 0.2 @tab 0.07 @tab 0.16 @tab 0.22 @tab 0.02
-@item projection @tab 0.16 @tab 0.2 @tab 0.28 @tab 0.08 @tab 0.1 @tab 0.26 @tab 0.05
-@item projection5 @tab 0.14 @tab 0.18 @tab 0.25 @tab 0.08 @tab 0.1 @tab 0.24 @tab 0.04
-@item qo2d @tab 0.61 @tab 0.66 @tab 0.7 @tab 0.58 @tab 0.62 @tab 0.67 @tab 0.54
-@item radar @tab 0.03 @tab 0.03 @tab 0.04 @tab 0.03 @tab 0.02 @tab 0.04 @tab 0.01
-@item refill @tab 0.02 @tab 0.02 @tab 0.03 @tab 0.02 @tab 0.02 @tab 0.05 @tab 0.01
-@item region @tab 0.05 @tab 0.06 @tab 0.11 @tab 0.04 @tab 0.08 @tab 0.15 @tab 0.02
-@item schemes @tab 0.1 @tab 0.15 @tab 0.19 @tab 0.07 @tab 0.11 @tab 0.2 @tab 0.02
-@item several_light @tab 0.07 @tab 0.1 @tab 0.13 @tab 0.02 @tab 0.11 @tab 0.15 @tab 0.02
-@item solve @tab 0.07 @tab 0.07 @tab 0.13 @tab 0.06 @tab 0.06 @tab 0.15 @tab 0.02
-@item stem @tab 0.04 @tab 0.04 @tab 0.08 @tab 0.04 @tab 0.03 @tab 0.08 @tab 0.02
-@item step @tab 0.04 @tab 0.05 @tab 0.07 @tab 0.04 @tab 0.04 @tab 0.08 @tab 0.02
-@item stereo @tab 0.06 @tab 0.08 @tab 0.09 @tab 0.03 @tab 0.08 @tab 0.11 @tab 0.02
-@item stfa @tab 0.06 @tab 0.1 @tab 0.17 @tab 0.04 @tab 0.07 @tab 0.14 @tab 0.03
-@item style @tab 0.18 @tab 0.2 @tab 0.28 @tab 0.1 @tab 0.12 @tab 0.36 @tab 0.03
-@item surf @tab 0.17 @tab 0.18 @tab 0.21 @tab 0.08 @tab 0.12 @tab 0.18 @tab 0.04
-@item surf3 @tab 2.5 @tab 2.18 @tab 2.56 @tab 1.91 @tab 1.92 @tab 2.52 @tab 0.58
-@item surf3a @tab 0.62 @tab 0.37 @tab 0.38 @tab 0.26 @tab 0.4 @tab 0.44 @tab 0.2
-@item surf3c @tab 0.61 @tab 0.36 @tab 0.39 @tab 0.24 @tab 0.4 @tab 0.43 @tab 0.19
-@item surfa @tab 0.04 @tab 0.07 @tab 0.09 @tab 0.02 @tab 0.07 @tab 0.11 @tab 0.02
-@item surfc @tab 0.04 @tab 0.07 @tab 0.09 @tab 0.02 @tab 0.07 @tab 0.1 @tab 0.01
-@item table @tab 0.24 @tab 0.22 @tab 0.31 @tab 0.07 @tab 0.07 @tab 0.13 @tab 0.04
-@item tape @tab 0.05 @tab 0.06 @tab 0.1 @tab 0.04 @tab 0.06 @tab 0.12 @tab 0.03
-@item tens @tab 0.04 @tab 0.03 @tab 0.06 @tab 0.04 @tab 0.03 @tab 0.07 @tab 0.02
-@item ternary @tab 0.15 @tab 0.18 @tab 0.25 @tab 0.09 @tab 0.11 @tab 0.3 @tab 0.04
-@item text @tab 0.15 @tab 0.15 @tab 0.21 @tab 0.05 @tab 0.04 @tab 0.1 @tab 0.02
-@item text2 @tab 0.1 @tab 0.1 @tab 0.17 @tab 0.06 @tab 0.06 @tab 0.12 @tab 0.02
-@item textmark @tab 0.07 @tab 0.07 @tab 0.12 @tab 0.04 @tab 0.04 @tab 0.12 @tab 0.01
-@item ticks @tab 0.11 @tab 0.11 @tab 0.17 @tab 0.06 @tab 0.06 @tab 0.16 @tab 0.02
-@item tile @tab 0.03 @tab 0.05 @tab 0.07 @tab 0.02 @tab 0.03 @tab 0.06 @tab 0.02
-@item tiles @tab 0.03 @tab 0.05 @tab 0.07 @tab 0.03 @tab 0.05 @tab 0.08 @tab 0.02
-@item torus @tab 0.13 @tab 0.17 @tab 0.24 @tab 0.07 @tab 0.11 @tab 0.17 @tab 0.05
-@item traj @tab 0.02 @tab 0.02 @tab 0.04 @tab 0.02 @tab 0.02 @tab 0.05 @tab 0.01
-@item triangulation @tab 0.04 @tab 0.07 @tab 0.09 @tab 0.02 @tab 0.06 @tab 0.12 @tab 0.02
-@item triplot @tab 0.03 @tab 0.13 @tab 0.18 @tab 0.03 @tab 0.12 @tab 0.19 @tab 0.01
-@item tube @tab 0.1 @tab 0.17 @tab 0.22 @tab 0.07 @tab 0.11 @tab 0.17 @tab 0.03
-@item type0 @tab 0.22 @tab 0.24 @tab 0.28 @tab 0.07 @tab 0.17 @tab 0.21 @tab 0.06
-@item type1 @tab 0.24 @tab 0.24 @tab 0.28 @tab 0.07 @tab 0.17 @tab 0.21 @tab 0.05
-@item type2 @tab 0.24 @tab 0.24 @tab 0.28 @tab 0.07 @tab 0.17 @tab 0.21 @tab 0.06
-@item vect @tab 0.1 @tab 0.1 @tab 0.18 @tab 0.06 @tab 0.06 @tab 0.16 @tab 0.04
-@item vecta @tab 0.03 @tab 0.04 @tab 0.07 @tab 0.03 @tab 0.03 @tab 0.08 @tab 0.02
-@item venn @tab 0.02 @tab 0.08 @tab 0.12 @tab 0.02 @tab 0.1 @tab 0.14 @tab 0.01
+@item alpha @tab 0.0994 @tab 0.106 @tab 0.137 @tab 0.034 @tab 0.0565 @tab 0.068 @tab 0.0332
+@item area @tab 0.0813 @tab 0.0666 @tab 0.11 @tab 0.0342 @tab 0.0426 @tab 0.0794 @tab 0.0435
+@item aspect @tab 0.0924 @tab 0.142 @tab 0.118 @tab 0.0281 @tab 0.0376 @tab 0.0693 @tab 0.0246
+@item axial @tab 0.706 @tab 0.606 @tab 0.911 @tab 0.243 @tab 0.264 @tab 0.475 @tab 0.0657
+@item axis @tab 0.136 @tab 0.163 @tab 0.155 @tab 0.0299 @tab 0.0293 @tab 0.0494 @tab 0.0506
+@item barh @tab 0.0811 @tab 0.105 @tab 0.121 @tab 0.0299 @tab 0.0326 @tab 0.0454 @tab 0.0273
+@item bars @tab 0.739 @tab 0.134 @tab 0.134 @tab 0.0477 @tab 0.0832 @tab 0.0662 @tab 0.0641
+@item belt @tab 0.0576 @tab 0.0984 @tab 0.0916 @tab 0.0429 @tab 0.0307 @tab 0.0465 @tab 0.0252
+@item box @tab 0.0938 @tab 0.105 @tab 0.127 @tab 0.0312 @tab 0.0352 @tab 0.0549 @tab 0.0501
+@item boxplot @tab 0.0469 @tab 0.127 @tab 0.0534 @tab 0.0587 @tab 0.0252 @tab 0.035 @tab 0.0152
+@item boxs @tab 0.242 @tab 0.223 @tab 0.331 @tab 0.0567 @tab 0.0683 @tab 0.189 @tab 0.095
+@item candle @tab 0.0842 @tab 0.132 @tab 0.0634 @tab 0.0541 @tab 0.0509 @tab 0.0532 @tab 0.016
+@item chart @tab 0.506 @tab 0.427 @tab 0.715 @tab 0.182 @tab 0.199 @tab 0.477 @tab 0.154
+@item cloud @tab 0.0927 @tab 4.72 @tab 5.16 @tab 0.0308 @tab 1.2 @tab 1.64 @tab 0.0265
+@item colorbar @tab 0.266 @tab 0.273 @tab 0.246 @tab 0.174 @tab 0.182 @tab 0.253 @tab 0.267
+@item combined @tab 0.603 @tab 0.401 @tab 0.458 @tab 0.306 @tab 0.276 @tab 0.362 @tab 0.256
+@item cones @tab 0.308 @tab 0.189 @tab 0.241 @tab 0.144 @tab 0.132 @tab 0.172 @tab 0.109
+@item cont @tab 0.079 @tab 0.0795 @tab 0.124 @tab 0.0374 @tab 0.0374 @tab 0.0606 @tab 0.0326
+@item cont_xyz @tab 0.14 @tab 0.106 @tab 0.249 @tab 0.33 @tab 0.159 @tab 0.115 @tab 0.152
+@item conta @tab 0.135 @tab 0.106 @tab 0.132 @tab 0.0822 @tab 0.101 @tab 0.0894 @tab 0.083
+@item contd @tab 0.209 @tab 0.181 @tab 0.2 @tab 0.0722 @tab 0.075 @tab 0.109 @tab 0.0666
+@item contf @tab 0.156 @tab 0.157 @tab 0.177 @tab 0.0645 @tab 0.0658 @tab 0.0881 @tab 0.0584
+@item contf_xyz @tab 0.214 @tab 0.211 @tab 0.175 @tab 0.0934 @tab 0.111 @tab 0.104 @tab 0.0851
+@item contfa @tab 0.293 @tab 0.224 @tab 0.259 @tab 0.142 @tab 0.165 @tab 0.176 @tab 0.14
+@item contv @tab 0.113 @tab 0.105 @tab 0.135 @tab 0.051 @tab 0.0482 @tab 0.071 @tab 0.0386
+@item correl @tab 0.0597 @tab 0.0798 @tab 0.0772 @tab 0.0617 @tab 0.0697 @tab 0.0569 @tab 0.0284
+@item curvcoor @tab 0.0906 @tab 0.0892 @tab 0.134 @tab 0.0434 @tab 0.0432 @tab 0.0688 @tab 0.0403
+@item cut @tab 1.21 @tab 0.776 @tab 0.795 @tab 0.843 @tab 0.632 @tab 0.683 @tab 0.62
+@item dat_diff @tab 0.144 @tab 0.104 @tab 0.13 @tab 0.105 @tab 0.0779 @tab 0.0954 @tab 0.0927
+@item dat_extra @tab 0.442 @tab 0.279 @tab 0.304 @tab 0.122 @tab 0.213 @tab 0.257 @tab 0.0869
+@item data1 @tab 5.13 @tab 4.08 @tab 3.72 @tab 3.74 @tab 3.45 @tab 3.95 @tab 3.35
+@item data2 @tab 3.31 @tab 2.72 @tab 2.81 @tab 3 @tab 2.98 @tab 2.82 @tab 2.61
+@item dens @tab 0.105 @tab 0.118 @tab 0.168 @tab 0.0456 @tab 0.0547 @tab 0.085 @tab 0.0426
+@item dens_xyz @tab 0.158 @tab 0.16 @tab 0.23 @tab 0.0827 @tab 0.168 @tab 0.106 @tab 0.148
+@item densa @tab 0.127 @tab 0.138 @tab 0.159 @tab 0.0915 @tab 0.0981 @tab 0.11 @tab 0.0805
+@item dew @tab 1.7 @tab 0.831 @tab 0.765 @tab 0.204 @tab 0.172 @tab 0.182 @tab 0.0895
+@item dots @tab 0.148 @tab 0.119 @tab 0.13 @tab 0.0535 @tab 0.0535 @tab 0.0674 @tab 0.0636
+@item error @tab 0.104 @tab 0.0724 @tab 0.0861 @tab 0.0999 @tab 0.121 @tab 0.111 @tab 0.0285
+@item error2 @tab 0.0625 @tab 0.0672 @tab 0.0873 @tab 0.0463 @tab 0.0359 @tab 0.0558 @tab 0.0365
+@item export @tab 0.177 @tab 0.221 @tab 0.249 @tab 0.112 @tab 0.124 @tab 0.154 @tab 0.17
+@item fall @tab 0.135 @tab 0.0346 @tab 0.0641 @tab 0.0363 @tab 0.0485 @tab 0.0797 @tab 0.084
+@item fit @tab 3.11 @tab 0.169 @tab 0.13 @tab 0.0734 @tab 0.0727 @tab 2.99 @tab 0.123
+@item flow @tab 0.513 @tab 0.386 @tab 0.497 @tab 0.272 @tab 0.423 @tab 0.377 @tab 0.262
+@item fog @tab 0.1 @tab 0.113 @tab 0.117 @tab 0.0297 @tab 0.039 @tab 0.0712 @tab 0.0616
+@item fonts @tab 2.67 @tab 2.63 @tab 3.03 @tab 2.74 @tab 2.67 @tab 2.88 @tab 2.94
+@item grad @tab 0.124 @tab 0.119 @tab 0.192 @tab 0.127 @tab 0.0672 @tab 0.109 @tab 0.0476
+@item hist @tab 0.216 @tab 0.202 @tab 0.226 @tab 0.131 @tab 0.149 @tab 0.142 @tab 0.0786
+@item indirect @tab 0.0602 @tab 0.0582 @tab 0.0586 @tab 0.0844 @tab 0.0792 @tab 0.152 @tab 0.0262
+@item inplot @tab 0.148 @tab 0.139 @tab 0.0964 @tab 0.0399 @tab 0.0624 @tab 0.0449 @tab 0.0495
+@item label @tab 0.146 @tab 0.0577 @tab 0.169 @tab 0.0578 @tab 0.0959 @tab 0.079 @tab 0.0289
+@item legend @tab 0.168 @tab 0.227 @tab 0.23 @tab 0.0345 @tab 0.0364 @tab 0.073 @tab 0.0382
+@item light @tab 0.107 @tab 0.0814 @tab 0.0821 @tab 0.0804 @tab 0.073 @tab 0.0774 @tab 0.073
+@item loglog @tab 0.0776 @tab 0.0741 @tab 0.113 @tab 0.0451 @tab 0.0375 @tab 0.0559 @tab 0.0335
+@item map @tab 0.178 @tab 0.119 @tab 0.188 @tab 0.0767 @tab 0.0887 @tab 0.111 @tab 0.0304
+@item mark @tab 0.0785 @tab 0.141 @tab 0.0551 @tab 0.028 @tab 0.0311 @tab 0.0365 @tab 0.016
+@item mask @tab 0.0854 @tab 0.131 @tab 0.115 @tab 0.0296 @tab 0.0412 @tab 0.0547 @tab 0.0213
+@item mesh @tab 0.11 @tab 0.112 @tab 0.0894 @tab 0.0368 @tab 0.0518 @tab 0.0508 @tab 0.0724
+@item mirror @tab 0.197 @tab 0.104 @tab 0.146 @tab 0.0363 @tab 0.0433 @tab 0.0695 @tab 0.0384
+@item molecule @tab 0.153 @tab 0.107 @tab 0.199 @tab 0.0653 @tab 0.0657 @tab 0.086 @tab 0.037
+@item ode @tab 1.49 @tab 0.618 @tab 0.718 @tab 0.62 @tab 0.595 @tab 0.72 @tab 0.556
+@item ohlc @tab 0.0347 @tab 0.0487 @tab 0.0551 @tab 0.0406 @tab 0.0281 @tab 0.0389 @tab 0.0167
+@item param1 @tab 0.316 @tab 0.247 @tab 0.321 @tab 0.119 @tab 0.155 @tab 0.158 @tab 0.0958
+@item param2 @tab 0.505 @tab 0.428 @tab 0.496 @tab 0.152 @tab 0.138 @tab 0.187 @tab 0.104
+@item param3 @tab 3.33 @tab 3.59 @tab 3.37 @tab 1.82 @tab 1.89 @tab 1.94 @tab 1.65
+@item paramv @tab 4.31 @tab 4.7 @tab 4.25 @tab 1.21 @tab 1.13 @tab 1.23 @tab 1.07
+@item parser @tab 0.074 @tab 0.102 @tab 0.128 @tab 0.0973 @tab 0.154 @tab 0.104 @tab 0.145
+@item pde @tab 0.943 @tab 0.934 @tab 0.987 @tab 1.01 @tab 0.816 @tab 0.79 @tab 0.809
+@item pipe @tab 4.13 @tab 2.98 @tab 2.46 @tab 0.597 @tab 0.848 @tab 0.815 @tab 0.588
+@item plot @tab 0.0702 @tab 0.0848 @tab 0.112 @tab 0.0409 @tab 0.0409 @tab 0.0568 @tab 0.029
+@item primitives @tab 0.0998 @tab 0.0958 @tab 0.175 @tab 0.0313 @tab 0.0363 @tab 0.0815 @tab 0.0265
+@item projection @tab 0.138 @tab 0.14 @tab 0.222 @tab 0.0463 @tab 0.046 @tab 0.157 @tab 0.104
+@item projection5 @tab 0.124 @tab 0.132 @tab 0.197 @tab 0.0414 @tab 0.0423 @tab 0.1 @tab 0.0353
+@item qo2d @tab 0.375 @tab 0.331 @tab 0.364 @tab 0.244 @tab 0.279 @tab 0.287 @tab 0.244
+@item radar @tab 0.0348 @tab 0.0503 @tab 0.0598 @tab 0.0582 @tab 0.0297 @tab 0.083 @tab 0.0147
+@item refill @tab 0.391 @tab 0.28 @tab 0.233 @tab 0.161 @tab 0.133 @tab 0.155 @tab 0.0867
+@item region @tab 0.0748 @tab 0.0719 @tab 0.117 @tab 0.0291 @tab 0.0319 @tab 0.0566 @tab 0.0256
+@item schemes @tab 0.123 @tab 0.102 @tab 0.184 @tab 0.0371 @tab 0.0392 @tab 0.0717 @tab 0.0469
+@item several_light @tab 0.0862 @tab 0.102 @tab 0.128 @tab 0.0284 @tab 0.0327 @tab 0.0912 @tab 0.0246
+@item solve @tab 0.126 @tab 0.0944 @tab 0.148 @tab 0.06 @tab 0.078 @tab 0.0841 @tab 0.0579
+@item stem @tab 0.061 @tab 0.0558 @tab 0.124 @tab 0.0312 @tab 0.0315 @tab 0.0479 @tab 0.0265
+@item step @tab 0.132 @tab 0.0962 @tab 0.0708 @tab 0.0321 @tab 0.0322 @tab 0.191 @tab 0.0398
+@item stereo @tab 0.0706 @tab 0.0877 @tab 0.137 @tab 0.0304 @tab 0.0334 @tab 0.0672 @tab 0.0394
+@item stfa @tab 0.177 @tab 0.0918 @tab 0.146 @tab 0.0518 @tab 0.0657 @tab 0.0935 @tab 0.059
+@item style @tab 0.176 @tab 0.166 @tab 0.226 @tab 0.0408 @tab 0.0426 @tab 0.082 @tab 0.0252
+@item surf @tab 0.191 @tab 0.191 @tab 0.233 @tab 0.0669 @tab 0.0704 @tab 0.105 @tab 0.118
+@item surf3 @tab 3.1 @tab 2.9 @tab 2.88 @tab 2.89 @tab 2.78 @tab 3.57 @tab 1.16
+@item surf3a @tab 0.754 @tab 0.471 @tab 0.526 @tab 0.399 @tab 0.394 @tab 0.511 @tab 0.349
+@item surf3c @tab 0.736 @tab 0.448 @tab 0.502 @tab 0.383 @tab 0.387 @tab 0.494 @tab 0.333
+@item surfa @tab 0.0647 @tab 0.112 @tab 0.0916 @tab 0.0298 @tab 0.0311 @tab 0.0626 @tab 0.025
+@item surfc @tab 0.0588 @tab 0.103 @tab 0.139 @tab 0.0313 @tab 0.0311 @tab 0.0602 @tab 0.0248
+@item table @tab 0.194 @tab 0.226 @tab 0.279 @tab 0.0358 @tab 0.0361 @tab 0.0809 @tab 0.0438
+@item tape @tab 0.1 @tab 0.108 @tab 0.125 @tab 0.0302 @tab 0.0326 @tab 0.0526 @tab 0.0405
+@item tens @tab 0.0959 @tab 0.109 @tab 0.0642 @tab 0.0727 @tab 0.0965 @tab 0.074 @tab 0.0254
+@item ternary @tab 0.142 @tab 0.137 @tab 0.205 @tab 0.041 @tab 0.0418 @tab 0.0942 @tab 0.0355
+@item text @tab 0.123 @tab 0.124 @tab 0.166 @tab 0.045 @tab 0.0567 @tab 0.0758 @tab 0.025
+@item text2 @tab 0.132 @tab 0.132 @tab 0.167 @tab 0.0721 @tab 0.0872 @tab 0.095 @tab 0.0467
+@item textmark @tab 0.224 @tab 0.0722 @tab 0.0939 @tab 0.126 @tab 0.0474 @tab 0.0575 @tab 0.0242
+@item ticks @tab 0.186 @tab 0.145 @tab 0.207 @tab 0.0341 @tab 0.042 @tab 0.0689 @tab 0.0609
+@item tile @tab 0.0861 @tab 0.0811 @tab 0.11 @tab 0.0277 @tab 0.0299 @tab 0.0451 @tab 0.0618
+@item tiles @tab 0.0558 @tab 0.0581 @tab 0.0772 @tab 0.0272 @tab 0.0303 @tab 0.0454 @tab 0.0583
+@item torus @tab 0.121 @tab 0.116 @tab 0.193 @tab 0.038 @tab 0.0448 @tab 0.104 @tab 0.0314
+@item traj @tab 0.0354 @tab 0.0395 @tab 0.0789 @tab 0.0467 @tab 0.0253 @tab 0.0364 @tab 0.0173
+@item triangulation @tab 0.0603 @tab 0.214 @tab 0.139 @tab 0.0455 @tab 0.0734 @tab 0.0845 @tab 0.0265
+@item triplot @tab 0.0692 @tab 0.0519 @tab 0.131 @tab 0.0497 @tab 0.0325 @tab 0.0943 @tab 0.0124
+@item tube @tab 0.151 @tab 0.135 @tab 0.294 @tab 0.0491 @tab 0.0601 @tab 0.108 @tab 0.0609
+@item type0 @tab 0.251 @tab 0.187 @tab 0.248 @tab 0.113 @tab 0.0785 @tab 0.157 @tab 0.0567
+@item type1 @tab 0.249 @tab 0.179 @tab 0.274 @tab 0.0796 @tab 0.0786 @tab 0.145 @tab 0.0564
+@item type2 @tab 0.246 @tab 0.212 @tab 0.25 @tab 0.0868 @tab 0.104 @tab 0.151 @tab 0.0625
+@item vect @tab 0.166 @tab 0.155 @tab 0.255 @tab 0.13 @tab 0.132 @tab 0.181 @tab 0.174
+@item vecta @tab 0.121 @tab 0.0841 @tab 0.108 @tab 0.0755 @tab 0.0672 @tab 0.155 @tab 0.0686
+@item venn @tab 0.0182 @tab 0.0527 @tab 0.0913 @tab 0.0368 @tab 0.0385 @tab 0.0706 @tab 0.013
 @end multitable
index 0a8d1791d18361aa0d1f974a95f581d6ae28d7c4..5a2b9f8cef0ed73168ce43f51404b3342c1091cb 100644 (file)
 @multitable @columnfractions .16 .12 .12 .12 .12 .12 .12 .12
 @headitem Name @tab q=0 @tab q=1 @tab q=2 @tab q=4 @tab q=5 @tab q=6 @tab q=8
-@item alpha @tab 0.13 @tab 0.32 @tab 0.41 @tab 0.08 @tab 0.32 @tab 0.46 @tab 0.06
-@item area @tab 0.09 @tab 0.26 @tab 0.38 @tab 0.1 @tab 0.2 @tab 0.34 @tab 0.05
-@item aspect @tab 0.09 @tab 0.08 @tab 0.15 @tab 0.08 @tab 0.08 @tab 0.18 @tab 0.05
-@item axial @tab 0.9 @tab 1.77 @tab 2.43 @tab 0.44 @tab 1.11 @tab 1.64 @tab 0.15
-@item axis @tab 0.14 @tab 0.13 @tab 0.22 @tab 0.12 @tab 0.11 @tab 0.29 @tab 0.06
-@item barh @tab 0.08 @tab 0.13 @tab 0.21 @tab 0.08 @tab 0.17 @tab 0.32 @tab 0.06
-@item bars @tab 0.09 @tab 0.13 @tab 0.22 @tab 0.09 @tab 0.18 @tab 0.36 @tab 0.06
-@item belt @tab 0.07 @tab 0.16 @tab 0.22 @tab 0.07 @tab 0.25 @tab 0.36 @tab 0.05
-@item box @tab 0.07 @tab 0.15 @tab 0.25 @tab 0.08 @tab 0.18 @tab 0.3 @tab 0.06
-@item boxplot @tab 0.06 @tab 0.05 @tab 0.11 @tab 0.06 @tab 0.06 @tab 0.14 @tab 0.05
-@item boxs @tab 0.31 @tab 0.63 @tab 1.03 @tab 0.13 @tab 0.45 @tab 0.72 @tab 0.11
-@item candle @tab 0.06 @tab 0.07 @tab 0.15 @tab 0.06 @tab 0.07 @tab 0.17 @tab 0.05
-@item chart @tab 0.71 @tab 2.39 @tab 2.9 @tab 0.4 @tab 2.65 @tab 3.62 @tab 0.33
-@item cloud @tab 0.08 @tab 10.6 @tab 12.1 @tab 0.08 @tab 8.62 @tab 11.2 @tab 0.07
-@item colorbar @tab 0.24 @tab 0.32 @tab 0.45 @tab 0.22 @tab 0.38 @tab 0.56 @tab 0.09
-@item combined @tab 0.53 @tab 0.62 @tab 0.82 @tab 0.32 @tab 0.59 @tab 0.85 @tab 0.24
-@item cones @tab 0.26 @tab 0.37 @tab 0.53 @tab 0.14 @tab 0.38 @tab 0.74 @tab 0.09
-@item cont @tab 0.16 @tab 0.15 @tab 0.26 @tab 0.12 @tab 0.12 @tab 0.3 @tab 0.08
-@item cont_xyz @tab 0.1 @tab 0.1 @tab 0.18 @tab 0.1 @tab 0.09 @tab 0.19 @tab 0.08
-@item conta @tab 0.09 @tab 0.09 @tab 0.16 @tab 0.08 @tab 0.09 @tab 0.2 @tab 0.07
-@item contd @tab 0.28 @tab 0.39 @tab 0.5 @tab 0.19 @tab 0.34 @tab 0.49 @tab 0.15
-@item contf @tab 0.24 @tab 0.35 @tab 0.46 @tab 0.18 @tab 0.32 @tab 0.47 @tab 0.13
-@item contf_xyz @tab 0.14 @tab 0.23 @tab 0.35 @tab 0.13 @tab 0.2 @tab 0.31 @tab 0.09
-@item contfa @tab 0.23 @tab 0.36 @tab 0.46 @tab 0.15 @tab 0.41 @tab 0.54 @tab 0.11
-@item contv @tab 0.19 @tab 0.3 @tab 0.4 @tab 0.16 @tab 0.33 @tab 0.41 @tab 0.11
-@item correl @tab 0.09 @tab 0.08 @tab 0.17 @tab 0.09 @tab 0.08 @tab 0.23 @tab 0.05
-@item curvcoor @tab 0.2 @tab 0.2 @tab 0.31 @tab 0.16 @tab 0.16 @tab 0.32 @tab 0.13
-@item cut @tab 1.13 @tab 0.98 @tab 1.09 @tab 0.6 @tab 1.07 @tab 1.26 @tab 0.49
-@item dat_diff @tab 0.1 @tab 0.2 @tab 0.29 @tab 0.09 @tab 0.24 @tab 0.37 @tab 0.07
-@item dat_extra @tab 0.33 @tab 0.32 @tab 0.43 @tab 0.17 @tab 0.3 @tab 0.45 @tab 0.1
-@item data1 @tab 4.01 @tab 2.91 @tab 3.02 @tab 2.47 @tab 2.78 @tab 2.99 @tab 2.26
-@item data2 @tab 2.65 @tab 2.36 @tab 2.41 @tab 2.24 @tab 2.31 @tab 2.51 @tab 2.16
-@item dens @tab 0.17 @tab 0.39 @tab 0.55 @tab 0.14 @tab 0.39 @tab 0.61 @tab 0.09
-@item dens_xyz @tab 0.12 @tab 0.29 @tab 0.42 @tab 0.1 @tab 0.32 @tab 0.47 @tab 0.07
-@item densa @tab 0.12 @tab 0.24 @tab 0.37 @tab 0.09 @tab 0.32 @tab 0.52 @tab 0.07
-@item dew @tab 1.76 @tab 1.07 @tab 1.1 @tab 0.2 @tab 0.3 @tab 0.38 @tab 0.11
-@item dots @tab 0.09 @tab 0.09 @tab 0.12 @tab 0.08 @tab 0.09 @tab 0.15 @tab 0.06
-@item error @tab 0.1 @tab 0.11 @tab 0.2 @tab 0.1 @tab 0.11 @tab 0.26 @tab 0.06
-@item error2 @tab 0.08 @tab 0.13 @tab 0.24 @tab 0.08 @tab 0.14 @tab 0.34 @tab 0.07
-@item export @tab 0.25 @tab 0.53 @tab 0.67 @tab 0.2 @tab 0.52 @tab 0.72 @tab 0.14
-@item fall @tab 0.06 @tab 0.07 @tab 0.15 @tab 0.07 @tab 0.07 @tab 0.17 @tab 0.06
-@item fexport @tab 3.7 @tab 3.72 @tab 4.62 @tab 1.82 @tab 1.87 @tab 2.71 @tab 2.67
-@item fit @tab 0.1 @tab 0.1 @tab 0.15 @tab 0.09 @tab 0.09 @tab 0.18 @tab 0.06
-@item flow @tab 0.35 @tab 0.36 @tab 0.56 @tab 0.29 @tab 0.29 @tab 0.53 @tab 0.27
-@item fog @tab 0.08 @tab 0.28 @tab 0.35 @tab 0.07 @tab 0.4 @tab 0.51 @tab 0.05
-@item fonts @tab 2.34 @tab 2.31 @tab 2.34 @tab 2.3 @tab 2.29 @tab 2.29 @tab 2.2
-@item grad @tab 0.11 @tab 0.37 @tab 0.55 @tab 0.1 @tab 0.4 @tab 0.6 @tab 0.08
-@item hist @tab 0.29 @tab 0.32 @tab 0.4 @tab 0.32 @tab 0.34 @tab 0.46 @tab 0.08
-@item inplot @tab 0.11 @tab 0.11 @tab 0.17 @tab 0.11 @tab 0.1 @tab 0.27 @tab 0.07
-@item label @tab 0.09 @tab 0.08 @tab 0.13 @tab 0.09 @tab 0.08 @tab 0.18 @tab 0.05
-@item legend @tab 0.23 @tab 0.28 @tab 0.44 @tab 0.17 @tab 0.26 @tab 0.47 @tab 0.06
-@item light @tab 0.56 @tab 0.56 @tab 0.6 @tab 0.57 @tab 0.57 @tab 0.59 @tab 0.57
-@item loglog @tab 0.19 @tab 0.19 @tab 0.28 @tab 0.15 @tab 0.15 @tab 0.27 @tab 0.12
-@item map @tab 0.09 @tab 0.21 @tab 0.31 @tab 0.09 @tab 0.23 @tab 0.39 @tab 0.06
-@item mark @tab 0.09 @tab 0.08 @tab 0.14 @tab 0.08 @tab 0.07 @tab 0.15 @tab 0.05
-@item mask @tab 0.12 @tab 0.31 @tab 0.33 @tab 0.11 @tab 0.29 @tab 0.37 @tab 0.06
-@item mesh @tab 0.08 @tab 0.07 @tab 0.19 @tab 0.07 @tab 0.07 @tab 0.23 @tab 0.05
-@item mirror @tab 0.19 @tab 0.26 @tab 0.38 @tab 0.12 @tab 0.24 @tab 0.43 @tab 0.07
-@item molecule @tab 0.15 @tab 0.32 @tab 0.41 @tab 0.07 @tab 0.21 @tab 0.28 @tab 0.06
-@item param1 @tab 0.33 @tab 0.47 @tab 0.61 @tab 0.19 @tab 0.33 @tab 0.69 @tab 0.11
-@item param2 @tab 0.7 @tab 0.97 @tab 1.11 @tab 0.32 @tab 0.76 @tab 0.96 @tab 0.27
-@item param3 @tab 3.08 @tab 3.95 @tab 4.16 @tab 1.7 @tab 2.87 @tab 3.22 @tab 1.53
-@item paramv @tab 5.05 @tab 4.86 @tab 5.15 @tab 1.3 @tab 1.61 @tab 1.67 @tab 1.3
-@item parser @tab 0.09 @tab 0.09 @tab 0.17 @tab 0.09 @tab 0.08 @tab 0.24 @tab 0.06
-@item pde @tab 2.2 @tab 2.44 @tab 2.54 @tab 2.1 @tab 2.39 @tab 2.51 @tab 2.06
-@item pipe @tab 4.83 @tab 3.58 @tab 3.6 @tab 0.89 @tab 1.6 @tab 1.64 @tab 0.69
-@item plot @tab 0.12 @tab 0.12 @tab 0.2 @tab 0.11 @tab 0.11 @tab 0.22 @tab 0.06
-@item primitives @tab 0.16 @tab 0.46 @tab 0.63 @tab 0.14 @tab 0.45 @tab 0.59 @tab 0.06
-@item projection @tab 0.22 @tab 0.35 @tab 0.57 @tab 0.13 @tab 0.3 @tab 0.66 @tab 0.09
-@item projection5 @tab 0.22 @tab 0.29 @tab 0.52 @tab 0.14 @tab 0.24 @tab 0.54 @tab 0.09
-@item qo2d @tab 0.67 @tab 0.91 @tab 1.11 @tab 0.65 @tab 0.86 @tab 1.02 @tab 0.57
-@item radar @tab 0.07 @tab 0.07 @tab 0.12 @tab 0.07 @tab 0.07 @tab 0.13 @tab 0.05
-@item refill @tab 0.06 @tab 0.06 @tab 0.11 @tab 0.07 @tab 0.06 @tab 0.16 @tab 0.06
-@item region @tab 0.09 @tab 0.22 @tab 0.36 @tab 0.1 @tab 0.18 @tab 0.36 @tab 0.05
-@item schemes @tab 0.18 @tab 0.39 @tab 0.53 @tab 0.19 @tab 0.39 @tab 0.57 @tab 0.07
-@item several_light @tab 0.11 @tab 0.44 @tab 0.52 @tab 0.08 @tab 0.6 @tab 0.71 @tab 0.05
-@item solve @tab 0.12 @tab 0.13 @tab 0.27 @tab 0.12 @tab 0.12 @tab 0.34 @tab 0.06
-@item stem @tab 0.08 @tab 0.08 @tab 0.18 @tab 0.09 @tab 0.09 @tab 0.23 @tab 0.05
-@item step @tab 0.09 @tab 0.1 @tab 0.16 @tab 0.1 @tab 0.1 @tab 0.18 @tab 0.06
-@item stereo @tab 0.11 @tab 0.27 @tab 0.36 @tab 0.07 @tab 0.4 @tab 0.52 @tab 0.06
-@item stfa @tab 0.12 @tab 0.21 @tab 0.47 @tab 0.11 @tab 0.24 @tab 0.42 @tab 0.06
-@item style @tab 0.24 @tab 0.29 @tab 0.43 @tab 0.18 @tab 0.39 @tab 0.8 @tab 0.07
-@item surf @tab 0.22 @tab 0.39 @tab 0.49 @tab 0.15 @tab 0.38 @tab 0.53 @tab 0.07
-@item surf3 @tab 2.85 @tab 2.76 @tab 3.93 @tab 2.47 @tab 2.66 @tab 4.14 @tab 0.64
-@item surf3a @tab 0.68 @tab 0.77 @tab 0.89 @tab 0.34 @tab 1.25 @tab 1.46 @tab 0.23
-@item surf3c @tab 0.68 @tab 0.75 @tab 0.87 @tab 0.34 @tab 1.24 @tab 1.47 @tab 0.23
-@item surfa @tab 0.09 @tab 0.25 @tab 0.33 @tab 0.07 @tab 0.37 @tab 0.48 @tab 0.05
-@item surfc @tab 0.08 @tab 0.25 @tab 0.34 @tab 0.08 @tab 0.36 @tab 0.47 @tab 0.06
-@item table @tab 0.28 @tab 0.29 @tab 0.44 @tab 0.12 @tab 0.1 @tab 0.23 @tab 0.07
-@item tape @tab 0.1 @tab 0.15 @tab 0.22 @tab 0.1 @tab 0.16 @tab 0.27 @tab 0.06
-@item tens @tab 0.08 @tab 0.08 @tab 0.14 @tab 0.09 @tab 0.09 @tab 0.18 @tab 0.06
-@item ternary @tab 0.21 @tab 0.28 @tab 0.46 @tab 0.17 @tab 0.3 @tab 0.63 @tab 0.08
-@item text @tab 0.2 @tab 0.2 @tab 0.31 @tab 0.1 @tab 0.11 @tab 0.22 @tab 0.06
-@item text2 @tab 0.16 @tab 0.15 @tab 0.26 @tab 0.12 @tab 0.11 @tab 0.24 @tab 0.06
-@item textmark @tab 0.11 @tab 0.12 @tab 0.2 @tab 0.09 @tab 0.09 @tab 0.23 @tab 0.06
-@item ticks @tab 0.16 @tab 0.16 @tab 0.27 @tab 0.14 @tab 0.15 @tab 0.28 @tab 0.06
-@item tile @tab 0.07 @tab 0.14 @tab 0.23 @tab 0.07 @tab 0.15 @tab 0.29 @tab 0.05
-@item tiles @tab 0.08 @tab 0.19 @tab 0.26 @tab 0.08 @tab 0.18 @tab 0.27 @tab 0.05
-@item torus @tab 0.2 @tab 0.48 @tab 0.69 @tab 0.11 @tab 0.32 @tab 0.5 @tab 0.08
-@item traj @tab 0.06 @tab 0.07 @tab 0.13 @tab 0.06 @tab 0.06 @tab 0.17 @tab 0.06
-@item triangulation @tab 0.09 @tab 0.23 @tab 0.34 @tab 0.08 @tab 0.27 @tab 0.44 @tab 0.05
-@item triplot @tab 0.08 @tab 0.59 @tab 0.77 @tab 0.08 @tab 0.64 @tab 0.83 @tab 0.05
-@item tube @tab 0.16 @tab 0.47 @tab 0.65 @tab 0.12 @tab 0.34 @tab 0.49 @tab 0.08
-@item type0 @tab 0.31 @tab 0.77 @tab 0.92 @tab 0.15 @tab 0.68 @tab 0.87 @tab 0.12
-@item type1 @tab 0.31 @tab 0.76 @tab 0.94 @tab 0.16 @tab 0.67 @tab 0.86 @tab 0.12
-@item type2 @tab 0.31 @tab 0.75 @tab 0.94 @tab 0.16 @tab 0.67 @tab 0.85 @tab 0.14
-@item vect @tab 0.15 @tab 0.15 @tab 0.31 @tab 0.12 @tab 0.12 @tab 0.34 @tab 0.08
-@item vecta @tab 0.08 @tab 0.08 @tab 0.16 @tab 0.09 @tab 0.08 @tab 0.24 @tab 0.06
-@item venn @tab 0.07 @tab 0.39 @tab 0.54 @tab 0.06 @tab 0.47 @tab 0.65 @tab 0.04
+@item alpha @tab 0.16 @tab 0.184 @tab 0.362 @tab 0.0868 @tab 0.105 @tab 0.246 @tab 0.0674
+@item area @tab 0.102 @tab 0.165 @tab 0.327 @tab 0.0795 @tab 0.124 @tab 0.255 @tab 0.0656
+@item aspect @tab 0.094 @tab 0.0939 @tab 0.15 @tab 0.0664 @tab 0.0674 @tab 0.11 @tab 0.0618
+@item axial @tab 0.909 @tab 0.985 @tab 2.03 @tab 0.371 @tab 0.464 @tab 1.28 @tab 0.105
+@item axis @tab 0.121 @tab 0.121 @tab 0.198 @tab 0.0705 @tab 0.0683 @tab 0.123 @tab 0.0951
+@item barh @tab 0.0886 @tab 0.105 @tab 0.181 @tab 0.068 @tab 0.0795 @tab 0.137 @tab 0.13
+@item bars @tab 0.11 @tab 0.126 @tab 0.207 @tab 0.0868 @tab 0.0973 @tab 0.162 @tab 0.0754
+@item belt @tab 0.0944 @tab 0.12 @tab 0.212 @tab 0.0674 @tab 0.089 @tab 0.192 @tab 0.0629
+@item box @tab 0.122 @tab 0.161 @tab 0.25 @tab 0.0735 @tab 0.0951 @tab 0.174 @tab 0.0641
+@item boxplot @tab 0.0696 @tab 0.0699 @tab 0.118 @tab 0.0633 @tab 0.0634 @tab 0.106 @tab 0.0514
+@item boxs @tab 0.296 @tab 0.354 @tab 0.786 @tab 0.111 @tab 0.213 @tab 0.58 @tab 0.0872
+@item candle @tab 0.0762 @tab 0.0787 @tab 0.143 @tab 0.0789 @tab 0.0859 @tab 0.135 @tab 0.0548
+@item chart @tab 0.572 @tab 0.778 @tab 2.39 @tab 0.244 @tab 0.429 @tab 1.64 @tab 0.2
+@item cloud @tab 0.0818 @tab 7.16 @tab 9.38 @tab 0.0691 @tab 2.43 @tab 4.96 @tab 0.063
+@item colorbar @tab 0.221 @tab 0.248 @tab 0.363 @tab 0.227 @tab 0.285 @tab 0.378 @tab 0.11
+@item combined @tab 0.583 @tab 0.464 @tab 0.697 @tab 0.339 @tab 0.375 @tab 0.586 @tab 0.293
+@item cones @tab 0.289 @tab 0.24 @tab 0.452 @tab 0.184 @tab 0.191 @tab 0.375 @tab 0.131
+@item cont @tab 0.124 @tab 0.123 @tab 0.208 @tab 0.0785 @tab 0.0778 @tab 0.14 @tab 0.0774
+@item cont_xyz @tab 0.134 @tab 0.13 @tab 0.184 @tab 0.113 @tab 0.113 @tab 0.163 @tab 0.108
+@item conta @tab 0.128 @tab 0.154 @tab 0.289 @tab 0.112 @tab 0.129 @tab 0.162 @tab 0.177
+@item contd @tab 0.239 @tab 0.255 @tab 0.354 @tab 0.12 @tab 0.142 @tab 0.236 @tab 0.103
+@item contf @tab 0.203 @tab 0.226 @tab 0.334 @tab 0.111 @tab 0.13 @tab 0.226 @tab 0.0992
+@item contf_xyz @tab 0.17 @tab 0.215 @tab 0.305 @tab 0.126 @tab 0.151 @tab 0.236 @tab 0.118
+@item contfa @tab 0.287 @tab 0.369 @tab 0.493 @tab 0.18 @tab 0.203 @tab 0.401 @tab 0.165
+@item contv @tab 0.162 @tab 0.176 @tab 0.306 @tab 0.089 @tab 0.103 @tab 0.212 @tab 0.076
+@item correl @tab 0.099 @tab 0.0894 @tab 0.169 @tab 0.0815 @tab 0.0855 @tab 0.129 @tab 0.0659
+@item curvcoor @tab 0.132 @tab 0.131 @tab 0.231 @tab 0.084 @tab 0.0843 @tab 0.151 @tab 0.124
+@item cut @tab 1.25 @tab 0.842 @tab 1.06 @tab 0.743 @tab 0.768 @tab 1.13 @tab 0.644
+@item dat_diff @tab 0.127 @tab 0.163 @tab 0.261 @tab 0.115 @tab 0.135 @tab 0.216 @tab 0.0846
+@item dat_extra @tab 0.328 @tab 0.26 @tab 0.351 @tab 0.17 @tab 0.267 @tab 0.3 @tab 0.114
+@item data1 @tab 4.98 @tab 3.75 @tab 3.98 @tab 3.6 @tab 3.52 @tab 3.9 @tab 3.29
+@item data2 @tab 3.28 @tab 2.74 @tab 2.82 @tab 2.81 @tab 2.78 @tab 3.2 @tab 2.61
+@item dens @tab 0.153 @tab 0.244 @tab 0.407 @tab 0.1 @tab 0.141 @tab 0.273 @tab 0.0771
+@item dens_xyz @tab 0.15 @tab 0.211 @tab 0.358 @tab 0.123 @tab 0.162 @tab 0.282 @tab 0.0961
+@item densa @tab 0.183 @tab 0.211 @tab 0.351 @tab 0.12 @tab 0.154 @tab 0.296 @tab 0.0912
+@item dew @tab 1.7 @tab 0.942 @tab 1.03 @tab 0.224 @tab 0.241 @tab 0.361 @tab 0.129
+@item dots @tab 0.161 @tab 0.167 @tab 0.217 @tab 0.104 @tab 0.11 @tab 0.148 @tab 0.0639
+@item error @tab 0.101 @tab 0.109 @tab 0.176 @tab 0.11 @tab 0.113 @tab 0.194 @tab 0.0688
+@item error2 @tab 0.0931 @tab 0.112 @tab 0.209 @tab 0.0742 @tab 0.0808 @tab 0.156 @tab 0.0675
+@item export @tab 0.287 @tab 0.363 @tab 0.531 @tab 0.174 @tab 0.22 @tab 0.36 @tab 0.253
+@item fall @tab 0.079 @tab 0.0752 @tab 0.157 @tab 0.0652 @tab 0.064 @tab 0.122 @tab 0.0868
+@item fit @tab 0.109 @tab 0.824 @tab 0.173 @tab 0.0894 @tab 0.0918 @tab 0.136 @tab 0.0793
+@item flow @tab 0.39 @tab 0.395 @tab 0.566 @tab 0.313 @tab 0.423 @tab 0.435 @tab 0.3
+@item fog @tab 0.111 @tab 0.169 @tab 0.362 @tab 0.0716 @tab 0.127 @tab 0.3 @tab 0.063
+@item fonts @tab 3 @tab 3.02 @tab 3.14 @tab 2.75 @tab 2.57 @tab 2.88 @tab 2.66
+@item grad @tab 0.119 @tab 0.229 @tab 0.424 @tab 0.103 @tab 0.158 @tab 0.306 @tab 0.0859
+@item hist @tab 0.294 @tab 0.303 @tab 0.358 @tab 0.209 @tab 0.217 @tab 0.274 @tab 0.0886
+@item indirect @tab 0.108 @tab 0.0908 @tab 0.147 @tab 0.111 @tab 0.114 @tab 0.16 @tab 0.0556
+@item inplot @tab 0.102 @tab 0.0998 @tab 0.174 @tab 0.0747 @tab 0.0726 @tab 0.123 @tab 0.0664
+@item label @tab 0.0836 @tab 0.0803 @tab 0.129 @tab 0.0808 @tab 0.08 @tab 0.12 @tab 0.0529
+@item legend @tab 0.185 @tab 0.195 @tab 0.3 @tab 0.0758 @tab 0.0864 @tab 0.171 @tab 0.0622
+@item light @tab 0.273 @tab 0.271 @tab 0.299 @tab 0.277 @tab 0.274 @tab 0.299 @tab 0.274
+@item loglog @tab 0.12 @tab 0.123 @tab 0.198 @tab 0.076 @tab 0.0779 @tab 0.133 @tab 0.0692
+@item map @tab 0.107 @tab 0.159 @tab 0.255 @tab 0.12 @tab 0.149 @tab 0.316 @tab 0.0684
+@item mark @tab 0.083 @tab 0.0937 @tab 0.126 @tab 0.072 @tab 0.0723 @tab 0.11 @tab 0.0507
+@item mask @tab 0.12 @tab 0.24 @tab 0.257 @tab 0.0723 @tab 0.141 @tab 0.169 @tab 0.0597
+@item mesh @tab 0.0866 @tab 0.0906 @tab 0.189 @tab 0.0661 @tab 0.0932 @tab 0.156 @tab 0.0638
+@item mirror @tab 0.163 @tab 0.164 @tab 0.305 @tab 0.08 @tab 0.094 @tab 0.209 @tab 0.0679
+@item molecule @tab 0.155 @tab 0.166 @tab 0.354 @tab 0.0754 @tab 0.111 @tab 0.263 @tab 0.0628
+@item ode @tab 0.652 @tab 0.654 @tab 0.788 @tab 0.631 @tab 0.636 @tab 0.793 @tab 0.635
+@item ohlc @tab 0.0668 @tab 0.0668 @tab 0.117 @tab 0.0675 @tab 0.0734 @tab 0.104 @tab 0.053
+@item param1 @tab 0.288 @tab 0.295 @tab 0.518 @tab 0.137 @tab 0.158 @tab 0.352 @tab 0.147
+@item param2 @tab 0.555 @tab 0.54 @tab 0.767 @tab 0.591 @tab 0.232 @tab 0.51 @tab 0.151
+@item param3 @tab 3.15 @tab 3.63 @tab 3.78 @tab 1.86 @tab 2.03 @tab 2.35 @tab 1.61
+@item paramv @tab 4.55 @tab 4.9 @tab 4.7 @tab 1.14 @tab 1.19 @tab 1.35 @tab 1.11
+@item parser @tab 0.118 @tab 0.116 @tab 0.195 @tab 0.115 @tab 0.122 @tab 0.225 @tab 0.0954
+@item pde @tab 0.883 @tab 0.961 @tab 1.13 @tab 0.834 @tab 0.843 @tab 0.953 @tab 0.781
+@item pipe @tab 4.27 @tab 3.23 @tab 3.04 @tab 0.664 @tab 0.831 @tab 0.993 @tab 0.52
+@item plot @tab 0.154 @tab 0.119 @tab 0.221 @tab 0.0921 @tab 0.0933 @tab 0.143 @tab 0.0835
+@item primitives @tab 0.143 @tab 0.188 @tab 0.43 @tab 0.0749 @tab 0.108 @tab 0.313 @tab 0.0879
+@item projection @tab 0.182 @tab 0.207 @tab 0.494 @tab 0.0878 @tab 0.103 @tab 0.349 @tab 0.0768
+@item projection5 @tab 0.17 @tab 0.2 @tab 0.427 @tab 0.0835 @tab 0.0956 @tab 0.323 @tab 0.11
+@item qo2d @tab 0.325 @tab 0.423 @tab 0.596 @tab 0.286 @tab 0.341 @tab 0.5 @tab 0.26
+@item radar @tab 0.0724 @tab 0.0738 @tab 0.115 @tab 0.076 @tab 0.0804 @tab 0.135 @tab 0.0499
+@item refill @tab 0.329 @tab 0.263 @tab 0.38 @tab 0.197 @tab 0.167 @tab 0.286 @tab 0.114
+@item region @tab 0.0964 @tab 0.235 @tab 0.265 @tab 0.0729 @tab 0.0986 @tab 0.191 @tab 0.0663
+@item schemes @tab 0.158 @tab 0.205 @tab 0.358 @tab 0.0947 @tab 0.116 @tab 0.231 @tab 0.0633
+@item several_light @tab 0.121 @tab 0.136 @tab 0.494 @tab 0.0704 @tab 0.0966 @tab 0.427 @tab 0.0609
+@item solve @tab 0.138 @tab 0.134 @tab 0.247 @tab 0.108 @tab 0.104 @tab 0.204 @tab 0.0741
+@item stem @tab 0.103 @tab 0.101 @tab 0.171 @tab 0.079 @tab 0.0745 @tab 0.135 @tab 0.0653
+@item step @tab 0.114 @tab 0.11 @tab 0.157 @tab 0.0782 @tab 0.0755 @tab 0.119 @tab 0.0636
+@item stereo @tab 0.12 @tab 0.138 @tab 0.308 @tab 0.0715 @tab 0.0996 @tab 0.274 @tab 0.065
+@item stfa @tab 0.128 @tab 0.168 @tab 0.366 @tab 0.0982 @tab 0.122 @tab 0.273 @tab 0.0732
+@item style @tab 0.181 @tab 0.202 @tab 0.338 @tab 0.0814 @tab 0.0929 @tab 0.19 @tab 0.0614
+@item surf @tab 0.235 @tab 0.233 @tab 0.395 @tab 0.12 @tab 0.137 @tab 0.284 @tab 0.0811
+@item surf3 @tab 3.33 @tab 3.34 @tab 4.02 @tab 3.66 @tab 3.31 @tab 5.02 @tab 1.18
+@item surf3a @tab 0.825 @tab 0.581 @tab 0.901 @tab 0.469 @tab 0.641 @tab 1.34 @tab 0.378
+@item surf3c @tab 0.797 @tab 0.577 @tab 0.91 @tab 0.471 @tab 0.637 @tab 1.34 @tab 0.375
+@item surfa @tab 0.0979 @tab 0.141 @tab 0.358 @tab 0.0698 @tab 0.0953 @tab 0.264 @tab 0.0639
+@item surfc @tab 0.0992 @tab 0.135 @tab 0.3 @tab 0.0682 @tab 0.0964 @tab 0.252 @tab 0.0619
+@item table @tab 0.213 @tab 0.205 @tab 0.33 @tab 0.0784 @tab 0.0796 @tab 0.159 @tab 0.0633
+@item tape @tab 0.1 @tab 0.117 @tab 0.211 @tab 0.07 @tab 0.0808 @tab 0.147 @tab 0.0662
+@item tens @tab 0.0891 @tab 0.0865 @tab 0.14 @tab 0.108 @tab 0.11 @tab 0.153 @tab 0.181
+@item ternary @tab 0.18 @tab 0.199 @tab 0.376 @tab 0.0867 @tab 0.0968 @tab 0.263 @tab 0.07
+@item text @tab 0.164 @tab 0.165 @tab 0.253 @tab 0.0863 @tab 0.088 @tab 0.155 @tab 0.0635
+@item text2 @tab 0.145 @tab 0.145 @tab 0.211 @tab 0.109 @tab 0.109 @tab 0.168 @tab 0.0717
+@item textmark @tab 0.115 @tab 0.113 @tab 0.171 @tab 0.0847 @tab 0.0815 @tab 0.133 @tab 0.16
+@item ticks @tab 0.18 @tab 0.184 @tab 0.277 @tab 0.0756 @tab 0.074 @tab 0.161 @tab 0.063
+@item tile @tab 0.0826 @tab 0.116 @tab 0.209 @tab 0.0671 @tab 0.0839 @tab 0.16 @tab 0.0638
+@item tiles @tab 0.0856 @tab 0.134 @tab 0.217 @tab 0.0685 @tab 0.0901 @tab 0.157 @tab 0.0678
+@item torus @tab 0.168 @tab 0.202 @tab 0.521 @tab 0.0812 @tab 0.114 @tab 0.372 @tab 0.0758
+@item traj @tab 0.0641 @tab 0.065 @tab 0.13 @tab 0.066 @tab 0.0625 @tab 0.112 @tab 0.0529
+@item triangulation @tab 0.0895 @tab 0.127 @tab 0.304 @tab 0.0839 @tab 0.117 @tab 0.271 @tab 0.0707
+@item triplot @tab 0.0721 @tab 0.176 @tab 0.581 @tab 0.0639 @tab 0.118 @tab 0.439 @tab 0.0497
+@item tube @tab 0.151 @tab 0.219 @tab 0.48 @tab 0.0922 @tab 0.132 @tab 0.347 @tab 0.0719
+@item type0 @tab 0.296 @tab 0.289 @tab 0.656 @tab 0.135 @tab 0.196 @tab 0.555 @tab 0.117
+@item type1 @tab 0.294 @tab 0.286 @tab 0.661 @tab 0.138 @tab 0.196 @tab 0.566 @tab 0.116
+@item type2 @tab 0.311 @tab 0.304 @tab 0.67 @tab 0.155 @tab 0.215 @tab 0.574 @tab 0.135
+@item vect @tab 0.19 @tab 0.192 @tab 0.31 @tab 0.175 @tab 0.164 @tab 0.273 @tab 0.12
+@item vecta @tab 0.0971 @tab 0.0982 @tab 0.186 @tab 0.108 @tab 0.118 @tab 0.31 @tab 0.0698
+@item venn @tab 0.064 @tab 0.24 @tab 0.397 @tab 0.0631 @tab 0.155 @tab 0.323 @tab 0.0474
 @end multitable
diff --git a/texinfo/udav/udav_anim.png b/texinfo/udav/udav_anim.png
new file mode 100644 (file)
index 0000000..0941539
Binary files /dev/null and b/texinfo/udav/udav_anim.png differ
index 460bdaca4dc3372d1fc5064c84f4a0a6ba14dbe0..4dca6b852d2954b4a8eb9114a3fa50c939d39725 100644 (file)
Binary files a/texinfo/udav/udav_arg.png and b/texinfo/udav/udav_arg.png differ
index b01f1125722b0f017b1876381290c6ef0227631a..3ff37df720054cfba908bfe1239ec9b3337cd928 100644 (file)
Binary files a/texinfo/udav/udav_calc.png and b/texinfo/udav/udav_calc.png differ
index d222c3e896c7178f648c1cc6a069b955d4ee7e8f..16c1ec935a5ed3f8ea29469b2e4284efadeddd1d 100644 (file)
Binary files a/texinfo/udav/udav_cmd.png and b/texinfo/udav/udav_cmd.png differ
index 686b1beefd614460579470df5b6cd326cf126c27..3b3383d6076159b5afc072caff83cd0cd0d6d485 100644 (file)
Binary files a/texinfo/udav/udav_data.png and b/texinfo/udav/udav_data.png differ
index 2ff2e38b1b51eee06ab613a3720e6c003785685b..c633082f03c374c38e1213412e2c23c3deea519e 100644 (file)
Binary files a/texinfo/udav/udav_gen_set.png and b/texinfo/udav/udav_gen_set.png differ
index 2f78ab9a352f4aa270b3e64d4ed831e461ccb476..b95c59a5b4874874661c8a3dbd03764781e66a1e 100644 (file)
Binary files a/texinfo/udav/udav_help.png and b/texinfo/udav/udav_help.png differ
diff --git a/texinfo/udav/udav_inplot.png b/texinfo/udav/udav_inplot.png
new file mode 100644 (file)
index 0000000..66c0e10
Binary files /dev/null and b/texinfo/udav/udav_inplot.png differ
index 0eb1a67d84fbf23611ba2c9285840f503eecc09d..40be0143ed391bb3ebceced0ed7d41335a20f42b 100644 (file)
Binary files a/texinfo/udav/udav_light.png and b/texinfo/udav/udav_light.png differ
index c93ae90fdc26e8d4c5b660bfe9334256acd1fa70..8c5af028c0553be3c976f04cb213657f216e1131 100644 (file)
Binary files a/texinfo/udav/udav_main.png and b/texinfo/udav/udav_main.png differ
diff --git a/texinfo/udav/udav_mask.png b/texinfo/udav/udav_mask.png
new file mode 100644 (file)
index 0000000..80dcc35
Binary files /dev/null and b/texinfo/udav/udav_mask.png differ
index 5e523d95b48c86a314bbd18cb361970fc4203ff0..fe89ab9eae503f7d935d74d5c9c81e652294c99d 100644 (file)
Binary files a/texinfo/udav/udav_opt.png and b/texinfo/udav/udav_opt.png differ
index e494e7a8d553647dda8284e0af7f28ebb0b502b4..a387ce87edbee8e2825efce31195e94e57774de0 100644 (file)
Binary files a/texinfo/udav/udav_pen.png and b/texinfo/udav/udav_pen.png differ
index 2235acf4948648dc55caaa86722fd1b26a052d4c..fba154b748fa6a7a73884980be9c5416b5b12e21 100644 (file)
Binary files a/texinfo/udav/udav_prop.png and b/texinfo/udav/udav_prop.png differ
index 6b5984a10f57d4a6750f58eb965c46f83af18443..9895a4848c2b989f2ff556054379e4ac808f1079 100644 (file)
Binary files a/texinfo/udav/udav_sch.png and b/texinfo/udav/udav_sch.png differ
index 7276dd6845d5197b76e2f2dc5bacac1d4bdd2702..09dee8133275bb76f5eb18e059d935aa2838f133 100644 (file)
Binary files a/texinfo/udav/udav_txt.png and b/texinfo/udav/udav_txt.png differ
index 9c1507d5c680765345ae1a14c027b04e5eed0199..25d03b6afea0894faf381a6975c59bb6a96f5a69 100644 (file)
Binary files a/texinfo/udav/udav_var.png and b/texinfo/udav/udav_var.png differ
index 99a5d125625f4eb63f67c792e59e7d5cf3db75b0..74621d946c4a4c44b7e53b628cbdfbfcce0c31a1 100644 (file)
@@ -57,21 +57,29 @@ There are a set of dialogs, which allow change/add a command, setup global plot
 
 @ufig{udav_cmd,8, New command dialog}
 
-One of most interesting dialog (hotkey @key{Meta-C} or @key{Win-C}) is dialog which help to enter new command or change arguments of existed one. It allows consequently select the category of command, command name in category and appropriate set of command arguments. At this right side show detailed command description. Required argument(s) are denoted by bold text. Strings are placed in apostrophes, like @code{'txt'}. Buttons below table allow to call dialogs for changing style of command (if argument @code{'fmt'} is present in the list of command arguments); to set variable or expression for argument(s); to add options for command.
+One of most interesting dialog (hotkey @key{Meta-C} or @key{Win-C}) is dialog which help to enter new command or change arguments of existed one. It allows consequently select the category of command, command name in category and appropriate set of command arguments. At this right side show detailed command description. Required argument(s) are denoted by bold text. Strings are placed in apostrophes, like @code{'txt'}. Buttons below table allow to call dialogs for changing style of command (if argument @code{'fmt'} is present in the list of command arguments); to set variable or expression for argument(s); to add options for command. Note, you can click on a cell to enter value, or double-click to call corresponding dialog.
 
 @ufig{udav_pen,5, Style dialog - pen style}
 @ufig{udav_sch,5, Style dialog - color scheme}
 @ufig{udav_txt,5, Style dialog - text style}
+@ufig{udav_mask,5, Style dialog - manual mask}
 
-Dialog for changing style can be called independently, but usually is called from @emph{New command} dialog or by double click on primitive. It contain 3 tabs: one for pen style, one for color scheme, one for text style. You should select appropriate one. Resulting string of style and sample picture are shown at bottom of dialog.
+Dialog for changing style can be called independently, but usually is called from @emph{New command} dialog or by double click on primitive. It contain 3 tabs: one for pen style, one for color scheme, one for text style. You should select appropriate one. Resulting string of style and sample picture are shown at bottom of dialog. Usually it can be called from New command dialog.
 
 @ufig{udav_var,3, Variable dialog}
 
-Dialog for entering variable allow to select variable or expression which can be used as argument of a command. Here you can select the variable name; range of indexes in each directions; operation which will be applied (like, summation, finding minimal/maximal values and so on).
+Dialog for entering variable allow to select variable or expression which can be used as argument of a command. Here you can select the variable name; range of indexes in each directions; operation which will be applied (like, summation, finding minimal/maximal values and so on). Usually it can be called from New command dialog.
 
-@ufig{udav_opt,7.5, Variable dialog}
+@ufig{udav_opt,7.5, Dialog for options of a command}
+
+Dialog for command options allow to change @ref{Command options}. Usually it can be called from New command dialog.
+
+
+
+@ufig{udav_inplot,8, New inplot dialog}
+
+Another interesting dialog, which help to select and properly setup a @ref{subplot}, @ref{inplot}, @ref{columnplot}, @ref{stickplot} and similar commands.
 
-Dialog for command options allow to change @ref{Command options}.
 
 @ufig{udav_gen_set,9, Dialog for general properties}
 @ufig{udav_light,9, Dialog for light properties}
index 99a5d125625f4eb63f67c792e59e7d5cf3db75b0..74621d946c4a4c44b7e53b628cbdfbfcce0c31a1 100644 (file)
@@ -57,21 +57,29 @@ There are a set of dialogs, which allow change/add a command, setup global plot
 
 @ufig{udav_cmd,8, New command dialog}
 
-One of most interesting dialog (hotkey @key{Meta-C} or @key{Win-C}) is dialog which help to enter new command or change arguments of existed one. It allows consequently select the category of command, command name in category and appropriate set of command arguments. At this right side show detailed command description. Required argument(s) are denoted by bold text. Strings are placed in apostrophes, like @code{'txt'}. Buttons below table allow to call dialogs for changing style of command (if argument @code{'fmt'} is present in the list of command arguments); to set variable or expression for argument(s); to add options for command.
+One of most interesting dialog (hotkey @key{Meta-C} or @key{Win-C}) is dialog which help to enter new command or change arguments of existed one. It allows consequently select the category of command, command name in category and appropriate set of command arguments. At this right side show detailed command description. Required argument(s) are denoted by bold text. Strings are placed in apostrophes, like @code{'txt'}. Buttons below table allow to call dialogs for changing style of command (if argument @code{'fmt'} is present in the list of command arguments); to set variable or expression for argument(s); to add options for command. Note, you can click on a cell to enter value, or double-click to call corresponding dialog.
 
 @ufig{udav_pen,5, Style dialog - pen style}
 @ufig{udav_sch,5, Style dialog - color scheme}
 @ufig{udav_txt,5, Style dialog - text style}
+@ufig{udav_mask,5, Style dialog - manual mask}
 
-Dialog for changing style can be called independently, but usually is called from @emph{New command} dialog or by double click on primitive. It contain 3 tabs: one for pen style, one for color scheme, one for text style. You should select appropriate one. Resulting string of style and sample picture are shown at bottom of dialog.
+Dialog for changing style can be called independently, but usually is called from @emph{New command} dialog or by double click on primitive. It contain 3 tabs: one for pen style, one for color scheme, one for text style. You should select appropriate one. Resulting string of style and sample picture are shown at bottom of dialog. Usually it can be called from New command dialog.
 
 @ufig{udav_var,3, Variable dialog}
 
-Dialog for entering variable allow to select variable or expression which can be used as argument of a command. Here you can select the variable name; range of indexes in each directions; operation which will be applied (like, summation, finding minimal/maximal values and so on).
+Dialog for entering variable allow to select variable or expression which can be used as argument of a command. Here you can select the variable name; range of indexes in each directions; operation which will be applied (like, summation, finding minimal/maximal values and so on). Usually it can be called from New command dialog.
 
-@ufig{udav_opt,7.5, Variable dialog}
+@ufig{udav_opt,7.5, Dialog for options of a command}
+
+Dialog for command options allow to change @ref{Command options}. Usually it can be called from New command dialog.
+
+
+
+@ufig{udav_inplot,8, New inplot dialog}
+
+Another interesting dialog, which help to select and properly setup a @ref{subplot}, @ref{inplot}, @ref{columnplot}, @ref{stickplot} and similar commands.
 
-Dialog for command options allow to change @ref{Command options}.
 
 @ufig{udav_gen_set,9, Dialog for general properties}
 @ufig{udav_light,9, Dialog for light properties}
index 3b5769397f26a0f810dc504c744d1822bd371768..f560bbaf9afbe659d0a21cfaa1e310a51aaa175a 100644 (file)
@@ -1,3 +1,2 @@
-@set VERSION 2.2
-@set MINVER .2
-@c @set MINVER 
+@set VERSION 2.3
+@set MINVER @c .2
index de7fdf5a5fea995cebaf76355d482bd3e2bd94a2..b9dc2c9452b6c658b570a3e6f5dd331604f4d2f6 100644 (file)
@@ -52,12 +52,9 @@ Generally, MathGL is GPL library. However, you can use LGPL license for MathGL c
 
 @strong{Latest news}
 @itemize
-@item @emph{19 March 2014.}
-New version (v.2.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are compatibility changes for MS VisualStudio 2010 and early, and documentation update.
-@item @emph{10 March 2014.}
-New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are extend of 'region' plot, improve export to TeX, add missing Fortran functions, bugfixes, and other improvements, which denoted @ref{News, here}. Note, this release looks as bug free, but next release (v.2.3) will introduce a set of improvements which may not so stable at first time.
-@item @emph{22 January 2014.}
-New version (v.@value{VERSION}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are support of Qt5 and Pascal, improvements in JavaScript interface, bugfixes, and other improvements, which denoted @ref{News, here}.
+@item @emph{7 August 2014.}
+New version (v.@value{VERSION}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are many major improvements for both MathGL core and for UDAV, which denoted @ref{News, here}.
+@comment  New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are extend of 'region' plot, improve export to TeX, add missing Fortran functions, bugfixes, and other improvements, which denoted @ref{News, here}. Note, this release looks as bug free, but next release (v.2.3) will introduce a set of improvements which may not so stable at first time.
 @item @emph{11 November 2013.}
 New version (v.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are speeding up, new plot kinds and data handling functions, new plot styles, masks for bitmap output, wx-widget, Lua interface, and many other improvements, which denoted @ref{News, here}.
 @end itemize
@@ -78,8 +75,77 @@ Javascript interface was developed with support of @url{http://www.datadvance.ne
 @nav{}
 
 @itemize
-@item
-@strong{19 March 2014.}
+@item @strong{7 August 2014.}
+New version (v.2.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are major improvements and speeding up of core MathGL and UDAV.
+@itemize @bullet
+@item Add background image, which allow in particular semi-transparent background color. Correspondingly add function @ref{rasterize} for saving current image as background, and function @ref{background} for loading background image from PNG or JPEG file.
+@item Add primitives to draw @ref{polygon} and angle @ref{arc}.
+@item Allow arbitrary factor for axis ticks (like, @code{gr->SetTicks('x',M_PI,0,NAN,"\\pi");} or @code{@ref{xtick} pi '\pi'}).
+@item Add function @code{AddTick()} for adding manual tick to the list of existed ones.
+
+@item Add new styles and symbols:
+@itemize
+@item arrow style @samp{X} (see @ref{Line styles});
+@item color gradient (color scheme) for text string (see @ref{Color scheme});
+@item manual dash style, like @samp{@{df090@}} (see @ref{Line styles});
+@item manual mask style, like @samp{@{s00ff00182424f800@}} (see @ref{Color scheme});
+@item styles @samp{fFE0123456789+-} for printing numbers in functions @ref{axis}, @ref{colorbar}, @ref{table}, @ref{label};
+@item style @samp{!} to disable ticks tuning in @ref{axis} and @ref{colorbar};
+@item style @samp{!} to draw @ref{grid} lines at subticks coordinates too;
+@item special symbol @samp{\b} which will be ignored at printing;
+@item calligraphic TeX symbols, like @samp{\calB}, @samp{\calE}, @samp{\calF}, @samp{\calH}, @samp{\calI}, @samp{\calL}, @samp{\calM}, @samp{\calR}, @samp{\ell}, @samp{\scrg}, @samp{\scro}.
+@end itemize
+
+@item Add @ref{ode} solving functions for textual formulas.
+@item Add function for global cubic spline interpolation, and function @ref{gspline} to refill data using global spline.
+
+@item Add functions @code{random(dat)} and @code{gamma_inc(a,x)} to the list of known functions for formula parsing
+@item Add @code{inf} variable to the MGL and formula parsing
+@item Allow reading JPEG files for @ref{import}.
+@item Function @ref{subdata} now can handle NULL argument(s). Add variants of @ref{subdata} with provided 1 and 2 arguments.
+
+@item Warning messages and information are printed to @code{stderr} until call of @code{mgl_suppress_warn(true);} will disable it.
+@item Add function @ref{version} to check if MathGL version is valid.
+
+@item Add move constructor(s) if compiler support C++11 rvalues.
+
+@item Changes in algorithms:
+@itemize
+@item Greatly increase speed of formula parsing (i.e. of functions @ref{modify}, @ref{fill} and similar), and speeding up many other places;
+@item Improve algorithm for contours drawing and filling, taking special attention to quasi-random data;
+@item Function @code{Spline()} now use 5-th order polynomials to keep continuity of 2nd derivative too;
+@item Add function attributes @code{pure} or @code{const}, which potentially can speed up drawing;
+@item Use spline instead of linear interpolation in functions @ref{flow} and @ref{pipe};
+@item Adjust @ref{columnplot} and @ref{gridplot} positions for non-zero distance between the inplots;
+@item Improve @ref{colorbar} labels drawing for the case of disabled label rotation;
+@item Choose new scales for @ref{perspective};
+@item Allow 'negative' angles for text rotation;
+@item Use new s-hull version for triangulation.
+@end itemize
+
+@item Add @code{ViewAsRotate()} function which handle arguments of @ref{view} by the same way as @ref{rotate} function, i.e @code{View(tetx,tetz,tety)} <=> @code{ViewAsRotate(-tetz,-tetx,-tety)}.
+@item Function @code{mglWindow::Adjust()} for Quality&4==0 now show image in widgets even if draw function is absent (i.e. =NULL).
+@item Make function mgl_get_curvs() to be exported. This function is used internally to connect line segments to a set of curves (in particular, for contour lines).
+
+@item Improvements in UDAV
+@itemize
+@item Rearrange tool buttons;
+@item Add features for manual dashing and manual mask in Style dialog;
+@item Add dialog for new dialog for new inplots (including @ref{subplot}, @ref{multiplot}, @ref{columnplot}, @ref{stickplot}, @ref{gridplot});
+@item Add option to use dots plot at image refreshing (for faster rotation etc);
+@item Add new primitives (@ref{arc}, @ref{polygon}, rotated @ref{text}) as mouse handled ones;
+@item Add close button to data tabs;
+@item Add button to stop script drawing and @code{stop()} slot for QMathGL;
+@item Allow to delete/hide/unhide selected plot;
+@item Allow to move selected plot between inplots;
+@item Improve NewCommand dialog. Now it replace the script command if user change arguments only;
+@item MGL commands @ref{perspective} and @ref{fog} now work correctly in UDAV;
+@item Update icons to use Oxygen ones.
+@end itemize
+@end itemize
+
+
+@item @strong{19 March 2014.}
 New version (v.2.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are compatibility changes for MS VisualStudio 2010 and early.
 @itemize @bullet
 @item Compatibility changes for MS VisualStudio 2010 and early.
@@ -88,8 +154,7 @@ New version (v.2.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL}
 @item Update documentation.
 @end itemize
 
-@item
-@strong{10 March 2014.}
+@item @strong{10 March 2014.}
 New version (v.2.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor improvements and bugfixes:
 @itemize @bullet
 @item Add mgl_region_3d() to draw region (or ribbon) between 2 curves. Correspondingly extend mglGraph::Region() function and MGL command 'region'.
@@ -100,8 +165,7 @@ New version (v.2.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} i
 @item Minor bugfixes and memory leaks.
 @end itemize
 
-@item
-@strong{22 January 2014.}
+@item @strong{22 January 2014.}
 New version (v.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor improvements and bugfixes:
 @itemize @bullet
 @item Add Qt5 support.
@@ -125,8 +189,7 @@ New version (v.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} i
 @item Other minor bugfixes and memory leaks.
 @end itemize
 
-@item
-@strong{11 November 2013.}
+@item @strong{11 November 2013.}
 New version (v.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
 @itemize @bullet
 @item Add OpenMP calls mostly everywhere (can work as replacement of pthreads - a bit faster since more loops is parallelized).
@@ -160,212 +223,26 @@ New version (v.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is
 @item Update docs.
 @end itemize
 
-@item
-@strong{8 May 2013.}
-New version (v.2.1.3.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
-@itemize @bullet
-@item Compatibility changes for MS VS.
-@item Bugfixes for cmake options @code{enable-double=OFF, enable-zlib=OFF}.
-@item Enable mouse actions for Firefox in JS sample.
-@end itemize
-
-@item
-@strong{2 May 2013.}
-New version (v.2.1.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
-@itemize @bullet
-@item Functions @ref{sinfft}, @ref{cosfft}, @ref{hankel} and so on, become multi-threaded.
-@item Use DFT instead of FFT if GSL support is disabled (much slow!).
-@item Add Join() function for joining mglData arrays (see @ref{join})
-@item Add Roots() function for root finding of nonlinear equation (see @ref{roots})
-@item Add class mglExprC for parsing formula with complex numbers (see @ref{Evaluate expression})
-@item Correctly read #QNAN values in data files
-@item Speed up @ref{dots} drawing
-@item Add flag to disable tick labels at axis origin (see SetOriginTick())
-@item Add MGL commands @ref{origintick}, @ref{tickshift}
-@item WriteJSON now use zlib if filename end at 'z' (like "test.jsonz")
-@item Make separate libmgl-mpi
-@item Add SetAutoRanges() function (duplicate corresponding options)
-@item Add JSON sample usage via QtWebKit (thanks to DATADVANCE)
-@item Bugfixes and memory leaks
-@end itemize
-
-@item
-@strong{28 January 2013.}
-New version (v.2.1.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
-@itemize @bullet
-@item Exclude "local" functions from resulting library.
-@item String in MGL script now can be concatenated with another string or data/numbers (like @samp{'max(u)=',u.max,' a.u.'}).
-@item Bugfix for colors in 3D PDF.
-@item Bugfix for drawing in MPI mode.
-@item If Aspect() function have NAN argument(s) then it try to select optimal aspect ratio.
-@item Option 'size' in Legend() now change only text size (not mark size).
-@item Option 'meshnum' now influence on Boxs() and Belt() functions
-@item Adjust marks drawing (line width and dots).
-@item Minor improvements and bugfixes.
-@end itemize
-
-@item
-@strong{24 December 2012.}
-New version (v.2.1.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
-@itemize @bullet
-@item Bugfix for SetRange(val,val) function
-@item Exclude export MGL to CPP
-@item MGL parsing now produce errors for any wrong list of arguments
-@item Add help message to mgl.cgi
-@item Improve text rotation at View()
-@item Make compatible with GIF library v.5.0.
-@item Bugfix for making MPI interface.
-@item Bugfix for running in Win32 mode.
-@item Update docs and MGL samples
-@end itemize
-
-@item
-@strong{13 December 2012.}
-New version (v.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are speeding up and many improvements and bugfixes:
-@itemize @bullet
-@item
-Add class mglDataC for complex data arrays.
-@item
-Add Vect3() plot for drawing vectors on slice of 3d vector field. See @ref{Vect3 sample}.
-@item
-Add Table() function for drawing table with data values. See @ref{Table sample}.
-@item
-Add ZoomAxis() for zooming/shifting axis range as whole.
-@item
-Add WriteJSON() function for exporting in JSON format suitable for later drawing by JavaScript
-@item
-Add JavaScript code for visualizing JSON data. See @uref{../json.html, samples}.
-@item
-Add mgl.cgi tool which return PNG image for CGI request in form of MGL script.
-@item
-Add mglData::Solve() for finding x-value where dat(x)=val. See @ref{Solve sample}.
-@item
-Add mglData::Clean() for removing rows with duplicate values for given column.
-@item
-Add MGL commands 'errbox', 'face'
-
-@item
-Color can be specified as its RGB[A] values, i.e. like @samp{@{xFFFFFF@}} or @samp{@{xFFFFFFFF@}}. See @ref{Line styles}.
-@item
-Color in color scheme  may have position in range [0,1]. Format is @samp{@{CN,pos@}} or @samp{@{xFFFFFF,pos@}}. See @ref{Color scheme}.
-@item
-Now pen width for marks is proportional to pen width of line multiplied by size of marks.
-@item
-Now you can use different font-faces in the plot simultaneously. See @ref{Text features}.
-@item
-Now Legend() automatically use several columns if it contain too many legend entries.
-@item
-Add style '-' for legend for drawing them horizontally. See @ref{Legend sample}.
-@item
-Vectors is drawn now even if only starting or ending points are placed in bounding box.
-@item
-Strongly rewrite the algorithm of vector field plotting.
-
-@item
-Grid lines for NAN origin values are always located at far-away edges.
-@item
-Try correctly place axis and tick labels even for axis with inverse range (i.e. for v2<v1). Note, it work well for 2D axis. One should use Aspect() with negative values to do it correctly in general case.
-@item
-Axis style 'XYZ' draw corresponding axis with ticks labels on opposite side. This also influence on following Label() calls.
-@item
-Text is drawn for initially invisible axis (like z-axis) too.
-
-@item
-Frames now save 3D information if MGL_VECT_FRAME is set (by default).
-@item
-Add functions GetFrame(), DelFrame(), SetFrame(), ShowFrame() for replacing or showing data from given frame. It can be use to hide/show a set of plot(s) quickly. Work if MGL_VECT_FRAME is set on (by default is on).
-@item
-CalcXYZ() function now use data from z-buffer for better determining @{x,y,z@} coordinates.
-
-@item
-Add dialog for data arguments in "New command" dialog of UDAV. See @ref{UDAV dialogs}.
-@item
-Value of arguments are saved while the kind of command is changed in "New command" dialog of UDAV.
-@item
-Extend classification of commands in "New command" dialog of UDAV and make it automatic.
-@item
-Mouse position at an object click now is displayed on the image itself.
-@item
-Add zoom in/out by mouse wheel.
-@item
-Add zoom in/out of axis range by mouse wheel, and shift of axis range by middle button.
-@item
-Text editor in UDAV now highlight current line.
-@item
-Completer can be switched off correctly now.
-@item
-Multi-line strings (i.e. separated by "\" symbol) are highlighted correctly now.
-@item
-Add option to enable/disable selected plot in UDAV.
-@item
-Rearrange hot-keys in UDAV and in QMathGL.
-
-@item
-Make code compilable by Borland compiler too.
-@item
-Improve output in OpenGL mode.
-@item
-Add fog at export in EPS/SVG formats.
-@item
-Add mglParse::AllowFileIO() for enable/disable I/O commands in MGL scripts.
-
-@item
-Export functions now can write in stdout if file name is "-".
-@item
-Picture drawing now use multi-threading for each stage.
-
-@item
-Functions mglData::Spline*, mglData::Linear* now can return gradient at the point.
-@item
-mglFourier now make true inverse transform.
-
-@item
-Add annotation for all pure C functions.
-@item
-Update list of built-in glyphs.
-@item
-Update samples.
-@item
-Update documentation.
-@item
-Different bugfixes.
-
-@item
-@strong{INCOMPATIBLE CHANGES:} in the arguments of functions: mgl_axis, mgl_axis_grid, mgl_label, mgl_labelw, mgl_legend_pos, mgl_legend; and in functions for MGL parsing.
-@item
-@strong{MINOR INCOMPATIBLE:} plotting functions now use double argument always.
-@end itemize
-
-@item 
-@strong{23 August 2011.} Version 2.0.beta was released.
-@item 
-@strong{30 May 2011.} Version 1.11.2 was released.
-@item 
-@strong{8 November 2010.} Version 1.11 was released.
-@item 
-@strong{28 December 2009.} Version 1.10 was released.
-@item 
-@strong{8 July 2009.} Version 1.9 was released.
-@item 
-@strong{27 November 2008.} Version 1.8 was released.
-@item 
-@strong{5 June 2008.} Version 1.7 was released.
-@item 
-@strong{17 March 2008.} Version 1.6 was released.
-@item 
-@strong{11 January 2008.} Version 1.5 was released.
-@item 
-@strong{30 October 2007.} Version 1.4 was released.
-@item 
-@strong{15 October 2007.} Version 1.3 was released.
-@item 
-@strong{10 September 2007.} Version 1.2 was released.
-@item 
-@strong{23 May 2007.} Version 1.1 was released.
-@item 
-@strong{2 April 2007.} Version 1.0 was released.
-@item 
-@strong{24 January 2007.} First public release (v.0.8).
+@item @strong{8 May 2013.} Version 2.1.3.1 was released.
+@item @strong{2 May 2013.} Version 2.1.3 was released.
+@item @strong{28 January 2013.} Version 2.1.2 was released.
+@item @strong{24 December 2012.} Version 2.1.1 was released.
+@item @strong{13 December 2012.} Version 2.1 was released.
+@item @strong{23 August 2011.} Version 2.0.beta was released.
+@item @strong{30 May 2011.} Version 1.11.2 was released.
+@item @strong{8 November 2010.} Version 1.11 was released.
+@item @strong{28 December 2009.} Version 1.10 was released.
+@item @strong{8 July 2009.} Version 1.9 was released.
+@item @strong{27 November 2008.} Version 1.8 was released.
+@item @strong{5 June 2008.} Version 1.7 was released.
+@item @strong{17 March 2008.} Version 1.6 was released.
+@item @strong{11 January 2008.} Version 1.5 was released.
+@item @strong{30 October 2007.} Version 1.4 was released.
+@item @strong{15 October 2007.} Version 1.3 was released.
+@item @strong{10 September 2007.} Version 1.2 was released.
+@item @strong{23 May 2007.} Version 1.1 was released.
+@item @strong{2 April 2007.} Version 1.0 was released.
+@item @strong{24 January 2007.} First public release (v.0.8).
 @end itemize
 
 @external{}
index cc07e7e134f21b3e51a3e554c8c5ec22537bd2c5..9771dfa64cf9c2b5e74609d606cf564963209a2c 100644 (file)
@@ -52,12 +52,9 @@ Generally, MathGL is GPL library. However, you can use LGPL license for MathGL c
 
 @strong{Latest news}
 @itemize
-@item @emph{19 March 2014.}
-New version (v.2.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are compatibility changes for MS VisualStudio 2010 and early, and documentation update.
-@item @emph{10 March 2014.}
-New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are extend of 'region' plot, improve export to TeX, add missing Fortran functions, bugfixes, and other improvements, which denoted @ref{News, here}. Note, this release looks as bug free, but next release (v.2.3) will introduce a set of improvements which may not so stable at first time.
-@item @emph{22 January 2014.}
-New version (v.@value{VERSION}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are support of Qt5 and Pascal, improvements in JavaScript interface, bugfixes, and other improvements, which denoted @ref{News, here}.
+@item @emph{7 August 2014.}
+New version (v.@value{VERSION}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are many major improvements for both MathGL core and for UDAV, which denoted @ref{News, here}.
+@comment  New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are extend of 'region' plot, improve export to TeX, add missing Fortran functions, bugfixes, and other improvements, which denoted @ref{News, here}. Note, this release looks as bug free, but next release (v.2.3) will introduce a set of improvements which may not so stable at first time.
 @item @emph{11 November 2013.}
 New version (v.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are speeding up, new plot kinds and data handling functions, new plot styles, masks for bitmap output, wx-widget, Lua interface, and many other improvements, which denoted @ref{News, here}.
 @end itemize
@@ -78,9 +75,77 @@ Javascript interface was developed with support of @url{http://www.datadvance.ne
 @nav{}
 
 @itemize
-@item
-@strong{19 March 2014.}
-New version (v.2.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are compatibility changes for MS VisualStudio 2010 and early.
+@item @strong{7 August 2014.}
+New version (v.2.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are major improvements and speeding up of core MathGL and UDAV.
+@itemize @bullet
+@item Add background image, which allow in particular semi-transparent background color. Correspondingly add function @ref{rasterize} for saving current image as background, and function @ref{background} for loading background image from PNG or JPEG file.
+@item Add primitives to draw @ref{polygon} and angle @ref{arc}.
+@item Allow arbitrary factor for axis ticks (like, @code{gr->SetTicks('x',M_PI,0,NAN,"\\pi");} or @code{@ref{xtick} pi '\pi'}).
+@item Add function mglGraph::AddTick() for adding manual tick to the list of existed ones.
+
+@item Add new styles and symbols:
+@itemize
+@item arrow style @samp{X} (see @ref{Line styles});
+@item color gradient (color scheme) for text string (see @ref{Color scheme});
+@item manual dash style, like @samp{@{df090@}} (see @ref{Line styles});
+@item manual mask style, like @samp{@{s00ff00182424f800@}} (see @ref{Color scheme});
+@item styles @samp{fFE0123456789+-} for printing numbers in functions @ref{axis}, @ref{colorbar}, @ref{table}, @ref{label};
+@item style @samp{!} to disable ticks tuning in @ref{axis} and @ref{colorbar};
+@item style @samp{!} to draw @ref{grid} lines at subticks coordinates too;
+@item special symbol @samp{\b} which will be ignored at printing;
+@item calligraphic TeX symbols, like @samp{\calB}, @samp{\calE}, @samp{\calF}, @samp{\calH}, @samp{\calI}, @samp{\calL}, @samp{\calM}, @samp{\calR}, @samp{\ell}, @samp{\scrg}, @samp{\scro}.
+@end itemize
+
+@item Add @ref{ode} solving functions for textual formulas.
+@item Add function for global cubic spline interpolation, and function @ref{gspline} to refill data using global spline.
+
+@item Add functions @code{random(dat)} and @code{gamma_inc(a,x)} to the list of known functions for formula parsing
+@item Add @code{inf} variable to the MGL and formula parsing
+@item Allow reading JPEG files for @ref{import}.
+@item Function @ref{subdata} now can handle NULL argument(s). Add variants of @ref{subdata} with provided 1 and 2 arguments.
+
+@item Warning messages and information are printed to @code{stderr} until call of @code{mgl_suppress_warn(true);} will disable it.
+@item Add function @ref{version} to check if MathGL version is valid.
+
+@item Add move constructor(s) if compiler support C++11 rvalues.
+
+@item Changes in algorithms:
+@itemize
+@item Greatly increase speed of formula parsing (i.e. of functions @ref{modify}, @ref{fill} and similar), and speeding up many other places;
+@item Improve algorithm for contours drawing and filling, taking special attention to quasi-random data;
+@item Function @code{Spline()} now use 5-th order polynomials to keep continuity of 2nd derivative too;
+@item Add function attributes @code{pure} or @code{const}, which potentially can speed up drawing;
+@item Use spline instead of linear interpolation in functions @ref{flow} and @ref{pipe};
+@item Adjust @ref{columnplot} and @ref{gridplot} positions for non-zero distance between the inplots;
+@item Improve @ref{colorbar} labels drawing for the case of disabled label rotation;
+@item Choose new scales for @ref{perspective};
+@item Allow 'negative' angles for text rotation;
+@item Use new s-hull version for triangulation.
+@end itemize
+
+@item Add @code{ViewAsRotate()} function which handle arguments of @ref{view} by the same way as @ref{rotate} function, i.e @code{View(tetx,tetz,tety)} <=> @code{ViewAsRotate(-tetz,-tetx,-tety)}.
+@item Function @code{mglWindow::Adjust()} for Quality&4==0 now show image in widgets even if draw function is absent (i.e. =NULL).
+@item Make function mgl_get_curvs() to be exported. This function is used internally to connect line segments to a set of curves (in particular, for contour lines).
+
+@item Improvements in UDAV
+@itemize
+@item Rearrange tool buttons;
+@item Add features for manual dashing and manual mask in Style dialog;
+@item Add dialog for new dialog for new inplots (including @ref{subplot}, @ref{multiplot}, @ref{columnplot}, @ref{stickplot}, @ref{gridplot});
+@item Add option to use dots plot at image refreshing (for faster rotation etc);
+@item Add new primitives (@ref{arc}, @ref{polygon}, rotated @ref{text}) as mouse handled ones;
+@item Add close button to data tabs;
+@item Add button to stop script drawing and @code{stop()} slot for QMathGL;
+@item Allow to delete/hide/unhide selected plot;
+@item Allow to move selected plot between inplots;
+@item Improve NewCommand dialog. Now it replace the script command if user change arguments only;
+@item MGL commands @ref{perspective} and @ref{fog} now work correctly in UDAV;
+@item Update icons to use Oxygen ones.
+@end itemize
+@end itemize
+
+
+@item @strong{19 March 2014.}
 New version (v.2.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are compatibility changes for MS VisualStudio 2010 and early.
 @itemize @bullet
 @item Compatibility changes for MS VisualStudio 2010 and early.
@@ -89,8 +154,7 @@ New version (v.2.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL}
 @item Update documentation.
 @end itemize
 
-@item
-@strong{10 March 2014.}
+@item @strong{10 March 2014.}
 New version (v.2.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor improvements and bugfixes:
 @itemize @bullet
 @item Add mgl_region_3d() to draw region (or ribbon) between 2 curves. Correspondingly extend mglGraph::Region() function and MGL command 'region'.
@@ -101,8 +165,7 @@ New version (v.2.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} i
 @item Minor bugfixes and memory leaks.
 @end itemize
 
-@item
-@strong{22 January 2014.}
+@item @strong{22 January 2014.}
 New version (v.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor improvements and bugfixes:
 @itemize @bullet
 @item Add Qt5 support.
@@ -126,8 +189,7 @@ New version (v.2.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} i
 @item Other minor bugfixes and memory leaks.
 @end itemize
 
-@item
-@strong{11 November 2013.}
+@item @strong{11 November 2013.}
 New version (v.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
 @itemize @bullet
 @item Add OpenMP calls mostly everywhere (can work as replacement of pthreads - a bit faster since more loops is parallelized).
@@ -161,212 +223,26 @@ New version (v.2.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is
 @item Update docs.
 @end itemize
 
-@item
-@strong{8 May 2013.}
-New version (v.2.1.3.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
-@itemize @bullet
-@item Compatibility changes for MS VS.
-@item Bugfixes for cmake options @code{enable-double=OFF, enable-zlib=OFF}.
-@item Enable mouse actions for Firefox in JS sample.
-@end itemize
-
-@item
-@strong{2 May 2013.}
-New version (v.2.1.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
-@itemize @bullet
-@item Functions @ref{sinfft}, @ref{cosfft}, @ref{hankel} and so on, become multi-threaded.
-@item Use DFT instead of FFT if GSL support is disabled (much slow!).
-@item Add Join() function for joining mglData arrays (see @ref{join})
-@item Add Roots() function for root finding of nonlinear equation (see @ref{roots})
-@item Add class mglExprC for parsing formula with complex numbers (see @ref{Evaluate expression})
-@item Correctly read #QNAN values in data files
-@item Speed up @ref{dots} drawing
-@item Add flag to disable tick labels at axis origin (see SetOriginTick())
-@item Add MGL commands @ref{origintick}, @ref{tickshift}
-@item WriteJSON now use zlib if filename end at 'z' (like "test.jsonz")
-@item Make separate libmgl-mpi
-@item Add SetAutoRanges() function (duplicate corresponding options)
-@item Add JSON sample usage via QtWebKit (thanks to DATADVANCE)
-@item Bugfixes and memory leaks
-@end itemize
-
-@item
-@strong{28 January 2013.}
-New version (v.2.1.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
-@itemize @bullet
-@item Exclude "local" functions from resulting library.
-@item String in MGL script now can be concatenated with another string or data/numbers (like @samp{'max(u)=',u.max,' a.u.'}).
-@item Bugfix for colors in 3D PDF.
-@item Bugfix for drawing in MPI mode.
-@item If Aspect() function have NAN argument(s) then it try to select optimal aspect ratio.
-@item Option 'size' in Legend() now change only text size (not mark size).
-@item Option 'meshnum' now influence on Boxs() and Belt() functions
-@item Adjust marks drawing (line width and dots).
-@item Minor improvements and bugfixes.
-@end itemize
-
-@item
-@strong{24 December 2012.}
-New version (v.2.1.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor bugfixes and improvements:
-@itemize @bullet
-@item Bugfix for SetRange(val,val) function
-@item Exclude export MGL to CPP
-@item MGL parsing now produce errors for any wrong list of arguments
-@item Add help message to mgl.cgi
-@item Improve text rotation at View()
-@item Make compatible with GIF library v.5.0.
-@item Bugfix for making MPI interface.
-@item Bugfix for running in Win32 mode.
-@item Update docs and MGL samples
-@end itemize
-
-@item
-@strong{13 December 2012.}
-New version (v.2.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are speeding up and many improvements and bugfixes:
-@itemize @bullet
-@item
-Add class mglDataC for complex data arrays.
-@item
-Add Vect3() plot for drawing vectors on slice of 3d vector field. See @ref{Vect3 sample}.
-@item
-Add Table() function for drawing table with data values. See @ref{Table sample}.
-@item
-Add ZoomAxis() for zooming/shifting axis range as whole.
-@item
-Add WriteJSON() function for exporting in JSON format suitable for later drawing by JavaScript
-@item
-Add JavaScript code for visualizing JSON data. See @uref{../json.html, samples}.
-@item
-Add mgl.cgi tool which return PNG image for CGI request in form of MGL script.
-@item
-Add mglData::Solve() for finding x-value where dat(x)=val. See @ref{Solve sample}.
-@item
-Add mglData::Clean() for removing rows with duplicate values for given column.
-@item
-Add MGL commands 'errbox', 'face'
-
-@item
-Color can be specified as its RGB[A] values, i.e. like @samp{@{xFFFFFF@}} or @samp{@{xFFFFFFFF@}}. See @ref{Line styles}.
-@item
-Color in color scheme  may have position in range [0,1]. Format is @samp{@{CN,pos@}} or @samp{@{xFFFFFF,pos@}}. See @ref{Color scheme}.
-@item
-Now pen width for marks is proportional to pen width of line multiplied by size of marks.
-@item
-Now you can use different font-faces in the plot simultaneously. See @ref{Text features}.
-@item
-Now Legend() automatically use several columns if it contain too many legend entries.
-@item
-Add style '-' for legend for drawing them horizontally. See @ref{Legend sample}.
-@item
-Vectors is drawn now even if only starting or ending points are placed in bounding box.
-@item
-Strongly rewrite the algorithm of vector field plotting.
-
-@item
-Grid lines for NAN origin values are always located at far-away edges.
-@item
-Try correctly place axis and tick labels even for axis with inverse range (i.e. for v2<v1). Note, it work well for 2D axis. One should use Aspect() with negative values to do it correctly in general case.
-@item
-Axis style 'XYZ' draw corresponding axis with ticks labels on opposite side. This also influence on following Label() calls.
-@item
-Text is drawn for initially invisible axis (like z-axis) too.
-
-@item
-Frames now save 3D information if MGL_VECT_FRAME is set (by default).
-@item
-Add functions GetFrame(), DelFrame(), SetFrame(), ShowFrame() for replacing or showing data from given frame. It can be use to hide/show a set of plot(s) quickly. Work if MGL_VECT_FRAME is set on (by default is on).
-@item
-CalcXYZ() function now use data from z-buffer for better determining @{x,y,z@} coordinates.
-
-@item
-Add dialog for data arguments in "New command" dialog of UDAV. See @ref{UDAV dialogs}.
-@item
-Value of arguments are saved while the kind of command is changed in "New command" dialog of UDAV.
-@item
-Extend classification of commands in "New command" dialog of UDAV and make it automatic.
-@item
-Mouse position at an object click now is displayed on the image itself.
-@item
-Add zoom in/out by mouse wheel.
-@item
-Add zoom in/out of axis range by mouse wheel, and shift of axis range by middle button.
-@item
-Text editor in UDAV now highlight current line.
-@item
-Completer can be switched off correctly now.
-@item
-Multi-line strings (i.e. separated by "\" symbol) are highlighted correctly now.
-@item
-Add option to enable/disable selected plot in UDAV.
-@item
-Rearrange hot-keys in UDAV and in QMathGL.
-
-@item
-Make code compilable by Borland compiler too.
-@item
-Improve output in OpenGL mode.
-@item
-Add fog at export in EPS/SVG formats.
-@item
-Add mglParse::AllowFileIO() for enable/disable I/O commands in MGL scripts.
-
-@item
-Export functions now can write in stdout if file name is "-".
-@item
-Picture drawing now use multi-threading for each stage.
-
-@item
-Functions mglData::Spline*, mglData::Linear* now can return gradient at the point.
-@item
-mglFourier now make true inverse transform.
-
-@item
-Add annotation for all pure C functions.
-@item
-Update list of built-in glyphs.
-@item
-Update samples.
-@item
-Update documentation.
-@item
-Different bugfixes.
-
-@item
-@strong{INCOMPATIBLE CHANGES:} in the arguments of functions: mgl_axis, mgl_axis_grid, mgl_label, mgl_labelw, mgl_legend_pos, mgl_legend; and in functions for MGL parsing.
-@item
-@strong{MINOR INCOMPATIBLE:} plotting functions now use double argument always.
-@end itemize
-
-@item 
-@strong{23 August 2011.} Version 2.0.beta was released.
-@item 
-@strong{30 May 2011.} Version 1.11.2 was released.
-@item 
-@strong{8 November 2010.} Version 1.11 was released.
-@item 
-@strong{28 December 2009.} Version 1.10 was released.
-@item 
-@strong{8 July 2009.} Version 1.9 was released.
-@item 
-@strong{27 November 2008.} Version 1.8 was released.
-@item 
-@strong{5 June 2008.} Version 1.7 was released.
-@item 
-@strong{17 March 2008.} Version 1.6 was released.
-@item 
-@strong{11 January 2008.} Version 1.5 was released.
-@item 
-@strong{30 October 2007.} Version 1.4 was released.
-@item 
-@strong{15 October 2007.} Version 1.3 was released.
-@item 
-@strong{10 September 2007.} Version 1.2 was released.
-@item 
-@strong{23 May 2007.} Version 1.1 was released.
-@item 
-@strong{2 April 2007.} Version 1.0 was released.
-@item 
-@strong{24 January 2007.} First public release (v.0.8).
+@item @strong{8 May 2013.} Version 2.1.3.1 was released.
+@item @strong{2 May 2013.} Version 2.1.3 was released.
+@item @strong{28 January 2013.} Version 2.1.2 was released.
+@item @strong{24 December 2012.} Version 2.1.1 was released.
+@item @strong{13 December 2012.} Version 2.1 was released.
+@item @strong{23 August 2011.} Version 2.0.beta was released.
+@item @strong{30 May 2011.} Version 1.11.2 was released.
+@item @strong{8 November 2010.} Version 1.11 was released.
+@item @strong{28 December 2009.} Version 1.10 was released.
+@item @strong{8 July 2009.} Version 1.9 was released.
+@item @strong{27 November 2008.} Version 1.8 was released.
+@item @strong{5 June 2008.} Version 1.7 was released.
+@item @strong{17 March 2008.} Version 1.6 was released.
+@item @strong{11 January 2008.} Version 1.5 was released.
+@item @strong{30 October 2007.} Version 1.4 was released.
+@item @strong{15 October 2007.} Version 1.3 was released.
+@item @strong{10 September 2007.} Version 1.2 was released.
+@item @strong{23 May 2007.} Version 1.1 was released.
+@item @strong{2 April 2007.} Version 1.0 was released.
+@item @strong{24 January 2007.} First public release (v.0.8).
 @end itemize
 
 @external{}
index 8cc9bc9b6787b5daf0890a83171d0740cbbf7bf3..e4b155d5e647bc4409bac7ba0c7e498fb28b3459 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -1,95 +1,71 @@
-
-============= NEW FOR LATER =============
+-Wall -Wsuggest-attribute=pure -Wsuggest-attribute=const
+
+============= FAR FUTURE ================
+
+1. Graph(mreal x, mreal y, names, styles, font, size); -- names = "node1[node2,node3,node4[node5,node6]]", styles -- the same + apply for subnodes if absent. Styles are colors (fill,border,line), dash (to subnodes), marks "dos^v><", arrows.
+2. introduce new primitive type=5 -- arrow for Quality&3!=3. for better drawing in projections + json/view ?!?
+3. GTK window/widgets ???
+4. 2D textures as one of standard way for coloring -- if '%' present in color scheme
+5. Improve fplot, fsurf ???
+6. Get true coordinates in CalcXYZ for curved equations too.
+7. setLineDash in JSON
+8. add real(), imag(), conj() + accurate types in MGL + add 'complex' in MGL ???
+9. Inplot data should have ranges (add mglInPlot{x1,x2,y1,y2,Bp or something like this} which include mglMatrix instead of mglBase::Bp) + calc coor + JS
+10. Test mglDataC::Diffraction() + write sample + add rational function???
+11. Complex (hex) colors in inline text command (like #{b9} or #{x0000ff})
+12. Extra markers for '&' and '&#' signs ?!?
+13. Enable consecutive (as multiplication of matrices instead of single summary one) rotation of axis + the same in JS. Problem with widgets?!?
+14. Export background image to svg ???
+15. Frames by mouse in UDAV ???
+       A. мысли о frame??? для группы графиков -- не "удалять" их, а запихивать в отдельный кадр -- вопрос что с анимацией???
+       B. как делать анимацию (кадры) для мышиной версии ... список кадров, кнопки добавить в кадры + вставить из кадра
+16. Docs about mgl_datac_diffr
+17. Extend QO + extra docs
+
+ZZ. Update *.i for new functions {before release!!!}
+
+
+============= NEW FEATURES =============
 
 1. Export to COLLADA !!!
-2. GTK window/widgets ???
-3. Labels at TriCont()
-4. Rewrite glyph drawing for bitmaps (speeding up by excluding boundary checks) ?!?
+2. 3D text (with depth, for Quality=3)
+3. Text along 3D curve (for Quality=3)
+4. Check centered curved text (see text2)
 
-5. 2D textures as one of standard way for coloring -- if '%' present in color scheme
-6. Graph(mreal x, mreal y, names, styles, font, size); -- names = "node1[node2,node3,node4[node5,node6]]", styles -- the same + apply for subnodes if absent. Styles are colors (fill,border,line), dash (to subnodes), marks "dos^v><", arrows.
-7. 3D text (with depth, for Quality=3)
-8. Text along 3D curve (for Quality=3)
-9. introduce new primitive type=5 -- arrow for Quality&3!=3. for better drawing in projections + json/view ?!?
+5. Export to X3D
 
-10. New tests:
+6. New tests:
        c. Tests for mglDataC arrays (as separate flag)
        e. Test for Crop, Momentum, NormSl, Sew, DiffParam, Envelope, STFA for all directions "xyz"; Clean, Last, First, Find, Spline3, FindAny, Insert, Delete, Put, SetId/Column, Squeeze, Extend, Trace, Combine, new Max/Min/Momentum, FillSample, Hist, operators, Sort, Roots, Jacobian
        u. Test FlowP + 3d
 
-11. Check centered curved text (see text2)
-12. Export to X3D
-
-13. Inplot data should have ranges (add mglInPlot{x1,x2,y1,y2,Bp or something like this} which include mglMatrix instead of mglBase::Bp) + calc coor + JS
-14. 'perspective' command in UDAV
-15. Check octave 3.8
-16. Use mglFormulaCalc() for data transformation/filling (much faster but require more memory) + the same for complex
-17. Test mglDataC::Diffraction() + write sample + add rational function???
-
-18. Use mglStack<T> instead of std::vector<T> due to multi-threading
-19. Get true coordinates in CalcXYZ for curved equations too
-20. Add mglDataVar, mglDataCol, mglDataFunc for handling special (temporary) data + add real(), imag(), conj() + accurate types in MGL + add 'expr'/'complex' in MGL
-
-21. Check if Fortran versions possible for: mgl_data_info, mgl_datas_hdf, mgl_get_fit, mgl_get_mess, mgl_get_plotid
-22. Replace pthread by openmp in mgl_draw_thr() and similar
-23. Add function Rasterize() -- Finish() + clear points -- m.b. add background image for export, which will be cleared at Clf()???
-
 ============= DOCUMENTATION =============
 
 A. Paper about MathGL!!!
 B. Add chapter with real samples
 C. Translate to Russian everything
+D. Docs about JS interface
 
-1. Extend Dots sample (add A, CA, Tens)
-2. Extend Refill sample (add 2d)
-3. Docs about JS interface
-
-4. Extend docs about region
-5. Docs about mgl_datac_diffr
+YY. Sample like http://pyxplot.org.uk/examples/05ap/02hlines/index.html using Stem()
 
 ============= UDAV =============
 
-01. Show plot at creation stage (if option is enabled -- can be long process!!!) + auto axis range or [-1,1] by default
-
-02. Double click -> setup dialog (optionally -- after QTreeWidgetItem)
-
-03. Dialog for InPlot(s):
-{SubPlot,MultiPlot}    -- enable rotate,aspect,title
-{ColumnPlot}           -- enable rotate,several
-{StickPlot}            -- enable several
-{InPlot}                       -- enable rotate,aspect,title
-Image with gray alternatives and black choice
-
-04. QTreeWidgetItem -- ICON (func/call,if,for,once,subplot,...); annotation/name; (keep LINE - POS in script). After editing/changing --> put text to editor.
-Buttons: new,load,save // newcmd,hide,annotation,collapse on/off,setup // calc. Click on item cause change of line number in editor.
-05. Group/ungroup if command in single line, separated by ':'
-06. Hide plot/group by putting "#h " at beginning of line
-07. Annotation of plot/group -- comment before it
-08. Drag&drop plot/group between inplots (in tree widget)
-
-09. Create default plot dependently of selected row/column/range in data table
-10. Data change via menu/toolbar -- save to internal script => enable undo + save initial array(?)
-
-11. Speed up rotation like as done in JavaScript
-
-12. Multi-threading for enabling "stop".
-
-13. Manual rotate (i.e. change rotate arguments) by spinboxes ???
+2. Create default plot depending on selected row/column/range in data table ?!?
 
-14. Close button on data tabs ?!?
+3. Manual data changing should be written into script
+       a. Suggest to save into HDF5 if data changed manually
+       b. Each manual change in cell produce command like 'put dat val i j k'
+       c. Add command to insert as 'list'
+       d. Reset script after saving to HDF5 or putting to main script
+       e. Ask about script changes before closing data tab
 
-15. Add dialog for mask creation.
 
 ============= UNSURE ===========
 
-1. Problem with \calB and so on (\calH, ...) -- they are present only in italic font :(.
-2. create PWT fonts
-3. \dfrac for normal size and centering  (sample \big\big{\frac{1}{2}}) ???
-4. "Cut off" curves if text is printed inside it (for contour labels) ?!?
-5. String variables in MGL + readstr command.
-6. Pool of threads for speeding up ??? or openmp ???
-7. Read DICOM files
-8. Check RunThr() in python/octave
-9. Try libtcc (TinyCC) as alternative to MGL -- how to handle ^ operator???
-10. Auto axis range for formulas, like AutoRange("y(x)") or AutoRange('x',"x(t)").
-11. Use Hershey as built-in font ??? -- for smaller size only
+1. \dfrac for normal size and centering  (sample \big\big{\frac{1}{2}}) ???
+2. "Cut off" curves if text is printed inside it (for contour labels) ?!?
+3. String variables in MGL + readstr command.
+4. Read DICOM files
+5. Check RunThr() in python/octave
+6. Auto axis range for formulas, like AutoRange("y(x)") or AutoRange('x',"x(t)").
+7. Use Hershey as built-in font ??? -- for smaller size only
index ce0282028766cfe29a64bc205385975b69c76fbc..1abb7d0ee5c8d88db352f504f5c598896831ee4a 100644 (file)
@@ -4,11 +4,11 @@ if(enable-qt)
 set(udav_src anim_dlg.cpp find_dlg.cpp mem_pnl.cpp prop_dlg.cpp textedit.cpp args_dlg.cpp
        help_pnl.cpp newcmd_dlg.cpp text_pnl.cpp calc_dlg.cpp hint_dlg.cpp
        open_dlg.cpp qmglsyntax.cpp udav_wnd.cpp dat_pnl.cpp info_dlg.cpp opt_dlg.cpp setup_dlg.cpp
-       files_dlg.cpp plot_pnl.cpp style_dlg.cpp data_dlg.cpp tree_pnl.cpp)
+       files_dlg.cpp plot_pnl.cpp style_dlg.cpp data_dlg.cpp tree_pnl.cpp subplot_dlg.cpp )
 
 set(udav_moc_hdr anim_dlg.h files_dlg.h info_dlg.h opt_dlg.h text_pnl.h args_dlg.h
        find_dlg.h mem_pnl.h plot_pnl.h setup_dlg.h udav_wnd.h calc_dlg.h help_pnl.h newcmd_dlg.h
-       prop_dlg.h style_dlg.h dat_pnl.h open_dlg.h textedit.h hint_dlg.h data_dlg.h)
+       prop_dlg.h style_dlg.h dat_pnl.h open_dlg.h textedit.h hint_dlg.h data_dlg.h subplot_dlg.h )
 
 set(udav_rc udav.qrc)
 
index ca81add236810bc83eade4da089a9128b9afbe0f..9888ffd3509380e35e2f768defb6e4e598716709 100644 (file)
@@ -47,7 +47,7 @@ void addDataPanel(QWidget *wnd, QWidget *w, QString name);
 void deleteDat(void *o)                {       if(o)   delete ((DatPanel *)o); }
 void refreshData(QWidget *w)   {       ((DatPanel *)w)->refresh();     }
 //-----------------------------------------------------------------------------
-QWidget *newDataWnd(InfoDialog *inf, QWidget *wnd, mglVar *v)
+QWidget *newDataWnd(InfoDialog *inf, QWidget *wnd, mglDataA *v)
 {
        DatPanel *t = new DatPanel(inf);
        if(v)   t->setVar(v);
@@ -73,18 +73,19 @@ DatPanel::DatPanel(InfoDialog *inf, QWidget *parent) : QWidget(parent)
        setWindowIcon(QPixmap(table_xpm));
 }
 //-----------------------------------------------------------------------------
-DatPanel::~DatPanel()  {       if(var) var->o = 0;     }
+DatPanel::~DatPanel()  {       if(var && var->o==this) var->o = 0;     }
 //-----------------------------------------------------------------------------
 void DatPanel::refresh()
 {
        bool rc = false;
        if(!var)        return;
        infoDlg->allowRefresh=false;
-       if(nx!=var->nx) {       nx = var->nx;   tab->setColumnCount(nx);        rc=true;        }
-       if(ny!=var->ny) {       ny = var->ny;   tab->setRowCount(ny);   rc=true;        }
-       if(kz>=var->nz) {       kz = 0;                 emit sliceChanged(0);   }
-       if(nz!=var->ny) {       nz = var->nz;   emit nzChanged(nz);             }
-       id = QString(var->id.c_str());
+       if(nx!=var->GetNx())    {       nx = var->GetNx();      tab->setColumnCount(nx);        rc=true;        }
+       if(ny!=var->GetNy())    {       ny = var->GetNy();      tab->setRowCount(ny);   rc=true;        }
+       if(kz>=var->GetNz())    {       kz = 0; emit sliceChanged(0);   }
+       if(nz!=var->GetNz())    {       nz = var->GetNz();      emit nzChanged(nz);             }
+       const mglData *dd = dynamic_cast<const mglData *>(var); if(dd)  id = QString(dd->id.c_str());
+       const mglDataC *dc = dynamic_cast<const mglDataC *>(var);       if(dc)  id = QString(dc->id.c_str());
        if(nz==1 && ny>1 && !id.isEmpty())
        {
                QStringList head;
@@ -112,8 +113,9 @@ void DatPanel::refresh()
        }
        for(i=0;i<nx;i++)       for(j=0;j<ny;j++)
        {
-               f = var->GetVal(i,j,kz);
+               f = var->v(i,j,kz);
                if(mgl_isnan(f))        s = "nan";
+               else if(mgl_isbad(f))   s=f>0?"inf":"-inf";
                else    s.sprintf("%g",f);
                tab->item(j,i)->setText(s);
        }
@@ -125,7 +127,7 @@ void DatPanel::refresh()
        ready = true;
 }
 //-----------------------------------------------------------------------------
-void DatPanel::setVar(mglVar *v)
+void DatPanel::setVar(mglDataA *v)
 {
        ready = false;
        if(var) var->o = 0;
@@ -160,13 +162,18 @@ void DatPanel::putValue(int r, int c)
        if(!var || r<0 || c<0 || r>=ny || c>=nx || !ready)      return;
        QString s = tab->item(r,c)->text().toLower();
        mreal f;
-       f = s=="nan" ? NAN : s.toDouble();
-       if(f!=var->GetVal(c,r,kz))
+       if(s=="nan")    f=NAN;
+       else if(s=="inf")       f=INFINITY;
+       else if(s=="-inf")      f=-INFINITY;
+       else    f = s.toDouble();
+       if(f!=var->v(c,r,kz))
        {
-               if(mgl_isnan(f))        s="nan";        else    s.sprintf("%g", f);
+               if(mgl_isnan(f))        s="nan";
+               else if(mgl_isbad(f))   s=f>0?"inf":"-inf";
+               else    s.sprintf("%g", f);
                tab->item(r,c)->setText(s);
        }
-       var->SetVal(f,c,r,kz);
+       var->set_v(f,c,r,kz);
        infoDlg->refresh();
 }
 //-----------------------------------------------------------------------------
@@ -193,6 +200,7 @@ void DatPanel::save()
 //-----------------------------------------------------------------------------
 void DatPanel::load()
 {
+       mglData *d = dynamic_cast<mglData *>(var);      if(!d)  return;
        QString fn = QFileDialog::getOpenFileName(this, tr("UDAV - Load data"), "",
                                tr("Data files (*.dat)\nHDF5 files (*.h5 *.hdf)\nPNG files (*.png)\nAll files (*.*)"));
        if(fn.isEmpty())        return;
@@ -201,15 +209,15 @@ void DatPanel::load()
        {
                bool ok;
                QString s = QInputDialog::getText(this, tr("UDAV - Import PNG"), tr("Enter color scheme for picture"), QLineEdit::Normal, MGL_DEF_SCH, &ok);
-               if(ok)  var->Import(fn.toStdString().c_str(), s.toStdString().c_str());
+               if(ok)  d->Import(fn.toStdString().c_str(), s.toStdString().c_str());
        }
        else if(ext=="h5" || ext=="hdf")
        {
                bool ok;
                QString s = QInputDialog::getText(this, tr("UDAV - Read from HDF"), tr("Enter data name"), QLineEdit::Normal, QString::fromStdWString(var->s), &ok);
-               if(ok)  var->ReadHDF(fn.toStdString().c_str(), s.toStdString().c_str());
+               if(ok)  d->ReadHDF(fn.toStdString().c_str(), s.toStdString().c_str());
        }
-       else    var->Read(fn.toStdString().c_str());
+       else    d->Read(fn.toStdString().c_str());
        refresh();
 }
 //-----------------------------------------------------------------------------
@@ -243,7 +251,7 @@ void DatPanel::paste()
                {
                        t = s.section('\t',j,j,QString::SectionSkipEmpty);
                        if(t.isEmpty()) {       j=nx;   continue;       }
-                       var->SetVal(t.toDouble(),j+c,i+r,kz);
+                       var->set_v(t.toDouble(),j+c,i+r,kz);
                }
        }
        refresh();
@@ -278,7 +286,12 @@ void DatPanel::inrange()
        QString v1("-1"), v2("1"), dir("x");
        if(sizesDialog(tr("UDAV - Fill data"), tr("Enter range for data and direction of filling"), tr("From"), tr("To"), tr("Direction"), v1, v2, dir))
        {
-               var->Fill(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
+               mglData *d = dynamic_cast<mglData *>(var);
+               if(d)   d->Fill(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
+               mglDataC *dc = dynamic_cast<mglDataC *>(var);
+               if(dc)  dc->Fill(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
+               mglDataV *dv = dynamic_cast<mglDataV *>(var);
+               if(dv)  dv->Fill(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
                refresh();
        }
 }
@@ -288,7 +301,8 @@ void DatPanel::norm()
        QString v1("0"), v2("1"), how;
        if(sizesDialog(tr("UDAV - Normalize data"), tr("Enter range for final data"), tr("From"), tr("To"), tr("Symmetrical?"), v1, v2, how))
        {
-               var->Norm(v1.toDouble(), v2.toDouble(), (how=="on" || how.contains('s')));
+               mglData *d = dynamic_cast<mglData *>(var);
+               if(d)   d->Norm(v1.toDouble(), v2.toDouble(), (how=="on" || how.contains('s')));
                refresh();
        }
 }
@@ -298,7 +312,8 @@ void DatPanel::normsl()
        QString v1("0"), v2("1"), dir("z");
        if(sizesDialog(tr("UDAV - Normalize by slice"), tr("Enter range for final data"), tr("From"), tr("To"), tr("Direction"), v1, v2, dir))
        {
-               var->NormSl(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
+               mglData *d = dynamic_cast<mglData *>(var);
+               if(d)   d->NormSl(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
                refresh();
        }
 }
@@ -308,7 +323,10 @@ void DatPanel::create()
        QString mx, my("1"), mz("1");
        if(sizesDialog(tr("UDAV - Clear data"), tr("Enter new data sizes"), tr("X-size"), tr("Y-size"), tr("Z-size"), mx, my, mz))
        {
-               var->Create(mx.toInt(), my.toInt(), mz.toInt());
+               mglData *d = dynamic_cast<mglData *>(var);
+               if(d)   d->Create(mx.toInt(), my.toInt(), mz.toInt());
+               mglDataC *c = dynamic_cast<mglDataC *>(var);
+               if(c)   c->Create(mx.toInt(), my.toInt(), mz.toInt());
                refresh();      updateDataItems();
        }
 }
@@ -319,7 +337,8 @@ void DatPanel::reSize()
        mx.sprintf("%d",nx);    my.sprintf("%d",ny);    mz.sprintf("%d",nz);
        if(sizesDialog(tr("UDAV - Resize data"), tr("Enter new data sizes"), tr("X-size"), tr("Y-size"), tr("Z-size"), mx, my, mz))
        {
-               var->Set(var->Resize(mx.toInt(), my.toInt(), mz.toInt()));
+               mglData *d = dynamic_cast<mglData *>(var);
+               if(d)   d->Set(d->Resize(mx.toInt(), my.toInt(), mz.toInt()));
                refresh();      updateDataItems();
        }
 }
@@ -329,7 +348,8 @@ void DatPanel::squize()
        QString mx("1"), my("1"), mz("1");
        if(sizesDialog(tr("UDAV - Squeeze data"), tr("Enter step of saved points. For example, '1' save all, '2' save each 2nd point, '3' save each 3d and so on."), tr("X-direction"), tr("Y-direction"), tr("Z-direction"), mx, my, mz))
        {
-               var->Squeeze(mx.toInt(), my.toInt(), mz.toInt());
+               mglData *d = dynamic_cast<mglData *>(var);
+               if(d)   d->Squeeze(mx.toInt(), my.toInt(), mz.toInt());
                refresh();      updateDataItems();
        }
 }
@@ -339,7 +359,8 @@ void DatPanel::crop()
        QString n1("1"), n2("1"), dir;
        if(sizesDialog(tr("UDAV - Crop data"), tr("Enter range of saved date."), tr("From"), tr("To"), tr("Direction"), n1, n2, dir))
        {
-               var->Squeeze(n1.toInt(), n2.toInt(), dir[0].toLatin1());
+               mglData *d = dynamic_cast<mglData *>(var);
+               if(d)   d->Squeeze(n1.toInt(), n2.toInt(), dir[0].toLatin1());
                refresh();      updateDataItems();
        }
 }
@@ -350,7 +371,8 @@ void DatPanel::rearrange()
        mx.sprintf("%d",nx);    my.sprintf("%d",ny);    mz.sprintf("%d",nz);
        if(sizesDialog(tr("UDAV - Rearrange data"), tr("Enter new data sizes"), tr("X-size"), tr("Y-size"), tr("Z-size"), mx, my, mz))
        {
-               var->Rearrange(mx.toInt(), my.toInt(), mz.toInt());
+               mglData *d = dynamic_cast<mglData *>(var);
+               if(d)   d->Rearrange(mx.toInt(), my.toInt(), mz.toInt());
                refresh();      updateDataItems();
        }
 }
@@ -379,9 +401,8 @@ void DatPanel::hist()
        bool res = d->exec();
        if(res && !v1->text().isEmpty() && !v2->text().isEmpty() && !id->text().isEmpty())
        {
-               mglVar *vv = parser.AddVar(id->text().toStdString().c_str());
-               if(!vv) return;
-               vv->Set(var->Hist(nm->value(), v1->text().toDouble(), v2->text().toDouble()));
+               mglData *vv = parser.AddVar(id->text().toStdString().c_str());
+               vv->Set(mglData(true,mgl_data_hist(var, nm->value(), v1->text().toDouble(), v2->text().toDouble(),0)));
                updateDataItems();
        }
 }
@@ -435,14 +456,9 @@ bool DatPanel::sizesDialog(const QString &cap, const QString &lab, const QString
        return res;
 }
 //-----------------------------------------------------------------------------
-#include "xpm/plot.xpm"
 #include "xpm/size.xpm"
-//#include "xpm/smth.xpm"
 #include "xpm/crop.xpm"
 #include "xpm/squize.xpm"
-//#include "xpm/sum.xpm"
-//#include "xpm/func.xpm"
-//#include "xpm/swap.xpm"
 #include "xpm/hist.xpm"
 #include "xpm/oper_dir.xpm"
 #include "xpm/oper_of.xpm"
@@ -515,7 +531,7 @@ void DatPanel::newdat()
        {
                mglGraph gr;
                parser.Execute(&gr,mgl.toStdString().c_str());
-               opers += mgl+"\n";
+               if(k>=6)        opers += mgl+"\n";
                updateDataItems();
        }
 }
@@ -599,13 +615,13 @@ void DatPanel::toolTop(QBoxLayout *l)
 
        // file menu
        o = menu->addMenu(tr("File"));
-       a = new QAction(QPixmap(":/xpm/document-open.png"), tr("Load data"), this);
+       a = new QAction(QPixmap(":/png/document-open.png"), tr("Load data"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(load()));
        a->setToolTip(tr("Load data from file. Data will be deleted only\nat exit but UDAV will not ask to save it (Ctrl+Shift+O)."));
        a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_O);   o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/document-save.png"), tr("Save data"), this);
+       a = new QAction(QPixmap(":/png/document-save.png"), tr("Save data"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(save()));
        a->setToolTip(tr("Save data to a file (Ctrl+Shift+S)."));
        a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_S);   o->addAction(a);
@@ -618,19 +634,19 @@ void DatPanel::toolTop(QBoxLayout *l)
 //     bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
 
-       a = new QAction(QPixmap(plot_xpm), tr("Plot data"), this);
+       a = new QAction(QPixmap(":/png/office-chart-line.png"), tr("Plot data"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(plot()));
        a->setToolTip(tr("Plot data in new script window. You may select the kind\nof plot, its style and so on."));
        o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/edit-copy.png"), tr("Copy data"), this);
+       a = new QAction(QPixmap(":/png/edit-copy.png"), tr("Copy data"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(copy()));
        a->setToolTip(tr("Copy range of numbers to clipboard (Ctrl+Shift+C)."));
        a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_C);   o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/edit-paste.png"), tr("Paste data"), this);
+       a = new QAction(QPixmap(":/png/edit-paste.png"), tr("Paste data"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(copy()));
        a->setToolTip(tr("Paste range of numbers from clipboard (Ctrl+Shift+P)."));
        a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_V);   o->addAction(a);
@@ -638,13 +654,13 @@ void DatPanel::toolTop(QBoxLayout *l)
 
        // navigation menu
        o = menu->addMenu(tr("Navigate"));
-       a = new QAction(QPixmap(":/xpm/go-first.png"), tr("First slice"), this);
+       a = new QAction(QPixmap(":/png/go-first.png"), tr("First slice"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(first()));
        a->setToolTip(tr("Go to the first data slice for 3D data."));
        o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/go-previous.png"), tr("Prev. slice"), this);
+       a = new QAction(QPixmap(":/png/go-previous.png"), tr("Prev. slice"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(prev()));
        a->setToolTip(tr("Go to the previous data slice for 3D data."));
        o->addAction(a);
@@ -662,13 +678,13 @@ void DatPanel::toolTop(QBoxLayout *l)
        a->setToolTip(tr("Go to the specified data slice for 3D data."));
        o->addAction(a);
 
-       a = new QAction(QPixmap(":/xpm/go-next.png"), tr("Next slice"), this);
+       a = new QAction(QPixmap(":/png/go-next.png"), tr("Next slice"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(next()));
        a->setToolTip(tr("Go to the next data slice for 3D data."));
        o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/go-last.png"), tr("Last slice"), this);
+       a = new QAction(QPixmap(":/png/go-last.png"), tr("Last slice"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(last()));
        a->setToolTip(tr("Go to the last data slice for 3D data."));
        o->addAction(a);
@@ -683,7 +699,7 @@ void DatPanel::toolLeft(QBoxLayout *l)
 
        // size menu
        o = menu->addMenu(tr("Sizes"));
-       a = new QAction(QPixmap(":/xpm/document-new.png"), tr("Create new"), this);
+       a = new QAction(QPixmap(":/png/document-new.png"), tr("Create new"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(create()));
        a->setToolTip(tr("Recreate the data with new sizes and fill it by zeros (Ctrl+Shift+N)."));
        a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_N);   o->addAction(a);
@@ -725,7 +741,7 @@ void DatPanel::toolLeft(QBoxLayout *l)
        a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_H);   o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-/*     a = new QAction(QPixmap(":/xpm/view-refresh.png"), tr("Refresh"), this);
+/*     a = new QAction(QPixmap(":/png/view-refresh.png"), tr("Refresh"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(refresh()));
        a->setToolTip(tr("Refresh data values."));
        o->addAction(a);
@@ -749,6 +765,11 @@ void DatPanel::toolLeft(QBoxLayout *l)
        o->addAction(a);*/
 
        l->addStretch(1);
+
+       a = new QAction(QPixmap(":/png/tab-close.png"), tr("Close tab"), this);
+       connect(a, SIGNAL(triggered()), this, SLOT(close()));
+       a->setToolTip(tr("Close this data tab."));
+       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 }
 //-----------------------------------------------------------------------------
 QString DatPanel::dataName()   {       return QString::fromStdWString(var->s); }
index 28d444f1974d19c155aa009c7112215dd4d9a3a1..1ddd32ab64b83021f2b2ae8eaa80067b29cacc32 100644 (file)
@@ -22,7 +22,7 @@
 //-----------------------------------------------------------------------------
 #include <QWidget>
 //-----------------------------------------------------------------------------
-class mglVar;
+class mglDataA;
 class QMenu;
 class QBoxLayout;
 class QTableWidget;
@@ -39,7 +39,7 @@ public:
        DatPanel(InfoDialog *inf, QWidget *parent = 0);
        ~DatPanel();
 
-       void setVar(mglVar *v);
+       void setVar(mglDataA *v);
        inline long GetNz()     {       return nz;      }       ///< Get number of slices
        QString dataName();
 
@@ -87,10 +87,10 @@ private slots:
 private:
        int nx,ny,nz;   ///< Data sizes
        QString id;
-       QString opers;
+       QString opers;  ///< MGL script of all operations done on data
        QTableWidget *tab;      ///< Table itself
        int kz;                 ///< Current z-slice
-       mglVar *var;    ///< Variable with data
+       mglDataA *var;  ///< Variable with data
 //     QSpinBox *sb;   ///< SpinBox for selecting slice
        bool ready;             ///< Data is refreshed
        QSpinBox *sb;
index 379dfa1b90078947d8ba142eaeba3b03159cf7f0..3ad3c551599be96f483488de995f68348796a04d 100644 (file)
@@ -128,11 +128,12 @@ void DataDialog::updateRes()
 void DataDialog::updateNames()
 {
        name->clear();
-       mglVar *v = parser.FindVar("");
-       QString s;
-       while(v)
-       {       name->addItem(QString::fromStdWString(v->s));           v = v->next;            }
-       
+       long i, n = parser.GetNumVar();
+       for(i=0;i<n;i++)
+       {
+               const mglDataA *v = parser.GetVar(i);
+               if(v)   name->addItem(QString::fromStdWString(v->s));
+       }
 }
 //-----------------------------------------------------------------------------
 void DataDialog::userRes()
index ed5f9b142c2d5a8f195785c12f3d0370befff878..2ada16022c04ad2582ad0075d46f3fc681e0be72 100644 (file)
@@ -45,18 +45,18 @@ HelpPanel::HelpPanel(QWidget *parent) : QWidget(parent)
        help = new QTextBrowser(this);          o->addWidget(help);
        help->setOpenExternalLinks(false);
 
-       b = new QPushButton(QPixmap(":/xpm/go-previous.png"), tr("Backward"));
+       b = new QPushButton(QPixmap(":/png/go-previous.png"), tr("Backward"));
        connect(b, SIGNAL(clicked()), help, SLOT(backward()));  a->addWidget(b);
        entry = new QLineEdit(this);    a->addWidget(entry);
        connect(entry, SIGNAL(textChanged(const QString &)), this, SLOT(showHelp(const QString &)));
        connect(entry, SIGNAL(returnPressed()), this, SLOT(showHelp()));
-       b = new QPushButton(QPixmap(":/xpm/go-next.png"), tr("Forward"));
+       b = new QPushButton(QPixmap(":/png/go-next.png"), tr("Forward"));
        connect(b, SIGNAL(clicked()), help, SLOT(forward()));   a->addWidget(b);
-//     b = new QPushButton(QPixmap(":/xpm/help-faq.png"), tr("Examples"));
+//     b = new QPushButton(QPixmap(":/png/help-faq.png"), tr("Examples"));
 //     connect(b, SIGNAL(clicked()), this, SLOT(showExamples()));      a->addWidget(b);
-       t = new QToolButton(this);      t->setIcon(QPixmap(":/xpm/zoom-in.png"));
+       t = new QToolButton(this);      t->setIcon(QPixmap(":/png/zoom-in.png"));
        connect(t, SIGNAL(clicked()), this, SLOT(zoomIn()));    a->addWidget(t);
-       t = new QToolButton(this);      t->setIcon(QPixmap(":/xpm/zoom-out.png"));
+       t = new QToolButton(this);      t->setIcon(QPixmap(":/png/zoom-out.png"));
        connect(t, SIGNAL(clicked()), this, SLOT(zoomOut()));   a->addWidget(t);
        setWindowTitle(tr("Help"));
 }
index 9531bb46b4997bf78f5c4e73486e03e852cb24b8..528da56c8d88afdd216f4c46fb8ad25511164dee 100644 (file)
@@ -72,10 +72,10 @@ void InfoDialog::refresh(bool force)
        draw->text = text;      mgl->update();
 }
 //-----------------------------------------------------------------------------
-void InfoDialog::setVar(mglVar *v)
+void InfoDialog::setVar(mglDataA *v)
 {
        var=v;
-       if(v)   kind->setCurrentIndex(v->ny>1 ? 1:0);
+       if(v)   kind->setCurrentIndex(v->GetNy()>1 ? 1:0);
        refresh();
 }
 //-----------------------------------------------------------------------------
index 34113f00cd59314b6130710f7fda4b91378172a7..3389f5da159b16348a19516990277ca547b117fa 100644 (file)
@@ -25,7 +25,7 @@
 //-----------------------------------------------------------------------------
 class QMathGL;
 class mglDrawScript;
-class mglVar;
+class mglDataA;
 class QComboBox;
 class QTextEdit;
 //-----------------------------------------------------------------------------
@@ -36,7 +36,7 @@ Q_OBJECT
 public:
        InfoDialog(QWidget *parent = 0);
        virtual ~InfoDialog();
-       void setVar(mglVar *v);
+       void setVar(mglDataA *v);
        void setSlice(int k)    {       kz=k;   refresh();      }
        bool allowRefresh;
 //     void setName(QString &name);
@@ -47,7 +47,7 @@ public slots:
 
 private:
        int kz;
-       mglVar *var;
+       mglDataA *var;
        QMathGL *mgl;
        QTextEdit *info;
        QComboBox *kind;
index 113540db0cd7b3ec5c3d9b3cdf462b3ce42d9bb1..77dd3c16b1ec25b3968b879c9f0cc752be5a5b52 100644 (file)
@@ -32,7 +32,7 @@
 //-----------------------------------------------------------------------------
 extern bool mglAutoSave;
 extern mglParse parser;
-QWidget *newDataWnd(InfoDialog *inf, QWidget *wnd, mglVar *v);
+QWidget *newDataWnd(InfoDialog *inf, QWidget *wnd, mglDataA *v);
 void refreshData(QWidget *w);
 //-----------------------------------------------------------------------------
 QWidget *createMemPanel(QWidget *p)    // NOTE: parent should be MainWindow
@@ -57,23 +57,23 @@ MemPanel::MemPanel(QWidget *parent) : QWidget(parent)
        infoDlg->setModal(true);        infoDlg->allowRefresh=false;
 
        v = new QVBoxLayout(this);      h = new QHBoxLayout();  v->addLayout(h);
-       b = new QToolButton(this);      b->setIcon(QPixmap(":/xpm/document-new.png"));
+       b = new QToolButton(this);      b->setIcon(QPixmap(":/png/document-new.png"));
        b->setToolTip(tr("Create new data array"));             h->addWidget(b);
        connect(b, SIGNAL(clicked()), this, SLOT(newTable()));
        b = new QToolButton(this);      b->setIcon(QPixmap(table_xpm));
        b->setToolTip(tr("Edit selected data array"));  h->addWidget(b);
        connect(b, SIGNAL(clicked()), this, SLOT(editData()));
-       b = new QToolButton(this);      b->setIcon(QPixmap(":/xpm/edit-delete.png"));
+       b = new QToolButton(this);      b->setIcon(QPixmap(":/png/edit-delete.png"));
        b->setToolTip(tr("Delete selected data array"));                h->addWidget(b);
        connect(b, SIGNAL(clicked()), this, SLOT(delData()));
        b = new QToolButton(this);      b->setIcon(QPixmap(preview_xpm));
        b->setToolTip(tr("Properties of selected data array")); h->addWidget(b);
        connect(b, SIGNAL(clicked()), this, SLOT(infoData()));
-       b = new QToolButton(this);      b->setIcon(QPixmap(":/xpm/view-refresh.png"));
+       b = new QToolButton(this);      b->setIcon(QPixmap(":/png/view-refresh.png"));
        b->setToolTip(tr("Update list of data arrays"));                h->addWidget(b);
        connect(b, SIGNAL(clicked()), this, SLOT(refresh()));
        h->addStretch(1);
-       b = new QToolButton(this);      b->setIcon(QPixmap(":/xpm/edit-delete.png"));
+       b = new QToolButton(this);      b->setIcon(QPixmap(":/png/edit-clear.png"));
        b->setToolTip(tr("Delete ALL data arrays"));    h->addWidget(b);
        connect(b, SIGNAL(clicked()), this, SLOT(delAllData()));
 
@@ -98,7 +98,7 @@ void MemPanel::newTable()
        QString name = QInputDialog::getText(this, tr("UDAV - New variable"),
                                tr("Enter name for new variable"), QLineEdit::Normal, "", &ok);
        if(!ok || name.isEmpty())       return;
-       mglVar *v = parser.AddVar(name.toStdString().c_str());
+       mglData *v = parser.AddVar(name.toStdString().c_str());
        QWidget *t;
        if(v->o)        t = (QWidget *)v->o;
        else            t = newDataWnd(infoDlg,wnd,v);
@@ -111,7 +111,7 @@ void MemPanel::editData(int n)
        if(tab->rowCount()<1)   return;
        if(n<0) n = tab->currentRow();
        if(n<0) n = 0;
-       mglVar *v = parser.FindVar(tab->item(n,0)->text().toStdString().c_str());
+       mglDataA *v = parser.FindVar(tab->item(n,0)->text().toStdString().c_str());
        if(!v)  return;
        QWidget *t;
        if(v->o)        t = (QWidget *)v->o;
@@ -124,7 +124,7 @@ void MemPanel::delData()
        if(tab->rowCount()<1)   return;
        int     n = tab->currentRow();
        if(n<0) n = 0;
-       mglVar *v = parser.FindVar(tab->item(n,0)->text().toStdString().c_str());
+       mglDataA *v = parser.FindVar(tab->item(n,0)->text().toStdString().c_str());
        if(!v && v->o)  ((QWidget *)v->o)->close();
        parser.DeleteVar(tab->item(n,0)->text().toStdString().c_str());
        refresh();
@@ -143,7 +143,7 @@ void MemPanel::infoData()
        if(tab->rowCount()<1)   return;
        int     n = tab->currentRow();
        if(n<0) n = 0;
-       mglVar *v = parser.FindVar(tab->item(n,0)->text().toStdString().c_str());
+       mglDataA *v = parser.FindVar(tab->item(n,0)->text().toStdString().c_str());
        if(!v)  return;
        infoDlg->setVar(v);
        QString s = QString::fromStdWString(v->s);
@@ -154,29 +154,29 @@ void MemPanel::infoData()
 //-----------------------------------------------------------------------------
 void MemPanel::refresh()
 {
-       mglVar *v = parser.FindVar("");
-       int n = 0;
-       while(v)        {       v = v->next;    n++;    }
-       tab->setRowCount(n);
-       v = parser.FindVar(""); n = 0;
+       long n = parser.GetNumVar(), m=0;
+       for(long i=0;i<n;i++)   if(parser.GetVar(i))    m++;
+       tab->setRowCount(m);
        QString s;
        QTableWidgetItem *it;
        Qt::ItemFlags flags=Qt::ItemIsSelectable|Qt::ItemIsEnabled;
-       while(v)
+       for(long i=m=0;i<n;i++)
        {
+               mglDataA *v = parser.GetVar(i);
+               if(!v)  continue;
                s = QString::fromStdWString(v->s);
                it = new QTableWidgetItem(s);
-               tab->setItem(n,0,it);   it->setFlags(flags);
-               s.sprintf("%ld * %ld * %ld", v->nx, v->ny, v->nz);
+               tab->setItem(m,0,it);   it->setFlags(flags);
+               s.sprintf("%ld * %ld * %ld", v->GetNx(), v->GetNy(), v->GetNz());
                it = new QTableWidgetItem(s);
-               tab->setItem(n,1,it);   it->setFlags(flags);
+               tab->setItem(m,1,it);   it->setFlags(flags);
                it->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
-               s.sprintf("%12ld", v->nx*v->ny*v->nz*sizeof(mreal));
+               s.sprintf("%12ld", v->GetNN()*sizeof(mreal));
                it = new QTableWidgetItem(s);
-               tab->setItem(n,2,it);   it->setFlags(flags);
+               tab->setItem(m,2,it);   it->setFlags(flags);
                it->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
                if(v->o)        refreshData((QWidget *)v->o);
-               v = v->next;    n++;
+               m++;
        }
        tab->sortItems(colSort);
 }
index db393ed4d616d9fbd52a43d2a498ce9e3f865f83..4500fad3b9c3b9078f12717b9664539dcf6a51e9 100644 (file)
@@ -20,7 +20,6 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include <QWidget>
-class mglVar;
 class InfoDialog;
 class QTableWidget;
 //-----------------------------------------------------------------------------
index c1799e91887b0dcfcc68a63e35a338f85141e05a..3d1d24fc1a8c67763fedef9dbcffc3de3a2a23fd 100644 (file)
@@ -26,6 +26,7 @@
 #include <QMessageBox>
 #include <QTextBrowser>
 #include <QToolButton>
+#include <QFileDialog>
 #include <mgl2/mgl.h>
 
 #include "newcmd_dlg.h"
@@ -37,7 +38,7 @@ extern QString pathHelp;
 //-----------------------------------------------------------------------------
 NewCmdDialog::NewCmdDialog(QWidget *p) : QDialog(p,Qt::WindowStaysOnTopHint)
 {
-       fillList();
+       replace = false;
        QPushButton *b;
        QToolButton *t;
        QHBoxLayout *m = new QHBoxLayout(this), *a;
@@ -47,9 +48,10 @@ NewCmdDialog::NewCmdDialog(QWidget *p) : QDialog(p,Qt::WindowStaysOnTopHint)
        datDialog = new DataDialog(this);
        type = new QComboBox(this);             o->addWidget(type);
        type->setToolTip(tr("Groups of MGL commands"));
+       fillList();
        name = new QComboBox(this);             o->addWidget(name);
        name->setToolTip(tr("MGL commands for selected group"));
-       type->addItems(types);  name->addItems(argn[0]);
+       name->addItems(argn[0]);
        info = new QLabel(this);                o->addWidget(info);
        info->setToolTip(tr("Short description of selected command"));
        kind= new QComboBox(this);              o->addWidget(kind);     kind->addItem("");
@@ -67,16 +69,11 @@ NewCmdDialog::NewCmdDialog(QWidget *p) : QDialog(p,Qt::WindowStaysOnTopHint)
        connect(args,SIGNAL(cellDoubleClicked(int,int)), this, SLOT(insertData()));
 
        a = new QHBoxLayout;    o->addLayout(a);
-       b = new QPushButton(tr("Add style"),this);      a->addWidget(b);
-       b->setToolTip(tr("Here you can select the plot style.\nThe result will be placed in 'fmt' argument."));
-       connect(b, SIGNAL(clicked()),this,SLOT(insertStl()));
-       b = new QPushButton(tr("Add data"),this);       a->addWidget(b);
-       connect(b, SIGNAL(clicked()),this,SLOT(insertData()));
        b = new QPushButton(tr("Options"),this);        a->addWidget(b);
        b->setToolTip(tr("Here you can specify command options.\nOptions are used for additional plot tunning."));
        connect(b, SIGNAL(clicked()),this,SLOT(insertOpt()));
-       QLabel *l=new QLabel(tr("Options"));    o->addWidget(l);
-       opt = new QLineEdit(this);      o->addWidget(opt);
+       opt = new QLineEdit(this);      a->addWidget(opt);
+
        a = new QHBoxLayout;    o->addLayout(a);
        b = new QPushButton(tr("Cancel"),this); a->addWidget(b);
        connect(b, SIGNAL(clicked()), this, SLOT(reject()));
@@ -87,14 +84,14 @@ NewCmdDialog::NewCmdDialog(QWidget *p) : QDialog(p,Qt::WindowStaysOnTopHint)
        a = new QHBoxLayout;    o->addLayout(a);
        help = new QTextBrowser(this);          help->setMinimumWidth(500);
        help->setOpenExternalLinks(false);      o->addWidget(help);
-       t = new QToolButton(p); t->setIcon(QPixmap(":/xpm/go-previous.png"));
+       t = new QToolButton(p); t->setIcon(QPixmap(":/png/go-previous.png"));
        connect(t, SIGNAL(clicked()), help, SLOT(backward()));  a->addWidget(t);
-       t = new QToolButton(p); t->setIcon(QPixmap(":/xpm/go-next.png"));
+       t = new QToolButton(p); t->setIcon(QPixmap(":/png/go-next.png"));
        connect(t, SIGNAL(clicked()), help, SLOT(forward()));   a->addWidget(t);
        a->addStretch(1);
-       t = new QToolButton(p); t->setIcon(QPixmap(":/xpm/zoom-in.png"));
+       t = new QToolButton(p); t->setIcon(QPixmap(":/png/zoom-in.png"));
        connect(t, SIGNAL(clicked()), this, SLOT(zoomIn()));    a->addWidget(t);
-       t = new QToolButton(p); t->setIcon(QPixmap(":/xpm/zoom-out.png"));
+       t = new QToolButton(p); t->setIcon(QPixmap(":/png/zoom-out.png"));
        connect(t, SIGNAL(clicked()), this, SLOT(zoomOut()));   a->addWidget(t);
 
        connect(type, SIGNAL(currentIndexChanged(int)),this,SLOT(typeChanged(int)));
@@ -116,12 +113,13 @@ void NewCmdDialog::parseCmd(const QString &txt)
        QRegExp sep("[ \t]");
        QString cmd = str.section(sep,0,0),a,b;
        bool opt,var,chr;
+       replace = false;
        for(int i=0;i<17;i++)
        {
                if(cmds[i].contains(cmd))       // find command first
                {
                        typeChanged(i);
-                       nameChanged(cmds[i].indexOf(cmd));
+                       name->setCurrentIndex(cmds[i].indexOf(cmd));
                        register int j,j0,k,k0;
                        bool ok;
                        for(j0=k0=-1,j=0;j<NUM_CH;j++)          // determine set of arguments
@@ -141,22 +139,47 @@ void NewCmdDialog::parseCmd(const QString &txt)
                        }
                        if(j0>=0)       // best choice
                        {
-                               kindChanged(j0);
+                               kind->setCurrentIndex(j0);
                                for(k=0;k<argn[j0].count();k++)
                                        args->item(k,1)->setText(str.section(sep,k+1,k+1).trimmed());
                        }
-                       return;         // selection is done
+                       replace = true; return;         // selection is done
                }
        }
 }
 //-----------------------------------------------------------------------------
+#include "xpm/preview.xpm"
+#include "xpm/text.xpm"
+#include "xpm/table.xpm"
+#include "xpm/oper_dir.xpm"
+#include "xpm/axis.xpm"
+#include "xpm/axis_sh.xpm"
+#include "xpm/plot.xpm"
+#include "xpm/box.xpm"
+#include "xpm/curve.xpm"
+#include "xpm/other.xpm"
+#include "xpm/vect.xpm"
+#include "xpm/tiles.xpm"
+//-----------------------------------------------------------------------------
 void NewCmdDialog::fillList()
 {
-       types<<tr("1D plots")<<tr("2D plots")<<tr("3D plots")<<tr("Dual plots")
-                       <<tr("Vector plots")<<tr("Other plots")<<tr("Text and legend")
-                       <<tr("Create data and I/O")<<tr("Data transform")<<tr("Data handling")
-                       <<tr("Axis and colorbar")<<tr("Axis setup")<<tr("General setup")
-                       <<tr("Scale and rotate")<<tr("Program flow")<<tr("Primitives");
+       type->addItem(QPixmap(plot_xpm), tr("1D plots"));
+       type->addItem(QPixmap(preview_xpm), tr("2D plots"));
+       type->addItem(QPixmap(":/png/weather-clouds.png"), tr("3D plots"));
+       type->addItem(QPixmap(tiles_xpm), tr("Dual plots"));
+       type->addItem(QPixmap(vect_xpm), tr("Vector plots"));
+       type->addItem(QPixmap(other_xpm), tr("Other plots"));
+       type->addItem(QPixmap(text_xpm), tr("Text and legend"));
+       type->addItem(QPixmap(table_xpm), tr("Create data and I/O"));
+       type->addItem(QPixmap(oper_dir_xpm), tr("Data transform"));
+       type->addItem(QPixmap(oper_dir_xpm), tr("Data handling"));
+       type->addItem(QPixmap(axis_xpm), tr("Axis and colorbar"));
+       type->addItem(QPixmap(axis_sh_xpm), tr("Axis setup"));
+       type->addItem(QPixmap(":/png/preferences-system.png"), tr("General setup"));
+       type->addItem(QPixmap(box_xpm), tr("Scale and rotate"));
+       type->addItem(QPixmap(":/png/media-playback-start.png"), tr("Program flow"));
+       type->addItem(QPixmap(curve_xpm), tr("Primitives"));
+
        // now fill it automatically from parser for all categories
        long i, n = parser.GetCmdNum();
        for(i=0;i<n;i++)
@@ -241,8 +264,7 @@ void NewCmdDialog::nameChanged(int s)
                kinds<<n+" "+a;
                parse(argn[k],a);
        }
-       name->setCurrentIndex(s);
-       kind->addItems(kinds);  kind->setCurrentIndex(0);
+       kind->addItems(kinds);  kind->setCurrentIndex(0);       replace = false;
 }
 //-----------------------------------------------------------------------------
 void NewCmdDialog::kindChanged(int s)
@@ -291,7 +313,20 @@ void NewCmdDialog::insertData()
        {
                if(datDialog->exec())   args->item(row,1)->setText(datDialog->getData());
        }
-       else            QMessageBox::warning(this,tr("New command"), tr("This argument is not data"));
+       else if(a=="'fmt'" || a=="_'fmt'")
+       {
+               if(stlDialog->exec())   args->item(row,1)->setText(stlDialog->getStyle());
+       }
+       else if(a=="'file'")
+       {
+               QString str = QFileDialog::getOpenFileName(this, tr("UDAV - Insert filename"));
+               if(!str.isEmpty())      args->item(row,1)->setText(str);
+       }
+       else if(a=="'path'")
+       {
+               QString str = QFileDialog::getExistingDirectory(this, tr("UDAV - Insert path"));
+               if(!str.isEmpty())      args->item(row,1)->setText(str);
+       }
 }
 //-----------------------------------------------------------------------------
 void NewCmdDialog::insertStl()
@@ -308,8 +343,7 @@ void NewCmdDialog::insertStl()
        int i;
        i = argn[s].indexOf("'fmt'");
        if(i<0) i = argn[s].indexOf("_'fmt'");
-       if(!stlDialog->exec())  return;
-       args->item(i,1)->setText(stlDialog->getStyle());
+       if(!stlDialog->exec())  args->item(i,1)->setText(stlDialog->getStyle());
 }
 //-----------------------------------------------------------------------------
 void NewCmdDialog::finish()
@@ -352,6 +386,6 @@ void NewCmdDialog::finish()
                        cmd = cmd + ' ' + txt;
                }
        }
-       cmd = cmd + opt->text();        accept();       emit result(cmd);
+       cmd = cmd + opt->text();        accept();       emit result(cmd, replace);
 }
 //-----------------------------------------------------------------------------
index c8080e147d0aa813f398b6582b07be7b0fb79bd0..7c80d92b47e439f0f3bad434f982d592dc13beb1 100644 (file)
@@ -54,7 +54,7 @@ public slots:
        void parseCmd(const QString &txt);
 
 signals:
-       void result(const QString &txt);
+       void result(const QString &txt, bool replace);
 
 private:
        QTextBrowser *help;
@@ -67,6 +67,7 @@ private:
        OptionDialog *optDialog;
        StyleDialog *stlDialog;
        DataDialog *datDialog;
+       bool replace;   // flag to be used in result() signal
 
        void fillList();
 };
index 87b76e55033432f89ab9cf43d0d615f176847fae..443eca5318a2dc064245db8bd4319c1df32055d0 100644 (file)
@@ -115,8 +115,8 @@ void DataOpenDialog::prepareResult()
        code = "";      numDataOpened++;        data = name->text();
        // prepare unique value of name for next time
        char buf[32];   snprintf(buf,32,"mgl_%d",numDataOpened);        name->setText(buf);
-       mglVar *v = parser.AddVar(data.toStdString().c_str());
-       bool dd=0;
+       mglData *v = parser.AddVar(data.toStdString().c_str());
+       int dd=0;
        if(rA->isChecked())     //      auto sizes
        {
                setlocale(LC_NUMERIC, "C");     v->Read(file.toStdString().c_str());    setlocale(LC_NUMERIC, "");
index 18e661d8d46f23df206c58a2c9168c3f4ec07940..ad6c9dd98624c15cb6bbe28f00cc72f582ef04da 100644 (file)
 #include <QMenuBar>
 #include <QMessageBox>
 #include <QTextEdit>
+#include <QTextBlock>
 
 #include <QMdiArea>
+#include "udav_wnd.h"
 #include "mgl2/qmathgl.h"
 #include "plot_pnl.h"
 #include "anim_dlg.h"
 #include "style_dlg.h"
+#include "newcmd_dlg.h"
+#include "subplot_dlg.h"
+
 extern bool mglAutoSave;
 extern bool mglHighlight;
+extern bool mglDotsRefr;
 extern mglParse parser;
 int animDelay=500;
 void raisePanel(QWidget *w);
@@ -48,10 +54,14 @@ PlotPanel::PlotPanel(QWidget *parent) : QWidget(parent)
        gifOn = jpgOn = false;
        animDialog = new AnimParam(this);       animPos = -1;
        stlDialog = new StyleDialog(this);
-       printer = new QPrinter;         curPos = -1;
+       newCmdDlg = new NewCmdDialog(this);
+       subplotDlg = new SubplotDialog(this);
+       printer = new QPrinter;         curPos = subId = -1;
        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(next()));
        connect(animDialog, SIGNAL(putText(const QString &)), this, SLOT(animText(const QString &)));
+       connect(newCmdDlg, SIGNAL(result(const QString&, bool)), this, SLOT(putCmd(const QString&)));
+       connect(subplotDlg, SIGNAL(result(const QString&)), this, SLOT(insCmd(const QString&)));
 
        menu = new QMenu(tr("Graphics"),this);
        popup = new QMenu(this);
@@ -59,6 +69,7 @@ PlotPanel::PlotPanel(QWidget *parent) : QWidget(parent)
        draw = new mglDrawScript(parser.Self());
        mgl_set_flag(mgl->getGraph(),1,MGL_SHOW_POS);   mgl->setDraw(draw);
        connect(mgl,SIGNAL(askStyle(int)),this,SLOT(setStyle(int)));
+       connect(mgl,SIGNAL(objChanged(int)),this,SLOT(setCurPos(int)));
 
        QBoxLayout *v,*h,*m;
        v = new QVBoxLayout(this);
@@ -76,7 +87,9 @@ PlotPanel::~PlotPanel()       {       delete printer; }
 void PlotPanel::setStyle(int id)
 {      if(stlDialog->exec())   mgl->setStyle(id, stlDialog->getStyle());       }
 //-----------------------------------------------------------------------------
-void PlotPanel::animText(const QString &txt)           {       animPutText(txt);       }
+void PlotPanel::setSubId(int id)       {       subId = id;     }
+//-----------------------------------------------------------------------------
+void PlotPanel::animText(const QString &txt)   {       animPutText(txt);       }
 //-----------------------------------------------------------------------------
 void PlotPanel::setCurPos(int pos)
 {
@@ -89,7 +102,9 @@ void PlotPanel::stop()       {       parser.Stop();  mgl->stop();    }
 void PlotPanel::execute()
 {
        if(mglAutoSave) save();
+       mgl->setDotsPreview(mglDotsRefr);
        raisePanel(this);
+       objId = subId = -1;
        emit clearWarn();
        QTime t;        t.start();
        mgl_set_facenum(mgl->getGraph(),0);
@@ -256,7 +271,7 @@ void PlotPanel::animParseText(const QString &txt)
        }
 }
 //-----------------------------------------------------------------------------
-#include "xpm/wire.xpm"
+//#include "xpm/wire.xpm"
 #include "xpm/text.xpm"
 #include "xpm/line.xpm"
 #include "xpm/curve.xpm"
@@ -264,15 +279,18 @@ void PlotPanel::animParseText(const QString &txt)
 #include "xpm/mark_s.xpm"
 #include "xpm/mark_a.xpm"
 #include "xpm/mark_d.xpm"
+#include "xpm/arc.xpm"
+#include "xpm/polygon.xpm"
+#include "xpm/box.xpm"
 //-----------------------------------------------------------------------------
 void PlotPanel::toolTop(QBoxLayout *l)
 {
-       QAction *a;
+       QAction *a, *aa;
        QMenu *o=menu, *oo;
        QToolButton *bb;
 
        // graphics menu
-       a = new QAction(QPixmap(":/xpm/alpha.png"), tr("Alpha"), this);
+       a = new QAction(QPixmap(":/png/alpha.png"), tr("Alpha"), this);
        a->setShortcut(Qt::CTRL+Qt::Key_T);     a->setCheckable(true);
        connect(a, SIGNAL(toggled(bool)), mgl, SLOT(setAlpha(bool)));
        connect(mgl, SIGNAL(alphaChanged(bool)), a, SLOT(setChecked(bool)));
@@ -280,7 +298,7 @@ void PlotPanel::toolTop(QBoxLayout *l)
        o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/weather-clear.png"), tr("Light"), this);
+       a = new QAction(QPixmap(":/png/weather-clear.png"), tr("Light"), this);
        a->setShortcut(Qt::CTRL+Qt::Key_L);     a->setCheckable(true);
        connect(a, SIGNAL(toggled(bool)), mgl, SLOT(setLight(bool)));
        connect(mgl, SIGNAL(lightChanged(bool)), a, SLOT(setChecked(bool)));
@@ -288,21 +306,21 @@ void PlotPanel::toolTop(QBoxLayout *l)
        o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(wire_xpm), tr("Grid"), this);
+       a = new QAction(QPixmap(":/png/view-grid.png"), tr("Grid"), this);
        a->setShortcut(Qt::CTRL+Qt::Key_G);     a->setCheckable(true);
        connect(a, SIGNAL(toggled(bool)), mgl, SLOT(setGrid(bool)));
        a->setToolTip(tr("Switch on/off grid of absolute coordinates (Ctrl+G)."));
        o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/object-rotate-right.png"), tr("Rotate by mouse"), this);
+       a = new QAction(QPixmap(":/png/transform-move.png"), tr("Rotate by mouse"), this);
        a->setCheckable(true);
        connect(a, SIGNAL(toggled(bool)), mgl, SLOT(setRotate(bool)));
        connect(mgl, SIGNAL(rotateChanged(bool)), a, SLOT(setChecked(bool)));
        a->setToolTip(tr("Switch on/off mouse handling of the graphics\n(rotation, shifting, zooming and perspective)."));
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-/*     a = new QAction(QPixmap(":/xpm/zoom-fit-best.png"), tr("Zoom by mouse"), this);
+/*     a = new QAction(QPixmap(":/png/zoom-fit-best.png"), tr("Zoom by mouse"), this);
        a->setCheckable(true);
        connect(a, SIGNAL(toggled(bool)), mgl, SLOT(setZoom(bool)));
        connect(mgl, SIGNAL(zoomChanged(bool)), a, SLOT(setChecked(bool)));
@@ -310,91 +328,149 @@ void PlotPanel::toolTop(QBoxLayout *l)
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);*/
 
        o->addSeparator();
-       a = new QAction(QPixmap(":/xpm/zoom-original.png"), tr("Restore"), this);
+       a = new QAction(QPixmap(":/png/zoom-original.png"), tr("Restore"), this);
        connect(a, SIGNAL(triggered()), mgl, SLOT(restore()));
        a->setToolTip(tr("Restore default graphics rotation, zoom and perspective (Ctrl+Space)."));
        a->setShortcut(Qt::CTRL+Qt::Key_Space);
        o->addAction(a);        popup->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/view-refresh.png"), tr("Redraw"), this);
+       a = new QAction(QPixmap(":/png/view-refresh.png"), tr("Redraw"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(execute()));
        a->setToolTip(tr("Execute script and redraw graphics (F5)."));
        a->setShortcut(Qt::Key_F5);
        o->addAction(a);        popup->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(tr("Adjust size"), this);
+       a = new QAction(QPixmap(":/png/view-fullscreen.png"), tr("Adjust size"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(adjust()));
        a->setToolTip(tr("Change canvas size to fill whole region (F6)."));
        a->setShortcut(Qt::Key_F6);             o->addAction(a);
 
-       a = new QAction(tr("Reload"), this);
+       a = new QAction(QPixmap(":/png/document-revert.png"), tr("Reload"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(pressF9()));
        a->setToolTip(tr("Restore status for 'once' command and reload data (F9)."));
        a->setShortcut(Qt::Key_F9);     o->addAction(a);        popup->addAction(a);
 
-       a = new QAction(QPixmap(":/xpm/process-stop.png"), tr("Stop"), this);
+       a = new QAction(QPixmap(":/png/process-stop.png"), tr("Stop"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(stop()));
        a->setToolTip(tr("Stop script execution (F7)."));
        a->setShortcut(Qt::Key_F7);     o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/edit-copy.png"), tr("Copy plot"), this);
+       a = new QAction(QPixmap(":/png/edit-copy.png"), tr("Copy plot"), this);
        connect(a, SIGNAL(triggered()), mgl, SLOT(copy()));
        a->setToolTip(tr("Copy graphics to clipboard (Ctrl+Shift+G)."));
        a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_G);
        o->addAction(a);        popup->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/edit-copy.png"), tr("Copy click coor."), this);
+       a = new QAction(QPixmap(":/png/edit-copy.png"), tr("Copy click coor."), this);
        connect(a, SIGNAL(triggered()), mgl, SLOT(copyClickCoor()));
        a->setToolTip(tr("Copy coordinates of last mouse click to clipboard."));
        o->addAction(a);        popup->addAction(a);
 
-       l->addStretch(1);
-       oo = new QMenu(tr("Primitives ..."),this);
-       a = new QAction(QPixmap(line_xpm), tr("Add line"), this);
-       connect(a, SIGNAL(triggered()), mgl, SLOT(addLine()));
-       connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
-       a->setToolTip(tr("Add line which properties can be changed later by mouse."));
-       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);        oo->addAction(a);
-
-       a = new QAction(QPixmap(curve_xpm), tr("Add curve"), this);
-       connect(a, SIGNAL(triggered()), mgl, SLOT(addCurve()));
-       connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
-       a->setToolTip(tr("Add curve which properties can be changed later by mouse."));
-       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);        oo->addAction(a);
-
-       a = new QAction(QPixmap(mark_s_xpm), tr("Add rect"), this);
-       connect(a, SIGNAL(triggered()), mgl, SLOT(addRect()));
-       connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
-       a->setToolTip(tr("Add rectangle which properties can be changed later by mouse."));
-       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);        oo->addAction(a);
-
-       a = new QAction(QPixmap(mark_d_xpm), tr("Add rhombus"), this);
-       connect(a, SIGNAL(triggered()), mgl, SLOT(addRhomb()));
-       connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
-       a->setToolTip(tr("Add rhombus which properties can be changed later by mouse."));
-       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);        oo->addAction(a);
-
-       a = new QAction(QPixmap(mark_o_xpm), tr("Add ellipse"), this);
-       connect(a, SIGNAL(triggered()), mgl, SLOT(addEllipse()));
-       connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
-       a->setToolTip(tr("Add ellipse which properties can be changed later by mouse."));
-       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);        oo->addAction(a);
-
-       a = new QAction(QPixmap(mark_a_xpm), tr("Add mark"), this);
-       connect(a, SIGNAL(triggered()), mgl, SLOT(addMark()));
-       connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
-       a->setToolTip(tr("Add marker which properties can be changed later by mouse."));
-       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);        oo->addAction(a);
-
-       a = new QAction(QPixmap(text_xpm), tr("Add text"), this);
-       connect(a, SIGNAL(triggered()), mgl, SLOT(addText()));
-       connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
-       a->setToolTip(tr("Add text which properties can be changed later by mouse."));
-       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);        oo->addAction(a);
+//     l->addStretch(1);
+       {
+               oo = new QMenu(tr("Primitives ..."),this);
+               aa=a = new QAction(QPixmap(line_xpm), tr("Add line"), this);
+               connect(a, SIGNAL(triggered()), mgl, SLOT(addLine()));
+               connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(tr("Add line which properties can be changed later by mouse."));
+               oo->addAction(a);
+
+               a = new QAction(QPixmap(arc_xpm), tr("Add arc"), this);
+               connect(a, SIGNAL(triggered()), mgl, SLOT(addArc()));
+               connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(tr("Add arc which properties can be changed later by mouse."));
+               oo->addAction(a);
+
+               a = new QAction(QPixmap(curve_xpm), tr("Add curve"), this);
+               connect(a, SIGNAL(triggered()), mgl, SLOT(addCurve()));
+               connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(tr("Add curve which properties can be changed later by mouse."));
+               oo->addAction(a);
+
+               a = new QAction(QPixmap(mark_s_xpm), tr("Add rect"), this);
+               connect(a, SIGNAL(triggered()), mgl, SLOT(addRect()));
+               connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(tr("Add rectangle which properties can be changed later by mouse."));
+               oo->addAction(a);
+
+               a = new QAction(QPixmap(mark_d_xpm), tr("Add rhombus"), this);
+               connect(a, SIGNAL(triggered()), mgl, SLOT(addRhomb()));
+               connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(tr("Add rhombus which properties can be changed later by mouse."));
+               oo->addAction(a);
+
+               a = new QAction(QPixmap(mark_o_xpm), tr("Add ellipse"), this);
+               connect(a, SIGNAL(triggered()), mgl, SLOT(addEllipse()));
+               connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(tr("Add ellipse which properties can be changed later by mouse."));
+               oo->addAction(a);
+
+               a = new QAction(QPixmap(polygon_xpm), tr("Add polygon"), this);
+               connect(a, SIGNAL(triggered()), mgl, SLOT(addPolygon()));
+               connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(tr("Add ellipse which properties can be changed later by mouse."));
+               oo->addAction(a);
+
+               a = new QAction(QPixmap(mark_a_xpm), tr("Add mark"), this);
+               connect(a, SIGNAL(triggered()), mgl, SLOT(addMark()));
+               connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(tr("Add marker which properties can be changed later by mouse."));
+               oo->addAction(a);
+
+               a = new QAction(QPixmap(text_xpm), tr("Add text"), this);
+               connect(a, SIGNAL(triggered()), mgl, SLOT(addText()));
+               connect(mgl, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(tr("Add text which properties can be changed later by mouse."));
+               oo->addAction(a);
+
+               bb = new QToolButton(this);     l->addWidget(bb);
+               bb->setDefaultAction(aa);       bb->setMenu(oo);
+               bb->setPopupMode(QToolButton::MenuButtonPopup);
+       }
+
+       a = new QAction(QPixmap(":/png/edit-delete.png"), tr("Delete selected"), this);
+       connect(a, SIGNAL(triggered()), this, SLOT(deleteSelected()));
+       a->setToolTip(tr("Delete selected plot."));
+       o->addAction(a);        popup->addAction(a);
+       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
+
+       a = new QAction(QPixmap(":/png/layer-visible-off.png"), tr("Hide selected"), this);
+       connect(a, SIGNAL(triggered()), this, SLOT(hideSelected()));
+       a->setToolTip(tr("Hide selected plot."));
+       o->addAction(a);        popup->addAction(a);
+       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
+
+       const MainWindow *mw=findMain(this);
+       if(mw)  {       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(mw->ahide);        }
+
+       a = new QAction(QPixmap(":/png/format-indent-more.png"), tr("New command"), this);
+       connect(a, SIGNAL(triggered()), newCmdDlg, SLOT(show()));
+       a->setToolTip(tr("Show dialog for new command and put it into the script."));
+       o->addAction(a);        popup->addAction(a);
+       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
+
+       a = new QAction(QPixmap(box_xpm), tr("New inplot"), this);
+       connect(a, SIGNAL(triggered()), subplotDlg, SLOT(show()));
+       a->setToolTip(tr("Show dialog for new inplot and put it into the script."));
+       o->addAction(a);        popup->addAction(a);
+       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
+
+       a = new QAction(QPixmap(":/png/object-order-lower.png"), tr("Move plot up"), this);
+       connect(a, SIGNAL(triggered()), this, SLOT(movePlotUp()));
+       a->setToolTip(tr("Move selected plot up to previous subplot."));
+       o->addAction(a);        popup->addAction(a);
+       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
+
+       a = new QAction(QPixmap(":/png/object-order-raise.png"), tr("Move plot down"), this);
+       connect(a, SIGNAL(triggered()), this, SLOT(movePlotDown()));
+       a->setToolTip(tr("Move selected plot down to next subplot."));
+       o->addAction(a);        popup->addAction(a);
+       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
+
 
        o->addMenu(oo); l->addStretch(1);
 
@@ -438,42 +514,42 @@ void PlotPanel::toolLeft(QBoxLayout *l)
 
        // zooming menu
        oo = o->addMenu(tr("Zoom/move"));
-       a = new QAction(QPixmap(":/xpm/go-previous.png"), tr("Move left"), this);
+       a = new QAction(QPixmap(":/png/arrow-left.png"), tr("Move left"), this);
        connect(a, SIGNAL(triggered()), mgl, SLOT(shiftLeft()));
        a->setShortcut(Qt::ALT+Qt::Key_Left);
        a->setToolTip(tr("Move graphics left by 1/3 of its width."));
        oo->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/go-up.png"), tr("Move up"), this);
+       a = new QAction(QPixmap(":/png/arrow-up.png"), tr("Move up"), this);
        connect(a, SIGNAL(triggered()), mgl, SLOT(shiftUp()));
        a->setShortcut(Qt::ALT+Qt::Key_Up);
        a->setToolTip(tr("Move graphics up by 1/3 of its height."));
        oo->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/zoom-in.png"), tr("Zoom in"), this);
+       a = new QAction(QPixmap(":/png/zoom-in.png"), tr("Zoom in"), this);
        connect(a, SIGNAL(triggered()), mgl, SLOT(zoomIn()));
        a->setShortcut(Qt::ALT+Qt::Key_Equal);
        a->setToolTip(tr("Zoom in graphics."));
        oo->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/zoom-out.png"), tr("Zoom out"), this);
+       a = new QAction(QPixmap(":/png/zoom-out.png"), tr("Zoom out"), this);
        connect(a, SIGNAL(triggered()), mgl, SLOT(zoomOut()));
        a->setShortcut(Qt::ALT+Qt::Key_Minus);
        a->setToolTip(tr("Zoom out graphics."));
        oo->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/go-down.png"), tr("Move down"), this);
+       a = new QAction(QPixmap(":/png/arrow-down.png"), tr("Move down"), this);
        connect(a, SIGNAL(triggered()), mgl, SLOT(shiftDown()));
        a->setShortcut(Qt::ALT+Qt::Key_Down);
        a->setToolTip(tr("Move graphics up down 1/3 of its height."));
        oo->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/go-next.png"), tr("Move right"), this);
+       a = new QAction(QPixmap(":/png/arrow-right.png"), tr("Move right"), this);
        connect(a, SIGNAL(triggered()), mgl, SLOT(shiftRight()));
        a->setShortcut(Qt::ALT+Qt::Key_Right);
        a->setToolTip(tr("Move graphics right by 1/3 of its width."));
@@ -482,38 +558,32 @@ void PlotPanel::toolLeft(QBoxLayout *l)
 
        // rotate menu
        oo = o->addMenu(tr("Rotate"));
-       a = new QAction(tr("Rotate up"), this);
+       a = new QAction(QPixmap(":/png/object-rotate-up.png"), tr("Rotate up"), this);
        a->setShortcut(Qt::SHIFT+Qt::META+Qt::Key_Up);
        connect(a, SIGNAL(triggered()), tet, SLOT(stepUp()));   oo->addAction(a);
        a->setToolTip(tr("Increase \\theta angle by 10 degrees."));
-       a = new QAction(tr("Rotate down"), this);
+       a = new QAction(QPixmap(":/png/object-rotate-down.png"), tr("Rotate down"), this);
        a->setShortcut(Qt::SHIFT+Qt::META+Qt::Key_Down);
        connect(a, SIGNAL(triggered()), tet, SLOT(stepDown())); oo->addAction(a);
        a->setToolTip(tr("Decrease \\theta angle by 10 degrees."));
-       a = new QAction(tr("Rotate left"), this);
+       a = new QAction(QPixmap(":/png/object-rotate-left.png"), tr("Rotate left"), this);
        a->setShortcut(Qt::SHIFT+Qt::META+Qt::Key_Right);
        connect(a, SIGNAL(triggered()), phi, SLOT(stepUp()));   oo->addAction(a);
        a->setToolTip(tr("Increase \\phi angle by 10 degrees."));
-       a = new QAction(tr("Rotate right"), this);
+       a = new QAction(QPixmap(":/png/object-rotate-right.png"), tr("Rotate right"), this);
        a->setShortcut(Qt::SHIFT+Qt::META+Qt::Key_Left);
        connect(a, SIGNAL(triggered()), phi, SLOT(stepDown())); oo->addAction(a);
        a->setToolTip(tr("Decrease \\phi angle by 10 degrees."));
 
        // animation menu
        oo = o->addMenu(tr("Animation"));
-       a = new QAction(QPixmap(":/xpm/media-seek-forward.png"), tr("Next slide"), this);
+       a = new QAction(QPixmap(":/png/media-seek-forward.png"), tr("Next slide"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(nextSlide()));
        a->setShortcut(Qt::CTRL+Qt::Key_Period);
        a->setToolTip(tr("Show next slide (Ctrl+.).")); oo->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/media-seek-backward.png"), tr("Prev slide"), this);
-       connect(a, SIGNAL(triggered()), this, SLOT(prevSlide()));
-       a->setShortcut(Qt::CTRL+Qt::Key_Comma);
-       a->setToolTip(tr("Show previous slide (Ctrl+,)."));     oo->addAction(a);
-       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
-
-       a = new QAction(QPixmap(":/xpm/film-b.png"), tr("Slideshow"), this);
+       a = new QAction(QPixmap(":/png/media-playback-start.png"), tr("Slideshow"), this);
        a->setCheckable(true);
        connect(a, SIGNAL(toggled(bool)), this, SLOT(animStart(bool)));
        connect(this, SIGNAL(animSwitch(bool)),a,SLOT(setChecked(bool)));
@@ -522,8 +592,117 @@ void PlotPanel::toolLeft(QBoxLayout *l)
        oo->addAction(tr("Setup show"), this, SLOT(animSetup()), Qt::CTRL+Qt::Key_W);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
+       a = new QAction(QPixmap(":/png/media-seek-backward.png"), tr("Prev slide"), this);
+       connect(a, SIGNAL(triggered()), this, SLOT(prevSlide()));
+       a->setShortcut(Qt::CTRL+Qt::Key_Comma);
+       a->setToolTip(tr("Show previous slide (Ctrl+,)."));     oo->addAction(a);
+       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
+
        l->addStretch(1);
 }
 //-----------------------------------------------------------------------------
 QString PlotPanel::getFit()    {       return QString(mgl_get_fit(mgl->getGraph()));   }
 //-----------------------------------------------------------------------------
+void PlotPanel::deleteSelected()
+{
+       if(curPos>=0)
+       {
+               textMGL->moveCursor(QTextCursor::Start);
+               for(int i=0;i<curPos;i++)       textMGL->moveCursor(QTextCursor::NextBlock);
+               QTextCursor tc= textMGL->textCursor();
+               tc.select(QTextCursor::LineUnderCursor);
+               tc.removeSelectedText();
+               tc.deleteChar();
+               curPos = -1;    execute();
+       }
+       else emit setStatus("No selection.");
+}
+//-----------------------------------------------------------------------------
+void PlotPanel::hideSelected()
+{
+       if(curPos>=0)
+       {
+               textMGL->moveCursor(QTextCursor::Start);
+               for(int i=0;i<curPos;i++)       textMGL->moveCursor(QTextCursor::NextBlock);
+               textMGL->insertPlainText("#h ");
+               curPos = -1;    execute();
+       }
+       else emit setStatus("No selection.");
+}
+//-----------------------------------------------------------------------------
+void PlotPanel::putCmd(const QString &cmd)
+{
+       textMGL->moveCursor(QTextCursor::Start);
+       if(curPos>=0)   for(int i=0;i<curPos;i++)
+               textMGL->moveCursor(QTextCursor::NextBlock);
+       textMGL->insertPlainText(cmd+"\n");
+       curPos = -1;    execute();
+}
+//-----------------------------------------------------------------------------
+void PlotPanel::insCmd(const QString &cmd)
+{
+       textMGL->moveCursor(QTextCursor::EndOfBlock);
+       textMGL->insertPlainText("\n"+cmd);
+       curPos = -1;    execute();
+}
+//-----------------------------------------------------------------------------
+void PlotPanel::movePlotUp()
+{
+       if(curPos>0)
+       {
+               QTextCursor tc = textMGL->textCursor();
+               tc.movePosition(QTextCursor::Start);
+               tc.movePosition(QTextCursor::NextBlock,QTextCursor::MoveAnchor,curPos);
+               tc.select(QTextCursor::BlockUnderCursor);
+               QString s = tc.selectedText();
+               tc.deleteChar();
+               bool ins=true;
+
+               while(tc.movePosition(QTextCursor::PreviousBlock))
+               {
+                       QString q = tc.block().text();
+                       if(q.startsWith("subplot ") || q.startsWith("inplot ") || q.startsWith("multiplot ") || q.startsWith("gridplot ") || q.startsWith("columnplot ") || q.startsWith("stickplot "))
+                       {
+                               tc.movePosition(QTextCursor::EndOfBlock);
+                               tc.insertText(s);       ins=false;      break;
+                       }
+               }
+               if(ins)
+               {
+                       tc.movePosition(QTextCursor::Start);    tc.insertText(s+"\n");
+                       tc.movePosition(QTextCursor::Start);    tc.deleteChar();
+               }
+               curPos = tc.block().blockNumber();      execute();
+       }
+       else if(curPos<0)       emit setStatus("No selection.");
+}
+//-----------------------------------------------------------------------------
+void PlotPanel::movePlotDown()
+{
+       if(curPos>=0)
+       {
+               QTextCursor tc = textMGL->textCursor();
+               tc.movePosition(QTextCursor::Start);
+               tc.movePosition(QTextCursor::NextBlock,QTextCursor::MoveAnchor,curPos);
+               tc.select(QTextCursor::BlockUnderCursor);
+               QString s = tc.selectedText();
+               if(curPos==0)   s = "\n"+s;
+               tc.deleteChar();
+               bool ins=true;
+
+               while(tc.movePosition(QTextCursor::NextBlock))
+               {
+                       QString q = tc.block().text();
+                       if(q.startsWith("subplot ") || q.startsWith("inplot ") || q.startsWith("multiplot ") || q.startsWith("gridplot ") || q.startsWith("columnplot ") || q.startsWith("stickplot "))
+                       {
+                               tc.movePosition(QTextCursor::EndOfBlock);
+                               tc.insertText(s);       ins=false;      break;
+                       }
+               }
+               if(ins) {       tc.movePosition(QTextCursor::End);      tc.insertText(s);       }
+               curPos = tc.block().blockNumber();      execute();
+       }
+       else emit setStatus("No selection.");
+}
+//-----------------------------------------------------------------------------
+
index 41e79974308e6fae6849bac5be346114691c3915..dd03f9e5cfb752f7ee2e57f2a70abe8fb7ab60dc 100644 (file)
@@ -21,6 +21,7 @@
 #define PLOT_PNL_H
 //-----------------------------------------------------------------------------
 #include <QWidget>
+#include <qabstractitemmodel.h>
 //-----------------------------------------------------------------------------
 class QMenu;
 class QTimer;
@@ -34,9 +35,10 @@ class mglDrawScript;
 class InfoDialog;
 class AnimParam;
 class DatPanel;
-class mglVar;
 class StyleDialog;
 class QPrinter;
+class NewCmdDialog;
+class SubplotDialog;
 //-----------------------------------------------------------------------------
 class PlotPanel : public QWidget
 {
@@ -44,8 +46,10 @@ Q_OBJECT
 public:
        QMenu *menu;
        QMathGL *mgl;
-       mglDrawScript *draw;            ///< Class for drawing MGL script
-       const QTextEdit *textMGL;       ///< Editor with MGL script body
+       mglDrawScript *draw;    ///< Class for drawing MGL script
+       QTextEdit *textMGL;             ///< Editor with MGL script body
+       NewCmdDialog *newCmdDlg;
+       SubplotDialog *subplotDlg;
        PlotPanel(QWidget *wp=0);
        ~PlotPanel();
        void setMGLFont(const QString &path);
@@ -75,6 +79,13 @@ private slots:
        void pressF9();
        void stop();
        void setStyle(int id);
+       void setSubId(int id);
+       void deleteSelected();
+       void hideSelected();
+       void putCmd(const QString &cmd);
+       void insCmd(const QString &cmd);
+       void movePlotUp();
+       void movePlotDown();
 
 private:
        bool gifOn, jpgOn;
@@ -89,6 +100,8 @@ private:
        QMenu *popup;
        QPrinter *printer;
        StyleDialog *stlDialog;
+       int objId;
+       int subId;
        
        void toolTop(QBoxLayout *l);
        void toolLeft(QBoxLayout *l);
diff --git a/udav/png/accessories-calculator.png b/udav/png/accessories-calculator.png
new file mode 100644 (file)
index 0000000..acc5ce0
Binary files /dev/null and b/udav/png/accessories-calculator.png differ
diff --git a/udav/png/alpha.png b/udav/png/alpha.png
new file mode 100644 (file)
index 0000000..fdb8836
Binary files /dev/null and b/udav/png/alpha.png differ
diff --git a/udav/png/arrow-down-double.png b/udav/png/arrow-down-double.png
new file mode 100644 (file)
index 0000000..bb5b211
Binary files /dev/null and b/udav/png/arrow-down-double.png differ
diff --git a/udav/png/arrow-down.png b/udav/png/arrow-down.png
new file mode 100644 (file)
index 0000000..bf8cc2a
Binary files /dev/null and b/udav/png/arrow-down.png differ
diff --git a/udav/png/arrow-left-double.png b/udav/png/arrow-left-double.png
new file mode 100644 (file)
index 0000000..6fb6b1f
Binary files /dev/null and b/udav/png/arrow-left-double.png differ
diff --git a/udav/png/arrow-left.png b/udav/png/arrow-left.png
new file mode 100644 (file)
index 0000000..4f2ad45
Binary files /dev/null and b/udav/png/arrow-left.png differ
diff --git a/udav/png/arrow-right-double.png b/udav/png/arrow-right-double.png
new file mode 100644 (file)
index 0000000..0a52981
Binary files /dev/null and b/udav/png/arrow-right-double.png differ
diff --git a/udav/png/arrow-right.png b/udav/png/arrow-right.png
new file mode 100644 (file)
index 0000000..3dc5c5a
Binary files /dev/null and b/udav/png/arrow-right.png differ
diff --git a/udav/png/arrow-up-double.png b/udav/png/arrow-up-double.png
new file mode 100644 (file)
index 0000000..91f48ac
Binary files /dev/null and b/udav/png/arrow-up-double.png differ
diff --git a/udav/png/arrow-up.png b/udav/png/arrow-up.png
new file mode 100644 (file)
index 0000000..afca099
Binary files /dev/null and b/udav/png/arrow-up.png differ
diff --git a/udav/png/dialog-information.png b/udav/png/dialog-information.png
new file mode 100644 (file)
index 0000000..8851b99
Binary files /dev/null and b/udav/png/dialog-information.png differ
diff --git a/udav/png/document-export.png b/udav/png/document-export.png
new file mode 100644 (file)
index 0000000..eb82440
Binary files /dev/null and b/udav/png/document-export.png differ
diff --git a/udav/png/document-import.png b/udav/png/document-import.png
new file mode 100644 (file)
index 0000000..82140be
Binary files /dev/null and b/udav/png/document-import.png differ
diff --git a/udav/png/document-new.png b/udav/png/document-new.png
new file mode 100644 (file)
index 0000000..a956a80
Binary files /dev/null and b/udav/png/document-new.png differ
diff --git a/udav/png/document-open-folder.png b/udav/png/document-open-folder.png
new file mode 100644 (file)
index 0000000..8f3ef6d
Binary files /dev/null and b/udav/png/document-open-folder.png differ
diff --git a/udav/png/document-open.png b/udav/png/document-open.png
new file mode 100644 (file)
index 0000000..17076a3
Binary files /dev/null and b/udav/png/document-open.png differ
diff --git a/udav/png/document-print.png b/udav/png/document-print.png
new file mode 100644 (file)
index 0000000..5977b3d
Binary files /dev/null and b/udav/png/document-print.png differ
diff --git a/udav/png/document-properties.png b/udav/png/document-properties.png
new file mode 100644 (file)
index 0000000..ab0e8ea
Binary files /dev/null and b/udav/png/document-properties.png differ
diff --git a/udav/png/document-revert.png b/udav/png/document-revert.png
new file mode 100644 (file)
index 0000000..47d7415
Binary files /dev/null and b/udav/png/document-revert.png differ
diff --git a/udav/png/document-save.png b/udav/png/document-save.png
new file mode 100644 (file)
index 0000000..22ff495
Binary files /dev/null and b/udav/png/document-save.png differ
diff --git a/udav/png/edit-clear.png b/udav/png/edit-clear.png
new file mode 100644 (file)
index 0000000..78d183f
Binary files /dev/null and b/udav/png/edit-clear.png differ
diff --git a/udav/png/edit-copy.png b/udav/png/edit-copy.png
new file mode 100644 (file)
index 0000000..54eaf77
Binary files /dev/null and b/udav/png/edit-copy.png differ
diff --git a/udav/png/edit-cut.png b/udav/png/edit-cut.png
new file mode 100644 (file)
index 0000000..f4a55e3
Binary files /dev/null and b/udav/png/edit-cut.png differ
diff --git a/udav/png/edit-delete.png b/udav/png/edit-delete.png
new file mode 100644 (file)
index 0000000..184f762
Binary files /dev/null and b/udav/png/edit-delete.png differ
diff --git a/udav/png/edit-find.png b/udav/png/edit-find.png
new file mode 100644 (file)
index 0000000..ee69755
Binary files /dev/null and b/udav/png/edit-find.png differ
diff --git a/udav/png/edit-paste.png b/udav/png/edit-paste.png
new file mode 100644 (file)
index 0000000..3f71b1c
Binary files /dev/null and b/udav/png/edit-paste.png differ
diff --git a/udav/png/edit-redo.png b/udav/png/edit-redo.png
new file mode 100644 (file)
index 0000000..c03bba0
Binary files /dev/null and b/udav/png/edit-redo.png differ
diff --git a/udav/png/edit-select-all.png b/udav/png/edit-select-all.png
new file mode 100644 (file)
index 0000000..2276ddc
Binary files /dev/null and b/udav/png/edit-select-all.png differ
diff --git a/udav/png/edit-undo.png b/udav/png/edit-undo.png
new file mode 100644 (file)
index 0000000..f123942
Binary files /dev/null and b/udav/png/edit-undo.png differ
diff --git a/udav/png/folder.png b/udav/png/folder.png
new file mode 100644 (file)
index 0000000..13c1962
Binary files /dev/null and b/udav/png/folder.png differ
diff --git a/udav/png/format-indent-more.png b/udav/png/format-indent-more.png
new file mode 100644 (file)
index 0000000..00309ea
Binary files /dev/null and b/udav/png/format-indent-more.png differ
diff --git a/udav/png/format-stroke-color.png b/udav/png/format-stroke-color.png
new file mode 100644 (file)
index 0000000..9523c25
Binary files /dev/null and b/udav/png/format-stroke-color.png differ
diff --git a/udav/png/go-bottom.png b/udav/png/go-bottom.png
new file mode 100644 (file)
index 0000000..37ea459
Binary files /dev/null and b/udav/png/go-bottom.png differ
diff --git a/udav/png/go-down.png b/udav/png/go-down.png
new file mode 100644 (file)
index 0000000..67e91ec
Binary files /dev/null and b/udav/png/go-down.png differ
diff --git a/udav/png/go-first-view.png b/udav/png/go-first-view.png
new file mode 100644 (file)
index 0000000..baee851
Binary files /dev/null and b/udav/png/go-first-view.png differ
diff --git a/udav/png/go-first.png b/udav/png/go-first.png
new file mode 100644 (file)
index 0000000..84119c6
Binary files /dev/null and b/udav/png/go-first.png differ
diff --git a/udav/png/go-jump-locationbar.png b/udav/png/go-jump-locationbar.png
new file mode 100644 (file)
index 0000000..637c1cf
Binary files /dev/null and b/udav/png/go-jump-locationbar.png differ
diff --git a/udav/png/go-last-view.png b/udav/png/go-last-view.png
new file mode 100644 (file)
index 0000000..c90d919
Binary files /dev/null and b/udav/png/go-last-view.png differ
diff --git a/udav/png/go-last.png b/udav/png/go-last.png
new file mode 100644 (file)
index 0000000..ebe69bd
Binary files /dev/null and b/udav/png/go-last.png differ
diff --git a/udav/png/go-next-view-page.png b/udav/png/go-next-view-page.png
new file mode 100644 (file)
index 0000000..3b8784b
Binary files /dev/null and b/udav/png/go-next-view-page.png differ
diff --git a/udav/png/go-next-view.png b/udav/png/go-next-view.png
new file mode 100644 (file)
index 0000000..8a9ff0a
Binary files /dev/null and b/udav/png/go-next-view.png differ
diff --git a/udav/png/go-next.png b/udav/png/go-next.png
new file mode 100644 (file)
index 0000000..8cbb81e
Binary files /dev/null and b/udav/png/go-next.png differ
diff --git a/udav/png/go-previous-view-page.png b/udav/png/go-previous-view-page.png
new file mode 100644 (file)
index 0000000..0a391d6
Binary files /dev/null and b/udav/png/go-previous-view-page.png differ
diff --git a/udav/png/go-previous-view.png b/udav/png/go-previous-view.png
new file mode 100644 (file)
index 0000000..d75f1e4
Binary files /dev/null and b/udav/png/go-previous-view.png differ
diff --git a/udav/png/go-previous.png b/udav/png/go-previous.png
new file mode 100644 (file)
index 0000000..87d0994
Binary files /dev/null and b/udav/png/go-previous.png differ
diff --git a/udav/png/go-top.png b/udav/png/go-top.png
new file mode 100644 (file)
index 0000000..803e432
Binary files /dev/null and b/udav/png/go-top.png differ
diff --git a/udav/png/go-up.png b/udav/png/go-up.png
new file mode 100644 (file)
index 0000000..5fafd13
Binary files /dev/null and b/udav/png/go-up.png differ
diff --git a/udav/png/help-contents.png b/udav/png/help-contents.png
new file mode 100644 (file)
index 0000000..b3ae2c3
Binary files /dev/null and b/udav/png/help-contents.png differ
diff --git a/udav/png/help-faq.png b/udav/png/help-faq.png
new file mode 100644 (file)
index 0000000..f6bc721
Binary files /dev/null and b/udav/png/help-faq.png differ
diff --git a/udav/png/layer-visible-off.png b/udav/png/layer-visible-off.png
new file mode 100644 (file)
index 0000000..74a4f07
Binary files /dev/null and b/udav/png/layer-visible-off.png differ
diff --git a/udav/png/layer-visible-on.png b/udav/png/layer-visible-on.png
new file mode 100644 (file)
index 0000000..ead7d91
Binary files /dev/null and b/udav/png/layer-visible-on.png differ
diff --git a/udav/png/list-add.png b/udav/png/list-add.png
new file mode 100644 (file)
index 0000000..eefb01e
Binary files /dev/null and b/udav/png/list-add.png differ
diff --git a/udav/png/list-remove.png b/udav/png/list-remove.png
new file mode 100644 (file)
index 0000000..f1f0dee
Binary files /dev/null and b/udav/png/list-remove.png differ
diff --git a/udav/png/media-playback-start.png b/udav/png/media-playback-start.png
new file mode 100644 (file)
index 0000000..80ff3a1
Binary files /dev/null and b/udav/png/media-playback-start.png differ
diff --git a/udav/png/media-seek-backward.png b/udav/png/media-seek-backward.png
new file mode 100644 (file)
index 0000000..6b76327
Binary files /dev/null and b/udav/png/media-seek-backward.png differ
diff --git a/udav/png/media-seek-forward.png b/udav/png/media-seek-forward.png
new file mode 100644 (file)
index 0000000..6c3b1c4
Binary files /dev/null and b/udav/png/media-seek-forward.png differ
diff --git a/udav/png/object-group.png b/udav/png/object-group.png
new file mode 100644 (file)
index 0000000..5238c12
Binary files /dev/null and b/udav/png/object-group.png differ
diff --git a/udav/png/object-order-lower.png b/udav/png/object-order-lower.png
new file mode 100644 (file)
index 0000000..7289dee
Binary files /dev/null and b/udav/png/object-order-lower.png differ
diff --git a/udav/png/object-order-raise.png b/udav/png/object-order-raise.png
new file mode 100644 (file)
index 0000000..8819a31
Binary files /dev/null and b/udav/png/object-order-raise.png differ
diff --git a/udav/png/object-rotate-down.png b/udav/png/object-rotate-down.png
new file mode 100644 (file)
index 0000000..b62a39c
Binary files /dev/null and b/udav/png/object-rotate-down.png differ
diff --git a/udav/png/object-rotate-left.png b/udav/png/object-rotate-left.png
new file mode 100644 (file)
index 0000000..facad55
Binary files /dev/null and b/udav/png/object-rotate-left.png differ
diff --git a/udav/png/object-rotate-right.png b/udav/png/object-rotate-right.png
new file mode 100644 (file)
index 0000000..6b6a518
Binary files /dev/null and b/udav/png/object-rotate-right.png differ
diff --git a/udav/png/object-rotate-up.png b/udav/png/object-rotate-up.png
new file mode 100644 (file)
index 0000000..08e5d44
Binary files /dev/null and b/udav/png/object-rotate-up.png differ
diff --git a/udav/png/object-ungroup.png b/udav/png/object-ungroup.png
new file mode 100644 (file)
index 0000000..e343ff4
Binary files /dev/null and b/udav/png/object-ungroup.png differ
diff --git a/udav/png/office-chart-bar.png b/udav/png/office-chart-bar.png
new file mode 100644 (file)
index 0000000..3be1013
Binary files /dev/null and b/udav/png/office-chart-bar.png differ
diff --git a/udav/png/office-chart-line.png b/udav/png/office-chart-line.png
new file mode 100644 (file)
index 0000000..501b078
Binary files /dev/null and b/udav/png/office-chart-line.png differ
diff --git a/udav/png/office-chart-scatter.png b/udav/png/office-chart-scatter.png
new file mode 100644 (file)
index 0000000..0ecfbf3
Binary files /dev/null and b/udav/png/office-chart-scatter.png differ
diff --git a/udav/png/package-x-generic.png b/udav/png/package-x-generic.png
new file mode 100644 (file)
index 0000000..9015426
Binary files /dev/null and b/udav/png/package-x-generic.png differ
diff --git a/udav/png/preferences-system.png b/udav/png/preferences-system.png
new file mode 100644 (file)
index 0000000..39587d0
Binary files /dev/null and b/udav/png/preferences-system.png differ
diff --git a/udav/png/process-stop.png b/udav/png/process-stop.png
new file mode 100644 (file)
index 0000000..3ff0409
Binary files /dev/null and b/udav/png/process-stop.png differ
diff --git a/udav/png/system-file-manager.png b/udav/png/system-file-manager.png
new file mode 100644 (file)
index 0000000..60cade4
Binary files /dev/null and b/udav/png/system-file-manager.png differ
diff --git a/udav/png/tab-close.png b/udav/png/tab-close.png
new file mode 100644 (file)
index 0000000..24f36f0
Binary files /dev/null and b/udav/png/tab-close.png differ
diff --git a/udav/png/table.png b/udav/png/table.png
new file mode 100644 (file)
index 0000000..bdebe96
Binary files /dev/null and b/udav/png/table.png differ
diff --git a/udav/png/text-csv.png b/udav/png/text-csv.png
new file mode 100644 (file)
index 0000000..e7a6cdd
Binary files /dev/null and b/udav/png/text-csv.png differ
diff --git a/udav/png/text-field.png b/udav/png/text-field.png
new file mode 100644 (file)
index 0000000..f997cbd
Binary files /dev/null and b/udav/png/text-field.png differ
diff --git a/udav/png/text-plain.png b/udav/png/text-plain.png
new file mode 100644 (file)
index 0000000..91b7da5
Binary files /dev/null and b/udav/png/text-plain.png differ
diff --git a/udav/png/text-x-generic.png b/udav/png/text-x-generic.png
new file mode 100644 (file)
index 0000000..2d7f2d6
Binary files /dev/null and b/udav/png/text-x-generic.png differ
diff --git a/udav/png/tools-wizard.png b/udav/png/tools-wizard.png
new file mode 100644 (file)
index 0000000..403714a
Binary files /dev/null and b/udav/png/tools-wizard.png differ
diff --git a/udav/png/transform-crop.png b/udav/png/transform-crop.png
new file mode 100644 (file)
index 0000000..bfd639b
Binary files /dev/null and b/udav/png/transform-crop.png differ
diff --git a/udav/png/transform-move.png b/udav/png/transform-move.png
new file mode 100644 (file)
index 0000000..6bba036
Binary files /dev/null and b/udav/png/transform-move.png differ
diff --git a/udav/png/transform-rotate.png b/udav/png/transform-rotate.png
new file mode 100644 (file)
index 0000000..8bfa17f
Binary files /dev/null and b/udav/png/transform-rotate.png differ
diff --git a/udav/png/transform-scale.png b/udav/png/transform-scale.png
new file mode 100644 (file)
index 0000000..34a1140
Binary files /dev/null and b/udav/png/transform-scale.png differ
diff --git a/udav/png/udav.png b/udav/png/udav.png
new file mode 100644 (file)
index 0000000..76ba7d9
Binary files /dev/null and b/udav/png/udav.png differ
diff --git a/udav/png/view-filter.png b/udav/png/view-filter.png
new file mode 100644 (file)
index 0000000..9cabc5a
Binary files /dev/null and b/udav/png/view-filter.png differ
diff --git a/udav/png/view-fullscreen.png b/udav/png/view-fullscreen.png
new file mode 100644 (file)
index 0000000..75f8a59
Binary files /dev/null and b/udav/png/view-fullscreen.png differ
diff --git a/udav/png/view-grid.png b/udav/png/view-grid.png
new file mode 100644 (file)
index 0000000..12e55ad
Binary files /dev/null and b/udav/png/view-grid.png differ
diff --git a/udav/png/view-group.png b/udav/png/view-group.png
new file mode 100644 (file)
index 0000000..e9aab73
Binary files /dev/null and b/udav/png/view-group.png differ
diff --git a/udav/png/view-refresh.png b/udav/png/view-refresh.png
new file mode 100644 (file)
index 0000000..3fd71d6
Binary files /dev/null and b/udav/png/view-refresh.png differ
diff --git a/udav/png/weather-clear.png b/udav/png/weather-clear.png
new file mode 100644 (file)
index 0000000..0704477
Binary files /dev/null and b/udav/png/weather-clear.png differ
diff --git a/udav/png/weather-clear_old.png b/udav/png/weather-clear_old.png
new file mode 100644 (file)
index 0000000..7dc15ea
Binary files /dev/null and b/udav/png/weather-clear_old.png differ
diff --git a/udav/png/weather-clouds.png b/udav/png/weather-clouds.png
new file mode 100644 (file)
index 0000000..c0bdffa
Binary files /dev/null and b/udav/png/weather-clouds.png differ
diff --git a/udav/png/zoom-draw.png b/udav/png/zoom-draw.png
new file mode 100644 (file)
index 0000000..393e752
Binary files /dev/null and b/udav/png/zoom-draw.png differ
diff --git a/udav/png/zoom-in.png b/udav/png/zoom-in.png
new file mode 100644 (file)
index 0000000..0e1fc37
Binary files /dev/null and b/udav/png/zoom-in.png differ
diff --git a/udav/png/zoom-original.png b/udav/png/zoom-original.png
new file mode 100644 (file)
index 0000000..f7bae85
Binary files /dev/null and b/udav/png/zoom-original.png differ
diff --git a/udav/png/zoom-out.png b/udav/png/zoom-out.png
new file mode 100644 (file)
index 0000000..7d4d55c
Binary files /dev/null and b/udav/png/zoom-out.png differ
index 8efcf3be4a3d6596bda6875f1938fd191aaeb923..1ebfebd5a2b97ccdd29a8cec333021ac072e7363 100644 (file)
@@ -48,6 +48,7 @@ extern bool mglCompleter;
 extern bool editPosBottom;\r
 extern bool loadInNewWnd;\r
 extern bool mglHighlight;\r
+extern bool mglDotsRefr;\r
 int defWidth, defHeight;\r
 QString pathFont;\r
 QString lang[]={"","ru"};\r
@@ -103,7 +104,7 @@ PropDialog::PropDialog(QWidget *parent) : QDialog(parent)
        pic.fill(cc[9]);        cb[9] = new QPushButton(pic, tr("CurrLine"), this);\r
        connect(cb[9], SIGNAL(clicked()),this, SLOT(setC9()));\r
        g->addWidget(cb[9], 2, 2);\r
-       \r
+\r
        l = new QLabel(tr("Path for help files"), this);        v->addWidget(l);\r
        h = new QHBoxLayout();          v->addLayout(h);\r
        hlp = new QLineEdit(pathHelp, this);    h->addWidget(hlp,1);\r
@@ -166,7 +167,9 @@ PropDialog::PropDialog(QWidget *parent) : QDialog(parent)
        cmpl->setChecked(mglCompleter); v->addWidget(cmpl);\r
        high = new QCheckBox(tr("Highlight current object(s)"), this);\r
        high->setChecked(mglHighlight); v->addWidget(high);\r
-       \r
+       dots = new QCheckBox(tr("Use dots plot for preview"), this);\r
+       dots->setChecked(mglDotsRefr);  v->addWidget(dots);\r
+\r
        h = new QHBoxLayout();          v->addLayout(h);\r
        h->addStretch(1);\r
        b = new QPushButton(tr("Cancel"), this);        h->addWidget(b);\r
@@ -230,6 +233,7 @@ void PropDialog::applyChanges()
        mglHighlight = high->isChecked();\r
        mglAutoPure = pure->isChecked();\r
        mglCompleter = cmpl->isChecked();\r
+       mglDotsRefr = dots->isChecked();\r
 \r
        // apply changes for all windows\r
 #ifdef WIN32\r
index 8f0e12641026d86e5203d4a13b0a11bfb1a06ce4..22b58e322b10ff111787745f8b9176bedcfffec6 100644 (file)
@@ -56,7 +56,7 @@ private:
        void setC(int k);
        QLabel *lbl;
        QPushButton *cb[10];
-       QCheckBox *run, *edt, *load, *save, *pure, *cmpl, *high;
+       QCheckBox *run, *edt, *load, *save, *pure, *cmpl, *high, *dots;
        QLineEdit *hlp, *defW, *defH;
        QFont defFont;
        QColor cc[10];
index 20efa2ba061a8eea9c05364289595827ceabd780..c088d982384b096fe9418c7495fa12e014c64c97 100644 (file)
@@ -85,7 +85,7 @@ void QMGLSyntax::highlightBlock(const QString &text)
                        for(j=0;j<13;j++)\r
                        {\r
                                l = strlen(o[j]);\r
-                               if(text.indexOf(o[j],i)==i && (i+l==text.length() || text[i+l].isSpace()))\r
+                               if(text.indexOf(o[j],i)==i && (i+l==long(text.length()) || text[i+l].isSpace()))\r
                                        setFormat(i,l,mglColorScheme[3]);\r
                        }\r
                }\r
@@ -100,9 +100,9 @@ void QMGLSyntax::highlightBlock(const QString &text)
                        setFormat(i,1,mglColorScheme[5]);\r
                else            // number as its symbolic id\r
                {\r
-                       const char *o[]={"nan","pi","on","off"};\r
-                       int l[4] = {3, 2, 2, 3};\r
-                       for(j=0;j<4;j++)\r
+                       const char *o[]={"nan","inf","pi","on","off"};\r
+                       int l[5] = {3, 3, 2, 2, 3};\r
+                       for(j=0;j<5;j++)\r
                                if(text.indexOf(o[j],i)==i && (i+l[j]==text.length() || text[i+l[j]].isSpace()))\r
                                        setFormat(i,l[j],mglColorScheme[5]);\r
                }\r
index 0f4c9188ec6e6a7880002e9b56168d29fbd75059..2150ab9fecc88cfb79aa76ba3fd8f5d165d4d692 100644 (file)
 #include <QLayout>\r
 #include <QLabel>\r
 #include <QLineEdit>\r
+#include <QToolButton>\r
 #include <mgl2/mgl.h>\r
 //-----------------------------------------------------------------------------\r
-#include "xpm/none.xpm"\r
-#include "xpm/mark_.xpm"\r
-#include "xpm/mark_cf.xpm"\r
-#include "xpm/mark_x.xpm"\r
-#include "xpm/mark_p.xpm"\r
-#include "xpm/mark_pf.xpm"\r
-#include "xpm/mark_o.xpm"\r
-#include "xpm/mark_of.xpm"\r
-#include "xpm/mark_s.xpm"\r
-#include "xpm/mark_sf.xpm"\r
-#include "xpm/mark_d.xpm"\r
-#include "xpm/mark_df.xpm"\r
-#include "xpm/mark_v.xpm"\r
-#include "xpm/mark_vf.xpm"\r
-#include "xpm/mark_t.xpm"\r
-#include "xpm/mark_tf.xpm"\r
-#include "xpm/mark_l.xpm"\r
-#include "xpm/mark_lf.xpm"\r
-#include "xpm/mark_r.xpm"\r
-#include "xpm/mark_rf.xpm"\r
-#include "xpm/mark_y.xpm"\r
-#include "xpm/mark_a.xpm"\r
-#include "xpm/mark_n.xpm"\r
-#include "xpm/dash_e.xpm"\r
-#include "xpm/dash_s.xpm"\r
-#include "xpm/dash_l.xpm"\r
-#include "xpm/dash_m.xpm"\r
-#include "xpm/dash_d.xpm"\r
-#include "xpm/dash_i.xpm"\r
-#include "xpm/dash_j.xpm"\r
-#include "xpm/arrow_n.xpm"\r
-#include "xpm/arrow_a.xpm"\r
-#include "xpm/arrow_v.xpm"\r
-#include "xpm/arrow_i.xpm"\r
-#include "xpm/arrow_k.xpm"\r
-#include "xpm/arrow_t.xpm"\r
-#include "xpm/arrow_s.xpm"\r
-#include "xpm/arrow_d.xpm"\r
-#include "xpm/arrow_o.xpm"\r
-//-----------------------------------------------------------------------------\r
 #include "style_dlg.h"\r
 void fillColors(QComboBox *cb);\r
 void fillArrows(QComboBox *cb);\r
+void fillBArrows(QComboBox *cb);\r
 void fillDashes(QComboBox *cb);\r
 void fillMarkers(QComboBox *cb);\r
+void fillMasks(QComboBox *cb);\r
 void convertFromGraph(QPixmap &pic, mglGraph *gr, uchar **buf);\r
 //-----------------------------------------------------------------------------\r
 StyleDialog::StyleDialog(QWidget *parent) : QDialog(parent)\r
 {\r
+       grBuf = 0;\r
        setWindowTitle(tr("UDAV - Insert style/scheme"));\r
        QWidget *p;\r
        QHBoxLayout *h;\r
@@ -87,18 +51,18 @@ StyleDialog::StyleDialog(QWidget *parent) : QDialog(parent)
        QGridLayout *g;\r
        QLabel *l;\r
        QPushButton *b;\r
-       grBuf = 0;\r
        tab = new QTabWidget(this);\r
+\r
        // line style\r
-       p = new QWidget(this);\r
-       g = new QGridLayout(p); g->setAlignment(Qt::AlignTop);\r
+       p = new QWidget(this);  v = new QVBoxLayout(p);\r
+       g = new QGridLayout;    g->setAlignment(Qt::AlignTop);  v->addLayout(g);\r
 //     g->setColStretch(0, 1); g->setColStretch(1, 1); g->setColStretch(2, 1);\r
        l = new QLabel(tr("Arrow at start"), p);        g->addWidget(l, 0, 0);\r
        l = new QLabel(tr("Dashing"), p);               g->addWidget(l, 0, 1);\r
        l = new QLabel(tr("Arrow at end"), p);  g->addWidget(l, 0, 2);\r
        a1 = new QComboBox(p);  g->addWidget(a1, 1, 0); fillArrows(a1);\r
        dash = new QComboBox(p);        g->addWidget(dash, 1, 1);       fillDashes(dash);\r
-       a2 = new QComboBox(p);  g->addWidget(a2, 1, 2); fillArrows(a2);\r
+       a2 = new QComboBox(p);  g->addWidget(a2, 1, 2); fillBArrows(a2);\r
        l = new QLabel(tr("Color"), p); g->addWidget(l, 2, 0, Qt::AlignRight);\r
        cline=new QComboBox(p); g->addWidget(cline, 2, 1);      fillColors(cline);\r
 \r
@@ -113,6 +77,17 @@ StyleDialog::StyleDialog(QWidget *parent) : QDialog(parent)
        l = new QLabel(tr("Line width"), p);    g->addWidget(l, 4, 0, Qt::AlignRight);\r
        width = new QSpinBox(p);        g->addWidget(width, 4, 1);\r
        width->setRange(1,9);   width->setValue(1);\r
+       \r
+       v->addStretch(1);\r
+       l = new QLabel(tr("Manual dashing"), p);        v->addWidget(l);\r
+       h = new QHBoxLayout;    v->addLayout(h);        h->setSpacing(1);\r
+       for(int i=0;i<16;i++)\r
+       {\r
+               dash_bit[i] = new QToolButton(this);\r
+               dash_bit[i]->setCheckable(true);\r
+               h->addWidget(dash_bit[i]);\r
+               connect(dash_bit[i],SIGNAL(toggled(bool)), this, SLOT(updatePic()));\r
+       }\r
        connect(a1,SIGNAL(activated(int)), this, SLOT(updatePic()));\r
        connect(a2,SIGNAL(activated(int)), this, SLOT(updatePic()));\r
        connect(dash,SIGNAL(activated(int)), this, SLOT(updatePic()));\r
@@ -121,6 +96,7 @@ StyleDialog::StyleDialog(QWidget *parent) : QDialog(parent)
        connect(nline,SIGNAL(valueChanged(int)), this, SLOT(updatePic()));\r
        connect(width,SIGNAL(valueChanged(int)), this, SLOT(updatePic()));\r
        tab->addTab(p, tr("Line style"));\r
+\r
        // color scheme\r
        p = new QWidget(this);\r
        v = new QVBoxLayout(p); v->setAlignment(Qt::AlignTop);\r
@@ -144,15 +120,34 @@ StyleDialog::StyleDialog(QWidget *parent) : QDialog(parent)
        g = new QGridLayout();  v->addLayout(g);\r
        l = new QLabel(tr("Axial direction"), p);       g->addWidget(l, 0, 0, Qt::AlignRight);\r
        l = new QLabel(tr("Text on contours"), p);      g->addWidget(l, 1, 0, Qt::AlignRight);\r
+       l = new QLabel(tr("Mask for bitmap coloring"), p);      g->addWidget(l, 2, 0, Qt::AlignRight);\r
+       l = new QLabel(tr("Mask rotation angle"), p);   g->addWidget(l, 3, 0, Qt::AlignRight);\r
+       l = new QLabel(tr("Mask size"), p);     g->addWidget(l, 4, 0, Qt::AlignRight);\r
        axial = new QComboBox(p);       g->addWidget(axial, 0, 1);\r
        axial->addItem(tr("none"));     axial->addItem("x");\r
        axial->addItem("y");    axial->addItem("z");\r
        ctext = new QComboBox(p);       g->addWidget(ctext, 1, 1);\r
        ctext->addItem(tr("none"));     ctext->addItem(tr("under"));    ctext->addItem(tr("above"));\r
+       mask = new QComboBox(p);        g->addWidget(mask, 2, 1);       fillMasks(mask);\r
+       angle = new QComboBox(p);       g->addWidget(angle, 3, 1);\r
+       angle->addItem(tr("none"));     \r
+       angle->addItem(QString::fromWCharArray(L"+45°"));\r
+       angle->addItem(QString::fromWCharArray(L"-45°"));      \r
+       angle->addItem(QString::fromWCharArray(L"90°"));\r
+       msize = new QSlider(p);         g->addWidget(msize, 4, 1);\r
+       msize->setRange(1, 9);          msize->setValue(1);\r
+       msize->setTickPosition(QSlider::TicksBothSides);\r
+       msize->setTickInterval(1);      msize->setPageStep(2);\r
+       msize->setOrientation(Qt::Horizontal);\r
+\r
        connect(axial,SIGNAL(activated(int)), this, SLOT(updatePic()));\r
        connect(ctext,SIGNAL(activated(int)), this, SLOT(updatePic()));\r
        connect(swire,SIGNAL(toggled(bool)), this, SLOT(updatePic()));\r
+       connect(mask,SIGNAL(activated(int)), this, SLOT(updatePic()));\r
+       connect(angle,SIGNAL(activated(int)), this, SLOT(updatePic()));\r
+       connect(msize,SIGNAL(valueChanged(int)), this, SLOT(updatePic()));\r
        tab->addTab(p, tr("Color scheme"));\r
+\r
        // font style\r
        p = new QWidget(this);\r
        v = new QVBoxLayout(p); v->setAlignment(Qt::AlignTop);\r
@@ -163,6 +158,7 @@ StyleDialog::StyleDialog(QWidget *parent) : QDialog(parent)
        wire = new QCheckBox(tr("Wire style"), p);      u->addWidget(wire);\r
        uline = new QCheckBox(tr("Underline"), p);      u->addWidget(uline);\r
        oline = new QCheckBox(tr("Overline"), p);       u->addWidget(oline);\r
+       font_sch = new QCheckBox(tr("Use color scheme"), p);    u->addWidget(font_sch);\r
        u = new QVBoxLayout();  h->addLayout(u);\r
        l = new QLabel(tr("Text color"), p);            u->addWidget(l);\r
        cfont = new QComboBox(p);       fillColors(cfont);      u->addWidget(cfont);\r
@@ -178,6 +174,7 @@ StyleDialog::StyleDialog(QWidget *parent) : QDialog(parent)
        connect(wire,SIGNAL(toggled(bool)), this, SLOT(updatePic()));\r
        connect(uline,SIGNAL(toggled(bool)), this, SLOT(updatePic()));\r
        connect(oline,SIGNAL(toggled(bool)), this, SLOT(updatePic()));\r
+       connect(font_sch,SIGNAL(toggled(bool)), this, SLOT(updatePic()));\r
        connect(cfont,SIGNAL(activated(int)), this, SLOT(updatePic()));\r
        connect(rbL,SIGNAL(toggled(bool)), this, SLOT(updatePic()));\r
        connect(rbC,SIGNAL(toggled(bool)), this, SLOT(updatePic()));\r
@@ -185,6 +182,18 @@ StyleDialog::StyleDialog(QWidget *parent) : QDialog(parent)
        tab->addTab(p, tr("Font style"));\r
        connect(tab,SIGNAL(currentChanged(int)), this, SLOT(updatePic()));\r
 \r
+       // hex-mask\r
+       p = new QWidget(this);\r
+       g = new QGridLayout(p); g->setAlignment(Qt::AlignTop);\r
+       for(int i=0;i<64;i++)\r
+       {\r
+               mask_bit[i] = new QToolButton(this);\r
+               mask_bit[i]->setCheckable(true);\r
+               g->addWidget(mask_bit[i],7-i/8,i%8);\r
+               connect(mask_bit[i],SIGNAL(toggled(bool)), this, SLOT(updatePic()));\r
+       }\r
+       tab->addTab(p, tr("Manual mask"));\r
+\r
        // dialog itself\r
        v = new QVBoxLayout(this);      v->addWidget(tab);\r
        h = new QHBoxLayout();          v->addLayout(h);\r
@@ -200,8 +209,9 @@ StyleDialog::StyleDialog(QWidget *parent) : QDialog(parent)
        b->setDefault(true);\r
 }\r
 //-----------------------------------------------------------------------------\r
-StyleDialog::~StyleDialog()    {       if(grBuf)       delete []grBuf; }\r
+StyleDialog::~StyleDialog()    {       if(grBuf)       delete []grBuf; grBuf = 0;      }\r
 //-----------------------------------------------------------------------------\r
+#include "xpm/none.xpm"\r
 void fillColors(QComboBox *cb)\r
 {\r
 //     string id :     "wbgrcmylenuqphkWBGRCMYLENUQPH"\r
@@ -238,6 +248,15 @@ void fillColors(QComboBox *cb)
        pic.fill(QColor(77,77,77));             cb->addItem(pic, QObject::tr("H - darkgray"));\r
 }\r
 //-----------------------------------------------------------------------------\r
+#include "xpm/arrow_n.xpm"\r
+#include "xpm/arrow_a.xpm"\r
+#include "xpm/arrow_v.xpm"\r
+#include "xpm/arrow_i.xpm"\r
+#include "xpm/arrow_k.xpm"\r
+#include "xpm/arrow_t.xpm"\r
+#include "xpm/arrow_s.xpm"\r
+#include "xpm/arrow_d.xpm"\r
+#include "xpm/arrow_o.xpm"\r
 void fillArrows(QComboBox *cb)\r
 {\r
        // "AVIKTSDO"\r
@@ -252,6 +271,37 @@ void fillArrows(QComboBox *cb)
        cb->addItem(QPixmap(arrow_o_xpm), QObject::tr("circle"));\r
 }\r
 //-----------------------------------------------------------------------------\r
+#include "xpm/barrow_n.xpm"\r
+#include "xpm/barrow_a.xpm"\r
+#include "xpm/barrow_v.xpm"\r
+#include "xpm/barrow_i.xpm"\r
+#include "xpm/barrow_k.xpm"\r
+#include "xpm/barrow_t.xpm"\r
+#include "xpm/barrow_s.xpm"\r
+#include "xpm/barrow_d.xpm"\r
+#include "xpm/barrow_o.xpm"\r
+void fillBArrows(QComboBox *cb)\r
+{\r
+       // "AVIKTSDO"\r
+       cb->addItem(QPixmap(barrow_n_xpm), QObject::tr("none"));\r
+       cb->addItem(QPixmap(barrow_a_xpm), QObject::tr("arrow"));\r
+       cb->addItem(QPixmap(barrow_v_xpm), QObject::tr("back arrow"));\r
+       cb->addItem(QPixmap(barrow_i_xpm), QObject::tr("stop"));\r
+       cb->addItem(QPixmap(barrow_k_xpm), QObject::tr("size"));\r
+       cb->addItem(QPixmap(barrow_t_xpm), QObject::tr("triangle"));\r
+       cb->addItem(QPixmap(barrow_s_xpm), QObject::tr("square"));\r
+       cb->addItem(QPixmap(barrow_d_xpm), QObject::tr("rhomb"));\r
+       cb->addItem(QPixmap(barrow_o_xpm), QObject::tr("circle"));\r
+}\r
+//-----------------------------------------------------------------------------\r
+#include "xpm/dash_e.xpm"\r
+#include "xpm/dash_s.xpm"\r
+#include "xpm/dash_l.xpm"\r
+#include "xpm/dash_m.xpm"\r
+#include "xpm/dash_d.xpm"\r
+#include "xpm/dash_i.xpm"\r
+#include "xpm/dash_j.xpm"\r
+#include "xpm/mark_n.xpm"\r
 void fillDashes(QComboBox *cb)\r
 {\r
        // "-|;=ji: "\r
@@ -263,8 +313,69 @@ void fillDashes(QComboBox *cb)
        cb->addItem(QPixmap(dash_i_xpm), QObject::tr("small dash dot"));\r
        cb->addItem(QPixmap(dash_d_xpm), QObject::tr("dots"));\r
        cb->addItem(QPixmap(mark_n_xpm), QObject::tr("none"));\r
+       cb->addItem(QPixmap(":/png/tools-wizard.png"), QObject::tr("manual"));\r
+}\r
+//-----------------------------------------------------------------------------\r
+#include "xpm/mask_a.xpm"\r
+#include "xpm/mask_d.xpm"\r
+#include "xpm/mask_d_.xpm"\r
+#include "xpm/mask_e.xpm"\r
+#include "xpm/mask_i.xpm"\r
+#include "xpm/mask_j.xpm"\r
+#include "xpm/mask_l.xpm"\r
+#include "xpm/mask_m.xpm"\r
+#include "xpm/mask_o.xpm"\r
+#include "xpm/mask_o_.xpm"\r
+#include "xpm/mask_p.xpm"\r
+#include "xpm/mask_r.xpm"\r
+#include "xpm/mask_s.xpm"\r
+#include "xpm/mask_s_.xpm"\r
+#include "xpm/mask_t.xpm"\r
+#include "xpm/mask_u.xpm"\r
+void fillMasks(QComboBox *cb)\r
+{\r
+       // "-+=;oOsS~<>jdD*^"\r
+       cb->addItem(QPixmap(none_xpm), QObject::tr("none"));\r
+       cb->addItem(QPixmap(mask_m_xpm), QObject::tr("line"));\r
+       cb->addItem(QPixmap(mask_p_xpm), QObject::tr("plus"));\r
+       cb->addItem(QPixmap(mask_e_xpm), QObject::tr("double line"));\r
+       cb->addItem(QPixmap(mask_i_xpm), QObject::tr("dash"));\r
+       cb->addItem(QPixmap(mask_o_xpm), QObject::tr("circle"));\r
+       cb->addItem(QPixmap(mask_O_xpm), QObject::tr("filled circle"));\r
+       cb->addItem(QPixmap(mask_s_xpm), QObject::tr("square"));\r
+       cb->addItem(QPixmap(mask_S_xpm), QObject::tr("filled square"));\r
+       cb->addItem(QPixmap(mask_t_xpm), QObject::tr("wave"));\r
+       cb->addItem(QPixmap(mask_l_xpm), QObject::tr("left sign"));\r
+       cb->addItem(QPixmap(mask_r_xpm), QObject::tr("right sign"));\r
+       cb->addItem(QPixmap(mask_j_xpm), QObject::tr("dash dot"));\r
+       cb->addItem(QPixmap(mask_d_xpm), QObject::tr("rhomb"));\r
+       cb->addItem(QPixmap(mask_D_xpm), QObject::tr("filled rhomb"));\r
+       cb->addItem(QPixmap(mask_a_xpm), QObject::tr("cross"));\r
+       cb->addItem(QPixmap(mask_u_xpm), QObject::tr("up sign"));\r
+       cb->addItem(QPixmap(":/png/tools-wizard.png"), QObject::tr("manual"));\r
 }\r
 //-----------------------------------------------------------------------------\r
+#include "xpm/mark_.xpm"\r
+#include "xpm/mark_cf.xpm"\r
+#include "xpm/mark_x.xpm"\r
+#include "xpm/mark_p.xpm"\r
+#include "xpm/mark_pf.xpm"\r
+#include "xpm/mark_o.xpm"\r
+#include "xpm/mark_of.xpm"\r
+#include "xpm/mark_s.xpm"\r
+#include "xpm/mark_sf.xpm"\r
+#include "xpm/mark_d.xpm"\r
+#include "xpm/mark_df.xpm"\r
+#include "xpm/mark_v.xpm"\r
+#include "xpm/mark_vf.xpm"\r
+#include "xpm/mark_t.xpm"\r
+#include "xpm/mark_tf.xpm"\r
+#include "xpm/mark_l.xpm"\r
+#include "xpm/mark_lf.xpm"\r
+#include "xpm/mark_r.xpm"\r
+#include "xpm/mark_rf.xpm"\r
+#include "xpm/mark_y.xpm"\r
+#include "xpm/mark_a.xpm"\r
 void fillMarkers(QComboBox *cb)\r
 {\r
        // ".+x*sdv^<>o.*+xsdv^<>o" : nf = 10\r
@@ -305,13 +416,14 @@ void StyleDialog::updatePic()
        if(f)\r
        {\r
                gr.SubPlot(1,1,0,"");\r
-               gr.SetMarkSize(20);\r
+               gr.SetMarkSize(15);\r
                gr.SetArrowSize(20);\r
                f = false;\r
        }\r
        result = "";\r
        int i,j;\r
        QString col="wbgrcmylenuqphkWBGRCMYLENUQPH", mrk=".+x*sdv^<>o.*+xsdv^<>o", dsh="|;=ji: ", arw="AVIKTSDO", s;\r
+       QString msk="-+=;oOsS~<>jdD*^", dir="/\\I";\r
        switch(tab->currentIndex())\r
        {\r
        case 0: // line style\r
@@ -321,7 +433,14 @@ void StyleDialog::updatePic()
                        if(i==0)        result += '_';\r
                        result += arw[j-1];\r
                }\r
-               i = dash->currentIndex();       if(i>0) result += dsh[i-1];\r
+               i = dash->currentIndex();\r
+               if(i>0 && i<8)  result += dsh[i-1];\r
+               else if(i==8)   // manual\r
+               {\r
+                       int d=0;\r
+                       for(int i=0;i<16;i++)   if(dash_bit[i]->isChecked())    d += 1<<i;\r
+                       result += "{d"+QString::number(d,16)+"}";\r
+               }\r
                i = mark->currentIndex();       if(i>0) result += mrk[i-1];\r
                if(i>11)        result += '#';\r
                i = cline->currentIndex();\r
@@ -335,6 +454,7 @@ void StyleDialog::updatePic()
                gr.Plot(x,y,result.toStdString().c_str());\r
                break;\r
        case 1: // color sceheme\r
+       case 3: // manual mask\r
                for(j=0;j<7;j++)\r
                {\r
                        i = cc[j]->currentIndex();\r
@@ -348,13 +468,47 @@ void StyleDialog::updatePic()
                i = ctext->currentIndex();\r
                if(i==1)        result += 't';\r
                if(i==2)        result += 'T';\r
+               i = mask->currentIndex();\r
+               if(i>0 && i<17)\r
+               {\r
+                       result += msk[i-1];\r
+                       i = angle->currentIndex();\r
+                       if(i>0) result += dir[i-1];\r
+                       i = msize->value();\r
+                       if(i>1) result += char('0'+i);\r
+               }\r
+               else if(i==17)\r
+               {\r
+                       uint64_t t=0;\r
+                       for(int j=0;j<64;j++)   if(mask_bit[j]->isChecked())    t += uint64_t(1)<<j;\r
+                       result += "{s"+QString::number(t,16)+"}";\r
+                       // TODO get hex-mask\r
+                       i = angle->currentIndex();\r
+                       if(i>0) result += dir[i-1];\r
+                       i = msize->value();\r
+                       if(i>1) result += char('0'+i);\r
+               }\r
+               \r
+               \r
                i = axial->currentIndex();\r
                if(i>0) result = result+':'+char('x'+i-1);\r
                gr.Surf(a,result.toStdString().c_str());\r
                break;\r
        case 2: // text style\r
-               i = cfont->currentIndex();\r
-               if(i>1) result += col[i-1];\r
+               if(font_sch->isChecked())       for(j=0;j<7;j++)\r
+               {\r
+                       i = cc[j]->currentIndex();\r
+                       if(i<1) break;\r
+                       QCharRef c = col[i-1];\r
+                       i = nn[j]->value();\r
+                       if(i!=5)        result += "{"+c+char('0'+i)+"}";\r
+                       else            result += c;\r
+               }\r
+               else\r
+               {\r
+                       i = cfont->currentIndex();\r
+                       if(i>1) result += col[i-1];\r
+               }\r
                result += ':';\r
                if(bold->isChecked())   result += 'b';\r
                if(ital->isChecked())   result += 'i';\r
@@ -384,3 +538,12 @@ void convertFromGraph(QPixmap &pic, mglGraph *gr, uchar **buf)
        pic = QPixmap::fromImage(img);\r
 }\r
 //-----------------------------------------------------------------------------\r
+void StyleDialog::showFontPage()\r
+{      tab->setCurrentIndex(2);        }\r
+//-----------------------------------------------------------------------------\r
+void StyleDialog::showPenPage()\r
+{      tab->setCurrentIndex(0);        }\r
+//-----------------------------------------------------------------------------\r
+void StyleDialog::showSchPage()\r
+{      tab->setCurrentIndex(1);        }\r
+//-----------------------------------------------------------------------------\r
index fd7fe968f9960787d7baee865487ead9a555a54e..348632c5aa160e3aaeedcb9d2be72e1b8eb5e8d7 100644 (file)
@@ -30,6 +30,7 @@ class QCheckBox;
 class QLabel;
 class QLineEdit;
 class QRadioButton;
+class QToolButton;
 //-----------------------------------------------------------------------------
 /// Selecting styles of command (like line style, color scheme, font style, axis style)
 class StyleDialog : public QDialog
@@ -39,6 +40,10 @@ public:
        QString getStyle()      {       return result;  };
        StyleDialog(QWidget *parent = 0);
        ~StyleDialog();
+       
+       void showFontPage();
+       void showPenPage();
+       void showSchPage();
 private slots:
        void updatePic();
 private:
@@ -55,6 +60,13 @@ private:
        QLineEdit *res;
        QRadioButton *rbL, *rbC, *rbR;
        uchar *grBuf;
+       QCheckBox *font_sch;
+       QComboBox *mask;
+       QComboBox *angle;
+       QSlider *msize;
+
+       QToolButton *dash_bit[16];      // 8 buttons for dashing
+       QToolButton *mask_bit[64];      // 8*8 buttons for mask
 };
 //-----------------------------------------------------------------------------
 #endif
diff --git a/udav/subplot_dlg.cpp b/udav/subplot_dlg.cpp
new file mode 100644 (file)
index 0000000..9d80c68
--- /dev/null
@@ -0,0 +1,332 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Alexey Balakin                                  *
+ *   mathgl.abalakin@gmail.com                                             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#include <QPushButton>
+#include <QCheckBox>
+#include <QRadioButton>
+#include <QSpinBox>
+#include <QLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <mgl2/qmathgl.h>
+#include "subplot_dlg.h"
+#include "style_dlg.h"
+//-----------------------------------------------------------------------------
+void convertFromGraph(QPixmap &pic, mglGraph *gr, uchar **buf);
+//-----------------------------------------------------------------------------
+SubplotDialog::SubplotDialog(QWidget *parent) : QDialog(parent)
+{
+       grBuf = 0;
+       setWindowTitle(tr("UDAV - Setup inplot"));
+       QLabel *l;
+       QPushButton *b;
+       QVBoxLayout *v = new QVBoxLayout(this), *u;
+       QGridLayout *g = new QGridLayout;       v->addLayout(g);
+       g->setColumnStretch(2, 1);      g->setColumnStretch(4, 1);
+       g->setColumnStretch(6, 1);      g->setColumnStretch(8, 1);
+       g->setColumnStretch(10, 1);     g->setAlignment(Qt::AlignTop);
+       // SubPlot section
+       cb = new QRadioButton("SubPlot",this);  g->addWidget(cb,0,0);
+       cb->setToolTip(tr("Set drawing area as cell of matrix nx*ny."));
+       connect(cb,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       l = new QLabel("nx",this);      g->addWidget(l,0,1);
+       bn = new QSpinBox(this);        g->addWidget(bn,0,2);
+       bn->setMinimum(1);      bn->setToolTip(tr("Horizontal size"));
+       connect(bn,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("ny",this);      g->addWidget(l,0,3);
+       bm = new QSpinBox(this);        g->addWidget(bm,0,4);
+       bm->setMinimum(1);      bm->setToolTip(tr("Vertical size"));
+       connect(bm,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("ind",this);     g->addWidget(l,0,5);
+       bk = new QSpinBox(this);        g->addWidget(bk,0,6);
+       bk->setMinimum(0);      bk->setToolTip(tr("Cell index"));
+       connect(bk,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+
+       // MultiPlot section
+       cm = new QRadioButton("MultiPlot",this);        g->addWidget(cm,1,0);
+       cm->setToolTip(tr("Set drawing area as cells of matrix nx*ny."));
+       connect(cm,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       l = new QLabel("nx",this);      g->addWidget(l,1,1);
+       mn = new QSpinBox(this);        g->addWidget(mn,1,2);
+       mn->setMinimum(1);      mn->setToolTip(tr("Horizontal size"));
+       connect(mn,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("ny",this);      g->addWidget(l,1,3);
+       mm = new QSpinBox(this);        g->addWidget(mm,1,4);
+       mm->setMinimum(1);      mm->setToolTip(tr("Vertical size"));
+       connect(mm,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("ind",this);     g->addWidget(l,1,5);
+       mk = new QSpinBox(this);        g->addWidget(mk,1,6);
+       mk->setMinimum(0);      mk->setToolTip(tr("Starting cell index"));
+       connect(mk,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("dx",this);      g->addWidget(l,1,7);
+       mx = new QSpinBox(this);        g->addWidget(mx,1,8);
+       mx->setMinimum(1);      mx->setToolTip(tr("Width of selected cells"));
+       connect(mx,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("dy",this);      g->addWidget(l,1,9);
+       my = new QSpinBox(this);        g->addWidget(my,1,10);
+       my->setMinimum(1);      my->setToolTip(tr("Height of selected cells"));
+       connect(my,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+
+       // GridPlot section
+       cg = new QRadioButton("GridPlot",this); g->addWidget(cg,2,0);
+       cg->setToolTip(tr("Set drawing area as cell of matrix nx*ny."));
+       connect(cg,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       l = new QLabel("nx",this);      g->addWidget(l,2,1);
+       gn = new QSpinBox(this);        g->addWidget(gn,2,2);
+       gn->setMinimum(1);      gn->setToolTip(tr("Horizontal size"));
+       connect(gn,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("ny",this);      g->addWidget(l,2,3);
+       gm = new QSpinBox(this);        g->addWidget(gm,2,4);
+       gm->setMinimum(1);      gm->setToolTip(tr("Vertical size"));
+       connect(gm,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("ind",this);     g->addWidget(l,2,5);
+       gk = new QSpinBox(this);        g->addWidget(gk,2,6);
+       gk->setMinimum(0);      gk->setToolTip(tr("Cell index"));
+       connect(gk,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("d",this);       g->addWidget(l,2,7);
+       gd = new QLineEdit(this);       g->addWidget(gd,2,8);
+       gd->setToolTip(tr("Distance between cells"));
+       connect(gd,SIGNAL(textChanged(QString)),this,SLOT(updatePic()));
+
+       // ColumnPlot section
+       cc = new QRadioButton("ColumnPlot",this);       g->addWidget(cc,3,0);
+       cc->setToolTip(tr("Set drawing area as cells of column."));
+       connect(cc,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       l = new QLabel("num",this);     g->addWidget(l,3,1);
+       cn = new QSpinBox(this);        g->addWidget(cn,3,2);
+       cn->setMinimum(1);      cn->setToolTip(tr("Size of column"));
+       connect(cn,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("ind",this);     g->addWidget(l,3,5);
+       ck = new QSpinBox(this);        g->addWidget(ck,3,6);
+       ck->setMinimum(0);      ck->setToolTip(tr("Cell index"));
+       connect(ck,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("d",this);       g->addWidget(l,3,7);
+       cd = new QLineEdit(this);       g->addWidget(cd,3,8);
+       cd->setToolTip(tr("Distance between cells"));
+       connect(cd,SIGNAL(textChanged(QString)),this,SLOT(updatePic()));
+
+       // StickPlot section
+       cs = new QRadioButton("StickPlot",this);        g->addWidget(cs,4,0);
+       cs->setToolTip(tr("Set drawing area as cells of stick."));
+       connect(cc,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       l = new QLabel("num",this);     g->addWidget(l,4,1);
+       sn = new QSpinBox(this);        g->addWidget(sn,4,2);
+       sn->setMinimum(1);      sn->setToolTip(tr("Size of stick"));
+       connect(sn,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("ind",this);     g->addWidget(l,4,5);
+       sk = new QSpinBox(this);        g->addWidget(sk,4,6);
+       sk->setMinimum(0);      sk->setToolTip(tr("Cell index"));
+       connect(sk,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+
+       // InPlot section
+       ci = new QRadioButton("InPlot",this);   g->addWidget(ci,5,0);
+       ci->setToolTip(tr("Set drawing area as cells of matrix nx*ny."));
+       connect(ci,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       l = new QLabel("x1",this);      g->addWidget(l,5,1);
+       x1 = new QLineEdit(this);       g->addWidget(x1,5,2);
+       x1->setText("0");       x1->setToolTip(tr("Left bottom edge"));
+       connect(x1,SIGNAL(textChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("x2",this);      g->addWidget(l,5,3);
+       x2 = new QLineEdit(this);       g->addWidget(x2,5,4);
+       x2->setText("1");       x2->setToolTip(tr("Right bottom edge"));
+       connect(x2,SIGNAL(textChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("y1",this);      g->addWidget(l,5,5);
+       y1 = new QLineEdit(this);       g->addWidget(y1,5,6);
+       y1->setText("0");       y1->setToolTip(tr("Left top edge"));
+       connect(y1,SIGNAL(textChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel("y2",this);      g->addWidget(l,5,7);
+       y2 = new QLineEdit(this);       g->addWidget(y2,5,8);
+       y2->setText("1");       y2->setToolTip(tr("Right top edge"));
+       connect(y2,SIGNAL(textChanged(QString)),this,SLOT(updatePic()));
+
+       QHBoxLayout *h, *H;
+       h = new QHBoxLayout;    v->addLayout(h);
+       u = new QVBoxLayout;    h->addLayout(u);
+
+       H = new QHBoxLayout;    u->addLayout(H);
+       l = new QLabel(tr("Rotate on"),this);   H->addWidget(l);
+       l = new QLabel(QString::fromWCharArray(L"θ"),this);    H->addWidget(l);
+       tet = new QSpinBox(this);       H->addWidget(tet,1);    tet->setValue(0);       tet->setSingleStep(5);
+       tet->setToolTip(tr("Angle around x axis (in degrees)"));
+       connect(tet,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel(QString::fromWCharArray(L"φ"),this);    H->addWidget(l);
+       phi = new QSpinBox(this);       H->addWidget(phi,1);    phi->setValue(0);       phi->setSingleStep(5);
+       phi->setToolTip(tr("Angle around z axis (in degrees)"));
+       connect(phi,SIGNAL(valueChanged(QString)),this,SLOT(updatePic()));
+
+       H = new QHBoxLayout;    u->addLayout(H);
+       l = new QLabel(tr("Aspect"),this);      H->addWidget(l);
+       l = new QLabel(tr("X/Z"),this); H->addWidget(l);
+       axz = new QLineEdit(this);      H->addWidget(axz);      axz->setText("1");
+       axz->setToolTip(tr("Aspect ratio of x-scale to z-acale"));
+       connect(axz,SIGNAL(textChanged(QString)),this,SLOT(updatePic()));
+       l = new QLabel(tr("Y/Z"),this); H->addWidget(l);
+       ayz = new QLineEdit(this);      H->addWidget(ayz);      ayz->setText("1");
+       ayz->setToolTip(tr("Aspect ratio of y-scale to z-acale"));
+       connect(ayz,SIGNAL(textChanged(QString)),this,SLOT(updatePic()));
+
+       H = new QHBoxLayout;    u->addLayout(H);
+       l = new QLabel(tr("Reserve at"),this);  H->addWidget(l);
+       rl = new QCheckBox(tr("left"),this);    H->addWidget(rl);       rl->setChecked(true);
+       rl->setToolTip(tr("Reserve space for labels at left side (style '<')"));
+       rb = new QCheckBox(tr("bottom"),this);  H->addWidget(rb);       rb->setChecked(true);
+       rb->setToolTip(tr("Reserve space for labels at bottom side (style '_')"));
+       rt = new QCheckBox(tr("top"),this);             H->addWidget(rt);       rt->setChecked(true);
+       rt->setToolTip(tr("Reserve space for labels at top side (style '^')"));
+       rr = new QCheckBox(tr("right"),this);   H->addWidget(rr);       rr->setChecked(true);
+       rr->setToolTip(tr("Reserve space for labels at right side (style '>')"));
+       rw = new QCheckBox(tr("Whole area"),this);      H->addWidget(rw);
+       rw->setToolTip(tr("Set to use whole area (style '#')"));
+       connect(rl,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       connect(rr,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       connect(rt,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       connect(rb,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+       connect(rw,SIGNAL(toggled(bool)),this,SLOT(updatePic()));
+
+       H = new QHBoxLayout;    u->addLayout(H);
+       l = new QLabel(tr("Title"),this);       H->addWidget(l);
+       title = new QLineEdit(this);            H->addWidget(title);
+       title->setToolTip(tr("Title for plot. Can be used in SubPlot or MultiPlot only."));
+       connect(title,SIGNAL(textChanged(QString)),this,SLOT(updatePic()));
+       b = new QPushButton(tr("Style"),this);  H->addWidget(b);
+       connect(b, SIGNAL(clicked()),this, SLOT(titleStl()));
+
+       H = new QHBoxLayout;    u->addLayout(H);
+       l = new QLabel(tr("Result is"),this);   H->addWidget(l);
+       res = new QLineEdit(this);              H->addWidget(res);      res->setReadOnly(true);
+       res->setToolTip(tr("Resulting string."));
+
+       pic = new QLabel(this); h->addWidget(pic,1);
+
+       h = new QHBoxLayout;    v->addLayout(h);        h->addStretch(1);
+       b = new QPushButton(tr("Cancel"),this); h->addWidget(b);
+       connect(b, SIGNAL(clicked()),this, SLOT(reject()));
+       b = new QPushButton(tr("OK"), this);    h->addWidget(b);        b->setDefault(true);
+       connect(b, SIGNAL(clicked()),this, SLOT(finish()));
+       
+       stlDialog = new StyleDialog(this);
+}
+//-----------------------------------------------------------------------------
+SubplotDialog::~SubplotDialog()        {       if(grBuf)       delete []grBuf; }
+//-----------------------------------------------------------------------------
+void SubplotDialog::finish()   {       accept();       emit result(cmd);       }
+//-----------------------------------------------------------------------------
+void SubplotDialog::updatePic()
+{
+       static mglGraph gr;     gr.SetSize(pic->width(),pic->height());
+       mglParse par;
+
+       setlocale(LC_NUMERIC, "C");
+       QString stl="'";        // style for subplot
+       if(rb->isChecked())     stl+='_';
+       if(rl->isChecked())     stl+='<';
+       if(rr->isChecked())     stl+='>';
+       if(rt->isChecked())     stl+='^';
+       if(rw->isChecked())     stl+='#';
+       stl += '\'';
+       if(stl=="'_<>^'")       stl="";
+       int Tet = tet->value(), Phi = phi->value();
+       int Ax = 1, Ay = 1;
+       if(!axz->text().isEmpty())      Ax = axz->text().toDouble();
+       if(!ayz->text().isEmpty())      Ay = ayz->text().toDouble();
+
+       if(cb->isChecked())     // subplot
+       {
+               int n=bn->value(), m=bm->value(), k=bk->value();
+               for(int i=0;i<n*m;i++)  if(i!=k)        {       gr.SubPlot(n,m,i);      gr.Box("h");    }
+               cmd = "subplot "+QString::number(n)+" "+QString::number(m)+" "+QString::number(k)+" "+stl;
+               if(!title->text().isEmpty())
+               {       cmd += ":title '"+title->text()+"'";    if(!fmt.isEmpty())      cmd += fmt;     }
+               if(Tet || Phi)  cmd += ":rotate "+QString::number(Tet)+" "+QString::number(Phi);
+               if(Ax!=1 || Ay!=1)      cmd += ":aspect "+QString::number(Ax)+" "+QString::number(Ay);
+               par.Execute(&gr, cmd.toStdWString().c_str());   gr.Box();
+               res->setText(cmd);
+       }
+       else if(cm->isChecked())        // multiplot
+       {
+               int n=mn->value(), m=mm->value(), k=mk->value(), dx=mx->value(), dy=my->value();
+               for(int i=0;i<n*m;i++)  if(i!=k)        {       gr.SubPlot(n,m,i);      gr.Box("h");    }
+               cmd = "multiplot "+QString::number(n)+" "+QString::number(m)+" "+QString::number(k)+" "+QString::number(dx)+" "+QString::number(dy)+" "+stl;
+               if(!title->text().isEmpty())
+               {       cmd += ":title '"+title->text()+"'";    if(!fmt.isEmpty())      cmd += fmt;     }
+               if(Tet || Phi)  cmd += ":rotate "+QString::number(Tet)+" "+QString::number(Phi);
+               if(Ax!=1 || Ay!=1)      cmd += ":aspect "+QString::number(Ax)+" "+QString::number(Ay);
+               par.Execute(&gr, cmd.toStdWString().c_str());   gr.Box();
+               res->setText(cmd);
+       }
+       else if(cg->isChecked())        // gridplot
+       {
+               int n=gn->value(), m=gm->value(), k=gk->value();
+               double d = gd->text().isEmpty()?0:gd->text().toDouble();
+               for(int i=0;i<n*m;i++)  if(i!=k)        {       gr.GridPlot(n,m,i,d);   gr.Box("h");    }
+               cmd = "gridplot "+QString::number(n)+" "+QString::number(m)+" "+QString::number(k)+" "+QString::number(d);
+               if(Ax!=1 || Ay!=1)      cmd += ":aspect "+QString::number(Ax)+" "+QString::number(Ay);
+               par.Execute(&gr, cmd.toStdWString().c_str());   gr.Box();
+               res->setText(cmd);
+       }
+       else if(cs->isChecked())        // stickplot
+       {
+               int n=sn->value(), k=sk->value();
+               for(int i=0;i<n;i++)    if(i!=k)        {       gr.StickPlot(n,i,Tet,Phi);      gr.Box("h");    }
+               cmd = "stickplot "+QString::number(n)+" "+QString::number(k)+" "+QString::number(Tet)+" "+QString::number(Phi);
+               if(Ax!=1 || Ay!=1)      cmd += ":aspect "+QString::number(Ax)+" "+QString::number(Ay);
+               par.Execute(&gr, cmd.toStdWString().c_str());   gr.Box();
+               res->setText(cmd);
+       }
+       else if(cc->isChecked())        // columnplot   // TODO add angles
+       {
+               int n=cn->value(), k=ck->value();
+               double d = cd->text().isEmpty()?0:cd->text().toDouble();
+               for(int i=0;i<n;i++)    if(i!=k)        {       gr.ColumnPlot(n,i,d);   gr.Rotate(Tet,Phi);     gr.Box("h");    }
+               cmd = "columnplot "+QString::number(n)+" "+QString::number(k)+" "+QString::number(d);
+               if(Tet || Phi)  cmd += ":rotate "+QString::number(Tet)+" "+QString::number(Phi);
+               if(Ax!=1 || Ay!=1)      cmd += ":aspect "+QString::number(Ax)+" "+QString::number(Ay);
+               par.Execute(&gr, cmd.toStdWString().c_str());   gr.Box();
+               res->setText(cmd);
+       }
+       else if(ci->isChecked())        // inplot
+       {
+               {       gr.SubPlot(1,1,0);      gr.Box("h");    }
+               cmd = "inplot "+x1->text()+" "+x2->text()+" "+y1->text()+" "+y2->text();
+               if(!title->text().isEmpty())
+               {       cmd += ":title '"+title->text()+"'";    if(!fmt.isEmpty())      cmd += fmt;     }
+               if(Tet || Phi)  cmd += ":rotate "+QString::number(Tet)+" "+QString::number(Phi);
+               if(Ax!=1 || Ay!=1)      cmd += ":aspect "+QString::number(Ax)+" "+QString::number(Ay);
+               par.Execute(&gr, cmd.toStdWString().c_str());   gr.Box();
+               res->setText(cmd);
+       }
+       setlocale(LC_NUMERIC, "");
+
+       
+       QPixmap p;
+       convertFromGraph(p, &gr, &grBuf);
+       pic->setPixmap(p);
+}
+//-----------------------------------------------------------------------------
+void SubplotDialog::titleStl()
+{
+       stlDialog->showFontPage();
+       if(stlDialog->exec())   {       fmt = " "+stlDialog->getStyle();        updatePic();    }
+}
+//-----------------------------------------------------------------------------
+void SubplotDialog::parseCmd(const QString& txt, bool final)
+{
+
+}
+//-----------------------------------------------------------------------------
diff --git a/udav/subplot_dlg.h b/udav/subplot_dlg.h
new file mode 100644 (file)
index 0000000..942c933
--- /dev/null
@@ -0,0 +1,68 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Alexey Balakin                                  *
+ *   mathgl.abalakin@gmail.com                                             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef SUBPLOTDIALOG_H
+#define SUBPLOTDIALOG_H
+//-----------------------------------------------------------------------------
+#include <QDialog>
+class QRadioButton;
+class QSpinBox;
+class QCheckBox;
+class QLabel;
+class QLineEdit;
+class StyleDialog;
+//-----------------------------------------------------------------------------
+class SubplotDialog : public QDialog
+{
+Q_OBJECT
+public:
+       SubplotDialog(QWidget *p);
+       ~SubplotDialog();
+       const QString &getCommand()     {       return cmd;     }
+public slots:
+       void parseCmd(const QString &txt, bool final=true);
+       void finish();
+signals:
+       void result(const QString &txt);
+private slots:
+       void updatePic();
+       void titleStl();
+private:
+       QRadioButton *cb, *ci, *cm, *cg, *cc, *cs;
+       QSpinBox *tet, *phi;
+       QLineEdit *axz, *ayz;
+       QLineEdit *title, *res;
+       QSpinBox *bn,*bm,*bk;                   // subplot
+       QLineEdit *x1,*x2,*y1,*y2;              // inplot
+       QSpinBox *sn,*sk;                               // stickplot
+       QSpinBox *mn,*mm,*mk,*mx,*my;   // multiplot
+       QSpinBox *gm,*gn,*gk;                   // gridplot
+       QSpinBox *cn,*ck;                               // columnplot
+       QLineEdit *cd, *gd;
+       QCheckBox *rb,*rr,*rl,*rt,*rw;  // style (where reserve)
+       QString cmd;    // resulting command
+       QString fmt;    // format for title
+       QLabel *pic;    // resulting image
+//     bool replace;   // flag to be used in result() signal
+       uchar *grBuf;
+       StyleDialog *stlDialog;
+};
+//-----------------------------------------------------------------------------
+#endif // SUBPLOTDIALOG_H
+//-----------------------------------------------------------------------------
index 8bc78ab08068333d7b8134fe4b51136a9c2910a9..c25662bbb7ae11da4b0f8d403232e28ac44aa24f 100644 (file)
@@ -38,6 +38,7 @@
 #include "setup_dlg.h"
 #include "text_pnl.h"
 #include "plot_pnl.h"
+#include "subplot_dlg.h"
 //-----------------------------------------------------------------------------
 FilesDialog *files_dlg=0;
 QString defFontFamily;
@@ -55,6 +56,7 @@ TextPanel::TextPanel(QWidget *parent) : QWidget(parent)
        optDialog = new OptionDialog(this);
        stlDialog = new StyleDialog(this);
        newCmdDlg = new NewCmdDialog(this);
+       subplotDlg = new SubplotDialog(this);
        setupDlg = new SetupDialog(this);
        dataOpenDlg = createDataOpenDlg(this);
        if(!files_dlg)  files_dlg= new FilesDialog;
@@ -64,7 +66,8 @@ TextPanel::TextPanel(QWidget *parent) : QWidget(parent)
        vars = words;
 
        connect(setupDlg, SIGNAL(putText(const QString &)), this, SLOT(animPutText(const QString &)));
-       connect(newCmdDlg, SIGNAL(result(const QString&)), this, SLOT(putLine(const QString&)));
+       connect(newCmdDlg, SIGNAL(result(const QString&, bool)), this, SLOT(putLine(const QString&, bool)));
+       connect(subplotDlg, SIGNAL(result(const QString&)), this, SLOT(putLine(const QString&)));
        connect(findDialog, SIGNAL(findText(const QString &, bool, bool)), this, SLOT(findText(const QString &, bool, bool)));
        connect(findDialog, SIGNAL(replText(const QString &, const QString &, bool, bool)), this, SLOT(replText(const QString &, const QString &, bool, bool)));
 
@@ -79,7 +82,8 @@ TextPanel::TextPanel(QWidget *parent) : QWidget(parent)
        menu = new QMenu(tr("Edit"),this);
        v = new QVBoxLayout(this);
        h = new QHBoxLayout();  v->addLayout(h);
-       toolTop(h);                             v->addWidget(edit);
+       toolTop(h);
+       v->addWidget(edit);
 }
 //-----------------------------------------------------------------------------
 TextPanel::~TextPanel()        {       delete printer; }
@@ -112,6 +116,19 @@ void TextPanel::insNVal()
        edit->textCursor().insertText(QString::number(res.GetVal(0)));
 }
 //-----------------------------------------------------------------------------
+void TextPanel::insPrim()
+{
+       QString str(graph->mgl->primitives);
+       if(str.isEmpty())
+       {
+               QMessageBox::warning(this,tr("UDAV"),tr("There is manual primitives."));
+               return;
+       }
+       edit->moveCursor(QTextCursor::Start);
+       edit->insertPlainText("subplot 1 1 0 '#'\n"+str+"subplot 1 1 0\n#----------\n");
+       graph->mgl->primitives = "";
+}
+//-----------------------------------------------------------------------------
 void TextPanel::insFitF()
 {
        QString str(graph->getFit());
@@ -132,7 +149,7 @@ void TextPanel::insFile()
 //-----------------------------------------------------------------------------
 void TextPanel::insPath()
 {
-       QString str = QFileDialog::getExistingDirectory(this, tr("UDAV - Insert filename"));
+       QString str = QFileDialog::getExistingDirectory(this, tr("UDAV - Insert path"));
        if(str.isEmpty())       return;
        edit->textCursor().insertText("'"+str+"'");
 }
@@ -140,11 +157,11 @@ void TextPanel::insPath()
 void TextPanel::refreshData()
 {
        vars=words;
-       mglVar *v = parser.FindVar("");
-       while(v)
+       long i,n=parser.GetNumVar();
+       for(i=0;i<n;i++)
        {
-               if(v->s.length()>2)     vars<<QString::fromStdWString(v->s);
-               v = v->next;
+               const mglDataA *v=parser.GetVar(i);
+               if(v && v->s.length()>2)        vars<<QString::fromStdWString(v->s);
        }
        setCompleter(mglCompleter);
 }
@@ -208,9 +225,20 @@ void TextPanel::animPutText(const QString &s)
 //-----------------------------------------------------------------------------
 //void TextPanel::putText(const QString &txt)  {       edit->insertPlainText(txt);     }
 //-----------------------------------------------------------------------------
-void TextPanel::putLine(const QString &txt)
-{      edit->moveCursor(QTextCursor::StartOfLine);
-       edit->insertPlainText(txt+"\n");        }
+void TextPanel::putLine(const QString &txt, bool replace)
+{
+       edit->moveCursor(QTextCursor::StartOfLine);
+       if(replace)
+       {
+               QTextCursor c = edit->textCursor();
+               c.select(QTextCursor::BlockUnderCursor);
+               c.removeSelectedText();
+               edit->setTextCursor(c);
+               if(c.atStart()) edit->insertPlainText(txt);
+               else    edit->insertPlainText("\n"+txt);
+       }
+       else    edit->insertPlainText(txt+"\n");
+}
 //-----------------------------------------------------------------------------
 void TextPanel::addStyle()
 {
@@ -237,7 +265,6 @@ QString TextPanel::selection()
 //-----------------------------------------------------------------------------
 void TextPanel::setCursorPosition(int n)
 {
-       graph->setCurPos(n);
        if(n<0) return;
        edit->moveCursor(QTextCursor::Start);
        for(int i=0;i<n;i++)    edit->moveCursor(QTextCursor::NextBlock);
@@ -281,10 +308,10 @@ void TextPanel::loadHDF5(const QString &fileName)
                        H5Dread(hd, H5T_C_S1, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
                        buf[dims[0]]=0;         // to be sure :)
                        QString str = buf;
-                       if(str.contains("#----- End of QMathGL block -----\n"))
+                       if(str.contains("subplot 1 1 0\n#----- End of QMathGL block -----\n"))
                        {
-                               graph->mgl->primitives = str.section("#----- End of QMathGL block -----\n",0,0);
-                               str = str.section("#----- End of QMathGL block -----\n",1);
+                               graph->mgl->primitives = str.section("subplot 1 1 0\n#----- End of QMathGL block -----\n",0,0).section("subplot 1 1 0 '#'\n",1);
+                               str = str.section("subplot 1 1 0\n#----- End of QMathGL block -----\n",1);
                        }
                        edit->setText(str);
                        graph->animParseText(edit->toPlainText());
@@ -296,7 +323,7 @@ void TextPanel::loadHDF5(const QString &fileName)
                else if(H5Tget_class(ht)==H5T_FLOAT || H5Tget_class(ht)==H5T_INTEGER)
                {
                        for(int j=0;name[j];j++)        if(!isalnum(name[j]))   name[j]='_';
-                       mglVar *v = parser.AddVar(name);
+                       mglData *v = parser.AddVar(name);
                        nx = ny = nz = 1;
                        if(rank>0 && rank<=3)
                        {
@@ -336,7 +363,7 @@ void TextPanel::saveHDF5(const QString &fileName)
        {       // save script
                QString txt;
                if(!graph->mgl->primitives.isEmpty())
-                       txt += graph->mgl->primitives + "#----- End of QMathGL block -----";
+                       txt += "subplot 1 1 0 '#'\n"+graph->mgl->primitives + "subplot 1 1 0\n#----- End of QMathGL block -----\n";
                txt += edit->toPlainText();
                dims[0] = txt.length()+1;
                char *buf = new char[dims[0]+1];
@@ -348,10 +375,13 @@ void TextPanel::saveHDF5(const QString &fileName)
                H5Dclose(hd);   H5Sclose(hs);
                delete []buf;
        }
-       mglVar *v = parser.FindVar("");
+       long n = parser.GetNumVar();
        char name[256];
-       while(v)
+       for(long i=0;i<n;i++)
        {
+               const mglData *v = dynamic_cast<const mglData *>(parser.GetVar(i));
+               mglData tmp;
+               if(!v)  {       tmp.Set(parser.GetVar(i));      v = &tmp;       }
                wcstombs(name,v->s.c_str(),v->s.length()+1);
                if(v->nz==1 && v->ny == 1)
                {       rank = 1;       dims[0] = v->nx;        }
@@ -364,7 +394,6 @@ void TextPanel::saveHDF5(const QString &fileName)
 
                H5Dwrite(hd, H5T_NATIVE_FLOAT, hs, hs, H5P_DEFAULT, v->a);
                H5Dclose(hd);   H5Sclose(hs);
-               v = v->next;
        }
        H5Fclose(hf);
        setCurrentFile(fileName);
@@ -461,13 +490,16 @@ void TextPanel::addSetup()        {       setupDlg->exec();       }
 //-----------------------------------------------------------------------------
 #include "xpm/option.xpm"
 #include "xpm/style.xpm"
+#include "xpm/curve.xpm"
+#include "xpm/box.xpm"
 //-----------------------------------------------------------------------------
 void TextPanel::toolTop(QBoxLayout *l)
 {
-       QAction *a;
+       QAction *a, *aa;
        QMenu *o=menu, *oo;
        QToolButton *bb;
        const MainWindow *mw=findMain(this);
+//     l->setSpacing(3);
 
        // general buttons
        if(mw)
@@ -476,13 +508,13 @@ void TextPanel::toolTop(QBoxLayout *l)
                bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(mw->asave);
        }
        // edit menu
-       a = new QAction(QPixmap(":/xpm/edit-undo.png"), tr("Undo"), this);
+       a = new QAction(QPixmap(":/png/edit-undo.png"), tr("Undo"), this);
        connect(a, SIGNAL(triggered()), edit, SLOT(undo()));
        a->setToolTip(tr("Undo editor change (Ctrl+Z)."));
        a->setShortcut(Qt::CTRL+Qt::Key_Z);     o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/edit-redo.png"), tr("Redo"), this);
+       a = new QAction(QPixmap(":/png/edit-redo.png"), tr("Redo"), this);
        connect(a, SIGNAL(triggered()), edit, SLOT(redo()));
        a->setToolTip(tr("Redo editor change (Ctrl+Shift+Z)."));
        a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_Z);   o->addAction(a);
@@ -490,28 +522,28 @@ void TextPanel::toolTop(QBoxLayout *l)
 
        o->addSeparator();
        o->addAction(tr("Clear all"), edit, SLOT(clear()));
-       a = new QAction(QPixmap(":/xpm/edit-cut.png"), tr("Cut text"), this);
+       a = new QAction(QPixmap(":/png/edit-cut.png"), tr("Cut text"), this);
        connect(a, SIGNAL(triggered()), edit, SLOT(cut()));
        a->setToolTip(tr("Cut selected text to clipboard (Ctrl+X)."));
        a->setShortcut(Qt::CTRL+Qt::Key_X);     o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/edit-copy.png"), tr("Copy text"), this);
+       a = new QAction(QPixmap(":/png/edit-copy.png"), tr("Copy text"), this);
        connect(a, SIGNAL(triggered()), edit, SLOT(copy()));
        a->setToolTip(tr("Copy selected text or data to clipboard (Ctrl+C)."));
        a->setShortcut(Qt::CTRL+Qt::Key_C);     o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       a = new QAction(QPixmap(":/xpm/edit-paste.png"), tr("Paste text"), this);
+       a = new QAction(QPixmap(":/png/edit-paste.png"), tr("Paste text"), this);
        connect(a, SIGNAL(triggered()), edit, SLOT(paste()));
        a->setToolTip(tr("Paste text or data from clipboard (Ctrl+V)."));
        a->setShortcut(Qt::CTRL+Qt::Key_V);     o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
-       o->addAction(QPixmap(":/xpm/edit-select-all.png"), tr("Select all"), edit, SLOT(selectAll()), Qt::CTRL+Qt::Key_A);
+       o->addAction(QPixmap(":/png/edit-select-all.png"), tr("Select all"), edit, SLOT(selectAll()), Qt::CTRL+Qt::Key_A);
        o->addSeparator();
 
-       a = new QAction(QPixmap(":/xpm/edit-find.png"), tr("Find/Replace"), this);
+       a = new QAction(QPixmap(":/png/edit-find.png"), tr("Find/Replace"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(find()));
        a->setToolTip(tr("Show dialog for text finding (Ctrl+F)."));
        a->setShortcut(Qt::CTRL+Qt::Key_F);     o->addAction(a);
@@ -524,11 +556,14 @@ void TextPanel::toolTop(QBoxLayout *l)
 
        // insert menu
        oo = o->addMenu(tr("Insert"));
-       a = new QAction(QPixmap(":/xpm/format-indent-more.png"), tr("New command"), this);
+       aa=a = new QAction(QPixmap(":/png/format-indent-more.png"), tr("New command"), this);
        a->setShortcut(Qt::META+Qt::Key_C);     connect(a, SIGNAL(triggered()), this, SLOT(newCmd()));
-       a->setToolTip(tr("Show dialog for new command and put it into the script."));
+       a->setToolTip(tr("Show dialog for new command or edit arguments of existed one."));
+       oo->addAction(a);
+       a = new QAction(QPixmap(box_xpm), tr("New inplot"), this);
+       a->setShortcut(Qt::META+Qt::Key_C);     connect(a, SIGNAL(triggered()), subplotDlg, SLOT(show()));
+       a->setToolTip(tr("Show dialog for new inplot and put it into the script."));
        oo->addAction(a);
-       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
        a = new QAction(tr("Fitted formula"), this);
        a->setShortcut(Qt::META+Qt::Key_F);     connect(a, SIGNAL(triggered()), this, SLOT(insFitF()));
@@ -546,22 +581,30 @@ void TextPanel::toolTop(QBoxLayout *l)
        a->setShortcut(Qt::META+Qt::Key_N);     connect(a, SIGNAL(triggered()), this, SLOT(insNVal()));
        a->setToolTip(tr("Replace expression by its numerical value."));
        oo->addAction(a);
-       a = new QAction(QPixmap(":/xpm/x-office-spreadsheet.png"), tr("File name"), this);
+       a = new QAction(QPixmap(":/png/text-csv.png"), tr("File name"), this);
        a->setShortcut(Qt::META+Qt::Key_P);     connect(a, SIGNAL(triggered()), this, SLOT(insFile()));
        a->setToolTip(tr("Select and insert file name."));
        oo->addAction(a);
-       a = new QAction(QPixmap(":/xpm/folder.png"), tr("Folder path"), this);
+       a = new QAction(QPixmap(":/png/folder.png"), tr("Folder path"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(insPath()));
        a->setToolTip(tr("Select and insert folder name."));
        oo->addAction(a);
+       a = new QAction(QPixmap(curve_xpm), tr("Manual primitives"), this);
+       a->setShortcut(Qt::META+Qt::Key_P);     connect(a, SIGNAL(triggered()), this, SLOT(insPrim()));
+       a->setToolTip(tr("Move mouse-handled primitives to script."));
+       oo->addAction(a);
 
-       a = new QAction(QPixmap(":/xpm/document-properties.png"), tr("Graphics setup"), this);
+       bb = new QToolButton(this);     l->addWidget(bb);
+       bb->setDefaultAction(aa);       bb->setMenu(oo);
+       bb->setPopupMode(QToolButton::MenuButtonPopup);
+
+       a = new QAction(QPixmap(":/png/document-properties.png"), tr("Graphics setup"), this);
        a->setShortcut(Qt::META+Qt::Key_G);     connect(a, SIGNAL(triggered()), this, SLOT(addSetup()));
        a->setToolTip(tr("Show dialog for plot setup and put code into the script.\nThis dialog setup axis, labels, lighting and other general things."));
-       oo->addAction(a);
+       o->addAction(a);
        bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(a);
 
        l->addStretch(1);
-       if(mw)  bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(mw->acalc);
+       if(mw)  {       bb = new QToolButton(this);     l->addWidget(bb);       bb->setDefaultAction(mw->acalc);        }
 }
 //-----------------------------------------------------------------------------
index 5d86d492280f997c05a600c76a2cf907029a4cf7..213a5f149b62d09f7a7558090dff702c5c615d4a 100644 (file)
@@ -33,6 +33,7 @@ class StyleDialog;
 class SetupDialog;
 class NewCmdDialog;
 class PlotPanel;
+class SubplotDialog;
 //-----------------------------------------------------------------------------
 class TextPanel : public QWidget
 {
@@ -42,6 +43,7 @@ public:
        TextEdit *edit;         ///< script itself
        PlotPanel *graph;       ///< NOTE: have to be filled!!!
        NewCmdDialog *newCmdDlg;
+       SubplotDialog *subplotDlg;
 
        TextPanel(QWidget *parent = 0);
        ~TextPanel();
@@ -63,7 +65,7 @@ public slots:
 //     void setEditPos(bool bottom);
        void animPutText(const QString &);
 //     void putText(const QString &txt);
-       void putLine(const QString &txt);
+       void putLine(const QString &txt, bool replace=false);
        void setCursorPosition(int);
 
        void addOptions();
@@ -72,6 +74,7 @@ public slots:
        void insFile();
        void insPath();
        void insFitF();
+       void insPrim();
        void newCmd(int n=-1);
        void addSetup();
 
index 67717376030eb0cac7ea5d42c8dbdf950de6691c..a7b22378f7cbffce466a5ce07b813e4d967e1797 100644 (file)
@@ -1,48 +1,67 @@
 <RCC>
-    <qresource prefix="/">
-        <file>udav.png</file>
-        <file>xpm/document-new.png</file>
-        <file>xpm/document-open.png</file>
-        <file>xpm/document-print.png</file>
-        <file>xpm/document-save.png</file>
-        <file>xpm/document-properties.png</file>
-        <file>xpm/document-export.png</file>
-        <file>xpm/document-import.png</file>
-        <file>xpm/alpha.png</file>
-        <file>xpm/preferences-system.png</file>
-        <file>xpm/edit-cut.png</file>
-        <file>xpm/edit-copy.png</file>
-        <file>xpm/edit-delete.png</file>
-        <file>xpm/edit-paste.png</file>
-        <file>xpm/edit-select-all.png</file>
-        <file>xpm/edit-find.png</file>
-        <file>xpm/edit-redo.png</file>
-        <file>xpm/edit-undo.png</file>
-        <file>xpm/process-stop.png</file>
-        <file>xpm/zoom-out.png</file>
-        <file>xpm/zoom-in.png</file>
-        <file>xpm/zoom-original.png</file>
-        <file>xpm/zoom-fit-best.png</file>
-        <file>xpm/view-refresh.png</file>
-        <file>xpm/weather-clear.png</file>
-        <file>xpm/help-contents.png</file>
-        <file>xpm/help-faq.png</file>
-        <file>xpm/go-first.png</file>
-        <file>xpm/go-last.png</file>
-        <file>xpm/go-previous.png</file>
-        <file>xpm/go-next.png</file>
-        <file>xpm/go-down.png</file>
-        <file>xpm/go-up.png</file>
-        <file>xpm/media-seek-backward.png</file>
-        <file>xpm/media-seek-forward.png</file>
-        <file>xpm/film-b.png</file>
-        <file>xpm/object-rotate-right.png</file>
-        <file>xpm/accessories-calculator.png</file>
-        <file>xpm/format-indent-more.png</file>
-        <file>xpm/x-office-spreadsheet.png</file>
-        <file>xpm/folder.png</file>
-        <file>xpm/text-x-generic.png</file>
-        <file>xpm/x-office-presentation.png</file>
-        <file>xpm/system-file-manager.png</file>
-    </qresource>
+       <qresource prefix="/">
+               <file>udav.png</file>
+               <file>png/document-new.png</file>
+               <file>png/document-open.png</file>
+               <file>png/document-print.png</file>
+               <file>png/document-save.png</file>
+               <file>png/document-properties.png</file>
+               <file>png/document-export.png</file>
+               <file>png/document-import.png</file>
+               <file>png/document-revert.png</file>
+               <file>png/alpha.png</file>
+               <file>png/preferences-system.png</file>
+               <file>png/edit-clear.png</file>
+               <file>png/edit-cut.png</file>
+               <file>png/edit-copy.png</file>
+               <file>png/edit-delete.png</file>
+               <file>png/edit-paste.png</file>
+               <file>png/edit-select-all.png</file>
+               <file>png/edit-find.png</file>
+               <file>png/edit-redo.png</file>
+               <file>png/edit-undo.png</file>
+               <file>png/process-stop.png</file>
+               <file>png/zoom-out.png</file>
+               <file>png/zoom-in.png</file>
+               <file>png/zoom-original.png</file>
+               <file>png/zoom-draw.png</file>
+               <file>png/view-refresh.png</file>
+               <file>png/weather-clear.png</file>
+               <file>png/weather-clouds.png</file>
+               <file>png/help-contents.png</file>
+               <file>png/help-faq.png</file>
+               <file>png/go-first.png</file>
+               <file>png/go-last.png</file>
+               <file>png/go-previous.png</file>
+               <file>png/go-next.png</file>
+               <file>png/go-down.png</file>
+               <file>png/go-up.png</file>
+               <file>png/arrow-down.png</file>
+               <file>png/arrow-up.png</file>
+               <file>png/arrow-left.png</file>
+               <file>png/arrow-right.png</file>
+               <file>png/media-seek-backward.png</file>
+               <file>png/media-seek-forward.png</file>
+               <file>png/media-playback-start.png</file>
+               <file>png/transform-move.png</file>
+               <file>png/accessories-calculator.png</file>
+               <file>png/format-indent-more.png</file>
+               <file>png/text-csv.png</file>
+               <file>png/folder.png</file>
+               <file>png/text-plain.png</file>
+               <file>png/office-chart-line.png</file>
+               <file>png/system-file-manager.png</file>
+               <file>png/view-grid.png</file>
+               <file>png/view-fullscreen.png</file>
+               <file>png/tab-close.png</file>
+               <file>png/layer-visible-off.png</file>
+               <file>png/layer-visible-on.png</file>
+               <file>png/object-order-lower.png</file>
+               <file>png/object-order-raise.png</file>
+               <file>png/object-rotate-up.png</file>
+               <file>png/object-rotate-down.png</file>
+               <file>png/object-rotate-left.png</file>
+               <file>png/object-rotate-right.png</file>
+               <file>png/tools-wizard.png</file>
+       </qresource>
 </RCC>
index 5d5f7dc33385f117c8ddc94d136f85c80fe688b8..adcefe5c9244821cd4b37068770d0c6f98acd849 100644 (file)
@@ -23,8 +23,6 @@
 #else
 #include <unistd.h>
 #endif
-#include <QUrl>
-#include <QFile>
 #include <QMenuBar>
 #include <QMessageBox>
 #include <QApplication>
 #include <QSplitter>
 #include <QFileDialog>
 #include <QStatusBar>
-#include <QTextStream>
 #include <QDockWidget>
 #include <QCloseEvent>
 #include <QTextCodec>
 #include <QTranslator>
-#include <QVariant>
 #include <QMimeData>
+#include <QUrl>
 //-----------------------------------------------------------------------------
 #if !defined(WIN32) && !defined(__APPLE__)
 #include <X11/Xlib.h>
@@ -59,6 +56,7 @@ int MaxRecentFiles=5;
 bool editPosBottom = false;
 bool mglAutoSave = false;
 bool mglHighlight = true;
+bool mglDotsRefr = true;
 bool mglAutoPure = true;
 bool mglCompleter = true;
 bool loadInNewWnd = false;
@@ -96,6 +94,7 @@ void mgl_ask_qt(const wchar_t *quest, wchar_t *res);
 //-----------------------------------------------------------------------------
 int main(int argc, char **argv)
 {
+       mgl_suppress_warn(true);
 //     QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
 #if !defined(WIN32) && !defined(__APPLE__)
        // try to fix possible multi-threading errors
@@ -162,6 +161,7 @@ void udavAddCommands(const mglCommand *cmd) // NOTE it work but I don't how I ca
        memcpy(buf, parser.Cmd, mp*sizeof(mglCommand));
        memcpy(buf+mp, cmd, (mc+1)*sizeof(mglCommand));
        qsort(buf, mp+mc, sizeof(mglCommand), mgl_cmd_cmp);
+#pragma omp critical(cmd_parser)
        if(parser.Cmd!=mgls_base_cmd)   delete []parser.Cmd;
        parser.Cmd = buf;
 }*/
@@ -190,22 +190,30 @@ MainWindow::MainWindow(QWidget *wp) : QMainWindow(wp)
        messWnd->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
        addDockWidget(Qt::BottomDockWidgetArea, messWnd);
        messWnd->resize(size().width(), 0);     new MessSyntax(mess);
-       connect(mess,SIGNAL(cursorPositionChanged()),this,SLOT(messClicked()));
+//     connect(mess,SIGNAL(cursorPositionChanged()),this,SLOT(messClicked()));
        connect(mess,SIGNAL(selectionChanged()),this,SLOT(messClicked()));
 
+       hideWnd = new QDockWidget(tr("Hidden plots"),this);
+       hidden = new TextEdit(this);    hideWnd->setWidget(hidden);
+       hideWnd->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
+       addDockWidget(Qt::BottomDockWidgetArea, hideWnd);
+       hideWnd->resize(size().width(), 0);     hidden->setReadOnly(true);
+       connect(hidden,SIGNAL(selectionChanged()),this,SLOT(hiddenClicked()));  // TODO
+//     connect(hidden,SIGNAL(cursorPositionChanged()),this,SLOT(hiddenClicked()));
+
        calcWnd = new QDockWidget(tr("Calculator"),this);
 
-       aload = a = new QAction(QPixmap(":/xpm/document-open.png"), tr("Open file"), this);
+       aload = a = new QAction(QPixmap(":/png/document-open.png"), tr("Open file"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(choose()));
        a->setToolTip(tr("Open and execute/show script or data from file (Ctrl+O).\nYou may switch off automatic exection in UDAV properties."));
        a->setShortcut(Qt::CTRL+Qt::Key_O);
 
-       asave = a = new QAction(QPixmap(":/xpm/document-save.png"), tr("Save script"), this);
+       asave = a = new QAction(QPixmap(":/png/document-save.png"), tr("Save script"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(save()));
        a->setToolTip(tr("Save script to a file (Ctrl+S)"));
        a->setShortcut(Qt::CTRL+Qt::Key_S);
 
-       acalc = a = new QAction(QPixmap(":/xpm/accessories-calculator.png"), tr("Calculator"), this);
+       acalc = a = new QAction(QPixmap(":/png/accessories-calculator.png"), tr("Calculator"), this);
        a->setShortcut(Qt::Key_F4);     a->setCheckable(true);
        connect(a, SIGNAL(toggled(bool)), calcWnd, SLOT(setVisible(bool)));
        connect(calcWnd, SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool)));
@@ -218,18 +226,24 @@ MainWindow::MainWindow(QWidget *wp) : QMainWindow(wp)
        connect(messWnd, SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool)));
        a->setChecked(false);   messWnd->setVisible(false);
 
+       ahide = a = new QAction(QPixmap(":/png/layer-visible-on.png"), tr("Show hidden plots"), this);
+       a->setShortcut(Qt::Key_F8);     a->setCheckable(true);
+       connect(a, SIGNAL(toggled(bool)), hideWnd, SLOT(setVisible(bool)));
+       connect(hideWnd, SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool)));
+       a->setChecked(false);   hideWnd->setVisible(false);
+
        graph = new PlotPanel(this);
-       rtab->addTab(graph,QPixmap(":/xpm/x-office-presentation.png"),tr("Canvas"));
+       rtab->addTab(graph,QPixmap(":/png/office-chart-line.png"),tr("Canvas"));
        //      connect(info,SIGNAL(addPanel(QWidget*)),this,SLOT(addPanel(QWidget*)));
        info = createMemPanel(this);
-       rtab->addTab(info,QPixmap(":/xpm/system-file-manager.png"),tr("Info"));
+       rtab->addTab(info,QPixmap(":/png/system-file-manager.png"),tr("Info"));
        hlp = createHlpPanel(this);
-       rtab->addTab(hlp,QPixmap(":/xpm/help-contents.png"),tr("Help"));
+       rtab->addTab(hlp,QPixmap(":/png/help-contents.png"),tr("Help"));
        edit = new TextPanel(this);     edit->graph = graph;
        graph->textMGL = edit->edit;
        connect(graph->mgl,SIGNAL(showWarn(QString)),mess,SLOT(setText(QString)));
        connect(graph,SIGNAL(clearWarn()),mess,SLOT(clear()));
-       ltab->addTab(edit,QPixmap(":/xpm/text-x-generic.png"),tr("Script"));
+       ltab->addTab(edit,QPixmap(":/png/text-plain.png"),tr("Script"));
 
        calcWnd->setWidget(createCalcDlg(this, edit->edit));
        calcWnd->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
@@ -252,10 +266,9 @@ MainWindow::MainWindow(QWidget *wp) : QMainWindow(wp)
        connect(graph->mgl, SIGNAL(refreshData()), edit, SLOT(refreshData()));
        connect(graph->mgl,SIGNAL(doubleClick(int)),edit,SLOT(newCmd(int)));
 
+       connect(edit->edit,SIGNAL(textChanged()),this,SLOT(updateHidden()));
        connect(mess, SIGNAL(textChanged()), this, SLOT(warnChanged()));
-//     connect(mdi, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(subActivated(QMdiSubWindow *)));
        connect(propDlg, SIGNAL(sizeChanged(int,int)), graph->mgl, SLOT(imgSize(int,int)));
-//     connect(propDlg, SIGNAL(propUpdated()), edit->edit, SLOT(update()));    // TODO: update qmglsyntax
        connect(edit->edit,SIGNAL(textChanged()), this, SLOT(setAsterix()));
        connect(edit->edit, SIGNAL(cursorPositionChanged()), this, SLOT(editPosChanged()));
        connect(edit,SIGNAL(setCurrentFile(QString)),this,SLOT(setCurrentFile(QString)));
@@ -275,7 +288,7 @@ void MainWindow::makeMenu()
        // file menu
        {
        o = menuBar()->addMenu(tr("File"));
-       a = new QAction(QPixmap(":/xpm/document-new.png"), tr("New script"), this);
+       a = new QAction(QPixmap(":/png/document-new.png"), tr("New script"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(newDoc()));
        a->setToolTip(tr("Create new empty script window (Ctrl+N)."));
        a->setShortcut(Qt::CTRL+Qt::Key_N);     o->addAction(a);
@@ -289,7 +302,7 @@ void MainWindow::makeMenu()
 
        o->addSeparator();
        o->addAction(tr("Print script"), edit, SLOT(printText()));
-       a = new QAction(QPixmap(":/xpm/document-print.png"), tr("Print graphics"), this);
+       a = new QAction(QPixmap(":/png/document-print.png"), tr("Print graphics"), this);
        connect(a, SIGNAL(triggered()), graph->mgl, SLOT(print()));
        a->setToolTip(tr("Open printer dialog and print graphics (Ctrl+P)"));
        a->setShortcut(Qt::CTRL+Qt::Key_P);     o->addAction(a);
@@ -305,22 +318,23 @@ void MainWindow::makeMenu()
        // settings menu
        {
        o = menuBar()->addMenu(tr("Settings"));
-       a = new QAction(QPixmap(":/xpm/preferences-system.png"), tr("Properties"), this);
+       a = new QAction(QPixmap(":/png/preferences-system.png"), tr("Properties"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(properties()));
        a->setToolTip(tr("Show dialog for UDAV properties."));  o->addAction(a);
        o->addAction(tr("Set arguments"), createArgsDlg(this), SLOT(exec()));
 
        o->addAction(acalc);
        o->addAction(ainfo);
+       o->addAction(ahide);
        }
 
        menuBar()->addSeparator();
        o = menuBar()->addMenu(tr("Help"));
-       a = new QAction(QPixmap(":/xpm/help-contents.png"), tr("MGL help"), this);
+       a = new QAction(QPixmap(":/png/help-contents.png"), tr("MGL help"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(showHelp()));
        a->setToolTip(tr("Show help on MGL commands (F1)."));
        a->setShortcut(Qt::Key_F1);     o->addAction(a);
-       a = new QAction(QPixmap(":/xpm/help-faq.png"), tr("Hints"), this);
+       a = new QAction(QPixmap(":/png/help-faq.png"), tr("Hints"), this);
        connect(a, SIGNAL(triggered()), this, SLOT(showHint()));
        a->setToolTip(tr("Show hints of MGL usage."));  o->addAction(a);
        o->addAction(tr("About"), this, SLOT(about()));
@@ -443,37 +457,10 @@ void MainWindow::setEditPos(bool bottom)
 //-----------------------------------------------------------------------------
 void MainWindow::properties()  {       propDlg->exec();        }
 //-----------------------------------------------------------------------------
-void MainWindow::messClicked()
-{
-       QString m = mess->toPlainText(), q;
-       int p = mess->textCursor().blockNumber();
-       for(;p>=0;p--)
-       {
-               q = m.section('\n',p,p);
-               if(q.contains("in line "))
-               {
-                       QString s = q.section(' ',-1);
-                       int n = s.toInt()-1;    if(n<0) return;
-                       edit->moveCursor(QTextCursor::Start);
-                       for(int i=0;i<n;i++)    edit->moveCursor(QTextCursor::NextBlock);
-                       break;
-               }
-       }
-       edit->setFocus();
-}
-//-----------------------------------------------------------------------------
-void MainWindow::warnChanged()
-{
-       if(mess->toPlainText().isEmpty())
-       {       messWnd->hide();        ainfo->setChecked(false);       }
-       else
-       {       messWnd->show();        ainfo->setChecked(true);        }
-}
-//-----------------------------------------------------------------------------
 void MainWindow::about()
 {
-       QString s = tr("UDAV v. 2.")+QString::number(MGL_VER2)+
-                               tr("\n(c) Alexey Balakin, 2007-2014\nhttp://mathgl.sf.net/");
+       QString s = tr("<a href='http://mathgl.sourceforge.net/doc_en/UDAV-overview.html'>UDAV</a> v. 2.")+QString::number(MGL_VER2)+
+       tr("<br>(c) Alexey Balakin, 2007-2014<br><br><a href='http://www.gnu.org/copyleft/gpl.html'>License is GPL v.2 or later.</a>");
        QMessageBox::about(this, tr("UDAV - about"), s);
 }
 //-----------------------------------------------------------------------------
@@ -508,6 +495,7 @@ void MainWindow::writeSettings()
        settings.setValue("/autoExec",  mglAutoExecute);
        settings.setValue("/autoSave",  mglAutoSave);
        settings.setValue("/highlight",  mglHighlight);
+       settings.setValue("/dotsRefresh", mglDotsRefr);
        settings.setValue("/autoPure",  mglAutoPure);
        settings.setValue("/editAtTop", editPosBottom);
        settings.setValue("/fontFamily", defFontFamily);
@@ -550,6 +538,7 @@ void MainWindow::readSettings()
        editPosBottom = settings.value("/editAtTop", false).toBool();
        mglCompleter = settings.value("/completer",  true).toBool();
        loadInNewWnd = settings.value("/loadInNewWnd", false).toBool();
+       mglDotsRefr = settings.value("/dotsRefresh", true).toBool();
        defFontFamily = settings.value("/fontFamily", "Georgia").toString();
        defFontSize = settings.value("/fontSize", 10).toInt();
        edit->setEditorFont();  setEditPos(editPosBottom);
@@ -720,19 +709,19 @@ void updateDataItems()
 //-----------------------------------------------------------------------------
 void MainWindow::addPanel(QWidget *w, QString name)
 {
-       ltab->addTab(w,QPixmap(":/xpm/x-office-spreadsheet.png"),name);
+       ltab->addTab(w,QPixmap(":/png/text-csv.png"),name);
        ltab->setCurrentWidget(w);
 }
 //-----------------------------------------------------------------------------
-MainWindow *findMain(QWidget *wnd)
+MGL_LOCAL_PURE MainWindow *findMain(QWidget *wnd)
 {
        MainWindow *mw=0;
        QObject *w=wnd;
 
-       while(w)
+       while(w && !mw)
        {
                mw = dynamic_cast<MainWindow *>(w);
-               if(mw)  break;  else w = w->parent();
+               w = w->parent();
        }
        return mw;
 }
@@ -743,3 +732,53 @@ void raisePanel(QWidget *w)
        if(mw)  mw->rtab->setCurrentWidget(w);
 }
 //-----------------------------------------------------------------------------
+void MainWindow::updateHidden()
+{
+       QTextCursor tc = edit->edit->textCursor();
+       long pos = tc.position(), i=0;
+       hidden->clear();
+       tc.movePosition(QTextCursor::Start);
+       do {
+               i++;
+               if(tc.block().text().startsWith("#h "))
+                       hidden->append("Line "+QString::number(i)+QString::fromWCharArray(L" → ")+tc.block().text().mid(3)+"\n");
+       } while(tc.movePosition(QTextCursor::NextBlock));
+       tc.setPosition(pos);
+}
+//-----------------------------------------------------------------------------
+void MainWindow::hiddenClicked()
+{
+       QString q = hidden->textCursor().block().text();
+       if(q.contains("Line "))
+       {
+               int n = q.section(' ',1,1).toInt()-1;
+               edit->edit->moveCursor(QTextCursor::Start);
+               for(int i=0;i<n;i++)    edit->edit->moveCursor(QTextCursor::NextBlock);
+               edit->edit->textCursor().deleteChar();
+               edit->edit->textCursor().deleteChar();
+               edit->edit->textCursor().deleteChar();
+       }
+       graph->execute();
+}
+//-----------------------------------------------------------------------------
+void MainWindow::messClicked()
+{
+       QString q = mess->textCursor().block().text();
+       if(q.contains("in line "))
+       {
+               QString s = q.section(' ',-1);
+               int n = q.section(' ',-1).toInt()-1;    if(n<0) return;
+               edit->moveCursor(QTextCursor::Start);
+               for(int i=0;i<n;i++)    edit->moveCursor(QTextCursor::NextBlock);
+       }
+       edit->setFocus();
+}
+//-----------------------------------------------------------------------------
+void MainWindow::warnChanged()
+{
+       if(mess->toPlainText().isEmpty())
+       {       messWnd->hide();        ainfo->setChecked(false);       }
+       else
+       {       messWnd->show();        ainfo->setChecked(true);        }
+}
+//-----------------------------------------------------------------------------
index 1091d7d6f26910658f4747f64ea614de6d216000..d101f136e29b49604a99347d1a7fd7e21ce81372 100644 (file)
@@ -49,7 +49,7 @@ class MainWindow : public QMainWindow
 friend void raisePanel(QWidget *w);
 Q_OBJECT
 public:
-       QAction *ainfo, *acalc, *asave, *aload;
+       QAction *ainfo, *acalc, *asave, *aload, *ahide;
        TextPanel *edit;
        PlotPanel *graph;
        QWidget *info;
@@ -82,6 +82,8 @@ private slots:
        void aboutQt();
        void openRecentFile();
        void showHelp();
+       void updateHidden();
+       void hiddenClicked();
 
        void messClicked();
        void properties();
@@ -99,9 +101,10 @@ private:
        QTabWidget *ltab, *rtab;
        QSplitter *split;
        QTextEdit *mess;        ///< messages and warnings
+       QTextEdit *hidden;      ///< commented(hidden) lines
        QString filename;
        QMenu *fileMenu;
-       QDockWidget *messWnd, *calcWnd;
+       QDockWidget *messWnd, *hideWnd, *calcWnd;
 
        void makeMenu();
        void makeDataMenu();
diff --git a/udav/xpm/accessories-calculator.png b/udav/xpm/accessories-calculator.png
deleted file mode 100644 (file)
index 9248971..0000000
Binary files a/udav/xpm/accessories-calculator.png and /dev/null differ
diff --git a/udav/xpm/alpha.png b/udav/xpm/alpha.png
deleted file mode 100644 (file)
index fdb8836..0000000
Binary files a/udav/xpm/alpha.png and /dev/null differ
diff --git a/udav/xpm/arrow_a.xpm b/udav/xpm/arrow_a.xpm
deleted file mode 100644 (file)
index 457c0aa..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * arrow_a_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"         ...    ",
-"       ....     ",
-"     .....      ",
-"   ......       ",
-" ...............",
-"   ......       ",
-"     .....      ",
-"       ....     ",
-"         ...    ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/arrow_d.xpm b/udav/xpm/arrow_d.xpm
deleted file mode 100644 (file)
index 834f703..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * arrow_d_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"     .          ",
-"    ...         ",
-"   .....        ",
-"  .......       ",
-" ...............",
-"  .......       ",
-"   .....        ",
-"    ...         ",
-"     .          ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/arrow_i.xpm b/udav/xpm/arrow_i.xpm
deleted file mode 100644 (file)
index a8c617e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * arrow_i_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-" ..             ",
-" ..             ",
-" ..             ",
-" ..             ",
-" ..             ",
-" ...............",
-" ..             ",
-" ..             ",
-" ..             ",
-" ..             ",
-" ..             ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/arrow_k.xpm b/udav/xpm/arrow_k.xpm
deleted file mode 100644 (file)
index 840d325..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * arrow_k_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-" ..             ",
-" ..      ...    ",
-" ..    ....     ",
-" ..  .....      ",
-" ........       ",
-" ...............",
-" ........       ",
-" ..  .....      ",
-" ..    ....     ",
-" ..      ...    ",
-" ..             ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/arrow_n.xpm b/udav/xpm/arrow_n.xpm
deleted file mode 100644 (file)
index 305238b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * arrow_n_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"  ..............",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/arrow_o.xpm b/udav/xpm/arrow_o.xpm
deleted file mode 100644 (file)
index 6f4b583..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * arrow_o_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"    ....        ",
-"   ......       ",
-"  ........      ",
-"  ........      ",
-"  ..............",
-"  ........      ",
-"  ........      ",
-"  .......       ",
-"    ....        ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/arrow_s.xpm b/udav/xpm/arrow_s.xpm
deleted file mode 100644 (file)
index ddeeb7f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * arrow_s_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"  ........      ",
-"  ........      ",
-"  ........      ",
-"  ........      ",
-"  ..............",
-"  ........      ",
-"  ........      ",
-"  ........      ",
-"  ........      ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/arrow_t.xpm b/udav/xpm/arrow_t.xpm
deleted file mode 100644 (file)
index 71ff9dc..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * arrow_t_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"         ..     ",
-"       ....     ",
-"     ......     ",
-"   ........     ",
-" ...............",
-"   ........     ",
-"     ......     ",
-"       ....     ",
-"         ..     ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/arrow_v.xpm b/udav/xpm/arrow_v.xpm
deleted file mode 100644 (file)
index 038a3e5..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * arrow_v_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"  ...           ",
-"   ....         ",
-"    .....       ",
-"     ......     ",
-"     ...........",
-"     ......     ",
-"    .....       ",
-"   ....         ",
-"  ...           ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/cons.xpm b/udav/xpm/cons.xpm
deleted file mode 100644 (file)
index b22b0f4..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* XPM */
-static const char * cons_xpm[] = {
-"16 16 4 1",
-"      c None",
-".     c #000000",
-"+     c #0000FF",
-"@     c #FF0000",
-"                ",
-" .............. ",
-" .            . ",
-" . . . . . . .. ",
-" .            . ",
-" . . . . . . .. ",
-" .............. ",
-"                ",
-"  +++++++++++++ ",
-"    +++++++++   ",
-"      +++++     ",
-"        +       ",
-" @@@@@@@@@@@@@@ ",
-" @ @ @ @ @ @ @@ ",
-" @@@@@@@@@@@@@@ ",
-"                "};
diff --git a/udav/xpm/crop.xpm b/udav/xpm/crop.xpm
deleted file mode 100644 (file)
index e18a730..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * crop_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"     .          ",
-"                ",
-"     .          ",
-"                ",
-" . . ......     ",
-"     .    .     ",
-"     .    .     ",
-"     .    .     ",
-"     .    .     ",
-"     ...... . . ",
-"                ",
-"          .     ",
-"                ",
-"          .     ",
-"                "};
diff --git a/udav/xpm/dash_d.xpm b/udav/xpm/dash_d.xpm
deleted file mode 100644 (file)
index 6892ce6..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * dash_d_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-".   .   .   .   ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/dash_e.xpm b/udav/xpm/dash_e.xpm
deleted file mode 100644 (file)
index 13eaf63..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * dash_e_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-". . . . . . . . ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/dash_i.xpm b/udav/xpm/dash_i.xpm
deleted file mode 100644 (file)
index 2ad1f1c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * dash_i_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-".. . .. . .. . .",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/dash_j.xpm b/udav/xpm/dash_j.xpm
deleted file mode 100644 (file)
index 70a9cc4..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * dash_j_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"....  .  ....  .",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/dash_l.xpm b/udav/xpm/dash_l.xpm
deleted file mode 100644 (file)
index 4346c08..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * dash_l_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"....    ....    ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/dash_m.xpm b/udav/xpm/dash_m.xpm
deleted file mode 100644 (file)
index 7cd2b39..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * dash_m_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"..  ..  ..  ..  ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/dash_s.xpm b/udav/xpm/dash_s.xpm
deleted file mode 100644 (file)
index 4edb6c5..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * dash_s_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"................",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/dialog-information.png b/udav/xpm/dialog-information.png
deleted file mode 100644 (file)
index 8851b99..0000000
Binary files a/udav/xpm/dialog-information.png and /dev/null differ
diff --git a/udav/xpm/diff.xpm b/udav/xpm/diff.xpm
deleted file mode 100644 (file)
index b90448a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * diff_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"   ..           ",
-"  .  .   .      ",
-"     .  .       ",
-"  ....  .       ",
-" .   . .  ..    ",
-" .  .  . .  .   ",
-"  ..  .     .   ",
-"      .  ....   ",
-"     .  .   .   ",
-"     .  .  . . .",
-"    .    ..   . ",
-"             . .",
-"                ",
-"                "};
diff --git a/udav/xpm/diff2.xpm b/udav/xpm/diff2.xpm
deleted file mode 100644 (file)
index 7a2d7eb..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char * diff2_xpm[] = {
-"16 16 3 1",
-"      c None",
-".     c #000000",
-"+     c #7F7F7F",
-"                ",
-"                ",
-"                ",
-"                ",
-"       .        ",
-"       ..       ",
-"      .+..      ",
-"     +. ..+     ",
-"     .   ..     ",
-"    .+   +..    ",
-"   +.     ..+   ",
-"   .       ..   ",
-"  .+       +..  ",
-"  ............  ",
-"                ",
-"                "};
diff --git a/udav/xpm/document-export.png b/udav/xpm/document-export.png
deleted file mode 100644 (file)
index eb82440..0000000
Binary files a/udav/xpm/document-export.png and /dev/null differ
diff --git a/udav/xpm/document-import.png b/udav/xpm/document-import.png
deleted file mode 100644 (file)
index 0b4e816..0000000
Binary files a/udav/xpm/document-import.png and /dev/null differ
diff --git a/udav/xpm/document-new.png b/udav/xpm/document-new.png
deleted file mode 100644 (file)
index 4c3efdd..0000000
Binary files a/udav/xpm/document-new.png and /dev/null differ
diff --git a/udav/xpm/document-open.png b/udav/xpm/document-open.png
deleted file mode 100644 (file)
index ab94046..0000000
Binary files a/udav/xpm/document-open.png and /dev/null differ
diff --git a/udav/xpm/document-print.png b/udav/xpm/document-print.png
deleted file mode 100644 (file)
index 35c37bd..0000000
Binary files a/udav/xpm/document-print.png and /dev/null differ
diff --git a/udav/xpm/document-properties.png b/udav/xpm/document-properties.png
deleted file mode 100644 (file)
index ab0e8ea..0000000
Binary files a/udav/xpm/document-properties.png and /dev/null differ
diff --git a/udav/xpm/document-save.png b/udav/xpm/document-save.png
deleted file mode 100644 (file)
index 22ff495..0000000
Binary files a/udav/xpm/document-save.png and /dev/null differ
diff --git a/udav/xpm/edit-copy.png b/udav/xpm/edit-copy.png
deleted file mode 100644 (file)
index 8dd48c4..0000000
Binary files a/udav/xpm/edit-copy.png and /dev/null differ
diff --git a/udav/xpm/edit-cut.png b/udav/xpm/edit-cut.png
deleted file mode 100644 (file)
index dc9eb9a..0000000
Binary files a/udav/xpm/edit-cut.png and /dev/null differ
diff --git a/udav/xpm/edit-delete.png b/udav/xpm/edit-delete.png
deleted file mode 100644 (file)
index 184f762..0000000
Binary files a/udav/xpm/edit-delete.png and /dev/null differ
diff --git a/udav/xpm/edit-find.png b/udav/xpm/edit-find.png
deleted file mode 100644 (file)
index d072d3c..0000000
Binary files a/udav/xpm/edit-find.png and /dev/null differ
diff --git a/udav/xpm/edit-paste.png b/udav/xpm/edit-paste.png
deleted file mode 100644 (file)
index 24588a3..0000000
Binary files a/udav/xpm/edit-paste.png and /dev/null differ
diff --git a/udav/xpm/edit-redo.png b/udav/xpm/edit-redo.png
deleted file mode 100644 (file)
index c3b0df0..0000000
Binary files a/udav/xpm/edit-redo.png and /dev/null differ
diff --git a/udav/xpm/edit-select-all.png b/udav/xpm/edit-select-all.png
deleted file mode 100644 (file)
index f4b0b19..0000000
Binary files a/udav/xpm/edit-select-all.png and /dev/null differ
diff --git a/udav/xpm/edit-undo.png b/udav/xpm/edit-undo.png
deleted file mode 100644 (file)
index 8b0fef9..0000000
Binary files a/udav/xpm/edit-undo.png and /dev/null differ
diff --git a/udav/xpm/film-b.png b/udav/xpm/film-b.png
deleted file mode 100644 (file)
index edccf1b..0000000
Binary files a/udav/xpm/film-b.png and /dev/null differ
diff --git a/udav/xpm/folder.png b/udav/xpm/folder.png
deleted file mode 100644 (file)
index 65bd0bb..0000000
Binary files a/udav/xpm/folder.png and /dev/null differ
diff --git a/udav/xpm/format-indent-more.png b/udav/xpm/format-indent-more.png
deleted file mode 100644 (file)
index 00309ea..0000000
Binary files a/udav/xpm/format-indent-more.png and /dev/null differ
diff --git a/udav/xpm/func.xpm b/udav/xpm/func.xpm
deleted file mode 100644 (file)
index e62cfe7..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * func_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"   .   .    .   ",
-"  .   .      .  ",
-"  .   .      .  ",
-" ... .  .  .  . ",
-"  .  .  .  .  . ",
-"  .  .   ..   . ",
-"  .  .   ..   . ",
-"  .  .  .  .  . ",
-"  .   . .  . .  ",
-"      .      .  ",
-"       .    .   ",
-"                ",
-"                "};
diff --git a/udav/xpm/go-down.png b/udav/xpm/go-down.png
deleted file mode 100644 (file)
index 3dd7fcc..0000000
Binary files a/udav/xpm/go-down.png and /dev/null differ
diff --git a/udav/xpm/go-first.png b/udav/xpm/go-first.png
deleted file mode 100644 (file)
index 9c15c09..0000000
Binary files a/udav/xpm/go-first.png and /dev/null differ
diff --git a/udav/xpm/go-last.png b/udav/xpm/go-last.png
deleted file mode 100644 (file)
index 6e904ef..0000000
Binary files a/udav/xpm/go-last.png and /dev/null differ
diff --git a/udav/xpm/go-next-b.png b/udav/xpm/go-next-b.png
deleted file mode 100644 (file)
index 1f48daf..0000000
Binary files a/udav/xpm/go-next-b.png and /dev/null differ
diff --git a/udav/xpm/go-next.png b/udav/xpm/go-next.png
deleted file mode 100644 (file)
index 6ef8de7..0000000
Binary files a/udav/xpm/go-next.png and /dev/null differ
diff --git a/udav/xpm/go-previous-b.png b/udav/xpm/go-previous-b.png
deleted file mode 100644 (file)
index 7c8443a..0000000
Binary files a/udav/xpm/go-previous-b.png and /dev/null differ
diff --git a/udav/xpm/go-previous.png b/udav/xpm/go-previous.png
deleted file mode 100644 (file)
index 659cd90..0000000
Binary files a/udav/xpm/go-previous.png and /dev/null differ
diff --git a/udav/xpm/go-up.png b/udav/xpm/go-up.png
deleted file mode 100644 (file)
index fa9a7d7..0000000
Binary files a/udav/xpm/go-up.png and /dev/null differ
diff --git a/udav/xpm/help-contents.png b/udav/xpm/help-contents.png
deleted file mode 100644 (file)
index b3ae2c3..0000000
Binary files a/udav/xpm/help-contents.png and /dev/null differ
diff --git a/udav/xpm/help-faq.png b/udav/xpm/help-faq.png
deleted file mode 100644 (file)
index f6bc721..0000000
Binary files a/udav/xpm/help-faq.png and /dev/null differ
diff --git a/udav/xpm/insert.xpm b/udav/xpm/insert.xpm
deleted file mode 100644 (file)
index e0143f1..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* XPM */
-static const char * insert_xpm[] = {
-"16 16 4 1",
-"      c None",
-".     c #0000FF",
-"#     c #000000",
-"w     c #FFFFFF",
-"                ",
-"                ",
-".  ############ ",
-".. #wwwwwwwwww# ",
-"...#w########w# ",
-"....wwwwwwwwww# ",
-".....########w# ",
-"......wwwwwwww# ",
-".......######w# ",
-"........wwwwww# ",
-".......######w# ",
-"......wwwwwwww# ",
-".....########w# ",
-"....wwwwwwwwww# ",
-"...############ ",
-"..              "};
diff --git a/udav/xpm/integr.xpm b/udav/xpm/integr.xpm
deleted file mode 100644 (file)
index ddccb22..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char * integr_xpm[] = {
-"16 16 3 1",
-"      c None",
-".     c #000000",
-"+     c #808080",
-"                ",
-"                ",
-"                ",
-"     .          ",
-"    .           ",
-"    .    .      ",
-"    .    .      ",
-"    .    .      ",
-"    .  ... . .  ",
-"    . .  .  .   ",
-"    . .  .  .   ",
-"    .  ... . .  ",
-"   .     +      ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/mark_.xpm b/udav/xpm/mark_.xpm
deleted file mode 100644 (file)
index b372f5a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark__xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"       ..       ",
-"       ..       ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/mark_a.xpm b/udav/xpm/mark_a.xpm
deleted file mode 100644 (file)
index 29f34cb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_a_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"    .       .   ",
-"     .     .    ",
-"      .   .     ",
-"      .   .     ",
-"       . .      ",
-"       ...      ",
-" .............. ",
-"       ...      ",
-"       . .      ",
-"      .   .     ",
-"      .   .     ",
-"     .     .    ",
-"    .       .   ",
-"                ",
-"                "};
diff --git a/udav/xpm/mark_cf.xpm b/udav/xpm/mark_cf.xpm
deleted file mode 100644 (file)
index f743a31..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_cf_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"     ......     ",
-"   ..      ..   ",
-"  .          .  ",
-" .            . ",
-" .            . ",
-".              .",
-".              .",
-".      ..      .",
-".      ..      .",
-".              .",
-".              .",
-" .            . ",
-" .            . ",
-"  .          .  ",
-"   ..      ..   ",
-"     ......     "};
diff --git a/udav/xpm/mark_d.xpm b/udav/xpm/mark_d.xpm
deleted file mode 100644 (file)
index 678d75e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_d_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"       ..       ",
-"      .  .      ",
-"     .    .     ",
-"    .      .    ",
-"   .        .   ",
-"  .          .  ",
-" .            . ",
-".              .",
-".              .",
-" .            . ",
-"  .          .  ",
-"   .        .   ",
-"    .      .    ",
-"     .    .     ",
-"      .  .      ",
-"       ..       "};
diff --git a/udav/xpm/mark_df.xpm b/udav/xpm/mark_df.xpm
deleted file mode 100644 (file)
index 582d420..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_df_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"       ..       ",
-"      ....      ",
-"     ......     ",
-"    ........    ",
-"   ..........   ",
-"  ............  ",
-" .............. ",
-"................",
-"................",
-" .............. ",
-"  ............  ",
-"   ..........   ",
-"    ........    ",
-"     ......     ",
-"      ....      ",
-"       ..       "};
diff --git a/udav/xpm/mark_l.xpm b/udav/xpm/mark_l.xpm
deleted file mode 100644 (file)
index 9edd3e0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_l_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"          ..    ",
-"        .. .    ",
-"       .   .    ",
-"     ..    .    ",
-"    .      .    ",
-"  ..       .    ",
-" .         .    ",
-".          .    ",
-".          .    ",
-" .         .    ",
-"  ..       .    ",
-"    .      .    ",
-"     ..    .    ",
-"       .   .    ",
-"        .. .    ",
-"          ..    "};
diff --git a/udav/xpm/mark_lf.xpm b/udav/xpm/mark_lf.xpm
deleted file mode 100644 (file)
index 2585eb4..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_lf_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"          ..    ",
-"        ....    ",
-"       .....    ",
-"     .......    ",
-"    ........    ",
-"  ..........    ",
-" ...........    ",
-"............    ",
-"............    ",
-" ...........    ",
-"  ..........    ",
-"    ........    ",
-"     .......    ",
-"       .....    ",
-"        ....    ",
-"          ..    "};
diff --git a/udav/xpm/mark_n.xpm b/udav/xpm/mark_n.xpm
deleted file mode 100644 (file)
index efb363e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* XPM */
-static const char * mark_n_xpm[] = {
-"16 16 1 1",
-"      c None",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/mark_o.xpm b/udav/xpm/mark_o.xpm
deleted file mode 100644 (file)
index 3154cdc..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_o_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"     ......     ",
-"   ..      ..   ",
-"  .          .  ",
-" .            . ",
-" .            . ",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-" .            . ",
-" .            . ",
-"  .          .  ",
-"   ..      ..   ",
-"     ......     "};
diff --git a/udav/xpm/mark_of.xpm b/udav/xpm/mark_of.xpm
deleted file mode 100644 (file)
index 3eeaf38..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_of_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"     ......     ",
-"   ..........   ",
-"  ............  ",
-" .............. ",
-" .............. ",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-" .............. ",
-" .............. ",
-"  ............  ",
-"   ..........   ",
-"     ......     "};
diff --git a/udav/xpm/mark_p.xpm b/udav/xpm/mark_p.xpm
deleted file mode 100644 (file)
index 3f40cfb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_p_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"................",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       "};
diff --git a/udav/xpm/mark_pf.xpm b/udav/xpm/mark_pf.xpm
deleted file mode 100644 (file)
index ea9cdac..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_pf_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"................",
-".       .      .",
-".       .      .",
-".       .      .",
-".       .      .",
-".       .      .",
-".       .      .",
-".       .      .",
-"................",
-".       .      .",
-".       .      .",
-".       .      .",
-".       .      .",
-".       .      .",
-".       .      .",
-"................"};
diff --git a/udav/xpm/mark_r.xpm b/udav/xpm/mark_r.xpm
deleted file mode 100644 (file)
index 8459014..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_r_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"    ..          ",
-"    . ..        ",
-"    .   .       ",
-"    .    ..     ",
-"    .      .    ",
-"    .       ..  ",
-"    .         . ",
-"    .          .",
-"    .          .",
-"    .         . ",
-"    .       ..  ",
-"    .      .    ",
-"    .    ..     ",
-"    .   .       ",
-"    . ..        ",
-"    ..          "};
diff --git a/udav/xpm/mark_rf.xpm b/udav/xpm/mark_rf.xpm
deleted file mode 100644 (file)
index cedcd01..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_rf_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"    ..          ",
-"    ....        ",
-"    .....       ",
-"    .......     ",
-"    ........    ",
-"    ..........  ",
-"    ........... ",
-"    ............",
-"    ............",
-"    ........... ",
-"    ..........  ",
-"    ........    ",
-"    .......     ",
-"    .....       ",
-"    ....        ",
-"    ..          "};
diff --git a/udav/xpm/mark_s.xpm b/udav/xpm/mark_s.xpm
deleted file mode 100644 (file)
index 1a4c012..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_s_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"................",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-".              .",
-"................"};
diff --git a/udav/xpm/mark_sf.xpm b/udav/xpm/mark_sf.xpm
deleted file mode 100644 (file)
index 5a89f1d..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_sf_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................",
-"................"};
diff --git a/udav/xpm/mark_t.xpm b/udav/xpm/mark_t.xpm
deleted file mode 100644 (file)
index 1e6b398..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_t_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"       ..       ",
-"      .  .      ",
-"     .    .     ",
-"     .    .     ",
-"    .      .    ",
-"   .        .   ",
-"   .        .   ",
-"  .          .  ",
-" .            . ",
-" .            . ",
-".              .",
-"................",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/mark_tf.xpm b/udav/xpm/mark_tf.xpm
deleted file mode 100644 (file)
index 48f61c1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_tf_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"       ..       ",
-"      ....      ",
-"     ......     ",
-"     ......     ",
-"    ........    ",
-"   ..........   ",
-"   ..........   ",
-"  ............  ",
-" .............. ",
-" .............. ",
-"................",
-"................",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/mark_v.xpm b/udav/xpm/mark_v.xpm
deleted file mode 100644 (file)
index 9f03771..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_v_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"................",
-".              .",
-" .            . ",
-" .            . ",
-"  .          .  ",
-"   .        .   ",
-"   .        .   ",
-"    .      .    ",
-"     .    .     ",
-"     .    .     ",
-"      .  .      ",
-"       ..       "};
diff --git a/udav/xpm/mark_vf.xpm b/udav/xpm/mark_vf.xpm
deleted file mode 100644 (file)
index 39d7e99..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_vf_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"................",
-"................",
-" .............. ",
-" .............. ",
-"  ............  ",
-"   ..........   ",
-"   ..........   ",
-"    ........    ",
-"     ......     ",
-"     ......     ",
-"      ....      ",
-"       ..       "};
diff --git a/udav/xpm/mark_x.xpm b/udav/xpm/mark_x.xpm
deleted file mode 100644 (file)
index 8d7ee78..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_x_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-".              .",
-" .            . ",
-"  .          .  ",
-"   .        .   ",
-"    .      .    ",
-"     .    .     ",
-"      .  .      ",
-"       ..       ",
-"       ..       ",
-"      .  .      ",
-"     .    .     ",
-"    .      .    ",
-"   .        .   ",
-"  .          .  ",
-" .            . ",
-".              ."};
diff --git a/udav/xpm/mark_y.xpm b/udav/xpm/mark_y.xpm
deleted file mode 100644 (file)
index b5135fd..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * mark_y_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"   .         .  ",
-"    .       .   ",
-"     .     .    ",
-"      .   .     ",
-"       ...      ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"        .       ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/media-seek-backward.png b/udav/xpm/media-seek-backward.png
deleted file mode 100644 (file)
index ffcac31..0000000
Binary files a/udav/xpm/media-seek-backward.png and /dev/null differ
diff --git a/udav/xpm/media-seek-forward.png b/udav/xpm/media-seek-forward.png
deleted file mode 100644 (file)
index 4d7e2cd..0000000
Binary files a/udav/xpm/media-seek-forward.png and /dev/null differ
diff --git a/udav/xpm/none.xpm b/udav/xpm/none.xpm
deleted file mode 100644 (file)
index e81575f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * none_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"................",
-"..            ..",
-". .          . .",
-".  .        .  .",
-".   .      .   .",
-".    .    .    .",
-".     .  .     .",
-".      ..      .",
-".      ..      .",
-".     .  .     .",
-".    .    .    .",
-".   .      .   .",
-".  .        .  .",
-". .          . .",
-"..            ..",
-"................"};
diff --git a/udav/xpm/object-rotate-right.png b/udav/xpm/object-rotate-right.png
deleted file mode 100644 (file)
index 49e5727..0000000
Binary files a/udav/xpm/object-rotate-right.png and /dev/null differ
diff --git a/udav/xpm/oper.xpm b/udav/xpm/oper.xpm
deleted file mode 100644 (file)
index ca6a51d..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * oper_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"   .            ",
-"   .            ",
-" .....    ..... ",
-"   .            ",
-"   .            ",
-"                ",
-"                ",
-"                ",
-"    .       .   ",
-"   .      . . . ",
-"   .       ...  ",
-"  .        ...  ",
-"  .       . . . ",
-" .          .   ",
-"                "};
diff --git a/udav/xpm/oper_a.xpm b/udav/xpm/oper_a.xpm
deleted file mode 100644 (file)
index afa1a80..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * oper_a_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"    .           ",
-"    .           ",
-"    .    ...... ",
-" .......        ",
-"    .    ...... ",
-"    .           ",
-"    .           ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/oper_d.xpm b/udav/xpm/oper_d.xpm
deleted file mode 100644 (file)
index 2b89d5e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * oper_d_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"       .        ",
-"      .         ",
-"      .         ",
-"     .   ...... ",
-"     .          ",
-"    .    ...... ",
-"    .           ",
-"   .            ",
-"   .            ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/oper_m.xpm b/udav/xpm/oper_m.xpm
deleted file mode 100644 (file)
index f2f8db1..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char * oper_m_xpm[] = {
-"16 16 3 1",
-"      c None",
-".     c #000000",
-"+     c #7F7F7F",
-"                ",
-"                ",
-"                ",
-"                ",
-"   .   .        ",
-"   +. .+        ",
-"    +.+  ...... ",
-"  ......        ",
-"    +.+  ...... ",
-"   +. .+        ",
-"   .   .        ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/oper_s.xpm b/udav/xpm/oper_s.xpm
deleted file mode 100644 (file)
index 6bda134..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * oper_s_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"         ...... ",
-" .......        ",
-"         ...... ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/option.xpm b/udav/xpm/option.xpm
deleted file mode 100644 (file)
index d7dd6d6..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char * option_xpm[] = {
-"16 16 3 1",
-"      c None",
-".     c #000000",
-"+     c #7F0000",
-"                ",
-"                ",
-"                ",
-"   ..           ",
-"  .++.          ",
-"  .++.          ",
-"   ..           ",
-"                ",
-"                ",
-"   ..           ",
-"  .++.          ",
-"  .++.          ",
-"   .+. ++ ++ ++ ",
-"    .  ++ ++ ++ ",
-"   .            ",
-"                "};
diff --git a/udav/xpm/plot.xpm b/udav/xpm/plot.xpm
deleted file mode 100644 (file)
index e6e79c1..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* XPM */
-static const char * plot_xpm[] = {
-"16 16 4 1",
-"      c None",
-".     c #000000",
-"+     c #0000FF",
-"@     c #FF0000",
-"                ",
-" .              ",
-" ..           + ",
-" .          ++  ",
-" .         +    ",
-" ..       +     ",
-" .       +      ",
-" .       +      ",
-" ..  @@@+       ",
-" .  @  +@     @ ",
-" .@@   + @   @  ",
-" ..   +   @@@   ",
-" .  ++          ",
-" .++ .   .   .  ",
-" .............. ",
-"                "};
diff --git a/udav/xpm/preferences-system.png b/udav/xpm/preferences-system.png
deleted file mode 100644 (file)
index 9460dfc..0000000
Binary files a/udav/xpm/preferences-system.png and /dev/null differ
diff --git a/udav/xpm/preview.xpm b/udav/xpm/preview.xpm
deleted file mode 100644 (file)
index 0446109..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/* XPM */
-static const char *preview_xpm[] = {
-"16 16 174 2",
-"      c None",
-".     c #EA6E0E",
-"+     c #F67F06",
-"@     c #E3BB18",
-"#     c #A4E757",
-"$     c #56E6A3",
-"%     c #25DAD6",
-"&     c #11E5EB",
-"*     c #2AF5D0",
-"=     c #72F588",
-"-     c #B0EC4B",
-";     c #C7DC34",
-">     c #C3E336",
-",     c #98F563",
-"'     c #3FF6BC",
-")     c #07D5F5",
-"!     c #0E9EEA",
-"~     c #F44C0A",
-"{     c #FC0E00",
-"]     c #FB1900",
-"^     c #FF5B00",
-"/     c #F7C407",
-"(     c #B5FD49",
-"_     c #4BFFB3",
-":     c #0BF6F3",
-"<     c #05D9F9",
-"[     c #0CD2F2",
-"}     c #14DEEB",
-"|     c #1BF0E3",
-"1     c #20FEDE",
-"2     c #27FFD7",
-"3     c #2BFDD3",
-"4     c #3BEEC3",
-"5     c #F14F0A",
-"6     c #FC1400",
-"7     c #FB1700",
-"8     c #FF5000",
-"9     c #FBBA03",
-"0     c #B8FD46",
-"a     c #39FCC5",
-"b     c #01CAFE",
-"c     c #0088FF",
-"d     c #0075FF",
-"e     c #008FFF",
-"f     c #01CCFE",
-"g     c #22FCDC",
-"h     c #73FF8B",
-"i     c #BAFC44",
-"j     c #D3E228",
-"k     c #F47B0A",
-"l     c #FF8C00",
-"m     c #F4BA0A",
-"n     c #CBE733",
-"o     c #7DFC81",
-"p     c #2BEDD3",
-"q     c #03C1FB",
-"r     c #0090FF",
-"s     c #0082FF",
-"t     c #009DFF",
-"u     c #08D4F7",
-"v     c #3AFAC4",
-"w     c #98FF66",
-"x     c #E7EF18",
-"y     c #FEBC01",
-"z     c #F4920A",
-"A     c #F4AD0B",
-"B     c #D4F62A",
-"C     c #63FD9B",
-"D     c #16D9E9",
-"E     c #0296FD",
-"F     c #0063FF",
-"G     c #0059FF",
-"H     c #0076FF",
-"I     c #00B6FF",
-"J     c #1AF2E4",
-"K     c #6EFF90",
-"L     c #C8FD36",
-"M     c #F9E306",
-"N     c #FFB900",
-"O     c #FFA800",
-"P     c #F4AF0B",
-"Q     c #EFBD0D",
-"R     c #A0FF5E",
-"S     c #1BF3E3",
-"T     c #009CFF",
-"U     c #0056FF",
-"V     c #0041FF",
-"W     c #005DFF",
-"X     c #00A0FF",
-"Y     c #0EEEF0",
-"Z     c #5FFF9F",
-"`     c #B7FF47",
-" .    c #F1FA0D",
-"..    c #F9E606",
-"+.    c #F0E70E",
-"@.    c #D4F42A",
-"#.    c #9CF05F",
-"$.    c #F4AA0A",
-"%.    c #DFF01F",
-"&.    c #8DFD71",
-"*.    c #4CF4B2",
-"=.    c #2DDFD1",
-"-.    c #21D5DE",
-";.    c #1CDFE2",
-">.    c #20F4DE",
-",.    c #3BFFC3",
-"'.    c #79FF85",
-").    c #80FF7E",
-"!.    c #72FE8C",
-"~.    c #51FAAD",
-"{.    c #28EFD6",
-"].    c #14CDEA",
-"^.    c #F4760A",
-"/.    c #FF6B00",
-"(.    c #FD6D00",
-"_.    c #F87A05",
-":.    c #F1910C",
-"<.    c #E9B615",
-"[.    c #D8DF26",
-"}.    c #B2FC4C",
-"|.    c #70FF8E",
-"1.    c #2DFED1",
-"2.    c #0BE3F3",
-"3.    c #04B9FB",
-"4.    c #0099FE",
-"5.    c #0085FF",
-"6.    c #007EFF",
-"7.    c #0A84F4",
-"8.    c #F1480A",
-"9.    c #EA0500",
-"0.    c #C50000",
-"a.    c #B30000",
-"b.    c #BB0100",
-"c.    c #DA0600",
-"d.    c #FA3500",
-"e.    c #FCB403",
-"f.    c #ACFD52",
-"g.    c #24F8DA",
-"h.    c #00A5FF",
-"i.    c #0036FF",
-"j.    c #0046FF",
-"k.    c #007FFF",
-"l.    c #11C0EA",
-"m.    c #F4440A",
-"n.    c #E10100",
-"o.    c #B20000",
-"p.    c #990000",
-"q.    c #9B0000",
-"r.    c #B90000",
-"s.    c #EB0500",
-"t.    c #FF6700",
-"u.    c #E9E716",
-"v.    c #75FF89",
-"w.    c #1EE7E0",
-"x.    c #09B9F6",
-"y.    c #06ACF8",
-"z.    c #11C6ED",
-"A.    c #38F0C6",
-"B.    c #8FF26F",
-"C.    c #E9630E",
-"D.    c #F43606",
-"E.    c #E92406",
-"F.    c #E02006",
-"G.    c #DE2006",
-"H.    c #F43706",
-"I.    c #F56806",
-"J.    c #F5A106",
-"K.    c #EBCC11",
-"L.    c #CED92D",
-"M.    c #B9DB41",
-"N.    c #B9DD43",
-"O.    c #C8D933",
-"P.    c #E3CE18",
-"Q.    c #E8AB10",
-"                                ",
-"                                ",
-"                                ",
-". + @ # $ % & * = - ; > , ' ) ! ",
-"~ { ] ^ / ( _ : < [ } | 1 2 3 4 ",
-"5 6 7 8 9 0 a b c d e f g h i j ",
-"k l m n o p q r s t u v w x y z ",
-"A B C D E F G H I J K L M N O P ",
-"Q R S T U V W X Y Z `  ...+.@.#.",
-"$.%.&.*.=.-.;.>.,.Z '.).!.~.{.].",
-"^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.",
-"8.9.0.a.b.c.d.e.f.g.h.U i.j.k.l.",
-"m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.",
-"C.D.E.F.G.E.H.I.J.K.L.M.N.O.P.Q.",
-"                                ",
-"                                "};
diff --git a/udav/xpm/process-stop.png b/udav/xpm/process-stop.png
deleted file mode 100644 (file)
index ab6808f..0000000
Binary files a/udav/xpm/process-stop.png and /dev/null differ
diff --git a/udav/xpm/size.xpm b/udav/xpm/size.xpm
deleted file mode 100644 (file)
index 3a1d846..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * size_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-" .............. ",
-" .     .      . ",
-" .    ...     . ",
-" .     .      . ",
-" .     .      . ",
-" . .   .    . . ",
-" .............. ",
-" . .   .    . . ",
-" .     .      . ",
-" .     .      . ",
-" .     .      . ",
-" .    ...     . ",
-" .     .      . ",
-" .............. "};
diff --git a/udav/xpm/smth.xpm b/udav/xpm/smth.xpm
deleted file mode 100644 (file)
index a2b9d46..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char * smth_xpm[] = {
-"16 16 3 1",
-"      c None",
-".     c #000000",
-"+     c #FF0000",
-"                ",
-"                ",
-"                ",
-"                ",
-"    .           ",
-"    .           ",
-"   . .    .     ",
-"   . .    ..    ",
-"  +++.   . .    ",
-" +.  ++  +++.   ",
-"  .   .++   ++  ",
-" .    . .    .+ ",
-" .    . .     . ",
-"       .        ",
-"       .        ",
-"                "};
diff --git a/udav/xpm/squize.xpm b/udav/xpm/squize.xpm
deleted file mode 100644 (file)
index fa68e6a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char * squize_xpm[] = {
-"16 16 3 1",
-"      c None",
-".     c #000000",
-"+     c #7F7F7F",
-"                ",
-"                ",
-"     ......     ",
-"     .    .     ",
-"     .    .     ",
-"  .  .    .  .  ",
-"  +. .    . .+  ",
-"......    ......",
-"  +. .    . .+  ",
-"  .  .    .  .  ",
-"     .    .     ",
-"     .    .     ",
-"     .    .     ",
-"     ......     ",
-"                ",
-"                "};
diff --git a/udav/xpm/style.xpm b/udav/xpm/style.xpm
deleted file mode 100644 (file)
index 9125d5f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static const char * style_xpm[] = {
-"16 16 3 1",
-"      c None",
-".     c #FF0000",
-"q     c #7F0000",
-"                ",
-"                ",
-"                ",
-"   qqq   qqq    ",
-"   q.q   q.q    ",
-"   q.q   q.q    ",
-"   q.q   q.q    ",
-"    q     q     ",
-"    q     q     ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                ",
-"                "};
diff --git a/udav/xpm/sum.xpm b/udav/xpm/sum.xpm
deleted file mode 100644 (file)
index fc017ac..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * sum_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"   ..........   ",
-"   .        .   ",
-"    .       .   ",
-"     .          ",
-"      .         ",
-"       .        ",
-"        ..      ",
-"       .        ",
-"      .         ",
-"     .          ",
-"    .       .   ",
-"   .        .   ",
-"   ..........   ",
-"                "};
diff --git a/udav/xpm/swap.xpm b/udav/xpm/swap.xpm
deleted file mode 100644 (file)
index 6ad367c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* XPM */
-static const char * swap_xpm[] = {
-"16 16 4 1",
-"      c None",
-".     c #0000FF",
-"+     c #000000",
-"@     c #FF0000",
-"                ",
-"  .          .. ",
-"   .        .   ",
-"    .      .    ",
-"    .      .    ",
-"     ......     ",
-"   +         +  ",
-"  +           + ",
-"  +           + ",
-"  + +       + + ",
-"   ++  @@@  ++  ",
-"  +++ @   @ +++ ",
-"     @     @    ",
-"     @     @    ",
-"  @@@       @@@ ",
-"                "};
diff --git a/udav/xpm/system-file-manager.png b/udav/xpm/system-file-manager.png
deleted file mode 100644 (file)
index 60cade4..0000000
Binary files a/udav/xpm/system-file-manager.png and /dev/null differ
diff --git a/udav/xpm/table.xpm b/udav/xpm/table.xpm
deleted file mode 100644 (file)
index 43b33a4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* XPM */\r
-static const char * table_xpm[] = {\r
-"16 16 4 1",\r
-"      c None",\r
-"#     c #000000",\r
-"o     c #777777",\r
-".     c #FFFFFF",\r
-"                ",\r
-" ###############",\r
-" #ooo#oooo#oooo#",\r
-" #ooo#oooo#oooo#",\r
-" ###############",\r
-" #ooo#....#....#",\r
-" #ooo#....#....#",\r
-" ###############",\r
-" #ooo#....#....#",\r
-" #ooo#....#....#",\r
-" ###############",\r
-" #ooo#....#....#",\r
-" #ooo#....#....#",\r
-" ###############",\r
-"                ",\r
-"                "};\r
-\r
diff --git a/udav/xpm/text-x-generic.png b/udav/xpm/text-x-generic.png
deleted file mode 100644 (file)
index 2d7f2d6..0000000
Binary files a/udav/xpm/text-x-generic.png and /dev/null differ
diff --git a/udav/xpm/tran.xpm b/udav/xpm/tran.xpm
deleted file mode 100644 (file)
index 29fa1ee..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* XPM */
-static const char * tran_xpm[] = {
-"16 16 4 1",
-"      c None",
-".     c #000000",
-"+     c #FF0000",
-"@     c #0000FF",
-"                ",
-"                ",
-" ......++++++++ ",
-" .    .       + ",
-" . . ..+ + + ++ ",
-" .    .       + ",
-" . . ..+ + + ++ ",
-" .++++.++++++++ ",
-" . . ..         ",
-" .    .      @  ",
-" . . ..     @@@ ",
-" .    .      @  ",
-" . . ..      @  ",
-" .    .    @@   ",
-" . . .. @@@     ",
-" ......         "};
diff --git a/udav/xpm/udav.png b/udav/xpm/udav.png
deleted file mode 100644 (file)
index 76ba7d9..0000000
Binary files a/udav/xpm/udav.png and /dev/null differ
diff --git a/udav/xpm/update.xpm b/udav/xpm/update.xpm
deleted file mode 100644 (file)
index 5ee1dd6..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char *update_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #00007F",
-"                ",
-"                ",
-"      ....      ",
-"     .    .     ",
-"    .   .....   ",
-"    .    ...    ",
-"          .     ",
-"                ",
-"                ",
-"     .          ",
-"    ...    .    ",
-"   .....   .    ",
-"     .    .     ",
-"      ....      ",
-"                ",
-"                "};
diff --git a/udav/xpm/view-refresh.png b/udav/xpm/view-refresh.png
deleted file mode 100644 (file)
index 3fd71d6..0000000
Binary files a/udav/xpm/view-refresh.png and /dev/null differ
diff --git a/udav/xpm/weather-clear.png b/udav/xpm/weather-clear.png
deleted file mode 100644 (file)
index 7dc15ea..0000000
Binary files a/udav/xpm/weather-clear.png and /dev/null differ
diff --git a/udav/xpm/window.xpm b/udav/xpm/window.xpm
deleted file mode 100644 (file)
index 28ac182..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* XPM */\r
-static const char * window_xpm[] = {\r
-"16 16 10 1",\r
-"      c None",\r
-".     c #000000",\r
-"+     c #333377",\r
-"@     c #FFFFFF",\r
-"#     c #777777",\r
-"$     c #00007F",\r
-"%     c #4444FF",\r
-"&     c #FF0000",\r
-"*     c #007F00",\r
-"=     c #7F0000",\r
-"                ",\r
-"                ",\r
-"..............  ",\r
-".++++++++++++.  ",\r
-".@@@@@#@@@@@@.  ",\r
-".@$.............",\r
-".@@.%%%%%%%%%%%.",\r
-".@$.@@@@@#@@@@@.",\r
-".@@.@$$@@#@@@@@.",\r
-".@$.@@@@@#@@@@@.",\r
-".@@.@$&*@#@@@@@.",\r
-"....@@@@@#@@@@@.",\r
-"   .@$&=@#@@@@@.",\r
-"   .@@@@@#@@@@@.",\r
-"   .............",\r
-"                "};\r
diff --git a/udav/xpm/wire.xpm b/udav/xpm/wire.xpm
deleted file mode 100644 (file)
index b67d50b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static const char * wire_xpm[] = {
-"16 16 2 1",
-"      c None",
-".     c #000000",
-"                ",
-"                ",
-"                ",
-"     .    .     ",
-"     .    .     ",
-"     .    .     ",
-"  ............  ",
-"     .    .     ",
-"     .    .     ",
-"     .    .     ",
-"     .    .     ",
-"  ............  ",
-"     .    .     ",
-"     .    .     ",
-"     .    .     ",
-"                "};
diff --git a/udav/xpm/x-office-presentation.png b/udav/xpm/x-office-presentation.png
deleted file mode 100644 (file)
index f7ea302..0000000
Binary files a/udav/xpm/x-office-presentation.png and /dev/null differ
diff --git a/udav/xpm/x-office-spreadsheet.png b/udav/xpm/x-office-spreadsheet.png
deleted file mode 100644 (file)
index a6b1268..0000000
Binary files a/udav/xpm/x-office-spreadsheet.png and /dev/null differ
diff --git a/udav/xpm/zoom-fit-best.png b/udav/xpm/zoom-fit-best.png
deleted file mode 100644 (file)
index eb28409..0000000
Binary files a/udav/xpm/zoom-fit-best.png and /dev/null differ
diff --git a/udav/xpm/zoom-in.png b/udav/xpm/zoom-in.png
deleted file mode 100644 (file)
index 31ac736..0000000
Binary files a/udav/xpm/zoom-in.png and /dev/null differ
diff --git a/udav/xpm/zoom-original.png b/udav/xpm/zoom-original.png
deleted file mode 100644 (file)
index 8e35414..0000000
Binary files a/udav/xpm/zoom-original.png and /dev/null differ
diff --git a/udav/xpm/zoom-out.png b/udav/xpm/zoom-out.png
deleted file mode 100644 (file)
index df5be3c..0000000
Binary files a/udav/xpm/zoom-out.png and /dev/null differ
index 7b4e6b9e3579774724cc33565dd896469b53c59d..a5eeb9c95a5b7a2cecb47e06c5226d1413c1e974 100644 (file)
@@ -1,4 +1,6 @@
 
+add_executable(make_pas make_pas.cpp)
+
 add_executable(mglconv mglconv.cpp)
 target_link_libraries(mglconv mgl)
 install(
index 2504bc69b8e09ed73ee4d84f915fa1df3b60282b..cbe888e9945069f37d96b24a7775ed838fccded4 100644 (file)
@@ -73,10 +73,10 @@ const char *parse_name(char *name, char *fnc)
                else if(!strncmp(arg[j],"const char *",12))     strcat(res, "ptr ");
                else if(!strncmp(arg[j],"const wchar_t *",15))  strcat(res, "ptr ");
                else if(!strncmp(arg[j],"char ",5))     strcat(res, "char ");
-               else if(!strncmp(arg[j],"long ",5))     strcat(res, "int ");    // TODO check
-               else if(!strncmp(arg[j],"uint32_t ",9)) strcat(res, "int ");    // TODO check
+               else if(!strncmp(arg[j],"long ",5))     strcat(res, "int ");
+               else if(!strncmp(arg[j],"uint32_t ",9)) strcat(res, "int ");
                else if(!strncmp(arg[j],"int ",4))              strcat(res, "int ");
-               else if(!strncmp(arg[j],"mreal ",6))    strcat(res, "sf ");             // TODO check
+               else if(!strncmp(arg[j],"mreal ",6))    strcat(res, "sf ");
                else if(!strncmp(arg[j],"double ",7))   strcat(res, "double ");
                else if(!strncmp(arg[j],"gsl_vector *",12))     strcat(res, "ptr ");
                else if(!strncmp(arg[j],"gsl_matrix *",12))     strcat(res, "ptr ");
@@ -108,7 +108,7 @@ bool parse_file(const char *fname, FILE *out)
                if(strstr(buf, "TODO")) continue;
                if(strstr(buf, "//"))   continue;
                if(strstr(buf, "...)")) continue;
-               
+
                // TODO following 5 lines enable later
                if(strstr(buf, "* const *"))    continue;
                if(strstr(buf, "uint64_t"))     continue;
index b1ad6f21d824f2e212c70c6d6b5ee2be944b85e7..a2dd53b66057175f193001b69da4ba76863a529a 100644 (file)
@@ -3,19 +3,20 @@
 
 const char *files[] =
 {
-       "../include/mgl2/base_cf.h",
-       "../include/mgl2/data_cf.h",
-       "../include/mgl2/datac_cf.h",
-       "../include/mgl2/cont.h",
-       "../include/mgl2/fit.h",
-       "../include/mgl2/plot.h",
-       "../include/mgl2/surf.h",
-       "../include/mgl2/volume.h",
-       "../include/mgl2/vect.h",
-       "../include/mgl2/prim.h",
-       "../include/mgl2/other.h",
-       "../include/mgl2/canvas_cf.h",
-       "../include/mgl2/addon.h",
+       "../../include/mgl2/abstract.h",
+       "../../include/mgl2/base_cf.h",
+       "../../include/mgl2/data_cf.h",
+       "../../include/mgl2/datac_cf.h",
+       "../../include/mgl2/cont.h",
+       "../../include/mgl2/fit.h",
+       "../../include/mgl2/plot.h",
+       "../../include/mgl2/surf.h",
+       "../../include/mgl2/volume.h",
+       "../../include/mgl2/vect.h",
+       "../../include/mgl2/prim.h",
+       "../../include/mgl2/other.h",
+       "../../include/mgl2/canvas_cf.h",
+       "../../include/mgl2/addon.h",
        "" };
 
 const char *head =
@@ -433,12 +434,44 @@ bool parse_file(const char *fname, FILE *out)
                {
                        fprintf(out, "%s\n", buf);
                }
-               else if (          processDeclaration(out, buf, "void MGL_EXPORT",              "procedure %s; cdecl; external libmgl;\n")
+               else if (          processDeclaration(out, buf, "void MGL_EXPORT_PURE",         "procedure %s; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "int MGL_EXPORT_PURE",          "function %s: integer; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "double MGL_EXPORT_PURE",       "function %s: double; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "mreal MGL_EXPORT_PURE",        "function %s: mreal; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "long MGL_EXPORT_PURE",         "function %s: integer; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "mdual MGL_EXPORT_PURE",        "function %s: dual; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "MGL_EXPORT_PURE dual *",       "function %s: PDual; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "HMDT MGL_EXPORT_PURE",         "function %s: HMDT; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "HMGL MGL_EXPORT_PURE",         "function %s: HMGL; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "MGL_EXPORT_PURE const char *", "function %s: PChar; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "MGL_EXPORT_PURE mreal *",      "function %s: Pmreal; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "MGL_EXPORT_PURE const unsigned char *", "function %s: PByte; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "HMPR MGL_EXPORT_PURE",         "function %s: HMPR; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "HMEX MGL_EXPORT_PURE",         "function %s: HMEX; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "HADT MGL_EXPORT_PURE",         "function %s: HADT; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "HAEX MGL_EXPORT_PURE",         "function %s: HAEX; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "void MGL_EXPORT_CONST",                "procedure %s; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "int MGL_EXPORT_CONST",                 "function %s: integer; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "double MGL_EXPORT_CONST",      "function %s: double; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "mreal MGL_EXPORT_CONST",       "function %s: mreal; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "long MGL_EXPORT_CONST",                "function %s: integer; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "mdual MGL_EXPORT_CONST",       "function %s: dual; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "MGL_EXPORT_CONST dual *",      "function %s: PDual; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "HMDT MGL_EXPORT_CONST",                "function %s: HMDT; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "HMGL MGL_EXPORT_CONST",                "function %s: HMGL; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "MGL_EXPORT_CONST const char *", "function %s: PChar; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "MGL_EXPORT_CONST mreal *",     "function %s: Pmreal; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "MGL_EXPORT_CONST const unsigned char *", "function %s: PByte; cdecl; external libmgl;\n") 
+                                       || processDeclaration(out, buf, "HMPR MGL_EXPORT_CONST",                "function %s: HMPR; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "HMEX MGL_EXPORT_CONST",                "function %s: HMEX; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "HADT MGL_EXPORT_CONST",                "function %s: HADT; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "HAEX MGL_EXPORT_CONST",                "function %s: HAEX; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "void MGL_EXPORT",              "procedure %s; cdecl; external libmgl;\n")
                                        || processDeclaration(out, buf, "int MGL_EXPORT",               "function %s: integer; cdecl; external libmgl;\n") 
                                        || processDeclaration(out, buf, "double MGL_EXPORT",    "function %s: double; cdecl; external libmgl;\n") 
                                        || processDeclaration(out, buf, "mreal MGL_EXPORT",     "function %s: mreal; cdecl; external libmgl;\n") 
                                        || processDeclaration(out, buf, "long MGL_EXPORT",              "function %s: integer; cdecl; external libmgl;\n")
-                                       || processDeclaration(out, buf, "dual MGL_EXPORT",              "function %s: dual; cdecl; external libmgl;\n")
+                                       || processDeclaration(out, buf, "mdual MGL_EXPORT",     "function %s: dual; cdecl; external libmgl;\n")
                                        || processDeclaration(out, buf, "MGL_EXPORT dual *",    "function %s: PDual; cdecl; external libmgl;\n")
                                        || processDeclaration(out, buf, "HMDT MGL_EXPORT",              "function %s: HMDT; cdecl; external libmgl;\n") 
                                        || processDeclaration(out, buf, "HMGL MGL_EXPORT",              "function %s: HMGL; cdecl; external libmgl;\n")
@@ -453,10 +486,10 @@ bool parse_file(const char *fname, FILE *out)
                {
                        //already processed by processDeclaration
                }
-               else
+/*             else    // comment this -- it looks as it hangs on classes only, which should be omitted by anyway
                {
-                       fprintf(out, "!!!!\t%s\n", buf);        // NOTE should be never here!
-               }
+                       fprintf(out, "{!!!!\t%s}\n", buf);      // NOTE should be never here!
+               }*/
        }
        fclose(fp);
        return true;
@@ -464,7 +497,7 @@ bool parse_file(const char *fname, FILE *out)
 
 int main()
 {
-       FILE *fout = fopen("../include/mgl2/mgl_pas.pas", "wt");
+       FILE *fout = fopen("../../include/mgl2/mgl_pas.pas", "wt");
        fprintf(fout, "%s\n", head);
        for ( int i = 0; parse_file(files[i], fout); i++ ) {}
        fprintf(fout, "%s\n", footer);
index bf333cc56320c715a056ca71934d3de783c8433b..a7ff4adf8768a7e7418836ae091dc928c74e02d4 100644 (file)
@@ -21,7 +21,7 @@
 #include <unistd.h>
 #include "mgl2/mgl.h"
 //-----------------------------------------------------------------------------
-int mgl_hex(char ch)
+int MGL_LOCAL_CONST mgl_hex(char ch)
 {
        int res=-1;
        if(ch>='0' && ch<='9')  res = ch-'0';
@@ -54,6 +54,7 @@ void mgl_get_value(const char *buf, const char *name, char *val)
 //-----------------------------------------------------------------------------
 int main()
 {
+       mgl_suppress_warn(true);
        mglGraph gr;
        mglParse p(true);
 
@@ -68,7 +69,7 @@ int main()
        {
                long len=atol(getenv("CONTENT_LENGTH"));
                buf = new char[len+1];
-               fread(buf,len,1,stdin);
+               if(!fread(buf,len,1,stdin))     len=0;
                buf[len]=0;     alloc=true;
        }
        else            buf = getenv("QUERY_STRING");
index 4af827a431b2b02811f932ee6425055a7cc3bf6a..fe3eec62e7192d91d04909dfaeb93e8bfc0e3847 100644 (file)
@@ -25,12 +25,12 @@ void mgl_ask_gets(const wchar_t *quest, wchar_t *res);
 //-----------------------------------------------------------------------------\r
 int main(int argc, char *argv[])\r
 {\r
+       mgl_suppress_warn(true);\r
        mglGraph gr;\r
        mglParse p(true);\r
        char ch, buf[2048], iname[256]="", oname[256]="";\r
        std::vector<std::wstring> var;\r
 \r
-       register size_t i, n;\r
        while(1)\r
        {\r
                ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:ho:L:C:A:");\r
@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
                else if(ch=='A')\r
                {\r
                        std::wstring str;\r
-                       for(i=0;optarg[i];i++)  str.push_back(optarg[i]);\r
+                       for(long i=0;optarg[i];i++)     str.push_back(optarg[i]);\r
                        var.push_back(str);\r
                }\r
                else if(ch=='C')\r
@@ -89,7 +89,8 @@ int main(int argc, char *argv[])
 //     while(!feof(fp))        str.push_back(fgetwc(fp));\r
        if(*iname)      fclose(fp);\r
 \r
-       for(i=0;;)      // collect exact values\r
+       unsigned long n;\r
+       for(long i=0;;) // collect exact values\r
        {\r
                n = str.find(L"##a ",i);\r
                if(n==std::string::npos)        break;\r
@@ -108,7 +109,7 @@ int main(int argc, char *argv[])
        if(var.size()>1)        // there is animation\r
        {\r
                if(gif) gr.StartGIF(oname);\r
-               for(i=0;i<var.size();i++)\r
+               for(unsigned long i=0;i<var.size();i++)\r
                {\r
                        gr.NewFrame();\r
                        printf("frame %ld for $0 = \"%ls\"\n",i,var[i].c_str());\r
index 1c2685472ea69f103eadf3714e99384afecd08d7..75b37cc865830c44b53f606d77a73db1f64c2782 100644 (file)
@@ -40,7 +40,7 @@ int show(mglGraph *gr)
 int main(int argc, char **argv)
 {
        char ch, iname[256]="";
-       
+       mgl_suppress_warn(true);
        while(1)
        {
                ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:ho:L:");
@@ -83,9 +83,9 @@ int main(int argc, char **argv)
        if(mgld)
        {
                gr.Setup(false);
-               setlocale(LC_NUMERIC, "C");
+               gr.NewFrame();  setlocale(LC_NUMERIC, "C");
                gr.ImportMGLD(iname);
-               setlocale(LC_NUMERIC, "");
+               setlocale(LC_NUMERIC, "");      gr.EndFrame();
                gr.Update();
        }
        if(!mglGlobalMess.empty())      printf("%s",mglGlobalMess.c_str());
index 3302c58e7af18305007de27b01616499821aceee..61b20fdf173473a2a0b8d85c82470199a5a06dcb 100644 (file)
@@ -10,8 +10,7 @@ if(MGL_HAVE_FLTK)
        set_target_properties(mgl-fltk PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
        set_target_properties(mgl-fltk-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
        set_target_properties(mgl-fltk-static PROPERTIES COMPILE_FLAGS -DMGL_STATIC_DEFINE)
-       target_link_libraries(mgl-fltk mgl)
-       target_link_libraries(mgl-fltk ${FLTK_LIBRARIES})
+       target_link_libraries(mgl-fltk mgl ${FLTK_LIBRARIES})
 
        if(enable-mgl2)
                set_target_properties(mgl-fltk PROPERTIES OUTPUT_NAME "mgl2-fltk")
index eead69af89309ab2c397b63392561fe9f20aed68..15fb62d0c6267c2b52b580032d5c65c01de890d2 100644 (file)
 //-----------------------------------------------------------------------------
 #ifdef USE_GETTEXT
 #include <libintl.h>
-#else
-// Workaround for gcc 4.2
-#ifndef _LIBINTL_H
-#define gettext(x)     (x)
 #endif
+#ifndef _LIBINTL_H     // Workaround for gcc 4.2
+#define mgl_gettext(x) (x)
+#else
+#define mgl_gettext(x) gettext(x)
 #endif
 //-----------------------------------------------------------------------------
 #include "mgl2/canvas_wnd.h"
 #include "mgl2/fltk.h"
 //-----------------------------------------------------------------------------
-#include "xpm/alpha_on.xpm"
-#include "xpm/light_on.xpm"
-#include "xpm/zoom_on.xpm"
-#include "xpm/show_on.xpm"
-#include "xpm/rotate_on.xpm"
 #include "xpm/show_sl.xpm"
 #include "xpm/next_sl.xpm"
 #include "xpm/prev_sl.xpm"
 #include "xpm/rotate.xpm"
 #include "xpm/ok.xpm"
 #include "xpm/wire.xpm"
+#include "xpm/stop.xpm"
 //-----------------------------------------------------------------------------
-Fl_Pixmap xpm_a1(alpha_xpm), xpm_a2(alpha_on_xpm);
-Fl_Pixmap xpm_l1(light_on_xpm), xpm_l2(light_xpm);
-Fl_Pixmap xpm_z1(zoom_in_xpm), xpm_z2(zoom_on_xpm);
-Fl_Pixmap xpm_s1(show_sl_xpm), xpm_s2(show_on_xpm);
-Fl_Pixmap xpm_r1(rotate_xpm), xpm_r2(rotate_on_xpm);
+Fl_Pixmap xpm_a1(alpha_xpm);
+Fl_Pixmap xpm_l1(light_xpm);
+Fl_Pixmap xpm_z1(zoom_in_xpm);
+Fl_Pixmap xpm_s1(show_sl_xpm);
+Fl_Pixmap xpm_r1(rotate_xpm);
 Fl_Pixmap xpm_wire(wire_xpm);
 //-----------------------------------------------------------------------------
 /// Class allows the window creation for displaying plot bitmap with the help of FLTK library
@@ -123,12 +119,17 @@ Fl_MathGL::Fl_MathGL(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Widge
 //-----------------------------------------------------------------------------
 Fl_MathGL::~Fl_MathGL()        {       if(mgl_use_graph(gr,-1)<1)      mgl_delete_graph(gr);   }
 //-----------------------------------------------------------------------------
+void Fl_MathGL::stop(bool stop)        {       gr->AskStop(stop);      }
+//-----------------------------------------------------------------------------
+void mgl_fltk_event_func(void *)       {       Fl::awake();    }
+//-----------------------------------------------------------------------------
 void Fl_MathGL::set_graph(HMGL GR)
 {
        mglCanvas *gg = dynamic_cast<mglCanvas *>(GR);
        if(!gg) return;
        if(mgl_use_graph(gr,-1)<1)      mgl_delete_graph(gr);
        gr=gg;  mgl_use_graph(gg,1);
+       gr->SetEventFunc(mgl_fltk_event_func, NULL);
 }
 //-----------------------------------------------------------------------------
 void Fl_MathGL::draw()
@@ -161,7 +162,7 @@ void Fl_MathGL::update()
                mgl_set_alpha(gr,flag&1);       mgl_set_light(gr,flag&2);
                if(tet_val)     tet = tet_val->value();
                if(phi_val)     phi = phi_val->value();
-               mgl_zoom(gr,x1,y1,x2,y2);       mgl_view(gr,phi,0,tet);
+               mgl_zoom(gr,x1,y1,x2,y2);       mgl_view(gr,-phi,-tet,0);
                setlocale(LC_NUMERIC, "C");
                // use frames for quickly redrawing while adding/changing primitives
                if(mgl_is_frames(gr))   mgl_new_frame(gr);
@@ -174,7 +175,7 @@ void Fl_MathGL::update()
        }
        if(mgl_get_width(gr)!=w() || mgl_get_height(gr)!=h())
                size(mgl_get_width(gr), mgl_get_height(gr));
-       redraw();       Fl::flush();
+       gr->AskStop(false);     redraw();       Fl::flush();
 }
 //-----------------------------------------------------------------------------
 void Fl_MathGL::resize(int xx, int yy, int ww, int hh)
@@ -313,7 +314,7 @@ void Fl_MGLView::toggle(int &val, Fl_Button *b, const char *txt)
        val = 1-val;    b->value(val);
        if(menu && txt && *txt)
        {
-               Fl_Menu_Item *m = (Fl_Menu_Item *)menu->find_item(gettext(txt));
+               Fl_Menu_Item *m = (Fl_Menu_Item *)menu->find_item(mgl_gettext(txt));
                if(m && val)    m->set();
                if(m && !val)   m->clear();
        }
@@ -325,7 +326,7 @@ void Fl_MGLView::setoff(int &val, Fl_Button *b, const char *txt)
        val = 0;        b->value(val);
        if(menu && txt && *txt)
        {
-               Fl_Menu_Item *m = (Fl_Menu_Item *)menu->find_item(gettext(txt));
+               Fl_Menu_Item *m = (Fl_Menu_Item *)menu->find_item(mgl_gettext(txt));
                if(m && val)    m->set();
                if(m && !val)   m->clear();
        }
@@ -335,11 +336,11 @@ void Fl_MGLView::setoff(int &val, Fl_Button *b, const char *txt)
 void MGL_NO_EXPORT mgl_grid_cb(Fl_Widget*, void* v)
 {      if(v)   ((Fl_MGLView*)v)->toggle_grid();        }
 //-------------------------------------------------------------------------
-void MGL_NO_EXPORT mgl_alpha_cb(Fl_Widget*, void* v)   // alpha?xpm_a2:xpm_a1
+void MGL_NO_EXPORT mgl_alpha_cb(Fl_Widget*, void* v)
 {      if(v)   ((Fl_MGLView*)v)->toggle_alpha();       }
 void mglCanvasFL::ToggleAlpha()        {       Fl::lock();     mgl->toggle_alpha();    Fl::unlock();   }
 //-----------------------------------------------------------------------------
-void MGL_NO_EXPORT mgl_light_cb(Fl_Widget*, void* v)   // light?xpm_l2:xpm_l1
+void MGL_NO_EXPORT mgl_light_cb(Fl_Widget*, void* v)
 {      if(v)   ((Fl_MGLView*)v)->toggle_light();       }
 void mglCanvasFL::ToggleLight()        {       Fl::lock();     mgl->toggle_light();    Fl::unlock();   }
 //-----------------------------------------------------------------------------
@@ -379,77 +380,77 @@ void mglCanvasFL::Update()                {       Fl::lock();     mgl->update();  Fl::unlock();   }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_png_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.png", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.png", 0);
        if(!fname || !fname[0]) return;
        mgl_write_png(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_bps_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.eps", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.eps", 0);
        if(!fname || !fname[0]) return;
        mgl_write_bps(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_pngn_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.png", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.png", 0);
        if(!fname || !fname[0]) return;
        mgl_write_png_solid(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_jpeg_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.jpg", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.jpg", 0);
        if(!fname || !fname[0]) return;
        mgl_write_jpg(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_svg_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.svg", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.svg", 0);
        if(!fname || !fname[0]) return;
        mgl_write_svg(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_eps_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.eps", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.eps", 0);
        if(!fname || !fname[0]) return;
        mgl_write_eps(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_prc_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.prc", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.prc", 0);
        if(!fname || !fname[0]) return;
        mgl_write_prc(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0,1);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_tex_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.tex", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.tex", 0);
        if(!fname || !fname[0]) return;
        mgl_write_tex(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_obj_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.obj", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.obj", 0);
        if(!fname || !fname[0]) return;
        mgl_write_obj(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0,1);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_off_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.off", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.off", 0);
        if(!fname || !fname[0]) return;
        mgl_write_off(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0,0);
 }
 //-----------------------------------------------------------------------------
 void MGL_NO_EXPORT mgl_export_stl_cb(Fl_Widget*, void* v)
 {
-       char *fname = fl_file_chooser(gettext("Save File As?"), "*.stl", 0);
+       char *fname = fl_file_chooser(mgl_gettext("Save File As?"), "*.stl", 0);
        if(!fname || !fname[0]) return;
        mgl_write_stl(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
 }
@@ -541,27 +542,30 @@ void MGL_NO_EXPORT mgl_sshow_cb(Fl_Widget *, void *v)
        if(e->is_sshow())       Fl::add_timeout(e->delay(e->par), mgl_time_cb, v);
 }
 void mglCanvasFL::Animation()  {       Fl::lock();     mgl_sshow_cb(0,mgl);    Fl::unlock();   }
-void MGL_NO_EXPORT mgl_no_cb(Fl_Widget *, void *)      {}
+void MGL_LOCAL_CONST mgl_no_cb(Fl_Widget *, void *)    {}
+//-----------------------------------------------------------------------------
+void MGL_NO_EXPORT mgl_stop_cb(Fl_Widget*, void* v)
+{      Fl_MGLView *e = (Fl_MGLView*)v; if(e)   e->FMGL->stop();        }
 //-----------------------------------------------------------------------------
 Fl_Menu_Item pop_graph[20] = {
-       { gettext("Export"), 0, mgl_no_cb, 0, FL_SUBMENU,0,0,0,0},
-               { gettext("... as PNG"),        0, mgl_export_png_cb,0,0,0,0,0,0 },
-               { gettext("... as PNG (solid)"),        0, mgl_export_pngn_cb,0,0,0,0,0,0 },
-               { gettext("... as JPEG"),       0, mgl_export_jpeg_cb,0,0,0,0,0,0 },
-               { gettext("... as SVG"),        0, mgl_export_svg_cb,0,0,0,0,0,0 },
-               { gettext("... as vector EPS"), 0, mgl_export_eps_cb,0,0,0,0,0,0 },
-               { gettext("... as bitmap EPS"), 0, mgl_export_bps_cb, 0, FL_MENU_DIVIDER,0,0,0,0 },
-               { gettext("... as TeX"),        0, mgl_export_tex_cb,0,0,0,0,0,0 },
-               { gettext("... as OBJ"),        0, mgl_export_obj_cb,0,0,0,0,0,0 },
-               { gettext("... as PRC"),        0, mgl_export_prc_cb,0,0,0,0,0,0 },
-               { gettext("... as OFF"),        0, mgl_export_off_cb,0,0,0,0,0,0 },
-               { gettext("... as STL"),        0, mgl_export_stl_cb,0,0,0,0,0,0 },
+       { mgl_gettext("Export"), 0, mgl_no_cb, 0, FL_SUBMENU,0,0,0,0},
+               { mgl_gettext("... as PNG"),    0, mgl_export_png_cb,0,0,0,0,0,0 },
+               { mgl_gettext("... as PNG (solid)"),    0, mgl_export_pngn_cb,0,0,0,0,0,0 },
+               { mgl_gettext("... as JPEG"),   0, mgl_export_jpeg_cb,0,0,0,0,0,0 },
+               { mgl_gettext("... as SVG"),    0, mgl_export_svg_cb,0,0,0,0,0,0 },
+               { mgl_gettext("... as vector EPS"),     0, mgl_export_eps_cb,0,0,0,0,0,0 },
+               { mgl_gettext("... as bitmap EPS"),     0, mgl_export_bps_cb, 0, FL_MENU_DIVIDER,0,0,0,0 },
+               { mgl_gettext("... as TeX"),    0, mgl_export_tex_cb,0,0,0,0,0,0 },
+               { mgl_gettext("... as OBJ"),    0, mgl_export_obj_cb,0,0,0,0,0,0 },
+               { mgl_gettext("... as PRC"),    0, mgl_export_prc_cb,0,0,0,0,0,0 },
+               { mgl_gettext("... as OFF"),    0, mgl_export_off_cb,0,0,0,0,0,0 },
+               { mgl_gettext("... as STL"),    0, mgl_export_stl_cb,0,0,0,0,0,0 },
                { 0,0,0,0,0,0,0,0,0 },
-       { gettext("Copy graphics"),     0, 0, 0, FL_MENU_INACTIVE|FL_MENU_DIVIDER,0,0,0,0},
-       { gettext("Normal view"),       0, mgl_norm_cb,0,0,0,0,0,0 },
-       { gettext("Redraw plot"),       0, mgl_draw_cb,0,0,0,0,0,0 },
-       { gettext("Adjust size"),       0, mgl_adjust_cb,0,0,0,0,0,0 },
-       { gettext("Reload data"),       0, mgl_oncemore_cb,0,0,0,0,0,0 },
+       { mgl_gettext("Copy graphics"), 0, 0, 0, FL_MENU_INACTIVE|FL_MENU_DIVIDER,0,0,0,0},
+       { mgl_gettext("Normal view"),   0, mgl_norm_cb,0,0,0,0,0,0 },
+       { mgl_gettext("Redraw plot"),   0, mgl_draw_cb,0,0,0,0,0,0 },
+       { mgl_gettext("Adjust size"),   0, mgl_adjust_cb,0,0,0,0,0,0 },
+       { mgl_gettext("Reload data"),   0, mgl_oncemore_cb,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0 }
 };
 //-----------------------------------------------------------------------------
@@ -575,30 +579,33 @@ Fl_MGLView::Fl_MGLView(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Win
 
        alpha_bt = new Fl_Button(0, 1, 25, 25); alpha_bt->type(FL_TOGGLE_BUTTON);
        alpha_bt->image(xpm_a1);        alpha_bt->callback(mgl_alpha_cb,this);
-       alpha_bt->tooltip(gettext("Switch on/off transparency in the picture"));
+       alpha_bt->tooltip(mgl_gettext("Switch on/off transparency in the picture"));
 //     alpha_bt->box(FL_PLASTIC_UP_BOX);               alpha_bt->down_box(FL_PLASTIC_DOWN_BOX);
        light_bt = new Fl_Button(25, 1, 25, 25);        light_bt->type(FL_TOGGLE_BUTTON);
        light_bt->image(xpm_l1);        light_bt->callback(mgl_light_cb,this);
-       light_bt->tooltip(gettext("Switch on/off lightning in the picture"));
+       light_bt->tooltip(mgl_gettext("Switch on/off lightning in the picture"));
 //     light_bt->box(FL_PLASTIC_UP_BOX);               light_bt->down_box(FL_PLASTIC_DOWN_BOX);
        grid_bt = new Fl_Button(50, 1, 25, 25); grid_bt->type(FL_TOGGLE_BUTTON);
        grid_bt->image(xpm_wire);       grid_bt->callback(mgl_grid_cb,this);
-       grid_bt->tooltip(gettext("Switch on/off grid drawing"));
+       grid_bt->tooltip(mgl_gettext("Switch on/off grid drawing"));
        //      grid_bt->box(FL_PLASTIC_UP_BOX);                grid_bt->down_box(FL_PLASTIC_DOWN_BOX);
 
        rotate_bt = new Fl_Button(80, 1, 25, 25);rotate_bt->type(FL_TOGGLE_BUTTON);
        rotate_bt->image(xpm_r1);       rotate_bt->callback(mgl_rotate_cb,this);
-       rotate_bt->tooltip(gettext("Rotate picture by holding left mouse button"));
+       rotate_bt->tooltip(mgl_gettext("Rotate picture by holding left mouse button"));
 //     rotate_bt->box(FL_PLASTIC_UP_BOX);              rotate_bt->down_box(FL_PLASTIC_DOWN_BOX);
        zoom_bt = new Fl_Button(105, 1, 25, 25);        zoom_bt->type(FL_TOGGLE_BUTTON);
        zoom_bt->image(xpm_z1); zoom_bt->callback(mgl_zoom_cb,this);
-       zoom_bt->tooltip(gettext("Zoom in selected region of the picture"));
+       zoom_bt->tooltip(mgl_gettext("Zoom in selected region of the picture"));
 //     zoom_bt->box(FL_PLASTIC_UP_BOX);                        zoom_bt->down_box(FL_PLASTIC_DOWN_BOX);
-       o = new Fl_Button(130, 1, 25, 25);              o->tooltip(gettext("Return picture to normal zoom"));
+       o = new Fl_Button(130, 1, 25, 25);              o->tooltip(mgl_gettext("Return picture to normal zoom"));
        o->image(new Fl_Pixmap(zoom_out_xpm));  o->callback(mgl_norm_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
 
-       o = new Fl_Button(160, 1, 25, 25);      o->tooltip(gettext("Refresh the picture"));
+       o = new Fl_Button(160, 1, 25, 25);      o->tooltip(mgl_gettext("Stop drawing"));
+       o->image(new Fl_Pixmap(stop_xpm));      o->callback(mgl_stop_cb,this);
+
+       o = new Fl_Button(160, 1, 25, 25);      o->tooltip(mgl_gettext("Refresh the picture"));
        o->image(new Fl_Pixmap(ok_xpm));        o->callback(mgl_draw_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
 
@@ -606,40 +613,40 @@ Fl_MGLView::Fl_MGLView(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Win
        tet = new Fl_Counter(195, 1, 90, 25, 0);        tet->callback(mgl_draw_cb,this);
        phi = new Fl_Counter(290, 1, 90, 25, 0);        phi->callback(mgl_draw_cb,this);
        tet->lstep(10); tet->step(1);   tet->range(-180,180);
-       tet->tooltip(gettext("Theta angle (tilt z-axis)"));
+       tet->tooltip(mgl_gettext("Theta angle (tilt z-axis)"));
        phi->lstep(10); phi->step(1);   phi->range(-180,180);
-       phi->tooltip(gettext("Phi angle (rotate in x*y plane)"));
+       phi->tooltip(mgl_gettext("Phi angle (rotate in x*y plane)"));
 //     tet->box(FL_PLASTIC_UP_BOX);    phi->box(FL_PLASTIC_UP_BOX);
        g->end();       g->resizable(0);
 
        g = new Fl_Group(0,30,30,260);
-       o = new Fl_Button(1, 30, 25, 25);               o->tooltip(gettext("Shift the picture up"));
+       o = new Fl_Button(1, 30, 25, 25);               o->tooltip(mgl_gettext("Shift the picture up"));
        o->image(new Fl_Pixmap(up_1_xpm));              o->callback(mgl_su_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
-       o = new Fl_Button(1, 55, 25, 25);               o->tooltip(gettext("Shift the picture left"));
+       o = new Fl_Button(1, 55, 25, 25);               o->tooltip(mgl_gettext("Shift the picture left"));
        o->image(new Fl_Pixmap(left_1_xpm));    o->callback(mgl_sl_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
-       o = new Fl_Button(1, 80, 25, 25);               o->tooltip(gettext("Zoom in the picture"));
+       o = new Fl_Button(1, 80, 25, 25);               o->tooltip(mgl_gettext("Zoom in the picture"));
        o->image(new Fl_Pixmap(zoom_1_xpm));    o->callback(mgl_sz_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
-       o = new Fl_Button(1, 105, 25, 25);              o->tooltip(gettext("Zoom out the picture"));
+       o = new Fl_Button(1, 105, 25, 25);              o->tooltip(mgl_gettext("Zoom out the picture"));
        o->image(new Fl_Pixmap(norm_1_xpm));    o->callback(mgl_so_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
-       o = new Fl_Button(1, 130, 25, 25);              o->tooltip(gettext("Shift the picture right"));
+       o = new Fl_Button(1, 130, 25, 25);              o->tooltip(mgl_gettext("Shift the picture right"));
        o->image(new Fl_Pixmap(right_1_xpm));   o->callback(mgl_sr_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
-       o = new Fl_Button(1, 155, 25, 25);              o->tooltip(gettext("Shift the picture down"));
+       o = new Fl_Button(1, 155, 25, 25);              o->tooltip(mgl_gettext("Shift the picture down"));
        o->image(new Fl_Pixmap(down_1_xpm));    o->callback(mgl_sd_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
 
-       o = new Fl_Button(1, 185, 25, 25);              o->tooltip(gettext("Show previous frame in slideshow"));
+       o = new Fl_Button(1, 185, 25, 25);              o->tooltip(mgl_gettext("Show previous frame in slideshow"));
        o->image(new Fl_Pixmap(prev_sl_xpm));   o->callback(mgl_sprev_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
        anim_bt = new Fl_Button(1, 210, 25, 25);        anim_bt->type(FL_TOGGLE_BUTTON);
        anim_bt->image(xpm_s1); anim_bt->callback(mgl_sshow_cb,this);
-       anim_bt->tooltip(gettext("Run/Stop slideshow (graphics animation)"));
+       anim_bt->tooltip(mgl_gettext("Run/Stop slideshow (graphics animation)"));
 //     anim_bt->box(FL_PLASTIC_UP_BOX);                anim_bt->down_box(FL_PLASTIC_DOWN_BOX);
-       o = new Fl_Button(1, 235, 25, 25);              o->tooltip(gettext("Show next frame in slideshow"));
+       o = new Fl_Button(1, 235, 25, 25);              o->tooltip(mgl_gettext("Show next frame in slideshow"));
        o->image(new Fl_Pixmap(next_sl_xpm));   o->callback(mgl_snext_cb,this);
 //     o->box(FL_PLASTIC_UP_BOX);      o->down_box(FL_PLASTIC_DOWN_BOX);
 
@@ -674,7 +681,7 @@ void mglCanvasFL::GotoFrame(int d)
 void MGL_NO_EXPORT mgl_fl_next(void *v)        {       ((mglCanvasWnd*)v)->NextFrame();        }       ///< Callback function for next frame
 void MGL_NO_EXPORT mgl_fl_prev(void *v)        {       ((mglCanvasWnd*)v)->PrevFrame();        }       ///< Callback function for prev frame
 void MGL_NO_EXPORT mgl_fl_reload(void *v)      {       ((mglCanvasWnd*)v)->ReLoad();   }               ///< Callback function for reloading
-mreal MGL_NO_EXPORT mgl_fl_delay(void *v)      {       return ((mglCanvasWnd*)v)->GetDelay();  }       ///< Callback function for delay
+mreal MGL_LOCAL_PURE mgl_fl_delay(void *v)     {       return ((mglCanvasWnd*)v)->GetDelay();  }       ///< Callback function for delay
 //-----------------------------------------------------------------------------
 void MGL_EXPORT mgl_makemenu_fltk(Fl_Menu_ *m, Fl_MGLView *w)
 {
@@ -686,7 +693,7 @@ void MGL_EXPORT mgl_makemenu_fltk(Fl_Menu_ *m, Fl_MGLView *w)
        m->add("Graphics/Redraw", "f5", mgl_draw_cb, w);
        m->add("Graphics/Adjust size", "f6", mgl_adjust_cb, w);
        m->add("Graphics/Reload data", "f9", mgl_oncemore_cb, w);
-       //TODO  m->add("Graphics/Stop", "f7", mgl_stop_cb, w);
+       m->add("Graphics/Stop", "f7", mgl_stop_cb, w);
        //TODO  m->add("Graphics/Copy graphics","+^c", mgl_copyimg_cb, w);
 
        m->add("Graphics/Export/as PNG", "#p", mgl_export_png_cb, w);
index 2ecd8c00259b45adc709ee5a0e20da121f17dda6..a95fa6e82e769e83a2b938b8ee1c1471b451c7aa 100644 (file)
@@ -106,7 +106,8 @@ void _mgl_key_up(unsigned char ch,int ,int )
                printf("Use 'u', 'o' for changing distance to light\n");\r
                printf("Use 'r' for switching transparency\n");\r
                printf("Use 'f' for switching lightning\n");\r
-               printf("Use 'T' for exporting to TIFF file\n");\r
+               printf("Use 'E' for exporting to EPS file\n");\r
+               printf("Use 'S' for exporting to SVG file\n");\r
                printf("Use 'J' for exporting to JPEG file\n");\r
                printf("Use 'P' for exporting to PNG file\n");\r
                printf("Use ',', '.' for show other frames\n");\r
@@ -139,7 +140,10 @@ void _mgl_key_up(unsigned char ch,int ,int )
                glDeleteLists(1,_mgl_glwnd->NumFig);\r
                _mgl_glwnd->LoadFunc(_mgl_glwnd->FuncPar);\r
                if(_mgl_glwnd->DrawFunc)\r
+               {\r
+                       _mgl_glwnd->ResetFrames();\r
                        (_mgl_glwnd->DrawFunc)(_mgl_glwnd,_mgl_glwnd->FuncPar);\r
+               }\r
                _mgl_glwnd->Finish();\r
        }\r
        if(ch=='P')\r
@@ -160,6 +164,12 @@ void _mgl_key_up(unsigned char ch,int ,int )
                snprintf(str,128,"%s_%d.eps",_mgl_glwnd->PlotId.c_str(),_mgl_glwnd->curr_fig);\r
                mgl_write_eps(_mgl_glwnd, str, "Math GL");\r
        }\r
+       if(ch=='S')\r
+       {\r
+               char str[128];\r
+               snprintf(str,128,"%s_%d.svg",_mgl_glwnd->PlotId.c_str(),_mgl_glwnd->curr_fig);\r
+               mgl_write_svg(_mgl_glwnd, str, "Math GL");\r
+       }\r
        if(ch==' ')     _mgl_glwnd->Clf();\r
        if(ch=='m')     _mgl_glwnd->tt = 1-_mgl_glwnd->tt;\r
        rL = rL<0 ? 0 : (rL>5 ? 5 : rL);\r
@@ -192,7 +202,10 @@ void _mgl_display()
        else\r
        {\r
                if(_mgl_glwnd->DrawFunc)\r
+               {\r
+                       _mgl_glwnd->ResetFrames();\r
                        (_mgl_glwnd->DrawFunc)(_mgl_glwnd,_mgl_glwnd->FuncPar);\r
+               }\r
                _mgl_glwnd->Finish();\r
        }\r
        glFinish();\r
index 6d6cc11b3b0305141300ce46771785a560bb26a1..aea5f7c6268a2b2570493a3cf698507c743bce49 100644 (file)
@@ -36,6 +36,7 @@
 #include <QPrintDialog>
 #include <QFileDialog>
 #include <QInputDialog>
+#include <QThread>
 #include <limits.h>
 
 #include "mgl2/canvas_wnd.h"
@@ -45,6 +46,7 @@
 #define MGL_MAX_LINES  (INT_MAX-1000)
 #if !defined(WIN32) && !defined(__APPLE__)
 #include <X11/Xlib.h>
+#include <qt5/QtCore/QTimer>
 #endif
 //-----------------------------------------------------------------------------
 /// Base class for windows containing MathGL graphics
@@ -87,9 +89,38 @@ void MGL_EXPORT mgl_ask_qt(const wchar_t *quest, wchar_t *res)
 //             class QMathGL
 //
 //-----------------------------------------------------------------------------
+/// Internal class to be used for multi-threading plotting
+/*class mglTask : public QObject
+{
+       Q_OBJECT
+public:
+       mglCanvas *gr;          ///< Built-in mglCanvasQT-er instance (used by default)
+       void *draw_par;         ///< Parameters for drawing function mglCanvasWnd::DrawFunc.
+       /// Drawing function for window procedure. It should return the number of frames.
+       int (*draw_func)(mglBase *gr, void *par);
+       mglDraw *draw;          ///< Class for drawing -- need to call directly due to inheritance mechanism
+public slots:
+       void doWork();
+signals:
+       void plotDone();
+};
+//-----------------------------------------------------------------------------
+void mglTask::doWork()
+{
+       setlocale(LC_NUMERIC, "C");
+       if(mgl_is_frames(gr))   mgl_new_frame(gr);
+       if(draw_func)   draw_func(gr, draw_par);
+       else if(draw)   {       mglGraph g(gr); draw->Draw(&g); }
+       if(mgl_is_frames(gr))   mgl_end_frame(gr);
+       setlocale(LC_NUMERIC, "");
+       gr->Finish();
+       emit plotDone();
+}*/
+//-----------------------------------------------------------------------------
 QMathGL::QMathGL(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
 {
        autoResize = false;     draw_par = 0;   draw_func = 0;
+       dotsRefr = true;
        gr = new mglCanvas;     appName = "MathGL";
        popup = 0;      grBuf = 0;      draw = 0;
        phi = tet = per = 0;
@@ -97,10 +128,17 @@ QMathGL::QMathGL(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
        alpha = light = zoom = rotate = grid = viewYZ = custZoom = custDraw = false;
        resize(600, 400);       mgl_set_flag(gr, true, MGL_CLF_ON_UPD);
        timer = new QTimer(this);
+       timerRefr = new QTimer(this);   timerRefr->setInterval(100);
+       timerRefr->setSingleShot(true);
        enableWheel = enableMouse = true;
-//     resize(graph->GetWidth(), graph->GetHeight());
-//     mglConvertFromGraph(pic, graph, &grBuf);
        connect(timer, SIGNAL(timeout()), this, SLOT(nextSlide()));
+       connect(timerRefr, SIGNAL(timeout()), this, SLOT(refreshHQ()));
+
+/*     thread = new QThread();
+       task = new mglTask();   task->moveToThread(thread);
+       connect(thread, SIGNAL(started()), task, SLOT(doWork()));
+       connect(task, SIGNAL(plotDone()), thread, SLOT(quit()));
+       connect(thread, SIGNAL(finished()), this, SLOT(afterPlot()));*/
 }
 //-----------------------------------------------------------------------------
 QMathGL::~QMathGL()
@@ -110,6 +148,9 @@ QMathGL::~QMathGL()
        if(draw)        delete draw;
 }
 //-----------------------------------------------------------------------------
+void QMathGL::setDotsPreview(bool d)
+{      dotsRefr = d;   }
+//-----------------------------------------------------------------------------
 void QMathGL::setDraw(int (*func)(mglBase *gr, void *par), void *par)
 {
        if(draw)        delete draw;    draw = 0;
@@ -125,6 +166,7 @@ void QMathGL::setDraw(mglDraw *dr)
 }
 //-----------------------------------------------------------------------------
 double QMathGL::getRatio()     {       return double(mgl_get_width(gr))/mgl_get_height(gr);    }
+void mgl_qt_event_func(void *) {       QApplication::processEvents();  }
 //-----------------------------------------------------------------------------
 void QMathGL::setGraph(HMGL GR)        ///< Set grapher object
 {
@@ -132,6 +174,7 @@ void QMathGL::setGraph(HMGL GR)     ///< Set grapher object
        if(!gg) return;
        if(mgl_use_graph(gr,-1)<1)      mgl_delete_graph(gr);
        gr=gg;  mgl_use_graph(gg,1);
+       gr->SetEventFunc(mgl_qt_event_func, NULL);
 }
 //-----------------------------------------------------------------------------
 void QMathGL::paintEvent(QPaintEvent *)
@@ -257,46 +300,47 @@ void QMathGL::restore()
        else refresh();
 }
 //-----------------------------------------------------------------------------
-void QMathGL::stop()   {       gr->Stop=true;  }       //{     thr->terminate();       }
+void QMathGL::stop()   {       gr->AskStop(true);      }
+//-----------------------------------------------------------------------------
 void QMathGL::update()
 {
-/*     if(!thr->isRunning())
-       {
-               thr->gr = gr;   thr->text = text;
-               thr->line = line;       thr->start();
-       }
-       if(rotate)      thr->wait();
-       else    while(thr->isRunning()) qApp->processEvents();
-       if(warnMGL)     warnMGL->setText(thr->warn);*/
-
        if(draw_func || draw)
        {
                mgl_reset_frames(gr);   // remove previous frames
                if(mgl_get_flag(gr,MGL_CLF_ON_UPD))     mgl_set_def_param(gr);
                mgl_set_alpha(gr,alpha);        mgl_set_light(gr,light);
-               if(!isHidden()) QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-               setlocale(LC_NUMERIC, "C");
                // use frames for quickly redrawing while adding/changing primitives
                if(custDraw)    emit customDraw(x1,y1,x2,y2,true);
+
+               if(!isHidden()) QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+/*             task->gr = gr;  task->draw = draw;
+               task->draw_func = draw_func;
+               task->draw_par = draw_par;
+               thread->start();*/
+               setlocale(LC_NUMERIC, "C");
                if(mgl_is_frames(gr))   mgl_new_frame(gr);
                if(draw_func)   draw_func(gr, draw_par);
                else if(draw)   {       mglGraph g(gr); draw->Draw(&g); }
                if(mgl_is_frames(gr))   mgl_end_frame(gr);
                setlocale(LC_NUMERIC, "");
-               if(!isHidden()) QApplication::restoreOverrideCursor();
-               emit refreshData();
-               emit showWarn(mgl_get_mess(gr));
-               mousePos="";
+               gr->AskStop(false);     afterPlot();
        }
+}
+//-----------------------------------------------------------------------------
+void QMathGL::afterPlot()
+{
+       emit refreshData();
+       emit showWarn(mgl_get_mess(gr));
+       mousePos="";
+       if(!isHidden()) QApplication::restoreOverrideCursor();
        refresh();
 }
 //-----------------------------------------------------------------------------
-void QMathGL::draw_thr()
+void QMathGL::drawPrim()
 {
-       mgl_clf(gr);
+//     mgl_clf_nfog(gr);
        mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);
-       int c = g?g->GetCurFig():mgl_get_num_frame(gr)-1;
-       mgl_get_frame(gr, c);
+       mgl_get_frame(gr, g?g->GetCurFig():mgl_get_num_frame(gr)-1);
        mglParse pr;
        long i, n=primitives.count('\n');
        mglGraph gg(gr);
@@ -313,27 +357,43 @@ void QMathGL::draw_thr()
        gg.SetRanges(ox1,ox2);  gg.Pop();       setlocale(LC_NUMERIC, "");
 }
 //-----------------------------------------------------------------------------
-void *mgl_qt_thr(void *p)      {       QMathGL *q = (QMathGL *)p;      q->draw_thr();  return 0;       }
 void QMathGL::refresh()
 {
+       if(dotsRefr)
+       {
+               timerRefr->start();
+               int q = gr->GetQuality();
+               prevQuality = q!=MGL_DRAW_DOTS?q:prevQuality;
+               gr->SetQuality(MGL_DRAW_DOTS);
+       }
        if(mgl_is_frames(gr) && mgl_get_num_frame(gr)>0)
        {
-               if(draw_func || draw)
-               {
-/*#if MGL_HAVE_PTHREAD // TODO add qthread here later
-                       pthread_t tmp;
-                       pthread_create(&tmp, 0, mgl_qt_thr, this);
-                       pthread_join(tmp, 0);
-#else*/
-                       draw_thr();
-/*#endif*/
+               drawPrim();
+               if(custZoom)    emit customZoom(x1,y1,x2,y2,tet,phi,per);
+               else
+               {       mgl_zoom(gr,x1,y1,x2,y2);
+                       mgl_ask_perspective(gr,per);
+                       if(viewYZ)      mgl_view(gr,0,-tet,-phi);
+                       else            mgl_view(gr,-phi,-tet,0);
                }
+       }
+       mglConvertFromGraph(pic, gr, &grBuf);
+       if(pic.size()!=size())  setSize(pic.width(), pic.height());
+       repaint();
+}
+//-----------------------------------------------------------------------------
+void QMathGL::refreshHQ()
+{
+       gr->SetQuality(prevQuality);
+       if(mgl_is_frames(gr) && mgl_get_num_frame(gr)>0)
+       {
+               drawPrim();
                if(custZoom)    emit customZoom(x1,y1,x2,y2,tet,phi,per);
                else
                {       mgl_zoom(gr,x1,y1,x2,y2);
-                       mgl_perspective(gr,per);
-                       if(viewYZ)      mgl_view(gr,0,phi,tet);
-                       else            mgl_view(gr,phi,0,tet);
+                       mgl_ask_perspective(gr,per);
+                       if(viewYZ)      mgl_view(gr,0,-tet,-phi);
+                       else            mgl_view(gr,-phi,-tet,0);
                }
        }
        mglConvertFromGraph(pic, gr, &grBuf);
@@ -489,6 +549,13 @@ void QMathGL::mouseMoveEvent(QMouseEvent *ev)
                                        else    dr = hypot(dx,dy);
                                        res = tst.section(' ',0,4)+" "+QString::number(tst.section(' ',5,5).toFloat()+dr)+" "+tst.section(' ',6);
                                }
+                               else if(cmd=="arc")
+                               {
+                                       double x_=tst.section(' ',3,3).toFloat()-xx, y_=tst.section(' ',4,4).toFloat()-yy, a_=tst.section(' ',5,5).toFloat();
+                                       double c=cos(M_PI*a_/180), s=sin(M_PI*a_/180);
+                                       double a = atan2(x_,y_) - atan2(x_*c-y_*s+dx,x_*s+y_*c+dy);
+                                       res = tst.section(' ',0,4)+" "+QString::number(a*180/M_PI)+" "+tst.section(' ',6);
+                               }
                                else if(p.n==2)
                                {
                                        xx=tst.section(' ',5,5).toFloat();      yy=tst.section(' ',6,6).toFloat();
@@ -510,7 +577,7 @@ void QMathGL::mouseMoveEvent(QMouseEvent *ev)
                        QString tst = primitives.section('\n',id,id), cmd=tst.section(' ',0,0), res;
                        float dx = 2*(xe-x0)/float(w), dy = 2*(y0-ye)/float(h);
                        float x1=tst.section(' ',1,1).toFloat(), y1=tst.section(' ',2,2).toFloat(),x2,y2;
-                       if(cmd=="ball" || cmd=="text")
+                       if(cmd=="ball")
                                res = cmd+" "+QString::number(x1+dx)+" "+QString::number(y1+dy)+" "+tst.section(' ',3);
                        else if(cmd=="curve")
                        {
@@ -849,7 +916,7 @@ void QMathGL::adjust()
 {
        mgl_set_size(gr, parentWidget()->width()-3, parentWidget()->height()-3);
        setSize(parentWidget()->width()-3, parentWidget()->height()-3);
-       update();
+       update();       // TODO replace to refresh ?!?
 }
 //-----------------------------------------------------------------------------
 void QMathGL::addMark()
@@ -870,12 +937,24 @@ void QMathGL::addRhomb()
 void QMathGL::addEllipse()
 {      primitives += "ellipse -0.2 0 0.2 0 0.1 'r'\n"; refresh();      }
 //-----------------------------------------------------------------------------
+void QMathGL::addArc()
+{      primitives += "arc 0 0 0.2 0 60 'r2'\n";        refresh();      }
+//-----------------------------------------------------------------------------
+void QMathGL::addPolygon(int n)
+{
+       if(n<3)
+               n = QInputDialog::getText(QApplication::activeWindow(), "MathGL", tr("Enter number of vertexes")).toInt();
+       if(n>=3)
+       {       primitives += "polygon 0 0 0 0.2 "+QString::number(n)+" 'r'\n"; refresh();      }
+}
+//{    primitives += "arc -0.2 0 0.2 0 0.1 'r'\n";     refresh();      }
+//-----------------------------------------------------------------------------
 void QMathGL::addText(QString txt)
 {
        if(txt.isEmpty())
                txt = QInputDialog::getText(QApplication::activeWindow(), "MathGL", tr("Enter text"));
        if(!txt.isEmpty())
-       {       primitives += "text 0 0 '"+txt+"' ''\n";        refresh();      }
+       {       primitives += "text 0 0 0.1 0 '"+txt+"' ''\n";  refresh();      }
 }
 //-----------------------------------------------------------------------------
 //
@@ -957,33 +1036,36 @@ void mglCanvasQT::Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p
        else    Wnd->showMaximized();
 }
 //-----------------------------------------------------------------------------
-#include "xpm/fileprint.xpm"
+#include "xpm/alpha.xpm"
+#include "xpm/arc.xpm"
 #include "xpm/copy.xpm"
+#include "xpm/curve.xpm"
+#include "xpm/down_1.xpm"
+#include "xpm/fileprint.xpm"
 #include "xpm/left_1.xpm"
+#include "xpm/light.xpm"
+#include "xpm/line.xpm"
+#include "xpm/mark_a.xpm"
+#include "xpm/mark_d.xpm"
+#include "xpm/mark_o.xpm"
+#include "xpm/mark_s.xpm"
 #include "xpm/right_1.xpm"
-#include "xpm/down_1.xpm"
+#include "xpm/next_sl.xpm"
 #include "xpm/norm_1.xpm"
-#include "xpm/zoom_1.xpm"
-#include "xpm/up_1.xpm"
-#include "xpm/alpha.xpm"
-#include "xpm/light.xpm"
-#include "xpm/zoom_in.xpm"
-#include "xpm/zoom_out.xpm"
-#include "xpm/rotate.xpm"
 #include "xpm/ok.xpm"
-#include "xpm/show_sl.xpm"
-#include "xpm/next_sl.xpm"
 #include "xpm/prev_sl.xpm"
+#include "xpm/rotate.xpm"
+#include "xpm/show_sl.xpm"
 #include "xpm/text.xpm"
-#include "xpm/line.xpm"
-#include "xpm/curve.xpm"
-#include "xpm/mark_o.xpm"
-#include "xpm/mark_s.xpm"
-#include "xpm/mark_a.xpm"
-#include "xpm/mark_d.xpm"
+#include "xpm/polygon.xpm"
+#include "xpm/zoom_1.xpm"
+#include "xpm/zoom_in.xpm"
+#include "xpm/zoom_out.xpm"
+#include "xpm/up_1.xpm"
+#include "xpm/stop.xpm"
 //-----------------------------------------------------------------------------
 #define TR     QObject::tr
-QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, QSpinBox *&phi)
+MGL_EXPORT QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, QSpinBox *&phi)
 {
        QAction *a;
        QMenu *o, *oo;
@@ -1055,11 +1137,16 @@ QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, QSpinBox *&p
                a->setShortcut(Qt::ALT+Qt::Key_Space);
                o->addAction(a);        bb->addAction(a);       popup->addAction(a);
                bb->addSeparator();
+               o->addAction(a);        bb->addAction(a);       popup->addAction(a);
                a = new QAction(QPixmap(ok_xpm), TR("Re&draw"), Wnd);
                Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(update()));
                a->setToolTip(TR("Execute script and redraw graphics (F5)."));
                a->setShortcut(Qt::Key_F5);
                o->addAction(a);        bb->addAction(a);       popup->addAction(a);
+               a = new QAction(QPixmap(stop_xpm), TR("Stop"), Wnd);
+               Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(stop()));
+               a->setToolTip(TR("Ask to stop plot drawing (F7)."));
+               a->setShortcut(Qt::Key_F7);
                a = new QAction(TR("&Adjust size"), Wnd);
                Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(adjust()));
                a->setToolTip(TR("Change canvas size to fill whole region (F6)."));
@@ -1077,6 +1164,11 @@ QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, QSpinBox *&p
                Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
                a->setToolTip(TR("Add line which properties can be changed later by mouse."));
                bb->addAction(a);       oo->addAction(a);
+               a = new QAction(QPixmap(arc_xpm), TR("Add arc"), Wnd);
+               Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addArc()));
+               Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(TR("Add arc which properties can be changed later by mouse."));
+               bb->addAction(a);       oo->addAction(a);
                a = new QAction(QPixmap(curve_xpm), TR("Add curve"), Wnd);
                Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addCurve()));
                Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
@@ -1097,6 +1189,11 @@ QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, QSpinBox *&p
                Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
                a->setToolTip(TR("Add ellipse which properties can be changed later by mouse."));
                bb->addAction(a);       oo->addAction(a);
+               a = new QAction(QPixmap(polygon_xpm), TR("Add polygon"), Wnd);
+               Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addPolygon()));
+               Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
+               a->setToolTip(TR("Add polygon which properties can be changed later by mouse."));
+               bb->addAction(a);       oo->addAction(a);
                a = new QAction(QPixmap(mark_a_xpm), TR("Add mark"), Wnd);
                Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addMark()));
                Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
index 3989a4782be8c2ad38dc885e9899c84a44194bc5..b36401067d3ad230b56c1aeb6a4bf84aa6dabd6c 100644 (file)
@@ -217,7 +217,7 @@ wxBitmap MGL_EXPORT ConvertFromGraph(HMGL gr)
 //-----------------------------------------------------------------------------\r
 void wxMathGL::Repaint()\r
 {\r
-       mgl_zoom(gr,x1,y1,x2,y2);       mgl_view(gr,phi,0,tet); mgl_perspective(gr, per);\r
+       mgl_zoom(gr,x1,y1,x2,y2);       mgl_view(gr,-phi,-tet,0);       mgl_ask_perspective(gr, per);\r
        pic = ConvertFromGraph(gr);\r
        wxSize sz=GetSize();\r
        if(pic.GetWidth()!=sz.GetWidth() || pic.GetHeight()!=sz.GetHeight())\r