PolyLink
A library to allow manipulation of geometry from within Mathematica
 All Classes Namespaces Files Functions Variables Properties
PolyIO.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using Wolfram.NETLink;
7 
8 namespace PolyLink
9 {
10  public static class PolyIO
11  {
12  public static Polyhedron PolyFromName(Expr name)
13  {
14  return PolyFromExpr((
15  "{{" +
16  "PolyhedronData[{0}][[1]][[1]]," +
17  "Map[# - 1 &, PolyhedronData[{0}][[1]][[2]][[1]], {{2}}]" +
18  "}}"
19  ).MsEvalWith(name));
20  }
21 
22  //TODO HalfEdges appear to be going clockwise instead of counter-clockwise!! This could get really bad fast!!
23 
24  public static Polyhedron PolyFromExpr(Expr polyData)
25  {
26  var pointsExpr = polyData.Part(1);
27  var facetsExpr = polyData.Part(2);
28 
29  //TODO: Verify that input is valid
30  var pointList = pointsExpr.Parts().Select(e => new PointRef(e)).ToList();
31 
32  //Console.WriteLine("Point list is: {" + String.Join(",",pointList) + "}");
33 
34  var facetList = facetsExpr.Parts().Select(fe => FacetFromExpr(pointList, fe)).ToList();
35 
36  var poly = new Polyhedron();
37 
38  foreach (var facet in facetList)
39  {
40  poly.AddFacet(facet);
41  }
42 
43  //Refer to "Connect opposite halfEdges"
44  var halfEdges = facetList.SelectMany(f => f.HalfEdges).ToList();
45 
46  var dict = halfEdges.ToDictionary(halfEdge => halfEdge.EndPointPacket);
47 
48  foreach (var halfEdge in halfEdges)
49  {
50  halfEdge.Opposite = dict[halfEdge.OppositesEndPointPacket];
51  halfEdge.Start = halfEdge.Opposite.End;
52  halfEdge.End = halfEdge.Opposite.Start;
53  }
54  return poly;
55  }
56 
57  public static Facet FacetFromExpr(IList<PointRef> points, Expr f)
58  {
59  var pointIndices = f.Parts()
60  .Select(p => (int) p.AsInt64()); //Convert to point indices
61 
62  //Console.WriteLine("Facet has point indices {" + String.Join(",", pointIndices) + "}");
63 
64  var halfEdges = pointIndices
65  .Select(i => points[i])//Get referenced points
66  .CircularTuples(2)
67  .Select(pair => new HalfEdge(pair[0], pair[1]))//Get point pairs (to represent half edges)
68  .ToList();
69 
70  //Console.WriteLine(String.Join("\n", halfEdges));
71  //Console.WriteLine("-");
72 
73  foreach (var halfEdgePair in halfEdges.CircularTuples(2))
74  {
75  halfEdgePair[0].LinkNext(halfEdgePair[1]);
76  }
77  return new Facet(halfEdges.First());
78  }
79 
80  public static Polyhedron TestTriangle
81  {
82  get
83  {
84  var tetrahedron = PolyFromName("\"Tetrahedron\"".MsEvalWith());
85  var triangle = new Polyhedron();
86  triangle.AddFacet(tetrahedron.Facets.Skip(1).First().CloneWithAllHalfEdgesCloned);
87  return triangle;
88  }
89  }
90  }
91 }