public static void FindComposedPatterns(List <MyGroupingSurfaceForPatterns> listOfGroupingSurfaceForPatterns,
                                                out List <MyComposedPattern> listOfOutputComposedPattern,
                                                out List <MyComposedPattern> listOfOutputComposedPatternTwo, ModelDoc2 SwModel,
                                                SldWorks mySwApplication, ref StringBuilder fileOutput)

        {
            var toleranceOk              = true;
            var listOfComposedPattern    = new List <MyComposedPattern>();
            var listOfComposedPatternTwo = new List <MyComposedPattern>();

            //For each MyGroupingSurfaceForPatterns
            while (listOfGroupingSurfaceForPatterns.Count > 0 && toleranceOk)
            {
                var currentGroupingSurfaceForPatterns = new MyGroupingSurfaceForPatterns(
                    listOfGroupingSurfaceForPatterns[0].groupingSurface,
                    listOfGroupingSurfaceForPatterns[0].listOfPatternsLine,
                    listOfGroupingSurfaceForPatterns[0].listOfPatternsCircum);
                listOfGroupingSurfaceForPatterns.RemoveAt(0);

                fileOutput.AppendLine("");
                fileOutput.AppendLine("NUOVA SURFACE OF TYPE: " + currentGroupingSurfaceForPatterns.groupingSurface.Identity());
                fileOutput.AppendLine("(Al momento sono rimaste ancora " + listOfGroupingSurfaceForPatterns.Count +
                                      " superfici (oltre questa).)");

                // >>>>>>> LINEAR CASE:
                //first I group patterns by same length and same distance:
                var listOfListsOfCoherentPatternsLine = GroupFoundPatternsOfTypeLine(
                    currentGroupingSurfaceForPatterns.listOfPatternsLine, mySwApplication);
                if (listOfListsOfCoherentPatternsLine.Count == 0)
                {
                }

                //Then I group coherent patterns in subgroups of parallel patterns:
                foreach (var list in listOfListsOfCoherentPatternsLine)
                {
                    //Grouping in lists of parallel patterns
                    var listOfListsOfParallelPatterns = GroupPatternsInParallel(list);
                    var numOfListsOfParallelPatterns  = listOfListsOfParallelPatterns.Count;

                    if (list.Count == 2)
                    {
                        //I verify if a composed pattern with these 2 patterns has already been created
                        //in another GS:
                        if (ComposedPatternOfLength2AlreadyExists(listOfComposedPatternTwo, list) == false)
                        {
                            //if a composed pattern does not exist yet AND
                            //the 2 patterns are not parallel, I verify if it is REFLECTION:
                            if (numOfListsOfParallelPatterns == 0)
                            {
                                if (IsReflectionTwoPatterns(list[0], list[1]))
                                {
                                    var typeOfNewComposedPattern = "Composed REFLECTION of length 2";
                                    BuildNewComposedPatternOfLength2(fileOutput, typeOfNewComposedPattern,
                                                                     ref listOfComposedPattern, ref listOfComposedPatternTwo,
                                                                     ref listOfGroupingSurfaceForPatterns, list);
                                }
                            }
                            else
                            //if a composed pattern does not exist yet AND
                            //the 2 patterns are parallel, I verify if it is TRANSLARION:
                            {
                                if (IsTranslationTwoPatterns(list[0], list[1]))
                                {
                                    var typeOfNewComposedPattern = "Composed TRANSLATION of length 2";
                                    BuildNewComposedPatternOfLength2(fileOutput, typeOfNewComposedPattern,
                                                                     ref listOfComposedPattern, ref listOfComposedPatternTwo,
                                                                     ref listOfGroupingSurfaceForPatterns, list);
                                }
                                else
                                {
                                    if (IsReflectionTwoPatterns(list[0], list[1]))
                                    {
                                        var typeOfNewComposedPattern = "Composed REFLECTION of length 2";
                                        BuildNewComposedPatternOfLength2(fileOutput, typeOfNewComposedPattern,
                                                                         ref listOfComposedPattern, ref listOfComposedPatternTwo,
                                                                         ref listOfGroupingSurfaceForPatterns, list);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        foreach (var listOfParallelPatterns in listOfListsOfParallelPatterns)
                        {
                            if (listOfParallelPatterns.Count == 2)
                            {
                                //I verify if a composed pattern with these 2 patterns has already been created
                                //in another GS:
                                if (ComposedPatternOfLength2AlreadyExists(listOfComposedPatternTwo, list))
                                {
                                }
                                else
                                {
                                    if (IsTranslationTwoPatterns(listOfParallelPatterns[0], listOfParallelPatterns[1]))
                                    {
                                        var typeOfNewComposedPattern = "Composed TRANSLATION of length 2";
                                        BuildNewComposedPatternOfLength2(fileOutput, typeOfNewComposedPattern,
                                                                         ref listOfComposedPattern, ref listOfComposedPatternTwo,
                                                                         ref listOfGroupingSurfaceForPatterns, listOfParallelPatterns);
                                    }
                                    else
                                    {
                                        if (IsReflectionTwoPatterns(list[0], list[1]))
                                        {
                                            var typeOfNewComposedPattern = "Composed REFLECTION of length 2";
                                            BuildNewComposedPatternOfLength2(fileOutput, typeOfNewComposedPattern,
                                                                             ref listOfComposedPattern, ref listOfComposedPatternTwo,
                                                                             ref listOfGroupingSurfaceForPatterns, list);
                                        }
                                    }
                                }
                            }
                            else //(listOfParallelPatterns.Count > 2)
                            {
                                var listOfPatternCentroids = listOfParallelPatterns.Select(pattern => pattern.patternCentroid).ToList();
                                fileOutput.AppendLine("");
                                fileOutput.AppendLine("        >>>> CREATION OF ADJECENCY MATRICES FOR COMPOSED PATTERNS:");
                                var listOfMyMatrAdj = Functions.CreateMatrAdj(listOfPatternCentroids, ref fileOutput);

                                var maxPath = false; //it is TRUE if the maximum Pattern is found, FALSE otherwise.
                                while (listOfMyMatrAdj.Count > 0 && maxPath == false && toleranceOk)
                                {
                                    var currentMatrAdj = new MyMatrAdj(listOfMyMatrAdj[0].d, listOfMyMatrAdj[0].matr,
                                                                       listOfMyMatrAdj[0].nOccur);
                                    listOfMyMatrAdj.Remove(listOfMyMatrAdj[0]);
                                    //NOTA: forse la mia MatrAdj non deve essere rimossa ma conservata,
                                    //soprattutto nel caso in cui si presenta onlyShortPath = true
                                    //(non avrebbe senso cancellarla, ma conservarla per la ricerca di path
                                    //di 2 RE).
                                    List <MyPathOfPoints> listOfPathsOfCentroids;
                                    bool onlyShortPaths;
                                    maxPath = PathCreation_Part_ComposedPatterns.Functions.FindPaths_ComposedPatterns(currentMatrAdj,
                                                                                                                      listOfParallelPatterns,
                                                                                                                      ref fileOutput, out listOfPathsOfCentroids, out onlyShortPaths, ref toleranceOk,
                                                                                                                      ref listOfMyMatrAdj,
                                                                                                                      ref listOfGroupingSurfaceForPatterns, ref listOfComposedPattern,
                                                                                                                      ref listOfComposedPatternTwo, mySwApplication);
                                    //fileOutput.AppendLine("listOfPathOfCentroids.Count = " + listOfPathOfCentroids.Count, nameFile);

                                    if (toleranceOk)
                                    {
                                        if (listOfPathsOfCentroids != null)
                                        {
                                            if (maxPath == false)
                                            {
                                                if (onlyShortPaths == false)
                                                {
                                                    GetComposedPatternsFromListOfPathsLine(listOfPathsOfCentroids,
                                                                                           listOfParallelPatterns,
                                                                                           ref listOfMyMatrAdj, ref listOfGroupingSurfaceForPatterns,
                                                                                           ref listOfComposedPattern, ref listOfComposedPatternTwo, mySwApplication, ref fileOutput);
                                                }
                                                else
                                                {
                                                    //non faccio niente e li rimetto in gioco per
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        //Now coherent linear patterns that have not been set in a composed pattern yet
                        //are examined to see if they consitute any rotation composed pattern:

                        list.RemoveAll(
                            pattern =>
                            listOfComposedPattern.FindIndex(
                                composedPattern =>
                                composedPattern.listOfMyPattern.FindIndex(
                                    patternInComposedPattern =>
                                    patternInComposedPattern.idMyPattern == pattern.idMyPattern) != -1) != -1);
                        if (list.Count != 0)
                        {
                            if (list.Count == 2)
                            {
                                //  >>> POSSIBLE REFLECTION CAN EXIST

                                //I verify if a composed pattern with these 2 patterns has already been created
                                //in another GS:
                                if (ComposedPatternOfLength2AlreadyExists(listOfComposedPatternTwo, list))
                                {
                                }
                                else
                                {
                                    if (IsReflectionTwoPatterns(list[0], list[1]))
                                    {
                                        var typeOfNewComposedPattern = "Composed REFLECTION of length 2";
                                        BuildNewComposedPatternOfLength2(fileOutput, typeOfNewComposedPattern,
                                                                         ref listOfComposedPattern, ref listOfComposedPatternTwo,
                                                                         ref listOfGroupingSurfaceForPatterns, list);
                                    }
                                }
                            }
                            else
                            {
                                var listOfPatternCentroids1 = list.Select(pattern => pattern.patternCentroid).ToList();
                                fileOutput.AppendLine("");
                                fileOutput.AppendLine("        >>>> CREATION OF ADJECENCY MATRICES FOR COMPOSED PATTERNS:");
                                var listOfMyMatrAdj1 = Functions.CreateMatrAdj(listOfPatternCentroids1, ref fileOutput);

                                var maxPath = false; //it is TRUE if the maximum Pattern is found, FALSE otherwise.
                                while (listOfMyMatrAdj1.Count > 0 && maxPath == false && toleranceOk)
                                {
                                    var currentMatrAdj = new MyMatrAdj(listOfMyMatrAdj1[0].d, listOfMyMatrAdj1[0].matr,
                                                                       listOfMyMatrAdj1[0].nOccur);
                                    listOfMyMatrAdj1.Remove(listOfMyMatrAdj1[0]);
                                    //NOTA: forse la mia MatrAdj non deve essere rimossa ma conservata,
                                    //soprattutto nel caso in cui si presenta onlyShortPath = true
                                    //(non avrebbe senso cancellarla, ma conservarla per la ricerca di path
                                    //di 2 RE).
                                    List <MyPathOfPoints> listOfPathsOfCentroids1;
                                    bool onlyShortPaths1;

                                    var maxPath1 = PathCreation_Part_ComposedPatterns.Functions.FindPaths_ComposedPatterns(currentMatrAdj,
                                                                                                                           list, ref fileOutput, out listOfPathsOfCentroids1, out onlyShortPaths1,
                                                                                                                           ref toleranceOk, ref listOfMyMatrAdj1, ref listOfGroupingSurfaceForPatterns,
                                                                                                                           ref listOfComposedPattern, ref listOfComposedPatternTwo, mySwApplication);

                                    if (toleranceOk)
                                    {
                                        if (listOfPathsOfCentroids1 != null)
                                        {
                                            //I ignore every linear path (I look for composed rotational patterns now):
                                            var listOfCircularPaths =
                                                listOfPathsOfCentroids1.FindAll(
                                                    path =>
                                                    path.pathGeometricObject.GetType() == typeof(MyCircumForPath))
                                                .ToList();

                                            if (maxPath1 == false)
                                            {
                                                if (onlyShortPaths1 == false)
                                                {
                                                    GetComposedPatternsFromListOfPathsLine(listOfCircularPaths,
                                                                                           list, ref listOfMyMatrAdj1, ref listOfGroupingSurfaceForPatterns,
                                                                                           ref listOfComposedPattern, ref listOfComposedPatternTwo, mySwApplication, ref fileOutput);
                                                }
                                                else
                                                {
                                                    //non faccio niente e li rimetto in gioco per
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // >>>>>>> CIRCULAR CASE:
                #region da rivedere
                //first I group patterns by same length and same distance:
                var listOfListsOfCoherentPatternsCircum = GroupFoundPatternsOfTypeCircum(
                    currentGroupingSurfaceForPatterns.listOfPatternsCircum, mySwApplication);

                //Then I group coherent patterns in subgroups of patterns:
                foreach (var list in listOfListsOfCoherentPatternsCircum)
                {
                    var listOfListsOfPatternsWithSameCenterAndPlane = GroupPatternsWithSameCenterPlane(list);
                    var numOfListsOfParallelPatterns = listOfListsOfPatternsWithSameCenterAndPlane.Count;
                    //Grouping in lists of parallel patterns
                    foreach (var listOfPatternsWithSameCenterAndPlane in listOfListsOfPatternsWithSameCenterAndPlane)
                    {
                        if (listOfPatternsWithSameCenterAndPlane.Count == 2)
                        {
                            if (IsTranslationTwoPatterns(listOfPatternsWithSameCenterAndPlane[0], listOfPatternsWithSameCenterAndPlane[1]))
                            {
                                var typeOfNewComposedPattern = "Composed ROTATIONAL (same center) of length 2";
                                BuildNewComposedPatternOfLength2(fileOutput, typeOfNewComposedPattern,
                                                                 ref listOfComposedPattern, ref listOfComposedPatternTwo,
                                                                 ref listOfGroupingSurfaceForPatterns, listOfPatternsWithSameCenterAndPlane);
                            }
                        }
                        else //listOfPatternsWithSameCenterAndPlane.Count > 2
                        {
                            //    var listOfPatternCentroids =
                            //        listOfPatternsWithSameCenterAndPlane.Select(pattern => pattern.patternCentroid).ToList();
                            //    KLdebug.Print("", nameFile);
                            //    KLdebug.Print("        >>>> CREATION OF ADJECENCY MATRICES FOR COMPOSED PATTERNS:", nameFile);
                            //    var listOfMyMatrAdj = Functions.CreateMatrAdj(listOfPatternCentroids, ref fileOutput);

                            //    var indOfMatr = 0;
                            //    List<MyPathOfPoints> listOfPathsOfCentroids;
                            //    bool onlyShortPaths;


                            //    //////////////
                            //    var maxPath = Functions.FindPaths_ComposedPatterns(listOfMyMatrAdj[indOfMatr], listOfPatternsWithSameCenterAndPlane,
                            //            ref fileOutput, out listOfPathsOfCentroids, out onlyShortPaths, ref toleranceOk, ref listOfMyMatrAdj,
                            //            ref listOfGroupingSurfaceForPatterns, ref listOfComposedPattern, ref listOfComposedPatternTwo);

                            //    if (toleranceOk)
                            //    {
                            //        if (maxPath == false)
                            //        {
                            //            if (onlyShortPaths == false)
                            //            {
                            //                GetComposedPatternsFromListOfPathsLine(listOfPathsOfCentroids,
                            //                    listOfPatternsWithSameCenterAndPlane,
                            //                    ref listOfMyMatrAdj, ref listOfGroupingSurfaceForPatterns,
                            //                    ref listOfComposedPattern, ref listOfComposedPatternTwo);
                            //            }
                            //            else
                            //            {
                            //                //non faccio niente e li rimetto in gioco per
                            //            }
                            //        }
                            //    }
                            //    else
                            //    {
                            //        KLdebug.Print("===>>    TOLLERANZA NON SUFFICIENTEMENTE PICCOLA. TERMINATO.", nameFile);
                            //    }
                        }
                    }
                }
            }
            #endregion
            listOfOutputComposedPattern    = listOfComposedPattern;
            listOfOutputComposedPatternTwo = listOfComposedPatternTwo;
        }
        public static void MainPatternSearch_Part(bool EntirePart, ref List <MyGroupingSurface> listOfMyGroupingSurface,
                                                  List <MyGroupingSurface> listOfInitialGroupingSurface, ref StringBuilder fileOutput, SldWorks mySwApplication)
        {
            var listOfOutputPattern    = new List <MyPattern>(); //list of output patterns found
            var listOfOutputPatternTwo = new List <MyPattern>(); //list of output patterns of length 2 found
            var toleranceOK            = true;                   //it is TRUE if the tolerance level is OK during the paths searching, FALSE otherwise

            while (listOfMyGroupingSurface.Count > 0 && toleranceOK == true)
            {
                MyGroupingSurface currentGroupingSurface;
                if (!EntirePart)
                {
                    currentGroupingSurface =
                        new MyGroupingSurface(listOfMyGroupingSurface[0].groupingSurface,
                                              listOfMyGroupingSurface[0].listOfREOfGS);
                }
                else
                {
                    currentGroupingSurface = new MyGroupingSurface(listOfMyGroupingSurface[0].KLplanareSurface,
                                                                   listOfMyGroupingSurface[0].listOfREOfGS);
                }

                listOfMyGroupingSurface.RemoveAt(0);
                fileOutput.AppendLine(" ");
                fileOutput.AppendLine("(Al momento sono rimaste " + listOfMyGroupingSurface.Count +
                                      " superfici, compresa questa.)");

                PartUtilities.GeometryAnalysis.FindPatternsInGS(currentGroupingSurface, ref fileOutput,
                                                                ref listOfOutputPattern, ref listOfMyGroupingSurface,
                                                                ref listOfOutputPatternTwo, ref toleranceOK, listOfInitialGroupingSurface);
            }

            //Assigning of id numbers to the found MyPattern
            //(the id will be used in composed pattern search phase)
            //At the same time, we draw the pattern centroids
            ModelDoc2 SwModel = mySwApplication.ActiveDoc;

            SwModel.ClearSelection2(true);
            SwModel.Insert3DSketch();
            var i = 0;

            foreach (var pattern in listOfOutputPattern)
            {
                pattern.idMyPattern = i;
                i++;
                var listOfCentroidsOfPattern = pattern.listOfMyREOfMyPattern.Select(re => re.centroid).ToList();
                var patternCentroid          = ExtractInfoFromBRep.computeCentroidsOfVertices(listOfCentroidsOfPattern);
                pattern.patternCentroid = patternCentroid;
                //SwModel.CreatePoint2(pattern.patternCentroid.x, pattern.patternCentroid.y, pattern.patternCentroid.z);
            }
            foreach (var pattern in listOfOutputPatternTwo)
            {
                pattern.idMyPattern = i;
                i++;
                var listOfCentroidsOfPattern = pattern.listOfMyREOfMyPattern.Select(re => re.centroid).ToList();
                var patternCentroid          = ExtractInfoFromBRep.computeCentroidsOfVertices(listOfCentroidsOfPattern);
                pattern.patternCentroid = patternCentroid;
                //SwModel.CreatePoint2(pattern.patternCentroid.x, pattern.patternCentroid.y, pattern.patternCentroid.z);
            }
            //SwModel.InsertSketch();

            //Patterns are subdivided in Line patterns and in Circle patterns:
            var listOfOutputPatternLine   = new List <MyPattern>();
            var listOfOutputPatternCircum = new List <MyPattern>();

            foreach (var pattern in listOfOutputPattern)
            {
                if (pattern.pathOfMyPattern.GetType() == typeof(MyLine))
                {
                    listOfOutputPatternLine.Add(pattern);
                }
                else
                {
                    listOfOutputPatternCircum.Add(pattern);
                }
            }

            //The results are shown giving color to the model:
            ColorFace.MyVisualOutput(listOfOutputPatternLine, mySwApplication);
            ColorFace.MyVisualOutput(listOfOutputPatternCircum, mySwApplication);

            //The same for patterns of length 2:

            ColorFace.MyVisualOutput(listOfOutputPatternTwo, mySwApplication);

            //Build the list of MyGroupingSurfaceForPatterns:
            var listOfGroupingSurfaceForPatterns = new List <MyGroupingSurfaceForPatterns>();

            if (!EntirePart)
            {
                foreach (var gs in listOfInitialGroupingSurface)
                {
                    var listOfPatternsLineForThisGS = listOfOutputPatternLine.FindAll(
                        pattern => pattern.listOfGroupingSurfaces.FindIndex(
                            surface => ExtractInfoFromBRep.MyEqualsSurface(surface, gs.groupingSurface, mySwApplication)) !=
                        -1);
                    var listOfPatternsTwoForThisGS = listOfOutputPatternTwo.FindAll(
                        pattern => pattern.listOfGroupingSurfaces.FindIndex(
                            surface => ExtractInfoFromBRep.MyEqualsSurface(surface, gs.groupingSurface, mySwApplication)) !=
                        -1);
                    listOfPatternsLineForThisGS.AddRange(listOfPatternsTwoForThisGS);

                    var listOfPatternsCircumForThisGS = listOfOutputPatternCircum.FindAll(
                        pattern => pattern.listOfGroupingSurfaces.FindIndex(
                            surface => ExtractInfoFromBRep.MyEqualsSurface(surface, gs.groupingSurface, mySwApplication)) !=
                        -1);
                    if (listOfPatternsLineForThisGS.Count > 1 || listOfPatternsCircumForThisGS.Count > 1)
                    {
                        var newGSForPatterns = new MyGroupingSurfaceForPatterns(gs.groupingSurface,
                                                                                listOfPatternsLineForThisGS, listOfPatternsCircumForThisGS);
                        listOfGroupingSurfaceForPatterns.Add(newGSForPatterns);
                    }
                }
            }


            //>>>>>>>COMPOSED PATTERN SEARCH:
            List <MyComposedPattern> listOfOutputComposedPattern;
            List <MyComposedPattern> listOfOutputComposedPatternTwo;

            PartUtilities_ComposedPatterns.GeometryAnalysis.FindComposedPatterns(listOfGroupingSurfaceForPatterns, out listOfOutputComposedPattern,
                                                                                 out listOfOutputComposedPatternTwo, SwModel, mySwApplication, ref fileOutput);


            ColorFace.MyVisualOutput_ComposedPatterns(listOfOutputComposedPattern,
                                                      listOfOutputComposedPatternTwo, mySwApplication, SwModel);
        }