/// <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> 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> /// /// </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)); } } }
/// <inheritdoc/> /// <summary> /// /// </summary> /// <param name="particles"></param> public void Calculate(IReadOnlyList <IBody> particles) { foreach (var h in Handles) { h.Delta = _field.ValueAt(particles[h].Position); } }
/// <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> /// /// </summary> /// <param name="particles"></param> public override sealed void Calculate(IReadOnlyList <IBody> particles) { for (int i = 0; i < Handles.Count; i++) { var h = Handles[i]; h.Delta = _field.ValueAt(particles[h].Position); h.Weight = Weight; } }
/// <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> /// 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> /// 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> 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> 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> /// /// </summary> void UpdateGrowthRate() { // sample growth rate field or set to default if (_growthField == null) { foreach (var v in _verts) { v.GrowthRate = 1.0; } } else { Parallel.ForEach(Partitioner.Create(0, _verts.Count), range => { for (int i = range.Item1; i < range.Item2; i++) { var v = _verts[i]; if (v.IsUnused) { continue; } v.GrowthRate = _growthField.ValueAt(v.Position); } }); } // sample direction field if (_directionField != null) { var align = 1.0 - _settings.Alignment; Parallel.ForEach(Partitioner.Create(0, _verts.Count), range => { for (int i = range.Item1; i < range.Item2; i++) { var v = _verts[i]; if (v.IsUnused || !v.IsDegree2) { continue; } var n = _directionField.ValueAt(v.Position); var d = v.MoveSum; var dx = Vector3d.Project(d, n); v.MoveSum = dx + (d - dx) * align; // scale down perpendicular component } }); } }
/// <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 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> void UpdateMaxLengths(bool parallel = false) { var lengthRange = _settings.LengthRange; // set length targets to default if no field if (_lengthField == null) { var min = lengthRange.Min; for (int i = 0; i < _hedges.Count; i += 2) { _hedges[i].MaxLength = min; } return; } // evaluate field Action <Tuple <int, int> > body = range => { for (int i = range.Item1; i < range.Item2; i++) { var he = _hedges[i << 1]; if (he.IsRemoved) { continue; } var p = (he.Start.Position + he.End.Position) * 0.5; he.MaxLength = lengthRange.Evaluate(_lengthField.ValueAt(p)); } }; if (parallel) { Parallel.ForEach(Partitioner.Create(0, _hedges.Count >> 1), body); } else { body(Tuple.Create(0, _hedges.Count >> 1)); } }
/// <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> /// /// </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> /// 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> /// <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> /// 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) { double tolerance = 1d; Mesh mesh = null; IField3d <double> f = null; double iso = 0d; if (!DA.GetData(0, ref mesh)) { return; } if (!DA.GetData(1, ref f)) { return; } if (!DA.GetData(2, ref tolerance)) { return; } if (!DA.GetData(3, ref iso)) { return; } var lines = new List <LineCurve>(); Parallel.For(0, 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, tolerance)); }
/// <inheritdoc /> public void Calculate(ReadOnlyArrayView <Body> bodies) { _delta = _field.ValueAt(bodies[_index].Position.Current) * Strength; }
/// <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)))); }
/// <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="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)))); }
/// <inheritdoc /> public void Calculate(IReadOnlyList <IBody> bodies) { _handle.Delta = _field.ValueAt(bodies[_handle].Position) * Strength; }