Esempio n. 1
0
        public override IEnumerator <Triangle> GetEnumerator()
        {
            PartClassification classes = Classify(this.Original, this.OriginalMesh2);

            foreach (var tri in classes.BInsideA.Concat(classes.AInsideB))
            {
                yield return(tri);
            }
        }
Esempio n. 2
0
        // Classify parts of a solid as inside or outside another
        protected static PartClassification Classify(IMesh a, IMesh b)
        {
            // 0. Initialize intersection list
            List <List <Line3> > acuts = new List <List <Line3> >();
            List <List <Line3> > bcuts = new List <List <Line3> >();

            foreach (Triangle atri in a)
            {
                acuts.Add(new List <Line3>());
            }
            foreach (Triangle btri in b)
            {
                bcuts.Add(new List <Line3>());
            }

            // 1. Determine intersection lines O(N^2)
            Line3 hit;
            // Iterate over Solid A
            int k = 0;

            foreach (Triangle atri in a)
            {
                // Create cut list for this triangle in A
                List <Line3> atriCuts = acuts[k++];
                int          j        = 0;
                // Iterate over Solid b
                foreach (Triangle btri in b)
                {
                    // Create cut list for this triangle in B
                    List <Line3> btriCuts = bcuts[j++];
                    // Check if A & B intersect at these triangles
                    if (atri.Intersection(btri, out hit))
                    {
                        // Add line as a cut line for both triangles
                        atriCuts.Add(hit);
                        btriCuts.Add(hit);
                    }
                }
            }

            // 2. Split a mesh based on intersection lines O(2N)
            List <Triangle> SplitA = new List <Triangle>();
            List <Triangle> SplitB = new List <Triangle>();
            int             i      = 0;

            foreach (Triangle tri in a)
            {
                SplitA.AddRange(Cut(tri, acuts[i++]));
            }
            i = 0;
            foreach (Triangle tri in b)
            {
                SplitB.AddRange(Cut(tri, bcuts[i++]));
            }

            // 3. Classify triangles as AInsideB, AOutsideB, BInsideA, BOutsideA O(2N)
            // - you can use raycast (any dir) to determine if inside (odd hits) vs outside (even hits)
            PartClassification parts = new PartClassification();

            foreach (Triangle tri in SplitA)
            {
                Ray ray = new Ray(tri.Centre, tri.Normal);
                if (ray.CastAll(b).Count % 2 == 0)
                {
                    // Even - Outside
                    parts.AOutsideB.Add(tri);
                }
                else
                {
                    // Odd - Inside
                    parts.AInsideB.Add(tri);
                }
            }
            foreach (Triangle tri in SplitB)
            {
                Ray ray = new Ray(tri.Centre, tri.Normal);
                if (ray.CastAll(a).Count % 2 == 0)
                {
                    // Even - Outside
                    parts.BOutsideA.Add(tri);
                }
                else
                {
                    // Odd - Inside
                    parts.BInsideA.Add(tri);
                }
            }

            // 4. Return classifications
            return(parts);
        }