What function can I use instead of EditorUtility.GetAssetPath? - c#

UnityEditor it is only meant to work in the Editor only, but I need to use a similar feature in the playing mode.
ObjMaterial objMaterial = new ObjMaterial();
objMaterial.name = mats[material].name;
objMaterial.textureName = AssetDatabase.GetAssetPath(mats[material].mainTexture);
materialList.Add(objMaterial.name, objMaterial);
Full code:
\\\\\\\\\\\\\\\\\\\
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System;
using System.Linq;
struct ObjMaterial
{
public string name;
public string textureName;
}
public class Menu : MonoBehaviour {
public int window;
void Start () {
window = 1;
}
private static int vertexOffset = 0;
private static int normalOffset = 0;
private static int uvOffset = 0;
private static string targetFolder = "ExportedObj";
private static string MeshToString(Component mf, Dictionary<string, ObjMaterial> materialList)
{
Mesh m;
Material[] mats;
if(mf is MeshFilter)
{
m = (mf as MeshFilter).mesh;
mats = mf.GetComponent<Renderer>().sharedMaterials;
}
else if(mf is SkinnedMeshRenderer)
{
m = (mf as SkinnedMeshRenderer).sharedMesh;
mats = (mf as SkinnedMeshRenderer).sharedMaterials;
}
else
{
return "";
}
StringBuilder sb = new StringBuilder();
sb.Append("g ").Append(mf.name).Append("\n");
foreach(Vector3 lv in m.vertices)
{
Vector3 wv = mf.transform.TransformPoint(lv);
sb.Append(string.Format("v {0} {1} {2}\n",-wv.x,wv.y,wv.z));
}
sb.Append("\n");
foreach(Vector3 lv in m.normals)
{
Vector3 wv = mf.transform.TransformDirection(lv);
sb.Append(string.Format("vn {0} {1} {2}\n",-wv.x,wv.y,wv.z));
}
sb.Append("\n");
foreach(Vector3 v in m.uv)
{
sb.Append(string.Format("vt {0} {1}\n",v.x,v.y));
}
for (int material=0; material < m.subMeshCount; material ++) {
sb.Append("\n");
sb.Append("usemtl ").Append(mats[material].name).Append("\n");
sb.Append("usemap ").Append(mats[material].name).Append("\n");
//See if this material is already in the materiallist.
try
{
ObjMaterial objMaterial = new ObjMaterial();
objMaterial.name = mats[material].name;
objMaterial.textureName = EditorUtility.GetAssetPath(mats[material].mainTexture);
//else
//objMaterial.textureName = null;
materialList.Add(objMaterial.name, objMaterial);
}
catch (ArgumentException)
{
//Already in the dictionary
}
int[] triangles = m.GetTriangles(material);
for (int i=0;i<triangles.Length;i+=3)
{
//Because we inverted the x-component, we also needed to alter the triangle winding.
sb.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\n",
triangles[i]+1 + vertexOffset, triangles[i+1]+1 + normalOffset, triangles[i+2]+1 + uvOffset));
}
}
vertexOffset += m.vertices.Length;
normalOffset += m.normals.Length;
uvOffset += m.uv.Length;
return sb.ToString();
}
private static void Clear()
{
vertexOffset = 0;
normalOffset = 0;
uvOffset = 0;
}
private static Dictionary<string, ObjMaterial> PrepareFileWrite()
{
Clear();
return new Dictionary<string, ObjMaterial>();
}
private static void MaterialsToFile(Dictionary<string, ObjMaterial> materialList, string folder, string filename)
{
using (StreamWriter sw = new StreamWriter(folder + "/" + filename + ".mtl"))
{
foreach( KeyValuePair<string, ObjMaterial> kvp in materialList )
{
sw.Write("\n");
sw.Write("newmtl {0}\n", kvp.Key);
sw.Write("Ka 0.6 0.6 0.6\n");
sw.Write("Kd 0.6 0.6 0.6\n");
sw.Write("Ks 0.9 0.9 0.9\n");
sw.Write("d 1.0\n");
sw.Write("Ns 0.0\n");
sw.Write("illum 2\n");
if (kvp.Value.textureName != null)
{
string destinationFile = kvp.Value.textureName;
int stripIndex = destinationFile.LastIndexOf('/');//FIXME: Should be Path.PathSeparator;
if (stripIndex >= 0)
destinationFile = destinationFile.Substring(stripIndex + 1).Trim();
string relativeFile = destinationFile;
destinationFile = folder + "/" + destinationFile;
Debug.Log("Copying texture from " + kvp.Value.textureName + " to " + destinationFile);
try
{
//Copy the source file
File.Copy(kvp.Value.textureName, destinationFile);
}
catch
{
}
sw.Write("map_Kd {0}", relativeFile);
}
sw.Write("\n\n\n");
}
}
}
private static void MeshToFile(Component mf, string folder, string filename)
{
Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
using (StreamWriter sw = new StreamWriter(folder +"/" + filename + ".obj"))
{
sw.Write("mtllib ./" + filename + ".mtl\n");
sw.Write(MeshToString(mf, materialList));
}
MaterialsToFile(materialList, folder, filename);
}
private static void MeshesToFile(Component[] mf, string folder, string filename)
{
Dictionary<string, ObjMaterial> materialList = PrepareFileWrite();
using (StreamWriter sw = new StreamWriter(folder +"/" + filename + ".obj"))
{
sw.Write("mtllib ./" + filename + ".mtl\n");
for (int i = 0; i < mf.Length; i++)
{
sw.Write(MeshToString(mf[i], materialList));
}
}
MaterialsToFile(materialList, folder, filename);
}
private static bool CreateTargetFolder()
{
try
{
System.IO.Directory.CreateDirectory(targetFolder);
}
catch
{
return false;
}
return true;
}
void OnGUI () {
GUI.BeginGroup (new Rect (Screen.width / 2 - 100, Screen.height / 2 - 100, 200, 200));
if(window == 1)
{
if(GUI.Button (new Rect (10,30,180,30), "Экспортировать"))
{
if (!CreateTargetFolder())
return;
GameObject[] selection = GameObject.FindGameObjectsWithTag("Boat");
if (selection.Length == 0)
{
//EditorUtility.DisplayDialog("No source object selected!", "Please select one or more target objects", "");
return;
}
int exportedObjects = 0;
ArrayList mfList = new ArrayList();
for (int i = 0; i < selection.Length; i++)
{
Component[] meshfilter = selection[i].GetComponentsInChildren(typeof(MeshFilter)).Concat(selection[i].GetComponentsInChildren(typeof(SkinnedMeshRenderer))).ToArray();
for (int m = 0; m < meshfilter.Length; m++)
{
exportedObjects++;
mfList.Add(meshfilter[m]);
}
}
if (exportedObjects > 0)
{
Component[] mf = new Component[mfList.Count];
for (int i = 0; i < mfList.Count; i++) {
mf [i] = (Component)mfList [i];
}
string filename = /*EditorApplication.currentScene +*/ "_" + exportedObjects;
int stripIndex = filename.LastIndexOf ('/');//FIXME: Should be Path.PathSeparator
if (stripIndex >= 0)
filename = filename.Substring (stripIndex + 1).Trim ();
MeshesToFile (mf, targetFolder, filename);
}
}
if(GUI.Button (new Rect (10,150,180,30), "Выход"))
{
window = 5;
}
}
if(window == 5)
{
GUI.Label(new Rect(50, 10, 180, 30), "Вы уже выходите?");
if(GUI.Button (new Rect (10,40,180,30), "Да"))
{
Application.Quit();
}
if(GUI.Button (new Rect (10,80,180,30), "Нет"))
{
window = 1;
}
}
GUI.EndGroup ();
}
}

Related

How to load images into an array of class?

I have following code in which I wand to load images.
But whenever I Run the code other fields in collection are found empty and only one image is found in all collection data, & The following error is generated.
IndexOutOfRangeException: Index was outside the bounds of the array.
(wrapper stelemref) System.Object.virt_stelemref_class_small_idepth(intptr,object)
Below is my code :
[System.Serializable]
public class CollectionDataClass
{
public string name;
public string id;
public string thumbnail;
public Texture2D collectionImage;
}
[System.Serializable]
public class DataClass
{
[SerializeField] public CollectionDataClass[] collectionDataClass;
}
[SerializeField] private DataClass[] DataClassArray;
public IEnumerator BookCatogary(string reqParameter)
{
BookCatogaryBodyClass BookCatogryClass = new BookCatogaryBodyClass(reqParameter);
string json = JsonConvert.SerializeObject(BookCatogryClass);
Debug.Log("==========================>" + json);
var req = new UnityWebRequest(bookCategaryAPI, "POST");
byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(json);
req.uploadHandler = (UploadHandler)new UploadHandlerRaw(jsonToSend);
req.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
req.SetRequestHeader("Content-Type", "application/json");
yield return req.SendWebRequest();
if (req.isNetworkError)
{
Debug.Log("Error While Sending: " + req.error);
}
else
{
Debug.Log("Received: " + req.downloadHandler.text);
string temp = req.downloadHandler.text;
bookCatogaryObject = JsonConvert.DeserializeObject<BookCatogaryReceivedDataClass>(temp);
catogaryCount = bookCatogaryObject.Data.Rows.Count;
GetCatogariesName(catogaryCount);
GenerateCollectionData();
}
}
public void GenerateCollectionData()
{
DataClassArray = new DataClass[bookCatogaryObject.Data.Rows.Count];
for (int i = 0; i <= bookCatogaryObject.Data.Rows.Count; i++)
{
DataClassArray[i] = new DataClass();
DataClassArray[i].collectionDataClass = new CollectionDataClass[bookCatogaryObject.Data.Rows[i].String.Count];
for (int m = 0; m < bookCatogaryObject.Data.Rows[i].String.Count; m++)
{
DataClassArray[i].collectionDataClass[m] = new CollectionDataClass();
DataClassArray[i].collectionDataClass[m].name = bookCatogaryObject.Data.Rows[i].String[m].CollectionTitle;
DataClassArray[i].collectionDataClass[m].id = bookCatogaryObject.Data.Rows[i].String[m].Id;
DataClassArray[i].collectionDataClass[m].thumbnail = bookCatogaryObject.Data.Rows[i].String[m].CollectionThumbnail;
StartCoroutine(DownloadImage(mediaUrl: DataClassArray[i].collectionDataClass[m].thumbnail , bookCatogaryObject.Data.Rows[i].String.Count));
}
}
}
IEnumerator DownloadImage(string mediaUrl, int count)
{
UnityWebRequest request = UnityWebRequestTexture.GetTexture(mediaUrl);
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
Debug.Log(request.error);
else
{
//collectionImage = ((DownloadHandlerTexture)request.downloadHandler).texture;
//collectionImageContainer[count] = collectionImage;
for (int i = 0; i <= bookCatogaryObject.Data.Rows.Count; i++)
{
DataClassArray[i] = new DataClass();
DataClassArray[i].collectionDataClass = new CollectionDataClass[bookCatogaryObject.Data.Rows[i].String.Count];
for (int m = 0; m < bookCatogaryObject.Data.Rows[i].String.Count; m++)
{
DataClassArray[i].collectionDataClass[m] = new CollectionDataClass();
DataClassArray[i].collectionDataClass[m].collectionImage = ((DownloadHandlerTexture)request.downloadHandler).texture;
}
}
}
}
This is not an answer to your question. I just wanted to show you how you can simplify code by using temp locals and object initializers. It also makes the code more efficient because it eliminates repeated indexing and member accesses. But more importantly, it makes the code more readable.
public async void GenerateCollectionData()
{
var rows = bookCatogaryObject.Data.Rows;
DataClassArray = new DataClass[rows.Count];
for (int i = 0; i < rows.Count; i++) {
var currentString = rows[i].String;
var dc = new DataClass {
collectionDataClass = new CollectionDataClass[currentString.Count]
};
DataClassArray[i] = dc;
for (int m = 0; m < currentString.Count; m++) {
var collection = currentString[m];
dc.collectionDataClass[m] = new CollectionDataClass {
name = collection.CollectionTitle,
id = collection.Id,
thumbnail = collection.CollectionThumbnail,
collectionImage = await GetImage(collection.CollectionThumbnail)
};
}
}
}
So finally I found the answer to above question, instead of using coroutines I used async Task to return downloaded texture to GenerateCollectionData() method.
Below is code for reference :
public async void GenerateCollectionData()
{
DataClassArray = new DataClass[bookCatogaryObject.Data.Rows.Count];
for (int i = 0; i < bookCatogaryObject.Data.Rows.Count; i++)
{
DataClassArray[i] = new DataClass();
DataClassArray[i].collectionDataClass = new CollectionDataClass[bookCatogaryObject.Data.Rows[i].String.Count];
for (int m = 0; m < bookCatogaryObject.Data.Rows[i].String.Count; m++)
{
DataClassArray[i].collectionDataClass[m] = new CollectionDataClass();
DataClassArray[i].collectionDataClass[m].name = bookCatogaryObject.Data.Rows[i].String[m].CollectionTitle;
DataClassArray[i].collectionDataClass[m].id = bookCatogaryObject.Data.Rows[i].String[m].Id;
DataClassArray[i].collectionDataClass[m].thumbnail = bookCatogaryObject.Data.Rows[i].String[m].CollectionThumbnail;
DataClassArray[i].collectionDataClass[m].collectionImage =
await GetImage(bookCatogaryObject.Data.Rows[i].String[m].CollectionThumbnail);
}
}
}
public static async Task<Texture2D> GetImage(string imageURL)
{
using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(imageURL))
{
var asyncOperation = www.SendWebRequest();
while (asyncOperation.isDone == false)
{
await Task.Delay(1000 / 30);
}
if (www.isNetworkError || www.isHttpError)
{
Debug.Log($"{www.error}, URL:{www.url}");
return null;
}
else
{
return DownloadHandlerTexture.GetContent(www);
}
}
}

Create mtl file for obj?

Hello i really need help. i am using unity and i have this code to export obj. but i also wantmy obj to contain textures. i can export texture as jpg but i do not want it, i need mtl file. i want obj to have that textures with it and not with jpg.so how can i make mtl for my exported obj file?
using System.Collections;
using System.IO;
using System.Text;
using System;
public class ObjExporter
{
public static string MeshToString(MeshFilter mf)
{
Mesh m = mf.mesh;
Material[] mats = mf.GetComponent<Renderer>().sharedMaterials;
StringBuilder sb = new StringBuilder();
//sb.Append("g ").Append(mf.name).Append("\n");
foreach (Vector3 v in m.vertices)
{
sb.Append(string.Format("v {0} {1} {2}\n", v.x, v.y, v.z));
}
sb.Append("\n");
foreach (Vector3 v in m.normals)
{
sb.Append(string.Format("vn {0} {1} {2}\n", v.x, v.y, v.z));
}
sb.Append("\n");
foreach (Vector3 v in m.uv)
{
sb.Append(string.Format("vt {0} {1}\n", v.x, v.y));
}
for (int material = 0; material < m.subMeshCount; material++)
{
sb.Append("\n");
sb.Append("usemtl ").Append(mats[material].name).Append("\n");
sb.Append("usemap ").Append(mats[material].name).Append("\n");
int[] triangles = m.GetTriangles(material);
for (int i = 0; i < triangles.Length; i += 3)
{
sb.Append(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n",
triangles[i] + 1, triangles[i + 1] + 1, triangles[i + 2] + 1));
}
}
return sb.ToString();
}
public static void MeshToFile(MeshFilter mf, string filename)
{
using (StreamWriter sw = new StreamWriter(filename))
{
sw.Write(MeshToString(mf));
string path = Application.dataPath + "/screenshots/" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".png";
}
}
}

Strategy optimization on all possible indicator values, permutation

I have struggled this for a few hours, I am trying to generate all possible combinations of all indicator parameters.
Assume I have indicators
Name possible value
sma5 5, 7, 9
sma10 10, 15
sma20 20, 25, 30
It can generate all combinations with a simple nested for loop
for(sma5=5;sma5<=9;sma5=sma5+2)
for(sma10=10;sma10<=15;sma10=sma10+5)
for(sma20=20;sma20<=30;sma20=sma20+5)
It would give 18 possible combinations
but I want to do a bit more than this, saying sma5 and sma20 can be switched over
sma5 range is now 20-30
sma20 range now is 5-9
This would give 6 more combinations if I am correct, which is 3!, 2x3
So in total would be 6 x 18 = 108 combinations
How do I write this in a clean code?
I want this as clean as possible, but can't figure it out, cuz I might possible add few more indicators
give my program more flexibility to modify
class StrObject
{
public string indicName { get; set; }
public int numbegin { get; set; }
public int numend { get; set; }
public int gap { get; set; }
}
class StrObjects : IEnumerable
{
ArrayList mylist = new ArrayList();
public StrObject this[int index]
{
get { return (StrObject)mylist[index]; }
set { mylist.Insert(index, value); }
}
IEnumerator IEnumerable.GetEnumerator()
{
return mylist.GetEnumerator();
}
}
class Program
{
static IEnumerable<IEnumerable<T>>
GetPermutations<T>(IEnumerable<T> list, int length)
{
if (length == 1) return list.Select(t => new T[] { t });
return GetPermutations(list, length - 1)
.SelectMany(t => list.Where(o => !t.Contains(o)),
(t1, t2) => t1.Concat(new T[] { t2 }));
}
private static void Main()
{
int countP = 0, countC = 0;
const int k = 3;
StrObjects myObjects = new StrObjects();
myObjects[0] = new StrObject() { indicName = "sma_5", numbegin = 5, numend=9, gap=2 };
myObjects[1] = new StrObject() { indicName = "sma_20", numbegin = 20, numend = 30, gap = 5 };
myObjects[2] = new StrObject() { indicName = "sma_50", numbegin = 50, numend = 60, gap = 5 };
var n = new[] { myObjects[0].indicName, myObjects[1].indicName, myObjects[2].indicName };
Console.Write("n: ");
foreach (var item in n)
{
Console.Write("{0} ", item);
}
Console.WriteLine();
Console.WriteLine("k: {0}", k);
Console.WriteLine();
Console.WriteLine("===============================");
Console.WriteLine("Permutations");
Console.WriteLine("===============================");
foreach (IEnumerable<string> i in GetPermutations(n, k))
{
Console.WriteLine(string.Join(" ", i));
countC++;
}
Console.WriteLine("Count : " + countC);
Console.ReadKey();
}
}
'''
finally able to pull some working code, it's a I don't know why it works but it works kind of code. at least it gets what I want
sma_day, 5,7,9
sma_day10, 10,15
sma_day50, 50,55,60
sma_vol5, 5,7,9
sma_vol10, 10,15,20
sma_vol20, 20,25,30
psyvalue 30,35,40,45,50
This should yield all 87480 combinations
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using System.Data.SqlClient;
using System.Collections;
namespace optimization
{
class indiObject
{
public string indicName { get; set; }
public int numbegin { get; set; }
public int numend { get; set; }
public int gap { get; set; }
}
class IndiObjects : IEnumerable
{
ArrayList mylist = new ArrayList();
public indiObject this[int index]
{
get { return (indiObject)mylist[index]; }
set { mylist.Insert(index, value); }
}
IEnumerator IEnumerable.GetEnumerator()
{
return mylist.GetEnumerator();
}
}
class Program
{
public static List<Task> tasks;
private const string pythonpath = #"C:\Python\Scripts\python.exe";
private const string scriptpath = #"C:\psy-Optimizer.py";
private const string connectionstr = #"SERVER =localhost;DATABASE=Stock;Trusted_Connection=True";
public delegate void strategy(Dictionary<string, string> dict);
public static int processcount = 0;
public static Task[] tasksArray;
static void Main(string[] args)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
tasks = new List<Task>();
int countC = 0;
const int k = 3;
IndiObjects myObjects = new IndiObjects();
myObjects[0] = new indiObject() { indicName = "sma_day5", numbegin = 5, numend = 9, gap = 2 };
myObjects[1] = new indiObject() { indicName = "sma_day20", numbegin = 20, numend = 30, gap = 5 };
myObjects[2] = new indiObject() { indicName = "sma_day50", numbegin = 50, numend = 60, gap = 5 };
IndiObjects myObjects2 = new IndiObjects();
myObjects2[0] = new indiObject() { indicName = "sma_vol5", numbegin = 5, numend = 9, gap = 2 };
myObjects2[1] = new indiObject() { indicName = "sma_vol10", numbegin = 10, numend = 19, gap = 5 };
myObjects2[2] = new indiObject() { indicName = "sma_vol20", numbegin = 20, numend = 30, gap = 5 };
var var1 = new[] { myObjects[0].indicName, myObjects[1].indicName, myObjects[2].indicName };
var var2 = new[] { myObjects2[0].indicName, myObjects2[1].indicName, myObjects2[2].indicName };
foreach (IEnumerable<string> i in GetPermutations(var1, k))
{
int[,] loopcount0 = new int[3, 3];
int count0 = 0;
foreach (string s in i)
{
//Console.WriteLine(s);
switch (s)
{
case "sma_day5":
loopcount0[count0, 0] = myObjects[0].numbegin;
loopcount0[count0, 1] = myObjects[0].numend;
loopcount0[count0, 2] = myObjects[0].gap;
break;
case "sma_day20":
loopcount0[count0, 0] = myObjects[1].numbegin;
loopcount0[count0, 1] = myObjects[1].numend;
loopcount0[count0, 2] = myObjects[1].gap;
break;
case "sma_day50":
loopcount0[count0, 0] = myObjects[2].numbegin;
loopcount0[count0, 1] = myObjects[2].numend;
loopcount0[count0, 2] = myObjects[2].gap;
break;
}
count0++;
}
for (int f1 = loopcount0[0, 0]; f1 <= loopcount0[0, 1]; f1 += loopcount0[0, 2])
for (int f2 = loopcount0[1, 0]; f2 <= loopcount0[1, 1]; f2 += loopcount0[1, 2])
for (int f3 = loopcount0[2, 0]; f3 <= loopcount0[2, 1]; f3 += loopcount0[2, 2])
foreach (IEnumerable<string> i2 in GetPermutations(var2, k))
{
int[,] loopcount = new int [3,3];
int count = 0;
//Console.WriteLine("sma_day5 " + f1 + "sma_day20" + f2 + "sma_day50" + f3);
foreach (string s in i2)
{
//Console.WriteLine(s);
switch (s)
{
case "sma_vol5":
loopcount[count, 0] = myObjects2[0].numbegin;
loopcount[count, 1] = myObjects2[0].numend;
loopcount[count, 2] = myObjects2[0].gap;
break;
case "sma_vol10":
loopcount[count, 0] = myObjects2[1].numbegin;
loopcount[count, 1] = myObjects2[1].numend;
loopcount[count, 2] = myObjects2[1].gap;
break;
case "sma_vol20":
loopcount[count, 0] = myObjects2[2].numbegin;
loopcount[count, 1] = myObjects2[2].numend;
loopcount[count, 2] = myObjects2[2].gap;
break;
}
count++;
}
for (int f4 = loopcount[0, 0]; f4 <= loopcount[0,1]; f4 += loopcount[0, 2])
for (int f5 = loopcount[1, 0]; f5 <= loopcount[1, 1]; f5 += loopcount[1, 2])
for (int f6 = loopcount[2, 0]; f6 <= loopcount[2, 1]; f6 += loopcount[2, 2])
for (int psyvalue = 30; psyvalue <= 50; psyvalue += 5)
for (int atrdist = 5; atrdist <= 5; atrdist++)
for (int day_atrdist = 5; day_atrdist <= 5; day_atrdist++)
{
try
{
dict.Clear();
dict.Add("--minutefromdate", "2017-01-01");
dict.Add("--dayfromdate", "2016-01-01");
dict.Add("--todate", "2022-01-01");
dict.Add("--sma_day5", f1.ToString());
dict.Add("--sma_day20", f2.ToString());
dict.Add("--sma_day50", f3.ToString());
dict.Add("--lfi", "11");
dict.Add("--sma_vol5", f4.ToString());
dict.Add("--sma_vol10", f5.ToString());
dict.Add("--sma_vol20", f6.ToString());
dict.Add("--day_atrdist", "5");
dict.Add("--atrdist", "5");
dict.Add("--psyvalue", psyvalue.ToString());
if (countC >= 72893)
{
tasks.Add(Task.Factory.StartNew(() => RunBacktrader(dict), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default));
}
// Console.WriteLine("Process ID " + countC++);
/*
string str="";
foreach (KeyValuePair<string, string> kvp in dict)
{
str += kvp.Key + "=" + kvp.Value ;
}
*/
Console.WriteLine("Process ID " + countC++);
tasksArray = tasks.Where(t => t != null).ToArray();
while (tasksArray.Length >= 10)
{
var completedTask = Task.WhenAny(tasks).Result;
tasks.Remove(completedTask);
Console.WriteLine("A task has been completed with result {0}.", completedTask.Id);
}
}
catch (Exception ex)
{
RecordLog(ex.Message);
}
}
}
//Console.WriteLine(string.Join(" ", i));
}
Console.Read();
}
private static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length)
{
if (length == 1) return list.Select(t => new T[] { t });
return GetPermutations(list, length - 1)
.SelectMany(t => list.Where(o => !t.Contains(o)),
(t1, t2) => t1.Concat(new T[] { t2 }));
}
private static void RunBacktrader(Dictionary<string, string> dict)
{
try
{
string paras = "";
foreach (KeyValuePair<string, string> pp in dict)
{
paras += pp.Key + "=" + pp.Value + " ";
}
Console.WriteLine("Tasks count " + processcount++);
string scriptName = scriptpath + " " + paras;
Process p = new Process();
p.StartInfo = new ProcessStartInfo(#pythonpath, #scriptName)
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
}
catch (Exception ex)
{
RecordLog("5 " + ex.Message);
}
}
private static void RecordLog(string message)
{
try
{
using (SqlConnection connection = new SqlConnection(connectionstr))
{
SqlCommand sqlcmd = new SqlCommand();
sqlcmd.Parameters.Add(new SqlParameter("message", message));
connection.Open();
sqlcmd.Connection = connection;
sqlcmd.CommandText = "INSERT INTO [dbo].[optmizationLog] (ExecTime, Steps) VALUES (GETDATE(), CAST(#message as varchar(512)) )";
sqlcmd.ExecuteNonQuery();
connection.Close();
}
}
catch (Exception ex)
{
Console.Write("duplicate");
}
}
}
}

How do i split a list into smaller lists based on keywords? (C# XNA)

Hi I'm currently working on a importer for a C# / XNA application and I need some help with filtering out the input( a List of string where each line is a "new" string) into smaller chunks(smaller List of string).
This is a sample of how the input is divided into "frames" with the mesh and camera data necessary to create a "keyframe".
num_frames 4
start 1
end 24
frame_rate 24
frame 1
meshes 2
name pCube1
color F:/MayaImporterExporter/ImporterExporter/Bin/Textures/image2.gif
bump F:/MayaImporterExporter/ImporterExporter/Bin/Textures/images.jpg
bumpDepth 1
vertices 36
meshData...
name pCube2
color NONE
bump none
bumpDepth 0
vertices 36
meshData...
cameras 1
name persp
cameraData...
frame 5
meshes 2
name pCube1
color F:/MayaImporterExporter/ImporterExporter/Bin/Textures/image2.gif
bump F:/MayaImporterExporter/ImporterExporter/Bin/Textures/images.jpg
bumpDepth 1
vertices 36
meshData...
name pCube2
color NONE
bump none
bumpDepth 0
vertices 36
meshData...
cameras 1
name persp
cameraData...
frame 10
meshes 2
name pCube1
color F:/MayaImporterExporter/ImporterExporter/Bin/Textures/image2.gif
bump F:/MayaImporterExporter/ImporterExporter/Bin/Textures/images.jpg
bumpDepth 1
vertices 36
meshData...
name pCube2
color NONE
bump none
bumpDepth 0
vertices 36
meshData...
cameras 1
name persp
cameraData...
frame 24
meshes 2
name pCube1
color F:/MayaImporterExporter/ImporterExporter/Bin/Textures/image2.gif
bump F:/MayaImporterExporter/ImporterExporter/Bin/Textures/images.jpg
bumpDepth 1
vertices 36
meshData...
name pCube2
color NONE
bump none
bumpDepth 0
vertices 36
meshData...
cameras 1
name persp
cameraData...
so the things i need to do is:
Split the input down into a smaller list containing the mesh and camera data for each keyframe .
Split the keyframe data into two lists( one for the meshes, and one to the cameras).
split the meshes/cameras into a List of List of Strings.
create the meshes and cameras form the "List of List of Strings"(I know this part ).
So I need some help to figure out how to filter out the input data into smaller chunks to create the meshes and cameras from the input.
You can use something similar to this:
var lines = File.ReadAllLines( path )
.Select( s => s.Trim( ) )
.Where( s => s.Length > 0 ).ToArray( );
int index = 0;
void Next() { index++; }
bool Peek(string token ) { return lines[index].StartsWith( token ) ;}
string ReadStringValue ( ) {
var value = lines[index].Split( ' ' )[1];
Next( );
return value;
};
string ReadIntValue () {
var value = lines[index].Split( ' ' )[1];
Next( );
return int.Parse(value);
};
Header ReadAnimation() {
var anim= new Animation();
while (index<lines.Length)
{
if (Peek("num_frames")) anim.NuMFrames = ReadIntValue();
if (Peek("start")) ....
if (Peek("frame")) anim.AddFrame( ReadFrame() );
}
}
Frame ReadFrame() {
if (Peek("frame")) {
var frame = new Frame();
frame.Index = ReadIntValue();
ReadMeshes( frame );
ReadCameras( frame );
return frame;
}
return null;
}
void ReadMeshes(Frame frame)
{
if (Peek("meshes")) {
int count = ReadIntValue();
for (int i =0; i<count; i++) {
frame.Meshes.Add( ReadMesh() );
}
}
}
Mesh ReadMesh() {
....
}
After some failed attempts on successfully implement the importer, I finally figured out how to make it work.
namespace Importer
{
class ImportHandler
{
List<string> inputString;
Readanyfile read= new Readanyfile();
int num_frames, start, end, frame_rate;
GraphicsDevice graphicsDevice;
classes_stat.KeyFrameAnimation Animation;
public ImportHandler(GraphicsDevice graphicsDevice, Game game,string _inputFile)
{
this.graphicsDevice = graphicsDevice;
this.inputString = read.Load();
ReadRawScene();
}
string ReadStringValue(string str)
{
var value = str.Split(' ')[1];
return value;
}
public int strToInt(string str)
{
var value = str.Split(' ')[1];
return int.Parse(value);
}
public float strToFloat(string str)
{
var value = str.Split(' ')[1];
return float.Parse(value);
}
public double strToDouble(string str)
{
var value = str.Split(' ')[1];
try
{
return double.Parse(value, System.Globalization.CultureInfo.InvariantCulture);
}
catch
{
return (double) 0.1f;
}
}
private static float[] ParseFloatArray(string str, int count)
{
var floats = new float[count];
var segments = str.Split(' ');
for (int i = 0; i < count; i++)
{
if (i < segments.Length)
{
try
{
floats[i] = (float)double.Parse(segments[i], System.Globalization.CultureInfo.InvariantCulture);
}
catch
{
floats[i] = 0;
}
}
}
return floats;
}
private Vector2 ParseVector2(string str)
{
var components = ParseFloatArray(str, 3);
var vec = new Vector2(components[0], components[1]);
return components[2] == 0
? vec
: vec / components[2];
}
private Vector3 ParseVector3(string str)
{
var components = ParseFloatArray(str, 4);
var vec = new Vector3(components[0], components[1], components[2]);
return components[3] == 0
? vec
: vec / components[3];
}
public void ReadRawScene()
{
List<classes_stat.KeyFrame> tempAni = new List<classes_stat.KeyFrame>();
for (int i = 0; i < inputString.Count(); i++ )
{
if (inputString[i].StartsWith("num_frames"))
{
num_frames = strToInt(inputString[i]);
}
if (inputString[i].StartsWith("start"))
{
start = strToInt(inputString[i]);
}
if (inputString[i].StartsWith("end"))
{
end = strToInt(inputString[i]);
}
if (inputString[i].StartsWith("frame_rate"))
{
frame_rate = strToInt(inputString[i]);
}
if (inputString[i].StartsWith("frame"))
{ tempAni.Add(ReadFrames(strToInt(inputString[i]), i, inputString));
}
Animation = new classes_stat.KeyFrameAnimation(frame_rate, start, end, num_frames, tempAni);
}
}
public classes_stat.KeyFrame ReadFrames(int frameIndex,int currentIndex, List<string> inputString )
{
List<MeshFromBinary> tempOutPutMesh = new List<MeshFromBinary>();
List<CameraFromBinary> tempOutPutCam = new List<CameraFromBinary>();
for (int i = currentIndex + 3; i < inputString.Count(); i++)
{
if (inputString[i].StartsWith("meshes"))
{
int count = strToInt(inputString[i]);
for (int x = 0; x < count; x++)
{
MeshFromBinary temp = ReadMeshes(i, inputString);
tempOutPutMesh.Add(temp);
}
}
if (inputString[i].StartsWith("cameras"))
{
int count = strToInt(inputString[i]);
for (int x = 0; x < count; x++)
{
tempOutPutCam.Add(ReadCameras(i, inputString));
}
}
if (inputString[i].StartsWith("frame"))
{
break;
}
}
classes_stat.KeyFrame frame = new classes_stat.KeyFrame(frameIndex, tempOutPutMesh, tempOutPutCam);
return frame;
}
private MeshFromBinary ReadMeshes(int currentIndex, List<string> inputString)
{
int tempCurrentIndex = 0;
List<classes_stat.MyOwnVertexFormat> temp = new List<classes_stat.MyOwnVertexFormat>();
string name;
Texture2D color = ContentTextures.crateTexture;
Texture2D bump = ContentTextures.crateTexture;
double bumpDepth = 0;
List<Vector3> tmpPos = new List<Vector3>();
List<Vector3> tmpNor = new List<Vector3>();
List<Vector3> tmpTan = new List<Vector3>();
List<Vector2> tmpUV = new List<Vector2>();
int numberofvertices = 0;
for (int i = currentIndex; i < inputString.Count(); i++)
{
if (inputString[i].StartsWith("name"))
{
name = ReadStringValue(inputString[i]);
}
if (inputString[i].StartsWith("color"))
{
string tmp = ReadStringValue(inputString[i]);
System.IO.FileStream stream = new System.IO.FileStream(tmp, System.IO.FileMode.Open);
color = Texture2D.FromStream(graphicsDevice, stream);
stream.Close();
stream.Dispose();
//temp.Add(ReadStringValue());
}
if (inputString[i].StartsWith("normalMap"))
{
string tmp = ReadStringValue(inputString[i]);
System.IO.FileStream stream = new System.IO.FileStream(tmp, System.IO.FileMode.Open);
bump = Texture2D.FromStream(graphicsDevice, stream);
stream.Close();
stream.Dispose();
}
if (inputString[i].StartsWith("bumpDepth"))
{
bumpDepth = strToDouble(inputString[i]);
}
if (inputString[i].StartsWith("vertices"))
{
numberofvertices = strToInt(inputString[i]);
}
if (inputString[i].StartsWith("v"))
{
tempCurrentIndex = (i - 1);
break;
}
}
for (int i = tempCurrentIndex; i < inputString.Count(); i++)
{
if (inputString[i].StartsWith("v"))
{
tmpPos.Add(ParseVector3(inputString[i]));
}
if (inputString[i].StartsWith("vn"))
{
tmpNor.Add(ParseVector3(inputString[i]));
}
if (inputString[i].StartsWith("t"))
{
tmpTan.Add(ParseVector3(inputString[i]));
}
if (inputString[i].StartsWith("vt"))
{
tmpUV.Add(ParseVector2(inputString[i]));
}
if (inputString[i].StartsWith("cameras"))
{
break;
}
if (inputString[i].StartsWith("name"))
{
break;
}
}
for (int i = 0; i < numberofvertices; i++)
{
temp.Add(new classes_stat.MyOwnVertexFormat(tmpPos[i], tmpNor[i], tmpTan[i], tmpUV[i]));
}
MeshFromBinary mMesh;
return mMesh = new MeshFromBinary(graphicsDevice, temp, color, bump, bumpDepth);
}
private CameraFromBinary ReadCameras(int currentIndex, List<string> inputString)
{
int tempCurrentIndex = 0;
CameraFromBinary temp;
string name;
Vector3 tmpPos = new Vector3();
Vector3 tmpDir = new Vector3();
Vector3 tmpUp = new Vector3();
double tmpV_FOV = new double();
double tmpH_FOV = new double();
double tmpNear_clipping_plane = new double();
double tmpFar_clipping_plane = new double();
double tmpAspect_ratio = new double();
for (int i = currentIndex; i < inputString.Count(); i++)
{
if (inputString[i].StartsWith("name"))
{
System.Console.WriteLine(ReadStringValue(inputString[i]));
name = ReadStringValue(inputString[i]);
tempCurrentIndex = (i + 1);
break;
}
}
for (int i = tempCurrentIndex; i < inputString.Count(); i++)
{
if (inputString[i].StartsWith("eye"))
{
tmpPos = ParseVector3(inputString[i]);
}
else if (inputString[i].StartsWith("up"))
{
tmpUp = ParseVector3(inputString[i]);
}
else if (inputString[i].StartsWith("rotXYZ"))
{
tmpDir = ParseVector3(inputString[i]);
}
else if (inputString[i].StartsWith("v_fov"))
{
tmpV_FOV = strToDouble(inputString[i]);
}
else if (inputString[i].StartsWith("h_fov"))
{
tmpH_FOV = strToDouble(inputString[i]);
}
else if (inputString[i].StartsWith("near_clipping_plane"))
{
tmpNear_clipping_plane = strToDouble(inputString[i]);
}
else if (inputString[i].StartsWith("far_clipping_plane"))
{
tmpFar_clipping_plane = strToDouble(inputString[i]);
}
else if (inputString[i].StartsWith("aspect_ratio"))
{
tmpAspect_ratio = strToDouble(inputString[i]);
}
else if (inputString[i].StartsWith("frame"))
{
break;
}
else if (inputString[i].StartsWith("cameras"))
{
break;
}
else if (inputString[i].StartsWith("name"))
{
break;
}
}
return temp = new CameraFromBinary(tmpPos, tmpDir, tmpV_FOV, tmpAspect_ratio, tmpNear_clipping_plane, tmpFar_clipping_plane);
}
}
}

Need help in finding the cause of Index out of range exception message

Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
I have the class WireObjectAnimation:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using DannyGeneral;
namespace AnimationEditor
{
class WireObjectAnimation
{
private List<WireObjectCoordinates> wocl = new List<WireObjectCoordinates>();
private WireObject wo1 = null;
string name;
int ndx;
public WireObjectAnimation(string name,WireObject wo)
{
this.name = name;
wo1 = wo;
WireObjectCoordinates woc;
woc = new WireObjectCoordinates(wo.woc);
wocl.Add(woc);
ndx = 0;
}
public void Save(string path , string fileName , PictureBox pb)
{
int framesNumberX = 0;
int framesNumberY = 0;
string fn;
string t = Path.GetFileNameWithoutExtension(this.name);
if (File.Exists(path + "\\" + "DATABASE" + "\\" + fileName + "\\" + t + ".txt"))
{
try
{
string f = Path.Combine(path + "\\" + "DATABASE" + "\\" + t + "\\" + fileName);
File.Delete(f);
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not delete file from disk. Original error: " + ex.Message);
}
fn = path + "\\" + "DATABASE" + "\\" + t + "\\" + fileName;
}
else
{
fn = path + "\\" + "DATABASE" + "\\" + fileName + "\\" + this.name + ".txt";
}
OptionsFile setting_file = new OptionsFile(fn);
setting_file.SetKey("File Name", fn);
setting_file.SetKey("Object Name", fileName);
setting_file.SetKey("Animation Name", this.name);
setting_file.SetKey("picturebox.Width", pb.Width.ToString());
setting_file.SetKey("picturebox.Height", pb.Height.ToString());
string[] xFrames = new string[wocl.Count];
string[] yFrames = new string[wocl.Count];
string X="";
string Y="";
for (int i = 0; i < wocl.Count; i++)
{
X = string.Format("Frame_X_{0} ", i + 1);
Y = string.Format("Frame_Y_{0} ", i + 1);
framesNumberX ++;
framesNumberY ++;
for (int j = 0; j < wocl[i].Point_X.Count; j++)
{
xFrames[i] += string.Format("{0},", wocl[i].Point_X[j]);
yFrames[i] += string.Format("{0},", wocl[i].Point_Y[j]);
}
string tt = xFrames[i].Trim(",".ToCharArray());
string yy = yFrames[i].Trim(",".ToCharArray());
setting_file.SetKey(X, tt);
setting_file.SetKey(Y, yy);
}
int resultX = framesNumberX / 2;
int resultY = framesNumberY / 2;
setting_file.SetKey("Number Of Frames X", resultX.ToString());
setting_file.SetKey("Number Of Frames Y", resultY.ToString());
}
public void Load(string path,string fileName)
{
int numberofframesX = 0;
int numberofframesY = 0;
string framesX = "";
string framesY = "";
string X = "";
string Y = "";
string t = path + "\\" + fileName;
OptionsFile setting_file = new OptionsFile(t);
string XX = setting_file.GetKey("Number Of Frames X");
string YY = setting_file.GetKey("Number Of Frames Y");
numberofframesX = Convert.ToInt32(XX);
numberofframesY = Convert.ToInt32(YY);
for (int i = 1; i < numberofframesX ; i++)
{
X = string.Format("Frame_X_{0} ", i);
framesX = setting_file.GetKey(X);
List<string> floatStrings = new List<string>(framesX.Split(new char[] { ',' }));
List<float> test = floatStrings.Select(tempStr => (float)Convert.ToDouble(tempStr)).ToList();
wo1.woc.Point_X = test;
}
for (int i = 1; i < numberofframesY; i++)
{
Y = string.Format("Frame_Y_{0} ", i);
framesY = setting_file.GetKey(Y);
List<string> floatStrings = new List<string>(framesY.Split(new char[] { ',' }));
List<float> test = floatStrings.Select(tempStr => (float)Convert.ToDouble(tempStr)).ToList();
wo1.woc.Point_Y = test;
}
}
public void SetFrame(int frameNumber, WireObjectCoordinates woc)
{
wocl[frameNumber].Set(woc);
}
public WireObjectCoordinates GetFrame(int frameNumber)
{
if (frameNumber > wocl.Count)
{
throw new Exception("not allowed!");
}
if (frameNumber == wocl.Count)
{
WireObjectCoordinates woc;
woc = new WireObjectCoordinates(wocl[wocl.Count - 1]);
wocl.Add(woc);
return woc;
}
else
{
return wocl[frameNumber];
}
}
}
}
Now when im doing loading the Load function i see the points its loading it good.
But then im trying to move the trackBar bar scroll to the right and then im getting the exception. Now thisl ine: wo1.woc.Point_X = test; the woc have 4 indexs and in each index Point_X and Point_Y are filled with numbers in each index.
In this class i have the functions SetFrame and GetFrame and im using GetFrame in Form1 scroll event of the trackBar:
private void trackBar1_Scroll(object sender, EventArgs e)
{
currentFrameIndex = trackBar1.Value;
textBox1.Text = "Frame Number : " + trackBar1.Value;
wireObject1.woc.Set(wireObjectAnimation1.GetFrame(currentFrameIndex));
LoadPictureAt(trackBar1.Value, sender);
button1.Enabled = false;
button2.Enabled = false;
button3.Enabled = false;
button4.Enabled = false;
button8.Enabled = false;
SaveFormPicutreBoxToBitMapIncludingDrawings();
return;
}
Now when im moving the trackBar once to the right it should paint the next set of numbers from the Point_X and Point_Y instead its going to the WireObjectCoordinates class and throw there the exception:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AnimationEditor
{
class WireObjectCoordinates
{
public List<float> Point_X = new List<float>();
public List<float> Point_Y = new List<float>();
public WireObjectCoordinates()
{
}
public WireObjectCoordinates(WireObjectCoordinates w)
{
Point_X.AddRange(w.Point_X);
Point_Y.AddRange(w.Point_Y);
}
public void Set(WireObjectCoordinates w)
{
for (int i = 0; i < Point_X.Count; i++)
{
Point_X[i] = w.Point_X[i];
Point_Y[i] = w.Point_Y[i];
}
}
}
}
The exception is on the line: Point_X[i] = w.Point_X[i];
Point_X[i] contain now 4 indexs from [0] to [3] each index contain a number like 332.0 333.0 334.0 335.0
And w.Point_X[i] contain now only one index [0] and this index have the number 332.0
i just dont understand why the exception is on this line.
The idea is that when im moving the trackBar to the right it should draw the next coordinates from the wo1.woc.Point_Y and wo1.woc.Point_X but i guess i did something wrong in the Load function ? Im not sure why its throwing the exception and its only when im moving the trackBar to the right once.
How do you expect your for loop to work? The loop variable i goes from 0 to the count of the Point_X list of this instance. But if the other instance w has a Point_X list of a lower count, or if the Point_Y list of this or the Point_Y list of w has, it will fail.
If you realize that Point_X.Count is 4 and w.Point_X.Count is only 1, then when i exceeds 0, the expression w.Point_X[i] will try to read an element of the list that does not exist. That throws the excpetion "Index was out of range".
But maybe you understand that?
throw a try catch around it it technically wont fix the problem but it wont crash anymore and just read over the error

Categories