collada: export UV Textures as materials. Note: the reimport of the exported collada files will have materials assigned instead of UV Face Textures! This is expected behavior
This commit is contained in:
@@ -138,7 +138,8 @@ extern bool bc_has_object_type(LinkNode *export_set, short obtype);
|
||||
char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n)
|
||||
{
|
||||
int layer_index = CustomData_get_layer_index(data, type);
|
||||
if (layer_index < 0) return NULL;
|
||||
if (layer_index < 0)
|
||||
return NULL;
|
||||
|
||||
return data->layers[layer_index + n].name;
|
||||
}
|
||||
@@ -147,9 +148,10 @@ char *bc_CustomData_get_active_layer_name(const CustomData *data, int type)
|
||||
{
|
||||
/* get the layer index of the active layer of type */
|
||||
int layer_index = CustomData_get_active_layer_index(data, type);
|
||||
if (layer_index < 0) return NULL;
|
||||
if (layer_index < 1)
|
||||
return NULL;
|
||||
|
||||
return data->layers[layer_index].name;
|
||||
return bc_CustomData_get_layer_name(data, type, layer_index-1);
|
||||
}
|
||||
|
||||
DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) {
|
||||
|
@@ -27,7 +27,6 @@
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "COLLADASWEffectProfile.h"
|
||||
#include "COLLADAFWColorOrTexture.h"
|
||||
@@ -49,21 +48,10 @@ extern "C" {
|
||||
#include "BKE_material.h"
|
||||
}
|
||||
|
||||
// OB_MESH is assumed
|
||||
static std::string getActiveUVLayerName(Object *ob)
|
||||
{
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
|
||||
int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
|
||||
if (num_layers)
|
||||
return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE));
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryEffects(sw), export_settings(export_settings) {
|
||||
}
|
||||
|
||||
|
||||
bool EffectsExporter::hasEffects(Scene *sce)
|
||||
{
|
||||
Base *base = (Base *)sce->base.first;
|
||||
@@ -86,13 +74,49 @@ bool EffectsExporter::hasEffects(Scene *sce)
|
||||
|
||||
void EffectsExporter::exportEffects(Scene *sce)
|
||||
{
|
||||
if (hasEffects(sce)) {
|
||||
this->scene = sce;
|
||||
openLibrary();
|
||||
MaterialFunctor mf;
|
||||
mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set);
|
||||
this->scene = sce;
|
||||
|
||||
if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) {
|
||||
if (hasEffects(sce)) {
|
||||
MaterialFunctor mf;
|
||||
openLibrary();
|
||||
mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set);
|
||||
closeLibrary();
|
||||
}
|
||||
}
|
||||
else if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_UV) {
|
||||
std::set<Object *> uv_textured_obs = bc_getUVTexturedObjects(sce, !this->export_settings->active_uv_only);
|
||||
std::set<Image *> uv_images = bc_getUVImages(sce, !this->export_settings->active_uv_only);
|
||||
if (uv_images.size() > 0) {
|
||||
openLibrary();
|
||||
std::set<Image *>::iterator uv_images_iter;
|
||||
for (uv_images_iter = uv_images.begin();
|
||||
uv_images_iter != uv_images.end();
|
||||
uv_images_iter++) {
|
||||
|
||||
closeLibrary();
|
||||
Image *ima = *uv_images_iter;
|
||||
std::string key(id_name(ima));
|
||||
key = translate_id(key);
|
||||
COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
|
||||
key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
|
||||
key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
|
||||
sampler.setImageId(key);
|
||||
|
||||
openEffect(key + "-effect");
|
||||
COLLADASW::EffectProfile ep(mSW);
|
||||
ep.setProfileType(COLLADASW::EffectProfile::COMMON);
|
||||
ep.setShaderType(COLLADASW::EffectProfile::PHONG);
|
||||
ep.setDiffuse(createTexture(ima, key, &sampler), false, "diffuse");
|
||||
COLLADASW::ColorOrTexture cot = getcol(0, 0, 0, 1.0f);
|
||||
ep.setSpecular(cot, false, "specular");
|
||||
ep.openProfile();
|
||||
ep.addProfileElements();
|
||||
ep.addExtraTechniques(mSW);
|
||||
ep.closeProfile();
|
||||
closeEffect();
|
||||
}
|
||||
closeLibrary();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +196,18 @@ void EffectsExporter::writeTextures(COLLADASW::EffectProfile &ep,
|
||||
}
|
||||
}
|
||||
|
||||
void EffectsExporter::exportUVMats(Object *ob)
|
||||
{
|
||||
std::vector<int> tex_indices;
|
||||
int active_uv_layer = -1;
|
||||
std::set<Image *> uv_textures;
|
||||
if (ob->type == OB_MESH && ob->totcol && this->export_settings->export_texture_type == BC_TEXTURE_TYPE_UV) {
|
||||
bool active_uv_only = this->export_settings->active_uv_only;
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
|
||||
}
|
||||
}
|
||||
|
||||
void EffectsExporter::operator()(Material *ma, Object *ob)
|
||||
{
|
||||
// create a list of indices to textures of type TEX_IMAGE
|
||||
@@ -365,7 +401,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
|
||||
|
||||
// used as fallback when MTex->uvname is "" (this is pretty common)
|
||||
// it is indeed the correct value to use in that case
|
||||
std::string active_uv(getActiveUVLayerName(ob));
|
||||
std::string active_uv(bc_get_active_uvlayer_name(ob));
|
||||
|
||||
// write textures
|
||||
// XXX very slow
|
||||
@@ -385,16 +421,18 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
|
||||
writeTextures(ep, key, sampler, t, ima, uvname);
|
||||
}
|
||||
|
||||
std::set<Image *>::iterator uv_t_iter;
|
||||
int idx;
|
||||
for (idx = 0, uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++, idx++ ) {
|
||||
if (active_uv_layer>-1 && idx==active_uv_layer) {
|
||||
if (active_uv_layer > -1) {
|
||||
// Export only UV textures assigned to active UV Layer (sounds reasonable, but is that correct?)
|
||||
std::set<Image *>::iterator uv_t_iter;
|
||||
|
||||
for (uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++) {
|
||||
Image *ima = *uv_t_iter;
|
||||
std::string key(id_name(ima));
|
||||
key = translate_id(key);
|
||||
int i = im_samp_map[key];
|
||||
COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i];
|
||||
ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse");
|
||||
ep.setShaderType(COLLADASW::EffectProfile::PHONG);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -47,6 +47,8 @@ class EffectsExporter: COLLADASW::LibraryEffects
|
||||
{
|
||||
public:
|
||||
EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
|
||||
void EffectsExporter::exportUVMats(Object *ob);
|
||||
|
||||
void exportEffects(Scene *sce);
|
||||
|
||||
void operator()(Material *ma, Object *ob);
|
||||
|
@@ -135,13 +135,15 @@ void GeometryExporter::operator()(Object *ob)
|
||||
// Only create Polylists if number of faces > 0
|
||||
if (me->totface > 0) {
|
||||
// XXX slow
|
||||
if (ob->totcol) {
|
||||
if (ob->totcol && this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) {
|
||||
for (int a = 0; a < ob->totcol; a++) {
|
||||
createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
|
||||
}
|
||||
}
|
||||
else {
|
||||
createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
|
||||
bool all_uv_layers = !this->export_settings->active_uv_only;
|
||||
std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers);
|
||||
createPolylists(uv_images, has_uvs, has_color, ob, me, geom_id, norind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,13 +223,15 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
|
||||
//createLooseEdgeList(ob, me, geom_id, norind);
|
||||
|
||||
// XXX slow
|
||||
if (ob->totcol) {
|
||||
if (ob->totcol && this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) {
|
||||
for (int a = 0; a < ob->totcol; a++) {
|
||||
createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
|
||||
}
|
||||
}
|
||||
else {
|
||||
createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
|
||||
bool all_uv_layers = !this->export_settings->active_uv_only;
|
||||
std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers);
|
||||
createPolylists(uv_images, has_uvs, has_color, ob, me, geom_id, norind);
|
||||
}
|
||||
|
||||
closeMesh();
|
||||
@@ -296,7 +300,8 @@ std::string GeometryExporter::makeVertexColorSourceId(std::string& geom_id, char
|
||||
return result;
|
||||
}
|
||||
|
||||
// powerful because it handles both cases when there is material and when there's not
|
||||
|
||||
// Export meshes with Materials
|
||||
void GeometryExporter::createPolylist(short material_index,
|
||||
bool has_uvs,
|
||||
bool has_color,
|
||||
@@ -361,13 +366,21 @@ void GeometryExporter::createPolylist(short material_index,
|
||||
int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1;
|
||||
for (i = 0; i < num_layers; i++) {
|
||||
if (!this->export_settings->active_uv_only || i == active_uv_index) {
|
||||
|
||||
std::string uv_name(bc_get_uvlayer_name(me, i));
|
||||
std::string effective_id = geom_id; // (uv_name == "") ? geom_id : uv_name;
|
||||
std::string layer_id = makeTexcoordSourceId(
|
||||
effective_id,
|
||||
i, this->export_settings->active_uv_only);
|
||||
|
||||
// char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
|
||||
/* Note: the third parameter denotes the offset of TEXCOORD in polylist elements
|
||||
For now this is always 2 (This may change sometime/maybe)
|
||||
*/
|
||||
COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD,
|
||||
makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings->active_uv_only)),
|
||||
2, // this is only until we have optimized UV sets
|
||||
(this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set
|
||||
);
|
||||
makeUrl(layer_id),
|
||||
2, // this is only until we have optimized UV sets
|
||||
(this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set
|
||||
);
|
||||
til.push_back(input3);
|
||||
}
|
||||
}
|
||||
@@ -697,7 +710,13 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
|
||||
MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a);
|
||||
|
||||
COLLADASW::FloatSourceF source(mSW);
|
||||
std::string layer_id = makeTexcoordSourceId(geom_id, a, this->export_settings->active_uv_only);
|
||||
std::string active_uv_name(bc_get_active_uvlayer_name(me));
|
||||
std::string effective_id = geom_id; // (active_uv_name == "") ? geom_id : active_uv_name;
|
||||
std::string layer_id = makeTexcoordSourceId(
|
||||
effective_id,
|
||||
a,
|
||||
this->export_settings->active_uv_only );
|
||||
|
||||
source.setId(layer_id);
|
||||
source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
|
||||
|
||||
|
@@ -55,9 +55,9 @@ ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings
|
||||
|
||||
void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
|
||||
{
|
||||
std::string name(id_name(image));
|
||||
std::string translated_name(translate_id(name));
|
||||
bool not_yet_exported = find(mImages.begin(), mImages.end(), translated_name) == mImages.end();
|
||||
std::string id(id_name(image));
|
||||
std::string translated_id(translate_id(id));
|
||||
bool not_yet_exported = find(mImages.begin(), mImages.end(), translated_id) == mImages.end();
|
||||
|
||||
if (not_yet_exported) {
|
||||
|
||||
@@ -88,7 +88,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
|
||||
|
||||
// make absolute destination path
|
||||
|
||||
BLI_strncpy(export_file, name.c_str(), sizeof(export_file));
|
||||
BLI_strncpy(export_file, id.c_str(), sizeof(export_file));
|
||||
BKE_image_path_ensure_ext_from_imformat(export_file, &imageFormat);
|
||||
|
||||
BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file);
|
||||
@@ -143,10 +143,11 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
|
||||
}
|
||||
}
|
||||
|
||||
COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), translated_name, translated_name); /* set name also to mNameNC. This helps other viewers import files exported from Blender better */
|
||||
/* set name also to mNameNC. This helps other viewers import files exported from Blender better */
|
||||
COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), translated_id, translated_id);
|
||||
img.add(mSW);
|
||||
fprintf(stdout, "Collada export: Added image: %s\n", export_file);
|
||||
mImages.push_back(translated_name);
|
||||
mImages.push_back(translated_id);
|
||||
|
||||
BKE_image_release_ibuf(image, imbuf, NULL);
|
||||
}
|
||||
@@ -161,7 +162,7 @@ void ImagesExporter::export_UV_Images()
|
||||
|
||||
for (node = this->export_settings->export_set; node; node = node->next) {
|
||||
Object *ob = (Object *)node->link;
|
||||
if (ob->type == OB_MESH && ob->totcol) {
|
||||
if (ob->type == OB_MESH) {
|
||||
Mesh *me = (Mesh *) ob->data;
|
||||
BKE_mesh_tessface_ensure(me);
|
||||
int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
|
||||
@@ -189,7 +190,13 @@ void ImagesExporter::export_UV_Images()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ============================================================
|
||||
* Check if there are any images to be exported
|
||||
* Returns true as soon as an object is detected that
|
||||
* either has an UV Texture assigned, or has a material
|
||||
* assigned that uses an Image Texture.
|
||||
* ============================================================
|
||||
*/
|
||||
bool ImagesExporter::hasImages(Scene *sce)
|
||||
{
|
||||
LinkNode *node;
|
||||
|
@@ -43,14 +43,19 @@ extern "C" {
|
||||
|
||||
void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only, BC_export_texture_type export_texture_type)
|
||||
{
|
||||
for (int a = 0; a < ob->totcol; a++) {
|
||||
Material *ma = give_current_material(ob, a + 1);
|
||||
|
||||
COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList();
|
||||
bool all_uv_layers = !active_uv_only;
|
||||
COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList();
|
||||
|
||||
if (ma) {
|
||||
std::string matid(get_material_id(ma));
|
||||
matid = translate_id(matid);
|
||||
if (export_texture_type == BC_TEXTURE_TYPE_UV)
|
||||
{
|
||||
std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers);
|
||||
std::set<Image *>::iterator uv_images_iter;
|
||||
for (uv_images_iter = uv_images.begin();
|
||||
uv_images_iter != uv_images.end();
|
||||
uv_images_iter++) {
|
||||
Image *ima = *uv_images_iter;
|
||||
std::string matid(id_name(ima));
|
||||
matid = get_material_id_from_id(matid);
|
||||
std::ostringstream ostr;
|
||||
ostr << matid;
|
||||
COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid));
|
||||
@@ -71,4 +76,32 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_materia
|
||||
iml.push_back(im);
|
||||
}
|
||||
}
|
||||
|
||||
else if (export_texture_type == BC_TEXTURE_TYPE_MAT) {
|
||||
for (int a = 0; a < ob->totcol; a++) {
|
||||
Material *ma = give_current_material(ob, a + 1);
|
||||
if (ma) {
|
||||
std::string matid(get_material_id(ma));
|
||||
matid = translate_id(matid);
|
||||
std::ostringstream ostr;
|
||||
ostr << matid;
|
||||
COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid));
|
||||
|
||||
// create <bind_vertex_input> for each uv map
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
|
||||
|
||||
int map_index = 0;
|
||||
int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1;
|
||||
for (int b = 0; b < totlayer; b++) {
|
||||
if (!active_uv_only || b == active_uv_index) {
|
||||
char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b);
|
||||
im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++));
|
||||
}
|
||||
}
|
||||
|
||||
iml.push_back(im);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,11 +31,12 @@
|
||||
#include "COLLADASWBindMaterial.h"
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "collada.h"
|
||||
|
||||
class InstanceWriter
|
||||
{
|
||||
protected:
|
||||
void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only);
|
||||
void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only, BC_export_texture_type export_texture_type);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -49,8 +49,7 @@ void MaterialsExporter::exportMaterials(Scene *sce)
|
||||
closeLibrary();
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
// Temporary discarded (to keep consistent commits)
|
||||
|
||||
else if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_UV)
|
||||
{
|
||||
std::set<Image *> uv_images = bc_getUVImages(sce, !this->export_settings->active_uv_only);
|
||||
@@ -72,7 +71,7 @@ void MaterialsExporter::exportMaterials(Scene *sce)
|
||||
closeLibrary();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool MaterialsExporter::hasMaterials(Scene *sce)
|
||||
|
Reference in New Issue
Block a user