Set material and color properties of Blob objects.
[blender-addons-contrib.git] / object_laplace_lightning.py
index ed84e187f51b2a02977ca9a536559859c60bc68b..f5d5cd173b47dbcbe56575aa2ecd656f34f14734 100644 (file)
 bl_info = {
     "name": "Laplacian Lightning",
     "author": "teldredge",
-    "version": (0, 2, 6),
-    "blender": (2, 6, 1),
-    "api": 43252,
-    "location": "View3D > ToolShelf > Laplacian Lightning",
+    "version": (0, 2, 7),
+    "blender": (2, 71, 0),
+    "location": "View3D > Toolshelf > Addons Tab",
     "description": "Lightning mesh generator using laplacian growth algorithm",
-    "warning": "Beta/Buggy.",
+    "warning": "Beta",
     "wiki_url": "http://www.funkboxing.com/wordpress/?p=301",
-    "tracker_url": "https://projects.blender.org/tracker/index.php?"
-                   "func=detail&aid=27189",
+    "tracker_url": "http://www.funkboxing.com/wordpress/?p=301",
     "category": "Object"}
         
 ######################################################################
@@ -34,6 +32,7 @@ bl_info = {
 ##################### BLENDER LAPLACIAN LIGHTNING ####################
 ############################ teldredge ###############################
 ######################## www.funkboxing.com ##########################
+################# https://developer.blender.org/T27189 ###############
 ######################################################################
 ######################## using algorithm from ########################
 ######################################################################
@@ -83,20 +82,25 @@ v0.2.6 - 06.20.11
         must have rot=0, scale=1, origin set to geometry
         often fails to block bolt with curved/complex shapes
     separate single and multi mesh creation
+v0.2.7 - 01.05.13
+    fixed the issue that prevented enabling the add-on
+    fixed makeMeshCube fxn
+    disabled visualization for voxels
 
 v0.x -
+    -prevent create_setup_objects from generating duplicates
     -fix vis fxn to only buildCPGraph once for VM or VS
     -improve list fxns (rid of ((x,y,z),w) and use (x,y,z,w)), use 'sets'
     -create python cmodule for a few of most costly fxns
         i have pretty much no idea how to do this yet
     -cloud and insulator can be groups of MESH objs
-    -?text output, possibly to save on interrupt, allow continue from text
+    -text output, possibly to save on interrupt, allow continue from text
     -?hook modifiers from tips->sides->main, weight w/ vert groups
     -user defined 'attractor' path
     -fix add curve function
     -animated arcs via. ionization path    
-    -environment map boundary conditions - requires Eqn. 15 from FSLG...
-    -?assign wattage at each segment for HDRI
+    -environment map boundary conditions - requires Eqn. 15 from FSLG.
+    -assign wattage at each segment for HDRI
     -?default settings for -lightning, -teslacoil, -spark/arc
     -fix hOrder functionality
     -multiple 'MAIN' brances for non-lightning discharges
@@ -115,7 +119,8 @@ import struct
 import bisect
 import os.path
 notZero = 0.0000000001
-scn = bpy.context.scene
+#scn = bpy.context.scene
+winmgr = bpy.context.window_manager
 
 ######################################################################
 ########################### UTILITY FXNS #############################
@@ -230,7 +235,7 @@ def readArrayFromFile(filename):
         arr.append((int(pt[0]), int(pt[1]), int(pt[2])))
     return arr
 
-def makeMeshCube(msize):
+def makeMeshCube_OLD(msize):
     msize = msize/2
     mmesh = bpy.data.meshes.new('q')
     mmesh.vertices.add(8)
@@ -252,6 +257,26 @@ def makeMeshCube(msize):
     mmesh.update(calc_edges=True)
     return(mmesh)
 
+def makeMeshCube(msize):
+    m2 = msize/2
+    #verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0),(0,0,5),(0,5,5),(5,5,5),(5,0,5)]
+    verts = [(-m2,-m2,-m2),(-m2,m2,-m2),(m2,m2,-m2),(m2,-m2,-m2),
+             (-m2,-m2,m2),(-m2,m2,m2),(m2,m2,m2),(m2,-m2,m2)]
+    faces = [(0,1,2,3), (4,5,6,7), (0,4,5,1), (1,5,6,2), (2,6,7,3), (3,7,4,0)]
+    #Define mesh and object
+    mmesh = bpy.data.meshes.new("Cube")
+    #mobject = bpy.data.objects.new("Cube", mmesh)
+    #Set location and scene of object
+    #mobject.location = bpy.context.scene.cursor_location
+    #bpy.context.scene.objects.link(mobject)
+    #Create mesh
+    mmesh.from_pydata(verts,[],faces)
+    mmesh.update(calc_edges=True)
+    return(mmesh)
+
 def writeArrayToCubes(arr, gridBU, orig, cBOOL = False, jBOOL = True):
     for a in arr:
         x = a[0]; y = a[1]; z = a[2]
@@ -437,7 +462,7 @@ def visualizeArray(cg, oob, gs, vm, vs, vc, vv, rst):
 
     if vm:  ###---WRITE ARRAY TO MULTI MESH
         
-        aMi, aHi, aTi = classifyStroke(cg, oct, scn.HORDER)
+        aMi, aHi, aTi = classifyStroke(cg, oct, winmgr.HORDER)
         print(':::WRITING TO MULTI-MESH')        
         writeStokeToMesh(cg, cjarr, aMi, aHi, aTi, origin, gs, rst)
         print(':::MULTI-MESH WRITTEN')
@@ -884,6 +909,7 @@ def getCandidateSites(aList, iList = []):
 ############################# SETUP FXNS #############################
 ######################################################################
 def setupObjects():
+    #if winmgr.OOB == "" or winmgr.OOB.name not in scene...
     oOB = bpy.data.objects.new('ELorigin', None)
     oOB.location = ((0,0,10))
     bpy.context.scene.objects.link(oOB)
@@ -910,24 +936,24 @@ def setupObjects():
     bpy.context.scene.objects.link(iOB)
 
     try:
-        scn.OOB = 'ELorigin'
-        scn.GOB = 'ELground'
-        scn.COB = 'ELcloud'
-        scn.IOB = 'ELinsulator'
+        winmgr.OOB = 'ELorigin'
+        winmgr.GOB = 'ELground'
+        winmgr.COB = 'ELcloud'
+        winmgr.IOB = 'ELinsulator'
     except: pass
 
 def checkSettings():
     check = True
-    if scn.OOB == "": 
+    if winmgr.OOB == "": 
         print('ERROR: NO ORIGIN OBJECT SELECTED')
         check = False
-    if scn.GROUNDBOOL and scn.GOB == "":
+    if winmgr.GROUNDBOOL and winmgr.GOB == "":
         print('ERROR: NO GROUND OBJECT SELECTED')
         check = False
-    if scn.CLOUDBOOL and scn.COB == "":
+    if winmgr.CLOUDBOOL and winmgr.COB == "":
         print('ERROR: NO CLOUD OBJECT SELECTED')        
         check = False
-    if scn.IBOOL and scn.IOB == "":
+    if winmgr.IBOOL and winmgr.IOB == "":
         print('ERROR: NO INSULATOR OBJECT SELECTED')        
         check = False
     #should make a popup here
@@ -941,38 +967,40 @@ def FSLG():
 ###======FAST SIMULATION OF LAPLACIAN GROWTH======###
     print('\n<<<<<<------GO GO GADGET: FAST SIMULATION OF LAPLACIAN GROWTH!')
     tc1 = time.clock()
-    TSTEPS = scn.TSTEPS
-
-    obORIGIN = scn.objects[scn.OOB]
-    obGROUND = scn.objects[scn.GOB]    
-    scn.ORIGIN = obORIGIN.location
-    scn.GROUNDZ = int((obGROUND.location[2] - scn.ORIGIN[2]) / scn.GSCALE)
+    TSTEPS = winmgr.TSTEPS
+
+    #obORIGIN = scn.objects[winmgr.OOB]    
+    #obGROUND = scn.objects[winmgr.GOB]
+    obORIGIN = bpy.context.scene.objects[winmgr.OOB]
+    obGROUND = bpy.context.scene.objects[winmgr.GOB]        
+    winmgr.ORIGIN = obORIGIN.location
+    winmgr.GROUNDZ = int((obGROUND.location[2] - winmgr.ORIGIN[2]) / winmgr.GSCALE)
     
     ###====== 1) INSERT INTIAL CHARGE(S) POINT (USES VERTS IF MESH)
     cgrid = [(0, 0, 0)]
     if obORIGIN.type == 'MESH':
         print("<<<<<<------ORIGIN OBJECT IS MESH, 'VOXELIZING' INTIAL CHARGES FROM VERTS")
-        cgrid = voxelByVertex(obORIGIN, scn.GSCALE)
-        if scn.VMMESH:
+        cgrid = voxelByVertex(obORIGIN, winmgr.GSCALE)
+        if winmgr.VMMESH:
             print("<<<<<<------CANNOT CLASSIFY STROKE FROM VERT ORIGINS YET, NO MULTI-MESH OUTPUT")
-            scn.VMMESH = False; scn.VSMESH = True
+            winmgr.VMMESH = False; winmgr.VSMESH = True
 
     ###---GROUND CHARGE CELL / INSULATOR LISTS (eChargeList/icList)
     eChargeList = []; icList = []
-    if scn.GROUNDBOOL:
-        eChargeList = fakeGroundChargePlane(scn.GROUNDZ, scn.GROUNDC)
-    if scn.CLOUDBOOL:
+    if winmgr.GROUNDBOOL:
+        eChargeList = fakeGroundChargePlane(winmgr.GROUNDZ, winmgr.GROUNDC)
+    if winmgr.CLOUDBOOL:
         print("<<<<<<------'VOXELIZING' CLOUD OBJECT (COULD TAKE SOME TIME)")
-        obCLOUD = scn.objects[scn.COB]
-        eChargeListQ = voxelByRays(obCLOUD, scn.ORIGIN, scn.GSCALE)
-        eChargeList = addCharges(eChargeListQ, scn.CLOUDC)
+        obCLOUD = bpy.context.scene.objects[winmgr.COB]
+        eChargeListQ = voxelByRays(obCLOUD, winmgr.ORIGIN, winmgr.GSCALE)
+        eChargeList = addCharges(eChargeListQ, winmgr.CLOUDC)
         print('<<<<<<------CLOUD OBJECT CELL COUNT = ', len(eChargeList) )        
-    if scn.IBOOL:
+    if winmgr.IBOOL:
         print("<<<<<<------'VOXELIZING' INSULATOR OBJECT (COULD TAKE SOME TIME)")
-        obINSULATOR = scn.objects[scn.IOB]
-        icList = voxelByRays(obINSULATOR, scn.ORIGIN, scn.GSCALE)
+        obINSULATOR = bpy.context.scene.objects[winmgr.IOB]
+        icList = voxelByRays(obINSULATOR, winmgr.ORIGIN, winmgr.GSCALE)
         print('<<<<<<------INSULATOR OBJECT CELL COUNT = ', len(icList) )
-        #writeArrayToCubes(icList, scn.GSCALE, scn.ORIGIN)
+        #writeArrayToCubes(icList, winmgr.GSCALE, winmgr.ORIGIN)
         #return 'THEEND'
         
     ###====== 2) LOCATE CANDIDATE SITES AROUND CHARGE
@@ -985,7 +1013,7 @@ def FSLG():
     while ts <= TSTEPS:
         ###====== 1) SELECT NEW GROWTH SITE (Eqn. 12)
         ###===GET PROBABILITIES AT CANDIDATE SITES
-        gProbs = getGrowthProbability(scn.BIGVAR, cSites)
+        gProbs = getGrowthProbability(winmgr.BIGVAR, cSites)
         ###===CHOOSE NEW GROWTH SITE BASED ON PROBABILITIES
         gSitei = weightedRandomChoice(gProbs)
         gsite  = cSites[gSitei][0]
@@ -1020,19 +1048,19 @@ def FSLG():
 
         ###===ITERATION COMPLETE
         istr1 = ':::T-STEP: ' + str(ts) + '/' + str(TSTEPS) 
-        istr12 = ' | GROUNDZ: ' + str(scn.GROUNDZ) + ' | '
+        istr12 = ' | GROUNDZ: ' + str(winmgr.GROUNDZ) + ' | '
         istr2 = 'CANDS: ' + str(len(cSites)) + ' | '
         istr3 = 'GSITE: ' + str(gsite)
         print(istr1 + istr12 + istr2 + istr3)        
         ts += 1
         
         ###---EARLY TERMINATION FOR GROUND/CLOUD STRIKE
-        if scn.GROUNDBOOL:
-            if gsite[2] == scn.GROUNDZ:
+        if winmgr.GROUNDBOOL:
+            if gsite[2] == winmgr.GROUNDZ:
                 ts = TSTEPS+1
                 print('<<<<<<------EARLY TERMINATION DUE TO GROUNDSTRIKE')
                 continue
-        if scn.CLOUDBOOL:
+        if winmgr.CLOUDBOOL:
             #if gsite in cloudList:
             if gsite in splitListCo(eChargeList):
                 ts = TSTEPS+1
@@ -1046,82 +1074,84 @@ def FSLG():
 
     reportSTRING = getReportString(tcRUN)    
     ###---VISUALIZE ARRAY
-    visualizeArray(cgrid, obORIGIN, scn.GSCALE, scn.VMMESH, scn.VSMESH, scn.VCUBE, scn.VVOX, reportSTRING)
+    visualizeArray(cgrid, obORIGIN, winmgr.GSCALE, winmgr.VMMESH, winmgr.VSMESH, winmgr.VCUBE, winmgr.VVOX, reportSTRING)
     print('<<<<<<------COMPLETE')
 
 ######################################################################
 ################################ GUI #################################
 ######################################################################
 ###---NOT IN UI
-bpy.types.Scene.ORIGIN = bpy.props.FloatVectorProperty(name = "origin charge")
-bpy.types.Scene.GROUNDZ = bpy.props.IntProperty(name = "ground Z coordinate")
-bpy.types.Scene.HORDER = bpy.props.IntProperty(name = "secondary paths orders")
+bpy.types.WindowManager.ORIGIN = bpy.props.FloatVectorProperty(name = "origin charge")
+bpy.types.WindowManager.GROUNDZ = bpy.props.IntProperty(name = "ground Z coordinate")
+bpy.types.WindowManager.HORDER = bpy.props.IntProperty(name = "secondary paths orders")
 ###---IN UI
-bpy.types.Scene.TSTEPS = bpy.props.IntProperty(
+bpy.types.WindowManager.TSTEPS = bpy.props.IntProperty(
     name = "iterations", description = "number of cells to create, will end early if hits ground plane or cloud")
-bpy.types.Scene.GSCALE = bpy.props.FloatProperty(
+bpy.types.WindowManager.GSCALE = bpy.props.FloatProperty(
     name = "grid unit size", description = "scale of cells, .25 = 4 cells per blenderUnit")
-bpy.types.Scene.BIGVAR = bpy.props.FloatProperty(
+bpy.types.WindowManager.BIGVAR = bpy.props.FloatProperty(
     name = "straightness", description = "straightness/branchiness of bolt, <2 is mush, >12 is staight line, 6.3 is good")
-bpy.types.Scene.GROUNDBOOL = bpy.props.BoolProperty(
+bpy.types.WindowManager.GROUNDBOOL = bpy.props.BoolProperty(
     name = "use ground object", description = "use ground plane or not")
-bpy.types.Scene.GROUNDC = bpy.props.IntProperty(
+bpy.types.WindowManager.GROUNDC = bpy.props.IntProperty(
     name = "ground charge", description = "charge of ground plane")
-bpy.types.Scene.CLOUDBOOL = bpy.props.BoolProperty(
+bpy.types.WindowManager.CLOUDBOOL = bpy.props.BoolProperty(
     name = "use cloud object", description = "use cloud obj, attracts and terminates like ground but any obj instead of z plane, can slow down loop if obj is large, overrides ground")
-bpy.types.Scene.CLOUDC = bpy.props.IntProperty(
+bpy.types.WindowManager.CLOUDC = bpy.props.IntProperty(
     name = "cloud charge", description = "charge of a cell in cloud object (so total charge also depends on obj size)")
 
-bpy.types.Scene.VMMESH = bpy.props.BoolProperty(
+bpy.types.WindowManager.VMMESH = bpy.props.BoolProperty(
     name = "multi mesh", description = "output to multi-meshes for different materials on main/sec/side branches")
-bpy.types.Scene.VSMESH = bpy.props.BoolProperty(
+bpy.types.WindowManager.VSMESH = bpy.props.BoolProperty(
     name = "single mesh", description = "output to single mesh for using build modifier and particles for effects")
-bpy.types.Scene.VCUBE = bpy.props.BoolProperty(
+bpy.types.WindowManager.VCUBE = bpy.props.BoolProperty(
     name = "cubes", description = "CTRL-J after run to JOIN, outputs a bunch of cube objest, mostly for testing")
-bpy.types.Scene.VVOX = bpy.props.BoolProperty(        
+bpy.types.WindowManager.VVOX = bpy.props.BoolProperty(        
     name = "voxel (experimental)", description = "output to a voxel file to bpy.data.filepath\FSLGvoxels.raw - doesn't work well right now")
-bpy.types.Scene.IBOOL = bpy.props.BoolProperty(
+bpy.types.WindowManager.IBOOL = bpy.props.BoolProperty(
     name = "use insulator object", description = "use insulator mesh object to prevent growth of bolt in areas")
-bpy.types.Scene.OOB = bpy.props.StringProperty(description = "origin of bolt, can be an Empty, if obj is mesh will use all verts as charges")
-bpy.types.Scene.GOB = bpy.props.StringProperty(description = "object to use as ground plane, uses z coord only")
-bpy.types.Scene.COB = bpy.props.StringProperty(description = "object to use as cloud, best to use a cube")
-bpy.types.Scene.IOB = bpy.props.StringProperty(description = "object to use as insulator, 'voxelized' before generating bolt, can be slow")
+bpy.types.WindowManager.OOB = bpy.props.StringProperty(description = "origin of bolt, can be an Empty, if obj is mesh will use all verts as charges")
+bpy.types.WindowManager.GOB = bpy.props.StringProperty(description = "object to use as ground plane, uses z coord only")
+bpy.types.WindowManager.COB = bpy.props.StringProperty(description = "object to use as cloud, best to use a cube")
+bpy.types.WindowManager.IOB = bpy.props.StringProperty(description = "object to use as insulator, 'voxelized' before generating bolt, can be slow")
 
 ###---DEFAULT USER SETTINGS
-scn.TSTEPS = 350
-scn.HORDER = 1
-scn.GSCALE = 0.12
-scn.BIGVAR = 6.3
-scn.GROUNDBOOL = True
-scn.GROUNDC = -250
-scn.CLOUDBOOL = False
-scn.CLOUDC = -1
-scn.VMMESH = True
-scn.VSMESH = False
-scn.VCUBE = False
-scn.VVOX = False
-scn.IBOOL = False
+winmgr.TSTEPS = 350
+winmgr.HORDER = 1
+winmgr.GSCALE = 0.12
+winmgr.BIGVAR = 6.3
+winmgr.GROUNDBOOL = True
+winmgr.GROUNDC = -250
+winmgr.CLOUDBOOL = False
+winmgr.CLOUDC = -1
+winmgr.VMMESH = True
+winmgr.VSMESH = False
+winmgr.VCUBE = False
+winmgr.VVOX = False
+winmgr.IBOOL = False
 try:
-    scn.OOB = "ELorigin"
-    scn.GOB = "ELground"
-    scn.COB = "ELcloud"
-    scn.IOB = "ELinsulator"    
+    winmgr.OOB = "ELorigin"
+    winmgr.GOB = "ELground"
+    winmgr.COB = "ELcloud"
+    winmgr.IOB = "ELinsulator"    
 except: pass
-### TESTING
+
+###---TESTING USER SETTINGS
 if False:
 #if True:
-    #scn.BIGVAR = 6.3
-    #scn.VSMESH = True
-    #scn.VMMESH = False
-    #scn.VCUBE = True
-    #scn.TSTEPS = 7500
-    scn.TSTEPS = 100
-    #scn.GROUNDC = -500
-    #scn.CLOUDC = -5
-    #scn.GROUNDBOOL = False
-    #scn.CLOUDBOOL = True
-    
-    #scn.IBOOL = True
+    winmgr.TSTEPS = 40
+    #winmgr.HORDER = 1
+    #winmgr.GSCALE = 0.12    
+    #winmgr.BIGVAR = 6.3
+    winmgr.GROUNDBOOL = True
+    #winmgr.GROUNDC = -500
+    winmgr.CLOUDBOOL = True
+    #winmgr.CLOUDC = -5
+    #winmgr.VMMESH = True
+    #winmgr.VSMESH = True
+    #winmgr.VCUBE = True
+    #winmgr.VVOX = True
+    winmgr.IBOOL = True
 
 class runFSLGLoopOperator(bpy.types.Operator):
     '''By The Mighty Hammer Of Thor!!!'''
@@ -1148,6 +1178,8 @@ class OBJECT_PT_fslg(bpy.types.Panel):
     bl_space_type = "VIEW_3D"
     bl_region_type = "TOOLS"
     bl_context = "objectmode"
+    bl_category = "Addons"
+    bl_options = {'DEFAULT_CLOSED'}
 
     def draw(self, context):
         scn = context.scene
@@ -1158,31 +1190,31 @@ class OBJECT_PT_fslg(bpy.types.Panel):
         #colR = row1.column()
         colR.label('-for progress open console-')
         colR.label('Help > Toggle System Console')        
-        colR.prop(scn, 'TSTEPS')
-        colR.prop(scn, 'GSCALE')        
-        colR.prop(scn, 'BIGVAR')
+        colR.prop(winmgr, 'TSTEPS')
+        colR.prop(winmgr, 'GSCALE')        
+        colR.prop(winmgr, 'BIGVAR')
         colR.operator('object.setup_objects_operator', text = 'create setup objects')        
         colR.label('origin object')
-        colR.prop_search(scn, "OOB",  context.scene, "objects")        
-        colR.prop(scn, 'GROUNDBOOL')
-        colR.prop_search(scn, "GOB",  context.scene, "objects")        
-        colR.prop(scn, 'GROUNDC') 
-        colR.prop(scn, 'CLOUDBOOL')
-        colR.prop_search(scn, "COB",  context.scene, "objects")        
-        colR.prop(scn, 'CLOUDC')
-        colR.prop(scn, 'IBOOL')
-        colR.prop_search(scn, "IOB",  context.scene, "objects")
+        colR.prop_search(winmgr, "OOB",  context.scene, "objects")        
+        colR.prop(winmgr, 'GROUNDBOOL')
+        colR.prop_search(winmgr, "GOB",  context.scene, "objects")        
+        colR.prop(winmgr, 'GROUNDC') 
+        colR.prop(winmgr, 'CLOUDBOOL')
+        colR.prop_search(winmgr, "COB",  context.scene, "objects")        
+        colR.prop(winmgr, 'CLOUDC')
+        colR.prop(winmgr, 'IBOOL')
+        colR.prop_search(winmgr, "IOB",  context.scene, "objects")
         colR.operator('object.runfslg_operator', text = 'generate lightning')
-        #col.prop(scn, 'HORDER')
-        colR.prop(scn, 'VMMESH')
-        colR.prop(scn, 'VSMESH')        
-        colR.prop(scn, 'VCUBE')
-        colR.prop(scn, 'VVOX')
+        #col.prop(winmgr, 'HORDER')
+        colR.prop(winmgr, 'VMMESH')
+        colR.prop(winmgr, 'VSMESH')        
+        colR.prop(winmgr, 'VCUBE')
+        #colR.prop(winmgr, 'VVOX')
 
 def getReportString(rtime):
-    rSTRING1 = 't:' + str(scn.TSTEPS) + ',sc:' + str(scn.GSCALE)[0:4] + ',uv:' + str(scn.BIGVAR)[0:4] + ',' 
-    rSTRING2 = 'ori:' + str(scn. ORIGIN[0]) + '/' + str(scn. ORIGIN[1]) + '/' + str(scn. ORIGIN[2]) + ','
-    rSTRING3 = 'gz:' + str(scn.GROUNDZ) + ',gc:' + str(scn.GROUNDC) + ',rtime:' + str(int(rtime))
+    rSTRING1 = 't:' + str(winmgr.TSTEPS) + ',sc:' + str(winmgr.GSCALE)[0:4] + ',uv:' + str(winmgr.BIGVAR)[0:4] + ',' 
+    rSTRING2 = 'ori:' + str(winmgr. ORIGIN[0]) + '/' + str(winmgr. ORIGIN[1]) + '/' + str(winmgr. ORIGIN[2]) + ','
+    rSTRING3 = 'gz:' + str(winmgr.GROUNDZ) + ',gc:' + str(winmgr.GROUNDC) + ',rtime:' + str(int(rtime))
     return rSTRING1 + rSTRING2 + rSTRING3
 
 def addReportProp(ob, str):
@@ -1237,8 +1269,8 @@ def BENCH():
     print('--->BENCHMARK TIME: ', btRUNb)
     print('--->GRIDSIZE: ', tsize, ' - ', tsize*tsize*tsize)
     
-#BENCH()    
-
+#BENCH()
 
-##################################
-################################
+######################################################################
+############################### THE END ##############################
+######################################################################