// File: tomfunkhouser[P]gaps/apps/msh2prp/msh2prp.cpp
// Function: ComputeVolumeProperties(gaps::R3Mesh*)
static R3MeshPropertySet *
ComputeVolumeProperties(R3Mesh *mesh)
{
  // Start statistics
  RNTime start_time;
  start_time.Read();
  if (print_verbose) {
    printf("Computing volume properties ...\n");
    fflush(stdout);
  }

  // Allocate property set
  R3MeshPropertySet *properties = new R3MeshPropertySet(mesh);
  if (!properties) {
    RNFail("Unable to allocate property set.\n");
    return NULL;
  }

  // Rasterize mesh surface into a grid
  R3Grid *grid = CreateGrid(mesh);
  if (!grid) {
    RNFail("Unable to create grid from mesh\n");
    return NULL;
  }

  // Consider density blurred in 3D at multiple scales
  int num_scales = 6;
  RNScalar sigma = Sigma(mesh) * grid->WorldToGridScaleFactor();
  for (int i = 0; i < num_scales; i++) {
    char name[1024];
    sprintf(name, "VolumeDensity%d", i);
    R3MeshProperty *property = new R3MeshProperty(mesh, name);

    // Compute vertex values
    grid->Blur(sigma);
    for (int i = 0; i < mesh->NVertices(); i++) {
      R3MeshVertex *vertex = mesh->Vertex(i);
      const R3Point& position = mesh->VertexPosition(vertex);
      RNScalar value = grid->WorldValue(position);
      property->SetVertexValue(i, value);
    }

    // Insert property
    InsertProperty(properties, property);

    // Increate sigma
    sigma *= 2;
  }

  // Print statistics
  if (print_verbose) {
    printf("  Time = %.2f seconds\n", start_time.Elapsed());
    printf("  # Properties = %d\n", properties->NProperties());
    printf("  Grid resolution = %d %d %d\n", grid->XResolution(), grid->YResolution(), grid->ZResolution());
    fflush(stdout);
  }

  // Delete grid
  delete grid;

  // Return property set
  return properties;
}

// Assembly:
subq $0x4c8, %rsp            # imm = 0x4C8
movq %rdi, 0x4b8(%rsp)
leaq 0x4a8(%rsp), %rdi
callq 0xe98e0
leaq 0x4a8(%rsp), %rdi
callq 0x1f280
cmpl $0x0, 0x1b1440(%rip)    # 0x1ca740
je 0x1931f
leaq 0x15b0ca(%rip), %rdi    # 0x1743d3
movb $0x0, %al
callq 0x11090
movq 0x1a7c79(%rip), %rax    # 0x1c0f90
movq (%rax), %rdi
callq 0x117f0
movl $0x18, %edi
callq 0x11680
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x40(%rsp)
movq 0x4b8(%rsp), %rsi
callq 0x24ce0
jmp 0x19343
movq 0x40(%rsp), %rax
movq %rax, 0x4a0(%rsp)
cmpq $0x0, 0x4a0(%rsp)
jne 0x193a2
leaq 0x15aef4(%rip), %rdi    # 0x174256
movb $0x0, %al
callq 0xedb00
movq $0x0, 0x4c0(%rsp)
jmp 0x1968a
movq 0x40(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
movl $0x18, %esi
callq 0x11690
jmp 0x1969a
movq 0x4b8(%rsp), %rdi
callq 0x1cab0
movq %rax, 0x488(%rsp)
cmpq $0x0, 0x488(%rsp)
jne 0x193e1
leaq 0x15b02b(%rip), %rdi    # 0x1743f4
movb $0x0, %al
callq 0xedb00
movq $0x0, 0x4c0(%rsp)
jmp 0x1968a
movl $0x6, 0x484(%rsp)
movq 0x4b8(%rsp), %rdi
callq 0x14850
movsd %xmm0, 0x38(%rsp)
movq 0x488(%rsp), %rdi
callq 0x1fa10
movaps %xmm0, %xmm1
movsd 0x38(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x478(%rsp)
movl $0x0, 0x474(%rsp)
movl 0x474(%rsp), %eax
cmpl 0x484(%rsp), %eax
jge 0x195b3
movl 0x474(%rsp), %edx
leaq 0x15afc6(%rip), %rsi    # 0x174415
xorl %eax, %eax
movl %eax, 0x2c(%rsp)
leaq 0x70(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x11120
movl $0x448, %edi            # imm = 0x448
callq 0x11680
movq 0x20(%rsp), %rdx
movq %rax, %rdi
movl 0x2c(%rsp), %eax
movq %rdi, %rcx
movq %rcx, 0x30(%rsp)
movq 0x4b8(%rsp), %rsi
movl %eax, %ecx
callq 0x27ef0
jmp 0x19493
movq 0x30(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x488(%rsp), %rdi
movsd 0x478(%rsp), %xmm0
callq 0x73160
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0x4b8(%rsp), %rdi
callq 0x1f2e0
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x1956f
movq 0x4b8(%rsp), %rdi
movl 0x64(%rsp), %esi
callq 0x1f380
movq %rax, 0x58(%rsp)
movq 0x4b8(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x1f4b0
movq %rax, 0x50(%rsp)
movq 0x488(%rsp), %rdi
movq 0x50(%rsp), %rsi
callq 0x1fa30
movsd %xmm0, 0x48(%rsp)
movq 0x68(%rsp), %rdi
movl 0x64(%rsp), %esi
movsd 0x48(%rsp), %xmm0
callq 0x2ae50
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x194bb
movq 0x30(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
movl $0x448, %esi            # imm = 0x448
callq 0x11690
jmp 0x1969a
movq 0x4a0(%rsp), %rdi
movq 0x68(%rsp), %rsi
xorl %edx, %edx
callq 0x148a0
movsd 0x15aa85(%rip), %xmm0   # 0x174010
mulsd 0x478(%rsp), %xmm0
movsd %xmm0, 0x478(%rsp)
movl 0x474(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x474(%rsp)
jmp 0x1942d
cmpl $0x0, 0x1b1186(%rip)    # 0x1ca740
je 0x1964e
leaq 0x4a8(%rsp), %rdi
callq 0xe99a0
leaq 0x15ac38(%rip), %rdi    # 0x17420c
movb $0x1, %al
callq 0x11090
movq 0x4a0(%rsp), %rdi
callq 0x1f400
movl %eax, %esi
leaq 0x15acc6(%rip), %rdi    # 0x1742b7
movb $0x0, %al
callq 0x11090
movq 0x488(%rsp), %rdi
callq 0x1fa70
movl %eax, 0x14(%rsp)
movq 0x488(%rsp), %rdi
callq 0x1fa90
movl %eax, 0x18(%rsp)
movq 0x488(%rsp), %rdi
callq 0x1fab0
movl 0x14(%rsp), %esi
movl 0x18(%rsp), %edx
movl %eax, %ecx
leaq 0x15aded(%rip), %rdi    # 0x174425
movb $0x0, %al
callq 0x11090
movq 0x1a794a(%rip), %rax    # 0x1c0f90
movq (%rax), %rdi
callq 0x117f0
movq 0x488(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x1967a
movq 0x8(%rsp), %rdi
callq 0x70040
movq 0x8(%rsp), %rdi
movl $0x250, %esi            # imm = 0x250
callq 0x11690
movq 0x4a0(%rsp), %rax
movq %rax, 0x4c0(%rsp)
movq 0x4c0(%rsp), %rax
addq $0x4c8, %rsp            # imm = 0x4C8
retq
movq 0x498(%rsp), %rdi
callq 0x11bb0
nopw (%rax,%rax)