Example #1
0
        public G3DAdapter(IG3D g3D)
        {
            //g3D.Validate();

            G3D = g3D;

            FaceSizes     = g3D.FaceSizes();
            PointsPerFace = g3D.HasFixedFaceSize() ? g3D.FirstFaceSize() : 0;
            Vertices      = g3D.VertexAttribute.ToVector3s();
            Indices       = g3D.CornerVertexIndices();
            NumFaces      = g3D.FaceCount();
            FaceIndices   = g3D.FaceIndices();
            MaterialIds   = g3D.MaterialIds();
        }
Example #2
0
 public static IArray <int> FaceIndices(this IG3D g3d)
 => g3d.FaceIndexAttribute?.ToInts()
 ?? (g3d.HasFixedFaceSize()
            ? g3d.CornerVertexIndices().Indices().Stride(g3d.FirstFaceSize())
            : g3d.FaceSizes().Accumulate((x, y) => x + y));
Example #3
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();
        }
Example #4
0
 public static int FaceCount(this IG3D g3d)
 => g3d.HasFixedFaceSize()
         ? g3d.CornerVertexIndices().Count / g3d.FirstFaceSize()
         : g3d.FaceSizeAttribute.ToInts().Count;