| Literature DB >> 27408832 |
Pirouz Nourian1, Romulo Gonçalves2, Sisi Zlatanova3, Ken Arroyo Ohori3, Anh Vu Vo4.
Abstract
Voxel representations have been used for years in scientific computation and medical imaging. The main focus of our research is to provide easy access to methods for making large-scale voxel models of built environment for environmental modelling studies while ensuring they are spatially correct, meaning they correctly represent topological and semantic relations among objects. In this article, we present algorithms that generate voxels (volumetric pixels) out of point cloud, curve, or surface objects. The algorithms for voxelization of surfaces and curves are a customization of the topological voxelization approach [1]; we additionally provide an extension of this method for voxelization of point clouds. The developed software has the following advantages:•It provides easy management of connectivity levels in the resulting voxels.•It is not dependant on any external library except for primitive types and constructs; therefore, it is easy to integrate them in any application.•One of the algorithms is implemented in C++ and C for platform independence and efficiency.Entities:
Keywords: 3D city models; Environmental modelling; Geo-spatial database; Point cloud voxelization; Topological voxelization
Year: 2016 PMID: 27408832 PMCID: PMC4929271 DOI: 10.1016/j.mex.2016.01.001
Source DB: PubMed Journal: MethodsX ISSN: 2215-0161
Intersection targets for topological voxelization reproduced after [1].
| Output connectivity | ||
|---|---|---|
| 6-connected | 26-connected | |
| 1D (curve) inputs | ||
| 2D (surface) inputs | ||
Duality of features in 3D space.
| Primal feature | Dual feature |
|---|---|
| 0D vertex (e.g. a point) | 3D body |
| 1D edge (e.g. a line segment) | 2D face |
| 2D face (e.g. a triangle or a pixel) | 1D edge |
| 3D body (e.g. a tetrahedron or a voxel) | 0D vertex |
Duality of features in 1D space.
| Primal feature | Dual feature |
|---|---|
| 0D vertex (e.g. a point) | 1D edge |
| 1D edge (e.g. a line segment) | 0D vertex |
Duality of features in 2D space.
| Primal feature | Dual feature |
|---|---|
| 0D vertex (e.g. a point) | 2D face |
| 1D edge (e.g. a line segment) | 1D edge |
| 2D face (e.g. a triangle or a pixel) | 0D vertex |
Fig. 2Representing adjacencies between 3D cells or bodies via their dual vertices [4].
Fig. 1Topological pixilation after [1] the rasterization at the left is based on an ‘outline’ intersection target which ensures a 4-connected rasterized curve in which every pixel has at least one neighbour sharing an edge with; the rasterization at the right is based on a ‘crosshair’ intersection target which ensures an 8-connected rasterized curve in which every pixel has at least one neighbour sharing a vertex with. Resulting pixels are highlighted in dark grey. Intersection Taregts are highlighted in yellow and intersections with them in red dots. Pixels are shown as blue squares.
Fig. 4Rotterdam AHN-2 dataset, Noordereiland, voxel count 31,880, 1 m × 1 m × 1 m.
Fig. 5Rotterdam AHN-2 dataset, Noordereiland, voxel count 81,588, 0.4 m × 0.4 m × 1 m.
Fig. 3Rotterdam AHN dataset, site in Noordereiland.
Fig. 6A set of curves extracted from OpenStreetMap representing a street network {Tarlabasi, Istanbul}.
Fig. 7Voxelized curves (street centrelines) with 6-connectivity from Tarlabasi dataset with the resolution 10 × 10 × 10.
Fig. 8A surface (triangular polygon mesh) voxelized with connectivity level 26.
Fig. 9A surface (triangular polygon mesh) voxelized with connectivity level 6.
| 1. Initialize |
| a. form a bounding box BBox in |
| b. define voxels as new list of 3D points; |
| c. define voxel size as Vector3d vSize = [sx, sy, sz]; |
| /* generate a bounding box equal or larger than the current bounding box in |
| d. ZBBox = |
| e. compute |
| f. compute |
| g. compute |
| h. define bool[,,] Voxels3I as a 3D array of Booleans of size [CX,CY,CZ]; |
| i. define List<Point3d>VoxelsOut as new list of 3D points; |
| 2. Compute voxels |
| a. For each vertex as Point3d in the point cloud do: |
| i. Compute integer |
| ii. Compute integer |
| iii. Compute integer |
| /*Check if a voxel was already generated for the {i,j,k} location in |
| b. If (Voxels3I[i, j, k] = false) |
| i. |
| ii. Point3d VoxelOut = new Point3d(i * Sx, j * Sy, k * Sz); |
| iii. Voxelout = Voxelout + VSize / 2 + Zbbox.Min; // change its reference as to the Z |
| iv. VoxelsOut.Append(VoxelOut); //and add it to the voxel output |
| 3. return voxels |
| 1. |
| /*to ensure the bounding box for voxels covers the whole bounding box in |
| a. Compute Point3d ZMinP = |
| b. Compute Point3d ZMaxP = |
| c. return new BoundingBox(ZMinP, ZMaxP); |
| 2. Function |
| a. Compute x = RPoint.X; y = RPoint.Y; z = RPoint.Z; |
| b. Compute u = VSize.X; v = VSize.Y; w = VSize.Z; |
| c. Compute |
| d. Compute |
| e. Compute |
| f. Return ZP = new |
| 3. Function |
| a. Compute x = RPoint.X; y = RPoint.Y; z = RPoint.Z; |
| b. Compute u = VSize.X; v = VSize.Y; w = VSize.Z; |
| c. Compute |
| d. Compute |
| e. Compute |
| f. Return ZP = new |
| 1. for each curve in curves: |
| a. form a bounding box in |
| b. define voxels as list of 3D points; |
| /* generate a bounding box equal or larger than the current bounding box in |
| c. ZBBox = |
| d. vSize = [sx, sy, sz]; |
| /* Pseudo code described by Algorithm 6*/ |
| e. VoxelPoints = |
| f. /*voxel centre points closer than the length of vSize to the curve which possibly intersect;*/ |
| g. near_voxel_points = VoxelPoints.FindAll(lambda| lambda.DistanceTo(Curve)<|vSize|/2; |
| f. for each voxel_point in near_voxel_points: |
| i. if (connectivity = = 26) |
| /* Pseudo code described by Algorithm 4*/ |
| intersectionTarget = |
| ii. elseif (connectivity = = 6) |
| /* Pseudo code described by Algorithm 5*/ |
| intersectionTarget = |
| iii. else |
| throw exception and prompt: “other connectivity levels undefined”; |
| iv. if ( |
| voxels.add (voxel_point); |
| 2. return voxels |
| 1. Initialize | |
| a. Mesh IntersectionTarget = new Mesh(); | |
| b. Point3d[] Vertices = new Point3d[12]; | |
| c. double u = (vSize.X / 2), v = (vSize.Y / 2), w = (vSize.Z / 2); | |
| 2. Create Vertices | |
| a. Vertices[00] = VoxelPoint + new Vector3d(+u, +v, 0);//parallel to XY | |
| b. Vertices[01] = VoxelPoint + new Vector3d(−u, +v, 0);//parallel to XY | |
| c. Vertices[02] = VoxelPoint + new Vector3d(−u, −v, 0);//parallel to XY | |
| d. Vertices[03] = VoxelPoint + new Vector3d(+u, −v, 0);//parallel to XY | |
| e. Vertices[04] = VoxelPoint + new Vector3d(0, +v, +w);// parallel to YZ | |
| f. Vertices[05] = VoxelPoint + new Vector3d(0, −v, +w);// parallel to YZ | |
| g. Vertices[06] = VoxelPoint + new Vector3d(0, −v, −w);// parallel to YZ | |
| h. Vertices[07] = VoxelPoint + new Vector3d(0, +v, −w);// parallel to YZ | |
| i. Vertices[08] = VoxelPoint + new Vector3d(+u, 0, +w);// parallel to ZX | |
| j. Vertices[09] = VoxelPoint + new Vector3d(−u, 0, +w);// parallel to ZX | |
| k. Vertices[10] = VoxelPoint + new Vector3d(−u, 0, −w);// parallel to ZX | |
| l. Vertices[11] = VoxelPoint + new Vector3d(+u, 0, −w);// parallel to ZX | |
| 3. Create Faces | |
| a. List<MeshFace>Faces = IntersectionTarget.Faces; | |
| b. Faces.AddFace(00, 01, 02, 03); //parallel to XY | |
| c. Faces.AddFace(04, 05, 06, 07); //parallel to YZ | |
| d. Faces.AddFace(08, 09, 10, 11); //parallel to ZX | |
| e. IntersectionTarget.Vertices.AddVertices(Vertices); | |
| f. IntersectionTarget.Faces.AddFaces(Faces); | |
| g. return IntersectionTarget; | |
| 1. Initialize | |
| a. Mesh IntersectionTarget = new Mesh(); | |
| b. double u = (vSize.X / 2), v = (vSize.Y / 2), w = (vSize.Z / 2); | |
| c. Point3d[] Vertices = new Point3d[9]; Vertices[0] = VoxelPoint; | |
| 2. Create vertices | |
| b. Vertices[1] = VoxelPoint − new Vector3d(+u, +v, +w); | |
| c. Vertices[2] = VoxelPoint − new Vector3d(−u, +v, +w); | |
| d. Vertices[3] = VoxelPoint − new Vector3d(−u, −v, +w); | |
| e. Vertices[4] = VoxelPoint − new Vector3d(+u, −v, +w); | |
| f. Vertices[5] = VoxelPoint + new Vector3d(−u, −v, +w); | |
| g. Vertices[6] = VoxelPoint + new Vector3d(+u, −v, +w); | |
| h. Vertices[7] = VoxelPoint + new Vector3d(+u, +v, +w); | |
| i. Vertices[8] = VoxelPoint + new Vector3d(−u, +v, +w); | |
| 3. Create faces | |
| A. List<meshface>faces = intersectiontarget.faces; | |
| b. Faces.AddFace(0, 1, 2); Faces.AddFace(0, 2, 6); | |
| c. Faces.AddFace(0, 6, 5); Faces.AddFace(0, 5, 1); | |
| d. Faces.AddFace(0, 4, 1); Faces.AddFace(0, 5, 8); | |
| e. Faces.AddFace(0, 8, 7); Faces.AddFace(0, 7, 3); | |
| f. Faces.AddFace(0, 3, 4); Faces.AddFace(0, 4, 8); | |
| g. Faces.AddFace(0, 7, 6); Faces.AddFace(0, 2, 3); | |
| h. IntersectionTarget.Vertices.AddVertices(Vertices); | |
| i. IntersectionTarget.Faces.AddFaces(Faces); | |
| 4. return IntersectionTarget; | |
| 1. Initialize |
| a. int i = 0, j = 0, k = 0; |
| b. |
| c. |
| d. |
| e. List<Point3d>VoxelPoints = new List<Point3d>(); |
| 2. Create voxels |
| a. for (k = 0; k < Kmax; k++) {for (j = 0; j < Jmax; j++){for (i = 0; i < Imax; i++) |
| i. Point3d RelPoint = new Point3d(i * vSize.X, j * vSize.Y, k * vSize.Z); |
| ii. RelPoint = RelPoint + new Vector3d(ZBBox.Min) + 0.5*VSize; |
| iii. VoxelPoints.Add(RelPoint); |
| 3. Return VoxelPoints; |
| 1. for each surface in surfaces: |
| a. form a bounding box in |
| b. define voxels as list of 3D points; |
| /* generate a bounding box equal or larger than the current bounding box in |
| c. ZBBox = |
| d. define voxel size as vSize = [sx, sy, sz]; |
| /* Pseudo code described by Algorithm 6*/ |
| a. VoxelPoints = |
| /*voxel centre points closer than half of the length vSize to the surface which possibly intersect with the input surface;*/ |
| e. near_voxel_points = VoxelPoints.FindAll(lambda| lambda.DistanceTo(Surface)<|VSize|/2 |
| f. for each voxel_point in near_voxel_points |
| i. if (connectivity= =26) |
| /* Pseudo code described by |
| 1. intersectionTarget = |
| ii. elseif (connectivity = = 6) |
| /* Pseudo code described by |
| 1. intersectionTarget = |
| iii. else |
| 1. throw exception and prompt: “other connectivity levels undefined”; |
| iv. if ( |
| 1. voxels.add(voxel_point); |
| 2. return voxels; |
| 1. Initialize | |
| a. Line[] IntersecTarget = new Line[3]; | |
| b. Point3d[] Vertices = new Point3d[6]; | |
| c. double u = (vSize.X / 2), v = (vSize.Y / 2), w = (vSize.Z / 2); | |
| 2. Create Vertices | |
| a. Vertices[0] = VoxelPoint + new Vector3d(+u, 0, 0); | |
| b. Vertices[1] = VoxelPoint + new Vector3d(0, +v, 0); | |
| c. Vertices[2] = VoxelPoint + new Vector3d(0, 0, +w); | |
| d. Vertices[3] = VoxelPoint + new Vector3d(−u, 0, 0); | |
| e. Vertices[4] = VoxelPoint + new Vector3d(0, −v, 0); | |
| f. Vertices[5] = VoxelPoint + new Vector3d(0, 0, −w); | |
| 3. Create Edges | |
| a. for (int i = 0; i <= 2; i++) | |
| i. IntersecTarget[i] = new Line(Vertices[i], Vertices[i + 3]); | |
| b. return IntersectionTarget; | |
| 1. Initialize | |
| a. Line[] IT = new Line[4]; | |
| b. Point3d[] VX = new Point3d[8]; | |
| c. double u = (vSize.X / 2), v = (vSize.Y / 2), w = (vSize.Z / 2); | |
| 2. Create Vertices | |
| a. VX[0] = VoxelPoint + new Vector3d(+u, +v, +w); | |
| b. VX[1] = VoxelPoint + new Vector3d(−u, +v, +w); | |
| c. VX[2] = VoxelPoint + new Vector3d(−u, −v, +w); | |
| d. VX[3] = VoxelPoint + new Vector3d(+u, −v, +w); | |
| e. VX[4] = VoxelPoint + new Vector3d(−u, −v, −w); | |
| f. VX[5] = VoxelPoint + new Vector3d(+u, −v, −w); | |
| g. VX[6] = VoxelPoint + new Vector3d(+u, +v, −w); | |
| h. VX[7] = VoxelPoint + new Vector3d(−u, +v, −w); | |
| 3. Create Edges | |
| a. IT[0] = new Line(VX[0], VX[4]); | |
| b. IT[1] = new Line(VX[1], VX[5]); | |
| c. IT[2] = new Line(VX[2], VX[6]); | |
| d. IT[3] = new Line(VX[3], VX[7]); | |
| e. return IT; | |
| 1. Initialize | |
| d. Line[] IT = new Line[12]; | |
| e. Point3d[] VX = new Point3d[8]; | |
| f. double u = (vSize.X / 2), v = (vSize.Y / 2), w = (vSize.Z / 2); | |
| 2. Create Vertices | |
| i. VX[0] = VoxelPoint + new Vector3d(+u, +v, +w); | |
| j. VX[1] = VoxelPoint + new Vector3d(−u, +v, +w); | |
| k. VX[2] = VoxelPoint + new Vector3d(−u, −v, +w); | |
| l. VX[3] = VoxelPoint + new Vector3d(+u, −v, +w); | |
| m. VX[4] = VoxelPoint + new Vector3d(−u, −v, −w); | |
| n. VX[5] = VoxelPoint + new Vector3d(+u, −v, −w); | |
| o. VX[6] = VoxelPoint + new Vector3d(+u, +v, −w); | |
| p. VX[7] = VoxelPoint + new Vector3d(−u, +v, −w); | |
| 3. Create Edges | |
| f. IT[00] = new Line(VX[0], VX[1]); | |
| g. IT[01] = new Line(VX[1], VX[2]); | |
| h. IT[02] = new Line(VX[2], VX[3]); | |
| i. IT[03] = new Line(VX[3], VX[0]); | |
| j. IT[04] = new Line(VX[0], VX[6]); | |
| k. IT[05] = new Line(VX[6], VX[5]); | |
| l. IT[06] = new Line(VX[5], VX[4]); | |
| m. IT[07] = new Line(VX[4], VX[7]); | |
| n. IT[08] = new Line(VX[5], VX[3]); | |
| o. IT[09] = new Line(VX[4], VX[2]); | |
| p. IT[10] = new Line(VX[1], VX[7]); | |
| q. IT[11] = new Line(VX[6], VX[7]); | |
| r. return IT; | |