Ejemplo n.º 1
0
        internal static Gear GearDetectorEstimate(TessellatedSolid solid, List <PrimitiveSurface> solidPrimitives)
        {
            var flats =
                solidPrimitives.Where(
                    p => p is Flat && p.Faces.Count > BoltAndGearConstants.TriabglesInTheGearSideFaces).ToList();

            foreach (var flatPrim in flats)
            {
                var outerGearEdges = GearEdge.FromTVGLEdgeClassToGearEdgeClass(flatPrim.OuterEdges);
                var patches        = SortedConnectedPatches(outerGearEdges);
                foreach (var patch in patches)
                {
                    var cluster  = new List <GearEdge> [2];
                    var newPatch = new List <GearEdge>();
                    if (ClusteringDenseAndSparseEdges.ContainsDense(patch))
                    {
                        cluster = ClusteringDenseAndSparseEdges.ClusteringDenseSparse(patch);
                    }
                    if (cluster[0] != null && cluster[1].Count > BoltAndGearConstants.AcceptableNumberOfDenseEdges)
                    {
                        newPatch = ClusteringDenseAndSparseEdges.ReplacingDenseEdges(patch, cluster);
                    }
                    var crossP = new List <double[]>();
                    if (newPatch.Count == 0)
                    {
                        newPatch = patch;
                    }
                    for (var i = 0; i < newPatch.Count - 1; i++)
                    {
                        var cross = new[] { 0.0, 0, 0 };
                        var vec1  = newPatch[i].Vector.normalize();
                        var vec2  = newPatch[i + 1].Vector.normalize();
                        if (SmoothAngle(vec1, vec2))
                        {
                            continue;
                        }
                        cross = vec1.crossProduct(vec2);
                        crossP.Add(cross);
                    }
                    if (crossP.Count < 10)
                    {
                        continue;
                    }
                    var crossSign = GeometryFunctions.ConvertCrossProductToSign(crossP);
                    if (!IsGear(crossSign))
                    {
                        continue;
                    }
                    //Console.WriteLine("Is " + solid.Name + " a gear? 'y' or 'n'");
                    //var read = Convert.ToString(Console.ReadLine());
                    //if (read == "n")
                    //    continue;
                    return(new Gear {
                        Solid = solid, Axis = flatPrim.Faces[0].Normal
                    });
                }
            }
            return(null);
        }
        internal static List <GearEdge> ReplacingDenseEdges(List <GearEdge> patch, List <GearEdge>[] cluster)
        {
            var copyPatch      = new List <GearEdge>(patch);
            var count          = patch.Count;
            var firstSparseInd = 0;

            if (cluster[1].Contains(patch[0])) //if the starting face is sparse
            {
                var numRem = 0;
                for (var i = 0; ; i++)
                {
                    if (cluster[0].Contains(patch[i]))
                    {
                        break;
                    }
                    copyPatch.Remove(patch[i]);
                    numRem++;
                }
                for (var i = patch.Count - 1; ; i--)
                {
                    if (cluster[0].Contains(patch[i]))
                    {
                        break;
                    }
                    copyPatch.Remove(patch[i]);
                    numRem++;
                }
                firstSparseInd = patch.IndexOf(copyPatch[0]);
                count          = patch.Count - numRem;
            }

            var localDense = new List <GearEdge>();

            for (var i = firstSparseInd; i < count; i++)
            {
                if (cluster[0].Contains(patch[i]))
                {
                    if (localDense.Count > 5)
                    {
                        // here I must replace the localDense with a new edge
                        var newVec      = localDense[localDense.Count - 1].To.Position.subtract(localDense[0].From.Position);
                        var newGearEdge = new GearEdge
                        {
                            To     = localDense[localDense.Count - 1].To,
                            From   = localDense[0].From,
                            Vector = new[] { newVec[0], newVec[1], newVec[2] }
                        };
                        var ind = copyPatch.IndexOf(localDense[0]);
                        copyPatch[ind] = newGearEdge;
                        for (var d = 1; d < localDense.Count; d++)
                        {
                            copyPatch.Remove(localDense[d]);
                        }
                    }
                    localDense.Clear();
                    continue;
                }
                localDense.Add(patch[i]);
            }
            return(copyPatch);
        }