Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Ablesons
three.js
提交
be792321
T
three.js
项目概览
Ablesons
/
three.js
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
three.js
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
be792321
编写于
5月 22, 2018
作者:
M
Mr.doob
提交者:
GitHub
5月 22, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #14102 from gkjohnson/ply-exporter-update
Ply exporter update
上级
bc44c95d
3dfba94d
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
418 addition
and
112 deletion
+418
-112
examples/js/exporters/GLTFExporter.js
examples/js/exporters/GLTFExporter.js
+1
-0
examples/js/exporters/PLYExporter.js
examples/js/exporters/PLYExporter.js
+417
-112
未找到文件。
examples/js/exporters/GLTFExporter.js
浏览文件 @
be792321
...
...
@@ -66,6 +66,7 @@ THREE.GLTFExporter.prototype = {
parse
:
function
(
input
,
onDone
,
options
)
{
var
DEFAULT_OPTIONS
=
{
binary
:
false
,
trs
:
false
,
onlyVisible
:
true
,
truncateDrawRange
:
true
,
...
...
examples/js/exporters/PLYExporter.js
浏览文件 @
be792321
...
...
@@ -5,9 +5,8 @@
* Usage:
* var exporter = new THREE.PLYExporter();
*
* // second argument is an array of attributes to
* // exclude from the format ('color', 'uv', 'normal')
* var data = exporter.parse(mesh, [ 'color' ]);
* // second argument is a list of options
* var data = exporter.parse(mesh, { binar: true, excludeAttributes: [ 'color' ] });
*
* Format Definition:
* http://paulbourke.net/dataformats/ply/
...
...
@@ -19,40 +18,75 @@ THREE.PLYExporter.prototype = {
constructor
:
THREE
.
PLYExporter
,
parse
:
function
(
object
,
excludePropertie
s
)
{
parse
:
function
(
object
,
option
s
)
{
if
(
Array
.
isArray
(
excludeProperties
)
!==
true
)
{
// Iterate over the valid meshes in the object
function
traverseMeshes
(
cb
)
{
excludeProperties
=
[];
object
.
traverse
(
function
(
child
)
{
if
(
child
.
isMesh
===
true
)
{
var
mesh
=
child
;
var
geometry
=
mesh
.
geometry
;
if
(
geometry
.
isGeometry
===
true
)
{
geometry
=
geomToBufferGeom
.
get
(
geometry
);
}
if
(
geometry
.
isBufferGeometry
===
true
)
{
if
(
geometry
.
getAttribute
(
'
position
'
)
!==
undefined
)
{
cb
(
mesh
,
geometry
);
}
}
}
}
);
}
var
includeNormals
=
excludeProperties
.
indexOf
(
'
normal
'
)
===
-
1
;
var
includeColors
=
excludeProperties
.
indexOf
(
'
color
'
)
===
-
1
;
var
includeUVs
=
excludeProperties
.
indexOf
(
'
uv
'
)
===
-
1
;
// Default options
var
defaultOptions
=
{
binary
:
false
,
excludeAttributes
:
[]
// normal, uv, color, index
};
options
=
Object
.
assign
(
defaultOptions
,
options
);
// count the number of vertices
var
excludeAttributes
=
options
.
excludeAttributes
;
var
geomToBufferGeom
=
new
WeakMap
();
var
includeNormals
=
false
;
var
includeColors
=
false
;
var
includeUVs
=
false
;
var
includeIndices
=
true
;
// count the vertices, check which properties are used,
// and cache the BufferGeometry
var
vertexCount
=
0
;
var
faceCount
=
0
;
var
vertexList
=
''
;
var
faceList
=
''
;
var
vertex
=
new
THREE
.
Vector3
();
var
normalMatrixWorld
=
new
THREE
.
Matrix3
();
object
.
traverse
(
function
(
child
)
{
if
(
child
instanceof
THREE
.
Mesh
)
{
if
(
child
.
isMesh
===
true
)
{
var
mesh
=
child
;
var
geometry
=
mesh
.
geometry
;
if
(
geometry
instanceof
THREE
.
Geometry
)
{
if
(
geometry
.
isGeometry
===
true
)
{
geometry
=
new
THREE
.
BufferGeometry
().
setFromObject
(
mesh
);
var
bufferGeometry
=
geomToBufferGeom
.
get
(
geometry
)
||
new
THREE
.
BufferGeometry
().
setFromObject
(
mesh
);
geomToBufferGeom
.
set
(
geometry
,
bufferGeometry
);
geometry
=
bufferGeometry
;
}
if
(
geometry
instanceof
THREE
.
BufferGeometry
)
{
if
(
geometry
.
isBufferGeometry
===
true
)
{
var
vertices
=
geometry
.
getAttribute
(
'
position
'
);
var
normals
=
geometry
.
getAttribute
(
'
normal
'
);
...
...
@@ -60,102 +94,279 @@ THREE.PLYExporter.prototype = {
var
colors
=
geometry
.
getAttribute
(
'
color
'
);
var
indices
=
geometry
.
getIndex
();
normalMatrixWorld
.
getNormalMatrix
(
mesh
.
matrixWorld
);
if
(
vertices
===
undefined
)
{
return
;
}
// form each line
for
(
var
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
++
)
{
vertexCount
+=
vertices
.
count
;
faceCount
+=
indices
?
indices
.
count
/
3
:
vertices
.
count
/
3
;
if
(
normals
!==
undefined
)
includeNormals
=
true
;
if
(
uvs
!==
undefined
)
includeUVs
=
true
;
vertex
.
x
=
vertices
.
getX
(
i
);
vertex
.
y
=
vertices
.
getY
(
i
);
vertex
.
z
=
vertices
.
getZ
(
i
);
if
(
colors
!==
undefined
)
includeColors
=
true
;
vertex
.
applyMatrix4
(
mesh
.
matrixWorld
);
}
}
// Position information
var
line
=
vertex
.
x
+
'
'
+
vertex
.
y
+
'
'
+
vertex
.
z
;
}
);
// Normal information
if
(
includeNormals
===
true
)
{
includeNormals
=
includeNormals
&&
excludeAttributes
.
indexOf
(
'
normal
'
)
===
-
1
;
includeColors
=
includeColors
&&
excludeAttributes
.
indexOf
(
'
color
'
)
===
-
1
;
includeUVs
=
includeUVs
&&
excludeAttributes
.
indexOf
(
'
uv
'
)
===
-
1
;
includeIndices
=
includeIndices
&&
excludeAttributes
.
indexOf
(
'
index
'
)
===
-
1
;
if
(
normals
!==
undefined
)
{
vertex
.
x
=
normals
.
getX
(
i
);
vertex
.
y
=
normals
.
getY
(
i
);
vertex
.
z
=
normals
.
getZ
(
i
);
if
(
includeIndices
&&
faceCount
!==
Math
.
floor
(
faceCount
)
)
{
vertex
.
applyMatrix3
(
normalMatrixWorld
);
// point cloud meshes will not have an index array and may not have a
// number of vertices that is divisble by 3 (and therefore representable
// as triangles)
console
.
error
(
line
+=
'
'
+
vertex
.
x
+
'
'
+
vertex
.
y
+
'
'
+
vertex
.
z
;
'
PLYExporter: Failed to generate a valid PLY file with triangle indices because the
'
+
'
number of indices is not divisible by 3.
'
}
else
{
);
line
+=
'
0 0 0
'
;
return
null
;
}
}
}
// get how many bytes will be needed to save out the faces
// so we can use a minimal amount of memory / data
var
indexByteCount
=
1
;
if
(
vertexCount
>
256
)
{
// 2^8 bits
indexByteCount
=
2
;
}
if
(
vertexCount
>
65536
)
{
// 2^16 bits
indexByteCount
=
4
;
}
var
header
=
'
ply
\n
'
+
`format
${
options
.
binary
?
'
binary_big_endian
'
:
'
ascii
'
}
1.0\n`
+
`element vertex
${
vertexCount
}
\n`
+
// position
'
property float x
\n
'
+
'
property float y
\n
'
+
'
property float z
\n
'
;
if
(
includeNormals
===
true
)
{
// normal
header
+=
'
property float nx
\n
'
+
'
property float ny
\n
'
+
'
property float nz
\n
'
;
}
if
(
includeUVs
===
true
)
{
// uvs
header
+=
'
property float s
\n
'
+
'
property float t
\n
'
;
}
if
(
includeColors
===
true
)
{
// colors
header
+=
'
property uchar red
\n
'
+
'
property uchar green
\n
'
+
'
property uchar blue
\n
'
;
}
if
(
includeIndices
===
true
)
{
// faces
header
+=
`element face
${
faceCount
}
\n`
+
`property list uchar uint
${
indexByteCount
*
8
}
vertex_index\n`
;
}
// UV information
if
(
includeUVs
===
true
)
{
header
+=
'
end_header
\n
'
;
if
(
uvs
!==
undefined
)
{
line
+=
'
'
+
uvs
.
getX
(
i
)
+
'
'
+
uvs
.
getY
(
i
);
// Generate attribute data
var
vertex
=
new
THREE
.
Vector3
();
var
normalMatrixWorld
=
new
THREE
.
Matrix3
();
if
(
options
.
binary
===
true
)
{
// Binary File Generation
var
headerBin
=
new
TextEncoder
().
encode
(
header
);
// 3 position values at 4 bytes
// 3 normal values at 4 bytes
// 3 color channels with 1 byte
// 2 uv values at 4 bytes
var
vertexListLength
=
vertexCount
*
(
4
*
3
+
(
includeNormals
?
4
*
3
:
0
)
+
(
includeColors
?
3
:
0
)
+
(
includeUVs
?
4
*
2
:
0
)
);
// 1 byte shape desciptor
// 3 vertex indices at ${indexByteCount} bytes
var
faceListLength
=
includeIndices
?
faceCount
*
(
indexByteCount
*
3
+
1
)
:
0
;
var
output
=
new
DataView
(
new
ArrayBuffer
(
headerBin
.
length
+
vertexListLength
+
faceListLength
)
);
new
Uint8Array
(
output
.
buffer
).
set
(
headerBin
,
0
);
var
vOffset
=
headerBin
.
length
;
var
fOffset
=
headerBin
.
length
+
vertexListLength
;
var
writtenVertices
=
0
;
traverseMeshes
(
function
(
mesh
,
geometry
)
{
var
vertices
=
geometry
.
getAttribute
(
'
position
'
);
var
normals
=
geometry
.
getAttribute
(
'
normal
'
);
var
uvs
=
geometry
.
getAttribute
(
'
uv
'
);
var
colors
=
geometry
.
getAttribute
(
'
color
'
);
var
indices
=
geometry
.
getIndex
();
normalMatrixWorld
.
getNormalMatrix
(
mesh
.
matrixWorld
);
for
(
var
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
++
)
{
vertex
.
x
=
vertices
.
getX
(
i
);
vertex
.
y
=
vertices
.
getY
(
i
);
vertex
.
z
=
vertices
.
getZ
(
i
);
vertex
.
applyMatrix4
(
mesh
.
matrixWorld
);
}
else
if
(
includeUVs
!==
false
)
{
line
+=
'
0 0
'
;
// Position information
output
.
setFloat32
(
vOffset
,
vertex
.
x
);
vOffset
+=
4
;
}
output
.
setFloat32
(
vOffset
,
vertex
.
y
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
vertex
.
z
);
vOffset
+=
4
;
// Normal information
if
(
includeNormals
===
true
)
{
if
(
normals
!=
null
)
{
vertex
.
x
=
normals
.
getX
(
i
);
vertex
.
y
=
normals
.
getY
(
i
);
vertex
.
z
=
normals
.
getZ
(
i
);
vertex
.
applyMatrix3
(
normalMatrixWorld
);
output
.
setFloat32
(
vOffset
,
vertex
.
x
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
vertex
.
y
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
vertex
.
z
);
vOffset
+=
4
;
}
else
{
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
}
// Color information
if
(
includeColors
===
true
)
{
}
if
(
colors
!==
undefined
)
{
// UV information
if
(
includeUVs
===
true
)
{
line
+=
'
'
+
Math
.
floor
(
colors
.
getX
(
i
)
)
+
'
'
+
Math
.
floor
(
colors
.
getY
(
i
)
)
+
'
'
+
Math
.
floor
(
colors
.
getZ
(
i
)
);
if
(
uvs
!=
null
)
{
}
else
{
output
.
setFloat32
(
vOffset
,
uvs
.
getX
(
i
)
);
vOffset
+=
4
;
line
+=
'
255 255 255
'
;
output
.
setFloat32
(
vOffset
,
uvs
.
getY
(
i
)
);
vOffset
+=
4
;
}
}
else
if
(
includeUVs
!==
false
)
{
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
output
.
setFloat32
(
vOffset
,
0
);
vOffset
+=
4
;
}
vertexList
+=
line
+
'
\n
'
;
}
// Color information
if
(
includeColors
===
true
)
{
if
(
colors
!=
null
)
{
output
.
setUint8
(
vOffset
,
Math
.
floor
(
colors
.
getX
(
i
)
*
255
)
);
vOffset
+=
1
;
output
.
setUint8
(
vOffset
,
Math
.
floor
(
colors
.
getY
(
i
)
*
255
)
);
vOffset
+=
1
;
output
.
setUint8
(
vOffset
,
Math
.
floor
(
colors
.
getZ
(
i
)
*
255
)
);
vOffset
+=
1
;
}
else
{
output
.
setUint8
(
vOffset
,
255
);
vOffset
+=
1
;
output
.
setUint8
(
vOffset
,
255
);
vOffset
+=
1
;
output
.
setUint8
(
vOffset
,
255
);
vOffset
+=
1
;
}
}
}
if
(
includeIndices
===
true
)
{
// Create the face list
var
faceIndexFunc
=
`setUint
${
indexByteCount
*
8
}
`
;
if
(
indices
!==
null
)
{
for
(
i
=
0
,
l
=
indices
.
count
;
i
<
l
;
i
+=
3
)
{
for
(
var
i
=
0
,
l
=
indices
.
count
;
i
<
l
;
i
+=
3
)
{
output
.
setUint8
(
fOffset
,
3
);
fOffset
+=
1
;
faceList
+=
`3
${
indices
.
getX
(
i
+
0
)
+
vertexCount
}
`
;
faceList
+=
`
${
indices
.
getX
(
i
+
1
)
+
vertexCount
}
`
;
faceList
+=
`
${
indices
.
getX
(
i
+
2
)
+
vertexCount
}
\n`
;
output
[
faceIndexFunc
](
fOffset
,
indices
.
getX
(
i
+
0
)
+
writtenVertices
);
fOffset
+=
indexByteCount
;
output
[
faceIndexFunc
](
fOffset
,
indices
.
getX
(
i
+
1
)
+
writtenVertices
);
fOffset
+=
indexByteCount
;
output
[
faceIndexFunc
](
fOffset
,
indices
.
getX
(
i
+
2
)
+
writtenVertices
);
fOffset
+=
indexByteCount
;
}
...
...
@@ -163,70 +374,164 @@ THREE.PLYExporter.prototype = {
for
(
var
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
+=
3
)
{
faceList
+=
`3
${
vertexCount
+
i
}
${
vertexCount
+
i
+
1
}
${
vertexCount
+
i
+
2
}
\n`
;
output
.
setUint8
(
fOffset
,
3
);
fOffset
+=
1
;
output
[
faceIndexFunc
](
fOffset
,
writtenVertices
+
i
);
fOffset
+=
indexByteCount
;
output
[
faceIndexFunc
](
fOffset
,
writtenVertices
+
i
+
1
);
fOffset
+=
indexByteCount
;
output
[
faceIndexFunc
](
fOffset
,
writtenVertices
+
i
+
2
);
fOffset
+=
indexByteCount
;
}
}
vertexCount
+=
vertices
.
count
;
faceCount
+=
indices
?
indices
.
count
/
3
:
vertices
.
count
/
3
;
}
// Save the amount of verts we've already written so we can offset
// the face index on the next mesh
writtenVertices
+=
vertices
.
count
;
}
);
return
output
;
}
else
{
// Ascii File Generation
// count the number of vertices
var
writtenVertices
=
0
;
var
vertexList
=
''
;
var
faceList
=
''
;
traverseMeshes
(
function
(
mesh
,
geometry
)
{
var
vertices
=
geometry
.
getAttribute
(
'
position
'
);
var
normals
=
geometry
.
getAttribute
(
'
normal
'
);
var
uvs
=
geometry
.
getAttribute
(
'
uv
'
);
var
colors
=
geometry
.
getAttribute
(
'
color
'
);
var
indices
=
geometry
.
getIndex
();
normalMatrixWorld
.
getNormalMatrix
(
mesh
.
matrixWorld
);
// form each line
for
(
var
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
++
)
{
vertex
.
x
=
vertices
.
getX
(
i
);
vertex
.
y
=
vertices
.
getY
(
i
);
vertex
.
z
=
vertices
.
getZ
(
i
);
vertex
.
applyMatrix4
(
mesh
.
matrixWorld
);
// Position information
var
line
=
vertex
.
x
+
'
'
+
vertex
.
y
+
'
'
+
vertex
.
z
;
// Normal information
if
(
includeNormals
===
true
)
{
if
(
normals
!=
null
)
{
vertex
.
x
=
normals
.
getX
(
i
);
vertex
.
y
=
normals
.
getY
(
i
);
vertex
.
z
=
normals
.
getZ
(
i
);
vertex
.
applyMatrix3
(
normalMatrixWorld
);
line
+=
'
'
+
vertex
.
x
+
'
'
+
vertex
.
y
+
'
'
+
vertex
.
z
;
}
else
{
line
+=
'
0 0 0
'
;
}
}
// UV information
if
(
includeUVs
===
true
)
{
if
(
uvs
!=
null
)
{
line
+=
'
'
+
uvs
.
getX
(
i
)
+
'
'
+
uvs
.
getY
(
i
);
}
else
if
(
includeUVs
!==
false
)
{
line
+=
'
0 0
'
;
}
}
// Color information
if
(
includeColors
===
true
)
{
if
(
colors
!=
null
)
{
line
+=
'
'
+
Math
.
floor
(
colors
.
getX
(
i
)
*
255
)
+
'
'
+
Math
.
floor
(
colors
.
getY
(
i
)
*
255
)
+
'
'
+
Math
.
floor
(
colors
.
getZ
(
i
)
*
255
);
}
else
{
line
+=
'
255 255 255
'
;
}
}
vertexList
+=
line
+
'
\n
'
;
}
}
// Create the face list
if
(
includeIndices
===
true
)
{
}
);
if
(
indices
!==
null
)
{
var
output
=
'
ply
\n
'
+
'
format ascii 1.0
\n
'
+
`element vertex
${
vertexCount
}
\n`
+
for
(
var
i
=
0
,
l
=
indices
.
count
;
i
<
l
;
i
+=
3
)
{
// position
'
property float x
\n
'
+
'
property float y
\n
'
+
'
property float z
\n
'
;
faceList
+=
`3
${
indices
.
getX
(
i
+
0
)
+
writtenVertices
}
`
;
faceList
+=
`
${
indices
.
getX
(
i
+
1
)
+
writtenVertices
}
`
;
faceList
+=
`
${
indices
.
getX
(
i
+
2
)
+
writtenVertices
}
\n`
;
if
(
includeNormals
===
true
)
{
}
// normal
output
+=
'
property float nx
\n
'
+
'
property float ny
\n
'
+
'
property float nz
\n
'
;
}
else
{
}
for
(
var
i
=
0
,
l
=
vertices
.
count
;
i
<
l
;
i
+=
3
)
{
if
(
includeUVs
===
true
)
{
faceList
+=
`3
${
writtenVertices
+
i
}
${
writtenVertices
+
i
+
1
}
${
writtenVertices
+
i
+
2
}
\n`
;
// uvs
output
+=
'
property float s
\n
'
+
'
property float t
\n
'
;
}
}
}
if
(
includeColors
===
true
)
{
faceCount
+=
indices
?
indices
.
count
/
3
:
vertices
.
count
/
3
;
// colors
output
+=
'
property uchar red
\n
'
+
'
property uchar green
\n
'
+
'
property uchar blue
\n
'
;
}
}
writtenVertices
+=
vertices
.
count
;
// faces
output
+=
`element face
${
faceCount
}
\n`
+
'
property list uchar int vertex_index
\n
'
+
'
end_header
\n
'
+
}
);
`
${
vertexList
}
\n`
+
`
${
faceList
}
\n`
;
return
`
${
header
}${
vertexList
}
\n
${
includeIndices
?
`
${
faceList
}
\n`
:
''
}
`
;
return
output
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录