DEV Community

Cover image for Drawing 3D Models in the Browser - with Python!
Meredydd Luff
Meredydd Luff

Posted on • Originally published at anvil.works

Drawing 3D Models in the Browser - with Python!

A 3D Christmas Tree in the Browser - With Nothing But Python

Good news: It's time to decorate the tree!

Bad news: Nobody will see it inside my house this year.

So I'm putting up a virtual one, in 3D.

Even more good news: I can do it all with nothing but Python!

Anvil lets me build web apps with Python. And I can use three.js, the browser-based 3D engine - without writing any Javascript at all! That's because Anvil lets you use Javascript libraries from Python.



Here's what the finished app looks like:

The finished app

Try it yourself >>


If you're feeling impatient, you can just grab the source code - or read on to find out how it works.

How I built it

1. Setup

Driving a Javascript library in Anvil is easy. First, I included the library in my Native Libraries:

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r122/three.min.js"></script>
Enter fullscreen mode Exit fullscreen mode

Now I can open my Python code and import the three.js library into Python, with from anvil.js.window import THREE.

I'm making my tree out of three ConeGeometry objects -- although they're Javascript objects, we can construct them straight from Python. Here's the Python code that actually builds the tree:

# Import the three.js library from Javascript-land:
from anvil.js.window import THREE

for i in range(3):
  geom = THREE.ConeGeometry(1, 1-0.2*i, 32)
  cone = THREE.Mesh(geom, green_tree)
  cone.position.y = i
  self.scene.add(cone)
Enter fullscreen mode Exit fullscreen mode

And voila: A tree -- in my browser, built with Python:

A 3D Christmas tree with no decoration


2. Time to decorate!

Now, a tree on its own isn't very interesting, so it's time to add some baubles. I'm adding spheres of random colours along the outside of each cone.

So, for each cone, we do some trigonometry - we'll walk round the cone, adding baubles at random intervals. Remember that a cone is wider at the bottom than at the top, so we use Python's random.triangular() to pick lower positions more often:

      bauble_geom = THREE.SphereGeometry(0.1)
      theta = 0
      while theta < 2*math.pi:

          # Move a bit further round the tree
          theta += random.triangular(0, 0.5, 1);
          # How far down the cone? (0=top point, 1=bottom edge)
          fh = random.triangular(0.3, 0.9, 0.9)
          # What's the radius of the cone, this far down?
          d = fh*r

          # What colour?
          material = THREE.MeshLambertMaterial({ 'color': f"hsl({random()*360}, 100%, 50%)" })
          bauble = THREE.Mesh(bauble_geom, material)

          # Hang it on the tree
          bauble.position.set(d*math.sin(theta), cone_base + (1-fh)*h, d*math.cos(theta))
          cone.add(bauble)
Enter fullscreen mode Exit fullscreen mode

3. Making it interactive

A Christmas tree is a personal expression, and everyone wants to customise theirs. So I've used Anvil's drag-and-drop UI designer to build a little control panel, and wire up the dropdowns to control the construction of the tree:

Adding UI to control the tree


Sharing it with the world

Time to publish my app and share it with the world! You can open it here:

https://3d-tree.anvil.app

And you can get the whole source code here:

Source code >>

Happy decorating! And if you enjoyed this, you should check out the rest of the Anvil Advent Calendar. We're building a web app a day with nothing but Python -- every day until Christmas!

Top comments (0)