Fix for recent API changes (register and unregister. Again thanks to filiciss
[blender-addons-contrib.git] / io_import_LRO_Lola_MGS_Mola_img.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 bl_info = {
20     "name": "LRO Lola & MGS Mola img Importer",
21     "author": "ValterVB",
22     "version": (1, 1, 5),
23     "blender": (2, 5, 6),
24     "api": 35196,
25     "location": "3D window > Tool Shelf",
26     "description": "Import DTM from LRO Lola and MGS Mola",
27     "warning": "May consume a lot of memory",
28     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
29         "Scripts/Import-Export/NASA_IMG_Importer",
30     "tracker_url": "http://projects.blender.org/tracker/index.php?"\
31         "func=detail&aid=25462",
32     "category": "Import-Export"}
33
34
35 #***********************************************************************
36 #ver. 0.0.1: -First version
37 #ver. 0.0.2: -Add check on path and file
38 #            -Check on selected coordinates more complete
39 #ver. 1.1.0: -Optimized for less memory
40 #ver. 1.1.1: -Correct bug for real value of the High (bad error).
41 #             now it's less artistic, bat more real Always possible use
42 #             the old formula. check Magnify (x4)
43 #            -Correct the bug for directory with dot in the name
44 #            -Add some warning and more information
45 #            -Add slider for the scale and info on it
46 #ver. 1.1.2: -Word correction
47 #            -Correct the problem for Unix (Upper lower case)
48 #              If the Ext of the file selected from user is upper
49 #              than the second file is Upper and Viceversa.
50 #              (I can't verify because i have Win)
51 #ver. 1.1.3: -Little fix for previous fix on upper/lower case
52 #ver. 1.1.4: -Fix for recent API changes. Thanks to Filiciss.
53 #            -Some code cleaning (PEP8)
54 #ver. 1.1.5: -Fix for recent API changes. Thanks to Filiciss.
55 #************************************************************************
56
57 import bpy
58 import os.path
59 import math
60 import array
61 import mathutils
62 from mathutils import *
63
64 TO_RAD = math.pi / 180  # From degrees to radians
65
66 # turning off relative path - it causes an error if it was true
67 if bpy.context.user_preferences.filepaths.use_relative_paths == True:
68     bpy.context.user_preferences.filepaths.use_relative_paths = False
69
70
71 # A very simple "bridge" tool.
72 # Connects two equally long vertex rows with faces.
73 # Returns a list of the new faces (list of  lists)
74 #
75 # vertIdx1 ... First vertex list (list of vertex indices).
76 # vertIdx2 ... Second vertex list (list of vertex indices).
77 # closed ... Creates a loop (first & last are closed).
78 # flipped ... Invert the normal of the face(s).
79 #
80 # Note: You can set vertIdx1 to a single vertex index to create a fan/star
81 #       of faces.
82 # Note: If both vertex idx list are the same length they have to have at
83 #       least 2 vertices.
84 def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
85     faces = []
86
87     if not vertIdx1 or not vertIdx2:
88         return None
89
90     if len(vertIdx1) < 2 and len(vertIdx2) < 2:
91         return None
92
93     fan = False
94     if (len(vertIdx1) != len(vertIdx2)):
95         if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
96             fan = True
97         else:
98             return None
99
100     total = len(vertIdx2)
101
102     if closed:
103         # Bridge the start with the end.
104         if flipped:
105             face = [
106                 vertIdx1[0],
107                 vertIdx2[0],
108                 vertIdx2[total - 1]]
109             if not fan:
110                 face.append(vertIdx1[total - 1])
111             faces.append(face)
112
113         else:
114             face = [vertIdx2[0], vertIdx1[0]]
115             if not fan:
116                 face.append(vertIdx1[total - 1])
117             face.append(vertIdx2[total - 1])
118             faces.append(face)
119
120     # Bridge the rest of the faces.
121     for num in range(total - 1):
122         if flipped:
123             if fan:
124                 face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
125             else:
126                 face = [vertIdx2[num], vertIdx1[num],
127                     vertIdx1[num + 1], vertIdx2[num + 1]]
128             faces.append(face)
129         else:
130             if fan:
131                 face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
132             else:
133                 face = [vertIdx1[num], vertIdx2[num],
134                     vertIdx2[num + 1], vertIdx1[num + 1]]
135             faces.append(face)
136     return faces
137
138
139 #Utility Function ********************************************************
140 #
141 #Input: Latitude Output: Number of the line (1 to n)
142 def LatToLine(Latitude):
143     tmpLines = round((MAXIMUM_LATITUDE - Latitude) * MAP_RESOLUTION + 1.0)
144     if tmpLines > LINES:
145         tmpLines = LINES
146     return tmpLines
147
148
149 #Input: Number of the line (1 to n) Output: Latitude
150 def LineToLat(Line):
151     if MAP_RESOLUTION == 0:
152         return 0
153     else:
154         return float(MAXIMUM_LATITUDE - (Line - 1) / MAP_RESOLUTION)
155
156
157 #Input: Longitude Output: Number of the point (1 to n)
158 def LongToPoint(Longitude):
159     tmpPoints = round((Longitude - WESTERNMOST_LONGITUDE) *
160                        MAP_RESOLUTION + 1.0)
161     if tmpPoints > LINE_SAMPLES:
162         tmpPoints = LINE_SAMPLES
163     return tmpPoints
164
165
166 #Input: Number of the Point (1 to n) Output: Longitude
167 def PointToLong(Point):
168     if MAP_RESOLUTION == 0:
169         return 0
170     else:
171         return float(WESTERNMOST_LONGITUDE + (Point - 1) / MAP_RESOLUTION)
172
173
174 #Input: Latitude Output: Neareast real Latitude on grid
175 def RealLat(Latitude):
176     return float(LineToLat(LatToLine(Latitude)))
177
178
179 #Input: Longitude Output: Neareast real Longitude on grid
180 def RealLong(Longitude):
181     return float(PointToLong(LongToPoint(Longitude)))
182 #**************************************************************************
183
184
185 #Read the LBL file
186 def ReadLabel(FileName):
187     global FileAndPath
188     global LINES, LINE_SAMPLES, SAMPLE_TYPE, SAMPLE_BITS, UNIT, MAP_RESOLUTION
189     global MAXIMUM_LATITUDE, MINIMUM_LATITUDE, WESTERNMOST_LONGITUDE
190     global EASTERNMOST_LONGITUDE, SCALING_FACTOR, OFFSET, RadiusUM, TARGET_NAME
191     global Message
192
193     if FileName == '':
194         LINES = LINE_SAMPLES = SAMPLE_BITS = MAP_RESOLUTION = 0
195         MAXIMUM_LATITUDE = MINIMUM_LATITUDE = 0.0
196         WESTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE = 0.0
197         OFFSET = SCALING_FACTOR = 0.0
198         SAMPLE_TYPE = UNIT = TARGET_NAME = RadiusUM = Message = ""
199         return
200
201     FileAndPath = FileName
202     FileAndExt = os.path.splitext(FileAndPath)
203     try:
204         #Check for UNIX that is case sensitive
205         #If the Ext of the file selected from user is Upper, than the second
206         #file is Upper and Viceversa
207         if FileAndExt[1].isupper():
208             f = open(FileAndExt[0] + ".LBL", 'r')  # Open the label file
209         else:
210             f = open(FileAndExt[0] + ".lbl", 'r')  # Open the label file
211         Message = ""
212     except:
213         Message = "FILE LBL NOT AVAILABLE OR YOU HAVEN'T SELECTED A FILE"
214         return
215
216     block = ""
217     OFFSET = 0
218     for line in f:
219         tmp = line.split("=")
220         if tmp[0].strip() == "OBJECT" and tmp[1].strip() == "IMAGE":
221             block = "IMAGE"
222         elif tmp[0].strip() == "OBJECT" and tmp[1].strip() == "IMAGE_MAP_PROJECTION":
223             block = "IMAGE_MAP_PROJECTION"
224         elif tmp[0].strip() == "END_OBJECT" and tmp[1].strip() == "IMAGE":
225             block = ""
226         elif tmp[0].strip() == "END_OBJECT" and tmp[1].strip() == "IMAGE_MAP_PROJECTION":
227             block = ""
228         elif tmp[0].strip() == "TARGET_NAME":
229             block = ""
230             TARGET_NAME = tmp[1].strip()
231         if block == "IMAGE":
232             if line.find("LINES") != -1 and not(line.startswith("/*")):
233                 tmp = line.split("=")
234                 LINES = int(tmp[1].strip())
235             elif line.find("LINE_SAMPLES") != -1 and not(line.startswith("/*")):
236                 tmp = line.split("=")
237                 LINE_SAMPLES = int(tmp[1].strip())
238             elif line.find("UNIT") != -1 and not(line.startswith("/*")):
239                 tmp = line.split("=")
240                 UNIT = tmp[1].strip()
241             elif line.find("SAMPLE_TYPE") != -1 and not(line.startswith("/*")):
242                 tmp = line.split("=")
243                 SAMPLE_TYPE = tmp[1].strip()
244             elif line.find("SAMPLE_BITS") != -1 and not(line.startswith("/*")):
245                 tmp = line.split("=")
246                 SAMPLE_BITS = int(tmp[1].strip())
247             elif line.find("SCALING_FACTOR") != -1 and not(line.startswith("/*")):
248                 tmp = line.split("=")
249                 tmp = tmp[1].split("<")
250                 SCALING_FACTOR = float(tmp[0].replace(" ", ""))
251             elif line.find("OFFSET") != -1 and not(line.startswith("/*")):
252                 tmp = line.split("=")
253                 if tmp[0].find("OFFSET") != -1 and len(tmp) > 1:
254                     tmp = tmp[1].split("<")
255                     tmp[0] = tmp[0].replace(".", "")
256                     OFFSET = float(tmp[0].replace(" ", ""))
257         elif block == "IMAGE_MAP_PROJECTION":
258             if line.find("A_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
259                 tmp = line.split("=")
260                 tmp = tmp[1].split("<")
261                 A_AXIS_RADIUS = float(tmp[0].replace(" ", ""))
262                 RadiusUM = tmp[1].rstrip().replace(">", "")
263             elif line.find("B_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
264                 tmp = line.split("=")
265                 tmp = tmp[1].split("<")
266                 B_AXIS_RADIUS = float(tmp[0].replace(" ", ""))
267             elif line.find("C_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
268                 tmp = line.split("=")
269                 tmp = tmp[1].split("<")
270                 C_AXIS_RADIUS = float(tmp[0].replace(" ", ""))
271             elif line.find("MAXIMUM_LATITUDE") != -1 and not(line.startswith("/*")):
272                 tmp = line.split("=")
273                 tmp = tmp[1].split("<")
274                 MAXIMUM_LATITUDE = float(tmp[0].replace(" ", ""))
275             elif line.find("MINIMUM_LATITUDE") != -1 and not(line.startswith("/*")):
276                 tmp = line.split("=")
277                 tmp = tmp[1].split("<")
278                 MINIMUM_LATITUDE = float(tmp[0].replace(" ", ""))
279             elif line.find("WESTERNMOST_LONGITUDE") != -1 and not(line.startswith("/*")):
280                 tmp = line.split("=")
281                 tmp = tmp[1].split("<")
282                 WESTERNMOST_LONGITUDE = float(tmp[0].replace(" ", ""))
283             elif line.find("EASTERNMOST_LONGITUDE") != -1 and not(line.startswith("/*")):
284                 tmp = line.split("=")
285                 tmp = tmp[1].split("<")
286                 EASTERNMOST_LONGITUDE = float(tmp[0].replace(" ", ""))
287             elif line.find("MAP_RESOLUTION") != -1 and not(line.startswith("/*")):
288                 tmp = line.split("=")
289                 tmp = tmp[1].split("<")
290                 MAP_RESOLUTION = float(tmp[0].replace(" ", ""))
291     f.close
292     MAXIMUM_LATITUDE = MAXIMUM_LATITUDE - 1 / MAP_RESOLUTION / 2
293     MINIMUM_LATITUDE = MINIMUM_LATITUDE + 1 / MAP_RESOLUTION / 2
294     WESTERNMOST_LONGITUDE = WESTERNMOST_LONGITUDE + 1 / MAP_RESOLUTION / 2
295     EASTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE - 1 / MAP_RESOLUTION / 2
296     if OFFSET == 0:  # When OFFSET isn't available I use the medium of the radius
297         OFFSET = (A_AXIS_RADIUS + B_AXIS_RADIUS + C_AXIS_RADIUS) / 3
298     else:
299         OFFSET = OFFSET / 1000  # Convert m to Km
300     if SCALING_FACTOR == 0:
301         SCALING_FACTOR = 1.0  # When isn'tavailable I set it to 1
302
303
304 def MakeMaterialMars(obj):
305     #Copied from io_convert_image_to_mesh_img
306     mat = bpy.data.materials.new("Mars")
307     mat.diffuse_shader = 'MINNAERT'
308     mat.diffuse_color = (0.426, 0.213, 0.136)
309     mat.darkness = 0.8
310
311     mat.specular_shader = 'WARDISO'
312     mat.specular_color = (1.000, 0.242, 0.010)
313     mat.specular_intensity = 0.010
314     mat.specular_slope = 0.100
315     obj.data.materials.append(mat)
316
317
318 def MakeMaterialMoon(obj):
319     #Same as Mars Material, but i have canged the color
320     mat = bpy.data.materials.new("Moon")
321     mat.diffuse_shader = 'MINNAERT'
322     mat.diffuse_color = (0.426, 0.426, 0.426)
323     mat.darkness = 0.8
324
325     mat.specular_shader = 'WARDISO'
326     mat.specular_color = (0.6, 0.6, 0.6)
327     mat.specular_intensity = 0.010
328     mat.specular_slope = 0.100
329     obj.data.materials.append(mat)
330
331
332 def clear_properties():
333     # can happen on reload
334     if bpy.context.scene is None:
335         return
336
337     LINES = LINE_SAMPLES = SAMPLE_BITS = MAP_RESOLUTION = 0
338     MAXIMUM_LATITUDE = MINIMUM_LATITUDE = 0.0
339     WESTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE = 0.0
340     OFFSET = SCALING_FACTOR = 0.0
341     SAMPLE_TYPE = UNIT = TARGET_NAME = RadiusUM = Message = ""
342
343     props = ["FromLat", "ToLat", "FromLong", "ToLong", "Scale"]
344     for p in props:
345         if p in bpy.types.Scene.bl_rna.properties:
346             exec("del bpy.types.Scene." + p)
347         if p in bpy.context.scene:
348             del bpy.context.scene[p]
349
350
351 #Import the data and draw the planet
352 class Import(bpy.types.Operator):
353     bl_idname = 'import.lro_and_mgs'
354     bl_label = 'Start Import'
355     bl_description = 'Import the data'
356
357     def execute(self, context):
358         From_Lat = RealLat(bpy.context.scene['FromLat'])
359         To_Lat = RealLat(bpy.context.scene['ToLat'])
360         From_Long = RealLong(bpy.context.scene['FromLong'])
361         To_Long = RealLong(bpy.context.scene['ToLong'])
362         BlenderScale = bpy.context.scene['Scale']
363         Exag = bpy.context.scene['Exaggerate']
364         Vertex = []  # Vertex array
365         Faces = []  # Faces arrays
366         FirstRow = []
367         SecondRow = []
368         print('*** Start create vertex ***')
369         FileAndPath = bpy.context.scene['fpath']
370         FileAndExt = os.path.splitext(FileAndPath)
371         #Check for UNIX that is case sensitive
372         #If the Ext of the file selected from user is Upper, than the second file is Upper and Viceversa
373         if FileAndExt[1].isupper():
374             FileName = FileAndExt[0] + ".IMG"
375         else:
376             FileName = FileAndExt[0] + ".img"
377         f = open(FileName, 'rb')
378         f.seek(int((int(LatToLine(From_Lat)) - 1) * (LINE_SAMPLES * (SAMPLE_BITS / 8))), 1)  # Skip the first n line of point
379         SkipFirstPoint = int((LongToPoint(From_Long) - 1) * (SAMPLE_BITS / 8))  # Nunmber of points to skip
380         PointsToRead = (LongToPoint(To_Long) - LongToPoint(From_Long) + 1) * (int(SAMPLE_BITS) / 8)  # Number of points to be read
381         SkipLastPoint = (LINE_SAMPLES * (SAMPLE_BITS / 8)) - PointsToRead - SkipFirstPoint  # Nunmber of points to skip
382         LatToRead = From_Lat
383         while (LatToRead >= To_Lat):
384             f.seek(SkipFirstPoint, 1)  # Skip the first n point
385             Altitudes = f.read(int(PointsToRead))  # Read all the point
386             Altitudes = array.array("h", Altitudes)  # Change to Array of signed short
387             if SAMPLE_TYPE == "MSB_INTEGER":
388                 Altitudes.byteswap()  # Change from MSB (big endian) to LSB (little endian)
389             LongToRead = From_Long
390             PointToRead = 0
391             while (LongToRead <= To_Long):
392                 if Exag:
393                     tmpRadius = (Altitudes[PointToRead] / SCALING_FACTOR / 1000 + OFFSET) / BlenderScale  # Old formula (High*4)
394                 else:
395                     tmpRadius = ((Altitudes[PointToRead] * SCALING_FACTOR) / 1000 + OFFSET) / BlenderScale  # Correct scale
396                 CurrentRadius = tmpRadius * (math.cos(LatToRead * TO_RAD))
397                 X = CurrentRadius * (math.sin(LongToRead * TO_RAD))
398                 Y = tmpRadius * math.sin(LatToRead * TO_RAD)
399                 Z = CurrentRadius * math.cos(LongToRead * TO_RAD)
400                 Vertex.append(Vector((float(X), float(Y), float(Z))))
401                 LongToRead += (1 / MAP_RESOLUTION)
402                 PointToRead += 1
403             f.seek(int(SkipLastPoint), 1)
404             LatToRead -= (1 / MAP_RESOLUTION)
405         f.close
406         del Altitudes
407         print('*** End create Vertex   ***')
408
409         print('*** Start create faces ***')
410         LinesToRead = int(LatToLine(To_Lat) - LatToLine(From_Lat) + 1)   # Number of the lines to read
411         PointsToRead = int(LongToPoint(To_Long) - LongToPoint(From_Long) + 1)  # Number of the points to read
412         for Point in range(0, PointsToRead):
413             FirstRow.append(Point)
414             SecondRow.append(Point + PointsToRead)
415         if int(PointsToRead) == LINE_SAMPLES:
416             FaceTemp = createFaces(FirstRow, SecondRow, closed=True, flipped=True)
417         else:
418             FaceTemp = createFaces(FirstRow, SecondRow, closed=False, flipped=True)
419         Faces.extend(FaceTemp)
420
421         FaceTemp = []
422         for Line in range(1, (LinesToRead - 1)):
423             FirstRow = SecondRow
424             SecondRow = []
425             FacesTemp = []
426             for Point in range(0, PointsToRead):
427                 SecondRow.append(Point + (Line + 1) * PointsToRead)
428             if int(PointsToRead) == LINE_SAMPLES:
429                 FaceTemp = createFaces(FirstRow, SecondRow, closed=True, flipped=True)
430             else:
431                 FaceTemp = createFaces(FirstRow, SecondRow, closed=False, flipped=True)
432             Faces.extend(FaceTemp)
433         del FaceTemp
434         print('*** End create faces   ***')
435
436         print ('*** Start draw ***')
437         mesh = bpy.data.meshes.new(TARGET_NAME)
438         mesh.from_pydata(Vertex, [], Faces)
439         del Faces
440         del Vertex
441         mesh.update()
442         ob_new = bpy.data.objects.new(TARGET_NAME, mesh)
443         ob_new.data = mesh
444         scene = bpy.context.scene
445         scene.objects.link(ob_new)
446         scene.objects.active = ob_new
447         ob_new.select = True
448         print ('*** End draw   ***')
449         print('*** Start Smooth ***')
450         bpy.ops.object.shade_smooth()
451         print('*** End Smooth   ***')
452         if TARGET_NAME == "MOON":
453             MakeMaterialMoon(ob_new)
454         elif TARGET_NAME == "MARS":
455             MakeMaterialMars(ob_new)
456         print('*** FINISHED ***')
457         return {'FINISHED'}
458
459
460 # drawing the user interface
461 class Img_Importer(bpy.types.Panel):
462     bl_space_type = "VIEW_3D"
463     bl_region_type = "TOOL_PROPS"
464     bl_label = "LRO Lola & MGS Mola IMG Importer"
465
466     def __init__(self):
467         LINES = LINE_SAMPLES = SAMPLE_BITS = MAP_RESOLUTION = 0
468         MAXIMUM_LATITUDE = MINIMUM_LATITUDE = 0.0
469         WESTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE = 0.0
470         OFFSET = SCALING_FACTOR = 0.0
471         SAMPLE_TYPE = UNIT = TARGET_NAME = RadiusUM = Message = ""
472
473         # intializing variables
474         props = [("FromLat", 0.0),
475                  ("ToLat", 0.0),
476                  ("FromLong", 0.0),
477                  ("ToLong", 0.0),
478                  ("Scale", 1),
479                  ("Exaggerate", False)]
480         for p, num in props:
481             if not p in bpy.context.scene.keys():
482                 bpy.context.scene[p] = num
483
484     def draw(self, context):
485         obj = context.object
486         typ = bpy.types.Scene
487         var = bpy.props
488         typ.fpath = var.StringProperty(name="Import File ", description="Select your img file", subtype="FILE_PATH", default="")
489
490         ReadLabel(bpy.context.scene.fpath)
491
492         typ.FromLat = var.FloatProperty(description="From Latitude", min=float(MINIMUM_LATITUDE), max=float(MAXIMUM_LATITUDE), precision=3)
493         typ.ToLat = var.FloatProperty(description="To Latitude", min=float(MINIMUM_LATITUDE), max=float(MAXIMUM_LATITUDE), precision=3)
494         typ.FromLong = var.FloatProperty(description="From Longitude", min=float(WESTERNMOST_LONGITUDE), max=float(EASTERNMOST_LONGITUDE), precision=3)
495         typ.ToLong = var.FloatProperty(description="To Longitude", min=float(WESTERNMOST_LONGITUDE), max=float(EASTERNMOST_LONGITUDE), precision=3)
496         typ.Scale = var.IntProperty(description="Scale", min=1, max=100, default=1)
497         typ.Exaggerate = var.BoolProperty(description="Magnify", default=False)
498
499         layout = self.layout
500         layout.prop(context.scene, "fpath")
501
502         col = layout.column()
503         split = col.split(align=True)
504         split.label("Minimum Latitude: " + str(MINIMUM_LATITUDE) + " deg")
505         split.label("Maximum Latitude: " + str(MAXIMUM_LATITUDE) + " deg")
506
507         split = col.split(align=True)
508         split.label("Westernmost Longitude: " + str(WESTERNMOST_LONGITUDE) + " deg")
509         split.label("Easternmost Longitude: " + str(EASTERNMOST_LONGITUDE) + " deg")
510
511         split = col.split(align=True)
512         split.label("Lines: " + str(LINES))
513         split.label("Line samples: " + str(LINE_SAMPLES))
514
515         split = col.split(align=True)
516         split.label("Sample type: " + str(SAMPLE_TYPE))
517         split.label("Sample bits: " + str(SAMPLE_BITS))
518
519         split = col.split(align=True)
520         split.label("Unit: " + UNIT)
521         split.label("Map resolution: " + str(MAP_RESOLUTION) + " pix/deg")
522
523         split = col.split(align=True)
524         split.label("Radius: " + str(OFFSET) + " " + RadiusUM)
525         split.label("Scale: " + str(SCALING_FACTOR))
526
527         split = col.split(align=True)
528         split.label("Target: ")
529         split.label(TARGET_NAME)
530
531         col = layout.column()
532         split = col.split(align=True)
533         split.prop(context.scene, "FromLat", "Northernmost Lat.")
534         split.prop(context.scene, "ToLat", "Southernmost Lat.")
535         if bpy.context.scene['FromLat'] < bpy.context.scene['ToLat']:
536             col = layout.column()
537             split = col.split(align=True)
538             split.label("Warning: Northernmost must be greater than Southernmost")
539
540         col = layout.column()
541         split = col.split(align=True)
542         split.prop(context.scene, "FromLong", "Westernmost Long.")
543         split.prop(context.scene, "ToLong", "Easternmost Long.")
544         if bpy.context.scene['FromLong'] > bpy.context.scene['ToLong']:
545             col = layout.column()
546             split = col.split(align=True)
547             split.label("Warning: Easternmost must be greater than Westernmost")
548
549         col = layout.column()
550         split = col.split(align=True)
551         #split.prop(context.scene, "Scale", "Scale")   #TO DO
552         split.prop(context.scene, "Exaggerate", "Magnify (x4)")
553         if bpy.context.scene.fpath != "":
554             col = layout.column()
555             split = col.split(align=True)
556             split.label("1 Blender unit = " + str(bpy.context.scene['Scale']) + RadiusUM)
557
558         if Message != "":
559             col = layout.column()
560             split = col.split(align=True)
561             split.label("Message: " + Message)
562
563         if bpy.context.scene.fpath.upper().endswith("IMG") or bpy.context.scene.fpath.upper().endswith("LBL"):  # Check if is selected the correct file
564             VertNumbers = (((RealLat(bpy.context.scene['FromLat']) - RealLat(bpy.context.scene['ToLat'])) * MAP_RESOLUTION) + 1) * ((RealLong(bpy.context.scene['ToLong']) - RealLong(bpy.context.scene['FromLong'])) * MAP_RESOLUTION + 1)
565         else:
566             VertNumbers = 0
567         #If I have 4 or plus vertex and at least 2 row and at least 2 point, I can import
568         if VertNumbers > 3 and (RealLat(bpy.context.scene['FromLat']) > RealLat(bpy.context.scene['ToLat'])) and (RealLong(bpy.context.scene['FromLong']) < RealLong(bpy.context.scene['ToLong'])):  # If I have 4 or plus vertex I can import
569             split = col.split(align=True)
570             split.label("Map resolution on the equator: ")
571             split.label(str(2 * math.pi * OFFSET / 360 / MAP_RESOLUTION) + " " + RadiusUM + "/pix")
572             col = layout.column()
573             split = col.split(align=True)
574             split.label("Real Northernmost Lat.: " + str(RealLat(bpy.context.scene['FromLat'])) + " deg")
575             split.label("Real Southernmost Long.: " + str(RealLat(bpy.context.scene['ToLat'])) + " deg")
576             split = col.split(align=True)
577             split.label("Real Westernmost Long.: " + str(RealLong(bpy.context.scene['FromLong'])) + " deg")
578             split.label("Real Easternmost Long.: " + str(RealLong(bpy.context.scene['ToLong'])) + "deg")
579             split = col.split(align=True)
580             #VertNumbers = (((RealLat(bpy.context.scene['FromLat']) - RealLat(bpy.context.scene['ToLat'])) * MAP_RESOLUTION) + 1) * ((RealLong(bpy.context.scene['ToLong']) - RealLong(bpy.context.scene['FromLong'])) * MAP_RESOLUTION + 1)
581             split.label("Numbers of vertex to be imported: " + str(int(VertNumbers)))
582             col.separator()
583             col.operator('import.lro_and_mgs', text='Import')
584
585
586 # registering the script
587 def register():
588     bpy.utils.register_module(__name__)
589
590
591 def unregister():
592     bpy.utils.unregister_module(__name__)
593     clear_properties()
594
595 if __name__ == "__main__":
596     register()