Added some polish
This commit is contained in:
parent
5d3676ee43
commit
9e9de119f8
51
__init__.py
51
__init__.py
|
|
@ -1,7 +1,52 @@
|
|||
from . import create_mesh_from_geotiff
|
||||
import bpy
|
||||
from bpy.props import FloatProperty, FloatVectorProperty, IntProperty, StringProperty
|
||||
from .create_mesh_from_geotiff import OBJECT_OT_create_mesh_from_geotiff
|
||||
from .import_geotiff_panel import OBJECT_PT_import_geotiff
|
||||
from .select_geotiff_file import OBJECT_OT_select_geotiff_file
|
||||
|
||||
def init_scene_vars():
|
||||
bpy.types.Scene.mapping_extension_geotiff_filename = StringProperty(
|
||||
name="Geotiff filename",
|
||||
description="Input GeoTIFF",
|
||||
maxlen=1024, # Max length of the string.
|
||||
options={'SKIP_SAVE'})
|
||||
bpy.types.Scene.mapping_extension_map_origin = FloatVectorProperty(
|
||||
name="Map origin",
|
||||
description="The map coordinate that should map to the blender origin",
|
||||
default=(0.0,0.0),
|
||||
size=2,
|
||||
options={'SKIP_SAVE'})
|
||||
bpy.types.Scene.mapping_extension_map_scale = IntProperty(
|
||||
name="Map Scale",
|
||||
description="Denominator or map scale. E.g. for a 1:10,000 scale, set this to 10000",
|
||||
default=10000,
|
||||
min=1,
|
||||
soft_max=1000000,
|
||||
options={'SKIP_SAVE'})
|
||||
bpy.types.Scene.mapping_extension_vertical_exaggeration = FloatProperty(
|
||||
name="Map vertical exaggeration",
|
||||
description="Scale applied to heights, on to of the map scale",
|
||||
default=6.0,
|
||||
min = 0.0,
|
||||
soft_min = 1.0,
|
||||
max = 1000000.0,
|
||||
soft_max = 20.0,
|
||||
options={'SKIP_SAVE'})
|
||||
|
||||
|
||||
|
||||
def del_scene_vars():
|
||||
del bpy.types.Scene.mapping_extension_geotiff_filename
|
||||
|
||||
|
||||
def register():
|
||||
create_mesh_from_geotiff.register()
|
||||
init_scene_vars()
|
||||
bpy.utils.register_class(OBJECT_PT_import_geotiff)
|
||||
bpy.utils.register_class(OBJECT_OT_create_mesh_from_geotiff)
|
||||
bpy.utils.register_class(OBJECT_OT_select_geotiff_file)
|
||||
|
||||
def unregister():
|
||||
create_mesh_from_geotiff.unregister()
|
||||
del_scene_vars()
|
||||
bpy.utils.unregister_class(OBJECT_PT_import_geotiff)
|
||||
bpy.utils.unregister_class(OBJECT_OT_create_mesh_from_geotiff)
|
||||
bpy.utils.unregister_class(OBJECT_OT_select_geotiff_file)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from bpy_extras.io_utils import ImportHelper
|
|||
import rasterio
|
||||
|
||||
class GridVertexGenerator():
|
||||
def __init__(self, grid_size_x, grid_size_y, cell_size_x, cell_size_y, dem_array):
|
||||
def __init__(self, *, grid_size_x, grid_size_y, cell_size_x, cell_size_y, dem_array, map_scale, vertical_exaggeration):
|
||||
self.cell_size_x = cell_size_x
|
||||
if cell_size_y is not None:
|
||||
self.cell_size_y = cell_size_y
|
||||
|
|
@ -13,6 +13,8 @@ class GridVertexGenerator():
|
|||
self.grid_size_x = grid_size_x
|
||||
self.grid_size_y = grid_size_y
|
||||
self.dem_array = dem_array
|
||||
self.map_scale = map_scale
|
||||
self.vertical_exaggeration = vertical_exaggeration
|
||||
|
||||
def __len__(self):
|
||||
return self.grid_size_x * self.grid_size_y
|
||||
|
|
@ -23,17 +25,12 @@ class GridVertexGenerator():
|
|||
def _generator(self):
|
||||
for j in range(self.grid_size_y):
|
||||
for i in range(self.grid_size_x):
|
||||
yield (i * self.cell_size_x,
|
||||
j * self.cell_size_y,
|
||||
self.dem_array[j][i])
|
||||
yield (i * self.cell_size_x * self.map_scale,
|
||||
j * self.cell_size_y * self.map_scale,
|
||||
self.dem_array[j][i] * self.map_scale * self.vertical_exaggeration)
|
||||
|
||||
class GridTriangleGenerator():
|
||||
def __init__(self, grid_size_x, grid_size_y, cell_size_x, cell_size_y=None):
|
||||
self.cell_size_x = cell_size_x
|
||||
if cell_size_y is not None:
|
||||
self.cell_size_y = cell_size_y
|
||||
else:
|
||||
self.cell_size_y = cell_size_x
|
||||
class GridQuadGenerator():
|
||||
def __init__(self, grid_size_x, grid_size_y):
|
||||
self.grid_size_x = grid_size_x
|
||||
self.grid_size_y = grid_size_y
|
||||
|
||||
|
|
@ -53,15 +50,21 @@ class GridTriangleGenerator():
|
|||
yield (v00, v10, v11, v01)
|
||||
|
||||
|
||||
class CreateMeshFromGeotiffOperator(bpy.types.Operator, ImportHelper):
|
||||
class OBJECT_OT_create_mesh_from_geotiff(bpy.types.Operator):
|
||||
"""Create a new object from a GeoTIFF"""
|
||||
bl_idname = "object.create_mesh_from_geotiff"
|
||||
bl_label = "Mesh from GeoTIFF"
|
||||
|
||||
filter_glob = StringProperty(default="*.tif;*.tiff", options={"HIDDEN"})
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.mapping_extension_geotiff_filename
|
||||
|
||||
def execute(self, context):
|
||||
with rasterio.open(self.properties.filepath) as geotiff:
|
||||
map_origin = context.scene.mapping_extension_map_origin
|
||||
map_scale = 1.0 / context.scene.mapping_extension_map_scale
|
||||
vertical_exaggeration = context.scene.mapping_extension_vertical_exaggeration
|
||||
filename = context.scene.mapping_extension_geotiff_filename
|
||||
with rasterio.open(filename) as geotiff:
|
||||
grid_size_x = geotiff.width
|
||||
grid_size_y = geotiff.height
|
||||
print(f"GeoTIFF is {grid_size_x}x{grid_size_y}")
|
||||
|
|
@ -80,29 +83,30 @@ class CreateMeshFromGeotiffOperator(bpy.types.Operator, ImportHelper):
|
|||
collection.objects.link(dem_obj)
|
||||
context.view_layer.objects.active = dem_obj
|
||||
print("Creating mesh data...")
|
||||
(vertices, edges, faces) = self.construct_mesh(grid_size_x, grid_size_y, cell_size_x, cell_size_y, dem_array)
|
||||
(vertices, edges, faces) = self.construct_mesh(grid_size_x=grid_size_x,
|
||||
grid_size_y=grid_size_y,
|
||||
cell_size_x=cell_size_x,
|
||||
cell_size_y=cell_size_y,
|
||||
dem_array=dem_array,
|
||||
map_scale=map_scale,
|
||||
vertical_exaggeration=vertical_exaggeration)
|
||||
print("Constructing mesh...")
|
||||
mesh.from_pydata(vertices, edges, faces, shade_flat=False)
|
||||
print("Done.")
|
||||
mesh.validate(verbose=True)
|
||||
return {'FINISHED'}
|
||||
|
||||
def construct_mesh(self, grid_size_x, grid_size_y, cell_size_x, cell_size_y, dem_array):
|
||||
return (GridVertexGenerator(grid_size_x, grid_size_y, cell_size_x, cell_size_y, dem_array),
|
||||
def construct_mesh(self, *, grid_size_x, grid_size_y, cell_size_x, cell_size_y, dem_array, map_scale, vertical_exaggeration):
|
||||
return (GridVertexGenerator(grid_size_x=grid_size_x,
|
||||
grid_size_y=grid_size_y,
|
||||
cell_size_x=cell_size_x,
|
||||
cell_size_y=cell_size_y,
|
||||
dem_array=dem_array,
|
||||
map_scale=map_scale,
|
||||
vertical_exaggeration=vertical_exaggeration),
|
||||
[],
|
||||
GridTriangleGenerator(grid_size_x, grid_size_y, cell_size_x, cell_size_y))
|
||||
GridQuadGenerator(grid_size_x, grid_size_y))
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(CreateMeshFromGeotiffOperator.bl_idname,
|
||||
text=CreateMeshFromGeotiffOperator.bl_label)
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(CreateMeshFromGeotiffOperator)
|
||||
bpy.types.VIEW3D_MT_add.append(menu_func)
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(CreateMeshFromGeotiffOperator)
|
||||
bpy.types.VIEW3D_MT_add.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import bpy
|
||||
from bpy.props import StringProperty
|
||||
|
||||
from .create_mesh_from_geotiff import OBJECT_OT_create_mesh_from_geotiff
|
||||
from .select_geotiff_file import OBJECT_OT_select_geotiff_file
|
||||
|
||||
class OBJECT_PT_import_geotiff(bpy.types.Panel):
|
||||
"""Import GeoTIFF"""
|
||||
bl_idname="IMPORT_GEOTIFF_PT_layout"
|
||||
bl_label = "Import GeoTIFF"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "Mapping"
|
||||
|
||||
def draw(self, context):
|
||||
column = self.layout.column()
|
||||
geotiff_filename_row = column.row()
|
||||
geotiff_filename_row.prop(context.scene, "mapping_extension_geotiff_filename")
|
||||
geotiff_filename_row.operator(OBJECT_OT_select_geotiff_file.bl_idname,
|
||||
icon='FILEBROWSER',
|
||||
text='')
|
||||
#column.prop(context.scene, "mapping_extension_map_origin")
|
||||
column.prop(context.scene, "mapping_extension_map_scale")
|
||||
column.prop(context.scene, "mapping_extension_vertical_exaggeration")
|
||||
column.operator(OBJECT_OT_create_mesh_from_geotiff.bl_idname)
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import bpy
|
||||
from bpy.props import StringProperty
|
||||
from bpy_extras.io_utils import ImportHelper
|
||||
|
||||
class OBJECT_OT_select_geotiff_file(bpy.types.Operator, ImportHelper):
|
||||
"""Display dialog to a GeoTIFF file for Mapping Tools to use."""
|
||||
bl_idname = "object.select_geotiff_file"
|
||||
bl_label = "Select GeoTIFF file"
|
||||
|
||||
filter_glob: StringProperty(default="*.tif;*.tiff", options={"HIDDEN"})
|
||||
filepath: StringProperty(subtype="FILE_PATH")
|
||||
|
||||
def execute(self, context):
|
||||
context.scene.mapping_extension_geotiff_filename=self.properties.filepath
|
||||
return {'FINISHED'}
|
||||
Loading…
Reference in New Issue