private static List <string> PartsLockedByTheFastenerFinder(TessellatedSolid fastener, Dictionary <string, List <TessellatedSolid> > solidsNoFastener,
                                                                    Dictionary <TessellatedSolid, List <PrimitiveSurface> > solidPrimitive)
        {
            PotentialCollisionOfFastenerAndSolid      = new List <string>();
            PotentialCollisionOfFastenerAndSolidStep2 = new List <string>();
            PotentialCollisionOfFastenerAndSolidStep3 = new List <string>();
            var lockedByTheFastener = new List <string>();

            foreach (var subAssem in solidsNoFastener)
            {
                foreach (var solid in subAssem.Value)
                {
                    // This has a way simpler blocking determination code. Check it out:
                    if (!BlockingDetermination.BoundingBoxOverlap(fastener, solid))
                    {
                        continue;
                    }
                    if (!BlockingDetermination.ConvexHullOverlap(fastener, solid))
                    {
                        continue;
                    }
                    if (!BlockingDetermination.ProximityFastener(fastener, solid))
                    {
                        continue;
                    }
                    //if (!FastenerPrimitiveOverlap(solidPrimitive[fastener], solidPrimitives)) continue;
                    lockedByTheFastener.Add(subAssem.Key);
                    break;
                }
            }
            if (!lockedByTheFastener.Any() && PotentialCollisionOfFastenerAndSolid.Any())
            {
                lockedByTheFastener.AddRange(PotentialCollisionOfFastenerAndSolid);
            }
            else if (!lockedByTheFastener.Any() && PotentialCollisionOfFastenerAndSolidStep2.Any())
            {
                lockedByTheFastener.AddRange(PotentialCollisionOfFastenerAndSolidStep2);
            }
            else if (!lockedByTheFastener.Any() && PotentialCollisionOfFastenerAndSolidStep3.Any())
            {
                lockedByTheFastener.AddRange(PotentialCollisionOfFastenerAndSolidStep3);
            }
            return(lockedByTheFastener);
        }
        internal static Dictionary <int, List <Component[]> > NonAdjacentBlocking = new Dictionary <int, List <Component[]> >(); //Component[0] is blocked by Component[1]
        internal static List <int> Run(designGraph assemblyGraph, List <TessellatedSolid> solids)
        {
            Solids     = new List <TessellatedSolid>(solids);
            Directions = IcosahedronPro.DirectionGeneration();
            var globalDirPool  = new List <int>();
            var solidPrimitive = BlockingDetermination.PrimitiveMaker(solids);

            //var gears = BoltAndGearDetection.GearDetector(solidPrimitive);

            AddingNodesToGraph(assemblyGraph, solids);//, gears, screwsAndBolts);

            /*for (var i = 0; i < solids.Count - 1; i++)
             * {
             *  var solid1 = solids[i];
             *  var solid1Primitives = solidPrimitive[solid1];
             *  for (var j = i + 1; j < solids.Count; j++)
             *  {
             *      var solid2 = solids[j];
             *      var solid2Primitives = solidPrimitive[solid2];
             *      List<int> localDirInd;
             *      double cert;
             *      if (BlockingDetermination.DefineBlocking(assemblyGraph, solid1, solid2, solid1Primitives, solid2Primitives,
             *          globalDirPool, out localDirInd, out cert))
             *      {
             *          // I wrote the code in a way that "solid1" is always "Reference" and "solid2" is always "Moving".
             *          //List<int> finDirs, infDirs;
             *          //UnconnectedBlockingDetermination.FiniteDirectionsBetweenConnectedParts(solid1, solid2, localDirInd, out finDirs, out infDirs);
             *          var from = assemblyGraph[solid2.Name]; // Moving
             *          var to = assemblyGraph[solid1.Name];   // Reference
             *          assemblyGraph.addArc((Component)from, (Component)to);
             *          var a = (Connection)assemblyGraph.arcs.Last();
             *          a.Certainty = cert;
             *          AddInformationToArc(a, localDirInd);
             *      }
             *  }
             * }*/
            return(globalDirPool);
        }
示例#3
0
        internal static void RunPerecptronLearner(bool regenerateTrainingData)
        {
            // this functions, finds the training stls, opens them,
            // read them and creates the csv file of the training data
            // which includes the features of each solid.

            // Here is what I need to pay attention:
            //    1. if the csv file exists and the user doesnt want to improve(!) the results
            //       do nothing
            //    2. if the csv doesnt exist or the user has new training stls, we can run it and
            //       improve the classifier.

            var path =

                                #if NOSRC
                Program.state.inputDir + "src/Assembly Planner/InitialGraphMaker/BoltAndGearDetector";
                                #else
                "bin/training";
                                #endif

            //Path to write the csv to:
                        #if NOSRC
            var trainingDataPath    = path + "/TrainingData.csv";
            var weightsAndVotesPath = path + "/WeightsAndVotes.csv";
                        #else
            var trainingDataPath    = path + "/ClassifierFiles/TrainingData.csv";
            var weightsAndVotesPath = path + "/ClassifierFiles/WeightsAndVotes.csv";
                        #endif

            if (!regenerateTrainingData && File.Exists(weightsAndVotesPath))
            {
                return;
            }
            if (!regenerateTrainingData && !File.Exists(weightsAndVotesPath) && File.Exists(trainingDataPath))
            {
                // CSV of the training data exists, but weights and votes, dont exist, therefore: run the Learner
                Learner(); // this will automatically create the csv containing weights and votes
                return;
            }
            if (!regenerateTrainingData && !File.Exists(weightsAndVotesPath) && !File.Exists(trainingDataPath))
            {
                Console.WriteLine("Sorry!! csv files don't exist. We need to generate the training data");
            }
            //statusReporter.PrintMessage("BOUNDING GEOMETRIES ARE SUCCESSFULLY CREATED.", 1f);
            //Path to read STLs from:

                        #if NOSRC
            var stlFastenerPath    = path + "/Fastener";
            var stlNotFastenerPath = path + "/notFastener";
                        #else
            var stlFastenerPath    = path + "/TrainingSTLs/Fastener";
            var stlNotFastenerPath = path + "/TrainingSTLs/notFastener";
                        #endif

            var fastenersTraining = StlToSolid(stlFastenerPath);
            var fastenerPrimitive = BlockingDetermination.PrimitiveMaker(fastenersTraining);

            var ntFastenersTraining  = StlToSolid(stlNotFastenerPath);
            var notFastenerPrimitive = BlockingDetermination.PrimitiveMaker(ntFastenersTraining);

            if (!File.Exists(trainingDataPath))
            {
                File.Create(trainingDataPath).Close();
            }

            // now fill the csv:
            TrainingDataCsvFiller(trainingDataPath, fastenerPrimitive, notFastenerPrimitive);
            Learner();
        }
示例#4
0
        internal static void Run(designGraph graph,
                                 List <TessellatedSolid> solids, List <int> gDir)
        {
            //Parallel.ForEach(gDir, dir =>
            foreach (var dir in gDir)
            {
                var direction             = DisassemblyDirections.Directions[dir];
                var blockingsForDirection = new List <NonAdjacentBlockings>();

                //Parallel.ForEach(solids.Where(s => graph.nodes.Any(n => n.name == s.Name)), solid =>
                foreach (var solid in solids.Where(s => graph.nodes.Any(n => n.name == s.Name)))
                {
                    // now find the blocking parts
                    var rays = new List <Ray>();
                    foreach (var vertex in solid.ConvexHull.Vertices)
                    {
                        rays.Add(
                            new Ray(
                                new Vertex(new[] { vertex.Position[0], vertex.Position[1],
                                                   vertex.Position[2] }),
                                new[] { direction[0], direction[1], direction[2] }));
                    }
                    // add more vertices to the ray
                    rays.AddRange(
                        AddingMoreRays(solid.ConvexHull.Edges.Where(e => e != null && e.Length > 2).ToArray(),
                                       direction));

                    foreach (var solidBlocking in
                             solids.Where(s => graph.nodes.Any(n => n.name == s.Name) && // it is not fastener
                                          s != solid           // it is not the same as current solid
                                          &&
                                          !graph.arcs.Any(a => // there is no arc between the current and the candidate
                                                          (a.From.name == solid.Name && a.To.name == s.Name) ||
                                                          (a.From.name == s.Name && a.To.name == solid.Name))))
                    {
                        if (!BoundingBoxBlocking(direction, solidBlocking, solid))
                        {
                            continue;
                        }
                        var distanceToTheClosestFace = double.PositiveInfinity;
                        var overlap = false;

                        if (BlockingDetermination.ConvexHullOverlap(solid, solidBlocking))
                        {
                            overlap = ConvexHullOverlappNonAdjacent(rays, solid, solidBlocking, direction);
                            continue;
                        }
                        else
                        {
                            overlap = DontConcexHullsOverlapNonAdjacent(rays, solidBlocking);
                        }
                        if (overlap)
                        {
                            blockingsForDirection.Add(new NonAdjacentBlockings
                            {
                                blockingSolids   = new[] { solid, solidBlocking },
                                blockingDistance = distanceToTheClosestFace
                            });
                        }
                    }
                }
                //);
                //  lock (NonAdjacentBlocking)
                NonAdjacentBlocking.Add(dir, blockingsForDirection);
            }
            //   );
            // To be fixed later:
            //    This ConvertToSecondary can be later added directly after generation.
            //ConvertToSecondaryArc(graph, NonAdjacentBlocking);
        }
示例#5
0
        internal static List <int> RunGraphGeneration(designGraph assemblyGraph, Dictionary <string, List <TessellatedSolid> > solidsNoFastener)
        {
            Solids           = Program.Solids;
            solidsNoFastener = Program.SolidsNoFastener;

            //$ Added because it seems that primitive surfaces are populated in step one
            //  Extracting primitives from the list of solids
            foreach (KeyValuePair <string, List <TessellatedSolid> > p in Solids)
            {
                foreach (TessellatedSolid t in p.Value)
                {
                    SolidPrimitive[t] = t.Primitives;
                }
            }
            //

            //PrintOutSomeInitialStats();
            var globalDirPool = new List <int>();
            // Detect gear mates
            //------------------------------------------------------------------------------------------
            var gears = GearDetector.Run(PartsWithOneGeom, SolidPrimitive);
            var sw    = new Stopwatch();

            sw.Start();

            // Add the solids as nodes to the graph. Exclude the fasteners
            //------------------------------------------------------------------------------------------
            //DisassemblyDirections.Solids = new List<TessellatedSolid>(solidsNoFastener);
            AddingNodesToGraph(assemblyGraph, solidsNoFastener); //, gears, screwsAndBolts);

            // Implementing region octree for every solid
            //------------------------------------------------------------------------------------------
            PartitioningSolid.Partitions     = new Dictionary <TessellatedSolid, Partition[]>();
            PartitioningSolid.PartitionsAABB = new Dictionary <TessellatedSolid, PartitionAABB[]>();
            PartitioningSolid.CreatePartitions(solidsNoFastener);

            // Part to part interaction to obtain removal directions between every connected pair
            //------------------------------------------------------------------------------------------

            Console.WriteLine(" \n\nAdjacent Blocking Determination ...");
            var width = 55;

            LoadingBar.start(width, 0);

            BlockingDetermination.OverlappingSurfaces = new List <OverlappedSurfaces>();
            var  solidNofastenerList = solidsNoFastener.ToList();
            long totalTriTobeChecked = 0;
            var  overlapCheck        = new HashSet <KeyValuePair <string, List <TessellatedSolid> >[]>();

            for (var i = 0; i < solidsNoFastener.Count - 1; i++)
            {
                var subAssem1 = solidNofastenerList[i];
                for (var j = i + 1; j < solidsNoFastener.Count; j++)
                {
                    var subAssem2 = solidNofastenerList[j];
                    overlapCheck.Add(new[] { subAssem1, subAssem2 });
                    var tri2Sub1 = subAssem1.Value.Sum(s => s.Faces.Length);
                    var tri2Sub2 = subAssem2.Value.Sum(s => s.Faces.Length);
                    totalTriTobeChecked += tri2Sub1 * tri2Sub2;
                }
            }
            var  total   = overlapCheck.Count;
            var  refresh = (int)Math.Ceiling(((float)total) / ((float)(width * 4)));
            var  check   = 0;
            long counter = 0;


            //$ Need to convert back to parallel after debug
            //foreach (var each in overlapCheck)
            Parallel.ForEach(overlapCheck, each =>
            {
                if (check % refresh == 0)
                {
                    LoadingBar.refresh(width, ((float)check) / ((float)total));
                }
                check++;
                var localDirInd = new List <int>();
                for (var t = 0; t < DisassemblyDirections.Directions.Count; t++)
                {
                    localDirInd.Add(t);
                }
                var connected = false;
                var certainty = 0.0;
                foreach (var solid1 in each[0].Value)
                {
                    foreach (var solid2 in each[1].Value)
                    {
                        counter += solid1.Faces.Length * solid2.Faces.Length;
                        double localCertainty;
                        var blocked = BlockingDetermination.DefineBlocking(solid1, solid2, globalDirPool,
                                                                           localDirInd, out localCertainty);
                        if (connected == false)
                        {
                            connected = blocked;
                        }
                        if (localCertainty > certainty)
                        {
                            certainty = localCertainty;
                        }
                    }
                }
                if (connected)
                {
                    // I wrote the code in a way that "solid1" is always "Reference" and "solid2" is always "Moving".
                    // Update the romoval direction if it is a gear mate:
                    localDirInd = GearDetector.UpdateRemovalDirectionsIfGearMate(each[0].Value,
                                                                                 each[1].Value, gears, localDirInd);
                    List <int> finDirs, infDirs;
                    NonadjacentBlockingDetermination.FiniteDirectionsBetweenConnectedPartsWithPartitioning(
                        each[0].Value, each[1].Value, localDirInd, out finDirs, out infDirs);
                    lock (assemblyGraph)
                    {
                        var from = assemblyGraph[each[1].Key]; // Moving
                        var to   = assemblyGraph[each[0].Key]; // Reference
                        assemblyGraph.addArc((node)from, (node)to, "", typeof(Connection));
                        var a       = (Connection)assemblyGraph.arcs.Last();
                        a.Certainty = certainty;
                        AddInformationToArc(a, finDirs, infDirs);
                    }
                }
            });
            LoadingBar.refresh(width, 1);
            Fastener.AddFastenersInformation(assemblyGraph, solidsNoFastener, SolidPrimitive);
            // create oppositeDirections for global direction pool.
            FindingOppositeDirectionsForGlobalPool(globalDirPool);

            // Simplify the solids, before doing anything
            //------------------------------------------------------------------------------------------
            foreach (var solid in solidsNoFastener)
            {
                Program.SolidsNoFastenerSimplified.Add(solid.Key, Program.SimplifiedSolids[solid.Key]);
            }
            SimplifySolids(Program.SimplifiedSolids, 0.7);

            // Implementing region octree for every solid
            //------------------------------------------------------------------------------------------
            PartitioningSolid.Partitions     = new Dictionary <TessellatedSolid, Partition[]>();
            PartitioningSolid.PartitionsAABB = new Dictionary <TessellatedSolid, PartitionAABB[]>();
            PartitioningSolid.CreatePartitions(Program.SimplifiedSolids);

            CheckToHaveConnectedGraph(assemblyGraph);


            return(globalDirPool);
        }
示例#6
0
        private static void CheckToHaveConnectedGraph(designGraph assemblyGraph)
        {
            // The code will crash if the graph is not connected
            // let's take a look:
            var batches       = new List <HashSet <Component> >();
            var stack         = new Stack <Component>();
            var visited       = new HashSet <Component>();
            var globalVisited = new HashSet <Component>();

            foreach (Component Component in assemblyGraph.nodes.Where(n => !globalVisited.Contains(n)))
            {
                stack.Clear();
                visited.Clear();
                stack.Push(Component);
                while (stack.Count > 0)
                {
                    var pNode = stack.Pop();
                    visited.Add(pNode);
                    globalVisited.Add(pNode);
                    List <Connection> a2;
                    lock (pNode.arcs)
                        a2 = pNode.arcs.Where(a => a is Connection).Cast <Connection>().ToList();

                    foreach (Connection arc in a2)
                    {
                        if (!assemblyGraph.nodes.Contains(arc.From) || !assemblyGraph.nodes.Contains(arc.To))
                        {
                            continue;
                        }
                        var otherNode = (Component)(arc.From == pNode ? arc.To : arc.From);
                        if (visited.Contains(otherNode))
                        {
                            continue;
                        }
                        stack.Push(otherNode);
                    }
                }
                if (visited.Count == assemblyGraph.nodes.Count)
                {
                    return;
                }
                batches.Add(new HashSet <Component>(visited));
            }
            Console.WriteLine("\nSome of the assembly parts are not connected to the rest of the model.");
            var referenceBatch = batches[0];
            var c      = false;
            var visits = 0;
            var loop   = 0;

            while (referenceBatch.Count < assemblyGraph.nodes.Count)
            {
                loop++;
                if (loop >= 15)
                {
                    break;
                }
                foreach (var rb in referenceBatch)
                {
                    for (var j = 1; j < batches.Count; j++)
                    {
                        foreach (var b in batches[j])
                        {
                            foreach (var p1 in Program.Solids[rb.name])
                            {
                                foreach (var p2 in Program.Solids[b.name])
                                {
                                    if (BlockingDetermination.BoundingBoxOverlap(p1, p2))
                                    {
                                        if (BlockingDetermination.ConvexHullOverlap(p1, p2))
                                        {
                                            visits++;
                                            if (visits == 1)
                                            {
                                                Console.WriteLine(
                                                    "\n   * Since the graph needs to be connected, the following connections are added by the software:");
                                            }
                                            // add a connection with low cetainty between them
                                            var lastAdded = (Connection)assemblyGraph.addArc(rb, b, "", typeof(Connection));
                                            lastAdded.Certainty = 0.1;
                                            referenceBatch.UnionWith(batches[j]);
                                            batches.RemoveAt(j);
                                            c = true;
                                            Console.WriteLine("\n      - " + lastAdded.XmlFrom + lastAdded.XmlTo);
                                        }
                                    }
                                    if (c)
                                    {
                                        break;
                                    }
                                }
                                if (c)
                                {
                                    break;
                                }
                            }
                            if (c)
                            {
                                break;
                            }
                        }
                        if (c)
                        {
                            break;
                        }
                    }
                    if (c)
                    {
                        break;
                    }
                }
            }
            if (loop < 15)
            {
                Console.WriteLine(
                    "\n   * When you are reviewing the connections, please pay a closer attention to the connections above");
            }
            else
            {
                Console.WriteLine("\n   * Some connections must be added manually between the following batches");
            }
            for (int i = 0; i < batches.Count; i++)
            {
                var batch = batches[i];
                Console.WriteLine("\n      - Batch " + i + ":");
                foreach (var component in batch)
                {
                    Console.WriteLine("         + " + component.name);
                }
            }
        }