123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- import time
- import math
- import json
- from django.core.urlresolvers import reverse
- from django.http import HttpResponseRedirect, HttpResponse
- from django.contrib import messages
- from django.core.cache import cache
- from django.conf import settings
- from mongoengine import ValidationError
- from bson.objectid import ObjectId
- from multiprocessing import Process
- from .models import SpriteMetaData
- from .service import SliceGenerator, SubvolumeCreator
- from ..models import Volume
- from ..views import handleException
- from visualization.mongodb import gridfshelper
- from datetime import datetime, timedelta
- import logging
- logger = logging.getLogger(__name__)
- def generateslice(request, id):
- if request.method != 'POST':
- messages.error(request, 'no post')
- return HttpResponseRedirect(reverse('volumes:show', args=(id,)))
- try:
- volume = Volume.objects(id=id)[0]
- except (IndexError, ValidationError) as e:
- return handleException(request, id, e)
- volume.generateSlicesStatus = 'running'
- volume.save()
- process = Process(target=SliceGenerator.sliceGenerator, args=(request, volume.id,))
- process.start()
- # just for testing and using pdb, using the same thread
- # SliceGenerator.sliceGenerator(request, volume.id)
- messages.info(request, 'generating textures, please wait and refresh from time to time')
- return HttpResponseRedirect(reverse('volumes:show', args=(id,)))
- def getSubvolume(request, id, x, y, z, t, depth, requestedRes, testId=None):
- starttime = time.time()
- try:
- volume = Volume.objects(id=id)[0]
- except (IndexError, ValidationError) as e:
- return handleException(request, id, e)
- x = int(x)
- y = int(y)
- z = int(z)
- t = int(t)
- depth = int(depth)
- if t >= len(volume.rawFrames) or t < 0:
- t = 0
- rawFrame = volume.rawFrames[t]
- sizex = rawFrame.originalSize.sizex
- sizey = rawFrame.originalSize.sizey
- sizez = rawFrame.originalSize.sizez
- if testId is None:
- ''' are there any sprites within 30pixels around the point ? '''
- spriteMetaDatas = SpriteMetaData.objects(
- x__gte=(x-sizex/10),
- x__lte=(x+sizex/10),
- y__gte=(y-sizey/10),
- y__lte=(y+sizey/10),
- z__gte=(z-sizez/10),
- z__lte=(z+sizez/10),
- depth=depth,
- volumeId=id
- )
- ''' found a generated sprite in the near of the clicked point, just using it '''
- if len(spriteMetaDatas) > 0:
- for spriteMetaData in spriteMetaDatas:
- spritefilename = '%s.%s' % (str(spriteMetaData.spriteId), spriteMetaData.format)
- if cache.get(spritefilename) is not None:
- return HttpResponse(spriteMetaData.jsonInformation, content_type='json')
- else:
- spriteMetaData.delete()
- ''' end testId is None '''
- spriteId = ObjectId()
- format = 'jpeg'
- ''' metadata information for this sprite'''
- now = datetime.now()
- spriteMetaData = SpriteMetaData()
- spriteMetaData.creationTime = now
- spriteMetaData.spriteId = str(spriteId)
- spriteMetaData.format = format
- spriteMetaData.volumeId = str(id)
- spriteMetaData.x = x
- spriteMetaData.y = y
- spriteMetaData.z = z
- spriteMetaData.t = t
- spriteMetaData.depth = depth
- ''' caluclating dimensions '''
- ''' zoom factor is calucated by 2 * depth '''
- zoomFactor = 2
- zoomFactor *= depth
- minWidth = int(math.floor(sizex / zoomFactor))
- ''' lower bound set to 300 pxs '''
- if minWidth < 300:
- minWidth = 300
- minWidthHalf = int(math.floor(minWidth / 2))
- numberOfLayers = minWidth # we want it to be cube
- sqrtZ = int(math.floor(math.sqrt(numberOfLayers)))
- numberOfLayers = int(math.pow(sqrtZ, 2))
- ''' error prevention let us not run out of the volume '''
- if numberOfLayers > rawFrame.originalSize.sizez:
- numberOfLayers = rawFrame.originalSize.sizez
- sqrtZ = int(math.floor(math.sqrt(numberOfLayers)))
- numberOfLayers = int(math.pow(sqrtZ, 2))
- minWidth = numberOfLayers
- minWidthHalf = int(math.floor(minWidth / 2))
- numberOfLayersHalf = int(math.floor(numberOfLayers / 2))
- ''' set borders correctly '''
- if ((x - minWidthHalf) < 0):
- x = 0
- elif x + minWidthHalf > rawFrame.originalSize.sizex:
- x = rawFrame.originalSize.sizex - minWidth
- else:
- x = x - minWidthHalf
- if y - minWidthHalf < 0:
- y = 0
- elif y + minWidthHalf > rawFrame.originalSize.sizey:
- y = rawFrame.originalSize.sizey - minWidth
- else:
- y = y - minWidthHalf
- print('originalsize in z %d' % rawFrame.originalSize.sizez)
- if z - numberOfLayersHalf < 0:
- z = 0
- elif z + numberOfLayersHalf > rawFrame.originalSize.sizez:
- z = rawFrame.originalSize.sizez - numberOfLayers
- else:
- z = z - numberOfLayersHalf
- '''
- creatorThread = SubvolumeCreator.SubvolumeCreator(volume.id, x, y, z, t, minWidth, sqrtZ, numberOfLayers, spriteId, format, starttime, testId)
- creatorThread.start()
- '''
- # requestedRes = int(request.session.get('requestedRes', 2048))
- # if requestedRes is None or requestedRes < 2048:
- # requestedRes = 2048
- requestedRes = int(requestedRes)
- creatorProcess = Process(
- target=SubvolumeCreator.subvolumeCreator,
- args=(
- volume.id,
- x,
- y,
- z,
- t,
- minWidth,
- sqrtZ,
- numberOfLayers,
- spriteId,
- format,
- requestedRes,
- starttime,
- testId,
- )
- )
- creatorProcess.start()
- infoObject = {}
- infoObject['slicesOverX'] = sqrtZ
- infoObject['slicesOverY'] = sqrtZ
- infoObject['numberOfSlices'] = numberOfLayers
- infoObject['spriteId'] = str(spriteId)
- infoObject['depth'] = depth
- infoObject['dimension'] = {}
- infoObject['dimension']['xmin'] = x
- infoObject['dimension']['ymin'] = y
- infoObject['dimension']['zmin'] = z
- infoObject['dimension']['xywidth'] = minWidth
- jsonString = json.dumps(infoObject)
- spriteMetaData.jsonInformation = jsonString
- spriteMetaData.save()
- return HttpResponse(jsonString, content_type='json')
- def getSubvolumeSprite(request, id, spriteId):
- return getSubvolumeFromCache(request, id, spriteId)
- '''return getSubvolumeFromGridFS(request, id, spriteId)'''
- def getSubvolumeFromGridFS(request, id, spriteId):
- filename = spriteId + '.jpeg'
- if gridfshelper.fileexists(filename):
- handle = gridfshelper.openfile(spriteId + '.jpeg')
- return HttpResponse(handle.read(), content_type='image/jpeg')
- else:
- return HttpResponse(None, content_type='image/jpeg')
- def getSubvolumeFromCache(request, id, spriteId):
- handle = cache.get(spriteId + '.jpeg')
- if handle is None:
- response = HttpResponse(None, content_type='image/jpeg')
- else:
- response = HttpResponse(handle, content_type='image/jpeg')
- response['Content-Length'] = len(handle)
- return response
- def subvolumeAvailable(request, id, spriteId):
- '''jsonstring = json.dumps({ 'available' : gridfshelper.fileexists(spriteId + '.jpeg') })'''
- jsonstring = json.dumps({'available': cache.get(spriteId + '.jpeg') is not None})
- return HttpResponse(jsonstring, content_type='json')
- def listfiles(request, id, plain=None):
- try:
- spriteMetaDatas = SpriteMetaData.objects()
- except (IndexError, ValidationError) as e:
- return handleException(request, id, e)
- print(plain)
- if plain is None:
- filenames = []
- for spriteMetaData in spriteMetaDatas:
- filenames.append(spriteMetaData.spriteId)
- else:
- filenames = gridfshelper.listfiles()
- print(filenames)
- jsonstring = json.dumps({'files': filenames})
- return HttpResponse(jsonstring, content_type='json')
- def deletefiles(request, id):
- try:
- spriteMetaDatas = SpriteMetaData.objects()
- except (IndexError, ValidationError) as e:
- return handleException(request, id, e)
- now = datetime.now()
- deleted = []
- kept = []
- minCachingTime = timedelta(seconds=settings.SUBVOLUME_CACHING_TIME)
- for spriteMetaData in spriteMetaDatas:
- timeDelta = now - spriteMetaData.creationTime
- if timeDelta > minCachingTime:
- deleted.append(spriteMetaData.getfilename())
- spriteMetaData.delete()
- else:
- kept.append(spriteMetaData.spriteId)
- return HttpResponse(
- json.dumps({
- 'deleted': deleted,
- 'kept': kept,
- 'minCachingTime(sec)': minCachingTime.total_seconds()
- }),
- content_type='json'
- )
|