/// <summary> /// /// </summary> void UpdateTargetLengths(IField3d <double> length, bool parallel = false) { var edges = _mesh.Edges; var d = _settings.LengthRange; if (parallel) { Parallel.ForEach(Partitioner.Create(0, edges.Count), range => Body(range.Item1, range.Item2)); } else { Body(0, edges.Count); } void Body(int from, int to) { for (int i = from; i < to; i++) { var he = edges[i]; if (he.IsUnused) { continue; } var p = (he.Start.Position + he.End.Position) * 0.5; he.TargetLength = d.Evaluate(length.ValueAt(p)); } } }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from input parameters and /// to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA) { IField3d <double> f0 = null; IField3d <double> f1 = null; if (!DA.GetData(0, ref f0)) { return; } if (!DA.GetData(1, ref f1)) { return; } DA.SetData(0, FuncField3d.CreateUnion(f0, f1)); /* * // We should now validate the data and warn the user if invalid data is supplied. * * if (turns <= 0) * { * AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Spiral turn count must be bigger than or equal to one"); * return; * } * */ }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; IField3d<double> f = null; if (!DA.GetData(0, ref mesh)) return; if (!DA.GetData(1, ref f)) return; double iso = 0; var lines = new List<LineCurve>(); for (int i = 0; i < mesh.Faces.Count; i++) { Point3d p0 = mesh.Vertices[mesh.Faces[i].A]; Point3d p1 = mesh.Vertices[mesh.Faces[i].B]; Point3d p2 = mesh.Vertices[mesh.Faces[i].C]; double t0 = f.ValueAt(mesh.Vertices[mesh.Faces[i].A]); double t1 = f.ValueAt(mesh.Vertices[mesh.Faces[i].B]); double t2 = f.ValueAt(mesh.Vertices[mesh.Faces[i].C]); int mask = 0; if (t0 >= iso) { mask |= 1; } if (t1 >= iso) { mask |= 2; } if (t2 >= iso) { mask |= 4; } switch (mask) { case 1: lines.Add(DrawLine(p0, p1, p2, Normalize(t0, t1, iso), Normalize(t0, t2, iso))); break; case 2: lines.Add(DrawLine(p1, p2, p0, Normalize(t1, t2, iso), Normalize(t1, t0, iso))); break; case 3: lines.Add(DrawLine(p2, p0, p1, Normalize(t2, t0, iso), Normalize(t2, t1, iso))); break; case 4: lines.Add(DrawLine(p2, p0, p1, Normalize(t2, t0, iso), Normalize(t2, t1, iso))); break; case 5: lines.Add(DrawLine(p1, p2, p0, Normalize(t1, t2, iso), Normalize(t1, t0, iso))); break; case 6: lines.Add(DrawLine(p0, p1, p2, Normalize(t0, t1, iso), Normalize(t0, t2, iso))); break; } } DA.SetDataList(0, Curve.JoinCurves(lines)); //contour = Curve.JoinCurves(lines); }
/// <summary> /// /// </summary> private static IEnumerable <Vector3d> IntegrateFromEuler(IField3d <Vector3d> field, Vector3d point, double stepSize) { yield return(point); while (true) { point += field.ValueAt(point) * stepSize; yield return(point); } }
/// <summary> /// /// </summary> /// <param name="field"></param> /// <param name="points"></param> /// <param name="stepSize"></param> /// <param name="stepCount"></param> /// <param name="mode"></param> private PolylineCurve[] SolveInstanceImpl(IField3d <Vec3d> field, List <Point3d> points, double stepSize, int stepCount) { var result = new PolylineCurve[points.Count]; Parallel.For(0, points.Count, i => { var pts = field.IntegrateFrom(points[i], stepSize, _mode).Take(stepCount).Select(p => (Point3d)p); result[i] = new PolylineCurve(pts); }); return(result); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; IField3d <double> f = null; Plane plane = new Plane(); double val = 1.00d; if (!DA.GetData(0, ref mesh)) { return; } if (!DA.GetData(1, ref f)) { return; } if (!DA.GetData(2, ref plane)) { return; } if (!DA.GetData(3, ref val)) { return; } var hem = mesh.ToHeMesh(); var field = MeshField3d.Double.Create(hem); double[] vals = new double[field.Mesh.Vertices.Count]; Parallel.ForEach(Partitioner.Create(0, mesh.Vertices.Count), range => { for (int i = range.Item1; i < range.Item2; i++) { Vector3d vec = plane.Origin - mesh.Vertices[i]; double proj = vec * plane.Normal; if (proj > 0) { vals[i] = val; } else { vals[i] = f.ValueAt(mesh.Vertices[i]); } } }); field.Set(vals); DA.SetData(0, field); }
/// <summary> /// /// </summary> private static IEnumerable <Vector3d> IntegrateFromRK2(IField3d <Vector3d> field, Vector3d point, double stepSize) { yield return(point); while (true) { var v0 = field.ValueAt(point); var v1 = field.ValueAt(point + v0 * stepSize); point += (v0 + v1) * 0.5 * stepSize; yield return(point); } }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; IField3d <double> f = null; Plane plane = new Plane(); double val = 1.00d; if (!DA.GetData(0, ref mesh)) { return; } if (!DA.GetData(1, ref f)) { return; } if (!DA.GetData(2, ref plane)) { return; } if (!DA.GetData(3, ref val)) { return; } Point3d[] pts = mesh.Vertices.ToPoint3dArray(); double[] vals = new double[pts.Length]; Parallel.ForEach(Partitioner.Create(0, pts.Length), range => { for (int i = range.Item1; i < range.Item2; i++) { Vector3d vec = plane.Origin - pts[i]; double proj = vec * plane.Normal; //dot product if (proj > 0) { vals[i] = val; } else { vals[i] = f.ValueAt(pts[i]); } } }); MeshField3d <double> fn = Utility.CreateMeshField(mesh, vals); DA.SetData(0, fn); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; IField3d <double> f = null; List <Plane> planes = new List <Plane>(); double val = 1.00d; if (!DA.GetData(0, ref mesh)) { return; } if (!DA.GetData(1, ref f)) { return; } if (!DA.GetDataList(2, planes)) { return; } if (!DA.GetData(3, ref val)) { return; } var hem = mesh.ToHeMesh(); var fn = MeshField3d.Double.Create(hem); var vals = new List <double>(); foreach (Point3d p in mesh.Vertices) { double v = f.ValueAt(p); foreach (var plane in planes) { var vec = plane.Origin - p; double proj = vec * plane.Normal; if (proj > 0) { v = val; break; } } vals.Add(v); } fn.Set(vals); DA.SetData(0, fn); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; IField3d <double> f0 = null; IField3d <double> f1 = null; List <double> t = new List <double>(); if (!DA.GetData(0, ref mesh)) { return; } if (!DA.GetData(1, ref f0)) { return; } if (!DA.GetData(2, ref f1)) { return; } if (!DA.GetDataList(3, t)) { return; } var hem = mesh.ToHeMesh(); List <MeshField3d <double> > blendfields = new List <MeshField3d <double> >(); for (int j = 0; j < t.Count; j++) { GH_Path pth = new GH_Path(j); List <double> currentBlend = new List <double>(); foreach (Point3d p in mesh.Vertices) { double val = SpatialSlur.SlurCore.SlurMath.Lerp(f0.ValueAt(p), f1.ValueAt(p), t[j]); currentBlend.Add(val); } var field = MeshField3d.Double.Create(hem); field.Set(currentBlend); blendfields.Add(field); } DA.SetDataList(0, blendfields); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; IField3d <double> f = null; Plane plane = new Plane(); double val = 1.00d; if (!DA.GetData(0, ref mesh)) { return; } if (!DA.GetData(1, ref f)) { return; } if (!DA.GetData(2, ref plane)) { return; } if (!DA.GetData(3, ref val)) { return; } var hem = mesh.ToHeMesh(); var fn = MeshField3d.Double.Create(hem); List <double> vals = new List <double>(); foreach (Point3d p in mesh.Vertices) { Vector3d vec = plane.Origin - p; double proj = vec * plane.Normal; //dot product if (proj > 0) { vals.Add(val); } else { vals.Add(f.ValueAt(p)); } } fn.Set(vals); DA.SetData(0, fn); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = null; IField3d <double> f0 = null; IField3d <double> f1 = null; List <double> t = new List <double>(); if (!DA.GetData(0, ref mesh)) { return; } if (!DA.GetData(1, ref f0)) { return; } if (!DA.GetData(2, ref f1)) { return; } if (!DA.GetDataList(3, t)) { return; } var hem = mesh.ToHeMesh(); List <MeshField3d <double> > blendfields = new List <MeshField3d <double> >(); for (int j = 0; j < t.Count; j++) { Point3d[] pts = mesh.Vertices.ToPoint3dArray(); double[] results = new double[pts.Length]; debugLog.Add(pts.Length.ToString()); Parallel.For(0, pts.Length, i => { results[i] = SpatialSlur.SlurCore.SlurMath.Lerp(f0.ValueAt(pts[i]), f1.ValueAt(pts[i]), t[j]); }); var field = Utility.CreateMeshField(mesh, results); blendfields.Add(field); } DA.SetDataList(0, debugLog); DA.SetDataList(1, blendfields); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from input parameters and /// to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA) { IField3d <double> f0 = null; IField3d <double> f1 = null; if (!DA.GetData(0, ref f0)) { return; } if (!DA.GetData(1, ref f1)) { return; } DA.SetData(0, Field3d.CreateUnion(f0, f1)); }
/// <summary> /// Returns a streamline through the given vector field starting at the given point. /// </summary> /// <param name="field"></param> /// <param name="point"></param> /// <param name="stepSize"></param> /// <param name="mode"></param> /// <returns></returns> public static IEnumerable <Vector3d> IntegrateFrom(IField3d <Vector3d> field, Vector3d point, double stepSize, IntegrationMode mode = IntegrationMode.Euler) { switch (mode) { case IntegrationMode.Euler: return(IntegrateFromEuler(field, point, stepSize)); case IntegrationMode.RK2: return(IntegrateFromRK2(field, point, stepSize)); case IntegrationMode.RK4: return(IntegrateFromRK4(field, point, stepSize)); } throw new NotSupportedException(); }
/// <summary> /// /// </summary> private static IEnumerable <Vector3d> IntegrateFromRK4(IField3d <Vector3d> field, Vector3d point, double stepSize) { double dt2 = stepSize * 0.5; double dt6 = stepSize / 6.0; yield return(point); while (true) { var v0 = field.ValueAt(point); var v1 = field.ValueAt(point + v0 * dt2); var v2 = field.ValueAt(point + v1 * dt2); var v3 = field.ValueAt(point + v2 * stepSize); point += (v0 + 2.0 * v1 + 2.0 * v2 + v3) * dt6; yield return(point); } }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { List <Mesh> mesh = new List <Mesh>(); IField3d <double> f0 = null; IField3d <double> f1 = null; List <double> t = new List <double>(); if (!DA.GetDataList(0, mesh)) { return; } if (!DA.GetData(1, ref f0)) { return; } if (!DA.GetData(2, ref f1)) { return; } if (!DA.GetDataList(3, t)) { return; } List <MeshField3d> fields = new List <MeshField3d>(); for (int i = 0; i < t.Count; i++) { List <double> currentBlend = new List <double>(); var currentField = MeshField3d.Double.Create(mesh[i].ToHeMesh()); foreach (Point3d p in mesh[i].Vertices) { double val = SlurMath.Lerp(f0.ValueAt(p), f1.ValueAt(p), t[i]); currentBlend.Add(val); currentField.Set(currentBlend); } fields.Add(currentField); } ; DA.SetDataList(0, fields); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { List <Mesh> mesh = new List <Mesh>(); IField3d <double> f0 = null; IField3d <double> f1 = null; List <double> t = new List <double>(); if (!DA.GetDataList(0, mesh)) { return; } if (!DA.GetData(1, ref f0)) { return; } if (!DA.GetData(2, ref f1)) { return; } if (!DA.GetDataList(3, t)) { return; } List <MeshField3d> fields = new List <MeshField3d>(); for (int i = 0; i < t.Count; i++) { var currentField = MeshField3d.Double.Create(mesh[i].ToHeMesh()); double[] currentBlend = new double[currentField.Mesh.Vertices.Count]; Parallel.For(0, currentField.Mesh.Vertices.Count, j => { currentBlend[j] = SlurMath.Lerp(f0.ValueAt(currentField.Mesh.Vertices[j].Position), f1.ValueAt(currentField.Mesh.Vertices[j].Position), t[i]); }); currentField.Set(currentBlend); fields.Add(currentField); } DA.SetDataList(0, fields); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="U"></typeparam> /// <param name="field"></param> /// <param name="other"></param> /// <param name="converter"></param> /// <param name="parallel"></param> public static void Sample <T, U>(this IDiscreteField3d <T> field, IField3d <U> other, Func <U, T> converter, bool parallel = false) { if (parallel) { Parallel.ForEach(Partitioner.Create(0, field.Count), range => Body(range.Item1, range.Item2)); } else { Body(0, field.Count); } void Body(int from, int to) { var vals = field.Values; for (int i = from; i < to; i++) { vals[i] = converter(other.ValueAt(field.CoordinateAt(i))); } } }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="U"></typeparam> /// <param name="field"></param> /// <param name="other"></param> /// <param name="converter"></param> /// <param name="parallel"></param> public static void Sample <T, U>(this IDiscreteField3d <T> field, IField3d <U> other, Func <U, T> converter, bool parallel = false) { var vals = field.Values; Action <Tuple <int, int> > body = range => { for (int i = range.Item1; i < range.Item2; i++) { vals[i] = converter(other.ValueAt(field.CoordinateAt(i))); } }; if (parallel) { Parallel.ForEach(Partitioner.Create(0, field.Count), body); } else { body(Tuple.Create(0, field.Count)); } }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="field"></param> /// <param name="other"></param> /// <param name="parallel"></param> public static void Sample <T>(this ISampledField3d <T> field, IField3d <T> other, bool parallel = false) { if (parallel) { Parallel.ForEach(Partitioner.Create(0, field.Count), range => Body(range.Item1, range.Item2)); } else { Body(0, field.Count); } void Body(int from, int to) { var vals = field.Values; for (int i = from; i < to; i++) { vals[i] = other.ValueAt(field.PointAt(i)); } } }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { IField3d <double> f = null; Mesh mesh = null; List <Color> colors = new List <Color>(); if (!DA.GetData(0, ref mesh)) { return; } if (!DA.GetData(1, ref f)) { return; } if (!DA.GetDataList(2, colors)) { return; } mesh.ColorVertices(i => { return(colors.Lerp(f.ValueAt(mesh.Vertices[i]))); }, true); DA.SetData(0, mesh); }
/// <summary> /// /// </summary> /// <param name="index"></param> /// <param name="field"></param> /// <param name="strength"></param> public ForceField(int index, IField3d <Vector3d> field, double strength = 1.0) { _index = index; Field = field; Strength = strength; }
/// <summary> /// /// </summary> /// <param name="func"></param> /// <param name="grad"></param> /// <returns></returns> public static FuncField3d <double> CreateDistanceToApprox(IField3d <double> function, IField3d <Vec3d> gradient, double threshold) { // impl ref // http://www.iquilezles.org/www/articles/distance/distance.htm return(Create(p => (function.ValueAt(p) - threshold) / (gradient.ValueAt(p).Length + SlurMath.ZeroTolerance))); }
/// <summary> /// /// </summary> /// <param name="f0"></param> /// <param name="f1"></param> /// <returns></returns> public static FuncField3d <double> CreateIntersection(IField3d <double> f0, IField3d <double> f1) { return(Create(p => SDFUtil.Intersection(f0.ValueAt(p), f1.ValueAt(p)))); }
/// <summary> /// /// </summary> /// <param name="f0"></param> /// <param name="f1"></param> /// <returns></returns> public static FuncField3d <double> CreateDifference(IField3d <double> f0, IField3d <double> f1) { return(Create(p => SDFUtil.Difference(f0.ValueAt(p), f1.ValueAt(p)))); }
/// <summary> /// /// </summary> /// <param name="field"></param> /// <param name="capacity"></param> /// <param name="strength"></param> public ForceField(int index, IField3d <Vec3d> field, double strength = 1.0) { _handle.Index = index; Field = field; Strength = strength; }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="transform"></param> /// <param name="other"></param> /// <returns></returns> public static IField3d <T> CreateTransformed <T>(IField3d <T> other, Transform3d transform) { transform.Invert(); return(Create(p => other.ValueAt(transform.Apply(p)))); }
/// <summary> /// /// </summary> /// <param name="f0"></param> /// <param name="f1"></param> /// <returns></returns> public static IField3d <double> CreateIntersection(IField3d <double> f0, IField3d <double> f1) { return(Create(p => DistanceFunctions.Intersection(f0.ValueAt(p), f1.ValueAt(p)))); }
/// <summary> /// /// </summary> /// <param name="field"></param> /// <param name="point"></param> /// <param name="stepSize"></param> /// <param name="mode"></param> /// <returns></returns> public static IEnumerable <Vec3d> IntegrateFrom(this IField3d <Vec3d> field, Vec3d point, double stepSize, IntegrationMode mode = IntegrationMode.Euler) { return(FieldSim.IntegrateFrom(field, point, stepSize, mode)); }
/// <summary> /// /// </summary> /// <param name="f0"></param> /// <param name="f1"></param> /// <returns></returns> public static IField3d <double> CreateDifference(IField3d <double> f0, IField3d <double> f1) { return(Create(p => DistanceFunctions.Difference(f0.ValueAt(p), f1.ValueAt(p)))); }