private static List <Ray> RayGeneratorForNoCVHOverlap(List <TessellatedSolid> solidMoving, double[] direction)
        {
            var rays = CombinedCVHForMultipleGeometries[solidMoving[0].Name].Vertices.Select(
                vertex =>
                new Ray(
                    new Vertex(new[] { vertex.Position[0], vertex.Position[1],
                                       vertex.Position[2] }),
                    new[] { direction[0], direction[1], direction[2] })).ToList();

            // add more vertices to the ray
            rays.AddRange(
                NonadjacentBlockingDetermination.AddingMoreRays(
                    CombinedCVHForMultipleGeometries[solidMoving[0].Name].Edges.Where(
                        e => e != null && e.Length > 2).ToArray(), direction));
            return(rays.OrderBy(a => Guid.NewGuid()).ToList());
        }
Beispiel #2
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);
        }