Pages : 1
#1 Le 28/11/2011, à 18:06
- kikislater
Problème script python et numpy
Bonjour,
j'ai un script qui charge une image via python gdal dans blender. gdal est une bibliothèque de SIG (Système d'information Géographique).
Lorsque j'interroge gdal j'ai une image de 360*360pixels.
Lorsque je lance le script et que je regarde dans blender combien j'ai de faces, j'en obtiens 359 sur un côté. J'obtiens également 360vertices sur un côté.
Or pour respecter les dimensions je devrais obtenir 360 faces (et donc 361 vertices) mais ce n'est pas le cas ...
Est-ce qu'un âme charitable pourrait m'expliquer si ça vient du script (peut-être le numpy.arrange) ou si ça vient de blender.
D'avance merci
Voici le script. Il fonctionne avec la version 2.49 de Blender
#!BPY
"""
Name: 'DEM import'
Blender: 243
Group: 'Import'
Tooltip: 'Imports anything that GDAL can read including DEMs'
License: New BSD
"""
import Blender
import BPyMessages
import bpy
import datetime
from osgeo import gdal, gdalconst
import numpy
import time
from Blender import BGL, Draw, Mesh, Scene, Window, sys
from Blender.Window import DrawProgressBar
from numpy import array, hstack
#terrain_file = '/home/stou/3D/terrain/77230965/77230965.tif'
#terrain_file = '/home/stou/3D/terrain/93988521/93988521.tif'
terrain_file = 'mon.tif'
grid_sizes_labels = [['1/3 Arcsecond', 1.0/3.0],
['1/9 Arcsecond', 1.0/9.0],
['1 Arcsecond', 1.0]
]
grid_sizes = [['1/3 Arcsecond', 10.0], ['1/9 Arcsecond', 10.0]]
# 1 BU = Xm
bu_in_meters = 25.0
def load_dem(sce):
dataset = gdal.Open(terrain_file, gdalconst.GA_ReadOnly)
terrain_data = array(dataset.ReadAsArray())#xsize=100,ysize=100))
grid_size = grid_sizes[0][1]
# x_size = dataset.RasterXSize
# y_size = dataset.RasterYSize
x_size = terrain_data.shape[0]
y_size = terrain_data.shape[1]
x_scale = y_scale = grid_size/bu_in_meters
print terrain_data.shape, terrain_data.reshape(-1, 1).shape
print x_scale, y_scale
# x_scale = float(x_size)
# y_scale = float(y_size)
z_scale = 1/bu_in_meters
scale = 1
window = Mesh.New('Terrain')
verts = []
time_start = time.time()
DrawProgressBar (0.0, "Preparing verteces...")
x, y = numpy.meshgrid(range(x_size), range(y_size))
# print x,y
# return
# data_verts = hstack((x.reshape(-1, 1), y.reshape(-1, 1)[::-1], terrain_data.reshape(-1, 1)))
data_verts = hstack((y.reshape(-1, 1), x.reshape(-1, 1), terrain_data.T.reshape(-1, 1)))
data_verts = array([0, y_size, 0]) + array([1, -1, 1])*data_verts
DrawProgressBar (0.3, "Scaling data...")
verts_ar = data_verts * array([x_scale, y_scale, z_scale], dtype=float)
DrawProgressBar (0.4, "Adding verteces...")
window.verts.extend(verts_ar.tolist())
vert_count = x_size*y_size
DrawProgressBar (0.5, "Generating faces...")
idx_ar = numpy.arange((y_size-1)*(x_size))
idx_truth = (idx_ar + 1) % x_size != 0
v_idx = idx_ar[idx_truth].reshape(-1, 1)
faces = hstack((v_idx + x_size,
v_idx + x_size + 1,
v_idx + 1,
v_idx)).tolist()
DrawProgressBar (0.8, "Generating faces...")
window.faces.extend(faces)
DrawProgressBar (1.0, "Adding faces...")
# for face in window.faces:
# face.smooth = 1
print "Total Elapsed time: " + str(datetime.timedelta(seconds = (time.time() - time_start)))
window.update()
# Save the object to the scene
sce.objects.new(window, 'myTerrain')
Blender.Redraw()
def main():
# Gets the current scene, there can be many scenes in 1 blend file.
sce = bpy.data.scenes.active
# Get the active object, there can only ever be 1
# and the active object is always the editmode object.
# ob_act = sce.objects.active
Window.WaitCursor(1)
# me = ob_act.getData(mesh=1) # old NMesh api is default
t = sys.time()
# Run the mesh editing function
load_dem(sce)
# main_gui = GeoToolsUI()
# Timing the script is a good way to be aware on any speed hits when scripting
print 'My Script finished in %.2f seconds' % (sys.time()-t)
Window.WaitCursor(0)
#mystring = ""
#mymsg = ""
#toggle = 0
class GeoToolsUI(object):
def __init__(self):
self.mystring = ''
self.mymsg = ''
self.toggle = 0
Draw.Register(self.gui, self.event, self.button_event)
def button_event(self, evt): # the function to handle Draw Button events
if evt == 1:
self.mymsg = "You pressed the toggle button."
self.toggle = 1 - self.toggle
Draw.Redraw(1)
def event(self, evt, val): # the function to handle input events
if not val: # val = 0: it's a key/mbutton release
if evt in [Draw.LEFTMOUSE, Draw.MIDDLEMOUSE, Draw.RIGHTMOUSE]:
self.mymsg = "You released a mouse button."
Draw.Redraw(1)
return
if evt == Draw.ESCKEY:
Draw.Exit() # exit when user presses ESC
return
elif Draw.AKEY <= evt <= Draw.ZKEY: self.mystring += chr(evt)
elif evt == Draw.SPACEKEY: self.mystring += ' '
elif evt == Draw.BACKSPACEKEY and len(self.mystring):
self.mystring = mystring[:-1]
else: return # no need to redraw if nothing changed
Draw.Redraw(1)
def gui(self): # the function to draw the screen
if len(self.mystring) > 90: self.mystring = ""
BGL.glClearColor(0, 0, 1, 1)
BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
BGL.glColor3f(1, 1, 1)
Draw.Toggle("Toggle", 1, 10, 10, 55, 20, self.toggle, "A toggle button")
BGL.glRasterPos2i(72, 16)
if self.toggle: toggle_state = "down"
else: toggle_state = "up"
Draw.Text("The toggle button is %s." % toggle_state, "small")
BGL.glRasterPos2i(10, 230)
Draw.Text("Type letters from a to z, ESC to leave.")
BGL.glRasterPos2i(20, 200)
Draw.Text(self.mystring)
BGL.glColor3f(1, 0.4, 0.3)
BGL.glRasterPos2i(340, 70)
Draw.Text(self.mymsg, "tiny")
# This lets you can import the script without running it
if __name__ == '__main__':
main()
Dernière modification par kikislater (Le 28/11/2011, à 18:07)
Hors ligne
#2 Le 28/11/2011, à 18:38
- kikislater
Re : Problème script python et numpy
Je penses avoir ma réponse :
Dans gdal l'élévation est définie par le pixel
Dans blender dans ce script on l'attribue aux vertices !
Donc j'ai ma solution, il faudrait que j'ouvre un fichiers de points avec ogr et le traiter dans numpy ... C'est pas gagné !
Hors ligne