Source code for pi3d.loader.parse_mtl

from collections import namedtuple

import logging

LOGGER = logging.getLogger(__name__)

RAISE_EXCEPTION_ON_ERROR = True

def _error(args, exception=None):
  LOGGER.error(*args)
  if RAISE_EXCEPTION_ON_ERROR:
    raise exception or Exception()

[docs]class Materials(object): NEW_MATERIAL_CHUNK = 'newmtl' float3_f = lambda x, y, z: [float(x), float(y), float(z)] float_f = lambda x: float(x) int_f = lambda x: int(x) str_f = lambda x: str(x) Prop = namedtuple('Prop', ['name', 'func']) PROPERTIES = { 'Ka': Prop('colorAmbient', float3_f), 'Kd': Prop('colorDiffuse', float3_f), 'Ks': Prop('colorSpecular', float3_f), 'Ke': Prop('colorEmissive', float3_f), 'Ni': Prop('opticalDensity', float_f), 'Ns': Prop('specularCoef', float_f), 'Tr': Prop('transparency', float_f), 'Tf': Prop('colorTransparency', float3_f), 'bump': Prop('mapBump', str_f), 'd': Prop('transparency', float_f), 'illum': Prop('illumination', int_f), 'map_Ka': Prop('mapAmbient', str_f), 'map_Kd': Prop('mapDiffuse', str_f), 'map_Ks': Prop('mapSpecular', str_f), 'map_Bump': Prop('mapBump', str_f), 'map_d': Prop('mapAlpha', str_f), } def __init__(self): self.identifier = None self.materials = {} self.material = {}
[docs] def parse_lines(self, lines): for line in lines: self.parse_line(line) return self.materials
[docs] def parse_line(self, line): line = line.strip() if not line.startswith('#'): chunks = line.strip().split() if chunks: name = chunks[0] args = chunks[1:] if name == Materials.NEW_MATERIAL_CHUNK: self.set_identifier(args, line) else: self.set_property(name, args)
[docs] def set_identifier(self, args, line): if not args: self.identifier = '' else: self.identifier = args[0].strip() if len(args) > 1: LOGGER.warning('too many arguments in identifier line "%s"', line) self.material = self.materials.get(self.identifier, {}) self.materials[self.identifier] = self.material
[docs] def set_property(self, name, args): prop = Materials.PROPERTIES.get(name, None) if not prop: LOGGER.error('ERROR: Don\'t understand property "%s"', name) if RAISE_EXCEPTION_ON_ERROR: raise Exception() else: if prop.name in self.material: LOGGER.warning('duplicate property %s in %s', prop.name, name) try: self.material[prop.name] = prop.func(*args) except: LOGGER.error('Couldn\'t set %s with args "%s"', name, args) if RAISE_EXCEPTION_ON_ERROR: raise
[docs]def parse_mtl(lines): """Parse MTL file. """ return Materials().parse_lines(lines)