29 Commits

Author SHA1 Message Date
AndreaRigoni
f2133c31d5 DetectorChamber vtk handler 2026-03-10 08:18:17 +00:00
AndreaRigoni
00275ac56d vtk camera position widget on viewer 2026-03-08 16:51:39 +00:00
AndreaRigoni
1374821344 added gizmo but not yet working 2026-03-08 10:21:38 +00:00
AndreaRigoni
2548582036 attach a widget (not working well yet) 2026-03-08 09:42:28 +00:00
AndreaRigoni
32a1104769 detector chamber in vtk 2026-03-08 08:46:21 +00:00
AndreaRigoni
3be7ec2274 add stl test 2026-03-08 08:05:22 +00:00
AndreaRigoni
38dd416ced vix raytracer representation 2026-03-07 09:07:07 +00:00
AndreaRigoni
e8f8e96521 reorganization of sources, moving cmt pertaining structures into HEP folder 2026-03-07 08:58:31 +00:00
AndreaRigoni
49cf0aeedd feat: disable camera spin/inertia by introducing a custom interactor style.r 2026-03-06 17:31:29 +00:00
40846bba78 Update .gitea/workflows/publish-docs.yaml
All checks were successful
MkDocs Subpath Deploy / build-and-deploy (push) Successful in 11s
2026-03-06 17:52:45 +01:00
4d681e3373 Update .gitea/workflows/publish-docs.yaml
Some checks failed
MkDocs Subpath Deploy / build-and-deploy (push) Failing after 12s
2026-03-06 17:51:53 +01:00
3a9efd5598 Update .gitea/workflows/publish-docs.yaml 2026-03-06 17:50:13 +01:00
fa1930f9d7 Merge pull request 'andrea-dev' (#1) from andrea-dev into main
Reviewed-on: #1
added CUDA for images and raytracing, added python bindings via pybind11, removed LTK, added documentation
2026-03-06 17:17:52 +01:00
AndreaRigoni
b64afe8773 add documention workflow 2026-03-06 10:45:33 +00:00
AndreaRigoni
f3ebba4931 add thrust 2026-03-06 10:45:14 +00:00
AndreaRigoni
79e1abb2ff add USE_CUDA env in python_build 2026-03-05 15:17:30 +00:00
AndreaRigoni
554eff9b55 add filters in python bindings 2026-03-05 15:03:19 +00:00
AndreaRigoni
42db99759f fix py dense 2026-03-05 14:26:05 +00:00
AndreaRigoni
69920acd61 poetry python build 2026-03-05 12:42:14 +00:00
AndreaRigoni
647d0caa1c feat: Add Python packaging infrastructure and comprehensive bindings for math and vector types. 2026-03-05 11:39:27 +00:00
AndreaRigoni
e69b29a259 add first python bindings 2026-03-05 09:16:15 +00:00
AndreaRigoni
9a59e031ed feat: Implement a custom MetaAllocator for uLib::Vector to enable GPU memory management and integrate CUDA support into the build system. 2026-03-04 20:52:01 +00:00
AndreaRigoni
adedbcc37c feat: add CUDA raytracing benchmark and refactor VoxRaytracer::RayData to use DataAllocator for host/device memory management. 2026-03-04 17:47:18 +00:00
AndreaRigoni
eb76521060 add clangd linting fix 2026-03-04 14:37:02 +00:00
AndreaRigoni
b1fb123026 feat: Implement CUDA support for VoxRaytracer, add CUDA tests for voxel image operations, and update CMake to enable CUDA compilation. 2026-03-04 13:59:45 +00:00
AndreaRigoni
52580d8cde refactor: migrate voxel data storage to DataAllocator for CUDA 2026-02-28 10:05:39 +00:00
AndreaRigoni
07915295cb feat: fix signaling and implement a ping-pong signal/slot test 2026-02-28 08:58:04 +00:00
AndreaRigoni
d56758d0b3 refactor: Update CMake build system and streamline Core object serialization and property handling. 2026-02-21 16:16:28 +00:00
AndreaRigoni
7ded15d596 chore: remove LTK, MOC, and QVTKViewport2 components. 2026-02-21 15:40:21 +00:00
198 changed files with 9978 additions and 9312 deletions

52
.clangd Normal file
View File

@@ -0,0 +1,52 @@
CompileFlags:
CompilationDatabase: build
Add:
- -I/home/rigoni/devel/cmt/ulib/src
- -isystem/home/share/micromamba/envs/mutom/include
- -isystem/home/share/micromamba/envs/mutom/include/eigen3
- -isystem/home/share/micromamba/envs/mutom/targets/x86_64-linux/include
- -isystem/home/share/micromamba/envs/mutom/lib/gcc/x86_64-conda-linux-gnu/14.3.0/include/c++
- -isystem/isystem/home/share/micromamba/envs/mutom/lib/gcc/x86_64-conda-linux-gnu/14.3.0/include/c++/x86_64-conda-linux-gnu
- -isystem/home/share/micromamba/envs/mutom/x86_64-conda-linux-gnu/sysroot/usr/include
- "--gcc-toolchain=/home/share/micromamba/envs/mutom"
- -D_ULIB_DETAIL_SIGNAL_EMIT
- -DUSE_CUDA
- -std=c++17
- "-D__host__="
- "-D__device__="
- "-D__global__="
- "-D__constant__="
- "-D__shared__="
- "-D__align__(x)="
- "-D__forceinline__=inline"
- "-D__launch_bounds__(x)="
Diagnostics:
UnusedIncludes: None
MissingIncludes: None
---
If:
PathExclude: [/home/rigoni/devel/cmt/ulib/src/.*]
Diagnostics:
Suppress: ["*"]
---
If:
PathMatch: [.*\.cu, .*/src/Math/testing/VoxRaytracerTest.cpp, .*/src/Math/VoxRaytracer.cpp, .*/src/Math/VoxImage.cpp]
CompileFlags:
Add:
- "-x"
- "cuda"
- "--cuda-path=/home/share/micromamba/envs/mutom"
- "--cuda-gpu-arch=sm_61"
- "--gcc-toolchain=/home/share/micromamba/envs/mutom"
- "-L/home/share/micromamba/envs/mutom/lib"
- "-lcudart"
- "-lcuda"
- "-U__host__"
- "-U__device__"
- "-U__global__"
- "-U__constant__"
- "-U__shared__"
- "-U__forceinline__"

View File

@@ -0,0 +1,42 @@
name: MkDocs Subpath Deploy
on:
workflow_dispatch: # trigger manuale
push:
branches:
- main # Trigger on main branch
jobs:
build-and-deploy:
runs-on: mildpub # Runner that can access to SSH_YFINPUB_HOST
steps:
- name: Checkout del codice
uses: actions/checkout@v4
- name: Configura Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Installa dipendenze
run: |
python -m pip install --upgrade pip
pip install mkdocs-material
pip install -r docs/docker/requirements.txt
- name: Build del sito
run: mkdocs build
- name: Deploy via SSH (SCP)
uses: https://github.com/appleboy/scp-action@master
with:
host: ${{ vars.SSH_YFINPUB_HOST }}
username: ${{ vars.SSH_YFINPUB_USER }}
key: ${{ secrets.MILD_PUB }}
port: 22
source: "site/*"
# Il percorso sul server deve corrispondere alla tua sottopagina
target: "/var/www/docs/cmt/uLib/"
strip_components: 1 # Rimuove la cartella "site/" e mette solo il contenuto
rm: true # Pulisce la cartella prima di copiare (opzionale, stile Vercel)

12
.gitignore vendored
View File

@@ -1,3 +1,15 @@
CMakeFiles/ CMakeFiles/
build/ build/
.cache/ .cache/
build_warnings*.log
final_build.log
cmake_configure.log
compile_commands.json
dist/
build_python/
src/Python/uLib/*.so*
src/Python/uLib/*.pyd
src/Python/uLib/*.pyc
src/Python/uLib/__pycache__
src/Python/uLib/.nfs*

32
.vscode/settings.json vendored
View File

@@ -1,8 +1,32 @@
{ {
"clangd.fallbackFlags": [ "clangd.fallbackFlags": [
"-I${workspaceFolder}/src", "-I/home/rigoni/devel/cmt/ulib/src",
"-I/home/share/micromamba/envs/mutom/include", "-isystem/home/share/micromamba/envs/mutom/include",
"-I/home/rigoni/.conan2/p/eigen5481853932f72/p/include/eigen3" "-isystem/home/share/micromamba/envs/mutom/include/eigen3",
"-isystem/home/share/micromamba/envs/mutom/targets/x86_64-linux/include",
"-isystem/home/share/micromamba/envs/mutom/lib/gcc/x86_64-conda-linux-gnu/14.3.0/include/c++",
"-isystem/home/share/micromamba/envs/mutom/lib/gcc/x86_64-conda-linux-gnu/14.3.0/include/c++/x86_64-conda-linux-gnu",
"-isystem/home/share/micromamba/envs/mutom/x86_64-conda-linux-gnu/sysroot/usr/include",
"--gcc-toolchain=/home/share/micromamba/envs/mutom",
"-D__host__=",
"-D__device__=",
"-D__global__=",
"-D__constant__=",
"-D__shared__=",
"-DUSE_CUDA",
"-D__CUDACC__"
], ],
"clangd.semanticHighlighting.enable": true "clangd.semanticHighlighting.enable": true,
"clangd.arguments": [
"--compile-commands-dir=build",
"--query-driver=/home/share/micromamba/envs/mutom/bin/g++,/home/share/micromamba/envs/mutom/bin/gcc,/home/share/micromamba/envs/mutom/bin/nvcc",
"--suppress-system-warnings",
"--all-scopes-completion",
"--completion-style=detailed",
"--header-insertion=never",
"-j=4",
"--pch-storage=memory",
"--background-index",
"--log=verbose"
]
} }

View File

@@ -82,7 +82,7 @@ ENDMACRO(uLib_add_target)
# TESTS and LIBRARIES must be defined # TESTS and LIBRARIES must be defined
macro(uLib_add_tests name) macro(uLib_add_tests name)
foreach(tn ${TESTS}) foreach(tn ${TESTS})
add_executable(${tn} EXCLUDE_FROM_ALL ${tn}.cpp) add_executable(${tn} ${tn}.cpp)
add_test(NAME ${tn} COMMAND ${tn}) add_test(NAME ${tn} COMMAND ${tn})
target_link_libraries(${tn} ${LIBRARIES}) target_link_libraries(${tn} ${LIBRARIES})
@@ -91,7 +91,9 @@ macro(uLib_add_tests name)
# custom target to compile all tests # custom target to compile all tests
add_custom_target(all-${name}-tests) add_custom_target(all-${name}-tests)
add_dependencies(all-${name}-tests ${TESTS}) if(TESTS)
add_dependencies(all-${name}-tests ${TESTS})
endif()
endmacro(uLib_add_tests name) endmacro(uLib_add_tests name)

View File

@@ -4,11 +4,31 @@
################################################################################ ################################################################################
cmake_minimum_required (VERSION 3.26) cmake_minimum_required (VERSION 3.26)
if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW)
endif()
## -------------------------------------------------------------------------- ## ## -------------------------------------------------------------------------- ##
project(uLib) project(uLib)
# CUDA Toolkit seems to be missing locally. Toggle ON if nvcc is made available.
option(USE_CUDA "Enable CUDA support" ON)
if(USE_CUDA)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -allow-unsupported-compiler")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Wno-deprecated-gpu-targets")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcudafe \"--diag_suppress=20012\"")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcudafe \"--diag_suppress=20014\"")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcudafe \"--diag_suppress=20015\"")
find_package(CUDAToolkit REQUIRED)
enable_language(CUDA)
set(CMAKE_CUDA_ARCHITECTURES 61)
include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
add_compile_definitions(USE_CUDA)
endif()
# The version number. # The version number.
set(PROJECT_VERSION_MAJOR 0) set(PROJECT_VERSION_MAJOR 0)
set(PROJECT_VERSION_MINOR 6) set(PROJECT_VERSION_MINOR 6)
@@ -76,6 +96,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_WARNING_OPTION}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -UULIB_SERIALIZATION_ON -Wno-cpp") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -UULIB_SERIALIZATION_ON -Wno-cpp")
# CTEST framework # CTEST framework
include(CTest)
enable_testing() enable_testing()
@@ -85,7 +106,8 @@ set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON) set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF) set(Boost_USE_STATIC_RUNTIME OFF)
message(STATUS "CMAKE_PREFIX_PATH is ${CMAKE_PREFIX_PATH}") message(STATUS "CMAKE_PREFIX_PATH is ${CMAKE_PREFIX_PATH}")
find_package(Boost 1.45.0 COMPONENTS program_options REQUIRED)
find_package(Boost 1.45.0 COMPONENTS program_options serialization unit_test_framework REQUIRED)
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
find_package(Eigen3 CONFIG REQUIRED) find_package(Eigen3 CONFIG REQUIRED)
@@ -98,6 +120,7 @@ include(${ROOT_USE_FILE})
find_package(VTK REQUIRED) find_package(VTK REQUIRED)
# include(${VTK_USE_FILE}) # include(${VTK_USE_FILE})
find_package(pybind11 REQUIRED)
option(CENTOS_SUPPORT "VTK definitions for CentOS" OFF) option(CENTOS_SUPPORT "VTK definitions for CentOS" OFF)
@@ -123,7 +146,8 @@ else()
RenderingFreeType RenderingFreeType
RenderingGL2PSOpenGL2 RenderingGL2PSOpenGL2
RenderingOpenGL2 RenderingOpenGL2
RenderingVolumeOpenGL2) RenderingVolumeOpenGL2
IOGeometry)
endif() endif()
set(CMAKE_REQUIRED_INCLUDES CMAKE_REQUIRED_INCLUDES math.h) set(CMAKE_REQUIRED_INCLUDES CMAKE_REQUIRED_INCLUDES math.h)
@@ -181,8 +205,8 @@ add_subdirectory(${SRC_DIR}/Core)
include_directories(${SRC_DIR}/Math) include_directories(${SRC_DIR}/Math)
add_subdirectory(${SRC_DIR}/Math) add_subdirectory(${SRC_DIR}/Math)
include_directories(${SRC_DIR}/Detectors) include_directories(${SRC_DIR}/HEP)
add_subdirectory(${SRC_DIR}/Detectors) add_subdirectory(${SRC_DIR}/HEP)
include_directories(${SRC_DIR}/Root) include_directories(${SRC_DIR}/Root)
add_subdirectory(${SRC_DIR}/Root) add_subdirectory(${SRC_DIR}/Root)
@@ -190,6 +214,8 @@ add_subdirectory(${SRC_DIR}/Root)
include_directories(${SRC_DIR}/Vtk) include_directories(${SRC_DIR}/Vtk)
add_subdirectory(${SRC_DIR}/Vtk) add_subdirectory(${SRC_DIR}/Vtk)
add_subdirectory(${SRC_DIR}/Python)
#add_subdirectory("${SRC_DIR}/utils/make_recipe") #add_subdirectory("${SRC_DIR}/utils/make_recipe")
## Documentation and packages ## Documentation and packages

16
CMakePresets.json Normal file
View File

@@ -0,0 +1,16 @@
{
"version": 8,
"configurePresets": [
{
"name": "andrea",
"displayName": "Custom configure preset",
"description": "Sets Ninja generator, build and install directory",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
}
}
]
}

View File

@@ -61,3 +61,10 @@ cmake --preset conan-release
```bash ```bash
cmake --build build -j10 cmake --build build -j10
``` ```
### Make python package
```bash
micromamba run -n mutom env USE_CUDA=ON poetry install
```

54
build_python.py Normal file
View File

@@ -0,0 +1,54 @@
import os
import subprocess
import sys
import shutil
def build(setup_kwargs):
"""
Build the C++ extension using CMake.
This function is called by poetry-core during the build process.
The binary is placed directly inside the uLib directory in src/Python.
"""
# Root of the whole project where this build_extension.py is located
project_root = os.path.abspath(os.path.dirname(__file__))
# Where the extension should go
package_dir = os.path.join(project_root, "src/Python/uLib")
# Ensure package directory exists
os.makedirs(package_dir, exist_ok=True)
# Temporary build directory
build_temp = os.path.join(project_root, "build_python")
os.makedirs(build_temp, exist_ok=True)
print(f"--- Running CMake build in {build_temp} ---")
print(f"Project root: {project_root}")
print(f"Target binary dir: {package_dir}")
# Determine if CUDA should be enabled
use_cuda = os.environ.get("USE_CUDA", "OFF").upper()
if use_cuda in ["ON", "1", "TRUE", "YES"]:
use_cuda = "ON"
else:
use_cuda = "OFF"
# CMake configuration
cmake_args = [
f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={package_dir}",
f"-DPYTHON_EXECUTABLE={sys.executable}",
"-DCMAKE_BUILD_TYPE=Release",
f"-DUSE_CUDA={use_cuda}",
"-G", "Unix Makefiles",
]
# Use micromamba to ensure Boost and VTK are found during the build
subprocess.check_call(["cmake", project_root] + cmake_args, cwd=build_temp)
subprocess.check_call(["cmake", "--build", ".", "--parallel", "--target", "uLib_python"], cwd=build_temp)
# Ensure the package is found by poetry during the wheel creation process.
# Return setup_kwargs for poetry-core.
return setup_kwargs
if __name__ == "__main__":
build({})

View File

@@ -1,6 +1,7 @@
[requires] [requires]
eigen/3.4.0 eigen/3.4.0
boost/1.83.0 boost/1.83.0
pybind11/3.0.2
[generators] [generators]
CMakeDeps CMakeDeps

View File

@@ -0,0 +1,41 @@
.tabbed-set {
display: flex;
position: relative;
flex-wrap: wrap;
}
.tabbed-set .highlight {
background: #ddd;
}
.tabbed-set .tabbed-content {
display: none;
order: 99;
width: 100%;
}
.tabbed-set label {
width: auto;
margin: 0 0.5em;
padding: 0.25em;
font-size: 120%;
cursor: pointer;
color: #ffffff !important;
}
.tabbed-set input {
position: absolute;
opacity: 0;
}
.tabbed-set input:nth-child(n+1) {
color: #333333;
}
.tabbed-set input:nth-child(n+1):checked + label {
color: cyan !important;
}
.tabbed-set input:nth-child(n+1):checked + label + .tabbed-content {
display: block;
}

17
docs/assets/css/extra.css Normal file
View File

@@ -0,0 +1,17 @@
@import "extensions/tabbed.css";
.md-grid {
max-width: 100%;
}
.md-main__inner {
margin-top: 0;
padding-top: 0;
}
.md-sidebar--secondary {
right: 1.5rem;
top: 4.8rem;
transform: none;
width: 18rem;
}

30
docs/docker/Dockerfile Normal file
View File

@@ -0,0 +1,30 @@
# Stage 1: Build the static site using MkDocs
FROM python:3.9-slim-buster as builder
# Set the working directory
WORKDIR /app
# Copy the requirements file
COPY requirements.txt .
# Install the Python dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application files
COPY ../.. .
# Build the MkDocs site
RUN mkdocs build
# Stage 2: Serve the static files with Nginx
FROM nginx:alpine
# Copy the built site from the builder stage
COPY --from=builder /app/site /usr/share/nginx/html
# Expose port 80 for the web server
EXPOSE 80
# Command to run Nginx in the foreground
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -0,0 +1,14 @@
# Dockerfile for development with live-reloading
FROM python:3.9-slim-buster
WORKDIR /app
# Copy and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Expose the port MkDocs serve will run on
EXPOSE 8000
# Command to run the development server
CMD ["mkdocs", "serve", "--dev-addr", "0.0.0.0:8000"]

View File

@@ -0,0 +1,13 @@
version: '3.8'
services:
mkdocs:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "8000:8000"
volumes:
- ../..:/app
environment:
- GIT_DISCOVERY_ACROSS_FILESYSTEM=1

View File

@@ -0,0 +1,17 @@
# ------------------------------------------------------------------
# MkDocs runtime dependencies for the docs Docker image
# ------------------------------------------------------------------
# Core: theme (provides mkdocs itself as a transitive dep)
mkdocs-material==9.7.1
# pymdownx.* extensions used in mkdocs.yml:
# arithmatex, highlight, superfences, tabbed, details, blocks.caption
# (also a hard dep of mkdocs-material, pinned here for reproducibility)
pymdown-extensions>=10.0
# Markdown math rendering support (arithmatex generic mode)
# JS side is loaded via CDN (polyfill.io + MathJax), no extra Python pkg needed
# Optional: PDF export plugin (exporter: block, currently commented out in mkdocs.yml)
mkdocs-exporter

1
docs/docker/runtime.txt Normal file
View File

@@ -0,0 +1 @@
3.7

63
docs/index.md Normal file
View File

@@ -0,0 +1,63 @@
# uLib
[![DOI](https://zenodo.org/badge/36926725.svg)](https://zenodo.org/badge/latestdoi/36926725)
**uLib** is the base toolkit library for the **CMT (Cosmic Muon Tomography)** project, developed at the University of Padova and INFN Sezione di Padova, Italy.
It provides:
- **Core** object model, timers, configuration, UUID utilities.
- **Math** linear algebra (Eigen3), structured grids, voxel images, ray-tracing, image filters.
- **Python bindings** full pybind11 interface for scripting and analysis workflows.
- Optional **CUDA** acceleration for voxel filtering (transparent RAM ↔ VRAM management).
---
## Quick Start
=== "Users (pip / poetry)"
```bash
# Activate your conda/micromamba environment first
micromamba activate mutom
poetry install # CPU build
USE_CUDA=ON poetry install # GPU build
```
=== "Developers (CMake)"
```bash
conan install . --output-folder=build --build=missing
cmake --preset conan-release
cmake --build build --target uLib_python -j$(nproc)
export PYTHONPATH="$(pwd)/build/src/Python:$(pwd)/src/Python"
```
Then in Python:
```python
import uLib
# Core
timer = uLib.Core.Timer()
timer.Start()
# Math
grid = uLib.Math.StructuredGrid([10, 10, 10])
grid.SetSpacing([1.0, 1.0, 1.0])
img = uLib.Math.VoxImage([10, 10, 10])
img.SetValue(0, 3.14)
print(img.GetValue(0))
```
---
## Documentation Sections
| Section | Description |
|---|---|
| [Python Installation](python/installation.md) | Environment setup, user install, developer build |
| [Python API Usage](python/usage.md) | Full API reference with examples |
| [Python Developer Guide](python/developer_guide.md) | Adding bindings, running tests, build details |
| [C++ Build Usage & CUDA](usage/usage.md) | CMake build, CUDA configuration |

View File

@@ -0,0 +1,179 @@
# Developer Guide Python Bindings
This guide is aimed at contributors who want to extend or modify the Python bindings for `uLib`.
---
## Repository Layout
```
ulib/
├── src/
│ └── Python/
│ ├── module.cpp # pybind11 module entry point
│ ├── core_bindings.cpp # uLib::Core bindings
│ ├── math_bindings.cpp # uLib::Math bindings
│ ├── math_filters_bindings.cpp# VoxImageFilter bindings
│ ├── CMakeLists.txt # builds uLib_python shared lib
│ ├── testing/ # Python unit tests
│ │ ├── pybind_test.py
│ │ ├── core_pybind_test.py
│ │ ├── math_pybind_test.py
│ │ └── math_filters_test.py
│ └── uLib/ # Python package (uLib_python.so lands here)
│ └── __init__.py
├── build_python.py # poetry build hook (calls CMake)
├── pyproject.toml # poetry metadata
└── condaenv.yml # conda/micromamba environment
```
---
## Adding a New Binding
All bindings live in the four source files listed above. The module entry point `module.cpp` calls `init_core()`, `init_math()`, and `init_math_filters()` in order.
### 1. Pick (or create) the right binding file
| C++ header location | Binding file |
|---|---|
| `src/Core/` | `core_bindings.cpp` |
| `src/Math/` (geometry, grids, VoxImage) | `math_bindings.cpp` |
| `src/Math/VoxImageFilter*.hpp` | `math_filters_bindings.cpp` |
### 2. Add the `#include` directive
```cpp
// math_bindings.cpp
#include "Math/MyNewClass.h"
```
### 3. Write the pybind11 binding inside the appropriate `init_*` function
```cpp
void init_math(py::module_ &m) {
// ... existing bindings ...
py::class_<MyNewClass>(m, "MyNewClass")
.def(py::init<>())
.def("MyMethod", &MyNewClass::MyMethod)
.def("AnotherMethod", &MyNewClass::AnotherMethod,
py::arg("x"), py::arg("y") = 0.0f);
}
```
### 4. Rebuild only the Python target
```bash
cmake --build build --target uLib_python -j$(nproc)
```
### 5. Write a Python test
Add a new test class to the relevant test file (or create a new one under `src/Python/testing/`):
```python
# src/Python/testing/math_pybind_test.py
class TestMyNewClass(unittest.TestCase):
def test_basic(self):
obj = uLib.Math.MyNewClass()
result = obj.MyMethod()
self.assertAlmostEqual(result, expected_value)
```
Register the test in `src/Python/CMakeLists.txt` if you add a new file:
```cmake
add_test(NAME pybind_my_new
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/testing/my_new_test.py)
set_tests_properties(pybind_my_new PROPERTIES
ENVIRONMENT "PYTHONPATH=$<TARGET_FILE_DIR:uLib_python>:${PROJECT_SOURCE_DIR}/src/Python")
```
---
## Build System Details
### CMakeLists.txt (`src/Python/`)
`pybind11_add_module` compiles the shared library `uLib_python` and links it against the C++ static/shared libraries `uLibCore` and `uLibMath`. The install target copies the `.so` into the standard library directory.
```cmake
pybind11_add_module(uLib_python
module.cpp core_bindings.cpp math_bindings.cpp math_filters_bindings.cpp)
target_link_libraries(uLib_python PRIVATE uLibCore uLibMath)
```
### poetry / build_python.py
`pyproject.toml` declares `build_python.py` as the custom build hook. When `poetry install` or `poetry build` is invoked it:
1. Calls `cmake <root> -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=<pkg_dir> ...` in `build_python/`.
2. Builds only the `uLib_python` target.
3. The resulting `.so` is placed inside `src/Python/uLib/` so it is picked up by Poetry as a package data file.
The `USE_CUDA` environment variable gates CUDA support at build time:
```bash
USE_CUDA=ON poetry install # with CUDA
USE_CUDA=OFF poetry install # CPU only (default)
```
---
## Running All Tests
```bash
# From the repository root, with PYTHONPATH set:
export PYTHONPATH="$(pwd)/build/src/Python:$(pwd)/src/Python"
python -m pytest src/Python/testing/ -v
```
Or through CMake's test runner (after building the full project):
```bash
cd build
ctest --output-on-failure -R pybind
```
Expected output (all passing):
```
Start 1: pybind_general
1/4 Test #1: pybind_general ............. Passed
Start 2: pybind_core
2/4 Test #2: pybind_core ................ Passed
Start 3: pybind_math
3/4 Test #3: pybind_math ................ Passed
Start 4: pybind_math_filters
4/4 Test #4: pybind_math_filters ........ Passed
```
---
## Memory Management Notes
`uLib::Vector<T>` has explicit GPU memory management. When wrapping methods that return references to internal data, use `py::return_value_policy::reference_internal` to avoid dangling references:
```cpp
.def("Data", &VoxImage<Voxel>::Data,
py::return_value_policy::reference_internal)
```
For objects held by `std::unique_ptr` without Python-side deletion, use `py::nodelete`:
```cpp
py::class_<Abstract::VoxImageFilter,
std::unique_ptr<Abstract::VoxImageFilter, py::nodelete>>(m, "AbstractVoxImageFilter")
```
---
## Useful References
- [pybind11 documentation](https://pybind11.readthedocs.io)
- [pybind11 STL containers](https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html)
- [pybind11 Eigen integration](https://pybind11.readthedocs.io/en/stable/advanced/cast/eigen.html)
- [CMake pybind11 integration](https://pybind11.readthedocs.io/en/stable/compiling.html)

146
docs/python/installation.md Normal file
View File

@@ -0,0 +1,146 @@
# Python Installation
The `uLib` Python package exposes the Core and Math C++ libraries via [pybind11](https://pybind11.readthedocs.io) bindings. There are two ways to install it: as an **end user** (pre-built wheel / pip) or as a **developer** (editable build from source).
---
## Prerequisites
`uLib` depends on native C++ libraries that must be compiled. Ensure the following are available in your environment before installing:
| Dependency | Minimum version | Notes |
|---|---|---|
| Python | 3.9 | |
| CMake | 3.12 | |
| pybind11 | 2.6.0 | |
| Conan | 2.x | for Eigen3 / Boost |
| micromamba / conda | any | recommended provides ROOT, VTK |
### Creating the `mutom` Conda/Micromamba Environment
A ready-to-use environment definition is provided as `condaenv.yml` at the repository root.
=== "Micromamba"
```bash
micromamba env create -f condaenv.yml
micromamba activate mutom
```
=== "Conda"
```bash
conda env create -f condaenv.yml
conda activate mutom
```
The environment installs CMake, Conan, ROOT, VTK, and the compiler toolchain.
> **CUDA (optional)**
> If you want GPU-accelerated voxel filtering, you also need NVCC inside the environment:
> ```bash
> micromamba install cuda-nvcc -c conda-forge
> ```
---
## User Installation (wheel / pip)
Once the native dependencies are present in your environment, install the package with Poetry or pip:
```bash
# Activate your environment first
micromamba activate mutom
# Build and install (CUDA disabled by default)
poetry install
# Build and install with CUDA support
USE_CUDA=ON poetry install
```
After installation the module is importable from anywhere in the environment:
```python
import uLib
print(dir(uLib.Core))
print(dir(uLib.Math))
```
---
## Developer Installation (editable / in-tree build)
For development you typically want to skip the packaging layer and work directly against the CMake build tree.
### Step 1 Install Conan dependencies
```bash
conan profile detect # first time only
conan install . --output-folder=build --build=missing
```
### Step 2 Configure and build
```bash
# Standard release build
cmake --preset conan-release
# …or manually
cmake -B build \
-DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_CUDA=OFF # set to ON when a GPU is available
cmake --build build --target uLib_python -j$(nproc)
```
The shared library (`uLib_python*.so`) is written to `build/src/Python/`.
### Step 3 Make the module importable
Point `PYTHONPATH` at the build output **and** the Python source directory (the latter carries the `uLib/__init__.py` that stitches sub-modules together):
```bash
export PYTHONPATH="$(pwd)/build/src/Python:$(pwd)/src/Python:$PYTHONPATH"
python -c "import uLib; print(uLib.__version__)"
```
Or, for a one-shot check:
```bash
PYTHONPATH="build/src/Python:src/Python" python src/Python/testing/pybind_test.py
```
### Step 4 Run the tests
CMake registers the Python tests alongside the C++ ones; use `ctest` from the build directory:
```bash
cd build
ctest --output-on-failure -R pybind
```
Individual test scripts can also be run directly once `PYTHONPATH` is set:
```bash
python src/Python/testing/core_pybind_test.py
python src/Python/testing/math_pybind_test.py
python src/Python/testing/math_filters_test.py
```
---
## Verifying the Installation
```python
import uLib
# Core module
obj = uLib.Core.Object()
timer = uLib.Core.Timer()
timer.Start()
elapsed = timer.StopWatch() # float, seconds
# Math module
v3 = uLib.Math.Vector3f([1.0, 0.0, 0.0])
print(v3[0]) # 1.0
```

373
docs/python/usage.md Normal file
View File

@@ -0,0 +1,373 @@
# Python API Usage
The `uLib` Python package is split into two sub-modules mirroring the C++ library:
| Sub-module | Contents |
|---|---|
| `uLib.Core` | Low-level utilities: `Object`, `Timer`, `Options`, `TypeRegister` |
| `uLib.Math` | Geometry, grids, voxel images, ray-tracing, image filters |
```python
import uLib
# Sub-modules are accessible as attributes
uLib.Core # core utilities
uLib.Math # mathematical structures
```
---
## uLib.Core
### Object
Base class for uLib objects; exposed to Python for type-hierarchy purposes.
```python
obj = uLib.Core.Object()
copy = obj.DeepCopy()
```
### Timer
Precision wall-clock timer.
```python
import time
timer = uLib.Core.Timer()
timer.Start()
time.sleep(0.5)
elapsed = timer.StopWatch() # returns elapsed seconds as float
print(f"Elapsed: {elapsed:.3f} s")
```
### Options
Wraps Boost.ProgramOptions for INI-style configuration files.
```python
opt = uLib.Core.Options("My Program")
opt.parse_config_file("config.ini") # load settings
n = opt.count("my_key") # check if key exists
opt.save_config_file("out.ini")
```
---
## uLib.Math Linear Algebra
The math module exposes Eigen3 vectors and matrices as well-typed Python objects with NumPy interoperability.
### Fixed-size Vectors
```python
import numpy as np
import uLib
# Construct from list
v3 = uLib.Math.Vector3f([1.0, 2.0, 3.0])
print(v3[0], v3[1], v3[2]) # 1.0 2.0 3.0
# Construct from NumPy array
arr = np.array([4.0, 5.0, 6.0], dtype=np.float32)
v3b = uLib.Math.Vector3f(arr)
# Zero-initialise
v4d = uLib.Math.Vector4d() # all zeros
# Available types
# Vector1f / 2f / 3f / 4f (float32)
# Vector1d / 2d / 3d / 4d (float64)
# Vector1i / 2i / 3i / 4i (int32)
```
### Fixed-size Matrices
```python
# 2-by-2 float matrix
m2f = uLib.Math.Matrix2f()
m2f[0, 0] = 1; m2f[0, 1] = 2
m2f[1, 0] = 3; m2f[1, 1] = 4
# From list (row-major)
m4f = uLib.Math.Matrix4f([1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1])
# From NumPy (2-D array)
mat = np.eye(3, dtype=np.float32)
m3f = uLib.Math.Matrix3f(mat)
# Dynamic matrices
mXf = uLib.Math.MatrixXf(4, 4) # 4×4 float, zeros
```
### Homogeneous Types
```python
# HPoint3f a 3-D point in homogeneous coordinates (w = 1)
p = uLib.Math.HPoint3f(1.0, 2.0, 3.0)
# HVector3f a free vector (w = 0)
v = uLib.Math.HVector3f(0.0, 1.0, 0.0)
# HLine3f a parametric ray
line = uLib.Math.HLine3f()
line.origin = uLib.Math.HPoint3f(0, 0, 0)
line.direction = uLib.Math.HVector3f(0, 0, 1)
```
---
## uLib.Math Transforms and Geometry
### AffineTransform
A rigid-body / affine transform stored as a 4×4 matrix.
```python
tf = uLib.Math.AffineTransform()
tf.SetPosition([1.0, 0.0, 0.0]) # translate
tf.Translate([0.0, 1.0, 0.0]) # cumulative translate
tf.Scale([2.0, 2.0, 2.0]) # uniform scale
tf.Rotate(uLib.Math.Vector3f([0, 0, 3.14159])) # Euler angles (rad)
mat4 = tf.GetWorldMatrix() # 4×4 matrix
pos = tf.GetPosition() # Vector3f
```
### Geometry
Inherits `AffineTransform`; converts points between world and local frames.
```python
geo = uLib.Math.Geometry()
geo.SetPosition([1.0, 1.0, 1.0])
world_pt = uLib.Math.Vector4f([2.0, 3.0, 2.0, 1.0])
local_pt = geo.GetLocalPoint(world_pt)
back = geo.GetWorldPoint(local_pt)
# back ≈ [2, 3, 2, 1]
```
### ContainerBox
An axis-aligned bounding box with an associated transform.
```python
box = uLib.Math.ContainerBox()
box.SetOrigin([-1.0, -1.0, -1.0])
box.SetSize([2.0, 2.0, 2.0])
print(box.GetSize()) # [2, 2, 2]
```
---
## uLib.Math Structured Grids
### StructuredGrid (3-D)
A 3-D voxel grid (origin, spacing, and integer dimensions).
```python
dims = uLib.Math.Vector3i([10, 10, 10])
grid = uLib.Math.StructuredGrid(dims)
grid.SetSpacing([1.0, 1.0, 1.0])
grid.SetOrigin([0.0, 0.0, 0.0])
print(grid.GetSpacing()) # [1, 1, 1]
print(grid.IsInsideBounds([5, 5, 5, 1])) # True
idx = grid.Find([2.5, 2.5, 2.5]) # returns grid cell index
```
### Structured2DGrid / Structured4DGrid
```python
grid2d = uLib.Math.Structured2DGrid()
grid2d.SetDims([100, 100])
grid2d.SetPhysicalSpace([0, 0], [1, 1])
print(grid2d.GetSpacing())
```
---
## uLib.Math VoxImage
`VoxImage` is a 3-D voxel volume where each cell stores a `Voxel` ( `.Value` + `.Count`).
```python
dims = uLib.Math.Vector3i([20, 20, 20])
img = uLib.Math.VoxImage(dims)
img.SetSpacing([0.5, 0.5, 0.5])
# Access by linear index
img.SetValue(0, 42.0)
print(img.GetValue(0)) # 42.0
# Access by 3-D index
img.SetValue(uLib.Math.Vector3i([1, 1, 1]), 7.5)
print(img.GetValue(uLib.Math.Vector3i([1, 1, 1]))) # 7.5
# Clipping / masking helpers
cropped = img.clipImage(uLib.Math.Vector3i([2, 2, 2]),
uLib.Math.Vector3i([18, 18, 18]))
masked = img.maskImage(0.0, 100.0, 0.0) # mask outside [0, 100]
# I/O
img.ExportToVti("output.vti")
img.ImportFromVti("output.vti")
```
### Voxel (element type)
```python
vox = uLib.Math.Voxel()
vox.Value = 1.5
vox.Count = 3
data = img.Data() # returns the underlying Vector_Voxel
vox0 = data[0]
print(vox0.Value, vox0.Count)
```
---
## uLib.Math VoxRaytracer
Performs ray-tracing through a `StructuredGrid` and returns per-voxel chord lengths.
```python
import numpy as np
import uLib
grid = uLib.Math.StructuredGrid([10, 10, 10])
grid.SetSpacing([1.0, 1.0, 1.0])
grid.SetOrigin([0.0, 0.0, 0.0])
rt = uLib.Math.VoxRaytracer(grid)
# Trace a ray between two homogeneous points (x, y, z, w=1)
p1 = np.array([0.5, 0.5, -1.0, 1.0], dtype=np.float32)
p2 = np.array([0.5, 0.5, 11.0, 1.0], dtype=np.float32)
result = rt.TraceBetweenPoints(p1, p2)
print("Voxels crossed:", result.Count())
print("Total length :", result.TotalLength())
elements = result.Data()
for i in range(result.Count()):
print(f" vox_id={elements[i].vox_id} L={elements[i].L:.4f}")
```
---
## uLib.Math Image Filters
All filters share the same interface: construct with a kernel size, attach a `VoxImage`, optionally set parameters, then call `.Run()`.
```python
import uLib
dims = uLib.Math.Vector3i([10, 10, 10])
img = uLib.Math.VoxImage(dims)
for i in range(10**3):
img.SetValue(i, float(i))
kernel_dims = uLib.Math.Vector3i([3, 3, 3])
```
### Linear (Gaussian / Box) Filter
```python
filt = uLib.Math.VoxFilterAlgorithmLinear(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27) # uniform box kernel, length = product of dims
filt.Run()
```
### ABTrim Filter
Applies alpha-beta trimming to remove outliers before averaging.
```python
filt = uLib.Math.VoxFilterAlgorithmAbtrim(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)
filt.SetABTrim(2, 2) # trim 2 low and 2 high values
filt.Run()
```
### Bilateral Filter
Edge-preserving smoothing controlled by a spatial sigma (from the kernel shape) and an intensity sigma.
```python
filt = uLib.Math.VoxFilterAlgorithmBilateral(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)
filt.SetIntensitySigma(0.3)
filt.Run()
```
### Threshold Filter
Zeros voxels below a threshold.
```python
filt = uLib.Math.VoxFilterAlgorithmThreshold(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)
filt.SetThreshold(0.5)
filt.Run()
```
### Median Filter
```python
filt = uLib.Math.VoxFilterAlgorithmMedian(kernel_dims)
filt.SetImage(img)
filt.SetKernelNumericXZY([1.0] * 27)
filt.Run()
```
---
## uLib.Math Accumulators
Accumulators collect scalar samples and return a summary statistic.
```python
# Arithmetic mean
acc = uLib.Math.Accumulator_Mean_f()
acc(10.0)
acc(20.0)
mean = acc() # 15.0
# Alpha-beta trimmed mean
acc2 = uLib.Math.Accumulator_ABTrim_f()
acc2.SetABTrim(0.1, 0.1) # trim bottom 10 % and top 10 %
acc2 += 1.0
acc2 += 9999.0 # outlier
acc2 += 5.0
result = acc2() # trimmed mean ≈ 3.0
```
---
## Dynamic Vectors (`uLib.Math.Vector_*`)
Typed dynamic arrays backed by `uLib::Vector<T>` with optional CUDA memory management.
```python
# Integer vector
vi = uLib.Math.Vector_i()
vi.append(1); vi.append(2); vi.append(3)
print(len(vi), vi[0])
# Float vector with CUDA management
vf = uLib.Math.Vector_f()
vf.append(1.5)
vf.MoveToVRAM() # copy to GPU (no-op when CUDA is absent)
vf.MoveToRAM() # copy back to CPU
# Other types: Vector_ui, Vector_l, Vector_ul, Vector_d
# Compound element types: Vector_Vector3f, Vector_Vector4f, Vector_Voxel …
```

60
docs/usage/usage.md Normal file
View File

@@ -0,0 +1,60 @@
# Usage and Installation Guide
## Requirements
### Compiling with CUDA Support
The library supports running VoxImage filtering operations directly on CUDA cores via transparent RAM/VRAM memory transfers.
By default, the `CMakeLists.txt` build system sets `USE_CUDA=ON` and will attempt to locate `nvcc` and the NVIDIA CUDA Toolkit. If the toolkit is missing, `CMake` will fail unless you explicitly configure the project with `-DUSE_CUDA=OFF`.
### 1. Installing CUDA Environment via Micromamba
If you are developing inside an isolated Conda/Micromamba environment (e.g., `mutom`), you can inject the CUDA compilers directly into your environment rather than relying on global system dependencies:
```bash
# Add the conda-forge channel if not already available
micromamba config append channels conda-forge
# Install nvcc and the necessary CUDA toolkit components
micromamba install cuda-nvcc
```
Verify your installation:
```bash
nvcc --version
```
### 2. Building the Project
Configure and compile the project using standard CMake flows:
```bash
mkdir -p build && cd build
# Configure CMake
# (Optional) Explicitly toggle CUDA: cmake -DUSE_CUDA=ON ..
cmake ..
# Compile the project and tests
make -j $(nproc)
```
### 3. Validating CUDA Support
You can verify that the CUDA kernels are launching correctly and allocating device memory through `DataAllocator` by running the mathematical unit tests.
```bash
# From the build directory
./src/Math/testing/VoxImageFilterTest
# Output should show:
# "Data correctly stayed in VRAM after CUDA execution!"
```
## How It Works Under The Hood
The `DataAllocator<T>` container automatically wraps memory allocations to transparently map to CPU RAM, or GPU VRAM. Standard iteration automatically pulls data backwards using implicit `MoveToRAM()` calls.
Filters using `#ifdef USE_CUDA` explicitly dictate `<buffer>.MoveToVRAM()` allocating directly on device bounds seamlessly. Fallbacks to Host compute iterations handle themselves automatically. Chaining specific filters together safely chains continuous VRAM operations avoiding costly Host copies in between iterations.

561
mkdocs.yml Normal file
View File

@@ -0,0 +1,561 @@
# site_name: uLib Documentation
# site_description: CMT Cosmic Muon Tomography uLib toolkit
# site_author: Andrea Rigoni Garola
# repo_url: https://github.com/cmt/ulib
# docs_dir: docs
# +--------------------------------------------------------------------------------------------------------+
# | |
# | This is the main file used by MkDocs to build the pages. |
# | It contains a lot of information and settings for you to read and use. |
# | Comments may contain "Read More" URLs to more in-depth documentation about the option for you to read. |
# | |
# | You can check out https://www.mkdocs.org/user-guide/configuration/ for a more detailed explanation of |
# | all the options MkDocs offers by default. |
# | |
# +------------------------------------------------- NOTE -------------------------------------------------+
# | |
# | Some of the options listed here are only available through the usage of Material for MkDocs. |
# | Those options will usually have a link to the docs of this Theme and also mention "Material" as name. |
# | The actual name of the theme is "Material for MkDocs" and "Material" is used for simplicity reasons. |
# | |
# +--------------------------------------------------------------------------------------------------------+
# +--------------------------------------------------------------------------------------------------------+
# | |
# | Main Page Settings for MkDocs. |
# | Those settings are site name, site description, Site author and also Site URL (Canonical URL) |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#site_name |
# | - https://www.mkdocs.org/user-guide/configuration/#site_description |
# | - https://www.mkdocs.org/user-guide/configuration/#site_author |
# | - https://www.mkdocs.org/user-guide/configuration/#site_url |
# | |
# +--------------------------------------------------------------------------------------------------------+
site_name: OpenCMT uLib Documentation
site_url: https://docs.mildstone.org/uLib/ # <--- project subfolder
use_directory_urls: true
site_description: 'Documentation for OpenCMT uLib'
site_author: 'Andrea Rigoni Garola'
# +--------------------------------------------------------------------------------------------------------+
# | |
# | This setting allows you to define your own Copyright notice. |
# | The text is treated as HTML code so you can use things like <a> tags or &copy; to display the |
# | Copyright icon. |
# | |
# | Where or IF the Copyright is displayed depends on the theme you use. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#copyright |
# | |
# +--------------------------------------------------------------------------------------------------------+
copyright: |
&copy; Author
# +--------------------------------------------------------------------------------------------------------+
# | |
# | The base folder to use. |
# | Any Markdown files you put into this folder will be turned into a static HTML page once you build or |
# | publish your page. |
# | |
# | It is also used as the base directory for other settings like the "extra_css" or "extra_javascript" |
# | option. |
# | |
# +--------------------------------------------------------------------------------------------------------+
docs_dir: docs/
# +--------------------------------------------------------------------------------------------------------+
# | |
# | These options allow to define a Repository to link to. |
# | The result will, depending on the theme, be a link somewhere shown on the page that links to the |
# | Repository with the specified repo_name. |
# | |
# | This will also enable a "edit" button on the page itself that allows the direct editing of the page. |
# | You can disable this by setting "edit_uri" to an empty String. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#repo_name |
# | - https://www.mkdocs.org/user-guide/configuration/#repo_url |
# | - https://www.mkdocs.org/user-guide/configuration/#edit_uri |
# | |
# +--------------------------------------------------------------------------------------------------------+
repo_name: OpenCMT/uLib
repo_url: https://gitea.mildstone.org/OpenCMT/uLib.git
#edit_uri: tree/master/docs # Uncomment to define a different URI/URL for the "edit" option
# +--------------------------------------------------------------------------------------------------------+
# | |
# | The "nav" option is where you define the navigation to show in MkDocs. |
# | |
# | Depending on the theme you use will the resulting Navigation look different. |
# | |
# | You can set different types of navigations. Either just the path, the path with a separate title or |
# | an external URL. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#documentation-layout |
# | |
# +--------------------------------------------------------------------------------------------------------+
nav:
- Home: index.md
- Python:
- Installation: python/installation.md
- API Usage: python/usage.md
- Developer Guide: python/developer_guide.md
- C++ Build:
- Usage & CUDA: usage/usage.md
# +--------------------------------------------------------------------------------------------------------+
# | |
# | The "theme" section allows you to define what theme to use. |
# | It is also used for theme-specific options, but also for advanced stuff such as theme-extensions, if |
# | the theme actually supports it. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#theme |
# | |
# +--------------------------------------------------------------------------------------------------------+
theme:
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "name" option is where you define the theme to use. |
# | |
# | Note that not all themes are included by default and will require you to install them first. |
# | The Material theme is one of them. See the "Read More" link for instructions on how to install it. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/getting-started/ |
# | |
# +------------------------------------------------------------------------------------------------------+
name: 'material'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The Material theme allows "theme-extsnions", meaning that you can override parts of it by either |
# | overriding a particular file, or only parts (blocks) of it. |
# | |
# | If you want to override parts of Material, uncomment the "custom_dir" option below and set the |
# | folder (relative to the mkdocs.yml file) where your theme extensions will be located at. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#custom_dir |
# | - https://squidfunk.github.io/mkdocs-material/customization/#extending-the-theme |
# | |
# +------------------------------------------------------------------------------------------------------+
#custom_dir: 'theme'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "favicon" option allows you to set your own image/icon to use in the browser-tab. |
# | |
# | Pretty much all image types are supported, but it's recommended to use a PNG, SVG or ICO image for |
# | the favicon. |
# | |
# | The directory is relative to the "docs_dir". |
# | |
# | Example: Having a favicon.png in docs/assets/images will result in the "favicon" setting showing |
# | 'assets/images/favicon.png' |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#favicon |
# | |
# +------------------------------------------------------------------------------------------------------+
#favicon: 'assets/images/favicon.png'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "palette" section is a Material option and allows you to define specific style options such as |
# | Color-Scheme, and primary and secondary Color. |
# | |
# | You can also define multiple palettes that can have different Color Schemses and primary and/or |
# | secondary Colors. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/ |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-palette-toggle |
# | |
# +------------------------------------------------------------------------------------------------------+
palette:
# Palette toggle for light mode
- media: "(prefers-color-scheme: light)"
scheme: default
primary: 'indigo'
accent: 'indigo'
toggle:
icon: material/brightness-7
name: Switch to dark mode
# Palette toggle for dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: 'indigo'
accent: 'indigo'
toggle:
icon: material/brightness-4
name: Switch to light mode
# +------------------------------------------------------------------------------------------------------+
# | |
# | With the "font" option can you set a different font to use. |
# | |
# | Material supports all Google fonts, but you can also define your own ones if you choose so. |
# | |
# | The "text" option is used for the regular font while "code" is used for code blocks, inline code and |
# | similar. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-fonts/ |
# | |
# +------------------------------------------------------------------------------------------------------+
#font:
# text: 'Roboto'
# code: 'Roboto Mono'
# +------------------------------------------------------------------------------------------------------+
# | |
# | Material suppors more than 40 different languages which you can set using the "language" option |
# | below. |
# | |
# | The default language is "en" (English). |
# | |
# | You can also enable/set a "selector" to allow switching between languages. |
# | See the "alternate" option in the "extra" section below for more information on this topic. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-language/ |
# | |
# +------------------------------------------------------------------------------------------------------+
#language: 'en'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "direction" option is commonly used together with the "language" option. |
# | |
# | It allows you to change the text direction from the default left-to-right (ltr) to right-to-left |
# | (rtl) which is used in certain languages. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-language/#directionality |
# | |
# +------------------------------------------------------------------------------------------------------+
#direction: 'ltr'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "features" option allows you to enable specific features of Material, by adding them to the |
# | list. |
# | |
# | Features are in the format <category>.<name>. As an example, the feature to enable tabs is called |
# | navigation.tabs. |
# | |
# | The list below contains all known features of Material. |
# | |
# | Features marked with a * are currently Insiders-only. (Last update: 11th December 2021) |
# | https://squidfunk.github.io/mkdocs-material/insiders/ |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/setting-up-navigation/ |
# | |
# +------------------------------------------------------------------------------------------------------+
features:
# Announce
#
#- announce.dismiss # Adds a "X" button to dismiss a news banner/mark it as read.*
# Header
#
#- header.autohide # Hide header when user scrolls past a specific point.
# Navigation:
#
#- navigation.expand # Expand all collapsable sections.
#- navigation.instant # Instant loading pages.
#- navigation.indexes # Attach pages directly to Sections. Incompatible with "toc.integrate"
#- navigation.sections # Render top sections as groups.
- navigation.tabs # Render top sections as tabs at the top.
#- navigation.tabs.sticky # Tabs won't disappear when scrolling down. Requires "navigation.tabs".
#- navigation.top # Adds a "Back to top" that is shown when scrolling up.
#- navigation.tracking # Updates the url with highlighted section anchor.
# Search
#
#- search.highlight # Search will highlight the searched word(s) on the page.*
#- search.share # Adds an option to share a search query link.*
#- search.suggest # Search will suggest the likeliest completion for a word.*
# Table of Contents
#
#- toc.integrate # Include the TOC sections in the left navugation.
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "icon" section allows you to define a icon to use for the logo and/or repository. |
# | |
# | To use already available icons will you need to set the right path for it, depending on which you |
# | want to use. |
# | |
# | Available icons: |
# | - FontAwesome |
# | - Brands: fontawesome/brands/... (https://fontawesome.com/icons?d=gallery&p=2&s=brands&m=free) |
# | - Regular: fontawesome/regular/... (https://fontawesome.com/icons?d=gallery&p=2&s=regular&m=free) |
# | - Solid: fontawesome/solid/... (https://fontawesome.com/icons?d=gallery&p=2&s=solid&m=free) |
# | |
# | - Material Design Icons: material/... (https://materialdesignicons.com/) |
# | |
# | - Octicons: octicons/... (https://primer.style/octicons/) |
# | |
# | You can also define your own Image for the logo. To do that, remove the "logo" option from "icon" |
# | instead add a "logo" option on the same level as the "icon" one, where you then set the path |
# | (relative to the "docs_dir") to the icon to use. Supported are all images types, including SVG. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#logo |
# | |
# +------------------------------------------------------------------------------------------------------+
icon:
logo: 'material/library'
repo: 'material/library'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "admonition" option allows you to set a different icon for each admonition type. |
# | |
# | This is currently a Insiders-only feature. (Last update: 7th October 2021) |
# | https://squidfunk.github.io/mkdocs-material/insiders/ |
# | |
# | Supported are all bundled icons: |
# | - FontAwesome |
# | - Brands: fontawesome/brands/... (https://fontawesome.com/icons?d=gallery&p=2&s=brands&m=free) |
# | - Regular: fontawesome/regular/... (https://fontawesome.com/icons?d=gallery&p=2&s=regular&m=free) |
# | - Solid: fontawesome/solid/... (https://fontawesome.com/icons?d=gallery&p=2&s=solid&m=free) |
# | |
# | - Material Design Icons: material/... (https://materialdesignicons.com/) |
# | |
# | - Octicons: octicons/... (https://primer.style/octicons/) |
# | |
# | You can also create and use your own icons. See the documentation for more information. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/reference/admonitions/#changing-the-icons |
# | |
# +------------------------------------------------------------------------------------------------------+
#admonition:
# note: 'octicons/tag-16'
# abstract: 'octicons/checklist-16'
# info: 'octicons/info-16'
# tip: 'octicons/squirrel-16'
# success: 'octicons/check-16'
# question: 'octicons/question-16'
# warning: 'octicons/alert-16'
# failure: 'octicons/x-circle-16'
# danger: 'octicons/zap-16'
# bug: 'octicons/bug-16'
# example: 'octicons/beaker-16'
# quote: 'octicons/quote-16'
# +--------------------------------------------------------------------------------------------------------+
# | |
# | With the "extra_css" option can you add your own (S)CSS files to enhance the documentation. |
# | |
# | The path to the file is relative to the "docs_dir". |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#extra_css |
# | |
# +--------------------------------------------------------------------------------------------------------+
extra_css:
- assets/css/extra.css
# +--------------------------------------------------------------------------------------------------------+
# | |
# | Similar to the "extra_css" option does the "extra_javascript" option allow you to set custom JS files |
# | to add extra featurues. |
# | |
# | The path to the file is relative to the "docs_dir". |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#extra_javascript |
# | |
# +--------------------------------------------------------------------------------------------------------+
extra_javascript:
- https://polyfill.io/v3/polyfill.min.js?features=es6
- https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
# +--------------------------------------------------------------------------------------------------------+
# | |
# | The "extra" section contains pretty much anything you want, as long as it is a valid key-value pair. |
# | |
# | Material uses this section for different custom settings that wouldn't fit in the theme section. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#extra |
# | |
# +--------------------------------------------------------------------------------------------------------+
extra:
# +------------------------------------------------------------------------------------------------------+
# | |
# | The social section allows you to set a list of entries which would be displayed in the footer of the |
# | page. |
# | |
# | Each entry has the exact same options: |
# | - icon: Path to the SVG icon to use. See "icon" section for available icon sets. |
# | - link: URL to which the icon should link. |
# | - name: Optional Name that would be displayed as title on hover. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/setting-up-the-footer/#social-links |
# | |
# +------------------------------------------------------------------------------------------------------+
social:
- icon: 'fontawesome/brands/github'
link: 'https://github.com/Andre601/mkdocs-template'
# +------------------------------------------------------------------------------------------------------+
# | |
# | Allows you to hide the "Made with Material for MkDocs" text in the footer of the pages by setting |
# | this to "true". |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/setting-up-the-footer/#generator-notice |
# | |
# +------------------------------------------------------------------------------------------------------+
#generator: true
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "manifest" option allows you to define a .manifest file to use. |
# | |
# | A .manifest file makes the doc act like a web-application and tells it how to behave when installed. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/reference/meta-tags/#adding-a-web-app-manifest |
# | |
# +------------------------------------------------------------------------------------------------------+
#manifest: manifest.webmanifest
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "alternate" option can be used to create a selector to switch languages. |
# | |
# | Using this requires you to create a specific, more complicated MkDocs setup. |
# | |
# | A Setup Guide for multi-language docs can be found here: |
# | https://github.com/squidfunk/mkdocs-material/discussions/2346 |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-language/#site-language-selector |
# | |
# +------------------------------------------------------------------------------------------------------+
#alternate:
# +--------------------------------------------------------------------------------------------------------+
# | |
# | MkDocs allows the usage of Markdown extensions which can do various things. |
# | |
# | Material includes the pymdownx extension which provides a lot of useful features to use. |
# | |
# | Note that some extensions may use specific settings that you need to set. |
# | Please check out the official documentation of PyMdownx for more information: |
# | https://facelessuser.github.io/pymdown-extensions/ |
# | |
# | Material already provides required CSS and JS values for the PyMdownX Extensions, which means you do |
# | not need to set them up yourself. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#markdown_extensions |
# | |
# +--------------------------------------------------------------------------------------------------------+
markdown_extensions:
- markdown.extensions.admonition:
- markdown.extensions.codehilite:
guess_lang: false
- markdown.extensions.toc:
permalink: true
- pymdownx.arithmatex:
generic: true
- attr_list
- md_in_html
- pymdownx.blocks.caption
- admonition
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.superfences
- pymdownx.tabbed:
alternate_style: true
- pymdownx.details
- attr_list
- tables
#- pymdownx.b64:
#- pymdownx.betterem:
#- pymdownx.caret:
#- pymdownx.critic:
#- pymdownx.details:
#- pymdownx.emoji:
#- pymdownx.escapeall:
#- pymdownx.extra:
#- pymdownx.extrarawhtml:
#- pymdownx.highlight:
#- pymdownx.inlinehilite:
#- pymdownx.keys:
#- pymdownx.magiclink:
#- pymdownx.mark:
#- pymdownx.pathconverter:
#- pymdownx.progressbar:
#- pymdownx.smartsymbols:
#- pymdownx.snippets:
#- pymdownx.striphtml:
#- pymdownx.superfences:
#- pymdownx.tabbed:
#- pymdownx.tasklist:
#- pymdownx.tilde:
# - exporter:
# formats:
# pdf:
# enabled: !ENV [MKDOCS_EXPORTER_PDF, true]
# concurrency: 8
# stylesheets:
# - resources/stylesheets/pdf.scss
# covers:
# front: resources/templates/covers/front.html.j2
# back: resources/templates/covers/back.html.j2
# aggregator:
# enabled: true
# output: .well-known/site.pdf
# covers: all
# theme:
# name: material
# palette:
# - scheme: default
# primary: indigo
# accent: blue
# toggle:
# icon: material/brightness-7
# name: Switch to dark mode
# - scheme: slate
# primary: indigo
# accent: blue
# toggle:
# icon: material/brightness-4
# name: Switch to light mode
# features:
# - navigation.tabs
# - navigation.sections
# - navigation.top
# - content.code.copy
# - content.tabs.link
# plugins:
# - search
# markdown_extensions:

7
poetry.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Poetry 2.3.1 and should not be changed by hand.
package = []
[metadata]
lock-version = "2.1"
python-versions = ">=3.9"
content-hash = "db9b4c08b159b17b239e26c67ead7c37b82d9f9eb06550245ae3134c095f98f7"

15
pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[tool.poetry]
name = "uLib"
version = "0.6.0"
description = "CMT Cosmic Muon Tomography project uLib python bindings"
authors = ["Andrea Rigoni Garola <andrea.rigoni@pd.infn.it>"]
readme = "README.md"
packages = [{ include = "uLib", from = "src/Python" }]
build = "build_python.py"
[tool.poetry.dependencies]
python = ">=3.9"
[build-system]
requires = ["poetry-core>=2.0.0", "pybind11>=2.6.0", "cmake>=3.12"]
build-backend = "poetry.core.masonry.api"

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,38 @@
set(HEADERS Options.h set(HEADERS
StaticInterface.h) Archives.h
Array.h
Collection.h
DataAllocator.h
Debug.h
Export.h
Function.h
Macros.h
Mpl.h
Object.h
Options.h
Serializable.h
Signal.h
Singleton.h
SmartPointer.h
StaticInterface.h
StringReader.h
Types.h
Uuid.h
Vector.h
)
set(SOURCES Options.cpp) set(SOURCES
Archives.cpp
Debug.cpp
Object.cpp
Options.cpp
Serializable.cpp
Signal.cpp
Uuid.cpp
)
set(LIBRARIES ${Boost_PROGRAM_OPTIONS_LIBRARY}) set(LIBRARIES Boost::program_options Boost::serialization)
set(libname ${PACKAGE_LIBPREFIX}Core) set(libname ${PACKAGE_LIBPREFIX}Core)
set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} ${libname} PARENT_SCOPE) set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} ${libname} PARENT_SCOPE)
@@ -14,14 +42,20 @@ add_library(${libname} SHARED ${SOURCES})
set_target_properties(${libname} PROPERTIES set_target_properties(${libname} PROPERTIES
VERSION ${PROJECT_VERSION} VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION}) SOVERSION ${PROJECT_SOVERSION})
if(USE_CUDA)
set(LIBRARIES ${LIBRARIES} CUDA::cudart)
endif()
target_link_libraries(${libname} ${LIBRARIES}) target_link_libraries(${libname} ${LIBRARIES})
install(TARGETS ${libname} install(TARGETS ${libname}
EXPORT "${PROJECT_NAME}Targets" EXPORT "uLibTargets"
RUNTIME DESTINATION ${INSTALL_BIN_DIR} COMPONENT bin RUNTIME DESTINATION ${INSTALL_BIN_DIR} COMPONENT bin
LIBRARY DESTINATION ${INSTALL_LIB_DIR} COMPONENT lib) LIBRARY DESTINATION ${INSTALL_LIB_DIR} COMPONENT lib)
install(FILES ${HEADERS} DESTINATION ${INSTALL_INC_DIR}/Core) install(FILES ${HEADERS} DESTINATION ${INSTALL_INC_DIR}/Core)
if(BUILD_TESTING)
include(uLibTargetMacros)
add_subdirectory(testing)
endif()

260
src/Core/DataAllocator.h Normal file
View File

@@ -0,0 +1,260 @@
/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
------------------------------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
//////////////////////////////////////////////////////////////////////////////*/
#ifndef U_MATH_DATAALLOCATOR_H
#define U_MATH_DATAALLOCATOR_H
#include <algorithm>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <vector>
#ifdef USE_CUDA
#include <cuda_runtime.h>
#include <thrust/device_vector.h>
#endif
namespace uLib {
enum class MemoryDevice { RAM, VRAM };
template <typename T> class DataAllocator {
public:
DataAllocator(size_t size = 0, bool owns_objects = true)
: m_Size(size), m_RamData(nullptr), m_VramData(nullptr),
m_Device(MemoryDevice::RAM), m_OwnsObjects(owns_objects) {
if (m_Size > 0) {
if (m_OwnsObjects)
m_RamData = new T[m_Size]();
else
m_RamData = static_cast<T *>(::operator new(m_Size * sizeof(T)));
}
}
DataAllocator(const DataAllocator<T> &other)
: m_Size(other.m_Size), m_RamData(nullptr), m_VramData(nullptr),
m_Device(other.m_Device), m_OwnsObjects(other.m_OwnsObjects) {
if (m_Size > 0) {
if (other.m_RamData) {
if (m_OwnsObjects)
m_RamData = new T[m_Size];
else
m_RamData = static_cast<T *>(::operator new(m_Size * sizeof(T)));
std::memcpy(m_RamData, other.m_RamData, m_Size * sizeof(T));
}
#ifdef USE_CUDA
if (other.m_VramData) {
cudaMalloc((void **)&m_VramData, m_Size * sizeof(T));
cudaMemcpy(m_VramData, other.m_VramData, m_Size * sizeof(T),
cudaMemcpyDeviceToDevice);
}
#endif
}
}
~DataAllocator() {
if (m_RamData) {
if (m_OwnsObjects)
delete[] m_RamData;
else
::operator delete(m_RamData);
}
#ifdef USE_CUDA
if (m_VramData) {
cudaFree(m_VramData);
}
#endif
}
DataAllocator &operator=(const DataAllocator &other) {
if (this != &other) {
m_OwnsObjects = other.m_OwnsObjects;
resize(other.m_Size);
m_Device = other.m_Device;
if (other.m_RamData) {
if (!m_RamData) {
if (m_OwnsObjects)
m_RamData = new T[m_Size];
else
m_RamData = static_cast<T *>(::operator new(m_Size * sizeof(T)));
}
std::memcpy(m_RamData, other.m_RamData, m_Size * sizeof(T));
}
#ifdef USE_CUDA
if (other.m_VramData) {
if (!m_VramData)
cudaMalloc((void **)&m_VramData, m_Size * sizeof(T));
cudaMemcpy(m_VramData, other.m_VramData, m_Size * sizeof(T),
cudaMemcpyDeviceToDevice);
}
#endif
}
return *this;
}
void MoveToRAM() {
if (m_Device == MemoryDevice::RAM)
return;
if (!m_RamData && m_Size > 0) {
if (m_OwnsObjects)
m_RamData = new T[m_Size]();
else
m_RamData = static_cast<T *>(::operator new(m_Size * sizeof(T)));
}
#ifdef USE_CUDA
if (m_VramData && m_Size > 0) {
cudaMemcpy(m_RamData, m_VramData, m_Size * sizeof(T),
cudaMemcpyDeviceToHost);
}
#endif
m_Device = MemoryDevice::RAM;
}
void MoveToVRAM() {
if (m_Device == MemoryDevice::VRAM)
return;
#ifdef USE_CUDA
if (!m_VramData && m_Size > 0) {
cudaMalloc((void **)&m_VramData, m_Size * sizeof(T));
}
if (m_RamData && m_Size > 0) {
cudaMemcpy(m_VramData, m_RamData, m_Size * sizeof(T),
cudaMemcpyHostToDevice);
}
#endif
m_Device = MemoryDevice::VRAM;
}
void resize(size_t size) {
if (m_Size == size)
return;
T *newRam = nullptr;
T *newVram = nullptr;
if (size > 0) {
if (m_OwnsObjects)
newRam = new T[size]();
else
newRam = static_cast<T *>(::operator new(size * sizeof(T)));
if (m_RamData) {
std::memcpy(newRam, m_RamData, std::min(m_Size, size) * sizeof(T));
}
#ifdef USE_CUDA
cudaMalloc((void **)&newVram, size * sizeof(T));
if (m_VramData) {
cudaMemcpy(newVram, m_VramData, std::min(m_Size, size) * sizeof(T),
cudaMemcpyDeviceToDevice);
}
#endif
}
if (m_RamData) {
if (m_OwnsObjects)
delete[] m_RamData;
else
::operator delete(m_RamData);
}
#ifdef USE_CUDA
if (m_VramData)
cudaFree(m_VramData);
#endif
m_Size = size;
m_RamData = newRam;
m_VramData = newVram;
}
size_t size() const { return m_Size; }
T &at(size_t index) {
MoveToRAM();
if (index >= m_Size)
throw std::out_of_range("Index out of range");
return m_RamData[index];
}
const T &at(size_t index) const {
const_cast<DataAllocator *>(this)->MoveToRAM();
if (index >= m_Size)
throw std::out_of_range("Index out of range");
return m_RamData[index];
}
T &operator[](size_t index) {
MoveToRAM();
return m_RamData[index];
}
const T &operator[](size_t index) const {
const_cast<DataAllocator *>(this)->MoveToRAM();
return m_RamData[index];
}
T *data() { return (m_Device == MemoryDevice::RAM) ? m_RamData : m_VramData; }
const T *data() const {
return (m_Device == MemoryDevice::RAM) ? m_RamData : m_VramData;
}
T *GetRAMData() { return m_RamData; }
const T *GetRAMData() const { return m_RamData; }
T *GetVRAMData() { return m_VramData; }
const T *GetVRAMData() const { return m_VramData; }
MemoryDevice GetDevice() const { return m_Device; }
// Iterator support for RAM operations
T *begin() {
MoveToRAM();
return m_RamData;
}
T *end() {
MoveToRAM();
return m_RamData + m_Size;
}
const T *begin() const {
const_cast<DataAllocator *>(this)->MoveToRAM();
return m_RamData;
}
const T *end() const {
const_cast<DataAllocator *>(this)->MoveToRAM();
return m_RamData + m_Size;
}
private:
size_t m_Size;
T *m_RamData;
T *m_VramData;
MemoryDevice m_Device;
bool m_OwnsObjects;
};
} // namespace uLib
#endif // U_MATH_DATAALLOCATOR_H

View File

@@ -23,95 +23,85 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CORE_EXPORT_H #ifndef U_CORE_EXPORT_H
#define U_CORE_EXPORT_H #define U_CORE_EXPORT_H
#include <utility>
#include <cstddef> // NULL #include <cstddef> // NULL
#include <iostream> #include <iostream>
#include <utility>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/stringize.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_polymorphic.hpp> #include <boost/type_traits/is_polymorphic.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/and.hpp> #include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp> #include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/serialization/extended_type_info.hpp> // for guid_defined only
#include <boost/serialization/static_warning.hpp>
#include <boost/serialization/assume_abstract.hpp> #include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/extended_type_info.hpp> // for guid_defined only
#include <boost/serialization/force_include.hpp> #include <boost/serialization/force_include.hpp>
#include <boost/serialization/singleton.hpp> #include <boost/serialization/singleton.hpp>
#include <boost/serialization/static_warning.hpp>
#include <boost/archive/detail/register_archive.hpp> #include <boost/archive/detail/register_archive.hpp>
#include "Core/Archives.h" #include "Core/Archives.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
namespace uLib { namespace uLib {
namespace Archive { namespace Archive {
namespace detail { namespace detail {
namespace extra_detail { namespace extra_detail {
template<class T> template <class T> struct guid_initializer {
struct guid_initializer void export_guid(boost::mpl::false_) const {
{ // generates the statically-initialized objects whose constructors
void export_guid(mpl::false_) const { // register the information allowing serialization of T objects
// generates the statically-initialized objects whose constructors // through pointers to their base classes.
// register the information allowing serialization of T objects boost::archive::detail::instantiate_ptr_serialization(
// through pointers to their base classes. (T *)0, 0, uLib::Archive::detail::adl_tag());
boost::archive::detail:: }
instantiate_ptr_serialization((T*)0, 0, void export_guid(boost::mpl::true_) const {}
uLib::Archive::detail::adl_tag()); guid_initializer const &export_guid() const {
} BOOST_STATIC_WARNING(boost::is_polymorphic<T>::value);
void export_guid(mpl::true_) const { // note: exporting an abstract base class will have no effect
} // and cannot be used to instantitiate serialization code
guid_initializer const & export_guid() const { // (one might be using this in a DLL to instantiate code)
BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); // BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value);
// note: exporting an abstract base class will have no effect export_guid(boost::serialization::is_abstract<T>());
// and cannot be used to instantitiate serialization code return *this;
// (one might be using this in a DLL to instantiate code) }
//BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value);
export_guid(boost::serialization::is_abstract< T >());
return *this;
}
}; };
template<typename T> template <typename T> struct init_guid;
struct init_guid;
} // anonymous } // namespace extra_detail
} // namespace detail } // namespace detail
} // namespace Archive } // namespace Archive
} // namespace uLib } // namespace uLib
#define ULIB_CLASS_EXPORT_IMPLEMENT(T) \
namespace uLib { \
#define ULIB_CLASS_EXPORT_IMPLEMENT(T) \ namespace Archive { \
namespace uLib { \ namespace detail { \
namespace Archive { \ namespace extra_detail { \
namespace detail { \ template <> struct init_guid<T> { \
namespace extra_detail { \ static guid_initializer<T> const &g; \
template<> \ }; \
struct init_guid< T > { \ guid_initializer<T> const &init_guid<T>::g = \
static guid_initializer< T > const & g; \ ::boost::serialization::singleton< \
}; \ guid_initializer<T>>::get_mutable_instance() \
guid_initializer< T > const & init_guid< T >::g = \ .export_guid(); \
::boost::serialization::singleton< \ } \
guid_initializer< T > \ } \
>::get_mutable_instance().export_guid(); \ } \
}}}} \ } \
/**/ /**/
#endif // EXPORT_H #endif // EXPORT_H

View File

@@ -110,11 +110,13 @@ bool Object::addSignalImpl(SignalBase *sig, GenericMFPtr fptr,
const char *name) { const char *name) {
ObjectPrivate::Signal s = {fptr, std::string(name), sig}; ObjectPrivate::Signal s = {fptr, std::string(name), sig};
d->sigv.push_back(s); d->sigv.push_back(s);
return true;
} }
bool Object::addSlotImpl(GenericMFPtr fptr, const char *name) { bool Object::addSlotImpl(GenericMFPtr fptr, const char *name) {
ObjectPrivate::Slot s = {fptr, std::string(name)}; ObjectPrivate::Slot s = {fptr, std::string(name)};
d->slov.push_back(s); d->slov.push_back(s);
return true;
} }
SignalBase *Object::findSignalImpl(const GenericMFPtr &fptr) const { SignalBase *Object::findSignalImpl(const GenericMFPtr &fptr) const {

View File

@@ -107,6 +107,7 @@ public:
// if(sig && slo) // if(sig && slo)
// return Object::connect(sig,slo->operator ()(),receiver); // return Object::connect(sig,slo->operator ()(),receiver);
// else return false; // else return false;
return false;
} }
// Qt5 style connector // // Qt5 style connector //
@@ -115,15 +116,16 @@ public:
connect(typename FunctionPointer<Func1>::Object *sender, Func1 sigf, connect(typename FunctionPointer<Func1>::Object *sender, Func1 sigf,
typename FunctionPointer<Func2>::Object *receiver, Func2 slof) { typename FunctionPointer<Func2>::Object *receiver, Func2 slof) {
SignalBase *sigb = sender->findOrAddSignal(sigf); SignalBase *sigb = sender->findOrAddSignal(sigf);
typedef boost::signals2::signal< ConnectSignal<typename FunctionPointer<Func1>::SignalSignature>(sigb, slof,
typename FunctionPointer<Func2>::SignalSignature> receiver);
SigT; return true;
ConnectSignal(sigb, slof, receiver);
} }
template <typename FuncT> template <typename FuncT>
static inline bool connect(SignalBase *sigb, FuncT slof, Object *receiver) { static inline bool connect(SignalBase *sigb, FuncT slof, Object *receiver) {
ConnectSignal(sigb, slof, receiver); ConnectSignal<typename FunctionPointer<FuncT>::SignalSignature>(sigb, slof,
receiver);
return true;
} }
template <typename FuncT> template <typename FuncT>
@@ -139,7 +141,7 @@ public:
} }
template <typename FuncT> inline bool addSlot(FuncT fun, const char *name) { template <typename FuncT> inline bool addSlot(FuncT fun, const char *name) {
this->addSlotImpl(GenericMFPtr(fun), name); return this->addSlotImpl(GenericMFPtr(fun), name);
} }
template <typename FuncT> template <typename FuncT>

View File

@@ -23,21 +23,19 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CORE_SIGNAL_H #ifndef U_CORE_SIGNAL_H
#define U_CORE_SIGNAL_H #define U_CORE_SIGNAL_H
#include <boost/typeof/typeof.hpp> #include <boost/typeof/typeof.hpp>
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
#include <boost/signals2/slot.hpp>
#include <boost/signals2/signal_type.hpp> #include <boost/signals2/signal_type.hpp>
#include <boost/signals2/slot.hpp>
#include "Function.h" #include "Function.h"
#include <boost/bind/bind.hpp>
using namespace boost::placeholders;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -48,12 +46,15 @@
#define slots #define slots
#define signals /*virtual void init_signals();*/ public #define signals /*virtual void init_signals();*/ public
#define emit #define emit
#define SLOT(a) BOOST_STRINGIZE(a) #define SLOT(a) BOOST_STRINGIZE(a)
#define SIGNAL(a) BOOST_STRINGIZE(a) #define SIGNAL(a) BOOST_STRINGIZE(a)
#define _ULIB_DETAIL_SIGNAL_EMIT(_name,...) \ #define _ULIB_DETAIL_SIGNAL_EMIT(_name, ...) \
static BOOST_AUTO(sig,this->findOrAddSignal(&_name)); \ do { \
sig->operator()(__VA_ARGS__); BOOST_AUTO(sig, this->findOrAddSignal(&_name)); \
if (sig) \
sig->operator()(__VA_ARGS__); \
} while (0)
/** /**
* Utility macro to implement signal emission implementa una delle seguenti: * Utility macro to implement signal emission implementa una delle seguenti:
@@ -66,103 +67,101 @@
* // cast automatico // * // cast automatico //
* static BOOST_AUTO(sig,this->findOrAddSignal(&Ob1::V0)); * static BOOST_AUTO(sig,this->findOrAddSignal(&Ob1::V0));
* sig->operator()(); * sig->operator()();
*/ */
#define ULIB_SIGNAL_EMIT(_name,...) _ULIB_DETAIL_SIGNAL_EMIT(_name,__VA_ARGS__) #define ULIB_SIGNAL_EMIT(_name, ...) \
_ULIB_DETAIL_SIGNAL_EMIT(_name, __VA_ARGS__)
namespace uLib { namespace uLib {
// A boost::signal wrapper structure /////////////////////////////////////////// // A boost::signal wrapper structure ///////////////////////////////////////////
// TODO ... // TODO ...
typedef boost::signals2::signal_base SignalBase; typedef boost::signals2::signal_base SignalBase;
template <typename T> template <typename T> struct Signal {
struct Signal { typedef boost::signals2::signal<T> type;
typedef boost::signals2::signal<T> type;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
namespace detail { namespace detail {
template <typename FuncT, typename SigSignature, int arity>
template <typename FuncT, int arity>
struct ConnectSignal {}; struct ConnectSignal {};
template <typename FuncT> template <typename FuncT, typename SigSignature>
struct ConnectSignal< FuncT, 0 > { struct ConnectSignal<FuncT, SigSignature, 0> {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) { static void connect(SignalBase *sigb, FuncT slof,
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT; typename FunctionPointer<FuncT>::Object *receiver) {
reinterpret_cast<SigT*>(sigb)->connect(slof); typedef typename Signal<SigSignature>::type SigT;
} reinterpret_cast<SigT *>(sigb)->connect(slof);
}
}; };
template <typename FuncT> template <typename FuncT, typename SigSignature>
struct ConnectSignal< FuncT, 1 > { struct ConnectSignal<FuncT, SigSignature, 1> {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) { static void connect(SignalBase *sigb, FuncT slof,
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT; typename FunctionPointer<FuncT>::Object *receiver) {
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver)); typedef typename Signal<SigSignature>::type SigT;
} reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver));
}
}; };
template <typename FuncT> template <typename FuncT, typename SigSignature>
struct ConnectSignal< FuncT, 2 > { struct ConnectSignal<FuncT, SigSignature, 2> {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) { static void connect(SignalBase *sigb, FuncT slof,
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT; typename FunctionPointer<FuncT>::Object *receiver) {
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver,_1)); typedef typename Signal<SigSignature>::type SigT;
} reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver, _1));
}
}; };
template <typename FuncT> template <typename FuncT, typename SigSignature>
struct ConnectSignal< FuncT, 3 > { struct ConnectSignal<FuncT, SigSignature, 3> {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) { static void connect(SignalBase *sigb, FuncT slof,
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT; typename FunctionPointer<FuncT>::Object *receiver) {
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver,_1,_2)); typedef typename Signal<SigSignature>::type SigT;
} reinterpret_cast<SigT *>(sigb)->connect(
boost::bind(slof, receiver, _1, _2));
}
}; };
template <typename FuncT> template <typename FuncT, typename SigSignature>
struct ConnectSignal< FuncT, 4 > { struct ConnectSignal<FuncT, SigSignature, 4> {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) { static void connect(SignalBase *sigb, FuncT slof,
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT; typename FunctionPointer<FuncT>::Object *receiver) {
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver,_1,_2,_3)); typedef typename Signal<SigSignature>::type SigT;
} reinterpret_cast<SigT *>(sigb)->connect(
boost::bind(slof, receiver, _1, _2, _3));
}
}; };
template <typename FuncT> template <typename FuncT, typename SigSignature>
struct ConnectSignal< FuncT, 5 > { struct ConnectSignal<FuncT, SigSignature, 5> {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) { static void connect(SignalBase *sigb, FuncT slof,
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT; typename FunctionPointer<FuncT>::Object *receiver) {
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver,_1,_2,_3,_4)); typedef typename Signal<SigSignature>::type SigT;
} reinterpret_cast<SigT *>(sigb)->connect(
boost::bind(slof, receiver, _1, _2, _3, _4));
}
}; };
} // namespace detail
} // detail template <typename FuncT> SignalBase *NewSignal(FuncT f) {
return new
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type;
template <typename FuncT>
SignalBase *NewSignal(FuncT f) {
// seems to work wow !
return new Signal<void()>::type;
} }
template <typename FuncT> template <typename SigSignature, typename FuncT>
void ConnectSignal(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) void ConnectSignal(SignalBase *sigb, FuncT slof,
{ typename FunctionPointer<FuncT>::Object *receiver) {
detail::ConnectSignal< FuncT, FunctionPointer<FuncT>::arity >::connect(sigb,slof,receiver); detail::ConnectSignal<FuncT, SigSignature,
FunctionPointer<FuncT>::arity>::connect(sigb, slof,
receiver);
} }
} // namespace uLib
} // uLib
#endif // SIGNAL_H #endif // SIGNAL_H

View File

@@ -23,69 +23,49 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CORE_UUID_H #ifndef U_CORE_UUID_H
#define U_CORE_UUID_H #define U_CORE_UUID_H
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/name_generator.hpp> #include <boost/uuid/name_generator.hpp>
#include <boost/uuid/random_generator.hpp> #include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp> #include <boost/uuid/uuid_io.hpp>
#include "Core/Mpl.h" #include "Core/Mpl.h"
#include "Core/Object.h" #include "Core/Object.h"
namespace uLib { namespace uLib {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Object Registration // // Object Registration //
typedef boost::uuids::uuid uuid_t; typedef boost::uuids::uuid uuid_t;
extern uuid_t uLib_dns_uuid; extern uuid_t uLib_dns_uuid;
template < typename T > template <typename T> class type_id : public boost::uuids::uuid {
class type_id : public boost::uuids::uuid {
public: public:
type_id() : type_id()
m_size(sizeof(T)), : m_size(sizeof(T)),
uuid(boost::uuids::name_generator(uLib_dns_uuid)(typeid(T).name())) uuid(boost::uuids::name_generator(uLib_dns_uuid)(typeid(T).name())) {
{ std::cout << "Request for register new type\n"
std::cout << "Request for register new type\n" << << "name: " << typeid(T).name() << "\n"
"name: " << typeid(T).name() << "\n" << << "uuid: " << to_string(*this) << "\n";
"uuid: " << to_string(*this) << "\n"; }
}
explicit type_id(boost::uuids::uuid const& u) explicit type_id(boost::uuids::uuid const &u) : boost::uuids::uuid(u) {}
: boost::uuids::uuid(u) {}
operator boost::uuids::uuid() { unsigned int size() const { return m_size; }
return static_cast<boost::uuids::uuid&>(*this);
}
operator boost::uuids::uuid() const {
return static_cast<boost::uuids::uuid const&>(*this);
}
unsigned int size() const { return m_size; }
private: private:
unsigned int m_size; unsigned int m_size;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -94,70 +74,57 @@ private:
namespace detail { namespace detail {
class TypeRegister { class TypeRegister {
typedef boost::uuids::name_generator IDGen_t; typedef boost::uuids::name_generator IDGen_t;
public: public:
struct RegisterEntry { struct RegisterEntry {
uuid_t id; uuid_t id;
int size; int size;
}; };
TypeRegister(uuid_t const &dns) : TypeRegister(uuid_t const &dns) : gen(dns) {}
gen(dns) {}
template< typename T >
RegisterEntry * AddType(T *t = NULL) {
RegisterEntry en = { gen(typeid(T).name()), sizeof(T) };
for(int i=0; i < m_registry.size(); ++i)
if(en.id == m_registry[i].id) return &(m_registry[i]);
m_registry.push_back(en);
return &m_registry.back();
}
void PrintSelf(std::ostream &o) {
std::cout << "RegisterController: \n";
for (int i=0; i<m_registry.size(); ++i)
o << "type [" << i << "]: "
<< to_string(m_registry[i].id) << " "
<< m_registry[i].size << "\n";
o << "\n";
}
template <typename T> RegisterEntry *AddType(T *t = NULL) {
RegisterEntry en = {gen(typeid(T).name()), sizeof(T)};
for (int i = 0; i < m_registry.size(); ++i)
if (en.id == m_registry[i].id)
return &(m_registry[i]);
m_registry.push_back(en);
return &m_registry.back();
}
void PrintSelf(std::ostream &o) {
std::cout << "RegisterController: \n";
for (int i = 0; i < m_registry.size(); ++i)
o << "type [" << i << "]: " << to_string(m_registry[i].id) << " "
<< m_registry[i].size << "\n";
o << "\n";
}
private: private:
IDGen_t gen; IDGen_t gen;
std::vector<RegisterEntry> m_registry; std::vector<RegisterEntry> m_registry;
}; };
} // detail } // namespace detail
class TypeRegister : public detail::TypeRegister { class TypeRegister : public detail::TypeRegister {
public: public:
typedef detail::TypeRegister BaseClass; typedef detail::TypeRegister BaseClass;
typedef detail::TypeRegister::RegisterEntry Entry; typedef detail::TypeRegister::RegisterEntry Entry;
static TypeRegister* Controller(); static TypeRegister *Controller();
private: private:
TypeRegister(); // Blocks constructor TypeRegister(); // Blocks constructor
static TypeRegister *s_Instance; // Singleton instance static TypeRegister *s_Instance; // Singleton instance
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// OBJECT REGISTER // // OBJECT REGISTER //
} // namespace uLib
} // uLib
#endif // UUID_H #endif // UUID_H

View File

@@ -23,156 +23,433 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CORE_VECTOR_H #ifndef U_CORE_VECTOR_H
#define U_CORE_VECTOR_H #define U_CORE_VECTOR_H
#include <vector>
#include <iostream> #include <iostream>
#include <map>
#include <mutex>
#include <vector>
#include <Core/DataAllocator.h>
#include <Core/StaticInterface.h>
#include <Core/SmartPointer.h>
#include <Core/CommaInitializer.h> #include <Core/CommaInitializer.h>
#include <Core/SmartPointer.h>
#include <Core/StaticInterface.h>
#ifdef USE_CUDA
#include <thrust/device_ptr.h>
#include <thrust/device_vector.h>
#endif
namespace uLib { namespace uLib {
// Vector Implemetation ... wraps std::vector // MetaAllocator Implementation ...
template <typename T> template <typename T> class MetaAllocator {
class Vector : public std::vector<T, std::allocator<T> >
{
typedef std::vector< T,std::allocator<T> > BaseClass;
typedef std::allocator<T> Allocator;
public:
typedef T TypeData;
typedef __gnu_cxx::__normal_iterator<T*, BaseClass > Iterator;
typedef __gnu_cxx::__normal_iterator<const T*, BaseClass> ConstIterator;
typedef CommaInitializer< Vector<T> , T > VectorCommaInit;
Vector(unsigned int size) : BaseClass(size) {}
Vector(unsigned int size, T &value) : BaseClass(size,value) {}
Vector() : BaseClass(0) {}
inline VectorCommaInit operator <<(T scalar) {
return VectorCommaInit(this, scalar);
}
inline void PrintSelf(std::ostream &o);
void remove_element(unsigned int index) {
std::swap(this->at(index),this->back());
this->pop_back();
}
void remove_element(T &t) {
std::swap(t, this->back());
this->pop_back();
}
};
template<typename T>
void Vector<T>::PrintSelf(std::ostream &o)
{
o << " *** uLib Vector *** \n";
o << " n. of items = " << this->size() << "\n";
for(int i=0; i< this->size(); ++i)
o << (T)this->at(i) << " ";
o << "\n";
}
template <typename T>
std::ostream & operator << (std::ostream &o, const Vector<T> &v) {
for(int i=0; i< v.size(); ++i)
o << (T)v.at(i) << " ";
o << "\n";
return o;
}
template <typename T>
std::ofstream & operator << (std::ofstream &o, const Vector<T> &v) {
for(int i=0; i< v.size(); ++i)
o << (T)v.at(i) << " ";
return o;
}
template < typename T >
std::istream & operator >> (std::istream &is, Vector<T> &v) {
T value;
while( is >> value ) {
if(is.fail()) v.push_back(0);
else v.push_back( value );
}
return is;
}
// Smart pointer Vector Implementation //
template <typename T>
class SmartVector : public SmartPointer< Vector<T> > {
typedef SmartPointer< Vector<T> > Base;
public: public:
using value_type = T;
using pointer = T *;
using const_pointer = const T *;
using reference = T &;
using const_reference = const T &;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
SmartVector() : Base(new Vector<T>()) { } template <class U> struct rebind {
SmartVector( const SmartVector &copy) : Base(copy) { } using other = MetaAllocator<U>;
SmartVector(unsigned int size) : Base(new Vector<T>((int)size)) { } };
virtual ~SmartVector() {} MetaAllocator() noexcept = default;
T& operator[](int p) { template <class U>
return Base::get()->at(p); constexpr MetaAllocator(const MetaAllocator<U> &) noexcept {}
T *allocate(std::size_t n) {
if (n == 0)
return nullptr;
DataAllocator<T> *da = new DataAllocator<T>(n, false);
T *ptr = da->GetRAMData();
std::lock_guard<std::mutex> lock(GetMutex());
GetAllocationMap()[ptr] = da;
return ptr;
} }
void swap_elements(unsigned int first, unsigned int second) { void deallocate(T *p, std::size_t /*n*/) noexcept {
std::swap(Base::get()->at(first),Base::get()->at(second)); if (!p)
return;
std::lock_guard<std::mutex> lock(GetMutex());
auto &map = GetAllocationMap();
auto it = map.find(p);
if (it != map.end()) {
delete it->second;
map.erase(it);
}
}
static DataAllocator<T> *GetDataAllocator(T *p) {
if (!p)
return nullptr;
std::lock_guard<std::mutex> lock(GetMutex());
auto &map = GetAllocationMap();
auto it = map.find(p);
if (it != map.end()) {
return it->second;
}
return nullptr;
}
private:
static std::map<T *, DataAllocator<T> *> &GetAllocationMap() {
static std::map<T *, DataAllocator<T> *> allocMap;
return allocMap;
}
static std::mutex &GetMutex() {
static std::mutex mtx;
return mtx;
}
};
template <class T, class U>
bool operator==(const MetaAllocator<T> &, const MetaAllocator<U> &) {
return true;
}
template <class T, class U>
bool operator!=(const MetaAllocator<T> &, const MetaAllocator<U> &) {
return false;
}
// Vector Implemetation ... wraps std::vector
template <typename T> class Vector : public std::vector<T, MetaAllocator<T>> {
typedef std::vector<T, MetaAllocator<T>> BaseClass;
typedef MetaAllocator<T> Allocator;
public:
typedef T TypeData;
typedef __gnu_cxx::__normal_iterator<T *, BaseClass> Iterator;
typedef __gnu_cxx::__normal_iterator<const T *, BaseClass> ConstIterator;
typedef CommaInitializer<Vector<T>, T> VectorCommaInit;
typedef typename BaseClass::iterator iterator;
typedef typename BaseClass::const_iterator const_iterator;
typedef typename BaseClass::size_type size_type;
typedef typename BaseClass::reference reference;
Vector(unsigned int size) : BaseClass(size) {}
Vector(unsigned int size, T &value) : BaseClass(size, value) {}
Vector() : BaseClass(0) {}
Vector(std::initializer_list<T> init) : BaseClass(init) {}
inline VectorCommaInit operator<<(T scalar) {
return VectorCommaInit(this, scalar);
}
void MoveToVRAM() {
if (auto alloc = MetaAllocator<T>::GetDataAllocator(BaseClass::data())) {
alloc->MoveToVRAM();
}
}
void MoveToRAM() {
if (auto alloc = MetaAllocator<T>::GetDataAllocator(BaseClass::data())) {
alloc->MoveToRAM();
}
}
T *GetVRAMData() {
if (auto alloc = MetaAllocator<T>::GetDataAllocator(BaseClass::data())) {
return alloc->GetVRAMData();
}
return nullptr;
}
const T *GetVRAMData() const {
if (auto alloc = MetaAllocator<T>::GetDataAllocator(
const_cast<T *>(BaseClass::data()))) {
return alloc->GetVRAMData();
}
return nullptr;
}
#ifdef USE_CUDA
/// Returns a thrust::device_ptr to the VRAM data (valid after MoveToVRAM()).
/// thrust::device_ptr<T> is itself a random-access iterator compatible with
/// all thrust algorithms (thrust::transform, thrust::sort,
/// thrust::for_each…).
thrust::device_ptr<T> DeviceData() {
if (auto alloc = MetaAllocator<T>::GetDataAllocator(BaseClass::data())) {
return thrust::device_pointer_cast(alloc->GetVRAMData());
}
return thrust::device_ptr<T>(nullptr);
}
thrust::device_ptr<const T> DeviceData() const {
if (auto alloc = MetaAllocator<T>::GetDataAllocator(
const_cast<T *>(BaseClass::data()))) {
return thrust::device_pointer_cast(
static_cast<const T *>(alloc->GetVRAMData()));
}
return thrust::device_ptr<const T>(nullptr);
}
/// Device-side begin iterator (valid after MoveToVRAM()).
thrust::device_ptr<T> DeviceBegin() { return DeviceData(); }
/// Device-side end iterator (valid after MoveToVRAM()).
thrust::device_ptr<T> DeviceEnd() {
return DeviceData() + static_cast<std::ptrdiff_t>(BaseClass::size());
}
thrust::device_ptr<const T> DeviceBegin() const { return DeviceData(); }
thrust::device_ptr<const T> DeviceEnd() const {
return DeviceData() + static_cast<std::ptrdiff_t>(BaseClass::size());
}
#endif // USE_CUDA
inline void PrintSelf(std::ostream &o);
// Overrides for auto-sync //
T &operator[](size_t i) {
this->MoveToRAM();
return BaseClass::operator[](i);
}
const T &operator[](size_t i) const {
const_cast<Vector *>(this)->MoveToRAM();
return BaseClass::operator[](i);
}
T &at(size_t i) {
this->MoveToRAM();
return BaseClass::at(i);
}
const T &at(size_t i) const {
const_cast<Vector *>(this)->MoveToRAM();
return BaseClass::at(i);
}
T &front() {
this->MoveToRAM();
return BaseClass::front();
}
const T &front() const {
const_cast<Vector *>(this)->MoveToRAM();
return BaseClass::front();
}
T &back() {
this->MoveToRAM();
return BaseClass::back();
}
const T &back() const {
const_cast<Vector *>(this)->MoveToRAM();
return BaseClass::back();
}
T *data() noexcept {
this->MoveToRAM();
return BaseClass::data();
}
const T *data() const noexcept {
const_cast<Vector *>(this)->MoveToRAM();
return BaseClass::data();
}
Iterator begin() noexcept {
this->MoveToRAM();
return BaseClass::begin();
}
ConstIterator begin() const noexcept {
const_cast<Vector *>(this)->MoveToRAM();
return BaseClass::begin();
}
Iterator end() noexcept {
this->MoveToRAM();
return BaseClass::end();
}
ConstIterator end() const noexcept {
const_cast<Vector *>(this)->MoveToRAM();
return BaseClass::end();
}
auto rbegin() noexcept {
this->MoveToRAM();
return BaseClass::rbegin();
}
auto rbegin() const noexcept {
const_cast<Vector *>(this)->MoveToRAM();
return BaseClass::rbegin();
}
auto rend() noexcept {
this->MoveToRAM();
return BaseClass::rend();
}
auto rend() const noexcept {
const_cast<Vector *>(this)->MoveToRAM();
return BaseClass::rend();
}
void push_back(const T &x) {
this->MoveToRAM();
BaseClass::push_back(x);
}
void push_back(T &&x) {
this->MoveToRAM();
BaseClass::push_back(std::move(x));
}
template <typename... Args> reference emplace_back(Args &&...args) {
this->MoveToRAM();
return BaseClass::emplace_back(std::forward<Args>(args)...);
}
void pop_back() {
this->MoveToRAM();
BaseClass::pop_back();
}
template <typename... Args>
iterator emplace(const_iterator pos, Args &&...args) {
this->MoveToRAM();
return BaseClass::emplace(pos, std::forward<Args>(args)...);
}
iterator insert(const_iterator pos, const T &x) {
this->MoveToRAM();
return BaseClass::insert(pos, x);
}
iterator insert(const_iterator pos, T &&x) {
this->MoveToRAM();
return BaseClass::insert(pos, std::move(x));
}
template <typename InputIt>
iterator insert(const_iterator pos, InputIt first, InputIt last) {
this->MoveToRAM();
return BaseClass::insert(pos, first, last);
}
iterator erase(const_iterator pos) {
this->MoveToRAM();
return BaseClass::erase(pos);
}
iterator erase(const_iterator first, const_iterator last) {
this->MoveToRAM();
return BaseClass::erase(first, last);
}
void resize(size_t n) {
this->MoveToRAM();
BaseClass::resize(n);
}
void resize(size_t n, const T &x) {
this->MoveToRAM();
BaseClass::resize(n, x);
}
void reserve(size_t n) {
this->MoveToRAM();
BaseClass::reserve(n);
}
void clear() noexcept {
this->MoveToRAM();
BaseClass::clear();
}
template <typename InputIt> void assign(InputIt first, InputIt last) {
this->MoveToRAM();
BaseClass::assign(first, last);
}
void assign(size_type count, const T &value) {
this->MoveToRAM();
BaseClass::assign(count, value);
} }
void remove_element(unsigned int index) { void remove_element(unsigned int index) {
std::swap(Base::get()->at(index),Base::get()->back()); this->MoveToRAM();
Base::get()->pop_back(); std::swap(this->at(index), this->back());
this->pop_back();
}
void remove_element(T &t) {
this->MoveToRAM();
std::swap(t, this->back());
this->pop_back();
}
};
template <typename T> void Vector<T>::PrintSelf(std::ostream &o) {
o << " *** uLib Vector *** \n";
o << " n. of items = " << this->size() << "\n";
for (int i = 0; i < this->size(); ++i)
o << (T)this->at(i) << " ";
o << "\n";
}
template <typename T>
std::ostream &operator<<(std::ostream &o, const Vector<T> &v) {
for (int i = 0; i < v.size(); ++i)
o << (T)v.at(i) << " ";
o << "\n";
return o;
}
template <typename T>
std::ofstream &operator<<(std::ofstream &o, const Vector<T> &v) {
for (int i = 0; i < v.size(); ++i)
o << (T)v.at(i) << " ";
return o;
}
template <typename T> std::istream &operator>>(std::istream &is, Vector<T> &v) {
T value;
while (is >> value) {
if (is.fail())
v.push_back(0);
else
v.push_back(value);
}
return is;
}
// Smart pointer Vector Implementation //
template <typename T> class SmartVector : public SmartPointer<Vector<T>> {
typedef SmartPointer<Vector<T>> Base;
public:
SmartVector() : Base(new Vector<T>()) {}
SmartVector(const SmartVector &copy) : Base(copy) {}
SmartVector(unsigned int size) : Base(new Vector<T>((int)size)) {}
virtual ~SmartVector() {}
T &operator[](int p) { return Base::get()->at(p); }
void swap_elements(unsigned int first, unsigned int second) {
std::swap(Base::get()->at(first), Base::get()->at(second));
}
void remove_element(unsigned int index) {
std::swap(Base::get()->at(index), Base::get()->back());
Base::get()->pop_back();
} }
void remove_element(T &t) { void remove_element(T &t) {
std::swap(t, Base::get()->back()); std::swap(t, Base::get()->back());
Base::get()->pop_back(); Base::get()->pop_back();
} }
}; };
// ------ Utils ------------------------------------------------------------- // // ------ Utils ------------------------------------------------------------- //
// RIFARE con iteratore ! // RIFARE con iteratore !
template <typename _Tp, class _CmpT> template <typename _Tp, class _CmpT>
inline const unsigned long inline unsigned long VectorSplice(const _Tp &_it, const _Tp &_end,
VectorSplice(const _Tp &_it, const _Tp &_end, const float value, _CmpT _comp) const float value, _CmpT _comp) {
{ _Tp it = _it;
_Tp it = _it; _Tp end = _end - 1;
_Tp end = _end-1; for (; it != end;) {
for(it; it != end;) if (_comp(*it, value))
{ ++it;
if (_comp(*it,value)) ++it; else if (_comp(*end, value))
else if(_comp(*end,value)) std::swap(*it,*end--); std::swap(*it, *end--);
else --end; else
} --end;
return it - _it; }
return it - _it;
} }
} // namespace uLib
} // uLib
#endif // VECTOR_H #endif // VECTOR_H

View File

@@ -8,7 +8,7 @@ set( TESTS
ObjectCopyTest ObjectCopyTest
StaticInterfaceTest StaticInterfaceTest
CommaInitTest CommaInitTest
DebugTTreeDumpTest # DebugTTreeDumpTest
BoostTest BoostTest
BoostAccumulatorTest BoostAccumulatorTest
PropertiesTest PropertiesTest
@@ -19,14 +19,20 @@ set( TESTS
UuidTest UuidTest
TypeIntrospectionTraversal TypeIntrospectionTraversal
OptionsTest OptionsTest
PingPongTest
VectorMetaAllocatorTest
) )
set(LIBRARIES set(LIBRARIES
${PACKAGE_LIBPREFIX}Core ${PACKAGE_LIBPREFIX}Core
${PACKAGE_LIBPREFIX}Math ${PACKAGE_LIBPREFIX}Math
${Boost_SERIALIZATION_LIBRARY} Boost::serialization
${Boost_SIGNALS_LIBRARY} Boost::program_options
${Boost_PROGRAM_OPTIONS_LIBRARY}
${ROOT_LIBRARIES} ${ROOT_LIBRARIES}
) )
uLib_add_tests(${uLib-module}) uLib_add_tests(Core)
if(USE_CUDA)
set_source_files_properties(VectorMetaAllocatorTest.cpp PROPERTIES LANGUAGE CUDA)
endif()

View File

@@ -0,0 +1,52 @@
#include "Core/Object.h"
#include "Core/Signal.h"
#include "testing-prototype.h"
#include <iostream>
using namespace uLib;
class Ping : public Object {
public:
signals:
void PingSignal(int count);
public slots:
void OnPong(int count) {
std::cout << "Ping received Pong " << count << std::endl;
if (count > 0)
ULIB_SIGNAL_EMIT(Ping::PingSignal, count - 1);
}
};
void Ping::PingSignal(int count) { ULIB_SIGNAL_EMIT(Ping::PingSignal, count); }
class Pong : public Object {
public:
signals:
void PongSignal(int count);
public slots:
void OnPing(int count) {
std::cout << "Pong received Ping " << count << std::endl;
if (count > 0)
ULIB_SIGNAL_EMIT(Pong::PongSignal, count - 1);
}
};
void Pong::PongSignal(int count) { ULIB_SIGNAL_EMIT(Pong::PongSignal, count); }
int main() {
BEGIN_TESTING(PingPong);
Ping ping;
Pong pong;
std::cout << "Connecting ping to pong" << std::endl;
Object::connect(&ping, &Ping::PingSignal, &pong, &Pong::OnPing);
std::cout << "Connecting pong to ping" << std::endl;
Object::connect(&pong, &Pong::PongSignal, &ping, &Ping::OnPong);
std::cout << "Emitting PingSignal(5)" << std::endl;
ping.PingSignal(5);
END_TESTING;
return 0;
}

View File

@@ -23,13 +23,10 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#include <iostream>
#include <fstream> #include <fstream>
#include <typeinfo> #include <iostream>
#include <string> #include <string>
#include <typeinfo>
#include "Core/Object.h" #include "Core/Object.h"
@@ -37,78 +34,43 @@
using namespace uLib; using namespace uLib;
struct A : Object {
uLibTypeMacro(A, Object) A() : numa(5552368) {}
int numa;
struct A : Object {
uLibTypeMacro(A,Object)
A() : numa(5552368) {}
int numa;
}; };
ULIB_SERIALIZABLE_OBJECT(A) ULIB_SERIALIZABLE_OBJECT(A)
ULIB_SERIALIZE_OBJECT(A,Object) { ULIB_SERIALIZE_OBJECT(A, Object) { ar &AR(numa); }
ar & AR(numa);
}
struct B : virtual Object { struct B : virtual Object {
uLibTypeMacro(B,Object) uLibTypeMacro(B, Object) B() : numb(5552369) {}
B() : numb(5552369) {} int numb;
int numb;
}; };
ULIB_SERIALIZABLE_OBJECT(B) ULIB_SERIALIZABLE_OBJECT(B)
ULIB_SERIALIZE_OBJECT(B,Object) { ar & AR(numb); } ULIB_SERIALIZE_OBJECT(B, Object) { ar &AR(numb); }
struct C : B { struct C : B {
uLibTypeMacro(C,B) uLibTypeMacro(C, B) C() : numc(5552370) {}
C() : numc(5552370) {} int numc;
int numc;
}; };
ULIB_SERIALIZABLE_OBJECT(C) ULIB_SERIALIZABLE_OBJECT(C)
ULIB_SERIALIZE_OBJECT(C,B) { ar & AR(numc); } ULIB_SERIALIZE_OBJECT(C, B) { ar &AR(numc); }
struct D : A,B { struct D : A, B {
uLibTypeMacro(D,A,B) uLibTypeMacro(D, A, B)
D() : numd(5552371) {} D()
int numd; : numd(5552371) {}
int numd;
}; };
ULIB_SERIALIZABLE_OBJECT(D) ULIB_SERIALIZABLE_OBJECT(D)
ULIB_SERIALIZE_OBJECT(D,A,B) { ar & AR(numd); } ULIB_SERIALIZE_OBJECT(D, A, B) { ar &AR(numd); }
int main() {
A o;
Archive::xml_oarchive(std::cout) << NVP(o);
main() {
A o; o.init_properties();
Archive::xml_oarchive(std::cout) << NVP(o);
} }

View File

@@ -23,20 +23,16 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#include <iostream>
#include <fstream> #include <fstream>
#include <iostream>
#include "Core/Object.h"
#include "Core/Archives.h" #include "Core/Archives.h"
#include "Core/Object.h"
#include "testing-prototype.h" #include "testing-prototype.h"
using namespace uLib; using namespace uLib;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -45,63 +41,51 @@ using namespace uLib;
struct V3f { struct V3f {
float x,y,z; float x, y, z;
V3f() V3f() { x = y = z = 0; }
{ x = y = z =0; }
V3f(float x, float y, float z) : V3f(float x, float y, float z) : x(x), y(y), z(z) {}
x(x), y(y), z(z) {}
template <class Archive> template <class Archive> void serialize(Archive &ar, unsigned int v) {
void serialize (Archive &ar,unsigned int v) { ar & "<" & NVP(x) & NVP(y) & NVP(z) & ">";
ar }
& "<" & NVP(x) & NVP(y) & NVP(z) & ">";
}
}; };
ULIB_CLASS_EXPORT_KEY(V3f); ULIB_CLASS_EXPORT_KEY(V3f);
ULIB_CLASS_EXPORT_IMPLEMENT(V3f); ULIB_CLASS_EXPORT_IMPLEMENT(V3f);
inline std::ostream &operator<<(std::ostream &o, const V3f &v) {
inline std::ostream & Archive::hrt_oarchive(o) << v;
operator <<(std::ostream &o, const V3f &v) { return o;
Archive::hrt_oarchive(o) << v;
return o;
} }
inline std::istream & inline std::istream &operator>>(std::istream &is, V3f &v) {
operator >>(std::istream &is, V3f &v) { Archive::hrt_iarchive(is) >> v;
Archive::hrt_iarchive(is) >> v; return is;
return is;
} }
int test_V3f() { int test_V3f() {
// testing human readble archive with simple serializable structure // // testing human readble archive with simple serializable structure //
V3f v1(1,2,3),v2,v3,v4; V3f v1(1, 2, 3), v2, v3, v4;
std::cout << "v --> " << v1 << "\n"; std::cout << "v --> " << v1 << "\n";
std::stringstream ss; ss << v1; std::stringstream ss;
std::cout << "ss.v --> " << ss.str() << "\n"; ss << v1;
std::cout << "ss.v --> " << ss.str() << "\n";
Archive::hrt_iarchive ar(ss); ar >> v2; Archive::hrt_iarchive ar(ss);
std::cout << "v2 --> " << v2 << "\n"; ar >> v2;
std::cout << "v2 --> " << v2 << "\n";
std::stringstream("<2 3 4>") >> v3; std::stringstream("<2 3 4>") >> v3;
std::cout << "v3 --> " << v3 << "\n"; std::cout << "v3 --> " << v3 << "\n";
// std::cout << "insert V3f string to parse: "; std::cin >> v4; // std::cout << "insert V3f string to parse: "; std::cin >> v4;
// std::cout << "v4 --> " << v4 << "\n"; // std::cout << "v4 --> " << v4 << "\n";
return (1); return (1);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -109,104 +93,72 @@ int test_V3f() {
// OBJECT SERIALIZATION // // OBJECT SERIALIZATION //
class A : public virtual Object { class A : public virtual Object {
uLibTypeMacro(A,Object) uLibTypeMacro(A, Object) ULIB_SERIALIZE_ACCESS public : A() : m_a(5552368) {}
ULIB_SERIALIZE_ACCESS
public:
A() : m_a(5552368) {}
properties() { void init_properties();
std::string p_a; std::string p_a;
};
uLibRefMacro(a, int);
uLibRefMacro (a,int);
private: private:
int m_a; int m_a;
}; };
void A::init_properties() { void A::init_properties() { p_a = "A property string"; }
$_init();
$$.p_a = "A property string";
}
ULIB_SERIALIZABLE_OBJECT(A) ULIB_SERIALIZABLE_OBJECT(A)
ULIB_SERIALIZE_OBJECT(A,Object) { ULIB_SERIALIZE_OBJECT(A, Object) {
ar ar & "Object A : " & "--> m_a = " & AR(m_a) & "\n" & "Object A properties: " &
& "Object A : " "---> p_a = " & AR(p_a) & "\n";
& "--> m_a = " & AR(m_a)
& "\n";
} }
ULIB_SERIALIZE_OBJECT_PROPS(A) {
ar
& "Object A properties: "
& "---> p_a = " & AR(p_a) & "\n";
}
int testing_xml_class() { int testing_xml_class() {
A a; a.init_properties(); A a;
a.init_properties();
{ {
std::ofstream file("test.xml"); std::ofstream file("test.xml");
Archive::xml_oarchive(file) << NVP(a); Archive::xml_oarchive(file) << NVP(a);
} }
a.a() = 0; a.a() = 0;
a.$$.p_a = "zero string"; a.p_a = "zero string";
{ {
std::ifstream file("test.xml"); std::ifstream file("test.xml");
Archive::xml_iarchive(file) >> NVP(a); Archive::xml_iarchive(file) >> NVP(a);
} }
Archive::xml_oarchive(std::cout) << NVP(a); Archive::xml_oarchive(std::cout) << NVP(a);
return ( a.a() == 5552368 && a.$$.p_a == "A property string" ); return (a.a() == 5552368 && a.p_a == "A property string");
} }
int testing_hrt_class() { int testing_hrt_class() {
A a; a.init_properties(); A a;
a.init_properties();
{ {
std::ofstream file("test.xml"); std::ofstream file("test.xml");
Archive::hrt_oarchive(file) << NVP(a); Archive::hrt_oarchive(file) << NVP(a);
} }
a.a() = 0; a.a() = 0;
a.$$.p_a = "zero string"; a.p_a = "zero string";
{ {
// ERRORE FIX ! // ERRORE FIX !
// std::ifstream file("test.xml"); // std::ifstream file("test.xml");
// Archive::hrt_iarchive(file) >> NVP(a); // Archive::hrt_iarchive(file) >> NVP(a);
} }
Archive::hrt_oarchive(std::cout) << NVP(a); Archive::hrt_oarchive(std::cout) << NVP(a);
return ( a.a() == 5552368 && a.$$.p_a == "A property string" ); return (a.a() == 5552368 && a.p_a == "A property string");
} }
int main() { int main() {
BEGIN_TESTING(Serialize Test); BEGIN_TESTING(Serialize Test);
TEST1( test_V3f() ); TEST1(test_V3f());
TEST1( testing_xml_class() ); TEST1(testing_xml_class());
// testing_hrt_class(); ///// << ERRORE in HRT with properties // testing_hrt_class(); ///// << ERRORE in HRT with properties
END_TESTING; END_TESTING;
} }

View File

@@ -23,93 +23,63 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#include <iostream> #include <iostream>
#include <typeinfo> #include <typeinfo>
#include "testing-prototype.h"
#include "Core/Types.h"
#include "Core/Object.h" #include "Core/Object.h"
#include "Core/Signal.h" #include "Core/Signal.h"
#include "Core/Types.h"
#include "testing-prototype.h"
using namespace uLib; using namespace uLib;
class Ob1 : public Object { class Ob1 : public Object {
public: public:
signals: signals:
void V0(); void V0();
int V1(int a);
void V1(int a);
}; };
// should be done by moc // // should be done by moc //
void Ob1::V0() { void Ob1::V0() { ULIB_SIGNAL_EMIT(Ob1::V0); }
ULIB_SIGNAL_EMIT(Ob1::V0);
}
int Ob1::V1(int a) {
ULIB_SIGNAL_EMIT(Ob1::V1,a);
}
void Ob1::V1(int a) { ULIB_SIGNAL_EMIT(Ob1::V1, a); }
class Ob2 : public Object { class Ob2 : public Object {
public slots: public slots:
void PrintV0() { void PrintV0() { std::cout << "Ob2 prints V0\n" << std::flush; }
std::cout << "Ob2 prints V0\n" << std::flush;
}
}; };
class Ob3 : public Object { class Ob3 : public Object {
public slots: public slots:
void PrintV0() { void PrintV0() { std::cout << "Ob3 prints V0\n" << std::flush; }
std::cout << "Ob3 prints V0\n" << std::flush;
}
void PrintNumber(int n) { void PrintNumber(int n) {
std::cout << "Ob3 is printing number: " << n << "\n"; std::cout << "Ob3 is printing number: " << n << "\n";
} }
}; };
int main() { int main() {
BEGIN_TESTING(Signals); BEGIN_TESTING(Signals);
Ob1 ob1; Ob1 ob1;
Ob2 ob2; Ob2 ob2;
Ob3 ob3; Ob3 ob3;
Object::connect(&ob1,&Ob1::V0,&ob2,&Ob2::PrintV0); Object::connect(&ob1, &Ob1::V0, &ob2, &Ob2::PrintV0);
Object::connect(&ob1,&Ob1::V0,&ob3,&Ob3::PrintV0); Object::connect(&ob1, &Ob1::V0, &ob3, &Ob3::PrintV0);
Object::connect(&ob1,&Ob1::V1,&ob3,&Ob3::PrintNumber); Object::connect(&ob1, &Ob1::V1, &ob3, &Ob3::PrintNumber);
// not working yet // not working yet
// Object::connect(&ob1,SIGNAL(V0(),&ob2,SLOT(PrintV0()) // Object::connect(&ob1,SIGNAL(V0(),&ob2,SLOT(PrintV0())
ob1.PrintSelf(std::cout); ob1.PrintSelf(std::cout);
emit ob1.V0(); emit ob1.V0();
emit ob1.V1(5552368); emit ob1.V1(5552368);
END_TESTING; END_TESTING;
} }

View File

@@ -23,90 +23,73 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#include <iostream> #include <iostream>
#include "testing-prototype.h" #include "testing-prototype.h"
#include <Core/StaticInterface.h> #include <Core/StaticInterface.h>
namespace uLib { namespace uLib {
//// INTERFACE TO COMPLEX CLASS ///// //// INTERFACE TO COMPLEX CLASS /////
namespace Interface { namespace Interface {
struct Test { struct Test {
MAKE_TRAITS MAKE_TRAITS
template<class Self> void check_structural() { template <class Self> void check_structural() {
uLibCheckFunction(Self,test,bool,int,float); uLibCheckFunction(Self, test, bool, int, float);
uLibCheckMember(Self,testmemb,int); uLibCheckMember(Self, testmemb, int);
} }
}; };
} } // namespace Interface
struct Test { struct Test {
bool test(int i, float f){} bool test(int i, float f) { return true; }
int testmemb; int testmemb;
}; };
//// INTERFAC TO SIMPLE CLASS /////////// //// INTERFAC TO SIMPLE CLASS ///////////
namespace Interface { namespace Interface {
struct Simple { struct Simple {
MAKE_TRAITS MAKE_TRAITS
template<class Self> void check_structural() { template <class Self> void check_structural() {
uLibCheckMember(Self,memb1,int); uLibCheckMember(Self, memb1, int);
uLibCheckMember(Self,memb2,float); uLibCheckMember(Self, memb2, float);
} }
}; };
} } // namespace Interface
struct Simple { struct Simple {
int memb1; int memb1;
float memb2; float memb2;
}; };
///////////////////////// /////////////////////////
template <class T> template <class T> class UseTest {
class UseTest {
public: public:
UseTest() { UseTest() {
Interface::IsA<T,Interface::Test>(); Interface::IsA<T, Interface::Test>();
T t; T t;
int i; float f; int i;
t.test(i,f); float f;
} t.test(i, f);
}
}; };
template <class T> template <class T> class UseSimple {
class UseSimple {
public: public:
UseSimple() { UseSimple() { Interface::IsA<T, Interface::Simple>(); }
Interface::IsA<T,Interface::Simple>();
}
}; };
} // namespace uLib
int main() {
BEGIN_TESTING(Static Interface);
uLib::UseTest<uLib::Test> u;
uLib::UseSimple<uLib::Simple> s;
END_TESTING;
} }
int main()
{
BEGIN_TESTING(Static Interface);
uLib::UseTest<uLib::Test> u;
uLib::UseSimple<uLib::Simple> s;
END_TESTING;
}

View File

@@ -0,0 +1,97 @@
/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
//////////////////////////////////////////////////////////////////////////////*/
#include "testing-prototype.h"
#include <Core/Vector.h>
#ifdef USE_CUDA
#include <thrust/device_ptr.h>
#include <thrust/transform.h>
struct DoubleFunctor {
__host__ __device__ int operator()(int x) const { return x * 2; }
};
#endif
int main() {
BEGIN_TESTING(VectorMetaAllocator);
uLib::Vector<int> v;
std::cout << "Pushing elements...\n";
v << 1, 2, 3, 4, 5;
std::cout << "Initial RAM contents: ";
for (size_t i = 0; i < v.size(); ++i) {
std::cout << v[i] << " ";
if (v[i] != (int)(i + 1)) {
std::cout << "\nError: Value mismatch at index " << i << "\n";
exit(1);
}
}
std::cout << "\n";
#ifdef USE_CUDA
std::cout << "Moving to VRAM...\n";
v.MoveToVRAM();
int *vram_ptr = v.GetVRAMData();
if (vram_ptr) {
std::cout << "Successfully obtained VRAM pointer: " << vram_ptr << "\n";
} else {
std::cout << "Error: Failed to obtain VRAM pointer!\n";
exit(1);
}
// Verify DeviceData() matches GetVRAMData()
{
thrust::device_ptr<int> dev_ptr = v.DeviceData();
if (dev_ptr.get() != vram_ptr) {
std::cout << "Error: DeviceData() does not match GetVRAMData()!\n";
exit(1);
}
std::cout << "DeviceData() matches GetVRAMData(). OK\n";
}
// Use thrust::transform via DeviceBegin()/DeviceEnd() to double all elements
// on device
std::cout << "Doubling elements on device via thrust::transform...\n";
thrust::transform(v.DeviceBegin(), v.DeviceEnd(), v.DeviceBegin(),
DoubleFunctor{});
std::cout << "Moving back to RAM...\n";
v.MoveToRAM();
std::cout << "RAM contents after VRAM trip + thrust transform: ";
for (size_t i = 0; i < v.size(); ++i) {
std::cout << v[i] << " ";
if (v[i] != (int)((i + 1) * 2)) {
std::cout << "\nError: Data corrupted after RAM->VRAM->thrust->RAM trip "
"at index "
<< i << "\n";
exit(1);
}
}
std::cout << "\n";
#else
std::cout << "USE_CUDA not defined, skipping VRAM tests.\n";
#endif
std::cout << "Scaling vector...\n";
for (size_t i = 0; i < v.size(); ++i)
v[i] *= 10;
std::cout << "Final contents: ";
for (size_t i = 0; i < v.size(); ++i)
std::cout << v[i] << " ";
std::cout << "\n";
END_TESTING;
}

View File

@@ -23,62 +23,47 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#include <Core/Vector.h>
#include "testing-prototype.h" #include "testing-prototype.h"
#include <Core/Vector.h>
#include <algorithm> #include <algorithm>
template < typename T > template <typename T> struct __Cmp {
struct __Cmp { bool operator()(const T &data, const float value) { return data <= value; }
bool operator()(const T &data, const float value) {
return data <= value;
}
}; };
template <typename _Tp, typename _CmpT>
inline const unsigned long VectorSplice(const _Tp &_it, const _Tp &_end,
const float value, _CmpT _comp) {
_Tp it = _it;
_Tp end = _end - 1;
template<typename _Tp, typename _CmpT> for (it; it != end;) {
inline const unsigned long if (_comp(*it, value))
VectorSplice(const _Tp &_it, const _Tp &_end, const float value, _CmpT _comp) it++;
{ else if (_comp(*end, value)) {
std::swap(*it, *end--);
_Tp it = _it; } else
_Tp end = _end-1; --end;
for(it; it != end; ) }
{ return it - _it;
if ( _comp(*it, value) ) it++;
else if( _comp(*end, value) )
{
std::swap(*it,*end--);
}
else --end;
}
return it - _it;
} }
int main() {
BEGIN_TESTING(Vector);
int main() uLib::Vector<float> v;
{ v << 5, 4, 3, 2, 6, 1, 2, 3, 65, 7, 32, 23, 4, 3, 45, 4, 34, 3, 4, 4, 3, 3, 4,
BEGIN_TESTING(Vector); 2, 2, 3;
uLib::Vector<float> v; int id = ::VectorSplice(v.begin(), v.end(), 3, __Cmp<float>());
v << 5,4,3,2,6,1,2,3,65,7,32,23,4,3,45,4,34,3,4,4,3,3,4,2,2,3;
std::cout << "id: " << id << "\n";
std::cout << "vector: ";
for (uLib::Vector<float>::Iterator it = v.begin(); it != v.end(); it++)
std::cout << *it << " ";
std::cout << std::endl;
// std::sort(v.begin(),v.end(),LT<float>());
END_TESTING;
int id = VectorSplice(v.begin(),v.end(),3,__Cmp<float>());
std::cout << "id: " << id << "\n";
std::cout << "vector: ";
for(uLib::Vector<float>::Iterator it = v.begin(); it!=v.end(); it++)
std::cout << *it <<" ";
std::cout << std::endl;
// std::sort(v.begin(),v.end(),LT<float>());
END_TESTING;
} }

View File

@@ -1,7 +0,0 @@
set(HEADERS MuonScatter.h MuonError.h MuonEvent.h)
set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} Detectors PARENT_SCOPE)
install(FILES ${HEADERS}
DESTINATION ${INSTALL_INC_DIR}/Detectors)

View File

@@ -1,18 +0,0 @@
# TESTS
set( TESTS
GDMLSolidTest
HierarchicalEncodingTest
)
#set(LIBRARIES
# ${PACKAGE_LIBPREFIX}Core
# ${PACKAGE_LIBPREFIX}Math
# ${PACKAGE_LIBPREFIX}Detectors
# ${Boost_SERIALIZATION_LIBRARY}
# ${Boost_SIGNALS_LIBRARY}
# ${Boost_PROGRAM_OPTIONS_LIBRARY}
# ${Eigen_LIBRARY}
# ${Geant4_LIBRARIES}
# ${ROOT_LIBRARIES}
#)
uLib_add_tests(${uLib-module})

View File

@@ -1,35 +0,0 @@
# SUBDIRS = .
include $(top_srcdir)/Common.am
DISTSOURCES = vtkviewport.cpp main.cpp
DISTHEADERS_MOC =
DISTHEADERS_NO_MOC =
FORMS = vtkviewport.ui
FORMHEADERS = $(FORMS:.ui=.h)
MOC_CC = $(FORMS:.ui=.moc.cpp) $(DISTHEADERS_MOC:.h=.moc.cpp)
bin_PROGRAMS = QTVtkViewport
BUILT_SOURCES = $(FORMHEADERS) $(MOC_CC)
CLEANFILES = $(BUILT_SOURCES)
EXTRA_DIST = $(FORMS)
QTVtkViewport_SOURCES = $(DISTSOURCES) $(DISTHEADERS_MOC) $(DISTHEADERS_NO_MOC)
nodist_QTVtkViewport_SOURCES = $(MOC_CC)
QTVtkViewport_LDADD = $(top_srcdir)/libmutom.la
.ui.h: $(FORMS)
$(UIC) -o ui_$@ $<
.ui.hpp: $(FORMS_HPP)
$(UIC) -o $@ $<
.h.moc.cpp:
$(MOC) -o $@ $<
SUFFIXES = .h .ui .moc.cpp

View File

@@ -1,18 +0,0 @@
#-------------------------------------------------
#
# Project created by QtCreator 2012-08-30T18:59:53
#
#-------------------------------------------------
QT += core gui
TARGET = QVTKViewport2
TEMPLATE = app
SOURCES += main.cpp\
vtkviewport.cpp
HEADERS += vtkviewport.h
FORMS += vtkviewport.ui

View File

@@ -1,453 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by Qt Creator 2.4.1, 2012-09-03T09:43:56. -->
<qtcreator>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QString" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QString" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">System</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">1</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Target.DesktopTarget</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 4.7.4 for GCC (Qt SDK) Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">3</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 4.7.4 for GCC (Qt SDK) Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">3</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.7.0 in PATH (System) Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">4</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3">
<value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.7.0 in PATH (System) Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">4</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.4">
<value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.7.0 (System) Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">5</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.5">
<value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit.gdb</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.7.0 (System) Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/home/andrea/devel/MuonTomography/mutom/uLib/trunk/src/Gui/Qt/QVTKViewport2</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">5</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">6</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">No deployment</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Project.UseGlobal">true</value>
<value type="bool" key="Analyzer.Project.UseGlobal">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">false</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">false</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
</valuelist>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">QVTKViewport2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4RunConfiguration.BaseEnvironmentBase">2</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">QVTKViewport2.pro</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.Qt4RunConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
<value type="QString">{f8bb0047-7f6e-45df-9cc8-e746abebf883}</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">10</value>
</data>
</qtcreator>

View File

@@ -1,38 +0,0 @@
/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
------------------------------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
//////////////////////////////////////////////////////////////////////////////*/
#include <QtGui/QApplication>
#include "vtkviewport.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
VtkViewport w;
w.show();
return a.exec();
}

View File

@@ -1,41 +0,0 @@
/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
------------------------------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
//////////////////////////////////////////////////////////////////////////////*/
#include "vtkviewport.h"
#include "ui_vtkviewport.h"
VtkViewport::VtkViewport(QWidget *parent) :
QWidget(parent),
ui(new Ui::VtkViewport)
{
ui->setupUi(this);
}
VtkViewport::~VtkViewport()
{
delete ui;
}

View File

@@ -1,49 +0,0 @@
/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
------------------------------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
//////////////////////////////////////////////////////////////////////////////*/
#ifndef VTKVIEWPORT_H
#define VTKVIEWPORT_H
#include <QWidget>
namespace Ui {
class VtkViewport;
}
class VtkViewport : public QWidget
{
Q_OBJECT
public:
explicit VtkViewport(QWidget *parent = 0);
~VtkViewport();
private:
Ui::VtkViewport *ui;
};
#endif // VTKVIEWPORT_H

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VtkViewport</class>
<widget class="QWidget" name="VtkViewport">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>580</width>
<height>536</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>140</x>
<y>170</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Hello World !</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

12
src/HEP/CMakeLists.txt Normal file
View File

@@ -0,0 +1,12 @@
################################################################################
##### HEP - High Energy Physics modules ########################################
################################################################################
include_directories(${SRC_DIR}/HEP)
add_subdirectory(Detectors)
add_subdirectory(Geant)
set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} PARENT_SCOPE)
set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} PARENT_SCOPE)

View File

@@ -0,0 +1,34 @@
set(HEADERS
ChamberHitEvent.h
DetectorChamber.h
ExperimentFitEvent.h
HierarchicalEncoding.h
Hit.h
HitMC.h
LinearFit.h
MuonError.h
MuonEvent.h
MuonScatter.h
)
set(libname ${PACKAGE_LIBPREFIX}Detectors)
set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} ${libname} PARENT_SCOPE)
set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} Detectors PARENT_SCOPE)
## Headers-only INTERFACE library
add_library(${libname} INTERFACE)
target_include_directories(${libname} INTERFACE
$<BUILD_INTERFACE:${SRC_DIR}>
$<INSTALL_INTERFACE:${INSTALL_INC_DIR}>
)
install(TARGETS ${libname}
EXPORT "uLibTargets")
install(FILES ${HEADERS}
DESTINATION ${INSTALL_INC_DIR}/HEP/Detectors)
if(BUILD_TESTING)
include(uLibTargetMacros)
add_subdirectory(testing)
endif()

View File

@@ -0,0 +1,15 @@
# TESTS
set( TESTS
# GDMLSolidTest
HierarchicalEncodingTest
)
set(LIBRARIES
${PACKAGE_LIBPREFIX}Core
${PACKAGE_LIBPREFIX}Math
Boost::serialization
Boost::program_options
Eigen3::Eigen
${ROOT_LIBRARIES}
)
uLib_add_tests(Detectors)

View File

@@ -0,0 +1,52 @@
################################################################################
##### HEP/Geant - Geant4 integration library ###################################
################################################################################
find_package(Geant4 QUIET)
if(NOT Geant4_FOUND)
message(STATUS "Geant4 not found - skipping mutomGeant library")
return()
endif()
message(STATUS "Geant4 found: ${Geant4_VERSION}")
include(${Geant4_USE_FILE})
set(HEADERS
GeantEvent.h
Matter.h
Scene.h
Solid.h
)
set(SOURCES
Scene.cpp
Solid.cpp
)
set(libname ${PACKAGE_LIBPREFIX}Geant)
set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} ${libname} PARENT_SCOPE)
set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} Geant PARENT_SCOPE)
add_library(${libname} SHARED ${SOURCES})
set_target_properties(${libname} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION})
target_include_directories(${libname} PRIVATE ${Geant4_INCLUDE_DIRS})
target_link_libraries(${libname}
${PACKAGE_LIBPREFIX}Core
${PACKAGE_LIBPREFIX}Math
${PACKAGE_LIBPREFIX}Detectors
${Geant4_LIBRARIES}
)
install(TARGETS ${libname}
EXPORT "uLibTargets"
RUNTIME DESTINATION ${INSTALL_BIN_DIR} COMPONENT bin
LIBRARY DESTINATION ${INSTALL_LIB_DIR} COMPONENT lib)
install(FILES ${HEADERS}
DESTINATION ${INSTALL_INC_DIR}/HEP/Geant)

View File

@@ -23,8 +23,6 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef U_GEANTEVENT_H #ifndef U_GEANTEVENT_H
#define U_GEANTEVENT_H #define U_GEANTEVENT_H
@@ -38,32 +36,25 @@ namespace uLib {
class GeantEventData { class GeantEventData {
public: public:
uLibGetMacro (EventID, Id_t ) uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf)
uLibGetMacro (Momentum,Scalarf ) uLibConstRefMacro(GenPos, Vector3f) uLibConstRefMacro(GenDir, Vector3f)
uLibConstRefMacro (GenPos, Vector3f) uLibConstRefMacro(ChEvents, Vector<ChamberHitEventData>)
uLibConstRefMacro (GenDir, Vector3f)
uLibConstRefMacro (ChEvents,Vector<ChamberHitEventData>)
private: private : friend class GeantEvent;
friend class GeantEvent; Id_t m_EventID;
Id_t m_EventID; Scalarf m_Momentum;
Scalarf m_Momentum; Vector3f m_GenPos;
Vector3f m_GenPos; Vector3f m_GenDir;
Vector3f m_GenDir; Vector<ChamberHitEventData> m_ChEvents;
Vector<ChamberHitEventData> m_ChEvents;
}; };
class GeantEvent { class GeantEvent {
public: public:
uLibSetMacro (EventID, Id_t ) uLibSetMacro(EventID, Id_t) uLibSetMacro(Momentum, Scalarf)
uLibSetMacro (Momentum,Scalarf ) uLibRefMacro(GenPos, Vector3f) uLibRefMacro(GenDir, Vector3f)
uLibRefMacro (GenPos, Vector3f) uLibRefMacro(ChEvents, Vector<ChamberHitEventData>)
uLibRefMacro (GenDir, Vector3f)
uLibRefMacro (ChEvents,Vector<ChamberHitEventData>)
}; };
} // namespace uLib
}
#endif // GEANTEVENT_H #endif // GEANTEVENT_H

View File

@@ -43,18 +43,25 @@ set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} Math PARENT_SCOPE)
add_library(${libname} SHARED ${SOURCES}) add_library(${libname} SHARED ${SOURCES})
set_target_properties(${libname} PROPERTIES set_target_properties(${libname} PROPERTIES
VERSION ${PROJECT_VERSION} VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION}) SOVERSION ${PROJECT_SOVERSION}
CXX_STANDARD 17
CUDA_STANDARD 17)
target_link_libraries(${libname} ${LIBRARIES}) target_link_libraries(${libname} ${LIBRARIES})
if(USE_CUDA)
set_source_files_properties(VoxRaytracer.cpp VoxImage.cpp PROPERTIES LANGUAGE CUDA)
endif()
install(TARGETS ${libname} install(TARGETS ${libname}
EXPORT "${PROJECT_NAME}Targets" EXPORT "uLibTargets"
RUNTIME DESTINATION ${INSTALL_BIN_DIR} COMPONENT bin RUNTIME DESTINATION ${INSTALL_BIN_DIR} COMPONENT bin
LIBRARY DESTINATION ${INSTALL_LIB_DIR} COMPONENT lib) LIBRARY DESTINATION ${INSTALL_LIB_DIR} COMPONENT lib)
install(FILES ${HEADERS} DESTINATION ${INSTALL_INC_DIR}/Math) install(FILES ${HEADERS} DESTINATION ${INSTALL_INC_DIR}/Math)
# TESTING if(BUILD_TESTING)
# include(uLibTargetMacros) include(uLibTargetMacros)
# add_subdirectory(testing) add_subdirectory(testing)
endif()

View File

@@ -29,63 +29,147 @@
#define U_CONTAINERBOX_H #define U_CONTAINERBOX_H
#include "Geometry.h" #include "Geometry.h"
#include "Math/Dense.h"
#include "Math/Transform.h"
#include <utility>
namespace uLib { namespace uLib {
/**
* @brief Represents an oriented bounding box (OBB) within a hierarchical transformation system.
*
* ContainerBox inherits from AffineTransform, which defines its parent coordinate system.
* It contains an internal local transformation (m_LocalT) that defines the box's
* specific origin and size relative to its own coordinate system.
*/
class ContainerBox : public AffineTransform { class ContainerBox : public AffineTransform {
public:
ContainerBox() : m_LocalT(this) {}
typedef AffineTransform BaseClass;
public:
/**
* @brief Default constructor.
* Initializes the local transformation with this instance as its parent.
*/
ContainerBox() :
m_LocalT(this) // BaseClass is Parent of m_LocalTransform
{}
/**
* @brief Copy constructor.
* @param copy The ContainerBox instance to copy from.
*/
ContainerBox(const ContainerBox &copy) : ContainerBox(const ContainerBox &copy) :
m_LocalT(this), m_LocalT(this), // BaseClass is Parent of m_LocalTransform
AffineTransform(copy) AffineTransform(copy)
{ {
// FIX for performance //
this->SetOrigin(copy.GetOrigin()); this->SetOrigin(copy.GetOrigin());
this->SetSize(copy.GetSize()); this->SetSize(copy.GetSize());
} }
/**
* @brief Sets the box origin relative to its coordinate system.
* @param v The origin position vector.
*/
inline void SetOrigin(const Vector3f &v) { m_LocalT.SetPosition(v); } inline void SetOrigin(const Vector3f &v) { m_LocalT.SetPosition(v); }
/**
* @brief Gets the box origin relative to its coordinate system.
* @return The origin position vector.
*/
inline Vector3f GetOrigin() const { return m_LocalT.GetPosition(); } inline Vector3f GetOrigin() const { return m_LocalT.GetPosition(); }
/**
* @brief Sets the size of the box.
* Re-initializes the local transformation and applies the new scale.
* @param v The size vector (width, height, depth).
*/
void SetSize(const Vector3f &v) { void SetSize(const Vector3f &v) {
Vector3f pos = this->GetOrigin(); Vector3f pos = this->GetOrigin();
m_LocalT = AffineTransform(this); m_LocalT = AffineTransform(this); // regenerate local transform
m_LocalT.Scale(v); m_LocalT.Scale(v);
m_LocalT.SetPosition(pos); m_LocalT.SetPosition(pos);
} }
/**
* @brief Gets the current size (scale) of the box.
* @return The size vector.
*/
inline Vector3f GetSize() const { return m_LocalT.GetScale(); } inline Vector3f GetSize() const { return m_LocalT.GetScale(); }
// FIX... // /**
* @brief Swaps two local axes of the box.
* @param first Index of the first axis (0=X, 1=Y, 2=Z).
* @param second Index of the second axis (0=X, 1=Y, 2=Z).
*/
inline void FlipLocalAxes(int first, int second) inline void FlipLocalAxes(int first, int second)
{ m_LocalT.FlipAxes(first,second); } { m_LocalT.FlipAxes(first,second); }
/**
* @brief Returns the world transformation matrix of the box's volume.
* @return A 4x4 transformation matrix.
*/
Matrix4f GetWorldMatrix() const { return m_LocalT.GetWorldMatrix(); } Matrix4f GetWorldMatrix() const { return m_LocalT.GetWorldMatrix(); }
/**
* @brief Returns the local transformation matrix of the box's volume.
* @return A 4x4 transformation matrix.
*/
Matrix4f GetLocalMatrix() const { return m_LocalT.GetMatrix(); }
/**
* @brief Transforms a point from box-local space to world space.
* @param v The local point (4D homogeneous vector).
* @return The transformed point in world space.
*/
inline Vector4f GetWorldPoint(const Vector4f &v) const { inline Vector4f GetWorldPoint(const Vector4f &v) const {
return m_LocalT.GetWorldMatrix() * v; return m_LocalT.GetWorldMatrix() * v;
} }
/**
* @brief Transforms a point from box-local space coordinates to world space.
* @param x X coordinate in local space.
* @param y Y coordinate in local space.
* @param z Z coordinate in local space.
* @return The transformed point in world space.
*/
inline Vector4f GetWorldPoint(const float x, const float y, const float z) { inline Vector4f GetWorldPoint(const float x, const float y, const float z) {
return this->GetWorldPoint(Vector4f(x,y,z,1)); return this->GetWorldPoint(Vector4f(x,y,z,1));
} }
/**
* @brief Transforms a point from world space to box-local space.
* @param v The world point (4D homogeneous vector).
* @return The transformed point in box-local space.
*/
inline Vector4f GetLocalPoint(const Vector4f &v) const { inline Vector4f GetLocalPoint(const Vector4f &v) const {
return m_LocalT.GetWorldMatrix().inverse() * v; return m_LocalT.GetWorldMatrix().inverse() * v;
} }
/**
* @brief Transforms a point from world space coordinates to box-local space.
* @param x X coordinate in world space.
* @param y Y coordinate in world space.
* @param z Z coordinate in world space.
* @return The transformed point in box-local space.
*/
inline Vector4f GetLocalPoint(const float x, const float y, const float z) { inline Vector4f GetLocalPoint(const float x, const float y, const float z) {
return this->GetLocalPoint(Vector4f(x,y,z,1)); return this->GetLocalPoint(Vector4f(x,y,z,1));
} }
/** Translate using transformation chain */
using BaseClass::Translate;
protected: /** Rotate using transformation chain */
using BaseClass::Rotate;
/** Scale using transformation chain */
using BaseClass::Scale;
private: private:
AffineTransform m_LocalT; AffineTransform m_LocalT;
}; };

View File

@@ -47,6 +47,7 @@
#ifndef ULIB_DENSEMATRIX_H #ifndef ULIB_DENSEMATRIX_H
#define ULIB_DENSEMATRIX_H #define ULIB_DENSEMATRIX_H
// #include <Eigen/src/Core/Matrix.h>
#include <stdlib.h> #include <stdlib.h>
#include <Eigen/Dense> #include <Eigen/Dense>
@@ -114,6 +115,21 @@ typedef unsigned long Scalarul;
typedef float Scalarf; typedef float Scalarf;
typedef double Scalard; typedef double Scalard;
typedef Eigen::Matrix<int, 1, 1> Vector1i;
typedef Eigen::Vector2i Vector2i;
typedef Eigen::Vector3i Vector3i;
typedef Eigen::Vector4i Vector4i;
typedef Eigen::Matrix<float, 1, 1> Vector1f;
typedef Eigen::Vector2f Vector2f;
typedef Eigen::Vector3f Vector3f;
typedef Eigen::Vector4f Vector4f;
typedef Eigen::Matrix<double, 1, 1> Vector1d;
typedef Eigen::Vector2d Vector2d;
typedef Eigen::Vector3d Vector3d;
typedef Eigen::Vector4d Vector4d;
typedef Eigen::Matrix<int, 1, 1> Matrix1i; typedef Eigen::Matrix<int, 1, 1> Matrix1i;
typedef Eigen::Matrix2i Matrix2i; typedef Eigen::Matrix2i Matrix2i;
typedef Eigen::Matrix3i Matrix3i; typedef Eigen::Matrix3i Matrix3i;
@@ -124,15 +140,15 @@ typedef Eigen::Matrix2f Matrix2f;
typedef Eigen::Matrix3f Matrix3f; typedef Eigen::Matrix3f Matrix3f;
typedef Eigen::Matrix4f Matrix4f; typedef Eigen::Matrix4f Matrix4f;
typedef Eigen::Matrix<int, 1, 1> Vector1i; typedef Eigen::Matrix<double, 1, 1> Matrix1d;
typedef Eigen::Vector2i Vector2i; typedef Eigen::Matrix2d Matrix2d;
typedef Eigen::Vector3i Vector3i; typedef Eigen::Matrix3d Matrix3d;
typedef Eigen::Vector4i Vector4i; typedef Eigen::Matrix4d Matrix4d;
typedef Eigen::MatrixXi MatrixXi;
typedef Eigen::MatrixXf MatrixXf;
typedef Eigen::MatrixXd MatrixXd;
typedef Eigen::Matrix<float, 1, 1> Vector1f;
typedef Eigen::Vector2f Vector2f;
typedef Eigen::Vector3f Vector3f;
typedef Eigen::Vector4f Vector4f;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Vector String interaction /////////////////////////////////////////////////// // Vector String interaction ///////////////////////////////////////////////////
@@ -175,7 +191,7 @@ std::string VectorxT_ToString(const Eigen::Matrix<T, size, 1> &vec) {
// } // }
template <typename T, int size> template <typename T, int size>
void operator>>(std::string &str, Eigen::Matrix<T, size, 1> &vec) { void operator >> (std::string &str, Eigen::Matrix<T, size, 1> &vec) {
VectorxT_StringTo(vec, str); VectorxT_StringTo(vec, str);
} }
@@ -188,6 +204,9 @@ public:
typedef Eigen::Matrix<Scalarf, 4, 1> BaseClass; typedef Eigen::Matrix<Scalarf, 4, 1> BaseClass;
_HPoint3f() : BaseClass(0, 0, 0, p) {} _HPoint3f() : BaseClass(0, 0, 0, p) {}
_HPoint3f(int rows, int cols) : BaseClass() {
this->operator()(3) = p;
}
_HPoint3f(float x, float y, float z) : BaseClass(x, y, z, p) {} _HPoint3f(float x, float y, float z) : BaseClass(x, y, z, p) {}
_HPoint3f(Vector3f &in) : BaseClass(in.homogeneous()) { _HPoint3f(Vector3f &in) : BaseClass(in.homogeneous()) {
this->operator()(3) = p; this->operator()(3) = p;

View File

@@ -36,7 +36,7 @@ namespace uLib {
class Geometry : public AffineTransform { class Geometry : public AffineTransform {
public: public:
inline Vector4f GetWorldPoint(const Vector4f &v) const { inline Vector4f GetWorldPoint(const Vector4f v) const {
return this->GetWorldMatrix() * v; return this->GetWorldMatrix() * v;
} }
@@ -44,7 +44,7 @@ public:
return this->GetWorldPoint(Vector4f(x,y,z,1)); return this->GetWorldPoint(Vector4f(x,y,z,1));
} }
inline Vector4f GetLocalPoint(const Vector4f &v) const { inline Vector4f GetLocalPoint(const Vector4f v) const {
return this->GetWorldMatrix().inverse() * v; return this->GetWorldMatrix().inverse() * v;
} }

View File

@@ -84,8 +84,8 @@ public:
inline void SetParent(AffineTransform *name) { this->m_Parent = name; } inline void SetParent(AffineTransform *name) { this->m_Parent = name; }
inline void SetMatrix (Matrix4f &mat) { m_T.matrix() = mat; } inline void SetMatrix (Matrix4f mat) { m_T.matrix() = mat; }
inline Matrix4f& GetMatrix () { return m_T.matrix(); } inline Matrix4f GetMatrix() const { return m_T.matrix(); }
Matrix4f GetWorldMatrix() const Matrix4f GetWorldMatrix() const
{ {
@@ -93,22 +93,22 @@ public:
else return m_Parent->GetWorldMatrix() * m_T.matrix(); // T = B * A // else return m_Parent->GetWorldMatrix() * m_T.matrix(); // T = B * A //
} }
inline void SetPosition(const Vector3f &v) { this->m_T.translation() = v; } inline void SetPosition(const Vector3f v) { this->m_T.translation() = v; }
inline Vector3f GetPosition() const { return this->m_T.translation(); } inline Vector3f GetPosition() const { return this->m_T.translation(); }
inline void SetRotation(const Matrix3f &m) { this->m_T.linear() = m; } inline void SetRotation(const Matrix3f m) { this->m_T.linear() = m; }
inline Matrix3f GetRotation() const { return this->m_T.rotation(); } inline Matrix3f GetRotation() const { return this->m_T.rotation(); }
inline void Translate(const Vector3f &v) { this->m_T.translate(v); } inline void Translate(const Vector3f v) { this->m_T.translate(v); }
inline void Scale(const Vector3f &v) { this->m_T.scale(v); } inline void Scale(const Vector3f v) { this->m_T.scale(v); }
inline Vector3f GetScale() const { return this->m_T.linear() * Vector3f(1,1,1); } // FIXXXXXXX inline Vector3f GetScale() const { return this->m_T.linear() * Vector3f(1,1,1); } // FIXXXXXXX
inline void Rotate(const Matrix3f &m) { this->m_T.rotate(m); } inline void Rotate(const Matrix3f m) { this->m_T.rotate(m); }
inline void Rotate(const float angle, Vector3f axis) inline void Rotate(const float angle, Vector3f axis)
{ {
@@ -122,12 +122,12 @@ public:
Rotate(angle,euler_axis); Rotate(angle,euler_axis);
} }
inline void PreRotate(const Matrix3f &m) { this->m_T.prerotate(m); } inline void PreRotate(const Matrix3f m) { this->m_T.prerotate(m); }
inline void QuaternionRotate(const Vector4f &q) inline void QuaternionRotate(const Vector4f q)
{ this->m_T.rotate(Eigen::Quaternion<float>(q)); } { this->m_T.rotate(Eigen::Quaternion<float>(q)); }
inline void EulerYZYRotate(const Vector3f &e) { inline void EulerYZYRotate(const Vector3f e) {
Matrix3f mat; Matrix3f mat;
mat = Eigen::AngleAxisf(e.x(), Vector3f::UnitY()) mat = Eigen::AngleAxisf(e.x(), Vector3f::UnitY())
* Eigen::AngleAxisf(e.y(), Vector3f::UnitZ()) * Eigen::AngleAxisf(e.y(), Vector3f::UnitZ())

View File

@@ -23,8 +23,6 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef U_MATH_VOXIMAGE_H #ifndef U_MATH_VOXIMAGE_H
#define U_MATH_VOXIMAGE_H #define U_MATH_VOXIMAGE_H
@@ -36,6 +34,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <vector> #include <vector>
#include <Core/DataAllocator.h>
namespace uLib { namespace uLib {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -46,36 +46,36 @@ namespace Abstract {
class VoxImage : public uLib::StructuredGrid { class VoxImage : public uLib::StructuredGrid {
public: public:
typedef uLib::StructuredGrid BaseClass; typedef uLib::StructuredGrid BaseClass;
virtual float GetValue(const Vector3i &id) const = 0; virtual float GetValue(const Vector3i &id) const = 0;
virtual float GetValue(const int id) const = 0; virtual float GetValue(const int id) const = 0;
virtual void SetValue(const Vector3i &id, float value) = 0; virtual void SetValue(const Vector3i &id, float value) = 0;
virtual void SetValue(const int id, float value) = 0; virtual void SetValue(const int id, float value) = 0;
virtual void SetDims(const Vector3i &size) = 0; virtual void SetDims(const Vector3i &size) = 0;
void ExportToVtk(const char *file, bool density_type = 0); void ExportToVtk(const char *file, bool density_type = 0);
// use this function to export to VTK binary format // use this function to export to VTK binary format
void ExportToVti (const char *file, bool density_type = 0, bool compressed = 0); void ExportToVti(const char *file, bool density_type = 0,
bool compressed = 0);
// this function has been deprecated in favor of ExportToVti
// but it is kept for backward compatibility and because it
// does not depend on vtk library
void ExportToVtkXml(const char *file, bool density_type = 0);
int ImportFromVtk(const char *file, bool density_type = 0); // this function has been deprecated in favor of ExportToVti
// but it is kept for backward compatibility and because it
// does not depend on vtk library
void ExportToVtkXml(const char *file, bool density_type = 0);
int ImportFromVti(const char *file, bool density_type = 0); int ImportFromVtk(const char *file, bool density_type = 0);
int ImportFromVti(const char *file, bool density_type = 0);
virtual ~VoxImage() {}
protected: protected:
VoxImage(const Vector3i &size) : BaseClass(size) {}
virtual ~VoxImage() {}
VoxImage(const Vector3i &size) : BaseClass(size) {}
}; };
} } // namespace Abstract
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// VOXEL //////////////////////////////////////////////////////////////////// // VOXEL ////////////////////////////////////////////////////////////////////
@@ -83,421 +83,416 @@ protected:
namespace Interface { namespace Interface {
struct Voxel { struct Voxel {
template<class Self> void check_structural() { template <class Self> void check_structural() {
uLibCheckMember(Self,Value, Scalarf); uLibCheckMember(Self, Value, Scalarf);
} }
}; };
} } // namespace Interface
struct Voxel { struct Voxel {
Scalarf Value; Scalarf Value = 0.0f;
Scalari Count = 0;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// VOX IMAGE ///////////////////////////////////////////////////////////////// // VOX IMAGE /////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <typename T> class VoxImage : public Abstract::VoxImage {
template< typename T >
class VoxImage : public Abstract::VoxImage {
public: public:
typedef Abstract::VoxImage BaseClass; typedef Abstract::VoxImage BaseClass;
VoxImage(); VoxImage();
VoxImage(const Vector3i &size); VoxImage(const Vector3i &size);
VoxImage(const VoxImage<T> &copy) : VoxImage(const VoxImage<T> &copy) : BaseClass(copy) {
BaseClass(copy) this->m_Data = copy.m_Data;
{ }
this->m_Data = copy.m_Data;
inline DataAllocator<T> &Data() { return this->m_Data; }
inline const DataAllocator<T> &ConstData() const { return m_Data; }
inline const T &At(int i) const { return m_Data.at(i); }
inline const T &At(const Vector3i &id) const { return m_Data.at(Map(id)); }
inline T &operator[](unsigned int i) { return m_Data[i]; }
inline T &operator[](const Vector3i &id) { return m_Data[Map(id)]; }
// this implements Abstract interface //
inline Scalarf GetValue(const Vector3i &id) const {
return this->At(id).Value;
}
inline Scalarf GetValue(const int id) const { return this->At(id).Value; }
inline void SetValue(const Vector3i &id, Scalarf value) {
this->operator[](id).Value = value;
}
inline void SetValue(const int id, float value) {
this->operator[](id).Value = value;
}
inline void SetDims(const Vector3i &size) {
this->m_Data.resize(size.prod());
StructuredGrid::SetDims(size);
}
inline VoxImage<T> clipImage(const Vector3i begin, const Vector3i end) const;
inline VoxImage<T> clipImage(const HPoint3f begin, const HPoint3f end) const;
inline VoxImage<T> clipImage(const float density) const;
inline VoxImage<T> clipImage(const float densityMin,
const float densityMax) const;
inline VoxImage<T> maskImage(const HPoint3f begin, const HPoint3f end,
float value) const;
inline VoxImage<T> maskImage(const float threshold, float belowValue = 0,
float aboveValue = 0) const;
inline VoxImage<T> fixVoxels(const float threshold, float tolerance) const;
inline VoxImage<T> fixVoxels(const float threshold, float tolerance,
const HPoint3f begin, const HPoint3f end) const;
inline VoxImage<T> fixVoxelsAroundPlane(const float threshold,
float tolerance, const HPoint3f begin,
const HPoint3f end,
bool aboveAir) const;
inline VoxImage<T> fixVoxels(const HPoint3f begin, const HPoint3f end) const;
inline VoxImage<T> Abs() const;
inline void SelectScalarfComponent(T &element, Scalarf *scalar);
inline void InitVoxels(T t);
// MATH OPERATORS //
inline void operator*=(Scalarf scalar) {
for (unsigned int i = 0; i < m_Data.size(); ++i)
m_Data[i].Value *= scalar;
}
inline void operator+=(Scalarf scalar) {
for (unsigned int i = 0; i < m_Data.size(); ++i)
m_Data[i].Value += scalar;
}
inline void operator/=(Scalarf scalar) {
for (unsigned int i = 0; i < m_Data.size(); ++i)
m_Data[i].Value /= scalar;
}
inline void operator-=(Scalarf scalar) {
for (unsigned int i = 0; i < m_Data.size(); ++i)
m_Data[i].Value -= scalar;
}
// MATH VoxImage Operators //
template <typename S> void operator+=(VoxImage<S> &sibling) {
if (this->GetDims() != sibling.GetDims()) {
// printf("Warning when adding VoxImages: I'm NOT doing it!\n");
return;
} // WARNING! You must Warn the user!
for (unsigned int i = 0; i < m_Data.size(); ++i) {
m_Data[i].Value += sibling.At(i).Value;
} }
}
inline std::vector<T> & Data() { return this->m_Data; } template <typename S> void operator-=(VoxImage<S> &sibling) {
inline const std::vector<T>& ConstData() const { return m_Data; } if (this->GetDims() != sibling.GetDims()) {
// printf("Warning when subtracting VoxImages: I'm NOT doing it!\n");
inline const T& At(int i) const { return m_Data.at(i); } return;
inline const T& At(const Vector3i &id) const { return m_Data.at(Map(id)); } } // WARNING! You must Warn the user!
inline T& operator[](unsigned int i) { return m_Data[i]; } for (unsigned int i = 0; i < m_Data.size(); ++i) {
inline T& operator[](const Vector3i &id) { return m_Data[Map(id)]; } m_Data[i].Value -= sibling.At(i).Value;
// this implements Abstract interface //
inline Scalarf GetValue(const Vector3i &id) const {
return this->At(id).Value;
}
inline Scalarf GetValue(const int id) const {
return this->At(id).Value;
} }
}
inline void SetValue(const Vector3i &id, Scalarf value) { template <typename S> void operator*=(VoxImage<S> &sibling) {
this->operator [](id).Value = value; if (this->GetDims() != sibling.GetDims()) {
} // printf("Warning when multiplying VoxImages: I'm NOT doing it!\n");
inline void SetValue(const int id, float value) { return;
this->operator [](id).Value = value; } // WARNING! You must Warn the user!
for (unsigned int i = 0; i < m_Data.size(); ++i) {
m_Data[i].Value *= sibling.At(i).Value;
} }
}
inline void SetDims(const Vector3i &size) { template <typename S> void operator/=(VoxImage<S> &sibling) {
this->m_Data.resize(size.prod()); if (this->GetDims() != sibling.GetDims()) {
BaseClass::BaseClass::SetDims(size); // FIX horrible coding style ! // printf("Warning when dividing VoxImages: I'm NOT doing it!\n");
} return;
} // WARNING! You must Warn the user!
inline VoxImage<T> clipImage(const Vector3i begin, const Vector3i end) const; for (unsigned int i = 0; i < m_Data.size(); ++i) {
inline VoxImage<T> clipImage(const HPoint3f begin, const HPoint3f end) const; m_Data[i].Value /= sibling.At(i).Value;
inline VoxImage<T> clipImage(const float density) const;
inline VoxImage<T> clipImage(const float densityMin, const float densityMax) const;
inline VoxImage<T> maskImage(const HPoint3f begin, const HPoint3f end, float value) const;
inline VoxImage<T> maskImage(const float threshold, float belowValue=0, float aboveValue=0) const;
inline VoxImage<T> fixVoxels(const float threshold, float tolerance) const;
inline VoxImage<T> fixVoxels(const float threshold, float tolerance, const HPoint3f begin, const HPoint3f end) const;
inline VoxImage<T> fixVoxelsAroundPlane(const float threshold, float tolerance, const HPoint3f begin, const HPoint3f end, bool aboveAir) const;
inline VoxImage<T> fixVoxels(const HPoint3f begin, const HPoint3f end) const;
inline VoxImage<T> Abs() const;
inline void SelectScalarfComponent(T &element, Scalarf *scalar);
inline void InitVoxels(T t);
// MATH OPERATORS //
inline void operator *=(Scalarf scalar) {
for(unsigned int i = 0; i < m_Data.size(); ++i)
m_Data[i].Value *= scalar;
}
inline void operator +=(Scalarf scalar) {
for(unsigned int i = 0; i < m_Data.size(); ++i)
m_Data[i].Value += scalar;
}
inline void operator /=(Scalarf scalar) {
for(unsigned int i = 0; i < m_Data.size(); ++i)
m_Data[i].Value /= scalar;
}
inline void operator -=(Scalarf scalar) {
for(unsigned int i = 0; i < m_Data.size(); ++i)
m_Data[i].Value -= scalar;
}
// MATH VoxImage Operators //
template <typename S>
void operator +=(VoxImage<S> &sibling) {
if (this->GetDims() != sibling.GetDims()) {
//printf("Warning when adding VoxImages: I'm NOT doing it!\n");
return;
}// WARNING! You must Warn the user!
for(unsigned int i = 0; i < m_Data.size(); ++i) {
m_Data[i].Value += sibling.At(i).Value;
}
}
template <typename S>
void operator -=(VoxImage<S> &sibling) {
if (this->GetDims() != sibling.GetDims()) {
//printf("Warning when subtracting VoxImages: I'm NOT doing it!\n");
return;
}// WARNING! You must Warn the user!
for(unsigned int i = 0; i < m_Data.size(); ++i) {
m_Data[i].Value -= sibling.At(i).Value;
}
}
template <typename S>
void operator *=(VoxImage<S> &sibling) {
if (this->GetDims() != sibling.GetDims()) {
//printf("Warning when multiplying VoxImages: I'm NOT doing it!\n");
return;
}// WARNING! You must Warn the user!
for(unsigned int i = 0; i < m_Data.size(); ++i) {
m_Data[i].Value *= sibling.At(i).Value;
}
}
template <typename S>
void operator /=(VoxImage<S> &sibling) {
if (this->GetDims() != sibling.GetDims()) {
//printf("Warning when dividing VoxImages: I'm NOT doing it!\n");
return;
}// WARNING! You must Warn the user!
for(unsigned int i = 0; i < m_Data.size(); ++i) {
m_Data[i].Value /= sibling.At(i).Value;
}
} }
}
private: private:
std::vector<T> m_Data; DataAllocator<T> m_Data;
}; };
template<typename T>
VoxImage<T>::VoxImage() :
m_Data(0),
BaseClass(Vector3i(0,0,0))
{ Interface::IsA <T,Interface::Voxel>(); /* structural check for T */ }
template<typename T>
VoxImage<T>::VoxImage(const Vector3i &size) :
m_Data(size.prod()),
BaseClass(size)
{ Interface::IsA <T,Interface::Voxel>(); /* structural check for T */ }
template <typename T> template <typename T>
VoxImage<T> VoxImage<T>::clipImage(const Vector3i begin, const Vector3i end) const VoxImage<T>::VoxImage() : m_Data(0), BaseClass(Vector3i(0, 0, 0)) {
{ Interface::IsA<T, Interface::Voxel>(); /* structural check for T */
Vector3i dim = (end-begin)+Vector3i(1,1,1);
VoxImage<T> out(*this);
out.SetDims(dim);
out.SetPosition(this->GetPosition() + this->GetSpacing().cwiseProduct(begin.cast<float>()) );
for(uint x = 0; x<dim(0); ++x )
for(uint y = 0; y<dim(1); ++y )
for(uint z = 0; z<dim(2); ++z )
{
Vector3i id = Vector3i(x,y,z);
out[id] = this->At(begin + id);
}
return out;
} }
template <typename T> template <typename T>
VoxImage<T> VoxImage<T>::clipImage(const HPoint3f begin, const HPoint3f end) const VoxImage<T>::VoxImage(const Vector3i &size)
{ : m_Data(size.prod()), BaseClass(size) {
Vector3i v1 = this->Find(begin); Interface::IsA<T, Interface::Voxel>(); /* structural check for T */
Vector3i v2 = this->Find(end);
return this->clipImage(v1,v2);
} }
template <typename T> template <typename T>
VoxImage<T> VoxImage<T>::clipImage(const float density) const VoxImage<T> VoxImage<T>::clipImage(const Vector3i begin,
{ const Vector3i end) const {
Vector3i v1 = this->GetDims(); Vector3i dim = (end - begin) + Vector3i(1, 1, 1);
Vector3i v2 = Vector3i(0,0,0); VoxImage<T> out(*this);
for(uint i=0; i< this->m_Data.size(); ++i) { out.SetDims(dim);
if( this->GetValue(i) >= density ) { out.SetPosition(this->GetPosition() +
Vector3i id = this->UnMap(i); this->GetSpacing().cwiseProduct(begin.cast<float>()));
v1 = v1.array().min(id.array());
v2 = v2.array().max(id.array()); for (uint x = 0; x < dim(0); ++x)
} for (uint y = 0; y < dim(1); ++y)
for (uint z = 0; z < dim(2); ++z) {
Vector3i id = Vector3i(x, y, z);
out[id] = this->At(begin + id);
}
return out;
}
template <typename T>
VoxImage<T> VoxImage<T>::clipImage(const HPoint3f begin,
const HPoint3f end) const {
Vector3i v1 = this->Find(begin);
Vector3i v2 = this->Find(end);
return this->clipImage(v1, v2);
}
template <typename T>
VoxImage<T> VoxImage<T>::clipImage(const float density) const {
Vector3i v1 = this->GetDims();
Vector3i v2 = Vector3i(0, 0, 0);
for (uint i = 0; i < this->m_Data.size(); ++i) {
if (this->GetValue(i) >= density) {
Vector3i id = this->UnMap(i);
v1 = v1.array().min(id.array());
v2 = v2.array().max(id.array());
} }
return this->clipImage(v1,v2); }
return this->clipImage(v1, v2);
} }
template <typename T> template <typename T>
VoxImage<T> VoxImage<T>::clipImage(const float densityMin, const float densityMax) const VoxImage<T> VoxImage<T>::clipImage(const float densityMin,
{ const float densityMax) const {
Vector3i v1 = this->GetDims(); Vector3i v1 = this->GetDims();
Vector3i v2 = Vector3i(0,0,0); Vector3i v2 = Vector3i(0, 0, 0);
for(uint i=0; i< this->m_Data.size(); ++i) { for (uint i = 0; i < this->m_Data.size(); ++i) {
if( this->GetValue(i) >= densityMin && this->GetValue(i) <= densityMax) { if (this->GetValue(i) >= densityMin && this->GetValue(i) <= densityMax) {
Vector3i id = this->UnMap(i); Vector3i id = this->UnMap(i);
v1 = v1.array().min(id.array()); v1 = v1.array().min(id.array());
v2 = v2.array().max(id.array()); v2 = v2.array().max(id.array());
}
} }
return this->clipImage(v1,v2); }
return this->clipImage(v1, v2);
} }
template <typename T> template <typename T>
VoxImage<T> VoxImage<T>::maskImage(const HPoint3f begin, const HPoint3f end, float value) const VoxImage<T> VoxImage<T>::maskImage(const HPoint3f begin, const HPoint3f end,
{ float value) const {
VoxImage<T> out(*this); VoxImage<T> out(*this);
out.SetDims(this->GetDims()); out.SetDims(this->GetDims());
out.SetPosition(this->GetPosition()); out.SetPosition(this->GetPosition());
Vector3i voxB = this->Find(begin); Vector3i voxB = this->Find(begin);
Vector3i voxE = this->Find(end); Vector3i voxE = this->Find(end);
Vector3i ID; Vector3i ID;
for(int ix=voxB(0); ix<voxE(0); ix++) for (int ix = voxB(0); ix < voxE(0); ix++)
for(int iy=voxB(1); iy<voxE(1); iy++) for (int iy = voxB(1); iy < voxE(1); iy++)
for(int iz=voxB(2); iz<voxE(2); iz++){ for (int iz = voxB(2); iz < voxE(2); iz++) {
ID << ix,iy,iz; ID << ix, iy, iz;
out.SetValue(ID,value*1.E-6); out.SetValue(ID, value * 1.E-6);
} }
return out; return out;
} }
template <typename T> template <typename T>
VoxImage<T> VoxImage<T>::maskImage(const float threshold, float belowValue, float aboveValue) const VoxImage<T> VoxImage<T>::maskImage(const float threshold, float belowValue,
{ float aboveValue) const {
std::cout << "VoxImage: maskImage, fixing voxels under threshold " << threshold; std::cout << "VoxImage: maskImage, fixing voxels under threshold "
if(belowValue) << threshold;
std::cout << " at value " << belowValue; if (belowValue)
else std::cout << " at value " << belowValue;
std::cout << " at -value"; else
std::cout << ", voxels above threshold at value "; std::cout << " at -value";
if(aboveValue) std::cout << ", voxels above threshold at value ";
std::cout << aboveValue; if (aboveValue)
else std::cout << aboveValue;
std::cout << "found"; else
std::cout << "found";
VoxImage<T> out(*this);
out.SetDims(this->GetDims());
out.SetPosition(this->GetPosition());
VoxImage<T> out(*this); for (uint i = 0; i < this->m_Data.size(); ++i) {
out.SetDims(this->GetDims()); // skip negative voxels: they are already frozen
out.SetPosition(this->GetPosition()); if (this->GetValue(i) >= 0) {
// voxels under threshold
for(uint i=0; i< this->m_Data.size(); ++i) { if (this->GetValue(i) <= threshold * 1.E-6) {
// skip negative voxels: they are already frozen if (belowValue) {
if( this->GetValue(i) >= 0 ){ // std::cout << "vox " << i << ", " <<
// voxels under threshold // this->GetValue(i); std::cout << " ----> set to " <<
if( this->GetValue(i) <= threshold*1.E-6 ){ // -1.*belowValue*1.E-6 << std::endl;
if(belowValue){ out.SetValue(i, -1. * belowValue * 1.E-6);
// std::cout << "vox " << i << ", " << this->GetValue(i); } else
// std::cout << " ----> set to " << -1.*belowValue*1.E-6 << std::endl; out.SetValue(i, -1. * this->GetValue(i));
out.SetValue(i,-1.*belowValue*1.E-6);} }
else // voxels over threshold
out.SetValue(i,-1.*this->GetValue(i)); else {
} if (aboveValue)
// voxels over threshold out.SetValue(i, aboveValue * 1.E-6);
else{ else
if(aboveValue) out.SetValue(i, this->GetValue(i));
out.SetValue(i,aboveValue*1.E-6); }
else
out.SetValue(i,this->GetValue(i));
}
}
} }
return out; }
return out;
} }
template <typename T> template <typename T>
VoxImage<T> VoxImage<T>::fixVoxels(const float threshold, float tolerance) const VoxImage<T> VoxImage<T>::fixVoxels(const float threshold,
{ float tolerance) const {
std::cout << "VoxImage: fixing voxels with value " << threshold << std::endl; std::cout << "VoxImage: fixing voxels with value " << threshold << std::endl;
VoxImage<T> out(*this); VoxImage<T> out(*this);
out.SetDims(this->GetDims()); out.SetDims(this->GetDims());
out.SetPosition(this->GetPosition()); out.SetPosition(this->GetPosition());
for(uint i=0; i< this->m_Data.size(); ++i) { for (uint i = 0; i < this->m_Data.size(); ++i) {
// voxels around threshold
if (fabs(this->GetValue(i) - threshold * 1.E-6) < tolerance * 1.E-6) {
// std::cout << "vox " << i << ", " << this->GetValue(i);
// std::cout << " ----> set to " << -1.*this->GetValue(i) <<
// std::endl;
out.SetValue(i, -1. * this->GetValue(i));
}
}
return out;
}
template <typename T> VoxImage<T> VoxImage<T>::Abs() const {
std::cout << "VoxImage: set abs voxels value " << std::endl;
VoxImage<T> out(*this);
out.SetDims(this->GetDims());
out.SetPosition(this->GetPosition());
for (uint i = 0; i < this->m_Data.size(); ++i)
out.SetValue(i, fabs(this->GetValue(i)));
return out;
}
template <typename T>
VoxImage<T> VoxImage<T>::fixVoxels(const float threshold, float tolerance,
const HPoint3f begin,
const HPoint3f end) const {
VoxImage<T> out(*this);
out.SetDims(this->GetDims());
out.SetPosition(this->GetPosition());
Vector3i voxB = this->Find(begin);
Vector3i voxE = this->Find(end);
Vector3i ID;
for (int ix = voxB(0); ix < voxE(0); ix++)
for (int iy = voxB(1); iy < voxE(1); iy++)
for (int iz = voxB(2); iz < voxE(2); iz++) {
ID << ix, iy, iz;
// voxels around threshold // voxels around threshold
if( fabs(this->GetValue(i) - threshold*1.E-6) < tolerance* 1.E-6 ){ if (fabs(this->GetValue(ID) - threshold * 1.E-6) < tolerance * 1.E-6) {
// std::cout << "vox " << i << ", " << this->GetValue(i); out.SetValue(ID, -1. * this->GetValue(ID));
// std::cout << " ----> set to " << -1.*this->GetValue(i) << std::endl;
out.SetValue(i,-1.*this->GetValue(i));
} }
} }
return out;
return out;
} }
template <typename T> template <typename T>
VoxImage<T> VoxImage<T>::Abs() const VoxImage<T> VoxImage<T>::fixVoxels(const HPoint3f begin,
{ const HPoint3f end) const {
std::cout << "VoxImage: set abs voxels value " << std::endl; VoxImage<T> out(*this);
out.SetDims(this->GetDims());
out.SetPosition(this->GetPosition());
VoxImage<T> out(*this); Vector3i voxB = this->Find(begin);
out.SetDims(this->GetDims()); Vector3i voxE = this->Find(end);
out.SetPosition(this->GetPosition());
for(uint i=0; i< this->m_Data.size(); ++i) Vector3i ID;
out.SetValue(i,fabs(this->GetValue(i)));
return out; for (int ix = voxB(0); ix < voxE(0); ix++)
for (int iy = voxB(1); iy < voxE(1); iy++)
for (int iz = voxB(2); iz < voxE(2); iz++) {
ID << ix, iy, iz;
// voxels around threshold
out.SetValue(ID, -1. * this->GetValue(ID));
}
return out;
} }
template <typename T> template <typename T>
VoxImage<T> VoxImage<T>::fixVoxels( const float threshold, float tolerance, const HPoint3f begin, const HPoint3f end) const VoxImage<T> VoxImage<T>::fixVoxelsAroundPlane(const float threshold,
{ float tolerance, const HPoint3f B,
VoxImage<T> out(*this); const HPoint3f E,
out.SetDims(this->GetDims()); bool aboveAir) const {
out.SetPosition(this->GetPosition()); VoxImage<T> out(*this);
Vector3i dim = this->GetDims();
out.SetDims(dim);
out.SetPosition(this->GetPosition());
Vector3i voxB = this->Find(begin); HPoint3f Bcoll = this->GetPosition().homogeneous();
Vector3i voxE = this->Find(end);
Vector3i ID; Vector3i ID;
for (int ix = 0; ix < dim(0); ix++)
for (int iy = 0; iy < dim(1); iy++)
for (int iz = 0; iz < dim(2); iz++) {
ID << ix, iy, iz;
for(int ix=voxB(0); ix<voxE(0); ix++) // B, E voxel position
for(int iy=voxB(1); iy<voxE(1); iy++) Vector3i iv(ix, iy, iz);
for(int iz=voxB(2); iz<voxE(2); iz++){ Vector3f v =
ID << ix,iy,iz; Vector3f(iv.cast<float>().cwiseProduct(this->GetSpacing()));
// voxels around threshold HPoint3f Bvox = Bcoll + HPoint3f(v);
if( fabs(this->GetValue(ID) - threshold*1.E-6) < tolerance*1.E-6 ){ HPoint3f Evox = Bvox + this->GetSpacing().homogeneous();
out.SetValue(ID,-1.*this->GetValue(ID)); HPoint3f V = Bvox + 0.5 * (this->GetSpacing().homogeneous());
}
}
return out; // if distance point (x0,y0) from line by points (x1,y1) and (x2,y2) is
// less than tolerance
float x1 = B[1];
float y1 = B[2];
float x2 = E[1];
float y2 = E[2];
float x0 = V[1];
float y0 = V[2];
float dist = fabs((x2 - x1) * (y1 - y0) - ((x1 - x0) * (y2 - y1))) /
sqrt((x2 - x1) * (x2 - x1) + ((y2 - y1) * (y2 - y1)));
float distSign = (x2 - x1) * (y1 - y0) - ((x1 - x0) * (y2 - y1));
// set voxel air value
if (dist < tolerance) {
// std::cout << "voxel " << iv << ", line " << dist << ", tolerance "
// << tolerance << std::endl;
out.SetValue(ID, threshold * 1.E-6);
} else
out.SetValue(ID, this->GetValue(ID));
if ((distSign > 0 && aboveAir) || (distSign < 0 && !aboveAir))
out.SetValue(ID, threshold * 1.E-6);
}
return out;
} }
template <typename T> template <typename T> void VoxImage<T>::InitVoxels(T t) {
VoxImage<T> VoxImage<T>::fixVoxels(const HPoint3f begin, const HPoint3f end) const std::fill(m_Data.begin(), m_Data.end(), t); // warning... stl function //
{
VoxImage<T> out(*this);
out.SetDims(this->GetDims());
out.SetPosition(this->GetPosition());
Vector3i voxB = this->Find(begin);
Vector3i voxE = this->Find(end);
Vector3i ID;
for(int ix=voxB(0); ix<voxE(0); ix++)
for(int iy=voxB(1); iy<voxE(1); iy++)
for(int iz=voxB(2); iz<voxE(2); iz++){
ID << ix,iy,iz;
// voxels around threshold
out.SetValue(ID,-1.*this->GetValue(ID));
}
return out;
} }
} // namespace uLib
template <typename T>
VoxImage<T> VoxImage<T>::fixVoxelsAroundPlane( const float threshold, float tolerance, const HPoint3f B, const HPoint3f E, bool aboveAir) const
{
VoxImage<T> out(*this);
Vector3i dim = this->GetDims();
out.SetDims(dim);
out.SetPosition(this->GetPosition());
HPoint3f Bcoll = this->GetPosition().homogeneous();
Vector3i ID;
for(int ix=0; ix<dim(0); ix++)
for(int iy=0; iy<dim(1); iy++)
for(int iz=0; iz<dim(2); iz++){
ID << ix,iy,iz;
// B, E voxel position
Vector3i iv(ix,iy,iz);
Vector3f v = Vector3f(iv.cast<float>().cwiseProduct(this->GetSpacing()));
HPoint3f Bvox = Bcoll + HPoint3f(v);
HPoint3f Evox = Bvox + this->GetSpacing().homogeneous();
HPoint3f V = Bvox + 0.5*(this->GetSpacing().homogeneous());
// if distance point (x0,y0) from line by points (x1,y1) and (x2,y2) is less than tolerance
float x1 = B[1];
float y1 = B[2];
float x2 = E[1];
float y2 = E[2];
float x0 = V[1];
float y0 = V[2];
float dist = fabs( (x2-x1)*(y1-y0) - ((x1-x0)*(y2-y1))) / sqrt( (x2-x1)*(x2-x1)+((y2-y1)*(y2-y1)));
float distSign = (x2-x1)*(y1-y0) - ((x1-x0)*(y2-y1));
// set voxel air value
if(dist < tolerance){
//std::cout << "voxel " << iv << ", line " << dist << ", tolerance " << tolerance << std::endl;
out.SetValue(ID,threshold*1.E-6);
}
else
out.SetValue(ID,this->GetValue(ID));
if((distSign>0 && aboveAir) || (distSign<0 && !aboveAir) )
out.SetValue(ID,threshold*1.E-6);
}
return out;
}
template<typename T>
void VoxImage<T>::InitVoxels(T t)
{
std::fill( m_Data.begin(), m_Data.end(), t ); // warning... stl function //
}
}
#endif // VOXIMAGE_H #endif // VOXIMAGE_H

View File

@@ -23,8 +23,6 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef VOXIMAGEFILTER_H #ifndef VOXIMAGEFILTER_H
#define VOXIMAGEFILTER_H #define VOXIMAGEFILTER_H
@@ -33,96 +31,83 @@
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
namespace uLib { namespace uLib {
namespace Interface { namespace Interface {
struct VoxImageFilterShape { struct VoxImageFilterShape {
template <class Self> void check_structural() { template <class Self> void check_structural() {
uLibCheckFunction(Self,operator(),float,float); uLibCheckFunction(Self, operator(), float, float);
uLibCheckFunction(Self,operator(),float,const Vector3f&); uLibCheckFunction(Self, operator(), float, const Vector3f &);
} }
}; };
} } // namespace Interface
template < typename VoxelT > class Kernel;
template <typename VoxelT> class Kernel;
namespace Abstract { namespace Abstract {
class VoxImageFilter { class VoxImageFilter {
public: public:
virtual void Run() = 0; virtual void Run() = 0;
virtual void SetImage(Abstract::VoxImage *image) = 0; virtual void SetImage(Abstract::VoxImage *image) = 0;
protected: protected:
virtual ~VoxImageFilter() {} virtual ~VoxImageFilter() {}
}; };
} } // namespace Abstract
template <typename VoxelT, typename AlgorithmT>
template < typename VoxelT, typename AlgorithmT > class VoxImageFilter : public Abstract::VoxImageFilter {
class VoxImageFilter : public Abstract::VoxImageFilter
{
public: public:
VoxImageFilter(const Vector3i &size); VoxImageFilter(const Vector3i &size);
void Run(); void Run();
void SetKernelNumericXZY(const std::vector<float> &numeric); void SetKernelNumericXZY(const std::vector<float> &numeric);
void SetKernelSpherical(float (*shape)(float)); void SetKernelSpherical(float (*shape)(float));
template < class ShapeT > template <class ShapeT> void SetKernelSpherical(ShapeT shape);
void SetKernelSpherical( ShapeT shape );
void SetKernelWeightFunction(float (*shape)(const Vector3f &)); void SetKernelWeightFunction(float (*shape)(const Vector3f &));
template < class ShapeT > template <class ShapeT> void SetKernelWeightFunction(ShapeT shape);
void SetKernelWeightFunction( ShapeT shape );
inline Kernel<VoxelT> GetKernelData() const { return this->m_KernelData; } inline const Kernel<VoxelT> &GetKernelData() const {
return this->m_KernelData;
}
inline Kernel<VoxelT> &GetKernelData() { return this->m_KernelData; }
inline VoxImage<VoxelT>* GetImage() const { return this->m_Image; } inline VoxImage<VoxelT> *GetImage() const { return this->m_Image; }
void SetImage(Abstract::VoxImage *image); void SetImage(Abstract::VoxImage *image);
protected: protected:
float Convolve(const VoxImage<VoxelT> &buffer, int index); // remove //
float Convolve(const VoxImage<VoxelT> &buffer, int index); // remove // void SetKernelOffset();
void SetKernelOffset(); float Distance2(const Vector3i &v);
float Distance2(const Vector3i &v); // protected members for algorithm access //
Kernel<VoxelT> m_KernelData;
// protected members for algorithm access // VoxImage<VoxelT> *m_Image;
Kernel<VoxelT> m_KernelData;
VoxImage<VoxelT> *m_Image;
private: private:
AlgorithmT *t_Algoritm; AlgorithmT *t_Algoritm;
}; };
} // namespace uLib
}
#endif // VOXIMAGEFILTER_H #endif // VOXIMAGEFILTER_H
#include "VoxImageFilter.hpp" #include "VoxImageFilter.hpp"
#include "VoxImageFilterLinear.hpp" #include "VoxImageFilter2ndStat.hpp"
#include "VoxImageFilterThreshold.hpp"
#include "VoxImageFilterMedian.hpp"
#include "VoxImageFilterABTrim.hpp" #include "VoxImageFilterABTrim.hpp"
#include "VoxImageFilterBilateral.hpp" #include "VoxImageFilterBilateral.hpp"
#include "VoxImageFilter2ndStat.hpp"
#include "VoxImageFilterCustom.hpp" #include "VoxImageFilterCustom.hpp"
#include "VoxImageFilterLinear.hpp"
#include "VoxImageFilterMedian.hpp"
#include "VoxImageFilterThreshold.hpp"

View File

@@ -23,280 +23,238 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef VOXIMAGEFILTER_HPP #ifndef VOXIMAGEFILTER_HPP
#define VOXIMAGEFILTER_HPP #define VOXIMAGEFILTER_HPP
#include <Math/Dense.h>
#include "Math/StructuredData.h" #include "Math/StructuredData.h"
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
#include "VoxImageFilter.h" #include "VoxImageFilter.h"
#include <Math/Dense.h>
namespace uLib { namespace uLib {
// KERNEL ////////////////////////////////////////////////////////////////////// // KERNEL //////////////////////////////////////////////////////////////////////
template < typename T > template <typename T> class Kernel : public StructuredData {
class Kernel : public StructuredData { typedef StructuredData BaseClass;
typedef StructuredData BaseClass;
public: public:
Kernel(const Vector3i &size); Kernel(const Vector3i &size);
inline T& operator[](const Vector3i &id) { return m_Data[Map(id)]; } inline T &operator[](const Vector3i &id) { return m_Data[Map(id)]; }
inline T& operator[](const int &id) { return m_Data[id]; } inline T &operator[](const int &id) { return m_Data[id]; }
inline int GetCenterData() const; inline int GetCenterData() const;
inline std::vector<T> & Data() { return this->m_Data; } inline DataAllocator<T> &Data() { return this->m_Data; }
inline const std::vector<T>& ConstData() const { return this->m_Data; } inline const DataAllocator<T> &ConstData() const { return this->m_Data; }
void PrintSelf(std::ostream &o) const; void PrintSelf(std::ostream &o) const;
private: private:
std::vector<T> m_Data; DataAllocator<T> m_Data;
}; };
template < typename T > template <typename T>
Kernel<T>::Kernel(const Vector3i &size) : Kernel<T>::Kernel(const Vector3i &size) : BaseClass(size), m_Data(size.prod()) {
BaseClass(size), Interface::IsA<T, Interface::Voxel>();
m_Data(size.prod())
{
Interface::IsA<T,Interface::Voxel>();
} }
template < typename T > template <typename T> inline int Kernel<T>::GetCenterData() const {
inline int Kernel<T>::GetCenterData() const static int center = Map(this->GetDims() / 2);
{ return center;
static int center = Map(this->GetDims() / 2);
return center;
} }
template < typename T > template <typename T> void Kernel<T>::PrintSelf(std::ostream &o) const {
void Kernel<T>::PrintSelf(std::ostream &o) const o << " Filter Kernel Dump [XZ_Y]: \n";
{ Vector3i index;
o << " Filter Kernel Dump [XZ_Y]: \n"; o << "\n Value: \n\n"
Vector3i index; << "------------------------------------------------- \n";
o << "\n Value: \n\n" for (int y = 0; y < this->GetDims()(1); ++y) {
<< "------------------------------------------------- \n"; o << "[y=" << y << "]\n";
for (int y = 0 ; y < this->GetDims()(1); ++y ) { for (int z = 0; z < this->GetDims()(2); ++z) {
o << "[y=" << y << "]\n"; for (int x = 0; x < this->GetDims()(0); ++x) {
for (int z = 0 ; z < this->GetDims()(2); ++z ) { index << x, y, z;
for (int x = 0 ; x < this->GetDims()(0); ++x ) { o << m_Data[Map(index)].Value << " ";
index << x,y,z; }
o << m_Data[Map(index)].Value << " "; o << "\n";
} o << "\n";
} o << " --------------------------------------------------- \n";
} }
o << "\n Offset: \n" o << " --------------------------------------------------- \n";
<< "------------------------------------------------- \n"; }
for (int y = 0 ; y < this->GetDims()(1); ++y ) { o << "\n Offset: \n"
o << "[y=" << y << "]\n"; << "------------------------------------------------- \n";
for (int z = 0 ; z < this->GetDims()(2); ++z ) { for (int y = 0; y < this->GetDims()(1); ++y) {
for (int x = 0 ; x < this->GetDims()(0); ++x ) { o << "[y=" << y << "]\n";
index << x,y,z; for (int z = 0; z < this->GetDims()(2); ++z) {
o << m_Data[Map(index)].Count << " "; for (int x = 0; x < this->GetDims()(0); ++x) {
} o << "\n"; index << x, y, z;
} o << " --------------------------------------------------- \n"; o << m_Data[Map(index)].Count << " ";
}
o << "\n";
} }
o << " --------------------------------------------------- \n";
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define _TPL_ template <typename VoxelT, typename AlgorithmT>
#define _TPLT_ VoxelT, AlgorithmT
#define _TPL_ template < typename VoxelT , typename AlgorithmT >
#define _TPLT_ VoxelT,AlgorithmT
_TPL_ _TPL_
VoxImageFilter<_TPLT_>::VoxImageFilter(const Vector3i &size) : VoxImageFilter<_TPLT_>::VoxImageFilter(const Vector3i &size)
m_KernelData(size), : m_KernelData(size), t_Algoritm(static_cast<AlgorithmT *>(this)) {}
t_Algoritm(static_cast<AlgorithmT *>(this))
{
_TPL_
void VoxImageFilter<_TPLT_>::Run() {
VoxImage<VoxelT> buffer = *m_Image;
#pragma omp parallel for
for (int i = 0; i < m_Image->Data().size(); ++i)
m_Image->operator[](i).Value = this->t_Algoritm->Evaluate(buffer, i);
#pragma omp barrier
} }
_TPL_ _TPL_
void VoxImageFilter<_TPLT_>::Run() void VoxImageFilter<_TPLT_>::SetKernelOffset() {
{ Vector3i id(0, 0, 0);
VoxImage<VoxelT> buffer = *m_Image; for (int z = 0; z < m_KernelData.GetDims()(2); ++z) {
#pragma omp parallel for for (int x = 0; x < m_KernelData.GetDims()(0); ++x) {
for(int i=0 ; i < m_Image->Data().size() ; ++i) for (int y = 0; y < m_KernelData.GetDims()(1); ++y) {
m_Image->operator [](i).Value = this->t_Algoritm->Evaluate(buffer,i); id << x, y, z;
#pragma omp barrier m_KernelData[id].Count = id.transpose() * m_Image->GetIncrements();
} }
_TPL_
void VoxImageFilter<_TPLT_>::SetKernelOffset()
{
Vector3i id(0,0,0);
for( int z=0 ; z < m_KernelData.GetDims()(2); ++z ) {
for( int x=0 ; x < m_KernelData.GetDims()(0); ++x ) {
for( int y=0 ; y < m_KernelData.GetDims()(1); ++y ) {
id << x,y,z;
m_KernelData[id].Count = id.transpose() * m_Image->GetIncrements();
}
}
} }
}
} }
_TPL_ _TPL_
float VoxImageFilter<_TPLT_>::Distance2(const Vector3i &v) float VoxImageFilter<_TPLT_>::Distance2(const Vector3i &v) {
{ Vector3i tmp = v;
Vector3i tmp = v; const Vector3i &dim = this->m_KernelData.GetDims();
const Vector3i &dim = this->m_KernelData.GetDims(); Vector3i center = dim / 2;
Vector3i center = dim / 2; tmp = tmp - center;
tmp = tmp - center; center = center.cwiseProduct(center);
center = center.cwiseProduct(center); tmp = tmp.cwiseProduct(tmp);
tmp = tmp.cwiseProduct(tmp); return (float)(tmp.sum()) /
return (float)(tmp.sum()) / (float)( center.sum() + 0.25 * (float)(center.sum() +
(3 - (dim(0) % 2) - (dim(1) % 2) - (dim(2) % 2))); 0.25 * (3 - (dim(0) % 2) - (dim(1) % 2) - (dim(2) % 2)));
} }
_TPL_ _TPL_
void VoxImageFilter<_TPLT_>::SetKernelNumericXZY(const std::vector<float> &numeric) void VoxImageFilter<_TPLT_>::SetKernelNumericXZY(
{ const std::vector<float> &numeric) {
// set data order // // set data order //
StructuredData::Order order = m_KernelData.GetDataOrder(); StructuredData::Order order = m_KernelData.GetDataOrder();
//m_KernelData.SetDataOrder(StructuredData::XZY); // m_KernelData.SetDataOrder(StructuredData::XZY);
Vector3i id; Vector3i id;
int index = 0; int index = 0;
for( int y=0 ; y < m_KernelData.GetDims()(1); ++y ) { for (int y = 0; y < m_KernelData.GetDims()(1); ++y) {
for( int z=0 ; z < m_KernelData.GetDims()(2); ++z ) { for (int z = 0; z < m_KernelData.GetDims()(2); ++z) {
for( int x=0 ; x < m_KernelData.GetDims()(0); ++x ) { for (int x = 0; x < m_KernelData.GetDims()(0); ++x) {
id << x,y,z; id << x, y, z;
m_KernelData[id].Value = numeric[index++]; m_KernelData[id].Value = numeric[index++];
} }
}
} }
//m_KernelData.SetDataOrder(order); }
// m_KernelData.SetDataOrder(order);
} }
_TPL_ _TPL_
void VoxImageFilter<_TPLT_>::SetKernelSpherical(float(* shape)(float)) void VoxImageFilter<_TPLT_>::SetKernelSpherical(float (*shape)(float)) {
{ Vector3i id;
Vector3i id; for (int y = 0; y < m_KernelData.GetDims()(1); ++y) {
for( int y=0 ; y < m_KernelData.GetDims()(1); ++y ) { for (int z = 0; z < m_KernelData.GetDims()(2); ++z) {
for( int z=0 ; z < m_KernelData.GetDims()(2); ++z ) { for (int x = 0; x < m_KernelData.GetDims()(0); ++x) {
for( int x=0 ; x < m_KernelData.GetDims()(0); ++x ) { id << x, y, z;
id << x,y,z; m_KernelData[id].Value = shape(this->Distance2(id));
m_KernelData[id].Value = shape(this->Distance2(id)); }
}
}
} }
}
} }
_TPL_ template <class ShapeT> _TPL_ template <class ShapeT>
void VoxImageFilter<_TPLT_>::SetKernelSpherical(ShapeT shape) void VoxImageFilter<_TPLT_>::SetKernelSpherical(ShapeT shape) {
{ Interface::IsA<ShapeT, Interface::VoxImageFilterShape>();
Interface::IsA<ShapeT,Interface::VoxImageFilterShape>(); Vector3i id;
Vector3i id; for (int y = 0; y < m_KernelData.GetDims()(1); ++y) {
for( int y=0 ; y < m_KernelData.GetDims()(1); ++y ) { for (int z = 0; z < m_KernelData.GetDims()(2); ++z) {
for( int z=0 ; z < m_KernelData.GetDims()(2); ++z ) { for (int x = 0; x < m_KernelData.GetDims()(0); ++x) {
for( int x=0 ; x < m_KernelData.GetDims()(0); ++x ) { id << x, y, z;
id << x,y,z; m_KernelData[id].Value = shape(this->Distance2(id));
m_KernelData[id].Value = shape(this->Distance2(id)); }
}
}
} }
}
} }
_TPL_ _TPL_
void VoxImageFilter<_TPLT_>::SetKernelWeightFunction(float (*shape)(const Vector3f &)) void VoxImageFilter<_TPLT_>::SetKernelWeightFunction(
{ float (*shape)(const Vector3f &)) {
const Vector3i &dim = m_KernelData.GetDims(); const Vector3i &dim = m_KernelData.GetDims();
Vector3i id; Vector3i id;
Vector3f pt; Vector3f pt;
for( int y=0 ; y < dim(1); ++y ) { for (int y = 0; y < dim(1); ++y) {
for( int z=0 ; z < dim(2); ++z ) { for (int z = 0; z < dim(2); ++z) {
for( int x=0 ; x < dim(0); ++x ) { for (int x = 0; x < dim(0); ++x) {
// get voxels centroid coords from kernel center // // get voxels centroid coords from kernel center //
id << x,y,z; id << x, y, z;
pt << id(0) - dim(0)/2 + 0.5 * !(dim(0) % 2), pt << id(0) - dim(0) / 2 + 0.5 * !(dim(0) % 2),
id(1) - dim(1)/2 + 0.5 * !(dim(1) % 2), id(1) - dim(1) / 2 + 0.5 * !(dim(1) % 2),
id(2) - dim(2)/2 + 0.5 * !(dim(2) % 2); id(2) - dim(2) / 2 + 0.5 * !(dim(2) % 2);
// compute function using given shape // // compute function using given shape //
m_KernelData[id].Value = shape(pt); m_KernelData[id].Value = shape(pt);
} }
}
} }
}
} }
_TPL_ template < class ShapeT > _TPL_ template <class ShapeT>
void VoxImageFilter<_TPLT_>::SetKernelWeightFunction(ShapeT shape) void VoxImageFilter<_TPLT_>::SetKernelWeightFunction(ShapeT shape) {
{ Interface::IsA<ShapeT, Interface::VoxImageFilterShape>();
Interface::IsA<ShapeT,Interface::VoxImageFilterShape>(); const Vector3i &dim = m_KernelData.GetDims();
const Vector3i &dim = m_KernelData.GetDims(); Vector3i id;
Vector3i id; Vector3f pt;
Vector3f pt; for (int y = 0; y < dim(1); ++y) {
for( int y=0 ; y < dim(1); ++y ) { for (int z = 0; z < dim(2); ++z) {
for( int z=0 ; z < dim(2); ++z ) { for (int x = 0; x < dim(0); ++x) {
for( int x=0 ; x < dim(0); ++x ) { // get voxels centroid coords from kernel center //
// get voxels centroid coords from kernel center // id << x, y, z;
id << x,y,z; pt << id(0) - dim(0) / 2 + 0.5 * !(dim(0) % 2),
pt << id(0) - dim(0)/2 + 0.5 * !(dim(0) % 2), id(1) - dim(1) / 2 + 0.5 * !(dim(1) % 2),
id(1) - dim(1)/2 + 0.5 * !(dim(1) % 2), id(2) - dim(2) / 2 + 0.5 * !(dim(2) % 2);
id(2) - dim(2)/2 + 0.5 * !(dim(2) % 2); // compute function using given shape //
// compute function using given shape // m_KernelData[id].Value = shape(pt);
m_KernelData[id].Value = shape(pt); }
}
}
} }
}
} }
_TPL_ _TPL_
void VoxImageFilter<_TPLT_>::SetImage(Abstract::VoxImage *image) void VoxImageFilter<_TPLT_>::SetImage(Abstract::VoxImage *image) {
{ this->m_Image = reinterpret_cast<VoxImage<VoxelT> *>(image);
this->m_Image = reinterpret_cast<VoxImage<VoxelT> *> (image); this->SetKernelOffset();
this->SetKernelOffset();
} }
_TPL_ _TPL_
float VoxImageFilter<_TPLT_>::Convolve(const VoxImage<VoxelT> &buffer, int index) float VoxImageFilter<_TPLT_>::Convolve(const VoxImage<VoxelT> &buffer,
{ int index) {
const std::vector<VoxelT> &vbuf = buffer.ConstData(); const DataAllocator<VoxelT> &vbuf = buffer.ConstData();
const std::vector<VoxelT> &vker = m_KernelData.ConstData(); const DataAllocator<VoxelT> &vker = m_KernelData.ConstData();
int vox_size = vbuf.size(); int vox_size = vbuf.size();
int ker_size = vker.size(); int ker_size = vker.size();
int pos; int pos;
float conv = 0, ksum = 0; float conv = 0, ksum = 0;
for (int ik = 0; ik < ker_size; ++ik) { for (int ik = 0; ik < ker_size; ++ik) {
pos = index + vker[ik].Count - vker[m_KernelData.GetCenterData()].Count; pos = index + vker[ik].Count - vker[m_KernelData.GetCenterData()].Count;
pos = (pos + vox_size) % vox_size; pos = (pos + vox_size) % vox_size;
conv += vbuf[pos].Value * vker[ik].Value; conv += vbuf[pos].Value * vker[ik].Value;
ksum += vker[ik].Value; ksum += vker[ik].Value;
} }
return conv / ksum; return conv / ksum;
} }
#undef _TPLT_ #undef _TPLT_
#undef _TPL_ #undef _TPL_
} // namespace uLib
}
#endif // VOXIMAGEFILTER_HPP #endif // VOXIMAGEFILTER_HPP

View File

@@ -23,14 +23,12 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef VOXIMAGEFILTER2NDSTAT_HPP #ifndef VOXIMAGEFILTER2NDSTAT_HPP
#define VOXIMAGEFILTER2NDSTAT_HPP #define VOXIMAGEFILTER2NDSTAT_HPP
#include <Math/Dense.h>
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
#include "VoxImageFilter.h" #include "VoxImageFilter.h"
#include <Math/Dense.h>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
///// VOXIMAGE FILTER ABTRIM ///////////////////////////////////////////////// ///// VOXIMAGE FILTER ABTRIM /////////////////////////////////////////////////
@@ -39,45 +37,42 @@
namespace uLib { namespace uLib {
template <typename VoxelT> template <typename VoxelT>
class VoxFilterAlgorithm2ndStat : class VoxFilterAlgorithm2ndStat
public VoxImageFilter<VoxelT, VoxFilterAlgorithm2ndStat<VoxelT> > { : public VoxImageFilter<VoxelT, VoxFilterAlgorithm2ndStat<VoxelT>> {
public: public:
typedef VoxImageFilter<VoxelT, VoxFilterAlgorithm2ndStat<VoxelT> > BaseClass; typedef VoxImageFilter<VoxelT, VoxFilterAlgorithm2ndStat<VoxelT>> BaseClass;
VoxFilterAlgorithm2ndStat(const Vector3i &size) : VoxFilterAlgorithm2ndStat(const Vector3i &size) : BaseClass(size) {}
BaseClass(size)
{ }
float Evaluate(const VoxImage<VoxelT> &buffer, int index) float Evaluate(const VoxImage<VoxelT> &buffer, int index) {
{ const DataAllocator<VoxelT> &vbuf = buffer.ConstData();
const std::vector<VoxelT> &vbuf = buffer.ConstData(); const DataAllocator<VoxelT> &vker = this->m_KernelData.ConstData();
const std::vector<VoxelT> &vker = this->m_KernelData.ConstData(); int vox_size = vbuf.size();
int vox_size = vbuf.size(); int ker_size = vker.size();
int ker_size = vker.size(); int pos;
int pos;
// mean // // mean //
float conv = 0, ksum = 0; float conv = 0, ksum = 0;
for (int ik = 0; ik < ker_size; ++ik) { for (int ik = 0; ik < ker_size; ++ik) {
pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; pos = index + vker[ik].Count -
pos = (pos + vox_size) % vox_size; vker[this->m_KernelData.GetCenterData()].Count;
conv += vbuf[pos].Value * vker[ik].Value; pos = (pos + vox_size) % vox_size;
ksum += vker[ik].Value; conv += vbuf[pos].Value * vker[ik].Value;
} ksum += vker[ik].Value;
float mean = conv / ksum;
// rms //
conv = 0;
for (int ik = 0; ik < ker_size; ++ik) {
pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + vox_size) % vox_size;
conv += pow((vbuf[pos].Value * vker[ik].Value) - mean , 2);
}
return conv / (vker.size() - 1) ;
} }
float mean = conv / ksum;
// rms //
conv = 0;
for (int ik = 0; ik < ker_size; ++ik) {
pos = index + vker[ik].Count -
vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + vox_size) % vox_size;
conv += pow((vbuf[pos].Value * vker[ik].Value) - mean, 2);
}
return conv / (vker.size() - 1);
}
}; };
} } // namespace uLib
#endif // VOXIMAGEFILTER2NDSTAT_HPP #endif // VOXIMAGEFILTER2NDSTAT_HPP

View File

@@ -23,14 +23,12 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef VOXIMAGEFILTERABTRIM_HPP #ifndef VOXIMAGEFILTERABTRIM_HPP
#define VOXIMAGEFILTERABTRIM_HPP #define VOXIMAGEFILTERABTRIM_HPP
#include <Math/Dense.h>
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
#include "VoxImageFilter.h" #include "VoxImageFilter.h"
#include <Math/Dense.h>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
///// VOXIMAGE FILTER ABTRIM ///////////////////////////////////////////////// ///// VOXIMAGE FILTER ABTRIM /////////////////////////////////////////////////
@@ -38,142 +36,257 @@
namespace uLib { namespace uLib {
#if defined(USE_CUDA) && defined(__CUDACC__)
template <typename VoxelT> template <typename VoxelT>
class VoxFilterAlgorithmAbtrim : __global__ void ABTrimFilterKernel(const VoxelT *in, VoxelT *out,
public VoxImageFilter<VoxelT, VoxFilterAlgorithmAbtrim<VoxelT> > { const VoxelT *kernel, int vox_size,
int ker_size, int center_count, int mAtrim,
int mBtrim) {
int index = blockIdx.x * blockDim.x + threadIdx.x;
if (index < vox_size) {
// Allocate space for sorting
extern __shared__ char shared_mem[];
VoxelT *mfh =
(VoxelT *)&shared_mem[threadIdx.x * ker_size * sizeof(VoxelT)];
struct KernelSortAscending for (int i = 0; i < ker_size; ++i) {
{ mfh[i].Count = i;
bool operator()(const VoxelT& e1, const VoxelT& e2) }
{ return e1.Value < e2.Value; }
}; for (int ik = 0; ik < ker_size; ik++) {
int pos = index + kernel[ik].Count - center_count;
if (pos < 0) {
pos += vox_size * ((-pos / vox_size) + 1);
}
pos = pos % vox_size;
mfh[ik].Value = in[pos].Value;
}
// Simple bubble sort for small arrays
for (int i = 0; i < ker_size - 1; i++) {
for (int j = 0; j < ker_size - i - 1; j++) {
if (mfh[j].Value > mfh[j + 1].Value) {
VoxelT temp = mfh[j];
mfh[j] = mfh[j + 1];
mfh[j + 1] = temp;
}
}
}
float ker_sum = 0;
float fconv = 0;
for (int ik = 0; ik < mAtrim; ik++) {
ker_sum += kernel[mfh[ik].Count].Value;
}
for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) {
fconv += mfh[ik].Value * kernel[mfh[ik].Count].Value;
ker_sum += kernel[mfh[ik].Count].Value;
}
for (int ik = ker_size - mBtrim; ik < ker_size; ik++) {
ker_sum += kernel[mfh[ik].Count].Value;
}
out[index].Value = fconv / ker_sum;
}
}
#endif
template <typename VoxelT>
class VoxFilterAlgorithmAbtrim
: public VoxImageFilter<VoxelT, VoxFilterAlgorithmAbtrim<VoxelT>> {
struct KernelSortAscending {
bool operator()(const VoxelT &e1, const VoxelT &e2) {
return e1.Value < e2.Value;
}
};
public: public:
typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmAbtrim<VoxelT> > BaseClass; typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmAbtrim<VoxelT>> BaseClass;
VoxFilterAlgorithmAbtrim(const Vector3i &size) : VoxFilterAlgorithmAbtrim(const Vector3i &size) : BaseClass(size) {
BaseClass(size) mAtrim = 0;
{ mBtrim = 0;
mAtrim = 0; }
mBtrim = 0;
#if defined(USE_CUDA) && defined(__CUDACC__)
void Run() {
if (this->m_Image->Data().GetDevice() == MemoryDevice::VRAM ||
this->m_KernelData.Data().GetDevice() == MemoryDevice::VRAM) {
this->m_Image->Data().MoveToVRAM();
this->m_KernelData.Data().MoveToVRAM();
VoxImage<VoxelT> buffer = *(this->m_Image);
buffer.Data().MoveToVRAM();
int vox_size = buffer.Data().size();
int ker_size = this->m_KernelData.Data().size();
VoxelT *d_img_out = this->m_Image->Data().GetVRAMData();
const VoxelT *d_img_in = buffer.Data().GetVRAMData();
const VoxelT *d_kernel = this->m_KernelData.Data().GetVRAMData();
int center_count =
this->m_KernelData[this->m_KernelData.GetCenterData()].Count;
int threadsPerBlock = 256;
int blocksPerGrid = (vox_size + threadsPerBlock - 1) / threadsPerBlock;
size_t shared_mem_size = threadsPerBlock * ker_size * sizeof(VoxelT);
ABTrimFilterKernel<<<blocksPerGrid, threadsPerBlock, shared_mem_size>>>(
d_img_in, d_img_out, d_kernel, vox_size, ker_size, center_count,
mAtrim, mBtrim);
cudaDeviceSynchronize();
} else {
BaseClass::Run();
}
}
#endif
float Evaluate(const VoxImage<VoxelT> &buffer, int index) {
const DataAllocator<VoxelT> &vbuf = buffer.ConstData();
const DataAllocator<VoxelT> &vker = this->m_KernelData.ConstData();
int vox_size = vbuf.size();
int ker_size = vker.size();
int pos;
std::vector<VoxelT> mfh(ker_size);
for (int i = 0; i < ker_size; ++i)
mfh[i].Count = i; // index key for ordering function
for (int ik = 0; ik < ker_size; ik++) {
pos = index + vker[ik].Count -
vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + vox_size) % vox_size;
mfh[ik].Value = vbuf[pos].Value;
} }
float Evaluate(const VoxImage<VoxelT> &buffer, int index) std::sort(mfh.begin(), mfh.end(), KernelSortAscending());
{ float ker_sum = 0;
const std::vector<VoxelT> &vbuf = buffer.ConstData(); float fconv = 0;
const std::vector<VoxelT> &vker = this->m_KernelData.ConstData(); for (int ik = 0; ik < mAtrim; ik++)
int vox_size = vbuf.size(); ker_sum += vker[mfh[ik].Count].Value;
int ker_size = vker.size(); for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) {
int pos; fconv += mfh[ik].Value * vker[mfh[ik].Count].Value; // convloution //
ker_sum += vker[mfh[ik].Count].Value;
std::vector<VoxelT> mfh(ker_size);
for (int i = 0; i < ker_size; ++i)
mfh[i].Count = i; //index key for ordering function
for (int ik = 0; ik < ker_size; ik++) {
pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + vox_size) % vox_size;
mfh[ik].Value = vbuf[pos].Value;
}
std::sort(mfh.begin(), mfh.end(), KernelSortAscending());
float ker_sum = 0;
float fconv = 0;
for (int ik = 0; ik < mAtrim; ik++)
ker_sum += vker[ mfh[ik].Count ].Value;
for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) {
fconv += mfh[ik].Value * vker[ mfh[ik].Count ].Value; // convloution //
ker_sum += vker[ mfh[ik].Count ].Value;
}
for (int ik = ker_size - mBtrim; ik < ker_size; ik++)
ker_sum += vker[ mfh[ik].Count ].Value;
return fconv / ker_sum;
} }
for (int ik = ker_size - mBtrim; ik < ker_size; ik++)
ker_sum += vker[mfh[ik].Count].Value;
inline void SetABTrim(int a, int b) { mAtrim = a; mBtrim = b; } return fconv / ker_sum;
}
inline void SetABTrim(int a, int b) {
mAtrim = a;
mBtrim = b;
}
private: private:
int mAtrim; int mAtrim;
int mBtrim; int mBtrim;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Roberspierre Filter // // Roberspierre Filter //
template <typename VoxelT> template <typename VoxelT>
class VoxFilterAlgorithmSPR : class VoxFilterAlgorithmSPR
public VoxImageFilter<VoxelT, VoxFilterAlgorithmSPR<VoxelT> > { : public VoxImageFilter<VoxelT, VoxFilterAlgorithmSPR<VoxelT>> {
struct KernelSortAscending struct KernelSortAscending {
{ bool operator()(const VoxelT &e1, const VoxelT &e2) {
bool operator()(const VoxelT& e1, const VoxelT& e2) return e1.Value < e2.Value;
{ return e1.Value < e2.Value; } }
}; };
public: public:
typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmSPR<VoxelT> > BaseClass; typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmSPR<VoxelT>> BaseClass;
VoxFilterAlgorithmSPR(const Vector3i &size) : VoxFilterAlgorithmSPR(const Vector3i &size) : BaseClass(size) {
BaseClass(size) mAtrim = 0;
{ mBtrim = 0;
mAtrim = 0; }
mBtrim = 0;
#if defined(USE_CUDA) && defined(__CUDACC__)
void Run() {
if (this->m_Image->Data().GetDevice() == MemoryDevice::VRAM ||
this->m_KernelData.Data().GetDevice() == MemoryDevice::VRAM) {
this->m_Image->Data().MoveToVRAM();
this->m_KernelData.Data().MoveToVRAM();
VoxImage<VoxelT> buffer = *(this->m_Image);
buffer.Data().MoveToVRAM();
int vox_size = buffer.Data().size();
int ker_size = this->m_KernelData.Data().size();
VoxelT *d_img_out = this->m_Image->Data().GetVRAMData();
const VoxelT *d_img_in = buffer.Data().GetVRAMData();
const VoxelT *d_kernel = this->m_KernelData.Data().GetVRAMData();
int center_count =
this->m_KernelData[this->m_KernelData.GetCenterData()].Count;
int threadsPerBlock = 256;
int blocksPerGrid = (vox_size + threadsPerBlock - 1) / threadsPerBlock;
size_t shared_mem_size = threadsPerBlock * ker_size * sizeof(VoxelT);
ABTrimFilterKernel<<<blocksPerGrid, threadsPerBlock, shared_mem_size>>>(
d_img_in, d_img_out, d_kernel, vox_size, ker_size, center_count,
mAtrim, mBtrim);
cudaDeviceSynchronize();
} else {
BaseClass::Run();
}
}
#endif
float Evaluate(const VoxImage<VoxelT> &buffer, int index) {
const DataAllocator<VoxelT> &vbuf = buffer.ConstData();
const DataAllocator<VoxelT> &vker = this->m_KernelData.ConstData();
int vox_size = vbuf.size();
int ker_size = vker.size();
int pos;
std::vector<VoxelT> mfh(ker_size);
for (int i = 0; i < ker_size; ++i)
mfh[i].Count = i; // index key for ordering function
for (int ik = 0; ik < ker_size; ik++) {
pos = index + vker[ik].Count -
vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + vox_size) % vox_size;
mfh[ik].Value = vbuf[pos].Value;
} }
float Evaluate(const VoxImage<VoxelT> &buffer, int index) std::sort(mfh.begin(), mfh.end(), KernelSortAscending());
{ float spr = vbuf[index].Value;
const std::vector<VoxelT> &vbuf = buffer.ConstData(); if ((mAtrim > 0 && spr <= mfh[mAtrim - 1].Value) ||
const std::vector<VoxelT> &vker = this->m_KernelData.ConstData(); (mBtrim > 0 && spr >= mfh[ker_size - mBtrim].Value)) {
int vox_size = vbuf.size(); float ker_sum = 0;
int ker_size = vker.size(); float fconv = 0;
int pos; for (int ik = 0; ik < mAtrim; ik++)
ker_sum += vker[mfh[ik].Count].Value;
for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) {
fconv += mfh[ik].Value * vker[mfh[ik].Count].Value;
ker_sum += vker[mfh[ik].Count].Value;
}
for (int ik = ker_size - mBtrim; ik < ker_size; ik++)
ker_sum += vker[mfh[ik].Count].Value;
std::vector<VoxelT> mfh(ker_size); return fconv / ker_sum;
for (int i = 0; i < ker_size; ++i) } else
mfh[i].Count = i; //index key for ordering function return spr;
for (int ik = 0; ik < ker_size; ik++) { }
pos = index + vker[ik].Count -
vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + vox_size) % vox_size;
mfh[ik].Value = vbuf[pos].Value;
}
std::sort(mfh.begin(), mfh.end(), KernelSortAscending()); inline void SetABTrim(int a, int b) {
float spr = vbuf[index].Value; mAtrim = a;
if( (mAtrim > 0 && spr <= mfh[mAtrim-1].Value) || mBtrim = b;
(mBtrim > 0 && spr >= mfh[ker_size - mBtrim].Value) ) }
{
float ker_sum = 0;
float fconv = 0;
for (int ik = 0; ik < mAtrim; ik++)
ker_sum += vker[ mfh[ik].Count ].Value;
for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) {
fconv += mfh[ik].Value * vker[ mfh[ik].Count ].Value;
ker_sum += vker[ mfh[ik].Count ].Value;
}
for (int ik = ker_size - mBtrim; ik < ker_size; ik++)
ker_sum += vker[ mfh[ik].Count ].Value;
return fconv / ker_sum;
}
else
return spr;
}
inline void SetABTrim(int a, int b) { mAtrim = a; mBtrim = b; }
private: private:
int mAtrim; int mAtrim;
int mBtrim; int mBtrim;
}; };
} // namespace uLib
}
#endif // VOXIMAGEFILTERABTRIM_HPP #endif // VOXIMAGEFILTERABTRIM_HPP

View File

@@ -23,14 +23,12 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef VOXIMAGEFILTERBILATERAL_HPP #ifndef VOXIMAGEFILTERBILATERAL_HPP
#define VOXIMAGEFILTERBILATERAL_HPP #define VOXIMAGEFILTERBILATERAL_HPP
#include <Math/Dense.h>
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
#include "VoxImageFilter.h" #include "VoxImageFilter.h"
#include <Math/Dense.h>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
///// VOXIMAGE FILTER LINEAR ///////////////////////////////////////////////// ///// VOXIMAGE FILTER LINEAR /////////////////////////////////////////////////
@@ -38,115 +36,119 @@
namespace uLib { namespace uLib {
template <typename VoxelT> template <typename VoxelT>
class VoxFilterAlgorithmBilateral : class VoxFilterAlgorithmBilateral
public VoxImageFilter<VoxelT, VoxFilterAlgorithmBilateral<VoxelT> > { : public VoxImageFilter<VoxelT, VoxFilterAlgorithmBilateral<VoxelT>> {
public: public:
typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmBilateral<VoxelT> > BaseClass; typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmBilateral<VoxelT>> BaseClass;
VoxFilterAlgorithmBilateral(const Vector3i &size) : BaseClass(size) { VoxFilterAlgorithmBilateral(const Vector3i &size) : BaseClass(size) {
m_sigma = 1; m_sigma = 1;
} }
float Evaluate(const VoxImage<VoxelT> &buffer, int index) float Evaluate(const VoxImage<VoxelT> &buffer, int index) {
{ const DataAllocator<VoxelT> &vbuf = buffer.ConstData();
const std::vector<VoxelT> &vbuf = buffer.ConstData(); const DataAllocator<VoxelT> &vker = this->m_KernelData.ConstData();
const std::vector<VoxelT> &vker = this->m_KernelData.ConstData(); int vox_size = vbuf.size();
int vox_size = vbuf.size(); int ker_size = vker.size();
int ker_size = vker.size(); int pos;
int pos; float conv = 0, ksum = 0;
float conv = 0, ksum = 0; float gamma_smooth;
float gamma_smooth; for (int ik = 0; ik < ker_size; ++ik) {
for (int ik = 0; ik < ker_size; ++ik) { // if (ik==this->m_KernelData.GetCenterData()) continue;
// if (ik==this->m_KernelData.GetCenterData()) continue; pos = index + vker[ik].Count -
pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + vox_size) % vox_size; pos = (pos + vox_size) % vox_size;
gamma_smooth = compute_gauss( fabs(vbuf[index].Value - vbuf[pos].Value) * 1.E6 ); gamma_smooth =
conv += vbuf[pos].Value * vker[ik].Value * gamma_smooth; compute_gauss(fabs(vbuf[index].Value - vbuf[pos].Value) * 1.E6);
ksum += vker[ik].Value * gamma_smooth; conv += vbuf[pos].Value * vker[ik].Value * gamma_smooth;
} ksum += vker[ik].Value * gamma_smooth;
return conv / ksum;
} }
return conv / ksum;
}
inline void SetIntensitySigma(const float s) { m_sigma = s; } inline void SetIntensitySigma(const float s) { m_sigma = s; }
private: private:
inline float compute_gauss(const float x) { inline float compute_gauss(const float x) {
return 1/(sqrt(2*M_PI)* m_sigma) * exp(-0.5*(x*x)/(m_sigma*m_sigma)); return 1 / (sqrt(2 * M_PI) * m_sigma) *
} exp(-0.5 * (x * x) / (m_sigma * m_sigma));
}
Scalarf m_sigma; Scalarf m_sigma;
}; };
template <typename VoxelT> template <typename VoxelT>
class VoxFilterAlgorithmBilateralTrim : class VoxFilterAlgorithmBilateralTrim
public VoxImageFilter<VoxelT, VoxFilterAlgorithmBilateralTrim<VoxelT> > { : public VoxImageFilter<VoxelT, VoxFilterAlgorithmBilateralTrim<VoxelT>> {
typedef std::pair<float,float> FPair; typedef std::pair<float, float> FPair;
struct KernelSortAscending struct KernelSortAscending {
{ bool operator()(const FPair &e1, const FPair &e2) {
bool operator()(const FPair& e1, const FPair& e2) return e1.second < e2.second;
{ return e1.second < e2.second; } }
}; };
public: public:
typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmBilateralTrim<VoxelT> > BaseClass; typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmBilateralTrim<VoxelT>>
VoxFilterAlgorithmBilateralTrim(const Vector3i &size) : BaseClass(size) { BaseClass;
m_sigma = 1; VoxFilterAlgorithmBilateralTrim(const Vector3i &size) : BaseClass(size) {
mAtrim = 0; m_sigma = 1;
mBtrim = 0; mAtrim = 0;
mBtrim = 0;
}
float Evaluate(const VoxImage<VoxelT> &buffer, int index) {
const DataAllocator<VoxelT> &vbuf = buffer.ConstData();
const DataAllocator<VoxelT> &vker = this->m_KernelData.ConstData();
int img_size = vbuf.size();
int ker_size = vker.size();
int pos;
std::vector<FPair> mfh(ker_size);
for (int i = 0; i < ker_size; ++i)
mfh[i].first = vker[i].Value; // kernel value in first
for (int ik = 0; ik < ker_size; ik++) {
pos = index + vker[ik].Count -
vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + img_size) % img_size;
mfh[ik].second = vbuf[pos].Value; // image value in second
} }
std::sort(mfh.begin(), mfh.end(), KernelSortAscending());
float Evaluate(const VoxImage<VoxelT> &buffer, int index) float conv = 0, ksum = 0;
{ float gamma_smooth;
const std::vector<VoxelT> &vbuf = buffer.ConstData(); // for (int ik = 0; ik < mAtrim; ik++)
const std::vector<VoxelT> &vker = this->m_KernelData.ConstData(); // ksum += mfh[ik].first;
int img_size = vbuf.size(); for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) {
int ker_size = vker.size(); gamma_smooth =
int pos; compute_gauss(fabs(vbuf[index].Value - mfh[ik].second) * 1.E6);
conv += mfh[ik].first * mfh[ik].second * gamma_smooth;
ksum += mfh[ik].first * gamma_smooth;
std::vector<FPair> mfh(ker_size);
for (int i = 0; i < ker_size; ++i)
mfh[i].first = vker[i].Value; // kernel value in first
for (int ik = 0; ik < ker_size; ik++) {
pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + img_size) % img_size;
mfh[ik].second = vbuf[pos].Value; // image value in second
}
std::sort(mfh.begin(), mfh.end(), KernelSortAscending());
float conv = 0, ksum = 0;
float gamma_smooth;
// for (int ik = 0; ik < mAtrim; ik++)
// ksum += mfh[ik].first;
for (int ik = mAtrim; ik < ker_size - mBtrim; ik++) {
gamma_smooth = compute_gauss( fabs(vbuf[index].Value - mfh[ik].second) * 1.E6 );
conv += mfh[ik].first * mfh[ik].second * gamma_smooth;
ksum += mfh[ik].first * gamma_smooth;
}
// for (int ik = ker_size - mBtrim; ik < ker_size; ik++)
// ksum += mfh[ik].first;
return conv / ksum;
} }
// for (int ik = ker_size - mBtrim; ik < ker_size; ik++)
// ksum += mfh[ik].first;
inline void SetIntensitySigma(const float s) { m_sigma = s; } return conv / ksum;
inline void SetABTrim(int a, int b) { mAtrim = a; mBtrim = b; } }
inline void SetIntensitySigma(const float s) { m_sigma = s; }
inline void SetABTrim(int a, int b) {
mAtrim = a;
mBtrim = b;
}
private: private:
inline float compute_gauss(const float x) { inline float compute_gauss(const float x) {
return 1/(sqrt(2*M_PI)* m_sigma) * exp(-0.5*(x*x)/(m_sigma*m_sigma)); return 1 / (sqrt(2 * M_PI) * m_sigma) *
} exp(-0.5 * (x * x) / (m_sigma * m_sigma));
}
Scalarf m_sigma; Scalarf m_sigma;
int mAtrim; int mAtrim;
int mBtrim; int mBtrim;
}; };
} } // namespace uLib
#endif // VOXIMAGEFILTERBILATERAL_HPP #endif // VOXIMAGEFILTERBILATERAL_HPP

View File

@@ -23,14 +23,12 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef VOXIMAGEFILTERCUSTOM_HPP #ifndef VOXIMAGEFILTERCUSTOM_HPP
#define VOXIMAGEFILTERCUSTOM_HPP #define VOXIMAGEFILTERCUSTOM_HPP
#include <Math/Dense.h>
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
#include "VoxImageFilter.h" #include "VoxImageFilter.h"
#include <Math/Dense.h>
#define likely(expr) __builtin_expect(!!(expr), 1) #define likely(expr) __builtin_expect(!!(expr), 1)
@@ -41,50 +39,50 @@
namespace uLib { namespace uLib {
template <typename VoxelT> template <typename VoxelT>
class VoxFilterAlgorithmCustom : class VoxFilterAlgorithmCustom
public VoxImageFilter<VoxelT, VoxFilterAlgorithmCustom<VoxelT> > { : public VoxImageFilter<VoxelT, VoxFilterAlgorithmCustom<VoxelT>> {
typedef float (*FunctionPt)(const std::vector<Scalarf> &);
typedef float (* FunctionPt)(const std::vector<Scalarf> &);
public: public:
typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmCustom<VoxelT> > BaseClass; typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmCustom<VoxelT>> BaseClass;
VoxFilterAlgorithmCustom(const Vector3i &size) : VoxFilterAlgorithmCustom(const Vector3i &size)
BaseClass(size), m_CustomEvaluate(NULL) : BaseClass(size), m_CustomEvaluate(NULL) {}
{}
float Evaluate(const VoxImage<VoxelT> &buffer, int index) float Evaluate(const VoxImage<VoxelT> &buffer, int index) {
{ if (likely(m_CustomEvaluate)) {
if(likely(m_CustomEvaluate)) { const DataAllocator<VoxelT> &vbuf = buffer.ConstData();
const std::vector<VoxelT> &vbuf = buffer.ConstData(); const DataAllocator<VoxelT> &vker = this->m_KernelData.ConstData();
const std::vector<VoxelT> &vker = this->m_KernelData.ConstData(); int vox_size = vbuf.size();
int vox_size = vbuf.size(); int ker_size = vker.size();
int ker_size = vker.size(); int pos;
int pos;
float ker_sum = 0; float ker_sum = 0;
std::vector<Scalarf> mfh(ker_size); std::vector<Scalarf> mfh(ker_size);
for (int ik = 0; ik < ker_size; ik++) { for (int ik = 0; ik < ker_size; ik++) {
pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; pos = index + vker[ik].Count -
pos = (pos + vox_size) % vox_size; vker[this->m_KernelData.GetCenterData()].Count;
mfh[ik] = vbuf[pos].Value * vker[ik].Value; pos = (pos + vox_size) % vox_size;
ker_sum += vker[ik].Value; mfh[ik] = vbuf[pos].Value * vker[ik].Value;
} ker_sum += vker[ik].Value;
}
return this->m_CustomEvaluate(mfh);
}
else
std::cerr << "Custom evaluate function is NULL \n" <<
"No operation performed by filter.\n";
return this->m_CustomEvaluate(mfh);
} else {
std::cerr << "Custom evaluate function is NULL \n"
<< "No operation performed by filter.\n";
return 0;
} }
}
inline void SetCustomEvaluate(FunctionPt funPt) { this->m_CustomEvaluate = funPt; } inline void SetCustomEvaluate(FunctionPt funPt) {
this->m_CustomEvaluate = funPt;
}
private: private:
FunctionPt m_CustomEvaluate; FunctionPt m_CustomEvaluate;
}; };
} } // namespace uLib
#endif // VOXIMAGEFILTERCUSTOM_HPP #endif // VOXIMAGEFILTERCUSTOM_HPP

View File

@@ -23,14 +23,12 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef VOXIMAGEFILTERLINEAR_HPP #ifndef VOXIMAGEFILTERLINEAR_HPP
#define VOXIMAGEFILTERLINEAR_HPP #define VOXIMAGEFILTERLINEAR_HPP
#include <Math/Dense.h>
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
#include "VoxImageFilter.h" #include "VoxImageFilter.h"
#include <Math/Dense.h>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
///// VOXIMAGE FILTER LINEAR ///////////////////////////////////////////////// ///// VOXIMAGE FILTER LINEAR /////////////////////////////////////////////////
@@ -38,32 +36,86 @@
namespace uLib { namespace uLib {
#if defined(USE_CUDA) && defined(__CUDACC__)
template <typename VoxelT>
__global__ void LinearFilterKernel(const VoxelT *in, VoxelT *out,
const VoxelT *kernel, int vox_size,
int ker_size, int center_count) {
int index = blockIdx.x * blockDim.x + threadIdx.x;
if (index < vox_size) {
float conv = 0;
float ksum = 0;
for (int ik = 0; ik < ker_size; ++ik) {
int pos = index + kernel[ik].Count - center_count;
if (pos < 0) {
pos += vox_size * ((-pos / vox_size) + 1);
}
pos = pos % vox_size;
conv += in[pos].Value * kernel[ik].Value;
ksum += kernel[ik].Value;
}
out[index].Value = conv / ksum;
}
}
#endif
template <typename VoxelT> template <typename VoxelT>
class VoxFilterAlgorithmLinear : class VoxFilterAlgorithmLinear
public VoxImageFilter<VoxelT, VoxFilterAlgorithmLinear<VoxelT> > { : public VoxImageFilter<VoxelT, VoxFilterAlgorithmLinear<VoxelT>> {
public: public:
typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmLinear<VoxelT> > BaseClass; typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmLinear<VoxelT>> BaseClass;
VoxFilterAlgorithmLinear(const Vector3i &size) : BaseClass(size) {} VoxFilterAlgorithmLinear(const Vector3i &size) : BaseClass(size) {}
float Evaluate(const VoxImage<VoxelT> &buffer, int index) #if defined(USE_CUDA) && defined(__CUDACC__)
{ void Run() {
const std::vector<VoxelT> &vbuf = buffer.ConstData(); if (this->m_Image->Data().GetDevice() == MemoryDevice::VRAM ||
const std::vector<VoxelT> &vker = this->m_KernelData.ConstData(); this->m_KernelData.Data().GetDevice() == MemoryDevice::VRAM) {
int vox_size = vbuf.size();
int ker_size = vker.size(); this->m_Image->Data().MoveToVRAM();
int pos; this->m_KernelData.Data().MoveToVRAM();
float conv = 0, ksum = 0;
for (int ik = 0; ik < ker_size; ++ik) { VoxImage<VoxelT> buffer = *(this->m_Image);
pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; buffer.Data().MoveToVRAM();
pos = (pos + vox_size) % vox_size;
conv += vbuf[pos].Value * vker[ik].Value; int vox_size = buffer.Data().size();
ksum += vker[ik].Value; int ker_size = this->m_KernelData.Data().size();
}
return conv / ksum; VoxelT *d_img_out = this->m_Image->Data().GetVRAMData();
const VoxelT *d_img_in = buffer.Data().GetVRAMData();
const VoxelT *d_kernel = this->m_KernelData.Data().GetVRAMData();
int center_count =
this->m_KernelData[this->m_KernelData.GetCenterData()].Count;
int threadsPerBlock = 256;
int blocksPerGrid = (vox_size + threadsPerBlock - 1) / threadsPerBlock;
LinearFilterKernel<<<blocksPerGrid, threadsPerBlock>>>(
d_img_in, d_img_out, d_kernel, vox_size, ker_size, center_count);
cudaDeviceSynchronize();
} else {
BaseClass::Run();
} }
}
#endif
float Evaluate(const VoxImage<VoxelT> &buffer, int index) {
const DataAllocator<VoxelT> &vbuf = buffer.ConstData();
const DataAllocator<VoxelT> &vker = this->m_KernelData.ConstData();
int vox_size = vbuf.size();
int ker_size = vker.size();
int pos;
float conv = 0, ksum = 0;
for (int ik = 0; ik < ker_size; ++ik) {
pos = index + vker[ik].Count -
vker[this->m_KernelData.GetCenterData()].Count;
pos = (pos + vox_size) % vox_size;
conv += vbuf[pos].Value * vker[ik].Value;
ksum += vker[ik].Value;
}
return conv / ksum;
}
}; };
} } // namespace uLib
#endif // VOXIMAGEFILTERLINEAR_HPP #endif // VOXIMAGEFILTERLINEAR_HPP

View File

@@ -23,14 +23,12 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef VOXIMAGEFILTERMEDIAN_HPP #ifndef VOXIMAGEFILTERMEDIAN_HPP
#define VOXIMAGEFILTERMEDIAN_HPP #define VOXIMAGEFILTERMEDIAN_HPP
#include <Math/Dense.h>
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
#include "VoxImageFilter.h" #include "VoxImageFilter.h"
#include <Math/Dense.h>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
///// VOXIMAGE FILTER MEDIAN ///////////////////////////////////////////////// ///// VOXIMAGE FILTER MEDIAN /////////////////////////////////////////////////
@@ -39,37 +37,38 @@
namespace uLib { namespace uLib {
template <typename VoxelT> template <typename VoxelT>
class VoxFilterAlgorithmMedian : class VoxFilterAlgorithmMedian
public VoxImageFilter<VoxelT, VoxFilterAlgorithmMedian<VoxelT> > { : public VoxImageFilter<VoxelT, VoxFilterAlgorithmMedian<VoxelT>> {
public: public:
typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmMedian<VoxelT> > BaseClass; typedef VoxImageFilter<VoxelT, VoxFilterAlgorithmMedian<VoxelT>> BaseClass;
VoxFilterAlgorithmMedian(const Vector3i &size) : BaseClass(size) {} VoxFilterAlgorithmMedian(const Vector3i &size) : BaseClass(size) {}
float Evaluate(const VoxImage<VoxelT> &buffer, int index) float Evaluate(const VoxImage<VoxelT> &buffer, int index) {
{ const DataAllocator<VoxelT> &vbuf = buffer.ConstData();
const std::vector<VoxelT> &vbuf = buffer.ConstData(); const DataAllocator<VoxelT> &vker = this->m_KernelData.ConstData();
const std::vector<VoxelT> &vker = this->m_KernelData.ConstData(); int vox_size = vbuf.size();
int vox_size = vbuf.size(); int ker_size = vker.size();
int ker_size = vker.size(); int pos;
int pos;
std::vector<float> mfh(ker_size); std::vector<float> mfh(ker_size);
for (int ik = 0; ik < ker_size; ik++) { for (int ik = 0; ik < ker_size; ik++) {
pos = index + vker[ik].Count - vker[this->m_KernelData.GetCenterData()].Count; pos = index + vker[ik].Count -
pos = (pos + vox_size) % vox_size; vker[this->m_KernelData.GetCenterData()].Count;
mfh[ik] = vbuf[pos].Value * vker[ik].Value; pos = (pos + vox_size) % vox_size;
} mfh[ik] = vbuf[pos].Value * vker[ik].Value;
std::sort(mfh.begin(), mfh.end());
pos = 0;
// count zeroes in filter kernel to move it out of median //
for (int i = 0; i < ker_size; ++i)
if (vker[i].Value == 0.0) pos++;
// median //
pos += (ker_size - pos) / 2;
return mfh[pos];
} }
std::sort(mfh.begin(), mfh.end());
pos = 0;
// count zeroes in filter kernel to move it out of median //
for (int i = 0; i < ker_size; ++i)
if (vker[i].Value == 0.0)
pos++;
// median //
pos += (ker_size - pos) / 2;
return mfh[pos];
}
}; };
} } // namespace uLib
#endif // VOXIMAGEFILTERMEDIAN_HPP #endif // VOXIMAGEFILTERMEDIAN_HPP

View File

@@ -39,48 +39,48 @@ namespace uLib {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void VoxRaytracer::RayData::AddElement(Id_t id, float L) { void VoxRaytracer::RayData::AddElement(Id_t id, float L) {
if (m_Count >= m_Data.size()) {
size_t new_size = m_Data.size() == 0 ? 128 : m_Data.size() * 2;
m_Data.resize(new_size);
}
Element el = {id, L}; Element el = {id, L};
m_Data.push_back(el); m_Data[m_Count] = el;
m_Count++;
m_TotalLength += L; m_TotalLength += L;
} }
void VoxRaytracer::RayData::AppendRay(const VoxRaytracer::RayData &in) { void VoxRaytracer::RayData::AppendRay(const VoxRaytracer::RayData &in) {
if (unlikely(!in.m_Data.size())) { if (unlikely(in.m_Count == 0)) {
std::cout << "Warinig: PoCA on exit border!\n"; std::cout << "Warinig: PoCA on exit border!\n";
return; return;
} else if (unlikely(!m_Data.size())) { } else if (unlikely(m_Count == 0)) {
m_Data = in.m_Data; m_Data.resize(in.m_Count);
for (size_t i = 0; i < in.m_Count; ++i) {
m_Data[i] = in.m_Data[i];
}
m_Count = in.m_Count;
m_TotalLength = in.m_TotalLength;
std::cout << "Warinig: PoCA on entrance border!\n"; std::cout << "Warinig: PoCA on entrance border!\n";
return; return;
} else { } else {
// Opzione 1) un voxel in piu' // // Opzione 1) un voxel in piu' //
if (in.m_Data.size() > 0) { if (in.m_Count > 0) {
m_Data.insert(m_Data.end(), in.m_Data.begin(), in.m_Data.end()); if (m_Count + in.m_Count > m_Data.size()) {
m_Data.resize(m_Count + in.m_Count);
}
for (size_t i = 0; i < in.m_Count; ++i) {
m_Data[m_Count + i] = in.m_Data[i];
}
m_Count += in.m_Count;
} }
// Opzione 2) merge dei voxel nel poca.
// RayData::Element &e1 = m_Data.back();
// const RayData::Element &e2 = in.m_Data.front();
// if(e1.vox_id == e2.vox_id)
// {
// m_Data.reserve(m_Data.size() + in.m_Data.size() - 1);
// e1.L += e2.L; //fix//
// m_Data.insert(m_Data.end(), in.m_Data.begin()+1,
// in.m_Data.end());
// }
// else {
// m_Data.reserve(m_Data.size() + in.m_Data.size());
// m_Data.insert(m_Data.end(), in.m_Data.begin(),
// in.m_Data.end());
// }
m_TotalLength += in.m_TotalLength; m_TotalLength += in.m_TotalLength;
} }
} }
void VoxRaytracer::RayData::PrintSelf(std::ostream &o) { void VoxRaytracer::RayData::PrintSelf(std::ostream &o) {
o << "Ray: total lenght " << m_TotalLength << "\n"; o << "Ray: total lenght " << m_TotalLength << "\n";
std::vector<Element>::iterator it; for (size_t i = 0; i < m_Count; ++i)
for (it = m_Data.begin(); it < m_Data.end(); ++it) o << "[ " << m_Data[i].vox_id << ", " << m_Data[i].L << "] \n";
o << "[ " << (*it).vox_id << ", " << (*it).L << "] \n";
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -144,14 +144,21 @@ VoxRaytracer::RayData
VoxRaytracer::TraceBetweenPoints(const HPoint3f &in, VoxRaytracer::TraceBetweenPoints(const HPoint3f &in,
const HPoint3f &out) const { const HPoint3f &out) const {
RayData ray; RayData ray;
// get the local points and the direction vector
// local to image means in the normalized voxel space where the size
// of the voxel is 1 in all dimensions
Vector4f pt1 = m_Image->GetLocalPoint(in); Vector4f pt1 = m_Image->GetLocalPoint(in);
Vector4f pt2 = m_Image->GetLocalPoint(out); Vector4f pt2 = m_Image->GetLocalPoint(out);
Vector4f s = pt2 - pt1; Vector4f s = pt2 - pt1;
// l is the total length of the ray in normalized voxel space
float l = s.head(3).norm(); float l = s.head(3).norm();
// L is the length of the ray between two grid lines in grid
Vector3f L(l / s(0), l / s(1), l / s(2)); Vector3f L(l / s(0), l / s(1), l / s(2));
// Vector3f scale; // FIXXX // Vector3f scale; // TODO: FIX Scaling
// scale << (m_Image->GetWorldMatrix() * Vector4f(1,0,0,0)).norm(), // scale << (m_Image->GetWorldMatrix() * Vector4f(1,0,0,0)).norm(),
// (m_Image->GetWorldMatrix() * Vector4f(0,1,0,0)).norm(), // (m_Image->GetWorldMatrix() * Vector4f(0,1,0,0)).norm(),
// (m_Image->GetWorldMatrix() * Vector4f(0,0,1,0)).norm(); // (m_Image->GetWorldMatrix() * Vector4f(0,0,1,0)).norm();
@@ -174,21 +181,23 @@ VoxRaytracer::TraceBetweenPoints(const HPoint3f &in,
float d; float d;
while (l > 0) { while (l > 0) {
// find which is the minimum of the offsets to the next grid line
// it will be also the actual normalized voxel ray length
d = offset.minCoeff(&id); d = offset.minCoeff(&id);
// see if the voxel is inside the grid (we are still inside image)
if (m_Image->IsInsideGrid(vid)) { if (m_Image->IsInsideGrid(vid)) {
// add the voxel to the ray with mapping id and length scaled
ray.AddElement(m_Image->Map(vid), d * m_scale(id)); ray.AddElement(m_Image->Map(vid), d * m_scale(id));
} }
// nan check // // move to the next voxel
// if(unlikely(!isFinite(d * scale(id)))) {
// std:: cout << "NAN in raytracer\n";
// exit(1);
// }
vid(id) += (int)fast_sign(s(id)); vid(id) += (int)fast_sign(s(id));
// update the remaining length
l -= d; l -= d;
// update the offsets
offset.array() -= d; offset.array() -= d;
offset(id) = fmin(L(id), l); offset(id) = fmin(L(id), l);
} }

View File

@@ -23,71 +23,108 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef VOXRAYTRACER_H #ifndef VOXRAYTRACER_H
#define VOXRAYTRACER_H #define VOXRAYTRACER_H
#include <Core/DataAllocator.h>
#include <Core/Vector.h>
#include <math.h> #include <math.h>
#include <vector> #include <vector>
#include "Math/StructuredGrid.h" #include "Math/StructuredGrid.h"
#include "Math/VoxImage.h"
#ifdef USE_CUDA
#include <cuda_runtime.h>
#endif
namespace uLib { namespace uLib {
class VoxRaytracer { class VoxRaytracer {
public: public:
class RayData { class RayData {
public: public:
RayData() : m_TotalLength(0) {} RayData() : m_TotalLength(0), m_Count(0) {}
typedef struct { struct Element {
Id_t vox_id; Id_t vox_id;
Scalarf L; Scalarf L;
} Element; ~Element() {}
inline void AddElement(Id_t id, float L);
void AppendRay ( const RayData &in);
inline const std::vector<Element>& Data() const { return this->m_Data; }
inline const Scalarf& TotalLength() const { return this->m_TotalLength; }
void PrintSelf(std::ostream &o);
private:
std::vector<Element> m_Data;
Scalarf m_TotalLength;
}; };
inline void AddElement(Id_t id, float L);
public: void AppendRay(const RayData &in);
VoxRaytracer(StructuredGrid &image) : m_Image(&image) {
m_scale << inline uLib::Vector<Element> &Data() { return this->m_Data; }
(m_Image->GetWorldMatrix() * Vector4f(1,0,0,0)).norm(),
(m_Image->GetWorldMatrix() * Vector4f(0,1,0,0)).norm(), inline const uLib::Vector<Element> &Data() const { return this->m_Data; }
(m_Image->GetWorldMatrix() * Vector4f(0,0,1,0)).norm();
inline size_t Count() const { return this->m_Count; }
inline size_t size() const { return this->m_Count; }
inline const Scalarf &TotalLength() const { return this->m_TotalLength; }
inline void SetCount(size_t c) {
this->m_Count = c;
if (this->m_Data.size() != c) {
this->m_Data.resize(c);
}
} }
bool GetEntryPoint(const HLine3f &line, HPoint3f &pt); inline void SetTotalLength(Scalarf tl) { this->m_TotalLength = tl; }
bool GetExitPoint(const HLine3f &line, HPoint3f &pt); void PrintSelf(std::ostream &o);
RayData TraceBetweenPoints(const HPoint3f &in, const HPoint3f &out) const; private:
uLib::Vector<Element> m_Data;
Scalarf m_TotalLength;
size_t m_Count;
};
RayData TraceLine(const HLine3f &line) const; public:
VoxRaytracer(StructuredGrid &image) : m_Image(&image) {
m_scale << (m_Image->GetWorldMatrix() * Vector4f(1, 0, 0, 0)).norm(),
(m_Image->GetWorldMatrix() * Vector4f(0, 1, 0, 0)).norm(),
(m_Image->GetWorldMatrix() * Vector4f(0, 0, 1, 0)).norm();
}
inline StructuredGrid* GetImage() const { return this->m_Image; } bool GetEntryPoint(const HLine3f &line, HPoint3f &pt);
bool GetExitPoint(const HLine3f &line, HPoint3f &pt);
RayData TraceBetweenPoints(const HPoint3f &in, const HPoint3f &out) const;
RayData TraceLine(const HLine3f &line) const;
inline StructuredGrid *GetImage() const { return this->m_Image; }
#ifdef USE_CUDA
template <typename VoxelT>
void AccumulateLinesCUDA(const HLine3f *lines, size_t num_lines,
VoxImage<VoxelT> &image);
void TraceLineCUDA(const HLine3f *lines, size_t num_lines, RayData *out_rays,
int max_elements_per_ray = 128,
float *kernel_time_ms = nullptr);
void TraceBetweenPointsCUDA(const HPoint3f *in_pts, const HPoint3f *out_pts,
size_t num_lines, RayData *out_rays,
int max_elements_per_ray = 128,
float *kernel_time_ms = nullptr);
#endif
private: private:
StructuredGrid *m_Image; StructuredGrid *m_Image;
Vector3f m_scale; Vector3f m_scale;
}; };
} } // namespace uLib
#ifdef USE_CUDA
#include "Math/VoxRaytracerCUDA.hpp"
#endif
#endif // VOXRAYTRACER_H #endif // VOXRAYTRACER_H

View File

@@ -0,0 +1,548 @@
#ifndef VOXRAYTRACERCUDA_H
#define VOXRAYTRACERCUDA_H
#ifdef USE_CUDA
#include "Math/VoxImage.h"
#include "Math/VoxRaytracer.h"
#include <cuda_runtime.h>
namespace uLib {
#ifdef __CUDACC__
template <typename VoxelT>
__global__ void
RaytraceAccumulateKernel(const float *lines_data, int num_lines,
VoxelT *d_image, int dim0, int dim1, int dim2,
const float *inv_world_matrix_data, float scale0,
float scale1, float scale2) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx >= num_lines)
return;
const float *line_ptr = &lines_data[idx * 8];
float o_vec[4] = {line_ptr[0], line_ptr[1], line_ptr[2], line_ptr[3]};
float d_vec[4] = {line_ptr[4], line_ptr[5], line_ptr[6], line_ptr[7]};
float pt[4] = {0, 0, 0, 0};
float s[4] = {0, 0, 0, 0};
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
float m_val = inv_world_matrix_data[i + j * 4];
pt[i] += m_val * o_vec[j];
s[i] += m_val * d_vec[j];
}
}
float l = sqrtf(s[0] * s[0] + s[1] * s[1] + s[2] * s[2]);
if (l == 0)
return;
float L[3];
L[0] = l / s[0];
L[1] = l / s[1];
L[2] = l / s[2];
float offset[3];
for (int i = 0; i < 3; ++i) {
float fpt_i = floorf(pt[i]);
offset[i] = (s[i] >= 0) ? (1.0f - (pt[i] - fpt_i)) : (pt[i] - fpt_i);
offset[i] = fabsf(offset[i] * L[i]);
L[i] = fabsf(L[i]);
}
int id;
float d;
int vid[3] = {(int)floorf(pt[0]), (int)floorf(pt[1]), (int)floorf(pt[2])};
float scale_arr[3] = {scale0, scale1, scale2};
while (vid[0] >= 0 && vid[0] < dim0 && vid[1] >= 0 && vid[1] < dim1 &&
vid[2] >= 0 && vid[2] < dim2) {
d = offset[0];
id = 0;
if (offset[1] < d) {
d = offset[1];
id = 1;
}
if (offset[2] < d) {
d = offset[2];
id = 2;
}
float L_intersect = d * scale_arr[id];
size_t vox_index = vid[0] * dim1 * dim2 + vid[1] * dim2 + vid[2];
atomicAdd(&(d_image[vox_index].Value), L_intersect);
float sign_s = (s[id] >= 0) ? 1.0f : -1.0f;
vid[id] += (int)sign_s;
offset[0] -= d;
offset[1] -= d;
offset[2] -= d;
offset[id] = L[id];
}
}
#endif
template <typename VoxelT>
void VoxRaytracer::AccumulateLinesCUDA(const HLine3f *lines, size_t num_lines,
VoxImage<VoxelT> &image) {
if (num_lines == 0)
return;
image.Data().MoveToVRAM();
float *d_lines = nullptr;
size_t lines_size = num_lines * sizeof(HLine3f);
cudaMalloc(&d_lines, lines_size);
cudaMemcpy(d_lines, lines, lines_size, cudaMemcpyHostToDevice);
int threadsPerBlock = 256;
int blocksPerGrid = (num_lines + threadsPerBlock - 1) / threadsPerBlock;
Vector3i dims = image.GetDims();
Matrix4f inv_world_matrix = image.GetWorldMatrix().inverse();
float *d_inv_world;
cudaMalloc(&d_inv_world, 16 * sizeof(float));
cudaMemcpy(d_inv_world, inv_world_matrix.data(), 16 * sizeof(float),
cudaMemcpyHostToDevice);
#ifdef __CUDACC__
RaytraceAccumulateKernel<<<blocksPerGrid, threadsPerBlock>>>(
d_lines, num_lines, image.Data().GetVRAMData(), dims(0), dims(1), dims(2),
d_inv_world, m_scale(0), m_scale(1), m_scale(2));
cudaDeviceSynchronize();
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) {
std::cerr << "CUDA Error in AccumulateLinesCUDA: "
<< cudaGetErrorString(err) << std::endl;
}
#else
std::cerr << "RaytraceAccumulateKernel requires NVCC!" << std::endl;
#endif
cudaFree(d_lines);
cudaFree(d_inv_world);
}
#ifdef __CUDACC__
__global__ void TraceBetweenPointsKernel(
const float *in_pts_data, const float *out_pts_data, int num_lines,
VoxRaytracer::RayData::Element **d_out_elements, size_t *d_out_counts,
float *d_out_lengths, int max_elements, int dim0, int dim1, int dim2,
const float *inv_world_matrix_data, float scale0, float scale1,
float scale2, int inc0, int inc1, int inc2) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx >= num_lines)
return;
VoxRaytracer::RayData::Element *ray_out = d_out_elements[idx];
size_t count = 0;
float tot_len = 0.0f;
const float *in_ptr = &in_pts_data[idx * 4];
const float *out_ptr = &out_pts_data[idx * 4];
float pt1[4] = {0, 0, 0, 0}, pt2[4] = {0, 0, 0, 0};
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
float m_val = inv_world_matrix_data[i + j * 4];
pt1[i] += m_val * in_ptr[j];
pt2[i] += m_val * out_ptr[j];
}
}
float s[4];
for (int i = 0; i < 4; ++i)
s[i] = pt2[i] - pt1[i];
float l = sqrtf(s[0] * s[0] + s[1] * s[1] + s[2] * s[2]);
if (l == 0) {
d_out_counts[idx] = count;
d_out_lengths[idx] = tot_len;
return;
}
float L[3];
L[0] = fabsf(l / s[0]);
L[1] = fabsf(l / s[1]);
L[2] = fabsf(l / s[2]);
float offset[3];
for (int i = 0; i < 3; ++i) {
float fpt_i = floorf(pt1[i]);
offset[i] = (s[i] >= 0) ? (1.0f - (pt1[i] - fpt_i)) : (pt1[i] - fpt_i);
offset[i] = fabsf(offset[i] * L[i]);
}
int vid[3] = {(int)floorf(pt1[0]), (int)floorf(pt1[1]), (int)floorf(pt1[2])};
int vid_out[3] = {(int)floorf(pt2[0]), (int)floorf(pt2[1]),
(int)floorf(pt2[2])};
float scale_arr[3] = {scale0, scale1, scale2};
if (vid[0] == vid_out[0] && vid[1] == vid_out[1] && vid[2] == vid_out[2]) {
if (vid[0] >= 0 && vid[0] < dim0 && vid[1] >= 0 && vid[1] < dim1 &&
vid[2] >= 0 && vid[2] < dim2) {
if (count < max_elements) {
int map_id = vid[0] * inc0 + vid[1] * inc1 + vid[2] * inc2;
ray_out[count].vox_id = map_id;
ray_out[count].L = l;
tot_len += l;
count++;
}
}
d_out_counts[idx] = count;
d_out_lengths[idx] = tot_len;
return;
}
int id;
float d;
while (l > 0) {
d = offset[0];
id = 0;
if (offset[1] < d) {
d = offset[1];
id = 1;
}
if (offset[2] < d) {
d = offset[2];
id = 2;
}
if (vid[0] >= 0 && vid[0] < dim0 && vid[1] >= 0 && vid[1] < dim1 &&
vid[2] >= 0 && vid[2] < dim2) {
if (count < max_elements) {
int map_id = vid[0] * inc0 + vid[1] * inc1 + vid[2] * inc2;
ray_out[count].vox_id = map_id;
ray_out[count].L = d * scale_arr[id];
tot_len += d * scale_arr[id];
count++;
}
}
float sign_s = (s[id] >= 0) ? 1.0f : -1.0f;
vid[id] += (int)sign_s;
l -= d;
offset[0] -= d;
offset[1] -= d;
offset[2] -= d;
offset[id] = fminf(L[id], l);
}
d_out_counts[idx] = count;
d_out_lengths[idx] = tot_len;
}
__global__ void TraceLineKernel(const float *lines_data, int num_lines,
VoxRaytracer::RayData::Element **d_out_elements,
size_t *d_out_counts, float *d_out_lengths,
int max_elements, int dim0, int dim1, int dim2,
const float *inv_world_matrix_data,
float scale0, float scale1, float scale2,
int inc0, int inc1, int inc2) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx >= num_lines)
return;
VoxRaytracer::RayData::Element *ray_out = d_out_elements[idx];
size_t count = 0;
float tot_len = 0.0f;
const float *line_ptr = &lines_data[idx * 8];
float o_vec[4] = {line_ptr[0], line_ptr[1], line_ptr[2], line_ptr[3]};
float d_vec[4] = {line_ptr[4], line_ptr[5], line_ptr[6], line_ptr[7]};
float pt[4] = {0, 0, 0, 0}, s[4] = {0, 0, 0, 0};
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
float m_val = inv_world_matrix_data[i + j * 4];
pt[i] += m_val * o_vec[j];
s[i] += m_val * d_vec[j];
}
}
float l = sqrtf(s[0] * s[0] + s[1] * s[1] + s[2] * s[2]);
if (l == 0) {
d_out_counts[idx] = count;
d_out_lengths[idx] = tot_len;
return;
}
float L[3];
L[0] = fabsf(l / s[0]);
L[1] = fabsf(l / s[1]);
L[2] = fabsf(l / s[2]);
float offset[3];
for (int i = 0; i < 3; ++i) {
float fpt_i = floorf(pt[i]);
offset[i] = (s[i] >= 0) ? (1.0f - (pt[i] - fpt_i)) : (pt[i] - fpt_i);
offset[i] = fabsf(offset[i] * L[i]);
}
int id;
float d;
int vid[3] = {(int)floorf(pt[0]), (int)floorf(pt[1]), (int)floorf(pt[2])};
float scale_arr[3] = {scale0, scale1, scale2};
while (vid[0] >= 0 && vid[0] < dim0 && vid[1] >= 0 && vid[1] < dim1 &&
vid[2] >= 0 && vid[2] < dim2) {
d = offset[0];
id = 0;
if (offset[1] < d) {
d = offset[1];
id = 1;
}
if (offset[2] < d) {
d = offset[2];
id = 2;
}
if (count < max_elements) {
int map_id = vid[0] * inc0 + vid[1] * inc1 + vid[2] * inc2;
ray_out[count].vox_id = map_id;
ray_out[count].L = d * scale_arr[id];
tot_len += d * scale_arr[id];
count++;
}
float sign_s = (s[id] >= 0) ? 1.0f : -1.0f;
vid[id] += (int)sign_s;
offset[0] -= d;
offset[1] -= d;
offset[2] -= d;
offset[id] = L[id];
}
d_out_counts[idx] = count;
d_out_lengths[idx] = tot_len;
}
#endif // __CUDACC__
inline void VoxRaytracer::TraceLineCUDA(const HLine3f *lines, size_t num_lines,
RayData *out_rays,
int max_elements_per_ray,
float *kernel_time_ms) {
if (num_lines == 0)
return;
float *d_lines = nullptr;
bool alloc_lines = false;
cudaPointerAttributes ptr_attr;
cudaPointerGetAttributes(&ptr_attr, lines);
if (ptr_attr.type == cudaMemoryTypeDevice) {
d_lines = (float *)lines;
} else {
alloc_lines = true;
size_t lines_size = num_lines * sizeof(HLine3f);
cudaMalloc(&d_lines, lines_size);
cudaMemcpy(d_lines, lines, lines_size, cudaMemcpyHostToDevice);
}
std::vector<RayData::Element *> h_out_elements(num_lines);
for (size_t i = 0; i < num_lines; ++i) {
out_rays[i].Data().resize(max_elements_per_ray);
out_rays[i].Data().MoveToVRAM();
h_out_elements[i] = out_rays[i].Data().GetVRAMData();
}
RayData::Element **d_out_elements;
cudaMalloc(&d_out_elements, num_lines * sizeof(RayData::Element *));
cudaMemcpy(d_out_elements, h_out_elements.data(),
num_lines * sizeof(RayData::Element *), cudaMemcpyHostToDevice);
size_t *d_out_counts;
float *d_out_lengths;
cudaMalloc(&d_out_counts, num_lines * sizeof(size_t));
cudaMalloc(&d_out_lengths, num_lines * sizeof(float));
int threadsPerBlock = 256;
int blocksPerGrid = (num_lines + threadsPerBlock - 1) / threadsPerBlock;
Vector3i dims = m_Image->GetDims();
Vector3i incs = m_Image->GetIncrements();
Matrix4f inv_world_matrix = m_Image->GetWorldMatrix().inverse();
float *d_inv_world;
cudaMalloc(&d_inv_world, 16 * sizeof(float));
cudaMemcpy(d_inv_world, inv_world_matrix.data(), 16 * sizeof(float),
cudaMemcpyHostToDevice);
#ifdef __CUDACC__
cudaEvent_t start, stop;
if (kernel_time_ms) {
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start);
}
TraceLineKernel<<<blocksPerGrid, threadsPerBlock>>>(
d_lines, num_lines, d_out_elements, d_out_counts, d_out_lengths,
max_elements_per_ray, dims(0), dims(1), dims(2), d_inv_world, m_scale(0),
m_scale(1), m_scale(2), incs(0), incs(1), incs(2));
if (kernel_time_ms) {
cudaEventRecord(stop);
cudaEventSynchronize(stop);
cudaEventElapsedTime(kernel_time_ms, start, stop);
cudaEventDestroy(start);
cudaEventDestroy(stop);
} else {
cudaDeviceSynchronize();
}
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) {
std::cerr << "CUDA Error in TraceLineCUDA: " << cudaGetErrorString(err)
<< std::endl;
}
#else
std::cerr << "TraceLineKernel requires NVCC!" << std::endl;
#endif
std::vector<size_t> h_out_counts(num_lines);
std::vector<float> h_out_lengths(num_lines);
cudaMemcpy(h_out_counts.data(), d_out_counts, num_lines * sizeof(size_t),
cudaMemcpyDeviceToHost);
cudaMemcpy(h_out_lengths.data(), d_out_lengths, num_lines * sizeof(float),
cudaMemcpyDeviceToHost);
for (size_t i = 0; i < num_lines; ++i) {
out_rays[i].SetCount(h_out_counts[i]);
out_rays[i].SetTotalLength(h_out_lengths[i]);
}
if (alloc_lines) {
cudaFree(d_lines);
}
cudaFree(d_out_elements);
cudaFree(d_out_counts);
cudaFree(d_out_lengths);
cudaFree(d_inv_world);
}
inline void VoxRaytracer::TraceBetweenPointsCUDA(
const HPoint3f *in_pts, const HPoint3f *out_pts, size_t num_lines,
RayData *out_rays, int max_elements_per_ray, float *kernel_time_ms) {
if (num_lines == 0)
return;
float *d_in_pts = nullptr;
float *d_out_pts = nullptr;
bool alloc_pts = false;
cudaPointerAttributes ptr_attr;
cudaPointerGetAttributes(&ptr_attr, in_pts);
if (ptr_attr.type == cudaMemoryTypeDevice) {
d_in_pts = (float *)in_pts;
d_out_pts = (float *)out_pts;
} else {
alloc_pts = true;
size_t pts_size = num_lines * sizeof(HPoint3f);
cudaMalloc(&d_in_pts, pts_size);
cudaMalloc(&d_out_pts, pts_size);
cudaMemcpy(d_in_pts, in_pts, pts_size, cudaMemcpyHostToDevice);
cudaMemcpy(d_out_pts, out_pts, pts_size, cudaMemcpyHostToDevice);
}
std::vector<RayData::Element *> h_out_elements(num_lines);
for (size_t i = 0; i < num_lines; ++i) {
out_rays[i].Data().resize(max_elements_per_ray);
out_rays[i].Data().MoveToVRAM();
h_out_elements[i] = out_rays[i].Data().GetVRAMData();
}
RayData::Element **d_out_elements;
cudaMalloc(&d_out_elements, num_lines * sizeof(RayData::Element *));
cudaMemcpy(d_out_elements, h_out_elements.data(),
num_lines * sizeof(RayData::Element *), cudaMemcpyHostToDevice);
size_t *d_out_counts;
float *d_out_lengths;
cudaMalloc(&d_out_counts, num_lines * sizeof(size_t));
cudaMalloc(&d_out_lengths, num_lines * sizeof(float));
int threadsPerBlock = 256;
int blocksPerGrid = (num_lines + threadsPerBlock - 1) / threadsPerBlock;
Vector3i dims = m_Image->GetDims();
Vector3i incs = m_Image->GetIncrements();
Matrix4f inv_world_matrix = m_Image->GetWorldMatrix().inverse();
float *d_inv_world;
cudaMalloc(&d_inv_world, 16 * sizeof(float));
cudaMemcpy(d_inv_world, inv_world_matrix.data(), 16 * sizeof(float),
cudaMemcpyHostToDevice);
#ifdef __CUDACC__
cudaEvent_t start, stop;
if (kernel_time_ms) {
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start);
}
TraceBetweenPointsKernel<<<blocksPerGrid, threadsPerBlock>>>(
d_in_pts, d_out_pts, num_lines, d_out_elements, d_out_counts,
d_out_lengths, max_elements_per_ray, dims(0), dims(1), dims(2),
d_inv_world, m_scale(0), m_scale(1), m_scale(2), incs(0), incs(1),
incs(2));
if (kernel_time_ms) {
cudaEventRecord(stop);
cudaEventSynchronize(stop);
cudaEventElapsedTime(kernel_time_ms, start, stop);
cudaEventDestroy(start);
cudaEventDestroy(stop);
} else {
cudaDeviceSynchronize();
}
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) {
std::cerr << "CUDA Error in TraceBetweenPointsCUDA: "
<< cudaGetErrorString(err) << std::endl;
}
#else
std::cerr << "TraceBetweenPointsKernel requires NVCC!" << std::endl;
#endif
std::vector<size_t> h_out_counts(num_lines);
std::vector<float> h_out_lengths(num_lines);
cudaMemcpy(h_out_counts.data(), d_out_counts, num_lines * sizeof(size_t),
cudaMemcpyDeviceToHost);
cudaMemcpy(h_out_lengths.data(), d_out_lengths, num_lines * sizeof(float),
cudaMemcpyDeviceToHost);
for (size_t i = 0; i < num_lines; ++i) {
out_rays[i].SetCount(h_out_counts[i]);
out_rays[i].SetTotalLength(h_out_lengths[i]);
}
if (alloc_pts) {
cudaFree(d_in_pts);
cudaFree(d_out_pts);
}
cudaFree(d_out_elements);
cudaFree(d_out_counts);
cudaFree(d_out_lengths);
cudaFree(d_inv_world);
}
} // namespace uLib
#endif // USE_CUDA
#endif // VOXRAYTRACERCUDA_H

View File

@@ -23,88 +23,90 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#include "Math/Accumulator.h" #include "Math/Accumulator.h"
#include "testing-prototype.h" #include "testing-prototype.h"
#include <TRandom.h> #include <TRandom.h>
#include <iostream>
#include <vector>
// #include <boost/accumulators/framework/accumulator_set.hpp>
//#include <boost/accumulators/framework/accumulator_set.hpp> // #include <boost/accumulators/statistics/count.hpp>
//#include <boost/accumulators/statistics/count.hpp> // #include <boost/accumulators/accumulators.hpp>
//#include <boost/accumulators/accumulators.hpp>
using namespace uLib; using namespace uLib;
int test_ABTrim() { int test_ABTrim() {
Accumulator_ABTrim<float> acc; Accumulator_ABTrim<float> acc;
acc.SetABTrim(1,1); acc.SetABTrim(1, 1);
std::vector<float> v; std::vector<float> v;
for(float tmpf : {1,5,5,5,300}) v.push_back(tmpf); for (float tmpf : {1, 5, 5, 5, 300})
//v << 1,5,5,5,300; v.push_back(tmpf);
// v << 1,5,5,5,300;
for(std::vector<float>::iterator itr=v.begin(); itr<v.end(); itr++) for (std::vector<float>::iterator itr = v.begin(); itr < v.end(); itr++)
acc += *itr; acc += *itr;
// TODO missing operator << // TODO missing operator <<
//std::cout << "Accumulating Trim(1,1) vector: " // std::cout << "Accumulating Trim(1,1) vector: "
// << v << " ... out = " << acc() << "\n"; // << v << " ... out = " << acc() << "\n";
return( acc() == 15.0 );
return (acc() == 15.0);
} }
int test_Mean() { int test_Mean() {
Accumulator_Mean<float> mean; Accumulator_Mean<float> mean;
TRandom rnd; TRandom rnd;
const int c = 10000000; const int c = 10000000;
std::vector<float> v; std::vector<float> v;
v.reserve(c); v.reserve(c);
for(int i=0;i<c;++i) v.push_back( rnd.Gaus(2000,5) ); for (int i = 0; i < c; ++i)
v.push_back(rnd.Gaus(2000, 5));
float m = 0;
for(int i=0;i<c;++i) m += v[i];
m /= c;
std::cout << "simple mean: " << m << "\n";
for(int i=0;i<c;++i) mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for(int i=0;i<c;++i) mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for(int i=0;i<c;++i) mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for(int i=0;i<c;++i) mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for(int i=0;i<c;++i) mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for(int i=0;i<c;++i) mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for(int i=0;i<c;++i) mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
float m = 0;
for (int i = 0; i < c; ++i)
m += v[i];
m /= c;
std::cout << "simple mean: " << m << "\n";
for (int i = 0; i < c; ++i)
mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for (int i = 0; i < c; ++i)
mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for (int i = 0; i < c; ++i)
mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for (int i = 0; i < c; ++i)
mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for (int i = 0; i < c; ++i)
mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for (int i = 0; i < c; ++i)
mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
mean.AddPass();
for (int i = 0; i < c; ++i)
mean(v[i]);
std::cout << "mean pass: " << mean() << "\n";
return 1;
} }
int main(void) { int main(void) {
BEGIN_TESTING(Accumulator); BEGIN_TESTING(Accumulator);
//TEST1( test_ABTrim() ); // TEST1( test_ABTrim() );
test_Mean(); test_Mean();
END_TESTING; END_TESTING;
} }

View File

@@ -5,6 +5,7 @@ set(TESTS
ContainerBoxTest ContainerBoxTest
VoxImageTest VoxImageTest
VoxRaytracerTest VoxRaytracerTest
VoxRaytracerTestExtended
StructuredDataTest StructuredDataTest
VoxImageFilterTest VoxImageFilterTest
PolicyTest PolicyTest
@@ -17,6 +18,13 @@ set(TESTS
set(LIBRARIES set(LIBRARIES
${PACKAGE_LIBPREFIX}Core ${PACKAGE_LIBPREFIX}Core
${PACKAGE_LIBPREFIX}Math ${PACKAGE_LIBPREFIX}Math
Boost::serialization
Eigen3::Eigen
) )
uLib_add_tests(Math) uLib_add_tests(Math)
if(USE_CUDA)
set_source_files_properties(VoxImageTest.cpp VoxImageCopyTest.cpp VoxImageFilterTest.cpp VoxRaytracerTest.cpp VoxRaytracerTestExtended.cpp PROPERTIES LANGUAGE CUDA)
set_source_files_properties(VoxRaytracerTest.cpp VoxRaytracerTestExtended.cpp PROPERTIES CXX_STANDARD 17 CUDA_STANDARD 17)
endif()

Some files were not shown because too many files have changed in this diff Show More