Package: bimpy
bimpy - bundled imgui for pythonbimpyis a a native extension for Python built with C++ andthat provides bindings todear imguiand distributed as a self-contained package bundled withglfwandgl3wFeatures:Immediate mode UI with python. The API is kept as close to the original dear imgui as possible.bimpyalready has all necessary functionality for window/OpenGL context creation and hides those details from the user.bimpycan display images from ndarrays, PIL Images, numpy arrays, etc.,bimpyworks on Windows, GNU Linux, and macOS.bimpydoes not have dependencies and can be easily built from sources. Building relies only on distutils.Hello world with bimpyCore API tries to map to the Dear ImGui as close as possible. There is additional API, such asbimpy.Appclass that simplifiesbimpyusageCore APIUsingbimpy.Appclassimportbimpyasbpctx=bp.Context()ctx.init(600,600,"Hello")s=bp.String()f=bp.Float()whilenotctx.should_close():withctx:bp.text("Hello, world!")ifbp.button("OK"):print(s.value)bp.input_text('string',str,256)bp.slider_float("float",f,0,1)importbimpyasbpclassApp(bp.App):def__init__(self):super(App,self).__init__(title='Test')self.s=bp.String()self.f=bp.Float()defon_update(self):bp.text("Hello, world!")ifbp.button("OK"):print(self.s.value)bp.input_text('string',self.s,256)bp.slider_float("float",self.f,0,1)app=App()app.run()Display imagesDisplay PIL image:importbimpyfromPILimportImagectx=bimpy.Context()ctx.init(800,800,"Image")image=Image.open("test.png")im=bimpy.Image(image)whilenotctx.should_close():withctx:bimpy.text("Display PIL Image")bimpy.image(im)Similarly, numpy arrays with 2 dimensions, 3 dimensions (2, 3 or 4 channels) of typenp.uint8can be displayed.Display numpy, ndarray image:importbimpyfromPILimportImageimportnumpyasnpctx=bimpy.Context()ctx.init(800,800,"Image")image=np.asarray(Image.open("3.png"),dtype=np.uint8)im=bimpy.Image(image)whilenotctx.should_close():withctx:bimpy.text("Display Image of type:")bimpy.same_line()bimpy.text(str(type(image)))bimpy.image(im)More examples here:https://github.com/podgorskiy/bimpy/blob/master/examples/image.pyNon-english textUse builtinbp.load_fontsto load fonts with CJK, cyrillic, greek  charactersimportbimpyasbpctx=bp.Context()ctx.init(600,600,"Hello")bp.load_fonts(chinese=True,latin_ext=True,japanese=True,cyrillic=True)whilenotctx.should_close():withctx:chinese=u"學而不思則罔，思而不學則殆。"japanese=u"二兎を追う者は一兎をも得ず。 "hiragana=u"あ い う え お か ..."katakana=u"ア イ ウ エ オ カ ..."kanji="川 月 木 心 火 左 北 今..."ukrainian="Садок вишневий коло..."polish="Hej, tam gdzieś z nad..."russian="Ночь, улица, фонарь, ..."bp.text('Chinese:')bp.indent()bp.text(chinese)bp.unindent()bp.text('Japanese:')bp.indent()bp.text(japanese)bp.bullet_text("hiragana: "+hiragana)bp.bullet_text("katakana: "+katakana)bp.bullet_text("kanji: "+kanji)bp.unindent()bp.separator()bp.text('Ukrainian:')bp.indent()bp.text(ukrainian)bp.unindent()bp.separator()bp.text('Polish:')bp.indent()bp.text(polish)bp.unindent()bp.separator()bp.text('Russian:')bp.indent()bp.text(russian)bp.unindent()bp.separator()InstallInstallation is easy since the package does not have dependencies:pipinstallbimpyOr you can build and install from sources:pythonsetup.pyinstallAll 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:call"%VS140COMNTOOLS%\VsDevCmd.bat"setVS90COMNTOOLS=%VS140COMNTOOLS%
pythonsetup.pyinstallIf building on Linux, the following dependencies will be needed:sudoapt-getinstallmesa-common-devlibxi-devlibxinerama-devlibxrandr-devlibxcursor-devTo build all wheels for linux package distribution (manylinux) runbuild_manylinux_wheels.sh.For testing/debugging there is a CMakeList.txt included. It is not used by setup.py, but can be handy in order to build/debug package from certain IDEs.How to use it?Introbimpyis python binding fordear 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 fromdear imgui. All functions are renamed fromCamelCasetosnake_case, which is more common for python. For exampleImGui::InputTextis mapped tobimpy.input_text.Context and windowFirst of all, you need to importbimpyimportbimpyDistinctively fromdear imgui, bimpy does not have global state (dear imguihas it by default, but it has an option not to have one). So, you will need to create a context.ctx=bimpy.Context(width,height,name)Where integerswidthandheightspecify the size of the window, and stringnameis a caption of the window.All calls tobimpy's API must be withinwithstatement applied to the context object:withctx:bimpy.text("Hello, world!")And there must be only onewithstatement applied to the context object per frame.Or, a second option is to manualy callctx.new_frame()before all API calls, and thenctx.render()after.ctx.new_frame()bimpy.text("Hello, world!")ctx.render()You can have multipleContextobjects for multiple windows, however, API is not thread-safe.VariablesAllimguiAPI that provides user input (such asInputText,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,bimpyprovides special wrappers, that allow passing those variables by reference.For example, to useslider_float, you will need first to create a variable that will hold the state:f=bimpy.Float();You can access the value in the following way:f.valueTo use it withslider_floatsimply pass it to that function:bimpy.slider_float("float slider",f,0.0,1.0)Allimguiinput functions that provide multiple inputs, likeSliderFloat2,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:f1=bimpy.Float();f2=bimpy.Float();f3=bimpy.Float();while(notctx.should_close()):withctx:bimpy.slider_float3("float",f1,f2,f3,0.0,1.0)Draw commandsSome draw commands are exposed. In contrast to C++ API, the exposed functions are not methods ofImDrawList, but global functions. All drawing functions should be called inside thebegin/endcalls of a window.List of exposed drawing functions:add_circle(centre:_bimpy.Vec2,radius:float,col:int,num_segments:int=12,thickness:float=1.0)->Noneadd_circle_filled(centre:_bimpy.Vec2,radius:float,col:int,num_segments:int=12)->Noneadd_line(a:_bimpy.Vec2,b:_bimpy.Vec2,col:int,thickness:float=1.0)->Noneadd_quad(a:_bimpy.Vec2,b:_bimpy.Vec2,c:_bimpy.Vec2,d:_bimpy.Vec2,col:int,thickness:float=1.0)->Noneadd_quad_filled(a:_bimpy.Vec2,b:_bimpy.Vec2,c:_bimpy.Vec2,d:_bimpy.Vec2,col:int)->Noneadd_rect(a:_bimpy.Vec2,b:_bimpy.Vec2,col:int,rounding:float=0.0,rounding_corners_flags:int=Corner.All,thickness:float=1.0)->Noneadd_rect_filled(a:_bimpy.Vec2,b:_bimpy.Vec2,col:int,rounding:float=0.0,rounding_corners_flags:int=Corner.All)->Noneadd_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)->Noneadd_triangle(a:_bimpy.Vec2,b:_bimpy.Vec2,c:_bimpy.Vec2,col:int,thickness:float=1.0)->Noneadd_triangle_filled(a:_bimpy.Vec2,b:_bimpy.Vec2,c:_bimpy.Vec2,col:int)->NoneSimple usage example below:importbimpyimportnumpyasnpctx=bimpy.Context()ctx.init(1200,1200,"Draw Commands Test")withctx: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=[]defgenerate_fake_data():datapoints.clear()foriinrange(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)*5rotation=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+=positiondatapoints.append((x,rotation,position,scale))axis=x=np.array([[-1,0],[1,0],[0,-1],[0,1]])whilenotctx.should_close():ctx.new_frame()bimpy.set_next_window_pos(bimpy.Vec2(20,20),bimpy.Condition.Once)bimpy.set_next_window_size(bimpy.Vec2(800,600),bimpy.Condition.Once)bimpy.begin("Drawings")window_pos=bimpy.get_window_pos()center=bimpy.Vec2(100,100)+window_posm=100.0foriinrange(len(datapoints)):(x,R,P,S)=datapoints[i]forjinrange(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)+Pbimpy.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.set_next_window_pos(bimpy.Vec2(20,640),bimpy.Condition.Once)bimpy.set_next_window_size(bimpy.Vec2(800,140),bimpy.Condition.Once)bimpy.begin("Controls")bimpy.input_int("Data points count",DATA_POINTS)bimpy.input_int("Clasters count",CLASTERS)bimpy.slider_float("std",std,0.0,3.0)ifbimpy.button("Generate data"):generate_fake_data()bimpy.end()ctx.render()Acknowledgementsrobobuggyhttps://github.com/gfannesnjazzhttps://github.com/njazzFlorian Rotthttps://github.com/sauberfredzakxhttps://github.com/zakxJoel Linnhttps://github.com/JoelLinn