-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add slice render method #49
Conversation
So the basic idea is... render to a slice of triangles (in memory) rather than write it via a channel to the file? A few observations... building a bolt in the benchmark - the screw form doesn't render well with octree marching cubes. because the signed distance field is actually wrong at far distances. Probably doesn't matter for the purposes of the benchmark, but still... Octree marching cubes is single threaded. getting some go routines in there could give some xN speedups. (N == number of cores) What I really want to see work properly is the double contouring renderer. At the moment it's slow and the result is shitty. |
I believe both would benefit from the same rewrite since the use of channels is inefficient in this case. I do have an idea for speeding it using multi-core functionality up but it requires considerable concurrency infrastructure. Channels should ideally receive a large batch of triangles to write to file as a I think the best approach is to first have a working non-concurrent simple implementation of the renderer without fancy channels. Once you have a working single threaded renderer one can start thinking of reusing the single-threaded functions one has at hand to be multithreaded and developing a MultiCoreRenderer3 interface or something of the sort. If I am given your blessing I will tear down the concurrent implementation as it stands today and rewrite all of it to be single-threaded with the possibility of a even faster multi core version tomorrow. As for the double contouring renderer I can give that a go as well- Be warned I'm not that well versed in computational geometry, if that's were the problem lies. |
I am also in need of solving #35, which was the primary reason I forked this repository... I may end up shaving more yaks than I planned. |
The normal marching cubes (march3.go) is concurrent. btw - the reason the slower march3.go is kept around is because of the afore-mentioned issues with rendering objects with approximated distance fields (screw threads mostly). Other than that the octree renderer is equivalient to uniform cube decomposition of space- it just does less work. If performance is a significant concern then there's a big gain to be had in throwing more cores at the octree renderer.ie xN where N is how many cores you have. In this case a channel implementation for streaming the triangle out is advantageous because it takes care of concurrency issues for you.
It might be an idea to try some channel buffering experiments to see if there are any performance gains to be had from that. I suspect most of the gains you've seen with an in-memory slice could be gained by a bit more decoupling between the renderer and the file writer.
That's a byte buffer oriented interface. Marching cubes creates a stream of triangles, and how you choose to marshal those into bytes is somewhat arbitrary, e.g. stl, 3mf, .... Now nothing stops you from building a converter - triangle input channel, write to io.Writer with a marshalling format of your own design- but that doesn't belong in the renderer. E.g. object + renderer -> stl writer (to file) |
I think you are mixing them up? func (m *MarchingCubesUniform) Render(s sdf.SDF3, meshCells int, output chan<- *Triangle3) {
// work out the region we will sample
bb0 := s.BoundingBox()
bb0Size := bb0.Size()
meshInc := bb0Size.MaxComponent() / float64(meshCells)
bb1Size := bb0Size.DivScalar(meshInc)
bb1Size = bb1Size.Ceil().AddScalar(1)
bb1Size = bb1Size.MulScalar(meshInc)
bb := sdf.NewBox3(bb0.Center(), bb1Size)
for _, tri := range marchingCubes(s, bb, meshInc) { // this is a slice, not a channel
output <- tri
}
} While
I wrote a single-threaded implementation for I want to write a real-time browser 3d renderer (current sdf-ui implementation is slow and clunky) using three.js and Go WASM bindings to make it a pleasure to work with sdfx (this is for the CERN-organized hackathon/competition). As the As a user, contributor and just random guy on the internet, I strongly suggest the |
No. Read the code. The dcache3 stuff had locks put on it in preparation for a multi-threaded octree renderer, but it's not currently necessary.
That's a different problem than the renderer deals with. ie - 3d preview concerns itself with visible faces while STL generation has to concern itself with the whole object. |
I was wrong. I think I managed to find the parallelization in normal marching cubes in an
I'm not concerning myself with low level 3d preview-
For my application triangles become bytes when I send them over http. I guess I could use the
Yes, this is true. The single-triangle queue given by the
I'm not sure what form a "good" |
Octree rendering got almost a x2 speed boost. With a little creative freedom I'd offer rewriting the STL part of the
render
package as it seems to be lush with room for improvement, both speed and API thoughtfulness such as adding io.Writer convention, minimizing heap usage, and more.