Collada: added new functions for improved material exporter (not used yet)
This commit is contained in:
parent
ce531ed1a1
commit
0d2b1da3a6
|
@ -52,6 +52,7 @@ extern "C" {
|
|||
#include "collada_internal.h"
|
||||
#include "collada_utils.h"
|
||||
|
||||
|
||||
// TODO: optimize UV sets by making indexed list with duplicates removed
|
||||
GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings)
|
||||
{
|
||||
|
@ -420,6 +421,165 @@ void GeometryExporter::createPolylist(short material_index,
|
|||
polylist.finish();
|
||||
}
|
||||
|
||||
void GeometryExporter::createPolylists(std::set<Image *> uv_images,
|
||||
bool has_uvs,
|
||||
bool has_color,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
std::string& geom_id,
|
||||
std::vector<BCPolygonNormalsIndices>& norind)
|
||||
{
|
||||
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;
|
||||
|
||||
createPolylist(ima, has_uvs,
|
||||
has_color,
|
||||
ob,
|
||||
me,
|
||||
geom_id,
|
||||
norind);
|
||||
}
|
||||
}
|
||||
// Export Meshes with UV Textures (export as materials, see effectExporter and MaterialExporter)
|
||||
// Important: Image *ima must point to an Image
|
||||
void GeometryExporter::createPolylist(Image *ima,
|
||||
bool has_uvs,
|
||||
bool has_color,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
std::string& geom_id,
|
||||
std::vector<BCPolygonNormalsIndices>& norind)
|
||||
{
|
||||
|
||||
std::string imageid(id_name(ima));
|
||||
MPoly *mpolys = me->mpoly;
|
||||
MLoop *mloops = me->mloop;
|
||||
MTexPoly *mtpolys = me->mtpoly;
|
||||
|
||||
int totpolys = me->totpoly;
|
||||
|
||||
// <vcount>
|
||||
int i;
|
||||
int faces_in_polylist = 0;
|
||||
std::vector<unsigned long> vcount_list;
|
||||
|
||||
// count faces with this material
|
||||
for (i = 0; i < totpolys; i++) {
|
||||
MTexPoly *tp = &mtpolys[i];
|
||||
MPoly *p = &mpolys[i];
|
||||
|
||||
std::string tpageid(id_name(tp->tpage));
|
||||
if (tpageid == imageid) {
|
||||
faces_in_polylist++;
|
||||
vcount_list.push_back(p->totloop);
|
||||
}
|
||||
}
|
||||
|
||||
// no faces using this material
|
||||
if (faces_in_polylist == 0) {
|
||||
fprintf(stderr, "%s: Image %s is not used.\n", id_name(ob).c_str(), imageid);
|
||||
return;
|
||||
}
|
||||
|
||||
COLLADASW::Polylist polylist(mSW);
|
||||
|
||||
// sets count attribute in <polylist>
|
||||
polylist.setCount(faces_in_polylist);
|
||||
|
||||
// sets material name
|
||||
std::string material_id = get_material_id_from_id(imageid);
|
||||
std::ostringstream ostr;
|
||||
ostr << translate_id(material_id);
|
||||
polylist.setMaterial(ostr.str());
|
||||
|
||||
COLLADASW::InputList &til = polylist.getInputList();
|
||||
|
||||
// creates <input> in <polylist> for vertices
|
||||
COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0);
|
||||
|
||||
// creates <input> in <polylist> for normals
|
||||
COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1);
|
||||
|
||||
til.push_back(input1);
|
||||
til.push_back(input2);
|
||||
|
||||
// if mesh has uv coords writes <input> for TEXCOORD
|
||||
int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
|
||||
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);
|
||||
|
||||
/* 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(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);
|
||||
}
|
||||
}
|
||||
|
||||
int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
|
||||
if (totlayer_mcol > 0) {
|
||||
int map_index = 0;
|
||||
|
||||
for (int a = 0; a < totlayer_mcol; a++) {
|
||||
char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a);
|
||||
COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR,
|
||||
makeUrl(makeVertexColorSourceId(geom_id, layer_name)),
|
||||
(has_uvs) ? 3 : 2, // all color layers have same index order
|
||||
map_index // set number equals color map index
|
||||
);
|
||||
til.push_back(input4);
|
||||
map_index++;
|
||||
}
|
||||
}
|
||||
|
||||
// sets <vcount>
|
||||
polylist.setVCountList(vcount_list);
|
||||
|
||||
// performs the actual writing
|
||||
polylist.prepareToAppendValues();
|
||||
|
||||
// <p>
|
||||
int texindex = 0;
|
||||
for (i = 0; i < totpolys; i++) {
|
||||
MTexPoly *tp = &mtpolys[i];
|
||||
MPoly *p = &mpolys[i];
|
||||
int loop_count = p->totloop;
|
||||
std::string tpageid(id_name(tp->tpage));
|
||||
if (tpageid == imageid) {
|
||||
MLoop *l = &mloops[p->loopstart];
|
||||
BCPolygonNormalsIndices normal_indices = norind[i];
|
||||
|
||||
for (int j = 0; j < loop_count; j++) {
|
||||
polylist.appendValues(l[j].v);
|
||||
polylist.appendValues(normal_indices[j]);
|
||||
if (has_uvs)
|
||||
polylist.appendValues(texindex + j);
|
||||
|
||||
if (has_color)
|
||||
polylist.appendValues(texindex + j);
|
||||
}
|
||||
}
|
||||
|
||||
texindex += loop_count;
|
||||
}
|
||||
|
||||
polylist.finish();
|
||||
}
|
||||
|
||||
// creates <source> for positions
|
||||
void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
|
||||
|
|
|
@ -85,15 +85,33 @@ public:
|
|||
Mesh *me,
|
||||
std::string& geom_id);
|
||||
|
||||
// powerful because it handles both cases when there is material and when there's not
|
||||
// Create polylists for meshes with Materials
|
||||
void createPolylist(short material_index,
|
||||
bool has_uvs,
|
||||
bool has_color,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
std::string& geom_id,
|
||||
std::vector<BCPolygonNormalsIndices>& norind);
|
||||
|
||||
bool has_uvs,
|
||||
bool has_color,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
std::string& geom_id,
|
||||
std::vector<BCPolygonNormalsIndices>& norind);
|
||||
|
||||
// Create polylists for meshes with UV Textures
|
||||
void createPolylists(std::set<Image *> uv_images,
|
||||
bool has_uvs,
|
||||
bool has_color,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
std::string& geom_id,
|
||||
std::vector<BCPolygonNormalsIndices>& norind);
|
||||
|
||||
// Create polylists for meshes with UV Textures
|
||||
void createPolylist(Image *ima,
|
||||
bool has_uvs,
|
||||
bool has_color,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
std::string& geom_id,
|
||||
std::vector<BCPolygonNormalsIndices>& norind);
|
||||
|
||||
// creates <source> for positions
|
||||
void createVertsSource(std::string geom_id, Mesh *me);
|
||||
|
||||
|
|
|
@ -344,7 +344,13 @@ std::string get_camera_id(Object *ob)
|
|||
|
||||
std::string get_material_id(Material *mat)
|
||||
{
|
||||
return translate_id(id_name(mat)) + "-material";
|
||||
std::string id = id_name(mat);
|
||||
return get_material_id_from_id(id);
|
||||
}
|
||||
|
||||
std::string get_material_id_from_id(std::string id)
|
||||
{
|
||||
return translate_id(id) + "-material";
|
||||
}
|
||||
|
||||
std::string get_morph_id(Object *ob)
|
||||
|
|
|
@ -103,6 +103,7 @@ extern std::string get_joint_sid(Bone *bone, Object *ob_arm);
|
|||
extern std::string get_camera_id(Object *ob);
|
||||
|
||||
extern std::string get_material_id(Material *mat);
|
||||
extern std::string get_material_id_from_id(std::string id);
|
||||
|
||||
extern std::string get_morph_id(Object *ob);
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "COLLADAFWMeshPrimitive.h"
|
||||
#include "COLLADAFWMeshVertexData.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
extern "C" {
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
|
@ -831,4 +833,160 @@ void bc_sanitize_mat(float mat[4][4], int precision)
|
|||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
mat[i][j] = double_round(mat[i][j], precision);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns name of Active UV Layer or empty String if no active UV Layer defined.
|
||||
* Assuming the Object is of type MESH
|
||||
*/
|
||||
std::string bc_get_active_uvlayer_name(Object *ob)
|
||||
{
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
return bc_get_active_uvlayer_name(me);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns name of Active UV Layer or empty String if no active UV Layer defined
|
||||
*/
|
||||
std::string bc_get_active_uvlayer_name(Mesh *me)
|
||||
{
|
||||
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 "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns UV Layer name or empty string if layer index is out of range
|
||||
*/
|
||||
std::string bc_get_uvlayer_name(Mesh *me, int layer)
|
||||
{
|
||||
int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
|
||||
if (num_layers && layer < num_layers) {
|
||||
return std::string(bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, layer));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Return the list of Mesh objects with assigned UVtextures and Images
|
||||
* Note: We need to create artificaial materials for each of them
|
||||
*
|
||||
***********************************************************************/
|
||||
std::set<Object *> bc_getUVTexturedObjects(Scene *sce, bool all_uv_layers)
|
||||
{
|
||||
std::set <Object *> UVObjects;
|
||||
Base *base = (Base *)sce->base.first;
|
||||
|
||||
while (base) {
|
||||
Object *ob = base->object;
|
||||
bool has_uvimage = false;
|
||||
if (ob->type == OB_MESH) {
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
|
||||
|
||||
for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) {
|
||||
if (all_uv_layers || active_uv_layer == i)
|
||||
{
|
||||
if (me->pdata.layers[i].type == CD_MTEXPOLY) {
|
||||
MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
|
||||
MPoly *mpoly = me->mpoly;
|
||||
for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
|
||||
|
||||
Image *ima = txface->tpage;
|
||||
if (ima != NULL) {
|
||||
has_uvimage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_uvimage) {
|
||||
UVObjects.insert(ob);
|
||||
}
|
||||
}
|
||||
base = base->next;
|
||||
}
|
||||
return UVObjects;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Return the list of UV Texture images from all exported Mesh Items
|
||||
* Note: We need to create one artificial material for each Image.
|
||||
*
|
||||
***********************************************************************/
|
||||
std::set<Image *> bc_getUVImages(Scene *sce, bool all_uv_layers)
|
||||
{
|
||||
std::set <Image *> UVImages;
|
||||
Base *base = (Base *)sce->base.first;
|
||||
|
||||
while (base) {
|
||||
Object *ob = base->object;
|
||||
bool has_uvimage = false;
|
||||
if (ob->type == OB_MESH) {
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
|
||||
|
||||
for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) {
|
||||
if (all_uv_layers || active_uv_layer == i)
|
||||
{
|
||||
if (me->pdata.layers[i].type == CD_MTEXPOLY) {
|
||||
MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
|
||||
MPoly *mpoly = me->mpoly;
|
||||
for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
|
||||
|
||||
Image *ima = txface->tpage;
|
||||
if (ima != NULL) {
|
||||
if (UVImages.find(ima) == UVImages.end())
|
||||
UVImages.insert(ima);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
base = base->next;
|
||||
}
|
||||
return UVImages;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Return the list of UV Texture images for the given Object
|
||||
* Note: We need to create one artificial material for each Image.
|
||||
*
|
||||
***********************************************************************/
|
||||
std::set<Image *> bc_getUVImages(Object *ob, bool all_uv_layers)
|
||||
{
|
||||
std::set <Image *> UVImages;
|
||||
|
||||
bool has_uvimage = false;
|
||||
if (ob->type == OB_MESH) {
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
|
||||
|
||||
for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) {
|
||||
if (all_uv_layers || active_uv_layer == i)
|
||||
{
|
||||
if (me->pdata.layers[i].type == CD_MTEXPOLY) {
|
||||
MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
|
||||
MPoly *mpoly = me->mpoly;
|
||||
for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
|
||||
|
||||
Image *ima = txface->tpage;
|
||||
if (ima != NULL) {
|
||||
if (UVImages.find(ima) == UVImages.end())
|
||||
UVImages.insert(ima);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return UVImages;
|
||||
}
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
extern "C" {
|
||||
|
@ -80,6 +81,7 @@ extern void bc_set_mark(Object *ob);
|
|||
|
||||
extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n);
|
||||
extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type);
|
||||
extern char *bc_CustomData_get_layer_name(const CustomData *data, int layer_index, int type);
|
||||
|
||||
extern void bc_bubble_sort_by_Object_name(LinkNode *export_set);
|
||||
extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only);
|
||||
|
@ -109,6 +111,14 @@ extern bool bc_get_property_matrix(Bone *bone, std::string key, float mat[4][4])
|
|||
|
||||
extern void bc_create_restpose_mat(const ExportSettings *export_settings, Bone *bone, float to_mat[4][4], float world[4][4], bool use_local_space);
|
||||
|
||||
extern std::string bc_get_active_uvlayer_name(Object *ob);
|
||||
extern std::string bc_get_active_uvlayer_name(Mesh *me);
|
||||
extern std::string bc_get_uvlayer_name(Mesh *me, int layer);
|
||||
|
||||
extern std::set<Image *> bc_getUVImages(Scene *sce, bool all_uv_layers);
|
||||
extern std::set<Image *> bc_getUVImages(Object *ob, bool all_uv_layers);
|
||||
extern std::set<Object *> bc_getUVTexturedObjects(Scene *sce, bool all_uv_layers);
|
||||
|
||||
class BCPolygonNormalsIndices
|
||||
{
|
||||
std::vector<unsigned int> normal_indices;
|
||||
|
|
Loading…
Reference in New Issue