Hacker News new | past | comments | ask | show | jobs | submit login
3D Wireframes Using SVG (prideout.net)
394 points by prideout on July 8, 2019 | hide | past | favorite | 54 comments

This is great! There is, however, one potential issue with this implementation stated here:

"Faces are sorted back-to-front in a very approximate way according to the Z centroid".

In certain cases, this can lead to showing the back face and hiding the front face because the centroid position is not sufficient for figuring out the Z order of triangles.

Other than this minor issue, it's a great implementation.

Yeah, the painter's algorithm fails with certain geometries, like when polygons intersect each other, or when they overlap in a certain way.

Maybe I should compare min positions rather than centroids, but I don't think that would fix those cases.

I think the only real fix involves splitting up the polygons for the failure cases, which seems complex.

Centroids is a reasonable approximation, if your geometry is not very coarse. PlayStation games often used this because the hardware lacked a depth buffer.

You're right! The min positions won't resolve the issue either and, unfortunately, there is no trivial fix for it.

Handling intersecting polygons, as you said, is a bit more complex, but for overlapping polygons it's possible to find the Z-order robustly by computing the intersections with the line of sight.

perhaps you could preprocess the shape using the Binary Space Partitioning (BSP) algorithm. there’s a step in the algorithm that finds polygons that would cause z-sorting conflict and splits them along the exact line you need to resolve the conflict. you end up with a data structure that gives you the z sorting order for any camera angle.

For triangles only the intersection case matters. General Polygons could be a bit more complicated. As long as the object is watertight, it's easier.

I recently ran into similar problems to be solved in Python, because I am trying to build a replacement for OpenSCAD by duct-taping together various Python packages. Shapely is quite useful for 2D geometry (like intersection and stuff). PyMesh is extremely useful for 3D meshes, but hard to build.

There are some non photorealistic rendering (NPR) options for Blender, many of them implemented in Python. I don't know if they can output SVG data currently.

ThreeJs has an SVG engine, meaning a backend that outputs SVG.

> build a replacement for OpenSCAD

I am very interested in this.

My first attempt was using the Blender API, you can take a look at https://github.com/akloster/blender-vraag

Currently I am trying to reimplement the "construct" part with Pymesh and Shapely, but I haven't published it yet.

Have you tried python-occ? http://www.pythonocc.org/

Thank you for the suggestion. I hadn't seen that yet. From a cursory look it's not completely what I am looking for, but maybe it can be useful.

One of the problems for me is that I am sort of stumbling into this "CAD" thing from a coding perspective. CAD programs like Fusion 360° or FreeCAD seem a bit too complicated for me, and through my grappling with the concepts I am reinventing some concepts/tools.

Particularly I want to develop 3D printed objects the same way I would do data science: Start with Jupyter notebooks, iterate, maybe end up with parametric Python scripts.

python-occ may be particularly well suited. They have ipywidgets to look at the models. https://www.youtube.com/watch?v=ieX_GC1sdrQ https://github.com/tpaviot/pythonocc-core/blob/master/src/Di...

I have only taken a cursory look. So far a lot of the links are dead and it's a bit hard to see examples of the API.

I certainly agree with that. It has seen more work recently from the BIM side. http://www.pythonocc.org/ has examples but the most recent work is really demos using it as a part of other projects. https://pure.tue.nl/ws/files/119667686/20190402_Krijnen.pdf https://link.springer.com/article/10.1007/s42496-019-00007-4 https://arxiv.org/pdf/1810.10795.pdf The difficulty for a lot of CAD systems is the NURBS type line geometry interactions. https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline

Have you tried Cadquery for FreeCAD? Allows you to build your models in Python

There was quite a lot of openscad replacement going on in 2011. I even made a lua based alternative.

If you have only one camera angle, you can certainly do polygon intersection to avoid dealing with overlapping polygons.

It's not necessarily going to be as efficient (or rather, as hardware-acceleratable) as computing Z at each point and maintaining a Z-buffer, but that would assume a fixed resolution.

This isn't raster rendering, he is producing an SVG file.

You're entirely right; I've edited my comment accordingly. Thank you.

encoding normal-face direction via the polygon winding can help cull out many edge cases before they would even be an issue.

Awesome work!

I ran the 4 shape example through SVGOMG and lowered the precision slider down until it didn't affect the perceived output.

The result was about 40% of the original size.


SVG tested:


Side note -- if using React, svg2jsx is great for converting the SVG properties to React JSX names.


Ah I've been looking for something like svg2jsx for a while... thanks for sharing!

It was one of those moments where I knew someone out there MUST'VE made a tool for it, but it was a discoverability problem.

You can also take a look at this: https://svgr.now.sh/ It converts SVG to both react and react-native.

Very nice! This reminds me a bit of Michael Fogleman's 3D Line Art Engine [0]. His project was motivated by a desire to make vector art for a pen plotter, so not quite the same goals. I appreciate how you've woven together images, code, and explanatory text in this post.

[0] https://github.com/fogleman/ln

Also Sketch (for ps/pdf rather than svg): http://sketch4latex.sourceforge.net/

I wish I could find it, but a while back there was a post about a web-based vector renderer for 3D objects, possibly a three.js plugin. It has some really nice looking demos.

I don't think it was seen.io, but seen.io appears to do something similar to this post, in JS: http://seenjs.io/

You're thinking of Zdog: https://zzz.dog

Absolutely! Thanks!

Outstanding documentation quality - simple descriptions of the context, problem and solution, at increasing levels of specificity. Other people should learn from this when writing their own Readmes.

Nice. But 17 digits of of precision is on the rendered drawing bit much.

Yeah this is crazy neat but the unnecessary precision is a real bummer that could be solved by just restricting things to three decimal places. For example when I use a utility like https://jakearchibald.github.io/svgomg/ to optimize, I see a 3.53k -> 2.21k reduction for the sphere with lighting. This is not just from precision reduction but also using simple paths over polygons ... there could likely be increased size savings by "rolling up" the fills in the final output.

Still a crazy neat tool but targeting edges as paths instead of polygons would save quite a few bites when hosting this stuff.

Thanks for pointing this out, I just now added a precision field to the Engine class to help with this.

I have thought about doing something similar for PDF reports in a CAE app. Concluded it won’t scale. I need to handle high-poly meshes, 1M vertices and more. That’s why instead I’m using 600DPI jpeg images, rendered on GPU.

But when you know the mesh is low-poly, the technique is really cool. It should be trivial to port from Python to any other language, also from SVG to e.g. PDF.

Anyone know of something that vectorizes STLs or OBJs into a 2D perhaps ortho perspective?

The `Lightness' subproject under LumberSharp does (among many other things) this: https://github.com/daeken/LumberSharp

I built this out to translate 3d models or signed distance fields to SVGs for pen plotting purposes. You can see an example here, generated from a few lines of distance field code: https://scontent-atl3-1.cdninstagram.com/vp/9212f4c15cf30583...

And another generated from an STL I generated with OpenSCAD (part of an Egg sculpture series I did for 3d printing): https://scontent-atl3-1.cdninstagram.com/vp/d3fdf208c687551a...

When I did 3D printing, I racked my brain how to render STL files to SVG. Blender (can import STL and) seems to be able to render to SVG with a plugin (https://blender.stackexchange.com/questions/23661/render-3d-...) but I was never so happy about the results. This small Python code is really so much better!

You don't actually need a plugin -- Blender comes with this feature built-in. It's called "Freestyle" rendering.


Maybe you can do this with gl2ps [1]. You can read the STL file with python-occ [2] and then export it to vector format (it uses gl2ps for this).

[1] http://geuz.org/gl2ps/ [2] http://www.pythonocc.org/

It looks like this library could do it. OBJ is a very simple format to parse, but I'm sure there are libraries to do that too.

This seems useful for SIGGRAPH paper graphics.

BTW I always think this website is something to do with being Out and Pride. That is my default parsing no matter how many times I've seen cool stuff on this website and the great stuff that Philip does.

Lol :) Phil, perhaps you can consider renamimg to prideout.computergraphics.net!

This is cool! I’m very interested in vector rendering techniques. What’s the current best heuristic for crease detection when doing NPR rendering?

Unfortunately I can only +1 this a single time.

Well, you can star it on github, too. :]

This is really cool. I wonder what the performance would be like for real-time transformations and animations.

I wonder if one might use an svg tween to get a continuous wiggle 3D?

This is a very nice library. It deserves to be ported to JS so it can be enjoyed in the front end too.

You have access to GPU hardware in web frontends, through WebGL. It’s faster, also more power efficient.

I was thinking that svg would get you better browser support, but it turns out it just gets you IE9/10 and Opera Mini. Which might be important for business apps, but I guess not for everyone:



I am interested at where it would be an advantage (if at all) to use SVG over OpenGL on the front end or server?

I know little about modern web development, but I think WebGL is way more efficient on clients.

Even on mobiles, GPUs have much more computing power. They have architecture designed for transforming vertices and computing lightning, very fast and highly parallel.

In best case, SVG will take input triangles and submit them to GPU. Very small overhead (slightly more GPU bandwidth because lightning, when it’s that simple, bandwidth is often more expensive than compute). But in worst case, SVGs will rasterize on CPU, very slow in comparison.

If you rasterize on the server e.g. send jpeg images to browser, it becomes complicated, and depends on many factors like scene complexity and server hardware. Rasterizing triangles is much cheaper on GPU, but JPEG compressor needs data in system RAM not in VRAM, need to download back, relatively slow. Also on many public clouds virtual GPUs are expensive.

Is it really more power-efficient? CPUs are often a smaller process node than integrated GPUs and it's much easier to share common work between pixels with CPU rendering, reducing redundant operations.

> Is it really more power-efficient?

I would expect huge difference for similar operations. Current-gen $300 GPU consumes 120W doing 4.6 TFlops. Current-gen $300 CPU consumes 65 W doing 16 flop/cycle * 3.6 GHz * 8 cores = 0.4 GFlops. GPU cores don't spend electricity minimizing latency e.g. predicting branches, and they work at much lower frequencies.

Also some parts of the pipeline are implemented in hardware (rasterizer, texture units, alpha blending, Z buffer), they don't cost flops and hardware implementation is likely even more efficient than shader cores. E.g. if you want a gradient, load/compute per-vertex colors and the rasterizer will interpolate in hardware.

I guess not!

And I need more Innovation in 3d printing space, most slicer seem to suck.

Very neat utility!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact