padne.ui ======== .. py:module:: padne.ui Attributes ---------- .. autoapisummary:: padne.ui.log padne.ui.VERTEX_SHADER_MESH padne.ui.FRAGMENT_SHADER_MESH padne.ui.VERTEX_SHADER_DISCONNECTED padne.ui.FRAGMENT_SHADER_DISCONNECTED padne.ui.VERTEX_SHADER_EDGES padne.ui.FRAGMENT_SHADER_EDGES padne.ui.VERTEX_SHADER_POINTS padne.ui.FRAGMENT_SHADER_POINTS Classes ------- .. autoapisummary:: padne.ui.DeferedDict padne.ui.BaseSpatialIndex padne.ui.VertexSpatialIndex padne.ui.FaceSpatialIndex padne.ui.BaseTool padne.ui.PanTool padne.ui.SetMinValueTool padne.ui.SetMaxValueTool padne.ui.ToolManager padne.ui.AppToolBar padne.ui.ShaderProgram padne.ui.RenderedMesh padne.ui.RenderedPoints padne.ui.MeshViewer padne.ui.EditableValueLabel padne.ui.ColorScaleWidget padne.ui.MainWindow Functions --------- .. autoapisummary:: padne.ui.configure_opengl padne.ui.main Module Contents --------------- .. py:data:: log .. py:data:: VERTEX_SHADER_MESH :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ #version 330 core layout(location = 0) in vec2 position; layout(location = 1) in float color; out float frag_value; uniform mat4 mvp; void main() { gl_Position = mvp * vec4(position, 0.0, 1.0); frag_value = color; } """ .. raw:: html
.. py:data:: FRAGMENT_SHADER_MESH :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ #version 330 core in float frag_value; out vec4 out_color; #define COLOR_COUNT 256 uniform float v_max = 1.0; uniform float v_min = 0.0; uniform vec3 color_map[COLOR_COUNT]; void main() { float t = (frag_value - v_min) / (v_max - v_min); float rescaled = t * COLOR_COUNT; int idx = clamp(int(rescaled), 0, COLOR_COUNT - 1); out_color = vec4(color_map[idx], 1.0); } """ .. raw:: html
.. py:data:: VERTEX_SHADER_DISCONNECTED :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ #version 330 core layout(location = 0) in vec2 position; layout(location = 1) in float color; // We still have the color attribute but ignore it uniform mat4 mvp; void main() { gl_Position = mvp * vec4(position, 0.0, 1.0); } """ .. raw:: html
.. py:data:: FRAGMENT_SHADER_DISCONNECTED :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ #version 330 core out vec4 out_color; void main() { // Render disconnected copper in a subdued gray out_color = vec4(0.1, 0.1, 0.1, 1.0); } """ .. raw:: html
.. py:data:: VERTEX_SHADER_EDGES :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ #version 330 core layout(location = 0) in vec2 position; layout(location = 1) in vec3 color; out vec3 frag_color; uniform mat4 mvp; void main() { gl_Position = mvp * vec4(position, 0.0, 1.0); frag_color = color; } """ .. raw:: html
.. py:data:: FRAGMENT_SHADER_EDGES :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ #version 330 core in vec3 frag_color; out vec4 out_color; void main() { out_color = vec4(frag_color, 1.0); } """ .. raw:: html
.. py:data:: VERTEX_SHADER_POINTS :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ #version 330 core layout(location = 0) in vec2 position; layout(location = 1) in vec3 vertex_color; out vec3 frag_color; uniform mat4 mvp; uniform float point_size = 5.0; void main() { gl_Position = mvp * vec4(position, 0.0, 1.0); gl_PointSize = point_size; frag_color = vertex_color; // Pass color to fragment shader } """ .. raw:: html
.. py:data:: FRAGMENT_SHADER_POINTS :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ #version 330 core in vec3 frag_color; // Input color from vertex shader out vec4 out_color; void main() { out_color = vec4(frag_color, 1.0); } """ .. raw:: html
.. py:class:: DeferedDict[K, V] A dictionary-like object that can hold futures for values, unwrapping them when accessed. .. py:method:: is_ready(key: K) -> bool .. py:method:: set_future(key: K, future: concurrent.futures.Future[V]) .. py:method:: clear() .. py:class:: BaseSpatialIndex .. py:attribute:: tree :type: Optional[scipy.spatial.cKDTree] .. py:attribute:: values :type: list[float] .. py:attribute:: shape :type: shapely.geometry.MultiPolygon .. py:method:: from_layer_data(layer: padne.solver.problem.Layer, layer_solution: padne.solver.LayerSolution) -> BaseSpatialIndex :classmethod: .. py:method:: query_nearest(x: float, y: float) -> Optional[float] Find nearest value to given coordinates. .. py:class:: VertexSpatialIndex Bases: :py:obj:`BaseSpatialIndex` Spatial index for fast vertex value lookups within a layer. .. py:class:: FaceSpatialIndex Bases: :py:obj:`BaseSpatialIndex` Spatial index for fast face value lookups within a layer. .. py:class:: BaseTool(mesh_viewer: MeshViewer, tool_manager: ToolManager) Bases: :py:obj:`abc.ABC` Helper class that provides a standard way to create an ABC using inheritance. .. py:attribute:: mesh_viewer .. py:attribute:: tool_manager .. py:property:: name :type: str Returns the display name of the tool. .. py:property:: status_tip :type: str Returns the status tip for the tool. .. py:method:: on_activate() Called when the tool becomes active. .. py:method:: on_deactivate() Called when the tool becomes inactive. .. py:property:: shortcut :type: Optional[tuple[PySide6.QtCore.Qt.Key, PySide6.QtCore.Qt.KeyboardModifier]] .. py:method:: on_shortcut_press(world_point: padne.mesh.Point) Handles a shortcut press event. .. py:method:: on_mesh_click(world_point: padne.mesh.Point, event: PySide6.QtGui.QMouseEvent) Handles a click event on the mesh. .. py:method:: on_screen_drag(dx: float, dy: float, event: PySide6.QtGui.QMouseEvent) Handles a screen drag event. .. py:class:: PanTool(mesh_viewer: MeshViewer, tool_manager: ToolManager) Bases: :py:obj:`BaseTool` Helper class that provides a standard way to create an ABC using inheritance. .. py:property:: name :type: str Returns the display name of the tool. .. py:property:: status_tip :type: str Returns the status tip for the tool. .. py:method:: on_screen_drag(dx: float, dy: float, event: PySide6.QtGui.QMouseEvent) Handles a screen drag event. .. py:class:: SetMinValueTool(mesh_viewer: MeshViewer, tool_manager: ToolManager) Bases: :py:obj:`PanTool` Helper class that provides a standard way to create an ABC using inheritance. .. py:property:: name :type: str Returns the display name of the tool. .. py:property:: status_tip :type: str Returns the status tip for the tool. .. py:property:: shortcut .. py:method:: on_mesh_click(world_point: padne.mesh.Point, event: PySide6.QtGui.QMouseEvent) Handles a click event on the mesh. .. py:method:: on_shortcut_press(world_point: padne.mesh.Point) Handles a shortcut press event. .. py:class:: SetMaxValueTool(mesh_viewer: MeshViewer, tool_manager: ToolManager) Bases: :py:obj:`PanTool` Helper class that provides a standard way to create an ABC using inheritance. .. py:property:: name :type: str Returns the display name of the tool. .. py:property:: status_tip :type: str Returns the status tip for the tool. .. py:property:: shortcut .. py:method:: on_mesh_click(world_point: padne.mesh.Point, event: PySide6.QtGui.QMouseEvent) Handles a click event on the mesh. .. py:method:: on_shortcut_press(world_point: padne.mesh.Point) Handles a shortcut press event. .. py:class:: ToolManager(mesh_viewer: MeshViewer, parent=None) Bases: :py:obj:`PySide6.QtCore.QObject` .. py:attribute:: mesh_viewer .. py:attribute:: available_tools :type: list[BaseTool] .. py:attribute:: active_tool :type: Optional[BaseTool] .. py:method:: activate_tool(tool_to_activate: Optional[BaseTool]) .. py:method:: handle_mesh_click(world_point: padne.mesh.Point, event: PySide6.QtGui.QMouseEvent) .. py:method:: handle_screen_drag(dx: float, dy: float, event: PySide6.QtGui.QMouseEvent) .. py:method:: handle_key_press_in_mesh(world_point: padne.mesh.Point, key: PySide6.QtCore.Qt.Key, modifiers: PySide6.QtCore.Qt.KeyboardModifiers) .. py:class:: AppToolBar(tool_manager: ToolManager, mesh_viewer: MeshViewer, parent=None) Bases: :py:obj:`PySide6.QtWidgets.QToolBar` .. py:attribute:: tool_manager .. py:attribute:: mesh_viewer .. py:method:: updateLayerSelectionMenu(layer_names: list[str]) .. py:method:: updateActiveLayerInMenu(active_layer_name: str) .. py:method:: updateActiveModeInMenu(active_mode_name: str) Update which mode action is checked. .. py:class:: ShaderProgram .. py:attribute:: shader_program :type: PySide6.QtOpenGL.QOpenGLShaderProgram .. py:method:: from_source(vertex_source, fragment_source) :classmethod: .. py:method:: use() .. py:class:: RenderedMesh .. py:attribute:: vao_triangles :type: int .. py:attribute:: triangle_count :type: int .. py:attribute:: vao_edges :type: int .. py:attribute:: edge_count :type: int .. py:attribute:: vao_boundary :type: int .. py:attribute:: boundary_count :type: int .. py:class:: PreparedData .. py:attribute:: triangle_vertices :type: numpy.ndarray[numpy.float32] .. py:attribute:: triangle_colors :type: numpy.ndarray[numpy.float32] .. py:attribute:: edge_vertices :type: numpy.ndarray[numpy.float32] .. py:attribute:: edge_colors :type: numpy.ndarray[numpy.float32] .. py:attribute:: boundary_vertices :type: numpy.ndarray[numpy.float32] .. py:attribute:: boundary_colors :type: numpy.ndarray[numpy.float32] .. py:method:: from_prepared_data(data: RenderedMesh) -> RenderedMesh :classmethod: .. py:method:: prepare_zero_form(msh: padne.mesh.Mesh, values: padne.mesh.ZeroForm) -> RenderedMesh :classmethod: .. py:method:: prepare_two_form(msh: padne.mesh.Mesh, values: padne.mesh.TwoForm) -> RenderedMesh :classmethod: .. py:method:: render_triangles() .. py:method:: render_edges() .. py:method:: render_boundary() .. py:method:: prepare_mesh(msh: padne.mesh.Mesh) -> RenderedMesh :classmethod: Create a RenderedMesh from a mesh with zero values. Used for disconnected copper regions that will be rendered in gray. .. py:class:: RenderedPoints .. py:attribute:: vao_points :type: int .. py:attribute:: point_count :type: int .. py:method:: from_points(points_data: list[tuple[tuple[float, float], tuple[float, float, float]]]) :classmethod: .. py:method:: render() .. py:class:: MeshViewer(parent=None) Bases: :py:obj:`PySide6.QtOpenGLWidgets.QOpenGLWidget` .. py:class:: BaseRenderingMode .. py:attribute:: unit :type: str .. py:attribute:: name :type: str .. py:attribute:: color_map :type: padne.colormaps.UniformColorMap .. py:attribute:: min_value :type: float :value: 0.0 .. py:attribute:: max_value :type: float :value: 1.0 .. py:attribute:: solution :type: Optional[padne.solver.Solution] :value: None .. py:attribute:: spatial_indices :type: dict[str, BaseSpatialIndex] .. py:attribute:: rendered_meshes :type: dict[str, list[RenderedMesh]] .. py:attribute:: disconnected_rendered_meshes :type: dict[str, list[RenderedMesh]] .. py:method:: autoscale_values(solution: padne.solver.Solution) Autoscale values for the rendering mode. .. py:method:: set_solution(solution: padne.solver.Solution) :abstractmethod: Initialize this mode with solution data (build indices + meshes). .. py:method:: pick_nearest_value(layer_name: str, world_x: float, world_y: float) -> Optional[float] Pick value at coordinates using spatial index. .. py:method:: get_rendered_meshes_for_layer(layer_name: str) -> list[RenderedMesh] Get pre-built rendered meshes for a layer. .. py:method:: get_disconnected_rendered_meshes_for_layer(layer_name: str) -> list[RenderedMesh] Get pre-built disconnected rendered meshes for a layer. .. py:class:: VoltageRenderingMode Bases: :py:obj:`BaseRenderingMode` .. py:attribute:: unit :type: str :value: 'V' .. py:attribute:: name :type: str :value: 'Potential' .. py:attribute:: color_map :type: padne.colormaps.UniformColorMap .. py:class:: PowerDensityRenderingMode Bases: :py:obj:`BaseRenderingMode` .. py:attribute:: unit :type: str :value: 'W/mm²' .. py:attribute:: name :type: str :value: 'Power Density' .. py:attribute:: color_map :type: padne.colormaps.UniformColorMap .. py:attribute:: valueRangeChanged .. py:attribute:: currentLayerChanged .. py:attribute:: availableLayersChanged .. py:attribute:: currentModeChanged .. py:attribute:: unitChanged .. py:attribute:: colorMapChanged .. py:attribute:: meshClicked .. py:attribute:: screenDragged .. py:attribute:: keyPressedInMesh .. py:attribute:: mousePositionChanged .. py:attribute:: visibilityChanged .. py:attribute:: solution :type: None | padne.solver.Solution :value: None .. py:attribute:: rendered_meshes :type: dict[str, list] .. py:attribute:: rendered_connection_points :type: dict[str, RenderedPoints] .. py:attribute:: connection_points_visible :type: bool :value: True .. py:attribute:: modes .. py:attribute:: current_mode_index :value: 0 .. py:attribute:: scale :value: 1.0 .. py:attribute:: offset_x :value: 0.0 .. py:attribute:: offset_y :value: 0.0 .. py:attribute:: needs_initial_autoscale :value: False .. py:attribute:: last_mouse_screen_pos :type: Optional[PySide6.QtCore.QPointF] :value: None .. py:attribute:: last_mouse_position_change_ts .. py:attribute:: current_layer_index :value: 0 .. py:attribute:: visible_layers :value: [] .. py:attribute:: mesh_shader :value: None .. py:attribute:: edge_shader :value: None .. py:attribute:: points_shader :value: None .. py:attribute:: edges_visible :value: True .. py:attribute:: outline_visible :value: True .. py:property:: current_rendering_mode :type: BaseRenderingMode Get the currently active rendering mode. .. py:property:: current_layer_name :type: str Get the name of the currently active layer. .. py:property:: aspect_ratio :type: float Get the current aspect ratio (width/height). .. py:method:: autoscaleValue() -> None Automatically adjust the min/max values for color scaling using the current rendering mode. .. py:method:: autoscaleXY() -> None Automatically adjust the offset and scale to fit all meshes in the view. Sets the view to display all meshes with a small margin around them. .. py:method:: setSolution(solution: padne.solver.Solution) Set the solution for the mesh viewer. .. py:method:: setupConnectionPointsData() -> None Set up the connection points data for rendering. .. py:method:: initializeGL() -> None Initialize OpenGL settings. .. py:method:: resizeGL(width: int, height: int) -> None Handle window resizing. .. py:method:: paintGL() -> None Render the mesh using shaders. .. py:method:: mousePressEvent(event: PySide6.QtGui.QMouseEvent) -> None Handle mouse press events. .. py:method:: mouseMoveEvent(event: PySide6.QtGui.QMouseEvent) -> None Handle mouse movement. .. py:method:: mouseReleaseEvent(event: PySide6.QtGui.QMouseEvent) -> None Handle mouse release events. .. py:method:: panViewByScreenDelta(dx_screen: float, dy_screen: float) -> None Pans the view based on a screen delta. Args: dx_screen: Change in x screen coordinate. dy_screen: Change in y screen coordinate. .. py:method:: setMinValue(value: float) -> None Sets the minimum of the color scale; clamps max upward if needed. .. py:method:: setMaxValue(value: float) -> None Sets the maximum of the color scale; clamps min downward if needed. .. py:method:: setMinValueFromWorldPoint(world_point: padne.mesh.Point) -> None Sets the minimum value of the color scale from a world point. If the selected value is greater than the current maximum, both min and max are set to the selected value. Args: world_point: The point in world coordinates. .. py:method:: setMaxValueFromWorldPoint(world_point: padne.mesh.Point) -> None Sets the maximum value of the color scale from a world point. If the selected value is less than the current minimum, both min and max are set to the selected value. Args: world_point: The point in world coordinates. .. py:method:: wheelEvent(event: PySide6.QtGui.QWheelEvent) -> None Handle mouse wheel for zooming towards cursor position. .. py:method:: keyPressEvent(event: PySide6.QtGui.QKeyEvent) -> None Handle keyboard events. .. py:method:: switchLayerBy(direction: int = 1) -> None Switch to the next or previous layer in the cycle. Args: direction: 1 for next layer, -1 for previous layer .. py:method:: switchToNextLayer() -> None Switch to the next layer in the cycle. .. py:method:: switchToPreviousLayer() -> None Switch to the previous layer in the cycle. .. py:method:: setEdgesVisible(visible: bool) Slot to set the visibility of mesh edges. .. py:method:: setOutlineVisible(visible: bool) Slot to set the visibility of outline edges. .. py:method:: setConnectionPointsVisible(visible: bool) Slot to set the visibility of connection points. .. py:method:: setCurrentLayerByName(layer_name: str) Sets the current layer by its name. .. py:method:: setCurrentModeByName(mode_name: str) Sets the current rendering mode by its name. .. py:class:: EditableValueLabel(parent=None) Bases: :py:obj:`PySide6.QtWidgets.QLabel` A QLabel that turns into a QLineEdit on double-click for in-place value editing. .. py:attribute:: valueEdited .. py:attribute:: value :value: 0.0 .. py:attribute:: unit :value: '' .. py:method:: setValue(value: float, unit: str) -> None .. py:method:: mouseDoubleClickEvent(event: PySide6.QtGui.QMouseEvent) -> None .. py:method:: eventFilter(watched, event) .. py:class:: ColorScaleWidget(parent=None) Bases: :py:obj:`PySide6.QtWidgets.QWidget` Widget that displays a color scale with delta and absolute range. .. py:attribute:: unitChanged .. py:attribute:: minValueEdited .. py:attribute:: maxValueEdited .. py:attribute:: v_min :value: 0.0 .. py:attribute:: v_max :value: 1.0 .. py:attribute:: unit :value: 'V' .. py:attribute:: color_map .. py:attribute:: delta_label :type: Optional[PySide6.QtWidgets.QLabel] :value: None .. py:attribute:: max_label :type: Optional[EditableValueLabel] :value: None .. py:attribute:: min_label :type: Optional[EditableValueLabel] :value: None .. py:method:: setupUI() -> None Set up the UI components. .. py:method:: setRange(v_min, v_max) Set the minimum and maximum values for the scale. .. py:method:: setUnit(unit) Set the unit for the scale. .. py:method:: setColorMap(color_map) Set the color map for the scale. .. py:method:: updateLabels() -> None Update the delta and range labels. .. py:method:: paintEvent(event: PySide6.QtGui.QPaintEvent) -> None Paint the color gradient scale. .. py:class:: MainWindow(solution: padne.solver.Solution, warnings_list: Optional[list[warnings.WarningMessage]] = None) Bases: :py:obj:`PySide6.QtWidgets.QMainWindow` .. py:attribute:: projectLoaded .. py:attribute:: project_file_name .. py:attribute:: warnings_list .. py:attribute:: warnings_shown :value: False .. py:attribute:: mesh_viewer .. py:attribute:: tool_manager .. py:attribute:: color_scale .. py:attribute:: app_toolbar .. py:method:: updateCurrentLayer(layer_name: str) -> None Update the window title to show the current layer. .. py:method:: updateMousePosition(world_point: padne.mesh.Point, value) Update status bar with mouse position and value. .. py:method:: showEvent(event: PySide6.QtGui.QShowEvent) -> None Override showEvent to display warnings after window is visible. .. py:function:: configure_opengl() -> None Configure OpenGL settings for the application. .. py:function:: main(solution: padne.solver.Solution, warnings_list: Optional[list[warnings.WarningMessage]] = None) -> int Main entry point for the UI application.