fractorium/Source/apoconv/Form1.cs

614 lines
15 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
namespace apoconv
{
public partial class Form1 : Form
{
private List<ParamInfo> m_Params = new List<ParamInfo>();
private List<PrecalcParamInfo> m_StructParams = new List<PrecalcParamInfo>();
private List<string> m_PrecalcFuncLines = new List<string>();
private List<string> m_CalcFuncLines = new List<string>();
private List<string> m_FinalCalcFuncLines = new List<string>();
private readonly SortedDictionary<string, string> replacements = new SortedDictionary<string, string>()
{
{ "(double)", "" },
{ "(float)", "" },
{ "double", "T" },
{ "float", "T" },
{ "Complex", "std::complex<T>" },
//{ "0.0", "0" },
{ "0.5", "T(0.5)" },
{ "1.0", "T(1.0)" },
{ "1.5", "T(1.5)" },
{ "2.0", "T(2.0)" },
{ "3.0", "T(3.0)" },
{ "0.1", "T(0.1)" },
{ "0.01", "T(0.01)" },
{ "0.001", "T(0.001)" },
{ "12.9898", "T(12.9898)" },
{ "78.233", "T(78.233)" },
{ "43758.5453", "T(43758.5453)" },
{ "FTx", "helper.In.x" },
{ "FTy", "helper.In.y" },
{ "FTz", "helper.In.z" },
{ "FPx", "helper.Out.x" },
{ "FPy", "helper.Out.y" },
{ "FPz", "helper.Out.z" },
{ "VVAR", "m_Weight" },
{ "floor(", "Floor<T>(" },
{ "ceil(", "std::ceil(" },
{ "round(", "std::round(" },
{ "sin(", "std::sin(" },
{ "sinh(", "std::sinh(" },
{ "asin(", "std::asin(" },
{ "asinh(", "std::asinh(" },
{ "cos(", "std::cos(" },
{ "cosh(", "std::cosh(" },
{ "acos(", "std::acos(" },
{ "acosh(", "std::acosh(" },
{ "tan(", "std::tan(" },
{ "tanh(", "std::tanh(" },
{ "atan(", "std::atan(" },
{ "atan2(", "std::atan2(" },
{ "atanh(", "std::atanh(" },
{ "sqrt(", "std::sqrt(" },
{ "pow(", "std::pow(" },
{ "fabs(", "std::abs(" },
{ "abs(", "std::abs(" },
{ "log(", "std::log(" },
{ "exp(", "std::exp(" },
{ "sqr(", "Sqr(" },
{ "random01()", "rand.Frand01<T>()" },
{ "M_E", "T(M_E)" },
{ "M_LOG2E", "T(M_LOG2E)" },
{ "M_LOG10E", "T(M_LOG10E)" },
{ "M_LN2", "T(M_LN2)" },
{ "M_LN10", "T(M_LN10)" },
{ "M_PI", "T(M_PI)" },
{ "M_PI_2", "T(M_PI_2)" },
{ "M_PI_4", "M_PI4" },
{ "M_1_PI", "T(M_1_PI)" },
{ "M_2_PI", "T(M_2_PI)" },
{ "M_2_SQRTPI", "T(M_2_SQRTPI)" },
{ "M_SQRT2", "T(M_SQRT2)" },
{ "M_SQRT1_2", "T(M_SQRT1_2)" },
};
public Form1()
{
InitializeComponent();
//var lines = File.ReadAllLines("./waves4.cpp");
//textBox1.Lines = lines;
}
string Apo2Fractorium(string[] lines, bool doexport)
{
if (lines.Length == 0)
return "";
//doexport = false;
bool isparvar = false;
string pluginname = "";
string varclassname = "";
m_Params.Clear();
m_StructParams.Clear();
m_PrecalcFuncLines.Clear();
m_CalcFuncLines.Clear();
m_FinalCalcFuncLines.Clear();
bool structstart = false;
foreach (var line in lines)
{
if (line.Contains("APO_PLUGIN"))
{
var splits = line.Split(new char[] { '\"' });
if (splits.Length >= 1)
{
pluginname = splits[1];
varclassname = pluginname.FirstCharToUpper() + "Variation";
}
}
}
foreach (var line in lines)
{
if (line.Contains("typedef struct"))
{
structstart = true;
continue;
}
if (structstart)
{
if (line.Contains("{"))
continue;
if (line.Contains("}"))
break;
var splits = line.Trim().Split(new string[] { " ", ",", ";", "(", ")", "double", "float", "int", "unsigned", "long", "short", "char" }, StringSplitOptions.RemoveEmptyEntries);
foreach (var split in splits)
{
m_StructParams.Add(new PrecalcParamInfo
{
OrigName = split.Trim(),
Name = split.Trim(),
MemberName = "m_" + split.RemoveFirst(pluginname + "_").FirstCharToUpper().Replace("_", "").Trim(),
});
isparvar = true;
}
}
}
bool paramsstart = false;
foreach (var line in lines)
{
if (line.Contains("APO_VARIABLES("))
{
paramsstart = true;
continue;
}
if (paramsstart)
{
if (line.Contains(");"))
break;
var splits = line.Split(new char[] { '(', ')', ',' });
if (splits.Length > 2)
{
var pt = "";
var l = "";
var u = "";
var def = "";
if (line.Contains("VAR_INTEGER_RANGE"))
{
pt = "eParamType::INTEGER";
if (splits.Length >= 5)
{
l = splits[2].Trim();
u = splits[3].Trim();
def = splits[4].Trim();
}
}
else if (line.Contains("VAR_REAL_RANGE"))
{
pt = "eParamType::REAL";
if (splits.Length >= 5)
{
l = splits[2].Trim();
u = splits[3].Trim();
def = splits[4].Trim();
}
}
else if (line.Contains("VAR_REAL_CYCLE"))
{
pt = "eParamType::REAL_CYCLIC";
if (splits.Length >= 5)
{
l = splits[2].Trim();
u = splits[3].Trim();
def = splits[4].Trim();
}
}
else if (line.Contains("VAR_INTEGER_NONZERO"))
{
pt = "eParamType::INTEGER_NONZERO";
def = splits[2].Trim();
}
else if (line.Contains("INTEGER("))
{
pt = "eParamType::INTEGER";
def = splits[2].Trim();
}
else
def = splits[2].Trim();
m_Params.Add(new ParamInfo
{
Name = splits[1].Trim(),
MemberName = "m_" + splits[1].RemoveFirst(pluginname + "_").FirstCharToUpper().Replace("_", "").Trim(),
Default = def,
Lower = l,
Upper = u,
ParamType = pt
});
isparvar = true;
}
}
}
foreach (var param in m_Params)
{
if (m_StructParams.Any(pi => pi.Name == param.Name))
m_StructParams.RemoveAll(pi => pi.Name == param.Name);
}
foreach (var param in m_StructParams)
{
if (!param.Name.StartsWith(pluginname + "_"))
param.Name = pluginname + "_" + param.Name;
if (!param.Name.EndsWith("_precalc"))
param.Name = param.Name + "_precalc";
if (!param.MemberName.EndsWith("Precalc"))
param.MemberName += "Precalc";
}
bool calcstart = false;
int bracketcount = 0;
foreach (var line in lines)
{
if (line.Contains("PluginVarCalc"))
{
calcstart = true;
continue;
}
if (calcstart)
{
if (line.Contains("{"))
bracketcount++;
if (line.Contains("}"))
bracketcount--;
if (bracketcount <= 0)
break;
if (line != "{" && !line.Contains("return"))
{
var templine = line;
if (line.Contains("FPx") || line.Contains("FPy") || line.Contains("FPz"))
{
templine = templine.Replace("+=", "=");
templine = templine.Replace("-=", "= -(");//Will cause an error, forcing manual inspection
}
m_CalcFuncLines.Add(templine.Trim());
}
}
}
bool precalcstart = false;
bracketcount = 0;
foreach (var line in lines)
{
if (line.Contains("PluginVarPrepare"))
{
precalcstart = true;
continue;
}
if (precalcstart)
{
if (line.Contains("{"))
bracketcount++;
if (line.Contains("}"))
bracketcount--;
if (bracketcount <= 0)
break;
if (line != "{" && !line.Contains("return"))
{
var templine = line;
foreach (var rep in replacements)
templine = templine.Replace(rep.Key, rep.Value);
m_PrecalcFuncLines.Add(templine.Trim());
}
}
}
string final = "/// <summary>\r\n";
final += "/// " + pluginname + ".\r\n";
final += "/// </summary>\r\n";
final += "template <typename T>\r\n";
if (isparvar)
final += "class " + varclassname + " : public ParametricVariation<T>\r\n";
else
final += "class " + varclassname + " : public Variation<T>\r\n";
final += "{\r\n";
final += "public:\r\n";
if (isparvar)
final += "\t" + varclassname + "(T weight = 1.0) : ParametricVariation<T>(\"" + pluginname + "\", eVariationId::VAR_" + pluginname.ToUpper() + ", weight)\r\n";
else
final += "\t" + varclassname + "(T weight = 1.0) : Variation<T>(\"" + pluginname + "\", eVariationId::VAR_" + pluginname.ToUpper() + ", weight)\r\n";
final += "\t{\r\n";
if (isparvar)
final += "\t Init();\r\n";
final += "\t}\r\n\r\n";
if (isparvar)
final += "\tPARVARCOPY(" + varclassname + ")\r\n";
else
final += "\tVARCOPY(" + varclassname + ")\r\n";
final += "\r\n\tvirtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override\r\n";
final += "\t{\r\n";
foreach (var line in m_CalcFuncLines)
{
var templine = "\t\t" + line;
foreach (var rep in replacements)
templine = templine.Replace(rep.Key, rep.Value);
templine += "\r\n";
foreach (var param in m_Params)
templine = templine.Replace("VAR(" + param.Name + ")", param.MemberName);
foreach (var param in m_StructParams)
templine = templine.Replace("VAR(" + param.OrigName + ")", param.MemberName);
m_FinalCalcFuncLines.Add(templine.Trim());
final += templine;
}
final += "\t\thelper.Out.z = DefaultZ(helper);\r\n";
final += "\t}\r\n";
final += "\r\n\tvirtual string OpenCLString() const override\r\n";
final += "\t{\r\n";
final += "\t ostringstream ss, ss2;\r\n";
final += "\t intmax_t i = 0, varIndex = IndexInXform();\r\n";
final += "\t ss2 << \"_\" << XformIndexInEmber() << \"]\";\r\n";
final += "\t string index = ss2.str();\r\n";
final += "\t string weight = WeightDefineString();\r\n";
foreach (var param in m_Params)
{
final += "\t\tstring " + param.MemberName.Replace("m_", "").ToLower() + " = \"parVars[\" + ToUpper(m_Params[i++].Name()) + index;\r\n";
}
foreach (var param in m_StructParams)
{
final += "\t\tstring " + param.MemberName.Replace("m_", "").ToLower() + " = \"parVars[\" + ToUpper(m_Params[i++].Name()) + index;\r\n";
}
final += "\t\tss << \"\\t{\\n\"\r\n";
foreach (var line in m_FinalCalcFuncLines)
{
string templine;
if (line != "")
templine = "\t\t<< \"\\t\\t" + line + "\\n\"\r\n";
else
templine = "\t\t<< \"\\n\"\r\n";
templine = templine.Replace("\\tT ", "\\treal_t ").
Replace("helper.In.x", "vIn.x").
Replace("helper.In.y", "vIn.y").
Replace("helper.In.z", "vIn.z").
Replace("helper.Out.x", "vOut.x").
Replace("helper.Out.y", "vOut.y").
Replace("helper.Out.z", "vOut.z").
Replace("Floor<T>", "floor").
Replace("std::abs", "fabs").
Replace("m_Weight", "\" << weight << \"").
Replace("std::", "").
Replace("rand.Frand01<T>()", "MwcNext01(mwc)").
Replace("T(", "(real_t)(")
;
foreach (var param in m_Params)
{
if (templine.Contains(param.MemberName))
templine = templine.Replace(param.MemberName, "\" << " + param.MemberName.Substring(2).ToLower() + " << \"");
}
foreach (var param in m_StructParams)
{
if (templine.Contains(param.MemberName))
templine = templine.Replace(param.MemberName, "\" << " + param.MemberName.Substring(2).ToLower() + " << \"");
}
final += templine;
}
final += "\t\t<< \"\\t\\tvOut.z = \" << DefaultZCl()\r\n";
final += "\t\t<< \"\\t}\\n\";\r\n";
final += "\t\treturn ss.str();\r\n";
final += "\t}\r\n";
if (isparvar)
{
final += "\r\n\tvirtual void Precalc() override\r\n";
final += "\t{\r\n";
foreach (var line in m_PrecalcFuncLines)
{
var templine = line;
foreach (var param in m_Params)
templine = templine.Replace("VAR(" + param.Name + ")", param.MemberName);
foreach (var param in m_StructParams)
templine = templine.Replace("VAR(" + param.OrigName + ")", param.MemberName);
final += "\t\t" + templine + "\r\n";
}
final += "\t}\r\n";
}
final += "\r\n\tvirtual vector<string> OpenCLGlobalFuncNames() const override\r\n";
final += "\t{\r\n";
final += "\t return vector<string> { \"Zeps\" };\r\n";
final += "\t}\r\n";
bool saidprecalc = false;
if (isparvar)
{
final += "\r\nprotected:\r\n";
final += "\tvoid Init()\r\n";
final += "\t{\r\n";
final += "\t\tstring prefix = Prefix();\r\n";
final += "\t\tm_Params.clear();\r\n";
foreach (var param in m_Params)
final += "\t\tm_Params.push_back(ParamWithName<T>(&" + param.MemberName
+ ", prefix + \""
+ param.Name
+ (param.Default != "0" && param.Default != "0.0" && param.Default != "" || param.ParamType != "" ?
"\", T(" + param.Default + ")"
:
"\"")
+ (param.ParamType != "" ? ", " + param.ParamType : "")
+ (param.Lower != "" ? ", T(" + param.Lower + ")" : "")
+ (param.Upper != "" ? ", T(" + param.Upper + ")" : "")
+ "));\r\n";
foreach (var param in m_StructParams)
{
final += "\t\tm_Params.push_back(ParamWithName<T>(true, &" + param.MemberName
+ ", prefix + \""
+ param.Name + "\"));" + (!saidprecalc ? "//Precalc." : "") + "\r\n";
saidprecalc = true;
}
final += "\t}\r\n";
final += "\r\nprivate:\r\n";
foreach (var param in m_Params)
final += "\tT " + param.MemberName + ";\r\n";
saidprecalc = false;
foreach (var param in m_StructParams)
{
final += "\tT " + param.MemberName + ";" + (!saidprecalc ? "//Precalc." : "") + "\r\n";
saidprecalc = true;
}
}
final += "};\r\n\r\n";
if (doexport)
{
if (isparvar)
final += "MAKEPREPOSTPARVAR(" + pluginname.FirstCharToUpper() + ", " + pluginname + ", " + pluginname.ToUpper() + ")\r\n";
else
final += "MAKEPREPOSTVAR(" + pluginname.FirstCharToUpper() + ", " + pluginname + ", " + pluginname.ToUpper() + ")\r\n";
final += "EXPORTPREPOSTREGVAR(" + pluginname.FirstCharToUpper() + ", T) \\\r\n";
final += "ADDPREPOSTREGVAR(" + pluginname.FirstCharToUpper() + ")\r\n\r\n";
}
return final;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Text = Apo2Fractorium(textBox1.Lines, true);
}
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
textBox1.TextChanged -= textBox1_TextChanged;
string final = "";
List<string> tb1lines = new List<string>();
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (var file in files)
{
var lines = File.ReadAllLines(file);
tb1lines.AddRange(lines.ToList());
final += Apo2Fractorium(lines, true);
}
textBox1.Lines = tb1lines.ToArray();
textBox2.Text = final;
}
textBox1.TextChanged += textBox1_TextChanged;
}
private void textBox1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
}
public class ParamInfo
{
public string Name = "";
public string MemberName = "";
public string Default = "";
public string Lower = "";
public string Upper = "";
public string ParamType = "";
}
public class PrecalcParamInfo : ParamInfo
{
public string OrigName = "";
}
public static class StringExtensions
{
public static string FirstCharToUpper(this string input)
{
switch (input)
{
case null: throw new ArgumentNullException(nameof(input));
case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
default: return input.First().ToString().ToUpper() + input.Substring(1);
}
}
public static string RemoveFirst(this string input, string removeString)
{
int index = input.IndexOf(removeString);
return (index < 0)
? input
: input.Remove(index, removeString.Length);
}
}
}