Пример #1
0
        /// <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;
        }
Пример #2
0
        /// <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;
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <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
            });
        }
Пример #5
0
        /// <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;
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        //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();
        }