GithubHelp home page GithubHelp logo

kr15h / ofxpimapper Goto Github PK

View Code? Open in Web Editor NEW
455.0 50.0 91.0 53.56 MB

Projection mapping addon for openFrameworks that works on the Raspberry Pi

Home Page: http://ofxpimapper.com

License: Other

C++ 95.98% Makefile 3.85% Shell 0.06% C 0.11%

ofxpimapper's Introduction

ofxPiMapper

Ubuntu Workflow Badge Windows Workflow Badge OSX Workflow Badge

Projection mapping addon for openFrameworks that runs on the Raspberry Pi. It is being developed and tested against the latest stable openFrameworks version (0.11.0).

The project started as master's thesis project by Krisjanis Rijnieks at the Aalto Media Lab. Currently being developed during free time. Please donate to create more free time.

Note on build status: GitHub Actions ubuntu-latest, windows-latest and osx-latest images with 64bit environments are used.

Introduction

This repository contains the addon for openFrameworks. It is expected to be used as an extension for your custom openFrameworks project where you create a custom FBO source that is being animated by an advanced process rather than a plain video.

If you are planning to use videos and images only, consider using the precompiled Raspberry Pi image available from the ofxPiMapper website. It is based on a recent Raspberry Pi OS disk image and contains compiled installation of openFrameworks along with all the scripts and services that make Pi Mapper start automatically.

Installation

Clone or download the repository to your openFrameworks addons folder. Make sure that default openFrameworks examples compile and run before trying ofxPiMapper examples. There are a few things that you should do depending on if you are compiling on the Raspberry Pi or not.

  • Raspberry Pi
    Please install the ofxOMXPlayer addon before compiling.
  • Windows MSYS2
    Go to patches/msys2 directory and run ./patch.sh
  • Other platforms
    Please rename the addons.make.rpi file to addons.make.

To test, use Terminal to change the directory to example_basic, compile and run.

cd path/to/openFrameworks/addons/ofxPiMapper/example_basic
make
cd bin
./example_basic

If you plan to use example_remote-server and example_remote-client, make sure that you have added ofxJSON dependency to your openFrameworks/addons folder prior compilation.

Usage

Currently a keyboard and a mouse has to be used in order to do the mapping with ofxPiMapper.

Modes

PiMapper has 4 modes:

  1. Presentation mode
  2. Texture mapping mode
  3. Surface editing mode
  4. Source assignment mode

You can access these modes by pressing 1, 2, 3 or 4 respectively.

Presentation mode

This mode is activated once the application starts up. It does not show anything else except the final projection mapping as it was saved previously.

Texture mapping mode

In this mode you can adjust the texture coordinates of the surface you have selected in the surface editing mode.

Surface editing mode

Here you can select, move and distort the surfaces you have created.

Source assignment mode

After you select a surface in surface editing mode, activate this mode to be able to choose a source for the surface. Afterwards you might want to go to the texture mapping mode to adjust texture coordinates.

Other shortcuts

These other shortcuts that you can use while using the example app.

Key Function
1 Presentation mode
2 Texture editing mode
3 Projection mapping mode, use this to select a surface first
4 Source selection mode
i Show info
t Add triangle surface
q Add quad surface
g Add grid warp surface
c Add circle surface
d Duplicate selected surface
+ Scale surface up
- Scale surface down
p Toggle perspective warping (quad surfaces only)
F Expand selected surface to fill the screen (quad surfaces only)
] Add columns to grid surface (grid warp surfaces only)
[ Remove columns from grid surface (grid warp surfaces only)
} Add rows to grid surface (grid warp surfaces only)
{ Remove rows from grid surface (grid warp surfaces only)
. Select next surface (projection mapping mode only)
, Select previous surface (projection mapping mode only)
> Select next vertex
< Select previous vertex
0 Move selected surface one layer up
9 Move selected surface one layer down
s Save composition
l Hide/show layer panel
z Undo
rbt Reboot (Raspberry Pi only)
sdn Shutdown (Raspberry Pi only)
new Clear composition (remove all surfaces)
ext Exit application and return to command line
BACKSPACE ('' via SSH) Delete surface.
SPACE Toggle pause for video sources (texture and projection mapping modes)
TAB Select next source (no need to use the source selection interface)
Arrow keys Move selection. If no surface is selected in the projection mapping mode, all surfaces are moved.
/ Toggle 1px/10px steps for keyboard moves on Raspberry Pi

Notes on Video Encoding

Easiest way to achieve success is to use HandBrake with the following settings. This will produce a .mkv file with 16bit FLAC audio with 22.05KHz sampling rate.

Preset: Fast 720p30
Summary / Format: MKV File
Video / Framerate: Same as source
Video / Profile: Baseline
Audio / Codec: FLAC 16-bit
Audio / Samplerate: 22.05

If you are familiar with ffmpeg, use the following. It will produce a .mov file. PCM audio codec with 22KHz sampling rate is used.

ffmpeg -i input-video.mp4 -s 1280x720 -aspect 16:9 \
  -c:v libx264 -profile:v baseline \
  -c:a pcm_s16le -ar 22000 -ac 2 \
  output-video.mov

These two settings have shown the best results so far. Audio problems and video playback at the beginning of longer video files was the main issue in most cases. Please open an issue if you have better suggestions.

Extended Functionality

Examples represent extended functionality of ofxPiMapper. Enter each example separately to find out more.

Problems with Audio

If you are having problems with audio playback, here are two steps for you. Before you do these, make sure audio of your video file works.

Step 1

Open example openFrameworks application ofApp.cpp file in a text editor.

cd /home/pi/openFrameworks/addons/ofxPiMapper/example
nano src/ofApp.cpp

Make sure that the following line looks as follows.

ofx::piMapper::VideoSource::enableAudio = true;

Save the file (CTRL + X, Y and ENTER). Recompile and run the example.

make && make run

Step 2

If the sound still does not work, try to use raspi-config.

sudo raspi-config

Select "7 Advanced Options" and "A9 Audio" then "0 Auto". You can use one of the force options if you want to be 100% sure.

Open alsamixer.

alsamixer

Set the volume to a value between 90 to 100 by using the arrow keys. ESC to exit the mixer.

Launch ofxPiMapper example, select a surface and set a video source with audio. Should work.

Development

Keeping it simple. Developing ofxPiMapper master branch against the latest stable release version of openFrameworks.

Licence

ofxPiMapper is distributed under the MIT License. See the LICENSE file for further details. Just add my name somewhere along your project Krisjanis Rijnieks whenever possible.

Supporters

You can become a supporter by donating BitCoins, via PayPal or becoming a Patreon. Please check https://ofxpimapper.com for details. List of supporters below.

Dependencies

Before moving on, make sure that you have all the dependencies installed.

  • ofxGui (available in oF by default)
  • ofxXmlSettings (available in oF by default)
  • ofxOMXPlayer (needed only on Raspberry Pi)

To install dependencies, cd into openFrameworks/addons directory and execute the following:

git clone https://github.com/jvcleave/ofxOMXPlayer.git

The ofxOMXPlayer addon recommends you to use its releases. Currently the latest release is 0.9.0-compatible. To checkout the code of the relase, go to the ofxOMXPlayer addon directory and checkout the relase.

cd openFrameworks/addons/ofxOMXPlayer
git checkout 0.9.0-compatible

You can check the latest releases on the ofxOMXPlayer GitHub repository.

ofxpimapper's People

Contributors

c-mendoza avatar dasoe avatar gitter-badger avatar kr15h avatar lobodelmar avatar magdesign avatar pierrep avatar sebllll avatar toughvj avatar u3dreal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ofxpimapper's Issues

Replace ofxUI

Either there is a better add-on or custom version. The best would be to have a custom version with specific look and feel of course.

In my installation something big is wrong (problems with mouse, fullscreen, info.. etc.)

Hi Krisjanis,

first of all thank you for this great project!!!

Last weekend I spent trying to get ofxPiMapper working as expected. But I didn't get it. It felt like I make something totally wrong like I would use incompatible version of OF or os. No mouse (doesn't matter wether it is the projection mapping state), fullscreen doesn't work, no info is showed (only grey lines), the right surface is empty and etc...
But I use: RPI 2B, Raspbian Jessie Lite, OF 0.9.2.. and actually it should work. On MacOS ofxPiMapper works as expected.

May be you have seen something similar and can directly recognize what is wrong...

Thank you in advance.

here are the output and the pic of the fullscreen mode:

pi@raspberrypi:~/openFrameworks/addons/ofxPiMapper/example $ make run
HOST_OS=Linux
checking pkg-config libraries:   cairo zlib gstreamer-app-1.0 gstreamer-1.0 gstreamer-video-1.0 gstreamer-base-1.0 libudev freetype2 fontconfig sndfile openal openssl libpulse-simple alsa gtk+-3.0 
[warning] ofAppEGLWindow: init(): X11 not availble on RPI yet, using a native window instead
[notice ] ofAppEGLWindow: setupRPiNativeWindow(): screenRect: 1920x1080
[notice ] ofAppEGLWindow: setupRPiNativeWindow(): windowRect: 800x450
[notice ] ofAppEGLWindow: createSurface(): setting up EGL Display
[notice ] ofAppEGLWindow: createSurface(): EGL Display correctly set 0x1
[notice ] ofAppEGLWindow: createSurface(): no current renderer selected
[notice ] ofAppEGLWindow: createSurface(): default renderer detected
[notice ] ofAppEGLWindow: createSurface(): surface created correctly
[notice ] ofAppEGLWindow: createSurface(): API bound correctly
[notice ] ofAppEGLWindow: createSurface(): -----EGL-----
[notice ] ofAppEGLWindow: createSurface(): EGL_VERSION_MAJOR = 1
[notice ] ofAppEGLWindow: createSurface(): EGL_VERSION_MINOR = 4
[notice ] ofAppEGLWindow: createSurface(): EGL_CLIENT_APIS = OpenGL_ES OpenVG
[notice ] ofAppEGLWindow: createSurface(): EGL_VENDOR = Broadcom
[notice ] ofAppEGLWindow: createSurface(): EGL_VERSION = 1.4
[notice ] ofAppEGLWindow: createSurface(): EGL_EXTENSIONS = EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_vg_parent_image EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_lock_surface 
[notice ] ofAppEGLWindow: createSurface(): GL_RENDERER = VideoCore IV HW
[notice ] ofAppEGLWindow: createSurface(): GL_VERSION  = OpenGL ES-CM 1.1
[notice ] ofAppEGLWindow: createSurface(): GL_VENDOR   = Broadcom
[notice ] ofAppEGLWindow: createSurface(): -------------
[notice ] ofAppEGLWindow: setupPeripherals(): peripheral setup complete
[notice ] ofAppEGLWindow: setupNativeUDev(): created udev object
[notice ] ofAppEGLWindow: setupMouse(): mouse_fd= 5 devicePath=/dev/input/by-path/platform-3f980000.usb-usb-0:1.2:1.0-event-mouse
[notice ] ofAppEGLWindow: setupMouse(): mouse device name = Razer Razer Copperhead Laser Mouse
[notice ] ofAppEGLWindow: setupKeyboard(): keyboard_fd= 6 devicePath=/dev/input/by-path/platform-3f980000.usb-usb-0:1.5.2:1.0-event-kbd
[notice ] ofAppEGLWindow: setupKeyboard(): keyboard device name = Apple Inc. Apple Keyboard
[notice ] ofAppEGLWindow: setupPeripherals(): native event setup complete
[notice ] MediaServer: Attempting to add FBO source with name Cross FBO Source
[notice ] MediaServer: Source new, adding
[notice ] MediaServer: Attempting to add FBO source with name Custom FBO Source
[notice ] MediaServer: Source new, adding
[ error ] Application::loadXmlSettings(): surfaces.xml does not exist
[warning] Application::setup(): Failed to load user settings

[notice ] MediaServer: Attempting to load FBO source with name Custom FBO Source
[notice ] FboSource: Adding app listeners
[notice ] MediaServer: Current Custom FBO Source reference count: 1
[notice ] bool ofxOMXPlayerEngine::didReadFile(bool): didOpenMovie TOOK 50 MS
[notice ] bool ofxOMXPlayerEngine::openPlayer(int): duration SET: 33.3333
[notice ] bool OMXClock::OMXStart(double, bool): at pts: 0
[notice ] bool ofxOMXPlayerEngine::openPlayer(int): Opened video PASS
[notice ] MediaServer: Initialized reference count of /home/pi/openFrameworks/addons/ofxPiMapper/example/bin/data/sources/videos/test.mov to 1
[notice ] MediaServer: Initialized reference count of /home/pi/openFrameworks/addons/ofxPiMapper/example/bin/data/sources/images/image4.jpg to 1

fullscreen

can't build under OSX

hello,

thanks for the addon
i have a problem : i can't make it to build under OSX El Capitan and oF09

see attached image
capture d ecran 2016-01-15 a 11 58 38

any clue ?

Add getId() method for source classes

Now we have getName() for FBO sources and getPath() for loadable sources. Need to figure out an ID protocol so any source would have an ID instead of something different.

List of keyboard shortcuts

Keyboard shortcuts/instructions for the following actions need to be documented (or added):

  • Adding a triangle
  • Deleting a triangle
  • Adding a node to a triangle
  • Deleting a node
  • Going fullscreen

Source Selection

When doing videomapping, in most cases the projector is offscreen and half of the image is not really visible, so it would be very nice to display the sources in center of the screen.

Is this possible, can i define it somewhere before compiling?

Crashing when loading omxPlayer source repeatedly

After loading the video the second time on RPi app crashes and this is the output:

[notice ] MediaServer: Initialized reference count of /home/pi/openFrameworks/addons/ofxPiMapper/example/bin/data/sources/videos/test.mov to 1
terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_S_create

error building in debian 64 bits

hello,

here i am facing these errors with the latest commit :

In file included from /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.cpp:1:0: /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.h:29:48: error: expected class-name before ‘{’ token class TerminalListener : public Poco::Runnable { ^ /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.h:42:9: error: ‘Thread’ in namespace ‘Poco’ does not name a type Poco::Thread thread; ^ /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.cpp: In member function ‘void ofx::piMapper::TerminalListener::setup(ofx::piMapper::KeyListener*, int)’: /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.cpp:37:8: error: expected unqualified-id before ‘.’ token thread.start(*this); ^ /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.cpp: In member function ‘void ofx::piMapper::TerminalListener::run()’: /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.cpp:41:15: error: expected primary-expression before ‘.’ token while (thread.isRunning()){ ^ /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.cpp:62:10: error: expected unqualified-id before ‘.’ token thread.sleep(sleepTime); ^ /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.cpp: In member function ‘void ofx::piMapper::TerminalListener::close()’: /home/major/oF092/addons/ofxPiMapper/src/Utils/TerminalListener.cpp:69:8: error: expected unqualified-id before ‘.’ token thread.tryJoin(50); ^ /home/major/oF092/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk:335: recipe for target '/home/major/oF092/addons/obj/linux64/Release/ofxPiMapper/src/Utils/TerminalListener.o' failed make[1]: *** [/home/major/oF092/addons/obj/linux64/Release/ofxPiMapper/src/Utils/TerminalListener.o] Error 1 make[1]: Leaving directory '/home/major/oF092/apps/myApps/ofMapper' /home/major/oF092/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk:126: recipe for target 'Release' failed make: *** [Release] Error 2

building an old branch is ok. For example this one :
https://github.com/kr15h/ofxPiMapper/tree/53b7d31c976ff0c26e1272d786595d14a09999e8

Add Video Source

Possibility to easily assign a video source to a surface. This involves to make the the overall surface system better organized.

Remote Control

To be truly useable an Application for remote Controlling the App would be great. Have you looked into that? I would suggest doing it over OSC and mirror the scene on the Remote Controlling device.

Can I use an X Display as a source?

I have a Raspberry Pi and a small pocket-sized projector and I'd like to be able to project my raspberry pi to any wall while correcting for keystone distortion. Is there any way to mirror my desktop using this program?

Very sensitive mouse behaviour

Using ofxPiMapper without X.

When using generic USB mouse, its very sensitive to use, is it possible to adjust the mouse sensitivity somewhere ?

Also Logitech wireless mouse is not working, where is the location to load mouse drivers ?

Changing sources with TAB do not work always

For new surfaces - the default source is not changed.
For surfaces with a source already - instead of the next source, white surface is displayed. Either the source is not loaded or something else.

SourcesEditor setup is not run

If ofxPiMapper is being initialised during oF setup() it is already too late to set up the SourcesEditor. It results in source lists not being initialised or even worse - crashing the app because of uninitialised vectors.

Gstreamer problem

Hello,

I am facing a problem with latest commit of ofxPiMapper and oF0.9.2 under Ubuntu Trusty 64.

I installed oF and launched install_dependencies.sh and install_codecs.sh

Compiling went well but when running i get the messages :

[error] ofGstUtils: embedded video playback halted for plugin, module source reported: Ressource not found
[error] ofGstUtils: startPipelin(): unable to pause pipeline
[error] ofGstUtils: embedded video playback halted for plugin, module decodebin1 reported: Your GSTreamer installation is mussing a plug-in

App is running. Images are ok, but video stays black

thanks

surface not consistent between window mode and fullscreen mode

hello,

in window mode : add a quad and warp it

capture d ecran 2016-02-18 a 23 32 55

go in fullscreen mode : image is scaling following the app window size instead of keeping inside the quad

capture d ecran 2016-02-18 a 23 33 11

When clicking the surface to edit it, image texture resizes back to the quad surface

Image texture should follox the scale of the quad no matter we are toggling fullscreen or not

Fbo source

Custom FBO source feature. Possibility to register custom sources in media server thus making them available via sources editor in the UI.

Merge branch feature-fboSource

ofxIO.h No such file or directory

Hi,
when i try to compile the PiMapper example App i get the following error:

In file included from ../../../addons/ofxPiMapper/src/MediaServer/MediaServer.h:15:0,
                 from ../../../addons/ofxPiMapper/src/Surfaces/SurfaceManager.h:7,
                 from ../../../addons/ofxPiMapper/src/ofxPiMapper.h:4,
                 from src/ofApp.h:4,
                 from src/ofApp.cpp:1:
../../../addons/ofxPiMapper/src/MediaServer/DirectoryWatcher.h:12:19: fatal error: ofxIO.h: No such file or directory
compilation terminated.

The open frameworks version was installed yesterday and the normal examples work.

Problems with Raspbian Jessie

I couldn't get the example to work with Jessie.
After reading in the chat i tried installing Raspbian Wheezy, which did work.

After loading the app on RPi 2, switch video sources then app crashes and this is the output:(3 case)

case1:
[notice ] MediaServer: Initialized reference count of /home/pi/of_v0.8.4_linuxarm7l_release/addon/ofxPiMapper/example/bin/data/sources/videos/test.mov to 1
Segmentation fault
../../../libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk:168: recipe for target 'run' failed
make: ***[run]Error 139

case2:(sometime)
[warning] bool ofxOMXPlayerEngine::setup(ofxOMXPlayerSettings&): FAST PATH MOVE OPEN FAILED - LIKELY A STREAM, TRYING SLOW PATH
[ error ] COMXPlayer::OpenFile - xxx......

case3:(enableAudio=true)
[ error ] COMXAudioCodecOMX::GetChannelMap - FFmpeg reported 2 channels, but the layout contains 0 ignoring
...

rpi2 - using mouse

hello,

i was able to build piManager on a raspberry pi 2 under raspbian lite but without x11 i imagine i can't use the mouse right ?

so i installed openbox, but this doesn't work either...

how can i use the mouse on rpi ?

thanks a lot

Raspberry PI 3 + textured 1080p video?

I've tried running ofxPiMapper on the new RPI 3 with Raspbian Jessie Lite, and it works perfectly!
1080p video in textured mode runs at 30-40fps, but still doesn't run as smooth as i expected.
There's still some horizontal tearing, with a 1500kbps 1080p mp4 file.
Tested with GPU memory 128 - 256 - 320 - 768 mb.

RPI 3 only came out yesterday, but i'm very keen to know if this is possible with the new hardware!

Namespaces

While looking at ofxIO I noticed that using namespaces would be a good way to structure the code. There are already a lot of Classes and it would be nicer to write ofxPiMapper::QuadSurface. ofxIO goes even further and has two namespaces ofx and IO. So there you have to use ofx::IO::*.
What do you think?

fullscreen mode not fullscreen

hello,

when using fullscreen=true at app launch, app stays in window mode when starting.

using "f" key to make it fullscreen doesn't work the first time. Needs to use "f" twice to make it fullscreen.

i am under ubuntu 14.04 64 bits and oF0.9.2

Ogg support ?

Hello,

I would like to use the Ogg codec form my videos as it appears to be the smoother solution for me.

Is there a way to make Ogg codec usable ?

I think ofxPiMapper uses GStreamer which should support the Ogg Theora codec, but in ofxPiMapper example, when switching to media selection mode (mode 4), ogg encoded videos doesn't show up.

Thanks

Once quad perspective is activated, selecting an area in the input source view results in non consistent output: output doesn't reflect the area selected

In a way this is because of how perspective warping works. @aspeteRakete used a method described here http://www.reedbeta.com/blog/2012/05/26/quadrilateral-interpolation-part-1/

I wonder what MadMapper perspective warping looks like, will check it out. In my opinion, the perfect solution is a combination of mesh warping and perspective warping.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.