/SketchModeller/SketchModeller.Modelling/Views/NewConeViewModel.cs

https://bitbucket.org/alexshtf/sketchmodeller · C# · 240 lines · 201 code · 39 blank · 0 comment · 22 complexity · 76d68a643ad10d2477720794634283bd MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using SketchModeller.Infrastructure.Data;
  6. using SketchModeller.Infrastructure;
  7. using System.Windows.Media.Media3D;
  8. using Utils;
  9. using SketchModeller.Infrastructure.Shared;
  10. using Microsoft.Practices.Unity;
  11. using Microsoft.Practices.Prism.Commands;
  12. using System.Diagnostics.Contracts;
  13. using SketchModeller.Utilities;
  14. using Microsoft.Practices.Prism.Events;
  15. using SketchModeller.Infrastructure.Services;
  16. using System.Windows;
  17. using System.Windows.Input;
  18. using SketchModeller.Modelling.Editing;
  19. using Petzold.Media3D;
  20. namespace SketchModeller.Modelling.Views
  21. {
  22. public class NewConeViewModel : NewPrimitiveViewModel
  23. {
  24. public const double MIN_LENGTH = 0.01;
  25. public const double MIN_DIAMETER = 0.01;
  26. private const ModifierKeys TRACKBALL_MODIFIERS = ModifierKeys.Alt;
  27. private const ModifierKeys LENGTH_MODIFIER = ModifierKeys.Control;
  28. private const ModifierKeys DIAMETER_MODIFIER = ModifierKeys.Shift;
  29. private const ModifierKeys AXIS_MOVE_MODIFIER = ModifierKeys.Control | ModifierKeys.Shift;
  30. private NewCone model;
  31. private bool initializing;
  32. [InjectionConstructor]
  33. public NewConeViewModel(
  34. UiState uiState = null,
  35. ICurveAssigner curveAssigner = null,
  36. IEventAggregator eventAggregator = null,
  37. IConstrainedOptimizer optimizer = null)
  38. : base(uiState, curveAssigner, eventAggregator, optimizer)
  39. {
  40. topRadius = 0.2;
  41. bottomRadius = 0.2;
  42. length = 0.5;
  43. axis = MathUtils3D.UnitZ;
  44. center = MathUtils3D.Origin;
  45. model = new NewCone();
  46. UpdateModel();
  47. }
  48. public void Init(NewCone newModel)
  49. {
  50. this.model = newModel;
  51. UpdateFromModel();
  52. }
  53. public override void UpdateFromModel()
  54. {
  55. initializing = true;
  56. try
  57. {
  58. Axis = model.Axis;
  59. Center = model.Center;
  60. Length = model.Length;
  61. TopRadius = model.TopRadius;
  62. BottomRadius = model.BottomRadius;
  63. }
  64. finally
  65. {
  66. initializing = false;
  67. }
  68. }
  69. #region Axis property
  70. private Vector3D axis;
  71. public Vector3D Axis
  72. {
  73. get { return axis; }
  74. set
  75. {
  76. axis = value;
  77. RaisePropertyChanged(() => Axis);
  78. }
  79. }
  80. #endregion
  81. #region Center property
  82. private Point3D center;
  83. public Point3D Center
  84. {
  85. get { return center; }
  86. set
  87. {
  88. center = value;
  89. RaisePropertyChanged(() => Center);
  90. }
  91. }
  92. #endregion
  93. #region Length property
  94. private double length;
  95. public double Length
  96. {
  97. get { return length; }
  98. set
  99. {
  100. length = value;
  101. RaisePropertyChanged(() => Length);
  102. }
  103. }
  104. #endregion
  105. #region TopRadius property
  106. private double topRadius;
  107. public double TopRadius
  108. {
  109. get { return topRadius; }
  110. set
  111. {
  112. topRadius = value;
  113. RaisePropertyChanged(() => TopRadius);
  114. }
  115. }
  116. #endregion
  117. #region BottomRadius property
  118. private double bottomRadius;
  119. public double BottomRadius
  120. {
  121. get { return bottomRadius; }
  122. set
  123. {
  124. bottomRadius = value;
  125. RaisePropertyChanged(() => BottomRadius);
  126. }
  127. }
  128. #endregion
  129. public DragStartProximities DragStartProximity { get; set; }
  130. public override IEditor StartEdit(Point startPos, LineRange startRay)
  131. {
  132. return new Editor(startPos, startRay, this);
  133. }
  134. public override Vector3D ApproximateAxis
  135. {
  136. get { return Axis; }
  137. }
  138. protected override void RaisePropertyChanged(string propertyName)
  139. {
  140. base.RaisePropertyChanged(propertyName);
  141. UpdateModel();
  142. }
  143. private void UpdateModel()
  144. {
  145. if (!initializing)
  146. {
  147. model.Axis.Value = axis;
  148. model.Center.Value = center;
  149. model.Length.Value = length;
  150. model.TopRadius.Value = topRadius;
  151. model.BottomRadius.Value = bottomRadius;
  152. }
  153. }
  154. public enum DragStartProximities
  155. {
  156. Top,
  157. Bottom,
  158. }
  159. #region Editor class
  160. private class Editor : BaseEditor
  161. {
  162. private NewConeViewModel viewModel;
  163. public Editor(Point startPoint, LineRange startRay, NewConeViewModel viewModel)
  164. : base(startPoint, startRay, viewModel)
  165. {
  166. this.viewModel = viewModel;
  167. }
  168. protected override void PerformDrag(Vector dragVector2d, Vector3D vector3D, Vector3D axisDragVector, Point3D? currDragPosition)
  169. {
  170. if (Keyboard.Modifiers == ModifierKeys.None)
  171. viewModel.Center = viewModel.Center + vector3D;
  172. else if (Keyboard.Modifiers == AXIS_MOVE_MODIFIER)
  173. viewModel.Center = viewModel.Center + axisDragVector;
  174. else if (Keyboard.Modifiers == TRACKBALL_MODIFIERS)
  175. {
  176. viewModel.Axis = viewModel.TrackballRotate(viewModel.Axis, dragVector2d);
  177. }
  178. else if (Keyboard.Modifiers == DIAMETER_MODIFIER)
  179. {
  180. var axis = Vector3D.CrossProduct(viewModel.Axis, viewModel.SketchPlane.Normal);
  181. if (axis != default(Vector3D))
  182. {
  183. axis.Normalize();
  184. var radiusDelta = 0.5 * Vector3D.DotProduct(axis, vector3D);
  185. if (viewModel.DragStartProximity == DragStartProximities.Top)
  186. viewModel.TopRadius = Math.Max(NewConeViewModel.MIN_DIAMETER, viewModel.TopRadius + radiusDelta);
  187. else if (viewModel.DragStartProximity == DragStartProximities.Bottom)
  188. viewModel.BottomRadius = Math.Max(NewConeViewModel.MIN_DIAMETER, viewModel.BottomRadius + radiusDelta);
  189. }
  190. }
  191. else if (Keyboard.Modifiers == LENGTH_MODIFIER)
  192. {
  193. var axis = viewModel.Axis.Normalized();
  194. var lengthDelta = Vector3D.DotProduct(axis, vector3D) * 2;
  195. viewModel.Length = Math.Max(NewCylinderViewModel.MIN_LENGTH, viewModel.Length + lengthDelta);
  196. }
  197. }
  198. }
  199. #endregion
  200. }
  201. }