bimpy - bundled imgui for python
Project description
bimpy - bundled imgui for python
================================
:Downloads: .. figure:: https://pepy.tech/badge/bimpy
:Build status: .. figure:: https://travis-ci.org/podgorskiy/bimpy.svg?branch=master
:License: .. figure:: https://img.shields.io/badge/License-MIT-yellow.svg
**bimpy** is a python module that provides bindings to `dear imgui <https://github.com/ocornut/imgui>`__ and distributed as a self-contained package bundled with `glfw <https://github.com/glfw/glfw>`__ and `gl3w <https://github.com/skaslev/gl3w>`__.
Features:
* Allows to create immediate mode UI with python easily. The API is kept as close to the original dear imgui as possible.
* **bimpy** already has all necessary functionality for window/OpenGL context creation and hides those details from the user.
* **bimpy** supports multiple contexts and allows creating multiple windows.
* **bimpy** works on Windows, GNU Linux, and macOS.
* **bimpy** does not have dependencies and can be easely built from sources. Building relies only on distutils.
Hello-world with bimpy:
.. code:: python
import bimpy
ctx = bimpy.Context()
ctx.init(600, 600, "Hello")
str = bimpy.String()
f = bimpy.Float();
while(not ctx.should_close()):
with ctx:
bimpy.text("Hello, world!")
if bimpy.button("OK"):
print(str.value)
bimpy.input_text('string', str, 256)
bimpy.slider_float("float", f, 0.0, 1.0)
.. figure:: https://i.imgur.com/rL7cFj7.png
:alt: hello-world
Install
=======
Installation is easy since the package does not have dependencies:
.. code:: shell
pip install bimpy
Or you can build and install from sources:
.. code:: shell
python setup.py install
All c/c++ sources are built with distutils. All you need is a compiler with C++11 support.
Windows users, who use python 2.7 may encounter problems, because on Windows, python 2.7 uses MSVC 9.0, which doesn't have support for c++11. However, you still can build it with more recent MSVC (for example MSVC 14.0, which is Visual C++ 2015) using the commands below:
.. code:: shell
call "%VS140COMNTOOLS%\VsDevCmd.bat"
set VS90COMNTOOLS=%VS140COMNTOOLS%
python setup.py install
How to use it?
==============
Intro
-----
**bimpy** is python binding for `dear imgui <https://github.com/ocornut/imgui>`__ and tries to match the C++ API. Also, it has some additional functions to create a window and some other differences.
It has binding for the most functions from **dear imgui**. All functions are renamed from **CamelCase** to **snake_case**, which is more common for python. For example ``ImGui::InputText`` is mapped to ``bimpy.input_text``.
Context and window
------------------
First of all, you need to import **bimpy**
.. code:: python
import bimpy
Distinctively from **dear imgui**, bimpy does not have global state (**dear imgui** has it by default, but it has an option not to have one). So, you will need to create a context.
.. code:: python
ctx = bimpy.Context(width, height, name)
Where integers *width* and *height* specify the size of the window, and string *name* is a caption of the window.
All calls to **bimpy**'s API must be within *with* statement applied to the context object:
.. code:: python
with ctx:
bimpy.text("Hello, world!")
And there must be only one *with* statement applied to the context object per frame.
Or, a second option is to manualy call ``ctx.new_frame()`` before all API calls, and then ``ctx.render()`` after.
.. code:: python
ctx.new_frame()
bimpy.text("Hello, world!")
ctx.render()
You can have multiple *Context* objects for multiple windows, however, API is not thread-safe.
Variables
------------------
All **imgui** API that provides user input (such as *InputText*, *SliderFloat*, etc.) modifies the variable through the reference to it. However, in python, such objects as integers, floats and strings are passed always by value. Because of this, **bimpy** provides special wrappers, that allow passing those variables by reference.
For example, to use *slider_float*, you will need first to create a variable that will hold the state:
.. code:: python
f = bimpy.Float();
You can access the value in the following way: ``f.value``
To use it with *slider_float* simply pass it to that function:
.. code:: python
bimpy.slider_float("float slider", f, 0.0, 1.0)
All **imgui** input functions that provide multiple inputs, like *SliderFloat2*, *SliderInt4*, *InputInt3*, etc. are mapped to equivalent functions, but instead of passing an array of variables, you need to list all variables in the argument list:
.. code:: python
f1 = bimpy.Float();
f2 = bimpy.Float();
f3 = bimpy.Float();
while(not ctx.should_close()):
with ctx:
bimpy.slider_float3("float", f1, f2, f3, 0.0, 1.0)
Draw commands
------------------
Some draw commands are exposed. In contrast to C++ API, the exposed functions are not methods of **ImDrawList**, but global functions. All drawing functions should be called inside the *begin/end* calls of a window.
List of exposed drawing functions:
.. code:: python
add_circle(centre: _bimpy.Vec2, radius: float, col: int, num_segments: int=12, thickness: float=1.0) -> None
add_circle_filled(centre: _bimpy.Vec2, radius: float, col: int, num_segments: int=12) -> None
add_line(a: _bimpy.Vec2, b: _bimpy.Vec2, col: int, thickness: float=1.0) -> None
add_quad(a: _bimpy.Vec2, b: _bimpy.Vec2, c: _bimpy.Vec2, d: _bimpy.Vec2, col: int, thickness: float=1.0) -> None
add_quad_filled(a: _bimpy.Vec2, b: _bimpy.Vec2, c: _bimpy.Vec2, d: _bimpy.Vec2, col: int) -> None
add_rect(a: _bimpy.Vec2, b: _bimpy.Vec2, col: int, rounding: float=0.0, rounding_corners_flags: int=Corner.All, thickness: float=1.0) -> None
add_rect_filled(a: _bimpy.Vec2, b: _bimpy.Vec2, col: int, rounding: float=0.0, rounding_corners_flags: int=Corner.All) -> None
add_rect_filled_multicolor(a: _bimpy.Vec2, b: _bimpy.Vec2, col_upr_left: int, col_upr_right: int, col_bot_right: int, col_bot_lefs: int) -> None
add_triangle(a: _bimpy.Vec2, b: _bimpy.Vec2, c: _bimpy.Vec2, col: int, thickness: float=1.0) -> None
add_triangle_filled(a: _bimpy.Vec2, b: _bimpy.Vec2, c: _bimpy.Vec2, col: int) -> None
Simple usage example below:
.. figure:: https://i.imgur.com/MU5Vhfl.png
:alt: hello-world
.. code:: python
import bimpy
import numpy as np
ctx = bimpy.Context()
ctx.init(1200, 1200, "ITQ")
with ctx:
bimpy.themes.set_light_theme()
DATA_POINTS = bimpy.Int(30)
CLASTERS = bimpy.Int(4)
std = bimpy.Float(0.5)
colors = [0x4b19e6, 0x4bb43c, 0x19e1ff, 0xc88200, 0x3182f5, 0xb41e91, 0xf0f046, 0xf032e6, 0xd2f53c,
0xfabebe, 0x008080, 0xe6beff, 0xaa6e28, 0xfffac8, 0x800000, 0xaaffc3, 0x808000, 0xffd8b1,
0x000080, 0x808080, 0xFFFFFF, 0x000000]
datapoints = []
def generate_fake_data():
datapoints.clear()
for i in range(CLASTERS.value):
x = np.random.normal(size=(DATA_POINTS.value, 2))
alpha = np.random.rand()
scale = std.value * np.random.rand(2) * np.eye(2, 2)
position = np.random.rand(2) * 5
rotation = np.array([[np.cos(alpha), np.sin(alpha)], [-np.sin(alpha), np.cos(alpha)]])
x = np.matmul(x, scale)
x = np.matmul(x, rotation)
x += position
datapoints.append((x, rotation, position, scale))
axis = x = np.array([[-1, 0], [1, 0], [0, -1], [0, 1]])
while not ctx.should_close():
ctx.new_frame()
bimpy.begin("Drawings", flags=bimpy.WindowFlags.ShowBorders)
window_pos = bimpy.get_window_pos()
center = bimpy.Vec2(100, 100) + window_pos
m = 100.0
for i in range(len(datapoints)):
(x, R, P, S) = datapoints[i]
for j in range(x.shape[0]):
point = bimpy.Vec2(x[j, 0], x[j, 1])
bimpy.add_circle_filled(point * m + center, 5, 0xAF000000 + colors[i], 100)
axis_ = np.matmul(axis, S * 2.0)
axis_ = np.matmul(axis_, R) + P
bimpy.add_line(
center + bimpy.Vec2(axis_[0, 0], axis_[0, 1]) * m,
center + bimpy.Vec2(axis_[1, 0], axis_[1, 1]) * m,
0xFFFF0000, 1)
bimpy.add_line(
center + bimpy.Vec2(axis_[2, 0], axis_[2, 1]) * m,
center + bimpy.Vec2(axis_[3, 0], axis_[3, 1]) * m,
0xFFFF0000, 1)
bimpy.end()
bimpy.begin("Controls", flags=bimpy.WindowFlags.ShowBorders)
bimpy.input_int("Data points count", DATA_POINTS)
bimpy.input_int("Clasters count", CLASTERS)
bimpy.slider_float("std", std, 0.0, 3.0)
if bimpy.button("Generate data"):
generate_fake_data()
bimpy.end()
ctx.render()
Acknowledgements
=======
* robobuggy https://github.com/gfannes
* njazz https://github.com/njazz
================================
:Downloads: .. figure:: https://pepy.tech/badge/bimpy
:Build status: .. figure:: https://travis-ci.org/podgorskiy/bimpy.svg?branch=master
:License: .. figure:: https://img.shields.io/badge/License-MIT-yellow.svg
**bimpy** is a python module that provides bindings to `dear imgui <https://github.com/ocornut/imgui>`__ and distributed as a self-contained package bundled with `glfw <https://github.com/glfw/glfw>`__ and `gl3w <https://github.com/skaslev/gl3w>`__.
Features:
* Allows to create immediate mode UI with python easily. The API is kept as close to the original dear imgui as possible.
* **bimpy** already has all necessary functionality for window/OpenGL context creation and hides those details from the user.
* **bimpy** supports multiple contexts and allows creating multiple windows.
* **bimpy** works on Windows, GNU Linux, and macOS.
* **bimpy** does not have dependencies and can be easely built from sources. Building relies only on distutils.
Hello-world with bimpy:
.. code:: python
import bimpy
ctx = bimpy.Context()
ctx.init(600, 600, "Hello")
str = bimpy.String()
f = bimpy.Float();
while(not ctx.should_close()):
with ctx:
bimpy.text("Hello, world!")
if bimpy.button("OK"):
print(str.value)
bimpy.input_text('string', str, 256)
bimpy.slider_float("float", f, 0.0, 1.0)
.. figure:: https://i.imgur.com/rL7cFj7.png
:alt: hello-world
Install
=======
Installation is easy since the package does not have dependencies:
.. code:: shell
pip install bimpy
Or you can build and install from sources:
.. code:: shell
python setup.py install
All c/c++ sources are built with distutils. All you need is a compiler with C++11 support.
Windows users, who use python 2.7 may encounter problems, because on Windows, python 2.7 uses MSVC 9.0, which doesn't have support for c++11. However, you still can build it with more recent MSVC (for example MSVC 14.0, which is Visual C++ 2015) using the commands below:
.. code:: shell
call "%VS140COMNTOOLS%\VsDevCmd.bat"
set VS90COMNTOOLS=%VS140COMNTOOLS%
python setup.py install
How to use it?
==============
Intro
-----
**bimpy** is python binding for `dear imgui <https://github.com/ocornut/imgui>`__ and tries to match the C++ API. Also, it has some additional functions to create a window and some other differences.
It has binding for the most functions from **dear imgui**. All functions are renamed from **CamelCase** to **snake_case**, which is more common for python. For example ``ImGui::InputText`` is mapped to ``bimpy.input_text``.
Context and window
------------------
First of all, you need to import **bimpy**
.. code:: python
import bimpy
Distinctively from **dear imgui**, bimpy does not have global state (**dear imgui** has it by default, but it has an option not to have one). So, you will need to create a context.
.. code:: python
ctx = bimpy.Context(width, height, name)
Where integers *width* and *height* specify the size of the window, and string *name* is a caption of the window.
All calls to **bimpy**'s API must be within *with* statement applied to the context object:
.. code:: python
with ctx:
bimpy.text("Hello, world!")
And there must be only one *with* statement applied to the context object per frame.
Or, a second option is to manualy call ``ctx.new_frame()`` before all API calls, and then ``ctx.render()`` after.
.. code:: python
ctx.new_frame()
bimpy.text("Hello, world!")
ctx.render()
You can have multiple *Context* objects for multiple windows, however, API is not thread-safe.
Variables
------------------
All **imgui** API that provides user input (such as *InputText*, *SliderFloat*, etc.) modifies the variable through the reference to it. However, in python, such objects as integers, floats and strings are passed always by value. Because of this, **bimpy** provides special wrappers, that allow passing those variables by reference.
For example, to use *slider_float*, you will need first to create a variable that will hold the state:
.. code:: python
f = bimpy.Float();
You can access the value in the following way: ``f.value``
To use it with *slider_float* simply pass it to that function:
.. code:: python
bimpy.slider_float("float slider", f, 0.0, 1.0)
All **imgui** input functions that provide multiple inputs, like *SliderFloat2*, *SliderInt4*, *InputInt3*, etc. are mapped to equivalent functions, but instead of passing an array of variables, you need to list all variables in the argument list:
.. code:: python
f1 = bimpy.Float();
f2 = bimpy.Float();
f3 = bimpy.Float();
while(not ctx.should_close()):
with ctx:
bimpy.slider_float3("float", f1, f2, f3, 0.0, 1.0)
Draw commands
------------------
Some draw commands are exposed. In contrast to C++ API, the exposed functions are not methods of **ImDrawList**, but global functions. All drawing functions should be called inside the *begin/end* calls of a window.
List of exposed drawing functions:
.. code:: python
add_circle(centre: _bimpy.Vec2, radius: float, col: int, num_segments: int=12, thickness: float=1.0) -> None
add_circle_filled(centre: _bimpy.Vec2, radius: float, col: int, num_segments: int=12) -> None
add_line(a: _bimpy.Vec2, b: _bimpy.Vec2, col: int, thickness: float=1.0) -> None
add_quad(a: _bimpy.Vec2, b: _bimpy.Vec2, c: _bimpy.Vec2, d: _bimpy.Vec2, col: int, thickness: float=1.0) -> None
add_quad_filled(a: _bimpy.Vec2, b: _bimpy.Vec2, c: _bimpy.Vec2, d: _bimpy.Vec2, col: int) -> None
add_rect(a: _bimpy.Vec2, b: _bimpy.Vec2, col: int, rounding: float=0.0, rounding_corners_flags: int=Corner.All, thickness: float=1.0) -> None
add_rect_filled(a: _bimpy.Vec2, b: _bimpy.Vec2, col: int, rounding: float=0.0, rounding_corners_flags: int=Corner.All) -> None
add_rect_filled_multicolor(a: _bimpy.Vec2, b: _bimpy.Vec2, col_upr_left: int, col_upr_right: int, col_bot_right: int, col_bot_lefs: int) -> None
add_triangle(a: _bimpy.Vec2, b: _bimpy.Vec2, c: _bimpy.Vec2, col: int, thickness: float=1.0) -> None
add_triangle_filled(a: _bimpy.Vec2, b: _bimpy.Vec2, c: _bimpy.Vec2, col: int) -> None
Simple usage example below:
.. figure:: https://i.imgur.com/MU5Vhfl.png
:alt: hello-world
.. code:: python
import bimpy
import numpy as np
ctx = bimpy.Context()
ctx.init(1200, 1200, "ITQ")
with ctx:
bimpy.themes.set_light_theme()
DATA_POINTS = bimpy.Int(30)
CLASTERS = bimpy.Int(4)
std = bimpy.Float(0.5)
colors = [0x4b19e6, 0x4bb43c, 0x19e1ff, 0xc88200, 0x3182f5, 0xb41e91, 0xf0f046, 0xf032e6, 0xd2f53c,
0xfabebe, 0x008080, 0xe6beff, 0xaa6e28, 0xfffac8, 0x800000, 0xaaffc3, 0x808000, 0xffd8b1,
0x000080, 0x808080, 0xFFFFFF, 0x000000]
datapoints = []
def generate_fake_data():
datapoints.clear()
for i in range(CLASTERS.value):
x = np.random.normal(size=(DATA_POINTS.value, 2))
alpha = np.random.rand()
scale = std.value * np.random.rand(2) * np.eye(2, 2)
position = np.random.rand(2) * 5
rotation = np.array([[np.cos(alpha), np.sin(alpha)], [-np.sin(alpha), np.cos(alpha)]])
x = np.matmul(x, scale)
x = np.matmul(x, rotation)
x += position
datapoints.append((x, rotation, position, scale))
axis = x = np.array([[-1, 0], [1, 0], [0, -1], [0, 1]])
while not ctx.should_close():
ctx.new_frame()
bimpy.begin("Drawings", flags=bimpy.WindowFlags.ShowBorders)
window_pos = bimpy.get_window_pos()
center = bimpy.Vec2(100, 100) + window_pos
m = 100.0
for i in range(len(datapoints)):
(x, R, P, S) = datapoints[i]
for j in range(x.shape[0]):
point = bimpy.Vec2(x[j, 0], x[j, 1])
bimpy.add_circle_filled(point * m + center, 5, 0xAF000000 + colors[i], 100)
axis_ = np.matmul(axis, S * 2.0)
axis_ = np.matmul(axis_, R) + P
bimpy.add_line(
center + bimpy.Vec2(axis_[0, 0], axis_[0, 1]) * m,
center + bimpy.Vec2(axis_[1, 0], axis_[1, 1]) * m,
0xFFFF0000, 1)
bimpy.add_line(
center + bimpy.Vec2(axis_[2, 0], axis_[2, 1]) * m,
center + bimpy.Vec2(axis_[3, 0], axis_[3, 1]) * m,
0xFFFF0000, 1)
bimpy.end()
bimpy.begin("Controls", flags=bimpy.WindowFlags.ShowBorders)
bimpy.input_int("Data points count", DATA_POINTS)
bimpy.input_int("Clasters count", CLASTERS)
bimpy.slider_float("std", std, 0.0, 3.0)
if bimpy.button("Generate data"):
generate_fake_data()
bimpy.end()
ctx.render()
Acknowledgements
=======
* robobuggy https://github.com/gfannes
* njazz https://github.com/njazz
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
bimpy-0.0.9.tar.gz
(917.1 kB
view hashes)
Built Distributions
bimpy-0.0.9-cp36-cp36m-win_amd64.whl
(643.8 kB
view hashes)
bimpy-0.0.9-cp36-cp36m-win32.whl
(546.1 kB
view hashes)
bimpy-0.0.9-cp27-cp27m-win_amd64.whl
(625.4 kB
view hashes)
bimpy-0.0.9-cp27-cp27m-win32.whl
(534.4 kB
view hashes)
Close
Hashes for bimpy-0.0.9-cp36-cp36m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | afd8680ff2729b60475b1e661ebd7e6960818a81a011e0950d5d3ee4c2221a93 |
|
MD5 | 45434f8f3754f5255a13d7ae41a2832e |
|
BLAKE2b-256 | 2099839eff2b756344750cede8c172eed6750255719cf6f7acf75d21173b8fc0 |
Close
Hashes for bimpy-0.0.9-cp36-cp36m-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 24d041b2299e356df24e067ab618ad07ce913eff7135d9879d8bbe94f163da27 |
|
MD5 | 8034545d7a8b8e36f1a525b9e842b73c |
|
BLAKE2b-256 | e4912d47d7deb2bf78c98d9fa93a7572f38c07415a0b0c05e25ad2ce9ed59ffc |
Close
Hashes for bimpy-0.0.9-cp27-cp27m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3b19686cddf528d3cf9862bfb85db3d34b7e52cb6ba29b9d0128379d31818690 |
|
MD5 | 61ca00ab70e445d881dd881f1c8bc604 |
|
BLAKE2b-256 | a98b9b35d5068b633669361158d582434e99741f3bf2d82ec0686f659e33178e |
Close
Hashes for bimpy-0.0.9-cp27-cp27m-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 97efdfae6a81a283ffd7b0e14e8745cc1ad0654740fdbf45a93d797bc963c5cb |
|
MD5 | 384665da34422c2395045f0e0895670c |
|
BLAKE2b-256 | 2103788fa72f1fe16a8e3b4d8c16dabcf7953cc16272aa0fc7b95a8386d97cc3 |