17 #include "mayaShader.h"
18 #include "maya_funcs.h"
19 #include "config_maya.h"
20 #include "string_utils.h"
21 #include "pnmImageHeader.h"
24 #include "pre_maya_include.h"
25 #include <maya/MFnDependencyNode.h>
26 #include <maya/MFnLambertShader.h>
27 #include <maya/MFnPhongShader.h>
28 #include <maya/MFnMesh.h>
29 #include <maya/MPlug.h>
30 #include <maya/MPlugArray.h>
31 #include <maya/MColor.h>
32 #include <maya/MObject.h>
33 #include <maya/MStatus.h>
34 #include "post_maya_include.h"
44 MFnDependencyNode engine_fn(engine);
46 set_name(engine_fn.name().asChar());
48 if (maya_cat.is_debug()) {
50 <<
"Reading shading engine " << get_name() <<
"\n";
53 _flat_color.set(1,1,1,1);
55 MPlug shader_plug = engine_fn.findPlug(
"surfaceShader");
56 bool found_shader =
false;
57 if (!shader_plug.isNull()) {
59 shader_plug.connectedTo(shader_pa,
true,
false);
60 maya_cat.spam() <<
"shader plug connected to: " << shader_pa.length() << endl;
61 for (
size_t i = 0; i < shader_pa.length() && !found_shader; i++) {
62 MObject shader = shader_pa[0].node();
63 if (shader.hasFn(MFn::kPhong)) {
65 found_shader = find_textures_legacy(shader);
67 found_shader = find_textures_modern(shader);
69 }
else if (shader.hasFn(MFn::kLambert)) {
70 found_shader = find_textures_legacy(shader);
74 }
else if (shader.hasFn(MFn::kSurfaceShader)) {
75 found_shader = find_textures_legacy(shader);
81 "Unrecognized shader type: only lambert and phong supported (lambert deprecated).\n";
102 output(ostream &out)
const {
103 out <<
"Shader " << get_name();
112 write(ostream &out)
const {
113 out <<
"Shader " << get_name() <<
"\n";
124 if (_color.size() > 0)
144 LColor rgba(1.0f, 1.0f, 1.0f, 1.0f);
146 if (_color.size() && _color[idx]->_has_flat_color) {
147 rgba[0] = (PN_stdfloat)_color[idx]->_flat_color[0];
148 rgba[1] = (PN_stdfloat)_color[idx]->_flat_color[1];
149 rgba[2] = (PN_stdfloat)_color[idx]->_flat_color[2];
152 if (_transparency._has_flat_color) {
157 _transparency._flat_color[0] * lumin_red +
158 _transparency._flat_color[1] * lumin_grn +
159 _transparency._flat_color[2] * lumin_blu;
160 rgba[3] = 1.0f - (PN_stdfloat)trans;
175 for (
size_t i=0; i<_color_maps.size(); i++) {
176 _all_maps.push_back(_color_maps[i]);
178 for (
size_t i=0; i<_trans_maps.size(); i++) {
179 _all_maps.push_back(_trans_maps[i]);
181 for (
size_t i=0; i<_normal_maps.size(); i++) {
182 _all_maps.push_back(_normal_maps[i]);
184 for (
size_t i=0; i<_glow_maps.size(); i++) {
185 _all_maps.push_back(_glow_maps[i]);
187 for (
size_t i=0; i<_gloss_maps.size(); i++) {
188 _all_maps.push_back(_gloss_maps[i]);
190 for (
size_t i=0; i<_height_maps.size(); i++) {
191 _all_maps.push_back(_height_maps[i]);
194 for (
size_t i=0; i<_color.size(); i++) {
195 if (_color[i]->_has_texture) {
196 _all_maps.push_back(_color[i]);
199 if (_transparency._has_texture) {
200 _all_maps.push_back(&_transparency);
211 find_textures_modern(MObject shader) {
212 if (!shader.hasFn(MFn::kPhong)) {
214 <<
"The new codepath expects to see phong shaders only.\n";
218 MFnPhongShader phong_fn(shader);
219 MFnDependencyNode shader_fn(shader);
221 if (maya_cat.is_spam()) {
223 <<
" Reading modern surface shader " << shader_fn.name().asChar() <<
"\n";
226 string n = shader_fn.name().asChar();
228 MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug(
"color"),
false);
229 if (_color_maps.size() == 0) {
230 MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug(
"colorR"),
false);
232 MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug(
"transparency"),
true);
233 if (_trans_maps.size() == 0) {
234 MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug(
"transparencyR"),
true);
236 MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug(
"normalCamera"),
false);
237 if (_normal_maps.size() == 0) {
238 MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug(
"normalCameraR"),
false);
240 MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug(
"specularColor"),
true);
241 if (_gloss_maps.size() == 0) {
242 MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug(
"specularColorR"),
true);
244 MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug(
"incandescence"),
true);
245 if (_glow_maps.size() == 0) {
246 MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug(
"incandescenceR"),
true);
248 MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug(
"surfaceThickness"),
true);
249 if (_height_maps.size() == 0) {
250 MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug(
"surfaceThicknessR"),
true);
255 MColor
color = phong_fn.color(&status);
257 _flat_color.set(color.r, color.g, color.b, color.a);
260 color = phong_fn.transparency(&status);
262 _flat_color[3] = 1.0 - ((color[0] + color[1] + color[2]) * (1.0/3.0));
275 for (
size_t i=0; i<_all_maps.size(); i++) {
277 MayaFileToUVSetMap::iterator p = map.find(def->_texture_name);
278 if (p == map.end()) {
279 def->_uvset_name =
"map1";
281 def->_uvset_name = (*p).second;
285 calculate_pairings();
298 calculate_pairings() {
304 for (
size_t i=0; i<_all_maps.size(); i++) {
305 _all_maps[i]->_opposite = 0;
308 bool using_transparency = (_trans_maps.size() > 0);
310 for (
int retry=0; retry<2; retry++) {
311 bool perfect=(retry==0);
312 for (
size_t i=0; i<_color_maps.size(); i++) {
313 if ((_color_maps[i]->_blend_type == MayaShaderColorDef::BT_modulate)||
314 (_color_maps[i]->_blend_type == MayaShaderColorDef::BT_unspecified)) {
315 for (
size_t j=0; j<_trans_maps.size(); j++) {
316 try_pair(_color_maps[i], _trans_maps[j], perfect);
322 if (!using_transparency) {
323 for (
int retry=0; retry<2; retry++) {
324 bool perfect=(retry==0);
325 for (
size_t i=0; i<_color_maps.size(); i++) {
326 for (
size_t j=0; j<_glow_maps.size(); j++) {
327 try_pair(_color_maps[i], _glow_maps[j], perfect);
329 for (
size_t j=0; j<_gloss_maps.size(); j++) {
330 try_pair(_color_maps[i], _gloss_maps[j], perfect);
336 for (
int retry=0; retry<2; retry++) {
337 bool perfect=(retry==0);
338 for (
size_t i=0; i<_normal_maps.size(); i++) {
339 for (
size_t j=0; j<_height_maps.size(); j++) {
340 try_pair(_normal_maps[i], _height_maps[j], perfect);
345 for (
size_t i=0; i<_normal_maps.size(); i++) {
346 _normal_maps[i]->_blend_type = MayaShaderColorDef::BT_normal;
348 for (
size_t i=0; i<_glow_maps.size(); i++) {
349 if (_glow_maps[i]->_opposite) {
350 _glow_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
351 _glow_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_glow;
353 _glow_maps[i]->_blend_type = MayaShaderColorDef::BT_glow;
356 for (
size_t i=0; i<_gloss_maps.size(); i++) {
357 if (_gloss_maps[i]->_opposite) {
358 _gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
359 _gloss_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_gloss;
361 _gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_gloss;
364 for (
size_t i=0; i<_height_maps.size(); i++) {
365 if (_height_maps[i]->_opposite) {
366 _height_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
367 _height_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_normal_height;
369 _height_maps[i]->_blend_type = MayaShaderColorDef::BT_height;
372 for (
size_t i=0; i<_trans_maps.size(); i++) {
373 if (_trans_maps[i]->_opposite) {
374 _trans_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
375 _trans_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate;
377 _trans_maps[i]->_blend_type = MayaShaderColorDef::BT_modulate;
390 if ((map1->_opposite)||(map2->_opposite)) {
395 if (map1->_texture_filename != map2->_texture_filename) {
400 string pre1 = get_file_prefix(map1->_texture_filename);
401 string pre2 = get_file_prefix(map2->_texture_filename);
408 if ((map1->_projection_type != map2->_projection_type) ||
409 (map1->_projection_matrix != map2->_projection_matrix) ||
410 (map1->_u_angle != map2->_u_angle) ||
411 (map1->_v_angle != map2->_v_angle) ||
412 (map1->_uvset_name != map2->_uvset_name) ||
413 (map1->_mirror != map2->_mirror) ||
414 (map1->_stagger != map2->_stagger) ||
415 (map1->_wrap_u != map2->_wrap_u) ||
416 (map1->_wrap_v != map2->_wrap_v) ||
417 (map1->_repeat_uv != map2->_repeat_uv) ||
418 (map1->_offset != map2->_offset) ||
419 (map1->_rotate_uv != map2->_rotate_uv)) {
423 map1->_opposite = map2;
424 map2->_opposite = map1;
434 get_file_prefix(
const string &fn) {
437 size_t offs = base.find(
"_");
438 if (offs != string::npos) {
439 base = base.substr(0, offs);
441 offs = base.find(
"-");
442 if (offs != string::npos) {
443 base = base.substr(0, offs);
456 find_textures_legacy(MObject shader) {
458 MFnDependencyNode shader_fn(shader);
460 if (maya_cat.is_spam()) {
462 <<
" Reading legacy surface shader " << shader_fn.name().asChar() <<
"\n";
469 MPlug color_plug = shader_fn.findPlug(
"color");
470 if (color_plug.isNull()) {
474 color_plug = shader_fn.findPlug(
"outColor");
477 if (!color_plug.isNull()) {
479 color_plug.connectedTo(color_pa,
true,
false);
482 for (
size_t i = 0; i < color_pa.length(); i++) {
483 maya_cat.spam() <<
"color_pa[" << i <<
"]:" << color_pa[i].name().asChar() << endl;
484 color_p->find_textures_legacy(
this, color_pa[0].node());
487 if (color_pa.length() < 1) {
489 maya_cat.spam() << shader_fn.name().asChar() <<
" was not connected to texture" << endl;
490 this->_color.push_back(color_p);
495 MPlug trans_plug = shader_fn.findPlug(
"transparency");
496 if (trans_plug.isNull()) {
497 trans_plug = shader_fn.findPlug(
"outTransparency");
500 if (!trans_plug.isNull()) {
502 trans_plug.connectedTo(trans_pa,
true,
false);
504 for (
size_t i = 0; i < trans_pa.length(); i++) {
505 maya_cat.spam() <<
"read a transparency texture" << endl;
506 _transparency.find_textures_legacy(
this, trans_pa[0].node(),
true);
512 bool b_color_def =
true;
513 if (shader.hasFn(MFn::kLambert)) {
514 MFnLambertShader lambert_fn(shader);
515 MColor color = lambert_fn.color(&status);
519 for (
size_t i=0; i<_color.size(); ++i) {
520 _color[i]->_has_flat_color =
true;
521 _color[i]->_flat_color.set(color.r, color.g, color.b, color.a);
522 maya_cat.spam() << shader_fn.name().asChar() <<
" set shader color" << endl;
524 if (!_color[i]->_has_flat_color && !_color[i]->_has_texture)
527 _transparency._flat_color.set(0.0, 0.0, 0.0, 0.0);
530 color = lambert_fn.transparency(&status);
532 _transparency._has_flat_color =
true;
533 _transparency._flat_color.set(color.r, color.g, color.b, color.a);
540 maya_cat.info() << shader_fn.name().asChar() <<
"Color def not found" << endl;
541 if (maya_cat.is_spam()) {
543 <<
" Color definition not found.\n";
LColor get_rgba(size_t idx=0) const
Returns the overall color of the shader as a single-precision rgba value, where the alpha component r...
void collect_maps()
Recalculates the all_maps list.
The name of a file, such as a texture file or an Egg file.
This defines the various attributes that Maya may associate with the "color" channel for a particular...
MayaShaderColorDef * get_color_def(size_t idx=0) const
This is part of the deprecated codepath.
This is the base class for all three-component vectors and points.
string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
MayaShader(MObject engine, bool legacy_shader)
Reads the Maya "shading engine" to determine the relevant shader properties.
void bind_uvsets(MayaFileToUVSetMap &map)
Assigns the uvset_name of each MayaShaderColorDef using the given file-to-uvset map.
static Filename from_os_specific(const string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes, and no drive letter) based on the supplied filename string that describes a filename in the local system conventions (for instance, on Windows, it may use backslashes or begin with a drive letter and a colon).