summaryrefslogtreecommitdiff
path: root/trunk/users/vasile/stl2gcode/povray.py
blob: 6f9f41079822b9260820b48b381005257d5496a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
## povray.py is Copyright (C) 2008 James Vasile.  It is free software;
## you can redistribute it and/or modify it under the terms of the GNU
## General Public License as published by the Free Software
## Foundation; either version 3 of the License, or any later version.

## povray.py is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.  You should have received
## a copy of the GNU General Public License along with the work; if
## not, write to the Free Software Foundation, Inc., 51 Franklin
## Street, 5th Floor, Boston, MA 02110-1301 USA
##
## Not tested on Windows or Mac boxes.

from miscellaneous import *
import re

class object:
    '''POVRAY include object'''
    x = X = y = Y = z = Z = None
    code = None
    __name = None

    def __init__(self, str = ''):
        # empty is no initial code, one line is a filespec, multiline is code
        import re
        p = re.compile("\n")
        m = re.search(p, str)
        if str:
            if m: self.code = str  # it's code
            else:  # it's a filespec
                ## TODO: error handling
                self.code = slurp_file(str)

    def name(self):
        if self.__name: return self.__name
        p = re.compile('\#declare\s*(\w*)\s*=\s*[object|mesh]')
        m = re.search(p, self.code)
        if not m:
            print fname+".inc improperly formatted.  Can't find object name.\n"
            sys.exit(2)
        self.__name = m.group(1)
        return self.__name

    def min_max(self):
        '''Calculates the min and max for x, y, and z.
        Assumes the object is a mesh of triangles
        or that the inc file contains #declares tellings us the min and max
        TODO: DTRT if the object is an SDL object'''

        ## if inc file has #declares telling us the min max, read it and use it
        ret = 0;
        regex = re.compile('\s*#declare\s*(m..)_([x|y|z])\s*=\s*([-\.0123456789]*)')
        for declare in re.finditer(regex, self.code):
            var = declare.group(2)
            if declare.group(1) == 'max': var = var.capitalize()
            exec('self.' + var + ' = float(' + str(declare.group(3)) + ')')
            ret = 1
        if ret: return

        ## otherwise, calculate min and max from the mesh
        self.x = self.y = self.z = 9999999999
        self.X = self.Y = self.Z = -9999999999


        tri_regex = re.compile('triangle {.*?\n(.*?\n.*?\n.*?)\n')
        for tri in re.finditer(tri_regex, self.code):
            vertex_regex = re.compile ('<(.*?)>');
            for vertex in re.finditer(vertex_regex, tri.group(1)):
                (x, y, z) = vertex.group(1).split(', ', 2)
                if float(x) < self.x: self.x = float(x)
                if float(x) > self.X: self.X = float(x)
                if float(y) < self.y: self.y = float(y)
                if float(y) > self.Y: self.Y = float(y)
                if float(z) < self.z: self.z = float(z)
                if float(z) > self.Z: self.Z = float(z)


    def min_x(self):
        if self.x: return self.x
        else: self.min_max()
        return self.x

    def max_x(self):
        if self.X: return self.X
        else: self.min_max()
        return self.X

    def min_y(self):
        if self.y: return self.y
        else: self.min_max()
        return self.y

    def max_y(self):
        if self.Y: return self.Y
        else: self.min_max()
        return self.Y

    def min_z(self):
        if self.z: return self.z
        else: self.min_max()
        return self.z

    def max_z(self):
        if self.Z: return self.Z
        else: self.min_max()
        return self.Z