Compose3D.jl and ThreeJS.jl – Interactive 3D Graphics in the Browser

By: Julia Developers

Re-posted from: http://feedproxy.google.com/~r/JuliaLang/~3/9QyEFTa8sCA/compose3d-threejs

Over the last three months, I’ve been working on Compose3D,
which is an extension of the amazing Compose package to 3D. My work on
Compose3D began as a project for my Computer Graphics course along with Pranav T Bhat,
and by the end of the course, we had a working prototype for Compose3D with support for contexts and geometries and a
very basic WebGL backend.

It has been my pleasure to have been able to continue this work under the guidance of Shashi Gowda
and Simon Danisch as a part of the first ever Julia Summer of Code, generously
sponsored by the Gordon and Betty Moore Foundation. While I’ve been able to add quite a lot of
functionality to Compose3D, it isn’t totally ready for release yet. Hopefully, in some time it
will be ready. But as a happy side effect, I have been able to abstract out the WebGL rendering functionality provided
by the original prototype (and a lot more!) to a separate package called
ThreeJS.jl,
which can now be used to render 3D graphics in browsers using Julia, opening up possibilities of displaying such
scenes in IJulia notebooks and Escher.

ThreeJS.jl

ThreeJS is now responsible for all the WebGL rendering done by Compose3D. It can also be used as a standalone package for
other graphics packages to use as a backend.

Initially, my approach to render scenes in Compose3D was to just emit out the corresponding JavaScript code, into the
IJulia notebook, which would then run it! This worked pretty well in IJulia notebooks, but it was soon apparent that
there were several flaws with this approach.

  • It was hard to extend.
  • Did not play well with Escher.
  • Nor did it work with Interact to provide interactivity.

So Shashi suggested implementing a Polymer wrapper around the excellent
three.js library, to create threejs web components. The Polymer team had done some work on
creating threejs components and had a basic implementation of the same ready, which I promptly forked
and tweaked to add functionality I needed. It’s quite safe to say that I’ve spent more time writing JavaScript than
Julia during JSoC!

Switching over to using web components suddenly opened up 2 major avenues. Compose3D could now work with Escher and
also provided interactivity. ThreeJS outputs Patchwork
elements, which lets it use Patchwork’s clever diffing capabilities, thereby updating only the required DOM elements and
helping performance.

On the other hand, web components introduced issues with IJulia notebooks regarding serving the files required by
ThreeJS. I’m still working on finding a good solution for this problem, but for now, a hack gets ThreeJS working in
IJulia, albiet with some limitations.

Drawing stuff!

Anyway, now we were all set to draw 3D scenes in browsers! The below code snippet, for example, would draw a red cube
illuminated from a corner. The camera in the scenes drawn by ThreeJS can be rotated, zoomed and panned using your mouse
or trackpad, allowing you to explore the scene.

import ThreeJS
ThreeJS.outerdiv() << (ThreeJS.initscene() <<
    [
        ThreeJS.mesh(0.0, 0.0, 0.0) <<
        [
            ThreeJS.box(1.0,1.0,1.0),
            ThreeJS.material(Dict(:kind=>"lambert",:color=>"red"))
        ],
        ThreeJS.pointlight(3.0, 3.0, 3.0),
        ThreeJS.camera(0.0, 0.0, 10.0)
    ])  

Making them interactive

Currently, interactivity is broken in IJulia (a side effect of the switch to Polymer 1.0, and the new sneaky DOM),
so Escher is the way to go if you want to interact with your 3D scene. So an example for this can be the same scene as before,
but after adding a slider and make it such that the size of the cube is controlled by the slider.

import ThreeJS
function main(window)
  push!(window.assets, "widgets")
  push!(window.assets, ("ThreeJS", "threejs"))
  side = Input(1.0)
  vbox(
    slider(1.0:5.0) >>> side,
    lift(side) do val
      ThreeJS.outerdiv() << (ThreeJS.initscene() <<
      [
          ThreeJS.mesh(0.0, 0.0, 0.0) <<
          [
              ThreeJS.box(val, val, val),
              ThreeJS.material(Dict(:kind=>"lambert",:color=>"red"))
          ],
          ThreeJS.pointlight(3.0, 3.0, 3.0),
          ThreeJS.camera(0.0, 0.0, 10.0)
      ])
    end
  )
end

You can also do animations!

Small scale animations can also be created using Escher. Instead of using sliders to update the elements,
we just update it at certain intervals using the every function or the fpswhen functions. A scene with a
rotating cube can be drawn using just a couple of modifications of the above code.

import ThreeJS
function main(window)
  push!(window.assets, "widgets")
  push!(window.assets, ("ThreeJS", "threejs"))
  rx = 0.0
  ry = 0.0
  rz = 0.0
  delta = fpswhen(window.alive, 60) #Update at 60 FPS
  lift(delta) do _
      rx += 0.5
      ry += 0.5
      rz += 0.5
      ThreeJS.outerdiv() << (ThreeJS.initscene() <<
      [
          ThreeJS.mesh(0.0, 0.0, 0.0) <<
          [
              ThreeJS.box(2.0, 2.0, 2.0, rx = rx, ry = ry, rz = rz),
              ThreeJS.material(Dict(:kind=>"lambert",:color=>"red"))
          ],
          ThreeJS.pointlight(3.0, 3.0, 3.0),
          ThreeJS.camera(0.0, 0.0, 10.0)
      ])
    end
end

Rotating Cube

Surf and mesh plots! (Sort of)

ThreeJS has support to render parametric surfaces, which are basically the kind of surfaces drawn by
a typical surf plot. It also has support for drawing lines like a typical mesh plot. Colormaps can
be applied to these surfaces by passing in an array of colors to be used. Colors to be applied are
calculated and chosen by ThreeJS. These come into effect when put together with materials using the colorkind
property of vertex. Screenshots of such surfaces drawn by ThreeJS are shown below.

Parametric surface
Mesh lines

Compose3D

Compose3D provides an abstraction over the rendering library and lets you compose together primitives to
build scenes just like the inspiration for it, the Compose library. This lets you create very interesting
structures, with very less code! Compose3D has similar features to Compose, with users being able to create 3D contexts, and then use relative and absolute measures inside them and compose other primitives together.

My favorite example to showcase Compose3D would be the Sierpinski pyramid example. Here, we split the parent context
into the sections that we want and then just draw the pyramid in them! So the bottom half of the 3D space is split into 4,
and then, a pyramid is arranged on top of them.

using Compose3D

function sierpinski(n)
    if n == 0
        compose(Context(0w,0h,0d,1w,1h,1d),pyramid(0w,0h,0d,1w,1h)) #The basic unit
    else
        t = sierpinski(n - 1)
        compose(Context(0w,0h,0d,1w,1h,1d),
        (Context(0w,0h,0d,(1/2)w,(1/2)h,(1/2)d), t),
        (Context(0w,0h,0.5d,(1/2)w,(1/2)h,(1/2)d), t),
        (Context(0.5w,0h,0.5d,(1/2)w,(1/2)h,(1/2)d), t),
        (Context(0.5w,0h,0d,(1/2)w,(1/2)h,(1/2)d), t),
        (Context(0.25w,0.5h,0.25d,(1/2)w,(1/2)h,(1/2)d), t)) #The top one
    end
end
compose(Context(-5mm,-5mm,-5mm,10mm,10mm,10mm),sierpinski(3))

And voila! You have a Sierpinski pyramid of level 3 like in the figure below.

Sierpinski
The switch to ThreeJS allows Compose3D all the advantages that comes with ThreeJS. This includes interactivity
and animations!

For example, the same Sierpinski example can be have some interactive elements, say a slider defining the
number of levels of recursion and maybe some controlling the colors of the pyramid. This can be done easily
in Escher just like it was done with ThreeJS. After defining the sierpinski function given below, just creating a slider
and hooking it up to the sierpinski function will set this up!

function main(window)
    push!(window.assets, ("ThreeJS", "threejs")) #Push the threejs static assets
    push!(window.assets, "widgets")
    n = Input(0.0)

    vbox(
        slider(0.0:3.0) >>> n, #Set up the slider
        lift(n) do i
            #Draw the composed figure!
            draw(
                Patchable3D(100,100),
                compose(
                    Context(-5mm,-5mm,-5mm,10mm,10mm,10mm), sierpinski(i)
                )
            )
        end
    )
end

Interactive Sierpinski

An an example for animations, I ported the Escher boids example by Ian Dunning from 2D to 3D and a screencast of the same can be found below.

Future directions

  • Several new primitives have been added in ThreeJS which don’t yet have corresponding primitives in Compose3D.
  • Add support for text in ThreeJS allowing use of labels in plots.
  • Being able to use surf and mesh that will automatically draw scaled surface plots in browsers and a WebGL based
    plotting library around ThreeJS.
  • Actually get Compose3D ready for public use!

Julia, data analysis’s little sister…meets SAP HANA

By: Alvaro "Blag" Tejada Galindo

Re-posted from: http://blagrants.blogspot.com/2015/10/julia-data-analysiss-little-sistermeets.html

This post was originally posted on Julia, data analysis’s little sister…meets SAP HANA.


Julia is not that young right now…as it first appeared on 2012 -:) It is a high-level dynamic programming language designed to address the requirements of high-performance numerical and scientific computing while also being effective for general purpose programming.
Woaw! That was a big description…so why should we care? Well…maybe because Julia was designed to be the language to rule them all…a language that can be used in any given situation…and without stopping to say if that’s true or not…I must say…Julia is really cool -:)
So…no example or demonstration would be complete if we didn’t hook it up with SAP HANA, right? So…let’s go and do it -;)
First, we need to create a Calculation View and call it “FLIGHTS_BY_CARRIER”. It will be composed of two tables, SCARR and SFLIGHT.
First, we need to create a Join object and link the table by MANDT and CARRID. From here select the following fields as output MANDT, CARRID, CARRNAME, PRICE and CURRENCY.
Then create an Aggregation object selecting the fields CARRNAME, PRICE (As Aggregated Column) and CURRENCY. Filter the CURRENCY field by ‘USD’.
Then create a Projection object and select only PRICE and CARRNAME.
On the Semantics object make sure to select “CROSS CLIENT” as the Default Client.
Now, switch to the SAP HANA Development View and create a new repository. Call it “Flights”.
Create a new “XS Engine” project and call it “Flights” as well. Link it to the “Flights” repository.
Create an empty “.xsapp” file.
Create a file called “.xsaccess” with the following code.
.xsaccess
{
"exposed" : true,
"authentication" : [ { "method" : "Basic" } ]
}

Finally create a file called “flights.xsodata” with the following code

flights.xodata
service {
"Blag/FLIGHTS_BY_CARRIER.calculationview" as "FLIGHTS" keys
generate local "Id";
}

Activate your project and launch it on your browser, you should see something like this…

The SAP HANA part is done…so we can move into the Julia part…

Go into your Julia environment and install the following packages

  • HTTPClient
  • Codecs
  • LightXML

You only need to do Pkg.add(“PackageName”) for each of them.

Then create a file called Julia_HANA_XML.jl on your favorite editor and copy the following code

Julia_HANA_XML.jl
using HTTPClient.HTTPC
using Codecs
using LightXML

credentials=encode(Base64,"SYSTEM:YourPassword")
Auth = bytestring(credentials)
Auth = "Basic " * Auth

flights=HTTPC.get("http://YourServer:8000/Flights/flights.xsodata/FLIGHTS",RequestOptions(headers=[("Authorization",Auth)]))

raw_text = takebuf_string(flights.body)
xdoc = parse_string(raw_text)
xroot = root(xdoc)

entry = get_elements_by_tagname(xroot,"entry")

for flights in entry
print(content(find_element(find_element(find_element(flights,"content"),"properties"),"CARRNAME")),": ",
content(find_element(find_element(find_element(flights,"content"),"properties"),"PRICE")),"n")
end

To run this application, simply go to your Julia environment and type

Include(“Julia_HANA_XML.jl”)

If you are wondering…why didn’t I use JSON instead of XML? Well…there’s an easy explanation for that -:) Somehow…the HTTPClient package have a problem using ?$format=json so I was forced to use XML instead…
Greetings,
Blag.
Development Culture.

#MonthOfJulia Day 36: Markdown

Julia-Logo-Markdown

Markdown is a lightweight format specification language developed by John Gruber. Markdown can be converted to HTML, LaTeX or other document formats. You probably knew all that already. The syntax is pretty simple. Check out this useful cheatsheet.

In the latest stable version of Julia support for markdown is provided in the Base package.

julia> using Base.Markdown
julia> import Base.Markdown: MD, Paragraph, Header, Italic, Bold, LineBreak, plain, term, html,
                             Table, Code, LaTeX, writemime

Markdown is stored in objects of type Base.Markdown.MD. As you’ll see below, there are at least two ways to construct markdown objects: either directly from a string (using markdown syntax) or programmatically (using a selection of formatting functions).

julia> d1 = md"foo *italic foo* **bold foo** `code foo`";
julia> d2 = MD(Paragraph(["foo ", Italic("italic foo"), " ", Bold("bold foo"), " ",
               Code("code foo")]));
julia> typeof(d1)
Base.Markdown.MD
julia> d1 == d2
true

You’ll find that Base.Markdown.MD objects are rendered with appropriate formatting in your console.
julia-console-markdown

Functions html() and latex() convert Base.Markdown.MD objects into other formats. Another way of rendering markdown elements is with writemime(), where the output is determined by specifying a MIME type.

julia> html(d1)
"<p>foo <em>italic foo</em> <strong>bold foo</strong> <code>code foo</code></p>n"
julia> latex(d1)
"foo \emph{italic foo} \textbf{bold foo} \texttt{code foo}n"

Markdown has support for section headers, both ordered and unordered lists, tables, code fragments and block quotes.

julia> d3 = md"""# Chapter Title
       ## Section Title
       ### Subsection Title""";
julia> d4 = MD(Header{2}("Section Title"));
julia> d3 |> html
"<h1>Chapter Title</h1>n<h2>Section Title</h2>n<h3>Subsection Title</h3>n"
julia> latex(d4)
"\subsection{Section Title}n"

Most Julia packages come with a README.md markdown file which provides an overview of the package. The readme() function gives you direct access to these files’ contents.

julia> readme("Quandl")
  Quandl.jl
  ============
  (Image: Build Status)
  (Image: Coverage Status)
  (Image: Quandl)

  Documentation is provided by Read the Docs.

  See the Quandl API Help Page for further details about the Quandl API. This package 
  closely follows the nomenclature used by that documentation.

We can also use parse_file() to treat the contents of a file as markdown.

julia> d6 = Markdown.parse_file(joinpath(homedir(), ".julia/v0.4/NaNMath/README.md"));

This is rendered below as LaTeX.

section{NaNMath}
Implementations of basic math functions which return texttt{NaN} instead of throwing a
texttt{DomainError}.
Example:
begin{verbatim}
import NaNMath
NaNMath.log(-100) # NaN
NaNMath.pow(-1.5,2.3) # NaN
end{verbatim}
In addition this package provides functions that aggregate one dimensional arrays and ignore
elements that are NaN. The following functions are implemented:
begin{verbatim}
sum
maximum
minimum
mean
var
std
end{verbatim}
Example:
begin{verbatim}
using NaNMath; nm=NaNMath
nm.sum([1., 2., NaN]) # result: 3.0
end{verbatim}
href{https://travis-ci.org/mlubin/NaNMath.jl}{begin{figure}
centering
includegraphics{https://travis-ci.org/mlubin/NaNMath.jl.svg?branch=master}
caption{Build Status}
end{figure}
}

And here it is as HTML.

NaNMath

Implementations of basic math functions which return NaN instead of throwing a DomainError.
Example:

import NaNMath
NaNMath.log(-100) # NaN
NaNMath.pow(-1.5,2.3) # NaN

In addition this package provides functions that aggregate one dimensional arrays and ignore elements that are NaN. The following functions are implemented:

sum
maximum
minimum
mean
var
std

Example:

using NaNMath; nm=NaNMath
nm.sum([1., 2., NaN]) # result: 3.0

Build Status

What particularly appeals to me about the markdown functionality in Julia is the potential for automated generation of documentation and reports. To see more details of my dalliance with Julia and markdown, visit github.

The post #MonthOfJulia Day 36: Markdown appeared first on Exegetic Analytics.