private static bool SlotHeadBolt(TessellatedSolid solid, List <PrimitiveSurface> solidPrim,
                                         Dictionary <TemporaryFlat, List <TemporaryFlat> > equalPrimitives, List <TessellatedSolid> repeated)
        {
            repeated.Add(solid);
            var twoFlat = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 2);

            if (!twoFlat.Any())
            {
                return(false);
            }
            foreach (var candidateHex in twoFlat)
            {
                var candidateHexVal = equalPrimitives[candidateHex];
                var cos             = (candidateHexVal[0]).Normal.dotProduct((candidateHexVal[1]).Normal);
                if (!(Math.Abs(-1 - cos) < 0.0001))
                {
                    continue;
                }
                // I will add couple of conditions here:
                //    1. If the number of solid vertices in front of each flat is equal to another
                //    2. If the summation of the vertices in 1 is greater than the total # of verts
                //    3. and I also need to add some constraints for the for eample the area of the cylinder
                var leftVerts  = VertsInfrontOfFlat(solid, candidateHexVal[0]);
                var rightVerts = VertsInfrontOfFlat(solid, candidateHexVal[1]);
                if (Math.Abs(leftVerts - rightVerts) > 2 || leftVerts + rightVerts <= solid.Vertices.Length)
                {
                    continue;
                }
                if (!solidPrim.Where(p => p is Cylinder).Cast <Cylinder>().Any(c => c.IsPositive))
                {
                    continue;
                }
                var lengthAndRadius = FastenerEngagedLengthAndRadiusNoThread(solid, solidPrim);
                foreach (var repeatedSolid in repeated)
                {
                    var fastener = new Fastener
                    {
                        Solid            = repeatedSolid,
                        FastenerType     = FastenerTypeEnum.Bolt,
                        Tool             = Tool.FlatBlade,
                        RemovalDirection =
                            //RemovalDirectionFinderForSlot(candidateHexVal.Cast<Flat>().ToList(),
                            //    solidPrim.Where(p => p is Flat).Cast<Flat>().ToList()),
                            FastenerDetector.RemovalDirectionFinderUsingObb(repeatedSolid,
                                                                            BoundingGeometry.OrientedBoundingBoxDic[repeatedSolid]),
                        OverallLength =
                            GeometryFunctions.SortedLengthOfObbEdges(BoundingGeometry.OrientedBoundingBoxDic[solid])[2],
                        EngagedLength = lengthAndRadius[0],
                        Diameter      = lengthAndRadius[1] * 2.0,
                        Certainty     = 1.0
                    };
                    lock (FastenerDetector.Fasteners)
                        FastenerDetector.Fasteners.Add(fastener);
                }
                return(true);
            }
            return(false);
        }
示例#2
0
        internal static int CommonHeadCheck(TessellatedSolid solid, List <PrimitiveSurface> solidPrim,
                                            Dictionary <TemporaryFlat, List <TemporaryFlat> > equalPrimitives, out double toolSize)
        {
            // 0: false (doesnt have any common head shape)
            // 1: HexBolt or Nut
            // 2: Allen
            // 3: Phillips
            // 4: Slot
            // 5: Phillips and Slot combo

            toolSize = 0.0;
            // check for hex bolt, nut and allen -------------------------------------------------------------
            var sixFlat   = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 6);
            var eightFlat = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 8);
            var twoFlat   = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 2);
            var fourFlat  = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 4);

            //if (!sixFlat.Any()) return 0;
            foreach (var candidateHex in sixFlat)
            {
                var candidateHexVal = equalPrimitives[candidateHex];
                var cos             = new List <double>();
                var firstPrimNormal = (candidateHexVal[0]).Normal;
                for (var i = 1; i < candidateHexVal.Count; i++)
                {
                    cos.Add(firstPrimNormal.dotProduct((candidateHexVal[i]).Normal));
                }
                // if it is a hex or allen bolt, the cos list must have two 1/2, two -1/2 and one -1
                if (cos.Count(c => Math.Abs(0.5 - c) < 0.0001) != 2 ||
                    cos.Count(c => Math.Abs(-0.5 - c) < 0.0001) != 2 ||
                    cos.Count(c => Math.Abs(-1 - c) < 0.0001) != 1)
                {
                    continue;
                }
                toolSize = AutoNonthreadedFastenerDetection.ToolSizeFinder(candidateHexVal);
                if (AutoNonthreadedFastenerDetection.IsItAllen(candidateHexVal))
                {
                    return(2);
                }
                return(1);
            }
            foreach (var candidateHex in eightFlat)
            {
                var candidateHexVal = equalPrimitives[candidateHex];
                var cos             = new List <double>();
                var firstPrimNormal = (candidateHexVal[0]).Normal;
                for (var i = 1; i < candidateHexVal.Count; i++)
                {
                    cos.Add(firstPrimNormal.dotProduct((candidateHexVal[i]).Normal));
                }
                var oneFlat = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 1);
                // Any flat that is adjacent to all of these eights?
                // if it is philips head, the cos list must have four 0, two -1 and one 1
                foreach (var sh in oneFlat)
                {
                    if (candidateHexVal.All(f => f.OuterEdges.Any(sh.OuterEdges.Contains)))
                    {
                        return(3);
                    }
                }

                /*if (cos.Count(c => Math.Abs(0.0 - c) < 0.0001) != 4 ||
                 *  cos.Count(c => Math.Abs(-1 - c) < 0.0001) != 2 ||
                 *  cos.Count(c => Math.Abs(1 - c) < 0.0001) != 1) continue;
                 * return 3;*/
                continue;
            }
            foreach (var candidateHex in twoFlat)
            {
                var candidateHexVal = equalPrimitives[candidateHex];
                var cos             = (candidateHexVal[0]).Normal.dotProduct((candidateHexVal[1]).Normal);
                if (!(Math.Abs(-1 - cos) < 0.0001))
                {
                    continue;
                }
                // I will add couple of conditions here:
                //    1. If the number of solid vertices in front of each flat is equal to another
                //    2. If the summation of the vertices in 1 is greater than the total # of verts
                //    3. and I also need to add some constraints for the for eample the area of the cylinder
                var leftVerts  = AutoNonthreadedFastenerDetection.VertsInfrontOfFlat(solid, candidateHexVal[0]);
                var rightVerts = AutoNonthreadedFastenerDetection.VertsInfrontOfFlat(solid, candidateHexVal[1]);
                if (Math.Abs(leftVerts - rightVerts) > 10 || leftVerts + rightVerts <= solid.Vertices.Length)
                {
                    continue;
                }
                return(4);
            }

            var eachSlot = 0;
            var flats    = new List <TemporaryFlat>();

            foreach (var candidateHex in fourFlat)
            {
                var candidateHexVal = equalPrimitives[candidateHex];
                var cos             = new List <double>();
                var firstPrimNormal = (candidateHexVal[0]).Normal;
                for (var i = 1; i < candidateHexVal.Count; i++)
                {
                    cos.Add(firstPrimNormal.dotProduct((candidateHexVal[i]).Normal));
                }
                // if it is a slot and phillips combo the cos list must have two -1 and one 1
                // and this needs to appear 2 times.
                if (cos.Count(c => Math.Abs(-1 - c) < 0.0001) != 2 ||
                    cos.Count(c => Math.Abs(1 - c) < 0.0001) != 1)
                {
                    continue;
                }
                flats.AddRange(candidateHexVal);
                eachSlot++;
            }
            if (eachSlot == 2)
            {
                return(5);
            }
            return(0);
        }
        private static bool PhillipsSlotComboHeadBolt(TessellatedSolid solid, List <PrimitiveSurface> solidPrim,
                                                      Dictionary <TemporaryFlat, List <TemporaryFlat> > equalPrimitives, List <TessellatedSolid> repeated)
        {
            repeated.Add(solid);
            var fourFlat = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 4);

            if (fourFlat.Count < 2)
            {
                return(false);
            }
            var eachSlot = 0;
            var flats    = new List <TemporaryFlat>();

            foreach (var candidateHex in fourFlat)
            {
                var candidateHexVal = equalPrimitives[candidateHex];
                var cos             = new List <double>();
                var firstPrimNormal = (candidateHexVal[0]).Normal;
                for (var i = 1; i < candidateHexVal.Count; i++)
                {
                    cos.Add(firstPrimNormal.dotProduct((candidateHexVal[i]).Normal));
                }
                // if it is a slot and phillips combo the cos list must have two -1 and one 1
                // and this needs to appear 2 times.
                if (cos.Count(c => Math.Abs(-1 - c) < 0.0001) != 2 ||
                    cos.Count(c => Math.Abs(1 - c) < 0.0001) != 1)
                {
                    continue;
                }
                if (!solidPrim.Where(p => p is Cylinder).Cast <Cylinder>().Any(c => c.IsPositive))
                {
                    continue;
                }
                flats.AddRange(candidateHexVal);
                eachSlot++;
            }
            if (eachSlot != 2)
            {
                return(false);
            }
            var lengthAndRadius = FastenerEngagedLengthAndRadiusNoThread(solid, solidPrim);

            foreach (var repeatedSolid in repeated)
            {
                var fastener = new Fastener
                {
                    Solid            = repeatedSolid,
                    FastenerType     = FastenerTypeEnum.Bolt,
                    Tool             = Tool.PhillipsBlade,
                    RemovalDirection =
                        //RemovalDirectionFinderForAllenHexPhillips(flats.Cast<Flat>().ToList(),
                        //    BoundingGeometry.OrientedBoundingBoxDic[solid]),
                        FastenerDetector.RemovalDirectionFinderUsingObb(repeatedSolid, BoundingGeometry.OrientedBoundingBoxDic[repeatedSolid]),
                    OverallLength =
                        GeometryFunctions.SortedLengthOfObbEdges(BoundingGeometry.OrientedBoundingBoxDic[solid])[2],
                    EngagedLength = lengthAndRadius[0],
                    Diameter      = lengthAndRadius[1] * 2.0,
                    Certainty     = 1.0
                };
                lock (FastenerDetector.Fasteners)
                    FastenerDetector.Fasteners.Add(fastener);
            }
            return(true);
        }
        private static bool PhillipsHeadBolt(TessellatedSolid solid, List <PrimitiveSurface> solidPrim,
                                             Dictionary <TemporaryFlat, List <TemporaryFlat> > equalPrimitives, List <TessellatedSolid> repeated)
        {
            repeated.Add(solid);
            var eightFlat = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 8);

            if (!eightFlat.Any())
            {
                // before I return false, I will take the ones with 4 faces that have a close area and merge them.

                /*var fourEqual1 = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 4);
                 * var closeArea1 = new List<TemporaryFlat[]>();
                 * for (var i = 0; i < fourEqual1.Count - 1; i++)
                 * {
                 *  for (var j = i + 1; j < fourEqual1.Count; j++)
                 *  {
                 *      if (Math.Abs(fourEqual1[i].Area - fourEqual1[j].Area) < 0.1 * fourEqual1[i].Area)
                 *      {
                 *          closeArea1.Add(new[] { fourEqual1[i], fourEqual1[j] });
                 *          break;
                 *      }
                 *  }
                 * }
                 * foreach (var cA in closeArea1)
                 * {
                 *  equalPrimitives[cA[0]].AddRange(equalPrimitives[cA[1]]);
                 * }
                 * return PhillipsHeadBolt(solid, solidPrim, equalPrimitives, repeated);*/
                return(false);
            }
            foreach (var candidateHex in eightFlat)
            {
                var candidateHexVal = equalPrimitives[candidateHex];
                var cos             = new List <double>();
                var firstPrimNormal = (candidateHexVal[0]).Normal;
                for (var i = 1; i < candidateHexVal.Count; i++)
                {
                    cos.Add(firstPrimNormal.dotProduct((candidateHexVal[i]).Normal));
                }
                // if it is philips head, the cos list must have four 0, two -1 and one 1
                if (cos.Count(c => Math.Abs(0.0 - c) < 0.025) != 4 ||
                    cos.Count(c => Math.Abs(-1 - c) < 0.025) != 2 ||
                    cos.Count(c => Math.Abs(1 - c) < 0.001) != 1)
                {
                    continue;
                }
                var lengthAndRadius = FastenerEngagedLengthAndRadiusNoThread(solid, solidPrim);
                foreach (var repeatedSolid in repeated)
                {
                    var fastener = new Fastener
                    {
                        Solid            = repeatedSolid,
                        FastenerType     = FastenerTypeEnum.Bolt,
                        Tool             = Tool.PhillipsBlade,
                        RemovalDirection =
                            //RemovalDirectionFinderForAllenHexPhillips(candidateHexVal.Cast<Flat>().ToList(),
                            //    BoundingGeometry.OrientedBoundingBoxDic[solid]),
                            FastenerDetector.RemovalDirectionFinderUsingObb(repeatedSolid, BoundingGeometry.OrientedBoundingBoxDic[repeatedSolid]),
                        OverallLength =
                            GeometryFunctions.SortedLengthOfObbEdges(BoundingGeometry.OrientedBoundingBoxDic[solid])[2],
                        EngagedLength = lengthAndRadius[0],
                        Diameter      = lengthAndRadius[1] * 2.0,
                        Certainty     = 1.0
                    };
                    lock (FastenerDetector.Fasteners)
                        FastenerDetector.Fasteners.Add(fastener);
                }
                return(true);
            }
            // before I return false, I will take the ones with 4 faces that have a close area and merge them.

            /*var fourEqual = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 4);
             * var closeArea = new List<TemporaryFlat[]>();
             * for (var i = 0; i < fourEqual.Count - 1; i++)
             * {
             *  for (var j = i+1; j < fourEqual.Count; j++)
             *  {
             *      if (Math.Abs(fourEqual[i].Area - fourEqual[j].Area) < 0.01*fourEqual[i].Area)
             *      {
             *          closeArea.Add(new []{ fourEqual[i] , fourEqual[j] });
             *          break;
             *      }
             *  }
             * }
             * foreach (var cA in closeArea)
             * {
             *  equalPrimitives[cA[0]].AddRange(equalPrimitives[cA[1]]);
             * }
             * return PhillipsHeadBolt(solid, solidPrim, equalPrimitives, repeated);*/
            return(false);
        }
        private static bool HexBoltNutAllen(TessellatedSolid solid, List <PrimitiveSurface> solidPrim,
                                            Dictionary <TemporaryFlat, List <TemporaryFlat> > equalPrimitives, List <TessellatedSolid> repeated)
        {
            repeated.Add(solid);
            var sixFlat = FastenerDetector.EqualPrimitivesFinder(equalPrimitives, 6);

            if (!sixFlat.Any())
            {
                return(false);
            }
            foreach (var candidateHex in sixFlat)
            {
                var candidateHexVal = equalPrimitives[candidateHex];
                var cos             = new List <double>();
                var firstPrimNormal = (candidateHexVal[0]).Normal;
                for (var i = 1; i < candidateHexVal.Count; i++)
                {
                    cos.Add(firstPrimNormal.dotProduct((candidateHexVal[i]).Normal));
                }
                // if it is a hex or allen bolt, the cos list must have two 1/2, two -1/2 and one -1
                if (cos.Count(c => Math.Abs(0.5 - c) < 0.0001) != 2 ||
                    cos.Count(c => Math.Abs(-0.5 - c) < 0.0001) != 2 ||
                    cos.Count(c => Math.Abs(-1 - c) < 0.0001) != 1)
                {
                    continue;
                }
                var lengthAndRadius = FastenerEngagedLengthAndRadiusNoThread(solid, solidPrim);
                if (IsItAllen(candidateHexVal))
                {
                    // this is a socket bolt (allen)
                    foreach (var repeatedSolid in repeated)
                    {
                        var fastener = new Fastener
                        {
                            Solid            = repeatedSolid,
                            FastenerType     = FastenerTypeEnum.Bolt,
                            Tool             = Tool.Allen,
                            ToolSize         = ToolSizeFinder(candidateHexVal),
                            RemovalDirection =
                                //RemovalDirectionFinderForAllenHexPhillips(candidateHexVal.Cast<Flat>().ToList(),
                                //    BoundingGeometry.OrientedBoundingBoxDic[solid]),
                                FastenerDetector.RemovalDirectionFinderUsingObb(repeatedSolid, BoundingGeometry.OrientedBoundingBoxDic[repeatedSolid]),
                            OverallLength =
                                GeometryFunctions.SortedLengthOfObbEdges(BoundingGeometry.OrientedBoundingBoxDic[solid])[2],
                            EngagedLength = lengthAndRadius[0],
                            Diameter      = lengthAndRadius[1] * 2.0,
                            Certainty     = 1.0
                        };
                        lock (FastenerDetector.Fasteners)
                            FastenerDetector.Fasteners.Add(fastener);
                    }
                    return(true);
                }
                // else: it is a hex bolt or nut
                if (IsItNut(solidPrim.Where(p => p is Cylinder).Cast <Cylinder>().ToList(), solid))
                {
                    foreach (var repeatedSolid in repeated)
                    {
                        lock (FastenerDetector.Nuts)
                            FastenerDetector.Nuts.Add(new Nut
                            {
                                NutType       = NutType.Hex,
                                Solid         = repeatedSolid,
                                ToolSize      = ToolSizeFinder(candidateHexVal),
                                OverallLength = lengthAndRadius[0],
                                Diameter      = lengthAndRadius[1] * 2.0,
                                Certainty     = 1.0
                            });
                    }
                    return(true);
                }
                foreach (var repeatedSolid in repeated)
                {
                    lock (FastenerDetector.Fasteners)
                        FastenerDetector.Fasteners.Add(new Fastener
                        {
                            Solid            = repeatedSolid,
                            FastenerType     = FastenerTypeEnum.Bolt,
                            Tool             = Tool.HexWrench,
                            ToolSize         = ToolSizeFinder(candidateHexVal),
                            RemovalDirection =
                                //RemovalDirectionFinderForAllenHexPhillips(candidateHexVal.Cast<Flat>().ToList(),
                                //    BoundingGeometry.OrientedBoundingBoxDic[solid]),
                                FastenerDetector.RemovalDirectionFinderUsingObb(repeatedSolid, BoundingGeometry.OrientedBoundingBoxDic[repeatedSolid]),
                            OverallLength =
                                GeometryFunctions.SortedLengthOfObbEdges(BoundingGeometry.OrientedBoundingBoxDic[solid])
                                [2],
                            EngagedLength = lengthAndRadius[0],
                            Diameter      = lengthAndRadius[1] * 2.0,
                            Certainty     = 1.0
                        });
                }
                return(true);
            }
            return(false);
        }