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 */
50 MayaShader *MayaShaders::
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 */
132 MayaShader *MayaShaders::
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::
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 */
178 MayaShader *MayaShaders::
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 }
MayaShader
Corresponds to a single "shader" in Maya.
Definition: mayaShader.h:30
MayaShader::bind_uvsets
void bind_uvsets(MayaFileToUVSetMap &map)
Assigns the uvset_name of each MayaShaderColorDef using the given file-to- uvset map.
Definition: mayaShader.cxx:255
MayaShaders::clear
void clear()
Frees all of the previously-defined MayaShader objects associated with this set.
Definition: mayaShaders.cxx:189
MayaShaders::bind_uvsets
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
MayaShaders::find_shader_for_shading_engine
MayaShader * find_shader_for_shading_engine(MObject engine, bool legacy_shader)
Returns the MayaShader object associated with the indicated "shading engine".
Definition: mayaShaders.cxx:133
MayaShaders::get_shader
MayaShader * get_shader(int n) const
Returns the nth MayaShader that has been discovered so far.
Definition: mayaShaders.cxx:179
MayaShaders::get_num_shaders
int get_num_shaders() const
Returns the number of unique MayaShaders that have been discovered so far.
Definition: mayaShaders.cxx:171
MayaShaders::find_uv_link
std::string find_uv_link(const std::string &match)
Returns the current mapping from file to uvset for the given file texture name.
Definition: mayaShaders.cxx:158
MayaShaders::find_shader_for_node
MayaShader * find_shader_for_node(MObject node, bool legacy_shader)
Extracts the shader assigned to the indicated node.
Definition: mayaShaders.cxx:51
config_maya.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
mayaShader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
mayaShaders.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
maya_funcs.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
post_maya_include.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pre_maya_include.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.