diff --git a/examples/loadObjDemo.php b/examples/loadObjDemo.php index 5d309b6..0ff7b8d 100644 --- a/examples/loadObjDemo.php +++ b/examples/loadObjDemo.php @@ -7,7 +7,11 @@ use Blobt\Luxcore\core\LoardObj; include dirname(dirname(__FILE__)) . "/vendor/autoload.php"; -$ply = new LoardObj('/home/yuanjiajia/Desktop/blender/test/3D.obj'); -$ply->toPly(LoardObj::TYPE_BINARY); +ini_set('memory_limit','4096M'); + +$ply = new LoardObj('/home/yuanjiajia/Desktop/blender/test/3D.obj',LoardObj::CLOSE); +$ply = $ply->toPly(); + +var_dump($ply ); ?> diff --git a/src/core/LoardObj.php b/src/core/LoardObj.php index 31f7fc2..12dff71 100644 --- a/src/core/LoardObj.php +++ b/src/core/LoardObj.php @@ -32,7 +32,7 @@ class LoardObj * @param string $objFile 传入obj文件 * @param bool $flipYZ 是否翻转Z轴Y轴 */ - public function __construct( string $objFile, bool $flipYZ = self::OPEN ) + public function __construct( string $objFile, bool $flipYZ = self::CLOSE ) { $this->objFile = $objFile; $this->readObj(); @@ -42,13 +42,16 @@ class LoardObj /** * @param string $format 储存 ply模型 的格式 */ - public function toPly( string $format = self::TYPE_BINARY) + public function toPly( string $path = null,string $format = self::TYPE_BINARY) { $this->createPly(); - return $this->writePly($format); + if( $path == null) $path = getcwd()."/ply"; + return $this->writePly( $path, $format ); } + + /** * 读取OBJ模型数据,并拆分模型 */ @@ -79,8 +82,8 @@ class LoardObj while( !feof($handle) ) // 读取所有的 顶点坐标、UV坐标、顶点法线、面片,并存入到相应的数组 { $line = fgets( $handle ); - $line = ltrim( $line ); - $line = explode(' ', $line); + $line = trim( $line ); + $line = preg_split("/[\s]+/", $line); switch( $line[0] ) { case 'v': @@ -101,6 +104,8 @@ class LoardObj case 'o': array_shift($line); // 将 o 开头的行(object名) 作为一个键名(按照 ‘o’ 关键字拆分OBJ模型) $line = implode("_", $line); + $fileType = mb_detect_encoding($line , array('UTF-8','GBK','LATIN1','BIG5')) ; + $line = mb_convert_encoding($line ,'utf-8' , $fileType); $keyName = $line; break; @@ -116,9 +121,6 @@ class LoardObj } - - - /** * 翻转模型的YZ轴向 */ @@ -131,10 +133,15 @@ class LoardObj $this->objData['v'][$key][] = $value[2]; $this->objData['v'][$key][] = $value[1]; } - } - - + foreach( $this->objData['vn'] as $key => $value) + { + $this->objData['vn'][$key] = []; + $this->objData['vn'][$key][] = $value[0]; + $this->objData['vn'][$key][] = $value[2]; + $this->objData['vn'][$key][] = $value[1]; + } + } /** * 利用已经拆分的 obj 模型数据,生成多个 ply 模型,并将这些模型储存在 plyData 数组中 @@ -144,12 +151,11 @@ class LoardObj foreach( $this->objData['meshs'] as $meshs_key => $meshs_value ) { - var_dump($this->objData); $ply = []; $vCount = 0; $fCount = 0; - foreach( $meshs_value as $face_value ) // 生成顶点和面数据 + foreach( $meshs_value as $face_value ) // 生成顶点和面数据 { $face_value = implode('/', $face_value); $face_value = explode('/', $face_value); @@ -166,7 +172,8 @@ class LoardObj break; case 2: - $vt = array_splice($this->objData['vt'][$v_value-1],2); + if( $v_value == null ) $vt = ['0.0000','0.0000']; + else $vt = array_slice($this->objData['vt'][$v_value-1],0,2); break; case 0; @@ -180,11 +187,11 @@ class LoardObj ; } } - $ply['face'][$fCount] = implode(' ',$lineFace); + $ply['face'][$fCount] = count($lineFace).' '.implode(' ',$lineFace); $fCount++; } - $ply['header'][] = 'ply'; // 生成头部数据 + $ply['header'][] = 'ply'; // 生成头部数据 $ply['header'][] = "format "; $ply['header'][] = "comment Created by reaiyunju, source file: ''"; $ply['header'][] = "element vertex ".$vCount; @@ -200,7 +207,7 @@ class LoardObj $ply['header'][] = "property list uchar uint vertex_indices"; $ply['header'][] = "end_header"; - $this->plyData[$meshs_key] = $ply; // 在 数组plyData 中添加一个 $key 所指名称的ply模型 + $this->plyData[$meshs_key] = $ply; // 在 数组plyData 中添加一个 $key 所指名称的ply模型 } } @@ -209,57 +216,69 @@ class LoardObj /** * 将 $plyData 数组中的ply模型 写入硬盘 */ - private function writePly(string $format) + private function writePly( string $path, string $format ) { + + if( !is_dir($path) ) + { + if( !mkdir( $path,0777,true) ) + { + throw new \Exception("!!! Failed to create the specified directory:".$path); + } + } + $plyFile = []; $handle = null; foreach( $this->plyData as $key => $value ) { - $plyFile[] = $key."ply"; - $handle = fopen( $key."ply",'w+'); + $plyFile[] = $path.'/'.$key.".ply"; + $handle = fopen( $path.'/'.$key.".ply",'w+'); - foreach( $value['header'] as $h_key => $h_value) // 写入头部数据 + $data = null; + foreach( $value['header'] as $h_key => $h_value) // 1、写入头部数据 { if( $h_key == 1 ) $data = $h_value.$format."\n"; else $data = $h_value."\n"; fwrite($handle,$data); } - foreach( $value['vertex'] as $v_value ) // 写入顶点数据 + foreach( $value['vertex'] as $v_value ) // 2、写入顶点数据 { - if( $format == self::TYPE_BINARY ) // 二进制格试写入 + if( $format == self::TYPE_BINARY ) { + $data = null; foreach( explode(' ', $v_value) as $v ) { $data .= pack('f',$v); } - fwrite($handle,$data); + fwrite($handle,$data); // 二进制格试写入 } else { - $data = $v_value."\n"; // 文本格试写入 - fwrite($handle,$data); + $data = $v_value."\n"; + fwrite($handle,$data); // 文本格试写入 } } - foreach( $value['face'] as $f_value ) // 写入面片数据 - { - if( $format == self::TYPE_BINARY ) // 二进制格试写入 - { - foreach( explode(' ', $f_value) as $v ) - { - $data .= pack('f',$v); - } - fwrite($handle,$data); + $data = null; + foreach( $value['face'] as $f_value ) // 3、写入面片数据 + { + if( $format == self::TYPE_BINARY ) + { + $f_value = explode(' ', $f_value); + $data .= pack("C",$f_value[0]); + unset($f_value[0]); + foreach( $f_value as $v ) $data .= pack("i",$v);// 二进制格试写入 } else { - $data = $f_value."\n"; // 文本格试写入 - fwrite($handle,$data); + $data .= $f_value."\n"; // 文本格试写入 } } + fwrite($handle,$data); + fclose($handle); + $handle = null; } - return $plyFile; }