public GeometryTool() { var gc = new GeometryControl(); gc.ResetAllPoints += ResetAllPoints; Control = gc; _mousePos = new Point(0, 0); }
private Coordinate GetNormal(Viewport3D vp, DisplacementPoint point, GeometryControl.Axis axis) { switch (axis) { case GeometryControl.Axis.XAxis: return Coordinate.UnitX; case GeometryControl.Axis.YAxis: return Coordinate.UnitY; case GeometryControl.Axis.ZAxis: return Coordinate.UnitZ; case GeometryControl.Axis.FaceNormal: return point.Parent.Plane.Normal; case GeometryControl.Axis.PointNormal: return point.Displacement.Normal; case GeometryControl.Axis.TowardsViewport: var v = vp.Camera.LookAt; return new Coordinate((decimal) v.X, (decimal) v.Y, (decimal) v.Z).Normalise(); default: throw new ArgumentOutOfRangeException("axis"); } }
private void ApplyEffect(decimal distance, Coordinate normal, DisplacementPoint point, GeometryControl.Effect effect, GeometryControl.Brush brush, decimal spatialRadius, int pointSize, Easing softEdgeFunc) { var disps = new List<Displacement>(); //CollectJoinedDisplacements(disps, point.Parent, Selection.GetSelectedFaces().OfType<Displacement>().ToList()); disps.AddRange(Document.Selection.GetSelectedFaces().OfType<Displacement>()); var list = new List<Tuple<DisplacementPoint, decimal>>(); if (brush == GeometryControl.Brush.Point) { // If we're in point brush mode, select the points by location in the displacement grid list.Add(Tuple.Create(_currentPoint, 1m)); var ratio = 1m / pointSize; var cx = _currentPoint.XIndex; var cy = _currentPoint.YIndex; for (var i = 1; i < pointSize; i++) { var edge = 1 - softEdgeFunc.Evaluate(ratio * i);// softEdge ? 1 - (ratio * i) : 1; var points = new List<DisplacementPoint>(); for (var j = -i; j <= i; j++) { // Get the points in a box around the point, distance i // points.Add(disp.GetPoint(cx - i, cy + j)); // points.Add(disp.GetPoint(cx + i, cy + j)); // if (j == -i || j == i) continue; // points.Add(disp.GetPoint(cx + j, cy - i)); // points.Add(disp.GetPoint(cx + j, cy + i)); } list.AddRange(points.Where(x => x != null).Select(x => Tuple.Create(x, edge))); } } else if (brush == GeometryControl.Brush.Spatial) { // For spatial brush mode, select the points by distance from the current point var points = disps.SelectMany(x => x.GetPoints()) .Select(x => new { Point = x, Distance = (x.Location - _currentPoint.Location).VectorMagnitude() }) .Where(x => x.Distance <= spatialRadius); // list.AddRange(points.Select(x => Tuple.Create(x.Point, softEdge ? (spatialRadius - x.Distance) / spatialRadius : 1))); list.AddRange(points.Select(x => Tuple.Create(x.Point, 1 - softEdgeFunc.Evaluate(1 - (spatialRadius - x.Distance) / spatialRadius)))); } if (!list.Any()) return; switch (effect) { case GeometryControl.Effect.RelativeDistance: list.ForEach( x => x.Item1.CurrentPosition.Location += normal * (distance * x.Item2)); break; case GeometryControl.Effect.AbsoluteDistance: list.ForEach( x => x.Item1.CurrentPosition.Location = x.Item1.InitialPosition + (x.Item1.Parent.Plane.Normal * distance)); break; case GeometryControl.Effect.SmoothPoints: var avg = list.Select(x => x.Item1.Location).Aggregate(Coordinate.Zero, (x, y) => x + y) / list.Count; foreach (var pt in list) { var dist = (pt.Item1.Location - avg).Dot(normal); var mult = -Math.Sign(dist) * Math.Min(Math.Abs(dist), Math.Abs(distance)); pt.Item1.CurrentPosition.Location += mult * pt.Item2 * normal; } break; default: throw new ArgumentOutOfRangeException("effect"); } }