Esempio n. 1
0
        public VoxelGrid(Component component, Vect3 plane1Normal = null, Vect3 plane2Normal = null, Vect3 plane3Normal = null)
        {
            orientedBbox = new OrientedBBox(component, plane1Normal, plane2Normal, plane3Normal);
            componentOBBs[component.index] = orientedBbox;

            SetupVoxelGrid();

            this.CreateShellFromFaces(component);
        }
Esempio n. 2
0
        public VoxelGrid(Structure structure, Vect3 plane1Normal = null, Vect3 plane2Normal = null, Vect3 plane3Normal = null)
        {
            orientedBbox = new OrientedBBox(structure, plane1Normal, plane2Normal, plane3Normal);

            SetupVoxelGrid(structure);

            foreach (Component component in structure.components)
            {
                CreateShellFromFaces(component);
            }
        }
Esempio n. 3
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;
                            }
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        private void SetupVoxelGrid(Structure structure = null)
        {
            ComponentWiseResolutionDivider = DefaultComponentWiseResolutionDivider;
            double rightLength;
            double heightLength;
            double depthLength;

            if (resolution == 0)
            {
                if (structure != null)
                {
                    double shortestSide = 0;
                    foreach (var component in structure.components)
                    {
                        OrientedBBox componentOBB = new OrientedBBox(component);

                        rightLength  = (componentOBB.localMaxX - componentOBB.localOrigin).Length();
                        heightLength = (componentOBB.localMaxY - componentOBB.localOrigin).Length();
                        depthLength  = (componentOBB.localMaxZ - componentOBB.localOrigin).Length();

                        shortestSide += Math.Min(rightLength, Math.Min(heightLength, depthLength));

                        componentOBBs[component.index] = componentOBB;
                    }

                    shortestSide /= structure.components.Count;

                    resolution = shortestSide / ComponentWiseResolutionDivider;
                }
                else
                {
                    rightLength  = (orientedBbox.localMaxX - orientedBbox.localOrigin).Length();
                    heightLength = (orientedBbox.localMaxY - orientedBbox.localOrigin).Length();
                    depthLength  = (orientedBbox.localMaxZ - orientedBbox.localOrigin).Length();
                    double shortestSide = Math.Min(rightLength, Math.Min(heightLength, depthLength));
                    resolution = shortestSide / ComponentWiseResolutionDivider;
                }
            }

            halfResolution = resolution / 2d;

            rightLength  = (orientedBbox.localMaxX - orientedBbox.localOrigin).Length();
            heightLength = (orientedBbox.localMaxY - orientedBbox.localOrigin).Length();
            depthLength  = (orientedBbox.localMaxZ - orientedBbox.localOrigin).Length();


            xBound = Convert.ToInt32(Math.Round(rightLength / resolution)) + 4 + 1;
            yBound = Convert.ToInt32(Math.Round(heightLength / resolution)) + 4 + 1;
            zBound = Convert.ToInt32(Math.Round(depthLength / resolution)) + 4 + 1;

            voxelStartCoordinate = orientedBbox.localOrigin - (orientedBbox.localX * 2d * resolution +
                                                               orientedBbox.localY * 2d * resolution +
                                                               orientedBbox.localZ * 2d * resolution);

            // Include offset to move start position to the first cube center.
            voxelMiddleStartCoordinate = orientedBbox.localOrigin - (orientedBbox.localX * 1.5d * resolution +
                                                                     orientedBbox.localY * 1.5d * resolution +
                                                                     orientedBbox.localZ * 1.5d * resolution);

            coordinateGrid = new bool[xBound][][];
            for (int i = 0; i < coordinateGrid.Length; i++)
            {
                coordinateGrid[i] = new bool[yBound][];

                for (int j = 0; j < coordinateGrid[i].Length; j++)
                {
                    coordinateGrid[i][j] = new bool[zBound];
                }
            }

            // Resolution offsets are based around the Voxel center. This allows faster intersection calculations.
            resolutionOffsets = new List <Vect3>
            {
                new Vect3(-halfResolution, -halfResolution, -halfResolution),
                new Vect3(-halfResolution, -halfResolution, halfResolution),
                new Vect3(-halfResolution, halfResolution, -halfResolution),
                new Vect3(-halfResolution, halfResolution, halfResolution),
                new Vect3(halfResolution, -halfResolution, -halfResolution),
                new Vect3(halfResolution, -halfResolution, halfResolution),
                new Vect3(halfResolution, halfResolution, -halfResolution),
                new Vect3(halfResolution, halfResolution, halfResolution)
            };
        }