public MPolygon WriteMPolygon(IPolygon polygon) { var mPolygon = new MPolygon(); var mpolygonLoopCollection = GetMPolygonLoopCollection(polygon); try { foreach (var mpolygonLoop in mpolygonLoopCollection) { var mPolygonLoop = (MPolygonLoop)mpolygonLoop; mPolygon.AppendMPolygonLoop(mPolygonLoop, false, 0.0); } } finally { foreach (var mpolygonLoop in mpolygonLoopCollection) { if (mpolygonLoop is IDisposable) { (mpolygonLoop as IDisposable).Dispose(); } } } mPolygon.BalanceTree(); return(mPolygon); }
public IMultiPolygon ReadMultiPolygon(MPolygon multiPolygon) { var list = new List <Polygon>(); int num = multiPolygon.NumMPolygonLoops - 1; for (int i = 0; i <= num; i++) { if (multiPolygon.GetLoopDirection(i) == 0) { var coordinates = this.GetMPolygonLoopCoordinates(multiPolygon, multiPolygon.GetMPolygonLoopAt(i)); var shell = (LinearRing)this.GeometryFactory.CreateLinearRing(coordinates); var list2 = new List <LinearRing>(); IntegerCollectionEnumerator enumerator = multiPolygon.GetChildLoops(i).GetEnumerator(); while (enumerator.MoveNext()) { int current = enumerator.Current; if (multiPolygon.GetLoopDirection(current) == LoopDirection.Annotation) // 1???? { var coordinates1 = this.GetMPolygonLoopCoordinates(multiPolygon, multiPolygon.GetMPolygonLoopAt(current)); list2.Add((LinearRing)this.GeometryFactory.CreateLinearRing(coordinates1)); } } list.Add((Polygon)this.GeometryFactory.CreatePolygon(shell, list2.ToArray())); } } return(this.GeometryFactory.CreateMultiPolygon(list.ToArray())); }
public MPolygon WriteMPolygon(MultiPolygon multiPolygon) { var mPolygon = new MPolygon(); var geometries = multiPolygon.Geometries; for (int i = 0; i < geometries.Length; i++) { var polygon = (IPolygon)geometries[i]; var mpolygonLoopCollection = GetMPolygonLoopCollection(polygon); try { foreach (var mpolygonLoop in mpolygonLoopCollection) { var mPolygonLoop = (MPolygonLoop)mpolygonLoop; mPolygon.AppendMPolygonLoop(mPolygonLoop, false, 0.0); } } finally { foreach (var mpolygonLoop in mpolygonLoopCollection) { if (mpolygonLoop is IDisposable) { (mpolygonLoop as IDisposable).Dispose(); } } } } mPolygon.BalanceTree(); return(mPolygon); }
// fCWALL public void ExtrudeToCeiling(double zMin) { Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor; // TODO znalezc dlaczego nie wyciaga scian na zewnatrz polygonu try { Polyline pline = Entity as Polyline; Point3dCollection points = new Point3dCollection(); pline.GetStretchPoints(points); MPolygonLoop mPolyLoop = new MPolygonLoop(); for (int i = 0; i <= pline.NumberOfVertices - 1; i++) { mPolyLoop.Add(new BulgeVertex(new Point2d(points[i].X, points[i].Y), 0)); } // Dodaje na koncu poczatek polilini tak zeby zamknac mPolyLoop.Add(new BulgeVertex(new Point2d(points[0].X, points[0].Y), 0)); MPolygon mPoly = new MPolygon(); mPoly.AppendMPolygonLoop(mPolyLoop, false, 0); List <Entity> obsts = new List <Entity>(); // Start a transaction using (Transaction acTrans = acDoc.Database.TransactionManager.StartTransaction()) { // Request for objects to be selected in the drawing area PromptSelectionResult acSSPrompt = acDoc.Editor.GetSelection(); // If the prompt status is OK, objects were selected if (acSSPrompt.Status == PromptStatus.OK) { SelectionSet acSSet = acSSPrompt.Value; foreach (SelectedObject acSSObj in acSSet) { // Check to make sure a valid SelectedObject object was returned if (acSSObj != null) { // Open the selected object for write Entity acEnt = acTrans.GetObject(acSSObj.ObjectId, OpenMode.ForRead) as Entity; obsts.Add(acEnt); } } } } CheckIntersection(pline, mPoly, obsts, zMin); // Usun polilinie Utils.Utils.DeleteObject(pline.ObjectId); } catch (System.Exception e) { ed.WriteMessage("Program exception: " + e.ToString()); } }
// Start is called before the first frame update void Start() { var poly = new MPolygon(); poly.Add(12); poly.Add(15); poly.Add(28); List <MPolygon> newPolys; poly.Cut(new PolygonSide(12, 15), 28, out newPolys, 3); Misc.DebugList("Polys: ", newPolys); }
private bool isOnPolygonSide(Vector3 intersection, MPolygon polygon, out PolygonSide intersectSide) { foreach (var side in polygon.GetSides()) { if (LinearAlgebra.isInSegment(intersection, vertices[side.left], vertices[side.right])) { intersectSide = side; return(true); } } intersectSide = null; return(false); }
private bool isPolygonCorner(Vector3 intersection, MPolygon polygon, out int intersectCorner) { foreach (var corner in polygon) { if (LinearAlgebra.IsNear(intersection, vertices[corner])) { intersectCorner = corner; return(true); } } intersectCorner = -1; return(false); }
internal void Reduce(List <Vector3> vertices) { var newPoly = new MPolygon(); foreach (var vertex in this) { if (!newPoly.Contains(vertex)) { newPoly.Add(vertex); } } this.Clear(); this.AddRange(newPoly); }
public List <MPolygon> Triangulate() { List <MPolygon> polys = new List <MPolygon> (); for (int i = 2; i < Count; i++) { MPolygon newPoly = new MPolygon(); newPoly.Add(this [0]); newPoly.Add(this [i - 1]); newPoly.Add(this [i]); polys.Add(newPoly); } return(polys); }
/// <summary>Создаём MPolygon из Geometry.TPolygon</summary> /// <param name="wp"> Geometry.TPolygon </param> /// <returns> MPolygon </returns> public MPolygon MakePolygon(Geometry.TPolygon wp) { var mpoly = new MPolygon(); var acPolyColl = ConvertPolygon(wp); foreach (MPolygonLoop loop in acPolyColl) { mpoly.AppendMPolygonLoop(loop, false, 0); } mpoly.PatternScale = 50; mpoly.PatternSpace = 50; mpoly.SetPattern(HatchPatternType.PreDefined, "ANSI37"); return(mpoly); }
private void PolygonButton_Click(object sender, RoutedEventArgs e) { MPolygon mp; MLngLatCollection xys = new MLngLatCollection(); xys.Add(map.Center); xys.Add(new MLngLat(map.Center.LngX + 0.0001, map.Center.LatY + 0.0001)); xys.Add(new MLngLat(map.Center.LngX - 0.0041, map.Center.LatY - 0.0001)); xys.Add(new MLngLat(map.Center.LngX + 0.0021, map.Center.LatY + 0.0031)); xys.Add(new MLngLat(map.Center.LngX + 0.0051, map.Center.LatY - 0.0031)); map.Children.Add(mp = new MPolygon() { LngLats = xys, LineColor = Colors.Green, LineThickness = 4 }); }
/// <summary> /// Проверка наличия самопересечений в полилинии /// True - нет самопересечений /// </summary> public static bool CheckCross(this Polyline pline) { using var mpoly = new MPolygon(); var isValidBoundary = false; try { mpoly.AppendLoopFromBoundary(pline, true, Tolerance.Global.EqualPoint); if (mpoly.NumMPolygonLoops != 0) { isValidBoundary = true; } } catch { // Самопересечение } return(isValidBoundary); }
Coordinate[] GetMPolygonLoopCoordinates(MPolygon multiPolygon, MPolygonLoop multiPolygonLoop) { var coordinateList = new CoordinateList(); int num = multiPolygonLoop.Count - 1; for (var i = 0; i <= num; i++) { BulgeVertex bulgeVertex = multiPolygonLoop[i]; if (Math.Abs(bulgeVertex.Bulge) < 1e-06) { coordinateList.Add(this.ReadCoordinate(bulgeVertex.Vertex), this.AllowRepeatedCoordinates); } else { Point2d vertex; if (i + 1 <= multiPolygonLoop.Count - 1) { vertex = multiPolygonLoop[i + 1].Vertex; } else { vertex = multiPolygonLoop[0].Vertex; } var tessellatedCurveCoordinates = this.GetTessellatedCurveCoordinates(multiPolygon.Ecs, bulgeVertex.Vertex, vertex, bulgeVertex.Bulge); for (var j = 0; j < tessellatedCurveCoordinates.Length; j++) { coordinateList.Add(tessellatedCurveCoordinates[j], this.AllowRepeatedCoordinates); } } } if (!coordinateList[0].Equals2D(coordinateList[coordinateList.Count - 1])) { coordinateList.Add(coordinateList[0]); } return(coordinateList.ToCoordinateArray()); }
private void UpdatePoly(MPolygon poly) { }
// fWALL public void ExtrudeWall(double zmin, double zmax, double height) { Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor; // TODO: poprawic narozniki w przypadku prostopadlych scian // skosy - moglyby byc po zewnetrznej stronie try { Polyline pline = Entity as Polyline; Point3dCollection points = new Point3dCollection(); pline.GetStretchPoints(points); MPolygonLoop mPolyLoop = new MPolygonLoop(); for (int i = 0; i <= pline.NumberOfVertices - 1; i++) { mPolyLoop.Add(new BulgeVertex(new Point2d(points[i].X, points[i].Y), 0)); } // Dodaje na koncu poczatek polilini tak zeby zamknac mPolyLoop.Add(new BulgeVertex(new Point2d(points[0].X, points[0].Y), 0)); MPolygon mPoly = new MPolygon(); mPoly.AppendMPolygonLoop(mPolyLoop, false, 0); for (int i = 0; i < pline.NumberOfVertices - 1; i++) { Point3d middle = new Point3d(); if (points[i].X == points[i + 1].X) { middle = new Point3d(points[i].X + Utils.Utils.snapUnit.X, (points[i].Y + points[i + 1].Y) / 2, points[i].Z); } else if (points[i].Y == points[i + 1].Y) { middle = new Point3d((points[i].X + points[i + 1].X) / 2, points[i].Y + Utils.Utils.snapUnit.Y, points[i].Z); } else { middle = new Point3d((points[i].X + points[i + 1].X / 2) + Utils.Utils.snapUnit.X, (points[i].Y + points[i + 1].Y / 2) + Utils.Utils.snapUnit.Y, points[i].Z); } if (mPoly.IsPointInsideMPolygon(middle, 0).Count == 1) { if (points[i].X == points[i + 1].X) { Utils.Utils.CreateBox(points[i].X, points[i + 1].X - Utils.Utils.snapUnit.X, points[i].Y, points[i + 1].Y, zmin, zmax); } else if (points[i].Y == points[i + 1].Y) { Utils.Utils.CreateBox(points[i].X, points[i + 1].X, points[i].Y, points[i + 1].Y - Utils.Utils.snapUnit.Y, zmin, zmax); } else { Utils.Utils.Bresenham(points[i].X, points[i].Y, points[i + 1].X, points[i + 1].Y, height, zmin); } } else if (mPoly.IsPointInsideMPolygon(middle, 0).Count == 0) { if (points[i].X == points[i + 1].X) { Utils.Utils.CreateBox(points[i].X, points[i + 1].X + Utils.Utils.snapUnit.X, points[i].Y, points[i + 1].Y, zmin, zmax); } else if (points[i].Y == points[i + 1].Y) { Utils.Utils.CreateBox(points[i].X, points[i + 1].X, points[i].Y, points[i + 1].Y + Utils.Utils.snapUnit.Y, zmin, zmax); } else { Utils.Utils.Bresenham(points[i].X, points[i].Y, points[i + 1].X, points[i + 1].Y, height, zmin); } } } // Usun polilinie Utils.Utils.DeleteObject(pline.ObjectId); } catch (System.Exception e) { ed.WriteMessage("Program exception: " + e.ToString()); } }
private int CutPolygon(MPolygon polygon, out List <MPolygon> newPolys, PolygonSide side, int corner) { return(polygon.Cut(side, corner, out newPolys, vertices.Count)); }
private int GetOwnerOfPolygon(List <HashSet <int> > bounds, Dictionary <int, int> cutNodes, MPolygon polygon) { int result = -1; foreach (var vertex in polygon) { if (!cutNodes.ContainsValue(vertex)) { for (int i = 0; i < bounds.Count; i++) { var boundary = bounds[i]; if (boundary.Contains(vertex)) { if (result == -1 || result == i) { result = i; } else { Debug.LogWarning("Vertex " + vertex + " is Part of multiple bounds " + polygon.ToString()); return(-2); } } } } } if (result != -1) { return(result); } else { // Debug.LogWarning ("No Owner found for " + polygon.ToString ()); // DebugAtPolygon (vertices, polygon, Color.black); return(-1); } }
private void DebugAtPolygon(List <Vector3> vertices, MPolygon t, Color c) { Vector3 barycenter = (vertices[t[0]] + vertices[t[1]] + vertices[t[2]]) / 3; Misc.DebugSphere(barycenter, c, "Hit: " + t.ToString()); }
private List <int> CutUpPolygons(int triangle, PolygonSide side, Vector3 pointSide, int corner, Vector3 pointCorner, out List <MPolygon> newPolys, out MPolygon remove) { var polys = polyAtTriangle[triangle]; var cutPointIndices = new List <int> (); newPolys = null; remove = null; if (!LinearAlgebra.isInSegment(pointCorner, vertices[side.left], vertices[side.right])) { for (int j = 0; j < polys.Count; j++) { var polygon = polys[j]; var numNewVerts = -1; bool entryInPolygon = isPolygonCorner(pointCorner, polygon, out corner); bool exitInPolygon = isOnPolygonSide(pointSide, polygon, out side); if (entryInPolygon && exitInPolygon) { remove = polygon; numNewVerts = CutPolygon(polygon, out newPolys, side, corner); } if (numNewVerts > 0) { var newV1 = vertices.Count; if (!vertices.Contains(pointSide)) { vertices.Add(pointSide); normals.Add(GetMiddleNormal(side, pointSide)); cutPointIndices.Add(newV1); } else { var newIndex = vertices.IndexOf(pointSide); foreach (var pol in newPolys) { int index = pol.IndexOf(newV1); pol.RemoveAt(index); pol.Insert(index, newIndex); } cutPointIndices.Add(newIndex); } break; } } } return(cutPointIndices); }
private List <int> CutUpPolygons(int triangle, PolygonSide pairEntry, PolygonSide pairExit, Vector3 pointEntry, Vector3 pointExit, out List <MPolygon> newPolys, out MPolygon remove) { var polys = polyAtTriangle[triangle]; newPolys = null; remove = null; var cutPointIndices = new List <int> (); for (int j = 0; j < polys.Count; j++) { var polygon = polys[j]; var numNewVerts = -1; bool entryInPolygon = isOnPolygonSide(pointEntry, polygon, out pairEntry); bool exitInPolygon = isOnPolygonSide(pointExit, polygon, out pairExit); if (entryInPolygon != exitInPolygon) { Debug.LogWarning("Entry but not Exit in Polygon (or exit but not entry. This probably means the polygon was cross-cutted."); } if (entryInPolygon && exitInPolygon) { remove = polygon; numNewVerts = CutPolygon(polygon, out newPolys, pairEntry, pairExit); } if (numNewVerts > 0) { var newV1 = vertices.Count; var newV2 = vertices.Count + 1; if (!vertices.Contains(pointExit)) { vertices.Add(pointExit); normals.Add(GetMiddleNormal(pairExit, pointExit)); cutPointIndices.Add(newV1); } else { var newIndex = vertices.IndexOf(pointExit); foreach (var pol in newPolys) { int index = pol.IndexOf(newV1); pol.RemoveAt(index); pol.Insert(index, newIndex); } cutPointIndices.Add(newIndex); } if (!vertices.Contains(pointEntry)) { vertices.Add(pointEntry); normals.Add(GetMiddleNormal(pairEntry, pointEntry)); cutPointIndices.Add(newV2); } else { var newIndex = vertices.IndexOf(pointEntry); foreach (var pol in newPolys) { int index = pol.IndexOf(newV2); pol.RemoveAt(index); pol.Insert(index, newIndex); } cutPointIndices.Add(newIndex); } break; } } return(cutPointIndices); }
public void CheckIntersection(Polyline pline, MPolygon mPoly, List <Entity> obsts, double zMin) { Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor; Point3dCollection plinePoints = new Point3dCollection(); pline.GetStretchPoints(plinePoints); foreach (Entity acEnt in obsts) { ed.WriteMessage("\n\nNowy strop:"); //ed.WriteMessage("\nWymiary: " + acEnt.GeometricExtents.ToString()); //ed.WriteMessage("\nXdata:" + Xdata.LoadXData(acEnt.ObjectId)); string tmpXdata = Utils.Xdata.LoadXData(acEnt.ObjectId); if (tmpXdata.Contains("verticalCeiling")) { ed.WriteMessage("\nJest Xdata: " + tmpXdata); continue; } // Utworz prostokat i polilinie ze stropu do ktorego ma byc wyciagnieta narysowana polilinia Rect rObst = new Rect(new Point(acEnt.GeometricExtents.MinPoint.X, acEnt.GeometricExtents.MinPoint.Y), new Point(acEnt.GeometricExtents.MaxPoint.X, acEnt.GeometricExtents.MaxPoint.Y)); Polyline pObst = new Polyline(); pObst.AddVertexAt(0, new Point2d(acEnt.GeometricExtents.MinPoint.X, acEnt.GeometricExtents.MinPoint.Y), 0, 0, 0); pObst.AddVertexAt(1, new Point2d(acEnt.GeometricExtents.MaxPoint.X, acEnt.GeometricExtents.MinPoint.Y), 0, 0, 0); pObst.AddVertexAt(2, new Point2d(acEnt.GeometricExtents.MaxPoint.X, acEnt.GeometricExtents.MaxPoint.Y), 0, 0, 0); pObst.AddVertexAt(3, new Point2d(acEnt.GeometricExtents.MinPoint.X, acEnt.GeometricExtents.MaxPoint.Y), 0, 0, 0); pObst.AddVertexAt(4, new Point2d(acEnt.GeometricExtents.MinPoint.X, acEnt.GeometricExtents.MinPoint.Y), 0, 0, 0); // Sprawdz czy narysowana polilinia przecina sie ze stropem Point3dCollection pts = new Point3dCollection(); pline.IntersectWith(pObst, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero); //ed.WriteMessage("\nLiczba przeciec: " + pts.Count.ToString()); // Ustaw parametry wyciagniecia sciany - narysowanej polilini double zmax = acEnt.GeometricExtents.MinPoint.Z; // Dodatkowa zmienna zabezpieczajaca przed ponownym narysowaniem lini ktore sa pod stropem ale sie nie przecinaja z nim bool drawn = false; bool drawn2 = false; if (pts.Count > 0) { // Dla kazdego punktu przeciecia for (int j = 0; j < pts.Count; j++) { //ed.WriteMessage("\nPoint:" + ptIntersection); // Sprawdz wszystkie punkty narysowanej polilinii for (int i = 0; i < pline.NumberOfVertices - 1; i++) { // Utworz linie pomiedzy 2 kolejnymi wierzcholkami Line pSingleLine = new Line(pline.GetPoint3dAt(i), pline.GetPoint3dAt(i + 1)); Point3d p = pSingleLine.GetClosestPointTo(pts[j], false); // Jezeli punkt lezy na lini - odleglosc od lini do punktu jest rowna 0 if ((p - pts[j]).Length <= Tolerance.Global.EqualPoint) { //ed.WriteMessage("\nPoints[i]: " + plinePoints[i].ToString()); //ed.WriteMessage("\npoint: " + pts[j].ToString()); //ed.WriteMessage("\nIndex i: " + i.ToString()); // Jezeli punkt narysowanej polilinii znajduje sie pod analizowanym stropem if (rObst.Contains(new Point(plinePoints[i].X, plinePoints[i].Y))) { CreateWall(mPoly, plinePoints[i], pts[j], zMin, zmax); } // Jezeli punkt narysowanej polilinii nie znajduje sie pod analizowanym stropem else { // Jezeli kolejny punkt narysowanej polilinii znajduje sie pod analizowanym stropem if (rObst.Contains(new Point(plinePoints[i + 1].X, plinePoints[i + 1].Y))) { CreateWall(mPoly, pts[j], plinePoints[i + 1], zMin, zmax); } // Jezeli kolejny punkt narysowanej polilinii nie znajduej sie pod analizowanym stropem else if (!rObst.Contains(new Point(plinePoints[i + 1].X, plinePoints[i + 1].Y)) && drawn2 == false) { CreateWall(mPoly, pts[j], pts[j + 1], zMin, zmax); } } } // Jezeli punkt nie lezy na linii - linia jest narysowana wewnatrz obrysu stropu else { // Jezeli dwa kolejne punkty znajduja sie pod analizowanym stropem if (rObst.Contains(new Point(plinePoints[i].X, plinePoints[i].Y)) && rObst.Contains(new Point(plinePoints[i + 1].X, plinePoints[i + 1].Y)) && drawn == false) { CreateWall(mPoly, plinePoints[i], plinePoints[i + 1], zMin, zmax); } } } // Ustaw wartosci na true, tak aby kolejne punkty nie powodowaly rysowania tych samych lini, ktore nie przecinaja stropu ... drawn = true; drawn2 = true; } } // Nie ma przeciecia z polilinia - wszystkie punkty znajduja sie pod jednym obiektem - stropem else { for (int i = 0; i < pline.NumberOfVertices - 1; i++) { CreateWall(mPoly, plinePoints[i], plinePoints[i + 1], zMin, zmax); } } } }
/// <summary> /// Проверка наличия самопересечений в полилинии /// True - нет самопересечений /// </summary> public static bool CheckCross(this Polyline pline) { MPolygon mpoly = new MPolygon(); bool isValidBoundary = false; try { mpoly.AppendLoopFromBoundary(pline, true, Tolerance.Global.EqualPoint); if (mpoly.NumMPolygonLoops != 0) { isValidBoundary = true; } } catch { } mpoly.Dispose(); return isValidBoundary; }
public IEnumerator Cut(MPath path) { while (buildingGraph) { yield return(new WaitForSeconds(0.01f)); } DebugTime("Total Cut"); Vector3 normal = path.GetNormal(0); path.InsertPositionAt(0, path.dotFrom.transform.position); path.InsertNormalAt(0, normal); path.AddPosition(path.dotTo.transform.position); path.AddNormal(normal); DebugTime("Identify Cuts"); mesh = manifold.gameObject.GetComponent <MeshFilter> ().mesh; var vertices = mesh.vertices.ToList(); meshTriangles = mesh.triangles.ToList(); meshNormals = mesh.normals.ToList(); // Misc.DebugSphere (vertices[1299], Color.blue, "1299"); // Misc.DebugSphere (vertices[1334], Color.blue, "1334"); // Misc.DebugSphere (vertices[1335], Color.blue, "1335"); // DebugAtTriangle (2596, Color.white, "2596"); // DebugAtTriangle (2597, Color.white, "2597"); var cutPointIdentifier = new CutPointIdentifier(g, manifold); cutPointIdentifier.IdentifyCuts(path); var cutPoints = cutPointIdentifier.cutPoints; var cutEdges = cutPointIdentifier.cutEdges; var cutPointType = cutPointIdentifier.cutPointType; var cutTriangles = cutPointIdentifier.cutTriangles; var cutAlongEdges = cutPointIdentifier.cutAlongEdges; var cutNodes = cutPointIdentifier.cutNodes; DebugTime("Identify Cuts"); Debug.Log("Identification done, resulting in " + cutPoints.Count + " cut Points."); List <HashSet <int> > bounds; List <HashSet <int> > meshVertexPres; GetNewMeshVertices(vertices, cutNodes, cutAlongEdges, cutEdges, out bounds, out meshVertexPres); Debug.Log("GetBounds done, resulting in " + bounds.Count + " bounds."); int numComponents = meshVertexPres.Count; DebugTime("Set up Polygons"); var polyAtTriangle = new Dictionary <int, List <MPolygon> > (); foreach (var i in cutTriangles.Keys) { var index = cutTriangles[i]; polyAtTriangle[index] = new List <MPolygon> (); var list = new MPolygon(); list.Add(meshTriangles[index * 3]); list.Add(meshTriangles[index * 3 + 1]); list.Add(meshTriangles[index * 3 + 2]); polyAtTriangle[index].Add(list); } DebugTime("Set up Polygons"); // foreach (var item in cutTriangles.Keys) { // DebugAtTriangle (cutTriangles[item], Color.red, item + ""); // } DebugTime("Cut up Polygons"); oldVertexNumber = vertices.Count; var polygonCutter = new PolygonCutter(meshTriangles, meshNormals, vertices, polyAtTriangle); var sidesOfCut = polygonCutter.Cut(cutPoints, cutEdges, cutNodes, cutTriangles); List <Vector3> normals = polygonCutter.normals; var cutPointsToVertices = polygonCutter.cutPointVertices; DebugTime("Cut up Polygons"); // for (int i = 0; i < cutPoints.Count; i++) { // Vector3 cp = cutPoints[i]; // Misc.DebugSphere (cp, Color.red, i + "cp"); // } DebugTime("Triangulate"); var to = new TriangleOrdering(vertices, polyAtTriangle, bounds, cutNodes, cutPointsToVertices, sidesOfCut); Pair <HashSet <int> > sideBounds; var polygons = to.orderTriangles(out sideBounds); DebugTime("Triangulate"); Debug.Log("Triangulation done, resulting in " + polygons.Count + " lists of polygons."); // foreach (var item in sidesOfCut.left) { // DebugAtPolygon (vertices, item, Color.green); // } // foreach (var item in sidesOfCut.right) { // DebugAtPolygon (vertices, item, Color.red); // } var newMeshVertexPres = new List <HashSet <int> > (); newMeshVertexPres.Add(new HashSet <int> ()); newMeshVertexPres.Add(new HashSet <int> ()); foreach (var bound in sideBounds.left) { newMeshVertexPres[0].UnionWith(meshVertexPres[bound]); } foreach (var bound in sideBounds.right) { newMeshVertexPres[1].UnionWith(meshVertexPres[bound]); } numComponents = 2; if (newMeshVertexPres[0].SetEquals(newMeshVertexPres[1])) { numComponents = 1; polygons[0].AddRange(polygons[1]); } DebugTime("GetTriangles"); List <List <int> > meshts; List <List <Vector3> > meshvs, meshns; SetUpNewMeshes(vertices, cutTriangles, newMeshVertexPres, out meshts, out meshvs, out meshns); DebugTime("Set Normals and Triangles"); DebugTime("Set up manifolds"); SetUpManifolds(vertices, meshts, meshvs, meshns, normals, polygons, cutPoints, numComponents); SetSwitchedManifolds(); DebugTime("Set up manifolds"); //SLOW DebugTime("Total Cut"); }
private int GetOwnerOfPolygon(Dictionary <int, List <MPolygon> > polyAtTriangle, Dictionary <MPolygon, int> polygonOwners, Dictionary <int, int> cutPointsToVertices, MPolygon polygon) { List <PolygonSide> realNeighborSides; List <PolygonSide> fakeNeighborSides; getNeighborSides(polyAtTriangle, cutPointsToVertices, polygon, out realNeighborSides, out fakeNeighborSides); foreach (var neighborSide in realNeighborSides) { var neighbors = getNeighbors(polyAtTriangle, neighborSide); neighbors.Remove(polygon); foreach (var neighbor in neighbors) { int neighborOwner = polygonOwners[neighbor]; if (neighborOwner >= 0) { return(neighborOwner); } } } return(-1); }
internal Pair <List <MPolygon> > Cut(List <Vector3> cutPoints, Dictionary <int, PolygonSide> cutEdges, Dictionary <int, int> cutNodes, Dictionary <int, int> cutTriangles) { var lhs = new List <MPolygon> (); var rhs = new List <MPolygon> (); for (int i = 1; i < cutPoints.Count + 1; i++) { PolygonSide pairEntry = null; PolygonSide pairExit = null; int vertexEntry = -1; int vertexExit = -1; int bIndex = i - 1; var pointEntry = cutPoints[bIndex]; if (cutEdges.ContainsKey(bIndex)) { pairEntry = cutEdges[bIndex]; } else if (cutNodes.ContainsKey(bIndex)) { vertexEntry = cutNodes[bIndex]; // Debug.Log ("Vertex entry not null at " + vertexEntry); } int tIndex = i == cutPoints.Count ? 0 : i; var pointExit = cutPoints[tIndex]; if (cutEdges.ContainsKey(tIndex)) { pairExit = cutEdges[tIndex]; } else if (cutNodes.ContainsKey(tIndex)) { vertexExit = cutNodes[tIndex]; // Debug.Log ("Vertex exit not null at " + vertexExit); } List <MPolygon> newPolys = null; var triangle = -1; MPolygon remove = null; if (pairEntry != null && vertexExit != -1) { // Debug.Log ("Cut from " + pairEntry + " to " + vertexExit + " at triangle " + tIndex); triangle = cutTriangles[tIndex]; var cutPointIndices = CutUpPolygons(triangle, pairEntry, pointEntry, vertexExit, pointExit, out newPolys, out remove); if (cutPointIndices.Count == 1) { cutPointVertices[cutPointIndices[0]] = tIndex; lhs.Add(newPolys[1]); rhs.Add(newPolys[0]); if (newPolys[0].Contains(1370)) { Debug.Log("p-v Adding " + newPolys[0] + " to rhs and " + newPolys[1] + " to lhs"); } } else { // Debug.Log ("Same entry and exit at p-v " + pairEntry + " to " + vertexExit + " with " + cutTriangles[bIndex] + " and " + cutTriangles[tIndex] + " " + isLHS (GetTriangle (triangle), pairEntry, vertexExit)); // if (isLHS (GetTriangle (triangle), pairEntry, vertexExit)) { // lhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); // foreach (var item in polyAtTriangle[cutTriangles[tIndex]]) { // if (item.Contains (1299)) { // Debug.Log ("p-v Adding " + item); // } // } // } else { // rhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); // } } } else if (vertexEntry != -1 && pairExit != null) { // Debug.Log ("Cut from " + vertexEntry + " to " + pairExit); triangle = cutTriangles[tIndex]; var cutPointIndices = CutUpPolygons(triangle, pairExit, pointExit, vertexEntry, pointEntry, out newPolys, out remove); if (cutPointIndices.Count == 1) { cutPointVertices[cutPointIndices[0]] = tIndex; lhs.Add(newPolys[0]); rhs.Add(newPolys[1]); if (newPolys[1].Contains(1370)) { Debug.Log("v-p Adding " + newPolys[1] + " to rhs and " + newPolys[0] + " to lhs"); } } else { // Debug.Log ("Same entry and exit at v-p " + pairExit + " to " + vertexEntry + " with " + cutTriangles[bIndex] + " and " + cutTriangles[tIndex] + " " + isLHS (GetTriangle (triangle), pairExit, vertexEntry)); // if (isLHS (GetTriangle (triangle), pairExit, vertexEntry)) { // lhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); // foreach (var item in polyAtTriangle[cutTriangles[tIndex]]) { // if (item.Contains (1299)) { // Debug.Log ("v-p Adding " + item); // } // } // } else { // rhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); // } } } else if (vertexEntry != -1 && vertexExit != -1) { //Nothing } else if (pairEntry != null && pairExit != null) { if (!pairEntry.SameAs(pairExit)) { triangle = cutTriangles[tIndex]; var cutPointIndices = CutUpPolygons(triangle, pairEntry, pairExit, pointEntry, pointExit, out newPolys, out remove); if (cutPointIndices.Count == 2) { cutPointVertices[cutPointIndices[0]] = tIndex; cutPointVertices[cutPointIndices[1]] = bIndex; lhs.Add(newPolys[0]); rhs.Add(newPolys[1]); if (newPolys[1].Contains(1335)) { Debug.Log("p-p Adding " + newPolys[1] + " to rhs and " + newPolys[0] + " to lhs"); } } } else { // Debug.Log ("Same entry and exit at " + pairEntry + " to " + pairExit + " with " + cutTriangles[bIndex] + " and " + cutTriangles[tIndex]); // Misc.DebugSphere (vertices[pairEntry.left], Color.white, "Entry " + pairEntry + " left"); // Misc.DebugSphere (vertices[pairEntry.right], Color.white, "Entry " + pairEntry + " right"); // rhs.AddRange (polyAtTriangle[cutTriangles[bIndex]]); // foreach (var item in polyAtTriangle[cutTriangles[bIndex]]) { // if (item.Contains (1297)) { // Debug.Log ("e-e Adding " + item + " to rhs"); // } // } // lhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); } } if (newPolys != null) { polyAtTriangle[triangle].Remove(remove); lhs.Remove(remove); rhs.Remove(remove); polyAtTriangle[triangle].AddRange(newPolys); } } return(new Pair <List <MPolygon> > (lhs, rhs)); }
private void getNeighborSides(Dictionary <int, List <MPolygon> > polyAtTriangle, Dictionary <int, int> cutPointsToVertices, MPolygon polygon, out List <PolygonSide> realNeighbors, out List <PolygonSide> fakeNeighbors) { realNeighbors = new List <PolygonSide> (); fakeNeighbors = new List <PolygonSide> (); var sides = polygon.GetSides(); foreach (var side in sides) { if (IsSeparatingEdge(cutPointsToVertices, side)) { fakeNeighbors.Add(side); } else { realNeighbors.Add(side); } } }
private int CutPolygon(MPolygon polygon, out List <MPolygon> newPolys, PolygonSide sideEntry, PolygonSide sideExit) { return(polygon.Cut(sideEntry, sideExit, out newPolys, vertices.Count)); }
private void PointerPressedDraw(bool rightButtonPressed, Point startPosition) { if (CurrentShapeType == ShapeType.Polygon || CurrentShapeType == ShapeType.Bezier) { DrawClickTool.IsChecked = true; SelectedTool = Tools.DrawClick; } if (SelectedTool == Tools.DrawClick) { if (CurrentShapeType == ShapeType.Polygon || CurrentShapeType == ShapeType.Bezier) { if (ClickedTimes++ >= 1) { if (rightButtonPressed) { if (ClickedTimes >= 4) { ClickedTimes = 0; var poly = PendingShape as MPolygon; if (CurrentShapeType == ShapeType.Polygon) { poly.AddSegment(poly.StartLocation); } poly.StartLocation = new Point(0, 0); poly.EndLocation = new Point(0, 0); poly.Closed = true; AddShape(); return; } else { --ClickedTimes; } } else { if (CurrentShapeType == ShapeType.Polygon || CurrentShapeType == ShapeType.Bezier) { (PendingShape as MPolygon).AddSegment(startPosition); } } this.canvasControl.Invalidate(); return; } } else { if (ClickedTimes == 0) { ClickedTimes = 1; } else { ClickedTimes = 0; AddShape(); return; } } } if (CurrentShapeType == ShapeType.Rectangle) { PendingShape = new MRectangle(startPosition, startPosition); } else if (CurrentShapeType == ShapeType.Circle) { PendingShape = new MCircle(startPosition, startPosition); } else if (CurrentShapeType == ShapeType.Line) { PendingShape = new MLine(startPosition, startPosition); } else if (CurrentShapeType == ShapeType.Polygon) { PendingShape = new MPolygon(startPosition, startPosition); } else if (CurrentShapeType == ShapeType.Bezier) { PendingShape = new MBezier(startPosition, startPosition); } PendingShape.Mode = ShapeModes.Drawing; this.canvasControl.Invalidate(); }
public void CreateWall(MPolygon mPoly, Point3d p1, Point3d p2, double zmin, double zmax) { //ed.WriteMessage("\nTutaj: " + mPoly.GeometricExtents.ToString()); double x1 = Math.Round(p1.X, 4); double x2 = Math.Round(p2.X, 4); double y1 = Math.Round(p1.Y, 4); double y2 = Math.Round(p2.Y, 4); double z1 = Math.Round(p1.Z, 4); double height = zmax - zmin; x1 = Math.Round(x1 / Utils.Utils.snapUnit.X) * Utils.Utils.snapUnit.X; x2 = Math.Round(x2 / Utils.Utils.snapUnit.X) * Utils.Utils.snapUnit.X; y1 = Math.Round(y1 / Utils.Utils.snapUnit.Y) * Utils.Utils.snapUnit.Y; y2 = Math.Round(y2 / Utils.Utils.snapUnit.Y) * Utils.Utils.snapUnit.Y; //ed.WriteMessage("\nDiagnostic"); //ed.WriteMessage("\nx1: " + x1); //ed.WriteMessage("\nx2: " + x2); //ed.WriteMessage("\ny1: " + y1); //ed.WriteMessage("\ny2: " + y2); Point3d middle = new Point3d(); if (x1 == x2) { middle = new Point3d(x1 + Utils.Utils.snapUnit.X, (y1 + y2) / 2, z1); //ed.WriteMessage("\nx1 = x2, middle: " + middle.ToString()); } else if (y1 == y2) { middle = new Point3d((x1 + x2) / 2, y1 + Utils.Utils.snapUnit.Y, z1); } else { middle = new Point3d((x1 + x2 / 2) + Utils.Utils.snapUnit.X, (y1 + y2 / 2) + Utils.Utils.snapUnit.Y, z1); } if (mPoly.IsPointInsideMPolygon(middle, 0).Count == 1) { if (x1 == x2) { Utils.Utils.CreateBox(x1, x2 - Utils.Utils.snapUnit.X, y1, y2, zmin, zmax); //ed.WriteMessage("\nis inside."); } else if (y1 == y2) { Utils.Utils.CreateBox(x1, x2, y1, y2 - Utils.Utils.snapUnit.Y, zmin, zmax); } else { Utils.Utils.Bresenham(x1, y1, x2, y2, height, zmin); } } else if (mPoly.IsPointInsideMPolygon(middle, 0).Count == 0) { if (x1 == x2) { Utils.Utils.CreateBox(x1, x2 + Utils.Utils.snapUnit.X, y1, y2, zmin, zmax); //ed.WriteMessage("\nczy jest zamk: " + mPoly.IsReallyClosing.ToString()); //ed.WriteMessage("\nis not inside."); } else if (y1 == y2) { Utils.Utils.CreateBox(x1, x2, y1, y2 + Utils.Utils.snapUnit.Y, zmin, zmax); } else { Utils.Utils.Bresenham(x1, y1, x2, y2, height, zmin); } } }