List <Vertex> IndexVertices(TriangleNet.Data.Triangle triangle, Dictionary <int, int> indexDict, ref int highestIndex, out int[] newIndices) { var newVertices = new List <Vertex>(); newIndices = new int[3]; if (indexDict.ContainsKey(triangle.P0)) { newIndices[0] = indexDict[triangle.P0]; } else { TriangleNet.Data.Vertex vertex0 = triangle.GetVertex(0); newVertices.Add(new Vertex((float)vertex0.X, (float)vertex0.Y)); indexDict.Add(vertex0.ID, highestIndex); newIndices[0] = highestIndex; highestIndex++; } if (indexDict.ContainsKey(triangle.P1)) { newIndices[1] = indexDict[triangle.P1]; } else { TriangleNet.Data.Vertex vertex1 = triangle.GetVertex(1); newVertices.Add(new Vertex((float)vertex1.X, (float)vertex1.Y)); indexDict.Add(vertex1.ID, highestIndex); newIndices[1] = highestIndex; highestIndex++; } if (indexDict.ContainsKey(triangle.P2)) { newIndices[2] = indexDict[triangle.P2]; } else { TriangleNet.Data.Vertex vertex2 = triangle.GetVertex(2); newVertices.Add(new Vertex((float)vertex2.X, (float)vertex2.Y)); indexDict.Add(vertex2.ID, highestIndex); newIndices[2] = highestIndex; highestIndex++; } return(newVertices); }
public void DrawSurface() { if (!CheckLicense.Check()) { return; } Autodesk.AutoCAD.ApplicationServices.Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Topography topo = Topography.Instance; Topography.SurfaceType surface = Topography.PickSurface(); if (surface == Topography.SurfaceType.None) { return; } if (!Topography.EnsureSurfaceNotEmpty(surface)) { return; } TriangleNet.Mesh mesh = (surface == Topography.SurfaceType.Original ? topo.OriginalTIN : topo.ProposedTIN); // Object type PromptKeywordOptions opts = new PromptKeywordOptions("\nÇizim nesneleri [Geçici/3dFace/Point/polyfaceMesh] <Geçici>: ", "Temporary 3dFace Point polyfaceMesh"); opts.Keywords.Default = "Temporary"; opts.AllowNone = true; PromptResult res = doc.Editor.GetKeywords(opts); string outputType = res.StringResult; if (res.Status == PromptStatus.None) { outputType = "Temporary"; } else if (res.Status != PromptStatus.OK) { return; } // Color option opts = new PromptKeywordOptions("\nRenkli çizim [E/H] <E>: ", "Yes No"); opts.Keywords.Default = "Yes"; opts.AllowNone = true; res = doc.Editor.GetKeywords(opts); bool useColor = true; if (res.Status == PromptStatus.None) { useColor = true; } else if (res.Status != PromptStatus.OK) { return; } else { useColor = (string.Compare(res.StringResult, "Yes", StringComparison.OrdinalIgnoreCase) == 0); } double zmin = double.MaxValue; double zmax = double.MinValue; foreach (TriangleNet.Data.Vertex v in mesh.Vertices) { zmin = Math.Min(zmin, v.Attributes[0]); zmax = Math.Max(zmax, v.Attributes[0]); } using (Transaction tr = db.TransactionManager.StartTransaction()) using (BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)) { try { if (string.Compare(outputType, "Temporary", StringComparison.OrdinalIgnoreCase) == 0) { EraseTemporaryGraphics(); foreach (TriangleNet.Data.Triangle tri in mesh.Triangles) { TriangleNet.Data.Vertex v1 = tri.GetVertex(0); TriangleNet.Data.Vertex v2 = tri.GetVertex(1); TriangleNet.Data.Vertex v3 = tri.GetVertex(2); Face face = new Face(new Point3d(v1.X, v1.Y, v1.Attributes[0]), new Point3d(v2.X, v2.Y, v2.Attributes[0]), new Point3d(v3.X, v3.Y, v3.Attributes[0]), true, true, true, true); if (useColor) { face.Color = ColorFromZ((v1.Attributes[0] + v2.Attributes[0] + v3.Attributes[0]) / 3, zmin, zmax); } temporaryGraphics.Add(face); } DrawTemporaryGraphics(); } else if (string.Compare(outputType, "3dFace", StringComparison.OrdinalIgnoreCase) == 0) { foreach (TriangleNet.Data.Triangle tri in mesh.Triangles) { TriangleNet.Data.Vertex v1 = tri.GetVertex(0); TriangleNet.Data.Vertex v2 = tri.GetVertex(1); TriangleNet.Data.Vertex v3 = tri.GetVertex(2); Face face = new Face(new Point3d(v1.X, v1.Y, v1.Attributes[0]), new Point3d(v2.X, v2.Y, v2.Attributes[0]), new Point3d(v3.X, v3.Y, v3.Attributes[0]), true, true, true, true); if (useColor) { face.Color = ColorFromZ((v1.Attributes[0] + v2.Attributes[0] + v3.Attributes[0]) / 3, zmin, zmax); } btr.AppendEntity(face); tr.AddNewlyCreatedDBObject(face, true); } } else if (string.Compare(outputType, "Point", StringComparison.OrdinalIgnoreCase) == 0) { foreach (TriangleNet.Data.Vertex v in mesh.Vertices) { DBPoint point = new DBPoint(new Point3d(v.X, v.Y, v.Attributes[0])); if (useColor) { point.Color = ColorFromZ(v.Attributes[0], zmin, zmax); } btr.AppendEntity(point); tr.AddNewlyCreatedDBObject(point, true); } } else if (string.Compare(outputType, "polyfaceMesh", StringComparison.OrdinalIgnoreCase) == 0) { PolyFaceMesh pfm = new PolyFaceMesh(); btr.AppendEntity(pfm); tr.AddNewlyCreatedDBObject(pfm, true); // Vertices SortedDictionary <int, Point3d> vertices = new SortedDictionary <int, Point3d>(); foreach (TriangleNet.Data.Vertex v in mesh.Vertices) { vertices.Add(v.ID, new Point3d(v.X, v.Y, v.Attributes[0])); } foreach (KeyValuePair <int, Point3d> v in vertices) { PolyFaceMeshVertex point = new PolyFaceMeshVertex(v.Value); pfm.AppendVertex(point); tr.AddNewlyCreatedDBObject(point, true); } // Faces foreach (TriangleNet.Data.Triangle tri in mesh.Triangles) { FaceRecord face = new FaceRecord((short)(tri.P0 + 1), (short)(tri.P1 + 1), (short)(tri.P2 + 1), 0); if (useColor) { face.Color = ColorFromZ((tri.GetVertex(0).Attributes[0] + tri.GetVertex(1).Attributes[0] + tri.GetVertex(2).Attributes[0]) / 3, zmin, zmax); } pfm.AppendFaceRecord(face); tr.AddNewlyCreatedDBObject(face, true); } } } catch (System.Exception ex) { MessageBox.Show("Error: " + ex.ToString(), "XCOM", MessageBoxButtons.OK, MessageBoxIcon.Error); } tr.Commit(); } }
protected static ExcavationSection ExcavateSlopeAtPoint(TriangleNet.Mesh surfaceMesh, ExcavationSection section, Point3d bottomPoint, Vector3d normal) { double xyLen = Math.Sqrt(normal.X * normal.X + normal.Y * normal.Y); ExcavationSection outSection = new ExcavationSection(); foreach (ExcavationSectionElement inputelement in section.Elements) { ExcavationSectionElement element = (ExcavationSectionElement)inputelement.Clone(); element.HasIntersection = false; element.HasTopPoint = false; element.CurrentRatio = double.MaxValue; element.BottomPoint = bottomPoint; // Calculate 3D slope Vector3d slope = new Vector3d(normal.X / xyLen * element.H, normal.Y / xyLen * element.H, element.V); slope = slope / slope.Length; element.Slope = slope; // Intersects slope vectors with surface triangles foreach (TriangleNet.Data.Triangle tri in surfaceMesh.Triangles) { TriangleNet.Data.Vertex v1 = tri.GetVertex(0); TriangleNet.Data.Vertex v2 = tri.GetVertex(1); TriangleNet.Data.Vertex v3 = tri.GetVertex(2); // Intersect the 3D ray from excavation bottom with the triangle double t; Point3d topPoint; bool intersect = RayTriangleIntersection(bottomPoint, slope, new Point3d(v1.X, v1.Y, v1.Attributes[0]), new Point3d(v2.X, v2.Y, v2.Attributes[0]), new Point3d(v3.X, v3.Y, v3.Attributes[0]), out t, out topPoint); double xyDist = double.MaxValue; double zDist = double.MaxValue; if (intersect) { xyDist = new Vector3d(topPoint.X - bottomPoint.X, topPoint.Y - bottomPoint.Y, 0).Length; zDist = topPoint.Z - bottomPoint.Z; } if (!intersect || (element.HeightLimit > 0 && zDist > element.HeightLimit) || (element.LengthLimit > 0 && xyDist > element.LengthLimit)) { t = double.MaxValue; } if (t < element.CurrentRatio) { element.CurrentRatio = t; element.TopPoint = topPoint; element.HasIntersection = true; } } // Create the output section if (element.HasIntersection) { // This element intersected the surface // Add to output section and end calculation element.HasTopPoint = true; outSection.Elements.Add(element); break; } else { // No intersections // Add to output section and continue calculation // Calculate the top point for this element (bottom point for the next element) if (element.HeightLimit > 0) { element.TopPoint = element.BottomPoint + slope * element.HeightLimit / element.V; element.HasTopPoint = true; } else if (element.LengthLimit > 0) { element.TopPoint = element.BottomPoint + slope * element.LengthLimit / element.H; element.HasTopPoint = true; } else { element.HasTopPoint = false; } outSection.Elements.Add(element); bottomPoint = element.TopPoint; } } return(outSection); }
/// <summary> /// Returns the contour polylines at the given elevation. /// </summary> /// <param name="surface">The type of surface being operated on</param> /// <param name="z">Elevation</param> public IEnumerable <Polyline> ContourAt(SurfaceType surface, double z) { Autodesk.AutoCAD.ApplicationServices.Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Autodesk.AutoCAD.DatabaseServices.Database db = doc.Database; Point3d planePoint = new Point3d(0, 0, z); Vector3d planeNormal = Vector3d.ZAxis; // List of segments Queue <Tuple <Point3d, Point3d> > segments = new Queue <Tuple <Point3d, Point3d> >(); foreach (TriangleNet.Data.Triangle tri in ((surface == SurfaceType.Original) ? originalSurface : proposedSurface).Triangles) { TriangleNet.Data.Vertex v1 = tri.GetVertex(0); TriangleNet.Data.Vertex v2 = tri.GetVertex(1); TriangleNet.Data.Vertex v3 = tri.GetVertex(2); Point3d p1 = new Point3d(v1.X, v1.Y, v1.Attributes[0]); Point3d p2 = new Point3d(v2.X, v2.Y, v2.Attributes[0]); Point3d p3 = new Point3d(v3.X, v3.Y, v3.Attributes[0]); if (PlaneTriangleIntersection(planePoint, planeNormal, p1, p2, p3, out Point3d ptOut1, out Point3d ptOut2)) { segments.Enqueue(new Tuple <Point3d, Point3d>(ptOut1, ptOut2)); } } // Create curves from segments double epsilon = 0.000001; Tolerance tol = new Tolerance(epsilon, epsilon); List <Polyline> contours = new List <Polyline>(); while (segments.Count > 0) { LinkedList <Point3d> curvePoints = new LinkedList <Point3d>(); Tuple <Point3d, Point3d> firstSegment = segments.Dequeue(); curvePoints.AddFirst(firstSegment.Item1); curvePoints.AddLast(firstSegment.Item2); bool added = false; do { int n = segments.Count; added = false; for (int i = 0; i < n; i++) { Tuple <Point3d, Point3d> segment = segments.Dequeue(); Point3d p1 = segment.Item1; Point3d p2 = segment.Item2; Point3d startPoint = curvePoints.First.Value; Point3d endPoint = curvePoints.Last.Value; if (startPoint.IsEqualTo(p1, tol)) { curvePoints.AddFirst(p2); added = true; } else if (startPoint.IsEqualTo(p2, tol)) { curvePoints.AddFirst(p1); added = true; } else if (endPoint.IsEqualTo(p1, tol)) { curvePoints.AddLast(p2); added = true; } else if (endPoint.IsEqualTo(p2, tol)) { curvePoints.AddLast(p1); added = true; } else { segments.Enqueue(segment); } } } while (added); Polyline pline = AcadEntity.CreatePolyLine(db, curvePoints.First().IsEqualTo(curvePoints.Last(), tol), curvePoints.ToArray()); pline.ColorIndex = 31; pline.Elevation = z; contours.Add(pline); } return(contours); }
/// <summary> /// Drapes the curve over the given surface. /// </summary> /// <param name="curve">The curve to drape</param> /// <param name="surface">The type of surface being operated on</param> /// <param name="curveDiscretizationLength">Length of discrete segments</param> public Point3dCollection DrapeCurve(Curve curve, SurfaceType surface, double curveDiscretizationLength = 1.0) { SortedList <double, Point3d> results = new SortedList <double, Point3d>(); // Divide the curve into equal segments double sp = curve.StartParam; double ep = curve.EndParam; double len = curve.GetLength(); int nmax = (int)Math.Ceiling(len / curveDiscretizationLength); double distStep = len / nmax; // Intersects slope vectors with surface triangles Extents3d ex = curve.GeometricExtents; Vector3d dir = new Vector3d(0, 0, -1); foreach (TriangleNet.Data.Triangle tri in ((surface == SurfaceType.Original) ? originalSurface : proposedSurface).Triangles) { TriangleNet.Data.Vertex v1 = tri.GetVertex(0); TriangleNet.Data.Vertex v2 = tri.GetVertex(1); TriangleNet.Data.Vertex v3 = tri.GetVertex(2); if (v1.X < ex.MinPoint.X && v2.X < ex.MinPoint.X && v3.X < ex.MinPoint.X) { continue; } if (v1.X > ex.MaxPoint.X && v2.X > ex.MaxPoint.X && v3.X > ex.MaxPoint.X) { continue; } if (v1.Y < ex.MinPoint.Y && v2.Y < ex.MinPoint.Y && v3.Y < ex.MinPoint.Y) { continue; } if (v1.Y > ex.MaxPoint.Y && v2.Y > ex.MaxPoint.Y && v3.Y > ex.MaxPoint.Y) { continue; } Point3d p1 = new Point3d(v1.X, v1.Y, v1.Attributes[0]); Point3d p2 = new Point3d(v2.X, v2.Y, v2.Attributes[0]); Point3d p3 = new Point3d(v3.X, v3.Y, v3.Attributes[0]); double dist = 0.0; for (int i = 0; i <= (curve.Closed ? nmax - 1 : nmax); i++) { double param = curve.GetParameterAtDistance(dist); if (param < sp) { param = sp; } if (param > ep) { param = ep; } Point3d pt = curve.GetPointAtParameter(param); if (RayTriangleIntersection(pt, dir, p1, p2, p3, out _, out Point3d ptOut)) { results[dist] = ptOut; } dist += distStep; } } return(new Point3dCollection(results.Values.ToArray())); }
protected void GenerateTrisForShape() { if (vertices.Length >= 6 && vertices.Length % 2 == 0) { InputGeometry bottomGeometry = new InputGeometry(); List <Point> shape = new List <Point> (); int halfVertLen = vertices.Length / 2; for (int i = 0; i < halfVertLen; i++) { shape.Add(new Point(vertices[i].x, vertices[i].z)); } bottomGeometry.AddRing(shape); TriangleNet.Mesh bottomMesh = new TriangleNet.Mesh(); bottomMesh.Triangulate(bottomGeometry); List <Vector3> verts = new List <Vector3>(bottomMesh.triangles.Count * 3); List <int> triangleIndices = new List <int>(bottomMesh.triangles.Count * 3); foreach (KeyValuePair <int, TriangleNet.Data.Triangle> pair in bottomMesh.triangles) { TriangleNet.Data.Triangle triangle = pair.Value; TriangleNet.Data.Vertex vertex0 = triangle.GetVertex(0); TriangleNet.Data.Vertex vertex1 = triangle.GetVertex(1); TriangleNet.Data.Vertex vertex2 = triangle.GetVertex(2); Vector3 p0 = new Vector3(vertex0.x, 0, vertex0.y); Vector3 p1 = new Vector3(vertex1.x, 0, vertex1.y); Vector3 p2 = new Vector3(vertex2.x, 0, vertex2.y); verts.Add(p0); verts.Add(p1); verts.Add(p2); triangleIndices.Add(GetIndexForVertex(p0)); triangleIndices.Add(GetIndexForVertex(p1)); triangleIndices.Add(GetIndexForVertex(p2)); } // Create top Side List <int> triangleIndecesReversed = new List <int>(); for (int i = triangleIndices.Count - 1; i >= 0; i--) { triangleIndecesReversed.Add(triangleIndices[i] + halfVertLen); } triangleIndices.AddRange(triangleIndecesReversed); // Add edges List <int> edgeIndeces = new List <int>(); for (int i = 0; i < halfVertLen; i++) { int leftBottom = i; int rightBottom = (i == halfVertLen - 1 ? 0 : i + 1); int leftTop = i + halfVertLen; int rightTop = (i == halfVertLen - 1 ? halfVertLen : i + halfVertLen + 1); edgeIndeces.Add(leftTop); edgeIndeces.Add(rightTop); edgeIndeces.Add(leftBottom); edgeIndeces.Add(rightBottom); edgeIndeces.Add(leftBottom); edgeIndeces.Add(rightTop); } triangleIndices.AddRange(edgeIndeces); tris = triangleIndices.ToArray(); } else { Debug.LogError("[BaseShape.GenerateTrisForShape] Invalid vertices set for shape!"); } }
private void endBtn_Click(object sender, RoutedEventArgs e) { this._host.CommandReset.Click -= endBtn_Click; this._host.Menues.IsEnabled = true; this._host.UIMessage.Visibility = Visibility.Hidden; //this.JGraphMode = false; this._host.Cursor = Cursors.Arrow; this._host.FloorScene.MouseLeftButtonDown -= FloorScene_MouseLeftButtonDown; try { #region Create Graph HashSet <UV> pnts = new HashSet <UV>(); TriangleNet.Behavior behavior = new Behavior(); TriangleNet.Mesh t_mesh = new TriangleNet.Mesh(); TriangleNet.Geometry.InputGeometry geom = new TriangleNet.Geometry.InputGeometry(); foreach (Node node in JGNodes) { TriangleNet.Data.Vertex vertex = new TriangleNet.Data.Vertex(node.Coordinates.U, node.Coordinates.V, 0); geom.AddPoint(vertex); pnts.Add(node.Coordinates); } t_mesh.Triangulate(geom); var graph = new JGGraph(pnts); foreach (var item in t_mesh.Triangles) { UV a = null; var vrtx = t_mesh.GetVertex(item.P0); if (vrtx != null) { a = new UV(vrtx.X, vrtx.Y); } UV b = null; vrtx = t_mesh.GetVertex(item.P1); if (vrtx != null) { b = new UV(vrtx.X, vrtx.Y); } UV c = null; vrtx = t_mesh.GetVertex(item.P2); if (vrtx != null) { c = new UV(vrtx.X, vrtx.Y); } if (a != null && b != null) { graph.AddConnection(a, b); } if (a != null && c != null) { graph.AddConnection(a, c); } if (c != null && b != null) { graph.AddConnection(c, b); } } #endregion #region Remove Edges with isovists at the ends that do not overlap this.edges = graph.ToEdges(); Dictionary <int, Isovist> IsovistGuid = new Dictionary <int, Isovist>(); foreach (JGVertex item in graph.Vertices) { double x = double.NegativeInfinity; foreach (JGVertex vertex in item.Connections) { var y = item.Point.DistanceTo(vertex.Point); if (y > x) { x = y; } } var isovist = CellularIsovistCalculator.GetIsovist(item.Point, x, BarrierType.Visual, this._host.cellularFloor); IsovistGuid.Add(item.Point.GetHashCode(), isovist); } HashSet <JGEdge> visibleVertexes = new HashSet <JGEdge>(); foreach (JGEdge item in this.edges) { Isovist v1 = null; IsovistGuid.TryGetValue(item.P1.GetHashCode(), out v1); Isovist v2 = null; IsovistGuid.TryGetValue(item.P2.GetHashCode(), out v2); if (v1 != null && v2 != null) { if (v2.VisibleCells.Overlaps(v1.VisibleCells)) { visibleVertexes.Add(item); } } } #endregion #region setting the edges JGEdge.LineToEdgeGuide.Clear(); foreach (JGEdge edge in this.edges) { edge.Clear(); } this.edges = visibleVertexes.ToList <JGEdge>(); foreach (JGEdge item in this.edges) { item.Draw(); } #endregion //cleaning up the used data t_mesh = null; graph = null; geom.Clear(); geom = null; visibleVertexes = null; IsovistGuid = null; //enabling edit mode this.EditGraph.IsEnabled = true; this.DrawJG.IsEnabled = true; this.Hide_show_Menu.IsEnabled = true; this.CreateCovexGraph.Header = "Reset Convex Graph"; } catch (Exception error) { MessageBox.Show(error.Report()); } }
static PointF VertexToPoint(TriangleNet.Data.Vertex v) { return(new PointF((float)v.X, (float)v.Y)); }