Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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