Пример #1
0
        public List <Vect3> ConvertFaceToLocal(Face face, Component component)
        {
            List <Vect3> facePositions = new List <Vect3>
            {
                component.GetCoordinate(face.vertexIndices[0]),
                component.GetCoordinate(face.vertexIndices[1]),
                component.GetCoordinate(face.vertexIndices[2])
            };

            return(ConvertToLocalCoordinates(facePositions));
        }
Пример #2
0
        /*
         * Fills internal volume of voxels by finding points in the voxel grid captured
         * by a mesh. Relies on the original meshes to perform odd/even polygon capture calculation.
         *
         * https://en.wikipedia.org/wiki/Point_in_polygon
         */
        public void FillInternalVolume(Component component)
        {
            OrientedBBox componentOBB = componentOBBs[component.index];

            List <Vect3> points = new List <Vect3>();

            foreach (var vertex in component.vertices)
            {
                points.Add(vertex.coordinate);
            }

            VoxelSpan componentVoxelSpan = new VoxelSpan(points, this, BorderOffset);

            for (int x = componentVoxelSpan.minX; x < componentVoxelSpan.maxX; x++)
            {
                for (int z = componentVoxelSpan.minZ; z < componentVoxelSpan.maxZ; z++)
                {
                    for (int y = componentVoxelSpan.minY; y < componentVoxelSpan.maxY; y++)
                    {
                        if (!coordinateGrid[x][y][z] && coordinateGrid[x][Math.Max(0, y - 1)][z])
                        {
                            Vect3 globalPos = voxelStartCoordinate +
                                              orientedBbox.localX * x * resolution +
                                              orientedBbox.localY * y * resolution +
                                              orientedBbox.localZ * z * resolution;

                            if (!componentOBB.ContainsGlobalCoordinate(globalPos, OrientedBBoxExpansionFactor))
                            {
                                continue;
                            }

                            int intersects = 0;
                            foreach (Face face in component.faces)
                            {
                                Vect3 triA = component.GetCoordinate(face.vertexIndices[0]);
                                Vect3 triB = component.GetCoordinate(face.vertexIndices[1]);
                                Vect3 triC = component.GetCoordinate(face.vertexIndices[2]);

                                // if (intersect_triangle(globalPos, Vect3.Up, triA, triB, triC))
                                if (rayIntersectsTriangle(globalPos, Vect3.Up, triA, triB, triC))
                                {
                                    intersects++;
                                }
                            }

                            if ((intersects % 2) != 0)
                            {
                                int rise = 0;
                                while (!coordinateGrid[x][y + rise][z])
                                {
                                    coordinateGrid[x][y + rise][z] = true;
                                    rise++;
                                }
                            }
                            else if (intersects == 0)
                            {
                                // If there is no intersecting surface above whatsoever, this column cannot
                                // contain points that are inside a polygon.
                                break;
                            }
                        }
                    }
                }
            }
        }
Пример #3
0
        /*
         * Finds and removes redundant points in a circular list of vertices that describe an exterior ring of a mesh.
         *
         * Examines the list three elements at a time. If the vector formed by the first and second element has the same
         * direction as the the vector formed by the second and third element, the second element is redundant and removed.
         */
        private static void RemoveRedundantPoints(ref LinkedList <int> floorSideVertices, Component component)
        {
            Vect3 firstPoint;
            Vect3 secondPoint;
            Vect3 thirdPoint;

            Vect3 firstToSecond;;
            Vect3 secondToThird;

            //Handle midlist cases
            var current = floorSideVertices.First.Next;

            while (current != floorSideVertices.Last)
            {
                if (current == floorSideVertices.First)
                {
                    current = current.Next; continue;
                }

                firstPoint  = component.GetCoordinate(current.Previous.Value);
                secondPoint = component.GetCoordinate(current.Value);
                thirdPoint  = component.GetCoordinate(current.Next.Value);

                firstToSecond = secondPoint - firstPoint;
                secondToThird = thirdPoint - secondPoint;

                if (firstToSecond.AngleTo(secondToThird) < AngleEqualityTolerance)
                {
                    current = current.Previous;
                    floorSideVertices.Remove(current.Next);
                }
                else
                {
                    current = current.Next;
                }
            }
            //Noncircular list data structure for circular list

            // Compare secondToLast->Last->First, if same, remove last, repeat check
            firstPoint  = component.GetVertex(floorSideVertices.Last.Previous.Value).coordinate;
            secondPoint = component.GetVertex(floorSideVertices.Last.Value).coordinate;
            thirdPoint  = component.GetVertex(floorSideVertices.First.Value).coordinate;

            firstToSecond = secondPoint - firstPoint;
            secondToThird = thirdPoint - secondPoint;

            while (firstToSecond.AngleTo(secondToThird) < AngleEqualityTolerance)
            {
                floorSideVertices.RemoveLast();
                firstPoint  = component.GetVertex(floorSideVertices.Last.Previous.Value).coordinate;
                secondPoint = component.GetVertex(floorSideVertices.Last.Value).coordinate;
                thirdPoint  = component.GetVertex(floorSideVertices.First.Value).coordinate;

                firstToSecond = secondPoint - firstPoint;
                secondToThird = thirdPoint - secondPoint;
            }

            // Compare Last->->First->SecondAfterFirst, if same, remove first, repeat check
            firstPoint  = component.GetVertex(floorSideVertices.Last.Value).coordinate;
            secondPoint = component.GetVertex(floorSideVertices.First.Value).coordinate;
            thirdPoint  = component.GetVertex(floorSideVertices.First.Next.Value).coordinate;

            firstToSecond = secondPoint - firstPoint;
            secondToThird = thirdPoint - secondPoint;

            while (firstToSecond.AngleTo(secondToThird) < AngleEqualityTolerance)
            {
                floorSideVertices.RemoveFirst();
                firstPoint  = component.GetVertex(floorSideVertices.Last.Value).coordinate;
                secondPoint = component.GetVertex(floorSideVertices.First.Value).coordinate;
                thirdPoint  = component.GetVertex(floorSideVertices.First.Next.Value).coordinate;

                firstToSecond = secondPoint - firstPoint;
                secondToThird = thirdPoint - secondPoint;
            }
        }