anderslanglands / alShaders2

BSD 3-Clause "New" or "Revised" License
75 stars 38 forks source link

Accommodate C4D naming changes in 5.1 #22

Closed jonahfriedman closed 6 years ago

jonahfriedman commented 6 years ago

Peter very helpfully supplied a patch for this. It needs tests and to not cause issues for other path-based applications such as Katana, HtoA (and perhaps could be useful for those applications as well).

Patch:

diff --git a/cryptomatte/cryptomatte.h b/cryptomatte/cryptomatte.h
index e7d2eef..8465e30 100644
--- a/cryptomatte/cryptomatte.h
+++ b/cryptomatte/cryptomatte.h
@@ -246,19 +246,28 @@ inline void get_clean_object_name(const char* obj_full_name, char obj_name_out[M
     bool obj_already_done = false;

     const uint8_t mode_maya = 0;
-    const uint8_t mode_c4d = 1;
+    const uint8_t mode_c4d_old = 1;
     const uint8_t mode_si = 2;
+    const uint8_t mode_c4d = 3;
     uint8_t mode = mode_maya;

-    // C4DtoA: c4d|obj_hierarchy|...
+    // C4DtoA prior 2.3: c4d|obj_hierarchy|...
     if (strncmp(nsp_name, "c4d|", 4) == 0) {
-        mode = mode_c4d;
+        mode = mode_c4d_old;
         const char* nsp = nsp_name + 4;
         size_t len = strlen(nsp);
         memmove(nsp_name, nsp, len);
         nsp_name[len] = '\0';
     }

+    // C4DtoA from 2.3: /obj_hierarchy|obj_cache_hierarchy
+    // where '/' is used as the separator in the object hierarchy
+    // For instance: /Null/Sphere
+    //               /Null/Cloner|Null/Sphere1
+    if (nsp_name[0] == '/') {
+        mode = mode_c4d;
+    }
+
     char* sitoa_suffix = strstr(nsp_name, ".SItoA.");
     if (sitoa_suffix) { // in Softimage mode
         mode = mode_si;
@@ -267,8 +276,13 @@ inline void get_clean_object_name(const char* obj_full_name, char obj_name_out[M
     }

     char* nsp_separator = NULL;
-    if (mode == mode_c4d) // find last c4d mode switch {
+    if (mode == mode_c4d_old) // find last c4d mode switch {
         nsp_separator = strrchr(nsp_name, '|');
+    else if (mode == mode_c4d) { // find last c4d mode switch 
+        char* lastPipe = strrchr(nsp_name, '|');
+        char* lastSlash = strrchr(nsp_name, '/');
+        nsp_separator = lastSlash > lastPipe ? lastSlash : lastPipe;
+    }
     else if (mode == mode_si)
         nsp_separator = strchr(nsp_name, '.');
     else if (mode == mode_maya)
@@ -297,7 +311,7 @@ inline void get_clean_material_name(const char* mat_full_name, char mat_name_out
                                     bool strip_ns) {
     safe_copy_to_buffer(mat_name_out, mat_full_name);

-    // C4DtoA: c4d|mat_name|root_node_name
+    // C4DtoA prior 2.3: c4d|mat_name|root_node_name
     if (strncmp(mat_name_out, "c4d|", 4) == 0) {
         // Chop first element
         char* str_cut = mat_name_out + 4;
@@ -308,6 +322,17 @@ inline void get_clean_material_name(const char* mat_full_name, char mat_name_out
         }
         return;
     }
+    // C4DtoA from 2.3: /mat_name|root_node_name
+    if (mat_name_out[0] == '/' && strchr(mat_name_out, '|')) {
+        // Chop the prefix
+        char* str_cut = mat_name_out + 1;
+        // Snip the mat name
+        char* mat_name_start = strtok(str_cut, "|");
+        if (mat_name_start != NULL) {
+            memmove(mat_name_out, mat_name_start, strlen(mat_name_start) + 1);
+        }
+        return;
+    }

     // Example:
     //      Softimage:
jonahfriedman commented 6 years ago

This is done, and isn't C4D specific, it's any path that starts with "/". I'm going to leave this open for the moment because I think it's likely we'll want to revisit it before release.

jonahfriedman commented 6 years ago

I decided to deal with this by giving a bunch of options under an advanced tab to enable or disable various aspects of name parsing (as they exist today).