/// <summary>
        /// Creates a readme to list which model groups are being generated.
        /// </summary>
        public static void UpdateMainReadme(Assembly executingAssembly, List <List <Manifest> > manifests, string savePath, string[] testGroupName)
        {
            // Use the manifest list to build a table of contents.
            var newTableOfContents = new StringBuilder();
            var testGroupNameIndex = 0;

            foreach (var manifest in manifests)
            {
                newTableOfContents.AppendLine("");
                newTableOfContents.AppendLine($"## {testGroupName[testGroupNameIndex]} Tests");
                foreach (var modelgroup in manifest)
                {
                    string ReadableFolderName = ReadmeStringHelper.GenerateNameWithSpaces(modelgroup.Folder, true);
                    newTableOfContents.AppendLine($"- [{ReadableFolderName}](Output/{testGroupName[testGroupNameIndex]}/{modelgroup.Folder}/README.md)");
                }
                testGroupNameIndex++;
            }

            // Reads the readme file template.
            string template;

            using (Stream stream = executingAssembly.GetManifestResourceStream("AssetGenerator.ReadmeTemplates.Page_Main.md"))
                using (var streamReader = new StreamReader(stream))
                {
                    template = streamReader.ReadToEnd();
                }

            // Find and replace the table of contents section with the newly built one.
            template = template.Replace($"~~TableOfContents~~", newTableOfContents.ToString());

            // Write out the readme file.
            string readmeFilePath = Path.Combine(savePath, "README.md");

            File.WriteAllText(readmeFilePath, template);
        }
Example #2
0
        static public void UpdateMainReadme(Assembly executingAssembly, string outputFolder, List <Manifest> manifests)
        {
            // Use the main manifest to build an updated table of contents
            StringBuilder newTableOfContents = new StringBuilder();

            foreach (var modelgroup in manifests)
            {
                newTableOfContents.AppendLine(string.Format("- [{0}](Output/{1}/README.md)",
                                                            ReadmeStringHelper.GenerateNameWithSpaces(modelgroup.folder, true), modelgroup.folder));
            }

            // Reads the readme file template
            string template;
            string templatePath = "AssetGenerator.ReadmeTemplates.README.md";

            using (Stream stream = executingAssembly.GetManifestResourceStream(templatePath))
                using (var streamReader = new StreamReader(stream))
                {
                    template = streamReader.ReadToEnd();
                }

            // Find and replace the table of contents section with the newly built one
            template = template.Replace("~~TableOfContents~~", newTableOfContents.ToString());

            // Write out the readme file
            string readmeFilePath = Path.Combine(Directory.GetParent(outputFolder).ToString(), "README.md");

            File.WriteAllText(readmeFilePath, template);
        }
 public Property(PropertyName enumName, object displayValue)
 {
     Name             = enumName;
     ReadmeColumnName = ReadmeStringHelper.GenerateNameWithSpaces(enumName.ToString());
     ReadmeValue      = ReadmeStringHelper.ConvertValueToString(displayValue);
 }
Example #4
0
        public void SetupHeader(ModelGroup test)
        {
            // Setup the log file header
            if (test.requiredProperty != null)
            {
                // List attributes that are set in every generated model (prerequisites)
                readmePrereqs.Add(new List <string>()); // First line of table must be blank
                readmePrereqs.Add(new List <string>
                {
                    "Property", // First cells are a static label
                    "**Values**"
                });
                readmePrereqs.Add(new List <string>
                {
                    ":---:", // Hyphens for row after header
                    ":---:",
                });
                for (int i = 0; i < test.requiredProperty.Count; i++)
                {
                    string attributeName;
                    attributeName = test.requiredProperty[i].name.ToString();
                    attributeName = ReadmeStringHelper.GenerateNameWithSpaces(attributeName);
                    readmePrereqs.Add(new List <string>
                    {
                        attributeName,
                        ReadmeStringHelper.ConvertTestValueToString(test.requiredProperty[i])
                    });
                }
            }

            // Now start the table for generated models
            readme.Add(new List <string>()); // First line of table must be blank
            readme.Add(new List <string>
            {
                " ",
                "Reference Image"     // First cell is empty, the second is a static header name
            });
            readme.Add(new List <string>
            {
                ":---:",     // Hyphens for rows after header
                ":---:"
            });
            for (int i = 0; i < test.properties.Count; i++)
            {
                string attributeName;
                if (test.properties[i].prerequisite != Propertyname.Undefined && test.properties[i].propertyGroup == 0)
                {
                    attributeName = test.properties[i].prerequisite.ToString() + test.properties[i].name.ToString();
                }
                else
                {
                    attributeName = test.properties[i].name.ToString();
                }
                attributeName = ReadmeStringHelper.GenerateNameWithSpaces(attributeName);
                if (attributeName != lastName) // Skip duplicate names caused by non-binary attributes
                {
                    lastName = attributeName;
                    readme[1].Add(attributeName);
                    readme[2].Add(":---:");
                }
            }
        }
Example #5
0
        public void SetupTable(ModelGroup test, int comboIndex, List <List <Property> > combos)
        {
            string modelGroupName = test.modelGroupName.ToString();
            string modelNumber    = comboIndex.ToString("D2");
            string liveURL        = string.Format("https://bghgary.github.io/glTF-Asset-Generator/Preview/BabylonJS/?fileName={0}_{1}.gltf",
                                                  modelGroupName, modelNumber);

            readme.Add(new List <string> // New row for a new model
            {
                // Displays the number of the model and is a link to the model
                string.Format("[{1}]({0}_{1}.gltf)<br>[View]({2})", modelGroupName, modelNumber, liveURL),
                // Also a reference image in the second cell
                string.Format("[<img src=\"Thumbnails/{0}_{1}.png\" align=\"middle\">](ReferenceImages/{0}_{1}.png)",
                              modelGroupName, modelNumber)
            });
            int        logIndex      = readme.Count - 1;
            List <int> nonBinaryUsed = new List <int>();

            foreach (var possibleAttribute in test.properties)
            {
                var attributeIndex = combos[comboIndex].FindIndex(e =>
                                                                  e.name == possibleAttribute.name &&
                                                                  e.prerequisite == possibleAttribute.prerequisite);
                if (attributeIndex != -1)
                {
                    if (possibleAttribute.propertyGroup > 0)
                    {
                        var alreadyUsed = nonBinaryUsed.Exists(x => x == possibleAttribute.propertyGroup);
                        if (alreadyUsed)
                        {
                            // Overwrites the empty cell if a nonbinary of the same time had already been encountered and not used
                            readme[logIndex][readme[logIndex].Count - 1] = ReadmeStringHelper.ConvertTestValueToString(possibleAttribute);
                        }
                        else
                        {
                            // Creates a new cell, since this nonbinary type had not been encountered before
                            readme[logIndex].Add(ReadmeStringHelper.ConvertTestValueToString(possibleAttribute));
                            nonBinaryUsed.Add(possibleAttribute.propertyGroup);
                        }
                    }
                    else
                    {
                        readme[logIndex].Add(ReadmeStringHelper.ConvertTestValueToString(possibleAttribute));
                    }
                }
                else
                {
                    if (possibleAttribute.propertyGroup > 0)
                    {
                        var alreadyUsed = nonBinaryUsed.Exists(x => x == possibleAttribute.propertyGroup);
                        if (!alreadyUsed)
                        {
                            readme[logIndex].Add(" ");
                            nonBinaryUsed.Add(possibleAttribute.propertyGroup);
                        }
                    }
                    else
                    {
                        readme[logIndex].Add(" ");
                    }
                }
            }
        }
Example #6
0
        private static void Main(string[] args)
        {
            Stopwatch.StartNew();

            Assembly        executingAssembly       = Assembly.GetExecutingAssembly();
            string          executingAssemblyFolder = Path.GetDirectoryName(executingAssembly.Location);
            string          outputFolder            = Path.GetFullPath(Path.Combine(executingAssemblyFolder, @"..\..\..\..\Output"));
            List <Manifest> manifestMaster          = new List <Manifest>();

            // Make an inventory of what images there are
            var textures = FileHelper.FindImageFiles(executingAssembly, "Textures");
            var figures  = FileHelper.FindImageFiles(executingAssembly, "Figures");

            // Uses Reflection to create a list containing one instance of each group of models
            List <dynamic> allModelGroups = new List <dynamic>();

            foreach (var type in executingAssembly.GetTypes())
            {
                var modelGroupAttribute = type.GetCustomAttribute <ModelGroupAttribute>();
                if (modelGroupAttribute != null)
                {
                    ConstructorInfo ctor       = type.GetConstructor(new Type[] { typeof(List <string>), typeof(List <string>) });
                    dynamic         modelGroup = ctor.Invoke(new dynamic[] { textures, figures });
                    allModelGroups.Add(modelGroup);
                }
            }

            foreach (var modelGroup in allModelGroups)
            {
                List <List <Property> > combos = ComboHelper.AttributeCombos(modelGroup);

                ReadmeBuilder readme   = new ReadmeBuilder();
                Manifest      manifest = new Manifest(modelGroup.modelGroupName);

                string assetFolder = Path.Combine(outputFolder, modelGroup.modelGroupName.ToString());

                FileHelper.ClearOldFiles(outputFolder, assetFolder);
                Directory.CreateDirectory(assetFolder);

                // Copy all of the images used by the model group into that model group's output directory
                FileHelper.CopyImageFiles(executingAssembly, assetFolder, modelGroup.usedTextures, useThumbnails: true);
                FileHelper.CopyImageFiles(executingAssembly, assetFolder, modelGroup.usedFigures);


                readme.SetupHeader(modelGroup);

                int numCombos = combos.Count;
                for (int comboIndex = 0; comboIndex < numCombos; comboIndex++)
                {
                    string[] name = ReadmeStringHelper.GenerateName(combos[comboIndex]);

                    var asset = new Runtime.Asset
                    {
                        Generator = "glTF Asset Generator",
                        Version   = "2.0",
                        Extras    = new Runtime.Extras
                        {
                            // Inserts a string into the .gltf containing the properties that are set for a given model, for debug.
                            Attributes = String.Join(" - ", name)
                        }
                    };

                    var gltf = new glTFLoader.Schema.Gltf
                    {
                        Asset = asset.ConvertToSchema()
                    };

                    var dataList = new List <Data>();

                    var geometryData = new Data(modelGroup.modelGroupName.ToString() + "_" + comboIndex.ToString("00") + ".bin");
                    dataList.Add(geometryData);

                    Runtime.GLTF wrapper = Common.SinglePlane();

                    wrapper.Asset = asset;

                    Runtime.Material mat = new Runtime.Material();

                    // Takes the current combo and uses it to bundle together the data for the desired properties
                    wrapper = modelGroup.SetModelAttributes(wrapper, mat, combos[comboIndex], ref gltf);

                    // Passes the desired properties to the runtime layer, which then coverts that data into
                    // a gltf loader object, ready to create the model
                    Runtime.GLTFConverter.ConvertRuntimeToSchema(wrapper, ref gltf, geometryData);

                    // Makes last second changes to the model that bypass the runtime layer
                    // in order to add 'features that don't really exist otherwise
                    modelGroup.PostRuntimeChanges(combos[comboIndex], ref gltf);

                    // Creates the .gltf file and writes the model's data to it
                    var filename  = modelGroup.modelGroupName.ToString() + "_" + comboIndex.ToString("00") + ".gltf";
                    var assetFile = Path.Combine(assetFolder, filename);
                    glTFLoader.Interface.SaveModel(gltf, assetFile);

                    // Creates the .bin file and writes the model's data to it
                    foreach (var data in dataList)
                    {
                        data.Writer.Flush();

                        var dataFile = Path.Combine(assetFolder, data.Name);
                        File.WriteAllBytes(dataFile, ((MemoryStream)data.Writer.BaseStream).ToArray());
                    }

                    readme.SetupTable(modelGroup, comboIndex, combos);
                    manifest.files.Add(filename);
                }

                readme.WriteOut(executingAssembly, modelGroup, assetFolder);
                manifestMaster.Add(manifest);

                // Write out the manifest JSON specific to this model group
                string json = Newtonsoft.Json.JsonConvert.SerializeObject(manifest, Newtonsoft.Json.Formatting.Indented);
                File.WriteAllText(Path.Combine(assetFolder, "Manifest.json"), json);
            }

            // Write out the master manifest JSON containing all of the model groups
            string jsonMaster = Newtonsoft.Json.JsonConvert.SerializeObject(manifestMaster.ToArray(), Newtonsoft.Json.Formatting.Indented);

            File.WriteAllText(Path.Combine(outputFolder, "Manifest.json"), jsonMaster);

            // Update the main readme
            ReadmeBuilder.UpdateMainReadme(executingAssembly, outputFolder, manifestMaster);

            // Create reference images
            ReferenceImages.Create(executingAssembly, outputFolder, manifestMaster);

            Console.WriteLine("Model Creation Complete!");
            Console.WriteLine("Completed in : " + TimeSpan.FromTicks(Stopwatch.GetTimestamp()).ToString());
        }