Skip to content

Commit

Permalink
Streamlines code translation
Browse files Browse the repository at this point in the history
  • Loading branch information
Chengxuan-Li committed Mar 5, 2024
1 parent 9fb0c5f commit cc84414
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 108 deletions.
86 changes: 86 additions & 0 deletions Components/GenerateStreamlines.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Grasshopper.Kernel;
using Rhino.Geometry;
using System;
using System.Collections.Generic;
using UrbanDesignEngine.IO;
using UrbanDesignEngine.Tensor;

namespace UrbanDesignEngine.Components
{
public class GenerateStreamlines : GH_Component
{
/// <summary>
/// Initializes a new instance of the GenerateStreamlines class.
/// </summary>
public GenerateStreamlines()
: base("GenerateStreamlines", "GSl",
"Create streamlines of a given tensor field",
"UrbanDesignEngine", "TensorField")
{
}

/// <summary>
/// Registers all the input parameters for this component.
/// </summary>
protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
{
pManager.AddScriptVariableParameter("UDETensorField", "UTF", "UDETensorField instance", GH_ParamAccess.item);
}

/// <summary>
/// Registers all the output parameters for this component.
/// </summary>
protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
{
pManager.AddCurveParameter("Streamlines", "Sl", "Generated streamlines", GH_ParamAccess.list);
}

/// <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)
{
ScriptVariableGetter svg0 = ScriptVariableGetter.AllAttributableScriptVariableClassesGetter(this, DA, 0, true);
MultipleTensorFields tfm0 = default;
VariableGetterStatus result = svg0.GetVariableFromAllSimpleTensorFieldTypes(out SimpleTensorField tf0);
if (result == VariableGetterStatus.TypeError)
{
result = ScriptVariableGetter.GetScriptVariable<MultipleTensorFields>(this, DA, 0, true, out tfm0);
if (result != VariableGetterStatus.Success) return;
}
else
{
tfm0 = new MultipleTensorFields(tf0);
}

RK4Integrator integrator = new RK4Integrator(tfm0, StreamlineParams.Default);
StreamlineGenerator sg = new StreamlineGenerator(integrator, new Vector3d(0, 0, 0), new Vector3d(100, 100, 0), StreamlineParams.Default);
sg.RunCreateAllStreamlines();
List<Curve> pls = sg.allStreamlinesSimple.ConvertAll(vs => (Curve) new Polyline(vs.ConvertAll(v => new Point3d(v))).ToNurbsCurve());
DA.SetDataList(0, pls);

}

/// <summary>
/// Provides an Icon for the component.
/// </summary>
protected override System.Drawing.Bitmap Icon
{
get
{
//You can add image files to your project resources and access them like this:
// return Resources.IconForThisComponent;
return null;
}
}

/// <summary>
/// Gets the unique ID for this component. Do not change this ID after release.
/// </summary>
public override Guid ComponentGuid
{
get { return new Guid("e3747a2d-cef4-4b85-bf59-76ad295428d2"); }
}
}
}
3 changes: 2 additions & 1 deletion Tensor/CurveTensorField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ namespace UrbanDesignEngine.Tensor
public class CurveTensorField : ObjectTensorField<Curve>
{
Curve Curve;
public override TensorFieldType TensorFieldType => TensorFieldType.CurveAttractor;
public CurveTensorField(Curve curve, double range, double extent) : base(curve, range, extent)
{
Curve = curve;
geometry = Curve;
TensorFieldType = TensorFieldType.CurveAttractor;

DecayRange = range;
Extent = extent;
}
Expand Down
71 changes: 51 additions & 20 deletions Tensor/GridStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace UrbanDesignEngine.Tensor
{
public struct GridIndex : IDuplicable<GridIndex>
public struct GridIndex : IDuplicable<GridIndex>, IEquatable<GridIndex>
{
public int x;
public int y;
Expand All @@ -21,13 +21,18 @@ public GridIndex(int x, int y)

public GridIndex Duplicate()
{
return new GridIndex { x = x, y = y};
return new GridIndex { x = x, y = y };
}

public bool Equals(GridIndex other)
{
return x == other.x && y == other.y;
}
}

public class Grid : IDuplicable<Grid>
{
Dictionary<GridIndex, List<Vector3d>> Content = new Dictionary<GridIndex, List<Vector3d>>();
public Dictionary<GridIndex, List<Vector3d>> Content = new Dictionary<GridIndex, List<Vector3d>>();
protected int xDim = 0;
protected int yDim = 0;

Expand All @@ -40,24 +45,32 @@ public Grid Duplicate()
return new Grid() { xDim = xDim, yDim = yDim, Content = Content.ToDictionary(entry => entry.Key.Duplicate(), entry => entry.Value.ConvertAll(v => new Vector3d(v))) };
}

public List<Vector3d> Get(int x, int y)
public bool Get(GridIndex gi, out List<Vector3d> vecs)
{
Content.TryGetValue(new GridIndex(x, y), out List<Vector3d> vecs);
return vecs;
return Content.TryGetValue(gi, out vecs);
}

public void Set(int x, int y, int z, Vector3d vec)
public bool Get(int x, int y, out List<Vector3d> vecs)
{
return Content.TryGetValue(new GridIndex(x, y), out vecs);
}

public void Set(int x, int y, Vector3d vec)
{
xDim = Math.Max(x + 1, xDim);
yDim = Math.Max(y + 1, yDim);
zDim = Math.Max(z + 1, zDim);
if (z < 0) z = zDim - 1;
Content.Add(new GridIndex(x, y, z), vec);
if (Content.TryGetValue(new GridIndex(x, y), out List<Vector3d> vecs))
{
vecs.Add(vec);
} else
{
Content.Add(new GridIndex(x, y), new List<Vector3d> { vec });
}
}

public void Set(GridIndex id, Vector3d vec)
{
Set(id.x, id.y, id.z, vec);
Set(id.x, id.y, vec);
}
}

Expand All @@ -83,6 +96,21 @@ public GridStorage(Vector3d worldDimensions, Vector3d origin, double dsep)

public void AddAll(GridStorage gridStorage)
{
foreach (var kvp in gridStorage.Grid.Content)
{
if (Grid.Get(kvp.Key, out List<Vector3d> vecs))
{
vecs.AddRange(kvp.Value);
} else
{
foreach (Vector3d v in kvp.Value)
{
Grid.Set(kvp.Key.x, kvp.Key.y, v);
}

}
}
/*
for (int i = 0; i < gridStorage.Grid.Length; i++)
{
for (int j = 0; j < gridStorage.Grid[i].Length; j++)
Expand All @@ -93,9 +121,10 @@ public void AddAll(GridStorage gridStorage)
}
}
}
*/
}

public void AddPolyline(Vector3d[] line)
public void AddPolyline(List<Vector3d> line)
{
foreach (var v in line)
{
Expand All @@ -111,7 +140,7 @@ public void AddSample(Vector3d v)

public void AddSample(Vector3d v, GridIndex coords)
{
Grid.Set(coords.x, coords.y, coords.z, v);
Grid.Set(coords.x, coords.y, v);
}

public bool IsValidSample(Vector3d v, double dSq = double.NaN)
Expand All @@ -132,7 +161,8 @@ public bool IsValidSample(Vector3d v, double dSq = double.NaN)
cell.y += y;
if (!VectorOutOfBounds(cell, this.gridDimensions))
{
if (!VectorFarFromVectors(v, Grid[(int)cell.X][(int)cell.Y], dSq))
if (!Grid.Get(cell, out List<Vector3d> vecs)) return false;
if (!VectorFarFromVectors(v, vecs , dSq))
{
return false;
}
Expand All @@ -149,7 +179,7 @@ public bool VectorFarFromVectors(Vector3d v, List<Vector3d> vectors, double dSq)
{
if (!sample.Equals(v))
{
double distanceSq = sample.DistanceToSquared(v);
double distanceSq = new Point3d(sample).DistanceTo(new Point3d(v));
if (distanceSq < dSq)
{
return false;
Expand All @@ -174,8 +204,10 @@ public List<Vector3d> GetNearbyPoints(Vector3d v, double distance)
cell.y += y;
if (!VectorOutOfBounds(cell, this.gridDimensions))
{
for (int i = 0; i < Grid.ZDim)
outList.AddRange(Grid[(int)cell.X][(int)cell.Y]);
if (Grid.Get(cell, out List<Vector3d> vecs))
{
outList.AddRange(vecs);
}
}
}
}
Expand Down Expand Up @@ -210,13 +242,12 @@ private GridIndex GetSampleCoords(Vector3d worldV)
Vector3d v = WorldToGrid(worldV);
if (VectorOutOfBounds(v, this.worldDimensions))
{
return new GridIndex(0, 0, 0);
return new GridIndex(0, 0);
}

return new GridIndex(
(int)Math.Floor(v.X / this.dsep),
(int)Math.Floor(v.Y / this.dsep),
-1
(int)Math.Floor(v.Y / this.dsep)
);
}
}
Expand Down
14 changes: 7 additions & 7 deletions Tensor/Integrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ public FieldIntegrator(ITensorField field)
TensorField = field;
}

public abstract Vector3d Integrate(Point3d point, bool major);
public abstract Vector3d Integrate(Vector3d point, bool major);

protected Vector3d SampleFieldVector(Point3d point, bool major)
protected Vector3d SampleFieldVector(Vector3d point, bool major)
{
TensorField.ContextAwareEvaluate(-1, point, out Vector3d majorVector, out Vector3d minorVector, out double scalar);
TensorField.ContextAwareEvaluate(-1, new Point3d(point), out Vector3d majorVector, out Vector3d minorVector, out double scalar);
return major ? majorVector : minorVector;
}

public bool OnLand(Point3d point)
public bool OnLand(Vector3d point)
{
return TensorField.Contains(point);
return TensorField.Contains(new Point3d(point));
}
}

Expand All @@ -40,7 +40,7 @@ public EulerIntegrator(ITensorField field, StreamlineParams parameters) : base(f
SParams = parameters;
}

public override Vector3d Integrate(Point3d point, bool major)
public override Vector3d Integrate(Vector3d point, bool major)
{
return SampleFieldVector(point, major) * SParams.Dstep;
}
Expand All @@ -55,7 +55,7 @@ public RK4Integrator(ITensorField field, StreamlineParams parameters) : base(fie
SParams = parameters;
}

public override Vector3d Integrate(Point3d point, bool major)
public override Vector3d Integrate(Vector3d point, bool major)
{
Vector3d k1 = SampleFieldVector(point, major);
Vector3d k23 = SampleFieldVector(point + new Vector3d(SParams.Dstep / 2, SParams.Dstep / 2, 0), major);
Expand Down
3 changes: 2 additions & 1 deletion Tensor/LineTensorField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ namespace UrbanDesignEngine.Tensor
public class LineTensorField : ObjectTensorField<Curve>
{
public Line Line;

public override TensorFieldType TensorFieldType => TensorFieldType.LineAttractor;
public LineTensorField(Line line, double range, double extent) : base(line.ToNurbsCurve(), range, extent)
{
Line = line;
geometry = line.ToNurbsCurve();
TensorFieldType = TensorFieldType.LineAttractor;
DecayRange = range;
Extent = extent;
}
Expand Down
4 changes: 2 additions & 2 deletions Tensor/PolylineTensorField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ namespace UrbanDesignEngine.Tensor
public class PolylineTensorField : ObjectTensorField<Curve>
{
public Polyline Polyline;

public override TensorFieldType TensorFieldType => TensorFieldType.PolylineAttractor;
public PolylineTensorField(Polyline polyline, double range, double extent) : base(polyline.ToPolylineCurve(), range, extent)
{
Polyline = polyline;
geometry = polyline.ToNurbsCurve();
TensorFieldType = TensorFieldType.PolylineAttractor;

DecayRange = range;
Extent = extent;
}
Expand Down
3 changes: 2 additions & 1 deletion Tensor/RadialTensorField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ namespace UrbanDesignEngine.Tensor
{
public class RadialTensorField : ObjectTensorField<Point>, IHasGHIOPreviewGeometryListParam<RadialTensorField, GHIOTensorFieldCurvesParam<RadialTensorField>, Curve>, IHasGeometryList<Curve>
{
public override TensorFieldType TensorFieldType => TensorFieldType.PointAttractor;
public RadialTensorField(Point3d point, double range, double extent) : base(new Point(point), range, extent)
{
geometry = new Point(point);
TensorFieldType = TensorFieldType.PointAttractor;

DecayRange = range;
Extent = extent;
}
Expand Down
2 changes: 1 addition & 1 deletion Tensor/SimpleTensorField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public SimpleTensorField(MatrixEntry<Point3d> v00, MatrixEntry<Point3d> v01, Mat
Matrix[1, 1] = v11;
}
*/
public TensorFieldType TensorFieldType => TensorFieldType.Uniform;
public virtual TensorFieldType TensorFieldType => TensorFieldType.Uniform;

public Curve BoundaryCurve = default;

Expand Down
Loading

0 comments on commit cc84414

Please sign in to comment.