示例#1
0
        void RefreshNormals()
        {
            Normals          = new Loxyz();
            Normals.Count    = Bounds.Count;
            DrawPoints       = new Loxyz();
            DrawPoints.Count = ParamCurves.Count;
            if (!DrawRelativToSurfaceBase)
            {
                for (int i = 0; i < Bounds.Count; i++)
                {
                    EdgeLoop EL = Bounds[i];
                    for (int k = 0; k < EL.Count; k++)
                    {
                        Edge E = EL[k];
                        DrawPoints[i].Add(E.EdgeStart.Value);
                    }
                }
            }

            for (int i = 0; i < ParamCurves.Count; i++)
            {
                xyArray A = ParamCurves[i].getxyArrayClosed(false);
                if (DrawRelativToSurfaceBase)
                {
                    DrawPoints[i] = A.ToxyzArray();
                }

                int ct = 0;
                for (int t = 0; t < ParamCurves[i].Count; t++)
                {
                    ct = ct + ParamCurves[i][t].Resolution;
                }
                xyzArray NormalsLoop = new xyzArray(ct);
                Normals[i] = NormalsLoop;
                int id = 0;

                for (int j = 0; j < ParamCurves[i].Count; j++)
                {
                    List <Face> L = GetFaces(this, i, j);
                    Edge        E = Bounds[i][j];

                    if (L == null)
                    {
                        Normals = null;

                        DrawPoints = null;
                        return;
                    }
                    double SmoothAngle = Parent.SmoothAngle;
                    xyz    N           = Surface.Normal(0, 0).normalized();
                    xyz    N1          = Surface.Normal(0, 0).normalized();
                    for (int k = 0; k < L.Count; k++)
                    {
                        if (System.Math.Abs((N1 * L[k].Surface.Normal(0, 0).normalized())) > System.Math.Cos(SmoothAngle))
                        {
                            N = N + L[k].Surface.Normal(0, 0).normalized();
                        }
                    }
                    N = N.normalized();
                    if (DrawRelativToSurfaceBase)
                    {
                        Matrix M = Surface.Base.ToMatrix().invert();
                        N = M * N - M * new xyz(0, 0, 0);
                    }

                    NormalsLoop[id] = N;
                    id++;
                }
            }
        }
示例#2
0
        /// <summary>
        /// activates a <b>CatMull</b> division.
        /// </summary>
        public void CatMull()
        {
            for (int i = 0; i < VertexList.Count; i++)
            {
                Vertex3d V = VertexList[i];
                V.Tag = new SubDivisionDescriptor();
            }

            for (int i = 0; i < FaceList.Count; i++)
            {
                Face F = FaceList[i];
                F.DrawRelativToSurfaceBase = false;
                int n = 0;
                for (int j = 0; j < F.Bounds.Count; j++)
                {
                    xyz      subDivCenter = new xyz(0, 0, 0);
                    EdgeLoop EL           = F.Bounds[j];
                    for (int k = 0; k < EL.Count; k++)
                    {
                        n++;
                        Edge E = EL[k];


                        subDivCenter = subDivCenter + E.EdgeStart.Value;
                    }
                    F.Tag = subDivCenter * (1f / (float)EL.Count);
                }
            }

            for (int i = 0; i < FaceList.Count; i++)
            {
                Face F = FaceList[i];

                int n = 0;
                for (int j = 0; j < F.Bounds.Count; j++)
                {
                    EdgeLoop EL = F.Bounds[j];
                    for (int k = 0; k < EL.Count; k++)
                    {
                        n++;
                        Edge E        = EL[k];
                        Face Neighbor = null;
                        if (E.SameSense)
                        {
                            Neighbor = E.EdgeCurve.Neighbors[1] as Face;
                        }
                        else
                        {
                            Neighbor = E.EdgeCurve.Neighbors[0] as Face;
                        }
                        E.Tag = ((xyz)(E.EdgeCurve.Neighbors[1] as Face).Tag + (xyz)(E.EdgeCurve.Neighbors[0] as Face).Tag + E.EdgeStart.Value + E.EdgeEnd.Value) * (1f / 4f);
                        // Mittelwert der Facepunkte und der Anfangs und Endpunkte im Tag speichern
                        //     E.Tag = ((xyz)F.Tag + (xyz)Neighbor.Tag + E.EdgeStart.Value + E.EdgeEnd.Value) * 0.25;
                        //
                        // den Descriptor im Vertex E.EdgeEnd.Tag updaten
                        SubDivisionDescriptor SDD = E.EdgeEnd.Tag as SubDivisionDescriptor;
                        SDD.Edges.Add(E);
                        SDD.Faces.Add(F);
                    }
                }
            }

            // Update Vertixlist
            xyz Q = new xyz(0, 0, 0);
            xyz R = new xyz(0, 0, 0);

            for (int i = 0; i < VertexList.Count; i++)
            {
                Vertex3d V = VertexList[i];
                SubDivisionDescriptor SDV = V.Tag as SubDivisionDescriptor;
                int n = SDV.Faces.Count;
                if (n == 0)
                {
                    return;
                }
                Q = new xyz(0, 0, 0);
                R = new xyz(0, 0, 0);
                for (int j = 0; j < SDV.Faces.Count; j++)
                {
                    Q = (xyz)SDV.Faces[j].Tag + Q;
                }
                Q = Q * (1f / (float)SDV.Faces.Count);


                for (int j = 0; j < SDV.Edges.Count; j++)
                {
                    R = (xyz)SDV.Edges[j].Tag + R;
                }
                R = R * (1f / (float)SDV.Edges.Count);

                xyz S = V.Value;
                V.Value = (Q + R * 2 + S * (n - 3)) * (1f / (float)n);
            }

            // Kanten Ersetzen
            for (int i = 0; i < FaceList.Count; i++)
            {
                Face F = FaceList[i];



                for (int j = 0; j < F.Bounds.Count; j++)
                {
                    EdgeLoop EL = F.Bounds[j];
                    for (int k = 0; k < EL.Count; k++)
                    {
                        Edge E = EL[k];

                        if (E.SameSense)
                        {
                            E.EdgeCurve.A = E.EdgeStart.Value;
                            E.EdgeCurve.B = E.EdgeEnd.Value;
                        }
                    }
                }
            }

            // Kanten Ersetzen
            for (int i = 0; i < FaceList.Count; i++)
            {
                Face F = FaceList[i];



                for (int j = 0; j < F.Bounds.Count; j++)
                {
                    EdgeLoop EL = F.Bounds[j];
                    for (int k = 0; k < EL.Count; k++)
                    {
                        Edge E = EL[k];
                        if (E.SameSense)
                        {
                            Vertex3d V = new Vertex3d((xyz)E.Tag);

                            insertVertexToSameSenseEdge(F, j, k, V);
                            k++;
                        }
                    }
                }
            }

            FaceList Temp = new FaceList();

            for (int i = 0; i < FaceList.Count; i++)
            {
                Face F = FaceList[i];
                for (int x = 0; x < F.Bounds.Count; x++)
                {
                    EdgeLoop EL = F.Bounds[x];



                    Edge E2 = null;

                    Vertex3d V1 = new Vertex3d();
                    V1.Value = (xyz)F.Tag;
                    VertexList.Add(V1);


                    Vertex3d V4 = null;
                    Vertex3d V2 = null;



                    int startIndex = 1;
                    if (EL[0].EdgeStart.Tag == null) // StartPunkt ist eingefügt
                    {
                        startIndex = 0;
                    }

                    int id = startIndex;

                    int  counter = 0;
                    Edge First   = null;
                    Edge Last    = null;
                    while (id >= 0)
                    {
                        counter++;
                        EdgeLoop newEl = new EdgeLoop();

                        V2 = EL[id].EdgeStart;


                        if (id + 1 < EL.Count)
                        {
                            V4 = EL[id + 1].EdgeEnd;
                        }
                        else
                        {
                            V4 = EL[0].EdgeEnd;
                        }
                        Face newF = new Face();
                        newF.Parent = F.Parent;
                        Temp.Add(newF);


                        EdgeLoop   ELF = new EdgeLoop();
                        List <xyz> Pt  = new List <xyz>();
                        newF.Surface = new PlaneSurface(V1.Value, V2.Value, V4.Value);
                        //    newF.Surface = new PlaneSurface(V1.Value, V2.Value, V4.Value);
                        Edge EA = new Edge();
                        ELF.Add(EA);
                        EdgeList.Add(EA);
                        EA.EdgeStart = V1;
                        EA.EdgeEnd   = V2;
                        if (Last == null)
                        {
                            EA.EdgeCurve = new Line3D(V1.Value, V2.Value);
                            Pt.Add(V1.Value);
                            EdgeCurveList.Add(EA.EdgeCurve);
                            EA.EdgeCurve.Neighbors    = new Face[2];
                            EA.SameSense              = true;
                            EA.EdgeCurve.Neighbors[0] = newF;
                            if (id == startIndex)
                            {
                                First = EA;
                            }
                        }
                        else
                        {
                            EA.EdgeStart = Last.EdgeEnd;
                            Pt.Add(EA.EdgeStart.Value);
                            EA.EdgeEnd   = Last.EdgeStart;
                            EA.EdgeCurve = Last.EdgeCurve;
                            EA.EdgeCurve.Neighbors[1] = newF;
                            EA.SameSense = false;
                        }


                        newF.Bounds.Add(ELF);

                        E2 = EL[id];

                        if (E2.SameSense)
                        {
                            E2.EdgeCurve.Neighbors[0] = newF;
                        }
                        else
                        {
                            E2.EdgeCurve.Neighbors[1] = newF;
                        }
                        Pt.Add(E2.EdgeStart.Value);
                        ELF.Add(E2);


                        Edge E3 = null;
                        if (id + 1 < EL.Count)
                        {
                            E3 = EL[id + 1];
                        }
                        else
                        {
                            E3 = EL[0];
                        }
                        Pt.Add(E3.EdgeStart.Value);
                        if (E3.SameSense)
                        {
                            E3.EdgeCurve.Neighbors[0] = newF;
                        }
                        else
                        {
                            E3.EdgeCurve.Neighbors[1] = newF;
                        }



                        ELF.Add(E3);



                        Edge EE = new Edge();
                        EdgeList.Add(EE);
                        EE.EdgeStart = V4;
                        EE.EdgeEnd   = V1;
                        ELF.Add(EE);
                        Pt.Add(V4.Value);


                        if (counter < 4)
                        {
                            EE.EdgeCurve = new Line3D(EE.EdgeStart.Value, EE.EdgeEnd.Value);
                            EdgeCurveList.Add(EE.EdgeCurve);

                            EE.EdgeCurve.Neighbors    = new Face[2];
                            EE.EdgeCurve.Neighbors[0] = newF;
                            EE.SameSense = true;
                        }
                        else
                        {
                            EE.EdgeCurve = First.EdgeCurve;
                            EE.EdgeStart = First.EdgeEnd;
                            EE.EdgeEnd   = First.EdgeStart;
                            EE.EdgeCurve.Neighbors[1] = newF;
                            EE.SameSense = false;
                        }
                        Last = EE;



                        id++;
                        id++;
                        // newF.Surface = new SmoothPlane(Pt[0],Pt[1],Pt[2],Pt[3], new xyz(1, 0, 0), new xyz(1, 0, 0), new xyz(1, 0, 0), new xyz(1, 0, 0));
                        //     newF.Surface = new SmoothPlane(Pt[0], Pt[1], Pt[2], Pt[3], (Pt[0] - Pt[1]) & (Pt[0] - Pt[3]), (Pt[1] - Pt[0]) & (Pt[1] - Pt[2]), (Pt[2] - Pt[1]) & (Pt[3] - Pt[1]), (Pt[0] - Pt[3]) & (Pt[2] - Pt[3]));
                        if (id + 1 > EL.Count)
                        {
                            break;
                        }

                        //   newF.Surface = new PlaneSurface(V1.Value, V2.Value, V4.Value);
                    }
                }
            }
            FaceList = Temp;
            for (int i = 0; i < FaceList.Count; i++)
            {
                Face F = FaceList[i];
                F.Surface.BoundedCurves = new Loca();
                List <xyz> P  = new List <xyz>();
                xyz        P1 = new xyz(0, 0, 0);
                xyz        P2 = new xyz(0, 0, 0);
                xyz        P3 = new xyz(0, 0, 0);
                xyz        P4 = new xyz(0, 0, 0);

                for (int k = 0; k < F.Bounds.Count; k++)
                {
                    CurveArray CA = new CurveArray();
                    F.Surface.BoundedCurves.Add(CA);
                    for (int l = 0; l < F.Bounds[k].Count; l++)
                    {
                        Edge E = F.Bounds[k][l];

                        CA.Add(new Line(F.Surface.ProjectPoint(E.EdgeStart.Value), F.Surface.ProjectPoint(E.EdgeEnd.Value)));
                        if (l < 4)
                        {
                            P.Add(E.EdgeStart.Value);
                        }
                    }
                    if (i == 3)
                    {
                        List <Edge> L1 = new List <Edge>();
                        for (int j = 0; j < 3; j++)
                        {
                            for (int m = 0; m < FaceList[j].Bounds.Count; m++)
                            {
                                xyz A = new xyz(0, 0, 0);
                                for (int h = 0; h < FaceList[j].Bounds[m].Count; h++)
                                {
                                    Edge E = FaceList[j].Bounds[m][h];

                                    L1.Add(E);
                                }
                            }
                        }

                        for (int h = 0; h < L1.Count; h++)
                        {
                            for (int m = 0; m < L1.Count; m++)
                            {
                                if ((L1[h].EdgeStart.Value.dist(L1[m].EdgeStart.Value) < 0.001) && (h != m))
                                {
                                }
                            }
                        }
                    }
                }

                xyz  n  = ((P[2] - P[0]) & (P[1] - P[0]));
                xyz  m1 = ((P[3] - P[0]) & (P[2] - P[0]));
                Loca L  = F.Surface.BoundedCurves;
                if (i / 2 * 2 == i)
                {
                    F.Surface = new SmoothPlane(P[0], P[1], P[2], P[3], n);
                }
                else
                {
                    F.Surface = new SmoothPlane(P[0], P[1], P[2], P[3], m1);
                }
                F.Surface.BoundedCurves = L;



                //   (P[1] - P[0]) & (P[1] - P[2]), (P[2] - P[1]) & (P[2] - P[3]), (P[3] - P[0]) & (P[3] - P[2]));
                F.DrawRelativToSurfaceBase = false;
            }
        }
示例#3
0
        /// <summary>
        /// creates a <see cref="Face"/> for a <see cref="Solid"/> in the <see cref="Model.Solid"/>.
        /// The Curves are all <see cref="Line3D"/>. The <see cref="Face"/> is plane and has as <see cref="Face.Surface"/> a <see cref="PlaneSurface"/>.
        /// </summary>
        /// <param name="Solid">is the target in which the <see cref="Face"/> will be posed.</param>
        /// <param name="Bounds">contains the <see cref="Vertex3d"/> for the <see cref="Line3D"/>.</param>
        /// <returns>a <see cref="Face"/></returns>
        public static Face SolidPlane(Solid Solid, Vertex3dArray_2 Bounds)
        {
            if (Bounds.Count == 0)
            {
                return(null);
            }
            xyz N = new xyz(0, 0, 0);
            xyz P = Bounds[0][0].Value;

            for (int i = 1; i < Bounds[0].Count - 1; i++)
            {
                xyz A = Bounds[0][i].Value;
                xyz B = Bounds[0][i + 1].Value;
                xyz M = N;
                N = N + ((A - P) & (B - P));
            }
            N = N.normalized() * (-1);
            Base Base = Base.UnitBase;

            Base.BaseO = P;
            Base.BaseZ = N;
            if ((Base.BaseZ & new xyz(1, 0, 0)).dist(xyz.Null) > 0.01)
            {
                Base.BaseY = (Base.BaseZ & (new xyz(1, 0, 0))).normalized();
                Base.BaseX = Base.BaseY & Base.BaseZ;
            }
            else
            {
                Base.BaseY = (Base.BaseZ & (new xyz(0, 1, 0))).normalized();
                Base.BaseX = Base.BaseY & Base.BaseZ;
            }

            PlaneSurface Surface = new PlaneSurface();

            Surface.Base = Base;
            //-------------------------------------
            //-------- Create the Face
            Face Result = new Face();

            // ---- With Plane Surface
            Result.Surface = Surface;
            if (Solid != null)
            {
                Solid.FaceList.Add(Result);
            }
            //----- Set the Edges
            for (int i = 0; i < Bounds.Count; i++)
            {
                EdgeLoop Edgeloop = new EdgeLoop();
                Result.Bounds.Add(Edgeloop);
                for (int j = 0; j < Bounds[i].Count; j++)
                {
                    Vertex3d A = Bounds[i][j];
                    Vertex3d B = null;
                    if (j == Bounds[i].Count - 1)
                    {
                        B = Bounds[i][0];
                    }
                    else
                    {
                        B = Bounds[i][j + 1];
                    }
                    Edge E = Edge.SolidEdge(Solid, Result, A, B, new Line3D(A.Value, B.Value));

                    Edgeloop.Add(E);
                }
            }

            Result.RefreshParamCurves();
            return(Result);
        }