Patch by Jan Diederich for COLLADA exporter: translate invalid characters in Id names before using them as DAE ids (see bug report https://projects.blender.org/tracker/?func=detail&atid=498&aid=19787&group_id=9).

Thanks!
This commit is contained in:
Arystanbek Dyussenov
2009-11-07 14:28:57 +00:00
parent 58e44463fb
commit 01b2059d85

View File

@@ -124,6 +124,60 @@ char *CustomData_get_active_layer_name(const CustomData *data, int type)
return data->layers[layer_index].name;
}
/**
Translation map.
Used to translate every COLLADA id to a valid id, no matter what "wrong" letters may be
included. Look at the IDREF XSD declaration for more.
Follows strictly the COLLADA XSD declaration which explicitly allows non-english chars,
like special chars (e.g. micro sign), umlauts and so on.
The COLLADA spec also allows additional chars for member access ('.'), these
must obviously be removed too, otherwise they would be heavily misinterpreted.
*/
const unsigned char translate_map[256] = {
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 45, 95, 95,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 95, 95, 95, 95, 95, 95,
95, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 95, 95, 95, 95, 95,
95, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 183,
95, 95, 95, 95, 95, 95, 95, 95,
192, 193, 194, 195, 196, 197, 198, 199,
200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 95,
216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231,
232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 95,
248, 249, 250, 251, 252, 253, 254, 255};
/** Look at documentation of translate_map */
static std::string translate_id(const std::string &id)
{
std::string id_translated = id;
for (int i=0; i < id_translated.size(); i++)
{
id_translated[i] = translate_map[id_translated[i]];
}
return id_translated;
}
static std::string id_name(void *id)
{
return ((ID*)id)->name + 2;
@@ -131,28 +185,17 @@ static std::string id_name(void *id)
static std::string get_geometry_id(Object *ob)
{
return id_name(ob) + "-mesh";
return translate_id(id_name(ob)) + "-mesh";
}
static std::string get_light_id(Object *ob)
{
return id_name(ob) + "-light";
return translate_id(id_name(ob)) + "-light";
}
static std::string get_camera_id(Object *ob)
{
return id_name(ob) + "-camera";
}
static void replace_chars(char *str, char chars[], char with)
{
char *ch, *p;
for (ch = chars; *ch; ch++) {
while ((p = strchr(str, *ch))) {
*p = with;
}
}
return translate_id(id_name(ob)) + "-camera";
}
/*
@@ -236,10 +279,11 @@ public:
if (!ma) continue;
if (find(mMat.begin(), mMat.end(), id_name(ma)) == mMat.end()) {
std::string translated_id = translate_id(id_name(ma));
if (find(mMat.begin(), mMat.end(), translated_id) == mMat.end()) {
(*this->f)(ma, ob);
mMat.push_back(id_name(ma));
mMat.push_back(translated_id);
}
}
}
@@ -384,8 +428,9 @@ public:
polylist.setCount(faces_in_polylist);
// sets material name
if (has_material)
polylist.setMaterial(id_name(ma));
if (has_material) {
polylist.setMaterial(translate_id(id_name(ma)));
}
COLLADASW::InputList &til = polylist.getInputList();
@@ -664,6 +709,7 @@ protected:
if (ma) {
std::string matid(id_name(ma));
matid = translate_id(matid);
COLLADASW::InstanceMaterial im(matid, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid));
// create <bind_vertex_input> for each uv layer
@@ -807,18 +853,14 @@ private:
std::string get_joint_id(Bone *bone, Object *ob_arm)
{
return id_name(ob_arm) + "_" + bone->name;
return translate_id(id_name(ob_arm) + "_" + bone->name);
}
std::string get_joint_sid(Bone *bone)
{
char name[100];
BLI_strncpy(name, bone->name, sizeof(name));
// these chars have special meaning in SID
replace_chars(name, ".()", '_');
return name;
return translate_id(name);
}
// parent_mat is armature-space
@@ -872,7 +914,7 @@ private:
std::string get_controller_id(Object *ob_arm)
{
return id_name(ob_arm) + SKIN_CONTROLLER_ID_SUFFIX;
return translate_id(id_name(ob_arm)) + SKIN_CONTROLLER_ID_SUFFIX;
}
// ob should be of type OB_MESH
@@ -1144,7 +1186,8 @@ public:
void exportScene(Scene *sce) {
// <library_visual_scenes> <visual_scene>
openVisualScene(id_name(sce));
std::string id_naming = id_name(sce);
openVisualScene(translate_id(id_naming), id_naming);
// write <node>s
//forEachMeshObjectInScene(sce, *this);
@@ -1187,7 +1230,7 @@ public:
void writeNodes(Object *ob, Scene *sce)
{
COLLADASW::Node node(mSW);
node.setNodeId(id_name(ob));
node.setNodeId(translate_id(id_name(ob)));
node.setType(COLLADASW::Node::NODE);
node.start();
@@ -1296,6 +1339,7 @@ public:
Image *image = mtex->tex->ima;
std::string name(id_name(image));
name = translate_id(name);
char rel[FILE_MAX];
char abs[FILE_MAX];
char src[FILE_MAX];
@@ -1350,7 +1394,7 @@ public:
std::vector<int> tex_indices;
createTextureIndices(ma, tex_indices);
openEffect(id_name(ma) + "-effect");
openEffect(translate_id(id_name(ma)) + "-effect");
COLLADASW::EffectProfile ep(mSW);
ep.setProfileType(COLLADASW::EffectProfile::COMMON);
@@ -1425,6 +1469,7 @@ public:
Image *ima = t->tex->ima;
std::string key(id_name(ima));
key = translate_id(key);
// create only one <sampler>/<surface> pair for each unique image
if (im_samp_map.find(key) == im_samp_map.end()) {
@@ -1466,6 +1511,7 @@ public:
// we assume map input is always TEXCO_UV
std::string key(id_name(ima));
key = translate_id(key);
int i = im_samp_map[key];
COLLADASW::Sampler *sampler = (COLLADASW::Sampler*)samp_surf[i][0];
//COLLADASW::Surface *surface = (COLLADASW::Surface*)samp_surf[i][1];
@@ -1508,7 +1554,7 @@ public:
/*COLLADASW::Surface *surface*/)
{
COLLADASW::Texture texture(id_name(ima));
COLLADASW::Texture texture(translate_id(id_name(ima)));
texture.setTexcoord(uv_layer_name);
//texture.setSurface(*surface);
texture.setSampler(*sampler);
@@ -1557,9 +1603,9 @@ public:
{
std::string name(id_name(ma));
openMaterial(name);
openMaterial(translate_id(name), name);
std::string efid = name + "-effect";
std::string efid = translate_id(name) + "-effect";
addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid));
closeMaterial();
@@ -1851,16 +1897,21 @@ public:
const char *axis_names[] = {"X", "Y", "Z"};
const char *axis_name = NULL;
char c_anim_id[100]; // careful!
char c_anim_name[100]; // careful!
if (fcu->array_index < 3)
axis_name = axis_names[fcu->array_index];
BLI_snprintf(c_anim_id, sizeof(c_anim_id), "%s.%s.%s", (char*)ob_name.c_str(), fcu->rna_path, axis_names[fcu->array_index]);
BLI_snprintf(c_anim_id, sizeof(c_anim_id), "%s.%s.%s", (char*)translate_id(ob_name).c_str(),
fcu->rna_path, axis_names[fcu->array_index]);
std::string anim_id(c_anim_id);
BLI_snprintf(c_anim_name, sizeof(c_anim_name), "%s.%s.%s",
(char*)ob_name.c_str(), fcu->rna_path, axis_names[fcu->array_index]);
std::string anim_name = c_anim_name;
// check rna_path is one of: rotation, scale, location
openAnimation(anim_id);
openAnimation(anim_id, anim_name);
// create input source
std::string input_id = create_source(Sampler::INPUT, fcu, anim_id, axis_name);
@@ -1882,7 +1933,8 @@ public:
addSampler(sampler);
std::string target = ob_name + "/" + get_transform_sid(fcu->rna_path, axis_name);
std::string target = translate_id(ob_name)
+ "/" + get_transform_sid(fcu->rna_path, axis_name);
addChannel(COLLADABU::URI(empty, sampler_id), target);
closeAnimation();
@@ -1893,18 +1945,23 @@ public:
const char *axis_names[] = {"X", "Y", "Z"};
const char *axis_name = NULL;
char c_anim_id[100]; // careful!
char c_anim_name[100]; // careful!
if (fcu->array_index < 3)
axis_name = axis_names[fcu->array_index];
std::string transform_sid = get_transform_sid(fcu->rna_path, axis_name);
BLI_snprintf(c_anim_id, sizeof(c_anim_id), "%s.%s.%s", (char*)ob_name.c_str(), (char*)bone_name.c_str(), (char*)transform_sid.c_str());
BLI_snprintf(c_anim_id, sizeof(c_anim_id), "%s.%s.%s", (char*)translate_id(ob_name).c_str(),
(char*)translate_id(bone_name).c_str(), (char*)transform_sid.c_str());
std::string anim_id(c_anim_id);
BLI_snprintf(c_anim_name, sizeof(c_anim_name), "%s.%s.%s",
(char*)ob_name.c_str(), (char*)bone_name.c_str(), (char*)transform_sid.c_str());
std::string anim_name(c_anim_name);
// check rna_path is one of: rotation, scale, location
openAnimation(anim_id);
openAnimation(anim_id, anim_name);
// create input source
std::string input_id = create_source(Sampler::INPUT, fcu, anim_id, axis_name);
@@ -1926,7 +1983,7 @@ public:
addSampler(sampler);
std::string target = ob_name + "_" + bone_name + "/" + transform_sid;
std::string target = translate_id(ob_name + "_" + bone_name) + "/" + transform_sid;
addChannel(COLLADABU::URI(empty, sampler_id), target);
closeAnimation();
@@ -2122,7 +2179,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename)
se.exportScene(sce);
// <scene>
std::string scene_name(id_name(sce));
std::string scene_name(translate_id(id_name(sce)));
COLLADASW::Scene scene(&sw, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING,
scene_name));
scene.add();