├── .gitattributes
├── .gitignore
├── Examples
├── App.config
├── Examples.csproj
├── Gallery
│ ├── 170720_Relief_02.gif
│ └── h_01_3_zoom_2.png
├── Grasshopper
│ ├── Distance_Transform.gh
│ ├── Dynamic_Remesher.3dm
│ ├── Dynamic_Remesher.gh
│ ├── Funicular_Network.3dm
│ ├── Funicular_Network.gh
│ ├── Geodesic_Field.3dm
│ ├── Geodesic_Field.gh
│ ├── Geodesic_Field_3d.3dm
│ ├── Geodesic_Field_3d.gh
│ ├── HeMesh_Unroll.gh
│ ├── IDWField_Example.3dm
│ ├── IDWField_Example.gh
│ ├── Noise_Field_Integration.gh
│ ├── Quad_Strips.gh
│ ├── Sort_Faces_By_Depth.gh
│ ├── SphereCollide.3dm
│ ├── Sphere_Collide.gh
│ ├── Steiner_Tree_Finder.gh
│ ├── User Objects
│ │ └── SlurCS.ghuser
│ └── Volumetric_Clustering.gh
├── HeMeshFromFile.cs
├── Paths.cs
├── PlanarizeHeMesh.cs
├── PlanarizeQuad.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── Resources
│ ├── Images
│ │ └── Geoff-McFetridge-Hands.png
│ ├── chair_planar_0.obj
│ ├── chair_smooth_0.obj
│ ├── fabric_pucker_0.obj
│ ├── fabric_pucker_1.obj
│ ├── face_0.obj
│ ├── face_mapped_0.obj
│ ├── fortune_cookie_0.obj
│ ├── minimal_0.obj
│ ├── ring_crimped_0.obj
│ ├── shell_low_poly_0.obj
│ └── skeleton_0.obj
└── packages.config
├── LICENSE.md
├── README.md
├── SlurGH
├── Components
│ ├── Display
│ │ ├── DisplayFaceColors.cs
│ │ └── NormalShader.cs
│ ├── Enums
│ │ ├── DistanceMetrics.cs
│ │ ├── FieldType.cs
│ │ ├── NoiseType.cs
│ │ └── SimState.cs
│ ├── Mesh
│ │ ├── AlignVertices.cs
│ │ ├── MeshClosedPolyline.cs
│ │ ├── MeshExtrude.cs
│ │ ├── MeshFlip.cs
│ │ ├── MeshLoft.cs
│ │ ├── MeshLoftPair.cs
│ │ └── MeshSeparate.cs
│ └── SpatialSlur
│ │ ├── Fields
│ │ ├── CreateGridField.cs
│ │ ├── CreateNoiseField.cs
│ │ ├── EvaluateField.cs
│ │ ├── GeodesicDistance.cs
│ │ ├── IntegrateField.cs
│ │ └── ResampleField.cs
│ │ ├── Meshes
│ │ ├── CreateDual.cs
│ │ ├── EdgeLines.cs
│ │ ├── FacePlanarity.cs
│ │ ├── FacePolylines.cs
│ │ ├── HeGraphFromLines.cs
│ │ ├── HeMeshFromPolylines.cs
│ │ ├── HeMeshUnroll.cs
│ │ ├── HoleBoundaries.cs
│ │ └── VertexPositions.cs
│ │ └── Tools
│ │ ├── CreateFeature.cs
│ │ ├── DynamicRemesherSettings.cs
│ │ └── DynamicRemesherSolver.cs
├── Params
│ └── SpatialSlur
│ │ ├── HeGraph3dParam.cs
│ │ └── HeMesh3dParam.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── SlurGH.csproj
├── SlurGHInfo.cs
└── Types
│ ├── GH_HeGraph3d.cs
│ └── GH_HeMesh3d.cs
├── SpatialSlur.sln
└── SpatialSlur
├── Collections
├── ArrayView.cs
├── Extensions
│ ├── ArrayExtensions.cs
│ ├── ArrayViewExtensions.cs
│ ├── IDictionaryExtensions.cs
│ ├── IEnumerableExtensions.cs
│ ├── IListExtensions.cs
│ ├── IReadOnlyListExtensions.cs
│ ├── ListExtensions.cs
│ └── ReadOnlyArrayViewExtensions.cs
├── HashGrid2d.cs
├── HashGrid3d.cs
├── KMeans.cs
├── KdTree.cs
├── ListView.cs
├── PriorityQueue.cs
├── ProbabilitySelector.cs
├── Proximity.cs
├── QueueSet.cs
├── ReadOnlyArrayView.cs
├── ReadOnlyListView.cs
├── ReadOnlySet.cs
├── RefList.cs
├── Sequences.cs
├── StackSet.cs
└── UniformPartitioner.cs
├── Core
├── Atomic.cs
├── AxisAngle3d.cs
├── ColorConversion.cs
├── Extensions
│ ├── ColorExtensions.cs
│ ├── GenericExtensions.cs
│ └── RandomExtensions.cs
├── Geometry.cs
├── Interop.cs
├── Interval2d.cs
├── Interval3d.cs
├── Intervald.cs
├── Intervalf.cs
├── Matrix.cs
├── Matrix2d.cs
├── Matrix3d.cs
├── Matrix4d.cs
├── Orient2d.cs
├── Orient3d.cs
├── OrthoBasis2d.cs
├── OrthoBasis3d.cs
├── Plane3d.cs
├── Property.cs
├── Quaterniond.cs
├── SlurMath.cs
├── Templates
│ ├── Matrix.cs
│ ├── Matrix.tt
│ ├── Vector.cs
│ └── Vector.tt
├── Transform2d.cs
├── Transform3d.cs
├── Utilities.cs
├── Vector2d.cs
├── Vector2i.cs
├── Vector3d.cs
├── Vector3f.cs
├── Vector3i.cs
└── Vector4d.cs
├── Dynamics
├── Body.cs
├── BodyPosition.cs
├── BodyRotation.cs
├── ConstraintSolver.cs
├── ConstraintSolverSettings.cs
├── Constraints
│ ├── AbovePlane.cs
│ ├── AlignPair.cs
│ ├── Angle.cs
│ ├── Cocircular.cs
│ ├── Coincident.cs
│ ├── Colinear.cs
│ ├── Constraint.cs
│ ├── Coplanar.cs
│ ├── Cospherical.cs
│ ├── CyclicQuad.cs
│ ├── DihedralAngle.cs
│ ├── Distance.cs
│ ├── EqualizeLengths.cs
│ ├── InsideBounds.cs
│ ├── LaplacianSmooth.cs
│ ├── MinimizeArea.cs
│ ├── MinimizeDistance.cs
│ ├── OnCircle.cs
│ ├── OnCurve.cs
│ ├── OnExtendedMesh.cs
│ ├── OnExtendedSurface.cs
│ ├── OnLine.cs
│ ├── OnMesh.cs
│ ├── OnPlane.cs
│ ├── OnPosition.cs
│ ├── OnRotation.cs
│ ├── OnSphere.cs
│ ├── OnSurface.cs
│ ├── OnTarget.cs
│ ├── OutsideSphere.cs
│ ├── PlanarQuad.cs
│ ├── PositionGroup.cs
│ ├── PositionPair.cs
│ ├── RelativePosition.cs
│ ├── RelativeRotation.cs
│ ├── TangentialQuad.cs
│ ├── TangentialSmooth.cs
│ ├── Translation.cs
│ └── Trapezoid.cs
├── Extensions
│ └── IEnumerableExtensions.cs
├── Forces
│ ├── AreaWeight.cs
│ ├── FalseWeight.cs
│ ├── Force.cs
│ ├── ForceField.cs
│ ├── LinearWeight.cs
│ ├── PositionGroup.cs
│ ├── Pressure.cs
│ ├── SphereCollide.cs
│ └── Weight.cs
└── Interfaces
│ └── IConstraint.cs
├── Fields
├── Derived
│ ├── GridField2dDouble.cs
│ ├── GridField2dVector2d.cs
│ ├── GridField2dVector3d.cs
│ ├── GridField3dDouble.cs
│ ├── GridField3dMatrix3d.cs
│ ├── GridField3dVector3d.cs
│ ├── IDWField3dDouble.cs
│ ├── IDWField3dVector3d.cs
│ ├── MeshField3dDouble.cs
│ └── MeshField3dVector3d.cs
├── DistanceFunctions.cs
├── DistanceTransform.cs
├── Enums
│ ├── IntegrationMode.cs
│ ├── SampleMode.cs
│ └── WrapMode.cs
├── Extensions
│ ├── GridField2dExtensions.cs
│ ├── GridField3dExtensions.cs
│ ├── GridField3dFactoryExtensions.cs
│ ├── ISampledField2dExtensions.cs
│ ├── ISampledField3dExtensions.cs
│ ├── ISampledFieldExtensions.cs
│ ├── ListExtensions.cs
│ └── MeshFieldExtensions.cs
├── Field2d.cs
├── Field3d.cs
├── Filter.cs
├── FuncField2d.cs
├── FuncField3d.cs
├── GeodesicDistance.cs
├── Grid.cs
├── Grid2d.cs
├── Grid3d.cs
├── GridField2d.cs
├── GridField2dFactory.cs
├── GridField3d.cs
├── GridField3dFactory.cs
├── GridPoint2d.cs
├── GridPoint3d.cs
├── IDWConstant3d.cs
├── IDWField3d.cs
├── IDWFieldFactory.cs
├── IDWMesh3d.cs
├── IDWObject3d.cs
├── IDWPoint3d.cs
├── ImplicitSurfaces.cs
├── Interfaces
│ ├── IField2d.cs
│ ├── IField3d.cs
│ ├── IGradient2d.cs
│ ├── IGradient3d.cs
│ ├── ISampledField.cs
│ ├── ISampledField2d.cs
│ └── ISampledField3d.cs
├── Interop.cs
├── MeshField3d.cs
├── MeshField3dFactory.cs
├── Noise.cs
├── PerlinNoise2d.cs
├── PerlinNoise3d.cs
├── SimplexNoise2d.cs
├── SimplexNoise3d.cs
└── Streamline.cs
├── Meshes
├── Delegates.cs
├── EdgeListView.cs
├── Enums
│ └── SmoothBoundaryType.cs
├── Extensions
│ ├── FaceExtensions.cs
│ ├── HalfedgeExtensions.cs
│ ├── HeStructureExtensions.cs
│ └── VertexExtensions.cs
├── FaceQuadrangulator.cs
├── FaceTriangulator.cs
├── GraphSearch.cs
├── HalfedgeList.cs
├── HeGraph.cs
├── HeGraph3d.cs
├── HeGraph3dFactory.cs
├── HeGraphFactory.cs
├── HeMesh.cs
├── HeMesh3d.cs
├── HeMesh3dFactory.cs
├── HeMeshFactory.cs
├── HeMeshUnroller.cs
├── Impl
│ ├── Halfedge.cs
│ ├── HeGraph.cs
│ ├── HeGraphFactory.cs
│ ├── HeMesh.cs
│ ├── HeMeshFactory.cs
│ ├── HeStructure.cs
│ └── Node.cs
├── Interfaces
│ ├── IFaceQuadrangulator.cs
│ ├── IFaceTriangulator.cs
│ ├── INormal3d.cs
│ └── IPosition3d.cs
├── Interop.cs
├── Matrix.cs
├── NodeList.cs
├── QuadStrip.cs
├── Selection.cs
├── Subdivision.cs
├── TriMesh.cs
├── TriMesh3d.cs
└── TriMesh3f.cs
├── Properties
└── AssemblyInfo.cs
├── Rhino
├── Conversions.cs
├── Extensions
│ ├── ArrayViewExtensions.cs
│ ├── BoundingBoxExtensions.cs
│ ├── GridField2dExtensions.cs
│ ├── GridField3dExtensions.cs
│ ├── HeGraphFactoryExtensions.cs
│ ├── HeMeshExtensions.cs
│ ├── HeMeshFactoryExtensions.cs
│ ├── HeNodeExtensions.cs
│ ├── HeStructureExtensions.cs
│ ├── IEnumerableExtensions.cs
│ ├── ISampledField3dExtensions.cs
│ ├── Interval2dExtensions.cs
│ ├── Interval3dExtensions.cs
│ ├── LineExtensions.cs
│ ├── MeshExtensions.cs
│ ├── Orient3dExtensions.cs
│ ├── PlaneExtensions.cs
│ ├── Point3dExtensions.cs
│ ├── PriorityQueueExtensions.cs
│ ├── QuadStripExtensions.cs
│ ├── TransformExtensions.cs
│ └── Vector3dExtensions.cs
├── Field3d.cs
├── Isosurface.cs
└── RhinoFactory.cs
├── SpatialSlur.csproj
├── Tools
├── DynamicRemesher.cs
├── Features
│ ├── CurveFeature.cs
│ ├── ExtendedMeshFeature.cs
│ ├── IFeature.cs
│ ├── ISurfaceFeature.cs
│ ├── MeshFeature.cs
│ ├── PointCloudFeature.cs
│ └── PointFeature.cs
├── LoopGrower.cs
└── SteinerFinder.cs
├── Unity
├── Conversions.cs
└── Extensions
│ ├── ArrayExtensions.cs
│ ├── IReadOnlyListExtensions.cs
│ └── Matrix4x4Extensions.cs
└── packages.config
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/Examples/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Examples/Gallery/170720_Relief_02.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Gallery/170720_Relief_02.gif
--------------------------------------------------------------------------------
/Examples/Gallery/h_01_3_zoom_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Gallery/h_01_3_zoom_2.png
--------------------------------------------------------------------------------
/Examples/Grasshopper/Distance_Transform.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Distance_Transform.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/Dynamic_Remesher.3dm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Dynamic_Remesher.3dm
--------------------------------------------------------------------------------
/Examples/Grasshopper/Dynamic_Remesher.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Dynamic_Remesher.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/Funicular_Network.3dm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Funicular_Network.3dm
--------------------------------------------------------------------------------
/Examples/Grasshopper/Funicular_Network.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Funicular_Network.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/Geodesic_Field.3dm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Geodesic_Field.3dm
--------------------------------------------------------------------------------
/Examples/Grasshopper/Geodesic_Field.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Geodesic_Field.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/Geodesic_Field_3d.3dm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Geodesic_Field_3d.3dm
--------------------------------------------------------------------------------
/Examples/Grasshopper/Geodesic_Field_3d.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Geodesic_Field_3d.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/HeMesh_Unroll.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/HeMesh_Unroll.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/IDWField_Example.3dm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/IDWField_Example.3dm
--------------------------------------------------------------------------------
/Examples/Grasshopper/IDWField_Example.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/IDWField_Example.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/Noise_Field_Integration.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Noise_Field_Integration.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/Quad_Strips.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Quad_Strips.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/Sort_Faces_By_Depth.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Sort_Faces_By_Depth.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/SphereCollide.3dm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/SphereCollide.3dm
--------------------------------------------------------------------------------
/Examples/Grasshopper/Sphere_Collide.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Sphere_Collide.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/Steiner_Tree_Finder.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Steiner_Tree_Finder.gh
--------------------------------------------------------------------------------
/Examples/Grasshopper/User Objects/SlurCS.ghuser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/User Objects/SlurCS.ghuser
--------------------------------------------------------------------------------
/Examples/Grasshopper/Volumetric_Clustering.gh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Grasshopper/Volumetric_Clustering.gh
--------------------------------------------------------------------------------
/Examples/HeMeshFromFile.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using SpatialSlur.Fields;
8 | using SpatialSlur.Meshes;
9 |
10 | namespace SpatialSlur.Examples
11 | {
12 | ///
13 | ///
14 | ///
15 | static class HeMeshFromFile
16 | {
17 | const string _fileIn = "face_0.obj";
18 | const string _fileOut = "face_mapped_0.obj";
19 |
20 |
21 | ///
22 | ///
23 | ///
24 | ///
25 | public static void Start()
26 | {
27 | var mesh = HeMesh3d.Factory.CreateFromOBJ(Paths.Resources + _fileIn);
28 | var verts = mesh.Vertices;
29 |
30 | var texCoords = new Vector2d[verts.Count];
31 | double scale = 0.5;
32 | double offset = scale * Math.PI * 0.25;
33 |
34 | // create texture coordinates from implicit function
35 | for (int i = 0; i < verts.Count; i++)
36 | {
37 | var p = verts[i].Position * scale;
38 | var u = ImplicitSurfaces.Gyroid(p.X, p.Y, p.Z);
39 | var v = ImplicitSurfaces.Gyroid(p.X + offset, p.Y + offset, p.Z + offset);
40 | texCoords[i] = new Vector2d(u, v);
41 | }
42 |
43 | // compute vertex normals & write to file
44 | mesh.Vertices.Action(v => v.Normal = v.GetNormal(), true);
45 | Interop.Meshes.WriteToObj(mesh, Paths.Resources + _fileOut, v => texCoords[v]);
46 |
47 | Console.WriteLine("File written successfully. Press return to exit.");
48 | Console.ReadLine();
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Examples/Paths.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Notes
3 | */
4 |
5 | namespace SpatialSlur.Examples
6 | {
7 | ///
8 | ///
9 | ///
10 | static class Paths
11 | {
12 | public const string Resources = @"../../Resources/";
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Examples/PlanarizeHeMesh.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Linq;
8 | using SpatialSlur;
9 | using SpatialSlur.Meshes;
10 | using SpatialSlur.Dynamics;
11 | using SpatialSlur.Dynamics.Constraints;
12 |
13 | namespace SpatialSlur.Examples
14 | {
15 | ///
16 | ///
17 | ///
18 | static class PlanarizeHeMesh
19 | {
20 | const string _fileIn = "chair_smooth_0.obj";
21 | const string _fileOut = "chair_planar_0.obj";
22 |
23 |
24 | ///
25 | ///
26 | ///
27 | public static void Start()
28 | {
29 | // import halfedge mesh
30 | var mesh = HeMesh3d.Factory.CreateFromOBJ(Paths.Resources + _fileIn);
31 |
32 | // create particles
33 | var bodies = mesh.Vertices.Select(v => new Body(v.Position)).ToArray();
34 |
35 | // create constraints
36 | var constraints = mesh.Faces.Where(f => !f.IsDegree3)
37 | .Select(f => new Coplanar(f.Vertices.Select(v => v.Index)))
38 | .ToArray();
39 |
40 | // create solver
41 | var solver = new ConstraintSolver();
42 | solver.Settings.LinearDamping = 0.1;
43 |
44 | // wait for keypress to start the solver
45 | Console.WriteLine("Press return to start the solver.");
46 | Console.ReadLine();
47 |
48 | // step the solver until converged
49 | while (!solver.IsConverged)
50 | {
51 | solver.Step(bodies, constraints, true);
52 | Console.WriteLine($" step {solver.StepCount}");
53 | }
54 | Console.WriteLine("\nSolver converged! Press return to exit.");
55 |
56 | // update mesh vertices
57 | mesh.Vertices.Action(v => v.Position = bodies[v].Position.Current); // mesh elements (vertices, halfedges, faces) are implicitly converted to their index
58 |
59 | // compute vertex normals & write to file
60 | mesh.Vertices.Action(v => v.Normal = v.GetNormal(), true);
61 | Interop.Meshes.WriteToObj(mesh, Paths.Resources + _fileOut);
62 | Console.ReadLine();
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Examples/PlanarizeQuad.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using SpatialSlur;
8 | using SpatialSlur.Dynamics;
9 | using SpatialSlur.Dynamics.Constraints;
10 |
11 | namespace SpatialSlur.Examples
12 | {
13 | ///
14 | /// Planarizes a randomly generated quadrilateral.
15 | ///
16 | static class PlanarizeQuad
17 | {
18 | ///
19 | ///
20 | ///
21 | ///
22 | public static void Start()
23 | {
24 | var random = new Random(0);
25 | var box = new Interval3d(new Vector3d(0.0), new Vector3d(10.0)); // create a interval between the (0,0,0) and (10,10,10)
26 |
27 | // create bodies
28 | var bodies = new Body[] {
29 | new Body(random.NextVector3d(box)),
30 | new Body(random.NextVector3d(box)),
31 | new Body(random.NextVector3d(box)),
32 | new Body(random.NextVector3d(box))
33 | };
34 |
35 | // create constraints
36 | var constraints = new IConstraint[] {
37 | new PlanarQuad(0, 1, 2, 3)
38 | };
39 |
40 | // create solver
41 | var solver = new ConstraintSolver();
42 |
43 | // wait for keypress to start the solver
44 | Console.WriteLine("Press return to start the solver.");
45 | Console.ReadLine();
46 |
47 | // step the solver until converged
48 | while (!solver.IsConverged)
49 | {
50 | solver.Step(bodies, constraints);
51 | Console.WriteLine($" step {solver.StepCount}");
52 | }
53 |
54 | Console.WriteLine("\nSolver converged! Press return to exit.");
55 | Console.ReadLine();
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Examples/Program.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System.Linq;
7 | using System.Collections.Generic;
8 |
9 | namespace SpatialSlur.Examples
10 | {
11 | ///
12 | ///
13 | ///
14 | static class Program
15 | {
16 | ///
17 | ///
18 | ///
19 | public static void Main()
20 | {
21 | PlanarizeHeMesh.Start();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Examples/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("Examples")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("Examples")]
12 | [assembly: AssemblyCopyright("Copyright © David Reeves 2017")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("2bcae614-c7c3-4359-9701-3a1f7dd4c85f")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion(SpatialSlur.AssemblyInfo.VersionNumber)]
35 |
--------------------------------------------------------------------------------
/Examples/Resources/Images/Geoff-McFetridge-Hands.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davreev/SpatialSlur/8c14b0c40cf102fa51f28091a2d6f213c56aba97/Examples/Resources/Images/Geoff-McFetridge-Hands.png
--------------------------------------------------------------------------------
/Examples/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2014 David Reeves
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/SlurGH/Components/Display/DisplayFaceColors.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Drawing;
9 |
10 | using Grasshopper.Kernel;
11 | using Grasshopper.Kernel.Types;
12 |
13 | using SpatialSlur.Meshes;
14 | using SpatialSlur.Rhino;
15 | using SpatialSlur.Grasshopper.Params;
16 |
17 | namespace SpatialSlur.Grasshopper.Components
18 | {
19 | ///
20 | ///
21 | ///
22 | public class DisplayFaceColors : GH_Component
23 | {
24 | ///
25 | ///
26 | ///
27 | public DisplayFaceColors()
28 | : base("Display Face Colors", "FaceCol",
29 | "Applies a solid color to each face in a halfedge mesh.",
30 | "SpatialSlur", "Display")
31 | {
32 | }
33 |
34 |
35 | ///
36 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
37 | {
38 | pManager.AddParameter(new HeMesh3dParam(), "heMesh", "heMesh", "Mesh to color", GH_ParamAccess.item);
39 | pManager.AddColourParameter("colors", "colors", "", GH_ParamAccess.list);
40 | }
41 |
42 |
43 | ///
44 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
45 | {
46 | pManager.AddMeshParameter("mesh", "mesh", "Colored mesh", GH_ParamAccess.item);
47 | }
48 |
49 |
50 | ///
51 | protected override void SolveInstance(IGH_DataAccess DA)
52 | {
53 | HeMesh3d mesh = null;
54 | List colors = new List();
55 |
56 | if (!DA.GetData(0, ref mesh)) return;
57 | if (!DA.GetDataList(1, colors)) return;
58 |
59 | int last = colors.Count - 1;
60 | var result = mesh.ToPolySoup(f => colors[Math.Min(f, last)]);
61 |
62 | DA.SetData(0, new GH_Mesh(result));
63 | }
64 |
65 |
66 | ///
67 | /// Provides an Icon for every component that will be visible in the User Interface.
68 | /// Icons need to be 24x24 pixels.
69 | ///
70 | protected override System.Drawing.Bitmap Icon
71 | {
72 | get { return null; }
73 | }
74 |
75 |
76 | ///
77 | /// Each component must have a unique Guid to identify it.
78 | /// It is vital this Guid doesn't change otherwise old ghx files
79 | /// that use the old ID will partially fail during loading.
80 | ///
81 | public override Guid ComponentGuid
82 | {
83 | get { return new Guid("{65C6B961-F1D1-4C41-87C9-C43FB3778923}"); }
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/SlurGH/Components/Enums/DistanceMetrics.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 |
12 | namespace SpatialSlur.Grasshopper.Components
13 | {
14 | ///
15 | ///
16 | ///
17 | public enum DistanceMetric
18 | {
19 | ///
20 | Manhattan,
21 | ///
22 | Euclidean,
23 | ///
24 | Chebyshev
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SlurGH/Components/Enums/FieldType.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Notes
3 | */
4 |
5 | namespace SpatialSlur.Grasshopper.Components
6 | {
7 | ///
8 | ///
9 | ///
10 | public enum FieldType
11 | {
12 | Scalar,
13 | Vector
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/SlurGH/Components/Enums/NoiseType.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Notes
3 | */
4 |
5 | namespace SpatialSlur.Grasshopper.Components
6 | {
7 | ///
8 | ///
9 | ///
10 | public enum NoiseType
11 | {
12 | Perlin,
13 | Simplex
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/SlurGH/Components/Enums/SimState.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Notes
3 | */
4 |
5 | namespace SpatialSlur.Grasshopper.Components
6 | {
7 | ///
8 | ///
9 | ///
10 | public enum SimState
11 | {
12 | Play,
13 | Pause,
14 | Reset
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/SlurGH/Components/Mesh/AlignVertices.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Linq;
8 |
9 | using Grasshopper.Kernel;
10 | using Grasshopper.Kernel.Types;
11 | using Rhino.Geometry;
12 |
13 | using SpatialSlur;
14 | using SpatialSlur.Collections;
15 |
16 | using Vec3d = Rhino.Geometry.Vector3d;
17 |
18 | namespace SpatialSlur.Grasshopper.Components
19 | {
20 | ///
21 | ///
22 | ///
23 | public class AlignVertices : GH_Component
24 | {
25 | ///
26 | ///
27 | ///
28 | public AlignVertices()
29 | : base("Align Vertices", "AlignVerts",
30 | "Aligns positions of near-coincident vertices in a mesh.",
31 | "Mesh", "Util")
32 | {
33 | }
34 |
35 |
36 | ///
37 | protected override void RegisterInputParams(GH_InputParamManager pManager)
38 | {
39 | pManager.AddMeshParameter("mesh", "mesh", "Mesh with vertices to align", GH_ParamAccess.item);
40 | pManager.AddNumberParameter("radius", "radius", "Vertex search radius", GH_ParamAccess.item, 1.0e-4);
41 | }
42 |
43 |
44 | ///
45 | protected override void RegisterOutputParams(GH_OutputParamManager pManager)
46 | {
47 | pManager.AddMeshParameter("result", "result", "Mesh with aligned vertices", GH_ParamAccess.item);
48 | }
49 |
50 |
51 | ///
52 | protected override void SolveInstance(IGH_DataAccess DA)
53 | {
54 | Mesh mesh = null;
55 | double tol = 0.0;
56 |
57 | if (!DA.GetData(0, ref mesh)) return;
58 | if (!DA.GetData(1, ref tol)) return;
59 |
60 | var verts = mesh.Vertices;
61 | var points = verts.Select(p => (Vector3d)p).ToArray();
62 |
63 | Proximity.Consolidate(points, tol, 3);
64 | //Message = (points.Consolidate(tol)) ? "Converged" : "Not converged";
65 |
66 | for (int i = 0; i < verts.Count; i++)
67 | verts[i] = (Point3f)points[i];
68 |
69 | DA.SetData(0, new GH_Mesh(mesh));
70 | }
71 |
72 |
73 | ///
74 | /// Provides an Icon for every component that will be visible in the User Interface.
75 | /// Icons need to be 24x24 pixels.
76 | ///
77 | protected override System.Drawing.Bitmap Icon
78 | {
79 | get { return null; }
80 | }
81 |
82 |
83 | ///
84 | /// Each component must have a unique Guid to identify it.
85 | /// It is vital this Guid doesn't change otherwise old ghx files
86 | /// that use the old ID will partially fail during loading.
87 | ///
88 | public override Guid ComponentGuid
89 | {
90 | get { return new Guid("{FC8A6CF2-C16A-4A23-8012-28B9F36B1844}"); }
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/SlurGH/Components/Mesh/MeshClosedPolyline.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using Grasshopper.Kernel;
8 | using Grasshopper.Kernel.Types;
9 | using Rhino.Geometry;
10 |
11 | using Vec3d = Rhino.Geometry.Vector3d;
12 |
13 | namespace SpatialSlur.Grasshopper.Components
14 | {
15 | ///
16 | ///
17 | ///
18 | public class MeshClosedPolyline : GH_Component
19 | {
20 | ///
21 | ///
22 | ///
23 | public MeshClosedPolyline()
24 | : base("Mesh Closed Polyline", "MeshPoly",
25 | "Creates a mesh from a closed polyline.",
26 | "Mesh", "Util")
27 | {
28 | }
29 |
30 |
31 | ///
32 | protected override void RegisterInputParams(GH_InputParamManager pManager)
33 | {
34 | pManager.AddCurveParameter("polyline", "poly", "Closed polyline to mesh", GH_ParamAccess.item);
35 | }
36 |
37 |
38 | ///
39 | protected override void RegisterOutputParams(GH_OutputParamManager pManager)
40 | {
41 | pManager.AddMeshParameter("mesh", "mesh", "Resulting mesh", GH_ParamAccess.item);
42 | }
43 |
44 |
45 | ///
46 | protected override void SolveInstance(IGH_DataAccess DA)
47 | {
48 | GH_Curve curve = null;
49 | if (!DA.GetData(0, ref curve)) return;
50 |
51 | if (!curve.Value.TryGetPolyline(out var poly))
52 | throw new ArgumentException("The given curve is not a polyline.");
53 |
54 | DA.SetData(0, new GH_Mesh(Mesh.CreateFromClosedPolyline(poly)));
55 | }
56 |
57 |
58 | ///
59 | /// Provides an Icon for every component that will be visible in the User Interface.
60 | /// Icons need to be 24x24 pixels.
61 | ///
62 | protected override System.Drawing.Bitmap Icon
63 | {
64 | get { return null; }
65 | }
66 |
67 |
68 | ///
69 | /// Each component must have a unique Guid to identify it.
70 | /// It is vital this Guid doesn't change otherwise old ghx files
71 | /// that use the old ID will partially fail during loading.
72 | ///
73 | public override Guid ComponentGuid
74 | {
75 | get { return new Guid("{8D35230C-B9CD-479D-AAD6-F579E4BEB5F1}"); }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/SlurGH/Components/Mesh/MeshExtrude.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using Rhino.Geometry;
8 | using Grasshopper.Kernel;
9 | using Grasshopper.Kernel.Types;
10 | using SpatialSlur.Rhino;
11 |
12 | using Vec3d = Rhino.Geometry.Vector3d;
13 |
14 | namespace SpatialSlur.Grasshopper.Components
15 | {
16 | ///
17 | ///
18 | ///
19 | public class MeshExtrude : GH_Component
20 | {
21 | ///
22 | ///
23 | ///
24 | public MeshExtrude()
25 | : base("Mesh Extrude", "Extrude",
26 | "Extrudes a mesh from a polyline",
27 | "Mesh", "Util")
28 | {
29 | }
30 |
31 |
32 | ///
33 | protected override void RegisterInputParams(GH_InputParamManager pManager)
34 | {
35 | pManager.AddCurveParameter("polyline", "poly", "", GH_ParamAccess.item);
36 | pManager.AddVectorParameter("direction", "dir", "", GH_ParamAccess.item, Vec3d.Zero);
37 | }
38 |
39 |
40 | ///
41 | protected override void RegisterOutputParams(GH_OutputParamManager pManager)
42 | {
43 | pManager.AddMeshParameter("result", "result", "Extruded mesh", GH_ParamAccess.item);
44 | }
45 |
46 |
47 | ///
48 | protected override void SolveInstance(IGH_DataAccess DA)
49 | {
50 | Curve crv = null;
51 | var dir = new Vec3d();
52 |
53 | if (!DA.GetData(0, ref crv)) return;
54 | if (!DA.GetData(1, ref dir)) return;
55 |
56 | Polyline poly;
57 |
58 | if (!crv.TryGetPolyline(out poly))
59 | throw new ArgumentException();
60 |
61 | var mesh = RhinoFactory.Mesh.CreateExtrusion(poly, dir);
62 | DA.SetData(0, new GH_Mesh(mesh));
63 | }
64 |
65 |
66 | ///
67 | /// Provides an Icon for every component that will be visible in the User Interface.
68 | /// Icons need to be 24x24 pixels.
69 | ///
70 | protected override System.Drawing.Bitmap Icon
71 | {
72 | get { return null; }
73 | }
74 |
75 |
76 | ///
77 | /// Each component must have a unique Guid to identify it.
78 | /// It is vital this Guid doesn't change otherwise old ghx files
79 | /// that use the old ID will partially fail during loading.
80 | ///
81 | public override Guid ComponentGuid
82 | {
83 | get { return new Guid("{7A0D856D-7C43-42D1-AEEC-BACDDA1881A4}"); }
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/SlurGH/Components/Mesh/MeshLoft.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using Rhino.Geometry;
9 | using Grasshopper.Kernel;
10 | using Grasshopper.Kernel.Types;
11 | using SpatialSlur.Rhino;
12 |
13 | namespace SpatialSlur.Grasshopper.Components
14 | {
15 | ///
16 | ///
17 | ///
18 | public class MeshLoft : GH_Component
19 | {
20 | ///
21 | ///
22 | ///
23 | public MeshLoft()
24 | : base("Mesh Loft", "Loft",
25 | "Creates a mesh through a list of polylines",
26 | "Mesh", "Util")
27 | {
28 | }
29 |
30 |
31 | ///
32 | protected override void RegisterInputParams(GH_InputParamManager pManager)
33 | {
34 | pManager.AddCurveParameter("polylines", "polys", "", GH_ParamAccess.list);
35 | }
36 |
37 |
38 | ///
39 | protected override void RegisterOutputParams(GH_OutputParamManager pManager)
40 | {
41 | pManager.AddMeshParameter("result", "result", "Lofted mesh", GH_ParamAccess.item);
42 | }
43 |
44 |
45 | ///
46 | protected override void SolveInstance(IGH_DataAccess DA)
47 | {
48 | List curves = new List();
49 |
50 | if (!DA.GetDataList(0, curves)) return;
51 |
52 | var polys = curves.ConvertAll(crv =>
53 | {
54 | if (!crv.TryGetPolyline(out Polyline poly))
55 | throw new ArgumentException();
56 |
57 | return poly;
58 | });
59 |
60 | var mesh = RhinoFactory.Mesh.CreateLoft(polys);
61 |
62 | DA.SetData(0, new GH_Mesh(mesh));
63 | }
64 |
65 |
66 | ///
67 | /// Provides an Icon for every component that will be visible in the User Interface.
68 | /// Icons need to be 24x24 pixels.
69 | ///
70 | protected override System.Drawing.Bitmap Icon
71 | {
72 | get { return null; }
73 | }
74 |
75 |
76 | ///
77 | /// Each component must have a unique Guid to identify it.
78 | /// It is vital this Guid doesn't change otherwise old ghx files
79 | /// that use the old ID will partially fail during loading.
80 | ///
81 | public override Guid ComponentGuid
82 | {
83 | get { return new Guid("{BCFCF1AE-046B-4164-AF5A-12E5EE9F71CD}"); }
84 | }
85 | }
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/SlurGH/Components/Mesh/MeshLoftPair.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using Grasshopper.Kernel;
8 | using Grasshopper.Kernel.Types;
9 | using Rhino.Geometry;
10 | using SpatialSlur.Rhino;
11 |
12 | namespace SpatialSlur.Grasshopper.Components
13 | {
14 | ///
15 | ///
16 | ///
17 | public class MeshLoftPair : GH_Component
18 | {
19 | ///
20 | ///
21 | ///
22 | public MeshLoftPair()
23 | : base("Mesh Loft Pair", "LoftPair",
24 | "Creates a mesh between a pair of polylines",
25 | "Mesh", "Util")
26 | {
27 | }
28 |
29 |
30 | ///
31 | protected override void RegisterInputParams(GH_InputParamManager pManager)
32 | {
33 | pManager.AddCurveParameter("polylineA", "polyA", "", GH_ParamAccess.item);
34 | pManager.AddCurveParameter("polylineB", "polyB", "", GH_ParamAccess.item);
35 | }
36 |
37 |
38 | ///
39 | protected override void RegisterOutputParams(GH_OutputParamManager pManager)
40 | {
41 | pManager.AddMeshParameter("result", "result", "Lofted mesh", GH_ParamAccess.item);
42 | }
43 |
44 |
45 | ///
46 | protected override void SolveInstance(IGH_DataAccess DA)
47 | {
48 | Curve crvA = null;
49 | Curve crvB = null;
50 |
51 | if (!DA.GetData(0, ref crvA)) return;
52 | if (!DA.GetData(1, ref crvB)) return;
53 |
54 | if (!crvA.TryGetPolyline(out Polyline polyA))
55 | throw new ArgumentException();
56 |
57 | if (!crvB.TryGetPolyline(out Polyline polyB))
58 | throw new ArgumentException();
59 |
60 | var mesh = RhinoFactory.Mesh.CreateLoft(polyA, polyB);
61 |
62 | DA.SetData(0, new GH_Mesh(mesh));
63 | }
64 |
65 |
66 | ///
67 | /// Provides an Icon for every component that will be visible in the User Interface.
68 | /// Icons need to be 24x24 pixels.
69 | ///
70 | protected override System.Drawing.Bitmap Icon
71 | {
72 | get { return null; }
73 | }
74 |
75 |
76 | ///
77 | /// Each component must have a unique Guid to identify it.
78 | /// It is vital this Guid doesn't change otherwise old ghx files
79 | /// that use the old ID will partially fail during loading.
80 | ///
81 | public override Guid ComponentGuid
82 | {
83 | get { return new Guid("{C8AA832B-3A0C-4CF8-A63A-65414619BDF8}"); }
84 | }
85 | }
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/SlurGH/Components/Mesh/MeshSeparate.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using Rhino.Geometry;
8 | using Grasshopper.Kernel;
9 | using Grasshopper.Kernel.Types;
10 | using SpatialSlur.Rhino;
11 |
12 | namespace SpatialSlur.Grasshopper.Components
13 | {
14 | ///
15 | ///
16 | ///
17 | public class MeshSeparate : GH_Component
18 | {
19 | ///
20 | ///
21 | ///
22 | public MeshSeparate()
23 | : base("Mesh Separate", "Separate",
24 | "Separates all faces in a given mesh",
25 | "Mesh", "Util")
26 | {
27 | }
28 |
29 |
30 | ///
31 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
32 | {
33 | pManager.AddMeshParameter("mesh", "mesh", "Mesh to separate", GH_ParamAccess.item);
34 | }
35 |
36 |
37 | ///
38 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
39 | {
40 | pManager.AddMeshParameter("result", "result", "Separated mesh", GH_ParamAccess.item);
41 | }
42 |
43 |
44 | ///
45 | protected override void SolveInstance(IGH_DataAccess DA)
46 | {
47 | Mesh mesh = null;
48 | if (!DA.GetData(0, ref mesh)) return;
49 |
50 | mesh = mesh.ToPolySoup();
51 |
52 | DA.SetData(0, new GH_Mesh(mesh));
53 | }
54 |
55 |
56 | ///
57 | /// Provides an Icon for every component that will be visible in the User Interface.
58 | /// Icons need to be 24x24 pixels.
59 | ///
60 | protected override System.Drawing.Bitmap Icon
61 | {
62 | get { return null; }
63 | }
64 |
65 |
66 | ///
67 | /// Each component must have a unique Guid to identify it.
68 | /// It is vital this Guid doesn't change otherwise old ghx files
69 | /// that use the old ID will partially fail during loading.
70 | ///
71 | public override Guid ComponentGuid
72 | {
73 | get { return new Guid("{29FE6C46-B4B0-4BEE-95D6-549001490DE5}"); }
74 | }
75 | }
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/SlurGH/Components/SpatialSlur/Meshes/FacePlanarity.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Linq;
8 |
9 | using Grasshopper.Kernel;
10 |
11 | using SpatialSlur.Meshes;
12 | using SpatialSlur.Grasshopper.Types;
13 | using SpatialSlur.Grasshopper.Params;
14 |
15 | namespace SlurGH.Components
16 | {
17 | ///
18 | ///
19 | ///
20 | public class FacePlanarity : GH_Component
21 | {
22 | ///
23 | ///
24 | ///
25 | public FacePlanarity()
26 | : base("Face Planarity", "FacePln",
27 | "Returns the planar deviation of each face in a halfedge mesh.",
28 | "SpatialSlur", "Mesh")
29 | {
30 | }
31 |
32 |
33 | ///
34 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
35 | {
36 | pManager.AddParameter(new HeMesh3dParam(), "heMesh", "heMesh", "", GH_ParamAccess.item);
37 | }
38 |
39 |
40 | ///
41 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
42 | {
43 | pManager.AddNumberParameter("result", "result", "", GH_ParamAccess.list);
44 | }
45 |
46 |
47 | ///
48 | protected override void SolveInstance(IGH_DataAccess DA)
49 | {
50 | GH_HeMesh3d mesh = null;
51 | if (!DA.GetData(0, ref mesh)) return;
52 |
53 | var result = mesh.Value.Faces.Select(f => f.IsUnused ? 0.0 : f.GetPlanarity(v => v.Position));
54 | DA.SetDataList(0, result);
55 | }
56 |
57 |
58 | ///
59 | /// Provides an Icon for every component that will be visible in the User Interface.
60 | /// Icons need to be 24x24 pixels.
61 | ///
62 | protected override System.Drawing.Bitmap Icon
63 | {
64 | get { return null; }
65 | }
66 |
67 |
68 | ///
69 | /// Each component must have a unique Guid to identify it.
70 | /// It is vital this Guid doesn't change otherwise old ghx files
71 | /// that use the old ID will partially fail during loading.
72 | ///
73 | public override Guid ComponentGuid
74 | {
75 | get { return new Guid("{85A0F167-8DCD-4397-848F-93482E6708D7}"); }
76 | }
77 | }
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/SlurGH/Components/SpatialSlur/Meshes/FacePolylines.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Linq;
8 |
9 | using Grasshopper.Kernel;
10 | using Grasshopper.Kernel.Types;
11 | using Rhino.Geometry;
12 |
13 | using SpatialSlur.Grasshopper.Types;
14 | using SpatialSlur.Grasshopper.Params;
15 |
16 | namespace SlurGH.Components
17 | {
18 | ///
19 | ///
20 | ///
21 | public class FacePolylines : GH_Component
22 | {
23 | ///
24 | ///
25 | ///
26 | public FacePolylines()
27 | : base("Face Polylines", "FacePolys",
28 | "Returns the boundary of each face in a given halfedge mesh as a closed polyline",
29 | "SpatialSlur", "Mesh")
30 | {
31 | }
32 |
33 |
34 | ///
35 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
36 | {
37 | pManager.AddParameter(new HeMesh3dParam(), "heMesh", "heMesh", "", GH_ParamAccess.item);
38 | }
39 |
40 |
41 | ///
42 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
43 | {
44 | pManager.AddCurveParameter("result", "result", "", GH_ParamAccess.list);
45 | }
46 |
47 |
48 | ///
49 | protected override void SolveInstance(IGH_DataAccess DA)
50 | {
51 | GH_HeMesh3d mesh = null;
52 | if (!DA.GetData(0, ref mesh)) return;
53 |
54 | var result = mesh.Value.Faces.Select(f =>
55 | {
56 | if (f.IsUnused) return new GH_Curve();
57 |
58 | var poly = new Polyline(f.Halfedges.Select(he => (Point3d)he.Start.Position));
59 | poly.Add(poly[0]);
60 |
61 | return new GH_Curve(poly.ToNurbsCurve());
62 | });
63 |
64 | DA.SetDataList(0, result);
65 | }
66 |
67 |
68 | ///
69 | /// Provides an Icon for every component that will be visible in the User Interface.
70 | /// Icons need to be 24x24 pixels.
71 | ///
72 | protected override System.Drawing.Bitmap Icon
73 | {
74 | get { return null; }
75 | }
76 |
77 |
78 | ///
79 | /// Each component must have a unique Guid to identify it.
80 | /// It is vital this Guid doesn't change otherwise old ghx files
81 | /// that use the old ID will partially fail during loading.
82 | ///
83 | public override Guid ComponentGuid
84 | {
85 | get { return new Guid("{BD140500-B9EA-43EE-94B9-358BEACF803C}"); }
86 | }
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/SlurGH/Components/SpatialSlur/Meshes/HeMeshFromPolylines.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 |
10 | using Rhino.Geometry;
11 | using Grasshopper.Kernel;
12 | using Grasshopper.Kernel.Types;
13 |
14 | using SpatialSlur.Meshes;
15 | using SpatialSlur.Rhino;
16 | using SpatialSlur.Grasshopper.Types;
17 | using SpatialSlur.Grasshopper.Params;
18 |
19 | namespace SpatialSlur.Grasshopper.Components
20 | {
21 | ///
22 | ///
23 | ///
24 | public class HeMeshFromPolylines : GH_Component
25 | {
26 | ///
27 | ///
28 | ///
29 | public HeMeshFromPolylines()
30 | : base("HeMesh From Polylines", "FromPolys",
31 | "Creates a halfedge mesh from a list of closed polylines",
32 | "SpatialSlur", "Mesh")
33 | {
34 | }
35 |
36 |
37 | ///
38 | protected override void RegisterInputParams(GH_InputParamManager pManager)
39 | {
40 | pManager.AddCurveParameter("polylines", "polys", "", GH_ParamAccess.list);
41 | pManager.AddNumberParameter("tolerance", "tol", "", GH_ParamAccess.item, 1.0e-4);
42 | }
43 |
44 |
45 | ///
46 | protected override void RegisterOutputParams(GH_OutputParamManager pManager)
47 | {
48 | pManager.AddParameter(new HeMesh3dParam(), "result", "result", "", GH_ParamAccess.item);
49 | }
50 |
51 |
52 | ///
53 | protected override void SolveInstance(IGH_DataAccess DA)
54 | {
55 | var curves = new List();
56 | if (!DA.GetDataList(0, curves)) return;
57 |
58 | var tol = 0.0;
59 | if (!DA.GetData(1, ref tol)) return;
60 |
61 | var mesh = HeMesh3d.Factory.CreateFromPolylines(curves.Select(crv =>
62 | {
63 | crv.Value.TryGetPolyline(out Polyline poly);
64 | return poly;
65 | }), tol);
66 |
67 | DA.SetData(0, new GH_HeMesh3d(mesh));
68 | }
69 |
70 |
71 | ///
72 | /// Provides an Icon for every component that will be visible in the User Interface.
73 | /// Icons need to be 24x24 pixels.
74 | ///
75 | protected override System.Drawing.Bitmap Icon
76 | {
77 | get { return null; }
78 | }
79 |
80 |
81 | ///
82 | /// Each component must have a unique Guid to identify it.
83 | /// It is vital this Guid doesn't change otherwise old ghx files
84 | /// that use the old ID will partially fail during loading.
85 | ///
86 | public override Guid ComponentGuid
87 | {
88 | get { return new Guid("{2A36DB93-46BB-419C-810B-98B67D88BEDB}"); }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/SlurGH/Components/SpatialSlur/Meshes/HoleBoundaries.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Linq;
8 |
9 | using Grasshopper.Kernel;
10 | using Grasshopper.Kernel.Types;
11 | using Rhino.Geometry;
12 |
13 | using SpatialSlur.Grasshopper.Types;
14 | using SpatialSlur.Grasshopper.Params;
15 |
16 | namespace SlurGH.Components
17 | {
18 | ///
19 | ///
20 | ///
21 | public class HoleBoundaries : GH_Component
22 | {
23 | ///
24 | ///
25 | ///
26 | public HoleBoundaries()
27 | : base("Hole Boundaries", "HoleBnds",
28 | "Returns the boundary of each hole in a given halfedge mesh as a closed polyline",
29 | "SpatialSlur", "Mesh")
30 | {
31 | }
32 |
33 |
34 | ///
35 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
36 | {
37 | pManager.AddParameter(new HeMesh3dParam(), "heMesh", "heMesh", "Halfedge structure to extract from", GH_ParamAccess.item);
38 | }
39 |
40 |
41 | ///
42 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
43 | {
44 | pManager.AddCurveParameter("result", "result", "Face polylines", GH_ParamAccess.list);
45 | }
46 |
47 |
48 | ///
49 | protected override void SolveInstance(IGH_DataAccess DA)
50 | {
51 | GH_HeMesh3d mesh = null;
52 | if (!DA.GetData(0, ref mesh)) return;
53 |
54 | var result = mesh.Value.GetHoles().Select(he0 =>
55 | {
56 | var poly = new Polyline(he0.Circulate.Select(he => (Point3d)he.Start.Position));
57 | poly.Add(poly[0]);
58 |
59 | return new GH_Curve(poly.ToNurbsCurve());
60 | });
61 |
62 | DA.SetDataList(0, result);
63 | }
64 |
65 |
66 | ///
67 | /// Provides an Icon for every component that will be visible in the User Interface.
68 | /// Icons need to be 24x24 pixels.
69 | ///
70 | protected override System.Drawing.Bitmap Icon
71 | {
72 | get { return null; }
73 | }
74 |
75 |
76 | ///
77 | /// Each component must have a unique Guid to identify it.
78 | /// It is vital this Guid doesn't change otherwise old ghx files
79 | /// that use the old ID will partially fail during loading.
80 | ///
81 | public override Guid ComponentGuid
82 | {
83 | get { return new Guid("{0B107055-DE31-467B-9762-C0F44430A2FF}"); }
84 | }
85 | }
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/SlurGH/Components/SpatialSlur/Meshes/VertexPositions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Linq;
8 |
9 | using Grasshopper.Kernel;
10 | using Grasshopper.Kernel.Types;
11 | using SpatialSlur.Meshes;
12 |
13 | namespace SpatialSlur.Grasshopper.Components
14 | {
15 | ///
16 | ///
17 | ///
18 | public class VertexPositions : GH_Component
19 | {
20 | ///
21 | ///
22 | ///
23 | public VertexPositions()
24 | : base("Vertex Positions", "VertPos",
25 | "Returns the position of each vertex in a halfedge graph.",
26 | "SpatialSlur", "Mesh")
27 | {
28 | }
29 |
30 |
31 | ///
32 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
33 | {
34 | pManager.AddGenericParameter("heGraph", "heGraph", "", GH_ParamAccess.item);
35 | }
36 |
37 |
38 | ///
39 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
40 | {
41 | pManager.AddPointParameter("result", "result", "Vertex positions", GH_ParamAccess.list);
42 | }
43 |
44 |
45 | ///
46 | protected override void SolveInstance(IGH_DataAccess DA)
47 | {
48 | GH_ObjectWrapper goo = null;
49 | if (!DA.GetData(0, ref goo)) return;
50 |
51 | var obj = goo.Value;
52 |
53 | if (obj is HeGraph3d)
54 | {
55 | var graph = (HeGraph3d)obj;
56 | DA.SetDataList(0, graph.Vertices.Select(v => new GH_Point(v.Position)));
57 | }
58 | else if (obj is HeMesh3d)
59 | {
60 | var mesh = (HeMesh3d)obj;
61 | DA.SetDataList(0, mesh.Vertices.Select(v => new GH_Point(v.Position)));
62 | }
63 | }
64 |
65 |
66 | ///
67 | /// Provides an Icon for every component that will be visible in the User Interface.
68 | /// Icons need to be 24x24 pixels.
69 | ///
70 | protected override System.Drawing.Bitmap Icon
71 | {
72 | get { return null; }
73 | }
74 |
75 |
76 | ///
77 | /// Each component must have a unique Guid to identify it.
78 | /// It is vital this Guid doesn't change otherwise old ghx files
79 | /// that use the old ID will partially fail during loading.
80 | ///
81 | public override Guid ComponentGuid
82 | {
83 | get { return new Guid("{F39B5887-09E7-4D40-B0C6-CA69073936B1}"); }
84 | }
85 | }
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/SlurGH/Components/SpatialSlur/Tools/CreateFeature.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using Rhino.Geometry;
8 | using Grasshopper.Kernel;
9 | using Grasshopper.Kernel.Types;
10 | using SpatialSlur.Tools;
11 |
12 | namespace SpatialSlur.Grasshopper.Components
13 | {
14 | ///
15 | ///
16 | ///
17 | public class CreateFeature : GH_Component
18 | {
19 | ///
20 | ///
21 | ///
22 | public CreateFeature()
23 | : base("Creates Features", "Feature",
24 | "Creates a geometric feature used for dynamic remeshing",
25 | "SpatialSlur", "Mesh")
26 | {
27 | }
28 |
29 |
30 | ///
31 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
32 | {
33 | pManager.AddGenericParameter("geometry", "geom", "", GH_ParamAccess.item);
34 | }
35 |
36 |
37 | ///
38 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
39 | {
40 | pManager.AddGenericParameter("result", "result", "", GH_ParamAccess.item);
41 | }
42 |
43 |
44 | ///
45 | protected override void SolveInstance(IGH_DataAccess DA)
46 | {
47 | GH_ObjectWrapper goo = null;
48 | if (!DA.GetData(0, ref goo)) return;
49 |
50 | IFeature feat = null;
51 |
52 | switch (goo.Value)
53 | {
54 | case Mesh m:
55 | feat = new MeshFeature(m);
56 | break;
57 | case Curve c:
58 | feat = new CurveFeature(c);
59 | break;
60 | case Point3d p:
61 | feat = new PointFeature(p);
62 | break;
63 | default:
64 | throw new ArgumentException();
65 | }
66 |
67 | DA.SetData(0, new GH_ObjectWrapper(feat));
68 | }
69 |
70 |
71 | ///
72 | /// Provides an Icon for every component that will be visible in the User Interface.
73 | /// Icons need to be 24x24 pixels.
74 | ///
75 | protected override System.Drawing.Bitmap Icon
76 | {
77 | get { return null; }
78 | }
79 |
80 |
81 | ///
82 | /// Each component must have a unique Guid to identify it.
83 | /// It is vital this Guid doesn't change otherwise old ghx files
84 | /// that use the old ID will partially fail during loading.
85 | ///
86 | public override Guid ComponentGuid
87 | {
88 | get { return new Guid("{0FEF2BE4-6432-4352-ADE2-F160108EDA12}"); }
89 | }
90 | }
91 | }
92 |
93 |
--------------------------------------------------------------------------------
/SlurGH/Params/SpatialSlur/HeGraph3dParam.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using Grasshopper.Kernel;
5 |
6 | using SpatialSlur.Grasshopper.Types;
7 |
8 | /*
9 | * Notes
10 | */
11 |
12 | namespace SpatialSlur.Grasshopper.Params
13 | {
14 | ///
15 | ///
16 | ///
17 | public class HeGraph3dParam : GH_PersistentParam
18 | {
19 | ///
20 | ///
21 | ///
22 | public HeGraph3dParam()
23 | :base("HeGraph", "HeGraph", "", "SpatialSlur", "Parameters")
24 | {
25 | }
26 |
27 |
28 | ///
29 | public override GH_Exposure Exposure
30 | {
31 | get { return GH_Exposure.primary; }
32 | }
33 |
34 |
35 | ///
36 | protected override Bitmap Icon
37 | {
38 | get { return null; }
39 | }
40 |
41 |
42 | ///
43 | public override Guid ComponentGuid
44 | {
45 | get { return new Guid("{E173CB1B-FBE2-4F71-89A2-D520C6AF6A7F}"); }
46 | }
47 |
48 |
49 | ///
50 | protected override GH_GetterResult Prompt_Singular(ref GH_HeGraph3d value)
51 | {
52 | value = new GH_HeGraph3d();
53 | return GH_GetterResult.success;
54 | }
55 |
56 |
57 | ///
58 | protected override GH_GetterResult Prompt_Plural(ref List values)
59 | {
60 | values = new List();
61 | return GH_GetterResult.success;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/SlurGH/Params/SpatialSlur/HeMesh3dParam.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using Grasshopper.Kernel;
5 |
6 | using SpatialSlur.Grasshopper.Types;
7 |
8 | /*
9 | * Notes
10 | */
11 |
12 | namespace SpatialSlur.Grasshopper.Params
13 | {
14 | ///
15 | ///
16 | ///
17 | public class HeMesh3dParam : GH_PersistentParam
18 | {
19 | ///
20 | ///
21 | ///
22 | public HeMesh3dParam()
23 | :base("HeMesh", "HeMesh", "", "SpatialSlur", "Parameters")
24 | {
25 | }
26 |
27 |
28 | ///
29 | public override GH_Exposure Exposure
30 | {
31 | get { return GH_Exposure.primary; }
32 | }
33 |
34 |
35 | ///
36 | protected override Bitmap Icon
37 | {
38 | get { return null; }
39 | }
40 |
41 |
42 | ///
43 | public override Guid ComponentGuid
44 | {
45 | get { return new Guid("{AEEA983D-0B68-44F0-B908-C5B3FCB09C13}"); }
46 | }
47 |
48 |
49 | ///
50 | protected override GH_GetterResult Prompt_Singular(ref GH_HeMesh3d value)
51 | {
52 | value = new GH_HeMesh3d();
53 | return GH_GetterResult.success;
54 | }
55 |
56 |
57 | ///
58 | protected override GH_GetterResult Prompt_Plural(ref List values)
59 | {
60 | values = new List();
61 | return GH_GetterResult.success;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/SlurGH/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("SlurGH")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("David Reeves")]
11 | [assembly: AssemblyProduct("SlurGH")]
12 | [assembly: AssemblyCopyright("Copyright © David Reeves 2017")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("bc254a97-352c-41d5-bebe-cf792abe454d")] // This will also be the Guid of the Rhino plug-in
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion(SpatialSlur.AssemblyInfo.VersionNumber)]
--------------------------------------------------------------------------------
/SlurGH/SlurGHInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using Grasshopper.Kernel;
4 |
5 | namespace SpatialSlur.Grasshopper
6 | {
7 | ///
8 | ///
9 | ///
10 | public class SlurGHInfo : GH_AssemblyInfo
11 | {
12 | private const string _version = "0.3.0";
13 |
14 |
15 | ///
16 | public override string Name
17 | {
18 | get { return "SpatialSlur.SlurGH"; }
19 | }
20 |
21 |
22 | ///
23 | public override Bitmap Icon
24 | {
25 | get { return null; }
26 | }
27 |
28 |
29 | ///
30 | public override string Description
31 | {
32 | get { return ""; }
33 | }
34 |
35 |
36 | ///
37 | public override Guid Id
38 | {
39 | get { return new Guid("8546948e-7b1e-4e42-beb9-a924be0b7964"); }
40 | }
41 |
42 |
43 | ///
44 | public override string AuthorName
45 | {
46 | get { return "David Reeves"; }
47 | }
48 |
49 |
50 | ///
51 | public override string AuthorContact
52 | {
53 | get { return "http://spatialslur.com/contact/"; }
54 | }
55 |
56 |
57 | ///
58 | public override string AssemblyVersion
59 | {
60 | get => _version;
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/SpatialSlur/Collections/Extensions/ArrayViewExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 |
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur
12 | {
13 | ///
14 | ///
15 | ///
16 | public static partial class ArrayViewExtensions
17 | {
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | ///
27 | public static void Convert(this ArrayView source, Func converter, ArrayView result, bool parallel = false)
28 | {
29 | ReadOnlyArrayViewExtensions.Convert(source, converter, result, parallel);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/SpatialSlur/Collections/Extensions/IDictionaryExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | /*
4 | * Notes
5 | */
6 |
7 | namespace SpatialSlur
8 | {
9 | ///
10 | ///
11 | ///
12 | public static class IDictionaryExtensions
13 | {
14 | ///
15 | /// Assigns the contents of another dictionary to this one.
16 | ///
17 | ///
18 | ///
19 | ///
20 | ///
21 | public static void Set(this IDictionary source, IDictionary other)
22 | {
23 | foreach (var pair in other)
24 | source[pair.Key] = pair.Value;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SpatialSlur/Collections/Extensions/ReadOnlyArrayViewExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Concurrent;
8 | using System.Threading.Tasks;
9 |
10 | using SpatialSlur.Collections;
11 |
12 | namespace SpatialSlur
13 | {
14 | ///
15 | ///
16 | ///
17 | public static partial class ReadOnlyArrayViewExtensions
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | ///
27 | ///
28 | public static void Convert(this ReadOnlyArrayView source, Func converter, ArrayView result, bool parallel = false)
29 | {
30 | if (parallel)
31 | {
32 | Parallel.ForEach(Partitioner.Create(0, source.Count), range =>
33 | {
34 | for (int i = range.Item1; i < range.Item2; i++)
35 | result[i] = converter(source[i]);
36 | });
37 | }
38 | else
39 | {
40 | for (int i = 0; i < source.Count; i++)
41 | result[i] = converter(source[i]);
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/SpatialSlur/Collections/ReadOnlySet.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections;
8 | using System.Collections.Generic;
9 |
10 | namespace SpatialSlur.Collections
11 | {
12 | ///
13 | ///
14 | ///
15 | ///
16 | public struct ReadOnlySet : IEnumerable
17 | {
18 | #region Static Members
19 |
20 | ///
21 | ///
22 | ///
23 | ///
24 | public static implicit operator ReadOnlySet(HashSet source)
25 | {
26 | return new ReadOnlySet(source);
27 | }
28 |
29 | #endregion
30 |
31 |
32 | private HashSet _source;
33 |
34 |
35 | ///
36 | ///
37 | ///
38 | ///
39 | public ReadOnlySet(HashSet source)
40 | {
41 | _source = source;
42 | }
43 |
44 |
45 | ///
46 | ///
47 | ///
48 | public int Count
49 | {
50 | get { return _source.Count; }
51 | }
52 |
53 |
54 | ///
55 | ///
56 | ///
57 | public bool HasSource
58 | {
59 | get => _source != null;
60 | }
61 |
62 |
63 | ///
64 | ///
65 | ///
66 | ///
67 | ///
68 | public bool Contains(T item)
69 | {
70 | return _source.Contains(item);
71 | }
72 |
73 |
74 | ///
75 | ///
76 | ///
77 | ///
78 | public HashSet.Enumerator GetEnumerator()
79 | {
80 | return _source.GetEnumerator();
81 | }
82 |
83 |
84 | #region Explicit Interface Implementations
85 |
86 | IEnumerator IEnumerable.GetEnumerator()
87 | {
88 | return GetEnumerator();
89 | }
90 |
91 |
92 | IEnumerator IEnumerable.GetEnumerator()
93 | {
94 | return GetEnumerator();
95 | }
96 |
97 | #endregion
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/SpatialSlur/Collections/Sequences.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 |
9 | namespace SpatialSlur.Collections
10 | {
11 | ///
12 | ///
13 | ///
14 | public static class Sequences
15 | {
16 | ///
17 | ///
18 | ///
19 | ///
20 | ///
21 | public static IEnumerable CountFrom(int start)
22 | {
23 | while (true)
24 | yield return start++;
25 | }
26 |
27 |
28 | ///
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public static IEnumerable CountFrom(int start, int stride)
35 | {
36 | while (true)
37 | {
38 | yield return start;
39 | start += stride;
40 | }
41 | }
42 |
43 |
44 | ///
45 | ///
46 | ///
47 | ///
48 | public static IEnumerable Fibonacci()
49 | {
50 | int n0 = 0;
51 | int n1 = 1;
52 |
53 | yield return n0;
54 | yield return n1;
55 |
56 | while (true)
57 | {
58 | int n2 = n0 + n1;
59 | yield return n2;
60 | n0 = n1;
61 | n1 = n2;
62 | }
63 | }
64 |
65 |
66 | ///
67 | ///
68 | ///
69 | ///
70 | ///
71 | ///
72 | public static IEnumerable> CountInBase(int digits, int radix)
73 | {
74 | var curr = new int[digits];
75 | var n = Pow(radix, digits);
76 |
77 | yield return curr;
78 |
79 | while (--n > 0L)
80 | {
81 | int i = 0;
82 |
83 | // increment
84 | curr[i]++;
85 |
86 | // carry
87 | while (curr[i] == radix)
88 | {
89 | curr[i++] = 0;
90 | curr[i]++;
91 | }
92 |
93 | yield return curr;
94 | }
95 |
96 | long Pow(long x, long y)
97 | {
98 | long result = 1;
99 |
100 | for (long i = 0; i < y; i++)
101 | result *= x;
102 |
103 | return result;
104 | }
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/SpatialSlur/Core/Atomic.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 |
5 | namespace SpatialSlur
6 | {
7 | ///
8 | /// Extends atomic operations from Interlocked class to SpatialSlur primitive types
9 | ///
10 | public static class Atomic
11 | {
12 | ///
13 | ///
14 | ///
15 | ///
16 | ///
17 | public static void Exchange(ref Vector2i v0, Vector2i v1)
18 | {
19 | Interlocked.Exchange(ref v0.X, v1.X);
20 | Interlocked.Exchange(ref v0.Y, v1.Y);
21 | }
22 |
23 |
24 | ///
25 | ///
26 | ///
27 | ///
28 | ///
29 | public static void Exchange(ref Vector2d v0, Vector2d v1)
30 | {
31 | Interlocked.Exchange(ref v0.X, v1.X);
32 | Interlocked.Exchange(ref v0.Y, v1.Y);
33 | }
34 |
35 |
36 | ///
37 | ///
38 | ///
39 | ///
40 | ///
41 | public static void Exchange(ref Vector3i v0, Vector3i v1)
42 | {
43 | Interlocked.Exchange(ref v0.X, v1.X);
44 | Interlocked.Exchange(ref v0.Y, v1.Y);
45 | Interlocked.Exchange(ref v0.Z, v1.Z);
46 | }
47 |
48 |
49 | ///
50 | ///
51 | ///
52 | ///
53 | ///
54 | public static void Exchange(ref Vector3f v0, Vector3f v1)
55 | {
56 | Interlocked.Exchange(ref v0.X, v1.X);
57 | Interlocked.Exchange(ref v0.Y, v1.Y);
58 | Interlocked.Exchange(ref v0.Z, v1.Z);
59 | }
60 |
61 |
62 | ///
63 | ///
64 | ///
65 | ///
66 | ///
67 | public static void Exchange(ref Vector3d v0, Vector3d v1)
68 | {
69 | Interlocked.Exchange(ref v0.X, v1.X);
70 | Interlocked.Exchange(ref v0.Y, v1.Y);
71 | Interlocked.Exchange(ref v0.Z, v1.Z);
72 | }
73 |
74 |
75 | ///
76 | ///
77 | ///
78 | ///
79 | ///
80 | public static void Exchange(ref Vector4d v0, Vector4d v1)
81 | {
82 | Interlocked.Exchange(ref v0.X, v1.X);
83 | Interlocked.Exchange(ref v0.Y, v1.Y);
84 | Interlocked.Exchange(ref v0.Z, v1.Z);
85 | Interlocked.Exchange(ref v0.W, v1.W);
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/SpatialSlur/Core/Extensions/ColorExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System.Drawing;
7 |
8 |
9 | namespace SpatialSlur
10 | {
11 | ///
12 | ///
13 | ///
14 | public static class ColorExtensions
15 | {
16 | ///
17 | ///
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | public static Color LerpTo(this Color c, Color other, double t)
24 | {
25 | int a = (int)(c.A + (other.A - c.A) * t);
26 | int r = (int)(c.R + (other.R - c.R) * t);
27 | int g = (int)(c.G + (other.G - c.G) * t);
28 | int b = (int)(c.B + (other.B - c.B) * t);
29 | return Color.FromArgb(a, r, g, b);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/SpatialSlur/Core/Extensions/GenericExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System.Collections.Generic;
7 |
8 | namespace SpatialSlur
9 | {
10 | ///
11 | ///
12 | ///
13 | public static class GenericExtensions
14 | {
15 | ///
16 | ///
17 | ///
18 | ///
19 | ///
20 | ///
21 | public static IEnumerable Yield(this T item)
22 | {
23 | yield return item;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SpatialSlur/Core/Matrix.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 |
12 | namespace SpatialSlur
13 | {
14 | ///
15 | ///
16 | ///
17 | public static partial class Matrix
18 | {
19 | ///
20 | /// Returns the entries of the covariance matrix in row-major order.
21 | ///
22 | ///
23 | ///
24 | public static void GetCovariance(IEnumerable vectors, double[] result)
25 | {
26 | var mean = new double[vectors.First().Length];
27 | vectors.Mean(mean);
28 | GetCovariance(vectors, mean, result);
29 | }
30 |
31 |
32 | ///
33 | /// Returns the entries of the covariance matrix in row-major order.
34 | ///
35 | ///
36 | ///
37 | ///
38 | public static void GetCovariance(IEnumerable vectors, double[] mean, double[] result)
39 | {
40 | int dim = mean.Length;
41 | int n = 0;
42 |
43 | Array.Clear(result, 0, dim * dim);
44 |
45 | // calculate uppper triangular values
46 | foreach (double[] v in vectors)
47 | {
48 | for (int i = 0; i < dim; i++)
49 | {
50 | double di = v[i] - mean[i];
51 |
52 | for (int j = i; j < dim; j++)
53 | result[i * dim + j] += di * (v[j] - mean[j]);
54 | }
55 |
56 | n++;
57 | }
58 |
59 | var t = 1.0 / n;
60 |
61 | // average and set lower triangular values
62 | for (int i = 0; i < dim; i++)
63 | {
64 | result[i * dim + i] *= t; // diagonal entry
65 |
66 | // lower triangular
67 | for (int j = i + 1; j < dim; j++)
68 | result[j * dim + i] = result[i * dim + j] *= t;
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/SpatialSlur/Core/Utilities.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Runtime.CompilerServices;
8 |
9 | namespace SpatialSlur
10 | {
11 | ///
12 | /// Static class for stray methods that don't yet fit anywhere else (boo).
13 | ///
14 | public static class Utilities
15 | {
16 | ///
17 | ///
18 | ///
19 | ///
20 | ///
21 | ///
22 | public static void Swap(ref U a, ref U b)
23 | {
24 | var c = a;
25 | a = b;
26 | b = c;
27 | }
28 |
29 |
30 | ///
31 | ///
32 | ///
33 | ///
34 | ///
35 | public static void BoundsCheck(int index, int count)
36 | {
37 | if ((uint)index >= (uint)count)
38 | throw new IndexOutOfRangeException();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Body.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | namespace SpatialSlur.Dynamics
9 | {
10 | ///
11 | ///
12 | ///
13 | [Serializable]
14 | public readonly struct Body
15 | {
16 | ///
17 | public readonly BodyPosition Position;
18 |
19 | ///
20 | public readonly BodyRotation Rotation;
21 |
22 |
23 | ///
24 | ///
25 | ///
26 | ///
27 | public Body(Vector3d position)
28 | {
29 | Position = new BodyPosition(position);
30 | Rotation = null;
31 | }
32 |
33 |
34 | ///
35 | ///
36 | ///
37 | ///
38 | ///
39 | public Body(Vector3d position, Quaterniond rotation)
40 | {
41 | Position = new BodyPosition(position);
42 | Rotation = new BodyRotation(rotation);
43 | }
44 |
45 |
46 | ///
47 | ///
48 | ///
49 | ///
50 | ///
51 | public Body(BodyPosition position, BodyRotation rotation)
52 | {
53 | Position = position;
54 | Rotation = rotation;
55 | }
56 |
57 |
58 | ///
59 | ///
60 | ///
61 | ///
62 | private Body(Body other)
63 | {
64 | Position = other.Position?.Duplicate();
65 | Rotation = other.Rotation?.Duplicate();
66 | }
67 |
68 |
69 | ///
70 | /// Returns a deep copy of this body.
71 | ///
72 | ///
73 | public Body Duplicate()
74 | {
75 | return new Body(this);
76 | }
77 |
78 |
79 | ///
80 | ///
81 | ///
82 | ///
83 | ///
84 | public void Deconstruct(out BodyPosition position, out BodyRotation rotation)
85 | {
86 | position = Position;
87 | rotation = Rotation;
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/ConstraintSolverSettings.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | namespace SpatialSlur.Dynamics
9 | {
10 | ///
11 | ///
12 | ///
13 | [Serializable]
14 | public class ConstraintSolverSettings
15 | {
16 | private double _linearDamping = 0.1;
17 | private double _angularDamping = 0.1;
18 |
19 | private double _linearTolerance = 1.0e-4;
20 | private double _angularTolerance = 1.0e-4;
21 |
22 | private double _timeStep = 1.0;
23 |
24 |
25 | ///
26 | ///
27 | ///
28 | public double LinearDamping
29 | {
30 | get { return _linearDamping; }
31 | set
32 | {
33 | if (value < 0.0 || value > 1.0)
34 | throw new ArgumentOutOfRangeException("The value must be between 0.0 and 1.0.");
35 |
36 | _linearDamping = value;
37 | }
38 | }
39 |
40 |
41 | ///
42 | ///
43 | ///
44 | public double AngularDamping
45 | {
46 | get { return _angularDamping; }
47 | set
48 | {
49 | if (value < 0.0 || value > 1.0)
50 | throw new ArgumentOutOfRangeException("The value must be between 0.0 and 1.0.");
51 |
52 | _angularDamping = value;
53 | }
54 | }
55 |
56 |
57 | ///
58 | ///
59 | ///
60 | public double LinearTolerance
61 | {
62 | get { return _linearTolerance; }
63 | set
64 | {
65 | if (value < 0.0)
66 | throw new ArgumentOutOfRangeException("The value cannot be negative.");
67 |
68 | _linearTolerance = value;
69 | }
70 | }
71 |
72 |
73 | ///
74 | ///
75 | ///
76 | public double AngularTolerance
77 | {
78 | get { return _angularTolerance; }
79 | set
80 | {
81 | if (value < 0.0)
82 | throw new ArgumentOutOfRangeException("The value cannot be negative.");
83 |
84 | _angularTolerance = value;
85 | }
86 | }
87 |
88 |
89 | ///
90 | ///
91 | ///
92 | public double TimeStep
93 | {
94 | get { return _timeStep; }
95 | set
96 | {
97 | if (value < 0.0)
98 | throw new ArgumentOutOfRangeException("The value cannot be negative.");
99 |
100 | _timeStep = value;
101 | }
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/Cocircular.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class Cocircular : PositionGroup
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | public Cocircular(double weight = 1.0)
24 | : base(weight)
25 | {
26 | }
27 |
28 |
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public Cocircular(IEnumerable indices, double weight = 1.0)
35 | : base(indices, weight)
36 | {
37 | }
38 |
39 |
40 | ///
41 | protected override bool Calculate(ReadOnlyArrayView bodies, ReadOnlyArrayView indices, ArrayView deltas)
42 | {
43 | int n = indices.Count;
44 |
45 | if (n < 4 || !Geometry.FitCircleToPoints(Indices.Select(i => bodies[i].Position.Current), out Vector3d p, out Vector3d z, out double r))
46 | {
47 | deltas.Clear();
48 | return false;
49 | }
50 |
51 | for (int i = 0; i < n; i++)
52 | {
53 | var d = Vector3d.Project(p - bodies[indices[i]].Position.Current, z);
54 | deltas[i] = d * (1.0 - r / d.Length);
55 | }
56 |
57 | return true;
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/Coincident.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class Coincident : PositionGroup
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | public Coincident(double weight = 1.0)
24 | : base(weight)
25 | {
26 | }
27 |
28 |
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public Coincident(IEnumerable indices, double weight = 1.0)
35 | : base(indices, weight)
36 | {
37 | }
38 |
39 |
40 | ///
41 | protected override bool Calculate(ReadOnlyArrayView bodies, ReadOnlyArrayView indices, ArrayView deltas)
42 | {
43 | int n = indices.Count;
44 |
45 | if(n < 2)
46 | {
47 | deltas.Clear();
48 | return false;
49 | }
50 |
51 | var p = Indices.Select(i => bodies[i].Position.Current).Mean();
52 |
53 | for (int i = 0; i < n; i++)
54 | deltas[i] = p - bodies[indices[i]].Position.Current;
55 |
56 | return true;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/Colinear.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class Colinear : PositionGroup
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | public Colinear(double weight = 1.0)
24 | : base(weight)
25 | {
26 | }
27 |
28 |
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public Colinear(IEnumerable indices, double weight = 1.0)
35 | : base(indices, weight)
36 | {
37 | }
38 |
39 |
40 | ///
41 | protected override bool Calculate(ReadOnlyArrayView bodies, ReadOnlyArrayView indices, ArrayView deltas)
42 | {
43 | int n = indices.Count;
44 |
45 | if(n < 3 || !Geometry.FitLineToPoints(Indices.Select(i => bodies[i].Position.Current), out Vector3d p, out Vector3d d))
46 | {
47 | deltas.Clear();
48 | return false;
49 | }
50 |
51 | for (int i = 0; i < n; i++)
52 | deltas[i] = Vector3d.Reject(p - bodies[indices[i]].Position.Current, d);
53 |
54 | return true;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/Constraint.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | namespace SpatialSlur.Dynamics.Constraints
9 | {
10 | ///
11 | /// Contains any implementation details common to ALL constraints.
12 | ///
13 | [Serializable]
14 | public abstract class Constraint
15 | {
16 | private double _weight;
17 |
18 |
19 | ///
20 | ///
21 | ///
22 | ///
23 | public double Weight
24 | {
25 | get { return _weight; }
26 | set
27 | {
28 | if (value < 0.0)
29 | throw new ArgumentOutOfRangeException("The value cannot be negative.");
30 |
31 | _weight = value;
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/Coplanar.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class Coplanar : PositionGroup
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | public Coplanar(double weight = 1.0)
24 | : base(weight)
25 | {
26 | }
27 |
28 |
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public Coplanar(IEnumerable indices, double weight = 1.0)
35 | : base(indices, weight)
36 | {
37 | }
38 |
39 |
40 | ///
41 | protected override bool Calculate(ReadOnlyArrayView bodies, ReadOnlyArrayView indices, ArrayView deltas)
42 | {
43 | int n = indices.Count;
44 |
45 | if(n < 4 || !Geometry.FitPlaneToPoints(Indices.Select(i => bodies[i].Position.Current), out Vector3d p, out Vector3d z))
46 | {
47 | deltas.Clear();
48 | return false;
49 | }
50 |
51 | for (int i = 0; i < n; i++)
52 | deltas[i] = Vector3d.Project(p - bodies[indices[i]].Position.Current, z);
53 |
54 | return true;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/Cospherical.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class Cospherical : PositionGroup
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | public Cospherical(double weight = 1.0)
24 | : base(weight)
25 | {
26 | }
27 |
28 |
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public Cospherical(IEnumerable indices, double weight = 1.0)
35 | : base(indices, weight)
36 | {
37 | }
38 |
39 |
40 | ///
41 | protected override bool Calculate(ReadOnlyArrayView bodies, ReadOnlyArrayView indices, ArrayView deltas)
42 | {
43 | int n = indices.Count;
44 |
45 | if(n < 4 || !Geometry.FitSphereToPoints(Indices.Select(i => bodies[i].Position.Current), out Vector3d p, out double r))
46 | {
47 | deltas.Clear();
48 | return false;
49 | }
50 |
51 | for (int i = 0; i < n; i++)
52 | {
53 | var d = p - bodies[indices[i]].Position.Current;
54 | deltas[i] = d * (1.0 - r / d.Length);
55 | }
56 |
57 | return true;
58 | }
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/EqualizeLengths.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | /// Each successive pair of handles represents a line segment.
15 | ///
16 | [Serializable]
17 | public class EqualizeLengths : PositionGroup
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | public EqualizeLengths(double weight = 1.0)
24 | {
25 | Weight = weight;
26 | }
27 |
28 |
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public EqualizeLengths(IEnumerable indices, double weight = 1.0)
35 | : base(indices, weight)
36 | {
37 | }
38 |
39 |
40 | ///
41 | ///
42 | ///
43 | ///
44 | ///
45 | ///
46 | ///
47 | protected override bool Calculate(ReadOnlyArrayView bodies, ReadOnlyArrayView indices, ArrayView deltas)
48 | {
49 | int n = indices.Count;
50 |
51 | // check if sufficient number of bodies
52 | if (n < 4)
53 | {
54 | deltas.Clear();
55 | return false;
56 | }
57 |
58 | var target = 0.0;
59 |
60 | // calculate target as mean length
61 | for (int i = 0; i < n; i += 2)
62 | {
63 | var d = bodies[indices[i + 1]].Position.Current - bodies[indices[i]].Position.Current;
64 | var m = d.Length;
65 | target += m;
66 |
67 | // cache to avoid redundant calcs
68 | deltas[i] = d;
69 | deltas[i + 1].X = m;
70 | }
71 |
72 | target /= n >> 1;
73 |
74 | // calculate deltas
75 | for (int i = 0; i < n; i += 2)
76 | {
77 | var d = deltas[i];
78 | var m = deltas[i + 1].X;
79 |
80 | d *= (1.0 - target / m) * 0.5;
81 | deltas[i] = d;
82 | deltas[i + 1] = -d;
83 | }
84 |
85 | return true;
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/InsideBounds.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class InsideBounds : Constraint, IConstraint
18 | {
19 | private Vector3d _delta;
20 | private int _index;
21 |
22 | private Interval3d _bounds;
23 | private bool _apply;
24 |
25 |
26 | ///
27 | ///
28 | ///
29 | ///
30 | ///
31 | ///
32 | public InsideBounds(int index, Interval3d bounds, double weight = 1.0)
33 | {
34 | _index = index;
35 | _bounds = bounds;
36 | Weight = weight;
37 | }
38 |
39 |
40 | ///
41 | ///
42 | ///
43 | public int Index
44 | {
45 | get { return _index; }
46 | set { _index = value; }
47 | }
48 |
49 |
50 | ///
51 | ///
52 | ///
53 | public Interval3d Bounds
54 | {
55 | get { return _bounds; }
56 | set { _bounds = value; }
57 | }
58 |
59 |
60 | ///
61 | public void Calculate(ReadOnlyArrayView bodies)
62 | {
63 | var p = bodies[_index].Position.Current;
64 |
65 | if (_bounds.Contains(p))
66 | {
67 | _delta = Vector3d.Zero;
68 | _apply = false;
69 | return;
70 | }
71 |
72 | _delta = _bounds.Clamp(p) - p;
73 | _apply = true;
74 | }
75 |
76 |
77 | ///
78 | public void Apply(ReadOnlyArrayView bodies)
79 | {
80 | if (_apply)
81 | bodies[_index].Position.AddDelta(_delta, Weight);
82 | }
83 |
84 |
85 | ///
86 | public void GetEnergy(out double linear, out double angular)
87 | {
88 | linear = _delta.Length;
89 | angular = 0.0;
90 | }
91 |
92 |
93 | #region Explicit Interface Implementations
94 |
95 | bool IConstraint.AffectsPosition
96 | {
97 | get { return true; }
98 | }
99 |
100 |
101 | bool IConstraint.AffectsRotation
102 | {
103 | get { return false; }
104 | }
105 |
106 |
107 | IEnumerable IConstraint.Indices
108 | {
109 | get { yield return _index; }
110 | set { _index = value.First(); }
111 | }
112 |
113 | #endregion
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/LaplacianSmooth.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using SpatialSlur.Collections;
9 |
10 | namespace SpatialSlur.Dynamics.Constraints
11 | {
12 | ///
13 | ///
14 | ///
15 | [Serializable]
16 | public class LaplacianSmooth : PositionGroup
17 | {
18 | ///
19 | ///
20 | ///
21 | ///
22 | public LaplacianSmooth(double weight = 1.0)
23 | : base(weight)
24 | {
25 | }
26 |
27 |
28 | ///
29 | ///
30 | ///
31 | ///
32 | ///
33 | public LaplacianSmooth(IEnumerable indices, double weight = 1.0)
34 | : base(indices, weight)
35 | {
36 | }
37 |
38 |
39 | ///
40 | protected override bool Calculate(ReadOnlyArrayView bodies, ReadOnlyArrayView indices, ArrayView deltas)
41 | {
42 | int n = indices.Count;
43 |
44 | // check if sufficient number of bodies
45 | if (n < 3)
46 | {
47 | deltas.Clear();
48 | return false;
49 | }
50 |
51 | var sum = new Vector3d();
52 |
53 | for (int i = 1; i < n; i++)
54 | sum += bodies[indices[i]].Position.Current;
55 |
56 | var t = 1.0 / (n - 1);
57 | var d = (sum * t - bodies[indices[0]].Position.Current) * 0.5;
58 |
59 | // apply projection to center
60 | deltas[0] = d;
61 | d *= -t;
62 |
63 | // distribute reverse among 1 ring
64 | for (int i = 1; i < n; i++)
65 | deltas[i] = d;
66 |
67 | return true;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/MinimizeDistance.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using SpatialSlur.Collections;
9 |
10 | namespace SpatialSlur.Dynamics.Constraints
11 | {
12 | ///
13 | ///
14 | ///
15 | [Serializable]
16 | public class MinimizeDistance : Constraint, IConstraint
17 | {
18 | private Vector3d _delta;
19 | private int _i0, _i1;
20 |
21 |
22 | ///
23 | ///
24 | ///
25 | ///
26 | ///
27 | ///
28 | public MinimizeDistance(int index0, int index1, double weight = 1.0)
29 | {
30 | _i0 = index0;
31 | _i1 = index1;
32 | Weight = weight;
33 | }
34 |
35 |
36 | ///
37 | ///
38 | ///
39 | public int Index0
40 | {
41 | get { return _i0; }
42 | set { _i0 = value; }
43 | }
44 |
45 |
46 | ///
47 | ///
48 | ///
49 | public int Index1
50 | {
51 | get { return _i1; }
52 | set { _i1 = value; }
53 | }
54 |
55 |
56 | ///
57 | public void Calculate(ReadOnlyArrayView bodies)
58 | {
59 | _delta = (bodies[_i1].Position.Current - bodies[_i0].Position.Current) * 0.5;
60 | }
61 |
62 |
63 | ///
64 | public void Apply(ReadOnlyArrayView bodies)
65 | {
66 | bodies[_i0].Position.AddDelta(_delta, Weight);
67 | bodies[_i1].Position.AddDelta(-_delta, Weight);
68 | }
69 |
70 |
71 | ///
72 | public void GetEnergy(out double linear, out double angular)
73 | {
74 | linear = _delta.Length * 2.0;
75 | angular = 0.0;
76 | }
77 |
78 |
79 | #region Explicit Interface Implementations
80 |
81 | bool IConstraint.AffectsPosition
82 | {
83 | get { return true; }
84 | }
85 |
86 |
87 | bool IConstraint.AffectsRotation
88 | {
89 | get { return false; }
90 | }
91 |
92 |
93 | IEnumerable IConstraint.Indices
94 | {
95 | get
96 | {
97 | yield return _i0;
98 | yield return _i1;
99 | }
100 | set
101 | {
102 | var itr = value.GetEnumerator();
103 |
104 | itr.MoveNext();
105 | _i0 = itr.Current;
106 |
107 | itr.MoveNext();
108 | _i1 = itr.Current;
109 | }
110 | }
111 |
112 | #endregion
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/OnCurve.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using Rhino.Geometry;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class OnCurve : OnTarget
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | public OnCurve(int index, Curve curve, double weight = 1.0)
26 | : base(index, curve, weight)
27 | {
28 | }
29 |
30 |
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | protected override Vector3d GetClosestPoint(Vector3d point)
37 | {
38 | var crv = Target;
39 | crv.ClosestPoint(point, out double t);
40 | return crv.PointAt(t);
41 | }
42 | }
43 | }
44 |
45 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/OnExtendedMesh.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using Rhino.Geometry;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class OnExtendedMesh : OnTarget
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | public OnExtendedMesh(int index, Mesh mesh, double weight = 1.0)
26 | : base(index, mesh, weight)
27 | {
28 | }
29 |
30 |
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | protected override Vector3d GetClosestPoint(Vector3d point)
37 | {
38 | var mesh = Target;
39 | var mp = mesh.ClosestMeshPoint(point, 0.0);
40 |
41 | Vector3d cp = mesh.PointAt(mp);
42 | Vector3d cn = mesh.NormalAt(mp);
43 | return point + Vector3d.Project(cp - point, cn);
44 | }
45 | }
46 | }
47 |
48 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/OnExtendedSurface.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using Rhino.Geometry;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class OnExtendedSurface : OnTarget
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | public OnExtendedSurface(int index, Surface surface, double weight = 1.0)
26 | : base(index, surface, weight)
27 | {
28 | }
29 |
30 |
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | protected override Vector3d GetClosestPoint(Vector3d point)
37 | {
38 | var srf = Target;
39 | srf.ClosestPoint(point, out double u, out double v);
40 |
41 | Vector3d cp = srf.PointAt(u, v);
42 | Vector3d cn = srf.NormalAt(u, v);
43 | return point + Vector3d.Project(cp - point, cn);
44 | }
45 | }
46 | }
47 |
48 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/OnMesh.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using Rhino.Geometry;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class OnMesh : OnTarget
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | public OnMesh(int index, Mesh mesh, double weight = 1.0)
26 | :base(index, mesh, weight)
27 | {
28 | }
29 |
30 |
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | protected override Vector3d GetClosestPoint(Vector3d point)
37 | {
38 | return Target.ClosestPoint(point);
39 | }
40 | }
41 | }
42 |
43 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/OnPlane.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class OnPlane : Constraint, IConstraint
18 | {
19 | private Vector3d _delta;
20 | private int _index;
21 |
22 | private Vector3d _origin;
23 | private Vector3d _normal;
24 |
25 |
26 | ///
27 | ///
28 | ///
29 | ///
30 | ///
31 | ///
32 | ///
33 | public OnPlane(int index, Vector3d origin, Vector3d normal, double weight = 1.0)
34 | {
35 | _index = index;
36 | _origin = origin;
37 | _normal = normal;
38 | Weight = weight;
39 | }
40 |
41 |
42 | ///
43 | ///
44 | ///
45 | public int Index
46 | {
47 | get { return _index; }
48 | set { _index = value; }
49 | }
50 |
51 |
52 | ///
53 | ///
54 | ///
55 | public Vector3d Origin
56 | {
57 | get { return _origin; }
58 | set { _origin = value; }
59 | }
60 |
61 |
62 | ///
63 | ///
64 | ///
65 | public Vector3d Normal
66 | {
67 | get { return _normal; }
68 | set { _normal = value; }
69 | }
70 |
71 |
72 | ///
73 | public void Calculate(ReadOnlyArrayView bodies)
74 | {
75 | _delta = Vector3d.Project(_origin - bodies[_index].Position.Current, _normal);
76 | }
77 |
78 |
79 | ///
80 | public void Apply(ReadOnlyArrayView bodies)
81 | {
82 | bodies[_index].Position.AddDelta(_delta, Weight);
83 | }
84 |
85 |
86 | ///
87 | public void GetEnergy(out double linear, out double angular)
88 | {
89 | linear = _delta.Length;
90 | angular = 0.0;
91 | }
92 |
93 |
94 | #region Explicit Interface Implementations
95 |
96 | bool IConstraint.AffectsPosition
97 | {
98 | get { return true; }
99 | }
100 |
101 |
102 | bool IConstraint.AffectsRotation
103 | {
104 | get { return false; }
105 | }
106 |
107 |
108 | IEnumerable IConstraint.Indices
109 | {
110 | get { yield return _index; }
111 | set { _index = value.First(); }
112 | }
113 |
114 | #endregion
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/OnPosition.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 |
14 | ///
15 | ///
16 | ///
17 | [Serializable]
18 | public class OnPosition : Constraint, IConstraint
19 | {
20 | private Vector3d _delta;
21 | private int _index;
22 |
23 | private Vector3d _target;
24 |
25 |
26 | ///
27 | ///
28 | ///
29 | ///
30 | ///
31 | ///
32 | public OnPosition(int index, Vector3d position, double weight = 1.0)
33 | {
34 | _index = index;
35 | _target = position;
36 | Weight = weight;
37 | }
38 |
39 |
40 | ///
41 | ///
42 | ///
43 | public int Index
44 | {
45 | get { return _index; }
46 | set { _index = value; }
47 | }
48 |
49 |
50 | ///
51 | ///
52 | ///
53 | public Vector3d Target
54 | {
55 | get { return _target; }
56 | set { _target = value; }
57 | }
58 |
59 |
60 | ///
61 | public void Calculate(ReadOnlyArrayView bodies)
62 | {
63 | _delta = _target - bodies[_index].Position.Current;
64 | }
65 |
66 |
67 | ///
68 | public void Apply(ReadOnlyArrayView bodies)
69 | {
70 | bodies[_index].Position.AddDelta(_delta, Weight);
71 | }
72 |
73 |
74 | ///
75 | public void GetEnergy(out double linear, out double angular)
76 | {
77 | linear = _delta.Length;
78 | angular = 0.0;
79 | }
80 |
81 |
82 | #region Explicit Interface Implementations
83 |
84 | bool IConstraint.AffectsPosition
85 | {
86 | get { return true; }
87 | }
88 |
89 |
90 | bool IConstraint.AffectsRotation
91 | {
92 | get { return false; }
93 | }
94 |
95 |
96 | IEnumerable IConstraint.Indices
97 | {
98 | get { yield return _index; }
99 | set { _index = value.First(); }
100 | }
101 |
102 | #endregion
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/OnRotation.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class OnRotation : Constraint, IConstraint
18 | {
19 | private Vector3d _delta;
20 | private int _index;
21 |
22 | private Quaterniond _target;
23 |
24 |
25 | ///
26 | ///
27 | ///
28 | ///
29 | ///
30 | ///
31 | public OnRotation(int index, Quaterniond target, double weight = 1.0)
32 | {
33 | _index = index;
34 | _target = target;
35 | Weight = weight;
36 | }
37 |
38 |
39 | ///
40 | ///
41 | ///
42 | public int Index
43 | {
44 | get { return _index; }
45 | set { _index = value; }
46 | }
47 |
48 |
49 | ///
50 | ///
51 | ///
52 | public Quaterniond Target
53 | {
54 | get { return _target; }
55 | set { _target = value; }
56 | }
57 |
58 |
59 | ///
60 | public void Calculate(ReadOnlyArrayView bodies)
61 | {
62 | _delta = Quaterniond.CreateFromTo(bodies[_index].Rotation.Current, _target).ToAxisAngle();
63 | }
64 |
65 |
66 | ///
67 | public void Apply(ReadOnlyArrayView bodies)
68 | {
69 | bodies[_index].Rotation.AddDelta(_delta, Weight);
70 | }
71 |
72 |
73 | ///
74 | public void GetEnergy(out double linear, out double angular)
75 | {
76 | linear = 0.0;
77 | angular = _delta.Length;
78 | }
79 |
80 |
81 | #region Explicit Interface Implementations
82 |
83 | bool IConstraint.AffectsPosition
84 | {
85 | get { return false; }
86 | }
87 |
88 |
89 | bool IConstraint.AffectsRotation
90 | {
91 | get { return true; }
92 | }
93 |
94 |
95 | IEnumerable IConstraint.Indices
96 | {
97 | get { yield return _index; }
98 | set { _index = value.First(); }
99 | }
100 |
101 | #endregion
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Constraints/OnSurface.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using Rhino.Geometry;
10 |
11 | namespace SpatialSlur.Dynamics.Constraints
12 | {
13 | ///
14 | ///
15 | ///
16 | [Serializable]
17 | public class OnSurface : OnTarget
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | public OnSurface(int index, Surface surface, double weight = 1.0)
26 | : base(index, surface, weight)
27 | {
28 | }
29 |
30 |
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | protected override Vector3d GetClosestPoint(Vector3d point)
37 | {
38 | var srf = Target;
39 |
40 | srf.ClosestPoint(point, out double u, out double v);
41 | return srf.PointAt(u, v);
42 | }
43 | }
44 | }
45 |
46 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Extensions/IEnumerableExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SpatialSlur.Dynamics;
8 |
9 | namespace SpatialSlur
10 | {
11 | ///
12 | ///
13 | ///
14 | public static partial class IEnumerableExtensions
15 | {
16 | #region IEnumerable
17 |
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | public static bool AreSatisfied(this IEnumerable constraints, double linearTolerance, double angularTolerance)
27 | where T : IConstraint
28 | {
29 | foreach(var c in constraints)
30 | {
31 | c.GetEnergy(out double lin, out double ang);
32 | if (lin >= linearTolerance || ang >= angularTolerance) return false;
33 | }
34 |
35 | return true;
36 | }
37 |
38 |
39 | ///
40 | ///
41 | ///
42 | ///
43 | ///
44 | ///
45 | public static void GetEnergySum(this IEnumerable constraints, out double linear, out double angular)
46 | where T : IConstraint
47 | {
48 | linear = 0.0;
49 | angular = 0.0;
50 |
51 | foreach (var c in constraints)
52 | {
53 | c.GetEnergy(out double lin, out double ang);
54 | linear += lin;
55 | angular += ang;
56 | }
57 | }
58 |
59 | #endregion
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Forces/Force.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | namespace SpatialSlur.Dynamics.Forces
9 | {
10 | ///
11 | ///
12 | ///
13 | public abstract class Force
14 | {
15 | private double _strength;
16 |
17 |
18 | ///
19 | ///
20 | ///
21 | ///
22 | public double Strength
23 | {
24 | get { return _strength; }
25 | set { _strength = value; }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Forces/ForceField.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 | using SpatialSlur.Fields;
11 |
12 | namespace SpatialSlur.Dynamics.Forces
13 | {
14 | ///
15 | ///
16 | ///
17 | [Serializable]
18 | public class ForceField : Force, IConstraint
19 | {
20 | private IField3d _field;
21 | private Vector3d _delta;
22 | private int _index;
23 |
24 |
25 | ///
26 | ///
27 | ///
28 | ///
29 | ///
30 | ///
31 | public ForceField(int index, IField3d field, double strength = 1.0)
32 | {
33 | _index = index;
34 | Field = field;
35 | Strength = strength;
36 | }
37 |
38 |
39 | ///
40 | ///
41 | ///
42 | public int Index
43 | {
44 | get { return _index; }
45 | set { _index = value; }
46 | }
47 |
48 |
49 | ///
50 | ///
51 | ///
52 | public IField3d Field
53 | {
54 | get { return _field; }
55 | set { _field = value ?? throw new ArgumentNullException(); }
56 | }
57 |
58 |
59 | ///
60 | public void Calculate(ReadOnlyArrayView bodies)
61 | {
62 | _delta = _field.ValueAt(bodies[_index].Position.Current) * Strength;
63 | }
64 |
65 |
66 | ///
67 | public void Apply(ReadOnlyArrayView bodies)
68 | {
69 | bodies[_index].Position.AddForce(_delta);
70 | }
71 |
72 |
73 | ///
74 | public void GetEnergy(out double linear, out double angular)
75 | {
76 | linear = _delta.Length;
77 | angular = 0.0;
78 | }
79 |
80 |
81 | #region Explicit Interface Implementations
82 |
83 | bool IConstraint.AffectsPosition
84 | {
85 | get { return true; }
86 | }
87 |
88 |
89 | bool IConstraint.AffectsRotation
90 | {
91 | get { return false; }
92 | }
93 |
94 |
95 | IEnumerable IConstraint.Indices
96 | {
97 | get { yield return _index; }
98 | set { _index = value.First(); }
99 | }
100 |
101 | #endregion
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Forces/Weight.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using SpatialSlur.Collections;
10 |
11 | namespace SpatialSlur.Dynamics.Forces
12 | {
13 | ///
14 | /// Applies a force proportional to the mass of each particle.
15 | ///
16 | [Serializable]
17 | public class Weight : Force, IConstraint
18 | {
19 | private Vector3d _acceleration;
20 | private Vector3d _delta;
21 | private int _index;
22 |
23 |
24 | ///
25 | ///
26 | ///
27 | ///
28 | ///
29 | ///
30 | public Weight(int index, Vector3d acceleration, double strength = 1.0)
31 | {
32 | _index = index;
33 | _acceleration = acceleration;
34 | Strength = strength;
35 | }
36 |
37 |
38 | ///
39 | ///
40 | ///
41 | public int Index
42 | {
43 | get { return _index; }
44 | set { _index = value; }
45 | }
46 |
47 |
48 | ///
49 | ///
50 | ///
51 | public Vector3d Acceleration
52 | {
53 | get { return _acceleration; }
54 | set { _acceleration = value; }
55 | }
56 |
57 |
58 | ///
59 | public void Calculate(ReadOnlyArrayView bodies)
60 | {
61 | _delta = _acceleration * (bodies[_index].Position.Mass * Strength);
62 | }
63 |
64 |
65 | ///
66 | public void Apply(ReadOnlyArrayView bodies)
67 | {
68 | bodies[_index].Position.AddForce(_delta);
69 | }
70 |
71 |
72 | ///
73 | public void GetEnergy(out double linear, out double angular)
74 | {
75 | linear = _delta.Length;
76 | angular = 0.0;
77 | }
78 |
79 |
80 | #region Explicit Interface Implementations
81 |
82 | bool IConstraint.AffectsPosition
83 | {
84 | get { return true; }
85 | }
86 |
87 |
88 | bool IConstraint.AffectsRotation
89 | {
90 | get { return false; }
91 | }
92 |
93 |
94 | IEnumerable IConstraint.Indices
95 | {
96 | get { yield return _index; }
97 | set { _index = value.First(); }
98 | }
99 |
100 | #endregion
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/SpatialSlur/Dynamics/Interfaces/IConstraint.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System.Collections.Generic;
7 | using SpatialSlur.Collections;
8 |
9 | namespace SpatialSlur.Dynamics
10 | {
11 | ///
12 | ///
13 | ///
14 | public interface IConstraint
15 | {
16 | ///
17 | /// Gets or sets the indices of the bodies affected by this constraint.
18 | ///
19 | IEnumerable Indices { get; set; }
20 |
21 |
22 | ///
23 | /// Returns true if this constraint affects a body's position.
24 | ///
25 | bool AffectsPosition { get; }
26 |
27 |
28 | ///
29 | /// Returns true if this constraint affects a body's rotation.
30 | ///
31 | bool AffectsRotation { get; }
32 |
33 |
34 | ///
35 | /// Calculates all forces and projections associated with this constraint.
36 | ///
37 | ///
38 | void Calculate(ReadOnlyArrayView bodies);
39 |
40 |
41 | ///
42 | /// Applies calculated forces and projections to the affected bodies.
43 | ///
44 | ///
45 | void Apply(ReadOnlyArrayView bodies);
46 |
47 |
48 | ///
49 | /// Returns the energy that this constraint is trying to minimize.
50 | /// The constraint is satisfied when this equals zero.
51 | ///
52 | void GetEnergy(out double linear, out double angular);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Derived/IDWField3dDouble.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | using SpatialSlur;
9 | using SpatialSlur.Fields;
10 |
11 | using D = SpatialSlur.SlurMath.Constantsd;
12 |
13 | namespace SpatialSlur.Fields
14 | {
15 | ///
16 | ///
17 | ///
18 | [Serializable]
19 | internal class IDWField3dDouble : IDWField3d
20 | {
21 | #region Nested Types
22 |
23 | ///
24 | ///
25 | ///
26 | internal class Factory : IDWFieldFactory
27 | {
28 | ///
29 | public override IDWField3d Create(double power, double epsilon = D.ZeroTolerance)
30 | {
31 | return new IDWField3dDouble(power, epsilon);
32 | }
33 | }
34 |
35 | #endregion
36 |
37 |
38 | ///
39 | ///
40 | ///
41 | public IDWField3dDouble(double power, double epsilon = D.ZeroTolerance)
42 | : base(power, epsilon)
43 | {
44 | }
45 |
46 |
47 | ///
48 | public sealed override IDWField3d Duplicate()
49 | {
50 | return IDWField3d.Double.CreateCopy(this);
51 | }
52 |
53 |
54 | ///
55 | public sealed override double ValueAt(Vector3d point)
56 | {
57 | double sum = 0.0;
58 | double wsum = 0.0;
59 |
60 | foreach (var obj in Objects)
61 | {
62 | double w = obj.Influence / Math.Pow(obj.DistanceTo(point) + Epsilon, Power);
63 | sum += obj.Value * w;
64 | wsum += w;
65 | }
66 |
67 | return (wsum > 0.0) ? sum / wsum : 0.0;
68 | }
69 |
70 |
71 | ///
72 | public sealed override void GradientAt(Vector3d point, out double gx, out double gy, out double gz)
73 | {
74 | throw new NotImplementedException();
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Derived/IDWField3dVector3d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | using SpatialSlur;
9 | using SpatialSlur.Fields;
10 |
11 | using D = SpatialSlur.SlurMath.Constantsd;
12 |
13 | namespace SpatialSlur.Fields
14 | {
15 | ///
16 | ///
17 | ///
18 | [Serializable]
19 | internal class IDWField3dVector3d : IDWField3d
20 | {
21 | #region Nested Types
22 |
23 | ///
24 | ///
25 | ///
26 | internal class Factory : IDWFieldFactory
27 | {
28 | ///
29 | public override IDWField3d Create(double power, double epsilon = D.ZeroTolerance)
30 | {
31 | return new IDWField3dVector3d(power, epsilon);
32 | }
33 | }
34 |
35 | #endregion
36 |
37 |
38 | ///
39 | ///
40 | ///
41 | public IDWField3dVector3d(double power, double epsilon = D.ZeroTolerance)
42 | : base(power, epsilon)
43 | {
44 | }
45 |
46 |
47 | ///
48 | public sealed override IDWField3d Duplicate()
49 | {
50 | return IDWField3d.Vector3d.CreateCopy(this);
51 | }
52 |
53 |
54 | ///
55 | public sealed override Vector3d ValueAt(Vector3d point)
56 | {
57 | Vector3d sum = Vector3d.Zero;
58 | double wsum = 0.0;
59 |
60 | foreach (var obj in Objects)
61 | {
62 | double w = obj.Influence / Math.Pow(obj.DistanceTo(point) + Epsilon, Power);
63 | sum += obj.Value * w;
64 | wsum += w;
65 | }
66 |
67 | return (wsum > 0.0) ? sum / wsum : new Vector3d();
68 | }
69 |
70 |
71 | ///
72 | public sealed override void GradientAt(Vector3d point, out Vector3d gx, out Vector3d gy, out Vector3d gz)
73 | {
74 | throw new NotImplementedException();
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Derived/MeshField3dDouble.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using SpatialSlur;
10 | using SpatialSlur.Meshes;
11 | using SpatialSlur.Fields;
12 |
13 | namespace SpatialSlur.Fields
14 | {
15 | ///
16 | ///
17 | ///
18 | [Serializable]
19 | internal class MeshField3dDouble : MeshField3d
20 | {
21 | #region Nested Types
22 |
23 | ///
24 | ///
25 | ///
26 | internal class Factory : MeshField3dFactory
27 | {
28 | ///
29 | public override MeshField3d Create(HeMesh3d mesh)
30 | {
31 | return new MeshField3dDouble(mesh);
32 | }
33 |
34 |
35 | ///
36 | public override MeshField3d Create(MeshField3d field)
37 | {
38 | return new MeshField3dDouble(field);
39 | }
40 | }
41 |
42 | #endregion
43 |
44 |
45 | ///
46 | ///
47 | ///
48 | ///
49 | public MeshField3dDouble(HeMesh3d mesh)
50 | : base(mesh)
51 | {
52 | }
53 |
54 |
55 | ///
56 | ///
57 | ///
58 | ///
59 | public MeshField3dDouble(MeshField3d other)
60 | : base(other)
61 | {
62 | }
63 |
64 |
65 | ///
66 | public sealed override MeshField3d Duplicate(bool setValues)
67 | {
68 | var result = MeshField3d.Double.Create(this);
69 | if(setValues) result.Set(this);
70 | return result;
71 | }
72 |
73 |
74 | ///
75 | public override double ValueAt(Vector3d weights, Vector3i indices)
76 | {
77 | return
78 | Values[indices.X] * weights.X +
79 | Values[indices.Y] * weights.Y +
80 | Values[indices.Z] * weights.Z;
81 | }
82 | }
83 | }
84 |
85 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Derived/MeshField3dVector3d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using SpatialSlur;
10 | using SpatialSlur.Fields;
11 | using SpatialSlur.Meshes;
12 |
13 | namespace SpatialSlur.Fields
14 | {
15 | ///
16 | ///
17 | ///
18 | [Serializable]
19 | internal class MeshField3dVector3d : MeshField3d
20 | {
21 | #region Nested Types
22 |
23 | ///
24 | ///
25 | ///
26 | internal class Factory : MeshField3dFactory
27 | {
28 | ///
29 | public override MeshField3d Create(HeMesh3d mesh)
30 | {
31 | return new MeshField3dVector3d(mesh);
32 | }
33 |
34 |
35 | ///
36 | public override MeshField3d Create(MeshField3d field)
37 | {
38 | return new MeshField3dVector3d(field);
39 | }
40 | }
41 |
42 | #endregion
43 |
44 |
45 | ///
46 | ///
47 | ///
48 | ///
49 | public MeshField3dVector3d(HeMesh3d mesh)
50 | : base(mesh)
51 | {
52 | }
53 |
54 |
55 | ///
56 | ///
57 | ///
58 | ///
59 | public MeshField3dVector3d(MeshField3d other)
60 | : base(other)
61 | {
62 | }
63 |
64 |
65 | ///
66 | public sealed override MeshField3d Duplicate(bool setValues)
67 | {
68 | var result = MeshField3d.Vector3d.Create(this);
69 | if (setValues) result.Set(this);
70 | return result;
71 | }
72 |
73 |
74 | ///
75 | public override Vector3d ValueAt(Vector3d weights, Vector3i indices)
76 | {
77 | return
78 | Values[indices.X] * weights.X +
79 | Values[indices.Y] * weights.Y +
80 | Values[indices.Z] * weights.Z;
81 | }
82 | }
83 | }
84 |
85 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Fields/DistanceFunctions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | *
5 | * References
6 | * http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
7 | */
8 |
9 | using System;
10 | using SpatialSlur;
11 |
12 | namespace SpatialSlur.Fields
13 | {
14 | ///
15 | ///
16 | ///
17 | public static class DistanceFunctions
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | public static double Sphere(Vector3d point, double radius)
26 | {
27 | return point.Length - radius;
28 | }
29 |
30 |
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | ///
37 | public static double Box(Vector3d point, Vector3d size)
38 | {
39 | var d = Vector3d.Abs(point) - size;
40 | return Math.Min(d.ComponentMax, 0.0) + Vector3d.Min(d, 0.0).Length;
41 | }
42 |
43 |
44 | ///
45 | ///
46 | ///
47 | ///
48 | ///
49 | ///
50 | ///
51 | ///
52 | public static double Capsule(Vector3d point, Vector3d start, Vector3d axis, double radius)
53 | {
54 | var d = point - start;
55 | var t = SlurMath.Saturate(Vector3d.Dot(d, axis) / axis.SquareLength);
56 | return (d - axis * t).Length - radius;
57 | }
58 |
59 |
60 | ///
61 | ///
62 | ///
63 | ///
64 | ///
65 | ///
66 | public static double Union(double d0, double d1)
67 | {
68 | return Math.Min(d0, d1);
69 | }
70 |
71 |
72 | ///
73 | ///
74 | ///
75 | ///
76 | ///
77 | ///
78 | public static double Difference(double d0, double d1)
79 | {
80 | return Math.Max(-d0, d1);
81 | }
82 |
83 |
84 | ///
85 | ///
86 | ///
87 | ///
88 | ///
89 | ///
90 | public static double Intersection(double d0, double d1)
91 | {
92 | return Math.Max(d0, d1);
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Enums/IntegrationMode.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | namespace SpatialSlur.Fields
7 | {
8 | ///
9 | ///
10 | ///
11 | public enum IntegrationMode
12 | {
13 | ///
14 | Euler,
15 | ///
16 | RK2,
17 | ///
18 | RK4
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Enums/SampleMode.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | namespace SpatialSlur.Fields
7 | {
8 | ///
9 | /// Determines how the field is sampled at a given point.
10 | ///
11 | public enum SampleMode
12 | {
13 | ///
14 | Nearest,
15 | ///
16 | Linear
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Enums/WrapMode.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | namespace SpatialSlur.Fields
7 | {
8 | ///
9 | /// Determines what happens when a field is evaluated beyond its bounds.
10 | ///
11 | public enum WrapMode
12 | {
13 | ///
14 | Clamp,
15 | ///
16 | Repeat,
17 | ///
18 | Mirror
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Extensions/GridField3dFactoryExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.IO;
8 | using System.Text;
9 |
10 | using SpatialSlur;
11 | using SpatialSlur.Fields;
12 |
13 | namespace SpatialSlur.Fields
14 | {
15 | ///
16 | ///
17 | ///
18 | public static class GridField3dFactoryExtensions
19 | {
20 | #region Vector3d
21 |
22 | ///
23 | ///
24 | ///
25 | ///
26 | ///
27 | ///
28 | public static GridField3d CreateFromFGA(this GridField3dFactory factory, string path)
29 | {
30 | var content = File.ReadAllText(path, Encoding.ASCII);
31 | var values = content.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
32 |
33 | int nx = int.Parse(values[0]);
34 | int ny = int.Parse(values[1]);
35 | int nz = int.Parse(values[2]);
36 |
37 | Vector3d p0 = new Vector3d(
38 | double.Parse(values[3]),
39 | double.Parse(values[4]),
40 | double.Parse(values[5]));
41 |
42 | Vector3d p1 = new Vector3d(
43 | double.Parse(values[6]),
44 | double.Parse(values[7]),
45 | double.Parse(values[8]));
46 |
47 | var result = factory.Create(nx, ny, nz, new Interval3d(p0, p1));
48 | var vecs = result.Values;
49 | int index = 0;
50 |
51 | for (int i = 9; i < values.Length; i += 3)
52 | {
53 | vecs[index++] = new Vector3d(
54 | double.Parse(values[i]),
55 | double.Parse(values[i + 1]),
56 | double.Parse(values[i + 2]));
57 | }
58 |
59 | return result;
60 | }
61 |
62 | #endregion
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Extensions/ISampledField2dExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Concurrent;
8 | using System.Threading.Tasks;
9 |
10 | namespace SpatialSlur.Fields
11 | {
12 | ///
13 | ///
14 | ///
15 | public static class ISampledField2dExtensions
16 | {
17 | ///
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | public static ISampledField2d Duplicate(this ISampledField2d field)
24 | where T : struct
25 | {
26 | return field.Duplicate(true);
27 | }
28 |
29 |
30 | ///
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | ///
37 | public static void Sample(this ISampledField2d field, IField2d other, bool parallel = false)
38 | {
39 | if (parallel)
40 | Parallel.ForEach(Partitioner.Create(0, field.Count), range => Body(range.Item1, range.Item2));
41 | else
42 | Body(0, field.Count);
43 |
44 | void Body(int from, int to)
45 | {
46 | var vals = field.Values;
47 |
48 | for (int i = from; i < to; i++)
49 | vals[i] = other.ValueAt(field.PointAt(i));
50 | }
51 | }
52 |
53 |
54 | ///
55 | ///
56 | ///
57 | ///
58 | ///
59 | ///
60 | ///
61 | ///
62 | ///
63 | public static void Sample(this ISampledField2d field, IField2d other, Func converter, bool parallel = false)
64 | {
65 | if (parallel)
66 | Parallel.ForEach(Partitioner.Create(0, field.Count), range => Body(range.Item1, range.Item2));
67 | else
68 | Body(0, field.Count);
69 |
70 | void Body(int from, int to)
71 | {
72 | var vals = field.Values;
73 |
74 | for (int i = from; i < to; i++)
75 | vals[i] = converter(other.ValueAt(field.PointAt(i)));
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Extensions/ISampledField3dExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Concurrent;
8 | using System.Threading.Tasks;
9 |
10 | namespace SpatialSlur.Fields
11 | {
12 | ///
13 | ///
14 | ///
15 | public static class ISampledField3dExtensions
16 | {
17 | ///
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | public static ISampledField3d Duplicate(this ISampledField3d field)
24 | where T : struct
25 | {
26 | return field.Duplicate(true);
27 | }
28 |
29 |
30 | ///
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | ///
37 | public static void Sample(this ISampledField3d field, IField3d other, bool parallel = false)
38 | {
39 | if (parallel)
40 | Parallel.ForEach(Partitioner.Create(0, field.Count), range => Body(range.Item1, range.Item2));
41 | else
42 | Body(0, field.Count);
43 |
44 | void Body(int from, int to)
45 | {
46 | var vals = field.Values;
47 |
48 | for (int i = from; i < to; i++)
49 | vals[i] = other.ValueAt(field.PointAt(i));
50 | }
51 | }
52 |
53 |
54 | ///
55 | ///
56 | ///
57 | ///
58 | ///
59 | ///
60 | ///
61 | ///
62 | ///
63 | public static void Sample(this ISampledField3d field, IField3d other, Func converter, bool parallel = false)
64 | {
65 | if (parallel)
66 | Parallel.ForEach(Partitioner.Create(0, field.Count), range => Body(range.Item1, range.Item2));
67 | else
68 | Body(0, field.Count);
69 |
70 | void Body(int from, int to)
71 | {
72 | var vals = field.Values;
73 |
74 | for (int i = from; i < to; i++)
75 | vals[i] = converter(other.ValueAt(field.PointAt(i)));
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Extensions/ListExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System.Collections.Generic;
7 | using SpatialSlur.Fields;
8 |
9 | namespace SpatialSlur
10 | {
11 | ///
12 | ///
13 | ///
14 | public static partial class ListExtensions
15 | {
16 | #region List>
17 |
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | public static void Add(this List> objects, Vector3d point, T value, double influence = 1.0)
27 | {
28 | objects.Add(IDWPoint3d.Create(point, value, influence));
29 | }
30 |
31 | #endregion
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Field2d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | namespace SpatialSlur.Fields
9 | {
10 | ///
11 | ///
12 | ///
13 | public static class Field2d
14 | {
15 | ///
16 | ///
17 | ///
18 | ///
19 | ///
20 | ///
21 | public static IField2d Create(Func valueAt)
22 | {
23 | return new FuncField2d(valueAt);
24 | }
25 |
26 |
27 | ///
28 | ///
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public static IField2d CreateTransformed(IField2d other, Transform2d transform)
35 | {
36 | transform.Invert();
37 | return Create(p => other.ValueAt(transform.Apply(p)));
38 | }
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/FuncField2d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | using SpatialSlur;
9 |
10 | namespace SpatialSlur.Fields
11 | {
12 | ///
13 | ///
14 | ///
15 | ///
16 | public class FuncField2d : IField2d, IField3d
17 | {
18 | ///
19 | public readonly Func ValueAt;
20 |
21 |
22 | ///
23 | ///
24 | ///
25 | ///
26 | internal FuncField2d(Func valueAt)
27 | {
28 | ValueAt = valueAt ?? throw new ArgumentNullException();
29 | }
30 |
31 |
32 | #region Explicit Interface Implementations
33 |
34 | T IField2d.ValueAt(Vector2d point)
35 | {
36 | return ValueAt(point);
37 | }
38 |
39 |
40 | T IField3d.ValueAt(Vector3d point)
41 | {
42 | return ValueAt(point.XY);
43 | }
44 |
45 | #endregion
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/FuncField3d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | namespace SpatialSlur.Fields
9 | {
10 | ///
11 | ///
12 | ///
13 | ///
14 | public class FuncField3d: IField2d, IField3d
15 | {
16 | ///
17 | public readonly Func ValueAt;
18 |
19 |
20 | ///
21 | ///
22 | ///
23 | ///
24 | internal FuncField3d(Func valueAt)
25 | {
26 | ValueAt = valueAt ?? throw new ArgumentNullException();
27 | }
28 |
29 |
30 | #region Explicit Interface Implementations
31 |
32 | T IField2d.ValueAt(Vector2d point)
33 | {
34 | return ValueAt(point.As3d);
35 | }
36 |
37 |
38 | T IField3d.ValueAt(Vector3d point)
39 | {
40 | return ValueAt(point);
41 | }
42 |
43 | #endregion
44 | }
45 | }
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Grid.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 |
12 | namespace SpatialSlur.Fields
13 | {
14 | ///
15 | ///
16 | ///
17 | internal static class Grid
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | public static Func GetWrapFunction(WrapMode mode)
25 | {
26 | switch (mode)
27 | {
28 | case WrapMode.Clamp:
29 | return Clamp;
30 | case WrapMode.Repeat:
31 | return Repeat;
32 | case WrapMode.Mirror:
33 | return Mirror;
34 | }
35 |
36 | throw new NotSupportedException();
37 | }
38 |
39 |
40 | ///
41 | ///
42 | ///
43 | ///
44 | ///
45 | ///
46 | ///
47 | public static int Wrap(int index, int count, WrapMode mode)
48 | {
49 | return
50 | mode == WrapMode.Mirror ? Mirror(index, count) :
51 | mode == WrapMode.Repeat ? Repeat(index, count) :
52 | Clamp(index, count);
53 |
54 | #if OBSOLETE
55 | // switch implementation doesn't allow for inline optimization
56 | switch (mode)
57 | {
58 | case WrapMode.Clamp:
59 | return Clamp(index, range);
60 | case WrapMode.Repeat:
61 | return Repeat(index, range);
62 | case WrapMode.Mirror:
63 | return Mirror(index, range);
64 | }
65 |
66 | throw new NotSupportedException();
67 | #endif
68 | }
69 |
70 |
71 | ///
72 | ///
73 | ///
74 | private static int Clamp(int i, int n)
75 | {
76 | return (i < 0) ? 0 : (i < n) ? i : n - 1;
77 | }
78 |
79 |
80 | ///
81 | ///
82 | ///
83 | private static int Repeat(int i, int n)
84 | {
85 | i %= n;
86 | return (i < 0) ? i + n : i;
87 | }
88 |
89 |
90 | ///
91 | ///
92 | ///
93 | private static int Mirror(int i, int n)
94 | {
95 | int n2 = n << 1;
96 | i %= n2;
97 | i = (i < 0) ? i + n2 : i;
98 | return n - Math.Abs(i - n);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/GridPoint2d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | namespace SpatialSlur.Fields
9 | {
10 | ///
11 | /// Barycentric representation of position in a two-dimensional grid.
12 | ///
13 | [Serializable]
14 | public struct GridPoint2d
15 | {
16 | ///
17 | public double Weight0;
18 | ///
19 | public int Index0;
20 |
21 | ///
22 | public double Weight1;
23 | ///
24 | public int Index1;
25 |
26 | ///
27 | public double Weight2;
28 | ///
29 | public int Index2;
30 |
31 | ///
32 | public double Weight3;
33 | ///
34 | public int Index3;
35 |
36 |
37 | ///
38 | /// Assumes components of the given point are between 0 and 1 inclusive.
39 | ///
40 | ///
41 | public void SetWeights(Vector2d point)
42 | {
43 | (var u0, var v0) = point;
44 |
45 | double u1 = 1.0 - u0;
46 | double v1 = 1.0 - v0;
47 |
48 | Weight0 = u1 * v1;
49 | Weight1 = u0 * v1;
50 | Weight2 = u1 * v0;
51 | Weight3 = u0 * v0;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/GridPoint3d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using SpatialSlur;
8 |
9 | namespace SpatialSlur.Fields
10 | {
11 | ///
12 | /// Barycentric representation of position in a three-dimensional grid.
13 | ///
14 | [Serializable]
15 | public struct GridPoint3d
16 | {
17 | ///
18 | public double Weight0;
19 | ///
20 | public int Index0;
21 |
22 | ///
23 | public double Weight1;
24 | ///
25 | public int Index1;
26 |
27 | ///
28 | public double Weight2;
29 | ///
30 | public int Index2;
31 |
32 | ///
33 | public double Weight3;
34 | ///
35 | public int Index3;
36 |
37 | ///
38 | public double Weight4;
39 | ///
40 | public int Index4;
41 |
42 | ///
43 | public double Weight5;
44 | ///
45 | public int Index5;
46 |
47 | ///
48 | public double Weight6;
49 | ///
50 | public int Index6;
51 |
52 | ///
53 | public double Weight7;
54 | ///
55 | public int Index7;
56 |
57 |
58 | ///
59 | ///
60 | ///
61 | ///
62 | public void SetWeights(Vector3d point)
63 | {
64 | (var u0, var v0, var w0) = point;
65 |
66 | double u1 = 1.0 - u0;
67 | double v1 = 1.0 - v0;
68 | double w1 = 1.0 - w0;
69 |
70 | Weight0 = u1 * v1 * w1;
71 | Weight1 = u0 * v1 * w1;
72 | Weight2 = u1 * v0 * w1;
73 | Weight3 = u0 * v0 * w1;
74 |
75 | Weight4 = u1 * v1 * w0;
76 | Weight5 = u0 * v1 * w0;
77 | Weight6 = u1 * v0 * w0;
78 | Weight7 = u0 * v0 * w0;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/IDWFieldFactory.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Linq;
8 |
9 | using SpatialSlur;
10 |
11 | using D = SpatialSlur.SlurMath.Constantsd;
12 |
13 | namespace SpatialSlur.Fields
14 | {
15 | ///
16 | ///
17 | ///
18 | public abstract class IDWFieldFactory
19 | {
20 | ///
21 | ///
22 | ///
23 | ///
24 | public abstract IDWField3d Create(double power, double epsilon = D.ZeroTolerance);
25 |
26 |
27 | ///
28 | ///
29 | ///
30 | ///
31 | ///
32 | public IDWField3d CreateCopy(IDWField3d other)
33 | {
34 | var result = Create(other.Power, other.Epsilon);
35 | result.Objects.AddRange(other.Objects.Select(obj => obj.Duplicate()));
36 | return result;
37 | }
38 |
39 |
40 | ///
41 | ///
42 | ///
43 | ///
44 | ///
45 | ///
46 | ///
47 | public IDWField3d CreateCopy(IDWField3d other, Func converter)
48 | {
49 | var result = Create(other.Power, other.Epsilon);
50 | result.Objects.AddRange(other.Objects.Select(obj => obj.Convert(converter)));
51 | return result;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/IDWObject3d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 |
12 | using SpatialSlur;
13 |
14 | namespace SpatialSlur.Fields
15 | {
16 | ///
17 | ///
18 | ///
19 | ///
20 | public abstract class IDWObject3d
21 | {
22 | private T _value;
23 | private double _influence;
24 |
25 |
26 | ///
27 | ///
28 | ///
29 | ///
30 | ///
31 | public abstract double DistanceTo(Vector3d point);
32 |
33 |
34 | ///
35 | ///
36 | ///
37 | public T Value
38 | {
39 | get => _value;
40 | set => _value = value;
41 | }
42 |
43 |
44 | ///
45 | ///
46 | ///
47 | public double Influence
48 | {
49 | get => _influence;
50 | set => _influence = value;
51 | }
52 |
53 |
54 | ///
55 | ///
56 | ///
57 | ///
58 | public abstract IDWObject3d Duplicate();
59 |
60 |
61 | ///
62 | ///
63 | ///
64 | ///
65 | ///
66 | public abstract IDWObject3d Convert(Func converter);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Interfaces/IField2d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using SpatialSlur;
7 |
8 | namespace SpatialSlur.Fields
9 | {
10 | ///
11 | /// Interface for a spatially varying function in 2 dimensions.
12 | ///
13 | ///
14 | public interface IField2d
15 | {
16 | ///
17 | /// Returns the value at the given point.
18 | ///
19 | ///
20 | ///
21 | T ValueAt(Vector2d point);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Interfaces/IField3d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using SpatialSlur;
7 |
8 | namespace SpatialSlur.Fields
9 | {
10 | ///
11 | /// Interface for a spatially varying function in 3 dimensions.
12 | ///
13 | public interface IField3d
14 | {
15 | ///
16 | /// Returns the value at the given point.
17 | ///
18 | ///
19 | ///
20 | T ValueAt(Vector3d point);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Interfaces/IGradient2d.cs:
--------------------------------------------------------------------------------
1 |
2 |
3 | /*
4 | * Notes
5 | */
6 |
7 | using SpatialSlur;
8 |
9 | namespace SpatialSlur.Fields
10 | {
11 | ///
12 | ///
13 | ///
14 | ///
15 | public interface IGradient2d
16 | {
17 | ///
18 | /// Returns the the gradient at the given point.
19 | ///
20 | ///
21 | ///
22 | ///
23 | void GradientAt(Vector2d point, out T dx, out T dy);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Interfaces/IGradient3d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using SpatialSlur;
7 |
8 | namespace SpatialSlur.Fields
9 | {
10 | ///
11 | ///
12 | ///
13 | ///
14 | public interface IGradient3d
15 | {
16 | ///
17 | /// Returns the the gradient at the given point.
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | void GradientAt(Vector3d point, out T dx, out T dy, out T dz);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Interfaces/ISampledField.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Notes
3 | */
4 |
5 | using SpatialSlur.Collections;
6 |
7 | namespace SpatialSlur.Fields
8 | {
9 | ///
10 | ///
11 | ///
12 | public interface ISampledField
13 | {
14 | ///
15 | /// Returns the field's array of sample values.
16 | ///
17 | ArrayView Values { get; }
18 |
19 |
20 | ///
21 | /// Returns the number of samples in the field.
22 | ///
23 | int Count { get; }
24 |
25 |
26 | ///
27 | /// Returns a copy of this field.
28 | /// Note that that value array of the returned field is a deep copy but other fields may be shallow depending on the implementation.
29 | ///
30 | ///
31 | ISampledField Duplicate(bool setValues);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Interfaces/ISampledField2d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System.Collections.Generic;
7 |
8 | using SpatialSlur;
9 |
10 | namespace SpatialSlur.Fields
11 | {
12 | ///
13 | ///
14 | ///
15 | public interface ISampledField2d : ISampledField, IField2d
16 | {
17 | ///
18 | /// Returns all sample points used by this field.
19 | ///
20 | IEnumerable Points { get; }
21 |
22 |
23 | ///
24 | /// Returns the sample point at the given index.
25 | ///
26 | ///
27 | ///
28 | Vector2d PointAt(int index);
29 |
30 |
31 | ///
32 | /// Returns a copy of this field.
33 | /// Note that that sample value array of the returned field is a deep copy but other fields may be shallow depending on the implementation.
34 | ///
35 | ///
36 | new ISampledField2d Duplicate(bool setValues);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/Interfaces/ISampledField3d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System.Collections.Generic;
7 |
8 | using SpatialSlur;
9 |
10 | namespace SpatialSlur.Fields
11 | {
12 | ///
13 | ///
14 | ///
15 | public interface ISampledField3d : ISampledField, IField3d
16 | {
17 | ///
18 | /// Returns all sample points used by this field.
19 | ///
20 | IEnumerable Points { get; }
21 |
22 |
23 | ///
24 | /// Returns the sample point at the given index.
25 | ///
26 | ///
27 | ///
28 | Vector3d PointAt(int index);
29 |
30 |
31 | ///
32 | /// Returns a copy of this field.
33 | /// Note that that sample value array of the returned field is a deep copy but other fields may be shallow depending on the implementation.
34 | ///
35 | ///
36 | new ISampledField3d Duplicate(bool setValues);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/SpatialSlur/Fields/MeshField3dFactory.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using SpatialSlur.Meshes;
10 |
11 | namespace SpatialSlur.Fields
12 | {
13 | ///
14 | ///
15 | ///
16 | public abstract class MeshField3dFactory
17 | where T : struct
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | public abstract MeshField3d Create(HeMesh3d mesh);
25 |
26 |
27 | ///
28 | ///
29 | ///
30 | ///
31 | ///
32 | public abstract MeshField3d Create(MeshField3d other);
33 |
34 |
35 | ///
36 | ///
37 | ///
38 | ///
39 | ///
40 | public MeshField3d CreateCopy(MeshField3d other)
41 | {
42 | var result = Create(other);
43 | result.Set(other);
44 | return result;
45 | }
46 |
47 |
48 | ///
49 | ///
50 | ///
51 | ///
52 | ///
53 | ///
54 | ///
55 | ///
56 | public MeshField3d CreateCopy(MeshField3d other, Func converter, bool parallel = false)
57 | where U : struct
58 | {
59 | var result = Create(other);
60 | other.Convert(converter, result, parallel);
61 | return result;
62 | }
63 | }
64 | }
65 |
66 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/Delegates.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 |
8 | namespace SpatialSlur.Meshes
9 | {
10 | ///
11 | ///
12 | ///
13 | internal static partial class Delegates
14 | {
15 | ///
16 | ///
17 | ///
18 | ///
19 | internal static class Position3d
20 | where T : IPosition3d
21 | {
22 | ///
23 | ///
24 | ///
25 | public static readonly Func Get = t => t.Position;
26 |
27 | ///
28 | ///
29 | ///
30 | public static readonly Action Set = (t, p) => t.Position = p;
31 | }
32 |
33 |
34 | ///
35 | ///
36 | ///
37 | ///
38 | internal static class Normal3d
39 | where T : INormal3d
40 | {
41 | ///
42 | ///
43 | ///
44 | public static readonly Func Get = t => t.Normal;
45 |
46 | ///
47 | ///
48 | ///
49 | public static readonly Action Set = (t, n) => t.Normal = n;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/Enums/SmoothBoundaryType.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | namespace SpatialSlur.Meshes
7 | {
8 | ///
9 | /// Enum of boundary types for smoothing.
10 | ///
11 | public enum SmoothBoundaryType
12 | {
13 | /// All boundary vertices are fixed.
14 | Fixed,
15 | /// Only degree 2 boundary vertices are fixed.
16 | CornerFixed,
17 | /// Boundary vertices are free.
18 | Free
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/HeGraph3dFactory.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using SpatialSlur;
9 | using SpatialSlur.Meshes.Impl;
10 |
11 | using D = SpatialSlur.SlurMath.Constantsd;
12 |
13 | namespace SpatialSlur.Meshes
14 | {
15 | using G = HeGraph3d;
16 | using V = HeGraph3d.Vertex;
17 | using E = HeGraph3d.Halfedge;
18 |
19 | ///
20 | ///
21 | ///
22 | [Serializable]
23 | public class HeGraph3dFactory : HeGraphFactory
24 | {
25 | ///
26 | public sealed override G Create(int vertexCapacity, int hedgeCapacity)
27 | {
28 | return new G(vertexCapacity, hedgeCapacity);
29 | }
30 |
31 |
32 | ///
33 | ///
34 | ///
35 | ///
36 | ///
37 | ///
38 | ///
39 | ///
40 | public G CreateFromLineSegments(IReadOnlyList endPoints, double tolerance = D.ZeroTolerance, bool allowMultiEdges = false, bool allowLoops = false)
41 | {
42 | return CreateFromLineSegments(endPoints, (v, p) => v.Position = p, tolerance, allowMultiEdges, allowLoops);
43 | }
44 |
45 |
46 | ///
47 | ///
48 | ///
49 | ///
50 | ///
51 | public G CreateFromVertexTopology(HeMesh mesh)
52 | {
53 | var graph = Create(mesh.Vertices.Count, mesh.Halfedges.Count);
54 | graph.AppendVertexTopology(mesh);
55 | return graph;
56 | }
57 |
58 |
59 | ///
60 | ///
61 | ///
62 | ///
63 | ///
64 | public G CreateFromFaceTopology(HeMesh mesh)
65 | {
66 | var graph = Create(mesh.Faces.Count, mesh.Halfedges.Count);
67 | graph.AppendFaceTopology(mesh);
68 | return graph;
69 | }
70 |
71 |
72 | ///
73 | ///
74 | ///
75 | ///
76 | ///
77 | public G CreateFromJson(string path)
78 | {
79 | var result = Create();
80 | Interop.Meshes.ReadFromJson(path, result);
81 | return result;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/HeGraphFactory.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using SpatialSlur.Meshes.Impl;
8 |
9 | namespace SpatialSlur.Meshes
10 | {
11 | using G = HeGraph;
12 | using V = HeGraph.Vertex;
13 | using E = HeGraph.Halfedge;
14 |
15 | ///
16 | ///
17 | ///
18 | [Serializable]
19 | public class HeGraphFactory : HeGraphFactory
20 | {
21 | ///
22 | public sealed override G Create(int vertexCapacity, int hedgeCapacity)
23 | {
24 | return new G(vertexCapacity, hedgeCapacity);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/HeMesh3dFactory.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using SpatialSlur;
9 | using SpatialSlur.Meshes.Impl;
10 |
11 | using D = SpatialSlur.SlurMath.Constantsd;
12 |
13 | namespace SpatialSlur.Meshes
14 | {
15 | using M = HeMesh3d;
16 | using V = HeMesh3d.Vertex;
17 | using E = HeMesh3d.Halfedge;
18 | using F = HeMesh3d.Face;
19 |
20 | ///
21 | ///
22 | ///
23 | [Serializable]
24 | public class HeMesh3dFactory : HeMeshFactory
25 | {
26 | ///
27 | public sealed override M Create(int vertexCapacity, int halfedgeCapacity, int faceCapacity)
28 | {
29 | return new M(vertexCapacity, halfedgeCapacity, faceCapacity);
30 | }
31 |
32 |
33 | ///
34 | ///
35 | ///
36 | ///
37 | public M CreateFromFaceVertexData(IEnumerable vertices, IEnumerable faces)
38 | where T : IEnumerable
39 | {
40 | return CreateFromFaceVertexData(vertices, faces, (v, p) => v.Position = p);
41 | }
42 |
43 |
44 | ///
45 | ///
46 | ///
47 | ///
48 | public M CreateFromPolygons(IEnumerable polygons, double tolerance = D.ZeroTolerance)
49 | where T : IEnumerable
50 | {
51 | return CreateFromPolygons(polygons, (v, p) => v.Position = p, tolerance);
52 | }
53 |
54 |
55 | ///
56 | ///
57 | ///
58 | ///
59 | public M CreateFromOBJ(string path)
60 | {
61 | return CreateFromObj(path, (v, p) => v.Position = p);
62 | }
63 |
64 |
65 | ///
66 | ///
67 | ///
68 | ///
69 | ///
70 | public M CreateFromJson(string path)
71 | {
72 | var result = Create();
73 | Interop.Meshes.ReadFromJson(path, result);
74 | return result;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/HeMeshFactory.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System;
7 | using SpatialSlur.Meshes.Impl;
8 |
9 | namespace SpatialSlur.Meshes
10 | {
11 | using M = HeMesh;
12 | using V = HeMesh.Vertex;
13 | using E = HeMesh.Halfedge;
14 | using F = HeMesh.Face;
15 |
16 | ///
17 | ///
18 | ///
19 | [Serializable]
20 | public class HeMeshFactory : HeMeshFactory
21 | {
22 | ///
23 | public sealed override M Create(int vertexCapacity, int hedgeCapacity, int faceCapacity)
24 | {
25 | return new M(vertexCapacity, hedgeCapacity, faceCapacity);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/Interfaces/IFaceQuadrangulator.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System.Collections.Generic;
7 | using SpatialSlur.Meshes.Impl;
8 |
9 | namespace SpatialSlur.Meshes
10 | {
11 | ///
12 | ///
13 | ///
14 | public interface IFaceQuadrangulator
15 | {
16 | ///
17 | /// Iterates through each quad in the face of the given halfedge.
18 | /// The last 2 vertices from each quad must not belong to the previously returned quad.
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | IEnumerable<(V, V, V, V)> GetQuads(HeMesh.Halfedge start)
26 | where V : HeMesh.Vertex
27 | where E : HeMesh.Halfedge
28 | where F : HeMesh.Face;
29 |
30 |
31 | ///
32 | /// Splits the face of the given halfedge into quads.
33 | ///
34 | ///
35 | ///
36 | ///
37 | ///
38 | ///
39 | void Quadrangulate(HeMesh mesh, E start)
40 | where V : HeMesh.Vertex
41 | where E : HeMesh.Halfedge
42 | where F : HeMesh.Face;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/Interfaces/IFaceTriangulator.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | using System.Collections.Generic;
7 | using SpatialSlur.Meshes.Impl;
8 |
9 | namespace SpatialSlur.Meshes
10 | {
11 | ///
12 | ///
13 | ///
14 | public interface IFaceTriangulator
15 | {
16 | ///
17 | /// Iterates through each triangle in the face of the given halfedge.
18 | /// The last vertex from each triangle must not belong to the previously returned triangle.
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | IEnumerable<(V, V, V)> GetTriangles(HeMesh.Halfedge start)
26 | where V : HeMesh.Vertex
27 | where E : HeMesh.Halfedge
28 | where F : HeMesh.Face;
29 |
30 |
31 | ///
32 | /// Splits the face of the given halfedge into triangles.
33 | ///
34 | ///
35 | ///
36 | ///
37 | ///
38 | ///
39 | void Triangulate(HeMesh mesh, E start)
40 | where V : HeMesh.Vertex
41 | where E : HeMesh.Halfedge
42 | where F : HeMesh.Face;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/Interfaces/INormal3d.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using SpatialSlur;
4 |
5 | /*
6 | * Notes
7 | */
8 |
9 | namespace SpatialSlur.Meshes
10 | {
11 | ///
12 | ///
13 | ///
14 | public interface INormal3d
15 | {
16 | ///
17 | Vector3d Normal { get; set; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/Interfaces/IPosition3d.cs:
--------------------------------------------------------------------------------
1 |
2 | using SpatialSlur;
3 |
4 | /*
5 | * Notes
6 | */
7 |
8 | namespace SpatialSlur.Meshes
9 | {
10 | ///
11 | ///
12 | ///
13 | public interface IPosition3d
14 | {
15 | ///
16 | Vector3d Position { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/TriMesh3d.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | namespace SpatialSlur.Meshes
7 | {
8 | ///
9 | ///
10 | ///
11 | public class TriMesh3d : TriMesh
12 | {
13 | ///
14 | ///
15 | ///
16 | public TriMesh3d()
17 | {
18 | }
19 |
20 |
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | public TriMesh3d(int vertexCount, int faceCount)
27 | : base(vertexCount, faceCount)
28 | {
29 | }
30 |
31 |
32 | ///
33 | ///
34 | ///
35 | ///
36 | public TriMesh3d(TriMesh3d other)
37 | : base(other)
38 | {
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/SpatialSlur/Meshes/TriMesh3f.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | namespace SpatialSlur.Meshes
7 | {
8 | ///
9 | ///
10 | ///
11 | public class TriMesh3f : TriMesh
12 | {
13 | ///
14 | ///
15 | ///
16 | public TriMesh3f()
17 | {
18 | }
19 |
20 |
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | public TriMesh3f(int vertexCount, int faceCount)
27 | : base(vertexCount, faceCount)
28 | {
29 | }
30 |
31 |
32 | ///
33 | ///
34 | ///
35 | ///
36 | public TriMesh3f(TriMesh3f other)
37 | : base(other)
38 | {
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/SpatialSlur/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SpatialSlur")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("SpatialSlur")]
13 | [assembly: AssemblyCopyright("Copyright © David Reeves 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("11db2625-f1c7-4fca-a7d3-f8ac93f99c8a")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | // [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyVersion(SpatialSlur.AssemblyInfo.VersionNumber)]
37 |
38 | // Expose internals
39 | //[assembly: InternalsVisibleTo("SlurGH")]
40 | //[assembly: InternalsVisibleTo("Examples")]
41 |
42 | namespace SpatialSlur
43 | {
44 | ///
45 | ///
46 | ///
47 | public static class AssemblyInfo
48 | {
49 | ///
50 | public const string VersionNumber = "0.3.1.*";
51 | }
52 | }
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/ArrayViewExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System.Collections.Generic;
9 | using System.Linq;
10 | using System.Text;
11 | using System.Threading.Tasks;
12 |
13 | using SpatialSlur.Collections;
14 |
15 | namespace SpatialSlur.Rhino
16 | {
17 | ///
18 | ///
19 | ///
20 | public static class ArrayViewExtensions
21 | {
22 | ///
23 | /// Workaround for lack of support for ref returns in Grasshopper script components
24 | ///
25 | ///
26 | ///
27 | ///
28 | ///
29 | public static T Get(this ArrayView view, int index)
30 | {
31 | return view[index];
32 | }
33 |
34 |
35 | ///
36 | /// Workaround for lack of support for ref returns in Grasshopper script components
37 | ///
38 | ///
39 | ///
40 | ///
41 | ///
42 | public static void Set(this ArrayView view, int index, T item)
43 | {
44 | view[index] = item;
45 | }
46 | }
47 | }
48 |
49 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/BoundingBoxExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using Rhino.Geometry;
9 | using SpatialSlur;
10 |
11 | namespace SpatialSlur.Rhino
12 | {
13 | ///
14 | ///
15 | ///
16 | public static class BoundingBoxExtensions
17 | {
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | public static Interval2d ToInterval2d(this BoundingBox bbox)
24 | {
25 | Vector3d p0 = bbox.Min;
26 | Vector3d p1 = bbox.Max;
27 | return new Interval2d(p0.XY, p1.XY);
28 | }
29 |
30 |
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | public static Interval3d ToInterval3d(this BoundingBox bbox)
37 | {
38 | return new Interval3d(bbox.Min, bbox.Max);
39 | }
40 | }
41 | }
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/GridField3dExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System.Collections.Generic;
9 |
10 | using Rhino.Geometry;
11 | using SpatialSlur;
12 | using SpatialSlur.Fields;
13 |
14 | namespace SpatialSlur.Rhino
15 | {
16 | ///
17 | ///
18 | ///
19 | public static class GridField3dExtensions
20 | {
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | ///
27 | public static Mesh ToPolySoup(this Grid3d field, IEnumerable selection)
28 | {
29 | var mesh = new Mesh();
30 | var verts = mesh.Vertices;
31 | var faces = mesh.Faces;
32 |
33 | (var dx, var dy) = (field.Scale.XY * 0.5);
34 |
35 | // add vertices
36 | foreach (int index in selection)
37 | {
38 | (var x, var y, var z) = field.ToWorldSpace(index);
39 | verts.Add(x - dx, y - dy, z);
40 | verts.Add(x + dx, y - dy, z);
41 | verts.Add(x - dx, y + dy, z);
42 | verts.Add(x + dx, y + dy, z);
43 | }
44 |
45 | // add faces
46 | for (int i = 0; i < verts.Count; i += 4)
47 | faces.AddFace(i, i + 1, i + 3, i + 2);
48 |
49 | return mesh;
50 | }
51 | }
52 | }
53 |
54 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/HeStructureExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System.Collections.Concurrent;
9 | using System.Threading.Tasks;
10 |
11 | using Rhino.Geometry;
12 | using SpatialSlur.Meshes;
13 | using SpatialSlur.Meshes.Impl;
14 |
15 | namespace SpatialSlur.Rhino
16 | {
17 | ///
18 | ///
19 | ///
20 | public static class HeStructureExtensions
21 | {
22 | ///
23 | ///
24 | ///
25 | ///
26 | ///
27 | ///
28 | ///
29 | ///
30 | public static void Transform(this HeStructure graph, Transform xform, bool parallel = false)
31 | where V : HeStructure.Vertex, IPosition3d
32 | where E : HeStructure.Halfedge
33 | {
34 | var verts = graph.Vertices;
35 |
36 | if (parallel)
37 | Parallel.ForEach(Partitioner.Create(0, verts.Count), range => Body(range.Item1, range.Item2));
38 | else
39 | Body(0, verts.Count);
40 |
41 | void Body(int from, int to)
42 | {
43 | for (int i = from; i < to; i++)
44 | {
45 | var v = verts[i];
46 | v.Position = xform.ApplyToPoint(v.Position);
47 | }
48 | }
49 | }
50 |
51 |
52 | ///
53 | ///
54 | ///
55 | ///
56 | ///
57 | ///
58 | ///
59 | ///
60 | public static void SpaceMorph(this HeStructure graph, SpaceMorph xmorph, bool parallel = false)
61 | where V : HeStructure.Vertex, IPosition3d
62 | where E : HeStructure.Halfedge
63 | {
64 | var verts = graph.Vertices;
65 |
66 | if (parallel)
67 | Parallel.ForEach(Partitioner.Create(0, verts.Count), range => Body(range.Item1, range.Item2));
68 | else
69 | Body(0, verts.Count);
70 |
71 | void Body(int from, int to)
72 | {
73 | for (int i = from; i < to; i++)
74 | {
75 | var v = verts[i];
76 | v.Position = xmorph.MorphPoint(v.Position);
77 | }
78 | }
79 | }
80 | }
81 | }
82 |
83 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/ISampledField3dExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using System.Collections.Concurrent;
10 | using System.Linq;
11 | using System.Threading.Tasks;
12 | using System.Drawing;
13 |
14 | using Rhino.Geometry;
15 | using SpatialSlur.Fields;
16 |
17 | namespace SpatialSlur.Rhino
18 | {
19 | ///
20 | ///
21 | ///
22 | public static class ISampledField3dExtensions
23 | {
24 | ///
25 | ///
26 | ///
27 | ///
28 | ///
29 | ///
30 | ///
31 | ///
32 | public static PointCloud ToPointCloud(this ISampledField3d field, Func getColor, bool parallel = false)
33 | where T : struct
34 | {
35 | var cloud = new PointCloud(field.Points.Select(p => new Point3d(p.X, p.Y, 0.0)));
36 |
37 | if (parallel)
38 | Parallel.ForEach(Partitioner.Create(0, field.Count), range => Body(range.Item1, range.Item2));
39 | else
40 | Body(0, field.Count);
41 |
42 | void Body(int from, int to)
43 | {
44 | var vals = field.Values;
45 |
46 | for (int i = from; i < to; i++)
47 | cloud[i].Color = getColor(vals[i]);
48 | }
49 |
50 | return cloud;
51 | }
52 | }
53 | }
54 |
55 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/Interval2dExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using Rhino.Geometry;
9 | using SpatialSlur;
10 |
11 | namespace SpatialSlur.Rhino
12 | {
13 | ///
14 | ///
15 | ///
16 | public static partial class Interval2dExtensions
17 | {
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | public static BoundingBox ToBoundingBox(this Interval2d interval)
24 | {
25 | var x = interval.X;
26 | var y = interval.Y;
27 | return new BoundingBox(x.A, y.A, 0.0, x.B, y.B, 0.0);
28 | }
29 | }
30 | }
31 |
32 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/Interval3dExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using Rhino.Geometry;
9 | using SpatialSlur;
10 |
11 | namespace SpatialSlur.Rhino
12 | {
13 | ///
14 | ///
15 | ///
16 | public static partial class Interval3dExtensions
17 | {
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | public static BoundingBox ToBoundingBox(this Interval3d interval)
24 | {
25 | var x = interval.X;
26 | var y = interval.Y;
27 | var z = interval.Z;
28 | return new BoundingBox(x.A, y.A, z.A, x.B, y.B, z.B);
29 | }
30 | }
31 | }
32 |
33 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/LineExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 |
9 | using Rhino.Geometry;
10 | using SpatialSlur;
11 |
12 | namespace SpatialSlur.Rhino
13 | {
14 | ///
15 | ///
16 | ///
17 | public static class LineExtensions
18 | {
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | public static Interval3d ToInterval3d(this Line line)
25 | {
26 | return new Interval3d(line.From, line.To);
27 | }
28 | }
29 | }
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/Orient3dExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using Rhino.Geometry;
9 | using SpatialSlur;
10 |
11 | using Vec3d = Rhino.Geometry.Vector3d;
12 |
13 | namespace SpatialSlur.Rhino
14 | {
15 | ///
16 | ///
17 | ///
18 | public static partial class Orient3dExtensions
19 | {
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | public static Plane ToPlane(this Orient3d orient)
26 | {
27 | return new Plane(
28 | orient.Translation,
29 | orient.Rotation.X,
30 | (Vec3d)orient.Rotation.Y
31 | );
32 | }
33 | }
34 | }
35 |
36 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/PlaneExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 |
9 | using Rhino.Geometry;
10 | using SpatialSlur;
11 |
12 | namespace SpatialSlur.Rhino
13 | {
14 | ///
15 | ///
16 | ///
17 | public static class PlaneExtensions
18 | {
19 | ///
20 | /// Returns the transformation matrix defined by this plane.
21 | ///
22 | ///
23 | ///
24 | public static Transform ToTransform(this Plane plane)
25 | {
26 | return RhinoFactory.Transform.CreateFromPlane(plane);
27 | }
28 |
29 |
30 | ///
31 | /// Returns the inverse of the transformation matrix defined by this plane.
32 | ///
33 | ///
34 | ///
35 | public static Transform ToTransformInverse(this Plane plane)
36 | {
37 | return RhinoFactory.Transform.CreateInverseFromPlane(plane);
38 | }
39 |
40 |
41 | ///
42 | ///
43 | ///
44 | ///
45 | ///
46 | public static Orient3d ToOrient3d(this Plane plane)
47 | {
48 | return new Orient3d(OrthoBasis3d.CreateFromXY(plane.XAxis, plane.YAxis), plane.Origin);
49 | }
50 | }
51 | }
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/Point3dExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 |
9 | using Rhino.Geometry;
10 |
11 | namespace SpatialSlur.Rhino
12 | {
13 | ///
14 | ///
15 | ///
16 | public static class Point3dExtensions
17 | {
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | ///
24 | ///
25 | public static Point3d LerpTo(this Point3d point, Point3d other, double factor)
26 | {
27 | return point + (other - point) * factor;
28 | }
29 |
30 |
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | ///
37 | public static double SquareDistanceTo(this Point3d point, Point3d other)
38 | {
39 | Vector3d v = other - point;
40 | return v.SquareLength;
41 | }
42 | }
43 | }
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/PriorityQueueExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 |
10 | using SpatialSlur.Collections;
11 |
12 | namespace SpatialSlur.Rhino
13 | {
14 | ///
15 | ///
16 | ///
17 | public static class PriorityQueueExtensions
18 | {
19 | ///
20 | /// Workaround for lack of support for ValueTuple in Grasshopper script components
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | ///
27 | public static void GetMin(this PriorityQueue queue, out K key, out V value)
28 | where K : IComparable
29 | {
30 | (key, value) = queue.Min;
31 | }
32 |
33 |
34 | ///
35 | /// Workaround for lack of support for ValueTuple in Grasshopper script components
36 | ///
37 | ///
38 | ///
39 | ///
40 | ///
41 | ///
42 | public static void RemoveMin(this PriorityQueue queue, out K key, out V value)
43 | where K : IComparable
44 | {
45 | (key, value) = queue.RemoveMin();
46 | }
47 | }
48 | }
49 |
50 | #endif
--------------------------------------------------------------------------------
/SpatialSlur/Rhino/Extensions/QuadStripExtensions.cs:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Notes
4 | */
5 |
6 | #if USING_RHINO
7 |
8 | using System;
9 | using System.Collections.Concurrent;
10 | using System.Drawing;
11 |
12 | using Rhino.Geometry;
13 | using SpatialSlur.Meshes;
14 | using SpatialSlur.Meshes.Impl;
15 |
16 | using Vec3d = Rhino.Geometry.Vector3d;
17 | using Vec3f = Rhino.Geometry.Vector3f;
18 |
19 | namespace SpatialSlur.Rhino
20 | {
21 | ///
22 | ///
23 | ///
24 | public static class QuadStripExtensions
25 | {
26 | ///
27 | ///
28 | ///
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | public static Mesh ToMesh(this QuadStrip strip)
35 | where V : HeMesh.Vertex, IPosition3d
36 | where E : HeMesh