Пример #1
0
        public static void Validate(this IG3D g3d)
        {
            // Check that no attributes are null
            var n = g3d.Attributes.Count(attr => attr == null);

            if (n > 0)
            {
                throw new Exception("Attributes cannot be null");
            }

            // Assure that there are no duplicates
            g3d.Attributes.ToDictionary();

            // Validate the descriptors
            foreach (var attr in g3d.Attributes)
            {
                attr.Descriptor.Validate();
            }

            // Compute the number of faces
            var faceCount = g3d.FaceCount();

            // Assure that there is a vertex attribute
            if (g3d.VertexAttribute.Descriptor.Association != Association.assoc_vertex)
            {
                throw new Exception("Vertex buffer is not associated with vertex: " + g3d.VertexAttribute.Descriptor);
            }

            if (g3d.VertexAttribute.Descriptor.DataArity != 3)
            {
                throw new Exception("Vertices should have an arity of 3");
            }

            if (g3d.Attributes(AttributeType.attr_vertex).Count() > 1)
            {
                throw new Exception("There can only be one vertex data set");
            }

            // Compute the number of vertices
            var vertexCount = g3d.VertexCount();

            // Computes the number of corners
            var cornerCount = g3d.CornerVertexIndices().Count;

            // Compute the number of groups. Groups requires the precense of a GroupIndex attribute
            var groupCount = g3d.GroupIndexAttributes().FirstOrDefault()?.Count ?? -1;

            // Compute the number of instance. The first instance channel determines the number of instances
            var instanceCount = g3d.Attributes(Association.assoc_instance).FirstOrDefault()?.Count ?? -1;

            // Check the number of items in each attribute
            foreach (var attr in g3d.Attributes)
            {
                switch (attr.Descriptor.Association)
                {
                case Association.assoc_vertex:
                    if (attr.Count != vertexCount)
                    {
                        throw new Exception($"Attribute {attr.Descriptor} has {attr.Count} items, expected {vertexCount}");
                    }
                    break;

                case Association.assoc_face:
                    if (attr.Count != faceCount)
                    {
                        throw new Exception($"Attribute {attr.Descriptor} has {attr.Count} items, expected {faceCount}");
                    }
                    break;

                case Association.assoc_corner:
                    if (attr.Count != cornerCount)
                    {
                        throw new Exception($"Attribute {attr.Descriptor} has {attr.Count} items, expected {cornerCount}");
                    }
                    break;

                case Association.assoc_edge:
                    if (attr.Count != cornerCount)
                    {
                        throw new Exception($"Attribute {attr.Descriptor} has {attr.Count} items, expected {cornerCount}");
                    }
                    break;

                case Association.assoc_object:
                    if (attr.Count != 1)
                    {
                        throw new Exception($"Attribute {attr.Descriptor} has {attr.Count} items, expected 1");
                    }
                    break;

                case Association.assoc_group:
                    if (attr.Count != groupCount)
                    {
                        throw new Exception($"Attribute {attr.Descriptor} has {attr.Count} items, expected {groupCount}");
                    }
                    break;

                case Association.assoc_instance:
                    if (attr.Count != instanceCount)
                    {
                        throw new Exception($"Attribute {attr.Descriptor} has {attr.Count} items, expected {instanceCount}");
                    }
                    break;

                case Association.assoc_none:
                    break;

                default:
                    throw new Exception($"Attribute {attr.Descriptor} has invalid association");
                }
            }

            // The following rules are stricter than absolutely necessary, but respecting them
            // will make coding geometry libraries easier to write on top of the thing.

            g3d.Attributes(AttributeType.attr_binormal).ToList()
            .ValidateDataType(DataType.dt_float32)
            .ValidateArity(3)
            .ValidateAssociation(Association.assoc_vertex);

            g3d.Attributes(AttributeType.attr_tangent).ToList()
            .ValidateDataType(DataType.dt_float32)
            .ValidateArity(3)
            .ValidateAssociation(Association.assoc_vertex);

            g3d.Attributes(AttributeType.attr_normal).ToList()
            .ValidateDataType(DataType.dt_float32)
            .ValidateArity(3)
            .ValidateAssociation(Association.assoc_face, Association.assoc_corner, Association.assoc_vertex);

            g3d.Attributes(AttributeType.attr_color).ToList()
            .ValidateArity(1, 3, 4)
            .ValidateAssociation(Association.assoc_face, Association.assoc_corner, Association.assoc_vertex,
                                 Association.assoc_object);

            g3d.Attributes(AttributeType.attr_visibility).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_int8, DataType.dt_int32, DataType.dt_float32);

            g3d.Attributes(AttributeType.attr_faceindex).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_int32)
            .ValidateAssociation(Association.assoc_face)
            .ValidateMaxOne();

            g3d.Attributes(AttributeType.attr_facesize).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_int32)
            .ValidateAssociation(Association.assoc_face, Association.assoc_object)
            .ValidateMaxOne();

            g3d.Attributes(AttributeType.attr_index).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_int32)
            .ValidateAssociation(Association.assoc_corner)
            .ValidateMaxOne();

            g3d.Attributes(AttributeType.attr_uv).ToList()
            .ValidateArity(2, 3)
            .ValidateDataType(DataType.dt_float32)
            .ValidateAssociation(Association.assoc_vertex, Association.assoc_corner);

            g3d.Attributes(AttributeType.attr_invalid).ToList()
            .ValidateNone();

            g3d.Attributes(AttributeType.attr_index).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_int32)
            .ValidateAssociation(Association.assoc_corner)
            .ValidateMaxOne();

            g3d.Attributes(AttributeType.attr_mapchannel_data).ToList()
            .ValidateArity(3)
            .ValidateDataType(DataType.dt_float32)
            .ValidateAssociation(Association.assoc_none);

            g3d.Attributes(AttributeType.attr_mapchannel_index).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_int32)
            .ValidateAssociation(Association.assoc_corner);

            g3d.Attributes(AttributeType.attr_materialid).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_int32)
            .ValidateAssociation(Association.assoc_face);

            g3d.Attributes(AttributeType.attr_pervertex).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_float32)
            .ValidateAssociation(Association.assoc_vertex);

            g3d.Attributes(AttributeType.attr_polygroup).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_int32)
            .ValidateAssociation(Association.assoc_face);

            g3d.Attributes(AttributeType.attr_smoothing).ToList()
            .ValidateArity(1)
            .ValidateDataType(DataType.dt_int32)
            .ValidateAssociation(Association.assoc_face);

            g3d.Attributes(AttributeType.attr_instance_transform).ToList()
            .ValidateArity(16)
            .ValidateDataType(DataType.dt_float32)
            .ValidateAssociation(Association.assoc_instance);

            g3d.Attributes(AttributeType.attr_vertex).ToList()
            .ValidateArity(3)
            .ValidateDataType(DataType.dt_float32, DataType.dt_float64)
            .ValidateAssociation(Association.assoc_vertex)
            .ValidateExactlyOne();
        }
Пример #2
0
 public static IArray <int> CornerVertexIndices(this IG3D g3d)
 => g3d.IndexAttribute == null
         ? g3d.VertexCount().Range()
         : g3d.IndexAttribute.ToInts();