A lot of cleaning, begining of documentation, junctions

This commit is contained in:
Thomas FORGIONE 2015-02-28 16:24:54 +01:00
parent 368f0ebe7d
commit 80553b879a
74 changed files with 2868 additions and 1255 deletions

9
Code/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
CMakeCache.txt
CMakeFiles
Makefile
cmake_install.cmake
install_manifest.txt
bin/*
build/*
*.a

28
Code/CMakeLists.txt Normal file
View File

@ -0,0 +1,28 @@
cmake_minimum_required (VERSION 2.8)
project (Paella)
# Options de compilateur
list( APPEND CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS} -g -Wall")
# Mettre les binaires dans bin
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_MODULE_PATH "cmake/Modules" "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
# Chercher les headers dans le dossier include
include_directories(include)
# SFML
find_package(SFML REQUIRED system window graphics network audio)
# OpenCV
find_package(OpenCV REQUIRED)
# OpenGL
find_package(OpenGL REQUIRED)
# Project version
set(VERSION_MAJOR 1)
set(VERSION_MINOR 0)
set(VERSION_PATCH 0)
add_subdirectory(src)

View File

@ -0,0 +1,359 @@
# This script locates the SFML library
# ------------------------------------
#
# Usage
# -----
#
# When you try to locate the SFML libraries, you must specify which modules you want to use (system, window, graphics, network, audio, main).
# If none is given, the SFML_LIBRARIES variable will be empty and you'll end up linking to nothing.
# example:
# find_package(SFML COMPONENTS graphics window system) // find the graphics, window and system modules
#
# You can enforce a specific version, either MAJOR.MINOR or only MAJOR.
# If nothing is specified, the version won't be checked (i.e. any version will be accepted).
# example:
# find_package(SFML COMPONENTS ...) // no specific version required
# find_package(SFML 2 COMPONENTS ...) // any 2.x version
# find_package(SFML 2.4 COMPONENTS ...) // version 2.4 or greater
#
# By default, the dynamic libraries of SFML will be found. To find the static ones instead,
# you must set the SFML_STATIC_LIBRARIES variable to TRUE before calling find_package(SFML ...).
# Since you have to link yourself all the SFML dependencies when you link it statically, the following
# additional variables are defined: SFML_XXX_DEPENDENCIES and SFML_DEPENDENCIES (see their detailed
# description below).
# In case of static linking, the SFML_STATIC macro will also be defined by this script.
# example:
# set(SFML_STATIC_LIBRARIES TRUE)
# find_package(SFML 2 COMPONENTS network system)
#
# On Mac OS X if SFML_STATIC_LIBRARIES is not set to TRUE then by default CMake will search for frameworks unless
# CMAKE_FIND_FRAMEWORK is set to "NEVER" for example. Please refer to CMake documentation for more details.
# Moreover, keep in mind that SFML frameworks are only available as release libraries unlike dylibs which
# are available for both release and debug modes.
#
# If SFML is not installed in a standard path, you can use the SFML_ROOT CMake (or environment) variable
# to tell CMake where SFML is.
#
# Output
# ------
#
# This script defines the following variables:
# - For each specified module XXX (system, window, graphics, network, audio, main):
# - SFML_XXX_LIBRARY_DEBUG: the name of the debug library of the xxx module (set to SFML_XXX_LIBRARY_RELEASE is no debug version is found)
# - SFML_XXX_LIBRARY_RELEASE: the name of the release library of the xxx module (set to SFML_XXX_LIBRARY_DEBUG is no release version is found)
# - SFML_XXX_LIBRARY: the name of the library to link to for the xxx module (includes both debug and optimized names if necessary)
# - SFML_XXX_FOUND: true if either the debug or release library of the xxx module is found
# - SFML_XXX_DEPENDENCIES: the list of libraries the module depends on, in case of static linking
# - SFML_LIBRARIES: the list of all libraries corresponding to the required modules
# - SFML_FOUND: true if all the required modules are found
# - SFML_INCLUDE_DIR: the path where SFML headers are located (the directory containing the SFML/Config.hpp file)
# - SFML_DEPENDENCIES: the list of libraries SFML depends on, in case of static linking
#
# example:
# find_package(SFML 2 COMPONENTS system window graphics audio REQUIRED)
# include_directories(${SFML_INCLUDE_DIR})
# add_executable(myapp ...)
# target_link_libraries(myapp ${SFML_LIBRARIES})
# define the SFML_STATIC macro if static build was chosen
if(SFML_STATIC_LIBRARIES)
add_definitions(-DSFML_STATIC)
endif()
# define the list of search paths for headers and libraries
set(FIND_SFML_PATHS
${SFML_ROOT}
$ENV{SFML_ROOT}
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw
/opt/local
/opt/csw
/opt)
# find the SFML include directory
find_path(SFML_INCLUDE_DIR SFML/Config.hpp
PATH_SUFFIXES include
PATHS ${FIND_SFML_PATHS})
# check the version number
set(SFML_VERSION_OK TRUE)
if(SFML_FIND_VERSION AND SFML_INCLUDE_DIR)
# extract the major and minor version numbers from SFML/Config.hpp
# we have to handle framework a little bit differently:
if("${SFML_INCLUDE_DIR}" MATCHES "SFML.framework")
set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/Headers/Config.hpp")
else()
set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/SFML/Config.hpp")
endif()
FILE(READ "${SFML_CONFIG_HPP_INPUT}" SFML_CONFIG_HPP_CONTENTS)
STRING(REGEX MATCH ".*#define SFML_VERSION_MAJOR ([0-9]+).*#define SFML_VERSION_MINOR ([0-9]+).*#define SFML_VERSION_PATCH ([0-9]+).*" SFML_CONFIG_HPP_CONTENTS "${SFML_CONFIG_HPP_CONTENTS}")
STRING(REGEX REPLACE ".*#define SFML_VERSION_MAJOR ([0-9]+).*" "\\1" SFML_VERSION_MAJOR "${SFML_CONFIG_HPP_CONTENTS}")
STRING(REGEX REPLACE ".*#define SFML_VERSION_MINOR ([0-9]+).*" "\\1" SFML_VERSION_MINOR "${SFML_CONFIG_HPP_CONTENTS}")
STRING(REGEX REPLACE ".*#define SFML_VERSION_PATCH ([0-9]+).*" "\\1" SFML_VERSION_PATCH "${SFML_CONFIG_HPP_CONTENTS}")
math(EXPR SFML_REQUESTED_VERSION "${SFML_FIND_VERSION_MAJOR} * 10000 + ${SFML_FIND_VERSION_MINOR} * 100 + ${SFML_FIND_VERSION_PATCH}")
# if we could extract them, compare with the requested version number
if (SFML_VERSION_MAJOR)
# transform version numbers to an integer
math(EXPR SFML_VERSION "${SFML_VERSION_MAJOR} * 10000 + ${SFML_VERSION_MINOR} * 100 + ${SFML_VERSION_PATCH}")
# compare them
if(SFML_VERSION LESS SFML_REQUESTED_VERSION)
set(SFML_VERSION_OK FALSE)
endif()
else()
# SFML version is < 2.0
if (SFML_REQUESTED_VERSION GREATER 10900)
set(SFML_VERSION_OK FALSE)
set(SFML_VERSION_MAJOR 1)
set(SFML_VERSION_MINOR x)
set(SFML_VERSION_PATCH x)
endif()
endif()
endif()
# find the requested modules
set(SFML_FOUND TRUE) # will be set to false if one of the required modules is not found
foreach(FIND_SFML_COMPONENT ${SFML_FIND_COMPONENTS})
string(TOLOWER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_LOWER)
string(TOUPPER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_UPPER)
set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER})
# no suffix for sfml-main, it is always a static library
if(FIND_SFML_COMPONENT_LOWER STREQUAL "main")
# release library
find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE
NAMES ${FIND_SFML_COMPONENT_NAME}
PATH_SUFFIXES lib64 lib
PATHS ${FIND_SFML_PATHS})
# debug library
find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG
NAMES ${FIND_SFML_COMPONENT_NAME}-d
PATH_SUFFIXES lib64 lib
PATHS ${FIND_SFML_PATHS})
else()
# static release library
find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE
NAMES ${FIND_SFML_COMPONENT_NAME}-s
PATH_SUFFIXES lib64 lib
PATHS ${FIND_SFML_PATHS})
# static debug library
find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG
NAMES ${FIND_SFML_COMPONENT_NAME}-s-d
PATH_SUFFIXES lib64 lib
PATHS ${FIND_SFML_PATHS})
# dynamic release library
find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE
NAMES ${FIND_SFML_COMPONENT_NAME}
PATH_SUFFIXES lib64 lib
PATHS ${FIND_SFML_PATHS})
# dynamic debug library
find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG
NAMES ${FIND_SFML_COMPONENT_NAME}-d
PATH_SUFFIXES lib64 lib
PATHS ${FIND_SFML_PATHS})
# choose the entries that fit the requested link type
if(SFML_STATIC_LIBRARIES)
if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE)
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE})
endif()
if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG)
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG})
endif()
else()
if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE)
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE})
endif()
if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG)
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG})
endif()
endif()
endif()
if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG OR SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE)
# library found
set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND TRUE)
# if both are found, set SFML_XXX_LIBRARY to contain both
if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE)
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY debug ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}
optimized ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE})
endif()
# if only one debug/release variant is found, set the other to be equal to the found one
if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE)
# debug and not release
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG})
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG})
endif()
if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG)
# release and not debug
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE})
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE})
endif()
else()
# library not found
set(SFML_FOUND FALSE)
set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND FALSE)
set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY "")
set(FIND_SFML_MISSING "${FIND_SFML_MISSING} SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY")
endif()
# mark as advanced
MARK_AS_ADVANCED(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY
SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE
SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG
SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE
SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG
SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE
SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG)
# add to the global list of libraries
set(SFML_LIBRARIES ${SFML_LIBRARIES} "${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY}")
endforeach()
# in case of static linking, we must also define the list of all the dependencies of SFML libraries
if(SFML_STATIC_LIBRARIES)
# detect the OS
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(FIND_SFML_OS_WINDOWS 1)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(FIND_SFML_OS_LINUX 1)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(FIND_SFML_OS_FREEBSD 1)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(FIND_SFML_OS_MACOSX 1)
endif()
# start with an empty list
set(SFML_DEPENDENCIES)
set(FIND_SFML_DEPENDENCIES_NOTFOUND)
# macro that searches for a 3rd-party library
macro(find_sfml_dependency output friendlyname)
find_library(${output} NAMES ${ARGN} PATHS ${FIND_SFML_PATHS} PATH_SUFFIXES lib)
if(${${output}} STREQUAL "${output}-NOTFOUND")
unset(output)
set(FIND_SFML_DEPENDENCIES_NOTFOUND "${FIND_SFML_DEPENDENCIES_NOTFOUND} ${friendlyname}")
endif()
endmacro()
# sfml-system
list(FIND SFML_FIND_COMPONENTS "system" FIND_SFML_SYSTEM_COMPONENT)
if(NOT ${FIND_SFML_SYSTEM_COMPONENT} EQUAL -1)
# update the list -- these are only system libraries, no need to find them
if(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD OR FIND_SFML_OS_MACOSX)
set(SFML_SYSTEM_DEPENDENCIES "pthread")
endif()
if(FIND_SFML_OS_LINUX)
set(SFML_SYSTEM_DEPENDENCIES ${SFML_SYSTEM_DEPENDENCIES} "rt")
endif()
if(FIND_SFML_OS_WINDOWS)
set(SFML_SYSTEM_DEPENDENCIES "winmm")
endif()
set(SFML_DEPENDENCIES ${SFML_SYSTEM_DEPENDENCIES} ${SFML_DEPENDENCIES})
endif()
# sfml-network
list(FIND SFML_FIND_COMPONENTS "network" FIND_SFML_NETWORK_COMPONENT)
if(NOT ${FIND_SFML_NETWORK_COMPONENT} EQUAL -1)
# update the list -- these are only system libraries, no need to find them
if(FIND_SFML_OS_WINDOWS)
set(SFML_NETWORK_DEPENDENCIES "ws2_32")
endif()
set(SFML_DEPENDENCIES ${SFML_NETWORK_DEPENDENCIES} ${SFML_DEPENDENCIES})
endif()
# sfml-window
list(FIND SFML_FIND_COMPONENTS "window" FIND_SFML_WINDOW_COMPONENT)
if(NOT ${FIND_SFML_WINDOW_COMPONENT} EQUAL -1)
# find libraries
if(FIND_SFML_OS_LINUX)
find_sfml_dependency(X11_LIBRARY "X11" X11)
find_sfml_dependency(XRANDR_LIBRARY "Xrandr" Xrandr)
find_sfml_dependency(UDEV_LIBRARIES "UDev" udev)
endif()
# update the list
if(FIND_SFML_OS_WINDOWS)
set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "opengl32" "winmm" "gdi32")
elseif(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD)
set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "GL" ${X11_LIBRARY} ${XRANDR_LIBRARY})
if(FIND_SFML_OS_FREEBSD)
set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "usbhid")
else()
set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} ${UDEV_LIBRARIES})
endif()
elseif(FIND_SFML_OS_MACOSX)
set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "-framework OpenGL -framework Foundation -framework AppKit -framework IOKit -framework Carbon")
endif()
set(SFML_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} ${SFML_DEPENDENCIES})
endif()
# sfml-graphics
list(FIND SFML_FIND_COMPONENTS "graphics" FIND_SFML_GRAPHICS_COMPONENT)
if(NOT ${FIND_SFML_GRAPHICS_COMPONENT} EQUAL -1)
# find libraries
find_sfml_dependency(FREETYPE_LIBRARY "FreeType" freetype)
find_sfml_dependency(GLEW_LIBRARY "GLEW" glew GLEW glew32 glew32s glew64 glew64s)
find_sfml_dependency(JPEG_LIBRARY "libjpeg" jpeg)
# update the list
set(SFML_GRAPHICS_DEPENDENCIES ${FREETYPE_LIBRARY} ${GLEW_LIBRARY} ${JPEG_LIBRARY})
set(SFML_DEPENDENCIES ${SFML_GRAPHICS_DEPENDENCIES} ${SFML_DEPENDENCIES})
endif()
# sfml-audio
list(FIND SFML_FIND_COMPONENTS "audio" FIND_SFML_AUDIO_COMPONENT)
if(NOT ${FIND_SFML_AUDIO_COMPONENT} EQUAL -1)
# find libraries
find_sfml_dependency(OPENAL_LIBRARY "OpenAL" openal openal32)
find_sfml_dependency(SNDFILE_LIBRARY "libsndfile" sndfile)
# update the list
set(SFML_AUDIO_DEPENDENCIES ${OPENAL_LIBRARY} ${SNDFILE_LIBRARY})
set(SFML_DEPENDENCIES ${SFML_AUDIO_DEPENDENCIES} ${SFML_DEPENDENCIES})
endif()
endif()
# handle errors
if(NOT SFML_VERSION_OK)
# SFML version not ok
set(FIND_SFML_ERROR "SFML found but version too low (requested: ${SFML_FIND_VERSION}, found: ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR}.${SFML_VERSION_PATCH})")
set(SFML_FOUND FALSE)
elseif(SFML_STATIC_LIBRARIES AND FIND_SFML_DEPENDENCIES_NOTFOUND)
set(FIND_SFML_ERROR "SFML found but some of its dependencies are missing (${FIND_SFML_DEPENDENCIES_NOTFOUND})")
set(SFML_FOUND FALSE)
elseif(NOT SFML_FOUND)
# include directory or library not found
set(FIND_SFML_ERROR "Could NOT find SFML (missing: ${FIND_SFML_MISSING})")
endif()
if (NOT SFML_FOUND)
if(SFML_FIND_REQUIRED)
# fatal error
message(FATAL_ERROR ${FIND_SFML_ERROR})
elseif(NOT SFML_FIND_QUIETLY)
# error but continue
message("${FIND_SFML_ERROR}")
endif()
endif()
# handle success
if(SFML_FOUND AND NOT SFML_FIND_QUIETLY)
message(STATUS "Found SFML ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR}.${SFML_VERSION_PATCH} in ${SFML_INCLUDE_DIR}")
endif()

View File

@ -1,16 +0,0 @@
set INCLUDE=-IC:/opencv/build/include
set LIBS=-LC:/opencv/build/x86/vc10/lib -lopencv_calib3d2410 -lopencv_contrib2410 -lopencv_core2410 -lopencv_features2d2410 -lopencv_flann2410 -lopencv_gpu2410 -lopencv_highgui2410 -lopencv_imgproc2410 -lopencv_legacy2410 -lopencv_ml2410 -lopencv_nonfree2410 -lopencv_objdetect2410 -lopencv_ocl2410 -lopencv_photo2410 -lopencv_stitching2410 -lopencv_superres2410 -lopencv_ts2410 -lopencv_video2410 -lopencv_videostab2410
g++ -std=c++11 -c -o obj/HelloCV/HelloCV.o src/HelloCV/HelloCV.cpp %INCLUDE%
g++ -std=c++11 -o bin/HelloCV.exe obj/HelloCV/* %LIBS%
g++ -std=c++11 -c -o obj/Calibration/Calibration.o src/Calibration/Calibration.cpp %INCLUDE%
g++ -std=c++11 -o bin/Calibration.exe obj/Calibration/* %LIBS%
g++ -std=c++11 -c -o obj/DetectionAndMatching/DetectionAndMatching.o src/DetectionAndMatching/DetectionAndMatching.cpp %INCLUDE%
g++ -std=c++11 -o bin/DetectionAndMatching.exe obj/DetectionAndMatching/* %LIBS%
g++ -std=c++11 -c -o obj/DetectionAndMatchingSift/DetectionAndMatchingSift.o src/DetectionAndMatchingSift/DetectionAndMatchingSift.cpp %INCLUDE%
g++ -std=c++11 -o bin/DetectionAndMatchingSift.exe obj/DetectionAndMatchingSift/* %LIBS%
pause

View File

@ -1,7 +0,0 @@
#!/usr/bin/bash
g++ -std=c++11 -c -o obj/HelloCV/HelloCV.o src/HelloCV/HelloCV.cpp
g++ -std=c++11 -o bin/HelloCV obj/HelloCV/* `pkg-config --libs opencv`
g++ -std=c++11 -c -o obj/Calibration/Calibration.o src/Calibration/Calibration.cpp
g++ -std=c++11 -o bin/Calibration obj/Calibration/* `pkg-config --libs opencv`

View File

@ -4,7 +4,7 @@
#include <vector>
#include "Vector.hpp"
namespace pae
namespace geo
{
// Forward declaration of class Spline
@ -15,8 +15,9 @@ class Spline;
float base(int j, int n, float t, std::vector<float> const& nodes);
// Function to compute the length of a spline
float splineLenght(pae::Spline<pae::Vector3<float>, float> const& spline);
}
float splineLenght(Spline<Vector3<float>, float> const& spline);
} // end namespace geo
#include "Spline.hpp"

View File

@ -3,9 +3,9 @@
#include <vector>
#include <utility>
#include "Vector.hpp"
#include "Geometry/Vector.hpp"
namespace pae
namespace geo
{
template<typename T>
@ -13,8 +13,8 @@ class Circle
{
public:
Circle() : center{}, points{} {};
Vector3<T> center;
std::vector<std::pair<unsigned int, Vector3<T>>> points;
geo::Vector3<T> center;
std::vector<std::pair<unsigned int, geo::Vector3<T>>> points;
};
}

View File

@ -0,0 +1,25 @@
#ifndef MATHFUNCTIONS_HPP
#define MATHFUNCTIONS_HPP
#include <vector>
#include "Geometry/Vector.hpp"
namespace geo
{
template<typename InputIt, typename T, typename Distance>
InputIt project(T const& elementToProject, InputIt first, InputIt last, Distance const& distance);
template <typename T, std::size_t N>
using Segment = std::pair<Vector<T,N>, Vector<T,N>>;
template<typename T>
float distanceToSegment(geo::Vector<T,2> const& v, geo::Segment<T,2> const& s);
} // namespace geo
#include "Geometry/MathFunctions.inl"
#endif // MATHFUNCTIONS_HPP

View File

@ -0,0 +1,52 @@
#include <limits>
#include "Geometry/MathFunctions.hpp"
namespace geo
{
template<typename InputIt, typename T, typename Distance>
InputIt project(T const& elementToProject, InputIt first, InputIt last, Distance const& distance)
{
float best_dist = std::numeric_limits<float>::max();
auto best_element = first;
for (; first != last; first++)
{
float current_dist = distance(elementToProject, *first);
if (current_dist < best_dist)
{
best_dist = current_dist;
best_element = first;
}
}
return best_element;
}
template<typename T>
float distanceToSegment(geo::Vector<T,2> const& v, geo::Segment<T,2> const& s)
{
geo::Vector<float,2> u = s.first-s.second;
auto a = -u.y();
auto b = u.x();
auto xH = (b*b*v.x() - a*b*v.y() + a*a*s.first.x() + a*b*s.first.y())/(a*a+b*b);
auto yH = xH;
if (std::abs(b) < std::abs(a))
yH = (b*xH-b*v.x()+a*v.y())/a;
else
yH = (-a*xH+a*s.first.x()+b*s.first.y())/b;
geo::Vector<T,2> ptH = {xH,yH};
T dist;
if ((ptH-s.first)*(ptH-s.second) <= 0)
dist = (v-ptH).norm2();
else
dist = std::min((v-s.first).norm2(),(v-s.second).norm2());
return dist;
}
} // namespace geo

View File

@ -2,10 +2,10 @@
#define MESH_HPP
#include <vector>
#include "Spline.hpp"
#include "Vector.hpp"
#include "Geometry/Spline.hpp"
#include "Geometry/Vector.hpp"
namespace pae
namespace geo
{
class Mesh
{
@ -23,14 +23,16 @@ class Mesh
friend std::ostream& operator<<(std::ostream& out, Mesh const& mesh);
void draw() const;
void drawEdges() const;
void prepare(bool gouraudShading = true);
void prepareEdges();
std::vector<Vector3<float>> vertices;
std::vector<Vector3<unsigned int>> faces;
std::vector<Vector3<float>> normals;
std::vector<geo::Vector3<float>> vertices;
std::vector<geo::Vector3<unsigned int>> faces;
std::vector<geo::Vector3<float>> normals;
std::vector<Vector3<float>> glVertices;
std::vector<Vector3<float>> glNormals;
std::vector<geo::Vector3<float>> glVertices;
std::vector<geo::Vector3<float>> glNormals;
private:
void prepareGouraudShading();
@ -45,7 +47,7 @@ class Mesh
/// \param circles Vector containing the circles along the curve of the
/// spline
////////////////////////////////////////////////////////////////////////
Mesh splineMeshing(std::vector<Circle<float>> const& circles, unsigned int offset=0);
Mesh splineMeshing(std::vector<geo::Circle<float>> const& circles, unsigned int offset=0);
}
#endif // MESH_HPP

View File

@ -0,0 +1,14 @@
#ifndef POINT_HPP
#define POINT_HPP
#include <utility>
#include "Geometry/Vector.hpp"
namespace geo
{
template<typename T>
using Point = std::pair<unsigned int, Vector3<T>>;
}
#endif // POINT_HPP

View File

@ -0,0 +1,105 @@
#ifndef SPLINE_HPP
#define SPLINE_HPP
#include <vector>
#include <tuple>
#include <cmath>
#include "Geometry/Circle.hpp"
#include "Utility/TupleFunctions.hpp"
namespace geo
{
///////////////////////////////////////////////////////////////
/// \brief Utility template class for manipulating B-splines
//////////////////////////////////////////////////////////////
template<typename... Types>
class Spline
{
public:
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// Creates an empty spline (with no control points)
///////////////////////////////////////////////////////////
Spline();
///////////////////////////////////////////////////////////
/// \brief Evaluates the spline at a certain time
///
/// \param t Time at which you want to evaluate the spline. Must be between 0 and 1
///
/// \return Tuple that corresponds to the points of the spline at time t
///////////////////////////////////////////////////////////
std::tuple<Types...> operator()(float t) const;
///////////////////////////////////////////////////////////
/// \brief Evaluates the derivative of the spline at a certain time
///
/// \param t Time at which you want to evaluate the derivative of the
/// spline. Must be between 0 and 1
///
/// \return Tuple that corresponds to the derivative of each
/// coordinates of the spline at time t
///////////////////////////////////////////////////////////
std::tuple<Types...> prime(float t) const;
///////////////////////////////////////////////////////////
/// \brief Prints the spline to the stream
///
/// \param t Time at which you want to evaluate the derivative of the
/// spline. Must be between 0 and 1
///
/// \return Tuple that corresponds to the derivative of each
/// coordinates of the spline at time t
///
/// Prints first the degree of the spline, than the nodes and finally
/// the control points. For example
/// \code
/// d 3
///
/// n 0 0 0 0 0.333333 0.666667 1 1 1 1
///
/// p 0.60 0.43 0.51 0.142
/// p 0.60 0.89 0.36 0.135
/// p 0.72 1.28 0.24 0.129
/// p 0.96 1.72 0.14 0.125
/// p 1.27 2.10 0.06 0.122
/// p 1.69 2.29 0 0.12
/// \endcode
///////////////////////////////////////////////////////////
template<typename... T>
friend std::ostream& operator<<( std::ostream& out, Spline<T...> const& spline);
geo::Circle<float> computeCircle(float t, unsigned int const nbPoints, geo::Vector3<float>& v, unsigned int const offset = 0) const;
std::vector<geo::Circle<float>> computeCircles(unsigned int nbCircles, unsigned int const nbPoints, unsigned int const globalOffset = 0) const;
// private:
///////////////////////////////////////////////////////////
/// \brief Add a control point to the spline
///
/// \param node String representation of the node to be added
///////////////////////////////////////////////////////////
void addControlPoint(std::string const& node);
std::vector<std::tuple<Types...>> controlPoints; ///< Vector of the control points of the spline
std::vector<float> nodes; ///< Vector of nodes of the spline
int degree; ///< Degree of the spline
};
namespace detail
{
template<typename... Types>
std::tuple<Types...> evalSpline(std::vector<std::tuple<Types...>> const& controlPoints , std::vector<float> const& nodes, int degree, float f);
template<typename... Types>
std::tuple<Types...> evalDerivativeSpline(std::vector<std::tuple<Types...>> const& controlPoints , std::vector<float> const& nodes, int degree, float f);
} // namespace detail
} // namespace geo
#include "Spline.inl"
#endif // SPLINE_HPP

View File

@ -2,11 +2,11 @@
#include <fstream>
#include <sstream>
#include <cmath>
#include "Vector.hpp"
#include "Base.hpp"
#include "Spline.hpp"
#include "Geometry/Vector.hpp"
#include "Geometry/Base.hpp"
#include "Geometry/Spline.hpp"
namespace pae
namespace geo
{
template<typename... Types>
@ -21,7 +21,7 @@ std::vector<Circle<float>> Spline<Types...>::computeCircles(unsigned int nbCircl
std::vector<Circle<float>> circles;
unsigned int offset = 0;
pae::Vector3<float> v{0.0f,0.0f,1.0f};
Vector3<float> v{0.0f,0.0f,1.0f};
for (unsigned int i = 0; i < nbCircles; i++)
{
@ -46,8 +46,6 @@ Circle<float> Spline<Types...>::computeCircle(float t, unsigned int const nbPoin
auto r_t = std::get<1>(S_t);
auto r_prime_t = std::get<1>(S_prime_t);
C_prime_t /= C_prime_t.norm();
auto a = C_prime_t.x();
auto b = C_prime_t.y();
auto c = C_prime_t.z();
@ -56,6 +54,7 @@ Circle<float> Spline<Types...>::computeCircle(float t, unsigned int const nbPoin
auto dist = std::abs(a * C_t.x() + b * C_t.y() + c * C_t.z() + d)/std::sqrt(a*a+b*b+c*c);
// std::cout << "dist : " << dist << std::endl;
C_prime_t /= C_prime_t.norm();
auto C_P_t = C_t + dist * C_prime_t;
auto C_t_C_P_t = C_P_t - C_t;
@ -76,6 +75,14 @@ Circle<float> Spline<Types...>::computeCircle(float t, unsigned int const nbPoin
circlePoints.points.push_back(std::make_pair(i+offset,circlePoint));
}
constexpr auto baseVector1 = Vector3<float>{1.0f,0.0f,0.0f};
auto baseVector2 = crossProduct(C_prime_t,baseVector1);
baseVector2 /= baseVector2.norm();
auto proj = (v*baseVector1)*baseVector1 + (v*baseVector2)*baseVector2;
proj /= proj.norm();
v = proj;
return circlePoints;
}
@ -85,28 +92,12 @@ std::tuple<Types...> Spline<Types...>::operator()(float f) const
return detail::evalSpline(controlPoints, nodes, degree, f);
}
template<typename... Types>
template<std::size_t I>
constexpr typename std::tuple_element<I, std::tuple<Types...>>::type
Spline<Types...>::operator()(float f) const
{
return std::get<I>((*this)(f));
}
template<typename... Types>
std::tuple<Types...> Spline<Types...>::prime(float f) const
{
return detail::evalDerivativeSpline(controlPoints, nodes, degree, f);
}
template<typename... Types>
template<std::size_t I>
constexpr typename std::tuple_element<I, std::tuple<Types...>>::type
Spline<Types...>::prime(float f) const
{
return std::get<I>(prime(f));
}
template<typename... Types>
std::ostream& operator<<(std::ostream& out, Spline<Types...> const& spline)
{
@ -133,7 +124,7 @@ void Spline<Types...>::addControlPoint(std::string const& point)
{
std::tuple<Types...> tuple;
std::stringstream stream{point};
detail::loadFromStream(tuple, stream);
pae::detail::loadFromStream(tuple, stream);
controlPoints.push_back(tuple);
}
@ -154,7 +145,7 @@ struct evalSplineHelper
for (auto i = 0u; i < nodes.size() - degree - 1; i++)
{
std::get<J>(tuple) += pae::base(i, degree, f, nodes) * std::get<J>(controlPoints[i]);
std::get<J>(tuple) += base(i, degree, f, nodes) * std::get<J>(controlPoints[i]);
}
evalSplineHelper<I-1,J+1,Types...>{}(controlPoints, nodes, degree, f, tuple);
@ -239,4 +230,4 @@ std::tuple<Types...> evalDerivativeSpline(std::vector<std::tuple<Types...>> cons
} // namespace detail
} // namespace pae
} // namespace geo

View File

@ -0,0 +1,343 @@
#ifndef VECTOR_HPP
#define VECTOR_HPP
#include <cmath>
#include <array>
#include <istream>
namespace geo
{
///////////////////////////////////////////////////////////////
/// \brief Utility template class for manipulating geometrics vector
///////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
class Vector
{
public:
//////////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// Calls the default constructor on each coordinates of the vector
//////////////////////////////////////////////////////////////////
Vector();
//////////////////////////////////////////////////////////////////
/// \brief Construct vector from its coordinates
///
/// \param l coordinates of the vector to construct
//////////////////////////////////////////////////////////////////
template<typename... Types>
constexpr Vector(Types... l);
/////////////////////////////////////////////////////////////////
/// \brief Construct vector from another vector of the same size
///
/// \param v Vector to copy
/////////////////////////////////////////////////////////////////
template<typename U>
Vector(Vector<U,N> const& v);
/////////////////////////////////////////////////////////////////
/// \brief Compute the square of the norm of a vector
///
/// \see norm
///
/// Use this method when you need to compare vector sizes
/////////////////////////////////////////////////////////////////
T norm2() const;
/////////////////////////////////////////////////////////////////
/// \brief Compute the norm of a vector
/////////////////////////////////////////////////////////////////
T norm() const;
/////////////////////////////////////////////////////////////////
/// \brief Overload of the unary operator -
///
/// \return A new vector with opposite coordinates
/////////////////////////////////////////////////////////////////
Vector<T,N> operator-();
/////////////////////////////////////////////////////////////////
/// \brief Overload of the operator +=
///
/// \param v Vector by which *this is increased
///
/// \return A reference to *this
///
/// This operator sums both vectors, and assigns the result to *this
/////////////////////////////////////////////////////////////////
Vector<T,N>& operator+=(Vector<T,N> const& v);
/////////////////////////////////////////////////////////////////
/// \brief Overload of the operator -=
///
/// \param v Vector by which *this is decreased
///
/// \return A reference to *this
///
/// This operator computes difference between the vectors, and assigns
/// the result to *this
/////////////////////////////////////////////////////////////////
Vector<T,N>& operator-=(Vector<T,N> const& v);
/////////////////////////////////////////////////////////////////
/// \brief Overload of the operator *=
///
/// \param f Coefficient by which the vector is multiplied
///
/// \return A reference to *this
///
/// This operator multiplies each coordinate of *this by f, and returns
/// a reference to *this
/////////////////////////////////////////////////////////////////
Vector<T,N>& operator*=(float f);
/////////////////////////////////////////////////////////////////
/// \brief Overload of the operator *=
///
/// \param f Coefficient by which the vector is divided
///
/// \return A reference to *this
///
/// This operator divides each coordinate of *this by f, and returns
/// a reference to *this
/////////////////////////////////////////////////////////////////
Vector<T,N>& operator/=(float f);
/////////////////////////////////////////////////////////////////
/// \brief Get x coordinate from the vector
///
/// \return A reference to the first coordinate of the vector
///
/// This method is available only if the number of coodinates is higher
/// than 0
/////////////////////////////////////////////////////////////////
T& x() {static_assert(N > 0, "x() doesn't exist on Vector<T,0>"); return data[0]; };
/////////////////////////////////////////////////////////////////
/// \brief Get y coordinate from the vector
///
/// \return A reference to the second coordinate of the vector
///
/// This method is available only if the number of coodinates is higher
/// than 1
/////////////////////////////////////////////////////////////////
T& y() {static_assert(N > 1, "y() doesn't exist on Vector<T,1>"); return data[1]; };
/////////////////////////////////////////////////////////////////
/// \brief Get z coordinate from the vector
///
/// \return A reference to the third coordinate of the vector
///
/// This method is available only if the number of coodinates is higher
/// than 2
/////////////////////////////////////////////////////////////////
T& z() {static_assert(N > 2, "z() doesn't exist on Vector<T,2>"); return data[2]; };
/////////////////////////////////////////////////////////////////
/// \brief Get t coordinate from the vector
///
/// \return A reference to the third coordinate of the vector
///
/// This method is available only if the number of coodinates is higher
/// than 3
/////////////////////////////////////////////////////////////////
T& t() {static_assert(N > 2, "t() doesn't exist on Vector<T,3>"); return data[3]; };
/////////////////////////////////////////////////////////////////
/// \brief Get x coordinate from the vector
///
/// \return A const reference to the first coordinate of the vector
///
/// This method is available only if the number of coodinates is higher
/// than 0
/////////////////////////////////////////////////////////////////
T const& x() const {static_assert(N > 0, "x() doesn't exist on Vector<T,0>"); return data[0]; };
/////////////////////////////////////////////////////////////////
/// \brief Get y coordinate from the vector
///
/// \return A const reference to the second coordinate of the vector
///
/// This method is available only if the number of coodinates is higher
/// than 1
/////////////////////////////////////////////////////////////////
T const& y() const {static_assert(N > 1, "y() doesn't exist on Vector<T,1>"); return data[1]; };
/////////////////////////////////////////////////////////////////
/// \brief Get z coordinate from the vector
///
/// \return A const reference to the third coordinate of the vector
///
/// This method is available only if the number of coodinates is higher
/// than 2
/////////////////////////////////////////////////////////////////
T const& z() const {static_assert(N > 2, "z() doesn't exist on Vector<T,2>"); return data[2]; };
/////////////////////////////////////////////////////////////////
/// \brief Get t coordinate from the vector
///
/// \return A const reference to the third coordinate of the vector
///
/// This method is available only if the number of coodinates is higher
/// than 3
/////////////////////////////////////////////////////////////////
T const& t() const {static_assert(N > 2, "t() doesn't exist on Vector<T,3>"); return data[3]; };
std::array<T,N> data; ///< Array where the coordinates of the vector are stored
};
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Compares two vectors
///
/// \return True if each coordinate is the same in l and r
/////////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
bool operator==(Vector<T,N> const& l, Vector<T,N> const& r);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Compares two vectors
///
/// \return True if at least one coordinate is not the same in l and r
/////////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
bool operator!=(Vector<T,N> const& l, Vector<T,N> const& r);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Overload of the operator +
///
/// \return The sum of l and r
///
/// This operator sums both vectors, and returns the new vector
/////////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
Vector<T,N> operator+(Vector<T,N> l, Vector<T,N> const& r);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Overload of the operator -
///
/// \return The difference between l and r
///
/// This operator computes the difference between the two vectors, and returns
/// the new vector
/////////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
Vector<T,N> operator-(Vector<T,N> l, Vector<T,N> const& r);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Overload of the operator * between two vectors
///
/// \param l first Vector
//
/// \param r second vector
///
/// \return The dot product l and r
///
/// This operator computes the sum of the product of the coordinates of the vectors
/////////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
T operator*(Vector<T,N> const& l, Vector<T,N> const& r);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Compute the crossProduct between two vectors
///
/// \param l first Vector
//
/// \param r second vector
///
/// \return The cross product l and r
///
/// This function computes the cross product between the two vectors
/// This function is only available on vector of size 3
/////////////////////////////////////////////////////////////////
template <typename T>
Vector<T,3> crossProduct(Vector<T,3> const& v1, Vector<T,3> const& v2);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Overload of the operator *
///
/// \param l Vector to muliply
//
/// \param f float by which the Vector is multiplied
///
/// \return The product between l and f
///
/// This operator computes the product between the vector and the float, and
/////////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
Vector<T,N> operator*(Vector<T,N> l, float f);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Overload of the operator /
///
/// \param l Vector to divide
//
/// \param f float by which the Vector is divided
///
/// \return The result of the division of l by f
///
/// This operator computes the division between the vector and the float, and
/// returns the new vector
/////////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
Vector<T,N> operator/(Vector<T,N> l, float f);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Overload of the operator>>
///
/// \param stream Stream from which the vector is loaded
//
/// \param v Vector that will be loaded from the streeam
///
/// \return A reference to the stream
///
/// Each coordinate will be loaded from the stream in the increasing order
/////////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
std::istream& operator>>(std::istream& stream, Vector<T,N>& v);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Overload of the operator<<
///
/// \param stream Stream where the Vector will be printed
//
/// \param v Vector that will be printed
///
/// \return A reference to the stream
///
/// Each coordinate will be printed, separeted by commas and surrounded by brackets
///
/// \code
/// geo::Vector<int,3> v{1,2,3};
/// std::cout << v << std::endl;
/// \endcode
///
/// will print [1, 2, 3]
/////////////////////////////////////////////////////////////////
template<typename T, std::size_t N>
std::ostream& operator<<(std::ostream& stream, Vector<T,N> const& v);
/////////////////////////////////////////////////////////////////
/// \relates Vector
/// \brief Smaller name for Vector of 3 coordinates
/////////////////////////////////////////////////////////////////
template<typename T>
using Vector3 = Vector<T,3>;
} // namespace geo
#include "Vector.inl"
#endif // VECTOR_HPP

View File

@ -1,8 +1,8 @@
#include <iostream>
#include <cmath>
#include "Vector.hpp"
#include "Geometry/Vector.hpp"
namespace pae
namespace geo
{
template<typename T, std::size_t N>
@ -13,12 +13,13 @@ Vector<T,N>::Vector() : data{}
template<typename T, std::size_t N>
template<typename...Types>
Vector<T,N>::Vector(Types... l) : data{{l...}}
constexpr Vector<T,N>::Vector(Types... l) : data{{static_cast<T>(l)...}}
{
}
template<typename T, std::size_t N>
Vector<T,N>::Vector(Vector<T,N> const& v) : data(v.data)
template<typename U>
Vector<T,N>::Vector(Vector<U,N> const& v) : data(v.data)
{
}
@ -35,22 +36,6 @@ T Vector<T,N>::norm() const
return std::sqrt(norm2());
}
template<typename T, std::size_t N>
Vector<T,N>& Vector<T,N>::operator=(T t)
{
for (auto& d : data)
d = t;
return *this;
}
template<typename T, std::size_t N>
Vector<T,N>& Vector<T,N>::operator=(Vector<T,N> t)
{
this->data = std::move(t.data);
return *this;
}
template<typename T, std::size_t N>
std::istream& operator>>(std::istream& stream, Vector<T,N>& v)
{
@ -170,6 +155,6 @@ Vector<T,3> crossProduct(Vector<T,3> const& v1, Vector<T,3> const& v2)
};
}
} // namespace pae
} // namespace geo

View File

@ -6,7 +6,7 @@
constexpr auto PI_2_MINUS_EPSILON = M_PI_2 - 0.1;
namespace pae
namespace sft
{
class FreeFlyCamera
@ -33,6 +33,6 @@ class FreeFlyCamera
};
}
} // namespace sft
#endif // FREE_FLY_CAMERA_HPP

View File

@ -4,45 +4,48 @@
#include <cmath>
#include <SFML/System/Vector3.hpp>
using sf::Vector3;
namespace sft
{
template <class T>
Vector3<T> makeVector(Vector3<T> const& from, Vector3<T> const& to)
sf::Vector3<T> makeVector(sf::Vector3<T> const& from, sf::Vector3<T> const& to)
{
return to - from;
}
template <class T>
double dotProduct(Vector3<T> const& v1, Vector3<T> const& v2)
double dotProduct(sf::Vector3<T> const& v1, sf::Vector3<T> const& v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
template <class T>
double norm2(Vector3<T> const& vecteur)
double norm2(sf::Vector3<T> const& vecteur)
{
return dotProduct(vecteur, vecteur);
}
template <class T>
double norm(Vector3<T> const& vecteur)
double norm(sf::Vector3<T> const& vecteur)
{
return sqrt(norm2(vecteur));
}
template <class T>
void normalize(Vector3<T>& vecteur)
void normalize(sf::Vector3<T>& vecteur)
{
vecteur /= norm(vecteur);
}
template <class T>
Vector3<T> crossProduct(Vector3<T> const& v1, Vector3<T> const& v2)
sf::Vector3<T> crossProduct(sf::Vector3<T> const& v1, sf::Vector3<T> const& v2)
{
return Vector3<T>{v1.y * v2.z - v1.z * v2.y,
return sf::Vector3<T>{v1.y * v2.z - v1.z * v2.y,
v1.z * v2.x - v1.x * v2.z,
v1.x * v2.y - v1.y * v2.x
};
}
} // namespace sft
#endif // VECTOR_FUNCTIONS_HPP

View File

@ -5,22 +5,8 @@
#include <vector>
#include <sstream>
#include "opencv2/features2d/features2d.hpp"
#include "Box.hpp"
class Vertex
{
public:
float x;
float y;
float z;
};
class Edge
{
public:
unsigned int v1;
unsigned int v2;
};
#include "Geometry/Vector.hpp"
class Skeleton
{
@ -50,7 +36,7 @@ class Skeleton
/// \param vertices Vector of vertices
/// \param path Vector of vertices index
////////////////////////////////////////////////////////////////////////
void loadFromVectors(std::vector<Vertex> const& vertices,
void loadFromVectors(std::vector<geo::Vector3<float>> const& vertices,
std::vector<unsigned int> const& path
);
@ -154,8 +140,8 @@ class Skeleton
friend unsigned int searchNearestBrancheIndex(cv::KeyPoint const& keypoint,
std::vector<Skeleton> branches
);
std::vector<Vertex> m_vertices;
std::vector<Edge> m_edges;
std::vector<geo::Vector3<float>> m_vertices;
std::vector<geo::Vector<unsigned int,2>> m_edges;
static std::stringstream stream;
};

View File

@ -0,0 +1,87 @@
#ifndef SKELETON3D_HPP
#define SKELETON3D_HPP
#include <vector>
#include <list>
#include "Geometry/Mesh.hpp"
#include "Geometry/Spline.hpp"
#include "Geometry/Point.hpp"
namespace pae
{
/////////////////////////////////////////////////////////
// Junction : a junction in the skeleton defined by a vector of pairs containing:
// - spline's index
// - t parameter where the junction
// is located on the spline
//
// Example : <<ind1,t1>, <ind2,t2>, <ind3,t3>>
//This junction is between 3 splines designated by their indexes.
////////////////////////////////////////////////////////
using Junction = std::vector<std::pair<unsigned int,float>>;
namespace detail
{
template<typename T>
bool whichSide(geo::Vector<T,4> const& plane, geo::Vector3<T> const& point);
template<typename T>
geo::Vector<float,4> closestPlane(std::vector<geo::Vector3<T>> const& points);
template<typename T>
std::pair<std::vector<std::list<geo::Point<T>>>, std::vector<std::list<geo::Point<T>>>> sortedPoints(geo::Vector<T,4> const& plane, std::vector<geo::Circle<T>> const& junction_circles);
}
template<typename T>
geo::Vector<T,4> meshJunction(geo::Mesh& mesh, geo::Vector3<T> const& junction_point, float junction_radius, std::vector<geo::Circle<T>> const& junction_circles);
template<typename T>
std::pair<geo::Point<float>,geo::Point<float>> closestPointsCircles(geo::Circle<float> const& circle1, geo::Circle<float> const& circle2);
template<typename... Types>
class Skeleton3D
{
public:
Skeleton3D();
bool loadFromFile(std::string const& path);
void meshJunctions(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles);
/////////////////////////////////////////////////////////////
/// \brief findExtremities : get the extremities of the skeleton
///
/// \param none
/// \output a vector of pair which contain the index of the spline
/// and the t where is the extremity
/////////////////////////////////////////////////////////////
std::vector<std::pair<unsigned int, float>> findExtremities();
////////////////////////////////////////////////////////////
/// \brief meshExtremities : compute the extremities as a mesh
///
/// \param the mesh and the circles associated to the splines
///
void meshExtremities(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles, unsigned int profondeur);
void meshExtremity(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles, unsigned int profondeur, std::pair<unsigned int,float> extremity);
void subdivision(geo::Mesh& mesh, unsigned int profondeur, geo::Circle<float> extremCircle, unsigned int intersectionIndex, geo::Vector3<float> intersection, geo::Vector3<float> center, float radius, float t);
void arcSubdivise(geo::Vector3<float> pt1, geo::Vector3<float> pt2, unsigned int profondeur, std::vector<geo::Vector3<float>>& arc, geo::Vector3<float> center, float radius);
std::pair<geo::Point<float>,geo::Point<float>> closestPointsCircles(geo::Circle<float> const& circle1, geo::Circle<float> const& circle2);
template<typename... T>
friend std::ostream& operator<<(std::ostream& out, Skeleton3D<T...> const& s);
// private:
std::vector<geo::Spline<Types...>> splines;
std::vector<Junction> junctions;
};
} // namespace pae
#include "Skeleton3D.inl"
#endif // SKELETON3D_HPP

View File

@ -0,0 +1,921 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <cmath>
#include <list>
#include <eigen3/Eigen/Dense>
#include <algorithm>
#include "Skeleton3D.hpp"
#include "Geometry/Point.hpp"
namespace pae
{
namespace detail
{
std::ostream& operator<<(std::ostream& out, std::pair<std::vector<std::list<geo::Point<float>>>, std::vector<std::list<geo::Point<float>>>> const& pair)
{
unsigned int i = 0;
out << "up_points_vector_list" << std::endl;
for (auto const& l : pair.first)
{
out << "circle_" << i << std::endl;
for (auto const& p : l)
{
out << p.first << " ";
}
out << std::endl;
i++;
}
out << std::endl << "Second list" << std::endl;
i = 0;
for (auto const& l : pair.second)
{
out << "circle_" << i << std::endl;
for (auto const& p : l)
{
out << p.first << " ";
}
out << std::endl;
i++;
}
return out;
}
} // namespace detail
template<typename... Types>
Skeleton3D<Types...>::Skeleton3D() : splines{}
{
}
template<typename... Types>
bool Skeleton3D<Types...>::loadFromFile(std::string const& path)
{
std::fstream file{path};
if (!file)
{
std::cerr << "Warning : couldn't load Skeleton from file " << path << std::endl;
return false;
}
std::stringstream stream;
std::string line;
bool alreadyFoundL = false;
geo::Spline<Types...> currentSpline;
while (std::getline(file, line))
{
if (line.size() == 0)
continue;
char first;
stream.clear();
stream.str(line);
stream >> first;
switch (first)
{
case 'd':
{
// Add the current spline
splines.push_back(currentSpline);
// Prepare the new one
currentSpline = geo::Spline<Types...>{};
// Set the degree of the spline
int i;
stream >> i;
currentSpline.degree = i;
break;
}
case 'n':
{
float x;
while (stream >> x)
{
currentSpline.nodes.push_back(x);
}
break;
}
case 'p':
{
// Add control point to the spline
// std::cout << "p->" << line << std::endl;
currentSpline.addControlPoint(line.substr(1));
break;
}
case 'l':
{
if (!alreadyFoundL)
{
splines.push_back(currentSpline);
alreadyFoundL = true;
}
float size_junction;
stream >> size_junction;
unsigned int x;
junctions.push_back(Junction{});
Junction& j = junctions[junctions.size()-1];
for (unsigned int i = 0; i<size_junction; i++)
{
stream >> x;
j.push_back(std::make_pair(x-1,0.0f));
}
float y;
for (unsigned int i = 0; i<size_junction; i++)
{
stream >> y;
j[i].second = y;
}
break;
}
}
}
if (!alreadyFoundL)
{
splines.push_back(currentSpline);
}
// Remove the first spline that is empty
splines.erase(splines.begin());
return true;
}
template<typename... T>
void Skeleton3D<T...>::meshJunctions(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles)
{
for(unsigned int i = 0; i < junctions.size(); i++)
{
geo::Vector3<float> junction_point; // sphere's center of the junction point
float junction_radius; // sphere's radius
// Get the junction elements
auto spline = splines[junctions[i][0].first];
auto tuple = spline(junctions[i][0].second);
junction_point = std::get<0>(tuple);
junction_radius = std::get<1>(tuple);
std::vector<geo::Circle<float>> junction_circles; // characteristic circles from the splines of the junction
for(unsigned int j = 0; j<junctions[i].size(); j++)
{
unsigned int indSpline = junctions[i][j].first;
float t = junctions[i][j].second;
auto spline_circles = splines_circles[indSpline];
if (t==0.0f)
{
junction_circles.push_back(spline_circles[0]);
}
else
{
junction_circles.push_back(spline_circles[spline_circles.size()-1]);
}
}
meshJunction<float>(mesh,junction_point,junction_radius, junction_circles);
}
}
template<typename T>
geo::Vector<T,4> meshJunction(geo::Mesh& mesh, geo::Vector3<T> const& junction_point, float junction_radius, std::vector<geo::Circle<T>> const& junction_circles)
{
// Compute the closest points between two consecutives circles
std::vector<geo::Vector3<float>> centerPoints;
// for (unsigned int i = 0; i<junction_circles.size(); i++)
// {
// Circle<float> const& circle1 = junction_circles[i];
// Circle<float> const& circle2 = junction_circles[(i+1)%junction_circles.size()];
// closestPoints.push_back(closestPointsCircles<T>(circle1,circle2));
// }
for (auto const& circle : junction_circles)
{
centerPoints.push_back(circle.center);
}
// Find the medium plane that cut the circles in two
geo::Vector<float,4> plane = detail::closestPlane<float>(centerPoints);
// Compute list of points upside the plane and downside
auto sorted_points = detail::sortedPoints<float>(plane, junction_circles);
using detail::operator<<;
geo::Vector3<float> direction{plane.x(),plane.y(),plane.z()};
direction /= direction.norm();
geo::Vector3<float> up_point_proj = junction_point - direction*junction_radius;
geo::Vector3<float>down_point_proj = junction_point + direction*junction_radius;
// direction = (down_medium_point - junction_point);
// direction /= direction.norm();
// direction *= junction_radius;
// Vector3<float> down_point_proj = junction_point + direction;
mesh.vertices.push_back(up_point_proj);
mesh.vertices.push_back(down_point_proj);
// choose the indice of the two new points
unsigned int ind_up = mesh.vertices.size()-2;
unsigned int ind_down = mesh.vertices.size()-1;
// std::cout << "ind_up = " << ind_up << std::endl;
// std::cout << "ind_down = " << ind_down << std::endl;
// mesh the up part of the sphere
for (auto const& up_points : sorted_points.first)
{
auto last = std::end(up_points);
last--;
for(auto it = std::begin(up_points), end = std::end(up_points); it != end; ++it)
{
if (it != last)
{
auto cp = it;
cp ++;
mesh.faces.push_back(geo::Vector3<unsigned int>{it->first,cp->first,ind_up});
}
}
}
// mesh the down part of the sphere
for (auto const& down_points : sorted_points.second)
{
auto last = std::end(down_points);
last--;
for(auto it = std::begin(down_points), end = std::end(down_points); it != end; ++it)
{
if (it != last)
{
auto cp = it;
cp ++;
mesh.faces.push_back(geo::Vector3<unsigned int>{it->first,cp->first,ind_down});
}
}
}
// // connect the four points around the plane
auto points_c1_up = sorted_points.first.at(0);
auto points_c2_up = sorted_points.first.at(1);
auto points_c1_down = sorted_points.second.at(0);
auto points_c2_down = sorted_points.second.at(1);
std::cout << " sorted_points = " << sorted_points << std::endl;
std::cout << "--------------------------------------------------------------------------" << std::endl;
for (auto const& p : points_c1_down)
{
std::cout << p.first << " ";
}
std::cout << std::endl;
auto p_c1_up = points_c1_up.front();
auto p_c1_up1 = points_c1_up.back();
auto p_c2_up = points_c2_up.front();
auto p_c2_up1 = points_c2_up.back();
std::cout << p_c1_up.first << " " << p_c1_up1.first << " " << p_c2_up.first << " " << p_c2_up1.first << std::endl;
std::vector<std::pair<geo::Point<float>, geo::Point<float>>> pairs{
{p_c1_up,p_c2_up},
{p_c1_up,p_c2_up1},
{p_c1_up1,p_c2_up},
{p_c1_up1,p_c2_up1}
};
auto min_pair = std::min_element(std::begin(pairs), std::end(pairs),
[] (std::pair<geo::Point<T>, geo::Point<T>> const& points,
std::pair<geo::Point<T>, geo::Point<T>> const& points2) {
return (points.first.second-points.second.second).norm2() <
(points2.first.second-points2.second.second).norm2();
});
unsigned int ind_i = std::distance(std::begin(pairs), min_pair);
std::pair<geo::Point<float>, geo::Point<float>> next_points;
unsigned int ind_p_c1_up = 0, ind_p_c2_up = 0, ind_p_c2_up1 = 0, ind_p_c1_up1 = 0, ind_p_c1_down = 0, ind_p_c1_down1 = 0, ind_p_c2_down = 0, ind_p_c2_down1 = 0;
std::cout << "ind_i = " << ind_i << std::endl;
switch(ind_i)
{
case 0 :
{
ind_p_c1_up = p_c1_up.first;
ind_p_c2_up = p_c2_up.first;
ind_p_c1_down = points_c1_down.back().first;
ind_p_c2_down = points_c2_down.back().first;
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_up, ind_p_c2_up, ind_p_c1_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_down, ind_p_c2_up, ind_p_c2_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_up, ind_p_c2_up, ind_up});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_down, ind_p_c2_down, ind_down});
geo::Point<float> p_c2_down = points_c2_down.front();
next_points = std::make_pair(p_c2_up1, p_c2_down);
break;
}
case 1 :
{
ind_p_c1_up = p_c1_up.first;
ind_p_c1_down1 = points_c1_down.back().first;
ind_p_c2_up1 = p_c2_up1.first;
ind_p_c2_down = points_c2_down.front().first;
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_up, ind_p_c2_up1, ind_p_c1_down1});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_down1, ind_p_c2_up1, ind_p_c2_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_up, ind_p_c2_up1, ind_up});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_down, ind_p_c1_down1, ind_down});
geo::Point<float> p_c2_down1 = points_c2_down.back();
next_points = std::make_pair(p_c2_up,p_c2_down1);
break;
}
case 2 :
{
ind_p_c1_up1 = p_c1_up1.first;
ind_p_c1_down = points_c1_down.front().first;
ind_p_c2_up = p_c2_up.first;
ind_p_c2_down1 = points_c2_down.back().first;
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_up1, ind_p_c2_up, ind_p_c1_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_up1, ind_p_c1_down, ind_p_c2_down1});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_up1, ind_p_c2_up, ind_up});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_down, ind_p_c2_down1, ind_down});
geo::Point<float> p_c2_down = points_c2_down.front();
next_points = std::make_pair(p_c2_up1, p_c2_down);
break;
}
case 3 :
{
ind_p_c2_up = p_c2_up1.first;
ind_p_c1_up = p_c1_up1.first;
ind_p_c1_down = points_c1_down.front().first;
ind_p_c2_down = points_c2_down.front().first;
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_up, ind_p_c2_up, ind_p_c1_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_down, ind_p_c2_up, ind_p_c2_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_up, ind_p_c2_up, ind_up});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c1_down, ind_p_c2_down, ind_down});
geo::Point<float> p_c2_up = points_c2_up.front();
auto p_c2_down1 = points_c2_down.back();
next_points = std::make_pair(p_c2_up,p_c2_down1);
break;
}
}
for (unsigned int i = 1; i < sorted_points.first.size(); i++)
{
auto points_c3_up = sorted_points.first[(i+1)%sorted_points.first.size()];
auto points_c3_down = sorted_points.second[(i+1)%sorted_points.first.size()];
auto p_c3_up = points_c3_up.front();
auto p_c3_up1 = points_c3_up.back();
auto p_c3_down = points_c3_down.front();
auto p_c3_down1 = points_c3_down.back(); ind_p_c1_up1 = p_c1_up1.first;
ind_p_c1_down = points_c1_down.back().first;
auto p_c2_up = next_points.first;
auto p_c2_down = next_points.second;
float dist_1 = (p_c2_up.second - p_c3_up.second).norm2();
float dist_2 = (p_c2_up.second - p_c3_up1.second).norm2();
if (dist_1<dist_2)
{
unsigned int ind_p_c2_up = p_c2_up.first;
unsigned int ind_p_c2_down = p_c2_down.first;
unsigned int ind_p_c3_up = p_c3_up.first;
unsigned int ind_p_c3_down = p_c3_down1.first;
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c2_up, ind_p_c3_up, ind_p_c2_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c2_down, ind_p_c3_up, ind_p_c3_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c2_up, ind_p_c3_up, ind_up});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c2_down, ind_p_c3_down, ind_down});
next_points.first = p_c3_up1;
next_points.second = p_c3_down;
}
else
{
unsigned int ind_p_c2_up = p_c2_up.first;
unsigned int ind_p_c2_down = p_c2_down.first;
unsigned int ind_p_c3_up = p_c3_up1.first;
unsigned int ind_p_c3_down = p_c3_down.first;
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c2_up, ind_p_c3_up, ind_p_c2_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c2_down, ind_p_c3_up, ind_p_c3_down});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c2_up, ind_p_c3_up, ind_up});
mesh.faces.push_back(geo::Vector3<unsigned int>{ind_p_c2_down, ind_p_c3_down, ind_down});
next_points.first = p_c3_up;
next_points.second = p_c3_down1;
}
}
return plane;
}
template<typename... T>
std::pair<geo::Point<float>,geo::Point<float>> Skeleton3D<T...>::closestPointsCircles(geo::Circle<float> const& circle1, geo::Circle<float> const& circle2)
{
float bestDistance = (circle1.points[0].second - circle2.points[0].second).norm2();
geo::Point<float> const* bestPoint1 = nullptr;
geo::Point<float> const* bestPoint2 = nullptr;
for(auto const& point1:circle1.points)
{
for(auto const& point2:circle2.points)
{
float twoDistance = (point1.second - point2.second).norm2();
if( twoDistance < bestDistance)
{
bestDistance = twoDistance;
bestPoint1 = &point1;
bestPoint2 = &point2;
}
}
}
return std::make_pair(*bestPoint1,*bestPoint2);
}
template<typename... T>
std::vector<std::pair<unsigned int, float>> Skeleton3D<T...>::findExtremities()
{
std::vector<std::pair<unsigned int, float>> extremities;
std::vector<unsigned int> indexJunctions;
//construction of a vector containing indexes of a spline *2 + t
if (junctions.empty())
{
for (unsigned int i=0;i<splines.size();i++)
{
extremities.push_back(std::make_pair(i,0));
extremities.push_back(std::make_pair(i,1));
}
return extremities;
}
for (unsigned int i=0;i<junctions.size();i++)
{
for (unsigned int j=0;j<junctions[i].size();j++)
{
std::pair<unsigned int, float> extremSpline = junctions[i][j];
indexJunctions.push_back(extremSpline.first*2 + extremSpline.second);
}
}
std::sort(indexJunctions.begin(),indexJunctions.end());
unsigned int index=0;
for (unsigned int i=0;i<splines.size();i++)
{
if (i*2==indexJunctions[index])
{
index++;
}
else
{
extremities.push_back(std::make_pair(i,0));
}
if (((i*2)+1)==indexJunctions[index])
{
index++;
}
else
{
extremities.push_back(std::make_pair(i,1));
}
}
return extremities;
}
template<typename... T>
void Skeleton3D<T...>::meshExtremities(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles, unsigned int profondeur)
{
std::vector<std::pair<unsigned int, float>> extremities = findExtremities();
for (unsigned int i=0;i<extremities.size();i++)
{
meshExtremity(mesh, splines_circles, profondeur, extremities[i]);
}
}
template<typename... T>
void Skeleton3D<T...>::meshExtremity(geo::Mesh& mesh, std::vector<std::vector<geo::Circle<float>>> const& splines_circles, unsigned int profondeur, std::pair<unsigned int,float> extremity)
{
// Get the junction elements
auto tuple = splines[extremity.first](extremity.second);
auto C_t = std::get<0>(tuple);
auto r_t = std::get<1>(tuple);
auto S_prime_t = splines[extremity.first].prime(extremity.second);
auto C_prime_t = std::get<0>(S_prime_t);
C_prime_t /= C_prime_t.norm();
auto intersection = C_t;
if (extremity.second == 0)
{
intersection -= r_t * C_prime_t;
}
else
{
intersection += r_t * C_prime_t;
}
geo::Circle<float> extremCircle;
if (extremity.second == 0)
{
extremCircle = splines_circles[extremity.first][0];
}
else
{
extremCircle = splines_circles[extremity.first][splines_circles[extremity.first].size()-1];
}
unsigned int intersectionIndex = mesh.vertices.size();
if (profondeur==0)
{
mesh.vertices.push_back(intersection);
for (unsigned int i=0;i<extremCircle.points.size();i++)
{
auto ip1 = extremCircle.points[i].first;
if (i==extremCircle.points.size()-1)
{
auto ip2 = extremCircle.points[0].first;
if (extremity.second==1)
{
mesh.faces.push_back(geo::Vector3<unsigned int> {ip1,ip2,intersectionIndex});
} else {
mesh.faces.push_back(geo::Vector3<unsigned int> {ip1,intersectionIndex,ip2});
}
}
else
{
auto ip2 = extremCircle.points[i+1].first;
if (extremity.second==1)
{
mesh.faces.push_back(geo::Vector3<unsigned int> {ip1,ip2,intersectionIndex});
} else {
mesh.faces.push_back(geo::Vector3<unsigned int> {ip1,intersectionIndex,ip2});
}
}
}
}
else
{
subdivision(mesh, profondeur, extremCircle, intersectionIndex, intersection, C_t, r_t, extremity.second);
}
}
template<typename... T>
void Skeleton3D<T...>::subdivision(geo::Mesh& mesh, unsigned int profondeur, geo::Circle<float> extremCircle, unsigned int intersectionIndex, geo::Vector3<float> intersection, geo::Vector3<float> center, float radius, float t)
{
std::vector<std::vector<geo::Vector3<float>>> arcs;
for (unsigned int i=0;i<extremCircle.points.size();i++)
{
// compute the points build by subdivision on one arc (between a point on the extrem
// circle and the extremity)
std::vector<geo::Vector3<float>> arc;
arc.push_back(intersection);
arcSubdivise(intersection, extremCircle.points[i].second, profondeur, arc, center, radius);
arc.push_back(extremCircle.points[i].second);
arcs.push_back(arc);
}
// Compute the mesh
//push the new vertices
unsigned int indexVertices = mesh.vertices.size();
unsigned int indexVerticesInit = indexVertices;
unsigned int nbPoints = arcs[0].size()-2;
//push the intersection
mesh.vertices.push_back(arcs[0][0]);
// push all the new vertices
for (unsigned int i=0;i<arcs.size();i++)
{
for (unsigned int j=1;j<arcs[i].size()-1;j++)
{
mesh.vertices.push_back(arcs[i][j]);
}
}
//push the faces
for (unsigned int i=0;i<arcs.size()-1;i++)
{
auto courant = arcs[i];
for (unsigned int j=0;j<courant.size()-2;j++)
{
if (j==0)
{
if (t==0)
{
mesh.faces.push_back({intersectionIndex, indexVertices + 1 + nbPoints, indexVertices + 1});
} else {
mesh.faces.push_back({intersectionIndex, indexVertices + 1, indexVertices + 1 + nbPoints});
}
}
else
{
if (t==0)
{
mesh.faces.push_back({indexVertices + j, indexVertices + j + 1 + nbPoints, indexVertices + j + 1});
mesh.faces.push_back({indexVertices + j, indexVertices + j + nbPoints, indexVertices + j + 1 + nbPoints});
} else {
mesh.faces.push_back({indexVertices + j, indexVertices + j + 1, indexVertices + j + 1 + nbPoints});
mesh.faces.push_back({indexVertices + j, indexVertices + j + 1 + nbPoints, indexVertices + j + nbPoints});
}
}
}
// before last point
unsigned int i1 = extremCircle.points[i].first;
unsigned int i2 = extremCircle.points[i+1].first;
if (t==0)
{
mesh.faces.push_back({indexVertices + nbPoints, i2, i1});
mesh.faces.push_back({indexVertices + nbPoints , indexVertices + 2*nbPoints , i2});
}
else {
mesh.faces.push_back({indexVertices + nbPoints, i1, i2});
mesh.faces.push_back({indexVertices + nbPoints , i2, indexVertices + 2*nbPoints});
}
// increment the indexVertices
indexVertices += nbPoints;
}
// the last mesh (last arc)
auto courant = arcs[arcs.size()-1];
for (unsigned int j=0;j<courant.size()-2;j++)
{
if (j==0)
{
if (t==0)
{
mesh.faces.push_back({intersectionIndex, indexVerticesInit + 1, indexVertices + 1});
} else {
mesh.faces.push_back({intersectionIndex, indexVertices + 1, indexVerticesInit + 1});
}
}
else
{
if (t==0)
{
mesh.faces.push_back({indexVertices + j, indexVerticesInit + j + 1, indexVertices + j + 1});
mesh.faces.push_back({indexVertices + j, indexVerticesInit + j, indexVerticesInit + j + 1});
} else {
mesh.faces.push_back({indexVertices + j, indexVertices + j + 1, indexVerticesInit + j + 1});
mesh.faces.push_back({indexVertices + j, indexVerticesInit + j + 1, indexVerticesInit + j});
}
}
}
// before last point
unsigned int i1 = extremCircle.points[arcs.size()-1].first;
unsigned int i2 = extremCircle.points[0].first;
if (t==0)
{
mesh.faces.push_back({indexVertices + nbPoints, i2, i1});
mesh.faces.push_back({indexVertices + nbPoints, indexVerticesInit + nbPoints, i2});
}
else
{
mesh.faces.push_back({indexVertices + nbPoints, i1, i2});
mesh.faces.push_back({indexVertices + nbPoints, i2, indexVerticesInit + nbPoints});
}
}
//pt1 the extremity
template<typename... T>
void Skeleton3D<T...>::arcSubdivise(geo::Vector3<float> pt1, geo::Vector3<float> pt2, unsigned int profondeur, std::vector<geo::Vector3<float>>& arc, geo::Vector3<float> center, float radius)
{
if (profondeur!=0)
{
// compute middle of arc
geo::Vector3<float> middleSegment;
middleSegment = (pt1+pt2)/2;
// projection on the sphere
geo::Vector3<float> direction = (middleSegment - center);
direction /= direction.norm();
direction *= radius;
geo::Vector3<float> middle = center + direction;
arcSubdivise(pt1, middle, profondeur-1, arc, center, radius);
arc.push_back(middle);
arcSubdivise(middle, pt2, profondeur-1, arc, center, radius);
}
}
template<typename... T>
std::ostream& operator<<(std::ostream& out, Skeleton3D<T...> const& s)
{
for (auto const& spline:s.splines)
{
out << spline << std::endl;
}
for (auto const& junction:s.junctions)
{
out << "l " << junction.size() << " ";
for (auto const& pair:junction)
{
out << pair.first << " ";
}
for (auto const& pair:junction)
{
out << pair.second << " ";
}
out << std::endl;
}
return out;
}
namespace detail
{
template<typename T>
bool whichSide(geo::Vector<float,4> const& plane, geo::Vector3<float> const& point)
{
return plane.x()*point.x() + plane.y()*point.y() + plane.z()*point.z() < - plane.t();
}
template<typename T>
geo::Vector<float,4> closestPlane(std::vector<geo::Vector3<T>> const& points)
{
if (points.size() == 3)
{
auto vec = crossProduct(points[1] - points[0], points[2] - points[0]);
vec /= vec.norm();
float t = - (points[0].x()*vec.x() + points[0].y()*vec.y() + points[0].z()*vec.z());
return geo::Vector<float,4>{vec.x(), vec.y(), vec.z(), t};
}
else
{
Eigen::MatrixXf m{points.size()*2,3};
for ( unsigned int i = 0; i < points.size(); i++)
{
m(i,0) = points[i].x();
m(i,1) = points[i].y();
m(i,2) = points[i].z();
}
Eigen::MatrixXf centered = m.rowwise() - m.colwise().mean();
Eigen::MatrixXf cov = centered.adjoint() * centered;
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eig{cov};
Eigen::Vector3f v1 = eig.eigenvectors().col(1);
Eigen::Vector3f v2 = eig.eigenvectors().col(2);
Eigen::Vector3f n = v1.cross(v2);
return( geo::Vector<float,4>{n(0),n(1),n(2), n.dot(m.colwise().mean())} );
}
}
template<typename T>
std::pair<std::vector<std::list<geo::Point<T>>>, std::vector<std::list<geo::Point<T>>>> sortedPoints(geo::Vector<T,4> const& plane, std::vector<geo::Circle<T>> const& junction_circles)
{
std::vector<std::list<geo::Point<float>>> up_points;
std::vector<std::list<geo::Point<float>>> down_points;
for (unsigned int i = 0; i < junction_circles.size(); i++)
{
std::list<geo::Point<float>> first_points; // points located on one side of the circle, the first side reached.The two sides are separated by the median plane computed earlier.
std::list<geo::Point<float>> second_points; // points located on the other side of the circle
const bool up_side = whichSide<double>(plane, junction_circles[i].points[0].second); // constant boolean initialized at the beginning to know with which side we begin the way on the circle.
bool side_current_points = up_side; // boolean to know on which side we must had the points.
for (unsigned int j = 0; j < junction_circles[i].points.size(); j++)
{
if (up_side == side_current_points)
{
if (whichSide<double>(plane, junction_circles[i].points[j].second) == up_side)
{
first_points.push_back(junction_circles[i].points[j]);
}
else
{
side_current_points = whichSide<double>(plane, junction_circles[i].points[j].second);
second_points.push_back(junction_circles[i].points[j]);
}
}
else
{
if (whichSide<double>(plane, junction_circles[i].points[j].second) == side_current_points)
{
second_points.push_back(junction_circles[i].points[j]);
}
else
{
break;
}
}
}
for (int j = static_cast<int>(junction_circles[i].points.size()-1); j >= 0; j--)
{
if (whichSide<double>(plane, junction_circles[i].points[j].second) == up_side)
{
first_points.push_front(junction_circles[i].points[j]);
}
else
{
break;
}
}
if (up_side)
{
up_points.push_back(first_points);
down_points.push_back(second_points);
}
else
{
up_points.push_back(second_points);
down_points.push_back(first_points);
}
}
return std::make_pair(up_points, down_points);
}
} // namespace detail
} // namespace pae

9
Code/src/CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
add_subdirectory(Calibration)
add_subdirectory(DetectionAndMatching)
add_subdirectory(Extern)
add_subdirectory(HelloCV)
add_subdirectory(Segmentation)
add_subdirectory(Skeleton)
add_subdirectory(Spline)
add_subdirectory(Geometry)
add_subdirectory(SFMLTools)

View File

@ -0,0 +1,2 @@
add_executable(Calibration Calibration.cpp)
target_link_libraries(Calibration ${OpenCV_LIBS})

View File

@ -1,21 +0,0 @@
SOURCES = Calibration.cpp
OBJECTS = $(SOURCES:.cpp=.o)
TARGET = main
LIBS = $(shell pkg-config opencv --libs)
CXX = g++
%.o: %.cpp
$(CXX) -std=c++14 -o $@ -c $< -Wall `pkg-config opencv --cflags`
all: $(OBJECTS)
$(CXX) -std=c++14 -o $(TARGET) $(OBJECTS) $(LIBS) -Wall
x: all
./$(TARGET)
clean:
rm -rf $(OBJECTS)
superclean: clean
rm -rf $(TARGET)

View File

@ -0,0 +1,2 @@
add_executable(DetectionAndMatching DetectionAndMatching.cpp)
target_link_libraries(DetectionAndMatching ${OpenCV_LIBS})

View File

@ -11,7 +11,7 @@
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include "DetectionAndMatching.hpp"
#include "DetectionAndMatching/DetectionAndMatching.hpp"
/*headers*/

View File

@ -1,21 +0,0 @@
SOURCES = DetectionAndMatching.cpp
OBJECTS = $(SOURCES:.cpp=.o)
TARGET = main
LIBS = $(shell pkg-config opencv --libs)
CXX = g++
%.o: %.cpp
$(CXX) -std=c++14 -o $@ -c $< -Wall `pkg-config opencv --cflags`
all: $(OBJECTS)
$(CXX) -std=c++14 -o $(TARGET) $(OBJECTS) $(LIBS) -Wall
x: all
./$(TARGET)
clean:
rm -rf $(OBJECTS)
superclean: clean
rm -rf $(TARGET)

6
Code/src/Extern/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,6 @@
file(GLOB EXTERN_SRC
"*.cpp"
)
add_executable(ExternalCalibration ${EXTERN_SRC})
target_link_libraries(ExternalCalibration ${OpenCV_LIBS})

View File

@ -1,4 +1,4 @@
#include "Camera.hpp"
#include "Extern/Camera.hpp"
#include <iostream>

View File

@ -1,5 +1,5 @@
#include "ChessboardCameraTracker.hpp"
#include "utility.hpp"
#include "Extern/ChessboardCameraTracker.hpp"
#include "Extern/utility.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>

View File

@ -1,21 +0,0 @@
SOURCES = utility.cpp Camera.cpp main.cpp ChessboardCameraTracker.cpp
OBJECTS = $(SOURCES:.cpp=.o)
TARGET = main
LIBS = $(shell pkg-config opencv --libs)
CXX = g++
%.o: %.cpp
$(CXX) -std=c++14 -o $@ -c $< -Wall `pkg-config opencv --cflags`
all: $(OBJECTS)
$(CXX) -std=c++14 -o $(TARGET) $(OBJECTS) $(LIBS) -Wall
x: all
./$(TARGET)
clean:
rm -rf $(OBJECTS)
superclean: clean
rm -rf $(TARGET)

View File

@ -1,5 +1,5 @@
#include "ChessboardCameraTracker.hpp"
#include "utility.hpp"
#include "Extern/ChessboardCameraTracker.hpp"
#include "Extern/utility.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

View File

@ -1,4 +1,4 @@
#include "utility.hpp"
#include "Extern/utility.hpp"
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>

View File

@ -1,9 +1,9 @@
#include <cmath>
#include <iostream>
#include "Base.hpp"
#include "Geometry/Base.hpp"
namespace pae
namespace geo
{
float base(int j, int n, float t, std::vector<float> const& nodes)
@ -29,7 +29,7 @@ float base(int j, int n, float t, std::vector<float> const& nodes)
}
}
float splineLenght(pae::Spline<pae::Vector3<float>, float> const& spline)
float splineLenght(Spline<Vector3<float>, float> const& spline)
{
float len = 0;
for (unsigned int i = 0; i < spline.controlPoints.size()-1; i++)
@ -41,4 +41,4 @@ float splineLenght(pae::Spline<pae::Vector3<float>, float> const& spline)
return len;
}
}
} // end namespace geo

View File

@ -0,0 +1,4 @@
add_library(Geometry Base.cpp Mesh.cpp)
add_executable(ProjectionTest ProjectionTest.cpp)
target_link_libraries(ProjectionTest Geometry)

View File

@ -3,9 +3,9 @@
#include <sstream>
#include <GL/gl.h>
#include "Mesh.hpp"
#include "Geometry/Mesh.hpp"
namespace pae
namespace geo
{
Mesh& Mesh::operator+=(Mesh const& m)
@ -58,6 +58,16 @@ void Mesh::draw() const
glDisable(GL_LIGHTING);
}
void Mesh::drawEdges() const
{
glColor3f(1,1,1);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vector3<float>), &(glVertices.at(0).x()));
glDrawArrays(GL_LINES, 0, glVertices.size());
glDisableClientState(GL_VERTEX_ARRAY);
}
void Mesh::prepare(bool gouraudShading)
{
glVertices.clear();
@ -87,6 +97,21 @@ void Mesh::prepare(bool gouraudShading)
}
void Mesh::prepareEdges()
{
glVertices.clear();
for (auto const& f : faces)
{
glVertices.push_back(Vector3<float>{vertices.at(f.x()).x(), vertices.at(f.x()).y(), vertices.at(f.x()).z()});
glVertices.push_back(Vector3<float>{vertices.at(f.y()).x(), vertices.at(f.y()).y(), vertices.at(f.y()).z()});
glVertices.push_back(Vector3<float>{vertices.at(f.x()).x(), vertices.at(f.x()).y(), vertices.at(f.x()).z()});
glVertices.push_back(Vector3<float>{vertices.at(f.z()).x(), vertices.at(f.z()).y(), vertices.at(f.z()).z()});
glVertices.push_back(Vector3<float>{vertices.at(f.y()).x(), vertices.at(f.y()).y(), vertices.at(f.y()).z()});
glVertices.push_back(Vector3<float>{vertices.at(f.z()).x(), vertices.at(f.z()).y(), vertices.at(f.z()).z()});
}
}
void Mesh::prepareGouraudShading()
{
// This vector registers the normal on each vertex
@ -165,4 +190,4 @@ Mesh splineMeshing(std::vector<Circle<float>> const& circles, unsigned int offse
return m;
}
} // namespace pae
} // namespace geo

View File

@ -0,0 +1,101 @@
#include <iostream>
#include <vector>
#include "Geometry/Vector.hpp"
#include "Geometry/MathFunctions.hpp"
std::size_t total = 0, failed = 0;
template<typename T>
std::ostream& operator<<(std::ostream& out, std::vector<T> const& vector)
{
for (auto const& v : vector)
{
out << v << std::endl;
}
return out;
}
void test(bool b)
{
if (b)
{
std::cout << "\033[32mTest succeded !\033[0m" << std::endl;
}
else
{
std::cout << "\033[31mTest failed !\033[0m" << std::endl;
failed++;
}
total++;
}
void printResult()
{
if (failed == 0)
{
std::cout << "\033[32mAll tests worked correctly !\033[0m" << std::endl;
}
else
{
std::cout << "\033[31m" << failed << " test"
<< (failed > 1 ? "s" : "")
<< " didn't work...\033[0m" << std::endl;
}
}
int main()
{
geo::Vector3<float> element1{0.0f,0.0f,0.0f};
std::vector<geo::Vector3<float>> space1 = {
{1.0f, 0.0f, 0.0f},
{0.0f, 2.0f, 0.0f},
{0.0f, 0.0f, 3.0f},
{-0.5f, 0.2f, 0.8f},
{0.6f, -0.8f, 0.0f}
};
auto const it1 = geo::project(element1, std::begin(space1), std::end(space1),
[] (geo::Vector3<float> const& v1, geo::Vector3<float> const& v2)
{
return (v1-v2).norm2();
}
);
test(std::distance(std::begin(space1), it1) == 3);
geo::Vector<float,2> element2{0.0f,0.0f};
std::vector<geo::Vector3<float>> space2 = {
{1.0f, 2.0f, 3.0f},
{1.0f, 0.0f, -2.0f},
{0.0f, 1.0f, -1.0f},
{1.0f, 1.0f, 2.5f}
};
auto const it2 = geo::project(element2, std::begin(space2), std::end(space2),
[] (geo::Vector<float, 2> const& v, geo::Vector3<float> const& d)
{
return std::abs(d.x()*v.x()+d.y()*v.y()+d.z())/d.norm();
}
);
test(std::distance(std::begin(space2), it2) == 2);
geo::Vector<float,2> element3{2.0f,2.0f};
std::vector<geo::Segment<float,2>> space3 = {
{geo::Vector<float,2>{0.0f,0.0f},geo::Vector<float,2>{1.0f,0.0f}},
{geo::Vector<float,2>{0.0f,1.0f},geo::Vector<float,2>{0.0f,3.0f}},
{geo::Vector<float,2>{3.0f,0.0f},geo::Vector<float,2>{4.0f,1.0f}},
{geo::Vector<float,2>{3.0f,3.0f},geo::Vector<float,2>{4.0f,3.0f}}
};
auto const it3 = geo::project(element3, std::begin(space3), std::end(space3), geo::distanceToSegment<float>);
test(std::distance(std::begin(space3), it3) == 3);
printResult();
return 0;
}

View File

@ -0,0 +1,2 @@
add_executable(HelloCV HelloCV.cpp)
target_link_libraries(HelloCV ${OpenCV_LIBS})

View File

@ -1,21 +0,0 @@
SOURCES = HelloCV.cpp
OBJECTS = $(SOURCES:.cpp=.o)
TARGET = main
LIBS = $(shell pkg-config opencv --libs)
CXX = g++
%.o: %.cpp
$(CXX) -std=c++14 -o $@ -c $< -Wall `pkg-config opencv --cflags`
all: $(OBJECTS)
$(CXX) -std=c++14 -o $(TARGET) $(OBJECTS) $(LIBS) -Wall
x: all
./$(TARGET)
clean:
rm -rf $(OBJECTS)
superclean: clean
rm -rf $(TARGET)

View File

@ -0,0 +1 @@
add_library(SFMLTools FreeFlyCamera.cpp)

View File

@ -2,10 +2,11 @@
#include <cmath>
#include <GL/glu.h>
#include <boost/algorithm/clamp.hpp>
#include "VectorFunctions.hpp"
#include "FreeFlyCamera.hpp"
namespace pae
#include "SFMLTools/VectorFunctions.hpp"
#include "SFMLTools/FreeFlyCamera.hpp"
namespace sft
{
FreeFlyCamera::FreeFlyCamera() : speed(0.1), sensitivity(0.001), theta(0), phi(0)
@ -69,4 +70,4 @@ void FreeFlyCamera::look() const
0,0,1);
}
}
} // namespace sft

View File

@ -0,0 +1,3 @@
add_executable(Segmentation grabcut.cpp)
target_link_libraries(Segmentation ${OpenCV_LIBS})

View File

@ -1,21 +0,0 @@
SOURCES = grabcut.cpp
OBJECTS = $(SOURCES:.cpp=.o)
TARGET = main
LIBS = $(shell pkg-config opencv --libs)
CXX = g++
%.o: %.cpp
$(CXX) -std=c++0x -o $@ -c $< -Wall `pkg-config opencv --cflags`
all: $(OBJECTS)
$(CXX) -std=c++0x -o $(TARGET) $(OBJECTS) $(LIBS) -Wall
x: all
./$(TARGET)
clean:
rm -rf $(OBJECTS)
superclean: clean
rm -rf $(TARGET)

View File

@ -1,6 +1,6 @@
#include <iostream>
#include <fstream>
#include "Box.hpp"
#include "Skeleton/Box.hpp"
Box::Box() : m_x_min{}, m_x_max{}, m_y_min{}, m_y_max{}
{

View File

@ -0,0 +1,6 @@
file(GLOB SKELETON_SRC
"*.cpp"
)
add_executable(Skeleton ${SKELETON_SRC})
target_link_libraries(Skeleton ${SFML_LIBRARIES} ${OPENGL_LIBRARIES})

View File

@ -2,8 +2,8 @@
#include <cmath>
#include <GL/glu.h>
#include <boost/algorithm/clamp.hpp>
#include "VectorFunctions.hpp"
#include "FreeFlyCamera.hpp"
#include "Skeleton/VectorFunctions.hpp"
#include "Skeleton/FreeFlyCamera.hpp"
FreeFlyCamera::FreeFlyCamera() : speed(10), sensitivity(0.001), theta(0), phi(0)
{

View File

@ -1,21 +0,0 @@
SOURCES = Box.cpp Skeleton.cpp FreeFlyCamera.cpp main.cpp
OBJECTS = $(SOURCES:.cpp=.o)
TARGET = main
LIBS = -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio -lGL -lGLU
CXX = g++
%.o: %.cpp
$(CXX) -std=c++14 -o $@ -c $< -Wall
all: $(OBJECTS)
$(CXX) -std=c++14 -o $(TARGET) $(OBJECTS) $(LIBS) -Wall
x: all
./$(TARGET)
clean:
rm -rf $(OBJECTS)
superclean: clean
rm -rf $(TARGET)

View File

@ -5,8 +5,8 @@
#include <GL/gl.h>
#include <boost/numeric/ublas/matrix.hpp>
#include "opencv2/features2d/features2d.hpp"
#include "Skeleton.hpp"
#include "Box.hpp"
#include "Skeleton/Skeleton.hpp"
#include "Skeleton/Box.hpp"
std::stringstream Skeleton::stream{};
@ -40,14 +40,14 @@ void Skeleton::loadFromFile(std::string const& path)
float y;
float z;
stream >> x >> y >> z;
m_vertices.push_back(Vertex{x,y,z});
m_vertices.push_back(geo::Vector3<float>{x,y,z});
break;
case 'e':
unsigned int v1;
unsigned int v2;
stream >> v1 >> v2;
m_edges.push_back(Edge{v1-1,v2-1});
m_edges.push_back(geo::Vector<unsigned int, 2>{v1-1,v2-1});
break;
default:
@ -57,14 +57,14 @@ void Skeleton::loadFromFile(std::string const& path)
}
void Skeleton::loadFromVectors(std::vector<Vertex> const& vertices,
void Skeleton::loadFromVectors(std::vector<geo::Vector3<float>> const& vertices,
std::vector<unsigned int> const& path
)
{
m_vertices = vertices;
for (unsigned int i = 0; i < path.size() - 1; i++)
{
m_edges.push_back(Edge{path[i], path[i+1]});
m_edges.push_back(geo::Vector<unsigned int,2>{path[i], path[i+1]});
}
}
@ -80,8 +80,8 @@ std::vector<unsigned int> Skeleton::countNeighbors()
for (auto const& edge : m_edges)
{
neighbors_counters[edge.v1]++;
neighbors_counters[edge.v2]++;
neighbors_counters[edge.x()]++;
neighbors_counters[edge.y()]++;
}
return neighbors_counters;
}
@ -90,7 +90,7 @@ std::vector<unsigned int> Skeleton::countNeighbors()
void Skeleton::draw() const
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2,GL_FLOAT,sizeof(Vertex),&m_vertices[0]);
glVertexPointer(2,GL_FLOAT,sizeof(geo::Vector3<float>),&m_vertices[0]);
glDrawElements(GL_LINES,m_edges.size()*2,GL_UNSIGNED_INT,&m_edges[0]);
glDisableClientState(GL_VERTEX_ARRAY);
}
@ -116,8 +116,8 @@ std::vector<Skeleton> Skeleton::split()
for(auto const& edge : m_edges)
{
auto v1 = edge.v1;
auto v2 = edge.v2;
auto v1 = edge.x();
auto v2 = edge.y();
connections[std::max(v1,v2)][std::min(v1,v2)]= true;
}
@ -226,8 +226,8 @@ std::vector<std::pair<unsigned int,unsigned int>> branchesMatching(std::vector<s
{
for (unsigned int j = 0; j < branches1[i].m_vertices.size(); j++)
{
branches1[i].m_vertices[j].x /= branches1[i].m_vertices[j].z;
branches1[i].m_vertices[j].y /= branches1[i].m_vertices[j].z;
branches1[i].m_vertices[j].x() /= branches1[i].m_vertices[j].z();
branches1[i].m_vertices[j].y() /= branches1[i].m_vertices[j].z();
}
}
@ -235,8 +235,8 @@ std::vector<std::pair<unsigned int,unsigned int>> branchesMatching(std::vector<s
{
for (unsigned int j = 0; j < branches2[i].m_vertices.size(); j++)
{
branches2[i].m_vertices[j].x /= branches2[i].m_vertices[j].z;
branches2[i].m_vertices[j].y /= branches2[i].m_vertices[j].z;
branches2[i].m_vertices[j].x() /= branches2[i].m_vertices[j].z();
branches2[i].m_vertices[j].y() /= branches2[i].m_vertices[j].z();
}
}
@ -323,10 +323,10 @@ unsigned int searchNearestBrancheIndex(cv::KeyPoint const& keypoint, std::vector
float xK = keypoint.pt.x;
float yK = keypoint.pt.y;
float xv1 = branche.m_vertices[edge.v1].x;
float yv1 = branche.m_vertices[edge.v1].y;
float xv2 = branche.m_vertices[edge.v2].x;
float yv2 = branche.m_vertices[edge.v2].y;
float xv1 = branche.m_vertices[edge.x()].x();
float yv1 = branche.m_vertices[edge.x()].y();
float xv2 = branche.m_vertices[edge.y()].x();
float yv2 = branche.m_vertices[edge.y()].y();
float xv1v2 = xv2 - xv1;
float yv1v2 = yv2 - yv1;
@ -382,14 +382,14 @@ std::ostream& operator<<(std::ostream& out, Skeleton const& s)
{
for (auto const& vertex : s.m_vertices)
{
out << "v " << vertex.x << " " << vertex.y << " " << vertex.z << "\n";
out << "v " << vertex.x() << " " << vertex.y() << " " << vertex.z() << "\n";
}
out << "\n";
for (auto const& edge : s.m_edges)
{
out << "e " << edge.v1 << " " << edge.v2 << "\n";
out << "e " << edge.x() << " " << edge.y() << "\n";
}
return out;

View File

@ -8,8 +8,8 @@
#include <GL/gl.h>
#include <GL/glu.h>
#include "FreeFlyCamera.hpp"
#include "Skeleton.hpp"
#include "Skeleton/FreeFlyCamera.hpp"
#include "Skeleton/Skeleton.hpp"
// Full hd : 1920x1080
constexpr auto WIDTH = 1920;

View File

@ -0,0 +1,4 @@
add_executable(TestJunction TestJunction.cpp)
target_link_libraries(TestJunction ${OPENGL_LIBRARIES} ${SFML_LIBRARIES} SFMLTools Geometry)
add_executable(MainDisplay MainDisplay.cpp)
target_link_libraries(MainDisplay ${OPENGL_LIBRARIES} ${SFML_LIBRARIES} SFMLTools Geometry)

View File

@ -0,0 +1,41 @@
auto c1 = geo::Circle<float>{};
c1.center = geo::Vector3<float>{2.0000f, 0.0000f, 0.0000f};
c1.points.push_back(std::make_pair(0, geo::Vector3<float>{2.0000f, 0.0000f, 1.0000f}));
c1.points.push_back(std::make_pair(1, geo::Vector3<float>{2.0000f, 0.5878f, 0.8090f}));
c1.points.push_back(std::make_pair(2, geo::Vector3<float>{2.0000f, 0.9511f, 0.3090f}));
c1.points.push_back(std::make_pair(3, geo::Vector3<float>{2.0000f, 0.9511f, -0.3090f}));
c1.points.push_back(std::make_pair(4, geo::Vector3<float>{2.0000f, 0.5878f, -0.8090f}));
c1.points.push_back(std::make_pair(5, geo::Vector3<float>{2.0000f, 0.0000f, -1.0000f}));
c1.points.push_back(std::make_pair(6, geo::Vector3<float>{2.0000f, -0.5878f, -0.8090f}));
c1.points.push_back(std::make_pair(7, geo::Vector3<float>{2.0000f, -0.9511f, -0.3090f}));
c1.points.push_back(std::make_pair(8, geo::Vector3<float>{2.0000f, -0.9511f, 0.3090f}));
c1.points.push_back(std::make_pair(9, geo::Vector3<float>{2.0000f, -0.5878f, 0.8090f}));
c1.points.push_back(std::make_pair(10, geo::Vector3<float>{2.0000f, -0.0000f, 1.0000f}));
auto c2 = geo::Circle<float>{};
c2.center = geo::Vector3<float>{0.0000f, 2.0000f, 0.0000f};
c2.points.push_back(std::make_pair(11, geo::Vector3<float>{0.0000f, 2.0000f, 1.0000f}));
c2.points.push_back(std::make_pair(12, geo::Vector3<float>{0.5878f, 2.0000f, 0.8090f}));
c2.points.push_back(std::make_pair(13, geo::Vector3<float>{0.9511f, 2.0000f, 0.3090f}));
c2.points.push_back(std::make_pair(14, geo::Vector3<float>{0.9511f, 2.0000f, -0.3090f}));
c2.points.push_back(std::make_pair(15, geo::Vector3<float>{0.5878f, 2.0000f, -0.8090f}));
c2.points.push_back(std::make_pair(16, geo::Vector3<float>{0.0000f, 2.0000f, -1.0000f}));
c2.points.push_back(std::make_pair(17, geo::Vector3<float>{-0.5878f, 2.0000f, -0.8090f}));
c2.points.push_back(std::make_pair(18, geo::Vector3<float>{-0.9511f, 2.0000f, -0.3090f}));
c2.points.push_back(std::make_pair(19, geo::Vector3<float>{-0.9511f, 2.0000f, 0.3090f}));
c2.points.push_back(std::make_pair(20, geo::Vector3<float>{-0.5878f, 2.0000f, 0.8090f}));
c2.points.push_back(std::make_pair(21, geo::Vector3<float>{-0.0000f, 2.0000f, 1.0000f}));
auto c3 = geo::Circle<float>{};
c3.center = geo::Vector3<float>{-1.4142f, -1.4142f, 0.0000f};
c3.points.push_back(std::make_pair(22, geo::Vector3<float>{-1.4142f, -1.4142f, 1.0000f}));
c3.points.push_back(std::make_pair(23, geo::Vector3<float>{-1.8298f, -0.9986f, 0.8090f}));
c3.points.push_back(std::make_pair(24, geo::Vector3<float>{-2.0867f, -0.7417f, 0.3090f}));
c3.points.push_back(std::make_pair(25, geo::Vector3<float>{-2.0867f, -0.7417f, -0.3090f}));
c3.points.push_back(std::make_pair(26, geo::Vector3<float>{-1.8298f, -0.9986f, -0.8090f}));
c3.points.push_back(std::make_pair(27, geo::Vector3<float>{-1.4142f, -1.4142f, -1.0000f}));
c3.points.push_back(std::make_pair(28, geo::Vector3<float>{-0.9986f, -1.8298f, -0.8090f}));
c3.points.push_back(std::make_pair(29, geo::Vector3<float>{-0.7417f, -2.0867f, -0.3090f}));
c3.points.push_back(std::make_pair(30, geo::Vector3<float>{-0.7417f, -2.0867f, 0.3090f}));
c3.points.push_back(std::make_pair(31, geo::Vector3<float>{-0.9986f, -1.8298f, 0.8090f}));
c3.points.push_back(std::make_pair(32, geo::Vector3<float>{-1.4142f, -1.4142f, 1.0000f}));

View File

@ -0,0 +1,38 @@
auto c1 = geo::Circle<float>{};
c1.center = geo::Vector3<float>{2.0000f, 0.0000f, 0.0000f};
c1.points.push_back(std::make_pair(0, geo::Vector3<float>{2.0000f, 0.0000f, 1.0000f}));
c1.points.push_back(std::make_pair(1, geo::Vector3<float>{2.0000f, 0.5878f, 0.8090f}));
c1.points.push_back(std::make_pair(2, geo::Vector3<float>{2.0000f, 0.9511f, 0.3090f}));
c1.points.push_back(std::make_pair(3, geo::Vector3<float>{2.0000f, 0.9511f, -0.3090f}));
c1.points.push_back(std::make_pair(4, geo::Vector3<float>{2.0000f, 0.5878f, -0.8090f}));
c1.points.push_back(std::make_pair(5, geo::Vector3<float>{2.0000f, 0.0000f, -1.0000f}));
c1.points.push_back(std::make_pair(6, geo::Vector3<float>{2.0000f, -0.5878f, -0.8090f}));
c1.points.push_back(std::make_pair(7, geo::Vector3<float>{2.0000f, -0.9511f, -0.3090f}));
c1.points.push_back(std::make_pair(8, geo::Vector3<float>{2.0000f, -0.9511f, 0.3090f}));
c1.points.push_back(std::make_pair(9, geo::Vector3<float>{2.0000f, -0.5878f, 0.8090f}));
auto c2 = geo::Circle<float>{};
c2.center = geo::Vector3<float>{0.0000f, 2.0000f, 0.0000f};
c2.points.push_back(std::make_pair(10, geo::Vector3<float>{0.0000f, 2.0000f, 1.0000f}));
c2.points.push_back(std::make_pair(11, geo::Vector3<float>{0.5878f, 2.0000f, 0.8090f}));
c2.points.push_back(std::make_pair(12, geo::Vector3<float>{0.9511f, 2.0000f, 0.3090f}));
c2.points.push_back(std::make_pair(13, geo::Vector3<float>{0.9511f, 2.0000f, -0.3090f}));
c2.points.push_back(std::make_pair(14, geo::Vector3<float>{0.5878f, 2.0000f, -0.8090f}));
c2.points.push_back(std::make_pair(15, geo::Vector3<float>{0.0000f, 2.0000f, -1.0000f}));
c2.points.push_back(std::make_pair(16, geo::Vector3<float>{-0.5878f, 2.0000f, -0.8090f}));
c2.points.push_back(std::make_pair(17, geo::Vector3<float>{-0.9511f, 2.0000f, -0.3090f}));
c2.points.push_back(std::make_pair(18, geo::Vector3<float>{-0.9511f, 2.0000f, 0.3090f}));
c2.points.push_back(std::make_pair(19, geo::Vector3<float>{-0.5878f, 2.0000f, 0.8090f}));
auto c3 = geo::Circle<float>{};
c3.center = geo::Vector3<float>{-1.4142f, -1.4142f, 0.0000f};
c3.points.push_back(std::make_pair(20, geo::Vector3<float>{-1.4142f, -1.4142f, 1.0000f}));
c3.points.push_back(std::make_pair(21, geo::Vector3<float>{-1.8298f, -0.9986f, 0.8090f}));
c3.points.push_back(std::make_pair(22, geo::Vector3<float>{-2.0867f, -0.7417f, 0.3090f}));
c3.points.push_back(std::make_pair(23, geo::Vector3<float>{-2.0867f, -0.7417f, -0.3090f}));
c3.points.push_back(std::make_pair(24, geo::Vector3<float>{-1.8298f, -0.9986f, -0.8090f}));
c3.points.push_back(std::make_pair(25, geo::Vector3<float>{-1.4142f, -1.4142f, -1.0000f}));
c3.points.push_back(std::make_pair(26, geo::Vector3<float>{-0.9986f, -1.8298f, -0.8090f}));
c3.points.push_back(std::make_pair(27, geo::Vector3<float>{-0.7417f, -2.0867f, -0.3090f}));
c3.points.push_back(std::make_pair(28, geo::Vector3<float>{-0.7417f, -2.0867f, 0.3090f}));
c3.points.push_back(std::make_pair(29, geo::Vector3<float>{-0.9986f, -1.8298f, 0.8090f}));

View File

@ -0,0 +1,38 @@
auto c1 = geo::Circle<float>{};
c1.center = geo::Vector3<float>{2.0000f, 0.0000f, 0.0000f};
c1.points.push_back(std::make_pair(0, geo::Vector3<float>{2.0000f, 0.0000f, 1.0000f}));
c1.points.push_back(std::make_pair(1, geo::Vector3<float>{2.0000f, 0.5878f, 0.8090f}));
c1.points.push_back(std::make_pair(2, geo::Vector3<float>{2.0000f, 0.9511f, 0.3090f}));
c1.points.push_back(std::make_pair(3, geo::Vector3<float>{2.0000f, 0.9511f, -0.3090f}));
c1.points.push_back(std::make_pair(4, geo::Vector3<float>{2.0000f, 0.5878f, -0.8090f}));
c1.points.push_back(std::make_pair(5, geo::Vector3<float>{2.0000f, 0.0000f, -1.0000f}));
c1.points.push_back(std::make_pair(6, geo::Vector3<float>{2.0000f, -0.5878f, -0.8090f}));
c1.points.push_back(std::make_pair(7, geo::Vector3<float>{2.0000f, -0.9511f, -0.3090f}));
c1.points.push_back(std::make_pair(8, geo::Vector3<float>{2.0000f, -0.9511f, 0.3090f}));
c1.points.push_back(std::make_pair(9, geo::Vector3<float>{2.0000f, -0.5878f, 0.8090f}));
auto c2 = geo::Circle<float>{};
c2.center = geo::Vector3<float>{0.0000f, 2.0000f, 0.0000f};
c2.points.push_back(std::make_pair(10, geo::Vector3<float>{0.0000f, 2.0000f, 1.0000f}));
c2.points.push_back(std::make_pair(11, geo::Vector3<float>{-0.5878f, 2.0000f, 0.8090f}));
c2.points.push_back(std::make_pair(12, geo::Vector3<float>{-0.9511f, 2.0000f, 0.3090f}));
c2.points.push_back(std::make_pair(13, geo::Vector3<float>{-0.9511f, 2.0000f, -0.3090f}));
c2.points.push_back(std::make_pair(14, geo::Vector3<float>{-0.5878f, 2.0000f, -0.8090f}));
c2.points.push_back(std::make_pair(15, geo::Vector3<float>{-0.0000f, 2.0000f, -1.0000f}));
c2.points.push_back(std::make_pair(16, geo::Vector3<float>{0.5878f, 2.0000f, -0.8090f}));
c2.points.push_back(std::make_pair(17, geo::Vector3<float>{0.9511f, 2.0000f, -0.3090f}));
c2.points.push_back(std::make_pair(18, geo::Vector3<float>{0.9511f, 2.0000f, 0.3090f}));
c2.points.push_back(std::make_pair(19, geo::Vector3<float>{0.5878f, 2.0000f, 0.8090f}));
auto c3 = geo::Circle<float>{};
c3.center = geo::Vector3<float>{-1.4142f, -1.4142f, 0.0000f};
c3.points.push_back(std::make_pair(20, geo::Vector3<float>{-1.4142f, -1.4142f, 1.0000f}));
c3.points.push_back(std::make_pair(21, geo::Vector3<float>{-1.8298f, -0.9986f, 0.8090f}));
c3.points.push_back(std::make_pair(22, geo::Vector3<float>{-2.0867f, -0.7417f, 0.3090f}));
c3.points.push_back(std::make_pair(23, geo::Vector3<float>{-2.0867f, -0.7417f, -0.3090f}));
c3.points.push_back(std::make_pair(24, geo::Vector3<float>{-1.8298f, -0.9986f, -0.8090f}));
c3.points.push_back(std::make_pair(25, geo::Vector3<float>{-1.4142f, -1.4142f, -1.0000f}));
c3.points.push_back(std::make_pair(26, geo::Vector3<float>{-0.9986f, -1.8298f, -0.8090f}));
c3.points.push_back(std::make_pair(27, geo::Vector3<float>{-0.7417f, -2.0867f, -0.3090f}));
c3.points.push_back(std::make_pair(28, geo::Vector3<float>{-0.7417f, -2.0867f, 0.3090f}));
c3.points.push_back(std::make_pair(29, geo::Vector3<float>{-0.9986f, -1.8298f, 0.8090f}));

View File

@ -0,0 +1,51 @@
auto c1 = geo::Circle<float>{};
c1.center = geo::Vector3<float>{2.0000f, 0.0000f, 0.0000f};
c1.points.push_back(std::make_pair(0, geo::Vector3<float>{2.0000f, 0.0000f, 1.0000f}));
c1.points.push_back(std::make_pair(1, geo::Vector3<float>{2.0000f, 0.5878f, 0.8090f}));
c1.points.push_back(std::make_pair(2, geo::Vector3<float>{2.0000f, 0.9511f, 0.3090f}));
c1.points.push_back(std::make_pair(3, geo::Vector3<float>{2.0000f, 0.9511f, -0.3090f}));
c1.points.push_back(std::make_pair(4, geo::Vector3<float>{2.0000f, 0.5878f, -0.8090f}));
c1.points.push_back(std::make_pair(5, geo::Vector3<float>{2.0000f, 0.0000f, -1.0000f}));
c1.points.push_back(std::make_pair(6, geo::Vector3<float>{2.0000f, -0.5878f, -0.8090f}));
c1.points.push_back(std::make_pair(7, geo::Vector3<float>{2.0000f, -0.9511f, -0.3090f}));
c1.points.push_back(std::make_pair(8, geo::Vector3<float>{2.0000f, -0.9511f, 0.3090f}));
c1.points.push_back(std::make_pair(9, geo::Vector3<float>{2.0000f, -0.5878f, 0.8090f}));
auto c2 = geo::Circle<float>{};
c2.center = geo::Vector3<float>{0.0000f, 2.0000f, 0.0000f};
c2.points.push_back(std::make_pair(10, geo::Vector3<float>{0.0000f, 2.0000f, 1.0000f}));
c2.points.push_back(std::make_pair(11, geo::Vector3<float>{0.5878f, 2.0000f, 0.8090f}));
c2.points.push_back(std::make_pair(12, geo::Vector3<float>{0.9511f, 2.0000f, 0.3090f}));
c2.points.push_back(std::make_pair(13, geo::Vector3<float>{0.9511f, 2.0000f, -0.3090f}));
c2.points.push_back(std::make_pair(14, geo::Vector3<float>{0.5878f, 2.0000f, -0.8090f}));
c2.points.push_back(std::make_pair(15, geo::Vector3<float>{0.0000f, 2.0000f, -1.0000f}));
c2.points.push_back(std::make_pair(16, geo::Vector3<float>{-0.5878f, 2.0000f, -0.8090f}));
c2.points.push_back(std::make_pair(17, geo::Vector3<float>{-0.9511f, 2.0000f, -0.3090f}));
c2.points.push_back(std::make_pair(18, geo::Vector3<float>{-0.9511f, 2.0000f, 0.3090f}));
c2.points.push_back(std::make_pair(19, geo::Vector3<float>{-0.5878f, 2.0000f, 0.8090f}));
auto c3 = geo::Circle<float>{};
c3.center = geo::Vector3<float>{-2.0000f, 0.0000f, 0.0000f};
c3.points.push_back(std::make_pair(20, geo::Vector3<float>{-2.0000f, 0.0000f, 1.0000f}));
c3.points.push_back(std::make_pair(21, geo::Vector3<float>{-2.0000f, -0.5878f, 0.8090f}));
c3.points.push_back(std::make_pair(22, geo::Vector3<float>{-2.0000f, -0.9511f, 0.3090f}));
c3.points.push_back(std::make_pair(23, geo::Vector3<float>{-2.0000f, -0.9511f, -0.3090f}));
c3.points.push_back(std::make_pair(24, geo::Vector3<float>{-2.0000f, -0.5878f, -0.8090f}));
c3.points.push_back(std::make_pair(25, geo::Vector3<float>{-2.0000f, -0.0000f, -1.0000f}));
c3.points.push_back(std::make_pair(26, geo::Vector3<float>{-2.0000f, 0.5878f, -0.8090f}));
c3.points.push_back(std::make_pair(27, geo::Vector3<float>{-2.0000f, 0.9511f, -0.3090f}));
c3.points.push_back(std::make_pair(28, geo::Vector3<float>{-2.0000f, 0.9511f, 0.3090f}));
c3.points.push_back(std::make_pair(29, geo::Vector3<float>{-2.0000f, 0.5878f, 0.8090f}));
auto c4 = geo::Circle<float>{};
c4.center = geo::Vector3<float>{0.0000f, -2.0000f, 0.0000f};
c4.points.push_back(std::make_pair(30, geo::Vector3<float>{0.0000f, -2.0000f, 1.0000f}));
c4.points.push_back(std::make_pair(31, geo::Vector3<float>{-0.5878f, -2.0000f, 0.8090f}));
c4.points.push_back(std::make_pair(32, geo::Vector3<float>{-0.9511f, -2.0000f, 0.3090f}));
c4.points.push_back(std::make_pair(33, geo::Vector3<float>{-0.9511f, -2.0000f, -0.3090f}));
c4.points.push_back(std::make_pair(34, geo::Vector3<float>{-0.5878f, -2.0000f, -0.8090f}));
c4.points.push_back(std::make_pair(35, geo::Vector3<float>{-0.0000f, -2.0000f, -1.0000f}));
c4.points.push_back(std::make_pair(36, geo::Vector3<float>{0.5878f, -2.0000f, -0.8090f}));
c4.points.push_back(std::make_pair(37, geo::Vector3<float>{0.9511f, -2.0000f, -0.3090f}));
c4.points.push_back(std::make_pair(38, geo::Vector3<float>{0.9511f, -2.0000f, 0.3090f}));
c4.points.push_back(std::make_pair(39, geo::Vector3<float>{0.5878f, -2.0000f, 0.8090f}));

View File

@ -0,0 +1,190 @@
#include <iostream>
#include <vector>
#include <memory>
#include <cmath>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <GL/gl.h>
#include <GL/glu.h>
#include "SFMLTools/FreeFlyCamera.hpp"
#include "Geometry/Mesh.hpp"
#include "Geometry/Vector.hpp"
#include "Geometry/Point.hpp"
#include "Spline/Skeleton3D.hpp"
// Full hd : 1920x1080
constexpr auto WIDTH = 1920;
constexpr auto HEIGHT = 1080;
void drawScene(sft::FreeFlyCamera const& camera, geo::Mesh const& mesh);
int main(int argc, char *argv[])
{
// Init mesh
pae::Skeleton3D<geo::Vector3<float>, float> skeleton;
if (argc <= 1)
{
if (!skeleton.loadFromFile("data/skl/skel.skl"))
{
std::cerr << "Default file not found ! Try with a file..." << std::endl;
}
}
else
{
auto path = std::string{argv[1]};
if (!skeleton.loadFromFile(path))
{
std::cerr << "File " << path << " not found ! Try with another file..." << std::endl;
}
}
geo::Mesh mesh;
std::vector<std::vector<geo::Circle<float>>> splines_circles;
unsigned int globalOffset = 0;
unsigned int pointsProportion = 22u;
unsigned int nbPointsPerCircle = 16u;
unsigned int profondeur = 2;
for (auto const& spline : skeleton.splines)
{
float l = geo::splineLenght(spline);
unsigned int nbCirclesOnTheSpline = std::max(static_cast<unsigned int>(std::round(pointsProportion*l)),2u);
auto spl = spline.computeCircles(nbCirclesOnTheSpline,nbPointsPerCircle,globalOffset);
splines_circles.push_back(spl);
mesh += geo::splineMeshing(spl);
globalOffset+=nbPointsPerCircle*nbCirclesOnTheSpline;
}
skeleton.meshExtremities(mesh, splines_circles, profondeur);
skeleton.meshJunctions(mesh,splines_circles);
mesh.prepareEdges();
// Création de la fenêtre
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT),
"pae",
sf::Style::Fullscreen,
sf::ContextSettings(32));
window.setVerticalSyncEnabled(true);
window.setMouseCursorVisible(false);
//Initialisation du mode 3D
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70,(double)WIDTH/HEIGHT,0.2,1000);
// Initialisation de Z-Buffer
glEnable(GL_DEPTH_TEST);
// Activer les textures
glEnable(GL_TEXTURE_2D);
// Autoriser la transparence
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Ces 2 lignes améliorent le rendu
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
// On efface le tampon d'affichage
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFlush();
// Camera
auto camera = sft::FreeFlyCamera{};
// la boucle principale
auto running = true;
auto captureRequired = false;
while (running)
{
// gestion des évènements
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
// on stoppe le programme
running = false;
}
else if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Escape)
{
running = false;
}
else if (event.key.code == sf::Keyboard::P)
{
captureRequired = true;
}
}
else if (event.type == sf::Event::MouseMoved)
{
// Hum...
}
else if (event.type == sf::Event::Resized)
{
// on ajuste le viewport lorsque la fenêtre est redimensionnée
glViewport(0, 0, event.size.width, event.size.height);
}
}
// Les trucs qui sont pas des évènements
camera.nextStep(WIDTH, HEIGHT);
sf::Mouse::setPosition(sf::Vector2i{WIDTH/2, HEIGHT/2});
// Dessin de la scene
drawScene(camera, mesh);
if (captureRequired)
{
window.capture().saveToFile("capture.jpg");
captureRequired = false;
}
// termine la trame courante (en interne, échange les deux tampons de rendu)
window.display();
}
// libération des ressources...
return 0;
}
void drawScene(sft::FreeFlyCamera const& camera, geo::Mesh const& mesh)
{
// Initialisation
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Position Camera gluLookAt(positionCamera, positionCible, vecteurVertical)
camera.look();
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3f(0,1,0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3f(0,0,1);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
// Dessin de carrés
mesh.drawEdges();
// MAJ de l'écran
glFlush();
}

View File

@ -8,15 +8,15 @@
#include <GL/gl.h>
#include <GL/glu.h>
#include "FreeFlyCamera.hpp"
#include "Mesh.hpp"
#include "Skeleton3D.hpp"
#include "Geometry/Mesh.hpp"
#include "Spline/FreeFlyCamera.hpp"
#include "Spline/Skeleton3D.hpp"
// Full hd : 1920x1080
constexpr auto WIDTH = 1920;
constexpr auto HEIGHT = 1080;
void drawScene(pae::FreeFlyCamera const& camera, pae::Mesh const& mesh);
void drawScene(pae::FreeFlyCamera const& camera, geo::Mesh const& mesh);
int main(int argc, char *argv[])
{
@ -53,11 +53,11 @@ int main(int argc, char *argv[])
glFlush();
// Init mesh
pae::Skeleton3D<pae::Vector3<float>, float> skeleton;
pae::Skeleton3D<geo::Vector3<float>, float> skeleton;
skeleton.loadFromFile("dinoboudin.skl");
pae::Mesh mesh;
std::vector<std::vector<pae::Circle<float>>> splines_circles;
geo::Mesh mesh;
std::vector<std::vector<geo::Circle<float>>> splines_circles;
unsigned int globalOffset = 0;
unsigned int pointsProportion = 22u;
@ -66,11 +66,11 @@ int main(int argc, char *argv[])
for (auto const& spline : skeleton.splines)
{
float l = pae::splineLenght(spline);
float l = geo::splineLenght(spline);
unsigned int nbCirclesOnTheSpline = std::max(static_cast<unsigned int>(std::round(pointsProportion*l)),2u);
auto spl = spline.computeCircles(nbCirclesOnTheSpline,nbPointsPerCircle,globalOffset);
splines_circles.push_back(spl);
mesh += pae::splineMeshing(spl);
mesh += geo::splineMeshing(spl);
globalOffset+=nbPointsPerCircle*nbCirclesOnTheSpline;
}
skeleton.meshExtremities(mesh, splines_circles, profondeur);
@ -139,7 +139,7 @@ int main(int argc, char *argv[])
return 0;
}
void drawScene(pae::FreeFlyCamera const& camera, pae::Mesh const& mesh)
void drawScene(pae::FreeFlyCamera const& camera, geo::Mesh const& mesh)
{
// Initialisation
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

View File

@ -1,27 +0,0 @@
SOURCES = Mesh.cpp Base.cpp FreeFlyCamera.cpp
OBJECTS = $(SOURCES:.cpp=.o)
MAIN1 = main.cpp
MAIN2 = MainSFML.cpp
TARGET1 = test
TARGET2 = sfml
LIBS = -lGL -lGLU -lsfml-system -lsfml-window -lsfml-graphics
CXX = g++
all: clean main MainSFML
%.o: %.cpp
$(CXX) -g -std=c++14 -o $@ -c $< -Wall
main: $(OBJECTS) main.o
$(CXX) -g -std=c++14 -o $(TARGET1) main.o $(OBJECTS) $(LIBS) -Wall
MainSFML: $(OBJECTS) MainSFML.o
$(CXX) -g -std=c++14 -o $(TARGET2) MainSFML.o $(OBJECTS) $(LIBS) -Wall
clean:
rm -rf *.o

View File

@ -1,105 +0,0 @@
#ifndef SKELETON3D_HPP
#define SKELETON3D_HPP
#include <vector>
#include <list>
#include "Mesh.hpp"
#include "Spline.hpp"
namespace pae
{
/////////////////////////////////////////////////////////
// Junction : a junction in the skeleton defined by a vector of pairs containing:
// - spline's index
// - t parameter where the junction
// is located on the spline
//
// Example : <<ind1,t1>, <ind2,t2>, <ind3,t3>>
//This junction is between 3 splines designated by their indexes.
////////////////////////////////////////////////////////
using Junction = std::vector<std::pair<unsigned int,float>>;
namespace detail
{
template<typename T>
using Point = std::pair<unsigned int, Vector3<T>>;
template<typename T>
bool whichSide(std::array<double,4> const& plane, Vector3<float> const& point);
template<typename T>
std::array<double,4> closestPlane(std::vector<std::pair<Point<T>,Point<T>>> const& points);
template<typename T>
std::vector<std::list<Point<T>>> sortedPoints(std::array<double,4> const& plane, std::vector<Circle<T>> const& junction_circles, std::vector<std::pair<Point<T>,Point<T>>> const& closest_points);
}
template<typename... Types>
class Skeleton3D
{
public:
Skeleton3D();
void loadFromFile(std::string const& path);
void meshJunctions(Mesh mesh, std::vector<std::vector<Circle<float>>> const& splines_circles);
void meshJunction(Mesh mesh, std::vector<std::vector<Circle<float>>> const& splines_circles, Junction const& junction);
/////////////////////////////////////////////////////////////
/// \brief findExtremities : get the extremities of the skeleton
///
/// \param none
/// \output a vector of pair which contain the index of the spline
/// and the t where is the extremity
/////////////////////////////////////////////////////////////
std::vector<std::pair<unsigned int, float>> findExtremities();
////////////////////////////////////////////////////////////
/// \brief meshExtremities : compute the extremities as a mesh
/// (call meshExtremity)
///
/// \param the mesh and the circles associated to the splines
///
///////////////////////////////////////////////////////////
void meshExtremities(Mesh& mesh, std::vector<std::vector<Circle<float>>> const& splines_circles, unsigned int depth);
void meshExtremity(Mesh& mesh, std::vector<std::vector<Circle<float>>> const& splines_circles, unsigned int depth, std::pair<unsigned int,float> extremity);
///////////////////////////////////////////////////////////
/// \brief subdivision : subdivise the initial meshExtremities
/// according to the depth (call arcSubdivise)
///
/// \param the initial mesh, the depth of the subdivision, the
/// the extrem circle, the index of the intersection,
/// the intersection point, the center of the circle,
/// the associated radius and the time t
//////////////////////////////////////////////////////////
void subdivision(Mesh& mesh, unsigned int depth, Circle<float> extremCircle, unsigned int intersectionIndex, Vector3<float> intersection, Vector3<float> center, float radius, float t);
void arcSubdivise(Vector3<float> pt1, Vector3<float> pt2, unsigned int depth, std::vector<Vector3<float>>& arc, Vector3<float> center, float radius);
//////////////////////////////////////////////////////////////
/// \brief buildBranches : build the segment between the cliks
/// the extremities and the jonctions
///
/// \param the cliks (vector of Vector3) and the number of circles
/// \return a vector which contain the segments along each splines,
/// segments are a pair of Vector3 with the time associated
/////////////////////////////////////////////////////////////
std::vector<std::vector<std::pair<std::pair<pae::Vector3<float>,float>,std::pair<pae::Vector3<float>,float>>>> buildBranches(std::vector<pae::Vector3<float>> click, unsigned int const nbCircles);
std::pair<detail::Point<float>,detail::Point<float>> closestPointsCircles(Circle<float> const& circle1, Circle<float> const& circle2);
template<typename... T>
friend std::ostream& operator<<(std::ostream& out, Skeleton3D<T...> const& s);
// private:
std::vector<Spline<Types...>> splines;
std::vector<Junction> junctions;
};
} // namespace pae
#include "Skeleton3D.inl"
#endif // SKELETON3D_HPP

View File

@ -1,675 +0,0 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <cmath>
#include <list>
#include <eigen3/Eigen/Dense>
#include "Skeleton3D.hpp"
#include <algorithm>
namespace pae
{
template<typename... Types>
Skeleton3D<Types...>::Skeleton3D() : splines{}
{
}
template<typename... Types>
void Skeleton3D<Types...>::loadFromFile(std::string const& path)
{
std::fstream file{path};
if (!file)
{
std::cerr << "Warning : couldn't load Skeleton from file " << path << std::endl;
return;
}
std::stringstream stream;
std::string line;
bool alreadyFoundL = false;
Spline<Types...> currentSpline;
while (std::getline(file, line))
{
if (line.size() == 0)
continue;
char first;
stream.clear();
stream.str(line);
stream >> first;
switch (first)
{
case 'd':
{
// Add the current spline
splines.push_back(currentSpline);
// Prepare the new one
currentSpline = Spline<Types...>{};
// Set the degree of the spline
int i;
stream >> i;
currentSpline.degree = i;
break;
}
case 'n':
{
float x;
while (stream >> x)
{
currentSpline.nodes.push_back(x);
}
break;
}
case 'p':
{
// Add control point to the spline
// std::cout << "p->" << line << std::endl;
currentSpline.addControlPoint(line.substr(1));
break;
}
case 'l':
{
if (!alreadyFoundL)
{
splines.push_back(currentSpline);
alreadyFoundL = true;
}
float size_junction;
stream >> size_junction;
unsigned int x;
junctions.push_back(Junction{});
Junction& j = junctions[junctions.size()-1];
for (unsigned int i = 0; i<size_junction; i++)
{
stream >> x;
j.push_back(std::make_pair(x-1,0.0f));
}
float y;
for (unsigned int i = 0; i<size_junction; i++)
{
stream >> y;
j[i].second = y;
}
break;
}
}
}
if (!alreadyFoundL)
{
splines.push_back(currentSpline);
}
// Remove the first spline that is empty
splines.erase(splines.begin());
}
template<typename... T>
void Skeleton3D<T...>::meshJunctions(Mesh mesh, std::vector<std::vector<Circle<float>>> const& splines_circles)
{
for(unsigned int i = 0; i<junctions.size(); i++)
{
meshJunction(mesh, splines_circles,junctions[i]);
}
}
template<typename... T>
void Skeleton3D<T...>::meshJunction(Mesh mesh, std::vector<std::vector<Circle<float>>> const& splines_circles, Junction const& junction)
{
std::vector<Circle<float>> junction_circles; // characteristic circles from the splines of the junction
Vector3<float> junction_point; // sphere's center of the junction point
float junction_radius; // sphere's radius
// Get the junction elements
auto tuple = splines[junction[0].first];
junction_point = std::get<0>(tuple)(junction[0].second);
junction_radius = std::get<1>(tuple)(junction[0].second);
for(unsigned int i = 0; i<junction.size(); i++)
{
unsigned int indSpline = junction[i].first;
float t = junction[i].second;
auto spline_circles = splines_circles[indSpline];
if (t==0.0f){
junction_circles.push_back(spline_circles[0]);
}
else
{
junction_circles.push_back(spline_circles[spline_circles.size()-1]);
}
}
// Compute the closest points between two consecutives circles
std::vector<std::pair<detail::Point<float>,detail::Point<float>>> closestPoints;
for (unsigned int i = 0; i<junction_circles.size(); i++)
{
Circle<float>& circle1 = junction_circles[i];
Circle<float>& circle2 = junction_circles[(i+1)%junction_circles.size()];
closestPoints.push_back(closestPointsCircles(circle1,circle2));
}
// Find the medium plane that cut the circles in two
std::array<double,4> plane = detail::closestPlane<float>(closestPoints);
// Compute list of points upside with the closestPointsCircles "correspondants" and outside
//TODO écrire un commentaire compréhensible !
std::vector<std::list<detail::Point<float>>> sorted_points = detail::sortedPoints<float>(plane, junction_circles,closestPoints);
}
template<typename... T>
std::pair<detail::Point<float>,detail::Point<float>> Skeleton3D<T...>::closestPointsCircles(Circle<float> const& circle1, Circle<float> const& circle2)
{
float bestDistance = (circle1.points[0].second - circle2.points[0].second).norm2();
detail::Point<float> const* bestPoint1 = nullptr;
detail::Point<float> const* bestPoint2 = nullptr;
for(auto const& point1:circle1.points)
{
for(auto const& point2:circle2.points)
{
float twoDistance = (point1.second - point2.second).norm2();
if( twoDistance < bestDistance)
{
bestDistance = twoDistance;
bestPoint1 = &point1;
bestPoint2 = &point2;
}
}
}
return std::make_pair(*bestPoint1,*bestPoint2);
}
template<typename... T>
std::vector<std::pair<unsigned int, float>> Skeleton3D<T...>::findExtremities()
{
std::vector<std::pair<unsigned int, float>> extremities;
std::vector<unsigned int> indexJunctions;
//construction of a vector containing indexes of a spline *2 + t
if (junctions.empty())
{
for (unsigned int i=0;i<splines.size();i++)
{
extremities.push_back(std::make_pair(i,0));
extremities.push_back(std::make_pair(i,1));
}
return extremities;
}
for (unsigned int i=0;i<junctions.size();i++)
{
for (unsigned int j=0;j<junctions[i].size();j++)
{
std::pair<unsigned int, float> extremSpline = junctions[i][j];
indexJunctions.push_back(extremSpline.first*2 + extremSpline.second);
}
}
std::sort(indexJunctions.begin(),indexJunctions.end());
unsigned int index=0;
for (unsigned int i=0;i<splines.size();i++)
{
if (i*2==indexJunctions[index])
{
index++;
}
else
{
extremities.push_back(std::make_pair(i,0));
}
if (((i*2)+1)==indexJunctions[index])
{
index++;
}
else
{
extremities.push_back(std::make_pair(i,1));
}
}
return extremities;
}
template<typename... T>
void Skeleton3D<T...>::meshExtremities(Mesh& mesh, std::vector<std::vector<Circle<float>>> const& splines_circles, unsigned int depth)
{
std::vector<std::pair<unsigned int, float>> extremities = findExtremities();
for (unsigned int i=0;i<extremities.size();i++)
{
meshExtremity(mesh, splines_circles, depth, extremities[i]);
}
}
template<typename... T>
void Skeleton3D<T...>::meshExtremity(Mesh& mesh, std::vector<std::vector<Circle<float>>> const& splines_circles, unsigned int depth, std::pair<unsigned int,float> extremity)
{
// Get the junction elements
auto tuple = splines[extremity.first](extremity.second);
auto C_t = std::get<0>(tuple);
auto r_t = std::get<1>(tuple);
auto S_prime_t = splines[extremity.first].prime(extremity.second);
auto C_prime_t = std::get<0>(S_prime_t);
C_prime_t /= C_prime_t.norm();
auto intersection = C_t;
if (extremity.second == 0)
{
intersection -= r_t * C_prime_t;
}
else
{
intersection += r_t * C_prime_t;
}
Circle<float> extremCircle;
if (extremity.second == 0)
{
extremCircle = splines_circles[extremity.first][0];
}
else
{
extremCircle = splines_circles[extremity.first][splines_circles[extremity.first].size()-1];
}
unsigned int intersectionIndex = mesh.vertices.size();
if (depth==0)
{
mesh.vertices.push_back(intersection);
for (unsigned int i=0;i<extremCircle.points.size();i++)
{
auto ip1 = extremCircle.points[i].first;
if (i==extremCircle.points.size()-1)
{
auto ip2 = extremCircle.points[0].first;
if (extremity.second==1)
{
mesh.faces.push_back(Vector3<unsigned int> {ip1,ip2,intersectionIndex});
} else {
mesh.faces.push_back(Vector3<unsigned int> {ip1,intersectionIndex,ip2});
}
}
else
{
auto ip2 = extremCircle.points[i+1].first;
if (extremity.second==1)
{
mesh.faces.push_back(Vector3<unsigned int> {ip1,ip2,intersectionIndex});
} else {
mesh.faces.push_back(Vector3<unsigned int> {ip1,intersectionIndex,ip2});
}
}
}
}
else
{
subdivision(mesh, depth, extremCircle, intersectionIndex, intersection, C_t, r_t, extremity.second);
}
}
template<typename... T>
void Skeleton3D<T...>::subdivision(Mesh& mesh, unsigned int depth, Circle<float> extremCircle, unsigned int intersectionIndex, Vector3<float> intersection, Vector3<float> center, float radius, float t)
{
std::vector<std::vector<Vector3<float>>> arcs;
for (unsigned int i=0;i<extremCircle.points.size();i++)
{
// compute the points build by subdivision on one arc (between a point on the extrem
// circle and the extremity)
std::vector<Vector3<float>> arc;
arc.push_back(intersection);
arcSubdivise(intersection, extremCircle.points[i].second, depth, arc, center, radius);
arc.push_back(extremCircle.points[i].second);
arcs.push_back(arc);
}
// Compute the mesh
//push the new vertices
unsigned int indexVertices = mesh.vertices.size();
unsigned int indexVerticesInit = indexVertices;
unsigned int nbPoints = arcs[0].size()-2;
//push the intersection
mesh.vertices.push_back(arcs[0][0]);
// push all the new vertices
for (unsigned int i=0;i<arcs.size();i++)
{
for (unsigned int j=1;j<arcs[i].size()-1;j++)
{
mesh.vertices.push_back(arcs[i][j]);
}
}
//push the faces
for (unsigned int i=0;i<arcs.size()-1;i++)
{
auto courant = arcs[i];
for (unsigned int j=0;j<courant.size()-2;j++)
{
if (j==0)
{
if (t==0)
{
mesh.faces.push_back({intersectionIndex, indexVertices + 1 + nbPoints, indexVertices + 1});
} else {
mesh.faces.push_back({intersectionIndex, indexVertices + 1, indexVertices + 1 + nbPoints});
}
}
else
{
if (t==0)
{
mesh.faces.push_back({indexVertices + j, indexVertices + j + 1 + nbPoints, indexVertices + j + 1});
mesh.faces.push_back({indexVertices + j, indexVertices + j + nbPoints, indexVertices + j + 1 + nbPoints});
} else {
mesh.faces.push_back({indexVertices + j, indexVertices + j + 1, indexVertices + j + 1 + nbPoints});
mesh.faces.push_back({indexVertices + j, indexVertices + j + 1 + nbPoints, indexVertices + j + nbPoints});
}
}
}
// before last point
unsigned int i1 = extremCircle.points[i].first;
unsigned int i2 = extremCircle.points[i+1].first;
if (t==0)
{
mesh.faces.push_back({indexVertices + nbPoints, i2, i1});
mesh.faces.push_back({indexVertices + nbPoints , indexVertices + 2*nbPoints , i2});
}
else {
mesh.faces.push_back({indexVertices + nbPoints, i1, i2});
mesh.faces.push_back({indexVertices + nbPoints , i2, indexVertices + 2*nbPoints});
}
// increment the indexVertices
indexVertices += nbPoints;
}
// the last mesh (last arc)
auto courant = arcs[arcs.size()-1];
for (unsigned int j=0;j<courant.size()-2;j++)
{
if (j==0)
{
if (t==0)
{
mesh.faces.push_back({intersectionIndex, indexVerticesInit + 1, indexVertices + 1});
} else {
mesh.faces.push_back({intersectionIndex, indexVertices + 1, indexVerticesInit + 1});
}
}
else
{
if (t==0)
{
mesh.faces.push_back({indexVertices + j, indexVerticesInit + j + 1, indexVertices + j + 1});
mesh.faces.push_back({indexVertices + j, indexVerticesInit + j, indexVerticesInit + j + 1});
} else {
mesh.faces.push_back({indexVertices + j, indexVertices + j + 1, indexVerticesInit + j + 1});
mesh.faces.push_back({indexVertices + j, indexVerticesInit + j + 1, indexVerticesInit + j});
}
}
}
// before last point
unsigned int i1 = extremCircle.points[arcs.size()-1].first;
unsigned int i2 = extremCircle.points[0].first;
if (t==0)
{
mesh.faces.push_back({indexVertices + nbPoints, i2, i1});
mesh.faces.push_back({indexVertices + nbPoints, indexVerticesInit + nbPoints, i2});
}
else
{
mesh.faces.push_back({indexVertices + nbPoints, i1, i2});
mesh.faces.push_back({indexVertices + nbPoints, i2, indexVerticesInit + nbPoints});
}
}
//pt1 the extremity
template<typename... T>
void Skeleton3D<T...>::arcSubdivise(Vector3<float> pt1, Vector3<float> pt2, unsigned int depth, std::vector<Vector3<float>>& arc, Vector3<float> center, float radius)
{
if (depth!=0)
{
// compute middle of arc
Vector3<float> middleSegment;
middleSegment = (pt1+pt2)/2;
// projection on the sphere
Vector3<float> direction = (middleSegment - center);
direction /= direction.norm();
direction *= radius;
Vector3<float> middle = center + direction;
arcSubdivise(pt1, middle, depth-1, arc, center, radius);
arc.push_back(middle);
arcSubdivise(middle, pt2, depth-1, arc, center, radius);
}
}
template<typename... T>
std::vector<std::vector<std::pair<std::pair<pae::Vector3<float>,float>,std::pair<pae::Vector3<float>,float>>>> Skeleton3D<T...>::buildBranches(std::vector<pae::Vector3<float>> clicks, unsigned int const nbCircles)
{
std::vector<std::vector<std::pair<std::pair<pae::Vector3<float>,float>,std::pair<pae::Vector3<float>,float>>>> totalSplineSegments;
//Compute the projection of each cliks on the spline
std::vector<std::tuple<pae::Vector3<float>, unsigned int, float>> pointsCorrespondingToCliks;
//std::vector<std::vector<std::pair<Vector<float>, float>>> pointsCorrespondingToClicks;
for (unsigned int i = 0; i < clicks.size(); i++)
{
auto C_t = std::get<0>(splines[0](0));
pae::Vector3<float> closestPoint = C_t;
float shortestDist = (clicks[i]-C_t).norm();
unsigned int shortestIndex = 0;
float shortestTime = 0;
for (unsigned int j = 0; j < splines.size(); j++)
{
for (unsigned int k = 0; k < nbCircles; k++)
{
C_t = std::get<0>(splines[j](static_cast<float>(k)/(nbCircles-1)));
float dist = (clicks[i]-C_t).norm();
if (dist < shortestDist)
{
closestPoint = C_t;
shortestDist = dist;
shortestIndex = j;
shortestTime = static_cast<float>(k)/(nbCircles-1);
}
}
}
pointsCorrespondingToCliks.push_back(std::make_tuple(C_t, shortestIndex, shortestTime));
}
for (unsigned int i = 0; i < splines.size(); i++)
{
std::vector<std::pair<pae::Vector3<float>, float>> pointsAlongTheSpline;
for (unsigned int j = 0; j < pointsCorrespondingToCliks.size(); j++)
{
if (std::get<1>(pointsCorrespondingToCliks[j]) == i)
{
auto const& ptj = pointsCorrespondingToCliks[j];
pointsAlongTheSpline.push_back({std::get<0>(ptj),std::get<2>(ptj)});
}
}
std::sort(std::begin(pointsAlongTheSpline),std::end(pointsAlongTheSpline),[](std::pair<pae::Vector3<float>,float> const& p1, std::pair<pae::Vector3<float>,float> const& p2){return p1.second < p2.second;});
std::vector<std::pair<std::pair<pae::Vector3<float>,float>,std::pair<pae::Vector3<float>,float>>> segments;
auto tuple = splines[i](0);
std::pair<pae::Vector3<float>, float> currentPoint = std::make_pair(std::get<0>(tuple),0);
std::pair<pae::Vector3<float>, float> nextPoint;
for (unsigned int j = 0; j < pointsAlongTheSpline.size(); j++)
{
nextPoint = std::make_pair(std::get<0>(splines[i](pointsAlongTheSpline[j].second)),pointsAlongTheSpline[j].second);
segments.push_back(std::make_pair(currentPoint,nextPoint));
currentPoint = nextPoint;
}
tuple = splines[i](1);
nextPoint = std::make_pair(std::get<0>(tuple),1);
segments.push_back(std::make_pair(currentPoint,nextPoint));
totalSplineSegments.push_back(segments);
}
return totalSplineSegments;
}
template<typename... T>
std::ostream& operator<<(std::ostream& out, Skeleton3D<T...> const& s)
{
for (auto const& spline:s.splines)
{
out << spline << std::endl;
}
for (auto const& junction:s.junctions)
{
out << "l " << junction.size() << " ";
for (auto const& pair:junction)
{
out << pair.first << " ";
}
for (auto const& pair:junction)
{
out << pair.second << " ";
}
out << std::endl;
}
return out;
}
namespace detail
{
template<typename T>
bool whichSide(std::array<double,4> const& plane, Vector3<float> const& point)
{
return plane[0]*point.x() + plane[1]*point.y() + plane[2]*point.z() < - plane[3];
}
template<typename T>
std::array<double,4> closestPlane(std::vector<std::pair<Point<T>,Point<T>>> const& points)
{
Eigen::MatrixXd m{points.size()*2,3};
for ( unsigned int i = 0; i < points.size()*2; i+=2)
{
m(i,0) = points[i].first.second.x();
m(i,1) = points[i].first.second.y();
m(i,2) = points[i].first.second.z();
m(i+1,0) = points[i].second.second.x();
m(i+1,1) = points[i].second.second.y();
m(i+1,2) = points[i].second.second.z();
}
Eigen::MatrixXd centered = m.rowwise() - m.colwise().mean();
Eigen::MatrixXd cov = centered.adjoint() * centered;
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eig{cov};
Eigen::Vector3d v1 = eig.eigenvectors().col(1);
Eigen::Vector3d v2 = eig.eigenvectors().col(2);
Eigen::Vector3d n = v1.cross(v2);
return( std::array<double,4>{n(0),n(1),n(2), n.dot(m.colwise().mean())} );
}
template<typename T>
std::vector<std::list<Point<T>>> sortedPoints(std::array<double,4> const& plane, std::vector<Circle<T>> const& junction_circles, std::vector<std::pair<Point<T>,Point<T>>> const& closest_points)
{
std::vector<std::list<Point<float>>> sorted_points;
for (unsigned int i = 0; i < junction_circles.size(); i++)
{
std::list<Point<float>> first_points;
std::list<Point<float>> second_points;
bool up_side = whichSide<double>(plane, junction_circles[i].points[0].second);
bool current_points = up_side;
for (unsigned int j = 0; j < junction_circles[i].points.size(); j++)
{
if (up_side == current_points)
{
if (whichSide<double>(plane, junction_circles[i].points[j].second) == up_side)
{
first_points.push_back(junction_circles[i].points[j]);
}
else
{
current_points = whichSide<double>(plane, junction_circles[i].points[j].second);
second_points.push_back(junction_circles[i].points[j]);
}
}
else
{
if (whichSide<double>(plane, junction_circles[i].points[j].second) == current_points)
{
second_points.push_back(junction_circles[i].points[j]);
}
else
{
break;
}
}
}
for (int j = static_cast<int>(junction_circles[i].points.size()-1); j >= 0; j--)
{
if (whichSide<double>(plane, junction_circles[i].points[j].second) == up_side)
{
first_points.push_front(junction_circles[i].points[j]);
}
else
{
break;
}
}
sorted_points.push_back(first_points);
sorted_points.push_back(second_points);
}
return sorted_points;
}
} // namespace detail
} // namespace pae

View File

@ -1,60 +0,0 @@
#ifndef SPLINE_HPP
#define SPLINE_HPP
#include <vector>
#include <tuple>
#include <cmath>
#include "Circle.hpp"
#include "TupleFunctions.hpp"
namespace pae
{
template<typename... Types>
class Spline
{
public:
Spline();
std::tuple<Types...> operator()(float f) const;
template<std::size_t I>
constexpr typename std::tuple_element<I, std::tuple<Types...>>::type
operator()(float f) const;
std::tuple<Types...> prime(float f) const;
template<std::size_t I>
constexpr typename std::tuple_element<I, std::tuple<Types...>>::type
prime(float f) const;
template<typename... T>
friend std::ostream& operator<<( std::ostream& out, Spline<T...> const& spline);
Circle<float> computeCircle(float t, unsigned int const nbPoints, Vector3<float>& v, unsigned int const offset = 0) const;
std::vector<Circle<float>> computeCircles(unsigned int nbCircles, unsigned int const nbPoints, unsigned int const globalOffset = 0) const;
// private:
void addControlPoint(std::string const& node);
std::vector<std::tuple<Types...>> controlPoints;
std::vector<float> nodes;
int degree;
};
namespace detail
{
template<typename... Types>
std::tuple<Types...> evalSpline(std::vector<std::tuple<Types...>> const& controlPoints , std::vector<float> const& nodes, int degree, float f);
template<typename... Types>
std::tuple<Types...> evalDerivativeSpline(std::vector<std::tuple<Types...>> const& controlPoints , std::vector<float> const& nodes, int degree, float f);
} // namespace detail
} // namespace pae
#include "Spline.inl"
#endif // SPLINE_HPP

View File

@ -0,0 +1,214 @@
#include <iostream>
#include <vector>
#include <memory>
#include <cmath>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <GL/gl.h>
#include <GL/glu.h>
#include "SFMLTools/FreeFlyCamera.hpp"
#include "Geometry/Mesh.hpp"
#include "Spline/Skeleton3D.hpp"
// Full hd : 1920x1080
constexpr auto WIDTH = 1920;
constexpr auto HEIGHT = 1080;
void drawScene(sft::FreeFlyCamera const& camera, geo::Mesh const& mesh, std::vector<geo::Circle<float>> const& circles, geo::Vector<float,4> const& plane);
void drawCircle(geo::Circle<float> const& circle);
int main(int argc, char *argv[])
{
// Init mesh
// pae::Skeleton3D<pae::Vector3<float>, float> skeleton;
// skeleton.loadFromFile("skel.skl");
geo::Mesh mesh;
#include "Circles1.cxx"
std::vector<std::vector<geo::Circle<float>>> splines_circles;
std::vector<geo::Circle<float>> circles;
circles.push_back(c1);
circles.push_back(c2);
circles.push_back(c3);
for (auto const& c : circles)
{
for (auto const& pt : c.points)
{
mesh.vertices.push_back(pt.second);
}
}
// skeleton.meshExtremities(mesh, splines_circles, profondeur);
auto plane = pae::meshJunction<float>(mesh,geo::Vector3<float>{0.0f,0.0f,0.0f}, 2, circles);
std::cout << plane << std::endl;
// Création de la fenêtre
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT),
"pae",
sf::Style::Fullscreen,
sf::ContextSettings(32));
window.setVerticalSyncEnabled(true);
window.setMouseCursorVisible(false);
//Initialisation du mode 3D
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70,(double)WIDTH/HEIGHT,0.2,1000);
// Initialisation de Z-Buffer
glEnable(GL_DEPTH_TEST);
// Activer les textures
glEnable(GL_TEXTURE_2D);
// Autoriser la transparence
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Ces 2 lignes améliorent le rendu
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
// On efface le tampon d'affichage
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFlush();
mesh.prepareEdges();
// Camera
auto camera = sft::FreeFlyCamera{};
// la boucle principale
auto running = true;
auto captureRequired = false;
while (running)
{
// gestion des évènements
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
// on stoppe le programme
running = false;
}
else if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Escape)
{
running = false;
}
else if (event.key.code == sf::Keyboard::P)
{
captureRequired = true;
}
}
else if (event.type == sf::Event::MouseMoved)
{
// Hum...
}
else if (event.type == sf::Event::Resized)
{
// on ajuste le viewport lorsque la fenêtre est redimensionnée
glViewport(0, 0, event.size.width, event.size.height);
}
}
// Les trucs qui sont pas des évènements
camera.nextStep(WIDTH, HEIGHT);
sf::Mouse::setPosition(sf::Vector2i{WIDTH/2, HEIGHT/2});
// Dessin de la scene
drawScene(camera, mesh, circles, plane);
if (captureRequired)
{
window.capture().saveToFile("capture.jpg");
captureRequired = false;
}
// termine la trame courante (en interne, échange les deux tampons de rendu)
window.display();
}
// libération des ressources...
return 0;
}
void drawScene(sft::FreeFlyCamera const& camera, geo::Mesh const& mesh, std::vector<geo::Circle<float>> const& circles, geo::Vector<float,4> const& plane)
{
// Initialisation
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Position Camera gluLookAt(positionCamera, positionCible, vecteurVertical)
camera.look();
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3f(0,1,0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3f(0,0,1);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
// Dessin de carrés
mesh.drawEdges();
// Dessin des cercles
glColor3f(1,0,0);
drawCircle(circles[0]);
glColor3f(0,1,0);
drawCircle(circles[1]);
glColor3f(0,0,1);
drawCircle(circles[2]);
// Dessin du plan
auto p1 = geo::Vector<float,3>{-plane.y(), plane.x(), -plane.t() / plane.z()};
auto v1 = geo::Vector<float,3>{-plane.z(), 0.0f, plane.x()};
auto v2 = geo::crossProduct(geo::Vector3<float>{plane.x(), plane.y(), plane.z()}, v1);
v1 /= v1.norm();
v2 /= v2.norm();
auto pt1 = p1 - 5*v1;
auto pt2 = p1 + 5*v2;
auto pt3 = p1 + 5*v1;
auto pt4 = p1 - 5*v2;
glColor4f(1.0,1.0,1.0,0.5);
glBegin(GL_QUADS);
glVertex3fv(&pt1.data[0]);
glVertex3fv(&pt2.data[0]);
glVertex3fv(&pt3.data[0]);
glVertex3fv(&pt4.data[0]);
glEnd();
// MAJ de l'écran
glFlush();
}
void drawCircle(geo::Circle<float> const& circle)
{
glBegin(GL_LINE_LOOP);
for (auto const& pt : circle.points)
glVertex3fv(&pt.second.data[0]);
glEnd();
}

View File

@ -1,77 +0,0 @@
#ifndef VECTOR_HPP
#define VECTOR_HPP
#include <cmath>
#include <array>
#include <istream>
namespace pae
{
template<typename T, std::size_t N>
class Vector
{
public:
Vector();
template<typename... Types>
Vector(Types... l);
Vector(Vector const& v);
T norm2() const;
T norm() const;
Vector<T,N>& operator=(T t);
Vector<T,N>& operator=(Vector<T,N> t);
Vector<T,N> operator-();
Vector<T,N>& operator+=(Vector<T,N> const& v);
Vector<T,N>& operator-=(Vector<T,N> const& v);
Vector<T,N>& operator*=(float f);
Vector<T,N>& operator/=(float f);
T& x() {static_assert(N > 0, "x() doesn't exist on Vector<T,0>"); return data[0]; };
T& y() {static_assert(N > 1, "y() doesn't exist on Vector<T,1>"); return data[1]; };
T& z() {static_assert(N > 2, "z() doesn't exist on Vector<T,2>"); return data[2]; };
T const& x() const {static_assert(N > 0, "x() doesn't exist on Vector<T,0>"); return data[0]; };
T const& y() const {static_assert(N > 1, "y() doesn't exist on Vector<T,1>"); return data[1]; };
T const& z() const {static_assert(N > 2, "z() doesn't exist on Vector<T,2>"); return data[2]; };
std::array<T,N> data;
};
template<typename T, std::size_t N>
bool operator==(Vector<T,N> const& l, Vector<T,N> const& r);
template<typename T, std::size_t N>
bool operator!=(Vector<T,N> const& l, Vector<T,N> const& r);
template<typename T, std::size_t N>
Vector<T,N> operator+(Vector<T,N> l, Vector<T,N> const& r);
template<typename T, std::size_t N>
Vector<T,N> operator-(Vector<T,N> l, Vector<T,N> const& r);
template<typename T, std::size_t N>
Vector<T,N> operator*(Vector<T,N> l, float f);
template<typename T, std::size_t N>
Vector<T,N> operator/(Vector<T,N> l, float f);
template<typename T, std::size_t N>
std::istream& operator>>(std::istream& stream, Vector<T,N>& v);
template<typename T, std::size_t N>
std::ostream& operator<<(std::ostream& stream, Vector<T,N> const& v);
template<typename T>
using Vector3 = Vector<T,3>;
} // namespace pae
#include "Vector.inl"
#endif // VECTOR_HPP

55
Code/src/Spline/gen.py Executable file
View File

@ -0,0 +1,55 @@
#!/usr/bin/python
import math as Math
counter = 0
def print_list(center , points, name="c"):
global counter
print("auto " + name +" = pae::Circle<float>{};")
print(name + ".center = pae::Vector3<float>{" + \
"{:0.4f}".format(center[0]) + "f, " + \
"{:0.4f}".format(center[1]) + "f, " + \
"{:0.4f}".format(center[2]) +"f};")
for v in points:
print(name + ".points.push_back(std::make_pair(" + str(counter) +", pae::Vector3<float>{" + \
"{:0.4f}".format(v[0]) + "f, " + \
"{:0.4f}".format(v[1]) + "f, " + \
"{:0.4f}".format(v[2]) + "f}));")
counter += 1
def sum_elements(l1,l2):
return [x+y for x,y in zip(l1,l2)]
def multiply_elements(l1,f):
return [x*f for x in l1]
def gen_circle(center, first_vector, second_vector, maximum = 10):
l = []
for cpt in range(0,maximum):
glut draw shpere theta = 2 * Math.pi * cpt/maximum
first = multiply_elements(first_vector, Math.cos(theta))
second = multiply_elements(second_vector, Math.sin(theta))
l.append(sum_elements(sum_elements(first, second), center))
return l
center1 = multiply_elements([1,0,0],2)
center2 = multiply_elements([0,1,0],2)
center3 = multiply_elements([-1,0,0],2)
center4 = multiply_elements([0,-1,0],2)
c1 = gen_circle(center1, [0,0,1], [0,1,0])
c2 = gen_circle(center2, [0,0,1], [1,0,0])
c3 = gen_circle(center3, [0,0,1], [0,-1,0])
c4 = gen_circle(center4, [0,0,1], [-1,0,0])
print_list(center1, c1, "c1")
print()
print_list(center2, c2, "c2")
print()
print_list(center3, c3, "c3")
print()
print_list(center4, c4, "c4")

View File

@ -1,32 +1,34 @@
#include <iostream>
#include <string>
#include "Vector.hpp"
#include "Skeleton3D.hpp"
#include "Spline.hpp"
#include "Mesh.hpp"
#include "Geometry/Vector.hpp"
#include "Geometry/Spline.hpp"
#include "Geometry/Mesh.hpp"
#include "Geometry/Point.hpp"
#include "Spline/Skeleton3D.hpp"
int main(int argc, char *argv[])
{
using namespace pae;
using namespace pae::detail;
Circle<float> c;
c.points.push_back(std::make_pair(7,pae::Vector3<float>{0.0f,2.0f,-1.0f}));
c.points.push_back(std::make_pair(8,pae::Vector3<float>{0.0f,1.0f,-1.0f}));
c.points.push_back(std::make_pair(9,pae::Vector3<float>{0.0f,0.0f,-1.0f}));
geo::Circle<float> c;
c.points.push_back(std::make_pair(7,geo::Vector3<float>{0.0f,2.0f,-1.0f}));
c.points.push_back(std::make_pair(8,geo::Vector3<float>{0.0f,1.0f,-1.0f}));
c.points.push_back(std::make_pair(9,geo::Vector3<float>{0.0f,0.0f,-1.0f}));
c.points.push_back(std::make_pair(0,pae::Vector3<float>{0.0f,0.0f, 1.0f}));
c.points.push_back(std::make_pair(1,pae::Vector3<float>{0.0f,1.0f, 1.0f}));
c.points.push_back(std::make_pair(2,pae::Vector3<float>{0.0f,2.0f, 1.0f}));
c.points.push_back(std::make_pair(3,pae::Vector3<float>{0.0f,3.0f, 1.0f}));
c.points.push_back(std::make_pair(4,pae::Vector3<float>{0.0f,4.0f, 1.0f}));
c.points.push_back(std::make_pair(5,pae::Vector3<float>{0.0f,4.0f,-1.0f}));
c.points.push_back(std::make_pair(6,pae::Vector3<float>{0.0f,3.0f,-1.0f}));
c.points.push_back(std::make_pair(0,geo::Vector3<float>{0.0f,0.0f, 1.0f}));
c.points.push_back(std::make_pair(1,geo::Vector3<float>{0.0f,1.0f, 1.0f}));
c.points.push_back(std::make_pair(2,geo::Vector3<float>{0.0f,2.0f, 1.0f}));
c.points.push_back(std::make_pair(3,geo::Vector3<float>{0.0f,3.0f, 1.0f}));
c.points.push_back(std::make_pair(4,geo::Vector3<float>{0.0f,4.0f, 1.0f}));
c.points.push_back(std::make_pair(5,geo::Vector3<float>{0.0f,4.0f,-1.0f}));
c.points.push_back(std::make_pair(6,geo::Vector3<float>{0.0f,3.0f,-1.0f}));
auto v = sortedPoints(std::array<double,4>{0,0,1,0},
std::vector<Circle<float>>{c},
std::vector<std::pair<Point<float>, Point<float>>>{});
std::vector<geo::Circle<float>>{c},
std::vector<std::pair<geo::Point<float>, geo::Point<float>>>{});
for (auto& element : v)
{