Skip to content

Commit c011035

Browse files
committed
Complete rewrite
Update the API, and make the tests more robust. Closes #75, #73.
1 parent 2b2e952 commit c011035

428 files changed

Lines changed: 100814 additions & 78424 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.clang-format

Lines changed: 68 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,95 @@
11
---
22
Language: Cpp
3-
# BasedOnStyle: LLVM
3+
# BasedOnStyle: Mozilla
44
AccessModifierOffset: -4
5-
ConstructorInitializerIndentWidth: 4
5+
AlignAfterOpenBracket: Align
6+
AlignConsecutiveAssignments: false
7+
AlignConsecutiveDeclarations: false
68
AlignEscapedNewlinesLeft: false
9+
AlignOperands: true
710
AlignTrailingComments: true
8-
AllowAllParametersOfDeclarationOnNextLine: true
11+
AllowAllParametersOfDeclarationOnNextLine: false
912
AllowShortBlocksOnASingleLine: false
13+
AllowShortCaseLabelsOnASingleLine: false
14+
AllowShortFunctionsOnASingleLine: Inline
1015
AllowShortIfStatementsOnASingleLine: false
1116
AllowShortLoopsOnASingleLine: false
12-
AllowShortFunctionsOnASingleLine: All
13-
AlwaysBreakTemplateDeclarations: true
17+
AlwaysBreakAfterDefinitionReturnType: None
18+
AlwaysBreakAfterReturnType: None
1419
AlwaysBreakBeforeMultilineStrings: false
15-
BreakBeforeBinaryOperators: false
16-
BreakBeforeTernaryOperators: true
17-
BreakConstructorInitializersBeforeComma: false
20+
AlwaysBreakTemplateDeclarations: true
21+
BinPackArguments: true
1822
BinPackParameters: true
23+
BraceWrapping:
24+
AfterClass: true
25+
AfterControlStatement: false
26+
AfterEnum: true
27+
AfterFunction: true
28+
AfterNamespace: false
29+
AfterObjCDeclaration: false
30+
AfterStruct: true
31+
AfterUnion: true
32+
BeforeCatch: false
33+
BeforeElse: false
34+
IndentBraces: false
35+
BreakBeforeBinaryOperators: None
36+
BreakBeforeBraces: Attach
37+
BreakBeforeTernaryOperators: true
38+
BreakConstructorInitializersBeforeComma: true
39+
BreakAfterJavaFieldAnnotations: false
40+
BreakStringLiterals: true
1941
ColumnLimit: 80
20-
ConstructorInitializerAllOnOneLineOrOnePerLine: true
42+
CommentPragmas: '^ IWYU pragma:'
43+
ConstructorInitializerAllOnOneLineOrOnePerLine: false
44+
ConstructorInitializerIndentWidth: 2
45+
ContinuationIndentWidth: 4
46+
Cpp11BracedListStyle: false
2147
DerivePointerAlignment: false
48+
DisableFormat: false
2249
ExperimentalAutoDetectBinPacking: false
23-
IndentCaseLabels: false
50+
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
51+
IncludeCategories:
52+
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
53+
Priority: 2
54+
- Regex: '^(<|"(gtest|isl|json)/)'
55+
Priority: 3
56+
- Regex: '.*'
57+
Priority: 1
58+
IncludeIsMainRegex: '$'
59+
IndentCaseLabels: true
60+
IndentWidth: 4
2461
IndentWrappedFunctionNames: false
25-
IndentFunctionDeclarationAfterType: false
26-
MaxEmptyLinesToKeep: 2
62+
JavaScriptQuotes: Leave
63+
JavaScriptWrapImports: true
2764
KeepEmptyLinesAtTheStartOfBlocks: true
65+
MacroBlockBegin: ''
66+
MacroBlockEnd: ''
67+
MaxEmptyLinesToKeep: 1
2868
NamespaceIndentation: None
29-
ObjCSpaceAfterProperty: false
30-
ObjCSpaceBeforeProtocolList: true
69+
ObjCBlockIndentWidth: 2
70+
ObjCSpaceAfterProperty: true
71+
ObjCSpaceBeforeProtocolList: false
3172
PenaltyBreakBeforeFirstCallParameter: 19
3273
PenaltyBreakComment: 300
33-
PenaltyBreakString: 1000
3474
PenaltyBreakFirstLessLess: 120
75+
PenaltyBreakString: 1000
3576
PenaltyExcessCharacter: 1000000
36-
PenaltyReturnTypeOnItsOwnLine: 60
77+
PenaltyReturnTypeOnItsOwnLine: 200
3778
PointerAlignment: Left
79+
ReflowComments: true
80+
SortIncludes: true
81+
SpaceAfterCStyleCast: false
82+
SpaceBeforeAssignmentOperators: true
83+
SpaceBeforeParens: ControlStatements
84+
SpaceInEmptyParentheses: false
3885
SpacesBeforeTrailingComments: 1
39-
Cpp11BracedListStyle: true
86+
SpacesInAngles: false
87+
SpacesInContainerLiterals: true
88+
SpacesInCStyleCastParentheses: false
89+
SpacesInParentheses: false
90+
SpacesInSquareBrackets: false
4091
Standard: Cpp11
41-
IndentWidth: 4
4292
TabWidth: 8
4393
UseTab: Never
44-
BreakBeforeBraces: Attach
45-
SpacesInParentheses: false
46-
SpacesInAngles: false
47-
SpaceInEmptyParentheses: false
48-
SpacesInCStyleCastParentheses: false
49-
SpacesInContainerLiterals: true
50-
SpaceBeforeAssignmentOperators: true
51-
ContinuationIndentWidth: 4
52-
CommentPragmas: '^ IWYU pragma:'
53-
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
54-
SpaceBeforeParens: ControlStatements
55-
DisableFormat: false
5694
...
5795

CMakeLists.txt

Lines changed: 47 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,72 @@
1-
project(cpd CXX)
21
cmake_minimum_required(VERSION 2.8.12)
2+
set(CPD_LANGUAGES CXX C)
3+
set(CPD_VERSION 0.4.0)
4+
set(CPD_SOVERSION 0)
35

4-
if(POLICY CMP0042)
5-
cmake_policy(SET CMP0042 NEW)
6+
# Policies
7+
if(POLICY CMP0048) # Project version
8+
cmake_policy(SET CMP0048 NEW)
9+
project(cpd LANGUAGES ${CPD_LANGUAGES} VERSION ${CPD_VERSION})
10+
else()
11+
project(cpd ${CPD_LANGUAGES})
612
endif()
7-
if(POLICY CMP0054)
8-
cmake_policy(SET CMP0054 NEW) # Quoted variables in IF statements
13+
14+
if(POLICY CMP0042) # MACOSX_RPATH
15+
cmake_policy(SET CMP0042 NEW)
916
endif()
1017

11-
set(CPD_VERSION 0.3.3)
12-
configure_file(
13-
src/version.cpp.in
14-
${PROJECT_BINARY_DIR}/src/version.cpp
15-
)
16-
set(CPD_SOVERSION 0)
17-
message(STATUS "[cpd] Version: ${CPD_VERSION}")
18+
# Depdencies
19+
find_package(Fgt REQUIRED)
1820

19-
set(GTEST_SOURCE_DIR "${PROJECT_SOURCE_DIR}/vendor/gtest-1.7.0")
21+
# Configuration
22+
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
2023

21-
option(WITH_TESTS "Build unit tests" ON)
24+
include(CMakePackageConfigHelpers)
25+
write_basic_package_version_file("${PROJECT_BINARY_DIR}/cmake/cpd-config-version.cmake" VERSION ${CPD_VERSION} COMPATIBILITY AnyNewerVersion)
26+
install(FILES cmake/cpd-config.cmake "${PROJECT_BINARY_DIR}/cmake/cpd-config-version.cmake" DESTINATION lib/cmake/cpd)
27+
configure_file(src/version.cpp.in "${PROJECT_BINARY_DIR}/src/version.cpp")
2228

23-
set(FGT_MINIMUM_VERSION 0.4)
24-
find_package(Fgt ${FGT_MINIMUM_VERSION} REQUIRED)
25-
message(STATUS "[cpd] Fgt version: ${Fgt_VERSION}")
29+
option(WITH_STRICT_WARNINGS "Build with stricter warnings" ON)
30+
if(WITH_STRICT_WARNINGS)
31+
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
32+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Wno-gnu-zero-variadic-macro-arguments")
33+
endif()
34+
endif()
2635

27-
add_library(Library-C++
28-
src/affine.cpp
29-
src/matrix.cpp
36+
# Targets
37+
set(library_src
38+
src/affinity_matrix.cpp
3039
src/nonrigid.cpp
31-
src/normalization.cpp
40+
src/normalize.cpp
3241
src/rigid.cpp
42+
src/probabilities.cpp
3343
src/utils.cpp
34-
${PROJECT_BINARY_DIR}/src/version.cpp
35-
)
36-
target_include_directories(Library-C++
37-
INTERFACE
38-
${CMAKE_INSTALL_PREFIX}/include
39-
PRIVATE
40-
include
41-
)
42-
target_link_libraries(Library-C++
43-
PUBLIC
44-
Fgt::Library-C++
45-
)
46-
target_compile_definitions(Library-C++
47-
PRIVATE
48-
_USE_MATH_DEFINES
44+
"${PROJECT_BINARY_DIR}/src/version.cpp"
4945
)
50-
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
51-
target_compile_options(Library-C++
52-
PRIVATE
53-
-pedantic -Wall
54-
)
55-
endif()
46+
add_library(Library-C++ ${library_src})
5647
set_target_properties(Library-C++ PROPERTIES
5748
OUTPUT_NAME cpd
5849
VERSION ${CPD_VERSION}
5950
SOVERSION ${CPD_SOVERSION}
6051
)
52+
target_link_libraries(Library-C++ PUBLIC Fgt::Library-C++)
53+
target_include_directories(Library-C++
54+
INTERFACE $<INSTALL_INTERFACE:include> $<INSTALL_INTERFACE:include/cpd/vendor>
55+
PRIVATE include include/cpd/vendor)
56+
install(TARGETS Library-C++ DESTINATION lib EXPORT cpd-targets)
6157
install(DIRECTORY include/cpd DESTINATION include)
62-
install(TARGETS Library-C++
63-
DESTINATION lib
64-
EXPORT cpd-targets
65-
)
66-
67-
configure_file(Doxyfile.in ${PROJECT_BINARY_DIR}/Doxyfile)
68-
add_custom_target(docs
69-
COMMAND doxygen ${PROJECT_BINARY_DIR}/Doxyfile
70-
)
58+
install(EXPORT cpd-targets NAMESPACE Cpd:: DESTINATION lib/cmake/cpd)
7159

60+
# Optional targets
61+
option(WITH_TESTS "Build test suite" ON)
7262
if(WITH_TESTS)
7363
enable_testing()
74-
add_subdirectory(${GTEST_SOURCE_DIR})
75-
set_target_properties(gtest PROPERTIES MACOSX_RPATH ON)
76-
set_target_properties(gtest_main PROPERTIES MACOSX_RPATH ON)
64+
set(GOOGLETEST_DIR "${PROJECT_SOURCE_DIR}/vendor/googletest-release-1.8.0/googletest")
7765
add_subdirectory(test)
7866
endif()
7967

80-
include(CMakePackageConfigHelpers)
81-
configure_file(cmake/cpd-config.cmake
82-
${PROJECT_BINARY_DIR}/cpd-config.cmake
83-
@ONLY
84-
)
85-
write_basic_package_version_file(
86-
${PROJECT_BINARY_DIR}/cpd-config-version.cmake
87-
VERSION ${CPD_VERSION}
88-
COMPATIBILITY AnyNewerVersion
89-
)
90-
install(FILES
91-
${PROJECT_BINARY_DIR}/cpd-config.cmake
92-
${PROJECT_BINARY_DIR}/cpd-config-version.cmake
93-
DESTINATION lib/cmake/cpd
94-
)
95-
install(EXPORT cpd-targets
96-
DESTINATION lib/cmake/cpd
97-
NAMESPACE Cpd::
98-
)
68+
option(WITH_DOCS "Build documentation" OFF)
69+
if(WITH_DOCS)
70+
configure_file(Doxyfile.in "${PROJECT_BINARY_DIR}/Doxyfile")
71+
add_custom_target(docs COMMAND doxygen "${PROJECT_BINARY_DIR}/Doxyfile")
72+
endif()

Doxyfile.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ PROJECT_LOGO =
5858
# entered, it will be relative to the location where doxygen was started. If
5959
# left blank the current directory will be used.
6060

61-
OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/doc
61+
OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/docs
6262

6363
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
6464
# directories (in 2 levels) under the output directory of each output format and
@@ -125,7 +125,7 @@ ABBREVIATE_BRIEF =
125125
# description.
126126
# The default value is: NO.
127127

128-
ALWAYS_DETAILED_SEC = NO
128+
ALWAYS_DETAILED_SEC = YES
129129

130130
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
131131
# inherited members of a class in the documentation of that class as if those

README.md

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ While ICP minimizes point-to-point distances, CPD uses a [Gaussian Mixture Model
88
If you're thinking that this is very computationally intensive, you're right — both the CPD algorithm and the underlying error calculations take a lot of time, which is why we've created [fgt](https://github.com/gadomski/fgt) to speed up those Gauss transforms.
99
We hope this library provides a freer and more performant alternative to the original reference Matlab implementation.
1010

11-
This library supports three variants of CPD:
11+
This library supports two variants of CPD:
1212

1313
- **rigid**: Uses a rigid transformation (i.e. rotation and translation, with an optional scaling) to align the two datasets.
1414
- **nonrigid**: Uses a two-parameter non-rigid transformation function to align the two datasets.
15-
- **affine**: Uses an affine transformation (with an optional scaling) to align the two datasets.
1615

17-
Andriy's reference implementation comes with one other type of registration, **nonrigid_lowrank**, which is not implemented in the latest version of this library (yet) (see [History](#history) for information on how to find and use a previous version of this library that has **nonrigid_lowrank**).
16+
Andriy's reference implementation comes with two other type of registrations, **affine** and **nonrigid_lowrank**, which are not implemented in the latest version of this library (yet) (see [History](#history) for information on how to find and use a previous version of this library that has **nonrigid_lowrank** and **affine**).
1817

1918
This code lives [on Github](https://github.com/gadomski/cpd).
2019
It has some [Doxygen documentation](http://gadomski.github.io/cpd) and is tested [by Travis](https://travis-ci.org/gadomski/cpd) and [by AppVeyor](https:://ci.appveyor.com/project/gadomski/cpd/branch/master).
@@ -25,31 +24,42 @@ We also have a [gitter chatroom](https://gitter.im/gadomski/cpd).
2524

2625
## Usage
2726

28-
**cpd** has a simple functional interface, which accepts [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page) matrices and aligns them using some sensible default parameters:
27+
Basic, default usage can be accomplished via some namespace-level methods:
2928

3029
```cpp
3130
#include <cpd/rigid.hpp>
3231

33-
cpd::RigidResult align_with_rigid(const Eigen::MatrixXd& X, const Eigen::MatrixXd& Y) {
34-
return cpd::rigid(X, Y);
32+
int main(int argc, char** argv) {
33+
cpd::Matrix fixed = load_points_from_somewhere();
34+
cpd::Matrix moving = load_points_from_somewhere();
35+
cpd::Rigid::Result result = cpd::rigid(fixed, moving);
3536
}
3637
```
3738
38-
If you want more control over the parameters, you can use the class-based interface:
39+
More advanced configuration can be accomplished by using a `Runner`:
3940
4041
```cpp
4142
#include <cpd/rigid.hpp>
42-
43-
cpd::RigidResult align_with_rigid(const Eigen::MatrixXd& X, const Eigen::MatrixXd& Y) {
44-
cpd::Rigid rigid;
45-
rigid.allow_scaling(true).no_reflections(false);
46-
return rigid.compute(X, Y);
43+
#include <cpd/runner.hpp>
44+
45+
int main(int argc, char** argv) {
46+
cpd::Matrix fixed = load_points_from_somewhere();
47+
cpd::Matrix moving = load_points_from_somewhere();
48+
cpd::Runner<cpd::Rigid, cpd::FgtProbabilityComputer> runner;
49+
runner.correspondence(true).outliers(0.2);
50+
cpd::Rigid::Result result = runner.run(fixed, moving);
4751
}
4852
```
4953

54+
See the code and the [documentation](http://gadomski.github.io/cpd) to discover all possible options, transformation methods, and probability calculation methods.
55+
56+
## Examples
57+
58+
See `examples/` in this code repository for some basic usage examples, including examples of how to set up a downstream CMake project that depends on cpd.
59+
5060
## Installation
5161

52-
**cpd** depends on [fgt](https://github.com/gadomski/fgt) at runtime and [CMake](https://cmake.org/) and Eigen at build-time.
62+
**cpd** depends on [fgt](https://github.com/gadomski/fgt) at runtime and [CMake](https://cmake.org/) and [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page) at build-time.
5363

5464
### On OSX
5565

0 commit comments

Comments
 (0)