コード例 #1
0
        private static MeshGeometry3D CreateSGCGeometry(
            Vector3D axis,
            double length,
            Point3D bottomCenter,
            IEnumerable <CylinderComponent> components)
        {
            //MessageBox.Show("Snapped Factory");
            var startPoint = bottomCenter;
            var endPoint   = bottomCenter + axis * length;

            var pathQuery = from component in components
                            select MathUtils3D.Lerp(startPoint, endPoint, component.Progress);

            var diametersQuery = from component in components
                                 select 2 * component.Radius;

            var builder = new MeshBuilder();

            builder.AddTube(
                pathQuery.ToArray(),
                null,
                diametersQuery.ToArray(),
                thetaDiv: 20,
                isTubeClosed: false);
            var geometry = builder.ToMesh(freeze: true);

            return(geometry);
        }
コード例 #2
0
        protected Point3D ProjectViewDirectionOnPlane(Plane3D plane, Point3D point)
        {
            var sndPoint = point + uiState.SketchPlane.Normal;
            var t        = plane.IntersectLine(point, sndPoint);

            return(MathUtils3D.Lerp(point, sndPoint, t));
        }
コード例 #3
0
 protected override NewPrimitive ConvertCore(SnappedCylinder snapped)
 {
     return(new NewCylinder
     {
         Axis = snapped.AxisResult,
         Length = snapped.LengthResult,
         Diameter = 2 * snapped.RadiusResult,
         Center = MathUtils3D.Lerp(snapped.TopCenterResult, snapped.BottomCenterResult, 0.5),
     });
 }
コード例 #4
0
        private double ContainedCenterOnContainerAxisProjection(CandidatePair pair)
        {
            var containedCenter = pair.Contained.CenterResult;
            var containerAxis   = pair.Container.NormalResult;
            var containerCenter = pair.Container.CenterResult;

            // this is t such that the projected point is (containerCenter + t * containerAxis);
            var projectionParameter = MathUtils3D.ProjectOnLine(containedCenter, containerCenter, containerAxis).Item1;

            return(projectionParameter);
        }
コード例 #5
0
        protected override NewPrimitive ConvertCore(SnappedCone snapped)
        {
            var result = new NewCone();

            result.Axis.Value         = snapped.AxisResult;
            result.TopRadius.Value    = snapped.TopRadiusResult;
            result.BottomRadius.Value = snapped.BottomRadiusResult;
            result.Length.Value       = snapped.LengthResult;
            result.Center.Value       = MathUtils3D.Lerp(snapped.TopCenterResult, snapped.BottomCenterResult, 0.5);
            return(result);
        }
コード例 #6
0
 protected override NewPrimitive ConvertCore(SnappedCone snapped)
 {
     return(new NewCone
     {
         Axis = snapped.AxisResult,
         TopRadius = snapped.TopRadiusResult,
         BottomRadius = snapped.BottomRadiusResult,
         Length = snapped.LengthResult,
         Center = MathUtils3D.Lerp(snapped.TopCenterResult, snapped.BottomCenterResult, 0.5),
     });
 }
コード例 #7
0
        /// <summary>
        /// Constructs a new instance of the <see cref="PolarPointsGenerator"/> class.
        /// </summary>
        /// <param name="center">The central point around which this class will generate other points.</param>
        /// <param name="xBase">Basis vector that serves as the X axis</param>
        /// <param name="yBase">Basis vector that serves as the Y axis</param>
        /// <remarks><paramref name="xBase"/> and <paramref name="yBase"/> vectors must be orthogonal</remarks>
        public PolarPointsGenerator(Point3D center, Vector3D xBase, Vector3D yBase)
        {
            Contract.Requires(xBase.LengthSquared > 0);
            Contract.Requires(yBase.LengthSquared > 0);
            Contract.Requires(MathUtils3D.AreOrthogonal(xBase, yBase));

            this.center = center;
            xBase.Normalize();
            yBase.Normalize();

            this.xBase = xBase;
            this.yBase = yBase;
        }
コード例 #8
0
        /// <summary>
        /// Generates an approximation of a circle given its center, a normal vector for the plane, and its radius.
        /// </summary>
        /// <param name="center">The circle's center</param>
        /// <param name="normal">Normal vector to the circle's plane</param>
        /// <param name="radius">Circle's radius.</param>
        /// <param name="count">Number of points that approximate the circle</param>
        /// <returns>An array of points that form the circle's approximation</returns>
        public static Point3D[] GenerateCircle(Point3D center, Vector3D normal, double radius, int count)
        {
            Contract.Requires(radius > 0);
            Contract.Requires(count >= 3);
            Contract.Ensures(Contract.Result <Point3D[]>() != null);
            Contract.Ensures(Contract.Result <Point3D[]>().Length == count);
            Contract.Ensures(Contract.ForAll(
                                 Contract.Result <Point3D[]>(),
                                 pnt => NumericUtils.AlmostEqual(radius * radius, (pnt - center).LengthSquared, 100)));

            var xAxis = MathUtils3D.NormalVector(normal).Normalized();
            var yAxis = Vector3D.CrossProduct(normal, xAxis).Normalized();

            return(GenerateCircle(center, xAxis, yAxis, radius, count));
        }
コード例 #9
0
        protected override NewPrimitive ConvertCore(SnappedCylinder snapped)
        {
            var result = new NewCylinder();

            result.Axis.Value     = snapped.AxisResult;
            result.Length.Value   = snapped.LengthResult;
            result.Diameter.Value = 2 * snapped.RadiusResult;
            result.Center.Value   = MathUtils3D.Lerp(snapped.TopCenterResult, snapped.BottomCenterResult, 0.5);

            result.EditConstraints.Add(new AxisOnLineConstraint(
                                           snapped.BottomCenterResult,
                                           snapped.AxisResult,
                                           result.Center,
                                           result.Axis));
            return(result);
        }
コード例 #10
0
        /// <summary>
        /// Gets the point on the sketch plane that is intersected by a given ray
        /// </summary>
        /// <param name="sketchPlane">The sketch plane</param>
        /// <param name="lineRange">The ray information</param>
        /// <returns>The point on the plane of <paramref name="sketchPlane"/> that intersects the ray given by <paramref name="lineRange"/>, or <c>null</c>
        /// if no such point exists.</returns>
        public static Point3D?PointFromRay(this SketchPlane sketchPlane, LineRange lineRange)
        {
            Contract.Requires(sketchPlane != null);

            var plane = Plane3D.FromPointAndNormal(sketchPlane.Center, sketchPlane.Normal);
            var t     = plane.IntersectLine(lineRange.Point1, lineRange.Point2);

            if (double.IsNaN(t))
            {
                return(null);
            }
            else
            {
                return(MathUtils3D.Lerp(lineRange.Point1, lineRange.Point2, t));
            }
        }
コード例 #11
0
        protected override NewPrimitive ConvertCore(SnappedStraightGenCylinder snapped)
        {
            var result = new NewStraightGenCylinder();

            result.Axis.Value   = snapped.AxisResult;
            result.Length.Value = snapped.LengthResult;
            result.Center.Value = MathUtils3D.Lerp(snapped.TopCenterResult, snapped.BottomCenterResult, 0.5);
            result.Components   = snapped.ComponentResults.CloneArray();

            result.EditConstraints.Add(new AxisOnLineConstraint(
                                           snapped.BottomCenterResult,
                                           snapped.AxisResult,
                                           result.Center,
                                           result.Axis));
            return(result);
        }
コード例 #12
0
        public void Drag(Point currPos, LineRange currRay)
        {
            var currDragPosition = PointOnSketchPlane(currRay);
            var dragVector3d     = currDragPosition - lastDragPosition3d;
            var dragVector2d     = currPos - lastDragPosition2d;

            if (dragVector3d != null)
            {
                var axisDragVector = MathUtils3D.ProjectVector(dragVector3d.Value, editable.ApproximateAxis);
                PerformDrag(dragVector2d, dragVector3d.Value, axisDragVector, currDragPosition);
                editable.NotifyDragged();
            }

            if (currDragPosition != null)
            {
                lastDragPosition3d = currDragPosition;
            }
            lastDragPosition2d = currPos;
        }
コード例 #13
0
        public SketchPlane(string name, Point3D center, Vector3D xAxis, Vector3D yAxis, Vector3D normal, double width, double height)
        {
            Contract.Requires(!string.IsNullOrEmpty(name));
            Contract.Requires(width > 0);
            Contract.Requires(height > 0);
            Contract.Requires(MathUtils3D.AreOrthogonal(xAxis, yAxis));
            Contract.Requires(MathUtils3D.AreOrthogonal(xAxis, normal));
            Contract.Requires(MathUtils3D.AreOrthogonal(yAxis, normal));

            xAxis.Normalize();
            yAxis.Normalize();
            normal.Normalize();

            Name   = name;
            Center = center;
            XAxis  = xAxis;
            YAxis  = yAxis;
            Normal = normal;
            Width  = width;
            Height = height;
        }
コード例 #14
0
        private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.Match(() => viewModel.SketchPlane))
            {
                var sketchPlane = viewModel.SketchPlane;

                var normal   = sketchPlane.Normal.Normalized();
                var center   = sketchPlane.Center;
                var position = sketchPlane.Center - 50 * normal;

                var lookAt = MathUtils3D.LookAt(position, normal, sketchPlane.YAxis.Normalized());
                camera.ViewMatrix = lookAt;

                light.Direction = normal;

                var projMatrix = Matrix3D.Identity;
                projMatrix.M33          = 0.0001;
                projMatrix.OffsetZ      = 0.2;
                camera.ProjectionMatrix = projMatrix;
            }
        }
コード例 #15
0
        /// <summary>
        /// Generates an approximation of a circle given its center, two orthonormal basis vectors for the plane, and its radius.
        /// </summary>
        /// <param name="center">The circle's center</param>
        /// <param name="u">First basis vector. This is the "X" axis.</param>
        /// <param name="v">Second basis vector. This is the "Y" axis.</param>
        /// <param name="radius">Circle's radius.</param>
        /// <param name="count">Number of points that approximate the circle</param>
        /// <returns>An array of points that form the circle's approximation</returns>
        public static Point3D[] GenerateCircle(Point3D center, Vector3D u, Vector3D v, double radius, int count)
        {
            Contract.Requires(MathUtils3D.AreOrthogonal(u, v));
            Contract.Requires(NumericUtils.AlmostEqual(u.LengthSquared, 1, 10));
            Contract.Requires(NumericUtils.AlmostEqual(v.LengthSquared, 1, 10));
            Contract.Requires(radius > 0);
            Contract.Requires(count >= 3);
            Contract.Ensures(Contract.Result <Point3D[]>() != null);
            Contract.Ensures(Contract.Result <Point3D[]>().Length == count);
            // we cannot really ensure that (?)
            //Contract.Ensures(Contract.ForAll(
            //    Contract.Result<Point3D[]>(),
            //    pnt => NumericUtils.AlmostEqual((pnt - center).LengthSquared, radius * radius, 100)));

            var result = new Point3D[count];

            for (int i = 0; i < count; ++i)
            {
                var fraction = i / (double)count;
                var angle    = 2 * Math.PI * fraction;
                result[i] = center + radius * (Math.Cos(angle) * u + Math.Sin(angle) * v);
            }
            return(result);
        }
コード例 #16
0
        private static MeshGeometry3D CreateGeometry(NewSGCViewModel viewModel)
        {
            var startPoint = viewModel.Center - 0.5 * viewModel.Length * viewModel.Axis;
            var endPoint   = viewModel.Center + 0.5 * viewModel.Length * viewModel.Axis;
            var components = viewModel.Components;

            var path = from component in components
                       select MathUtils3D.Lerp(startPoint, endPoint, component.Progress);

            var diameters = from component in components
                            select 2 * component.Radius;

            var builder = new MeshBuilder();

            builder.AddTube(
                path.ToArray(),
                null,
                diameters.ToArray(),
                thetaDiv: CIRCLE_DIV,
                isTubeClosed: false);
            var geometry = builder.ToMesh(freeze: true);

            return(geometry);
        }
コード例 #17
0
        private void OnTestCase(object ignore)
        {
            // data from which the cylinder and its curve representations will be created
            var axis       = RotationHelper.RotateVector(MathUtils3D.UnitY, MathUtils3D.UnitX, -20);
            var center     = MathUtils3D.Origin;
            var radius     = 0.2;
            var halfLength = 0.3;

            // basis vectors for the cylinder top/bottom planes
            var xBase = MathUtils3D.NormalVector(axis);
            var yBase = Vector3D.CrossProduct(xBase, axis);

            // generators for the top/bottom circles.
            var topGenerator    = new PolarPointsGenerator(center + halfLength * axis, xBase, yBase);
            var bottomGenerator = new PolarPointsGenerator(center - halfLength * axis, xBase, yBase);

            // angles to use for circles generation.
            const int COUNT  = 50;
            var       angles =
                from i in Enumerable.Range(0, COUNT)
                select 2 * Math.PI * i / COUNT;

            // generate top/bottom circles in 3D
            var topCircle3d =
                from angle in angles
                select topGenerator.GetPoint(angle, radius);

            var bottomCircle3d =
                from angle in angles
                select bottomGenerator.GetPoint(angle, radius);

            // generate the left line from top to bottom
            var leftLine3d =
                from i in Enumerable.Range(0, COUNT)
                let top = topGenerator.GetPoint(0, radius)
                          let bottom = bottomGenerator.GetPoint(0, radius)
                                       let fraction = i / (double)(COUNT - 1)
                                                      select MathUtils3D.Lerp(top, bottom, fraction);

            // generate right line from top to bottom
            var rightLine3d =
                from i in Enumerable.Range(0, COUNT)
                let top = topGenerator.GetPoint(Math.PI, radius)
                          let bottom = bottomGenerator.GetPoint(Math.PI, radius)
                                       let fraction = i / (double)(COUNT - 1)
                                                      select MathUtils3D.Lerp(top, bottom, fraction);

            // project all lines to 2D
            var topCircle2d    = Project(topCircle3d);
            var bottomCircle2d = Project(bottomCircle3d);
            var leftLine2d     = Project(leftLine3d);
            var rightLine2d    = Project(rightLine3d);

            // generate curve data
            var topCurve = new Polygon {
                CurveCategory = CurveCategories.Feature, Points = topCircle2d.ToArray()
            };
            var bottomCurve = new Polygon {
                CurveCategory = CurveCategories.Feature, Points = bottomCircle2d.ToArray()
            };
            var leftCurve = new Polyline {
                CurveCategory = CurveCategories.Silhouette, Points = leftLine2d.ToArray()
            };
            var rightCurve = new Polyline {
                CurveCategory = CurveCategories.Silhouette, Points = rightLine2d.ToArray()
            };

            // generate new primitive that exactly matches the curves
            var newcylinder = new NewCylinder();

            newcylinder.Axis.Value     = axis;
            newcylinder.Center.Value   = center;
            newcylinder.Length.Value   = halfLength * 2;
            newcylinder.Diameter.Value = radius * 2;

            // reset session data
            var sketchData =
                new SketchData
            {
                NewPrimitives     = new NewPrimitive[] { newcylinder },
                Curves            = new PointsSequence[] { topCurve, bottomCurve, leftCurve, rightCurve },
                SnappedPrimitives = new SnappedPrimitive[0],
                Annotations       = new Annotation[0],
            };

            sessionData.SketchData = sketchData;
            sessionData.Annotations.Clear();
            sessionData.Annotations.AddRange(sketchData.Annotations);
            sessionData.NewPrimitives.Clear();
            sessionData.NewPrimitives.AddRange(sketchData.NewPrimitives);
            sessionData.SketchObjects = sketchData.Curves.ToArray();
            sessionData.SnappedPrimitives.Clear();
            sessionData.SnappedPrimitives.AddRange(sessionData.SnappedPrimitives);
        }