1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3# vim: set fileencoding=utf-8 4 5## EXTRAITS DE LA LICENCE 6## Copyright CEA, contributeurs : Damien CALISTE, laboratoire L_Sim, (2012-2012) 7## Adresse mèl : 8## CALISTE, damien P caliste AT cea P fr. 9 10## Ce logiciel est un programme informatique servant à visualiser des 11## structures atomiques dans un rendu pseudo-3D. 12## Ce logiciel est régi par la licence CeCILL soumise au droit français et 13## respectant les principes de diffusion des logiciels libres. Vous pouvez 14## utiliser, modifier et/ou redistribuer ce programme sous les conditions 15## de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA 16## sur le site "http://www.cecill.info". 17## Le fait que vous puissiez accéder à cet en-tête signifie que vous avez 18## pris connaissance de la licence CeCILL, et que vous en avez accepté les 19## termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel). 20 21## LICENCE SUM UP 22## Copyright CEA, contributors: Damien CALISTE, L_Sim laboratory, (2012-2012) 23## E-mail address: 24## CALISTE, damien P caliste AT cea P fr. 25 26## This software is a computer program whose purpose is to visualize atomic 27## configurations in 3D. 28## This software is governed by the CeCILL license under French law and 29## abiding by the rules of distribution of free software. You can use, 30## modify and/ or redistribute the software under the terms of the CeCILL 31## license as circulated by CEA, CNRS and INRIA at the following URL 32## "http://www.cecill.info". 33## The fact that you are presently reading this means that you have had 34## knowledge of the CeCILL license and that you accept its terms. You can 35## find a copy of this licence shipped with this software at 36## Documentation/licence.en.txt. 37 38from gi.repository import v_sim 39from gi.repository import Gtk 40 41import numpy 42 43from matplotlib.figure import Figure 44from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas 45from matplotlib.backends.backend_cairo import RendererCairo as Renderer 46 47dpi = 100 48fig_width = 3 49fig_height = 2 50 51def mplCurveDraw(widget, cr, f, renderer): 52 renderer.gc.ctx = cr 53 w = widget.get_allocated_width() 54 h = widget.get_allocated_height() 55 cr.translate(max(0, (w - fig_width * dpi) * 0.5), 56 -max(0, (h - fig_height * dpi) * 0.5)) 57 renderer.set_width_height(w, h) 58 f.draw(renderer) 59 60def onTogglePick(widget, interPick, panel, wdx, wdy, wdz, wdx_ref, wdy_ref, wdz_ref): 61 render = v_sim.UiMainClass.getDefaultRendering() 62 if (widget.get_active()): 63 handle = interPick.connect("node-selection", onNodeSelected, panel, widget, 64 wdx, wdy, wdz, wdx_ref, wdy_ref, wdz_ref) 65 interPick.set_data("pick", handle) 66 render.pushInteractive(interPick) 67 render.pushMessage("Pick a node with the mouse") 68 else: 69 interPick.disconnect(interPick.get_data("pick")) 70 render.popInteractive(interPick) 71 render.popMessage() 72 73def onNodeSelected(inter, kind, node0, node1, node2, panel, toggle, 74 entryX, entryY, entryZ, entryX_ref, entryY_ref, entryZ_ref): 75 if not(kind == v_sim.InteractivePick.SELECTED): 76 return 77 78 data = panel.getData() 79 (x, y, z) = data.getNodeCoordinates(node0) 80 if entryX_ref is not None: 81 entryX.setValue(x - entryX_ref.getValue()) 82 else: 83 entryX.setValue(x) 84 if entryY_ref is not None: 85 entryY.setValue(y - entryY_ref.getValue()) 86 else: 87 entryY.setValue(y) 88 if entryZ_ref is not None: 89 entryZ.setValue(z - entryZ_ref.getValue()) 90 else: 91 entryZ.setValue(z) 92 toggle.set_active(False) 93 94def onDraw(widget, area, mplFig, panel, combo, (ox, oy, oz), (dx, dy, dz)): 95 # We get the scalar field. 96 it = combo.get_active_iter() 97 if it is None: 98 return 99 model = combo.get_model() 100 (field,) = model.get(it, v_sim.UiSurfacesFieldId.POINTER) 101 data = panel.getData() 102 103 # We setup the data to iterate over. 104 orig = numpy.array(data.convertXYZToReduced((ox.getValue(), oy.getValue(), oz.getValue()))) 105 vect = numpy.array(data.convertXYZToReduced((dx.getValue(), dy.getValue(), dz.getValue()))) 106 norm = 1. / numpy.sqrt(vect[0] * vect[0] + vect[1] * vect[1] + vect[2] * vect[2]) 107 vect *= norm 108 l0 = max(-orig[0] / max(vect[0], 1e-6), -orig[1] / max(vect[1], 1e-6), -orig[2] / max(vect[2], 1e-6)) 109 l1 = min((1. - orig[0]) / max(vect[0], 1e-6), (1. - orig[1]) / max(vect[1], 1e-6), (1. - orig[2]) / max(vect[2], 1e-6)) 110 orig0 = numpy.array(data.convertReducedToXYZ(tuple(orig + l0 * vect))) 111 vect0 = numpy.array(data.convertReducedToXYZ(tuple(orig + l1 * vect))) - orig0 112 norm = numpy.sqrt(vect0[0] * vect0[0] + vect0[1] * vect0[1] + vect0[2] * vect0[2]) 113 114 # We setup the data to be plotted. 115 a = mplFig.add_subplot(111) 116 x = numpy.arange(0.0, 1.0, 0.01) 117 y = numpy.arange(0.0, 1.0, 0.01) 118 for i in range(100): 119 point = orig0 + x[i] * vect0 120 (valid, val) = field.getValue(tuple(point), (0,0,0)) 121 if valid: 122 y[i] = val 123 x *= norm 124 a.plot(x,y) 125 # We ask for redraw of the widget. 126 area.queue_draw() 127 128def panelCreateSelection(panel, vbox, interPick, label, 129 wdx_ref = None, wdy_ref = None, wdz_ref = None): 130 # The line to choose the origin/orientation. 131 hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5) 132 vbox.pack_start(hbox, False, False, 0) 133 134 lbl = Gtk.Label.new(label) 135 hbox.pack_start(lbl, False, False, 0) 136 137 wdx = v_sim.UiNumericalEntry.new(0.) 138 wdx.set_width_chars(6) 139 hbox.pack_start(wdx, True, True, 0) 140 wdy = v_sim.UiNumericalEntry.new(0.) 141 wdy.set_width_chars(6) 142 hbox.pack_start(wdy, True, True, 0) 143 wdz = v_sim.UiNumericalEntry.new(0.) 144 wdz.set_width_chars(6) 145 hbox.pack_start(wdz, True, True, 0) 146 147 wd = Gtk.ToggleButton.new() 148 wd.add(Gtk.Image.new_from_stock(Gtk.STOCK_FIND, Gtk.IconSize.MENU)) 149 wd.connect("toggled", onTogglePick, interPick, panel, 150 wdx, wdy, wdz, wdx_ref, wdy_ref, wdz_ref) 151 hbox.pack_start(wd, False, False, 0) 152 153 return (wdx, wdy, wdz) 154 155def panelCreateWidgets(): 156 panel = v_sim.UiPanel.new("mytools", "Customized tools", "My tools") 157 panel.setDockable(True) 158 panel.attach(v_sim.UiPanelClass.getCommandPanel()); 159 160 vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0) 161 panel.add(vbox) 162 163 lbl = Gtk.Label.new("<b>Interpolate data along lines</b>") 164 lbl.set_alignment(0., 0.5) 165 lbl.set_use_markup(True) 166 vbox.pack_start(lbl, False, False, 0) 167 168 # The line to choose a data field. 169 hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5) 170 vbox.pack_start(hbox, False, False, 0) 171 172 lbl = Gtk.Label.new("Choose a data field:") 173 hbox.pack_start(lbl, False, False, 0) 174 175 combo = Gtk.ComboBox.new() 176 combo.set_model(v_sim.UiPanel.surfaces_getFields()) 177 hbox.pack_start(combo, True, True, 0) 178 renderer = Gtk.CellRendererText.new() 179 combo.pack_start(renderer, False) 180 renderer.set_property("xalign", 1.0) 181 combo.add_attribute(renderer, "markup", v_sim.UiSurfacesFieldId.LABEL) 182 183 interPick = v_sim.Interactive.new(v_sim.InteractiveId.PICK) 184 185 # The line to choose the origin. 186 (origx, origy, origz) = panelCreateSelection(panel, vbox, interPick, 187 "Choose the origin:") 188 189 # The line to choose the direction. 190 (dirx, diry, dirz) = panelCreateSelection(panel, vbox, interPick, 191 "Choose the direction:", 192 wdx_ref = origx, wdy_ref = origy, 193 wdz_ref = origz) 194 dirx.setValue(1.) 195 diry.setValue(1.) 196 dirz.setValue(1.) 197 198 # The drawing area for the curve. 199 hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0) 200 vbox.pack_start(hbox, True, True, 0) 201 202 scrolled = Gtk.ScrolledWindow.new(None, None) 203 scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) 204 hbox.pack_start(scrolled, True, True, 0) 205 206 f = Figure(figsize=(fig_width,fig_height), dpi = dpi) 207 canvas = FigureCanvas(f) 208 f.set_canvas(canvas) 209 renderer = Renderer(dpi = dpi) 210 211 area = Gtk.DrawingArea.new() 212 area.set_size_request(fig_width * dpi, fig_height * dpi) 213 area.connect("draw", mplCurveDraw, f, renderer) 214 scrolled.add_with_viewport(area) 215 216 # The toolbar for action on the curve. 217 wd = Gtk.Toolbar.new() 218 wd.set_orientation(Gtk.Orientation.VERTICAL) 219 wd.set_style(Gtk.ToolbarStyle.ICONS) 220 wd.set_icon_size(Gtk.IconSize.SMALL_TOOLBAR) 221 hbox.pack_start(wd, False, False, 0) 222 223 item = Gtk.ToolButton.new_from_stock(Gtk.STOCK_REFRESH) 224 item.connect("clicked", onDraw, area, f, panel, combo, 225 (origx, origy, origz), (dirx, diry, dirz)) 226 wd.insert(item, -1) 227 228 return (f, panel, interPick) 229 230# We create the widgets and plot the stuff. 231(mplFig, panel, i) = panelCreateWidgets() 232panel.show_all() 233 234