Пример #1
0
        /// <summary>
        /// Finds the cell a point is in relative to an edge
        /// The cell is part of the list of cells the edge is connected to.
        /// </summary>
        /// <param name="position">new vertex position</param>
        /// <returns>the cell the point is in</returns>
        public PFCell PointInCell(Point3d position)
        {
            // get all faces containing the edge
            // create dictionary with face normals pairs for each cell
            // see if vector from vert to point has the same direction as all the normals of those faces
            // if yes break

            var cellDihedrals = new Dictionary <PFCell, HashSet <Vector3d> >();

            //new Dictionary<PFCell, HashSet<Vector3d>>();

            foreach (var face in Faces)
            {
                if (cellDihedrals.TryGetValue(face.Cell, out HashSet <Vector3d> dihedral))
                {
                    dihedral.Add(face.Normal);
                }
                else
                {
                    cellDihedrals[face.Cell] = new HashSet <Vector3d> {
                        face.Normal
                    };
                }
            }

            PFCell result = new PFCell();

            foreach (var keyValue in cellDihedrals)
            {
                if (Util.InsideHedra(Vertices[0].Point, position, keyValue.Value.ToList()))
                {
                    result = keyValue.Key;
                    break;
                }
            }
            return(result);
        }
Пример #2
0
        /// <summary>
        /// Finds the cell some vertex moved into.
        /// The cell is part of the list of cells the vertex is connected to.
        /// </summary>
        /// <param name="position">new vertex position</param>
        /// <returns>the cell the vertex moves into</returns>
        public PFCell PointInCell(Point3d position)
        {
            // get all cells containing the vert
            // get all faces from cell containing the vert
            // see if vector from vert to point has the same direction as all the normals of those faces
            // if yes break
            if (Cells.Count == 0)
            {
                PopulateVertexCells();
            }


            var cellTrihedrals = Cells.ToDictionary(cell => cell, cell => new HashSet <Vector3d>());

            //new Dictionary<PFCell, HashSet<Vector3d>>();

            foreach (var face in Faces)
            {
                cellTrihedrals[face.Cell].Add(face.Normal);
            }

            PFCell result = new PFCell();

            foreach (var keyValue in cellTrihedrals)
            {
                if (!keyValue.Key.Exterior)
                {
                    if (Util.InsideHedra(Point, position, keyValue.Value.ToList()))
                    {
                        result = keyValue.Key;
                        break;
                    }
                }
            }
            return(result);
        }
Пример #3
0
        /// <summary>
        /// This deserializes a whole foam object from a Json string.
        /// Since it only looks at a singular object the dual cannot be deserialized here.
        /// Instead placeholder object will be used in the properties for the dual.
        ///
        /// </summary>
        /// <param name="jsonFoam"></param>
        /// <returns></returns>
        public static PFoam DeserializeFoam(string jsonFoam)
        {
            if (jsonFoam == "")
            {
                return(new PFoam());
            }
            // get the foam dict
            JavaScriptSerializer json = new JavaScriptSerializer();

            json.MaxJsonLength = 2147483647;

            var foamPropDict = json.Deserialize <Dictionary <string, object> >(jsonFoam);
            // create the foam and add its ID
            PFoam foam = new PFoam()
            {
                Id = (string)foamPropDict["Id"]
            };


            // extract the vertices dictionary and partially extract the vertices into the foam
            // create dicts for all properties that cannot be deserialized directly into the object.
            // also a new dict (Id, vertex)
            var vertObjDict = foamPropDict["Vertices"] as Dictionary <string, object>;
            var vertDict    = new Dictionary <int, PFVertex>();
            var vertEdgesId = new Dictionary <PFVertex, List <int> >();
            var vertFacesId = new Dictionary <PFVertex, List <int> >();
            var vertCellsId = new Dictionary <PFVertex, List <int> >();

            // since there is no real object from another foam to deserialize as dual
            // a place holder object is to be replaced as soon as the dual is available
            // var vertDualId = new Dictionary<PFVertex, int>();
            foreach (var vertKeyVal in vertObjDict)
            {
                var vertPropDict = vertKeyVal.Value as Dictionary <string, object>;

                PFVertex vert = new PFVertex();
                vert.Id = (int)vertPropDict["Id"];
                //Dictionary<string, double> coordList = vertPropDict["Point"] as Dictionary<string, double>;
                vert.Point    = PointFromDict(vertPropDict["Point"] as Dictionary <string, object>);
                vert.External = (bool)vertPropDict["External"];

                // this will make new versions compatible with older data json strings
                if (vertPropDict.ContainsKey("SupportGuid"))
                {
                    vert.SupportGuid   = Guid.Parse(vertPropDict["SupportGuid"] as string); // this will throw an exception if there is no guid
                    vert.InfluenceCoef = Convert.ToDouble(vertPropDict["InfluenceCoef"]);   // idem
                    vert.Fixed         = (bool)vertPropDict["Fixed"];                       // idem
                    vert.OnGeo         = (bool)vertPropDict["OnGeo"];
                    if (vert.SupportGuid != Guid.Empty)                                     // now try and find the object in the document
                    {
                        var restrGeo = Rhino.RhinoDoc.ActiveDoc.Objects.FindId(vert.SupportGuid);
                        if (restrGeo != null)
                        {
                            foam.SetVertexConstraints(new List <PFVertex> {
                                vert
                            }, restrGeo, vert.InfluenceCoef, vert.OnGeo);
                        }
                    }
                    if (vert.Fixed)
                    {
                        foam.SetVertexConstraints(new List <PFVertex> {
                            vert
                        }, new Point(vert.Point), 100, vert.OnGeo);
                        // this needs to be update after the offset part... based on the geometry
                    }
                }



                vertEdgesId[vert] = (vertPropDict["Edges"] as ArrayList).Cast <int>().ToList();
                vertFacesId[vert] = (vertPropDict["Faces"] as ArrayList).Cast <int>().ToList();
                vertCellsId[vert] = (vertPropDict["Cells"] as ArrayList).Cast <int>().ToList();
                vert.Dual         = new PFCell((int)vertPropDict["Dual"]); // dummy cell for dual
                //vertDualId[vert] = (int)vertPropDict["Dual"];
                foam.Vertices.Add(vert);
                vertDict.Add(vert.Id, vert);
            }


            // extract the edges from the dictionary and put the vertices in the edges.
            // after also put the pairs in the edges
            // create dictionaries for all properties not immediately fillable
            var edgeObjDict   = foamPropDict["Edges"] as Dictionary <string, object>;
            var edgeDict      = new Dictionary <int, PFEdge>();
            var edgePair      = new Dictionary <PFEdge, int>();
            var edgeFaces     = new Dictionary <PFEdge, List <int> >();
            var edgeFaceAngle = new Dictionary <PFEdge, List <double> >();
            var edgeDual      = new Dictionary <PFEdge, int>();

            foreach (var edgeKeyVal in edgeObjDict)
            {
                var    edgePropDict = edgeKeyVal.Value as Dictionary <string, object>;
                PFEdge edge         = new PFEdge(Int32.Parse(edgeKeyVal.Key));
                var    edgeVertsIds = (edgePropDict["Vertices"] as ArrayList).Cast <int>();
                foreach (int vertId in edgeVertsIds)
                {
                    edge.Vertices.Add(vertDict[vertId]); // add the vertex in the edge
                }
                //edgeDict[edge.Id] = edge;
                edge.External  = (bool)edgePropDict["External"];
                edge.Deviation = Convert.ToDouble(edgePropDict["Deviation"]);

                // this will make new versions compatible with older data json strings
                if (edgePropDict.ContainsKey("TargetLength"))
                {
                    edge.TargetLength  = Convert.ToDouble(edgePropDict["TargetLength"]);
                    edge.MinLength     = Convert.ToDouble(edgePropDict["MinLength"]);
                    edge.MaxLength     = Convert.ToDouble(edgePropDict["MaxLength"]);
                    edge.InfluenceCoef = Convert.ToDouble(edgePropDict["InfluenceCoef"]);
                }


                // put all properties that can't be filled right now in their dictionaries
                edgePair[edge]      = (int)edgePropDict["Pair"]; // for keeping score of the pair easier
                edgeFaces[edge]     = (edgePropDict["Faces"] as ArrayList).Cast <int>().ToList();
                edgeFaceAngle[edge] = (edgePropDict["FaceAngle"] as ArrayList).ToArray().Select(x => Convert.ToDouble(x)).ToList();
                edge.Dual           = new PFFace((int)edgePropDict["Dual"]); // dummy face for dual just placeholder
                // add edge to foam and edgeDict;
                foam.Edges.Add(edge);
                edgeDict.Add(edge.Id, edge);
            }
            // now that all the edges have been extracted we can populate edge.Pair
            foreach (var edge in foam.Edges)
            {
                edge.Pair = edgeDict[edgePair[edge]];
            }

            // extract the faces from the dictionary

            var faceObjDict = foamPropDict["Faces"] as Dictionary <string, object>;
            var faceDict    = new Dictionary <int, PFFace>();
            var faceCell    = new Dictionary <PFFace, int>();
            var facePair    = new Dictionary <PFFace, int>();

            foreach (var faceKeyVal in faceObjDict)
            {
                var    facePropDict = faceKeyVal.Value as Dictionary <string, object>;
                PFFace face         = new PFFace(Int32.Parse(faceKeyVal.Key));
                var    faceVertsIds = (facePropDict["Vertices"] as ArrayList).Cast <int>().ToList();
                foreach (var vertId in faceVertsIds)
                {
                    face.Vertices.Add(vertDict[vertId]);
                }
                var faceEdgesIds = (facePropDict["Edges"] as ArrayList).Cast <int>().ToList();
                face.Edges     = faceEdgesIds.Select(x => edgeDict[x]).ToList();
                faceCell[face] = (int)facePropDict["Cell"];
                facePair[face] = (int)facePropDict["Pair"];
                face.Normal    = VectorFromDict(facePropDict["Normal"] as Dictionary <string, object>);
                face.Centroid  = PointFromDict(facePropDict["Centroid"] as Dictionary <string, object>);
                face.Dual      = new PFEdge((int)facePropDict["Dual"]); // create a dummy edge as dual - replace later
                face.External  = (bool)facePropDict["External"];
                face.Area      = Convert.ToDouble(facePropDict["Area"]);

                if (facePropDict.ContainsKey("TargetArea"))
                {
                    face.TargetArea    = Convert.ToDouble(facePropDict["TargetArea"]);
                    face.InfluenceCoef = Convert.ToDouble(facePropDict["InfluenceCoef"]);
                }


                // add face to foam.faces and faceDict
                foam.Faces.Add(face);
                faceDict.Add(face.Id, face);
            }
            foreach (var face in foam.Faces)
            {
                face.Pair = faceDict[facePair[face]];
            }

            // extract cells from the dictionary
            var cellObjDict = foamPropDict["Cells"] as Dictionary <string, object>;
            var cellDict    = new Dictionary <int, PFCell>();

            foreach (var cellKeyVal in cellObjDict)
            {
                var    cellPropDict = cellKeyVal.Value as Dictionary <string, object>;
                PFCell cell         = new PFCell(Int32.Parse(cellKeyVal.Key));
                var    cellVertsIds = (cellPropDict["Vertices"] as ArrayList).Cast <int>();
                cell.Vertices = cellVertsIds.Select(x => vertDict[x]).ToList();
                var cellEdgesIds = (cellPropDict["Edges"] as ArrayList).Cast <int>();
                cell.Edges = cellEdgesIds.Select(x => edgeDict[x]).ToList();
                var cellFacesIds = (cellPropDict["Faces"] as ArrayList).Cast <int>();
                cell.Faces    = cellFacesIds.Select(x => faceDict[x]).ToList();
                cell.Centroid = PointFromDict(cellPropDict["Centroid"] as Dictionary <string, object>);
                cell.Dual     = (cellPropDict["Dual"] as ArrayList).Cast <int>().Select(x => new PFVertex(x, Point3d.Unset)).ToList(); // list of dummy points to be changed later
                cell.Exterior = (bool)cellPropDict["Exterior"];
                // add cell to foam.cells and cellDict
                foam.Cells.Add(cell);
                cellDict.Add(cell.Id, cell);
            }

            //populate properties of vertices
            foreach (var vert in foam.Vertices)
            {
                vert.Edges = vertEdgesId[vert].Select(x => edgeDict[x]).ToList();
                vert.Faces = vertFacesId[vert].Select(x => faceDict[x]).ToList();
                vert.Cells = vertCellsId[vert].Select(x => cellDict[x]).ToList();
            }
            //populate properties of edges
            foreach (var edge in foam.Edges)
            {
                edge.Faces     = edgeFaces[edge].Select(x => faceDict[x]).ToList();
                edge.FaceAngle = edgeFaceAngle[edge];
            }
            // populate the properties of faces
            foreach (var face in foam.Faces)
            {
                face.Cell = cellDict[faceCell[face]];
            }

            // now deserialize all other properties
            foam.ExtVetices = (foamPropDict["ExtVertices"] as ArrayList).Cast <int>().Select(x => vertDict[x]).ToList();
            foam.ExtEdges   = (foamPropDict["ExtEdges"] as ArrayList).Cast <int>().Select(x => edgeDict[x]).ToList();
            foam.ExtFaces   = (foamPropDict["ExtFaces"] as ArrayList).Cast <int>().Select(x => faceDict[x]).ToList();
            foam.Centroid   = PointFromDict(foamPropDict["Centroid"] as Dictionary <string, object>);
            foam.Dual       = new PFoam() // this is a dummy dual just a placeholder with Id
            {
                Id = foamPropDict["Dual"] as string
            };
            foam.MaxDeviation = Convert.ToDouble(foamPropDict["MaxDeviation"]);

            // put also the edges in the vertices - use the vertObjDict for that


            // populate the edges and vertices in the faces


            return(foam);
        }