home *** CD-ROM | disk | FTP | other *** search
- # ***** BEGIN LICENSE BLOCK *****
- # Version: MPL 1.1/GPL 2.0/LGPL 2.1
- #
- # The contents of this file are subject to the Mozilla Public License Version
- # 1.1 (the "License"); you may not use this file except in compliance with
- # the License. You may obtain a copy of the License at
- # http://www.mozilla.org/MPL/
- #
- # Software distributed under the License is distributed on an "AS IS" basis,
- # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- # for the specific language governing rights and limitations under the
- # License.
- #
- # The Original Code is the Python Computer Graphics Kit.
- #
- # The Initial Developer of the Original Code is Matthias Baas.
- # Portions created by the Initial Developer are Copyright (C) 2004
- # the Initial Developer. All Rights Reserved.
- #
- # Contributor(s):
- #
- # Alternatively, the contents of this file may be used under the terms of
- # either the GNU General Public License Version 2 or later (the "GPL"), or
- # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- # in which case the provisions of the GPL or the LGPL are applicable instead
- # of those above. If you wish to allow use of your version of this file only
- # under the terms of either the GPL or the LGPL, and not to allow others to
- # use your version of this file under the terms of the MPL, indicate your
- # decision by deleting the provisions above and replace them with the notice
- # and other provisions required by the GPL or the LGPL. If you do not delete
- # the provisions above, a recipient may use your version of this file under
- # the terms of any one of the MPL, the GPL or the LGPL.
- #
- # ***** END LICENSE BLOCK *****
- # $Id: objmaterial.py,v 1.7 2005/08/28 19:42:43 mbaas Exp $
-
- ## \file objmaterial.py
- ## Contains the OBJMaterial class.
-
- import os.path, sys
- import protocols
- from Interfaces import *
- from slots import *
- from material import Material
- import ribexport
- import _Image as Image
- from expression import Expression
- import _core
- from cgtypes import *
-
- # OBJTextureMap
- class OBJTextureMap:
- """A texture map definition as it appears in OBJ/MTL files.
- """
-
- def __init__(self,
- filename,
- offset = (0,0,0),
- scale = (1,1,1),
- turb = (0,0,0),
- mm = (0.0, 1.0),
- clamp = False,
- blendu = True,
- blendv = True,
- bumpsize = None,
- refltype = None):
-
- self.filename = filename
- self.offset = offset
- self.scale = scale
- self.turb = turb
- self.mm = mm
- self.clamp = clamp
- self.blendu = blendu
- self.blendv = blendv
- if bumpsize!=None:
- self.bumpsize = bumpsize
- if refltype!=None:
- self.refltype = refltype
-
-
- # OBJMaterial
- #class OBJMaterial(Material):
- class OBJMaterial(_core.GLMaterial):
- """This class represents a material as it appears in OBJ (or rather MTL) files.
-
- """
-
- protocols.advise(instancesProvide=[ribexport.IMaterial])
-
- def __init__(self,
- name="OBJMaterial",
- illum = 2,
- Ka = (0.2, 0.2, 0.2),
- Kd = (0.8, 0.8, 0.8),
- Ks = (0.0, 0.0, 0.0),
- Ke = (0.0, 0.0, 0.0),
- Ns = 0.0,
- Ni = 1.0,
- d = 1.0,
- Tr = 1.0,
- Tf = (1.0, 1.0, 1.0),
- sharpness = 0.0,
- map_Ka = None,
- map_Kd = None,
- map_Ks = None,
- map_Ke = None,
- map_Ns = None,
- map_d = None,
- map_Bump = None,
- refl = None, # one single map or a list of maps
- density = 1.0,
- ):
-
- # Material.__init__(self, name=name, density=density)
- _core.GLMaterial.__init__(self, name, density)
-
- # Create a Kd slot and connect it with the GL diffuse slot
- self.Kd_slot = Vec3Slot(vec3(Kd))
- self.addSlot("Kd", self.Kd_slot)
- self.diffuse_adapter = Expression("(col.x,col.y,col.z,1)", col=vec3())
- self.Kd_slot.connect(self.diffuse_adapter.col_slot)
- self.diffuse_adapter.output_slot.connect(self.diffuse_slot)
-
- self.illum = illum
- self.Ka = Ka
- # self.Kd = Kd
- self.Ks = Ks
- self.Ke = Ke
- self.Ns = Ns
- self.Ni = Ni
- self.d = d
- self.Tr = Tr
- self.Tf = vec3(Tf)
- self.sharpness = sharpness
- self.map_Ka = map_Ka
- self.map_Kd = map_Kd
- self.map_Ks = map_Ks
- self.map_Ke = map_Ke
- self.map_Ns = map_Ns
- self.map_d = map_d
- self.map_Bump = map_Bump
-
- if refl==None:
- refl = []
- else:
- # Turn refl into a list
- try:
- refl = list(refl)
- except:
- refl = [refl]
- self.refl = refl
-
- # "Hide" the GLMaterial slots
- self.removeSlot("ambient")
- self.removeSlot("diffuse")
- self.removeSlot("specular")
- self.removeSlot("shininess")
- self.removeSlot("emission")
-
- exec slotPropertyCode("Kd")
-
- def mtlDefinition(self):
- s = """illum %d
- Ka %f %f %f
- Kd %f %f %f
- Ks %f %f %f
- Ke %f %f %f
- Ns %f
- Ni %f
- """%(self.illum,
- self.Ka[0], self.Ka[1], self.Ka[2],
- self.Kd[0], self.Kd[1], self.Kd[2],
- self.Ks[0], self.Ks[1], self.Ks[2],
- self.Ke[0], self.Ke[1], self.Ke[2],
- self.Ns,
- self.Ni)
- if self.d!=1.0:
- s += "d %f\n"%self.d
- if self.Tr!=1.0:
- s += "Tr %f\n"%self.d
- if self.Tf[0]!=1.0 or self.Tf[1]!=1.0 or self.Tf[2]!=1.0:
- s += "Tf %f %f %f\n"%(self.Tf[0], self.Tf[1], self.Tf[2])
- s += self.mapDefinition("map_Ka", self.map_Ka)
- s += self.mapDefinition("map_Kd", self.map_Kd)
- s += self.mapDefinition("map_Ks", self.map_Ks)
- s += self.mapDefinition("map_Ke", self.map_Ke)
- s += self.mapDefinition("map_Ns", self.map_Ns)
- s += self.mapDefinition("map_d", self.map_d)
- s += self.mapDefinition("map_Bump", self.map_Bump)
- for map in self.refl:
- s += self.mapDefinition("refl", map)
- return s
-
- # mapDefinition
- def mapDefinition(self, mapname, map):
- """Return the map defintion line or an empty string.
- """
- if map==None:
- return ""
-
- onoff = {True:"on", False:"off"}
-
- res = mapname
- # -o
- u,v,w = map.offset
- if u!=0 or v!=0 or w!=0:
- res += " -o %f %f %f"%(u,v,w)
- # -s
- u,v,w = map.scale
- if u!=1 or v!=1 or w!=1:
- res += " -s %f %f %f"%(u,v,w)
- # -t
- u,v,w = map.turb
- if u!=0 or v!=0 or w!=0:
- res += " -t %f %f %f"%(u,v,w)
- # -mm
- base, gain = map.mm
- if base!=0 or gain!=1:
- res += " -mm %f %f"%(base, gain)
- # -clamp
- if map.clamp:
- res += " -clamp %s"%onoff[map.clamp]
- # -blendu
- if not map.blendu:
- res += " -blendu %s"%onoff[map.blendu]
- # -blendv
- if not map.blendv:
- res += " -blendv %s"%onoff[map.blendv]
- # -bm
- if mapname=="map_Bump" and getattr(map, "bumpsize", 1)!=1:
- res += " -bm %f"%map.bumpsize
- # -type
- if mapname=="refl":
- res += " -type %s"%getattr(map, "refltype", "sphere")
-
- return res+" %s\n"%map.filename
-
-
- def createPasses(self):
- """Returns a list of RenderPass objects."""
- texdefs = []
- if self.map_Ka!=None:
- texdefs.append((self.map_Ka.filename, "periodic", "periodic", "gaussian", 0.01, 0.01, {}))
- if self.map_Kd!=None:
- texdefs.append((self.map_Kd.filename, "periodic", "periodic", "gaussian", 0.01, 0.01, {}))
- if self.map_Ks!=None:
- texdefs.append((self.map_Ks.filename, "periodic", "periodic", "gaussian", 0.01, 0.01, {}))
- if self.map_d!=None:
- texdefs.append((self.map_d.filename, "periodic", "periodic", "gaussian", 0.01, 0.01, {}))
- if self.map_Bump!=None:
- texdefs.append((self.map_Bump.filename, "periodic", "periodic", "gaussian", 0.01, 0.01, {}))
-
- if texdefs!=[]:
- return [ribexport.TexPass(maps=texdefs)]
- else:
- return []
-
- def preProcess(self, exporter):
- """Preprocessing method.
-
- This method is called before the image is rendered and can be used
- to create or copy image maps.
- """
- pass
-
-
- def color(self):
- """Return the color for the RiColor() call or None.
- """
- return None
- # return self.Kd
-
- def opacity(self):
- """Return the opacity for the RiOpacity() call or None.
- """
- return None
- # a = self.Tr*self.d
- # return (a,a,a)
-
- def surfaceShaderName(self):
- """Returns the name of the corresponding surface shader or None.
- """
- return "matobj"
-
- def surfaceShaderSource(self):
- """Returns surface shader source code as a string or None.
-
- If the return value is None, then shaderName() must return
- the name of the shader to use.
- """
- return """// OBJ/MTL material shader
-
- surface $SHADERNAME(float illum = 2;
- color Ka = color "rgb" (0.2, 0.2, 0.2);
- color Kd = color "rgb" (0.8, 0.8, 0.8);
- color Ks = color "rgb" (0.8, 0.8, 0.8);
- color Ke = color "rgb" (0, 0, 0);
- float Ni = 0.0;
- float Ns = 0.0;
- float d = 1.0;
- float Tr = 1.0;
- color Tf = color "rgb" (1.0, 1.0, 1.0);
-
- string map_Ka = "";
- float map_Ka_offset[3] = {0, 0, 0};
- float map_Ka_scale[3] = {1, 1, 1};
-
- string map_Kd = "";
- float map_Kd_offset[3] = {0, 0, 0};
- float map_Kd_scale[3] = {1, 1, 1};
-
- string map_Ks = "";
- float map_Ks_offset[3] = {0, 0, 0};
- float map_Ks_scale[3] = {1, 1, 1};
-
- string map_Ke = "";
- float map_Ke_offset[3] = {0, 0, 0};
- float map_Ke_scale[3] = {1, 1, 1};
-
- string map_Ns = "";
- float map_Ns_offset[3] = {0, 0, 0};
- float map_Ns_scale[3] = {1, 1, 1};
-
- string map_d = "";
- float map_d_offset[3] = {0, 0, 0};
- float map_d_scale[3] = {1, 1, 1};
-
- varying point Pref = point(0,0,0);
- )
- {
- BAKE_BEGIN
- normal Nf = BAKE_NORMAL(N);
- color _Ka = Ka;
- color _Kd = Kd;
- color _Ks = Ks;
- color _Ke = Ke;
- float _Ns = Ns;
- float _d = d;
-
- if (map_Ka!="")
- {
- _Ka = texture(map_Ka,
- s*map_Ka_scale[0]+map_Ka_offset[0],
- (1-t)*map_Ka_scale[1]+map_Ka_offset[1]);
- }
-
- if (map_Kd!="")
- {
- _Kd = texture(map_Kd,
- s*map_Kd_scale[0]+map_Kd_offset[0],
- (1-t)*map_Kd_scale[1]+map_Kd_offset[1]);
- }
-
- if (map_Ks!="")
- {
- _Ks = texture(map_Ks,
- s*map_Ks_scale[0]+map_Ks_offset[0],
- (1-t)*map_Ks_scale[1]+map_Ks_offset[1]);
- }
-
- if (map_Ke!="")
- {
- _Ke = texture(map_Ke,
- s*map_Ke_scale[0]+map_Ke_offset[0],
- (1-t)*map_Ke_scale[1]+map_Ke_offset[1]);
- }
-
- if (map_Ns!="")
- {
- _Ns = texture(map_Ns,
- s*map_Ns_scale[0]+map_Ns_offset[0],
- (1-t)*map_Ns_scale[1]+map_Ns_offset[1]);
- }
-
- if (map_d!="")
- {
- _d = texture(map_d,
- s*map_d_scale[0]+map_d_offset[0],
- (1-t)*map_d_scale[1]+map_d_offset[1]);
- }
-
- if (illum==0)
- {
- Ci = _Kd;
- }
- else if (illum==1)
- {
- Ci = _Ka + _Kd*diffuse(Nf);
- }
- else
- {
- // Ns==0? then disable specular part
- if (_Ns<1E-6)
- {
- _Ks = color "rgb" (0,0,0);
- }
- Ci = _Ka*ambient() + _Kd*diffuse(Nf) + _Ks*specular(Nf,-normalize(I),1/_Ns) + _Ke;
- }
-
- Oi = _d*Tr*Tf;
- Ci *= Oi;
- BAKE_END
- }
- """
-
- def surfaceShaderParams(self, passes):
- """Return a dictionary with shader parameters and their values."""
- res = {"uniform float illum" : self.illum,
- "uniform color Ka" : self.Ka,
- "uniform color Kd" : self.Kd,
- "uniform color Ks" : self.Ks,
- "uniform color Ke" : self.Ke,
- "uniform float Ns" : self.Ns,
- "uniform float Ni" : self.Ni,
- "uniform float d" : self.d,
- "uniform float Tr" : self.Tr,
- "uniform color Tf" : self.Tf
- }
-
- if self.map_Ka!=None:
- texname = os.path.basename(self.map_Ka.filename)
- name, ext = os.path.splitext(texname)
- res["uniform string map_Ka"] = name+".tex"
- res["uniform float[3] map_Ka_offset"] = self.map_Ka.offset
- res["uniform float[3] map_Ka_scale"] = self.map_Ka.scale
-
- if self.map_Kd!=None:
- texname = os.path.basename(self.map_Kd.filename)
- name, ext = os.path.splitext(texname)
- res["uniform string map_Kd"] = name+".tex"
- res["uniform float[3] map_Kd_offset"] = self.map_Kd.offset
- res["uniform float[3] map_Kd_scale"] = self.map_Kd.scale
-
- if self.map_Ks!=None:
- texname = os.path.basename(self.map_Ks.filename)
- name, ext = os.path.splitext(texname)
- res["uniform string map_Ks"] = name+".tex"
- res["uniform float[3] map_Ks_offset"] = self.map_Ks.offset
- res["uniform float[3] map_Ks_scale"] = self.map_Ks.scale
-
- if self.map_Ke!=None:
- texname = os.path.basename(self.map_Ke.filename)
- name, ext = os.path.splitext(texname)
- res["uniform string map_Ke"] = name+".tex"
- res["uniform float[3] map_Ke_offset"] = self.map_Ke.offset
- res["uniform float[3] map_Ke_scale"] = self.map_Ke.scale
-
- if self.map_Ns!=None:
- texname = os.path.basename(self.map_Ns.filename)
- name, ext = os.path.splitext(texname)
- res["uniform string map_Ns"] = name+".tex"
- res["uniform float[3] map_Ns_offset"] = self.map_Ns.offset
- res["uniform float[3] map_Ns_scale"] = self.map_Ns.scale
-
- if self.map_d!=None:
- texname = os.path.basename(self.map_d.filename)
- name, ext = os.path.splitext(texname)
- res["uniform string map_d"] = name+".tex"
- res["uniform float[3] map_d_offset"] = self.map_d.offset
- res["uniform float[3] map_d_scale"] = self.map_d.scale
-
- return res
-
- def surfaceShaderTransform(self):
- return mat4(1)
-
- def displacementShaderName(self):
- if self.map_Bump==None:
- return None
-
- return "matobj_bump"
-
-
- def displacementShaderSource(self):
- if self.map_Bump==None:
- return None
-
- return """// OBJ/MTL material shader (bump)
-
- displacement $SHADERNAME(
- string map_Bump = "";
- float bump_size = 1.0;
- float map_Bump_offset[3] = {0, 0, 0};
- float map_Bump_scale[3] = {1, 1, 1};
- )
- {
- float amount = 0;
-
- if (map_Bump!="")
- {
- color bc = texture(map_Bump,
- s*map_Bump_scale[0]+map_Bump_offset[0],
- (1-t)*map_Bump_scale[1]+map_Bump_offset[1]);
- amount = (comp(bc,0)+comp(bc,1)+comp(bc,2))/3;
- }
-
- P = P + bump_size*amount*normalize(N);
- N = calculatenormal(P);
- }
- """
-
- def displacementShaderParams(self, passes):
- if self.map_Bump==None:
- return {}
-
- res = {}
- texname = os.path.basename(self.map_Bump.filename)
- name, ext = os.path.splitext(texname)
- res["uniform string map_Bump"] = name+".tex"
- res["uniform float bump_size"] = getattr(self.map_Bump, "bumpsize", 1.0)
- res["uniform float[3] map_Bump_offset"] = self.map_Bump.offset
- res["uniform float[3] map_Bump_scale"] = self.map_Bump.scale
- return res
-
- def displacementShaderTransform(self):
- return mat4(1)
-
- def displacementBound(self):
- if self.map_Bump==None:
- return "current", 0
- else:
- return "current", abs(getattr(self.map_Bump, "bumpsize", 1.0))
-
- def interiorShaderName(self):
- return None
-
- def interiorShaderSource(self):
- return None
-
- def interiorShaderParams(self, passes):
- return {}
-
- def interiorShaderTransform(self):
- return mat4(1)
-
-
-