/// <summary> /// Scales an edge to a desired length. /// Changes the edge in place. /// </summary> /// <param name="setLengh"></param> public void ScaleEdge(double setLengh) { Point3d midPoint = PFVertex.AverageVertexes(Vertices); Vector3d midToStart = Vertices[0].Point - midPoint; Vector3d midToEnd = Vertices[1].Point - midPoint; midToEnd.Unitize(); midToStart.Unitize(); Vertices[0].Point = midPoint + midToStart * setLengh / 2; Vertices[1].Point = midPoint + midToEnd * setLengh / 2; }
/// <summary> /// This scales an edge while keeping a given direction /// If edge is reversed it will be un-reversed by reconstruction to the new direction. /// </summary> /// <param name="dir">imposed direction</param> /// <param name="factor">scale factor</param> public void ScaleToDir(Vector3d dir, double factor) { factor = Math.Abs(factor); double originaLength = GetLength(); Point3d midPoint = PFVertex.AverageVertexes(Vertices); Point3d startNew = midPoint + dir * originaLength / 2 * factor; Point3d endNew = midPoint + dir * -originaLength / 2 * factor; Vertices[0].Point = startNew; Vertices[1].Point = endNew; }
/// <summary> /// Gets the orientation of the edge in rapport to its dual face /// </summary> /// <returns>True if vector (v1-v0) has same general orientation like the dual face normal</returns> public bool OrientationToDual() { if (Dual == null || Dual.Normal == Vector3d.Unset) { throw new PolyFrameworkException("Edge dual is null or Dual.Normal is unset"); } Point3d midPoint = PFVertex.AverageVertexes(Vertices); Vector3d midToStart = Vertices[0].Point - midPoint; Vector3d midToEnd = Vertices[1].Point - midPoint; midToStart.Unitize(); midToEnd.Unitize(); return((Dual.Normal - midToStart).Length > (Dual.Normal - midToEnd).Length); }
/// <summary> /// Scales the edge in one step /// If target length is set - scales the edge to target /// If not set it makes sure minLen smaller that length and length is smaller than maxLegth /// Uses the constraint move of the point to limit move /// </summary> /// <returns>List of 2 new vertices after the constrained move. They have the influence coefficient of the edge </returns> public List <PFVertex> Scale_Soft() { double originaLength = GetLength(); var direction = GetDirectionVector(); direction.Unitize(); double setLength; if (!double.IsNaN(TargetLength)) { setLength = TargetLength; } else if (originaLength < MinLength) { setLength = MinLength; } else if (originaLength > MaxLength) { setLength = MaxLength; } else { setLength = originaLength; } Point3d midPoint = PFVertex.AverageVertexes(Vertices); Point3d startNew = midPoint + direction * setLength / 2; Point3d endNew = midPoint + direction * -setLength / 2; var nVertStart = Vertices[0].Move(startNew); nVertStart.InfluenceCoef = this.InfluenceCoef; var nVertEnd = Vertices[1].Move(endNew); nVertEnd.InfluenceCoef = this.InfluenceCoef; return(new List <PFVertex> { nVertStart, nVertEnd }); }
/// <summary> /// 1 Step perpendincularization of the edge /// Will change the locations of the vertexes at the ends /// This should be used on a clone of the edge /// Requires dual of the edge to be set /// </summary> /// <returns>the length of the edge after the process </returns> public void PerpEdge(bool orientation, double lAdjCoef = 1.0) { if (lAdjCoef < 0) { lAdjCoef *= -1; } double originaLength = GetLength(); if (orientation) { lAdjCoef *= -1; } Point3d midPoint = PFVertex.AverageVertexes(Vertices); Point3d startNew = midPoint + Dual.Normal * originaLength / 2 * lAdjCoef; Point3d endNew = midPoint + Dual.Normal * originaLength / 2 * -lAdjCoef; Vertices[0].Point = startNew; Vertices[1].Point = endNew; }
/// <summary> /// Loads a structure from a set of breps and the attached serial string (JSON) /// If there is a dual present it links the dual and outputs it too /// </summary> /// <param name="edgeLines">The set of line curves with extra data in .UserDictionary</param> /// <param name="dual">The dual. If empty structure then no dual was found</param> /// <returns></returns> public static PFoam LoadFromCells(IList <Brep> cellBreps, out PFoam dual, bool updateGeometry = false) { dual = new PFoam(); var primal = new PFoam(); var vertLocations = new Dictionary <int, List <PFVertex> >(); foreach (var cellBrep in cellBreps) { if (cellBrep.Faces.Count < 2) { throw new PolyFrameworkException("LoadFromCells only works with PolySurfaces!"); } foreach (var bVert in cellBrep.Vertices) { if (bVert.UserDictionary.TryGetInteger("Id", out int vertId)) { if (vertLocations.TryGetValue(vertId, out List <PFVertex> vertList)) { vertList.Add(new PFVertex(vertId, bVert.Location)); } else { vertLocations[vertId] = new List <PFVertex> { new PFVertex(vertId, bVert.Location) }; } } } if (cellBrep.UserDictionary.TryGetString("Primal", out string primalString)) { primal = Util.DeserializeFoam(primalString); } if (cellBrep.UserDictionary.TryGetString("Dual", out string dualString)) { dual = Util.DeserializeFoam(dualString); } } if (primal.Cells.Count < 1) { throw new PolyFrameworkException("No serial data stored in the geometry or data has problems!"); } if (updateGeometry) { foreach (var vertex in primal.Vertices) { if (vertLocations.TryGetValue(vertex.Id, out List <PFVertex> vertPostions)) { vertex.Point = PFVertex.AverageVertexes(vertPostions); } } } foreach (var face in primal.Faces) { face.FaceMesh(); face.ComputeCentroid(); face.ComputeFaceNormal(); } foreach (var cell in primal.Cells) { cell.ComputeCentroid(); } primal.Centroid = PFVertex.AverageVertexes(primal.Vertices); if (dual.Cells.Count > 1) { //Util.ConnectDuals(ref primal, ref dual); foreach (var face in dual.Faces) { face.FaceMesh(); face.ComputeCentroid(); face.ComputeFaceNormal(); } foreach (var cell in dual.Cells) { cell.ComputeCentroid(); } dual.Centroid = PFVertex.AverageVertexes(dual.Vertices); } return(primal); }
/// <summary> /// Loads a structure from a set of breps and the attached serial string (JSON) /// If there is a dual present it links the dual and outputs it too /// </summary> /// <param name="edgeLines">The set of line curves with extra data in .UserDictionary</param> /// <param name="dual">The dual. If empty structure then no dual was found</param> /// <returns></returns> public static PFoam LoadFromMeshes(IList <Mesh> meshes, out PFoam dual, bool updateGeometry = false) { dual = new PFoam(); var primal = new PFoam(); var vertLocations = new Dictionary <int, List <PFVertex> >(); foreach (var mesh in meshes) { //if (faceBrep.Faces.Count > 1) throw new PolyFrameworkException("LoadFromFaces only works with individual faces!"); if (mesh.UserDictionary.TryGetDictionary("VertexIds", out Rhino.Collections.ArchivableDictionary vertDict)) { var sortedVerts = vertDict.ToList().OrderBy(x => int.Parse(x.Key)).Select(y => new Tuple <int, int>(int.Parse(y.Key), (int)y.Value)); foreach (var indexId in sortedVerts) { if (vertLocations.TryGetValue(indexId.Item2, out List <PFVertex> vertList)) { vertList.Add(new PFVertex(indexId.Item2, new Point3d(mesh.Vertices[indexId.Item1]))); } else { vertLocations[indexId.Item2] = new List <PFVertex> { new PFVertex(indexId.Item2, new Point3d(mesh.Vertices[indexId.Item1])) }; } } } if (mesh.UserDictionary.TryGetString("Primal", out string primalString)) { primal = Util.DeserializeFoam(primalString); } if (mesh.UserDictionary.TryGetString("Dual", out string dualString)) { dual = Util.DeserializeFoam(dualString); } } if (primal.Cells.Count < 1) { throw new PolyFrameworkException("No serial data stored in the geometry or data has problems!"); } if (updateGeometry) { foreach (var vertex in primal.Vertices) { if (vertLocations.TryGetValue(vertex.Id, out List <PFVertex> vertPostions)) { vertex.Point = PFVertex.AverageVertexes(vertPostions); } } } foreach (var face in primal.Faces) { face.FaceMesh(); face.ComputeCentroid(); face.ComputeFaceNormal(); } foreach (var cell in primal.Cells) { cell.ComputeCentroid(); } primal.Centroid = PFVertex.AverageVertexes(primal.Vertices); if (dual.Cells.Count > 1) { //Util.ConnectDuals(ref primal, ref dual); foreach (var face in dual.Faces) { face.FaceMesh(); face.ComputeCentroid(); face.ComputeFaceNormal(); } foreach (var cell in dual.Cells) { cell.ComputeCentroid(); } dual.Centroid = PFVertex.AverageVertexes(dual.Vertices); } return(primal); }
/// <summary> /// Loads a structure from a set of lines and the attached serial string (JSON) /// If there is a dual present it links the dual and outputs it too /// </summary> /// <param name="edgeLines">The set of line curves with extra data in .UserDictionary</param> /// <param name="dual">The dual. If empty structure then no dual was found</param> /// <returns></returns> public static PFoam LoadFromEdges(IList <Curve> edgeLines, out PFoam dual, bool updateGeometry = false) { dual = new PFoam(); var primal = new PFoam(); var vertLocations = new Dictionary <int, List <PFVertex> >(); foreach (var edgeLine in edgeLines) { if (edgeLine.UserDictionary.TryGetInteger("V0", out int v0)) { if (vertLocations.TryGetValue(v0, out List <PFVertex> vertList)) { vertList.Add(new PFVertex(v0, edgeLine.PointAtStart)); } else { vertLocations[v0] = new List <PFVertex> { new PFVertex(v0, edgeLine.PointAtStart) }; } } if (edgeLine.UserDictionary.TryGetInteger("V1", out int v1)) { if (vertLocations.TryGetValue(v1, out List <PFVertex> vertList)) { vertList.Add(new PFVertex(v1, edgeLine.PointAtEnd)); } else { vertLocations[v1] = new List <PFVertex> { new PFVertex(v1, edgeLine.PointAtEnd) }; } } if (edgeLine.UserDictionary.TryGetString("Primal", out string primalString)) { primal = Util.DeserializeFoam(primalString); } if (edgeLine.UserDictionary.TryGetString("Dual", out string dualString)) { dual = Util.DeserializeFoam(dualString); } } if (primal.Cells.Count < 1) { throw new PolyFrameworkException("No serial data stored in the geometry or data has problems!"); } if (updateGeometry) { foreach (var vertex in primal.Vertices) { if (vertLocations.TryGetValue(vertex.Id, out List <PFVertex> vertPostions)) { vertex.Point = PFVertex.AverageVertexes(vertPostions); } if (vertex.Fixed) // update the fixed position for the vertex based on new position { vertex.RestrictSupport = new Point(vertex.Point); //vertex.RestrictPosition = vertex.ConstrainPoint; } } } foreach (var face in primal.Faces) { face.FaceMesh(); face.ComputeCentroid(); face.ComputeFaceNormal(); } foreach (var cell in primal.Cells) { cell.ComputeCentroid(); } primal.Centroid = PFVertex.AverageVertexes(primal.Vertices); if (dual.Cells.Count > 1) { //Util.ConnectDuals(ref primal, ref dual); foreach (var face in dual.Faces) { face.FaceMesh(); face.ComputeCentroid(); face.ComputeFaceNormal(); } foreach (var cell in dual.Cells) { cell.ComputeCentroid(); } dual.Centroid = PFVertex.AverageVertexes(dual.Vertices); } return(primal); }
public IList <PFEdge> PickEdgeSingle(IList <PFEdge> available = null) { var pickedEdges = new List <PFEdge>(); var doc = Rhino.RhinoDoc.ActiveDoc; var selection = new HashSet <PFEdge>(); if (available != null && available.Count > 0) { selection = new HashSet <PFEdge>(available.Where(x => x.Id > 0)); } else { selection = new HashSet <PFEdge>(Edges.Where(x => x.Id > 0)); } var intPositiveEdges = Edges.Where(x => selection.Contains(x)).ToList(); var midPoints = intPositiveEdges.Select(x => PFVertex.AverageVertexes(x.Vertices)); var edgeConduit = new DrawPFEdgeConduit(intPositiveEdges) { Enabled = true }; doc.Views.Redraw(); var gEdge = new GetPFEdge(intPositiveEdges); gEdge.AddSnapPoints(midPoints.ToArray()); while (true) { gEdge.SetCommandPrompt("select Edge by mid-point. (<ESC> to exit"); gEdge.AcceptNothing(true); gEdge.AcceptString(true); //gVert.SetCursor() // this we can change after switching to Rhino 6 - api gEdge.SetDefaultString($"({pickedEdges.Count}) edges selected press <Enter> to accept"); gEdge.Get(true); doc.Views.Redraw(); var result = gEdge.CommandResult(); var strResult = gEdge.StringResult(); pickedEdges = new List <PFEdge>(); if (gEdge.CommandResult() == Rhino.Commands.Result.Cancel) { break; } bool breakFlag = false; foreach (var edge in intPositiveEdges) { if (edge.Picked) { edge.Picked = false; pickedEdges.Add(edge); breakFlag = true; doc.Views.Redraw(); break; } } if (breakFlag) { break; } //edgeConduit.UpdateLines(); //doc.Views.Redraw(); if (gEdge.GotDefault()) { break; } } edgeConduit.Enabled = false; doc.Views.Redraw(); return(pickedEdges); }
public IList <PFEdge> PickEdge(IList <PFEdge> available = null) { var pickedEdges = new List <PFEdge>(); var doc = Rhino.RhinoDoc.ActiveDoc; var selection = new HashSet <PFEdge>(); if (available != null && available.Count > 0) { selection = new HashSet <PFEdge>(available.Where(x => x.Id > 0)); } else { selection = new HashSet <PFEdge>(Edges.Where(x => x.Id > 0)); } var intPositiveEdges = Edges.Where(x => selection.Contains(x) && x.Vertices.All(y => !y.External)).ToList(); var midPoints = intPositiveEdges.Select(x => PFVertex.AverageVertexes(x.Vertices)); var edgeConduit = new DrawPFEdgeConduit(intPositiveEdges) { Enabled = true }; doc.Views.Redraw(); var gEdge = new GetPFEdge(intPositiveEdges); //var permOption = new OptionToggle(false, "temp", "perm"); gEdge.SetCommandPrompt("select Edges by mid-points. (<ESC> to exit"); //gEdge.AddOptionToggle("Remember", ref permOption); gEdge.AcceptNothing(true); gEdge.AcceptString(true); gEdge.AddSnapPoints(midPoints.ToArray()); while (true) { gEdge.SetCursor(CursorStyle.Hand); // this we can change after switching to Rhino 6 - api gEdge.SetDefaultString($"({pickedEdges.Count}) edges selected press <Enter> to accept"); gEdge.Get(true); doc.Views.Redraw(); var result = gEdge.CommandResult(); var strResult = gEdge.StringResult(); pickedEdges = new List <PFEdge>(); if (gEdge.CommandResult() == Rhino.Commands.Result.Cancel) { break; } foreach (var edge in intPositiveEdges) { if (edge.Picked) { edge.Picked = false; pickedEdges.Add(edge); edge.TargetLength = GetData.GetDoubleInViewport(PFVertex.AverageVertexes(edge.Vertices), edge.TargetLength); edge.InfluenceCoef = 1; doc.Views.Redraw(); break; } } //edgeConduit.UpdateLines(); //doc.Views.Redraw(); if (gEdge.GotDefault()) { break; } } edgeConduit.Enabled = false; doc.Views.Redraw(); return(pickedEdges); }
//float scale = 96 / (float)(int)Registry.GetValue("HKEY_CURRENT_USER\\Control Panel\\Desktop", "LogPixels", 96); public DrawPFEdgeConduit(List <PFEdge> edges) { m_conduit_edges = edges; m_conduit_edgeLines = edges.Select(x => x.CreateLine()).ToList(); m_conduit_midPoints = edges.Select(x => PFVertex.AverageVertexes(x.Vertices)).ToList(); }