private void AddFace(string values)
{
var currentGroup = this.CurrentGroup;
var builder = currentGroup.MeshBuilder;
var positions = builder.Positions;
var textureCoordinates = builder.TextureCoordinates;
var normals = builder.Normals;
Dictionary<int, int> smoothingGroupMap = null;
// If a smoothing group is defined, get the map from obj-file-index to current-group-vertex-index.
if (this.currentSmoothingGroup != 0)
{
if (!this.smoothingGroupMaps.TryGetValue(this.currentSmoothingGroup, out smoothingGroupMap))
{
smoothingGroupMap = new Dictionary<int, int>();
this.smoothingGroupMaps.Add(this.currentSmoothingGroup, smoothingGroupMap);
}
}
var fields = values.SplitOnWhitespace();
var faceIndices = new List<int>();
foreach (var field in fields)
{
if (string.IsNullOrEmpty(field))
{
continue;
}
var ff = field.Split('/');
int vi = int.Parse(ff[0]);
int vti = ff.Length > 1 && ff[1].Length > 0 ? int.Parse(ff[1]) : int.MaxValue;
int vni = ff.Length > 2 && ff[2].Length > 0 ? int.Parse(ff[2]) : int.MaxValue;
// Handle relative indices (negative numbers)
if (vi < 0)
{
vi = this.Points.Count + vi + 1;
}
if (vti < 0)
{
vti = this.TextureCoordinates.Count + vti + 1;
}
if (vni < 0)
{
vni = this.Normals.Count + vni + 1;
}
// Check if the indices are valid
if (vi - 1 >= this.Points.Count)
{
if (this.IgnoreErrors)
{
return;
}
throw new FileFormatException(string.Format("Invalid vertex index ({0}) on line {1}.", vi, this.currentLineNo));
}
if (vti == int.MaxValue)
{
// turn off texture coordinates in the builder
//builder.CreateTextureCoordinates = false;
builder.TextureCoordinates = null;
}
if (vni == int.MaxValue)
{
// turn off normals in the builder
//builder.CreateNormals = false;
builder.Normals = null;
}
// check if the texture coordinate index is valid
if (builder.HasTexCoords && vti - 1 >= this.TextureCoordinates.Count)
{
if (this.IgnoreErrors)
{
return;
}
throw new FileFormatException(string.Format("Invalid texture coordinate index ({0}) on line {1}.", vti, this.currentLineNo));
}
// check if the normal index is valid
if (builder.HasNormals && vni - 1 >= this.Normals.Count)
{
if (this.IgnoreErrors)
{
return;
}
throw new FileFormatException(string.Format("Invalid normal index ({0}) on line {1}.", vni, this.currentLineNo));
}
bool addVertex = true;
if (smoothingGroupMap != null)
{
int vix;
if (smoothingGroupMap.TryGetValue(vi, out vix))
{
// use the index of a previously defined vertex
addVertex = false;
}
else
{
// add a new vertex
vix = positions.Count;
smoothingGroupMap.Add(vi, vix);
}
faceIndices.Add(vix);
}
else
{
// if smoothing is off, always add a new vertex
faceIndices.Add(positions.Count);
}
if (addVertex)
{
// add vertex
positions.Add(this.Points[vi - 1]);
// add texture coordinate (if enabled)
if (builder.HasTexCoords)
{
textureCoordinates.Add(this.TextureCoordinates[vti - 1]);
}
// add normal (if enabled)
if (builder.HasNormals)
{
normals.Add(this.Normals[vni - 1]);
}
}
}
try
{
if (faceIndices.Count < 3)
{
throw new HelixToolkitException("Polygon must have at least 3 indices!");
}
if (this.ModelInfo.Faces == MeshFaces.QuadPatches)
{
if (faceIndices.Count == 3)
{
faceIndices.Add(faceIndices.Last());
builder.AddQuad(faceIndices);
}
if (faceIndices.Count == 4)
{
builder.AddQuad(faceIndices);
}
else
{
// add triangles by cutting ears algorithm
// this algorithm is quite expensive...
builder.AddPolygonByCuttingEars(faceIndices);
}
}
else
{
if (faceIndices.Count == 3)
{
builder.AddTriangle(faceIndices);
}
else if (faceIndices.Count == 4)
{
//builder.AddQuad(faceIndices);
builder.AddTriangleFan(faceIndices);
}
else
{
// add triangles by cutting ears algorithm
// this algorithm is quite expensive...
builder.AddPolygonByCuttingEars(faceIndices);
}
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(string.Format("Error composing polygonal object: {0}", ex.Message), "Error", MessageBoxButton.OKCancel);
}
}