Пример #1
0
        public Shell Result()
        {
            // the fillets edges fall into one of three categories:
            // - lengthwayTangential: edges that are tangential to other faces, i.e. they round the other faces
            // - crossway: edges that connect fillets
            // - filletEnd: here the fillets end or are otherwise broken up
            HashSet <Face>          lengthwayTangential = new HashSet <Face>();          // the two faces that this fillet rounds
            HashSet <Edge>          crossway            = new HashSet <Edge>();          // connection to the following or previous fillet
            HashSet <Edge>          lengthway           = new HashSet <Edge>();          // connection between fillet and rounded face
            HashSet <Edge>          filletEnd           = new HashSet <Edge>();          // an edge which is the end of a fillet
            Dictionary <Edge, Face> forking             = new Dictionary <Edge, Face>(); // a spherical face, where the fillets fork

            foreach (Face face in fillets)
            {
                if (face.Surface is ISurfaceOfArcExtrusion extrusion)
                {
                    foreach (Edge edge in face.AllEdgesIterated())
                    {
                        Face otherFace = edge.OtherFace(face);
                        if (edge.IsTangentialEdge() && edge.Curve2D(face).DirectionAt(0.5).IsMoreHorizontal != extrusion.ExtrusionDirectionIsV)
                        {
                            lengthwayTangential.Add(otherFace);
                            lengthway.Add(edge);
                        }
                        else if (fillets.Contains(otherFace))
                        {
                            crossway.Add(edge);
                        }
                        else
                        {
                            filletEnd.Add(edge);
                        }
                    }
                }
                else if (face.Surface is SphericalSurface)
                {
                    foreach (Edge edge in face.AllEdgesIterated())
                    {
                        Face otherFace = edge.OtherFace(face);
                        if (fillets.Contains(otherFace))
                        {
                            crossway.Add(edge);
                        }
                    }
                }
            }
            Dictionary <Edge, Vertex>   crosswayToVertex  = new Dictionary <Edge, Vertex>();
            Dictionary <Vertex, Vertex> verticesToReplace = new Dictionary <Vertex, Vertex>();

            foreach (Edge edg in Extensions.Combine <Edge>(crossway, filletEnd))
            {
                HashSet <Face> involved = edg.Vertex1.InvolvedFaces;
                involved.UnionWith(edg.Vertex2.InvolvedFaces);
                involved.ExceptWith(fillets);
                HashSet <Edge> involvedCrosswayEdges = new HashSet <Edge>();
                involvedCrosswayEdges.Add(edg);
                if (involved.Count < 3)
                {   // maybe the edge is part of a spherical face
                    Face sph = null;
                    if (edg.PrimaryFace.Surface is SphericalSurface && fillets.Contains(edg.PrimaryFace))
                    {
                        sph = edg.PrimaryFace;
                    }
                    else if (edg.SecondaryFace.Surface is SphericalSurface && fillets.Contains(edg.SecondaryFace))
                    {
                        sph = edg.SecondaryFace;
                    }
                    if (sph != null)
                    {
                        foreach (Edge spedge in sph.AllEdges)
                        {
                            if (spedge != edg && fillets.Contains(spedge.OtherFace(sph)))
                            {
                                involvedCrosswayEdges.Add(spedge);
                                involved.UnionWith(spedge.Vertex1.InvolvedFaces);
                                involved.UnionWith(spedge.Vertex2.InvolvedFaces);
                            }
                        }
                    }
                    involved.ExceptWith(fillets);
                }
                if (involved.Count >= 3) // which should be the case
                {
                    Face[]   ia = involved.ToArray();
                    GeoPoint ip = edg.Curve3D.PointAt(0.5);
                    if (Surfaces.IntersectThreeSurfaces(ia[0].Surface, ia[0].Domain, ia[1].Surface, ia[1].Domain, ia[2].Surface, ia[2].Domain, ref ip, out GeoPoint2D uv0, out GeoPoint2D uv1, out GeoPoint2D uv2))
                    {   // there should be an intersection point close to the middle of the crossway edge
                        Vertex v = new Vertex(ip);
                        foreach (Edge edge in involvedCrosswayEdges)
                        {
                            crosswayToVertex[edge]          = v;
                            verticesToReplace[edge.Vertex1] = v;
                            verticesToReplace[edge.Vertex2] = v;
                        }
                    }
                    else
                    {   // maybe two surfaces are identical with different domains: find a common edge
                        ip = edg.Curve3D.PointAt(0.5);
                        bool found = false;
                        for (int i = 0; i < involved.Count - 1; i++)
                        {
                            for (int j = i + 1; j < involved.Count; j++)
                            {
                                IEnumerable <Edge> commonEdges = new HashSet <Edge>(ia[i].AllEdges).Intersect(ia[j].AllEdges);
                                foreach (Edge e in commonEdges)
                                {
                                    if (e.IsConnected(edg))
                                    {
                                        for (int k = 0; k < involved.Count; k++)
                                        {
                                            if (k != i && k != j)
                                            {
                                                ia[k].Surface.Intersect(e.Curve3D, ia[k].Domain, out GeoPoint[] ips, out GeoPoint2D[] uvOnK, out double[] uOnCurve);