GaelVanhalst

Unwrapper: Polygon

Jan 25th, 2016
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.78 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows;
  5. using System.Windows.Media;
  6. using Unwrapper.CalculationClasses;
  7.  
  8. namespace Unwrapper.Elements
  9. {
  10.     [Serializable]
  11.     public class PolygonUW
  12.     {
  13.         public List<Vertex> Vertices { get; private set; }
  14.         public List<Edge> Edges { get; private set; }
  15.         public bool Selected = false;
  16.         private static readonly Brush DefaultColor = Brushes.Gray.Clone();
  17.         private static readonly Brush SelectedColor = Brushes.Blue.Clone();
  18.  
  19.         //Create polygon
  20.         public PolygonUW(List<Vertex> vertices)
  21.         {
  22.             Vertices = vertices;
  23.             DefaultColor.Opacity = 0.2;
  24.             SelectedColor.Opacity = 0.4;
  25.  
  26.             Edges=new List<Edge>();
  27.             for (int i = 0; i < vertices.Count; i++)
  28.             {
  29.                 var edge = new Edge(vertices[i], Vertices[(i + 1)%Vertices.Count]);
  30.                 Edges.Add(edge);
  31.  
  32.                 vertices[i].Polygon = this;
  33.             }
  34.         }
  35.  
  36.         //Draw polygon
  37.         public void DrawPolygon(DrawingContext drawingContext)
  38.         {
  39.             //Cull invalid polygons
  40.             if (Vertices.Count < 3) return;
  41.  
  42.             //Fill polygon if selected
  43.             if (Selected)
  44.             {
  45.                 var segments = new LineSegment[Vertices.Count - 1];
  46.                 for (int i = 1; i < Vertices.Count; i++)
  47.                 {
  48.  
  49.                     segments[i - 1] = new LineSegment(ScreenTransform.UvToScreen(Vertices[i].Group.Position), false);
  50.                 }
  51.                 var figure = new PathFigure(ScreenTransform.UvToScreen(Vertices[0].Group.Position), segments, true);
  52.                 var geo = new PathGeometry(new[] {figure});
  53.                 Brush brush;
  54.                 if (Selected) brush = SelectedColor;
  55.                 else brush = DefaultColor;
  56.  
  57.                 drawingContext.DrawGeometry(brush, null, geo);
  58.             }
  59.  
  60.             //Draw edges
  61.             foreach (var edge in Edges)
  62.             {
  63.                 if(!edge.Selected)
  64.                 edge.DrawEdge(drawingContext);
  65.             }
  66.         }
  67.  
  68.         //check if clicked on the polygon
  69.         public bool PointInsidePolygon(Point point)
  70.         {
  71.             var screenVertex0=ScreenTransform.UvToScreen(Vertices[0].Group.Position);
  72.             float xMin;
  73.             float xMax = xMin = (float)(screenVertex0.X);
  74.             float yMin;
  75.             float yMax = yMin = (float)(screenVertex0.Y);
  76.  
  77.  
  78.             foreach (var vertex in Vertices)
  79.             {
  80.                 var screenVertex = ScreenTransform.UvToScreen(vertex.Group.Position);
  81.                 xMin = (float)Math.Min(xMin, screenVertex.X);
  82.                 xMax = (float)Math.Max(xMax, screenVertex.X);
  83.  
  84.                 yMin = (float)Math.Min(yMin, screenVertex.Y);
  85.                 yMax = (float)Math.Max(yMax, screenVertex.Y);
  86.             }
  87.  
  88.             //Check if point is in the bounding box around polygon
  89.             if (point.X < xMin || point.X > xMax || point.Y < yMin || point.Y > yMax) return false;
  90.  
  91.             return PointInPolygon(point);
  92.         }
  93.  
  94.         //Check if given point is in the polygon
  95.         private bool PointInPolygon(Point point)
  96.         {
  97.             List<Point> transformedVertices=new List<Point>();
  98.             foreach (var vertex in Vertices)
  99.             {
  100.                 transformedVertices.Add(ScreenTransform.UvToScreen(vertex.Group.Position));
  101.             }
  102.  
  103.             int i, j, nvert = Vertices.Count();
  104.             bool c = false;
  105.            
  106.             for (i = 0, j = nvert - 1; i < nvert; j = i++)
  107.             {
  108.                 if ((((transformedVertices[i].Y) >= point.Y) != (transformedVertices[j].Y >= point.Y)) &&
  109.                     (point.X <=
  110.                      (transformedVertices[j].X - transformedVertices[i].X) *
  111.                      (point.Y - transformedVertices[i].Y) /
  112.                      (transformedVertices[j].Y - transformedVertices[i].Y) + transformedVertices[i].X)
  113.                     )
  114.                     c = !c;
  115.             }
  116.  
  117.             return c;
  118.         }
  119.  
  120.         //Check which polygons are selected by clicking
  121.         static public PolygonUW SelectPolygon(List<PolygonUW> Polygons, Point position)
  122.         {
  123.             PolygonUW result = null;
  124.             foreach (var polygon in Polygons)
  125.             {
  126.                 if (polygon.PointInsidePolygon(position)) result = polygon;
  127.             }
  128.  
  129.             return result;
  130.         }
  131.  
  132.         //Check which polygons are selected by selection box
  133.         static public List<PolygonUW> SelectPolygons(List<PolygonUW> polygons, Point position1, Point position2,bool completely)
  134.         {
  135.             List<PolygonUW> result = new List<PolygonUW>();
  136.             float xMin = (float)Math.Min(position1.X, position2.X);
  137.             float xMax = (float)Math.Max(position1.X, position2.X);
  138.             float yMin = (float)Math.Min(position1.Y, position2.Y);
  139.             float yMax = (float)Math.Max(position1.Y, position2.Y);
  140.  
  141.             foreach (var polygon in polygons)
  142.             {
  143.                 bool allPointsIn = true;
  144.  
  145.                 foreach (var point in polygon.Vertices)
  146.                 {
  147.                     var position=ScreenTransform.UvToScreen(point.Group.Position);
  148.                     if (!VertexGroup.PointInBox(xMin, xMax, yMin, yMax, position)) allPointsIn = false;
  149.                     else if (!completely)
  150.                     {
  151.                         allPointsIn = true;
  152.                         break;
  153.                     }
  154.                 }
  155.  
  156.                 //If the polygons need to completely in the selection box, then all points need to be in the selection box
  157.                 //else one of the edges of the polygon need to interesect with a line of the selectionbox
  158.                 if(allPointsIn)
  159.                 {
  160.                     result.Add(polygon);
  161.                 }
  162.                 else if(!completely)
  163.                 {
  164.                     foreach (var edge in polygon.Edges)
  165.                     {
  166.                         var edge1 = ScreenTransform.UvToScreen(edge.VertexOne.Group.Position);
  167.                         var edge2 = ScreenTransform.UvToScreen(edge.VertexTwo.Group.Position);
  168.                         var position3 = new Point(position2.X, position1.Y);
  169.                         var position4 = new Point(position1.X, position2.Y);
  170.                         if (
  171.                             Edge.LineIntersectsWithEdge(edge1, edge2, position1, position3) ||
  172.                             Edge.LineIntersectsWithEdge(edge1, edge2, position3, position2) ||
  173.                             Edge.LineIntersectsWithEdge(edge1, edge2, position2, position4) ||
  174.                             Edge.LineIntersectsWithEdge(edge1, edge2, position4, position1))
  175.                         {
  176.                             result.Add(polygon);
  177.                             break;
  178.                         }
  179.                     }
  180.                 }
  181.             }
  182.  
  183.             return result;
  184.         }
  185.  
  186.         //Selected all connected polygons, based on click
  187.         static public List<PolygonUW> SelectPolygonIsland(List<PolygonUW> polygons, Point position)
  188.         {
  189.             var result = new List<PolygonUW>();
  190.             foreach (var polygon in polygons.Where(polygon => polygon.PointInsidePolygon(position)).Where(polygon => !result.Contains(polygon)))
  191.             {
  192.                 result.Add(polygon);
  193.                 AddAllConectedPolygons(polygon,result);
  194.             }
  195.             return result;
  196.         }
  197.  
  198.         //Selected all connected polygons, based on selectionbox
  199.         static public List<PolygonUW> SelectPolygonIslands(List<PolygonUW> polygons, Point position1, Point position2, bool completely)
  200.         {
  201.             List<PolygonUW> result = new List<PolygonUW>();
  202.             float xMin = (float)Math.Min(position1.X, position2.X);
  203.             float xMax = (float)Math.Max(position1.X, position2.X);
  204.             float yMin = (float)Math.Min(position1.Y, position2.Y);
  205.             float yMax = (float)Math.Max(position1.Y, position2.Y);
  206.  
  207.             var polygonIslands = new List<List<PolygonUW>>();
  208.             var alreadyAddedPolygons = new List<PolygonUW>();
  209.  
  210.             foreach (var polygon in polygons)
  211.             {
  212.                 if (alreadyAddedPolygons.Contains(polygon)) continue;
  213.                 var polygonIsland = new List<PolygonUW> {polygon};
  214.                 AddAllConectedPolygons(polygon, polygonIsland);
  215.  
  216.                 polygonIslands.Add(polygonIsland);
  217.                 alreadyAddedPolygons.AddRange(polygonIsland);
  218.             }
  219.  
  220.  
  221.             foreach (var polygonIsland in polygonIslands)
  222.             {
  223.                 var allPointsIn = true;
  224.  
  225.                 foreach (var polygon in polygonIsland)
  226.                 {
  227.                     var doneChecking = false;
  228.                     foreach (var point in polygon.Vertices)
  229.                     {
  230.                         var position = ScreenTransform.UvToScreen(point.Group.Position);
  231.                         if (!VertexGroup.PointInBox(xMin, xMax, yMin, yMax, position)) allPointsIn = false;
  232.                         else if (!completely)
  233.                         {
  234.                             allPointsIn = true;
  235.                             doneChecking = true;
  236.                             break;
  237.                         }
  238.                     }
  239.                     if (doneChecking) break;
  240.                 }
  241.  
  242.                 //If the polygons need to completely in the selection box, then all points need to be in the selection box
  243.                 //else one of the edges of one of the polygons need to interesect with a line of the selectionbox
  244.                 if (allPointsIn)
  245.                 {
  246.                     result.AddRange(polygonIsland);
  247.                 }
  248.                 else if (!completely)
  249.                 {
  250.                     var gotHit = false;
  251.                     foreach (var polygon in polygonIsland)
  252.                     {
  253.                        
  254.                         foreach (var edge in polygon.Edges)
  255.                         {
  256.                             var edge1 = ScreenTransform.UvToScreen(edge.VertexOne.Group.Position);
  257.                             var edge2 = ScreenTransform.UvToScreen(edge.VertexTwo.Group.Position);
  258.                             var position3 = new Point(position2.X, position1.Y);
  259.                             var position4 = new Point(position1.X, position2.Y);
  260.                             if (!Edge.LineIntersectsWithEdge(edge1, edge2, position1, position3) &&
  261.                                 !Edge.LineIntersectsWithEdge(edge1, edge2, position3, position2) &&
  262.                                 !Edge.LineIntersectsWithEdge(edge1, edge2, position2, position4) &&
  263.                                 !Edge.LineIntersectsWithEdge(edge1, edge2, position4, position1)) continue;
  264.                             gotHit = true;
  265.                             break;
  266.                         }
  267.                         if (!gotHit) continue;
  268.                         result.AddRange(polygonIsland);
  269.                         break;
  270.                     }
  271.                 }
  272.             }
  273.  
  274.             return result;
  275.         }
  276.  
  277.         //Add all polygons connected to the given polygon
  278.         static private void AddAllConectedPolygons(PolygonUW polygon, List<PolygonUW> polygonList)
  279.         {
  280.             foreach (var vertexPolygon in polygon.Vertices)
  281.             {
  282.                 foreach (var vertex in vertexPolygon.Group.Vertices)
  283.                 {
  284.                     if(!polygonList.Contains(vertex.Polygon))
  285.                     {
  286.                         polygonList.Add(vertex.Polygon);
  287.                         AddAllConectedPolygons(vertex.Polygon, polygonList);
  288.                     }
  289.                 }
  290.             }
  291.         }
  292.     }
  293. }
Advertisement
Add Comment
Please, Sign In to add comment