past3d/pastebin/forms.py

87 lines
2.3 KiB
Python

import re
import os
import struct
from django.forms import ModelForm
from django import forms
from models import Geometry
facet_pattern = re.compile(r'facet normal\s+[0-9.e+-]+\s+[0-9.e+-]+\s+[0-9.e+-]+')
loop_pattern = re.compile(r'outer\s+loop')
vertex_pattern = re.compile(r'vertex\s+[0-9.e+-]+\s+[0-9.e+-]+\s+[0-9.e+-]+')
endloop_pattern = re.compile(r'endloop')
endfacet_pattern = re.compile(r'endfacet')
endsolid_pattern = re.compile(r'endsolid .*')
class STLUploadForm(ModelForm):
def clean_file(self):
stlfile = self.cleaned_data.get("file")
stlfile.open()
if stlfile.read(5) != "solid":
#print "binary"
#Skip header
stlfile.seek(80)
count = struct.unpack("i",stlfile.read(4))[0]
if stlfile.size - 84 != count * 50:
raise forms.ValidationError("Not a valid binary STL file.")
else:
#print "ascii"
next_patterns = [facet_pattern]
stlfile.readline()
line = stlfile.readline().strip()
matched_pattern = None
vertex_count = 0
while line != "":
corret = False
for pattern in next_patterns:
if pattern.match(line) != None:
corret = True
matched_pattern = pattern
if not corret:
raise forms.ValidationError("Not a valid ascii STL file.")
if matched_pattern == facet_pattern:
next_patterns = [loop_pattern]
if matched_pattern == loop_pattern:
vertex_count = 0
next_patterns = [vertex_pattern]
if matched_pattern == vertex_pattern:
vertex_count += 1
if vertex_count < 3:
next_patterns = [vertex_pattern, endloop_pattern]
else :
next_patterns = [endloop_pattern]
if matched_pattern == endloop_pattern:
next_patterns = [endfacet_pattern]
if matched_pattern == endfacet_pattern:
next_patterns = [facet_pattern, endsolid_pattern]
line = stlfile.readline().strip()
if matched_pattern != endsolid_pattern:
raise forms.ValidationError("Not a valid ascii STL file.")
stlfile.close()
return stlfile
class GeometryForm(STLUploadForm):
class Meta:
model = Geometry
fields = ['name', 'description', 'public', 'expiration', 'file', 'sourcefile']
class AnonymousGeometryForm(STLUploadForm):
expiration = forms.ChoiceField(choices=Geometry.EXPIRATION_CHOICES[:-1])
class Meta:
model = Geometry
fields = ['name', 'description', 'public', 'expiration', 'file']