/SketchModeller/SketchModeller.Modelling/Views/NewBGCViewModel.cs

https://bitbucket.org/alexshtf/sketchmodeller · C# · 313 lines · 256 code · 54 blank · 3 comment · 22 complexity · 0ed8301c485a19cc3be5af9d8acb246e MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using SketchModeller.Infrastructure.Shared;
  6. using SketchModeller.Infrastructure.Services;
  7. using Microsoft.Practices.Prism.Events;
  8. using SketchModeller.Infrastructure.Data;
  9. using Microsoft.Practices.Unity;
  10. using System.Windows.Media.Media3D;
  11. using Microsoft.Practices.Prism.ViewModel;
  12. using System.Collections.ObjectModel;
  13. using System.Windows.Input;
  14. using System.Windows;
  15. using Utils;
  16. using SketchModeller.Modelling.Editing;
  17. using Petzold.Media3D;
  18. namespace SketchModeller.Modelling.Views
  19. {
  20. class NewBGCViewModel : NewPrimitiveViewModel
  21. {
  22. public const double MIN_LENGTH = 0.01;
  23. public const double MIN_DIAMETER = 0.01;
  24. private const ModifierKeys TRACKBALL_MODIFIERS = ModifierKeys.Alt;
  25. private const ModifierKeys LENGTH_MODIFIER = ModifierKeys.Control;
  26. private const ModifierKeys DIAMETER_MODIFIER = ModifierKeys.Shift;
  27. private const ModifierKeys AXIS_MOVE_MODIFIER = ModifierKeys.Control | ModifierKeys.Shift;
  28. private static readonly ReadOnlyCollection<ComponentViewModel> EMPTY_COMPONENTS =
  29. Array.AsReadOnly(new ComponentViewModel[0]);
  30. private NewBendedGenCylinder model;
  31. private bool isUpdating;
  32. // the idex of the component that will be edited by the drag operation.
  33. private int dragStartComponent;
  34. [InjectionConstructor]
  35. public NewBGCViewModel(
  36. UiState uiState = null,
  37. ICurveAssigner curveAssigner = null,
  38. IEventAggregator eventAggregator = null,
  39. IConstrainedOptimizer optimizer = null)
  40. : base(uiState, curveAssigner, eventAggregator, optimizer)
  41. {
  42. model = new NewBendedGenCylinder();
  43. components = EMPTY_COMPONENTS;
  44. }
  45. public void Init(NewBendedGenCylinder newBgc)
  46. {
  47. Model = model = newBgc;
  48. UpdateFromModel();
  49. }
  50. public override void UpdateFromModel()
  51. {
  52. //MessageBox.Show("InsidePerformDragCore");
  53. isUpdating = true;
  54. try
  55. {
  56. Center = model.Center;
  57. Axis = model.Axis;
  58. Length = model.Length;
  59. U = model.Uview;
  60. V = model.Vview;
  61. Components = GenerateComponentViewModels(model.Components);
  62. }
  63. finally
  64. {
  65. isUpdating = false;
  66. }
  67. }
  68. #region Center property
  69. private Point3D center;
  70. public Point3D Center
  71. {
  72. get { return center; }
  73. set
  74. {
  75. center = value;
  76. RaisePropertyChanged(() => Center);
  77. if (!isUpdating)
  78. model.Center.Value = value;
  79. }
  80. }
  81. #endregion
  82. #region Axis property
  83. private Vector3D axis;
  84. public Vector3D Axis
  85. {
  86. get { return axis; }
  87. set
  88. {
  89. axis = value;
  90. RaisePropertyChanged(() => Axis);
  91. if (!isUpdating)
  92. model.Axis.Value = value;
  93. }
  94. }
  95. #endregion
  96. #region U property
  97. private Vector3D u;
  98. public Vector3D U
  99. {
  100. get { return u; }
  101. set
  102. {
  103. u = value;
  104. RaisePropertyChanged(() => U);
  105. if (!isUpdating)
  106. model.Uview = value;
  107. }
  108. }
  109. #endregion
  110. #region V property
  111. private Vector3D v;
  112. public Vector3D V
  113. {
  114. get { return v; }
  115. set
  116. {
  117. v = value;
  118. RaisePropertyChanged(() => V);
  119. if (!isUpdating)
  120. model.Vview = value;
  121. }
  122. }
  123. #endregion
  124. #region Length property
  125. private double length;
  126. public double Length
  127. {
  128. get { return length; }
  129. set
  130. {
  131. length = value;
  132. RaisePropertyChanged(() => Length);
  133. if (!isUpdating)
  134. model.Length.Value = value;
  135. }
  136. }
  137. #endregion
  138. #region Components property
  139. private ReadOnlyCollection<ComponentViewModel> components;
  140. public ReadOnlyCollection<ComponentViewModel> Components
  141. {
  142. get { return components; }
  143. set
  144. {
  145. components = value;
  146. RaisePropertyChanged(() => Components);
  147. if (!isUpdating)
  148. model.Components = GenerateComponents(value);
  149. }
  150. }
  151. #endregion
  152. #region component <--> component view models methods
  153. private static BendedCylinderComponent[] GenerateComponents(IEnumerable<ComponentViewModel> cvms)
  154. {
  155. var resultQuery =
  156. from cvm in cvms
  157. select new BendedCylinderComponent(cvm.Radius, cvm.Progress, cvm.S, cvm.T);
  158. return resultQuery.ToArray();
  159. }
  160. private static ReadOnlyCollection<ComponentViewModel> GenerateComponentViewModels(IEnumerable<BendedCylinderComponent> ccs)
  161. {
  162. var resultQuery =
  163. from cc in ccs
  164. select new ComponentViewModel(cc.Radius, cc.Progress, cc.S, cc.T);
  165. return Array.AsReadOnly(resultQuery.ToArray());
  166. }
  167. #endregion
  168. #region ComponentViewModel class
  169. public class ComponentViewModel
  170. {
  171. private readonly double radius;
  172. private readonly double progress;
  173. private readonly double s;
  174. private readonly double t;
  175. public ComponentViewModel(double radius, double progress, double s, double t)
  176. {
  177. this.radius = radius;
  178. this.progress = progress;
  179. this.s = s;
  180. this.t = t;
  181. }
  182. public double Radius
  183. {
  184. get { return radius; }
  185. }
  186. public double Progress
  187. {
  188. get { return progress; }
  189. }
  190. public double S
  191. {
  192. get { return s; }
  193. }
  194. public double T
  195. {
  196. get { return t; }
  197. }
  198. }
  199. #endregion
  200. public override IEditor StartEdit(Point startPos, Petzold.Media3D.LineRange startRay)
  201. {
  202. return new Editor(startPos, startRay, this);
  203. }
  204. public override Vector3D ApproximateAxis
  205. {
  206. get { return Axis; }
  207. }
  208. #region Editor class
  209. class Editor : BaseEditor
  210. {
  211. private NewBGCViewModel viewModel;
  212. public Editor(Point startPoint, LineRange startRay, NewBGCViewModel viewModel)
  213. : base(startPoint, startRay, viewModel)
  214. {
  215. this.viewModel = viewModel;
  216. }
  217. protected override void PerformDrag(Vector dragVector2d, Vector3D vector3D, Vector3D axisDragVector, Point3D? currDragPosition)
  218. {
  219. if (Keyboard.Modifiers == ModifierKeys.None)
  220. {
  221. viewModel.Center = viewModel.Center + vector3D;
  222. }
  223. else if (Keyboard.Modifiers == AXIS_MOVE_MODIFIER)
  224. viewModel.Center = viewModel.Center + axisDragVector;
  225. else if (Keyboard.Modifiers == TRACKBALL_MODIFIERS)
  226. {
  227. //MessageBox.Show("InsidePerformDragCore");
  228. viewModel.Axis = viewModel.TrackballRotate(viewModel.Axis, dragVector2d);
  229. viewModel.U = (viewModel.TrackballRotate(viewModel.U, dragVector2d)).Normalized();
  230. viewModel.V = (viewModel.TrackballRotate(viewModel.V, dragVector2d)).Normalized();
  231. }
  232. else if (Keyboard.Modifiers == DIAMETER_MODIFIER)
  233. {
  234. var axis = Vector3D.CrossProduct(viewModel.Axis, viewModel.SketchPlane.Normal);
  235. if (axis != default(Vector3D))
  236. {
  237. axis.Normalize();
  238. var radiusDelta = 0.5 * Vector3D.DotProduct(axis, vector3D);
  239. viewModel.Components = viewModel.RecomputeComponents(
  240. viewModel.Components,
  241. radiusDelta,
  242. viewModel.dragStartComponent);
  243. }
  244. }
  245. else if (Keyboard.Modifiers == LENGTH_MODIFIER)
  246. {
  247. var axis = viewModel.Axis.Normalized();
  248. var lengthDelta = Vector3D.DotProduct(axis, vector3D) * 2;
  249. viewModel.Length = Math.Max(MIN_LENGTH, viewModel.Length + lengthDelta);
  250. }
  251. }
  252. }
  253. #endregion
  254. private ReadOnlyCollection<NewBGCViewModel.ComponentViewModel> RecomputeComponents(ReadOnlyCollection<NewBGCViewModel.ComponentViewModel> readOnlyCollection, double radiusDelta, int dragStartComponent)
  255. {
  256. throw new NotImplementedException();
  257. }
  258. }
  259. }