Blender V4.5
EffectExporter.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2010-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <map>
10
11#include "COLLADASWEffectProfile.h"
12
13#include "EffectExporter.h"
14#include "MaterialExporter.h"
15#include "Materials.h"
16
17#include "collada_internal.h"
18#include "collada_utils.h"
19
20#include "DNA_mesh_types.h"
21
22#include "BKE_collection.hh"
23#include "BKE_customdata.hh"
24#include "BKE_material.hh"
25
26static std::string getActiveUVLayerName(Object *ob)
27{
28 Mesh *mesh = (Mesh *)ob->data;
29
31 if (num_layers) {
33 }
34
35 return "";
36}
37
38EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw,
39 BCExportSettings &export_settings,
40 KeyImageMap &key_image_map)
41 : COLLADASW::LibraryEffects(sw), export_settings(export_settings), key_image_map(key_image_map)
42{
43}
44
45bool EffectsExporter::hasEffects(Scene *sce)
46{
47 bool result = false;
49 int a;
50 for (a = 0; a < ob->totcol; a++) {
51 Material *ma = BKE_object_material_get(ob, a + 1);
52
53 /* no material, but check all of the slots */
54 if (!ma) {
55 continue;
56 }
57
58 result = true;
59 break;
60 }
61 }
63 return result;
64}
65
67{
68 if (hasEffects(sce)) {
69 this->mContext = C;
70 this->scene = sce;
71 openLibrary();
74 sce, *this, this->export_settings.get_export_set());
75
76 closeLibrary();
77 }
78}
79
80void EffectsExporter::set_shader_type(COLLADASW::EffectProfile &ep, Material *ma)
81{
82 /* XXX check if BLINN and PHONG can be supported as well */
83 ep.setShaderType(COLLADASW::EffectProfile::LAMBERT);
84}
85
86void EffectsExporter::set_transparency(COLLADASW::EffectProfile &ep, Material *ma)
87{
88 double alpha = bc_get_alpha(ma);
89 if (alpha < 1) {
90 /* workaround use <transparent> to avoid wrong handling of <transparency> by other tools */
91 COLLADASW::ColorOrTexture cot = bc_get_cot(0, 0, 0, alpha);
92 ep.setTransparent(cot, false, "alpha");
93 ep.setOpaque(COLLADASW::EffectProfile::A_ONE);
94 }
95}
96
97void EffectsExporter::set_diffuse_color(COLLADASW::EffectProfile &ep, Material *ma)
98{
99 COLLADASW::ColorOrTexture cot = bc_get_base_color(ma);
100 ep.setDiffuse(cot, false, "diffuse");
101}
102
103void EffectsExporter::set_ambient(COLLADASW::EffectProfile &ep, Material *ma)
104{
105 COLLADASW::ColorOrTexture cot = bc_get_ambient(ma);
106 ep.setAmbient(cot, false, "ambient");
107}
108void EffectsExporter::set_specular(COLLADASW::EffectProfile &ep, Material *ma)
109{
110 COLLADASW::ColorOrTexture cot = bc_get_specular(ma);
111 ep.setSpecular(cot, false, "specular");
112}
113void EffectsExporter::set_reflective(COLLADASW::EffectProfile &ep, Material *ma)
114{
115 COLLADASW::ColorOrTexture cot = bc_get_reflective(ma);
116 ep.setReflective(cot, false, "reflective");
117}
118
119void EffectsExporter::set_reflectivity(COLLADASW::EffectProfile &ep, Material *ma)
120{
121 double reflectivity = bc_get_reflectivity(ma);
122 if (reflectivity > 0.0) {
123 ep.setReflectivity(reflectivity, false, "specular");
124 }
125}
126
127void EffectsExporter::set_emission(COLLADASW::EffectProfile &ep, Material *ma)
128{
129 COLLADASW::ColorOrTexture cot = bc_get_emission(ma);
130 ep.setEmission(cot, false, "emission");
131}
132
133void EffectsExporter::set_ior(COLLADASW::EffectProfile &ep, Material *ma)
134{
135 double alpha = bc_get_ior(ma);
136 ep.setIndexOfRefraction(alpha, false, "ior");
137}
138
139void EffectsExporter::set_shininess(COLLADASW::EffectProfile &ep, Material *ma)
140{
141 double shininess = bc_get_shininess(ma);
142 ep.setShininess(shininess, false, "shininess");
143}
144
145void EffectsExporter::get_images(Material *ma, KeyImageMap &material_image_map)
146{
147 if (!ma->use_nodes) {
148 return;
149 }
150
151 MaterialNode material = MaterialNode(mContext, ma, key_image_map);
152 Image *image = material.get_diffuse_image();
153 if (image == nullptr) {
154 return;
155 }
156
157 std::string uid(id_name(image));
158 std::string key = translate_id(uid);
159
160 if (material_image_map.find(key) == material_image_map.end()) {
161 material_image_map[key] = image;
162 key_image_map[key] = image;
163 }
164}
165
166void EffectsExporter::create_image_samplers(COLLADASW::EffectProfile &ep,
167 KeyImageMap &material_image_map,
168 std::string &active_uv)
169{
170 KeyImageMap::iterator iter;
171
172 for (iter = material_image_map.begin(); iter != material_image_map.end(); iter++) {
173
174 Image *image = iter->second;
175 std::string uid(id_name(image));
176 std::string key = translate_id(uid);
177
178 COLLADASW::Sampler *sampler = new COLLADASW::Sampler(
179 COLLADASW::Sampler::SAMPLER_TYPE_2D,
180 key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
181 key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
182
183 sampler->setImageId(key);
184
185 ep.setDiffuse(createTexture(image, active_uv, sampler), false, "diffuse");
186 }
187}
188
190{
191 KeyImageMap material_image_map;
192
193 openEffect(get_effect_id(ma));
194
195 COLLADASW::EffectProfile ep(mSW);
196 ep.setProfileType(COLLADASW::EffectProfile::COMMON);
197 ep.openProfile();
198 set_shader_type(ep, ma); /* creates a Lambert Shader for now */
199
200 COLLADASW::ColorOrTexture cot;
201
202 set_diffuse_color(ep, ma);
203 set_emission(ep, ma);
204 set_ior(ep, ma);
205 set_reflectivity(ep, ma);
206 set_transparency(ep, ma);
207
208 /* TODO: */
209#if 0
210 set_shininess(ep, ma); /* Shininess not supported for lambert. */
211 set_ambient(ep, ma);
212 set_specular(ep, ma);
213#endif
214
215 get_images(ma, material_image_map);
216 std::string active_uv(getActiveUVLayerName(ob));
217 create_image_samplers(ep, material_image_map, active_uv);
218
219#if 0
220 uint a, b;
221 for (a = 0, b = 0; a < tex_indices.size(); a++) {
222 MTex *t = ma->mtex[tex_indices[a]];
223 Image *ima = t->tex->ima;
224
225 /* Image not set for texture */
226 if (!ima) {
227 continue;
228 }
229
230 std::string key(id_name(ima));
231 key = translate_id(key);
232
233 /* create only one <sampler>/<surface> pair for each unique image */
234 if (im_samp_map.find(key) == im_samp_map.end()) {
235 /* <newparam> <sampler> <source> */
236 COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
237 key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
238 key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
239 sampler.setImageId(key);
240 /* copy values to arrays since they will live longer */
241 samplers[a] = sampler;
242
243 /* store pointers so they can be used later when we create <texture>s */
244 samp_surf[b] = &samplers[a];
245 // samp_surf[b][1] = &surfaces[a];
246
247 im_samp_map[key] = b;
248 b++;
249 }
250 }
251
252 for (a = 0; a < tex_indices.size(); a++) {
253 MTex *t = ma->mtex[tex_indices[a]];
254 Image *ima = t->tex->ima;
255
256 if (!ima) {
257 continue;
258 }
259
260 std::string key(id_name(ima));
261 key = translate_id(key);
262 int i = im_samp_map[key];
263 std::string uvname = strlen(t->uvname) ? t->uvname : active_uv;
264 COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)
265 samp_surf[i]; /* possibly uninitialized memory ... */
266 writeTextures(ep, key, sampler, t, ima, uvname);
267 }
268#endif
269
270 /* performs the actual writing */
271 ep.addProfileElements();
272 ep.addExtraTechniques(mSW);
273
274 ep.closeProfile();
275 closeEffect();
276}
277
278COLLADASW::ColorOrTexture EffectsExporter::createTexture(Image *ima,
279 std::string &uv_layer_name,
280 COLLADASW::Sampler *sampler
281 /*COLLADASW::Surface *surface*/)
282{
283
284 COLLADASW::Texture texture(translate_id(id_name(ima)));
285 texture.setTexcoord(uv_layer_name);
286 // texture.setSurface(*surface);
287 texture.setSampler(*sampler);
288
289 COLLADASW::ColorOrTexture cot(texture);
290 return cot;
291}
292
293COLLADASW::ColorOrTexture EffectsExporter::getcol(float r, float g, float b, float a)
294{
295 COLLADASW::Color color(r, g, b, a);
296 COLLADASW::ColorOrTexture cot(color);
297 return cot;
298}
#define FOREACH_SCENE_OBJECT_END
#define FOREACH_SCENE_OBJECT_BEGIN(scene, _instance)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
unsigned int uint
@ CD_PROP_FLOAT2
struct Image Image
static std::string getActiveUVLayerName(Object *ob)
#define C
Definition RandGen.cpp:29
EffectsExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings, KeyImageMap &key_image_map)
COLLADASW::ColorOrTexture createTexture(Image *ima, std::string &uv_layer_name, COLLADASW::Sampler *sampler)
COLLADASW::ColorOrTexture getcol(float r, float g, float b, float a)
void operator()(Material *ma, Object *ob)
void exportEffects(bContext *C, Scene *sce)
Image * get_diffuse_image()
std::string translate_id(const char *idString)
std::string get_effect_id(Material *mat)
std::string id_name(void *id)
COLLADASW::ColorOrTexture bc_get_specular(Material *ma)
COLLADASW::ColorOrTexture bc_get_ambient(Material *ma)
double bc_get_alpha(Material *ma)
COLLADASW::ColorOrTexture bc_get_cot(float r, float g, float b, float a)
COLLADASW::ColorOrTexture bc_get_emission(Material *ma)
COLLADASW::ColorOrTexture bc_get_reflective(Material *ma)
double bc_get_reflectivity(Material *ma)
double bc_get_shininess(Material *ma)
COLLADASW::ColorOrTexture bc_get_base_color(Material *ma)
double bc_get_ior(Material *ma)
const char * bc_CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
std::map< std::string, Image * > KeyImageMap
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
char uvname[68]
struct Tex * tex
void forEachMaterialInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
CustomData corner_data
struct Image * ima
i
Definition text_draw.cc:230