Strange behavior when compounding 400+ cylinders

32 views
Skip to first unread message

Russell Kramer

unread,
Dec 13, 2017, 6:19:34 PM12/13/17
to VPython-users
I am building models of trees using cylinders for branches based on real data. On the left I rendered the tree with individual cylinders, on the right I used compound to make one object from all the cylinders. The only difference in the code is that I added a line to compound a list of branch cylinders.  

In the right-hand image the cylinders from branches 1-178 are connected by surfaces. There are 499 cylinders stored in a list. I know that compound should be able to handle many more than 500 objects. 

What could be going on? Perhaps this is a webGl problem?





Bruce Sherwood

unread,
Dec 13, 2017, 7:26:22 PM12/13/17
to VPython-users
Yes, it's a WebGL limitation, though it's a current failing of VPython not to issue an error message, nor does the documentation of compound say anything about this. Both failings need to be addressed.

The "model" or "mesh" in GPU memory for a cylinder requires the use of the equivalent of 200 vertex objects. If you compound 500 cylinders, that requires 200*500 = 100,000 vertexes. The current version of WebGL is able to handle only 65536 (2**16) vertexes in a single mesh, because the id number of a vertex is a 16-bit integer. There is a way around this limitation, however. Make a compound of 250 cylinders and a second compound of 250 cylinders. When you make your own object using vertex and triangle objects, and then compound them, after the compound is created those vertex objects are released back into the pool of 65536 possible vertexes.

Bruce

Russell Kramer

unread,
Dec 13, 2017, 8:39:59 PM12/13/17
to VPython-users
I should have mentioned that I tried compounding compounds of half the cylinders earlier and am having the same issue. Here is a sample of the code:

    brnchs is a list of 499 cylinder objects

    mid = round(len(brnchs)/2)                                     #get approximate mid point, round if total N is odd
    br1 = compound (brnchs[0:mid], visible = False)
    br2 = compound (brnchs[mid+1:len(brnchs)-1], visible = False)
    brnchs = [br1,br2]
    branches = compound(brnchs, visible = True)

This plots the same model as the original image on the right in the first post. I'll try again but split up the vector in four subsets of branches. 

Bruce Sherwood

unread,
Dec 13, 2017, 10:51:50 PM12/13/17
to VPython-users
Here is a simple program that makes 20 compounds each containing 250 cylinders, for a total of 5000 cylinders. It runs fine, so I don't know what problem your structure has.

from vpython import *

scene.width = scene.height = 600
scene.background = color.white
scene.range = 2
Ncompounds = 20
Ncylinders = 250
N = Ncompounds*Ncylinders

scene.title = '{} cylinders '.format(N)

def random_cylinder():
    c = (vec.random() + vec(1,1,1))/2
    return cylinder(pos=vec.random(), size=0.05*vec(1,1,1), color=c)

def make_compound(n):
    cyls = []
    for i in range(n):
        cyls.append(random_cylinder())
    return compound(cyls)

cs = [] # list of compounds
for i in range(Ncompounds):
    cs.append(make_compound(Ncylinders))

while True:
    rate(100)
    for c in cs:
        c.rotate(angle=0.02, axis=vector(0,1,0), origin=vector(0,0,0))

Kevin Karplus

unread,
Dec 14, 2017, 1:31:13 AM12/14/17
to vpytho...@googlegroups.com
I think Russel's problem was that he was compounding the compounds, so was still running into the 16-bit limit.  The compounds have to be rendered separately, as you are doing, to avoiding having a huge mesh.

Kevin Karplus   kar...@soe.ucsc.edu    http://www.soe.ucsc.edu/~karplus
Professor of Biomolecular Engineering, University of California, Santa Cruz (on sabbatical F2017)
Affiliations for identification only.


--
You received this message because you are subscribed to the Google Groups "VPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Bruce Sherwood

unread,
Dec 14, 2017, 8:39:14 AM12/14/17
to VPython-users
Ah. You're right, Kevin. I missed that important point.

Bruce

Russell Kramer

unread,
Dec 14, 2017, 6:13:34 PM12/14/17
to VPython-users
Thank you for clarifying. I'll use a list that compounds half of the cylinders for each item, then manipulate the shortened list by iterating through the items in it, which should be faster than iterating through all the individual cylinders. 
To unsubscribe from this group and stop receiving emails from it, send an email to vpython-user...@googlegroups.com.

Bruce Sherwood

unread,
Dec 14, 2017, 6:57:02 PM12/14/17
to VPython-users
It's not just that you will save time in your own code. Compounding 250 cylinders into one 3D object means that the work of the GPU to render them, and even the work of the CPU to tell the GPU what to render, is enormously reduced. If you run my little program you'll see 5000 cylinders rotating in a group.

Bruce

Russell Kramer

unread,
Dec 15, 2017, 1:47:44 PM12/15/17
to VPython-users
Yes, that is a great feature of compound objects! Thank you for all the work you've done to make such a great tool. 
Reply all
Reply to author
Forward
0 new messages