// Curve // NOTE: Autocad defines spline knots as a vector of size # control points + degree + 1. (# at start and end should match degree) // Conversions for autocad need to make sure this is satisfied, otherwise will cause protected mem crash. public NurbCurve3d NurbcurveToNative(Curve curve) { var points = new Point3dCollection(PointListToNative(curve.points, curve.units)); var knots = new KnotCollection(); for (int i = 0; i < curve.knots.Count; i++) { knots.Add(curve.knots[i]); if (curve.knots.Count == points.Count + curve.degree - 1) { if (i == 0 || i == curve.knots.Count - 1) { knots.Add(curve.knots[i]); } } } var weights = new DoubleCollection(curve.weights.ToArray()); NurbCurve3d _curve = new NurbCurve3d(curve.degree, knots, points, weights, curve.periodic); if (curve.closed) { _curve.MakeClosed(); } return(_curve); }
/// <summary> /// 根据两条样条曲线创建出位于其中间的一条新样条曲线 /// </summary> /// <param name="cur1"></param> /// <param name="cur2"></param> /// <returns></returns> private static NurbCurve3d MiddleCurve(NurbCurve3d cur1, NurbCurve3d cur2) { // Return a NurbCurve3d that's halfway between those passed in // Start by getting the period of both curves double per1, per2; var ip1 = cur1.IsPeriodic(out per1); var ip2 = cur2.IsPeriodic(out per2); // Make the sure the curves have the same degree, period, // number of control points, knots and weights if ( cur1.Degree != cur2.Degree || ip1 != ip2 || per1 != per2 || cur1.NumberOfControlPoints != cur2.NumberOfControlPoints || cur1.NumberOfKnots != cur2.NumberOfKnots || cur1.NumWeights != cur2.NumWeights ) { return(null); } var degree = cur1.Degree; var period = ip1; // Get the set of averaged control points var numPoints = cur1.NumberOfControlPoints; var pts = new Point3dCollection(); for (var i = 0; i < numPoints; i++) { var pt1 = cur1.ControlPointAt(i); var pt2 = cur2.ControlPointAt(i); pts.Add(pt1 + (pt2 - pt1) / 2); } // Get the set of averaged knots var numKnots = cur1.NumberOfKnots; var knots = new KnotCollection(); for (var i = 0; i < numKnots; i++) { knots.Add((cur1.KnotAt(i) + cur2.KnotAt(i)) / 2); } // Get the set of averaged weights var numWeights = cur1.NumWeights; var weights = new DoubleCollection(); for (var i = 0; i < numWeights; i++) { knots.Add((cur1.GetWeightAt(i) + cur2.GetWeightAt(i)) / 2); } // Create our new Ge curve based on all this data return(new NurbCurve3d(degree, knots, pts, weights, period)); }
// Curve public NurbCurve3d NurbcurveToNative(Curve curve) { // process control points // NOTE: for **closed periodic** curves that have "n" control pts, curves sent from rhino will have n+degree points. // Remove extra pts for autocad. var _points = PointListToNative(curve.points, curve.units).ToList(); if (curve.closed && curve.periodic) { _points = _points.GetRange(0, _points.Count - curve.degree); } var points = new Point3dCollection(_points.ToArray()); // process knots // NOTE: Autocad defines spline knots as a vector of size # control points + degree + 1. (# at start and end should match degree) // Conversions for autocad need to make sure this is satisfied, otherwise will cause protected mem crash. // NOTE: for **closed periodic** curves that have "n" control pts, # of knots should be n + 1. Remove degree = 3 knots from start and end. var _knots = curve.knots; if (curve.knots.Count == _points.Count + curve.degree - 1) // handles rhino format curves { _knots.Insert(0, _knots[0]); _knots.Insert(_knots.Count - 1, _knots[_knots.Count - 1]); } if (curve.closed && curve.periodic) // handles closed periodic curves { _knots = _knots.GetRange(curve.degree, _knots.Count - curve.degree * 2); } var knots = new KnotCollection(); foreach (var _knot in _knots) { knots.Add(_knot); } // process weights // NOTE: if all weights are the same, autocad convention is to pass an empty list (this will assign them a value of -1) // NOTE: for closed curves that have "n" control pts, curves sent from rhino will have n+degree points. Remove corresponding weights for autocad. var _weights = curve.weights; if (curve.closed && curve.periodic) // handles closed periodic curves { _weights = curve.weights.GetRange(0, _points.Count); } DoubleCollection weights; weights = (_weights.Distinct().Count() == 1) ? new DoubleCollection() : new DoubleCollection(_weights.ToArray()); NurbCurve3d _curve = new NurbCurve3d(curve.degree, knots, points, weights, curve.periodic); if (curve.closed) { _curve.MakeClosed(); } _curve.SetInterval(IntervalToNative(curve.domain)); return(_curve); }
public AC.NurbSurface SurfaceToNative(Geometry.Surface surface) { // Get control points var points = surface.GetControlPoints().Select(l => l.Select(p => new ControlPoint( ScaleToNative(p.x, p.units), ScaleToNative(p.y, p.units), ScaleToNative(p.z, p.units), p.weight, p.units)).ToList()).ToList(); var _surface = AC.NurbSurface.Create(new IntPtr(), true); // check what new unmanaged pointer does!! // Set control points Point3dCollection controlPoints = new Point3dCollection(); DoubleCollection weights = new DoubleCollection(); for (var i = 0; i < points.Count; i++) { for (var j = 0; j < points[i].Count; j++) { var pt = points[i][j]; controlPoints.Add(PointToNative(pt)); weights.Add(pt.weight); } } // Get knot vectors KnotCollection UKnots = new KnotCollection(); KnotCollection VKnots = new KnotCollection(); for (int i = 0; i < surface.knotsU.Count; i++) { UKnots.Add(surface.knotsU[i]); } for (int i = 0; i < surface.knotsV.Count; i++) { VKnots.Add(surface.knotsV[i]); } // Set surface info _surface.Set(surface.degreeU, surface.degreeV, 0, 0, surface.countU, surface.countV, controlPoints, weights, UKnots, VKnots); return(_surface); }