Refactor ply material handling.
This commit is contained in:
parent
42955d417d
commit
721a748198
@ -84,6 +84,66 @@ OV.PlyHeader = class
|
||||
}
|
||||
};
|
||||
|
||||
OV.PlyMaterialHandler = class
|
||||
{
|
||||
constructor (model)
|
||||
{
|
||||
this.model = model;
|
||||
this.vertexColors = [];
|
||||
this.colorToMaterial = {};
|
||||
}
|
||||
|
||||
AddVertexColor (color)
|
||||
{
|
||||
this.vertexColors.push (color);
|
||||
}
|
||||
|
||||
GetTriangleColor (v0, v1, v2)
|
||||
{
|
||||
let vertexCount = this.vertexColors.length;
|
||||
if (v0 >= vertexCount || v1 >= vertexCount || v2 >= vertexCount) {
|
||||
return null;
|
||||
}
|
||||
return this.vertexColors[v0];
|
||||
}
|
||||
|
||||
GetTriangleFaceMaterialIndex (color)
|
||||
{
|
||||
return this.GetMaterialIndexByColor (color);
|
||||
}
|
||||
|
||||
GetTriangleVertexMaterialIndex (v0, v1, v2)
|
||||
{
|
||||
let color = this.GetTriangleColor (v0, v1, v2);
|
||||
if (color === null) {
|
||||
return null;
|
||||
}
|
||||
return this.GetMaterialIndexByColor (color);
|
||||
}
|
||||
|
||||
GetMaterialIndexByColor (color)
|
||||
{
|
||||
let materialName = 'Color ' +
|
||||
OV.IntegerToHexString (color[0]) +
|
||||
OV.IntegerToHexString (color[1]) +
|
||||
OV.IntegerToHexString (color[2]) +
|
||||
OV.IntegerToHexString (color[3]);
|
||||
|
||||
let materialIndex = this.colorToMaterial[materialName];
|
||||
if (materialIndex === undefined) {
|
||||
let material = new OV.Material (OV.MaterialType.Phong);
|
||||
material.name = materialName;
|
||||
material.color = new OV.Color (color[0], color[1], color[2]);
|
||||
material.opacity = color[3] / 255.0;
|
||||
OV.UpdateMaterialTransparency (material);
|
||||
materialIndex = this.model.AddMaterial (material);
|
||||
this.colorToMaterial[materialName] = materialIndex;
|
||||
}
|
||||
|
||||
return materialIndex;
|
||||
}
|
||||
};
|
||||
|
||||
OV.ImporterPly = class extends OV.ImporterBase
|
||||
{
|
||||
constructor ()
|
||||
@ -238,7 +298,50 @@ OV.ImporterPly = class extends OV.ImporterBase
|
||||
|
||||
ReadBinaryContent (header, fileContent, headerLength)
|
||||
{
|
||||
function SkipAndGetColor (obj, reader, format, startIndex)
|
||||
function ReadByFormat (reader, format)
|
||||
{
|
||||
function ReadType (reader, type)
|
||||
{
|
||||
if (type === 'char' || type === 'int8') {
|
||||
return reader.ReadCharacter8 ();
|
||||
} else if (type === 'uchar' || type === 'uint8') {
|
||||
return reader.ReadUnsignedCharacter8 ();
|
||||
} else if (type === 'short' || type === 'int16') {
|
||||
return reader.ReadInteger16 ();
|
||||
} else if (type === 'ushort' || type === 'uint16') {
|
||||
return reader.ReadUnsignedInteger16 ();
|
||||
} else if (type === 'int' || type === 'int32') {
|
||||
return reader.ReadInteger32 ();
|
||||
} else if (type === 'uint' || type === 'uint32') {
|
||||
return reader.ReadUnsignedInteger32 ();
|
||||
} else if (type === 'float' || type === 'float32') {
|
||||
return reader.ReadFloat32 ();
|
||||
} else if (type === 'double' || type === 'double64') {
|
||||
return reader.ReadDouble64 ();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (format.isSingle) {
|
||||
return ReadType (reader, format.elemType);
|
||||
} else {
|
||||
let list = [];
|
||||
let count = ReadType (reader, format.countType);
|
||||
for (let i = 0; i < count; i++) {
|
||||
list.push (ReadType (reader, format.elemType));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
function SkipFormat (reader, format, startIndex)
|
||||
{
|
||||
for (let i = startIndex; i < format.length; i++) {
|
||||
ReadByFormat (reader, format[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function SkipAndGetColor (reader, format, startIndex)
|
||||
{
|
||||
let r = null;
|
||||
let g = null;
|
||||
@ -247,7 +350,7 @@ OV.ImporterPly = class extends OV.ImporterBase
|
||||
|
||||
for (let i = startIndex; i < format.length; i++) {
|
||||
let currFormat = format[i];
|
||||
let val = obj.ReadByFormat (reader, currFormat);
|
||||
let val = ReadByFormat (reader, currFormat);
|
||||
if (currFormat.name === 'red') {
|
||||
r = val;
|
||||
} else if (currFormat.name === 'green') {
|
||||
@ -266,47 +369,6 @@ OV.ImporterPly = class extends OV.ImporterBase
|
||||
return null;
|
||||
}
|
||||
|
||||
function GetMaterialFromColor (obj, color, colorToMaterial)
|
||||
{
|
||||
if (color === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let materialName = 'Color ' +
|
||||
OV.IntegerToHexString (color[0]) +
|
||||
OV.IntegerToHexString (color[1]) +
|
||||
OV.IntegerToHexString (color[2]) +
|
||||
OV.IntegerToHexString (color[3]);
|
||||
let materialIndex = colorToMaterial[materialName];
|
||||
if (materialIndex === undefined) {
|
||||
let material = new OV.Material (OV.MaterialType.Phong);
|
||||
material.name = materialName;
|
||||
material.color = new OV.Color (color[0], color[1], color[2]);
|
||||
material.opacity = color[3] / 255.0;
|
||||
OV.UpdateMaterialTransparency (material);
|
||||
materialIndex = obj.model.AddMaterial (material);
|
||||
colorToMaterial[materialName] = materialIndex;
|
||||
}
|
||||
|
||||
return materialIndex;
|
||||
}
|
||||
|
||||
function GetFaceColorByVertexColors (obj, v0, v1, v2, vertexColors, colorToMaterial)
|
||||
{
|
||||
let c0 = vertexColors[v0];
|
||||
let c1 = vertexColors[v1];
|
||||
let c2 = vertexColors[v2];
|
||||
let d0 = Math.abs (c0[0] - c1[0]) + Math.abs (c0[1] - c1[1]) + Math.abs (c0[2] - c1[2]);
|
||||
let d1 = Math.abs (c1[0] - c2[0]) + Math.abs (c1[1] - c2[1]) + Math.abs (c1[2] - c2[2]);
|
||||
let d2 = Math.abs (c0[0] - c2[0]) + Math.abs (c0[1] - c2[1]) + Math.abs (c0[2] - c2[2]);
|
||||
let min = Math.min (d0, d1, d2);
|
||||
let color = c0;
|
||||
if (min === d1) {
|
||||
color = c1;
|
||||
}
|
||||
return GetMaterialFromColor (obj, color, colorToMaterial);
|
||||
}
|
||||
|
||||
let reader = null;
|
||||
if (header.format === 'binary_little_endian') {
|
||||
reader = new OV.BinaryReader (fileContent, true);
|
||||
@ -317,43 +379,42 @@ OV.ImporterPly = class extends OV.ImporterBase
|
||||
}
|
||||
reader.Skip (headerLength);
|
||||
|
||||
let vertexColors = [];
|
||||
let colorToMaterial = {};
|
||||
let materialHandler = new OV.PlyMaterialHandler (this.model);
|
||||
let elements = header.GetElements ();
|
||||
for (let elementIndex = 0; elementIndex < elements.length; elementIndex++) {
|
||||
let element = elements[elementIndex];
|
||||
if (element.name === 'vertex') {
|
||||
for (let vertexIndex = 0; vertexIndex < element.count; vertexIndex++) {
|
||||
let x = this.ReadByFormat (reader, element.format[0]);
|
||||
let y = this.ReadByFormat (reader, element.format[1]);
|
||||
let z = this.ReadByFormat (reader, element.format[2]);
|
||||
let color = SkipAndGetColor (this, reader, element.format, 3);
|
||||
let x = ReadByFormat (reader, element.format[0]);
|
||||
let y = ReadByFormat (reader, element.format[1]);
|
||||
let z = ReadByFormat (reader, element.format[2]);
|
||||
let color = SkipAndGetColor (reader, element.format, 3);
|
||||
if (color !== null) {
|
||||
vertexColors.push (color);
|
||||
materialHandler.AddVertexColor (color);
|
||||
}
|
||||
this.mesh.AddVertex (new OV.Coord3D (x, y, z));
|
||||
}
|
||||
} else if (element.name === 'face') {
|
||||
for (let faceIndex = 0; faceIndex < element.count; faceIndex++) {
|
||||
let vertices = this.ReadByFormat (reader, element.format[0]);
|
||||
let faceColor = SkipAndGetColor (this, reader, element.format, 1);
|
||||
let vertices = ReadByFormat (reader, element.format[0]);
|
||||
let faceColor = SkipAndGetColor (reader, element.format, 1);
|
||||
for (let i = 0; i < vertices.length - 2; i++) {
|
||||
let v0 = vertices[0];
|
||||
let v1 = vertices[i + 1];
|
||||
let v2 = vertices[i + 2];
|
||||
let triangle = new OV.Triangle (v0, v1, v2);
|
||||
if (faceColor !== null) {
|
||||
triangle.mat = GetMaterialFromColor (this, faceColor, colorToMaterial);
|
||||
} else if (vertexColors.length === this.model.VertexCount ()) {
|
||||
triangle.mat = GetFaceColorByVertexColors (this, v0, v1, v2, vertexColors, colorToMaterial);
|
||||
triangle.mat = materialHandler.GetTriangleFaceMaterialIndex (faceColor);
|
||||
} else {
|
||||
triangle.mat = materialHandler.GetTriangleVertexMaterialIndex (v0, v1, v2);
|
||||
}
|
||||
this.mesh.AddTriangle (triangle);
|
||||
}
|
||||
}
|
||||
} else if (element.name === 'tristrips') {
|
||||
for (let triStripIndex = 0; triStripIndex < element.count; triStripIndex++) {
|
||||
let vertices = this.ReadByFormat (reader, element.format[0]);
|
||||
this.SkipFormat (reader, element.format, 1);
|
||||
let vertices = ReadByFormat (reader, element.format[0]);
|
||||
SkipFormat (reader, element.format, 1);
|
||||
let ccw = true;
|
||||
for (let i = 0; i < vertices.length - 2; i++) {
|
||||
let v0 = vertices[i];
|
||||
@ -375,51 +436,8 @@ OV.ImporterPly = class extends OV.ImporterBase
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.SkipFormat (reader, element.format, 0);
|
||||
SkipFormat (reader, element.format, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SkipFormat (reader, format, startIndex)
|
||||
{
|
||||
for (let i = startIndex; i < format.length; i++) {
|
||||
this.ReadByFormat (reader, format[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ReadByFormat (reader, format)
|
||||
{
|
||||
function ReadType (reader, type)
|
||||
{
|
||||
if (type === 'char' || type === 'int8') {
|
||||
return reader.ReadCharacter8 ();
|
||||
} else if (type === 'uchar' || type === 'uint8') {
|
||||
return reader.ReadUnsignedCharacter8 ();
|
||||
} else if (type === 'short' || type === 'int16') {
|
||||
return reader.ReadInteger16 ();
|
||||
} else if (type === 'ushort' || type === 'uint16') {
|
||||
return reader.ReadUnsignedInteger16 ();
|
||||
} else if (type === 'int' || type === 'int32') {
|
||||
return reader.ReadInteger32 ();
|
||||
} else if (type === 'uint' || type === 'uint32') {
|
||||
return reader.ReadUnsignedInteger32 ();
|
||||
} else if (type === 'float' || type === 'float32') {
|
||||
return reader.ReadFloat32 ();
|
||||
} else if (type === 'double' || type === 'double64') {
|
||||
return reader.ReadDouble64 ();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (format.isSingle) {
|
||||
return ReadType (reader, format.elemType);
|
||||
} else {
|
||||
let list = [];
|
||||
let count = ReadType (reader, format.countType);
|
||||
for (let i = 0; i < count; i++) {
|
||||
list.push (ReadType (reader, format.elemType));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user