Much hacking to change the generation of filenames and storage of same.

Option of creating 'deep directory' storage of filename.
Stored things now can have long names which is usually its UUID.
Got rid of the 'image' directory.
This commit is contained in:
Robert Adams
2019-02-16 20:19:58 -08:00
parent 3587d7ce6f
commit 56280830e3
12 changed files with 144 additions and 137 deletions
+60 -19
View File
@@ -15,8 +15,10 @@
*/
using System;
using System.Linq;
using System.Drawing;
using System.Collections.Generic;
using System.IO;
using System.Text;
using org.herbal3d.cs.CommonEntitiesUtil;
@@ -37,6 +39,21 @@ namespace org.herbal3d.cs.os.CommonEntities {
protected BLogger _log;
protected IParameters _params;
public PersistRules.AssetType AssetType = PersistRules.AssetType.Unknown;
// Return the filename for storing this object. Return null if doesn't store.
public string GetFilename(string pLongName) {
// often UUID's are turned to strings with hyphens. Make sure they are gone.
return PersistRules.GetFilename(this, pLongName, _params).Replace("-", "");
}
public string GetStorageDir(string pBaseDirectory, string pStorageName) {
string strippedStorageName = Path.GetFileNameWithoutExtension(pStorageName);
return PersistRules.StorageDirectory(pBaseDirectory, strippedStorageName, _params);
}
public string GetURI(string pURIBase, string pStorageName) {
return PersistRules.ReferenceURL(pURIBase, pStorageName);
}
public GltfClass() { }
public GltfClass(Gltf pRoot, string pID, BLogger pLog, IParameters pParams) {
BaseInit(pRoot, pID, pLog, pParams);
@@ -122,6 +139,11 @@ namespace org.herbal3d.cs.os.CommonEntities {
public GltfAttributes extensionsUsed; // list of extensions used herein
public GltfScene defaultScene; // ID of default scene
public OMV.UUID SceneUUID;
public readonly OMV.UUID GltfUUID; // Used to identify buffer
public readonly string IdentifyingString; // built from GltfUUID
public GltfAsset asset;
public GltfScenes scenes; // scenes that make up this package
@@ -142,13 +164,12 @@ namespace org.herbal3d.cs.os.CommonEntities {
public GltfSampler defaultSampler;
public PersistRules persist;
public Gltf(string pSceneName, BLogger pLog, IParameters pParams) : base() {
public Gltf(string pSceneName, BLogger pLog, IParameters pParams) :
base(null, pSceneName, pLog, pParams) {
gltfRoot = this;
_log = pLog;
_params = pParams;
persist = new PersistRules(PersistRules.AssetType.Scene, pSceneName, PersistRules.TargetType.Gltf, _log, _params);
AssetType = PersistRules.AssetType.Scene;
GltfUUID = OMV.UUID.Random();
IdentifyingString = GltfUUID.ToString().Replace("-", "");
extensionsUsed = new GltfAttributes();
asset = new GltfAsset(this, _log, _params);
@@ -322,7 +343,7 @@ namespace org.herbal3d.cs.os.CommonEntities {
// A key added to the buffer, vertices, and indices names to uniquify them
string buffNum = String.Format("{0:000}", buffers.Count + 1);
string buffName = this.defaultScene.name + "-buffer" + buffNum;
string buffName = this.defaultScene.name + "_buffer" + buffNum;
byte[] binBuffRaw = new byte[paddedSizeofIndices + sizeofVertices];
GltfBuffer binBuff = new GltfBuffer(gltfRoot, buffName, _log, _params) {
bufferBytes = binBuffRaw
@@ -575,18 +596,15 @@ namespace org.herbal3d.cs.os.CommonEntities {
return ret;
}
// Write the binary files into the specified target directory
// Write the binary files into the persist computed target directory
public void WriteBinaryFiles() {
foreach (var buff in buffers.Values) {
string outFilename = buff.persist.Filename;
// _log.DebugFormat("{0} WriteBinaryFiles: filename={1}", LogHeader, outFilename);
File.WriteAllBytes(outFilename, buff.bufferBytes);
buff.WriteBuffer();
}
}
public void WriteImages() {
foreach (var img in images.Values) {
img.imageInfo.persist.WriteImage(img.imageInfo);
img.WriteImage();
}
}
}
@@ -1148,18 +1166,21 @@ namespace org.herbal3d.cs.os.CommonEntities {
}
public class GltfBuffer : GltfClass {
public PersistRules persist;
public byte[] bufferBytes;
public string name;
public GltfExtensions extensions;
public GltfAttributes extras;
private readonly OMV.UUID _uuid; // Used to identify buffer
private readonly string _identifyingString;
public GltfBuffer(Gltf pRoot, string pID, BLogger pLog, IParameters pParams) : base(pRoot, pID, pLog, pParams) {
persist = new PersistRules(PersistRules.AssetType.Buff, pID, pLog, pParams);
AssetType = PersistRules.AssetType.Buff;
extensions = new GltfExtensions(pRoot);
extras = new GltfAttributes();
// Buffs go into the directory of the root
persist.BaseDirectory = pRoot.persist.BaseDirectory;
_uuid = OMV.UUID.Random();
_identifyingString = _uuid.ToString().Replace("-", "");
// Buffs go into the roots collection. Index is not used.
gltfRoot.buffers.Add(new BHashULong(gltfRoot.buffers.Count), this);
LogGltf("{0} GltfBuffer: created. ID={1}", "Gltf", ID);
}
@@ -1168,11 +1189,20 @@ namespace org.herbal3d.cs.os.CommonEntities {
var ret = new Dictionary<string, Object>();
if (!String.IsNullOrEmpty(name)) ret.Add("name", name);
ret.Add("byteLength", bufferBytes.Length);
ret.Add("uri", persist.Uri);
string outFilename = this.GetFilename(_identifyingString);
ret.Add("uri", this.GetURI(_params.P<string>("URIBase"), outFilename));
if (extensions != null && extensions.Count > 0) ret.Add("extensions", extensions.AsJSON());
if (extras != null && extras.Count > 0) ret.Add("extras", extras.AsJSON());
return ret;
}
public void WriteBuffer() {
string outFilename = this.GetFilename(_identifyingString);
string outDir = this.GetStorageDir(null, outFilename);
string absDir = PersistRules.CreateDirectory(outDir, _params);
File.WriteAllBytes(Path.Combine(absDir, outFilename), bufferBytes);
// _log.DebugFormat("{0} WriteBinaryFiles: filename={1}", LogHeader, outFilename);
}
}
// =============================================================
@@ -1377,6 +1407,7 @@ namespace org.herbal3d.cs.os.CommonEntities {
public GltfImage(Gltf pRoot, ImageInfo pImageInfo, BLogger pLog, IParameters pParams)
: base(pRoot, pImageInfo.handle.ToString() + "_img", pLog, pParams) {
imageInfo = pImageInfo;
AssetType = imageInfo.hasTransprency ? PersistRules.AssetType.ImageTrans : PersistRules.AssetType.Image;
if (pImageInfo.handle is EntityHandleUUID handleU) {
underlyingUUID = handleU.GetUUID();
}
@@ -1392,9 +1423,19 @@ namespace org.herbal3d.cs.os.CommonEntities {
return img;
}
public void WriteImage() {
string imgFilename = this.GetFilename(underlyingUUID.ToString());
string imgDir = this.GetStorageDir(null, imgFilename);
string absDir = PersistRules.CreateDirectory(imgDir, _params);
var targetType = PersistRules.FigureOutTargetTypeFromAssetType(AssetType, _params);
imageInfo.image.Save(Path.Combine(absDir, imgFilename),
PersistRules.TargetTypeToImageFormat[targetType]);
}
public override Object AsJSON() {
string imgFilename = this.GetFilename(underlyingUUID.ToString());
var ret = new Dictionary<string, Object> {
{ "uri", imageInfo.persist.Uri }
{ "uri", PersistRules.ReferenceURL(_params.P<string>("URIBase"), imgFilename) }
};
return ret;
}
-8
View File
@@ -29,7 +29,6 @@ namespace org.herbal3d.cs.os.CommonEntities {
public OMV.UUID imageIdentifier;
public bool hasTransprency = false;
public bool resizable = true; // true if image can be reduced in size
public PersistRules persist; // information in filesystem storage of the image
public Image image = null;
public int xSize = 0;
public int ySize = 0;
@@ -48,7 +47,6 @@ namespace org.herbal3d.cs.os.CommonEntities {
imageIdentifier = handle.GetUUID(); // image is unique unless underlying set
_log = pLog;
_params = pParams;
persist = new PersistRules(PersistRules.AssetType.Image, handle.ToString(), pLog, pParams);
}
// Create a new ImageInfo that has a copy of all the information from this one.
@@ -67,12 +65,6 @@ namespace org.herbal3d.cs.os.CommonEntities {
xSize = image.Width;
ySize = image.Height;
hasTransprency = CheckForTransparency();
if (hasTransprency) {
persist = new PersistRules(PersistRules.AssetType.ImageTrans, handle.ToString(), _log, _params);
}
else {
persist = new PersistRules(PersistRules.AssetType.Image, handle.ToString(), _log, _params);
}
// _log.DebugFormat("{0} SetImage. ID={1}, xSize={2}, ySize={3}, hasTrans={4}",
// _logHeader, handle, xSize, ySize, hasTransprency);
}
+71 -104
View File
@@ -36,6 +36,7 @@ namespace org.herbal3d.cs.os.CommonEntities {
public class PersistRules {
public enum AssetType {
Unknown,
Image,
ImageTrans,
Mesh,
@@ -65,7 +66,7 @@ namespace org.herbal3d.cs.os.CommonEntities {
// Asset types have a target type when stored
public readonly static Dictionary<AssetType, TargetType> AssetTypeToTargetType = new Dictionary<AssetType, TargetType>()
{ { AssetType.Image, TargetType.Default},
{ { AssetType.Image, TargetType.Default}, // 'Default' means look things up in parameters for the AssetType
{ AssetType.ImageTrans, TargetType.Default},
{ AssetType.Mesh, TargetType.Mesh},
{ AssetType.Buff, TargetType.Buff},
@@ -103,123 +104,89 @@ namespace org.herbal3d.cs.os.CommonEntities {
};
public string BaseDirectory { get; set; }
private AssetType _assetType;
private TargetType _targetType;
private string _assetInfo;
private BLogger _log;
private IParameters _params;
#pragma warning disable 414
private static readonly string _logHeader = "[PersistRules]";
#pragma warning restore 414
// Rules for storing files into TargetDir and into type specific sub-directory therein
public PersistRules(AssetType pAssetType, string pInfo, BLogger pLog, IParameters pParams) {
PersistInit(pAssetType, pInfo, TargetType.Default, pLog, pParams);
}
public PersistRules(AssetType pAssetType, string pInfo, TargetType pTargetType, BLogger pLog, IParameters pParams) {
PersistInit(pAssetType, pInfo, pTargetType, pLog, pParams);
}
public PersistRules Clone() {
PersistRules pr = new PersistRules(_assetType, _assetInfo, _targetType, _log, _params) {
BaseDirectory = this.BaseDirectory
};
return pr;
}
private void PersistInit(AssetType pAssetType, string pInfo, TargetType pTargetType, BLogger pLog, IParameters pParams) {
_log = pLog;
_params = pParams;
_assetType = pAssetType;
_assetInfo = pInfo;
_targetType = FigureOutTargetType();
BaseDirectory = AssetTypeToSubDir[_assetType];
}
public AssetType AssetAssetType;
public TargetType AssetTargetType;
public string AssetName;
// If target type is not specified, select the image type depending on parameters and transparency
private TargetType FigureOutTargetType() {
TargetType ret = AssetTypeToTargetType[_assetType];
public static TargetType FigureOutTargetTypeFromAssetType(AssetType pAssetType, IParameters pParams) {
TargetType ret = AssetTypeToTargetType[pAssetType];
// If target type is not specified, select the image type depending on parameters and transparency
if (_targetType == TargetType.Default) {
if (_assetType == AssetType.Image) {
ret = TextureFormatToTargetType[_params.P<string>("PreferredTextureFormatIfNoTransparency").ToLower()];
if (ret == TargetType.Default) {
if (pAssetType == AssetType.Image) {
ret = TextureFormatToTargetType[pParams.P<string>("PreferredTextureFormatIfNoTransparency").ToLower()];
}
if (_assetType == AssetType.ImageTrans) {
ret = TextureFormatToTargetType[_params.P<string>("PreferredTextureFormat").ToLower()];
if (pAssetType == AssetType.ImageTrans) {
ret = TextureFormatToTargetType[pParams.P<string>("PreferredTextureFormat").ToLower()];
}
}
return ret;
}
public string Filename {
get {
return CreateFilename();
}
}
public string Uri {
get {
return CreateURI();
}
}
public void WriteImage(ImageInfo imageInfo) {
string texFilename = CreateFilename();
if (imageInfo.image != null && !File.Exists(texFilename)) {
Image texImage = imageInfo.image;
try {
// _log.DebugFormat("{0} WriteOutImageForEP: id={1}, hasAlpha={2}, format={3}",
// _logHeader, faceInfo.textureID, faceInfo.hasAlpha, texImage.PixelFormat);
PersistRules.ResolveAndCreateDir(texFilename);
texImage.Save(texFilename, TargetTypeToImageFormat[_targetType]);
}
catch (Exception e) {
_log.ErrorFormat("{0} FAILED PNG FILE CREATION: {0}", e);
}
}
}
private string CreateFilename() {
// string fnbase = JoinFilePieces(_params.P<string>("OutputDir"), baseDirectory);
string fnbase = BaseDirectory;
return JoinFilePieces(fnbase, _assetInfo + "." + TargetTypeToExtension[_targetType]);
}
private string CreateURI() {
string uribase = JoinURIPieces(_params.P<string>("URIBase"), BaseDirectory);
return JoinURIPieces(uribase, _assetInfo + "." + TargetTypeToExtension[_targetType]);
}
/// <summary>
/// Turn the passed relative path name into an absolute directory path and
/// create the directory if it does not exist.
/// </summary>
/// <param name="pDir">Absolute or relative path to a directory</param>
/// <returns>Absolute path to directory or 'null' if cannot resolve or create the directory</returns>
public static string ResolveAndCreateDir(string pDir) {
string absDir = null;
try {
absDir = Path.GetFullPath(pDir);
absDir = Path.GetDirectoryName(absDir);
if (!Directory.Exists(absDir)) {
Directory.CreateDirectory(absDir);
}
}
catch (Exception e) {
// _log.ErrorFormat("{0} Failed creation of directory. dir={1}, e: {2}",
// _logHeader, absDir, e);
var temp = e; // supress warning
return null;
// Pass in a relative directory name and return a full directory path
// and create the directory if it doesn't exist.
public static string CreateDirectory(string pDir, IParameters pParams) {
string baseDir = pParams.P<string>("OutputDir");
string fullDir = PersistRules.JoinFilePieces(baseDir, pDir);
string absDir = Path.GetFullPath(fullDir);
if (!Directory.Exists(absDir)) {
Directory.CreateDirectory(absDir);
}
return absDir;
}
// Compute the filename of this object when written out.
// Mostly about computing the file extension based on the AssetType.
public static string GetFilename(GltfClass pObject, string pLongName, IParameters pParams) {
string ret = null;
if (pParams.P<bool>("UseReadableFilenames")) {
var targetType = FigureOutTargetTypeFromAssetType(pObject.AssetType, pParams);
ret = pObject.ID + "." + PersistRules.TargetTypeToExtension[targetType];
}
else {
var targetType = FigureOutTargetTypeFromAssetType(pObject.AssetType, pParams);
ret = pLongName + "." + PersistRules.TargetTypeToExtension[targetType];
}
return ret;
}
// Given a directory base and a filename, return the directory that that filename
// should be stored in.
// Uses sub-directories made out of the filename.
// "01234567890123456789" => "baseDirectory/01/23/45/6789"
public static string StorageDirectory(string baseDirectory, string pHash, IParameters pParams) {
string ret = null;
if (pParams.P<bool>("UseDeepFilenames") && pHash.Length >= 10) {
if (String.IsNullOrEmpty(baseDirectory)) {
ret = Path.Combine(pHash.Substring(0, 2),
Path.Combine(pHash.Substring(2, 2),
Path.Combine(pHash.Substring(4, 2),
pHash.Substring(6, 4)
)));
}
else {
ret = Path.Combine(baseDirectory,
Path.Combine(pHash.Substring(0, 2),
Path.Combine(pHash.Substring(2, 2),
Path.Combine(pHash.Substring(4, 2),
pHash.Substring(6, 4)
))));
}
}
else {
ret = String.IsNullOrEmpty(baseDirectory) ? "" : baseDirectory;
}
return ret;
}
// Create the URI for referring to this object.
// THis is as opposed to the storage directory as the HTTP server resolving
// this URL will do any extra filesystem hashing to access the file.
public static string ReferenceURL(string pBaseDirectory, string pStorageName) {
return JoinURIPieces(pBaseDirectory, pStorageName);
}
/// <summary>
/// Combine two filename pieces so there is one directory separator between.
/// This replaces System.IO.Path.Combine which has the nasty feature that it
+2 -2
View File
@@ -32,7 +32,7 @@ namespace org.herbal3d.cs.CommonEntitiesUtil {
private bool _verbose = false;
public override void SetVerbose(bool value) {
bool _verbose = value;
_verbose = value;
}
public override void Log(string msg, params Object[] args) {
@@ -53,7 +53,7 @@ namespace org.herbal3d.cs.CommonEntitiesUtil {
// Do logging with Log4net
public class LoggerLog4Net : BLogger {
private static string _logHeader = "[Logger]";
private static readonly string _logHeader = "[Logger]";
private ILog _log;
+5 -2
View File
@@ -194,9 +194,12 @@ namespace org.herbal3d.convoar {
Globals.log.DebugFormat("{0} num Gltf.buffers={1}", _logHeader, gltf.buffers.Count);
Globals.log.DebugFormat("{0} num Gltf.bufferViews={1}", _logHeader, gltf.bufferViews.Count);
PersistRules.ResolveAndCreateDir(gltf.persist.Filename);
string gltfFilename = gltf.GetFilename(gltf.IdentifyingString);
string gltfDir = gltf.GetStorageDir(null, gltfFilename);
string absDir = PersistRules.CreateDirectory(gltfDir, Globals.parms);
string gltfPath = Path.Combine(absDir, gltfFilename);
using (StreamWriter outt = File.CreateText(gltf.persist.Filename)) {
using (StreamWriter outt = File.CreateText(gltfPath)) {
gltf.ToJSON(outt);
}
gltf.WriteBinaryFiles();
+4
View File
@@ -62,6 +62,10 @@ namespace org.herbal3d.convoar {
"./convoar", "d" ),
new ParameterDefn<string>("URIBase", "the string added to be beginning of asset name to create URI",
"" ),
new ParameterDefn<bool>("UseReadableFilenames", "Whether filenames should be human readable or UUIDs",
true ),
new ParameterDefn<bool>("UseDeepFilenames", "Whether filenames be organized into a deep directory structure",
false ),
new ParameterDefn<string>("==========", "OAR Reading Specific Parameters", null),
new ParameterDefn<string>("ConvoarID", "GUID for 'convoar' identity (used for CreatorID, ...)",
+1 -1
View File
@@ -1 +1 @@
Thu 02/14/2019 22:11:53.95
Sat 02/16/2019 20:19:46.34
+1 -1
View File
@@ -1 +1 @@
4b63f5c3a62796ec87bae34ee445847f519e672c
3587d7ce6f067a16ff27c5d3b2133bb203eb41a6
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.