update_lod Subroutine

private subroutine update_lod(self, j, lo, hi, x)

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.

Arguments

Type IntentOptional 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


Calls

proc~~update_lod~~CallsGraph proc~update_lod update_lod proc~line_buffer line_buffer proc~update_lod->proc~line_buffer proc~segment_distance segment_distance proc~update_lod->proc~segment_distance proc~send_lod send_lod proc~update_lod->proc~send_lod interface~vkf_line_points vkf_line_points proc~line_buffer->interface~vkf_line_points interface~vkf_line_set_lod vkf_line_set_lod proc~send_lod->interface~vkf_line_set_lod proc~check_status check_status proc~send_lod->proc~check_status proc~lod_error~2 LineChain%lod_error proc~send_lod->proc~lod_error~2

Called by

proc~~update_lod~~CalledByGraph proc~update_lod update_lod proc~written LineChain%written proc~written->proc~update_lod proc~write_intermediates write_intermediates proc~write_intermediates->proc~written proc~write_marker write_marker proc~write_marker->proc~written proc~write_segments write_segments proc~write_segments->proc~written proc~write_segments~2 write_segments proc~write_segments~2->proc~written proc~add_intermediates add_intermediates proc~add_intermediates->proc~write_intermediates proc~marker_update MarkerArtist%marker_update proc~marker_update->proc~write_marker proc~marker_update->proc~add_intermediates proc~segment_update SegmentArtist%segment_update proc~segment_update->proc~write_segments proc~segments_late_update CustomLineSegments%segments_late_update proc~segments_late_update->proc~write_segments~2

Source Code

    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