Done
Here the modified script
#!BPY
"""
Name: 'Moon importer'
Blender: 249
Group: 'Misc'
Tooltip: 'Import altimetric date from LALT_GGT_MAP.IMG'
"""
#Script by ValterVB
#Italian blog: http://moonmaplab.blogspot.com/
#Web site (Work in progress): https://sites.google.com/site/moonmaplab/home
import math, array, bpy, Blender, gc
from Blender import Draw, BGL
from Blender import *
############################################################
# CHANGE HERE PATH AND FILE NAME
############################################################
NomeDelFile="L:\Nasa LRO\LOLA\DEM 64\LDEM_64.IMG"
#Variables for User interface management #################
#Assign a number for every event
evtNumDaLat=1
evtNumALat=2
evtNumDaLong=3
evtNumALong=4
evtPushEsegui=5
#Set starting value for the control
#You can insert here the decimal value
numberDaLat = Draw.Create(3.0)
numberALat = Draw.Create(0.0)
numberDaLong = Draw.Create(0.0078125)
numberALong = Draw.Create(359.9921875)
#Date inside the map file. Che if you use different map
START_LONG=0.0078125 #Westernmost longitude
START_LAT=89.9921875 #Max latitude
MOON_RADIUS=1737.400 #Radius of the moon
GRID_RES=0.015625 #Grid resolution: 1/64 of degrades. Change if you use a different map
PUNTI=23040 #Point for line. Change if you use a different map
LINEE=11520 #Total number of line.
SCALING_FACTOR=0.5 #Factor to use for correct the Value. Change if you use a different map
TO_RAD=math.pi/180 #From degrees to radians
Vertici=[] #Vertex array
Facce=[] #Faces arrays
#Input: Longitude
#Output: Number of the point on row (or column)
def Punto(Long):
tmpPunto=round((Long-START_LONG)/GRID_RES+1)
if tmpPunto>PUNTI:tmpPunto=PUNTI
return tmpPunto
#Input: Latitude
#Output: Number of the line (or row)
def Linea(Lat):
tmpLinea=round((START_LAT-Lat)/GRID_RES+1)
if tmpLinea>LINEE:tmpLinea=LINEE
return tmpLinea
#Input: Line number (or row)
#Output: Latitude
def Lat(Linea):
return START_LAT-(Linea-1)*GRID_RES
#Input: Point (or column)
#Output: Longitude
def Long(Punto):
return START_LONG+(Punto-1)*GRID_RES
#Here the function that draw the moon
def DisegnaLuna(Da_Lat, A_Lat, Da_Long, A_Long):
Window.WaitCursor(1)
tmpDa_Long=Da_Long
NumeroLinee=int(Linea(A_Lat)-Linea(Da_Lat)+1) #Number of the lines to read
NumeroPunti=int(Punto(A_Long)-Punto(Da_Long)+1) #Number of the points to read
f=open(NomeDelFile,'rb') #Open the file
f.seek((Linea(Da_Lat)-1)*PUNTI*2) #Skip the first n line of point
print "Start vertex"
#Loop on the latitude
while (Da_Lat>=A_Lat):
#Loop on the longitude
DatiAltezza=f.read(PUNTI*2) #Read all the point of the line
DatiAltezza=array.array("h",DatiAltezza) #Change to Array of short
while (Da_Long<=A_Long):
Raggio=DatiAltezza[int(Punto(Da_Long))-1]/SCALING_FACTOR/1000+MOON_RADIUS
RaggioCorrente=Raggio*(math.cos(Da_Lat*TO_RAD))
X=RaggioCorrente*(math.sin(Da_Long*TO_RAD))
Y=Raggio*math.sin(Da_Lat*TO_RAD)
Z=RaggioCorrente*math.cos(Da_Long*TO_RAD)
#Assign the values to the vertex
Vertici.append((float(X),float(Y),float(Z)))
Da_Long = Da_Long+GRID_RES
Da_Long=tmpDa_Long
Da_Lat=Da_Lat-GRID_RES
DatiAltezza=[] #I hope that free the memory
#Draw the vertex
me=Mesh.New('Luna')
me.verts.extend(Vertici)
Vertici[:]=[] #I hope that free the memory
DatiAltezza=None #I hope that free thememory
gc.collect()
print "End Vertex and Start face"
#Loop for create the faces
for Linee in range(1,NumeroLinee):
for Punti in range(1, NumeroPunti):
v1=Punti+(Linee-1)*NumeroPunti
v2=v1-1
v3=v1+NumeroPunti-1
v4=v3+1
Facce.append((v1,v2,v3,v4))
#To close last column
#If you don't draw all the circumference you must comment the following 9 lines
for r in range (1,NumeroLinee):
v0=NumeroPunti*(r-1)
v1=NumeroPunti*r-1
v2=v1+NumeroPunti
v3=v1+1
Facce.append((int(v0),
int(v1),
int(v2),
int(v3)))
me.faces.extend(Facce)
print "End face And Start Drawing"
Scene.GetCurrent().objects.new(me,"Luna")
Facce[:]=[] #I hope that free memory
gc.collect() #I hope that free memory
Luna = bpy.data.objects["Luna"]
Luna.setSize(0.01,0.01,0.01) #Scaling all the moon
Luna.select("Luna")
#Resolve the problem with the normal. I don't know why
#Window.EditMode(1)
#Window.EditMode(0)
me.update
Blender.Redraw()
print "End drawing"
Window.WaitCursor(0)
#Here we draw the interface
def gui():
global numberDaLat
global numberALat
global numberDaLong
global numberALong
BGL.glRasterPos2i(10,600)
Draw.Text("Press Q or ESC to quit.")
BGL.glRasterPos2i(10,550)
Draw.Text("Select latitude and longitude of the point of interest")
#Choice of "From latitude"
numberDaLat = Draw.Number("From Latitude", evtNumDaLat, 10, 525, 200, 18, numberDaLat.val, -90, 90, "From latitude")
#Choice of "To Latitude"
numberALat = Draw.Number("To Latitude", evtNumALat, 10, 500, 200, 18, numberALat.val, -90, 90, "To Latitude")
#Choice of "From longitude"
numberDaLong = Draw.Number("From Longitude", evtNumDaLong, 10, 475, 200, 18, numberDaLong.val, 0, 360, "From Longitud")
#Choice of "To longitude"
numberALong = Draw.Number("To Longitude", evtNumALong, 10, 450, 200, 18, numberALong.val, 0, 360, "To Longitude")
#Caluclate the vertex numbers
BGL.glRasterPos2i(10,400)
NumeroVertici=(((numberDaLat.val-numberALat.val)*64)+1)*((numberALong.val-numberDaLong.val)*64+1)
Draw.Text("Number of vertex: %i" % NumeroVertici)
#Check the coordinate
if NumeroVertici<0:
BGL.glRasterPos2i(10,350)
Draw.Text("ATTENTION CHECK THE COORDINATES.")
BGL.glRasterPos2i(10,325)
Draw.Text("From Latitude must be > than To Latitude")
BGL.glRasterPos2i(10,305)
Draw.Text("From Longitude must be > than To Longitude")
#Draw the button
Draw.Button("Import", evtPushEsegui, 10, 200, 160, 18, "Import the file")
#Mouse and keyboard events
def event(evt, val):
if evt == Draw.ESCKEY or evt == Draw.QKEY:
stop = Draw.PupMenu("OK?%t|Stop the script %x1")
if stop == 1:
Draw.Exit()
return
#Control events
def buttonEvt(evt):
global DatiAltezza
if evt == evtPushEsegui:
DisegnaLuna(Lat(Linea(numberDaLat.val)),Lat(Linea(numberALat.val)),Long(Punto(numberDaLong.val)),Long(Punto(numberALong.val)))
Draw.Exit()
if evt: #Redraw the window
Draw.Redraw()
#Main entry
Draw.Register(gui, event, buttonEvt)
This version is less memory hungry and is more flexible, I read only the line that I need. It’s possible do it better, now i read all the point of the line but I can saving memory reading only the points that i need.
Now I can read also the other versions less detailed, You must change the value in these row:
GRID_RES=0.015625 #Grid resolution: 1/64 of degrades. Change it if you use a different map
PUNTI=23040 #Point for line. Change it if you use a different map
LINEE=11520 #Total number of line. Change it if you use a different map
SCALING_FACTOR=0.5 #Factor to use for correct the Value. Change it if you use a different map
For ex. for the file LDEM 16:
PUNTI=5760
LINEE=2880
GRID_RES=1/16
One trick for saving memory: disable UNDO
Lat max and min for LDEM 64 are: 89.9921875 and -89.9921875
Max is 90-(GRID_RES/2), Min is -90+(GRID_RES/2)
Now you can use decimal value for coordinate.
If you like exagerate thing, you can play with Scaling Factor
If you want do a global map don’t change the grid resolution, you may have problem with the junction of the first and last column, it’s better change dataset (less detailed), alternatively, you must render some strip, save it with RGBA and then join the strips in video editor or GIMP. This is the tecnique that I have used for the video.
Attached an example, here for a more bigger rendering(4000x4000) http://picasaweb.google.com/valtervb1/MoonMapLaboratory02#5457524837239164066
At the end, if you like MARS, here you can found the dataset of MARS (max resolution 128 px/deg). I found it yesterday, if you try with these dataset remember that you must change also the MOON_RADIUS in the script. I think that the right dataset are Map type=Topography
I can’t Try, because I must finish my Moon I must landing ![:slight_smile: :slight_smile:](https://blenderartists.org/images/emoji/twitter/slight_smile.png?v=9)
Ciao
VB
Attachments