Getting base height from z values
Hi @dougmccune
Thanks for the great library. I was wondering about submitting a pull request with some additional functionality so I thought I'd get some feedback.
I have a buildings dataset which contains
- z values in the spatial data for the ground elevation of a building,
- an attribute for the height of the building
Using shp2stl currently I can use the attribute for the height using the extrudeBy option which works great. However there is nothing that allows me to utilise the z value for ground elevation. So I was wondering if we could introduce a new option called getBaseHeightFromZ. The other option might be to only support a single base height per building which could be derived from an attributed similar to how extrudeBy works.
I've looked upstream and there are a few tweaks that would be required in the shapefile library to support getting z vales into geojson. The topojson conversion part works ok in retaining z values.
Are that any pitfalls that you could see in such an approach? I'm happy to submit a pull request if you're interested.
Regards, Rowan
Just want to make sure I understand the intent. Are you trying to have the bottom of the model have different heights and not all be at z=0? Any chance you can post a small sample shapefile or geojson?
The only big issue I see is that the library tries to simplify the bottom of the model by unionining all the bottom shapes. The only goal of that is to reduce the complexity of the STL model. I assume we could just ensure that we skip that part if we're extruding the base by an attribute.
Another issue I could see is that you could certainly produce non watertight STLs, and maybe even ones that don't look like what you intend, if your shapes share adjoining boundaries. The way shp2stl works is that it uses topojson to combine all the 2D polys into their topojson representation (which figures out all the shared boundaries between shapes). That allows the top of the model to be one continuous mesh, if all the shapes are contiguous. So if you imagine two buildings that share a border, that gets turned into a single mesh, not two distinct meshes (great for 3D printing). But if you now imagine you have those two buildings (call them Building A and Building B) and A has a base elev of 0 and a top elev of 10, and then you have B with a base elev of 20 and a top elev of 30. Shp2stl is going to try to make the entire top of the model connected together, and the entire bottom also connected together, and you'd end up with a weird wall connecting your two buildings together (when in reality you want them split into two separate meshes). This is hard to describe without drawing a picture :) It may be a case though where we just let it do its thing and produce funky meshes in the edge case where you have adjoining polygons that don't actually overlap in z-space.
Also, as you mentioned, I'd think the way to implement it would be to copy the way extrudeBy works and add something like extrudeBaseBy, which could either be a string for an attribute or a function to allow you to do your own calculation. The main changes would end up being in topojson2threejs.js in the topojson2threeJSBottomPlanes method.
Thanks for the feedback @dougmccune , the whole mesh and 3D printing space is new to me so I'm playing catchup a bit. Your understanding of the request is spot on.
I had thought it might produce some slightly quirky results where you had adjacent buildings with different base elevations, although as you suggest, perhaps that's up to the consumer to either pass in decent data, or apply manual fixes afterwards...
~~PS On something unrelated I wonder if some of the code within topojson2threejs.js could be simplified with the use the BoxGeometries in ThreeJS, from what I can tell they were added to threejs after this library was written...~~ scrap that obviously shapes that you'd like to extrude are likely to be more than boxes!
Anyway I'll take a poke around the codebase and see if I can get something working...