internal static List <List <TessellatedSolid> > GroupingSmallParts(List <TessellatedSolid> firstFilter) { var groups = new List <List <TessellatedSolid> >(); for (var i = 0; i < firstFilter.Count - 1; i++) { for (var j = i + 1; j < firstFilter.Count; j++) { if (!BlockingDetermination.BoundingBoxOverlap(firstFilter[i], firstFilter[j])) { continue; } if (!BlockingDetermination.ConvexHullOverlap(firstFilter[i], firstFilter[j])) { continue; } var exist = groups.Where(group => @group.Contains(firstFilter[i]) || @group.Contains(firstFilter[j])).ToList(); if (exist.Any()) { exist[0].Add(exist[0].Contains(firstFilter[i]) ? firstFilter[j] : firstFilter[i]); } else { groups.Add(new List <TessellatedSolid> { firstFilter[i], firstFilter[j] }); } } } return(groups); }
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 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); }
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); } } }