예제 #1
0
        private void Form1_Load(object sender, EventArgs e)
        {
            Mesh M = new Mesh();
            FiniteSolverMethod Method = FiniteSolverMethod.EnergyModel;
            //Interop with catia to retrive exported stlPath
            string StlPath = CAT.SaveSurfaceAndFixedPoints(ref M.FixedPoints, ref M.oVecPlane);

            //Parse stlFile to Vertice and triangle matrix
            STLReader.STLRead(StlPath, ref M);
            if (M.Vertices.Count == 0 || M.TrianglesVertices.Count == 0) {
                MessageBox.Show("Não foi encontrada nenhuma informação na superficie exportada. Tente outra vez.");
                Environment.Exit(0);
            }

            //Detection of the most apropriated verticePoints
            M.ComputeFixedPoints();

            //Calculation of Plane of flattening
            M.ComputePlaneofFlattening();

            //Solve using the edge to edge interpretation of the article
            Vector<double> X = EdgeToEdgeSolver.Solve(M);

            //Print Result of triangles in CATIA;
            CAT.PrintTriangles(X, M);
            Vector<double> Y = Vector<double>.Build.Dense(X.Count);
            if (Method== FiniteSolverMethod.NewtonRaphson) {
                //Try to calculate de displacement vector based on finite-element analysis using NewtonRapson Method
                //ATENTION - IS NOT COMPLETE/WITH ERRORS!
                 Y =NewtonRaphsonFiniteSolver.solve(X, M);
            } else if (Method == FiniteSolverMethod.EnergyModel) {
                //Try to calculate de displacement vector based on energy analysis
                //ATENTION - IS NOT COMPLETE/WITH ERRORS!
                Y = EnergyModelFiniteSolver.solve(X, M);
            }
            CAT.PrintTriangles(Y, M);
            Application.Exit();
        }
예제 #2
0
 internal void PrintTriangles(Vector<double> X2, Mesh M)
 {
     PrintTriangles(X2, M.TrianglesVertices, M.oRoot, M.vDir1, M.vDir2, M.OneIndFix, M.OnePointFix);
 }
        public static Vector<double> solve(
            List<double[]> Vertices,
            List<int[]> TrianglesVertices,
            List<double[]> FacetNormals,
            Vector<double> X, Point3D oRoot,
            UnitVector3D vDir1,
            UnitVector3D vDir2, Mesh M)
        {
            //Method from article -Wang,Smith. Surface flattening based on energy model. Computer-Aided Design (2002) 823-833	

            //PseudoCode
            //Input: P - Set of nodes, in the initial position and N is the number of nodes
            //Output: the final positions of P with E(o) minimized

            //  FOR i = 1 TO n
            //        mi = p / 3 Sum(Ak), where Ak is the area

            //  WHILE (Relative Area difference Es > Permissible accuracy or Relative edge length difference Ec > Permissible accuracy)
            //  AND Variation of E(o) > Permissible percentage €
            //  AND the number of iterations < Permissible number N
            //        FOR i = 1 TO n
            //                Compute Tensile force of Node Pi: Fi = Sum(C * (Dist(PiPj) - Dist(QiQj)))nij where(P - 2D - Q - 3D nij - Vector Pi to Pj)
            //                Compute new position of Pi  qi = qi + dtqi. + dt ^ 2 / 2 qi..where qi.= qi.+ dtqi..and qi..= Fi / mi
            //                Compute Penalty force and aplly to Fpi
            //                Compute new position of Pi  qi = qi + dtqi. + dt ^ 2 / 2 qi..where qi.= qi.+ dtqi..and qi..= Fpi / mi
            //        Compute new Es= Sum(TotalAreaNow - TotalAreaBefore) / TotalAreaNow
            //        Compute new Ec= Sum(TotalLenghtNow - TotalLenghtBefore) / TotalLenghtNow
            //        Compute new E(o)Sum(E(pi)) where E(pi) = 0.5 * Sum(C * (Dist(PiPj) - Dist(QiQj))) ^ 2

            double[] Mass = new double [Vertices.Count];
            int[] MassCounter = new int[Vertices.Count];
            double Permissible = 0.00000001;
            Vector<double> Fi = Vector<double>.Build.Dense(2);
            List<Vector<double>> dqi = new List<Vector<double>>();
            List<Vector<double>> qi = new List<Vector<double>>();
            double LastEc = 0, Ec = 0;
            double LastEs = 0, Es = 0;
            double LastEo = 0, Eo = 0;
            double C = 0.5;
            double ro = 1;
            double t = 0.01;
            int N = 100;
            int Iteration = 0;
            double Total = 0;
            double LastTotal = 0;
            foreach (int[] tri in TrianglesVertices) {
                double A = getArea(Vertices[tri[0]], Vertices[tri[1]], Vertices[tri[2]]);
                double P = getPerimeter(Vertices[tri[0]], Vertices[tri[1]], Vertices[tri[2]]);
                Mass[tri[0]] += ((double)1 / (double)3) * A * ro;
                Mass[tri[1]] += ((double)1 / (double)3) * A * ro;
                Mass[tri[2]] += ((double)1 / (double)3) * A * ro;
                MassCounter[tri[0]] += 1;
                MassCounter[tri[1]] += 1;
                MassCounter[tri[2]] += 1;
                LastEc += A;
                LastEs += P;
            }
            for (int i = 0; i < Vertices.Count; i++) {
                Mass[i] = Mass[i] / MassCounter[i];
                qi.Add(Vector<double>.Build.DenseOfArray(new double[] { X[i * 2], X[i * 2 + 1], 0 }));
                dqi.Add(Vector<double>.Build.DenseOfArray(new double[] { 0, 0, 0 }));
            }
            do {
                Iteration += 1;
                LastEo = Eo;
                Eo = 0;
                Total = 0;
                for (int i = 0; i < Vertices.Count; i++) {
                    Point3D Pi = new Point3D(qi[i][0], qi[i][1], qi[i][2]);
                    Point3D Qi = new Point3D(Vertices[i][0], Vertices[i][1], Vertices[i][2]);
                    Fi = Vector<double>.Build.Dense(3);
                    for (int j = i+1; j < Vertices.Count; j++) {
                        if (i == j) continue;
                        Point3D Pj = new Point3D(qi[j][0], qi[j][1], qi[j][2]);
                        Point3D Qj = new Point3D(Vertices[j][0], Vertices[j][1], Vertices[j][2]);
                        UnitVector3D nij = new UnitVector3D((Pi.ToVector()- Pj.ToVector()).ToArray());
                        Fi += C * ((Pi.DistanceTo(Pj) - Qi.DistanceTo(Qj)) * nij).ToVector();
                        Eo += Math.Pow(C * ((Pi.DistanceTo(Pj) - Qi.DistanceTo(Qj))), 2);
                    }
                    Vector<double> ddqi = Fi / Mass[i];
                    Console.WriteLine(Fi);
                    dqi[i] += t * ddqi;
                    qi[i] += dqi[i] * t + 0.5 * Math.Pow(t, 2) * ddqi;

                    Total += Math.Abs(qi[i][0] - X[i * 2]);
                    Total += Math.Abs(qi[i][1] - X[i * 2] + 1);
                }
                Console.WriteLine(Total- LastTotal);
                LastTotal = Total;
                LastEc = Ec;
                Ec = 0;
                LastEs = Es;
                Es = 0;
                foreach (int[] tri in TrianglesVertices) {
                    double A = getArea(Vertices[tri[0]], Vertices[tri[1]], Vertices[tri[2]]);
                    double P = getPerimeter(Vertices[tri[0]], Vertices[tri[1]], Vertices[tri[2]]);
                    Ec += A;
                    Es += P;
                }
                if (((Ec - LastEc) / Ec < Permissible || (Es - LastEs) / Es < Permissible)
                    && (Eo - LastEo) / Eo < Permissible
                    && Iteration > N) break;
            } while (true);
            Vector<double> XResult = Vector<double>.Build.DenseOfArray(X.ToArray());

            for (int i = 0; i < Vertices.Count; i++) {
                //Console.WriteLine(qi[i][0] - X[i * 2]);
                Total += Math.Abs(qi[i][0] - X[i * 2]);
                XResult[i * 2] = qi[i][0];
                //Console.WriteLine(qi[i][1] - X[i * 2+1]);
                Total += Math.Abs(qi[i][1] - X[i * 2]+1);
                XResult[i * 2+1] = qi[i][1];
            }
            Console.WriteLine(Total);
            return XResult;
        }
 internal static Vector<double> solve(Vector<double> X, Mesh M)
 {
     return solve(M.Vertices, M.TrianglesVertices, M.FacetNormals, X, M.oRoot, M.vDir1, M.vDir2,M);
 }
예제 #5
0
 internal static void STLRead(string stlPath, ref Mesh M)
 {
     STLRead(stlPath, ref M.Vertices, ref M.TrianglesVertices, ref M.TrianglesEdges, ref M.Edges, ref M.FacetNormals);
 }
 internal static Vector<double> Solve(Mesh M)
 {
     return Solve(M.Vertices, M.TrianglesEdges, M.Edges, M.IndiceOfFixedPoints, M.oRoot, M.vDir1, M.vDir2);
 }