Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for MSVC compilers #46

Open
wants to merge 17 commits into
base: 35-investigate-migrating-to-meson
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions .github/workflows/build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: recursive

Expand All @@ -26,21 +26,19 @@ jobs:
with:
python-version: '3.11'

- name: Install rtools (mingw-w64) (see SciPy workflow for more details)
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
choco install rtools -y --no-progress --force --version=4.0.0.20220206
echo "c:\rtools40\ucrt64\bin;" >> $env:GITHUB_PATH
fi
shell: bash

- name: Install build dependencies from PyPI
run: |
python -m pip install meson cmake ninja

- name: Configure Meson
# Configure meson to dump all executables in the test directory so Windows would work
- name: Configure Meson (POSIX)
# Configure meson for POSIX environments
if: startsWith(matrix.os, 'windows') != true
run: cd ${{github.workspace}} && meson setup builddir

- name: Configure Meson (Windows)
# Configure meson for Windows environments
if: startsWith(matrix.os, 'windows') == true
run: cd ${{github.workspace}} && meson setup builddir --vsenv

- name: Build
# Build your program with the given configuration
Expand All @@ -49,4 +47,4 @@ jobs:
- name: Test
working-directory: ${{github.workspace}}/builddir
# Execute tests defined by meson test configuration.
run: meson test -v
run: meson test -v -j 1
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ TAGS
*.#*
*.o
*.so
*.dll
*.lib
*.exp
.vs/
.vscode/
.idea/
test/
build/
tests/
builddir/
54 changes: 32 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,34 @@

This project is the result of the collaborative effort of numerous researchers in order to provide one of the fastest PIV software on the market while remaining cross-platform and open-source. The software can do the following:

* Load images with .tif and .pnm extensions
* Save images with .tif and .pnm extensions
* Load images
* Save images
* Pre-process and modify images
* Perform digital PIV analysis including subpixel estimation
* and more!

Additionally, two examples are provided to demonstrate how the library can be used for background subtraction of images and multi-threaded PIV analysis.
## Image Loaders

Loading and storing images are crucial for any PIV software. Due to this requirement, openpiv-c--qt implements image loaders that can load, convert, and store images.
Currently, there are a few extensions that are supported, but more are under development.

|Supported Extensions | Decode | Encode |
|-------------------------|--------|--------|
| .b16 (PCO CamWare :tm: )| Planned| - |
| .bmp | Planned| Planned|
| .jpeg | Planned| Planned|
| .png | Planned| Planned|
| .pnm (.pbm, .pgm, .ppm) | x | x |
| .tif | x | x |
| .webp | Planned| Planned|

## Examples

To demonstrate how this library can perform, two examples are provided in the /examples folder. The first example,
[average_subtract](examples/average_subtract/README.md), is a utility that reads n images, calculates the average, and
writes out n new images with the average subtracted. Additionally, a second example, [process](examples/process/README.md),
is a straight-forward PIV cross correlator that reads two images and performs cross-correlation on them.

## Build

There are some external dependencies under external/, so when cloning use:
Expand All @@ -28,21 +48,22 @@ Building uses meson, and is simplified by using meson wrap files to specify the
* (linux) pkg-config (e.g. `apt install pkg-config`)
* curl, zip, unzip, tar (e.g. `apt install curl zip unzip tar`)
* ninja (e.g. `apt install ninja-build`)
* meson (e.g., pip install --user meson)
* meson (e.g., `pip install --user meson`)

Unix users can also use the method used for the Windows build environment as detailed below.
Unix users can also use a similar method to the Windows build environment as detailed below.

On Windows, the following can be used:
* install TDM-GCC or any other Windows GNU distribution
* install miniconda or venv and setup virtual environment
* install Visual Studio 2019 or 2022. Alternatively, MinGW-64 (installed via TDM-GCC 10) and Intel OneAPI c/c++ compilers are also known to work
* install miniconda or python along with venv and setup virtual environment
* pip install cmake (optional)
* pip install ninja
* pip install meson

To build:
* `meson setup builddir` Note, it is good practice to setup --prefix flags so files are not installed on the system.
* `meson setup builddir` Note, it is good practice to setup `--prefix` flags so files are not installed on the system.
* `meson compile -C builddir`

Meson provides multiple build types such as debug, debugoptimized, and release. To change the build type, use the --buildtype flag. For example, `meson setup builddir --buildtype debugoptimized`.
Meson provides multiple build types such as debug, debugoptimized, and release. To change the build type, use the `--buildtype` flag. For example, `meson setup builddir --buildtype debugoptimized`.

To run tests:

Expand All @@ -57,7 +78,7 @@ Sometimes you only want the runtime dynamic libraries and executables. Meson com

Make sure the prefix, or destdir, is set so binaries are not accidentally installed on the system.

The binaries are located the build or installation directory:
The binaries are located in the build or installation directory:

Build directory:
* builddir
Expand Down Expand Up @@ -195,27 +216,16 @@ sys 0m0.020s
This is about 230us per interrogation area (7 cores, 3696 interrogation areas, 0.122s)

## Dependencies

These are captured in `<dependency>.wrap`:

* c++17 compiler e.g. clang++-5.0, gcc7
* c++17 compiler e.g. clang++-5.0, gcc8
* python3
* [meson](https://mesonbuild.com/index.html)
* benchmark: used to run performance benchmarks
* catch2: unit test framework
* cxxopts: nice command line parsing
* libtiff: TIFF IO support
* libjpeg-turbo
* liblzma
* zlib

## Examples

* under build/examples are two simple applications:
* [process](examples/process/README.md): a straight-forward PIV cross correlator
* [average_subtract](examples/average_subtract/README.md): a utility to read in n
images, find the average and write out n new images with the mean subtracted

# TODO

* build
Expand Down
42 changes: 18 additions & 24 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,33 @@ project(
default_options: [
'buildtype=release',
'cpp_std=c++17',
'warning_level=2'
'warning_level=2'
]
)

fs = import('fs')

cpp = meson.get_compiler('cpp')

if cpp.get_id() == 'gcc'
cxx_compiler = cpp.get_id()

if cxx_compiler == 'gcc'
if not cpp.version().version_compare('>=8.4')
error('OpenPIV-c++ requires GCC >= 8.4')
endif
elif cpp.get_id() == 'msvc'
error('OpenPIV-c++ requires a GNU GCC compatible compiler')
endif

_gnu_args = cpp.get_supported_arguments(
'-Wno-unknown-pragmas',
'-export-symbols'
)

add_project_arguments(
_gnu_args,
language: 'cpp'
)
if cxx_compiler != 'msvc'
_gnu_args = cpp.get_supported_arguments(
'-ffast-math',
'-Wno-unknown-pragmas',
)

add_project_arguments(
_gnu_args,
language: 'cpp'
)
endif

pocketfft_include = include_directories(
'external/pocketfft'
Expand Down Expand Up @@ -89,14 +91,6 @@ jpeg_dep = dependency(
# static: true
)

lzma_dep = dependency(
'liblzma',
fallback: ['liblzma', 'lzma_dep'],
include_type: get_option('deps_include_type'),
required: true
# static: true
)

zlib_dep = dependency(
'zlib',
fallback: ['zlib', 'zlib_dep'],
Expand All @@ -109,7 +103,7 @@ tiff_dep = dependency(
'libtiff',
fallback: ['libtiff', 'libtiff4_dep'],
include_type: get_option('deps_include_type'),
default_options: ['jpeg=enabled', 'lzma=enabled', 'zlib=enabled'],
default_options: ['jpeg=enabled', 'zlib=enabled'],
required: true
# static: true
)
Expand All @@ -123,7 +117,7 @@ if get_option('benchmarks').enabled()
found_benchmark = benchmark_dep.found()
endif

openpivcore_deps = [
libopenpivcore_deps = [
fmt_dep,
# jpeg_dep, # jpeg image loaders are not currently implemented
# png_dep, # png image loaders are not currently implemented
Expand All @@ -142,7 +136,7 @@ subdir('openpiv')

openpiv_dep = declare_dependency(
include_directories: openpiv_include,
dependencies: openpivcore_deps,
dependencies: libopenpivcore_deps,
link_with: openpiv_lib
)

Expand Down
12 changes: 12 additions & 0 deletions openpiv/core/dll_export.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

#pragma once

#ifndef DLL_EXPORT

#if defined(_MSC_VER) && defined(EXPORT_DLL_SYMBOLS)
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif

#endif
34 changes: 18 additions & 16 deletions openpiv/core/rect.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
// local
#include "core/point.h"
#include "core/size.h"
#include "core/dll_export.h"

namespace openpiv::core {

/// basic 2D integer rectangle defined in terms of an origin (bottom left) and size.
/// bottom left in this case means the minimum of x and y.

class rect
{
public:
Expand All @@ -20,21 +22,21 @@ class rect
rect() = default;
rect( const rect& ) = default;
rect( rect&& ) = default;
rect( const point_t& bl, const core::size& size );
DLL_EXPORT rect( const point_t& bl, const core::size& size );

/// construct a rect from size with default origin
static rect from_size( const core::size& s );
DLL_EXPORT static rect from_size( const core::size& s );

rect& operator=( const rect& ) = default;
rect& operator=( rect&& ) = default;
bool operator==(const rect& rhs) const;
bool operator!=(const rect& rhs) const;
DLL_EXPORT bool operator==(const rect& rhs) const;
DLL_EXPORT bool operator!=(const rect& rhs) const;

point_t bottomLeft() const;
point_t topLeft() const;
point_t bottomRight() const;
point_t topRight() const;
point_t midpoint() const;
DLL_EXPORT point_t bottomLeft() const;
DLL_EXPORT point_t topLeft() const;
DLL_EXPORT point_t bottomRight() const;
DLL_EXPORT point_t topRight() const;
DLL_EXPORT point_t midpoint() const;

inline point_t::value_t bottom() const { return bottomLeft_[1]; }
inline point_t::value_t top() const { return bottom() + height(); }
Expand All @@ -47,16 +49,16 @@ class rect
inline core::size::component_t area() const { return size_.area(); }

/// is this rectangle wholly within \a r1
bool within( const rect& r1 ) const;
DLL_EXPORT bool within( const rect& r1 ) const;

/// is \a r1 wholly contained within this rectangle
bool contains( const rect& r1 ) const;
DLL_EXPORT bool contains( const rect& r1 ) const;

/// construct a dilated rectangle; positive values of d will grow
/// the rectangle, negative will shrink:
///
/// { {0, 0}, {10, 10} }.dilate(2) -> { {-2, -2}, {14, 14} }
rect dilate( int32_t d ) const;
DLL_EXPORT rect dilate( int32_t d ) const;

/// construct a dilated rectangle; positive values of d will grow
/// the rectangle, negative will shrink:
Expand All @@ -66,14 +68,14 @@ class rect
/// - 1 is a nullop
///
/// { {0, 0}, {10, 10} }.dilate(1.2) -> { {-1, -1}, {12, 12} }
rect dilate( double d ) const;

DLL_EXPORT rect dilate( double d ) const;
private:
point_t bottomLeft_;
core::size size_;
};

/// ostream operator
std::ostream& operator<<( std::ostream& os, const rect& r );
DLL_EXPORT std::ostream& operator<<( std::ostream& os, const rect& r );

}
}
Loading