Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /*
- Convert Genesis 3 poses to Genesis 8 (female)
- author : mork
- created : 16.06.2017
- version : 1.21
- license : NOMIL NOGOV, besides that, do with it what you want.
- os : linux - yes
- windows - not tested, needs a binary for unpacking gz and check if a file is compressed
- mac - don't know. could work
- dependencies:
- + gunzip
- + file
- challenges:
- + Content downloaded with Connect are in a different folder
- + Connect folders are all lowercase, regular content folders are not
- v1.1
- + fixed wrong order of copy/create folder in copyPoseFile
- + removed creating obsolete output folder
- + dunno :)
- v1.2
- + converted to class
- v1.21
- + fixed/added some comments, some cleanup
- */
- set_time_limit(1800);
- define('LBR', "\n");
- define('SEP', DIRECTORY_SEPARATOR);
- class DAZ_ConvertPose {
- private $_path_source;
- private $_path_destination;
- private static $_s_bDebug = false;
- private static $_s_dep_gunzip;
- private static $_s_dep_file;
- private static $_s_path_tmp = false;
- private $_subfolder;
- // if something from this list is within a source path, path is ignored
- // for me, clothing poses were the only thing causing troubles
- private static $_s_blacklist_source = [
- 'clothing'
- ];
- public function __construct() {
- $this->_subfolder = '';
- }
- // -------------------------------------------------------------------- //
- public function setDebug($bool) {
- self::$_s_bDebug = (bool)$bool;
- }
- // -------------------------------------------------------------------- //
- public static function s_checkDependencies() {
- /*---------- We need something to unpack gz files ----------*/
- exec('gunzip -h', $foo, $status);
- if ($status == 0) {
- self::$_s_dep_gunzip = 'gunzip -f';
- } else {
- echo "ERROR: missing dependency 'gunzip'. Please install it first.".LBR;
- echo " Example APT : sudo apt-get install gunzip".LBR;
- echo " Example pacman : sudo pacman -S gunzip".LBR;
- return false;
- }
- exec('file --help', $foo, $status);
- if ($status == 0) {
- self::$_s_dep_file = 'file';
- } else {
- echo "ERROR: missing dependency 'file'. Please install it first.".LBR;
- # no clue which package, should be on every linux distribution
- #echo " Example APT : sudo apt-get install gunzip".LBR
- #echo " Example pacman : sudo pacman -S gunzip".LBR
- return false;
- }
- return true;
- }
- // -------------------------------------------------------------------- //
- public function run() {
- /*---------- Scan for Pose folders ----------*/
- $source_folders = self::_s_collectPoseFolders($this->_path_source);
- if (!$source_folders) {
- echo "ERROR : No source pose folders found".LBR;
- return false;
- }
- /*---------- Scan for poses ----------*/
- $poses = self::_s_scanPoseFolders($source_folders);
- if (!$poses) {
- echo "ERROR : No poses found. Scanned ".sizeof($source_folders)." sources.".LBR;
- return false;
- }
- /*---------- Enable debug mode? ----------*/
- $r = self::_s_askYesNo("Enable debug mode?");
- if ($r == 'y' || $r == 'j')
- $this->setDebug(true);
- /*---------- If debug, output all source folders we will copy poses from ----------*/
- if (self::$_s_bDebug) {
- echo "Source folders:".LBR;
- foreach($source_folders as $k => $v) echo " $v".LBR;
- }
- /*---------- Init TMP dir ----------*/
- $this->initTmpDir();
- /*---------- Ask user if he wants a subfolder ----------*/
- $r = self::_s_askYesNo("Should I copy everything to a sub-folder in the G8 Pose folder?");
- if ($r == 'y' || $r == 'j') {
- do {
- $p = self::_s_readString("Please enter a name for the subfolder");
- $r = self::_s_askYesNo("Is this correct: ".$p);
- } while ($r != 'y' && $r != 'j');
- $this->_subfolder = $p;
- }
- /*---------- Copy poses and convert ----------*/
- $this->_convertAndCopy($poses);
- /*---------- Cleanup ----------*/
- $this->_cleanup();
- }
- // -------------------------------------------------------------------- //
- public function setPathSource($source_path) {
- if (!is_dir($source_path)) return false;
- // there should be a 'People' folder in the library
- if (!is_dir($source_path . SEP . 'People')) return false;
- $this->_path_source = $source_path;
- return true;
- }
- // -------------------------------------------------------------------- //
- public function setPathDestination($destination_path) {
- if (!is_dir($destination_path)) return false;
- // if we want to be flexible, it prohibits itself to do additional checks
- // it's virtually impossible to overwrite source content, so...
- $this->_path_destination = $destination_path;
- return true;
- }
- public function initTmpDir() {
- self::$_s_path_tmp = sys_get_temp_dir() . SEP . 'dazconverttmp';
- self::_s_checkPath(self::$_s_path_tmp);
- }
- // -------------------------------------------------------------------- //
- /**
- *
- * Cleanup any mess we might have created (temp files)
- *
- */
- private function _cleanup() {
- if (self::$_s_path_tmp && is_dir(self::$_s_path_tmp)) {
- rmdir(self::$_s_path_tmp);
- }
- }
- /**
- *
- * Copy all given pose files to DST_PATH/Genesis 8/Poses/<subfolder-if-any>/SRC_POSE
- *
- */
- private function _convertAndCopy($poses) {
- if (!$poses) return false;
- if (!is_array($poses)) return false;
- $old_folder = '';
- $ignore = 0; // 0 = ask for every file, 1 = ignore all, 2 = ignore current folder
- /*---------- loop over all found pose files (DUF or PNG or whatever) ----------*/
- foreach($poses as $poseIndex => $pose_source) {
- // replace source path with destination path, but keep subfolder structure
- $dst = $this->_path_destination . SEP . str_replace($this->_path_source, '', $pose_source);
- // convert G3 to G8 in destination folder structure
- $dst = str_replace('Genesis 3', 'Genesis 8', $dst);
- // if user provided a subfolder, insert it
- if (strlen($this->_subfolder)) {
- $dst = str_replace("Poses".SEP, "Poses".SEP.$this->_subfolder.SEP, $dst);
- }
- // if user ignored folder, check if we have a new folder
- if (dirname($dst) != $old_folder) {
- if ($ignore == 2) $ignore = 0; // if "folder yes", but folder changed, reset ignore to ask user again.
- }
- $old_folder = dirname($dst);
- // if user is not ignoring, ask him what to do
- if ($ignore == 0) {
- echo "Src: ".$pose_source.LBR;
- echo "Dst: ".$dst.LBR;
- $r = self::_s_askYesNoExt("Convert this file?", array("y" => "(y)es", "n" => "(n)o", "f" => "(f)older yes", "a" => "(a)ll yes", "c" => "(c)ancel"));
- switch($r) {
- case 'y' :
- break;
- case 'n' :
- continue;
- case 'f' :
- $ignore = 2;
- break;
- case 'a' :
- $ignore = 1;
- break;
- case 'c' : default :
- return false;
- break;
- }
- echo LBR;
- }
- /*---------- Make sure target folder exists ----------*/
- self::_s_checkPath(dirname($dst));
- /*---------- Copy file ----------*/
- if (copy($pose_source, $dst) == false) {
- echo "ERROR : Failed to copy file to $dst".LBR;
- $r = self::_s_askYesNo("Abort?");
- if ($r == 'y' || $r == 'j') return false;
- }
- /*---------- If a DUF file, process ----------*/
- if (strtolower(self::_s_getFileExtension(basename($dst))) == 'duf') {
- self::_s_processPoseFile($dst);
- }
- }
- }
- // -------------------------------------------------------------------- //
- /**
- *
- * Do a recursive scan on a source pose folder.
- * Basically collects all files within.
- * The provided source folder may be an array of source folders.
- *
- */
- private static function _s_scanPoseFolders($scan_folder) {
- $out = [];
- // we accept an array of folder, so if we get one, run this function for each.
- if (is_array($scan_folder)) {
- foreach($scan_folder as $k => $v) {
- $ret = self::_s_scanPoseFolders($v);
- if ($ret) $out = array_merge($out, $ret);
- }
- return $out;
- }
- if (!is_dir($scan_folder)) return false; // actually can't happen. only if user deletes it meanwhile.
- $files = scandir($scan_folder);
- if (!$files || sizeof($files) == 2) return false;
- foreach($files as $k => $file) {
- if ($file == '.' || $file == '..') continue;
- if (is_dir($scan_folder . DIRECTORY_SEPARATOR . $file)) {
- if(self::$_s_bDebug)
- echo "Is folder: ". $scan_folder . DIRECTORY_SEPARATOR . $file . LBR;
- // run this function on pose folder
- $ret = self::_s_scanPoseFolders($scan_folder . DIRECTORY_SEPARATOR . $file);
- if ($ret) $out = array_merge($out, $ret);
- } else {
- // add as valid source file
- $out[] = $scan_folder . DIRECTORY_SEPARATOR . $file;
- if(self::$_s_bDebug)
- echo "\t_s_scanPoseFolders | Added: ".$scan_folder . DIRECTORY_SEPARATOR . $file.LBR;
- }
- }
- return $out;
- }
- // -------------------------------------------------------------------- //
- /**
- *
- * Find all "Poses" folders within a "Genesis 3 Female" folder.
- * Might need some adjustment for Connect
- *
- */
- private static function _s_collectPoseFolders($dir) {
- if (!is_dir($dir)) return false;
- $out = [];
- $f = scandir($dir);
- if (!$f || sizeof($f) == 2) return false;
- foreach ($f as $key => $folder_name) {
- if ($folder_name == '.' || $folder_name == '..') continue;
- if (!is_dir($dir . DIRECTORY_SEPARATOR . $folder_name)) continue;
- // did we find a "poses" folder?
- if (strtolower($folder_name) == 'poses') {
- // verify that we are within a genesis 3 subfolder
- if (strrpos(strtolower($dir), 'genesis 3 female') !== false) {
- // blacklist check
- $bIgnore = false;
- if (sizeof(self::$_s_blacklist_source)) {
- foreach (self::$_s_blacklist_source as $key => $value) {
- if (stripos($dir . DIRECTORY_SEPARATOR . $folder_name, $value) !== false) {
- echo "Ignoring source folder due to blacklist ($value) : " . $dir . DIRECTORY_SEPARATOR . $folder_name . LBR;
- $bIgnore = true;
- break;
- }
- }
- }
- // add to list
- if (!$bIgnore) {
- echo "Added source folder : " . $dir . $folder_name . LBR;
- $out[] = realpath($dir . DIRECTORY_SEPARATOR . $folder_name);
- }
- }
- } else {
- $b = self::_s_collectPoseFolders($dir . DIRECTORY_SEPARATOR . $folder_name);
- if ($b) $out = array_merge($out, $b);
- }
- }
- return $out;
- }
- /**
- *
- * Read a DUF file, change some values, write back.
- * Uncompresses file to tmp folder, if necessary.
- *
- */
- private static function _s_processPoseFile($file) {
- /*---------- Does file exist? ----------*/
- if (!file_exists($file)) return false;
- /*---------- Check if the DUF file is compressed ----------*/
- $fileinfo = exec(self::$_s_dep_file . ' "'.$file.'"');
- $src = $file;
- if (strpos($fileinfo, 'compressed') !== false && strpos($fileinfo, 'uncompressed') == false) {
- if(self::$_s_bDebug)
- echo "\tis compressed: $file".LBR;
- $tmp_path = self::$_s_path_tmp . SEP . basename($file).SEP;
- self::_s_checkPath($tmp_path);
- if(self::$_s_bDebug)
- echo "\tuncompressing: $file\n\t\t".$tmp_path . SEP . basename($file).LBR;
- copy($file, $tmp_path . basename($file).'.gz');
- exec(self::$_s_dep_gunzip .' "'.($tmp_path . basename($file).'.gz').'"');
- $src = $tmp_path . basename($file);
- } else {
- if(self::$_s_bDebug)
- echo "\tis uncompressed: $file".LBR;
- }
- /*---------- Convert Pose ----------*/
- $data = file_get_contents($src);
- if ($data) {
- // Shoulder bend left
- // find the values of the lShldrBend.... keys
- if (preg_match("/lShldrBend:\?rotation\/z\/value\"(.*)\"keys\"\s*:\s\[\s*\[(.*)\]\s*\]\n/isU", $data, $match)) {
- $values = explode(",", $match[2]); // separate
- $values[0] = trim($values[0]); // clean
- $values[1] = trim($values[1]); // clean
- $old = $values[1]; // backup old if you want to output
- $values[1] += 45.0; // change value
- // replace old text with new text, containing the new values
- $new = str_replace($match[2], implode(", ", $values), $match[0]);
- $data = str_replace($match[0], $new, $data);
- #echo "Left Shoulder Bend: $old -> ".$values[1].LBR;
- }
- // Shoulder bend right
- if (preg_match("/rShldrBend:\?rotation\/z\/value\"(.*)\"keys\"\s*:\s\[\s*\[(.*)\]\s*\]\n/isU", $data, $match)) {
- $values = explode(",", $match[2]);
- $values[0] = trim($values[0]);
- $values[1] = trim($values[1]);
- $old = $values[1];
- $values[1] -= 45.0;
- $new = str_replace($match[2], implode(", ", $values), $match[0]);
- $data = str_replace($match[0], $new, $data);
- #echo "Right Shoulder Bend: $old -> ".$values[1].LBR;
- }
- // Thigh sidebyside left
- if (preg_match("/lThighBend:\?rotation\/z\/value\"(.*)\"keys\"\s*:\s\[\s*\[(.*)\]\s*\]\n/isU", $data, $match)) {
- $values = explode(",", $match[2]);
- $values[0] = trim($values[0]);
- $values[1] = trim($values[1]);
- $old = $values[1];
- $values[1] -= 6.0;
- $new = str_replace($match[2], implode(", ", $values), $match[0]);
- $data = str_replace($match[0], $new, $data);
- #echo "Left Thigh Bend: $old -> ".$values[1].LBR;
- }
- // Thigh sidebyside right
- if (preg_match("/rThighBend:\?rotation\/z\/value\"(.*)\"keys\"\s*:\s\[\s*\[(.*)\]\s*\]\n/isU", $data, $match)) {
- $values = explode(",", $match[2]);
- $values[0] = trim($values[0]);
- $values[1] = trim($values[1]);
- $old = $values[1];
- $values[1] += 6.0;
- $new = str_replace($match[2], implode(", ", $values), $match[0]);
- $data = str_replace($match[0], $new, $data);
- #echo "Right Thigh Bend: $old -> ".$values[1].LBR;
- }
- }
- /*---------- write back changed file ----------*/
- file_put_contents($file, $data);
- /*---------- if it was a compressed file, cleanup tmp data ----------*/
- if ($src != $file) {
- // remove temps
- unlink($tmp_path . basename($file));
- rmdir($tmp_path);
- }
- return true;
- }
- // -------------------------------------------------------------------- //
- /**
- *
- * Check if given path exists, if not, create it.
- * not tested on windows!
- *
- */
- private static function _s_checkPath($path) {
- $path = str_replace(SEP.SEP, SEP, $path);
- if (!preg_match("/".preg_quote(SEP, '/')."/", $path)) return false;
- $tmp = explode(SEP, $path);
- $new = array();
- foreach($tmp as $key => $value) {
- if ($value == '..') array_pop($new);
- else if ($value == '.') continue;
- else if (strlen($value) || !$key) array_push($new, $value);
- }
- $chk = "";
- foreach($tmp as $key => $value) {
- $chk .= $value.SEP;
- if (!is_dir($chk)) {
- if (!(mkdir($chk, 0777))) {
- echo "FAILED to create dir: $chk".LBR;
- return false;
- }
- }
- }
- return true;
- }
- // -------------------------------------------------------------------- //
- /**
- *
- * Return extension of file (without dot)
- *
- */
- private static function _s_getFileExtension($filename) {
- $filename = trim($filename);
- if (!mb_strlen($filename)) return '';
- if (($p = strripos($filename, '.')) === false) return '';
- return mb_substr($filename, $p+1);
- }
- // -------------------------------------------------------------------- //
- private static function _s_readString($str) {
- if (PHP_OS == 'WINNT') {
- echo $str." :";
- $k = stream_get_line(STDIN, 1024, PHP_EOL);
- } else $k = readline($str." :");
- return $k;
- }
- private static function _s_askYesNo($question) {
- do {
- if (PHP_OS == 'WINNT') {
- echo $question." (y/n): ";
- $k = stream_get_line(STDIN, 1024, PHP_EOL);
- } else $k = readline($question." (y/n): ");
- } while ($k != 'y' && $k != 'j' && $k != 'n');
- return $k;
- }
- private static function _s_askYesNoExt($question, $options) {
- $option_string = implode(", ", $options);
- do {
- if (PHP_OS == 'WINNT') {
- echo $question." ($option_string): ";
- $k = stream_get_line(STDIN, 1024, PHP_EOL);
- } else $k = readline($question." ($option_string): ");
- } while (!isset($options[strtolower($k)]));
- return strtolower($k);
- }
- }
- // -------------------------------------------------------------------- //
- // -------------------------------------------------------------------- //
- echo "******************************************************".LBR;
- echo "* DAZ3D - Convert Poses from Genesis 3 to Genesis 8 *".LBR;
- echo "* v1.21 *".LBR;
- echo "******************************************************".LBR;
- echo LBR;
- echo "This will convert G3 Poses from a source directory".LBR;
- echo "and copy them to the specified target directory.".LBR.LBR;
- /*---------- Check arguments ----------*/
- if (!isset($argv[1]) || !isset($argv[2]))
- die("Usage: php ".basename(__FILE__)." <path_to_source_library> <path_to_target_library>".LBR.LBR);
- /*---------- Check dependencies ----------*/
- if (!DAZ_ConvertPose::s_checkDependencies())
- exit;
- /*---------- Get us a new instance of the converter ----------*/
- $converter = new DAZ_ConvertPose();
- /*---------- Set source path ----------*/
- if (!$converter->setPathSource($argv[1]))
- die("Source path does not exist or is invalid (contains no 'People') folder:".LBR."\t".$arv[1].LBR.LBR);
- /*---------- Set destination path ----------*/
- if (!$converter->setPathDestination($argv[2]))
- die("Destination path does not exist:".LBR."\t".$arv[2].LBR.LBR);
- /*---------- Run the converter ----------*/
- $converter->run();
- /*---------- Done, eh? :) ----------*/
- die("All done, going home...".LBR.LBR);
- ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement