OBJ.parse()   F
last analyzed

Complexity

Conditions 18

Size

Total Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 18
dl 0
loc 67
rs 2.6879
c 2
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like OBJ.parse() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from ed2d.assets.mtlloader import MTL
2
from ed2d import files
3
4
class OBJ(object):
5
    def __init__(self, fileName):
6
        ''' Wavefront .obj file parser.'''
7
        objPath = files.resolve_path('data', 'models', fileName + '.obj')
8
9
        self.fmvnig = {}
10
11
        # Shared temporary storage of data
12
        self.tempVertices = []
13
        self.tempNormals = []
14
        self.tempUVs = []
15
16
        # Load the obj file
17
        with open(objPath, 'r') as objfile:
18
            self.lines = objfile.readlines()
19
20
        self.parse()
21
22
23
    def parse(self):
24
        ''' Perform the parsing of the obj format  '''
25
26
        matname = None
27
        valueType = None
28
29
        for line in self.lines:
30
            valueType, value = line.strip().split(' ', 1)
31
32
            # Don't bother unless the following key words exist in the line
33
            if valueType not in ['o', 'g', 'f', 'v', 'vt', 'vn', 'usemtl', 'mtllib']:
34
                continue
35
36
            value = value.split(' ')
37
38
            # Check first and continue on early because of string splitting
39
            if valueType == "usemtl":
40
                matname = value[0]
41
                continue
42
43
            if valueType in ['g', 'o']:
44
                # These objects reset state basically
45
                matname = None
46
                continue
47
48
            if valueType == 'mtllib':
49
                mtlpath = files.resolve_path('data', 'models', value[0])
50
51
                # Load the mtl file
52
                self.mtlfile = MTL(mtlpath)
53
                for material in self.mtlfile.data.keys():
54
                    self.fmvnig[material] = [ [], [], [] ]
55
56
                continue
57
58
            if valueType == "f":
59
                face = [item.split("/") for item in value]
60
                for typeGroup in face:
61
                    for typeIndex in range(len(typeGroup)):
62
                        if typeIndex == 0: # Vertex
63
                            typeSource = self.tempVertices
64
                        elif typeIndex == 1: # UV
65
                            typeSource = self.tempUVs
66
                        elif typeIndex == 2: # Normal
67
                            typeSource = self.tempNormals
68
69
                        index = typeGroup[typeIndex]
70
71
                        # Make sure data exists
72
                        if index != '':
73
                            index = int(index)
74
                            typeData = typeSource[index - 1]
75
76
                            self.fmvnig[matname][typeIndex].append(typeData)
77
                continue
78
79
            # Map the values after the keyword to floats
80
            value = list(map(float, value))
81
82
            if valueType == "v":
83
                self.tempVertices.append(value)
84
85
            elif valueType == "vt":
86
                self.tempUVs.append(value * 2)
87
88
            elif valueType == "vn":
89
                self.tempNormals.append(value)
90