PageRenderTime 58ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/yeti/model/graph/nodes/geometry/util/customObject.cs

https://bitbucket.org/dmmd123/yeti/
C# | 391 lines | 195 code | 72 blank | 124 comment | 17 complexity | 65d552a3f1929dfeb4a9269fcbf21c9d MD5 | raw file
Possible License(s): GPL-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Diagnostics;
  5. using System.Collections;
  6. using RMA.OpenNURBS;
  7. using yeti.model.yaml;
  8. using yeti.view.rhinoStuff;
  9. namespace yeti.model.graph.nodes
  10. {
  11. /// <summary>
  12. /// The customObject node has two functions:
  13. /// 1. It keeps track of all the custom Objects that have been created
  14. /// - The names of the custom objects
  15. /// - The parameters to the custom objects
  16. /// - The tokens that represent the custom objects.
  17. ///
  18. /// 2. It acts like a node in the graph
  19. ///
  20. /// So if you are to make:
  21. ///
  22. /// pointRow:
  23. /// yPos: {1,2,4}
  24. ///
  25. /// --- !pointRow
  26. /// point:
  27. /// y: !yPos
  28. /// x:
  29. /// from: 0
  30. /// to: 20
  31. /// ...
  32. ///
  33. /// Then all the code for pointRow is compiled into a graph.
  34. /// The customObject:
  35. /// - Keeps track of that graph (or at least what type of graph the customObject should be)
  36. /// - Setting the parameters of the custom object set nodes in the graph.
  37. /// - On draw all the parameters are applied and graph is drawn.
  38. ///
  39. ///
  40. /// Note that parameters are stored in a hashtable and the graph is stored just as a type.
  41. /// Rather than creating and applying the parameters to the graph when they come in,
  42. /// the graph is only created and the parameters only applied, when the graph is needed.
  43. /// </summary>
  44. class customObject : INodeData
  45. {
  46. ///////////////////////////////////////////
  47. // LANGUAGE
  48. ///////////////////////////////////////////
  49. public static readonly nodeLanguage language = new nodeLanguage
  50. {
  51. isPublic = false,
  52. isArray = false,
  53. Keyword = "",
  54. icon = yeti.view.dialog.textarea.iconType.myObject,
  55. Parameters = new Dictionary<string, Type>()
  56. {
  57. },
  58. Constructor = new string[] {}
  59. };
  60. public override nodeLanguage getLanguage()
  61. {
  62. return language;
  63. }
  64. public override string ToString()
  65. {
  66. return myType;
  67. }
  68. ///////////////////////////////////////////
  69. // CUSTOM OBJECT LANGUAGE
  70. ///////////////////////////////////////////
  71. /// <summary>
  72. /// TODO: The customObjects should probably be stored with the graph...
  73. /// </summary>
  74. private static Dictionary<string, lexical> customObjects = new Dictionary<string, lexical>();
  75. private static Dictionary<string, parametricGraph> customObjectsGraph = new Dictionary<string, parametricGraph>();
  76. ///
  77. /// <summary>
  78. /// This is what is created when a new object is selected in intellisense.
  79. /// </summary>
  80. /// <returns></returns>
  81. public static string getObjectDefault()
  82. {
  83. return @"--- !unnamed
  84. ...";
  85. }
  86. /// <summary>
  87. /// Removes all the objects from the language and starts again.
  88. /// </summary>
  89. public static void resetObjects()
  90. {
  91. customObjects = new Dictionary<string, lexical>();
  92. customObjectsGraph = new Dictionary<string, parametricGraph>();
  93. }
  94. /// <summary>
  95. /// Adds an object to the language
  96. /// </summary>
  97. /// <param name="objectName">Name of object</param>
  98. /// <param name="lexicalItRepresents">Lexical of the object.</param>
  99. public static void addObject(string objectName, lexical lexicalItRepresents)
  100. {
  101. if (objectName == null) return;
  102. customObjects.Add(objectName, lexicalItRepresents);
  103. }
  104. /// <summary>
  105. /// Gets all the objects currently in the language.
  106. /// </summary>
  107. /// <returns></returns>
  108. public static string[] getObjects()
  109. {
  110. //TODO: Cache this, and order alphabetically.
  111. List<string> newObjectList = new List<string>(customObjects.Keys);
  112. return newObjectList.ToArray();
  113. }
  114. public static bool isTypeOfObject(string objectKeyword)
  115. {
  116. return customObjects.ContainsKey(objectKeyword);
  117. }
  118. public static bool isParameterToObject(string objectKeyword, string parameter)
  119. {
  120. if (customObjects.ContainsKey(objectKeyword))
  121. {
  122. return customObjects[objectKeyword].isParameter(parameter);
  123. }
  124. return false;
  125. }
  126. public static Dictionary<string, Type> getObjectParameters(string objectKeyword)
  127. {
  128. if (customObjects.ContainsKey(objectKeyword))
  129. {
  130. return customObjects[objectKeyword].getParameters();
  131. }
  132. return null;
  133. }
  134. /// <summary>
  135. /// Gets the graph associated with a particular objectKeyword
  136. /// Returns false if an objectKeyword does not exist.
  137. /// </summary>
  138. /// <param name="objectKeyword"></param>
  139. /// <returns></returns>
  140. public static parametricGraph getObjectGraph(string objectKeyword)
  141. {
  142. if (customObjects.ContainsKey(objectKeyword))
  143. {
  144. return customObjects[objectKeyword].getGraph();
  145. //TODO: Cache the graph here.
  146. //before this can be done, the graph needs to be reset...
  147. //something to do with the set values??
  148. /*
  149. if (!customObjectsGraph.ContainsKey(objectKeyword))
  150. {
  151. customObjectsGraph.Add(objectKeyword, customObjects[objectKeyword].getGraph());
  152. }
  153. else
  154. {
  155. customObjectsGraph[objectKeyword].reset();
  156. }
  157. return customObjectsGraph[objectKeyword];*/
  158. }
  159. return null;
  160. }
  161. public static Type getObjectParameterType(string objectKeyword, string parameter)
  162. {
  163. if (customObjects.ContainsKey(objectKeyword))
  164. {
  165. return customObjects[objectKeyword].getParameterType(parameter);
  166. }
  167. return null;
  168. }
  169. public static lexical getObjectLexical(string objectKeyword)
  170. {
  171. if (customObjects.ContainsKey(objectKeyword))
  172. {
  173. return customObjects[objectKeyword];
  174. }
  175. return null;
  176. }
  177. ///////////////////////////////////////////
  178. // DATA
  179. ///////////////////////////////////////////
  180. private string myType;
  181. Hashtable parameterHashtable = new Hashtable();
  182. ///////////////////////////////////////////
  183. // CONSTRUCTORS
  184. ///////////////////////////////////////////
  185. public customObject(string _myType)
  186. : this(_myType, new Hashtable())
  187. {
  188. }
  189. public customObject(string _myType, Hashtable _parameterHashtable)
  190. {
  191. myType = _myType;
  192. parameterHashtable = _parameterHashtable;
  193. }
  194. public override INodeData clone()
  195. {
  196. //NOTE: to clone the custom node, we just copy the type and the parameterHashtable
  197. //The graph is created on the fly when we need it.
  198. return new customObject(myType, (Hashtable) parameterHashtable.Clone());
  199. }
  200. public string getMyType()
  201. {
  202. return myType;
  203. }
  204. ///////////////////////////////////////////
  205. // PARAMETERS
  206. ///////////////////////////////////////////
  207. public override object value
  208. {
  209. get
  210. {
  211. return null;
  212. }
  213. set
  214. {
  215. }
  216. }
  217. /// <summary>
  218. /// Rather than creating and updating the graph here,
  219. /// parameters are sent to a hashtable, and then when the graph is ready to
  220. /// be updated, everything is applied.
  221. /// </summary>
  222. /// <param name="parameterName"></param>
  223. /// <param name="values"></param>
  224. public override void setParameter(string parameterName, object value)
  225. {
  226. parameterHashtable.Add(parameterName, value);
  227. }
  228. /// <summary>
  229. /// Extracts the data from a node in the graph that shares the parameterName.
  230. /// Need to solve the graph before extracting parameters from it.
  231. ///
  232. /// </summary>
  233. /// <param name="parameterName"></param>
  234. /// <returns></returns>
  235. public override object getParameter(string parameterName)
  236. {
  237. //TODO:
  238. //This is super inefficent to create the graph every time you want a parameter.
  239. //In future, once node is updated, cache the results of the Graph and delete.
  240. parametricGraph myGraph = customObjects[myType].getGraph();
  241. //parametricGraph myGraph = customObject.getObjectGraph(myType);
  242. if (myGraph == null) return null;
  243. foreach (DictionaryEntry entry in parameterHashtable)
  244. {
  245. string parameter = (string)entry.Key;
  246. object value = entry.Value;
  247. if (myGraph.hasNode(parameter))
  248. {
  249. myGraph.getNode(parameter).setValue(new object[] { value });
  250. }
  251. }
  252. myGraph.update();
  253. INodeData[] data = myGraph.getNode(parameterName).getData();
  254. List<object> dataObjects = new List<object>();
  255. foreach (INodeData datum in data)
  256. {
  257. object datumParamValue = datum.getParameter("value");
  258. if (datum.getLanguage().isArray)
  259. {
  260. object[] datumParamArray = (object[])datumParamValue;
  261. dataObjects.AddRange(datumParamArray);
  262. }
  263. else
  264. {
  265. dataObjects.Add(datumParamValue);
  266. }
  267. }
  268. return dataObjects.ToArray();
  269. }
  270. ///////////////////////////////////////////
  271. // OUTPUTS
  272. ///////////////////////////////////////////
  273. /// <summary>
  274. /// To draw this node we need to update the graph with the right parameters
  275. /// and then tell it to redraw.
  276. /// TODO: In future can this be cached??
  277. /// </summary>
  278. public override void draw(bool highlight)
  279. {
  280. parametricGraph myGraph = customObject.getObjectGraph(myType);
  281. if (myGraph == null) return;
  282. foreach (DictionaryEntry entry in parameterHashtable)
  283. {
  284. string parameter = (string)entry.Key;
  285. object value = entry.Value;
  286. if (myGraph.hasNode(parameter))
  287. {
  288. myGraph.getNode(parameter).setValue(new object[] { value });
  289. }
  290. }
  291. myGraph.update();
  292. myGraph.draw(highlight);
  293. }
  294. /// <summary>
  295. /// To bake this node we need to update the graph with the right parameters
  296. /// then we tell it to bake.
  297. /// </summary>
  298. /// <param name="nameOfObject"></param>
  299. /// <param name="docToBakeTo"></param>
  300. public override void bake(string nameOfObject, RMA.Rhino.MRhinoDoc docToBakeTo)
  301. {
  302. parametricGraph myGraph = customObject.getObjectGraph(myType);
  303. if (myGraph == null) return;
  304. foreach (DictionaryEntry entry in parameterHashtable)
  305. {
  306. string parameter = (string)entry.Key;
  307. object value = entry.Value;
  308. if (myGraph.hasNode(parameter))
  309. {
  310. myGraph.getNode(parameter).setValue(new object[] { value });
  311. }
  312. }
  313. myGraph.update();
  314. myGraph.bake(docToBakeTo);
  315. }
  316. }
  317. }