/// <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); }
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); }
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(":---:"); } } }
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(" "); } } } }
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()); }