Panda3D
mayaShaders.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file mayaShaders.cxx
10  * @author drose
11  * @date 2000-02-11
12  */
13 
14 #include "mayaShaders.h"
15 #include "mayaShader.h"
16 #include "maya_funcs.h"
17 #include "config_maya.h"
18 
19 #include "pre_maya_include.h"
20 #include <maya/MStatus.h>
21 #include <maya/MObject.h>
22 #include <maya/MFnDependencyNode.h>
23 #include <maya/MFnMesh.h>
24 #include <maya/MObjectArray.h>
25 #include <maya/MPlug.h>
26 #include <maya/MPlugArray.h>
27 #include <maya/MFn.h>
28 #include "post_maya_include.h"
29 
30 using std::string;
31 
32 /**
33  *
34  */
35 MayaShaders::
36 MayaShaders() {
37 }
38 
39 /**
40  *
41  */
42 MayaShaders::
43 ~MayaShaders() {
44  clear();
45 }
46 
47 /**
48  * Extracts the shader assigned to the indicated node.
49  */
51 find_shader_for_node(MObject node, bool legacy_shader) {
52  MStatus status;
53  MFnDependencyNode node_fn(node);
54  // Look on the instObjGroups attribute for shading engines.
55  MObject iog_attr = node_fn.attribute("instObjGroups", &status);
56  if (!status) {
57  // The node is not renderable. What are you thinking?
58  maya_cat.error()
59  << node_fn.name().asChar() << " : not a renderable object.\n";
60  return nullptr;
61  }
62 
63  // instObjGroups is a multi attribute, whatever that means. For now, we'll
64  // just get the first connection, since that's what the example code did.
65  // Is there any reason to search deeper?
66 
67  MPlug iog_plug(node, iog_attr);
68  MPlugArray iog_pa;
69  iog_plug.elementByLogicalIndex(0).connectedTo(iog_pa, false, true, &status);
70  if (!status) {
71  // No shading group defined for this object.
72  maya_cat.error()
73  << node_fn.name().asChar() << " : no shading group defined.\n";
74  return nullptr;
75  }
76 
77  // Now we have a number of ShadingEngines defined, one for each of these
78  // connections we just turned up. Usually there will only be one. In fact,
79  // we'll just take the first one we find.
80 
81  size_t i;
82  for (i = 0; i < iog_pa.length(); i++) {
83  MObject engine = iog_pa[i].node();
84  if (engine.hasFn(MFn::kShadingEngine)) {
85  return find_shader_for_shading_engine(engine, legacy_shader);
86  }
87  }
88 
89  // Well, we didn't find a ShadingEngine after all. Huh.
90  maya_cat.debug()
91  << node_fn.name().asChar() << " : no shading engine found.\n";
92  return nullptr;
93 }
94 
95 /**
96  * Causes all shaders in the set to use the given mesh as a file-to-uvset map.
97  */
99 bind_uvsets(MObject mesh) {
100  _uvset_names.clear();
101  _file_to_uvset.clear();
102 
103  if (mesh.hasFn(MFn::kMesh)) {
104  MFnMesh mesh_fn(mesh);
105  MStatus status;
106  MStringArray maya_uvset_names;
107  status = mesh_fn.getUVSetNames(maya_uvset_names);
108  for (size_t i=0; i<maya_uvset_names.length(); ++i) {
109  MObjectArray moa;
110  string uvset_name = maya_uvset_names[i].asChar();
111  _uvset_names.push_back(uvset_name);
112  mesh_fn.getAssociatedUVSetTextures(maya_uvset_names[i], moa);
113  for (size_t j=0; j<moa.length(); ++j){
114  MFnDependencyNode dt(moa[j]);
115  string tex_name = dt.name().asChar();
116  _file_to_uvset[tex_name] = uvset_name;
117  }
118  }
119  }
120 
121  Shaders::iterator sha;
122  for (sha=_shaders.begin(); sha!=_shaders.end(); sha++) {
123  (*sha).second->bind_uvsets(_file_to_uvset);
124  }
125 }
126 
127 /**
128  * Returns the MayaShader object associated with the indicated "shading
129  * engine". This will create a new MayaShader object if this is the first
130  * time we have encountered the indicated engine.
131  */
133 find_shader_for_shading_engine(MObject engine, bool legacy_shader) {
134  MFnDependencyNode engine_fn(engine);
135  // See if we have already decoded this engine.
136  string engine_name = engine_fn.name().asChar();
137  Shaders::const_iterator si = _shaders.find(engine_name);
138  if (si != _shaders.end()) {
139  return (*si).second;
140  }
141 
142  // All right, this is a newly encountered shading engine. Create a new
143  // MayaShader object to represent it.
144  MayaShader *shader = new MayaShader(engine, legacy_shader);
145  shader->bind_uvsets(_file_to_uvset);
146 
147  // Record this for the future.
148  _shaders.insert(Shaders::value_type(engine_name, shader));
149  _shaders_in_order.push_back(shader);
150  return shader;
151 }
152 
153 /**
154  * Returns the current mapping from file to uvset for the given file texture
155  * name.
156  */
158 find_uv_link(const string &match) {
159  MayaFileToUVSetMap::iterator it = _file_to_uvset.find(match);
160  if (it == _file_to_uvset.end()) {
161  return "not found";
162  } else {
163  return (*it).second;
164  }
165 }
166 
167 /**
168  * Returns the number of unique MayaShaders that have been discovered so far.
169  */
171 get_num_shaders() const {
172  return _shaders_in_order.size();
173 }
174 
175 /**
176  * Returns the nth MayaShader that has been discovered so far.
177  */
179 get_shader(int n) const {
180  nassertr(n >= 0 && n < (int)_shaders_in_order.size(), nullptr);
181  return _shaders_in_order[n];
182 }
183 
184 /**
185  * Frees all of the previously-defined MayaShader objects associated with this
186  * set.
187  */
189 clear() {
190  ShadersInOrder::iterator si;
191  for (si = _shaders_in_order.begin(); si != _shaders_in_order.end(); ++si) {
192  delete (*si);
193  }
194 
195  _shaders.clear();
196  _shaders_in_order.clear();
197  _file_to_uvset.clear();
198 }
Corresponds to a single "shader" in Maya.
Definition: mayaShader.h:30
void bind_uvsets(MayaFileToUVSetMap &map)
Assigns the uvset_name of each MayaShaderColorDef using the given file-to- uvset map.
Definition: mayaShader.cxx:255
void clear()
Frees all of the previously-defined MayaShader objects associated with this set.
void bind_uvsets(MObject mesh)
Causes all shaders in the set to use the given mesh as a file-to-uvset map.
Definition: mayaShaders.cxx:99
MayaShader * find_shader_for_shading_engine(MObject engine, bool legacy_shader)
Returns the MayaShader object associated with the indicated "shading engine".
MayaShader * get_shader(int n) const
Returns the nth MayaShader that has been discovered so far.
int get_num_shaders() const
Returns the number of unique MayaShaders that have been discovered so far.
std::string find_uv_link(const std::string &match)
Returns the current mapping from file to uvset for the given file texture name.
MayaShader * find_shader_for_node(MObject node, bool legacy_shader)
Extracts the shader assigned to the indicated node.
Definition: mayaShaders.cxx:51
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.