Points lo .. hi of chunk j (a strip's) were written, the last being hi:
update the bounding box and the error bounds of the segments they change
at each stride, and give them to the renderer. x as in written.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(LineChain), | intent(inout) | :: | self | |||
| integer, | intent(in) | :: | j |
the chunk, and its points lo .. hi (chain indices) |
||
| integer, | intent(in) | :: | lo |
the chunk, and its points lo .. hi (chain indices) |
||
| integer, | intent(in) | :: | hi |
the chunk, and its points lo .. hi (chain indices) |
||
| real(kind=wp), | intent(in), | optional | :: | x(:,:) |
(3, chain points): the points, as in written |
subroutine update_lod(self, j, lo, hi, x) type(LineChain), intent(inout) :: self integer, intent(in) :: j, lo, hi !! the chunk, and its points lo .. hi (chain indices) real(wp), intent(in), optional :: x(:,:) !! (3, chain points): the points, as in [[written]] real(c_float), dimension(:,:,:), pointer :: p real(wp) :: b0, b1, q(3) integer :: n, q0, k, s, m, seg, a, e, mid, i associate (c => self%chunks(j)) call line_buffer(c%line, p) if (.not. associated(p)) return n = hi - c%first + 1 ! points written in the chunk (local 0 .. n-1) c%n_written = n q0 = lo - c%first ! the first one written now do i = q0, n - 1 ! the bounding box q = pt(i) if (i == 0) then c%box_lo = q c%box_hi = q else c%box_lo = min(c%box_lo, q) c%box_hi = max(c%box_hi, q) end if end do do k = 1, lod_levels s = 2**k m = 0 if (n >= 2) m = (n - 2) / s + 1 ! segments at stride s if (m == 0) exit if (.not. allocated(c%lod(k)%bound)) allocate(c%lod(k)%bound(0:(c%capacity - 2) / s)) do seg = max(0, q0 - 1) / s, m - 1 ! the segments the points written change a = seg * s e = min(a + s, n - 1) mid = a + s / 2 b0 = 0.0_wp ! the halves' bounds (none at stride 1) b1 = 0.0_wp if (k > 1) b0 = c%lod(k - 1)%bound(2 * seg) if (mid < e) then ! two halves: also the middle point's distance if (k > 1) b1 = c%lod(k - 1)%bound(2 * seg + 1) c%lod(k)%bound(seg) = real(max(b0, b1) + segment_distance(pt(mid), pt(a), pt(e)), c_float) else c%lod(k)%bound(seg) = real(b0, c_float) end if end do end do end associate call send_lod(self, j) contains !> Local point i of the chunk, in double precision. function pt(i) result(v) integer, intent(in) :: i !! the chunk's point (0-based local index) real(wp) :: v(3) if (present(x)) then v = x(:, self%chunks(j)%first + i) else v = real(p(1:3, 1, i + 1), wp) + real(p(1:3, 2, i + 1), wp) end if end function pt end subroutine update_lod