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  */
98 void MayaShaders::
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  */
157 string MayaShaders::
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  */
170 int MayaShaders::
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  */
188 void MayaShaders::
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 }
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_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.
MayaShader * get_shader(int n) const
Returns the nth MayaShader that has been discovered so far.
Corresponds to a single "shader" in Maya.
Definition: mayaShader.h:30
MayaShader * find_shader_for_shading_engine(MObject engine, bool legacy_shader)
Returns the MayaShader object associated with the indicated "shading engine".
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
MayaShader(MObject engine, bool legacy_shader)
Reads the Maya "shading engine" to determine the relevant shader properties.
Definition: mayaShader.cxx:43
std::string find_uv_link(const std::string &match)
Returns the current mapping from file to uvset for the given file texture name.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear()
Frees all of the previously-defined MayaShader objects associated with this set.
int get_num_shaders() const
Returns the number of unique MayaShaders that have been discovered so far.
void bind_uvsets(MayaFileToUVSetMap &map)
Assigns the uvset_name of each MayaShaderColorDef using the given file-to- uvset map.
Definition: mayaShader.cxx:255
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.