2013-10-01 16:38:42 +02:00
|
|
|
import os.path
|
|
|
|
import struct
|
2013-10-10 17:46:22 +02:00
|
|
|
import re
|
2013-10-01 16:38:42 +02:00
|
|
|
|
|
|
|
from hashlib import md5
|
2013-10-14 17:02:21 +02:00
|
|
|
from datetime import datetime, timedelta
|
2013-10-01 16:38:42 +02:00
|
|
|
|
|
|
|
from django.contrib.auth.models import User
|
|
|
|
from django.db import models
|
|
|
|
|
2013-10-10 17:46:22 +02:00
|
|
|
vertex_pattern = re.compile(r'vertex\s+([0-9.e+-]+)\s+([0-9.e+-]+)\s+([0-9.e+-]+)')
|
2013-10-01 16:38:42 +02:00
|
|
|
|
|
|
|
def safe_upload_path(base_dir):
|
|
|
|
|
|
|
|
def generate_path(instance, filename):
|
|
|
|
|
|
|
|
ext = os.path.splitext(filename)[1]
|
|
|
|
|
|
|
|
md5sum = md5()
|
|
|
|
md5sum.update(instance.name
|
|
|
|
+ str(datetime.now())
|
|
|
|
+ filename)
|
|
|
|
randomname = md5sum.hexdigest()
|
|
|
|
|
|
|
|
return os.path.join(base_dir,'%s%s' % (randomname, ext))
|
|
|
|
|
|
|
|
return generate_path
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Geometry(models.Model):
|
2013-10-14 17:02:21 +02:00
|
|
|
|
|
|
|
HOUR = 0
|
|
|
|
DAY = 1
|
|
|
|
WEEK = 2
|
|
|
|
MONTH = 3
|
|
|
|
FORERVER = 4
|
|
|
|
|
|
|
|
EXPIRATION_CHOICES = ((HOUR, 'one hour'),
|
|
|
|
(DAY, 'one day'),
|
|
|
|
(WEEK, 'one week'),
|
|
|
|
(MONTH, 'one month'),
|
|
|
|
(FORERVER, 'forever'))
|
|
|
|
|
|
|
|
DELTAS = { HOUR : timedelta(hours = 1),
|
|
|
|
DAY : timedelta(days = 1),
|
|
|
|
WEEK : timedelta(weeks = 1),
|
|
|
|
MONTH : timedelta(weeks = 4)}
|
|
|
|
|
2013-10-01 16:38:42 +02:00
|
|
|
name = models.CharField(max_length = 128)
|
|
|
|
description = models.TextField(blank=True)
|
2013-10-13 18:41:03 +02:00
|
|
|
user = models.ForeignKey(User, blank=True, null=True)
|
2013-10-01 16:38:42 +02:00
|
|
|
date = models.DateTimeField(auto_now_add=True)
|
2013-10-14 17:02:21 +02:00
|
|
|
expiration = models.IntegerField(default = 0, choices = EXPIRATION_CHOICES)
|
|
|
|
public = models.BooleanField(default=True)
|
2013-10-01 16:38:42 +02:00
|
|
|
polycount = models.IntegerField(blank=True, default=0)
|
2013-10-10 17:46:22 +02:00
|
|
|
width = models.FloatField(blank=True, default=0)
|
|
|
|
depth = models.FloatField(blank=True, default=0)
|
|
|
|
height = models.FloatField(blank=True, default=0)
|
2013-10-01 16:38:42 +02:00
|
|
|
file = models.FileField(upload_to=safe_upload_path('models'))
|
|
|
|
sourcefile = models.FileField(upload_to=safe_upload_path('sources'), blank=True)
|
|
|
|
|
2013-10-14 17:02:21 +02:00
|
|
|
def get_expiration_date(self):
|
|
|
|
for expiration in [self.HOUR, self.DAY, self.WEEK, self.MONTH]:
|
|
|
|
if self.expiration == expiration:
|
|
|
|
return self.date + self.DELTAS[expiration]
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2013-10-10 17:46:22 +02:00
|
|
|
def _generate_meta_infos(self):
|
|
|
|
print "Generating metainfos %s" % self.name
|
|
|
|
|
|
|
|
self.file.open()
|
|
|
|
|
|
|
|
count = 0
|
|
|
|
min_coord = [None,None,None]
|
|
|
|
max_coord = [None,None,None]
|
|
|
|
|
|
|
|
if self.file.read(5) != "solid":
|
|
|
|
print "binary"
|
|
|
|
#Skip header
|
|
|
|
self.file.seek(80)
|
|
|
|
count = struct.unpack("i",self.file.read(4))[0]
|
|
|
|
|
|
|
|
done = False
|
|
|
|
for pos in range(0,count):
|
|
|
|
#Skip normal (3 * 32bit)
|
|
|
|
self.file.seek(self.file.tell()+3*4)
|
|
|
|
#Loop over each coordinate
|
|
|
|
for vert in range(0,3):
|
|
|
|
# Loop over each coordinate
|
|
|
|
for i in range(0,3):
|
|
|
|
x = struct.unpack("<f",self.file.read(4))[0]
|
|
|
|
|
|
|
|
if min_coord[i] != None :
|
|
|
|
min_coord[i] = min(min_coord[i], x)
|
|
|
|
else:
|
|
|
|
min_coord[i] = x
|
|
|
|
|
|
|
|
if max_coord[i] != None :
|
|
|
|
max_coord[i] = max(max_coord[i], x)
|
|
|
|
else:
|
|
|
|
max_coord[i] = x
|
|
|
|
#Skip attributes (16bit)
|
|
|
|
self.file.seek(self.file.tell()+2)
|
|
|
|
|
|
|
|
else:
|
|
|
|
print "ascii"
|
|
|
|
|
|
|
|
line = self.file.readline()
|
|
|
|
while line != "":
|
|
|
|
line = line.strip()
|
|
|
|
if line.startswith("facet"):
|
|
|
|
count = count + 1
|
|
|
|
if line.startswith("vertex"):
|
|
|
|
coords = vertex_pattern.match(line).groups();
|
|
|
|
for i in range(0,3):
|
|
|
|
x = float(coords[i])
|
|
|
|
|
|
|
|
if min_coord[i] != None :
|
|
|
|
min_coord[i] = min(min_coord[i], x)
|
|
|
|
else:
|
|
|
|
min_coord[i] = x
|
|
|
|
|
|
|
|
if max_coord[i] != None :
|
|
|
|
max_coord[i] = max(max_coord[i], x)
|
|
|
|
else:
|
|
|
|
max_coord[i] = x
|
2013-10-01 16:38:42 +02:00
|
|
|
|
|
|
|
line = self.file.readline()
|
|
|
|
|
2013-10-10 17:46:22 +02:00
|
|
|
self.file.close()
|
|
|
|
|
|
|
|
self.width = max_coord[0] - min_coord[0]
|
|
|
|
self.depth = max_coord[1] - min_coord[1]
|
|
|
|
self.height = max_coord[2] - min_coord[2]
|
|
|
|
self.polycount = count
|
2013-10-01 16:38:42 +02:00
|
|
|
|
2013-10-14 17:02:21 +02:00
|
|
|
self.save()
|
|
|
|
|
2013-10-10 17:46:22 +02:00
|
|
|
def get_polycount(self):
|
|
|
|
if self.polycount == 0:
|
|
|
|
self._generate_meta_infos()
|
2013-10-01 16:38:42 +02:00
|
|
|
return self.polycount
|
|
|
|
|
2013-10-10 17:46:22 +02:00
|
|
|
def get_width(self):
|
|
|
|
if self.polycount == 0:
|
|
|
|
self._generate_meta_infos()
|
|
|
|
return self.width
|
|
|
|
|
|
|
|
def get_depth(self):
|
|
|
|
if self.polycount == 0:
|
|
|
|
self._generate_meta_infos()
|
|
|
|
return self.depth
|
|
|
|
|
|
|
|
def get_height(self):
|
|
|
|
if self.polycount == 0:
|
|
|
|
self._generate_meta_infos()
|
|
|
|
return self.height
|
|
|
|
|
2013-10-01 16:38:42 +02:00
|
|
|
|