Merge remote-tracking branch 'origin/master' into lm_wiping_dialog_colors
|
@ -18,8 +18,8 @@ AllowShortLoopsOnASingleLine: true
|
|||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: true
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
|
@ -37,18 +37,18 @@ BraceWrapping:
|
|||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 75
|
||||
ColumnLimit: 78
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
CompactNamespaces: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
|
|
1
.github/ISSUE_TEMPLATE.md
vendored
|
@ -24,3 +24,4 @@ _Is this a new feature request?_
|
|||
|
||||
#### Project File (.3MF) where problem occurs
|
||||
_Upload a PrusaSlicer Project File (.3MF) (`Plater -> Export plate as 3MF` for Slic3r PE 1.41.2 and older, `File -> Save` / `Save Project` for PrusaSlicer, Slic3r PE 1.42.0-alpha and newer)_
|
||||
_Images (PNG, GIF, JPEG), PDFs or text files could be drag & dropped to the issue directly, while all other files need to be zipped first (.zip, .gz)_
|
||||
|
|
2
Build.PL
|
@ -16,6 +16,8 @@ my %prereqs = qw(
|
|||
ExtUtils::MakeMaker 6.80
|
||||
ExtUtils::ParseXS 3.22
|
||||
ExtUtils::XSpp 0
|
||||
ExtUtils::XSpp::Cmd 0
|
||||
ExtUtils::CppGuess 0
|
||||
ExtUtils::Typemaps 0
|
||||
ExtUtils::Typemaps::Basic 0
|
||||
File::Basename 0
|
||||
|
|
112
CMakeLists.txt
|
@ -32,7 +32,6 @@ option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
|
|||
option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1)
|
||||
option(SLIC3R_PERL_XS "Compile XS Perl module and enable Perl unit and integration tests" 0)
|
||||
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
|
||||
option(SLIC3R_SYNTAXONLY "Only perform source code correctness checking, no binary output (UNIX only)" 0)
|
||||
|
||||
set(SLIC3R_GTK "2" CACHE STRING "GTK version to use with wxWidgets on Linux")
|
||||
|
||||
|
@ -53,14 +52,30 @@ if (SLIC3R_GUI)
|
|||
add_definitions(-DSLIC3R_GUI)
|
||||
endif ()
|
||||
|
||||
if (MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
set(IS_CLANG_CL TRUE)
|
||||
|
||||
# clang-cl can interpret SYSTEM header paths if -imsvc is used
|
||||
set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-imsvc")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall \
|
||||
-Wno-old-style-cast -Wno-reserved-id-macro -Wno-c++98-compat-pedantic")
|
||||
else ()
|
||||
set(IS_CLANG_CL FALSE)
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
if (SLIC3R_MSVC_COMPILE_PARALLEL)
|
||||
if (SLIC3R_MSVC_COMPILE_PARALLEL AND NOT IS_CLANG_CL)
|
||||
add_compile_options(/MP)
|
||||
endif ()
|
||||
# /bigobj (Increase Number of Sections in .Obj file)
|
||||
# error C3859: virtual memory range for PCH exceeded; please recompile with a command line option of '-Zm90' or greater
|
||||
# Generate symbols at every build target, even for the release.
|
||||
add_compile_options(-bigobj -Zm316 /Zi)
|
||||
add_compile_options(-bigobj -Zm520 /Zi)
|
||||
endif ()
|
||||
|
||||
if (MINGW)
|
||||
add_compile_options(-Wa,-mbig-obj)
|
||||
endif ()
|
||||
|
||||
# Display and check CMAKE_PREFIX_PATH
|
||||
|
@ -89,8 +104,6 @@ enable_testing ()
|
|||
# Enable C++11 language standard.
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
if(NOT WIN32)
|
||||
# Add DEBUG flags to debug builds.
|
||||
|
@ -149,30 +162,29 @@ endif()
|
|||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX)
|
||||
# Adding -fext-numeric-literals to enable GCC extensions on definitions of quad float literals, which are required by Boost.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals" )
|
||||
|
||||
if (SLIC3R_SYNTAXONLY)
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "true")
|
||||
set(CMAKE_C_ARCHIVE_CREATE "true")
|
||||
set(CMAKE_CXX_ARCHIVE_APPEND "true")
|
||||
set(CMAKE_C_ARCHIVE_APPEND "true")
|
||||
set(CMAKE_RANLIB "true")
|
||||
set(CMAKE_C_LINK_EXECUTABLE "true")
|
||||
set(CMAKE_CXX_LINK_EXECUTABLE "true")
|
||||
|
||||
set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> -fsyntax-only <DEFINES> <INCLUDES> <FLAGS> -c <SOURCE> && touch <OBJECT>")
|
||||
set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> -fsyntax-only <DEFINES> <INCLUDES> <FLAGS> -c <SOURCE> && touch <OBJECT>")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
add_compile_options(-Wall)
|
||||
if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
|
||||
if (NOT MINGW)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
|
||||
endif ()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder" )
|
||||
|
||||
# On GCC and Clang, no return from a non-void function is a warning only. Here, we make it an error.
|
||||
add_compile_options(-Werror=return-type)
|
||||
|
||||
#removes LOTS of extraneous Eigen warnings
|
||||
add_compile_options(-Wno-ignored-attributes)
|
||||
#removes LOTS of extraneous Eigen warnings (GCC only supports it since 6.1)
|
||||
#if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.1)
|
||||
# add_compile_options(-Wno-ignored-attributes) # Tamas: Eigen include dirs are marked as SYSTEM
|
||||
#endif()
|
||||
|
||||
#GCC generates loads of -Wunknown-pragmas when compiling igl. The fix is not easy due to a bug in gcc, see
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66943 or
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431
|
||||
# We will turn the warning of for GCC for now:
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
add_compile_options(-Wno-unknown-pragmas)
|
||||
endif()
|
||||
|
||||
if (SLIC3R_ASAN)
|
||||
add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
|
||||
|
@ -201,9 +213,12 @@ include_directories(${LIBDIR_BIN}/platform)
|
|||
include_directories(${LIBDIR}/clipper ${LIBDIR}/polypartition)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
|
||||
if(MSVC)
|
||||
# BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking.
|
||||
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x601 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x601 )
|
||||
endif(MSVC)
|
||||
endif(WIN32)
|
||||
|
||||
add_definitions(-DwxUSE_UNICODE -D_UNICODE -DUNICODE -DWXINTL_NO_GETTEXT_MACRO)
|
||||
|
||||
|
@ -234,21 +249,40 @@ if(SLIC3R_STATIC)
|
|||
# set(Boost_USE_STATIC_RUNTIME ON)
|
||||
endif()
|
||||
#set(Boost_DEBUG ON)
|
||||
# set(Boost_COMPILER "-vc120")
|
||||
# set(Boost_COMPILER "-mgw81")
|
||||
if(NOT WIN32)
|
||||
# boost::process was introduced first in version 1.64.0
|
||||
set(MINIMUM_BOOST_VERSION "1.64.0")
|
||||
endif()
|
||||
find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS system filesystem thread log locale regex)
|
||||
if(Boost_FOUND)
|
||||
# include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
||||
if (APPLE)
|
||||
|
||||
add_library(boost_libs INTERFACE)
|
||||
add_library(boost_headeronly INTERFACE)
|
||||
|
||||
if (APPLE)
|
||||
# BOOST_ASIO_DISABLE_KQUEUE : prevents a Boost ASIO bug on OS X: https://svn.boost.org/trac/boost/ticket/5339
|
||||
add_definitions(-DBOOST_ASIO_DISABLE_KQUEUE)
|
||||
endif()
|
||||
if(NOT SLIC3R_STATIC)
|
||||
add_definitions(-DBOOST_LOG_DYN_LINK)
|
||||
endif()
|
||||
target_compile_definitions(boost_headeronly INTERFACE BOOST_ASIO_DISABLE_KQUEUE)
|
||||
endif()
|
||||
|
||||
if(NOT SLIC3R_STATIC)
|
||||
target_compile_definitions(boost_headeronly INTERFACE BOOST_LOG_DYN_LINK)
|
||||
endif()
|
||||
|
||||
if(TARGET Boost::system)
|
||||
message(STATUS "Boost::boost exists")
|
||||
target_link_libraries(boost_headeronly INTERFACE Boost::boost)
|
||||
target_link_libraries(boost_libs INTERFACE
|
||||
boost_headeronly # includes the custom compile definitions as well
|
||||
Boost::system
|
||||
Boost::filesystem
|
||||
Boost::thread
|
||||
Boost::log
|
||||
Boost::locale
|
||||
Boost::regex
|
||||
)
|
||||
else()
|
||||
target_include_directories(boost_headeronly INTERFACE ${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(boost_libs INTERFACE boost_headeronly ${Boost_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# Find and configure intel-tbb
|
||||
|
@ -289,13 +323,13 @@ endif()
|
|||
|
||||
# Find eigen3 or use bundled version
|
||||
if (NOT SLIC3R_STATIC)
|
||||
find_package(Eigen3 3)
|
||||
find_package(Eigen3 3.3)
|
||||
endif ()
|
||||
if (NOT Eigen3_FOUND)
|
||||
set(Eigen3_FOUND 1)
|
||||
if (NOT EIGEN3_FOUND)
|
||||
set(EIGEN3_FOUND 1)
|
||||
set(EIGEN3_INCLUDE_DIR ${LIBDIR}/eigen/)
|
||||
endif ()
|
||||
include_directories(${EIGEN3_INCLUDE_DIR})
|
||||
include_directories(BEFORE SYSTEM ${EIGEN3_INCLUDE_DIR})
|
||||
|
||||
# Find expat or use bundled version
|
||||
# Always use the system libexpat on Linux.
|
||||
|
@ -327,6 +361,10 @@ if (NOT GLEW_FOUND)
|
|||
endif ()
|
||||
include_directories(${GLEW_INCLUDE_DIRS})
|
||||
|
||||
# Find the Cereal serialization library
|
||||
add_library(cereal INTERFACE)
|
||||
target_include_directories(cereal INTERFACE include)
|
||||
|
||||
# l10n
|
||||
set(L10N_DIR "${SLIC3R_RESOURCES_DIR}/localization")
|
||||
add_custom_target(pot
|
||||
|
|
|
@ -105,6 +105,9 @@ function(add_precompiled_header _target _input)
|
|||
cmake_parse_arguments(_PCH "FORCEINCLUDE" "SOURCE_CXX;SOURCE_C" "" ${ARGN})
|
||||
|
||||
get_filename_component(_input_we ${_input} NAME_WE)
|
||||
get_filename_component(_input_full ${_input} ABSOLUTE)
|
||||
file(TO_NATIVE_PATH "${_input_full}" _input_fullpath)
|
||||
|
||||
if(NOT _PCH_SOURCE_CXX)
|
||||
set(_PCH_SOURCE_CXX "${_input_we}.cpp")
|
||||
endif()
|
||||
|
@ -138,16 +141,16 @@ function(add_precompiled_header _target _input)
|
|||
set_source_files_properties("${_source}" PROPERTIES OBJECT_OUTPUTS "${_pch_c_pch}")
|
||||
else()
|
||||
if(_source MATCHES \\.\(cpp|cxx|cc\)$)
|
||||
set(_pch_compile_flags "${_pch_compile_flags} \"/Fp${_pch_cxx_pch}\" \"/Yu${_input}\"")
|
||||
set(_pch_compile_flags "${_pch_compile_flags} \"/Fp${_pch_cxx_pch}\" \"/Yu${_input_fullpath}\"")
|
||||
set(_pch_source_cxx_needed TRUE)
|
||||
set_source_files_properties("${_source}" PROPERTIES OBJECT_DEPENDS "${_pch_cxx_pch}")
|
||||
else()
|
||||
set(_pch_compile_flags "${_pch_compile_flags} \"/Fp${_pch_c_pch}\" \"/Yu${_input}\"")
|
||||
set(_pch_compile_flags "${_pch_compile_flags} \"/Fp${_pch_c_pch}\" \"/Yu${_input_fullpath}\"")
|
||||
set(_pch_source_c_needed TRUE)
|
||||
set_source_files_properties("${_source}" PROPERTIES OBJECT_DEPENDS "${_pch_c_pch}")
|
||||
endif()
|
||||
if(_PCH_FORCEINCLUDE)
|
||||
set(_pch_compile_flags "${_pch_compile_flags} /FI${_input}")
|
||||
set(_pch_compile_flags "${_pch_compile_flags} /FI${_input_fullpath}")
|
||||
endif(_PCH_FORCEINCLUDE)
|
||||
endif()
|
||||
|
||||
|
|
16
deps/CMakeLists.txt
vendored
|
@ -36,6 +36,12 @@ set(DESTDIR "${CMAKE_CURRENT_BINARY_DIR}/destdir" CACHE PATH "Destination direct
|
|||
option(DEP_DEBUG "Build debug variants (only applicable on Windows)" ON)
|
||||
option(DEP_WX_STABLE "Build against wxWidgets stable 3.0 as opposed to default 3.1 (Linux only)" OFF)
|
||||
|
||||
# On developer machines, it can be enabled to speed up compilation and suppress warnings coming from IGL.
|
||||
# FIXME:
|
||||
# Enabling this option is not safe. IGL will compile itself with its own version of Eigen while
|
||||
# Slic3r compiles with a different version which will cause runtime errors.
|
||||
# option(DEP_BUILD_IGL_STATIC "Build IGL as a static library. Might cause link errors and increase binary size." OFF)
|
||||
|
||||
message(STATUS "PrusaSlicer deps DESTDIR: ${DESTDIR}")
|
||||
message(STATUS "PrusaSlicer deps debug build: ${DEP_DEBUG}")
|
||||
|
||||
|
@ -70,7 +76,10 @@ elseif (APPLE)
|
|||
endif ()
|
||||
|
||||
include("deps-macos.cmake")
|
||||
else ()
|
||||
elseif (MINGW)
|
||||
message(STATUS "Building for MinGW...")
|
||||
include("deps-mingw.cmake")
|
||||
else()
|
||||
include("deps-linux.cmake")
|
||||
endif()
|
||||
|
||||
|
@ -83,7 +92,9 @@ if (MSVC)
|
|||
dep_libcurl
|
||||
dep_wxwidgets
|
||||
dep_gtest
|
||||
dep_cereal
|
||||
dep_nlopt
|
||||
# dep_qhull # Experimental
|
||||
dep_zlib # on Windows we still need zlib
|
||||
)
|
||||
|
||||
|
@ -96,7 +107,10 @@ else()
|
|||
dep_libcurl
|
||||
dep_wxwidgets
|
||||
dep_gtest
|
||||
dep_cereal
|
||||
dep_nlopt
|
||||
dep_qhull
|
||||
# dep_libigl # Not working, static build has different Eigen
|
||||
)
|
||||
|
||||
endif()
|
||||
|
|
2
deps/deps-macos.cmake
vendored
|
@ -111,6 +111,6 @@ ExternalProject_Add(dep_wxwidgets
|
|||
--with-expat=builtin
|
||||
--disable-debug
|
||||
--disable-debug_flag
|
||||
BUILD_COMMAND make "-j${NPROC}" && make -C locale allmo
|
||||
BUILD_COMMAND make "-j${NPROC}" && PATH=/usr/local/opt/gettext/bin/:$ENV{PATH} make -C locale allmo
|
||||
INSTALL_COMMAND make install
|
||||
)
|
||||
|
|
76
deps/deps-mingw.cmake
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
set(DEP_CMAKE_OPTS "-DCMAKE_POSITION_INDEPENDENT_CODE=ON")
|
||||
set(DEP_BOOST_TOOLSET "gcc")
|
||||
set(DEP_BITS 64)
|
||||
|
||||
find_package(Git REQUIRED)
|
||||
|
||||
# TODO make sure to build tbb with -flifetime-dse=1
|
||||
include("deps-unix-common.cmake")
|
||||
|
||||
ExternalProject_Add(dep_boost
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz"
|
||||
URL_HASH SHA256=882b48708d211a5f48e60b0124cf5863c1534cd544ecd0664bb534a4b5d506e9
|
||||
BUILD_IN_SOURCE 1
|
||||
CONFIGURE_COMMAND bootstrap.bat
|
||||
BUILD_COMMAND b2.exe
|
||||
-j "${NPROC}"
|
||||
--with-system
|
||||
--with-filesystem
|
||||
--with-thread
|
||||
--with-log
|
||||
--with-locale
|
||||
--with-regex
|
||||
"--prefix=${DESTDIR}/usr/local"
|
||||
"address-model=${DEPS_BITS}"
|
||||
"toolset=${DEP_BOOST_TOOLSET}"
|
||||
link=static
|
||||
define=BOOST_USE_WINAPI_VERSION=0x0502
|
||||
variant=release
|
||||
threading=multi
|
||||
boost.locale.icu=off
|
||||
"${DEP_BOOST_DEBUG}" release install
|
||||
INSTALL_COMMAND "" # b2 does that already
|
||||
)
|
||||
|
||||
ExternalProject_Add(dep_libcurl
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://curl.haxx.se/download/curl-7.58.0.tar.gz"
|
||||
URL_HASH SHA256=cc245bf9a1a42a45df491501d97d5593392a03f7b4f07b952793518d97666115
|
||||
CMAKE_ARGS
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DBUILD_TESTING=OFF
|
||||
-DCURL_STATICLIB=ON
|
||||
-DCURL_STATIC_CRT=ON
|
||||
-DENABLE_THREADED_RESOLVER=ON
|
||||
-DCURL_DISABLE_FTP=ON
|
||||
-DCURL_DISABLE_LDAP=ON
|
||||
-DCURL_DISABLE_LDAPS=ON
|
||||
-DCURL_DISABLE_TELNET=ON
|
||||
-DCURL_DISABLE_DICT=ON
|
||||
-DCURL_DISABLE_FILE=ON
|
||||
-DCURL_DISABLE_TFTP=ON
|
||||
-DCURL_DISABLE_RTSP=ON
|
||||
-DCURL_DISABLE_POP3=ON
|
||||
-DCURL_DISABLE_IMAP=ON
|
||||
-DCURL_DISABLE_SMTP=ON
|
||||
-DCURL_DISABLE_GOPHER=ON
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
${DEP_CMAKE_OPTS}
|
||||
)
|
||||
|
||||
ExternalProject_Add(dep_wxwidgets
|
||||
EXCLUDE_FROM_ALL 1
|
||||
GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
|
||||
GIT_TAG v3.1.1-patched
|
||||
# URL "https://github.com/wxWidgets/wxWidgets/releases/download/v3.1.1/wxWidgets-3.1.1.tar.bz2"
|
||||
# URL_HASH SHA256=c925dfe17e8f8b09eb7ea9bfdcfcc13696a3e14e92750effd839f5e10726159e
|
||||
# PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}\\wxwidgets-pngprefix.h" src\\png\\pngprefix.h
|
||||
CMAKE_ARGS
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DwxUSE_LIBPNG=builtin
|
||||
-DwxUSE_ZLIB=builtin
|
||||
-DwxUSE_OPENGL=ON
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
${DEP_CMAKE_OPTS}
|
||||
)
|
58
deps/deps-unix-common.cmake
vendored
|
@ -1,6 +1,12 @@
|
|||
|
||||
# The unix common part expects DEP_CMAKE_OPTS to be set
|
||||
|
||||
if (MINGW)
|
||||
set(TBB_MINGW_WORKAROUND "-flifetime-dse=1")
|
||||
else ()
|
||||
set(TBB_MINGW_WORKAROUND "")
|
||||
endif ()
|
||||
|
||||
ExternalProject_Add(dep_tbb
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz"
|
||||
|
@ -8,6 +14,7 @@ ExternalProject_Add(dep_tbb
|
|||
CMAKE_ARGS
|
||||
-DTBB_BUILD_SHARED=OFF
|
||||
-DTBB_BUILD_TESTS=OFF
|
||||
-DCMAKE_CXX_FLAGS=${TBB_MINGW_WORKAROUND}
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
${DEP_CMAKE_OPTS}
|
||||
)
|
||||
|
@ -19,6 +26,16 @@ ExternalProject_Add(dep_gtest
|
|||
CMAKE_ARGS -DBUILD_GMOCK=OFF ${DEP_CMAKE_OPTS} -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
)
|
||||
|
||||
ExternalProject_Add(dep_cereal
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/USCiLab/cereal/archive/v1.2.2.tar.gz"
|
||||
# URL_HASH SHA256=c6dd7a5701fff8ad5ebb45a3dc8e757e61d52658de3918e38bab233e7fd3b4ae
|
||||
CMAKE_ARGS
|
||||
-DJUST_INSTALL_CEREAL=on
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
${DEP_CMAKE_OPTS}
|
||||
)
|
||||
|
||||
ExternalProject_Add(dep_nlopt
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/stevengj/nlopt/archive/v2.5.0.tar.gz"
|
||||
|
@ -32,3 +49,44 @@ ExternalProject_Add(dep_nlopt
|
|||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
${DEP_CMAKE_OPTS}
|
||||
)
|
||||
find_package(Git REQUIRED)
|
||||
|
||||
ExternalProject_Add(dep_qhull
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/qhull/qhull/archive/v7.2.1.tar.gz"
|
||||
URL_HASH SHA256=6fc251e0b75467e00943bfb7191e986fce0e1f8f6f0251f9c6ce5a843821ea78
|
||||
CMAKE_ARGS
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
${DEP_CMAKE_OPTS}
|
||||
PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/qhull-mods.patch
|
||||
)
|
||||
|
||||
ExternalProject_Add(dep_libigl
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/libigl/libigl/archive/v2.0.0.tar.gz"
|
||||
URL_HASH SHA256=42518e6b106c7209c73435fd260ed5d34edeb254852495b4c95dce2d95401328
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
-DLIBIGL_BUILD_PYTHON=OFF
|
||||
-DLIBIGL_BUILD_TESTS=OFF
|
||||
-DLIBIGL_BUILD_TUTORIALS=OFF
|
||||
-DLIBIGL_USE_STATIC_LIBRARY=OFF #${DEP_BUILD_IGL_STATIC}
|
||||
-DLIBIGL_WITHOUT_COPYLEFT=OFF
|
||||
-DLIBIGL_WITH_CGAL=OFF
|
||||
-DLIBIGL_WITH_COMISO=OFF
|
||||
-DLIBIGL_WITH_CORK=OFF
|
||||
-DLIBIGL_WITH_EMBREE=OFF
|
||||
-DLIBIGL_WITH_MATLAB=OFF
|
||||
-DLIBIGL_WITH_MOSEK=OFF
|
||||
-DLIBIGL_WITH_OPENGL=OFF
|
||||
-DLIBIGL_WITH_OPENGL_GLFW=OFF
|
||||
-DLIBIGL_WITH_OPENGL_GLFW_IMGUI=OFF
|
||||
-DLIBIGL_WITH_PNG=OFF
|
||||
-DLIBIGL_WITH_PYTHON=OFF
|
||||
-DLIBIGL_WITH_TETGEN=OFF
|
||||
-DLIBIGL_WITH_TRIANGLE=OFF
|
||||
-DLIBIGL_WITH_XML=OFF
|
||||
PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-fixes.patch
|
||||
)
|
||||
|
||||
|
|
115
deps/deps-windows.cmake
vendored
|
@ -1,21 +1,38 @@
|
|||
|
||||
# https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html
|
||||
if (MSVC_VERSION EQUAL 1800)
|
||||
# 1800 = VS 12.0 (v120 toolset)
|
||||
set(DEP_VS_VER "12")
|
||||
set(DEP_BOOST_TOOLSET "msvc-12.0")
|
||||
elseif (MSVC_VERSION EQUAL 1900)
|
||||
# 1900 = VS 14.0 (v140 toolset)
|
||||
set(DEP_VS_VER "14")
|
||||
set(DEP_BOOST_TOOLSET "msvc-14.0")
|
||||
elseif (MSVC_VERSION GREATER 1900)
|
||||
elseif (MSVC_VERSION LESS 1920)
|
||||
# 1910-1919 = VS 15.0 (v141 toolset)
|
||||
set(DEP_VS_VER "15")
|
||||
set(DEP_BOOST_TOOLSET "msvc-14.1")
|
||||
elseif (MSVC_VERSION LESS 1930)
|
||||
# 1920-1929 = VS 16.0 (v142 toolset)
|
||||
set(DEP_VS_VER "16")
|
||||
set(DEP_BOOST_TOOLSET "msvc-14.2")
|
||||
else ()
|
||||
message(FATAL_ERROR "Unsupported MSVC version")
|
||||
endif ()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
set(DEP_BOOST_TOOLSET "clang-win")
|
||||
endif ()
|
||||
|
||||
if (${DEPS_BITS} EQUAL 32)
|
||||
set(DEP_MSVC_GEN "Visual Studio ${DEP_VS_VER}")
|
||||
set(DEP_PLATFORM "Win32")
|
||||
else ()
|
||||
if (DEP_VS_VER LESS 16)
|
||||
set(DEP_MSVC_GEN "Visual Studio ${DEP_VS_VER} Win64")
|
||||
else ()
|
||||
set(DEP_MSVC_GEN "Visual Studio ${DEP_VS_VER}")
|
||||
endif ()
|
||||
set(DEP_PLATFORM "x64")
|
||||
endif ()
|
||||
|
||||
|
||||
|
@ -28,8 +45,8 @@ endif ()
|
|||
|
||||
ExternalProject_Add(dep_boost
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz"
|
||||
URL_HASH SHA256=bd0df411efd9a585e5a2212275f8762079fed8842264954675a4fddc46cfcf60
|
||||
URL "https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz"
|
||||
URL_HASH SHA256=882b48708d211a5f48e60b0124cf5863c1534cd544ecd0664bb534a4b5d506e9
|
||||
BUILD_IN_SOURCE 1
|
||||
CONFIGURE_COMMAND bootstrap.bat
|
||||
BUILD_COMMAND b2.exe
|
||||
|
@ -57,6 +74,7 @@ ExternalProject_Add(dep_tbb
|
|||
URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz"
|
||||
URL_HASH SHA256=0545cb6033bd1873fcae3ea304def720a380a88292726943ae3b9b207f322efe
|
||||
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_DEBUG_POSTFIX=_debug
|
||||
-DTBB_BUILD_SHARED=OFF
|
||||
|
@ -81,6 +99,7 @@ ExternalProject_Add(dep_gtest
|
|||
URL "https://github.com/google/googletest/archive/release-1.8.1.tar.gz"
|
||||
URL_HASH SHA256=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c
|
||||
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
|
||||
CMAKE_ARGS
|
||||
-DBUILD_GMOCK=OFF
|
||||
-Dgtest_force_shared_crt=ON
|
||||
|
@ -100,11 +119,26 @@ if (${DEP_DEBUG})
|
|||
endif ()
|
||||
|
||||
|
||||
ExternalProject_Add(dep_cereal
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/USCiLab/cereal/archive/v1.2.2.tar.gz"
|
||||
# URL_HASH SHA256=c6dd7a5701fff8ad5ebb45a3dc8e757e61d52658de3918e38bab233e7fd3b4ae
|
||||
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
|
||||
CMAKE_ARGS
|
||||
-DJUST_INSTALL_CEREAL=on
|
||||
"-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
|
||||
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
|
||||
|
||||
ExternalProject_Add(dep_nlopt
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/stevengj/nlopt/archive/v2.5.0.tar.gz"
|
||||
URL_HASH SHA256=c6dd7a5701fff8ad5ebb45a3dc8e757e61d52658de3918e38bab233e7fd3b4ae
|
||||
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
|
||||
CMAKE_ARGS
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DNLOPT_PYTHON=OFF
|
||||
|
@ -133,6 +167,7 @@ ExternalProject_Add(dep_zlib
|
|||
URL "https://zlib.net/zlib-1.2.11.tar.xz"
|
||||
URL_HASH SHA256=4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066
|
||||
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
|
||||
CMAKE_ARGS
|
||||
-DSKIP_INSTALL_FILES=ON # Prevent installation of man pages et al.
|
||||
"-DINSTALL_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR}\\fallout" # I found no better way of preventing zlib from creating & installing DLLs :-/
|
||||
|
@ -199,6 +234,33 @@ if (${DEP_DEBUG})
|
|||
)
|
||||
endif ()
|
||||
|
||||
find_package(Git REQUIRED)
|
||||
|
||||
ExternalProject_Add(dep_qhull
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/qhull/qhull/archive/v7.2.1.tar.gz"
|
||||
URL_HASH SHA256=6fc251e0b75467e00943bfb7191e986fce0e1f8f6f0251f9c6ce5a843821ea78
|
||||
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
|
||||
-DCMAKE_DEBUG_POSTFIX=d
|
||||
PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/qhull-mods.patch
|
||||
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
|
||||
if (${DEP_DEBUG})
|
||||
ExternalProject_Get_Property(dep_qhull BINARY_DIR)
|
||||
ExternalProject_Add_Step(dep_qhull build_debug
|
||||
DEPENDEES build
|
||||
DEPENDERS install
|
||||
COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
|
||||
WORKING_DIRECTORY "${BINARY_DIR}"
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
||||
if (${DEPS_BITS} EQUAL 32)
|
||||
set(DEP_WXWIDGETS_TARGET "")
|
||||
|
@ -208,6 +270,51 @@ else ()
|
|||
set(DEP_WXWIDGETS_LIBDIR "vc_x64_lib")
|
||||
endif ()
|
||||
|
||||
find_package(Git REQUIRED)
|
||||
|
||||
ExternalProject_Add(dep_libigl
|
||||
EXCLUDE_FROM_ALL 1
|
||||
URL "https://github.com/libigl/libigl/archive/v2.0.0.tar.gz"
|
||||
URL_HASH SHA256=42518e6b106c7209c73435fd260ed5d34edeb254852495b4c95dce2d95401328
|
||||
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||
-DLIBIGL_BUILD_PYTHON=OFF
|
||||
-DLIBIGL_BUILD_TESTS=OFF
|
||||
-DLIBIGL_BUILD_TUTORIALS=OFF
|
||||
-DLIBIGL_USE_STATIC_LIBRARY=OFF #${DEP_BUILD_IGL_STATIC}
|
||||
-DLIBIGL_WITHOUT_COPYLEFT=OFF
|
||||
-DLIBIGL_WITH_CGAL=OFF
|
||||
-DLIBIGL_WITH_COMISO=OFF
|
||||
-DLIBIGL_WITH_CORK=OFF
|
||||
-DLIBIGL_WITH_EMBREE=OFF
|
||||
-DLIBIGL_WITH_MATLAB=OFF
|
||||
-DLIBIGL_WITH_MOSEK=OFF
|
||||
-DLIBIGL_WITH_OPENGL=OFF
|
||||
-DLIBIGL_WITH_OPENGL_GLFW=OFF
|
||||
-DLIBIGL_WITH_OPENGL_GLFW_IMGUI=OFF
|
||||
-DLIBIGL_WITH_PNG=OFF
|
||||
-DLIBIGL_WITH_PYTHON=OFF
|
||||
-DLIBIGL_WITH_TETGEN=OFF
|
||||
-DLIBIGL_WITH_TRIANGLE=OFF
|
||||
-DLIBIGL_WITH_XML=OFF
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
|
||||
-DCMAKE_DEBUG_POSTFIX=d
|
||||
PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-fixes.patch
|
||||
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
|
||||
if (${DEP_DEBUG})
|
||||
ExternalProject_Get_Property(dep_libigl BINARY_DIR)
|
||||
ExternalProject_Add_Step(dep_libigl build_debug
|
||||
DEPENDEES build
|
||||
DEPENDERS install
|
||||
COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
|
||||
WORKING_DIRECTORY "${BINARY_DIR}"
|
||||
)
|
||||
endif ()
|
||||
|
||||
ExternalProject_Add(dep_wxwidgets
|
||||
EXCLUDE_FROM_ALL 1
|
||||
GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
|
||||
|
|
128
deps/igl-fixes.patch
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
diff --git a/cmake/libigl-config.cmake.in b/cmake/libigl-config.cmake.in
|
||||
index 317c745c..f9808e1e 100644
|
||||
--- a/cmake/libigl-config.cmake.in
|
||||
+++ b/cmake/libigl-config.cmake.in
|
||||
@@ -2,28 +2,28 @@
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/libigl-export.cmake)
|
||||
|
||||
-if (TARGET igl::core)
|
||||
- if (NOT TARGET Eigen3::Eigen)
|
||||
- find_package(Eigen3 QUIET)
|
||||
- if (NOT Eigen3_FOUND)
|
||||
- # try with PkgCOnfig
|
||||
- find_package(PkgConfig REQUIRED)
|
||||
- pkg_check_modules(Eigen3 QUIET IMPORTED_TARGET eigen3)
|
||||
- endif()
|
||||
-
|
||||
- if (NOT Eigen3_FOUND)
|
||||
- message(FATAL_ERROR "Could not find required dependency Eigen3")
|
||||
- set(libigl_core_FOUND FALSE)
|
||||
- else()
|
||||
- target_link_libraries(igl::core INTERFACE PkgConfig::Eigen3)
|
||||
- set(libigl_core_FOUND TRUE)
|
||||
- endif()
|
||||
- else()
|
||||
- target_link_libraries(igl::core INTERFACE Eigen3::Eigen)
|
||||
- set(libigl_core_FOUND TRUE)
|
||||
- endif()
|
||||
-
|
||||
-endif()
|
||||
+# if (TARGET igl::core)
|
||||
+# if (NOT TARGET Eigen3::Eigen)
|
||||
+# find_package(Eigen3 QUIET)
|
||||
+# if (NOT Eigen3_FOUND)
|
||||
+# # try with PkgCOnfig
|
||||
+# find_package(PkgConfig REQUIRED)
|
||||
+# pkg_check_modules(Eigen3 QUIET IMPORTED_TARGET eigen3)
|
||||
+# endif()
|
||||
+#
|
||||
+# if (NOT Eigen3_FOUND)
|
||||
+# message(FATAL_ERROR "Could not find required dependency Eigen3")
|
||||
+# set(libigl_core_FOUND FALSE)
|
||||
+# else()
|
||||
+# target_link_libraries(igl::core INTERFACE PkgConfig::Eigen3)
|
||||
+# set(libigl_core_FOUND TRUE)
|
||||
+# endif()
|
||||
+# else()
|
||||
+# target_link_libraries(igl::core INTERFACE Eigen3::Eigen)
|
||||
+# set(libigl_core_FOUND TRUE)
|
||||
+# endif()
|
||||
+#
|
||||
+# endif()
|
||||
|
||||
check_required_components(libigl)
|
||||
|
||||
diff --git a/cmake/libigl.cmake b/cmake/libigl.cmake
|
||||
index 4b11007a..47e6c395 100644
|
||||
--- a/cmake/libigl.cmake
|
||||
+++ b/cmake/libigl.cmake
|
||||
@@ -445,6 +445,7 @@ function(install_dir_files dir_name)
|
||||
if(NOT LIBIGL_USE_STATIC_LIBRARY)
|
||||
file(GLOB public_sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.cpp
|
||||
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.c
|
||||
)
|
||||
endif()
|
||||
list(APPEND files_to_install ${public_sources})
|
||||
diff --git a/include/igl/AABB.cpp b/include/igl/AABB.cpp
|
||||
index 09537335..92e90cb7 100644
|
||||
--- a/include/igl/AABB.cpp
|
||||
+++ b/include/igl/AABB.cpp
|
||||
@@ -1071,5 +1071,11 @@ template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
|
||||
template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
|
||||
+template float igl::AABB<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> >, 3>::squared_distance<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > >(Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
|
||||
template bool igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, igl::Hit&) const;
|
||||
+template bool igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, std::vector<igl::Hit>&) const;
|
||||
+
|
||||
+template void igl::AABB<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> >, 3>::init<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > >(Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&);
|
||||
+
|
||||
+template bool igl::AABB<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> >, 3>::intersect_ray<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > >(Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, std::vector<igl::Hit, std::allocator<igl::Hit> >&) const;
|
||||
#endif
|
||||
diff --git a/include/igl/barycenter.cpp b/include/igl/barycenter.cpp
|
||||
index 065f82aa..ec2d96cd 100644
|
||||
--- a/include/igl/barycenter.cpp
|
||||
+++ b/include/igl/barycenter.cpp
|
||||
@@ -54,4 +54,6 @@ template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::M
|
||||
template void igl::barycenter<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
|
||||
template void igl::barycenter<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&);
|
||||
+
|
||||
+template void igl::barycenter<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> >, Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> >, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
|
||||
#endif
|
||||
diff --git a/include/igl/point_simplex_squared_distance.cpp b/include/igl/point_simplex_squared_distance.cpp
|
||||
index 2b98bd28..c66d9ae1 100644
|
||||
--- a/include/igl/point_simplex_squared_distance.cpp
|
||||
+++ b/include/igl/point_simplex_squared_distance.cpp
|
||||
@@ -178,4 +178,6 @@ template void igl::point_simplex_squared_distance<3, Eigen::Matrix<double, 1, 3,
|
||||
template void igl::point_simplex_squared_distance<3, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, double&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 1, 1, 3> >&);
|
||||
template void igl::point_simplex_squared_distance<2, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, Eigen::Matrix<double, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, double&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&);
|
||||
template void igl::point_simplex_squared_distance<2, Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, Eigen::Matrix<double, 1, 2, 1, 1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, double&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 1, 1, 2> >&);
|
||||
+
|
||||
+template void igl::point_simplex_squared_distance<3, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> >, Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> >, float, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> >::Index, float&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
|
||||
#endif
|
||||
diff --git a/include/igl/ray_box_intersect.cpp b/include/igl/ray_box_intersect.cpp
|
||||
index 4a88b89e..b547f8f8 100644
|
||||
--- a/include/igl/ray_box_intersect.cpp
|
||||
+++ b/include/igl/ray_box_intersect.cpp
|
||||
@@ -147,4 +147,6 @@ IGL_INLINE bool igl::ray_box_intersect(
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template bool igl::ray_box_intersect<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::AlignedBox<double, 3> const&, double const&, double const&, double&, double&);
|
||||
+
|
||||
+template bool igl::ray_box_intersect<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, float>(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::AlignedBox<float, 3> const&, float const&, float const&, float&, float&);
|
||||
#endif
|
||||
diff --git a/include/igl/ray_mesh_intersect.cpp b/include/igl/ray_mesh_intersect.cpp
|
||||
index 9a70a22b..4233e722 100644
|
||||
--- a/include/igl/ray_mesh_intersect.cpp
|
||||
+++ b/include/igl/ray_mesh_intersect.cpp
|
||||
@@ -83,4 +83,7 @@ IGL_INLINE bool igl::ray_mesh_intersect(
|
||||
template bool igl::ray_mesh_intersect<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
|
||||
template bool igl::ray_mesh_intersect<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::Hit&);
|
||||
template bool igl::ray_mesh_intersect<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1> const, 1, -1, false> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, igl::Hit&);
|
||||
+template bool igl::ray_mesh_intersect<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1> const, 1, -1, false> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
|
||||
+
|
||||
+template bool igl::ray_mesh_intersect<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> >, Eigen::Block<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > const, 1, -1, true> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Map<Eigen::Matrix<float, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Map<Eigen::Matrix<int, -1, -1, 3, -1, -1> const, 0, Eigen::Stride<0, 0> > const, 1, -1, true> > const&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
|
||||
#endif
|
121
deps/qhull-mods.patch
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
From a31ae4781a4afa60e21c70e5b4ae784bcd447c8a Mon Sep 17 00:00:00 2001
|
||||
From: tamasmeszaros <meszaros.q@gmail.com>
|
||||
Date: Thu, 6 Jun 2019 15:41:43 +0200
|
||||
Subject: [PATCH] prusa-slicer changes
|
||||
|
||||
---
|
||||
CMakeLists.txt | 44 +++++++++++++++++++++++++++++++++++---
|
||||
Config.cmake.in | 2 ++
|
||||
src/libqhull_r/qhull_r-exports.def | 2 ++
|
||||
src/libqhull_r/user_r.h | 2 +-
|
||||
4 files changed, 46 insertions(+), 4 deletions(-)
|
||||
create mode 100644 Config.cmake.in
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 59dff41..20c2ec5 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -61,7 +61,7 @@
|
||||
# $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
|
||||
|
||||
project(qhull)
|
||||
-cmake_minimum_required(VERSION 2.6)
|
||||
+cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, qhull-warn.pri
|
||||
set(qhull_VERSION2 "2015.2 2016/01/18") # not used, See global.c, global_r.c, rbox.c, rbox_r.c
|
||||
@@ -610,10 +610,48 @@ add_test(NAME user_eg3
|
||||
# Define install
|
||||
# ---------------------------------------
|
||||
|
||||
-install(TARGETS ${qhull_TARGETS_INSTALL}
|
||||
+install(TARGETS ${qhull_TARGETS_INSTALL} EXPORT QhullTargets
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
- ARCHIVE DESTINATION ${LIB_INSTALL_DIR})
|
||||
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
+ INCLUDES DESTINATION include)
|
||||
+
|
||||
+include(CMakePackageConfigHelpers)
|
||||
+
|
||||
+write_basic_package_version_file(
|
||||
+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake"
|
||||
+ VERSION ${qhull_VERSION}
|
||||
+ COMPATIBILITY AnyNewerVersion
|
||||
+)
|
||||
+
|
||||
+export(EXPORT QhullTargets
|
||||
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullTargets.cmake"
|
||||
+ NAMESPACE Qhull::
|
||||
+)
|
||||
+
|
||||
+configure_file(Config.cmake.in
|
||||
+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake"
|
||||
+ @ONLY
|
||||
+)
|
||||
+
|
||||
+set(ConfigPackageLocation lib/cmake/Qhull)
|
||||
+install(EXPORT QhullTargets
|
||||
+ FILE
|
||||
+ QhullTargets.cmake
|
||||
+ NAMESPACE
|
||||
+ Qhull::
|
||||
+ DESTINATION
|
||||
+ ${ConfigPackageLocation}
|
||||
+)
|
||||
+install(
|
||||
+ FILES
|
||||
+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake"
|
||||
+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake"
|
||||
+ DESTINATION
|
||||
+ ${ConfigPackageLocation}
|
||||
+ COMPONENT
|
||||
+ Devel
|
||||
+)
|
||||
|
||||
install(FILES ${libqhull_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull)
|
||||
install(FILES ${libqhull_DOC} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull)
|
||||
diff --git a/Config.cmake.in b/Config.cmake.in
|
||||
new file mode 100644
|
||||
index 0000000..bc92bfe
|
||||
--- /dev/null
|
||||
+++ b/Config.cmake.in
|
||||
@@ -0,0 +1,2 @@
|
||||
+include("${CMAKE_CURRENT_LIST_DIR}/QhullTargets.cmake")
|
||||
+
|
||||
diff --git a/src/libqhull_r/qhull_r-exports.def b/src/libqhull_r/qhull_r-exports.def
|
||||
index 325d57c..72f6ad0 100644
|
||||
--- a/src/libqhull_r/qhull_r-exports.def
|
||||
+++ b/src/libqhull_r/qhull_r-exports.def
|
||||
@@ -185,6 +185,7 @@ qh_memsetup
|
||||
qh_memsize
|
||||
qh_memstatistics
|
||||
qh_memtotal
|
||||
+qh_memcheck
|
||||
qh_merge_degenredundant
|
||||
qh_merge_nonconvex
|
||||
qh_mergecycle
|
||||
@@ -372,6 +373,7 @@ qh_settruncate
|
||||
qh_setunique
|
||||
qh_setvoronoi_all
|
||||
qh_setzero
|
||||
+qh_setendpointer
|
||||
qh_sharpnewfacets
|
||||
qh_skipfacet
|
||||
qh_skipfilename
|
||||
diff --git a/src/libqhull_r/user_r.h b/src/libqhull_r/user_r.h
|
||||
index fc105b9..7cca65a 100644
|
||||
--- a/src/libqhull_r/user_r.h
|
||||
+++ b/src/libqhull_r/user_r.h
|
||||
@@ -139,7 +139,7 @@ Code flags --
|
||||
REALfloat = 1 all numbers are 'float' type
|
||||
= 0 all numbers are 'double' type
|
||||
*/
|
||||
-#define REALfloat 0
|
||||
+#define REALfloat 1
|
||||
|
||||
#if (REALfloat == 1)
|
||||
#define realT float
|
||||
--
|
||||
2.16.2.windows.1
|
||||
|
|
@ -1,7 +1,15 @@
|
|||
|
||||
# Building PrusaSlicer on Mac OS
|
||||
|
||||
To build PrusaSlicer on Mac OS, you will need to install XCode, [CMake](https://cmake.org/) (available on Brew) and possibly git.
|
||||
To build PrusaSlicer on Mac OS, you will need the following software:
|
||||
|
||||
- XCode
|
||||
- CMake
|
||||
- git
|
||||
- gettext
|
||||
|
||||
XCode is available through Apple's App Store, the other three tools are available on
|
||||
[brew](https://brew.sh/) (use `brew install cmake git gettext` to install them).
|
||||
|
||||
### Dependencies
|
||||
|
||||
|
@ -20,6 +28,9 @@ You can also customize the bundle output path using the `-DDESTDIR=<some path>`
|
|||
**Warning**: Once the dependency bundle is installed in a destdir, the destdir cannot be moved elsewhere.
|
||||
(This is because wxWidgets hardcodes the installation path.)
|
||||
|
||||
FIXME The Cereal serialization library needs a tiny patch on some old OSX clang installations
|
||||
https://github.com/USCiLab/cereal/issues/339#issuecomment-246166717
|
||||
|
||||
|
||||
### Building PrusaSlicer
|
||||
|
||||
|
|
|
@ -1,24 +1,37 @@
|
|||
|
||||
# This how-to is out of date
|
||||
|
||||
We have switched to MS Visual Studio 2019.
|
||||
|
||||
We don't use MSVS 2013 any more. At the moment we are in the process of creating new pre-built dependency bundles
|
||||
and updating this document. In the meantime, you will need to compile the dependencies yourself
|
||||
[the same way as before](#building-the-dependencies-package-yourself)
|
||||
except with CMake generators for MSVS 2019 instead of 2013.
|
||||
|
||||
Thank you for understanding.
|
||||
|
||||
---
|
||||
|
||||
# Building PrusaSlicer on Microsoft Windows
|
||||
|
||||
The currently supported way of building PrusaSlicer on Windows is with CMake and MS Visual Studio 2013.
|
||||
~~The currently supported way of building PrusaSlicer on Windows is with CMake and MS Visual Studio 2013.
|
||||
You can use the free [Visual Studio 2013 Community Edition](https://www.visualstudio.com/vs/older-downloads/).
|
||||
CMake installer can be downloaded from [the official website](https://cmake.org/download/).
|
||||
CMake installer can be downloaded from [the official website](https://cmake.org/download/).~~
|
||||
|
||||
Building with newer versions of MSVS (2015, 2017) may work too as reported by some of our users.
|
||||
~~Building with newer versions of MSVS (2015, 2017) may work too as reported by some of our users.~~
|
||||
|
||||
_Note:_ Thanks to [**@supermerill**](https://github.com/supermerill) for testing and inspiration for this guide.
|
||||
|
||||
### Dependencies
|
||||
|
||||
On Windows PrusaSlicer is built against statically built libraries.
|
||||
We provide a prebuilt package of all the needed dependencies. This package only works on Visual Studio 2013, so if you are using a newer version of Visual Studio, you need to compile the dependencies yourself as per [below](#building-the-dependencies-package-yourself).
|
||||
~~We provide a prebuilt package of all the needed dependencies. This package only works on Visual Studio 2013, so~~ if you are using a newer version of Visual Studio, you need to compile the dependencies yourself as per [below](#building-the-dependencies-package-yourself).
|
||||
The package comes in a several variants:
|
||||
|
||||
- [64 bit, Release mode only](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=destdir-64.7z) (41 MB, 578 MB unpacked)
|
||||
- [64 bit, Release and Debug mode](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=destdir-64-dev.7z) (88 MB, 1.3 GB unpacked)
|
||||
- [32 bit, Release mode only](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=destdir-32.7z) (38 MB, 520 MB unpacked)
|
||||
- [32 bit, Release and Debug mode](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=destdir-32-dev.7z) (74 MB, 1.1 GB unpacked)
|
||||
- ~~64 bit, Release mode only (41 MB, 578 MB unpacked)~~
|
||||
- ~~64 bit, Release and Debug mode (88 MB, 1.3 GB unpacked)~~
|
||||
- ~~32 bit, Release mode only (38 MB, 520 MB unpacked)~~
|
||||
- ~~32 bit, Release and Debug mode (74 MB, 1.1 GB unpacked)~~
|
||||
|
||||
When unsure, use the _Release mode only_ variant, the _Release and Debug_ variant is only needed for debugging & development.
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ use Slic3r::Point;
|
|||
use Slic3r::Polygon;
|
||||
use Slic3r::Polyline;
|
||||
use Slic3r::Print::Object;
|
||||
use Slic3r::Print::Simple;
|
||||
use Slic3r::Surface;
|
||||
our $build = eval "use Slic3r::Build; 1";
|
||||
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
# A simple wrapper to quickly print a single model without a GUI.
|
||||
# Used by the command line slic3r.pl, by command line utilities pdf-slic3s.pl and view-toolpaths.pl,
|
||||
# and by the quick slice menu of the Slic3r GUI.
|
||||
#
|
||||
# It creates and owns an instance of Slic3r::Print to perform the slicing
|
||||
# and it accepts an instance of Slic3r::Model from the outside.
|
||||
|
||||
package Slic3r::Print::Simple;
|
||||
use Moo;
|
||||
|
||||
use Slic3r::Geometry qw(X Y);
|
||||
|
||||
has '_print' => (
|
||||
is => 'ro',
|
||||
default => sub { Slic3r::Print->new },
|
||||
handles => [qw(apply_config_perl_tests_only extruders output_filepath
|
||||
total_used_filament total_extruded_volume
|
||||
placeholder_parser process)],
|
||||
);
|
||||
|
||||
has 'duplicate' => (
|
||||
is => 'rw',
|
||||
default => sub { 1 },
|
||||
);
|
||||
|
||||
has 'scale' => (
|
||||
is => 'rw',
|
||||
default => sub { 1 },
|
||||
);
|
||||
|
||||
has 'rotate' => (
|
||||
is => 'rw',
|
||||
default => sub { 0 },
|
||||
);
|
||||
|
||||
has 'duplicate_grid' => (
|
||||
is => 'rw',
|
||||
default => sub { [1,1] },
|
||||
);
|
||||
|
||||
has 'print_center' => (
|
||||
is => 'rw',
|
||||
default => sub { Slic3r::Pointf->new(100,100) },
|
||||
);
|
||||
|
||||
has 'dont_arrange' => (
|
||||
is => 'rw',
|
||||
default => sub { 0 },
|
||||
);
|
||||
|
||||
has 'output_file' => (
|
||||
is => 'rw',
|
||||
);
|
||||
|
||||
sub set_model {
|
||||
# $model is of type Slic3r::Model
|
||||
my ($self, $model) = @_;
|
||||
|
||||
# make method idempotent so that the object is reusable
|
||||
$self->_print->clear_objects;
|
||||
|
||||
# make sure all objects have at least one defined instance
|
||||
my $need_arrange = $model->add_default_instances && ! $self->dont_arrange;
|
||||
|
||||
# apply scaling and rotation supplied from command line if any
|
||||
foreach my $instance (map @{$_->instances}, @{$model->objects}) {
|
||||
$instance->set_scaling_factor($instance->scaling_factor * $self->scale);
|
||||
$instance->set_rotation($instance->rotation + $self->rotate);
|
||||
}
|
||||
|
||||
if ($self->duplicate_grid->[X] > 1 || $self->duplicate_grid->[Y] > 1) {
|
||||
$model->duplicate_objects_grid($self->duplicate_grid->[X], $self->duplicate_grid->[Y], $self->_print->config->duplicate_distance);
|
||||
} elsif ($need_arrange) {
|
||||
$model->duplicate_objects($self->duplicate, $self->_print->config->min_object_distance);
|
||||
} elsif ($self->duplicate > 1) {
|
||||
# if all input objects have defined position(s) apply duplication to the whole model
|
||||
$model->duplicate($self->duplicate, $self->_print->config->min_object_distance);
|
||||
}
|
||||
$_->translate(0,0,-$_->bounding_box->z_min) for @{$model->objects};
|
||||
$model->center_instances_around_point($self->print_center) if (! $self->dont_arrange);
|
||||
|
||||
foreach my $model_object (@{$model->objects}) {
|
||||
$self->_print->auto_assign_extruders($model_object);
|
||||
$self->_print->add_model_object($model_object);
|
||||
}
|
||||
}
|
||||
|
||||
sub export_gcode {
|
||||
my ($self) = @_;
|
||||
$self->_print->validate;
|
||||
$self->_print->export_gcode($self->output_file // '');
|
||||
}
|
||||
|
||||
sub export_png {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->_before_export;
|
||||
|
||||
$self->_print->export_png(output_file => $self->output_file);
|
||||
|
||||
$self->_after_export;
|
||||
}
|
||||
|
||||
1;
|
|
@ -146,13 +146,16 @@ sub mesh {
|
|||
}
|
||||
|
||||
sub model {
|
||||
my ($model_name, %params) = @_;
|
||||
|
||||
my $input_file = "${model_name}.stl";
|
||||
my $mesh = mesh($model_name, %params);
|
||||
# $mesh->write_ascii("out/$input_file");
|
||||
my ($model_names, %params) = @_;
|
||||
$model_names = [ $model_names ] if ! ref($model_names);
|
||||
|
||||
my $model = Slic3r::Model->new;
|
||||
|
||||
for my $model_name (@$model_names) {
|
||||
my $input_file = "${model_name}.stl";
|
||||
my $mesh = mesh($model_name, %params);
|
||||
# $mesh->write_ascii("out/$input_file");
|
||||
|
||||
my $object = $model->add_object(input_file => $input_file);
|
||||
$model->set_material($model_name);
|
||||
$object->add_volume(mesh => $mesh, material_id => $model_name);
|
||||
|
@ -162,44 +165,47 @@ sub model {
|
|||
rotation => Slic3r::Pointf3->new(0, 0, $params{rotation} // 0),
|
||||
scaling_factor => Slic3r::Pointf3->new($params{scale} // 1, $params{scale} // 1, $params{scale} // 1),
|
||||
# old transform
|
||||
# rotation => $params{rotation} // 0,
|
||||
# scaling_factor => $params{scale} // 1,
|
||||
# rotation => $params{rotation} // 0,
|
||||
# scaling_factor => $params{scale} // 1,
|
||||
);
|
||||
}
|
||||
return $model;
|
||||
}
|
||||
|
||||
sub init_print {
|
||||
my ($models, %params) = @_;
|
||||
my $model;
|
||||
if (ref($models) eq 'ARRAY') {
|
||||
$model = model($models, %params);
|
||||
} elsif (ref($models)) {
|
||||
$model = $models;
|
||||
} else {
|
||||
$model = model([$models], %params);
|
||||
}
|
||||
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->apply($params{config}) if $params{config};
|
||||
$config->set('gcode_comments', 1) if $ENV{SLIC3R_TESTS_GCODE};
|
||||
|
||||
my $print = Slic3r::Print->new;
|
||||
$print->apply_config_perl_tests_only($config);
|
||||
|
||||
$models = [$models] if ref($models) ne 'ARRAY';
|
||||
$models = [ map { ref($_) ? $_ : model($_, %params) } @$models ];
|
||||
for my $model (@$models) {
|
||||
die "Unknown model in test" if !defined $model;
|
||||
if (defined $params{duplicate} && $params{duplicate} > 1) {
|
||||
$model->duplicate($params{duplicate} // 1, $print->config->min_object_distance);
|
||||
$model->duplicate($params{duplicate} // 1, $config->min_object_distance);
|
||||
}
|
||||
$model->arrange_objects($print->config->min_object_distance);
|
||||
$model->arrange_objects($config->min_object_distance);
|
||||
$model->center_instances_around_point($params{print_center} ? Slic3r::Pointf->new(@{$params{print_center}}) : Slic3r::Pointf->new(100,100));
|
||||
foreach my $model_object (@{$model->objects}) {
|
||||
$model_object->ensure_on_bed;
|
||||
$print->auto_assign_extruders($model_object);
|
||||
$print->add_model_object($model_object);
|
||||
}
|
||||
}
|
||||
# Call apply_config_perl_tests_only one more time, so that the layer height profiles are updated over all PrintObjects.
|
||||
$print->apply_config_perl_tests_only($config);
|
||||
|
||||
$print->apply($model, $config);
|
||||
$print->validate;
|
||||
|
||||
# We return a proxy object in order to keep $models alive as required by the Print API.
|
||||
return Slic3r::Test::Print->new(
|
||||
print => $print,
|
||||
models => $models,
|
||||
model => $model,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -250,7 +256,7 @@ sub add_facet {
|
|||
package Slic3r::Test::Print;
|
||||
use Moo;
|
||||
|
||||
has 'print' => (is => 'ro', required => 1, handles => [qw(process apply_config_perl_tests_only)]);
|
||||
has 'models' => (is => 'ro', required => 1);
|
||||
has 'print' => (is => 'ro', required => 1, handles => [qw(process apply)]);
|
||||
has 'model' => (is => 'ro', required => 1);
|
||||
|
||||
1;
|
||||
|
|
15
resources/icons/cross_focus.svg
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="cross">
|
||||
<g>
|
||||
|
||||
<line fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="14" y1="2" x2="2" y2="14"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<line fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="2" y1="2" x2="14" y2="14"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 659 B |
15
resources/icons/drop_to_bed.svg
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="modifer_x5F_bed">
|
||||
|
||||
<line fill="none" stroke="#ED6B21" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="2" y1="13" x2="13" y2="13"/>
|
||||
<path fill="#808080" d="M10.87,7.48c-0.2,0-0.37,0.16-0.37,0.37v1.47v0.74c0,0.2-0.17,0.37-0.37,0.37H4.97
|
||||
c-0.2,0-0.37-0.17-0.37-0.37L4.57,4.91c0-0.1,0.04-0.19,0.11-0.26c0.07-0.07,0.16-0.11,0.26-0.11l2.25,0v0
|
||||
c0.2,0,0.37-0.16,0.37-0.37c0-0.2-0.16-0.37-0.37-0.37H5.71c0,0-0.01,0-0.01,0l-0.76,0c-0.3,0-0.57,0.12-0.78,0.33
|
||||
C3.95,4.34,3.83,4.61,3.83,4.91l0.03,5.15c0,0.61,0.5,1.1,1.11,1.1h5.16c0.61,0,1.11-0.5,1.11-1.11V9.32V7.85
|
||||
C11.24,7.65,11.07,7.48,10.87,7.48z"/>
|
||||
<circle fill="#808080" stroke="#808080" stroke-miterlimit="10" cx="10.88" cy="4.12" r="2.12"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
25
resources/icons/edit_layers_all.svg
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="edit_x5F_layers_x5F_all">
|
||||
<line fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" x1="2" y1="2" x2="6" y2="2"/>
|
||||
<line fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" x1="2" y1="6" x2="6" y2="6"/>
|
||||
|
||||
<line fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" x1="2" y1="10" x2="14" y2="10"/>
|
||||
|
||||
<line fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" x1="2" y1="14" x2="14" y2="14"/>
|
||||
<path fill="#ED6B21" d="M14.62,4.37c-0.01-0.14,0.06-0.34,0.15-0.44l0.13-0.15c0.09-0.11,0.12-0.3,0.07-0.43l-0.2-0.49
|
||||
c-0.05-0.13-0.21-0.24-0.35-0.25l-0.2-0.01c-0.14-0.01-0.33-0.1-0.42-0.21c-0.09-0.1-0.37-0.46-0.38-0.6l-0.01-0.2
|
||||
c-0.01-0.14-0.12-0.3-0.25-0.35l-0.49-0.2C12.52,0.97,12.33,1,12.22,1.1l-0.15,0.13c-0.11,0.09-0.31,0.16-0.44,0.15
|
||||
c-0.14-0.01-0.59-0.06-0.69-0.15L10.78,1.1c-0.11-0.09-0.3-0.12-0.43-0.07l-0.49,0.2C9.73,1.28,9.61,1.44,9.6,1.58l-0.01,0.2
|
||||
C9.58,1.92,9.49,2.11,9.38,2.2c-0.1,0.09-0.46,0.37-0.6,0.38L8.58,2.6c-0.14,0.01-0.3,0.12-0.35,0.25l-0.2,0.49
|
||||
C7.97,3.48,8,3.67,8.1,3.78l0.13,0.15c0.09,0.11,0.16,0.31,0.15,0.44C8.37,4.52,8.32,4.96,8.23,5.07L8.1,5.22
|
||||
C8,5.33,7.97,5.52,8.03,5.65l0.2,0.49C8.28,6.27,8.44,6.39,8.58,6.4l0.2,0.01c0.14,0.01,0.33,0.1,0.42,0.21
|
||||
c0.09,0.1,0.37,0.46,0.38,0.6l0.01,0.2c0.01,0.14,0.12,0.3,0.25,0.35l0.49,0.2C10.48,8.03,10.67,8,10.78,7.9l0.15-0.13
|
||||
c0.11-0.09,0.31-0.16,0.44-0.15c0.14,0.01,0.59,0.06,0.69,0.15l0.15,0.13c0.11,0.09,0.3,0.12,0.43,0.07l0.49-0.2
|
||||
c0.13-0.05,0.24-0.21,0.25-0.35l0.01-0.2c0.01-0.14,0.1-0.33,0.21-0.42s0.46-0.37,0.6-0.38l0.2-0.01c0.14-0.01,0.3-0.12,0.35-0.25
|
||||
l0.2-0.49C15.03,5.52,15,5.33,14.9,5.22l-0.13-0.15C14.68,4.96,14.63,4.51,14.62,4.37z M11.5,6.6c-1.16,0-2.1-0.94-2.1-2.1
|
||||
s0.94-2.1,2.1-2.1s2.1,0.94,2.1,2.1S12.66,6.6,11.5,6.6z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
14
resources/icons/edit_layers_some.svg
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="edit_x5F_layers_x5F_some_1_">
|
||||
|
||||
<line fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" x1="2" y1="11" x2="14" y2="11"/>
|
||||
|
||||
<line fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" x1="2" y1="14" x2="14" y2="14"/>
|
||||
<path fill="#ED6B21" d="M7.68,8.87c0.18,0.18,0.47,0.18,0.64,0L11.19,6c0.18-0.18,0.12-0.32-0.13-0.32H9.62
|
||||
c-0.25,0-0.45-0.2-0.45-0.45V1.45C9.17,1.2,8.97,1,8.71,1H7.29C7.03,1,6.83,1.2,6.83,1.45v3.77c0,0.25-0.2,0.45-0.45,0.45H4.95
|
||||
C4.7,5.68,4.64,5.82,4.81,6L7.68,8.87z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 931 B |
13
resources/icons/eye_closed.svg
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="eye_x5F_close">
|
||||
<path fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||
M2,8c0,0,2,4,6,4s6-4,6-4s-2-4-6-4S2,8,2,8z"/>
|
||||
|
||||
<circle fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" cx="8" cy="8" r="1"/>
|
||||
|
||||
<line fill="none" stroke="#ED6B21" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="2" y1="14" x2="14" y2="2"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 856 B |
11
resources/icons/eye_open.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="eye_x5F_open">
|
||||
<path fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||
M2,8c0,0,2,4,6,4s6-4,6-4s-2-4-6-4S2,8,2,8z"/>
|
||||
|
||||
<circle fill="none" stroke="#808080" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" cx="8" cy="8" r="1"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 697 B |
10
resources/icons/lock_closed_f.svg
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="lock_x5F_closed">
|
||||
<path fill="none" stroke="#808080" stroke-width="3" stroke-miterlimit="9" d="M4,8V4c0,0,0-2,2-2c1,0,3,0,4,0c2,0,2,2,2,2v4"/>
|
||||
<path fill="#808080" d="M13,8H3C2.45,8,2,8.45,2,9v5c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1V9C14,8.45,13.55,8,13,8z M10,12H8.91
|
||||
c-0.21,0.58-0.76,1-1.41,1C6.67,13,6,12.33,6,11.5S6.67,10,7.5,10c0.65,0,1.2,0.42,1.41,1H10V12z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 728 B |
11
resources/icons/lock_open_f.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="lock_x5F_open">
|
||||
<path fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" d="M4,8V4c0,0,0-2,2-2
|
||||
c1,0,3,0,4,0c2,0,2,2,2,2v1"/>
|
||||
<path fill="#ED6B21" d="M13,8H3C2.45,8,2,8.45,2,9v5c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1V9C14,8.45,13.55,8,13,8z M10,12H8.91
|
||||
c-0.21,0.58-0.76,1-1.41,1C6.67,13,6,12.33,6,11.5S6.67,10,7.5,10c0.65,0,1.2,0.42,1.41,1H10V12z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 753 B |
23
resources/icons/mirroring_off.svg
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="mirror_x5F_off">
|
||||
<g>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||
M10,3.01l3,0c0.55,0,1,0.45,1,1v8c0,0.55-0.45,1-1,1h-3"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||
M6,3.01L3,3C2.45,3,2,3.45,2,4v8c0,0.55,0.45,1,1,1h3"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<line fill="none" stroke="#000000" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="1" x2="8" y2="3.5"/>
|
||||
|
||||
<line fill="none" stroke="#000000" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,3" x1="8" y1="6.5" x2="8" y2="11"/>
|
||||
<line fill="none" stroke="#000000" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="12.5" x2="8" y2="15"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
23
resources/icons/mirroring_on.svg
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="mirror_x5F_on">
|
||||
<g>
|
||||
<path fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M10,3.01l3,0
|
||||
c0.55,0,1,0.45,1,1v8c0,0.55-0.45,1-1,1h-3"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="none" stroke="#ED6B21" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M6,3.01L3,3
|
||||
C2.45,3,2,3.45,2,4v8c0,0.55,0.45,1,1,1h3"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<line fill="none" stroke="#000000" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="1" x2="8" y2="3.5"/>
|
||||
|
||||
<line fill="none" stroke="#000000" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,3" x1="8" y1="6.5" x2="8" y2="11"/>
|
||||
<line fill="none" stroke="#000000" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="12.5" x2="8" y2="15"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/icons/mirroring_transparent.png
Normal file
After Width: | Height: | Size: 93 B |
12
resources/icons/redo.svg
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="redo">
|
||||
<path fill="none" stroke="#ED6B21" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M13.39,11
|
||||
c-0.91,1.78-2.76,3-4.89,3C5.46,14,3,11.54,3,8.5C3,5.46,5.46,3,8.5,3C8.67,3,8.84,3.01,9,3.03"/>
|
||||
|
||||
<polygon fill="#ED6B21" stroke="#ED6B21" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
9,1 9,5 12,3 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 734 B |
12
resources/icons/redo_toolbar.svg
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="redo">
|
||||
<path fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" d="M13.39,11
|
||||
c-0.91,1.78-2.76,3-4.89,3C5.46,14,3,11.54,3,8.5C3,5.46,5.46,3,8.5,3C8.67,3,8.84,3.01,9,3.03"/>
|
||||
|
||||
<polygon fill="#ED6B21" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
9,1 9,5 12,3 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 734 B |
BIN
resources/icons/row.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/icons/table.png
Normal file
After Width: | Height: | Size: 465 B |
12
resources/icons/undo_toolbar.svg
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<g id="undo">
|
||||
<path fill="none" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-miterlimit="10" d="M3,11
|
||||
c0.91,1.78,2.76,3,4.89,3c3.04,0,5.5-2.46,5.5-5.5c0-3.04-2.46-5.5-5.5-5.5c-0.17,0-0.34,0.01-0.5,0.03"/>
|
||||
|
||||
<polygon fill="#ED6B21" stroke="#ED6B21" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
|
||||
7.39,1 7.39,5 4.39,3 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 746 B |
|
@ -1,4 +1,9 @@
|
|||
min_slic3r_version = 2.1.0-alpha0
|
||||
1.0.0-alpha0 Filament specific retract for PET and similar copolymers, and for FLEX
|
||||
min_slic3r_version = 1.42.0-alpha6
|
||||
0.8.3 FW version and SL1 materials update
|
||||
0.8.2 FFF and SL1 settings update
|
||||
0.8.1 Output settings and SLA materials update
|
||||
0.8.0 Updated for the PrusaSlicer 2.0.0 final release
|
||||
0.8.0-rc2 Updated firmware versions for MK2.5/S and MK3/S
|
||||
0.8.0-rc1 Updated SLA profiles
|
||||
|
@ -18,6 +23,8 @@ min_slic3r_version = 1.42.0-alpha
|
|||
0.4.0-alpha3 Update of SLA profiles
|
||||
0.4.0-alpha2 First SLA profiles
|
||||
min_slic3r_version = 1.41.3-alpha
|
||||
0.4.8 MK2.5/3/S FW update
|
||||
0.4.7 MK2/S/MMU FW update
|
||||
0.4.6 Updated firmware versions for MK2.5/S and MK3/S
|
||||
0.4.5 Enabled remaining time support for MK2/S/MMU1
|
||||
0.4.4 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||
|
@ -26,6 +33,8 @@ min_slic3r_version = 1.41.3-alpha
|
|||
0.4.1 New MK2.5S and MK3S FW versions
|
||||
0.4.0 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||
min_slic3r_version = 1.41.1
|
||||
0.3.8 MK2.5/3/S FW update
|
||||
0.3.7 MK2/S/MMU FW update
|
||||
0.3.6 Updated firmware versions for MK2.5 and MK3
|
||||
0.3.5 New MK2.5 and MK3 FW versions
|
||||
0.3.4 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||
|
@ -60,6 +69,8 @@ min_slic3r_version = 1.41.0-alpha
|
|||
0.2.0-alpha1 added initial profiles for the i3 MK3 Multi Material Upgrade 2.0
|
||||
0.2.0-alpha moved machine limits from the start G-code to the new print profile parameters
|
||||
min_slic3r_version = 1.40.0
|
||||
0.1.16 MK2.5/3/S FW update
|
||||
0.1.15 MK2/S/MMU FW update
|
||||
0.1.14 Updated firmware versions for MK2.5 and MK3
|
||||
0.1.13 New MK2.5 and MK3 FW versions
|
||||
0.1.12 New MK2.5 and MK3 FW versions
|
||||
|
|
|
@ -5,16 +5,30 @@ const vec3 back_color_light = vec3(0.365, 0.365, 0.365);
|
|||
|
||||
uniform sampler2D texture;
|
||||
uniform bool transparent_background;
|
||||
uniform bool svg_source;
|
||||
|
||||
varying vec2 tex_coords;
|
||||
|
||||
void main()
|
||||
vec4 svg_color()
|
||||
{
|
||||
// takes foreground from texture
|
||||
vec4 fore_color = texture2D(texture, tex_coords);
|
||||
|
||||
// calculates radial gradient
|
||||
vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(tex_coords.xy) - vec2(0.5)))));
|
||||
|
||||
vec4 fore_color = texture2D(texture, tex_coords);
|
||||
|
||||
// blends foreground with background
|
||||
gl_FragColor = vec4(mix(back_color, fore_color.rgb, fore_color.a), transparent_background ? fore_color.a : 1.0);
|
||||
return vec4(mix(back_color, fore_color.rgb, fore_color.a), transparent_background ? fore_color.a : 1.0);
|
||||
}
|
||||
|
||||
vec4 non_svg_color()
|
||||
{
|
||||
// takes foreground from texture
|
||||
vec4 color = texture2D(texture, tex_coords);
|
||||
return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = svg_source ? svg_color() : non_svg_color();
|
||||
}
|
|
@ -15,6 +15,7 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
|
|||
#define INTENSITY_AMBIENT 0.3
|
||||
|
||||
uniform mat4 volume_world_matrix;
|
||||
uniform float object_max_z;
|
||||
|
||||
// x = tainted, y = specular;
|
||||
varying vec2 intensity;
|
||||
|
@ -42,6 +43,12 @@ void main()
|
|||
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
|
||||
|
||||
// Scaled to widths of the Z texture.
|
||||
if (object_max_z > 0.0)
|
||||
// when rendering the overlay
|
||||
object_z = object_max_z * gl_MultiTexCoord0.y;
|
||||
else
|
||||
// when rendering the volumes
|
||||
object_z = (volume_world_matrix * gl_Vertex).z;
|
||||
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
add_subdirectory(slabasebed)
|
||||
add_subdirectory(slasupporttree)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <libslic3r/libslic3r.h>
|
||||
#include <libslic3r/TriangleMesh.hpp>
|
||||
#include <libslic3r/Tesselate.hpp>
|
||||
#include <libslic3r/ClipperUtils.hpp>
|
||||
#include <libslic3r/SLA/SLABasePool.hpp>
|
||||
#include <libslic3r/SLA/SLABoilerPlate.hpp>
|
||||
#include <libnest2d/tools/benchmark.h>
|
||||
|
@ -15,7 +16,8 @@ const std::string USAGE_STR = {
|
|||
|
||||
namespace Slic3r { namespace sla {
|
||||
|
||||
Contour3D create_base_pool(const ExPolygons &ground_layer,
|
||||
Contour3D create_base_pool(const Polygons &ground_layer,
|
||||
const ExPolygons &holes = {},
|
||||
const PoolConfig& cfg = PoolConfig());
|
||||
|
||||
Contour3D walls(const Polygon& floor_plate, const Polygon& ceiling,
|
||||
|
@ -43,36 +45,27 @@ int main(const int argc, const char *argv[]) {
|
|||
model.align_to_origin();
|
||||
|
||||
ExPolygons ground_slice;
|
||||
sla::Contour3D mesh;
|
||||
// TriangleMesh basepool;
|
||||
|
||||
sla::base_plate(model, ground_slice, 0.1f);
|
||||
|
||||
if(ground_slice.empty()) return EXIT_FAILURE;
|
||||
|
||||
// ExPolygon bottom_plate = ground_slice.front();
|
||||
// ExPolygon top_plate = bottom_plate;
|
||||
// sla::offset(top_plate, coord_t(3.0/SCALING_FACTOR));
|
||||
// sla::offset(bottom_plate, coord_t(1.0/SCALING_FACTOR));
|
||||
ground_slice = offset_ex(ground_slice, 0.5);
|
||||
ExPolygon gndfirst; gndfirst = ground_slice.front();
|
||||
sla::breakstick_holes(gndfirst, 0.5, 10, 0.3);
|
||||
|
||||
sla::Contour3D mesh;
|
||||
|
||||
bench.start();
|
||||
|
||||
// TriangleMesh pool;
|
||||
sla::PoolConfig cfg;
|
||||
cfg.min_wall_height_mm = 0;
|
||||
cfg.edge_radius_mm = 0.2;
|
||||
mesh = sla::create_base_pool(ground_slice, cfg);
|
||||
|
||||
// mesh.merge(triangulate_expolygon_3d(top_plate, 3.0, false));
|
||||
// mesh.merge(triangulate_expolygon_3d(bottom_plate, 0.0, true));
|
||||
// mesh = sla::walls(bottom_plate.contour, top_plate.contour, 0, 3, 2.0, [](){});
|
||||
cfg.edge_radius_mm = 0;
|
||||
mesh = sla::create_base_pool(to_polygons(ground_slice), {}, cfg);
|
||||
|
||||
bench.stop();
|
||||
|
||||
cout << "Base pool creation time: " << std::setprecision(10)
|
||||
<< bench.getElapsedSec() << " seconds." << endl;
|
||||
|
||||
// auto point = []()
|
||||
for(auto& trind : mesh.indices) {
|
||||
Vec3d p0 = mesh.points[size_t(trind[0])];
|
||||
Vec3d p1 = mesh.points[size_t(trind[1])];
|
||||
|
@ -83,7 +76,7 @@ int main(const int argc, const char *argv[]) {
|
|||
if(std::abs(a) < 1e-6) std::cout << "degenerate triangle" << std::endl;
|
||||
}
|
||||
|
||||
// basepool.write_ascii("out.stl");
|
||||
// basepool.write_ascii("out.stl");
|
||||
|
||||
std::fstream outstream("out.obj", std::fstream::out);
|
||||
mesh.to_obj(outstream);
|
||||
|
|
2
sandboxes/slasupporttree/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
add_executable(slasupporttree slasupporttree.cpp)
|
||||
target_link_libraries(slasupporttree libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES} ${CMAKE_DL_LIBS})
|
42
sandboxes/slasupporttree/slasupporttree.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include <libslic3r/libslic3r.h>
|
||||
#include <libslic3r/Model.hpp>
|
||||
#include <libslic3r/Tesselate.hpp>
|
||||
#include <libslic3r/ClipperUtils.hpp>
|
||||
#include <libslic3r/SLA/SLAAutoSupports.hpp>
|
||||
#include <libslic3r/SLA/SLASupportTree.hpp>
|
||||
#include <libslic3r/SLAPrint.hpp>
|
||||
#include <libslic3r/MTUtils.hpp>
|
||||
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <tbb/mutex.h>
|
||||
#include <future>
|
||||
|
||||
const std::string USAGE_STR = {
|
||||
"Usage: slasupporttree stlfilename.stl"
|
||||
};
|
||||
|
||||
int main(const int argc, const char *argv[]) {
|
||||
using namespace Slic3r;
|
||||
using std::cout; using std::endl;
|
||||
|
||||
if(argc < 2) {
|
||||
cout << USAGE_STR << endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
DynamicPrintConfig config;
|
||||
|
||||
Model model = Model::read_from_file(argv[1], &config);
|
||||
|
||||
SLAPrint print;
|
||||
|
||||
print.apply(model, config);
|
||||
print.process();
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
project(PrusaSlicer-native)
|
||||
|
||||
add_subdirectory(build-utils)
|
||||
add_subdirectory(admesh)
|
||||
add_subdirectory(avrdude)
|
||||
# boost/nowide
|
||||
|
@ -12,14 +13,12 @@ add_subdirectory(poly2tri)
|
|||
add_subdirectory(qhull)
|
||||
add_subdirectory(Shiny)
|
||||
add_subdirectory(semver)
|
||||
add_subdirectory(libigl)
|
||||
|
||||
# Adding libnest2d project for bin packing...
|
||||
set(LIBNEST2D_UNITTESTS ON CACHE BOOL "Force generating unittests for libnest2d")
|
||||
add_subdirectory(libnest2d)
|
||||
|
||||
include_directories(${LIBDIR}/qhull/src)
|
||||
#message(STATUS ${LIBDIR}/qhull/src)
|
||||
|
||||
add_subdirectory(libslic3r)
|
||||
|
||||
if (SLIC3R_GUI)
|
||||
|
@ -49,7 +48,7 @@ if (SLIC3R_GUI)
|
|||
endif ()
|
||||
endif ()
|
||||
else ()
|
||||
find_package(wxWidgets 3.1 REQUIRED COMPONENTS base core adv html gl)
|
||||
find_package(wxWidgets 3.1 REQUIRED COMPONENTS html adv gl core base)
|
||||
endif ()
|
||||
|
||||
if(UNIX)
|
||||
|
@ -58,6 +57,9 @@ if (SLIC3R_GUI)
|
|||
|
||||
include(${wxWidgets_USE_FILE})
|
||||
|
||||
# list(REMOVE_ITEM wxWidgets_LIBRARIES oleacc)
|
||||
message(STATUS "wx libs: ${wxWidgets_LIBRARIES}")
|
||||
|
||||
add_subdirectory(slic3r)
|
||||
endif()
|
||||
|
||||
|
@ -67,17 +69,23 @@ endif()
|
|||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/platform/msw/PrusaSlicer.rc.in ${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer.rc @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/platform/msw/PrusaSlicer.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer.manifest @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/platform/osx/Info.plist.in ${CMAKE_CURRENT_BINARY_DIR}/Info.plist @ONLY)
|
||||
if (MSVC)
|
||||
if (WIN32)
|
||||
add_library(PrusaSlicer SHARED PrusaSlicer.cpp PrusaSlicer.hpp)
|
||||
else ()
|
||||
add_executable(PrusaSlicer PrusaSlicer.cpp PrusaSlicer.hpp)
|
||||
endif ()
|
||||
if (NOT MSVC)
|
||||
|
||||
if (MINGW)
|
||||
target_link_options(PrusaSlicer PUBLIC "-Wl,-allow-multiple-definition")
|
||||
set_target_properties(PrusaSlicer PROPERTIES PREFIX "")
|
||||
endif (MINGW)
|
||||
|
||||
if (NOT WIN32)
|
||||
# Binary name on unix like systems (OSX, Linux)
|
||||
set_target_properties(PrusaSlicer PROPERTIES OUTPUT_NAME "prusa-slicer")
|
||||
endif ()
|
||||
|
||||
target_link_libraries(PrusaSlicer libslic3r)
|
||||
target_link_libraries(PrusaSlicer libslic3r cereal)
|
||||
if (APPLE)
|
||||
# add_compile_options(-stdlib=libc++)
|
||||
# add_definitions(-DBOOST_THREAD_DONT_USE_CHRONO -DBOOST_NO_CXX11_RVALUE_REFERENCES -DBOOST_THREAD_USES_MOVE)
|
||||
|
@ -93,11 +101,12 @@ endif ()
|
|||
|
||||
# Add the Slic3r GUI library, libcurl, OpenGL and GLU libraries.
|
||||
if (SLIC3R_GUI)
|
||||
target_link_libraries(PrusaSlicer libslic3r_gui ${wxWidgets_LIBRARIES})
|
||||
# target_link_libraries(PrusaSlicer ws2_32 uxtheme setupapi libslic3r_gui ${wxWidgets_LIBRARIES})
|
||||
target_link_libraries(PrusaSlicer libslic3r_gui ${wxWidgets_LIBRARIES})
|
||||
|
||||
# Configure libcurl and its dependencies OpenSSL & zlib
|
||||
find_package(CURL REQUIRED)
|
||||
if (NOT MSVC)
|
||||
if (NOT WIN32)
|
||||
# Required by libcurl
|
||||
find_package(ZLIB REQUIRED)
|
||||
endif()
|
||||
|
@ -125,7 +134,7 @@ if (SLIC3R_GUI)
|
|||
target_link_options(PrusaSlicer PUBLIC "$<$<CONFIG:RELEASE>:/DEBUG>")
|
||||
target_link_libraries(PrusaSlicer user32.lib Setupapi.lib OpenGL32.Lib GlU32.Lib)
|
||||
elseif (MINGW)
|
||||
target_link_libraries(PrusaSlicer -lopengl32)
|
||||
target_link_libraries(PrusaSlicer opengl32 ws2_32 uxtheme setupapi)
|
||||
elseif (APPLE)
|
||||
target_link_libraries(PrusaSlicer "-framework OpenGL")
|
||||
else ()
|
||||
|
@ -135,26 +144,34 @@ endif ()
|
|||
|
||||
# On Windows, a shim application is required to produce a console / non console version of the Slic3r application.
|
||||
# Also the shim may load the Mesa software OpenGL renderer if the default renderer does not support OpenGL 2.0 and higher.
|
||||
if (MSVC)
|
||||
if (WIN32)
|
||||
if (MINGW)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode")
|
||||
endif()
|
||||
|
||||
add_executable(PrusaSlicer_app_gui WIN32 PrusaSlicer_app_msvc.cpp ${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer.rc)
|
||||
# Generate debug symbols even in release mode.
|
||||
if(MSVC)
|
||||
target_link_options(PrusaSlicer_app_gui PUBLIC "$<$<CONFIG:RELEASE>:/DEBUG>")
|
||||
endif()
|
||||
target_compile_definitions(PrusaSlicer_app_gui PRIVATE -DSLIC3R_WRAPPER_NOCONSOLE)
|
||||
add_dependencies(PrusaSlicer_app_gui PrusaSlicer)
|
||||
set_target_properties(PrusaSlicer_app_gui PROPERTIES OUTPUT_NAME "prusa-slicer")
|
||||
target_include_directories(PrusaSlicer_app_gui SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(PrusaSlicer_app_gui PRIVATE boost_headeronly)
|
||||
|
||||
add_executable(PrusaSlicer_app_console PrusaSlicer_app_msvc.cpp ${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer.rc)
|
||||
# Generate debug symbols even in release mode.
|
||||
if (MSVC)
|
||||
target_link_options(PrusaSlicer_app_console PUBLIC "$<$<CONFIG:RELEASE>:/DEBUG>")
|
||||
endif ()
|
||||
target_compile_definitions(PrusaSlicer_app_console PRIVATE -DSLIC3R_WRAPPER_CONSOLE)
|
||||
add_dependencies(PrusaSlicer_app_console PrusaSlicer)
|
||||
set_target_properties(PrusaSlicer_app_console PROPERTIES OUTPUT_NAME "prusa-slicer-console")
|
||||
target_include_directories(PrusaSlicer_app_console SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(PrusaSlicer_app_console PRIVATE boost_headeronly)
|
||||
endif ()
|
||||
|
||||
# Link the resources dir to where Slic3r GUI expects it
|
||||
if (MSVC)
|
||||
if (WIN32)
|
||||
if (CMAKE_CONFIGURATION_TYPES)
|
||||
foreach (CONF ${CMAKE_CONFIGURATION_TYPES})
|
||||
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${CONF}" WIN_CONF_OUTPUT_DIR)
|
||||
|
|
|
@ -7,10 +7,13 @@
|
|||
#include <Windows.h>
|
||||
#include <wchar.h>
|
||||
#ifdef SLIC3R_GUI
|
||||
extern "C"
|
||||
{
|
||||
// Let the NVIDIA and AMD know we want to use their graphics card
|
||||
// on a dual graphics card system.
|
||||
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||
}
|
||||
#endif /* SLIC3R_GUI */
|
||||
#endif /* WIN32 */
|
||||
|
||||
|
@ -23,6 +26,7 @@
|
|||
#include <boost/nowide/args.hpp>
|
||||
#include <boost/nowide/cenv.hpp>
|
||||
#include <boost/nowide/iostream.hpp>
|
||||
#include <boost/nowide/integration/filesystem.hpp>
|
||||
|
||||
#include "unix/fhs.hpp" // Generated by CMake from ../platform/unix/fhs.hpp.in
|
||||
|
||||
|
@ -44,6 +48,7 @@
|
|||
#ifdef SLIC3R_GUI
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#endif /* SLIC3R_GUI */
|
||||
|
||||
using namespace Slic3r;
|
||||
|
@ -56,6 +61,26 @@ PrinterTechnology get_printer_technology(const DynamicConfig &config)
|
|||
|
||||
int CLI::run(int argc, char **argv)
|
||||
{
|
||||
// Switch boost::filesystem to utf8.
|
||||
try {
|
||||
boost::nowide::nowide_filesystem();
|
||||
} catch (const std::runtime_error& ex) {
|
||||
std::string caption = std::string(SLIC3R_APP_NAME) + " Error";
|
||||
std::string text = std::string("An error occured while setting up locale.\n") + (
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
// likely some linux system
|
||||
"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n"
|
||||
#endif
|
||||
SLIC3R_APP_NAME " will now terminate.\n\n") + ex.what();
|
||||
#if defined(_WIN32) && defined(SLIC3R_GUI)
|
||||
if (m_actions.empty())
|
||||
// Empty actions means Slicer is executed in the GUI mode. Show a GUI message.
|
||||
MessageBoxA(NULL, text.c_str(), caption.c_str(), MB_OK | MB_ICONERROR);
|
||||
#endif
|
||||
boost::nowide::cerr << text.c_str() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (! this->setup(argc, argv))
|
||||
return 1;
|
||||
|
||||
|
@ -91,7 +116,7 @@ int CLI::run(int argc, char **argv)
|
|||
PrinterTechnology other_printer_technology = get_printer_technology(config);
|
||||
if (printer_technology == ptUnknown) {
|
||||
printer_technology = other_printer_technology;
|
||||
} else if (printer_technology != other_printer_technology) {
|
||||
} else if (printer_technology != other_printer_technology && other_printer_technology != ptUnknown) {
|
||||
boost::nowide::cerr << "Mixing configurations for FFF and SLA technologies" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
@ -111,7 +136,7 @@ int CLI::run(int argc, char **argv)
|
|||
PrinterTechnology other_printer_technology = get_printer_technology(m_print_config);
|
||||
if (printer_technology == ptUnknown) {
|
||||
printer_technology = other_printer_technology;
|
||||
} else if (printer_technology != other_printer_technology) {
|
||||
} else if (printer_technology != other_printer_technology && other_printer_technology != ptUnknown) {
|
||||
boost::nowide::cerr << "Mixing configurations for FFF and SLA technologies" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
@ -241,7 +266,6 @@ int CLI::run(int argc, char **argv)
|
|||
} else if (opt_key == "cut" || opt_key == "cut_x" || opt_key == "cut_y") {
|
||||
std::vector<Model> new_models;
|
||||
for (auto &model : m_models) {
|
||||
model.repair();
|
||||
model.translate(0, 0, -model.bounding_box().min.z()); // align to z = 0
|
||||
size_t num_objects = model.objects.size();
|
||||
for (size_t i = 0; i < num_objects; ++ i) {
|
||||
|
@ -301,8 +325,9 @@ int CLI::run(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
} else if (opt_key == "repair") {
|
||||
for (auto &model : m_models)
|
||||
model.repair();
|
||||
// Models are repaired by default.
|
||||
//for (auto &model : m_models)
|
||||
// model.repair();
|
||||
} else {
|
||||
boost::nowide::cerr << "error: option not implemented yet: " << opt_key << std::endl;
|
||||
return 1;
|
||||
|
@ -406,7 +431,7 @@ int CLI::run(int argc, char **argv)
|
|||
outfile_final = sla_print.print_statistics().finalize_output_path(outfile);
|
||||
sla_print.export_raster(outfile_final);
|
||||
}
|
||||
if (outfile != outfile_final && Slic3r::rename_file(outfile, outfile_final) != 0) {
|
||||
if (outfile != outfile_final && Slic3r::rename_file(outfile, outfile_final)) {
|
||||
boost::nowide::cerr << "Renaming file " << outfile << " to " << outfile_final << " failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
@ -481,7 +506,10 @@ int CLI::run(int argc, char **argv)
|
|||
if (! m_extra_config.empty())
|
||||
gui->mainframe->load_config(m_extra_config);
|
||||
});
|
||||
return wxEntry(argc, argv);
|
||||
int result = wxEntry(argc, argv);
|
||||
//FIXME this is a workaround for the PrusaSlicer 2.1 release.
|
||||
_3DScene::destroy();
|
||||
return result;
|
||||
#else /* SLIC3R_GUI */
|
||||
// No GUI support. Just print out a help.
|
||||
this->print_help(false);
|
||||
|
@ -496,6 +524,7 @@ int CLI::run(int argc, char **argv)
|
|||
bool CLI::setup(int argc, char **argv)
|
||||
{
|
||||
{
|
||||
Slic3r::set_logging_level(1);
|
||||
const char *loglevel = boost::nowide::getenv("SLIC3R_LOGLEVEL");
|
||||
if (loglevel != nullptr) {
|
||||
if (loglevel[0] >= '0' && loglevel[0] <= '9' && loglevel[1] == 0)
|
||||
|
@ -576,7 +605,7 @@ void CLI::print_help(bool include_print_options, PrinterTechnology printer_techn
|
|||
#endif /* SLIC3R_GUI */
|
||||
<< std::endl
|
||||
<< "https://github.com/prusa3d/PrusaSlicer" << std::endl << std::endl
|
||||
<< "Usage: slic3r [ ACTIONS ] [ TRANSFORM ] [ OPTIONS ] [ file.stl ... ]" << std::endl
|
||||
<< "Usage: prusa-slicer [ ACTIONS ] [ TRANSFORM ] [ OPTIONS ] [ file.stl ... ]" << std::endl
|
||||
<< std::endl
|
||||
<< "Actions:" << std::endl;
|
||||
cli_actions_config_def.print_cli_help(boost::nowide::cout, false);
|
||||
|
@ -648,7 +677,7 @@ std::string CLI::output_filepath(const Model &model, IO::ExportFormat format) co
|
|||
return proposed_path.string();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
extern "C" {
|
||||
__declspec(dllexport) int __stdcall slic3r_main(int argc, wchar_t **argv)
|
||||
{
|
||||
|
|
|
@ -8,10 +8,13 @@
|
|||
#include <wchar.h>
|
||||
|
||||
#ifdef SLIC3R_GUI
|
||||
extern "C"
|
||||
{
|
||||
// Let the NVIDIA and AMD know we want to use their graphics card
|
||||
// on a dual graphics card system.
|
||||
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||
}
|
||||
#endif /* SLIC3R_GUI */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -202,6 +205,8 @@ extern "C" {
|
|||
Slic3rMainFunc slic3r_main = nullptr;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
#ifdef SLIC3R_WRAPPER_NOCONSOLE
|
||||
int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */)
|
||||
{
|
||||
|
@ -295,3 +300,4 @@ int wmain(int argc, wchar_t **argv)
|
|||
// argc minus the trailing nullptr of the argv
|
||||
return slic3r_main((int)argv_extended.size() - 1, argv_extended.data());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,4 +11,4 @@ add_library(admesh STATIC
|
|||
util.cpp
|
||||
)
|
||||
|
||||
target_include_directories(admesh SYSTEM PRIVATE ${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(admesh PRIVATE boost_headeronly)
|
||||
|
|
|
@ -25,209 +25,50 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
// Boost pool: Don't use mutexes to synchronize memory allocation.
|
||||
#define BOOST_POOL_NO_MT
|
||||
#include <boost/pool/object_pool.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
static int stl_check_normal_vector(stl_file *stl, int facet_num, int normal_fix_flag);
|
||||
static void reverse_facet(stl_file *stl, int facet_num)
|
||||
{
|
||||
++ stl->stats.facets_reversed;
|
||||
|
||||
static void
|
||||
stl_reverse_facet(stl_file *stl, int facet_num) {
|
||||
stl_vertex tmp_vertex;
|
||||
/* int tmp_neighbor;*/
|
||||
int neighbor[3];
|
||||
int vnot[3];
|
||||
int neighbor[3] = { stl->neighbors_start[facet_num].neighbor[0], stl->neighbors_start[facet_num].neighbor[1], stl->neighbors_start[facet_num].neighbor[2] };
|
||||
int vnot[3] = { stl->neighbors_start[facet_num].which_vertex_not[0], stl->neighbors_start[facet_num].which_vertex_not[1], stl->neighbors_start[facet_num].which_vertex_not[2] };
|
||||
|
||||
stl->stats.facets_reversed += 1;
|
||||
|
||||
neighbor[0] = stl->neighbors_start[facet_num].neighbor[0];
|
||||
neighbor[1] = stl->neighbors_start[facet_num].neighbor[1];
|
||||
neighbor[2] = stl->neighbors_start[facet_num].neighbor[2];
|
||||
vnot[0] = stl->neighbors_start[facet_num].which_vertex_not[0];
|
||||
vnot[1] = stl->neighbors_start[facet_num].which_vertex_not[1];
|
||||
vnot[2] = stl->neighbors_start[facet_num].which_vertex_not[2];
|
||||
|
||||
/* reverse the facet */
|
||||
tmp_vertex = stl->facet_start[facet_num].vertex[0];
|
||||
stl->facet_start[facet_num].vertex[0] =
|
||||
stl->facet_start[facet_num].vertex[1];
|
||||
// reverse the facet
|
||||
stl_vertex tmp_vertex = stl->facet_start[facet_num].vertex[0];
|
||||
stl->facet_start[facet_num].vertex[0] = stl->facet_start[facet_num].vertex[1];
|
||||
stl->facet_start[facet_num].vertex[1] = tmp_vertex;
|
||||
|
||||
/* fix the vnots of the neighboring facets */
|
||||
if(neighbor[0] != -1)
|
||||
stl->neighbors_start[neighbor[0]].which_vertex_not[(vnot[0] + 1) % 3] =
|
||||
(stl->neighbors_start[neighbor[0]].
|
||||
which_vertex_not[(vnot[0] + 1) % 3] + 3) % 6;
|
||||
if(neighbor[1] != -1)
|
||||
stl->neighbors_start[neighbor[1]].which_vertex_not[(vnot[1] + 1) % 3] =
|
||||
(stl->neighbors_start[neighbor[1]].
|
||||
which_vertex_not[(vnot[1] + 1) % 3] + 4) % 6;
|
||||
if(neighbor[2] != -1)
|
||||
stl->neighbors_start[neighbor[2]].which_vertex_not[(vnot[2] + 1) % 3] =
|
||||
(stl->neighbors_start[neighbor[2]].
|
||||
which_vertex_not[(vnot[2] + 1) % 3] + 2) % 6;
|
||||
// fix the vnots of the neighboring facets
|
||||
if (neighbor[0] != -1)
|
||||
stl->neighbors_start[neighbor[0]].which_vertex_not[(vnot[0] + 1) % 3] = (stl->neighbors_start[neighbor[0]].which_vertex_not[(vnot[0] + 1) % 3] + 3) % 6;
|
||||
if (neighbor[1] != -1)
|
||||
stl->neighbors_start[neighbor[1]].which_vertex_not[(vnot[1] + 1) % 3] = (stl->neighbors_start[neighbor[1]].which_vertex_not[(vnot[1] + 1) % 3] + 4) % 6;
|
||||
if (neighbor[2] != -1)
|
||||
stl->neighbors_start[neighbor[2]].which_vertex_not[(vnot[2] + 1) % 3] = (stl->neighbors_start[neighbor[2]].which_vertex_not[(vnot[2] + 1) % 3] + 2) % 6;
|
||||
|
||||
/* swap the neighbors of the facet that is being reversed */
|
||||
// swap the neighbors of the facet that is being reversed
|
||||
stl->neighbors_start[facet_num].neighbor[1] = neighbor[2];
|
||||
stl->neighbors_start[facet_num].neighbor[2] = neighbor[1];
|
||||
|
||||
/* swap the vnots of the facet that is being reversed */
|
||||
// swap the vnots of the facet that is being reversed
|
||||
stl->neighbors_start[facet_num].which_vertex_not[1] = vnot[2];
|
||||
stl->neighbors_start[facet_num].which_vertex_not[2] = vnot[1];
|
||||
|
||||
/* reverse the values of the vnots of the facet that is being reversed */
|
||||
stl->neighbors_start[facet_num].which_vertex_not[0] =
|
||||
(stl->neighbors_start[facet_num].which_vertex_not[0] + 3) % 6;
|
||||
stl->neighbors_start[facet_num].which_vertex_not[1] =
|
||||
(stl->neighbors_start[facet_num].which_vertex_not[1] + 3) % 6;
|
||||
stl->neighbors_start[facet_num].which_vertex_not[2] =
|
||||
(stl->neighbors_start[facet_num].which_vertex_not[2] + 3) % 6;
|
||||
// reverse the values of the vnots of the facet that is being reversed
|
||||
stl->neighbors_start[facet_num].which_vertex_not[0] = (stl->neighbors_start[facet_num].which_vertex_not[0] + 3) % 6;
|
||||
stl->neighbors_start[facet_num].which_vertex_not[1] = (stl->neighbors_start[facet_num].which_vertex_not[1] + 3) % 6;
|
||||
stl->neighbors_start[facet_num].which_vertex_not[2] = (stl->neighbors_start[facet_num].which_vertex_not[2] + 3) % 6;
|
||||
}
|
||||
|
||||
void
|
||||
stl_fix_normal_directions(stl_file *stl) {
|
||||
char *norm_sw;
|
||||
/* int edge_num;*/
|
||||
/* int vnot;*/
|
||||
int checked = 0;
|
||||
int facet_num;
|
||||
/* int next_facet;*/
|
||||
int i;
|
||||
int j;
|
||||
struct stl_normal {
|
||||
int facet_num;
|
||||
struct stl_normal *next;
|
||||
};
|
||||
struct stl_normal *head;
|
||||
struct stl_normal *tail;
|
||||
struct stl_normal *newn;
|
||||
struct stl_normal *temp;
|
||||
|
||||
int* reversed_ids;
|
||||
int reversed_count = 0;
|
||||
int id;
|
||||
int force_exit = 0;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
// this may happen for malformed models, see: https://github.com/prusa3d/PrusaSlicer/issues/2209
|
||||
if (stl->stats.number_of_facets == 0) return;
|
||||
|
||||
/* Initialize linked list. */
|
||||
head = (struct stl_normal*)malloc(sizeof(struct stl_normal));
|
||||
if(head == NULL) perror("stl_fix_normal_directions");
|
||||
tail = (struct stl_normal*)malloc(sizeof(struct stl_normal));
|
||||
if(tail == NULL) perror("stl_fix_normal_directions");
|
||||
head->next = tail;
|
||||
tail->next = tail;
|
||||
|
||||
/* Initialize list that keeps track of already fixed facets. */
|
||||
norm_sw = (char*)calloc(stl->stats.number_of_facets, sizeof(char));
|
||||
if(norm_sw == NULL) perror("stl_fix_normal_directions");
|
||||
|
||||
/* Initialize list that keeps track of reversed facets. */
|
||||
reversed_ids = (int*)calloc(stl->stats.number_of_facets, sizeof(int));
|
||||
if (reversed_ids == NULL) perror("stl_fix_normal_directions reversed_ids");
|
||||
|
||||
facet_num = 0;
|
||||
/* If normal vector is not within tolerance and backwards:
|
||||
Arbitrarily starts at face 0. If this one is wrong, we're screwed. Thankfully, the chances
|
||||
of it being wrong randomly are low if most of the triangles are right: */
|
||||
if (stl_check_normal_vector(stl, 0, 0) == 2) {
|
||||
stl_reverse_facet(stl, 0);
|
||||
reversed_ids[reversed_count++] = 0;
|
||||
}
|
||||
|
||||
/* Say that we've fixed this facet: */
|
||||
norm_sw[facet_num] = 1;
|
||||
checked++;
|
||||
|
||||
for(;;) {
|
||||
/* Add neighbors_to_list.
|
||||
Add unconnected neighbors to the list:a */
|
||||
for(j = 0; j < 3; j++) {
|
||||
/* Reverse the neighboring facets if necessary. */
|
||||
if(stl->neighbors_start[facet_num].which_vertex_not[j] > 2) {
|
||||
/* If the facet has a neighbor that is -1, it means that edge isn't shared by another facet */
|
||||
if(stl->neighbors_start[facet_num].neighbor[j] != -1) {
|
||||
if (norm_sw[stl->neighbors_start[facet_num].neighbor[j]] == 1) {
|
||||
/* trying to modify a facet already marked as fixed, revert all changes made until now and exit (fixes: #716, #574, #413, #269, #262, #259, #230, #228, #206) */
|
||||
for (id = reversed_count - 1; id >= 0; --id) {
|
||||
stl_reverse_facet(stl, reversed_ids[id]);
|
||||
}
|
||||
force_exit = 1;
|
||||
break;
|
||||
} else {
|
||||
stl_reverse_facet(stl, stl->neighbors_start[facet_num].neighbor[j]);
|
||||
reversed_ids[reversed_count++] = stl->neighbors_start[facet_num].neighbor[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If this edge of the facet is connected: */
|
||||
if(stl->neighbors_start[facet_num].neighbor[j] != -1) {
|
||||
/* If we haven't fixed this facet yet, add it to the list: */
|
||||
if(norm_sw[stl->neighbors_start[facet_num].neighbor[j]] != 1) {
|
||||
/* Add node to beginning of list. */
|
||||
newn = (struct stl_normal*)malloc(sizeof(struct stl_normal));
|
||||
if(newn == NULL) perror("stl_fix_normal_directions");
|
||||
newn->facet_num = stl->neighbors_start[facet_num].neighbor[j];
|
||||
newn->next = head->next;
|
||||
head->next = newn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* an error occourred, quit the for loop and exit */
|
||||
if (force_exit) break;
|
||||
|
||||
/* Get next facet to fix from top of list. */
|
||||
if(head->next != tail) {
|
||||
facet_num = head->next->facet_num;
|
||||
if(norm_sw[facet_num] != 1) { /* If facet is in list mutiple times */
|
||||
norm_sw[facet_num] = 1; /* Record this one as being fixed. */
|
||||
checked++;
|
||||
}
|
||||
temp = head->next; /* Delete this facet from the list. */
|
||||
head->next = head->next->next;
|
||||
free(temp);
|
||||
} else { /* if we ran out of facets to fix: */
|
||||
/* All of the facets in this part have been fixed. */
|
||||
stl->stats.number_of_parts += 1;
|
||||
if(checked >= stl->stats.number_of_facets) {
|
||||
/* All of the facets have been checked. Bail out. */
|
||||
break;
|
||||
} else {
|
||||
/* There is another part here. Find it and continue. */
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
if(norm_sw[i] == 0) {
|
||||
/* This is the first facet of the next part. */
|
||||
facet_num = i;
|
||||
if(stl_check_normal_vector(stl, i, 0) == 2) {
|
||||
stl_reverse_facet(stl, i);
|
||||
reversed_ids[reversed_count++] = i;
|
||||
}
|
||||
|
||||
norm_sw[facet_num] = 1;
|
||||
checked++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(head);
|
||||
free(tail);
|
||||
free(reversed_ids);
|
||||
free(norm_sw);
|
||||
}
|
||||
|
||||
static int stl_check_normal_vector(stl_file *stl, int facet_num, int normal_fix_flag) {
|
||||
/* Returns 0 if the normal is within tolerance */
|
||||
/* Returns 1 if the normal is not within tolerance, but direction is OK */
|
||||
/* Returns 2 if the normal is not within tolerance and backwards */
|
||||
/* Returns 4 if the status is unknown. */
|
||||
|
||||
stl_facet *facet;
|
||||
|
||||
facet = &stl->facet_start[facet_num];
|
||||
// Returns true if the normal was flipped.
|
||||
static bool check_normal_vector(stl_file *stl, int facet_num, int normal_fix_flag)
|
||||
{
|
||||
stl_facet *facet = &stl->facet_start[facet_num];
|
||||
|
||||
stl_normal normal;
|
||||
stl_calculate_normal(normal, facet);
|
||||
|
@ -236,58 +77,160 @@ static int stl_check_normal_vector(stl_file *stl, int facet_num, int normal_fix_
|
|||
|
||||
const float eps = 0.001f;
|
||||
if (normal_dif(0) < eps && normal_dif(1) < eps && normal_dif(2) < eps) {
|
||||
/* It is not really necessary to change the values here */
|
||||
/* but just for consistency, I will. */
|
||||
// Normal is within tolerance. It is not really necessary to change the values here, but just for consistency, I will.
|
||||
facet->normal = normal;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
stl_normal test_norm = facet->normal;
|
||||
stl_normalize_vector(test_norm);
|
||||
normal_dif = (normal - test_norm).cwiseAbs();
|
||||
if (normal_dif(0) < eps && normal_dif(1) < eps && normal_dif(2) < eps) {
|
||||
if(normal_fix_flag) {
|
||||
// The normal is not within tolerance, but direction is OK.
|
||||
if (normal_fix_flag) {
|
||||
facet->normal = normal;
|
||||
stl->stats.normals_fixed += 1;
|
||||
++ stl->stats.normals_fixed;
|
||||
}
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
test_norm *= -1.f;
|
||||
normal_dif = (normal - test_norm).cwiseAbs();
|
||||
if (normal_dif(0) < eps && normal_dif(1) < eps && normal_dif(2) < eps) {
|
||||
// Facet is backwards.
|
||||
if(normal_fix_flag) {
|
||||
// The normal is not within tolerance and backwards.
|
||||
if (normal_fix_flag) {
|
||||
facet->normal = normal;
|
||||
stl->stats.normals_fixed += 1;
|
||||
++ stl->stats.normals_fixed;
|
||||
}
|
||||
return 2;
|
||||
return true;
|
||||
}
|
||||
if(normal_fix_flag) {
|
||||
if (normal_fix_flag) {
|
||||
facet->normal = normal;
|
||||
stl->stats.normals_fixed += 1;
|
||||
++ stl->stats.normals_fixed;
|
||||
}
|
||||
return 4;
|
||||
// Status is unknown.
|
||||
return false;
|
||||
}
|
||||
|
||||
void stl_fix_normal_values(stl_file *stl) {
|
||||
int i;
|
||||
void stl_fix_normal_directions(stl_file *stl)
|
||||
{
|
||||
// This may happen for malformed models, see: https://github.com/prusa3d/PrusaSlicer/issues/2209
|
||||
if (stl->stats.number_of_facets == 0)
|
||||
return;
|
||||
|
||||
if (stl->error) return;
|
||||
struct stl_normal {
|
||||
int facet_num;
|
||||
stl_normal *next;
|
||||
};
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
stl_check_normal_vector(stl, i, 1);
|
||||
// Initialize linked list.
|
||||
boost::object_pool<stl_normal> pool;
|
||||
stl_normal *head = pool.construct();
|
||||
stl_normal *tail = pool.construct();
|
||||
head->next = tail;
|
||||
tail->next = tail;
|
||||
|
||||
// Initialize list that keeps track of already fixed facets.
|
||||
std::vector<char> norm_sw(stl->stats.number_of_facets, 0);
|
||||
// Initialize list that keeps track of reversed facets.
|
||||
std::vector<int> reversed_ids(stl->stats.number_of_facets, 0);
|
||||
|
||||
int facet_num = 0;
|
||||
int reversed_count = 0;
|
||||
// If normal vector is not within tolerance and backwards:
|
||||
// Arbitrarily starts at face 0. If this one is wrong, we're screwed. Thankfully, the chances
|
||||
// of it being wrong randomly are low if most of the triangles are right:
|
||||
if (check_normal_vector(stl, 0, 0)) {
|
||||
reverse_facet(stl, 0);
|
||||
reversed_ids[reversed_count ++] = 0;
|
||||
}
|
||||
|
||||
// Say that we've fixed this facet:
|
||||
norm_sw[facet_num] = 1;
|
||||
int checked = 1;
|
||||
|
||||
for (;;) {
|
||||
// Add neighbors_to_list. Add unconnected neighbors to the list.
|
||||
bool force_exit = false;
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
// Reverse the neighboring facets if necessary.
|
||||
if (stl->neighbors_start[facet_num].which_vertex_not[j] > 2) {
|
||||
// If the facet has a neighbor that is -1, it means that edge isn't shared by another facet
|
||||
if (stl->neighbors_start[facet_num].neighbor[j] != -1) {
|
||||
if (norm_sw[stl->neighbors_start[facet_num].neighbor[j]] == 1) {
|
||||
// trying to modify a facet already marked as fixed, revert all changes made until now and exit (fixes: #716, #574, #413, #269, #262, #259, #230, #228, #206)
|
||||
for (int id = reversed_count - 1; id >= 0; -- id)
|
||||
reverse_facet(stl, reversed_ids[id]);
|
||||
force_exit = true;
|
||||
break;
|
||||
}
|
||||
reverse_facet(stl, stl->neighbors_start[facet_num].neighbor[j]);
|
||||
reversed_ids[reversed_count ++] = stl->neighbors_start[facet_num].neighbor[j];
|
||||
}
|
||||
}
|
||||
// If this edge of the facet is connected:
|
||||
if (stl->neighbors_start[facet_num].neighbor[j] != -1) {
|
||||
// If we haven't fixed this facet yet, add it to the list:
|
||||
if (norm_sw[stl->neighbors_start[facet_num].neighbor[j]] != 1) {
|
||||
// Add node to beginning of list.
|
||||
stl_normal *newn = pool.construct();
|
||||
newn->facet_num = stl->neighbors_start[facet_num].neighbor[j];
|
||||
newn->next = head->next;
|
||||
head->next = newn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// an error occourred, quit the for loop and exit
|
||||
if (force_exit)
|
||||
break;
|
||||
|
||||
// Get next facet to fix from top of list.
|
||||
if (head->next != tail) {
|
||||
facet_num = head->next->facet_num;
|
||||
if (norm_sw[facet_num] != 1) { // If facet is in list mutiple times
|
||||
norm_sw[facet_num] = 1; // Record this one as being fixed.
|
||||
++ checked;
|
||||
}
|
||||
stl_normal *temp = head->next; // Delete this facet from the list.
|
||||
head->next = head->next->next;
|
||||
// pool.destroy(temp);
|
||||
} else { // If we ran out of facets to fix: All of the facets in this part have been fixed.
|
||||
++ stl->stats.number_of_parts;
|
||||
if (checked >= stl->stats.number_of_facets)
|
||||
// All of the facets have been checked. Bail out.
|
||||
break;
|
||||
// There is another part here. Find it and continue.
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
if (norm_sw[i] == 0) {
|
||||
// This is the first facet of the next part.
|
||||
facet_num = i;
|
||||
if (check_normal_vector(stl, i, 0)) {
|
||||
reverse_facet(stl, i);
|
||||
reversed_ids[reversed_count++] = i;
|
||||
}
|
||||
norm_sw[facet_num] = 1;
|
||||
++ checked;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pool.destroy(head);
|
||||
// pool.destroy(tail);
|
||||
}
|
||||
|
||||
void stl_fix_normal_values(stl_file *stl)
|
||||
{
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
check_normal_vector(stl, i, 1);
|
||||
}
|
||||
|
||||
void stl_reverse_all_facets(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
stl_normal normal;
|
||||
for(int i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
stl_reverse_facet(stl, i);
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
reverse_facet(stl, i);
|
||||
stl_calculate_normal(normal, &stl->facet_start[i]);
|
||||
stl_normalize_vector(normal);
|
||||
stl->facet_start[i].normal = normal;
|
||||
|
|
|
@ -23,92 +23,60 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
void
|
||||
stl_invalidate_shared_vertices(stl_file *stl) {
|
||||
if (stl->error) return;
|
||||
void stl_generate_shared_vertices(stl_file *stl, indexed_triangle_set &its)
|
||||
{
|
||||
// 3 indices to vertex per face
|
||||
its.indices.assign(stl->stats.number_of_facets, stl_triangle_vertex_indices(-1, -1, -1));
|
||||
// Shared vertices (3D coordinates)
|
||||
its.vertices.clear();
|
||||
its.vertices.reserve(stl->stats.number_of_facets / 2);
|
||||
|
||||
if (stl->v_indices != NULL) {
|
||||
free(stl->v_indices);
|
||||
stl->v_indices = NULL;
|
||||
}
|
||||
if (stl->v_shared != NULL) {
|
||||
free(stl->v_shared);
|
||||
stl->v_shared = NULL;
|
||||
}
|
||||
}
|
||||
// A degenerate mesh may contain loops: Traversing a fan will end up in an endless loop
|
||||
// while never reaching the starting face. To avoid these endless loops, traversed faces at each fan traversal
|
||||
// are marked with a unique fan_traversal_stamp.
|
||||
unsigned int fan_traversal_stamp = 0;
|
||||
std::vector<unsigned int> fan_traversal_facet_visited(stl->stats.number_of_facets, 0);
|
||||
|
||||
void
|
||||
stl_generate_shared_vertices(stl_file *stl) {
|
||||
int i;
|
||||
int j;
|
||||
int first_facet;
|
||||
int direction;
|
||||
int facet_num;
|
||||
int vnot;
|
||||
int next_edge;
|
||||
int pivot_vertex;
|
||||
int next_facet;
|
||||
int reversed;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* make sure this function is idempotent and does not leak memory */
|
||||
stl_invalidate_shared_vertices(stl);
|
||||
|
||||
stl->v_indices = (v_indices_struct*)
|
||||
calloc(stl->stats.number_of_facets, sizeof(v_indices_struct));
|
||||
if(stl->v_indices == NULL) perror("stl_generate_shared_vertices");
|
||||
stl->v_shared = (stl_vertex*)
|
||||
calloc((stl->stats.number_of_facets / 2), sizeof(stl_vertex));
|
||||
if(stl->v_shared == NULL) perror("stl_generate_shared_vertices");
|
||||
stl->stats.shared_malloced = stl->stats.number_of_facets / 2;
|
||||
stl->stats.shared_vertices = 0;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
stl->v_indices[i].vertex[0] = -1;
|
||||
stl->v_indices[i].vertex[1] = -1;
|
||||
stl->v_indices[i].vertex[2] = -1;
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
first_facet = i;
|
||||
for(j = 0; j < 3; j++) {
|
||||
if(stl->v_indices[i].vertex[j] != -1) {
|
||||
for (uint32_t facet_idx = 0; facet_idx < stl->stats.number_of_facets; ++ facet_idx) {
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
if (its.indices[facet_idx][j] != -1)
|
||||
// Shared vertex was already assigned.
|
||||
continue;
|
||||
}
|
||||
if(stl->stats.shared_vertices == stl->stats.shared_malloced) {
|
||||
stl->stats.shared_malloced += 1024;
|
||||
stl->v_shared = (stl_vertex*)realloc(stl->v_shared,
|
||||
stl->stats.shared_malloced * sizeof(stl_vertex));
|
||||
if(stl->v_shared == NULL) perror("stl_generate_shared_vertices");
|
||||
}
|
||||
|
||||
stl->v_shared[stl->stats.shared_vertices] =
|
||||
stl->facet_start[i].vertex[j];
|
||||
|
||||
direction = 0;
|
||||
reversed = 0;
|
||||
facet_num = i;
|
||||
vnot = (j + 2) % 3;
|
||||
|
||||
for(;;) {
|
||||
if(vnot > 2) {
|
||||
if(direction == 0) {
|
||||
// Create a new shared vertex.
|
||||
its.vertices.emplace_back(stl->facet_start[facet_idx].vertex[j]);
|
||||
// Traverse the fan around the j-th vertex of the i-th face, assign the newly created shared vertex index to all the neighboring triangles in the triangle fan.
|
||||
int facet_in_fan_idx = facet_idx;
|
||||
bool edge_direction = false;
|
||||
bool traversal_reversed = false;
|
||||
int vnot = (j + 2) % 3;
|
||||
// Increase the
|
||||
++ fan_traversal_stamp;
|
||||
for (;;) {
|
||||
// Next edge on facet_in_fan_idx to be traversed. The edge is indexed by its starting vertex index.
|
||||
int next_edge = 0;
|
||||
// Vertex index in facet_in_fan_idx, which is being pivoted around, and which is being assigned a new shared vertex.
|
||||
int pivot_vertex = 0;
|
||||
if (vnot > 2) {
|
||||
// The edge of facet_in_fan_idx opposite to vnot is equally oriented, therefore
|
||||
// the neighboring facet is flipped.
|
||||
if (! edge_direction) {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
direction = 1;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot % 3;
|
||||
direction = 0;
|
||||
}
|
||||
edge_direction = ! edge_direction;
|
||||
} else {
|
||||
if(direction == 0) {
|
||||
// The neighboring facet is correctly oriented.
|
||||
if (! edge_direction) {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot;
|
||||
} else {
|
||||
|
@ -116,87 +84,73 @@ stl_generate_shared_vertices(stl_file *stl) {
|
|||
next_edge = pivot_vertex;
|
||||
}
|
||||
}
|
||||
stl->v_indices[facet_num].vertex[pivot_vertex] =
|
||||
stl->stats.shared_vertices;
|
||||
its.indices[facet_in_fan_idx][pivot_vertex] = its.vertices.size() - 1;
|
||||
fan_traversal_facet_visited[facet_in_fan_idx] = fan_traversal_stamp;
|
||||
|
||||
next_facet = stl->neighbors_start[facet_num].neighbor[next_edge];
|
||||
if(next_facet == -1) {
|
||||
if(reversed) {
|
||||
// next_edge is an index of the starting vertex of the edge, not an index of the opposite vertex to the edge!
|
||||
int next_facet = stl->neighbors_start[facet_in_fan_idx].neighbor[next_edge];
|
||||
if (next_facet == -1) {
|
||||
// No neighbor going in the current direction.
|
||||
if (traversal_reversed) {
|
||||
// Went to one limit, then turned back and reached the other limit. Quit the fan traversal.
|
||||
break;
|
||||
} else {
|
||||
direction = 1;
|
||||
// Reached the first limit. Now try to reverse and traverse up to the other limit.
|
||||
edge_direction = true;
|
||||
vnot = (j + 1) % 3;
|
||||
reversed = 1;
|
||||
facet_num = first_facet;
|
||||
traversal_reversed = true;
|
||||
facet_in_fan_idx = facet_idx;
|
||||
}
|
||||
} else if(next_facet != first_facet) {
|
||||
vnot = stl->neighbors_start[facet_num].
|
||||
which_vertex_not[next_edge];
|
||||
facet_num = next_facet;
|
||||
} else {
|
||||
} else if (next_facet == facet_idx) {
|
||||
// Traversed a closed fan all around.
|
||||
// assert(! traversal_reversed);
|
||||
break;
|
||||
} else if (next_facet >= (int)stl->stats.number_of_facets) {
|
||||
// The mesh is not valid!
|
||||
// assert(false);
|
||||
break;
|
||||
} else if (fan_traversal_facet_visited[next_facet] == fan_traversal_stamp) {
|
||||
// Traversed a closed fan all around, but did not reach the starting face.
|
||||
// This indicates an invalid geometry (non-manifold).
|
||||
//assert(false);
|
||||
break;
|
||||
} else {
|
||||
// Continue traversal.
|
||||
// next_edge is an index of the starting vertex of the edge, not an index of the opposite vertex to the edge!
|
||||
vnot = stl->neighbors_start[facet_in_fan_idx].which_vertex_not[next_edge];
|
||||
facet_in_fan_idx = next_facet;
|
||||
}
|
||||
}
|
||||
stl->stats.shared_vertices += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_off(stl_file *stl, const char *file) {
|
||||
int i;
|
||||
FILE *fp;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
bool its_write_off(const indexed_triangle_set &its, const char *file)
|
||||
{
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_ascii: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "OFF\n");
|
||||
fprintf(fp, "%d %d 0\n",
|
||||
stl->stats.shared_vertices, stl->stats.number_of_facets);
|
||||
|
||||
for(i = 0; i < stl->stats.shared_vertices; i++) {
|
||||
fprintf(fp, "\t%f %f %f\n",
|
||||
stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2));
|
||||
}
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
fprintf(fp, "\t3 %d %d %d\n", stl->v_indices[i].vertex[0],
|
||||
stl->v_indices[i].vertex[1], stl->v_indices[i].vertex[2]);
|
||||
}
|
||||
fprintf(fp, "%d %d 0\n", (int)its.vertices.size(), (int)its.indices.size());
|
||||
for (int i = 0; i < its.vertices.size(); ++ i)
|
||||
fprintf(fp, "\t%f %f %f\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2));
|
||||
for (uint32_t i = 0; i < its.indices.size(); ++ i)
|
||||
fprintf(fp, "\t3 %d %d %d\n", its.indices[i][0], its.indices[i][1], its.indices[i][2]);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_vrml(stl_file *stl, const char *file) {
|
||||
int i;
|
||||
FILE *fp;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
bool its_write_vrml(const indexed_triangle_set &its, const char *file)
|
||||
{
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_vrml: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "#VRML V1.0 ascii\n\n");
|
||||
|
@ -214,51 +168,92 @@ stl_write_vrml(stl_file *stl, const char *file) {
|
|||
fprintf(fp, "\t\tDEF STLVertices Coordinate3 {\n");
|
||||
fprintf(fp, "\t\t\tpoint [\n");
|
||||
|
||||
for(i = 0; i < (stl->stats.shared_vertices - 1); i++) {
|
||||
fprintf(fp, "\t\t\t\t%f %f %f,\n",
|
||||
stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2));
|
||||
}
|
||||
fprintf(fp, "\t\t\t\t%f %f %f]\n",
|
||||
stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2));
|
||||
int i = 0;
|
||||
for (; i + 1 < its.vertices.size(); ++ i)
|
||||
fprintf(fp, "\t\t\t\t%f %f %f,\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2));
|
||||
fprintf(fp, "\t\t\t\t%f %f %f]\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2));
|
||||
fprintf(fp, "\t\t}\n");
|
||||
fprintf(fp, "\t\tDEF STLTriangles IndexedFaceSet {\n");
|
||||
fprintf(fp, "\t\t\tcoordIndex [\n");
|
||||
|
||||
for(i = 0; i < (stl->stats.number_of_facets - 1); i++) {
|
||||
fprintf(fp, "\t\t\t\t%d, %d, %d, -1,\n", stl->v_indices[i].vertex[0],
|
||||
stl->v_indices[i].vertex[1], stl->v_indices[i].vertex[2]);
|
||||
}
|
||||
fprintf(fp, "\t\t\t\t%d, %d, %d, -1]\n", stl->v_indices[i].vertex[0],
|
||||
stl->v_indices[i].vertex[1], stl->v_indices[i].vertex[2]);
|
||||
for (size_t i = 0; i + 1 < its.indices.size(); ++ i)
|
||||
fprintf(fp, "\t\t\t\t%d, %d, %d, -1,\n", its.indices[i][0], its.indices[i][1], its.indices[i][2]);
|
||||
fprintf(fp, "\t\t\t\t%d, %d, %d, -1]\n", its.indices[i][0], its.indices[i][1], its.indices[i][2]);
|
||||
fprintf(fp, "\t\t}\n");
|
||||
fprintf(fp, "\t}\n");
|
||||
fprintf(fp, "}\n");
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void stl_write_obj (stl_file *stl, const char *file) {
|
||||
int i;
|
||||
FILE* fp;
|
||||
bool its_write_obj(const indexed_triangle_set &its, const char *file)
|
||||
{
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == NULL) {
|
||||
char* error_msg = (char*)malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing", file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < stl->stats.shared_vertices; i++) {
|
||||
fprintf(fp, "v %f %f %f\n", stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2));
|
||||
}
|
||||
for (i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
fprintf(fp, "f %d %d %d\n", stl->v_indices[i].vertex[0]+1, stl->v_indices[i].vertex[1]+1, stl->v_indices[i].vertex[2]+1);
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_obj: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < its.vertices.size(); ++ i)
|
||||
fprintf(fp, "v %f %f %f\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2));
|
||||
for (size_t i = 0; i < its.indices.size(); ++ i)
|
||||
fprintf(fp, "f %d %d %d\n", its.indices[i][0]+1, its.indices[i][1]+1, its.indices[i][2]+1);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Check validity of the mesh, assert on error.
|
||||
bool stl_validate(const stl_file *stl, const indexed_triangle_set &its)
|
||||
{
|
||||
assert(! stl->facet_start.empty());
|
||||
assert(stl->facet_start.size() == stl->stats.number_of_facets);
|
||||
assert(stl->neighbors_start.size() == stl->stats.number_of_facets);
|
||||
assert(stl->facet_start.size() == stl->neighbors_start.size());
|
||||
assert(! stl->neighbors_start.empty());
|
||||
assert((its.indices.empty()) == (its.vertices.empty()));
|
||||
assert(stl->stats.number_of_facets > 0);
|
||||
assert(its.vertices.empty() || its.indices.size() == stl->stats.number_of_facets);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Verify validity of neighborship data.
|
||||
for (int facet_idx = 0; facet_idx < (int)stl->stats.number_of_facets; ++ facet_idx) {
|
||||
const stl_neighbors &nbr = stl->neighbors_start[facet_idx];
|
||||
const int *vertices = its.indices.empty() ? nullptr : its.indices[facet_idx].data();
|
||||
for (int nbr_idx = 0; nbr_idx < 3; ++ nbr_idx) {
|
||||
int nbr_face = stl->neighbors_start[facet_idx].neighbor[nbr_idx];
|
||||
assert(nbr_face < (int)stl->stats.number_of_facets);
|
||||
if (nbr_face != -1) {
|
||||
int nbr_vnot = nbr.which_vertex_not[nbr_idx];
|
||||
assert(nbr_vnot >= 0 && nbr_vnot < 6);
|
||||
// Neighbor of the neighbor is the original face.
|
||||
assert(stl->neighbors_start[nbr_face].neighbor[(nbr_vnot + 1) % 3] == facet_idx);
|
||||
int vnot_back = stl->neighbors_start[nbr_face].which_vertex_not[(nbr_vnot + 1) % 3];
|
||||
assert(vnot_back >= 0 && vnot_back < 6);
|
||||
assert((nbr_vnot < 3) == (vnot_back < 3));
|
||||
assert(vnot_back % 3 == (nbr_idx + 2) % 3);
|
||||
if (vertices != nullptr) {
|
||||
// Has shared vertices.
|
||||
if (nbr_vnot < 3) {
|
||||
// Faces facet_idx and nbr_face share two vertices accross the common edge. Faces are correctly oriented.
|
||||
assert((its.indices[nbr_face][(nbr_vnot + 1) % 3] == vertices[(nbr_idx + 1) % 3] && its.indices[nbr_face][(nbr_vnot + 2) % 3] == vertices[nbr_idx]));
|
||||
} else {
|
||||
// Faces facet_idx and nbr_face share two vertices accross the common edge. Faces are incorrectly oriented, one of them is flipped.
|
||||
assert((its.indices[nbr_face][(nbr_vnot + 2) % 3] == vertices[(nbr_idx + 1) % 3] && its.indices[nbr_face][(nbr_vnot + 1) % 3] == vertices[nbr_idx]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* _DEBUG */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check validity of the mesh, assert on error.
|
||||
bool stl_validate(const stl_file *stl)
|
||||
{
|
||||
indexed_triangle_set its;
|
||||
return stl_validate(stl, its);
|
||||
}
|
||||
|
|
187
src/admesh/stl.h
|
@ -27,6 +27,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <vector>
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
// Size of the binary STL header, free form.
|
||||
|
@ -40,6 +41,7 @@
|
|||
|
||||
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> stl_vertex;
|
||||
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> stl_normal;
|
||||
typedef Eigen::Matrix<int, 3, 1, Eigen::DontAlign> stl_triangle_vertex_indices;
|
||||
static_assert(sizeof(stl_vertex) == 12, "size of stl_vertex incorrect");
|
||||
static_assert(sizeof(stl_normal) == 12, "size of stl_normal incorrect");
|
||||
|
||||
|
@ -48,7 +50,7 @@ struct stl_facet {
|
|||
stl_vertex vertex[3];
|
||||
char extra[2];
|
||||
|
||||
stl_facet rotated(const Eigen::Quaternion<float, Eigen::DontAlign> &rot) {
|
||||
stl_facet rotated(const Eigen::Quaternion<float, Eigen::DontAlign> &rot) const {
|
||||
stl_facet out;
|
||||
out.normal = rot * this->normal;
|
||||
out.vertex[0] = rot * this->vertex[0];
|
||||
|
@ -67,39 +69,28 @@ static_assert(sizeof(stl_facet) >= SIZEOF_STL_FACET, "size of stl_facet incorrec
|
|||
|
||||
typedef enum {binary, ascii, inmemory} stl_type;
|
||||
|
||||
typedef struct {
|
||||
stl_vertex p1;
|
||||
stl_vertex p2;
|
||||
int facet_number;
|
||||
} stl_edge;
|
||||
struct stl_neighbors {
|
||||
stl_neighbors() { reset(); }
|
||||
void reset() {
|
||||
neighbor[0] = -1;
|
||||
neighbor[1] = -1;
|
||||
neighbor[2] = -1;
|
||||
which_vertex_not[0] = -1;
|
||||
which_vertex_not[1] = -1;
|
||||
which_vertex_not[2] = -1;
|
||||
}
|
||||
int num_neighbors_missing() const { return (this->neighbor[0] == -1) + (this->neighbor[1] == -1) + (this->neighbor[2] == -1); }
|
||||
int num_neighbors() const { return 3 - this->num_neighbors_missing(); }
|
||||
|
||||
typedef struct stl_hash_edge {
|
||||
// Key of a hash edge: sorted vertices of the edge.
|
||||
uint32_t key[6];
|
||||
// Compare two keys.
|
||||
bool operator==(const stl_hash_edge &rhs) { return memcmp(key, rhs.key, sizeof(key)) == 0; }
|
||||
bool operator!=(const stl_hash_edge &rhs) { return ! (*this == rhs); }
|
||||
int hash(int M) const { return ((key[0] / 11 + key[1] / 7 + key[2] / 3) ^ (key[3] / 11 + key[4] / 7 + key[5] / 3)) % M; }
|
||||
// Index of a facet owning this edge.
|
||||
int facet_number;
|
||||
// Index of this edge inside the facet with an index of facet_number.
|
||||
// If this edge is stored backwards, which_edge is increased by 3.
|
||||
int which_edge;
|
||||
struct stl_hash_edge *next;
|
||||
} stl_hash_edge;
|
||||
|
||||
typedef struct {
|
||||
// Index of a neighbor facet.
|
||||
int neighbor[3];
|
||||
// Index of an opposite vertex at the neighbor face.
|
||||
char which_vertex_not[3];
|
||||
} stl_neighbors;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int vertex[3];
|
||||
} v_indices_struct;
|
||||
|
||||
typedef struct {
|
||||
struct stl_stats {
|
||||
stl_stats() { this->reset(); }
|
||||
void reset() { memset(this, 0, sizeof(stl_stats)); this->volume = -1.0; }
|
||||
char header[81];
|
||||
stl_type type;
|
||||
uint32_t number_of_facets;
|
||||
|
@ -109,7 +100,6 @@ typedef struct {
|
|||
float bounding_diameter;
|
||||
float shortest_edge;
|
||||
float volume;
|
||||
unsigned number_of_blocks;
|
||||
int connected_edges;
|
||||
int connected_facets_1_edge;
|
||||
int connected_facets_2_edge;
|
||||
|
@ -126,45 +116,55 @@ typedef struct {
|
|||
int backwards_edges;
|
||||
int normals_fixed;
|
||||
int number_of_parts;
|
||||
int malloced;
|
||||
int freed;
|
||||
int facets_malloced;
|
||||
int collisions;
|
||||
int shared_vertices;
|
||||
int shared_malloced;
|
||||
} stl_stats;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
FILE *fp;
|
||||
stl_facet *facet_start;
|
||||
stl_hash_edge **heads;
|
||||
stl_hash_edge *tail;
|
||||
int M;
|
||||
stl_neighbors *neighbors_start;
|
||||
v_indices_struct *v_indices;
|
||||
stl_vertex *v_shared;
|
||||
struct stl_file {
|
||||
stl_file() {}
|
||||
|
||||
void clear() {
|
||||
this->facet_start.clear();
|
||||
this->neighbors_start.clear();
|
||||
this->stats.reset();
|
||||
}
|
||||
|
||||
size_t memsize() const {
|
||||
return sizeof(*this) + sizeof(stl_facet) * facet_start.size() + sizeof(stl_neighbors) * neighbors_start.size();
|
||||
}
|
||||
|
||||
std::vector<stl_facet> facet_start;
|
||||
std::vector<stl_neighbors> neighbors_start;
|
||||
// Statistics
|
||||
stl_stats stats;
|
||||
char error;
|
||||
} stl_file;
|
||||
};
|
||||
|
||||
struct indexed_triangle_set
|
||||
{
|
||||
indexed_triangle_set() {}
|
||||
|
||||
extern void stl_open(stl_file *stl, const char *file);
|
||||
extern void stl_close(stl_file *stl);
|
||||
void clear() { indices.clear(); vertices.clear(); }
|
||||
|
||||
size_t memsize() const {
|
||||
return sizeof(*this) + sizeof(stl_triangle_vertex_indices) * indices.size() + sizeof(stl_vertex) * vertices.size();
|
||||
}
|
||||
|
||||
std::vector<stl_triangle_vertex_indices> indices;
|
||||
std::vector<stl_vertex> vertices;
|
||||
//FIXME add normals once we get rid of the stl_file from TriangleMesh completely.
|
||||
//std::vector<stl_normal> normals
|
||||
};
|
||||
|
||||
extern bool stl_open(stl_file *stl, const char *file);
|
||||
extern void stl_stats_out(stl_file *stl, FILE *file, char *input_file);
|
||||
extern void stl_print_neighbors(stl_file *stl, char *file);
|
||||
extern void stl_put_little_int(FILE *fp, int value_in);
|
||||
extern void stl_put_little_float(FILE *fp, float value_in);
|
||||
extern void stl_write_ascii(stl_file *stl, const char *file, const char *label);
|
||||
extern void stl_write_binary(stl_file *stl, const char *file, const char *label);
|
||||
extern void stl_write_binary_block(stl_file *stl, FILE *fp);
|
||||
extern bool stl_print_neighbors(stl_file *stl, char *file);
|
||||
extern bool stl_write_ascii(stl_file *stl, const char *file, const char *label);
|
||||
extern bool stl_write_binary(stl_file *stl, const char *file, const char *label);
|
||||
extern void stl_check_facets_exact(stl_file *stl);
|
||||
extern void stl_check_facets_nearby(stl_file *stl, float tolerance);
|
||||
extern void stl_remove_unconnected_facets(stl_file *stl);
|
||||
extern void stl_write_vertex(stl_file *stl, int facet, int vertex);
|
||||
extern void stl_write_facet(stl_file *stl, char *label, int facet);
|
||||
extern void stl_write_edge(stl_file *stl, char *label, stl_hash_edge edge);
|
||||
extern void stl_write_neighbor(stl_file *stl, int facet);
|
||||
extern void stl_write_quad_object(stl_file *stl, char *file);
|
||||
extern bool stl_write_quad_object(stl_file *stl, char *file);
|
||||
extern void stl_verify_neighbors(stl_file *stl);
|
||||
extern void stl_fill_holes(stl_file *stl);
|
||||
extern void stl_fix_normal_directions(stl_file *stl);
|
||||
|
@ -186,9 +186,6 @@ extern void stl_get_size(stl_file *stl);
|
|||
template<typename T>
|
||||
extern void stl_transform(stl_file *stl, T *trafo3x4)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
for (uint32_t i_face = 0; i_face < stl->stats.number_of_facets; ++ i_face) {
|
||||
stl_facet &face = stl->facet_start[i_face];
|
||||
for (int i_vertex = 0; i_vertex < 3; ++ i_vertex) {
|
||||
|
@ -211,11 +208,8 @@ extern void stl_transform(stl_file *stl, T *trafo3x4)
|
|||
template<typename T>
|
||||
inline void stl_transform(stl_file *stl, const Eigen::Transform<T, 3, Eigen::Affine, Eigen::DontAlign>& t)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
const Eigen::Matrix<double, 3, 3, Eigen::DontAlign> r = t.matrix().template block<3, 3>(0, 0);
|
||||
for (size_t i = 0; i < stl->stats.number_of_facets; ++i) {
|
||||
for (size_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_facet &f = stl->facet_start[i];
|
||||
for (size_t j = 0; j < 3; ++j)
|
||||
f.vertex[j] = (t * f.vertex[j].template cast<T>()).template cast<float>().eval();
|
||||
|
@ -228,10 +222,7 @@ inline void stl_transform(stl_file *stl, const Eigen::Transform<T, 3, Eigen::Aff
|
|||
template<typename T>
|
||||
inline void stl_transform(stl_file *stl, const Eigen::Matrix<T, 3, 3, Eigen::DontAlign>& m)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < stl->stats.number_of_facets; ++i) {
|
||||
for (size_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_facet &f = stl->facet_start[i];
|
||||
for (size_t j = 0; j < 3; ++j)
|
||||
f.vertex[j] = (m * f.vertex[j].template cast<T>()).template cast<float>().eval();
|
||||
|
@ -241,13 +232,43 @@ inline void stl_transform(stl_file *stl, const Eigen::Matrix<T, 3, 3, Eigen::Don
|
|||
stl_get_size(stl);
|
||||
}
|
||||
|
||||
extern void stl_open_merge(stl_file *stl, char *file);
|
||||
extern void stl_invalidate_shared_vertices(stl_file *stl);
|
||||
extern void stl_generate_shared_vertices(stl_file *stl);
|
||||
extern void stl_write_obj(stl_file *stl, const char *file);
|
||||
extern void stl_write_off(stl_file *stl, const char *file);
|
||||
extern void stl_write_dxf(stl_file *stl, const char *file, char *label);
|
||||
extern void stl_write_vrml(stl_file *stl, const char *file);
|
||||
|
||||
template<typename T>
|
||||
extern void its_transform(indexed_triangle_set &its, T *trafo3x4)
|
||||
{
|
||||
for (stl_vertex &v_dst : its.vertices) {
|
||||
stl_vertex v_src = v_dst;
|
||||
v_dst(0) = T(trafo3x4[0] * v_src(0) + trafo3x4[1] * v_src(1) + trafo3x4[2] * v_src(2) + trafo3x4[3]);
|
||||
v_dst(1) = T(trafo3x4[4] * v_src(0) + trafo3x4[5] * v_src(1) + trafo3x4[6] * v_src(2) + trafo3x4[7]);
|
||||
v_dst(2) = T(trafo3x4[8] * v_src(0) + trafo3x4[9] * v_src(1) + trafo3x4[10] * v_src(2) + trafo3x4[11]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void its_transform(indexed_triangle_set &its, const Eigen::Transform<T, 3, Eigen::Affine, Eigen::DontAlign>& t)
|
||||
{
|
||||
const Eigen::Matrix<double, 3, 3, Eigen::DontAlign> r = t.matrix().template block<3, 3>(0, 0);
|
||||
for (stl_vertex &v : its.vertices)
|
||||
v = (t * v.template cast<T>()).template cast<float>().eval();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void its_transform(indexed_triangle_set &its, const Eigen::Matrix<T, 3, 3, Eigen::DontAlign>& m)
|
||||
{
|
||||
for (stl_vertex &v : its.vertices)
|
||||
v = (m * v.template cast<T>()).template cast<float>().eval();
|
||||
}
|
||||
|
||||
extern void its_rotate_x(indexed_triangle_set &its, float angle);
|
||||
extern void its_rotate_y(indexed_triangle_set &its, float angle);
|
||||
extern void its_rotate_z(indexed_triangle_set &its, float angle);
|
||||
|
||||
extern void stl_generate_shared_vertices(stl_file *stl, indexed_triangle_set &its);
|
||||
extern bool its_write_obj(const indexed_triangle_set &its, const char *file);
|
||||
extern bool its_write_off(const indexed_triangle_set &its, const char *file);
|
||||
extern bool its_write_vrml(const indexed_triangle_set &its, const char *file);
|
||||
|
||||
extern bool stl_write_dxf(stl_file *stl, const char *file, char *label);
|
||||
inline void stl_calculate_normal(stl_normal &normal, stl_facet *facet) {
|
||||
normal = (facet->vertex[1] - facet->vertex[0]).cross(facet->vertex[2] - facet->vertex[0]);
|
||||
}
|
||||
|
@ -258,24 +279,18 @@ inline void stl_normalize_vector(stl_normal &normal) {
|
|||
else
|
||||
normal *= float(1.0 / length);
|
||||
}
|
||||
inline bool stl_vertex_lower(const stl_vertex &a, const stl_vertex &b) {
|
||||
return (a(0) != b(0)) ? (a(0) < b(0)) :
|
||||
((a(1) != b(1)) ? (a(1) < b(1)) : (a(2) < b(2)));
|
||||
}
|
||||
extern void stl_calculate_volume(stl_file *stl);
|
||||
|
||||
extern void stl_repair(stl_file *stl, int fixall_flag, int exact_flag, int tolerance_flag, float tolerance, int increment_flag, float increment, int nearby_flag, int iterations, int remove_unconnected_flag, int fill_holes_flag, int normal_directions_flag, int normal_values_flag, int reverse_all_flag, int verbose_flag);
|
||||
extern void stl_repair(stl_file *stl, bool fixall_flag, bool exact_flag, bool tolerance_flag, float tolerance, bool increment_flag, float increment, bool nearby_flag, int iterations, bool remove_unconnected_flag, bool fill_holes_flag, bool normal_directions_flag, bool normal_values_flag, bool reverse_all_flag, bool verbose_flag);
|
||||
|
||||
extern void stl_initialize(stl_file *stl);
|
||||
extern void stl_count_facets(stl_file *stl, const char *file);
|
||||
extern void stl_allocate(stl_file *stl);
|
||||
extern void stl_read(stl_file *stl, int first_facet, bool first);
|
||||
extern void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first);
|
||||
extern void stl_reallocate(stl_file *stl);
|
||||
extern void stl_add_facet(stl_file *stl, stl_facet *new_facet);
|
||||
extern void stl_add_facet(stl_file *stl, const stl_facet *new_facet);
|
||||
|
||||
extern void stl_clear_error(stl_file *stl);
|
||||
extern int stl_get_error(stl_file *stl);
|
||||
extern void stl_exit_on_error(stl_file *stl);
|
||||
// Validate the mesh, assert on error.
|
||||
extern bool stl_validate(const stl_file *stl);
|
||||
extern bool stl_validate(const stl_file *stl, const indexed_triangle_set &its);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,158 +22,85 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/predef/other/endian.h>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
|
||||
#if !defined(SEEK_SET)
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
#endif
|
||||
|
||||
void
|
||||
stl_stats_out(stl_file *stl, FILE *file, char *input_file) {
|
||||
if (stl->error) return;
|
||||
|
||||
/* this is here for Slic3r, without our config.h
|
||||
it won't use this part of the code anyway */
|
||||
void stl_stats_out(stl_file *stl, FILE *file, char *input_file)
|
||||
{
|
||||
// This is here for Slic3r, without our config.h it won't use this part of the code anyway.
|
||||
#ifndef VERSION
|
||||
#define VERSION "unknown"
|
||||
#endif
|
||||
fprintf(file, "\n\
|
||||
================= Results produced by ADMesh version " VERSION " ================\n");
|
||||
fprintf(file, "\
|
||||
Input file : %s\n", input_file);
|
||||
if(stl->stats.type == binary) {
|
||||
fprintf(file, "\
|
||||
File type : Binary STL file\n");
|
||||
} else {
|
||||
fprintf(file, "\
|
||||
File type : ASCII STL file\n");
|
||||
}
|
||||
fprintf(file, "\
|
||||
Header : %s\n", stl->stats.header);
|
||||
fprintf(file, "\n================= Results produced by ADMesh version " VERSION " ================\n");
|
||||
fprintf(file, "Input file : %s\n", input_file);
|
||||
if (stl->stats.type == binary)
|
||||
fprintf(file, "File type : Binary STL file\n");
|
||||
else
|
||||
fprintf(file, "File type : ASCII STL file\n");
|
||||
fprintf(file, "Header : %s\n", stl->stats.header);
|
||||
fprintf(file, "============== Size ==============\n");
|
||||
fprintf(file, "Min X = % f, Max X = % f\n",
|
||||
stl->stats.min(0), stl->stats.max(0));
|
||||
fprintf(file, "Min Y = % f, Max Y = % f\n",
|
||||
stl->stats.min(1), stl->stats.max(1));
|
||||
fprintf(file, "Min Z = % f, Max Z = % f\n",
|
||||
stl->stats.min(2), stl->stats.max(2));
|
||||
|
||||
fprintf(file, "\
|
||||
========= Facet Status ========== Original ============ Final ====\n");
|
||||
fprintf(file, "\
|
||||
Number of facets : %5d %5d\n",
|
||||
stl->stats.original_num_facets, stl->stats.number_of_facets);
|
||||
fprintf(file, "\
|
||||
Facets with 1 disconnected edge : %5d %5d\n",
|
||||
stl->stats.facets_w_1_bad_edge, stl->stats.connected_facets_2_edge -
|
||||
stl->stats.connected_facets_3_edge);
|
||||
fprintf(file, "\
|
||||
Facets with 2 disconnected edges : %5d %5d\n",
|
||||
stl->stats.facets_w_2_bad_edge, stl->stats.connected_facets_1_edge -
|
||||
stl->stats.connected_facets_2_edge);
|
||||
fprintf(file, "\
|
||||
Facets with 3 disconnected edges : %5d %5d\n",
|
||||
stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets -
|
||||
stl->stats.connected_facets_1_edge);
|
||||
fprintf(file, "\
|
||||
Total disconnected facets : %5d %5d\n",
|
||||
stl->stats.facets_w_1_bad_edge + stl->stats.facets_w_2_bad_edge +
|
||||
stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets -
|
||||
stl->stats.connected_facets_3_edge);
|
||||
|
||||
fprintf(file,
|
||||
"=== Processing Statistics === ===== Other Statistics =====\n");
|
||||
fprintf(file, "\
|
||||
Number of parts : %5d Volume : % f\n",
|
||||
stl->stats.number_of_parts, stl->stats.volume);
|
||||
fprintf(file, "\
|
||||
Degenerate facets : %5d\n", stl->stats.degenerate_facets);
|
||||
fprintf(file, "\
|
||||
Edges fixed : %5d\n", stl->stats.edges_fixed);
|
||||
fprintf(file, "\
|
||||
Facets removed : %5d\n", stl->stats.facets_removed);
|
||||
fprintf(file, "\
|
||||
Facets added : %5d\n", stl->stats.facets_added);
|
||||
fprintf(file, "\
|
||||
Facets reversed : %5d\n", stl->stats.facets_reversed);
|
||||
fprintf(file, "\
|
||||
Backwards edges : %5d\n", stl->stats.backwards_edges);
|
||||
fprintf(file, "\
|
||||
Normals fixed : %5d\n", stl->stats.normals_fixed);
|
||||
fprintf(file, "Min X = % f, Max X = % f\n", stl->stats.min(0), stl->stats.max(0));
|
||||
fprintf(file, "Min Y = % f, Max Y = % f\n", stl->stats.min(1), stl->stats.max(1));
|
||||
fprintf(file, "Min Z = % f, Max Z = % f\n", stl->stats.min(2), stl->stats.max(2));
|
||||
fprintf(file, "========= Facet Status ========== Original ============ Final ====\n");
|
||||
fprintf(file, "Number of facets : %5d %5d\n", stl->stats.original_num_facets, stl->stats.number_of_facets);
|
||||
fprintf(file, "Facets with 1 disconnected edge : %5d %5d\n",
|
||||
stl->stats.facets_w_1_bad_edge, stl->stats.connected_facets_2_edge - stl->stats.connected_facets_3_edge);
|
||||
fprintf(file, "Facets with 2 disconnected edges : %5d %5d\n",
|
||||
stl->stats.facets_w_2_bad_edge, stl->stats.connected_facets_1_edge - stl->stats.connected_facets_2_edge);
|
||||
fprintf(file, "Facets with 3 disconnected edges : %5d %5d\n",
|
||||
stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets - stl->stats.connected_facets_1_edge);
|
||||
fprintf(file, "Total disconnected facets : %5d %5d\n",
|
||||
stl->stats.facets_w_1_bad_edge + stl->stats.facets_w_2_bad_edge + stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets - stl->stats.connected_facets_3_edge);
|
||||
fprintf(file, "=== Processing Statistics === ===== Other Statistics =====\n");
|
||||
fprintf(file, "Number of parts : %5d Volume : %f\n", stl->stats.number_of_parts, stl->stats.volume);
|
||||
fprintf(file, "Degenerate facets : %5d\n", stl->stats.degenerate_facets);
|
||||
fprintf(file, "Edges fixed : %5d\n", stl->stats.edges_fixed);
|
||||
fprintf(file, "Facets removed : %5d\n", stl->stats.facets_removed);
|
||||
fprintf(file, "Facets added : %5d\n", stl->stats.facets_added);
|
||||
fprintf(file, "Facets reversed : %5d\n", stl->stats.facets_reversed);
|
||||
fprintf(file, "Backwards edges : %5d\n", stl->stats.backwards_edges);
|
||||
fprintf(file, "Normals fixed : %5d\n", stl->stats.normals_fixed);
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_ascii(stl_file *stl, const char *file, const char *label) {
|
||||
int i;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
bool stl_write_ascii(stl_file *stl, const char *file, const char *label)
|
||||
{
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_ascii: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "solid %s\n", label);
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
fprintf(fp, " facet normal % .8E % .8E % .8E\n",
|
||||
stl->facet_start[i].normal(0), stl->facet_start[i].normal(1),
|
||||
stl->facet_start[i].normal(2));
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
fprintf(fp, " facet normal % .8E % .8E % .8E\n", stl->facet_start[i].normal(0), stl->facet_start[i].normal(1), stl->facet_start[i].normal(2));
|
||||
fprintf(fp, " outer loop\n");
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n",
|
||||
stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1),
|
||||
stl->facet_start[i].vertex[0](2));
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n",
|
||||
stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1),
|
||||
stl->facet_start[i].vertex[1](2));
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n",
|
||||
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2));
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n", stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1), stl->facet_start[i].vertex[0](2));
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n", stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1), stl->facet_start[i].vertex[1](2));
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2));
|
||||
fprintf(fp, " endloop\n");
|
||||
fprintf(fp, " endfacet\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "endsolid %s\n", label);
|
||||
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
stl_print_neighbors(stl_file *stl, char *file) {
|
||||
int i;
|
||||
FILE *fp;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_print_neighbors: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
bool stl_print_neighbors(stl_file *stl, char *file)
|
||||
{
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_print_neighbors: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
fprintf(fp, "%d, %d,%d, %d,%d, %d,%d\n",
|
||||
i,
|
||||
stl->neighbors_start[i].neighbor[0],
|
||||
|
@ -184,9 +111,10 @@ stl_print_neighbors(stl_file *stl, char *file) {
|
|||
(int)stl->neighbors_start[i].which_vertex_not[2]);
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef BOOST_LITTLE_ENDIAN
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
// Swap a buffer of 32bit data from little endian to big endian and vice versa.
|
||||
void stl_internal_reverse_quads(char *buf, size_t cnt)
|
||||
{
|
||||
|
@ -197,36 +125,27 @@ void stl_internal_reverse_quads(char *buf, size_t cnt)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
stl_write_binary(stl_file *stl, const char *file, const char *label) {
|
||||
FILE *fp;
|
||||
int i;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "wb");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_binary: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
bool stl_write_binary(stl_file *stl, const char *file, const char *label)
|
||||
{
|
||||
FILE *fp = boost::nowide::fopen(file, "wb");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_binary: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "%s", label);
|
||||
for(i = strlen(label); i < LABEL_SIZE; i++) putc(0, fp);
|
||||
for (size_t i = strlen(label); i < LABEL_SIZE; ++ i)
|
||||
putc(0, fp);
|
||||
|
||||
#if !defined(SEEK_SET)
|
||||
#define SEEK_SET 0
|
||||
#endif
|
||||
fseek(fp, LABEL_SIZE, SEEK_SET);
|
||||
#ifdef BOOST_LITTLE_ENDIAN
|
||||
#if BOOST_ENDIAN_LITTLE_BYTE
|
||||
fwrite(&stl->stats.number_of_facets, 4, 1, fp);
|
||||
for (i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
fwrite(stl->facet_start + i, SIZEOF_STL_FACET, 1, fp);
|
||||
#else /* BOOST_LITTLE_ENDIAN */
|
||||
for (const stl_facet &facet : stl->facet_start)
|
||||
fwrite(&facet, SIZEOF_STL_FACET, 1, fp);
|
||||
#else /* BOOST_ENDIAN_LITTLE_BYTE */
|
||||
char buffer[50];
|
||||
// Convert the number of facets to little endian.
|
||||
memcpy(buffer, &stl->stats.number_of_facets, 4);
|
||||
|
@ -238,44 +157,29 @@ stl_write_binary(stl_file *stl, const char *file, const char *label) {
|
|||
stl_internal_reverse_quads(buffer, 48);
|
||||
fwrite(buffer, SIZEOF_STL_FACET, 1, fp);
|
||||
}
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
#endif /* BOOST_ENDIAN_LITTLE_BYTE */
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_vertex(stl_file *stl, int facet, int vertex) {
|
||||
if (stl->error) return;
|
||||
void stl_write_vertex(stl_file *stl, int facet, int vertex)
|
||||
{
|
||||
printf(" vertex %d/%d % .8E % .8E % .8E\n", vertex, facet,
|
||||
stl->facet_start[facet].vertex[vertex](0),
|
||||
stl->facet_start[facet].vertex[vertex](1),
|
||||
stl->facet_start[facet].vertex[vertex](2));
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_facet(stl_file *stl, char *label, int facet) {
|
||||
if (stl->error) return;
|
||||
void stl_write_facet(stl_file *stl, char *label, int facet)
|
||||
{
|
||||
printf("facet (%d)/ %s\n", facet, label);
|
||||
stl_write_vertex(stl, facet, 0);
|
||||
stl_write_vertex(stl, facet, 1);
|
||||
stl_write_vertex(stl, facet, 2);
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_edge(stl_file *stl, char *label, stl_hash_edge edge) {
|
||||
if (stl->error) return;
|
||||
printf("edge (%d)/(%d) %s\n", edge.facet_number, edge.which_edge, label);
|
||||
if(edge.which_edge < 3) {
|
||||
stl_write_vertex(stl, edge.facet_number, edge.which_edge % 3);
|
||||
stl_write_vertex(stl, edge.facet_number, (edge.which_edge + 1) % 3);
|
||||
} else {
|
||||
stl_write_vertex(stl, edge.facet_number, (edge.which_edge + 1) % 3);
|
||||
stl_write_vertex(stl, edge.facet_number, edge.which_edge % 3);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_neighbor(stl_file *stl, int facet) {
|
||||
if (stl->error) return;
|
||||
void stl_write_neighbor(stl_file *stl, int facet)
|
||||
{
|
||||
printf("Neighbors %d: %d, %d, %d ; %d, %d, %d\n", facet,
|
||||
stl->neighbors_start[facet].neighbor[0],
|
||||
stl->neighbors_start[facet].neighbor[1],
|
||||
|
@ -285,131 +189,62 @@ stl_write_neighbor(stl_file *stl, int facet) {
|
|||
stl->neighbors_start[facet].which_vertex_not[2]);
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_quad_object(stl_file *stl, char *file) {
|
||||
FILE *fp;
|
||||
int i;
|
||||
int j;
|
||||
char *error_msg;
|
||||
bool stl_write_quad_object(stl_file *stl, char *file)
|
||||
{
|
||||
stl_vertex connect_color = stl_vertex::Zero();
|
||||
stl_vertex uncon_1_color = stl_vertex::Zero();
|
||||
stl_vertex uncon_2_color = stl_vertex::Zero();
|
||||
stl_vertex uncon_3_color = stl_vertex::Zero();
|
||||
stl_vertex color;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_quad_object: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_quad_object: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "CQUAD\n");
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
j = ((stl->neighbors_start[i].neighbor[0] == -1) +
|
||||
(stl->neighbors_start[i].neighbor[1] == -1) +
|
||||
(stl->neighbors_start[i].neighbor[2] == -1));
|
||||
if(j == 0) {
|
||||
color = connect_color;
|
||||
} else if(j == 1) {
|
||||
color = uncon_1_color;
|
||||
} else if(j == 2) {
|
||||
color = uncon_2_color;
|
||||
} else {
|
||||
color = uncon_3_color;
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
switch (stl->neighbors_start[i].num_neighbors_missing()) {
|
||||
case 0: color = connect_color; break;
|
||||
case 1: color = uncon_1_color; break;
|
||||
case 2: color = uncon_2_color; break;
|
||||
default: color = uncon_3_color;
|
||||
}
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
||||
stl->facet_start[i].vertex[0](0),
|
||||
stl->facet_start[i].vertex[0](1),
|
||||
stl->facet_start[i].vertex[0](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
||||
stl->facet_start[i].vertex[1](0),
|
||||
stl->facet_start[i].vertex[1](1),
|
||||
stl->facet_start[i].vertex[1](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
||||
stl->facet_start[i].vertex[2](0),
|
||||
stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
||||
stl->facet_start[i].vertex[2](0),
|
||||
stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1), stl->facet_start[i].vertex[0](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1), stl->facet_start[i].vertex[1](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
stl_write_dxf(stl_file *stl, const char *file, char *label) {
|
||||
int i;
|
||||
FILE *fp;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file */
|
||||
fp = boost::nowide::fopen(file, "w");
|
||||
if(fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
bool stl_write_dxf(stl_file *stl, const char *file, char *label)
|
||||
{
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_quad_object: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "999\n%s\n", label);
|
||||
fprintf(fp, "0\nSECTION\n2\nHEADER\n0\nENDSEC\n");
|
||||
fprintf(fp, "0\nSECTION\n2\nTABLES\n0\nTABLE\n2\nLAYER\n70\n1\n\
|
||||
0\nLAYER\n2\n0\n70\n0\n62\n7\n6\nCONTINUOUS\n0\nENDTAB\n0\nENDSEC\n");
|
||||
0\nLAYER\n2\n0\n70\n0\n62\n7\n6\nCONTINUOUS\n0\nENDTAB\n0\nENDSEC\n");
|
||||
fprintf(fp, "0\nSECTION\n2\nBLOCKS\n0\nENDSEC\n");
|
||||
|
||||
fprintf(fp, "0\nSECTION\n2\nENTITIES\n");
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
fprintf(fp, "0\n3DFACE\n8\n0\n");
|
||||
fprintf(fp, "10\n%f\n20\n%f\n30\n%f\n",
|
||||
stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1),
|
||||
stl->facet_start[i].vertex[0](2));
|
||||
fprintf(fp, "11\n%f\n21\n%f\n31\n%f\n",
|
||||
stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1),
|
||||
stl->facet_start[i].vertex[1](2));
|
||||
fprintf(fp, "12\n%f\n22\n%f\n32\n%f\n",
|
||||
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2));
|
||||
fprintf(fp, "13\n%f\n23\n%f\n33\n%f\n",
|
||||
stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1),
|
||||
stl->facet_start[i].vertex[2](2));
|
||||
fprintf(fp, "10\n%f\n20\n%f\n30\n%f\n", stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1), stl->facet_start[i].vertex[0](2));
|
||||
fprintf(fp, "11\n%f\n21\n%f\n31\n%f\n", stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1), stl->facet_start[i].vertex[1](2));
|
||||
fprintf(fp, "12\n%f\n22\n%f\n32\n%f\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2));
|
||||
fprintf(fp, "13\n%f\n23\n%f\n33\n%f\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2));
|
||||
}
|
||||
|
||||
fprintf(fp, "0\nENDSEC\n0\nEOF\n");
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
stl_clear_error(stl_file *stl) {
|
||||
stl->error = 0;
|
||||
}
|
||||
|
||||
void
|
||||
stl_exit_on_error(stl_file *stl) {
|
||||
if (!stl->error) return;
|
||||
stl->error = 0;
|
||||
stl_close(stl);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
stl_get_error(stl_file *stl) {
|
||||
return stl->error;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
|
||||
|
@ -35,279 +36,152 @@
|
|||
#error "SEEK_SET not defined"
|
||||
#endif
|
||||
|
||||
void
|
||||
stl_open(stl_file *stl, const char *file) {
|
||||
stl_initialize(stl);
|
||||
stl_count_facets(stl, file);
|
||||
stl_allocate(stl);
|
||||
stl_read(stl, 0, true);
|
||||
if (stl->fp != nullptr) {
|
||||
fclose(stl->fp);
|
||||
stl->fp = nullptr;
|
||||
static FILE* stl_open_count_facets(stl_file *stl, const char *file)
|
||||
{
|
||||
// Open the file in binary mode first.
|
||||
FILE *fp = boost::nowide::fopen(file, "rb");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: Couldn't open " << file << " for reading";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
// Find size of file.
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long file_size = ftell(fp);
|
||||
|
||||
void
|
||||
stl_initialize(stl_file *stl) {
|
||||
memset(stl, 0, sizeof(stl_file));
|
||||
stl->stats.volume = -1.0;
|
||||
}
|
||||
|
||||
#ifndef BOOST_LITTLE_ENDIAN
|
||||
extern void stl_internal_reverse_quads(char *buf, size_t cnt);
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
|
||||
void
|
||||
stl_count_facets(stl_file *stl, const char *file) {
|
||||
long file_size;
|
||||
uint32_t header_num_facets;
|
||||
uint32_t num_facets;
|
||||
int i;
|
||||
size_t s;
|
||||
// Check for binary or ASCII file.
|
||||
fseek(fp, HEADER_SIZE, SEEK_SET);
|
||||
unsigned char chtest[128];
|
||||
int num_lines = 1;
|
||||
char *error_msg;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Open the file in binary mode first */
|
||||
stl->fp = boost::nowide::fopen(file, "rb");
|
||||
if(stl->fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_initialize: Couldn't open %s for reading",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
/* Find size of file */
|
||||
fseek(stl->fp, 0, SEEK_END);
|
||||
file_size = ftell(stl->fp);
|
||||
|
||||
/* Check for binary or ASCII file */
|
||||
fseek(stl->fp, HEADER_SIZE, SEEK_SET);
|
||||
if (!fread(chtest, sizeof(chtest), 1, stl->fp)) {
|
||||
perror("The input is an empty file");
|
||||
stl->error = 1;
|
||||
return;
|
||||
if (! fread(chtest, sizeof(chtest), 1, fp)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The input is an empty file: " << file;
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
stl->stats.type = ascii;
|
||||
for(s = 0; s < sizeof(chtest); s++) {
|
||||
if(chtest[s] > 127) {
|
||||
for (size_t s = 0; s < sizeof(chtest); s++) {
|
||||
if (chtest[s] > 127) {
|
||||
stl->stats.type = binary;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rewind(stl->fp);
|
||||
rewind(fp);
|
||||
|
||||
/* Get the header and the number of facets in the .STL file */
|
||||
/* If the .STL file is binary, then do the following */
|
||||
if(stl->stats.type == binary) {
|
||||
/* Test if the STL file has the right size */
|
||||
if(((file_size - HEADER_SIZE) % SIZEOF_STL_FACET != 0)
|
||||
|| (file_size < STL_MIN_FILE_SIZE)) {
|
||||
fprintf(stderr, "The file %s has the wrong size.\n", file);
|
||||
stl->error = 1;
|
||||
return;
|
||||
uint32_t num_facets = 0;
|
||||
|
||||
// Get the header and the number of facets in the .STL file.
|
||||
// If the .STL file is binary, then do the following:
|
||||
if (stl->stats.type == binary) {
|
||||
// Test if the STL file has the right size.
|
||||
if (((file_size - HEADER_SIZE) % SIZEOF_STL_FACET != 0) || (file_size < STL_MIN_FILE_SIZE)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The file " << file << " has the wrong size.";
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET;
|
||||
|
||||
/* Read the header */
|
||||
if (fread(stl->stats.header, LABEL_SIZE, 1, stl->fp) > 79) {
|
||||
// Read the header.
|
||||
if (fread(stl->stats.header, LABEL_SIZE, 1, fp) > 79)
|
||||
stl->stats.header[80] = '\0';
|
||||
}
|
||||
|
||||
/* Read the int following the header. This should contain # of facets */
|
||||
bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, stl->fp) != 0;
|
||||
// Read the int following the header. This should contain # of facets.
|
||||
uint32_t header_num_facets;
|
||||
bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, fp) != 0;
|
||||
#ifndef BOOST_LITTLE_ENDIAN
|
||||
// Convert from little endian to big endian.
|
||||
stl_internal_reverse_quads((char*)&header_num_facets, 4);
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
if (! header_num_faces_read || num_facets != header_num_facets) {
|
||||
fprintf(stderr,
|
||||
"Warning: File size doesn't match number of facets in the header\n");
|
||||
if (! header_num_faces_read || num_facets != header_num_facets)
|
||||
BOOST_LOG_TRIVIAL(info) << "stl_open_count_facets: Warning: File size doesn't match number of facets in the header: " << file;
|
||||
}
|
||||
}
|
||||
/* Otherwise, if the .STL file is ASCII, then do the following */
|
||||
else {
|
||||
/* Reopen the file in text mode (for getting correct newlines on Windows) */
|
||||
// Otherwise, if the .STL file is ASCII, then do the following:
|
||||
else
|
||||
{
|
||||
// Reopen the file in text mode (for getting correct newlines on Windows)
|
||||
// fix to silence a warning about unused return value.
|
||||
// obviously if it fails we have problems....
|
||||
stl->fp = boost::nowide::freopen(file, "r", stl->fp);
|
||||
fp = boost::nowide::freopen(file, "r", fp);
|
||||
|
||||
// do another null check to be safe
|
||||
if(stl->fp == NULL) {
|
||||
error_msg = (char*)
|
||||
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
||||
sprintf(error_msg, "stl_initialize: Couldn't open %s for reading",
|
||||
file);
|
||||
perror(error_msg);
|
||||
free(error_msg);
|
||||
stl->error = 1;
|
||||
return;
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: Couldn't open " << file << " for reading";
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Find the number of facets */
|
||||
// Find the number of facets.
|
||||
char linebuf[100];
|
||||
while (fgets(linebuf, 100, stl->fp) != NULL) {
|
||||
/* don't count short lines */
|
||||
if (strlen(linebuf) <= 4) continue;
|
||||
|
||||
/* skip solid/endsolid lines as broken STL file generators may put several of them */
|
||||
if (strncmp(linebuf, "solid", 5) == 0 || strncmp(linebuf, "endsolid", 8) == 0) continue;
|
||||
|
||||
++num_lines;
|
||||
int num_lines = 1;
|
||||
while (fgets(linebuf, 100, fp) != nullptr) {
|
||||
// Don't count short lines.
|
||||
if (strlen(linebuf) <= 4)
|
||||
continue;
|
||||
// Skip solid/endsolid lines as broken STL file generators may put several of them.
|
||||
if (strncmp(linebuf, "solid", 5) == 0 || strncmp(linebuf, "endsolid", 8) == 0)
|
||||
continue;
|
||||
++ num_lines;
|
||||
}
|
||||
|
||||
rewind(stl->fp);
|
||||
rewind(fp);
|
||||
|
||||
/* Get the header */
|
||||
for(i = 0;
|
||||
(i < 80) && (stl->stats.header[i] = getc(stl->fp)) != '\n'; i++);
|
||||
stl->stats.header[i] = '\0'; /* Lose the '\n' */
|
||||
// Get the header.
|
||||
int i = 0;
|
||||
for (; i < 80 && (stl->stats.header[i] = getc(fp)) != '\n'; ++ i) ;
|
||||
stl->stats.header[i] = '\0'; // Lose the '\n'
|
||||
stl->stats.header[80] = '\0';
|
||||
|
||||
num_facets = num_lines / ASCII_LINES_PER_FACET;
|
||||
}
|
||||
|
||||
stl->stats.number_of_facets += num_facets;
|
||||
stl->stats.original_num_facets = stl->stats.number_of_facets;
|
||||
return fp;
|
||||
}
|
||||
|
||||
void
|
||||
stl_allocate(stl_file *stl) {
|
||||
if (stl->error) return;
|
||||
|
||||
/* Allocate memory for the entire .STL file */
|
||||
stl->facet_start = (stl_facet*)calloc(stl->stats.number_of_facets,
|
||||
sizeof(stl_facet));
|
||||
if(stl->facet_start == NULL) perror("stl_initialize");
|
||||
stl->stats.facets_malloced = stl->stats.number_of_facets;
|
||||
|
||||
/* Allocate memory for the neighbors list */
|
||||
stl->neighbors_start = (stl_neighbors*)
|
||||
calloc(stl->stats.number_of_facets, sizeof(stl_neighbors));
|
||||
if(stl->facet_start == NULL) perror("stl_initialize");
|
||||
}
|
||||
|
||||
void
|
||||
stl_open_merge(stl_file *stl, char *file_to_merge) {
|
||||
int num_facets_so_far;
|
||||
stl_type origStlType;
|
||||
FILE *origFp;
|
||||
stl_file stl_to_merge;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
/* Record how many facets we have so far from the first file. We will start putting
|
||||
facets in the next position. Since we're 0-indexed, it'l be the same position. */
|
||||
num_facets_so_far = stl->stats.number_of_facets;
|
||||
|
||||
/* Record the file type we started with: */
|
||||
origStlType=stl->stats.type;
|
||||
/* Record the file pointer too: */
|
||||
origFp=stl->fp;
|
||||
|
||||
/* Initialize the sturucture with zero stats, header info and sizes: */
|
||||
stl_initialize(&stl_to_merge);
|
||||
stl_count_facets(&stl_to_merge, file_to_merge);
|
||||
|
||||
/* Copy what we need to into stl so that we can read the file_to_merge directly into it
|
||||
using stl_read: Save the rest of the valuable info: */
|
||||
stl->stats.type=stl_to_merge.stats.type;
|
||||
stl->fp=stl_to_merge.fp;
|
||||
|
||||
/* Add the number of facets we already have in stl with what we we found in stl_to_merge but
|
||||
haven't read yet. */
|
||||
stl->stats.number_of_facets=num_facets_so_far+stl_to_merge.stats.number_of_facets;
|
||||
|
||||
/* Allocate enough room for stl->stats.number_of_facets facets and neighbors: */
|
||||
stl_reallocate(stl);
|
||||
|
||||
/* Read the file to merge directly into stl, adding it to what we have already.
|
||||
Start at num_facets_so_far, the index to the first unused facet. Also say
|
||||
that this isn't our first time so we should augment stats like min and max
|
||||
instead of erasing them. */
|
||||
stl_read(stl, num_facets_so_far, false);
|
||||
|
||||
/* Restore the stl information we overwrote (for stl_read) so that it still accurately
|
||||
reflects the subject part: */
|
||||
stl->stats.type=origStlType;
|
||||
stl->fp=origFp;
|
||||
}
|
||||
|
||||
extern void
|
||||
stl_reallocate(stl_file *stl) {
|
||||
if (stl->error) return;
|
||||
/* Reallocate more memory for the .STL file(s) */
|
||||
stl->facet_start = (stl_facet*)realloc(stl->facet_start, stl->stats.number_of_facets *
|
||||
sizeof(stl_facet));
|
||||
if(stl->facet_start == NULL) perror("stl_initialize");
|
||||
stl->stats.facets_malloced = stl->stats.number_of_facets;
|
||||
|
||||
/* Reallocate more memory for the neighbors list */
|
||||
stl->neighbors_start = (stl_neighbors*)
|
||||
realloc(stl->neighbors_start, stl->stats.number_of_facets *
|
||||
sizeof(stl_neighbors));
|
||||
if(stl->facet_start == NULL) perror("stl_initialize");
|
||||
}
|
||||
|
||||
|
||||
/* Reads the contents of the file pointed to by stl->fp into the stl structure,
|
||||
/* Reads the contents of the file pointed to by fp into the stl structure,
|
||||
starting at facet first_facet. The second argument says if it's our first
|
||||
time running this for the stl and therefore we should reset our max and min stats. */
|
||||
void stl_read(stl_file *stl, int first_facet, bool first) {
|
||||
stl_facet facet;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
if(stl->stats.type == binary) {
|
||||
fseek(stl->fp, HEADER_SIZE, SEEK_SET);
|
||||
} else {
|
||||
rewind(stl->fp);
|
||||
}
|
||||
static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first)
|
||||
{
|
||||
if (stl->stats.type == binary)
|
||||
fseek(fp, HEADER_SIZE, SEEK_SET);
|
||||
else
|
||||
rewind(fp);
|
||||
|
||||
char normal_buf[3][32];
|
||||
for(uint32_t i = first_facet; i < stl->stats.number_of_facets; i++) {
|
||||
if(stl->stats.type == binary)
|
||||
/* Read a single facet from a binary .STL file */
|
||||
{
|
||||
/* we assume little-endian architecture! */
|
||||
if (fread(&facet, 1, SIZEOF_STL_FACET, stl->fp) != SIZEOF_STL_FACET) {
|
||||
stl->error = 1;
|
||||
return;
|
||||
}
|
||||
for (uint32_t i = first_facet; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_facet facet;
|
||||
|
||||
if (stl->stats.type == binary) {
|
||||
// Read a single facet from a binary .STL file. We assume little-endian architecture!
|
||||
if (fread(&facet, 1, SIZEOF_STL_FACET, fp) != SIZEOF_STL_FACET)
|
||||
return false;
|
||||
#ifndef BOOST_LITTLE_ENDIAN
|
||||
// Convert the loaded little endian data to big endian.
|
||||
stl_internal_reverse_quads((char*)&facet, 48);
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
} else
|
||||
/* Read a single facet from an ASCII .STL file */
|
||||
{
|
||||
} else {
|
||||
// Read a single facet from an ASCII .STL file
|
||||
// skip solid/endsolid
|
||||
// (in this order, otherwise it won't work when they are paired in the middle of a file)
|
||||
fscanf(stl->fp, "endsolid%*[^\n]\n");
|
||||
fscanf(stl->fp, "solid%*[^\n]\n"); // name might contain spaces so %*s doesn't work and it also can be empty (just "solid")
|
||||
fscanf(fp, "endsolid%*[^\n]\n");
|
||||
fscanf(fp, "solid%*[^\n]\n"); // name might contain spaces so %*s doesn't work and it also can be empty (just "solid")
|
||||
// Leading space in the fscanf format skips all leading white spaces including numerous new lines and tabs.
|
||||
int res_normal = fscanf(stl->fp, " facet normal %31s %31s %31s", normal_buf[0], normal_buf[1], normal_buf[2]);
|
||||
int res_normal = fscanf(fp, " facet normal %31s %31s %31s", normal_buf[0], normal_buf[1], normal_buf[2]);
|
||||
assert(res_normal == 3);
|
||||
int res_outer_loop = fscanf(stl->fp, " outer loop");
|
||||
int res_outer_loop = fscanf(fp, " outer loop");
|
||||
assert(res_outer_loop == 0);
|
||||
int res_vertex1 = fscanf(stl->fp, " vertex %f %f %f", &facet.vertex[0](0), &facet.vertex[0](1), &facet.vertex[0](2));
|
||||
int res_vertex1 = fscanf(fp, " vertex %f %f %f", &facet.vertex[0](0), &facet.vertex[0](1), &facet.vertex[0](2));
|
||||
assert(res_vertex1 == 3);
|
||||
int res_vertex2 = fscanf(stl->fp, " vertex %f %f %f", &facet.vertex[1](0), &facet.vertex[1](1), &facet.vertex[1](2));
|
||||
int res_vertex2 = fscanf(fp, " vertex %f %f %f", &facet.vertex[1](0), &facet.vertex[1](1), &facet.vertex[1](2));
|
||||
assert(res_vertex2 == 3);
|
||||
int res_vertex3 = fscanf(stl->fp, " vertex %f %f %f", &facet.vertex[2](0), &facet.vertex[2](1), &facet.vertex[2](2));
|
||||
int res_vertex3 = fscanf(fp, " vertex %f %f %f", &facet.vertex[2](0), &facet.vertex[2](1), &facet.vertex[2](2));
|
||||
assert(res_vertex3 == 3);
|
||||
int res_endloop = fscanf(stl->fp, " endloop");
|
||||
int res_endloop = fscanf(fp, " endloop");
|
||||
assert(res_endloop == 0);
|
||||
// There is a leading and trailing white space around endfacet to eat up all leading and trailing white spaces including numerous tabs and new lines.
|
||||
int res_endfacet = fscanf(stl->fp, " endfacet ");
|
||||
int res_endfacet = fscanf(fp, " endfacet ");
|
||||
if (res_normal != 3 || res_outer_loop != 0 || res_vertex1 != 3 || res_vertex2 != 3 || res_vertex3 != 3 || res_endloop != 0 || res_endfacet != 0) {
|
||||
perror("Something is syntactically very wrong with this ASCII STL!");
|
||||
stl->error = 1;
|
||||
return;
|
||||
BOOST_LOG_TRIVIAL(error) << "Something is syntactically very wrong with this ASCII STL! ";
|
||||
return false;
|
||||
}
|
||||
|
||||
// The facet normal has been parsed as a single string as to workaround for not a numbers in the normal definition.
|
||||
|
@ -335,19 +209,48 @@ void stl_read(stl_file *stl, int first_facet, bool first) {
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Write the facet into memory. */
|
||||
// Write the facet into memory.
|
||||
stl->facet_start[i] = facet;
|
||||
stl_facet_stats(stl, facet, first);
|
||||
}
|
||||
|
||||
stl->stats.size = stl->stats.max - stl->stats.min;
|
||||
stl->stats.bounding_diameter = stl->stats.size.norm();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stl_open(stl_file *stl, const char *file)
|
||||
{
|
||||
stl->clear();
|
||||
FILE *fp = stl_open_count_facets(stl, file);
|
||||
if (fp == nullptr)
|
||||
return false;
|
||||
stl_allocate(stl);
|
||||
bool result = stl_read(stl, fp, 0, true);
|
||||
fclose(fp);
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef BOOST_LITTLE_ENDIAN
|
||||
extern void stl_internal_reverse_quads(char *buf, size_t cnt);
|
||||
#endif /* BOOST_LITTLE_ENDIAN */
|
||||
|
||||
void stl_allocate(stl_file *stl)
|
||||
{
|
||||
// Allocate memory for the entire .STL file.
|
||||
stl->facet_start.assign(stl->stats.number_of_facets, stl_facet());
|
||||
// Allocate memory for the neighbors list.
|
||||
stl->neighbors_start.assign(stl->stats.number_of_facets, stl_neighbors());
|
||||
}
|
||||
|
||||
void stl_reallocate(stl_file *stl)
|
||||
{
|
||||
stl->facet_start.resize(stl->stats.number_of_facets);
|
||||
stl->neighbors_start.resize(stl->stats.number_of_facets);
|
||||
}
|
||||
|
||||
void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
// While we are going through all of the facets, let's find the
|
||||
// maximum and minimum values for x, y, and z
|
||||
|
||||
|
@ -366,20 +269,3 @@ void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first)
|
|||
stl->stats.max = stl->stats.max.cwiseMax(facet.vertex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void stl_close(stl_file *stl)
|
||||
{
|
||||
assert(stl->fp == nullptr);
|
||||
assert(stl->heads == nullptr);
|
||||
assert(stl->tail == nullptr);
|
||||
|
||||
if (stl->facet_start != NULL)
|
||||
free(stl->facet_start);
|
||||
if (stl->neighbors_start != NULL)
|
||||
free(stl->neighbors_start);
|
||||
if (stl->v_indices != NULL)
|
||||
free(stl->v_indices);
|
||||
if (stl->v_shared != NULL)
|
||||
free(stl->v_shared);
|
||||
memset(stl, 0, sizeof(stl_file));
|
||||
}
|
||||
|
|
|
@ -25,36 +25,30 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
static void stl_rotate(float *x, float *y, const double c, const double s);
|
||||
static float get_area(stl_facet *facet);
|
||||
static float get_volume(stl_file *stl);
|
||||
|
||||
|
||||
void
|
||||
stl_verify_neighbors(stl_file *stl) {
|
||||
int i;
|
||||
int j;
|
||||
stl_edge edge_a;
|
||||
stl_edge edge_b;
|
||||
int neighbor;
|
||||
int vnot;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
void stl_verify_neighbors(stl_file *stl)
|
||||
{
|
||||
stl->stats.backwards_edges = 0;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
struct stl_edge {
|
||||
stl_vertex p1;
|
||||
stl_vertex p2;
|
||||
int facet_number;
|
||||
};
|
||||
stl_edge edge_a;
|
||||
edge_a.p1 = stl->facet_start[i].vertex[j];
|
||||
edge_a.p2 = stl->facet_start[i].vertex[(j + 1) % 3];
|
||||
neighbor = stl->neighbors_start[i].neighbor[j];
|
||||
vnot = stl->neighbors_start[i].which_vertex_not[j];
|
||||
|
||||
if(neighbor == -1)
|
||||
continue; /* this edge has no neighbor... Continue. */
|
||||
if(vnot < 3) {
|
||||
int neighbor = stl->neighbors_start[i].neighbor[j];
|
||||
if (neighbor == -1)
|
||||
continue; // this edge has no neighbor... Continue.
|
||||
int vnot = stl->neighbors_start[i].which_vertex_not[j];
|
||||
stl_edge edge_b;
|
||||
if (vnot < 3) {
|
||||
edge_b.p1 = stl->facet_start[neighbor].vertex[(vnot + 2) % 3];
|
||||
edge_b.p2 = stl->facet_start[neighbor].vertex[(vnot + 1) % 3];
|
||||
} else {
|
||||
|
@ -63,9 +57,8 @@ stl_verify_neighbors(stl_file *stl) {
|
|||
edge_b.p2 = stl->facet_start[neighbor].vertex[(vnot + 2) % 3];
|
||||
}
|
||||
if (edge_a.p1 != edge_b.p1 || edge_a.p2 != edge_b.p2) {
|
||||
/* These edges should match but they don't. Print results. */
|
||||
printf("edge %d of facet %d doesn't match edge %d of facet %d\n",
|
||||
j, i, vnot + 1, neighbor);
|
||||
// These edges should match but they don't. Print results.
|
||||
BOOST_LOG_TRIVIAL(info) << "edge " << j << " of facet " << i << " doesn't match edge " << (vnot + 1) << " of facet " << neighbor;
|
||||
stl_write_facet(stl, (char*)"first facet", i);
|
||||
stl_write_facet(stl, (char*)"second facet", neighbor);
|
||||
}
|
||||
|
@ -75,9 +68,6 @@ stl_verify_neighbors(stl_file *stl) {
|
|||
|
||||
void stl_translate(stl_file *stl, float x, float y, float z)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
stl_vertex new_min(x, y, z);
|
||||
stl_vertex shift = new_min - stl->stats.min;
|
||||
for (int i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
|
@ -85,29 +75,21 @@ void stl_translate(stl_file *stl, float x, float y, float z)
|
|||
stl->facet_start[i].vertex[j] += shift;
|
||||
stl->stats.min = new_min;
|
||||
stl->stats.max += shift;
|
||||
stl_invalidate_shared_vertices(stl);
|
||||
}
|
||||
|
||||
/* Translates the stl by x,y,z, relatively from wherever it is currently */
|
||||
void stl_translate_relative(stl_file *stl, float x, float y, float z)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
stl_vertex shift(x, y, z);
|
||||
for (int i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j] += shift;
|
||||
stl->stats.min += shift;
|
||||
stl->stats.max += shift;
|
||||
stl_invalidate_shared_vertices(stl);
|
||||
}
|
||||
|
||||
void stl_scale_versor(stl_file *stl, const stl_vertex &versor)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
// Scale extents.
|
||||
auto s = versor.array();
|
||||
stl->stats.min.array() *= s;
|
||||
|
@ -121,99 +103,96 @@ void stl_scale_versor(stl_file *stl, const stl_vertex &versor)
|
|||
for (int i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j].array() *= s;
|
||||
stl_invalidate_shared_vertices(stl);
|
||||
}
|
||||
|
||||
static void calculate_normals(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
stl_normal normal;
|
||||
for(uint32_t i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_calculate_normal(normal, &stl->facet_start[i]);
|
||||
stl_normalize_vector(normal);
|
||||
stl->facet_start[i].normal = normal;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stl_rotate_x(stl_file *stl, float angle) {
|
||||
int i;
|
||||
int j;
|
||||
static inline void rotate_point_2d(float &x, float &y, const double c, const double s)
|
||||
{
|
||||
double xold = x;
|
||||
double yold = y;
|
||||
x = float(c * xold - s * yold);
|
||||
y = float(s * xold + c * yold);
|
||||
}
|
||||
|
||||
void stl_rotate_x(stl_file *stl, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
stl_rotate(&stl->facet_start[i].vertex[j](1),
|
||||
&stl->facet_start[i].vertex[j](2), c, s);
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
rotate_point_2d(stl->facet_start[i].vertex[j](1), stl->facet_start[i].vertex[j](2), c, s);
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void
|
||||
stl_rotate_y(stl_file *stl, float angle) {
|
||||
int i;
|
||||
int j;
|
||||
void stl_rotate_y(stl_file *stl, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
stl_rotate(&stl->facet_start[i].vertex[j](2),
|
||||
&stl->facet_start[i].vertex[j](0), c, s);
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
rotate_point_2d(stl->facet_start[i].vertex[j](2), stl->facet_start[i].vertex[j](0), c, s);
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void
|
||||
stl_rotate_z(stl_file *stl, float angle) {
|
||||
int i;
|
||||
int j;
|
||||
void stl_rotate_z(stl_file *stl, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
stl_rotate(&stl->facet_start[i].vertex[j](0),
|
||||
&stl->facet_start[i].vertex[j](1), c, s);
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
rotate_point_2d(stl->facet_start[i].vertex[j](0), stl->facet_start[i].vertex[j](1), c, s);
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void its_rotate_x(indexed_triangle_set &its, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
for (stl_vertex &v : its.vertices)
|
||||
rotate_point_2d(v(1), v(2), c, s);
|
||||
}
|
||||
|
||||
void its_rotate_y(indexed_triangle_set& its, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
for (stl_vertex& v : its.vertices)
|
||||
rotate_point_2d(v(2), v(0), c, s);
|
||||
}
|
||||
|
||||
static void
|
||||
stl_rotate(float *x, float *y, const double c, const double s) {
|
||||
double xold = *x;
|
||||
double yold = *y;
|
||||
*x = float(c * xold - s * yold);
|
||||
*y = float(s * xold + c * yold);
|
||||
void its_rotate_z(indexed_triangle_set& its, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
for (stl_vertex& v : its.vertices)
|
||||
rotate_point_2d(v(0), v(1), c, s);
|
||||
}
|
||||
|
||||
void stl_get_size(stl_file *stl)
|
||||
{
|
||||
if (stl->error || stl->stats.number_of_facets == 0)
|
||||
if (stl->stats.number_of_facets == 0)
|
||||
return;
|
||||
stl->stats.min = stl->facet_start[0].vertex[0];
|
||||
stl->stats.max = stl->stats.min;
|
||||
for (int i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
const stl_facet &face = stl->facet_start[i];
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
stl->stats.min = stl->stats.min.cwiseMin(face.vertex[j]);
|
||||
|
@ -226,14 +205,9 @@ void stl_get_size(stl_file *stl)
|
|||
|
||||
void stl_mirror_xy(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for(int j = 0; j < 3; j++) {
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j](2) *= -1.0;
|
||||
}
|
||||
}
|
||||
float temp_size = stl->stats.min(2);
|
||||
stl->stats.min(2) = stl->stats.max(2);
|
||||
stl->stats.max(2) = temp_size;
|
||||
|
@ -245,13 +219,9 @@ void stl_mirror_xy(stl_file *stl)
|
|||
|
||||
void stl_mirror_yz(stl_file *stl)
|
||||
{
|
||||
if (stl->error) return;
|
||||
|
||||
for (int i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; j++)
|
||||
stl->facet_start[i].vertex[j](0) *= -1.0;
|
||||
}
|
||||
}
|
||||
float temp_size = stl->stats.min(0);
|
||||
stl->stats.min(0) = stl->stats.max(0);
|
||||
stl->stats.max(0) = temp_size;
|
||||
|
@ -263,48 +233,16 @@ void stl_mirror_yz(stl_file *stl)
|
|||
|
||||
void stl_mirror_xz(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < stl->stats.number_of_facets; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j](1) *= -1.0;
|
||||
}
|
||||
}
|
||||
float temp_size = stl->stats.min(1);
|
||||
stl->stats.min(1) = stl->stats.max(1);
|
||||
stl->stats.max(1) = temp_size;
|
||||
stl->stats.min(1) *= -1.0;
|
||||
stl->stats.max(1) *= -1.0;
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.facets_reversed -= stl->stats.number_of_facets; /* for not altering stats */
|
||||
}
|
||||
|
||||
static float get_volume(stl_file *stl)
|
||||
{
|
||||
if (stl->error)
|
||||
return 0;
|
||||
|
||||
// Choose a point, any point as the reference.
|
||||
stl_vertex p0 = stl->facet_start[0].vertex[0];
|
||||
float volume = 0.f;
|
||||
for(uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
// Do dot product to get distance from point to plane.
|
||||
float height = stl->facet_start[i].normal.dot(stl->facet_start[i].vertex[0] - p0);
|
||||
float area = get_area(&stl->facet_start[i]);
|
||||
volume += (area * height) / 3.0f;
|
||||
}
|
||||
return volume;
|
||||
}
|
||||
|
||||
void stl_calculate_volume(stl_file *stl)
|
||||
{
|
||||
if (stl->error) return;
|
||||
stl->stats.volume = get_volume(stl);
|
||||
if(stl->stats.volume < 0.0) {
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.volume = -stl->stats.volume;
|
||||
}
|
||||
stl->stats.facets_reversed -= stl->stats.number_of_facets; // for not altering stats
|
||||
}
|
||||
|
||||
static float get_area(stl_facet *facet)
|
||||
|
@ -335,123 +273,125 @@ static float get_area(stl_facet *facet)
|
|||
return 0.5f * n.dot(sum);
|
||||
}
|
||||
|
||||
void stl_repair(stl_file *stl,
|
||||
int fixall_flag,
|
||||
int exact_flag,
|
||||
int tolerance_flag,
|
||||
static float get_volume(stl_file *stl)
|
||||
{
|
||||
// Choose a point, any point as the reference.
|
||||
stl_vertex p0 = stl->facet_start[0].vertex[0];
|
||||
float volume = 0.f;
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
// Do dot product to get distance from point to plane.
|
||||
float height = stl->facet_start[i].normal.dot(stl->facet_start[i].vertex[0] - p0);
|
||||
float area = get_area(&stl->facet_start[i]);
|
||||
volume += (area * height) / 3.0f;
|
||||
}
|
||||
return volume;
|
||||
}
|
||||
|
||||
void stl_calculate_volume(stl_file *stl)
|
||||
{
|
||||
stl->stats.volume = get_volume(stl);
|
||||
if (stl->stats.volume < 0.0) {
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.volume = -stl->stats.volume;
|
||||
}
|
||||
}
|
||||
|
||||
void stl_repair(
|
||||
stl_file *stl,
|
||||
bool fixall_flag,
|
||||
bool exact_flag,
|
||||
bool tolerance_flag,
|
||||
float tolerance,
|
||||
int increment_flag,
|
||||
bool increment_flag,
|
||||
float increment,
|
||||
int nearby_flag,
|
||||
bool nearby_flag,
|
||||
int iterations,
|
||||
int remove_unconnected_flag,
|
||||
int fill_holes_flag,
|
||||
int normal_directions_flag,
|
||||
int normal_values_flag,
|
||||
int reverse_all_flag,
|
||||
int verbose_flag) {
|
||||
|
||||
int i;
|
||||
int last_edges_fixed = 0;
|
||||
|
||||
if (stl->error) return;
|
||||
|
||||
if(exact_flag || fixall_flag || nearby_flag || remove_unconnected_flag
|
||||
|| fill_holes_flag || normal_directions_flag) {
|
||||
bool remove_unconnected_flag,
|
||||
bool fill_holes_flag,
|
||||
bool normal_directions_flag,
|
||||
bool normal_values_flag,
|
||||
bool reverse_all_flag,
|
||||
bool verbose_flag)
|
||||
{
|
||||
if (exact_flag || fixall_flag || nearby_flag || remove_unconnected_flag || fill_holes_flag || normal_directions_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Checking exact...\n");
|
||||
exact_flag = 1;
|
||||
exact_flag = true;
|
||||
stl_check_facets_exact(stl);
|
||||
stl->stats.facets_w_1_bad_edge =
|
||||
(stl->stats.connected_facets_2_edge -
|
||||
stl->stats.connected_facets_3_edge);
|
||||
stl->stats.facets_w_2_bad_edge =
|
||||
(stl->stats.connected_facets_1_edge -
|
||||
stl->stats.connected_facets_2_edge);
|
||||
stl->stats.facets_w_3_bad_edge =
|
||||
(stl->stats.number_of_facets -
|
||||
stl->stats.connected_facets_1_edge);
|
||||
stl->stats.facets_w_1_bad_edge = (stl->stats.connected_facets_2_edge - stl->stats.connected_facets_3_edge);
|
||||
stl->stats.facets_w_2_bad_edge = (stl->stats.connected_facets_1_edge - stl->stats.connected_facets_2_edge);
|
||||
stl->stats.facets_w_3_bad_edge = (stl->stats.number_of_facets - stl->stats.connected_facets_1_edge);
|
||||
}
|
||||
|
||||
if(nearby_flag || fixall_flag) {
|
||||
if(!tolerance_flag) {
|
||||
if (nearby_flag || fixall_flag) {
|
||||
if (! tolerance_flag)
|
||||
tolerance = stl->stats.shortest_edge;
|
||||
}
|
||||
if(!increment_flag) {
|
||||
if (! increment_flag)
|
||||
increment = stl->stats.bounding_diameter / 10000.0;
|
||||
}
|
||||
|
||||
if(stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
for(i = 0; i < iterations; i++) {
|
||||
if(stl->stats.connected_facets_3_edge <
|
||||
stl->stats.number_of_facets) {
|
||||
if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
int last_edges_fixed = 0;
|
||||
for (int i = 0; i < iterations; ++ i) {
|
||||
if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
if (verbose_flag)
|
||||
printf("\
|
||||
Checking nearby. Tolerance= %f Iteration=%d of %d...",
|
||||
tolerance, i + 1, iterations);
|
||||
printf("Checking nearby. Tolerance= %f Iteration=%d of %d...", tolerance, i + 1, iterations);
|
||||
stl_check_facets_nearby(stl, tolerance);
|
||||
if (verbose_flag)
|
||||
printf(" Fixed %d edges.\n",
|
||||
stl->stats.edges_fixed - last_edges_fixed);
|
||||
printf(" Fixed %d edges.\n", stl->stats.edges_fixed - last_edges_fixed);
|
||||
last_edges_fixed = stl->stats.edges_fixed;
|
||||
tolerance += increment;
|
||||
} else {
|
||||
if (verbose_flag)
|
||||
printf("\
|
||||
All facets connected. No further nearby check necessary.\n");
|
||||
printf("All facets connected. No further nearby check necessary.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (verbose_flag)
|
||||
} else if (verbose_flag)
|
||||
printf("All facets connected. No nearby check necessary.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(remove_unconnected_flag || fixall_flag || fill_holes_flag) {
|
||||
if(stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
if (remove_unconnected_flag || fixall_flag || fill_holes_flag) {
|
||||
if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
if (verbose_flag)
|
||||
printf("Removing unconnected facets...\n");
|
||||
stl_remove_unconnected_facets(stl);
|
||||
} else
|
||||
if (verbose_flag)
|
||||
} else if (verbose_flag)
|
||||
printf("No unconnected need to be removed.\n");
|
||||
}
|
||||
|
||||
if(fill_holes_flag || fixall_flag) {
|
||||
if(stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
if (fill_holes_flag || fixall_flag) {
|
||||
if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) {
|
||||
if (verbose_flag)
|
||||
printf("Filling holes...\n");
|
||||
stl_fill_holes(stl);
|
||||
} else
|
||||
if (verbose_flag)
|
||||
} else if (verbose_flag)
|
||||
printf("No holes need to be filled.\n");
|
||||
}
|
||||
|
||||
if(reverse_all_flag) {
|
||||
if (reverse_all_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Reversing all facets...\n");
|
||||
stl_reverse_all_facets(stl);
|
||||
}
|
||||
|
||||
if(normal_directions_flag || fixall_flag) {
|
||||
if (normal_directions_flag || fixall_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Checking normal directions...\n");
|
||||
stl_fix_normal_directions(stl);
|
||||
}
|
||||
|
||||
if(normal_values_flag || fixall_flag) {
|
||||
if (normal_values_flag || fixall_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Checking normal values...\n");
|
||||
stl_fix_normal_values(stl);
|
||||
}
|
||||
|
||||
/* Always calculate the volume. It shouldn't take too long */
|
||||
// Always calculate the volume. It shouldn't take too long.
|
||||
if (verbose_flag)
|
||||
printf("Calculating volume...\n");
|
||||
stl_calculate_volume(stl);
|
||||
|
||||
if(exact_flag) {
|
||||
if (exact_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Verifying neighbors...\n");
|
||||
stl_verify_neighbors(stl);
|
||||
|
|
|
@ -74,6 +74,10 @@ if (MSVC)
|
|||
windows/unistd.cpp
|
||||
windows/getopt.c
|
||||
)
|
||||
elseif (MINGW)
|
||||
set(AVRDUDE_SOURCES ${AVRDUDE_SOURCES}
|
||||
windows/utf8.c
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(avrdude-conf-gen conf-generate.cpp)
|
||||
|
@ -81,13 +85,13 @@ add_executable(avrdude-conf-gen conf-generate.cpp)
|
|||
# Config file embedding
|
||||
add_custom_command(
|
||||
DEPENDS avrdude-conf-gen ${CMAKE_CURRENT_SOURCE_DIR}/avrdude-slic3r.conf
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/avrdude-slic3r.conf.h
|
||||
COMMAND $<TARGET_FILE:avrdude-conf-gen> avrdude-slic3r.conf avrdude_slic3r_conf > avrdude-slic3r.conf.h
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/avrdude-slic3r.conf.h
|
||||
COMMAND $<TARGET_FILE:avrdude-conf-gen> avrdude-slic3r.conf avrdude_slic3r_conf ${CMAKE_CURRENT_BINARY_DIR}/avrdude-slic3r.conf.h
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
add_custom_target(gen_conf_h
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/avrdude-slic3r.conf.h
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/avrdude-slic3r.conf.h
|
||||
)
|
||||
|
||||
add_library(avrdude STATIC ${AVRDUDE_SOURCES})
|
||||
|
@ -96,7 +100,15 @@ add_dependencies(avrdude gen_conf_h)
|
|||
add_executable(avrdude-slic3r main-standalone.cpp)
|
||||
target_link_libraries(avrdude-slic3r avrdude)
|
||||
|
||||
encoding_check(avrdude)
|
||||
encoding_check(avrdude-slic3r)
|
||||
|
||||
# Make avrdude-slic3r.conf.h includable:
|
||||
target_include_directories(avrdude SYSTEM PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if (WIN32)
|
||||
target_compile_definitions(avrdude PRIVATE WIN32NATIVE=1)
|
||||
if(MSVC)
|
||||
target_include_directories(avrdude SYSTEM PRIVATE windows) # So that sources find the getopt.h windows drop-in
|
||||
endif(MSVC)
|
||||
endif()
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
(void)p;
|
||||
|
||||
/* Signature byte reads are always 3 bytes. */
|
||||
|
||||
|
@ -83,9 +84,9 @@ static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
|||
static int prusa_init_external_flash(PROGRAMMER * pgm)
|
||||
{
|
||||
// Note: send/receive as in _the firmare_ send & receives
|
||||
const char entry_magic_send [] = "start\n";
|
||||
const char entry_magic_receive[] = "w25x20cl_enter\n";
|
||||
const char entry_magic_cfm [] = "w25x20cl_cfm\n";
|
||||
const char entry_magic_send[] = "start\n";
|
||||
const unsigned char entry_magic_receive[] = "w25x20cl_enter\n";
|
||||
const char entry_magic_cfm[] = "w25x20cl_cfm\n";
|
||||
const size_t buffer_len = 32; // Should be large enough for the above messages
|
||||
|
||||
int res;
|
||||
|
@ -94,7 +95,7 @@ static int prusa_init_external_flash(PROGRAMMER * pgm)
|
|||
|
||||
// 1. receive the "start" command
|
||||
recv_size = sizeof(entry_magic_send) - 1;
|
||||
res = serial_recv(&pgm->fd, buffer, recv_size);
|
||||
res = serial_recv(&pgm->fd, (unsigned char *)buffer, recv_size);
|
||||
if (res < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
|
||||
return -1;
|
||||
|
@ -111,7 +112,7 @@ static int prusa_init_external_flash(PROGRAMMER * pgm)
|
|||
|
||||
// 3. Receive the entry confirmation command
|
||||
recv_size = sizeof(entry_magic_cfm) - 1;
|
||||
res = serial_recv(&pgm->fd, buffer, recv_size);
|
||||
res = serial_recv(&pgm->fd, (unsigned char *)buffer, recv_size);
|
||||
if (res < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
|
||||
return -1;
|
||||
|
@ -142,7 +143,7 @@ static int arduino_open(PROGRAMMER * pgm, char * port)
|
|||
|
||||
// Sometimes there may be line noise generating input on the printer's USB-to-serial IC
|
||||
// Here we try to clean its input buffer with a sequence of newlines (a minimum of 9 is needed):
|
||||
const char cleanup_newlines[] = "\n\n\n\n\n\n\n\n\n\n";
|
||||
const unsigned char cleanup_newlines[] = "\n\n\n\n\n\n\n\n\n\n";
|
||||
if (serial_send(&pgm->fd, cleanup_newlines, sizeof(cleanup_newlines) - 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -341,7 +341,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
|||
avr_tpi_setup_rw(pgm, mem, 0, TPI_NVMCMD_NO_OPERATION);
|
||||
|
||||
/* load bytes */
|
||||
for (lastaddr = i = 0; i < mem->size; i++) {
|
||||
for (lastaddr = i = 0; i < (unsigned)mem->size; i++) {
|
||||
RETURN_IF_CANCEL();
|
||||
if (vmem == NULL ||
|
||||
(vmem->tags[i] & TAG_ALLOCATED) != 0)
|
||||
|
@ -374,7 +374,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
|||
|
||||
/* quickly scan number of pages to be written to first */
|
||||
for (pageaddr = 0, npages = 0;
|
||||
pageaddr < mem->size;
|
||||
pageaddr < (unsigned)mem->size;
|
||||
pageaddr += mem->page_size) {
|
||||
/* check whether this page must be read */
|
||||
for (i = pageaddr;
|
||||
|
@ -391,7 +391,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
|||
}
|
||||
|
||||
for (pageaddr = 0, failure = 0, nread = 0;
|
||||
!failure && pageaddr < mem->size;
|
||||
!failure && pageaddr < (unsigned)mem->size;
|
||||
pageaddr += mem->page_size) {
|
||||
RETURN_IF_CANCEL();
|
||||
/* check whether this page must be read */
|
||||
|
@ -437,7 +437,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
|||
}
|
||||
}
|
||||
|
||||
for (i=0; i < mem->size; i++) {
|
||||
for (i = 0; i < (unsigned)mem->size; i++) {
|
||||
RETURN_IF_CANCEL();
|
||||
if (vmem == NULL ||
|
||||
(vmem->tags[i] & TAG_ALLOCATED) != 0)
|
||||
|
@ -634,18 +634,18 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
writeop = mem->op[AVR_OP_WRITE_HI];
|
||||
else
|
||||
writeop = mem->op[AVR_OP_WRITE_LO];
|
||||
caddr = addr / 2;
|
||||
caddr = (unsigned short)(addr / 2);
|
||||
}
|
||||
else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) {
|
||||
if (addr & 0x01)
|
||||
writeop = mem->op[AVR_OP_LOADPAGE_HI];
|
||||
else
|
||||
writeop = mem->op[AVR_OP_LOADPAGE_LO];
|
||||
caddr = addr / 2;
|
||||
caddr = (unsigned short)(addr / 2);
|
||||
}
|
||||
else {
|
||||
writeop = mem->op[AVR_OP_WRITE];
|
||||
caddr = addr;
|
||||
caddr = (unsigned short)addr;
|
||||
}
|
||||
|
||||
if (writeop == NULL) {
|
||||
|
@ -723,7 +723,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
gettimeofday (&tv, NULL);
|
||||
prog_time = (tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
} while ((r != data) &&
|
||||
((prog_time-start_time) < mem->max_write_delay));
|
||||
((prog_time - start_time) < (unsigned long)mem->max_write_delay));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -878,7 +878,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||
}
|
||||
|
||||
/* write words, low byte first */
|
||||
for (lastaddr = i = 0; i < wsize; i += 2) {
|
||||
for (lastaddr = i = 0; i < (unsigned)wsize; i += 2) {
|
||||
RETURN_IF_CANCEL();
|
||||
if ((m->tags[i] & TAG_ALLOCATED) != 0 ||
|
||||
(m->tags[i + 1] & TAG_ALLOCATED) != 0) {
|
||||
|
@ -915,7 +915,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||
|
||||
/* quickly scan number of pages to be written to first */
|
||||
for (pageaddr = 0, npages = 0;
|
||||
pageaddr < wsize;
|
||||
pageaddr < (unsigned)wsize;
|
||||
pageaddr += m->page_size) {
|
||||
/* check whether this page must be written to */
|
||||
for (i = pageaddr;
|
||||
|
@ -928,7 +928,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||
}
|
||||
|
||||
for (pageaddr = 0, failure = 0, nwritten = 0;
|
||||
!failure && pageaddr < wsize;
|
||||
!failure && pageaddr < (unsigned)wsize;
|
||||
pageaddr += m->page_size) {
|
||||
RETURN_IF_CANCEL();
|
||||
/* check whether this page must be written to */
|
||||
|
@ -968,7 +968,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
|||
page_tainted = 0;
|
||||
flush_page = 0;
|
||||
|
||||
for (i=0; i<wsize; i++) {
|
||||
for (i = 0; i < (unsigned)wsize; i++) {
|
||||
RETURN_IF_CANCEL();
|
||||
data = m->buf[i];
|
||||
report_progress(i, wsize, NULL);
|
||||
|
|
|
@ -676,7 +676,7 @@ static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
avr910_set_addr(pgm, addr / rd_size);
|
||||
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
if ((max_addr - addr) < (unsigned)blocksize) {
|
||||
blocksize = max_addr - addr;
|
||||
}
|
||||
cmd[1] = (blocksize >> 8) & 0xff;
|
||||
|
|
|
@ -93,7 +93,7 @@ void AvrDude::priv::unset_handlers()
|
|||
|
||||
|
||||
int AvrDude::priv::run_one(const std::vector<std::string> &args) {
|
||||
std::vector<char*> c_args {{ const_cast<char*>(PACKAGE) }};
|
||||
std::vector<char*> c_args { const_cast<char*>(PACKAGE) };
|
||||
std::string command_line { PACKAGE };
|
||||
|
||||
for (const auto &arg : args) {
|
||||
|
@ -105,7 +105,7 @@ int AvrDude::priv::run_one(const std::vector<std::string> &args) {
|
|||
|
||||
HandlerGuard guard(*this);
|
||||
|
||||
message_fn(command_line.c_str(), command_line.size());
|
||||
message_fn(command_line.c_str(), (unsigned)command_line.size());
|
||||
|
||||
const auto res = ::avrdude_main(static_cast<int>(c_args.size()), c_args.data());
|
||||
|
||||
|
@ -200,7 +200,7 @@ AvrDude::Ptr AvrDude::run()
|
|||
auto &message_fn = self->p->message_fn;
|
||||
if (message_fn) {
|
||||
message_fn(msg, sizeof(msg));
|
||||
message_fn(what, std::strlen(what));
|
||||
message_fn(what, (unsigned)std::strlen(what));
|
||||
message_fn("\n", 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ int avrdude_main(int argc, char * argv []);
|
|||
#include <windows.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define strdup _strdup
|
||||
|
||||
#ifdef UNICODE
|
||||
#error "UNICODE should not be defined for avrdude bits on Windows"
|
||||
#endif
|
||||
|
|
|
@ -358,7 +358,7 @@ AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
|||
int matches;
|
||||
int l;
|
||||
|
||||
l = strlen(desc);
|
||||
l = (int)strlen(desc);
|
||||
matches = 0;
|
||||
match = NULL;
|
||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||
|
@ -662,7 +662,7 @@ void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
|
|||
prefix);
|
||||
|
||||
px = prefix;
|
||||
i = strlen(prefix) + 5;
|
||||
i = (int)strlen(prefix) + 5;
|
||||
buf = (char *)malloc(i);
|
||||
if (buf == NULL) {
|
||||
/* ugh, this is not important enough to bail, just ignore it */
|
||||
|
|
|
@ -128,7 +128,7 @@ static int buspirate_recv_bin(struct programmer_t *pgm, unsigned char *buf, size
|
|||
avrdude_message(MSG_DEBUG, "%s: buspirate_recv_bin():\n", progname);
|
||||
dump_mem(MSG_DEBUG, buf, len);
|
||||
|
||||
return len;
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
static int buspirate_expect_bin(struct programmer_t *pgm,
|
||||
|
@ -249,7 +249,7 @@ static int buspirate_send(struct programmer_t *pgm, const char *str)
|
|||
|
||||
static int buspirate_is_prompt(const char *str)
|
||||
{
|
||||
int strlen_str = strlen(str);
|
||||
int strlen_str = (int)strlen(str);
|
||||
/* Prompt ends with '>' or '> '
|
||||
* all other input probably ends with '\n' */
|
||||
return (str[strlen_str - 1] == '>' || str[strlen_str - 2] == '>');
|
||||
|
|
|
@ -675,7 +675,7 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
butterfly_set_addr(pgm, addr / rd_size);
|
||||
}
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
if ((max_addr - addr) < (unsigned)blocksize) {
|
||||
blocksize = max_addr - addr;
|
||||
};
|
||||
cmd[1] = (blocksize >> 8) & 0xff;
|
||||
|
|
|
@ -6,36 +6,42 @@
|
|||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " <file> <symbol name>" << std::endl;
|
||||
if (argc != 4) {
|
||||
std::cerr << "Usage: " << argv[0] << " <file> <symbol name> <output file>" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* filename = argv[1];
|
||||
const char* filename_in = argv[1];
|
||||
const char* symbol = argv[2];
|
||||
const char* filename_out = argv[3];
|
||||
|
||||
size_t size = 0;
|
||||
std::fstream file(filename);
|
||||
std::fstream file(filename_in, std::ios::in | std::ios::binary);
|
||||
if (!file.good()) {
|
||||
std::cerr << "Cannot read file: " << filename << std::endl;
|
||||
std::cerr << "Cannot read file: " << filename_in << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "/* WARN: This file is auto-generated from `" << filename << "` */" << std::endl;
|
||||
std::cout << "unsigned char " << symbol << "[] = {";
|
||||
std::fstream output(filename_out, std::ios::out | std::ios::trunc);
|
||||
if (!output.good()) {
|
||||
std::cerr << "Cannot open output file: " << filename_out << std::endl;
|
||||
}
|
||||
|
||||
output << "/* WARN: This file is auto-generated from `" << filename_in << "` */" << std::endl;
|
||||
output << "const unsigned char " << symbol << "[] = {";
|
||||
|
||||
char c;
|
||||
std::cout << std::hex;
|
||||
std::cout.fill('0');
|
||||
output << std::hex;
|
||||
output.fill('0');
|
||||
for (file.get(c); !file.eof(); size++, file.get(c)) {
|
||||
if (size % 12 == 0) { std::cout << "\n "; }
|
||||
std::cout << "0x" << std::setw(2) << (unsigned)c << ", ";
|
||||
if (size % 12 == 0) { output << "\n "; }
|
||||
output << "0x" << std::setw(2) << (unsigned)c << ", ";
|
||||
}
|
||||
|
||||
std::cout << "\n 0, 0\n};\n";
|
||||
output << "\n 0, 0\n};\n";
|
||||
|
||||
std::cout << std::dec;
|
||||
std::cout << "size_t " << symbol << "_size = " << size << ";" << std::endl;
|
||||
std::cout << "size_t " << symbol << "_size_yy = " << size + 2 << ";" << std::endl;
|
||||
output << std::dec;
|
||||
output << "const size_t " << symbol << "_size = " << size << ";" << std::endl;
|
||||
output << "const size_t " << symbol << "_size_yy = " << size + 2 << ";" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ TOKEN * string(char * text)
|
|||
return NULL; /* yyerror already called */
|
||||
}
|
||||
|
||||
len = strlen(text);
|
||||
len = (int)strlen(text);
|
||||
|
||||
tkn->value.type = V_STR;
|
||||
tkn->value.string = (char *) malloc(len+1);
|
||||
|
@ -351,7 +351,7 @@ int read_config(const char * file)
|
|||
}
|
||||
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
extern YY_BUFFER_STATE yy_scan_bytes(char *base, size_t size);
|
||||
extern YY_BUFFER_STATE yy_scan_bytes(const char *base, size_t size);
|
||||
extern void yy_delete_buffer(YY_BUFFER_STATE b);
|
||||
|
||||
int read_config_builtin()
|
||||
|
@ -363,7 +363,7 @@ int read_config_builtin()
|
|||
|
||||
// Note: Can't use yy_scan_buffer, it's buggy (?), leads to fread from a null FILE*
|
||||
// and so unfortunatelly we have to use the copying variant here
|
||||
YY_BUFFER_STATE buffer = yy_scan_bytes(avrdude_slic3r_conf, avrdude_slic3r_conf_size);
|
||||
YY_BUFFER_STATE buffer = yy_scan_bytes((const char *)avrdude_slic3r_conf, avrdude_slic3r_conf_size);
|
||||
if (buffer == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: read_config_builtin: Failed to initialize parsing buffer\n", progname);
|
||||
return -1;
|
||||
|
|
|
@ -3640,7 +3640,7 @@ static int parse_cmdbits(OPCODE * op)
|
|||
break;
|
||||
}
|
||||
|
||||
len = strlen(s);
|
||||
len = (int)strlen(s);
|
||||
|
||||
if (len == 0) {
|
||||
yyerror("invalid bit specifier \"\"");
|
||||
|
|
|
@ -1493,7 +1493,7 @@ static int parse_cmdbits(OPCODE * op)
|
|||
break;
|
||||
}
|
||||
|
||||
len = strlen(s);
|
||||
len = (int)strlen(s);
|
||||
|
||||
if (len == 0) {
|
||||
yyerror("invalid bit specifier \"\"");
|
||||
|
|
|
@ -264,7 +264,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
|
|||
unsigned char cksum;
|
||||
int rc;
|
||||
|
||||
len = strlen(rec);
|
||||
len = (int)strlen(rec);
|
||||
offset = 1;
|
||||
cksum = 0;
|
||||
|
||||
|
@ -274,7 +274,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
|
|||
for (i=0; i<2; i++)
|
||||
buf[i] = rec[offset++];
|
||||
buf[i] = 0;
|
||||
ihex->reclen = strtoul(buf, &e, 16);
|
||||
ihex->reclen = (unsigned char)strtoul(buf, &e, 16);
|
||||
if (e == buf || *e != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -294,7 +294,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
|
|||
for (i=0; i<2; i++)
|
||||
buf[i] = rec[offset++];
|
||||
buf[i] = 0;
|
||||
ihex->rectyp = strtoul(buf, &e, 16);
|
||||
ihex->rectyp = (unsigned char)strtoul(buf, &e, 16);
|
||||
if (e == buf || *e != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -308,7 +308,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
|
|||
for (i=0; i<2; i++)
|
||||
buf[i] = rec[offset++];
|
||||
buf[i] = 0;
|
||||
ihex->data[j] = strtoul(buf, &e, 16);
|
||||
ihex->data[j] = (char)strtoul(buf, &e, 16);
|
||||
if (e == buf || *e != 0)
|
||||
return -1;
|
||||
cksum += ihex->data[j];
|
||||
|
@ -320,7 +320,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
|
|||
for (i=0; i<2; i++)
|
||||
buf[i] = rec[offset++];
|
||||
buf[i] = 0;
|
||||
ihex->cksum = strtoul(buf, &e, 16);
|
||||
ihex->cksum = (char)strtoul(buf, &e, 16);
|
||||
if (e == buf || *e != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -361,7 +361,7 @@ static int ihex2b(char * infile, FILE * inf,
|
|||
|
||||
while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
|
||||
lineno++;
|
||||
len = strlen(buffer);
|
||||
len = (int)strlen(buffer);
|
||||
if (buffer[len-1] == '\n')
|
||||
buffer[--len] = 0;
|
||||
if (buffer[0] != ':')
|
||||
|
@ -388,7 +388,7 @@ static int ihex2b(char * infile, FILE * inf,
|
|||
return -1;
|
||||
}
|
||||
nextaddr = ihex.loadofs + baseaddr - fileoffset;
|
||||
if (nextaddr + ihex.reclen > bufsize) {
|
||||
if (nextaddr + ihex.reclen > (unsigned)bufsize) {
|
||||
avrdude_message(MSG_INFO, "%s: ERROR: address 0x%04x out of range at line %d of %s\n",
|
||||
progname, nextaddr+ihex.reclen, lineno, infile);
|
||||
return -1;
|
||||
|
@ -502,10 +502,11 @@ static int b2srec(unsigned char * inbuf, int bufsize,
|
|||
|
||||
cksum += n + addr_width + 1;
|
||||
|
||||
for (i=addr_width; i>0; i--)
|
||||
for (i = addr_width; i>0; i--) {
|
||||
cksum += (nextaddr >> (i-1) * 8) & 0xff;
|
||||
}
|
||||
|
||||
for (i=nextaddr; i<nextaddr + n; i++) {
|
||||
for (unsigned i = nextaddr; i < nextaddr + n; i++) {
|
||||
fprintf(outf, "%02X", buf[i]);
|
||||
cksum += buf[i];
|
||||
}
|
||||
|
@ -562,7 +563,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
|
|||
unsigned char cksum;
|
||||
int rc;
|
||||
|
||||
len = strlen(rec);
|
||||
len = (int)strlen(rec);
|
||||
offset = 1;
|
||||
cksum = 0;
|
||||
addr_width = 2;
|
||||
|
@ -582,7 +583,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
|
|||
for (i=0; i<2; i++)
|
||||
buf[i] = rec[offset++];
|
||||
buf[i] = 0;
|
||||
srec->reclen = strtoul(buf, &e, 16);
|
||||
srec->reclen = (char)strtoul(buf, &e, 16);
|
||||
cksum += srec->reclen;
|
||||
srec->reclen -= (addr_width+1);
|
||||
if (e == buf || *e != 0)
|
||||
|
@ -594,7 +595,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
|
|||
for (i=0; i<addr_width*2; i++)
|
||||
buf[i] = rec[offset++];
|
||||
buf[i] = 0;
|
||||
srec->loadofs = strtoull(buf, &e, 16);
|
||||
srec->loadofs = strtoul(buf, &e, 16);
|
||||
if (e == buf || *e != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -608,7 +609,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
|
|||
for (i=0; i<2; i++)
|
||||
buf[i] = rec[offset++];
|
||||
buf[i] = 0;
|
||||
srec->data[j] = strtoul(buf, &e, 16);
|
||||
srec->data[j] = (char)strtoul(buf, &e, 16);
|
||||
if (e == buf || *e != 0)
|
||||
return -1;
|
||||
cksum += srec->data[j];
|
||||
|
@ -620,7 +621,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
|
|||
for (i=0; i<2; i++)
|
||||
buf[i] = rec[offset++];
|
||||
buf[i] = 0;
|
||||
srec->cksum = strtoul(buf, &e, 16);
|
||||
srec->cksum = (char)strtoul(buf, &e, 16);
|
||||
if (e == buf || *e != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -650,7 +651,7 @@ static int srec2b(char * infile, FILE * inf,
|
|||
|
||||
while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
|
||||
lineno++;
|
||||
len = strlen(buffer);
|
||||
len = (int)strlen(buffer);
|
||||
if (buffer[len-1] == '\n')
|
||||
buffer[--len] = 0;
|
||||
if (buffer[0] != 0x53)
|
||||
|
@ -729,7 +730,7 @@ static int srec2b(char * infile, FILE * inf,
|
|||
return -1;
|
||||
}
|
||||
nextaddr -= fileoffset;
|
||||
if (nextaddr + srec.reclen > bufsize) {
|
||||
if (nextaddr + srec.reclen > (unsigned)bufsize) {
|
||||
avrdude_message(MSG_INFO, msg, progname, nextaddr+srec.reclen, "",
|
||||
lineno, infile);
|
||||
return -1;
|
||||
|
@ -1143,12 +1144,12 @@ static int fileio_rbin(struct fioparms * fio,
|
|||
|
||||
switch (fio->op) {
|
||||
case FIO_READ:
|
||||
rc = fread(buf, 1, size, f);
|
||||
rc = (int)fread(buf, 1, size, f);
|
||||
if (rc > 0)
|
||||
memset(mem->tags, TAG_ALLOCATED, rc);
|
||||
break;
|
||||
case FIO_WRITE:
|
||||
rc = fwrite(buf, 1, size, f);
|
||||
rc = (int)fwrite(buf, 1, size, f);
|
||||
break;
|
||||
default:
|
||||
avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
|
||||
|
@ -1190,7 +1191,7 @@ static int fileio_imm(struct fioparms * fio,
|
|||
progname, p);
|
||||
return -1;
|
||||
}
|
||||
mem->buf[loc] = b;
|
||||
mem->buf[loc] = (char)b;
|
||||
mem->tags[loc++] = TAG_ALLOCATED;
|
||||
p = strtok(NULL, " ,");
|
||||
rc = loc;
|
||||
|
@ -1452,7 +1453,7 @@ static int fmt_autodetect(char * fname, unsigned section)
|
|||
}
|
||||
|
||||
buf[MAX_LINE_LEN-1] = 0;
|
||||
len = strlen((char *)buf);
|
||||
len = (int)strlen((char *)buf);
|
||||
if (buf[len-1] == '\n')
|
||||
buf[--len] = 0;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
|
||||
|
||||
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(_MSC_VER)
|
||||
|
||||
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
|
||||
* if you want the limit (max/min) macros for int types.
|
||||
|
|
|
@ -444,7 +444,7 @@ lcreat ( void * liststruct, int elements )
|
|||
l->poolsize = DEFAULT_POOLSIZE;
|
||||
}
|
||||
else {
|
||||
l->poolsize = elements*sizeof(LISTNODE)+sizeof(NODEPOOL);
|
||||
l->poolsize = (short)(elements*sizeof(LISTNODE)+sizeof(NODEPOOL));
|
||||
}
|
||||
|
||||
l->n_ln_pool = (l->poolsize-sizeof(NODEPOOL))/sizeof(LISTNODE);
|
||||
|
@ -803,7 +803,7 @@ lget_n ( LISTID lid, unsigned int n )
|
|||
|
||||
CKLMAGIC(l);
|
||||
|
||||
if ((n<1)||(n>lsize(l))) {
|
||||
if ((n < 1) || (n > (unsigned)lsize(l))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -844,7 +844,7 @@ lget_ln ( LISTID lid, unsigned int n )
|
|||
|
||||
CKLMAGIC(l);
|
||||
|
||||
if ((n<1)||(n>lsize(l))) {
|
||||
if ((n < 1) || (n > (unsigned)lsize(l))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -952,7 +952,7 @@ lins_n ( LISTID lid, void * data_ptr, unsigned int n )
|
|||
|
||||
CKLMAGIC(l);
|
||||
|
||||
if ((n<1)||(n>(l->num+1))) {
|
||||
if ((n < 1) || (n > (unsigned)(l->num+1))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1193,7 +1193,7 @@ lrmv_n ( LISTID lid, unsigned int n )
|
|||
|
||||
CKLMAGIC(l);
|
||||
|
||||
if ((n<1)||(n>l->num)) {
|
||||
if ((n < 1) || (n > (unsigned)l->num)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,10 @@ struct ArgvUtf8 : std::vector<char*>
|
|||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
int wmain(int argc_w, wchar_t *argv_w[])
|
||||
{
|
||||
ArgvUtf8 argv_utf8(argc_w, argv_w);
|
||||
|
|
|
@ -107,7 +107,7 @@ int avrdude_message(const int msglvl, const char *format, ...)
|
|||
if (rc > 0 && rc < MSGBUFFER_SIZE) {
|
||||
avrdude_message_handler(msgbuffer, rc, avrdude_message_handler_user_p);
|
||||
} else {
|
||||
avrdude_message_handler(format_error, strlen(format_error), avrdude_message_handler_user_p);
|
||||
avrdude_message_handler(format_error, (unsigned)strlen(format_error), avrdude_message_handler_user_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,7 +567,7 @@ int avrdude_main(int argc, char * argv [])
|
|||
|
||||
// #endif
|
||||
|
||||
len = strlen(progname) + 2;
|
||||
len = (int)strlen(progname) + 2;
|
||||
for (i=0; i<len; i++)
|
||||
progbuf[i] = ' ';
|
||||
progbuf[i] = 0;
|
||||
|
@ -601,7 +601,7 @@ int avrdude_main(int argc, char * argv [])
|
|||
bitclock = strtod(optarg, &e);
|
||||
if (*e != 0) {
|
||||
/* trailing unit of measure present */
|
||||
int suffixlen = strlen(e);
|
||||
size_t suffixlen = strlen(e);
|
||||
switch (suffixlen) {
|
||||
case 2:
|
||||
if ((e[0] != 'h' && e[0] != 'H') || e[1] != 'z')
|
||||
|
|
|
@ -217,7 +217,7 @@ const char * pinmask_to_str(const pinmask_t * const pinmask) {
|
|||
* @param[in] size the number of entries in checklist
|
||||
* @returns 0 if all pin definitions are valid, -1 otherwise
|
||||
*/
|
||||
int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, bool output) {
|
||||
int pins_check(const struct programmer_t *const pgm, const struct pin_checklist_t *const checklist, const int size, const bool output) {
|
||||
static const struct pindef_t no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else
|
||||
int rv = 0; // return value
|
||||
int pinname; // loop counter through pinnames
|
||||
|
|
|
@ -292,7 +292,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
|
|||
if (hComPort == INVALID_HANDLE_VALUE) {
|
||||
const char *error = last_error_string(0);
|
||||
avrdude_message(MSG_INFO, "%s: ser_open(): can't open device \"%s\": %s\n", progname, port, error);
|
||||
free(error);
|
||||
free((char *)error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -460,10 +460,10 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
|
|||
|
||||
serial_w32SetTimeOut(hComPort,500);
|
||||
|
||||
if (!WriteFile(hComPort, buf, buflen, &written, NULL)) {
|
||||
if (!WriteFile(hComPort, buf, (DWORD)buflen, &written, NULL)) {
|
||||
const char *error = last_error_string(0);
|
||||
avrdude_message(MSG_INFO, "%s: ser_send(): write error: %s\n", progname, error);
|
||||
free(error);
|
||||
free((char *)error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -576,10 +576,10 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
|||
|
||||
serial_w32SetTimeOut(hComPort, serial_recv_timeout);
|
||||
|
||||
if (!ReadFile(hComPort, buf, buflen, &read, NULL)) {
|
||||
if (!ReadFile(hComPort, buf, (DWORD)buflen, &read, NULL)) {
|
||||
const char *error = last_error_string(0);
|
||||
avrdude_message(MSG_INFO, "%s: ser_recv(): read error: %s\n", progname, error);
|
||||
free(error);
|
||||
free((char *)error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -642,7 +642,7 @@ static int ser_drain(union filedescriptor *fd, int display)
|
|||
if (!readres) {
|
||||
const char *error = last_error_string(0);
|
||||
avrdude_message(MSG_INFO, "%s: ser_drain(): read error: %s\n", progname, error);
|
||||
free(error);
|
||||
free((char *)error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -308,8 +308,8 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
|
|||
progname, port);
|
||||
return -1;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle 0x%x\n",
|
||||
progname, port, (int)hComPort);
|
||||
avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle %p\n",
|
||||
progname, port, (void *)hComPort);
|
||||
|
||||
pgm->fd.pfd = (void *)hComPort;
|
||||
|
||||
|
@ -326,8 +326,8 @@ static void serbb_close(PROGRAMMER *pgm)
|
|||
pgm->setpin(pgm, PIN_AVR_RESET, 1);
|
||||
CloseHandle (hComPort);
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle 0x%x\n",
|
||||
progname, (int)hComPort);
|
||||
avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle %p\n",
|
||||
progname, (void *)hComPort);
|
||||
|
||||
hComPort = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
|
|
@ -821,7 +821,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
break;
|
||||
}
|
||||
|
||||
for (prusa3d_semicolon_workaround_round = 0; prusa3d_semicolon_workaround_round < (has_semicolon ? 2 : 1); ++ prusa3d_semicolon_workaround_round) {
|
||||
for (prusa3d_semicolon_workaround_round = 0; prusa3d_semicolon_workaround_round < (has_semicolon ? 2u : 1u); prusa3d_semicolon_workaround_round++) {
|
||||
/* build command block and avoid multiple send commands as it leads to a crash
|
||||
of the silabs usb serial driver on mac os x */
|
||||
i = 0;
|
||||
|
@ -834,7 +834,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
buf[i++] = block_size & 0x0f;
|
||||
buf[i++] = memtype;
|
||||
if (has_semicolon) {
|
||||
for (j = 0; j < block_size; ++i, ++ j) {
|
||||
for (j = 0; j < (unsigned)block_size; ++i, ++ j) {
|
||||
buf[i] = m->buf[addr + j];
|
||||
if (buf[i] == ';')
|
||||
buf[i] |= (prusa3d_semicolon_workaround_round ? 0xf0 : 0x0f);
|
||||
|
@ -1088,7 +1088,7 @@ static int stk500_set_sck_period(PROGRAMMER * pgm, double v)
|
|||
|
||||
min = 8.0 / STK500_XTAL;
|
||||
max = 255 * min;
|
||||
dur = v / min + 0.5;
|
||||
dur = (int)(v / min + 0.5);
|
||||
|
||||
if (v < min) {
|
||||
dur = 1;
|
||||
|
|
|
@ -130,58 +130,58 @@ struct jtagispentry
|
|||
#define SZ_SPI_MULTI (USHRT_MAX - 1)
|
||||
};
|
||||
|
||||
static const struct jtagispentry jtagispcmds[] = {
|
||||
/* generic */
|
||||
{ CMD_SET_PARAMETER, 2 },
|
||||
{ CMD_GET_PARAMETER, 3 },
|
||||
{ CMD_OSCCAL, 2 },
|
||||
{ CMD_LOAD_ADDRESS, 2 },
|
||||
/* ISP mode */
|
||||
{ CMD_ENTER_PROGMODE_ISP, 2 },
|
||||
{ CMD_LEAVE_PROGMODE_ISP, 2 },
|
||||
{ CMD_CHIP_ERASE_ISP, 2 },
|
||||
{ CMD_PROGRAM_FLASH_ISP, 2 },
|
||||
{ CMD_READ_FLASH_ISP, SZ_READ_FLASH_EE },
|
||||
{ CMD_PROGRAM_EEPROM_ISP, 2 },
|
||||
{ CMD_READ_EEPROM_ISP, SZ_READ_FLASH_EE },
|
||||
{ CMD_PROGRAM_FUSE_ISP, 3 },
|
||||
{ CMD_READ_FUSE_ISP, 4 },
|
||||
{ CMD_PROGRAM_LOCK_ISP, 3 },
|
||||
{ CMD_READ_LOCK_ISP, 4 },
|
||||
{ CMD_READ_SIGNATURE_ISP, 4 },
|
||||
{ CMD_READ_OSCCAL_ISP, 4 },
|
||||
{ CMD_SPI_MULTI, SZ_SPI_MULTI },
|
||||
/* all HV modes */
|
||||
{ CMD_SET_CONTROL_STACK, 2 },
|
||||
/* HVSP mode */
|
||||
{ CMD_ENTER_PROGMODE_HVSP, 2 },
|
||||
{ CMD_LEAVE_PROGMODE_HVSP, 2 },
|
||||
{ CMD_CHIP_ERASE_HVSP, 2 },
|
||||
{ CMD_PROGRAM_FLASH_HVSP, 2 },
|
||||
{ CMD_READ_FLASH_HVSP, SZ_READ_FLASH_EE },
|
||||
{ CMD_PROGRAM_EEPROM_HVSP, 2 },
|
||||
{ CMD_READ_EEPROM_HVSP, SZ_READ_FLASH_EE },
|
||||
{ CMD_PROGRAM_FUSE_HVSP, 2 },
|
||||
{ CMD_READ_FUSE_HVSP, 3 },
|
||||
{ CMD_PROGRAM_LOCK_HVSP, 2 },
|
||||
{ CMD_READ_LOCK_HVSP, 3 },
|
||||
{ CMD_READ_SIGNATURE_HVSP, 3 },
|
||||
{ CMD_READ_OSCCAL_HVSP, 3 },
|
||||
/* PP mode */
|
||||
{ CMD_ENTER_PROGMODE_PP, 2 },
|
||||
{ CMD_LEAVE_PROGMODE_PP, 2 },
|
||||
{ CMD_CHIP_ERASE_PP, 2 },
|
||||
{ CMD_PROGRAM_FLASH_PP, 2 },
|
||||
{ CMD_READ_FLASH_PP, SZ_READ_FLASH_EE },
|
||||
{ CMD_PROGRAM_EEPROM_PP, 2 },
|
||||
{ CMD_READ_EEPROM_PP, SZ_READ_FLASH_EE },
|
||||
{ CMD_PROGRAM_FUSE_PP, 2 },
|
||||
{ CMD_READ_FUSE_PP, 3 },
|
||||
{ CMD_PROGRAM_LOCK_PP, 2 },
|
||||
{ CMD_READ_LOCK_PP, 3 },
|
||||
{ CMD_READ_SIGNATURE_PP, 3 },
|
||||
{ CMD_READ_OSCCAL_PP, 3 },
|
||||
};
|
||||
// static const struct jtagispentry jtagispcmds[] = {
|
||||
// /* generic */
|
||||
// { CMD_SET_PARAMETER, 2 },
|
||||
// { CMD_GET_PARAMETER, 3 },
|
||||
// { CMD_OSCCAL, 2 },
|
||||
// { CMD_LOAD_ADDRESS, 2 },
|
||||
// /* ISP mode */
|
||||
// { CMD_ENTER_PROGMODE_ISP, 2 },
|
||||
// { CMD_LEAVE_PROGMODE_ISP, 2 },
|
||||
// { CMD_CHIP_ERASE_ISP, 2 },
|
||||
// { CMD_PROGRAM_FLASH_ISP, 2 },
|
||||
// { CMD_READ_FLASH_ISP, SZ_READ_FLASH_EE },
|
||||
// { CMD_PROGRAM_EEPROM_ISP, 2 },
|
||||
// { CMD_READ_EEPROM_ISP, SZ_READ_FLASH_EE },
|
||||
// { CMD_PROGRAM_FUSE_ISP, 3 },
|
||||
// { CMD_READ_FUSE_ISP, 4 },
|
||||
// { CMD_PROGRAM_LOCK_ISP, 3 },
|
||||
// { CMD_READ_LOCK_ISP, 4 },
|
||||
// { CMD_READ_SIGNATURE_ISP, 4 },
|
||||
// { CMD_READ_OSCCAL_ISP, 4 },
|
||||
// { CMD_SPI_MULTI, SZ_SPI_MULTI },
|
||||
// /* all HV modes */
|
||||
// { CMD_SET_CONTROL_STACK, 2 },
|
||||
// /* HVSP mode */
|
||||
// { CMD_ENTER_PROGMODE_HVSP, 2 },
|
||||
// { CMD_LEAVE_PROGMODE_HVSP, 2 },
|
||||
// { CMD_CHIP_ERASE_HVSP, 2 },
|
||||
// { CMD_PROGRAM_FLASH_HVSP, 2 },
|
||||
// { CMD_READ_FLASH_HVSP, SZ_READ_FLASH_EE },
|
||||
// { CMD_PROGRAM_EEPROM_HVSP, 2 },
|
||||
// { CMD_READ_EEPROM_HVSP, SZ_READ_FLASH_EE },
|
||||
// { CMD_PROGRAM_FUSE_HVSP, 2 },
|
||||
// { CMD_READ_FUSE_HVSP, 3 },
|
||||
// { CMD_PROGRAM_LOCK_HVSP, 2 },
|
||||
// { CMD_READ_LOCK_HVSP, 3 },
|
||||
// { CMD_READ_SIGNATURE_HVSP, 3 },
|
||||
// { CMD_READ_OSCCAL_HVSP, 3 },
|
||||
// /* PP mode */
|
||||
// { CMD_ENTER_PROGMODE_PP, 2 },
|
||||
// { CMD_LEAVE_PROGMODE_PP, 2 },
|
||||
// { CMD_CHIP_ERASE_PP, 2 },
|
||||
// { CMD_PROGRAM_FLASH_PP, 2 },
|
||||
// { CMD_READ_FLASH_PP, SZ_READ_FLASH_EE },
|
||||
// { CMD_PROGRAM_EEPROM_PP, 2 },
|
||||
// { CMD_READ_EEPROM_PP, SZ_READ_FLASH_EE },
|
||||
// { CMD_PROGRAM_FUSE_PP, 2 },
|
||||
// { CMD_READ_FUSE_PP, 3 },
|
||||
// { CMD_PROGRAM_LOCK_PP, 2 },
|
||||
// { CMD_READ_LOCK_PP, 3 },
|
||||
// { CMD_READ_SIGNATURE_PP, 3 },
|
||||
// { CMD_READ_OSCCAL_PP, 3 },
|
||||
// };
|
||||
|
||||
/*
|
||||
* From XML file:
|
||||
|
@ -379,15 +379,15 @@ static void stk500v2_jtag3_teardown(PROGRAMMER * pgm)
|
|||
}
|
||||
|
||||
|
||||
static unsigned short
|
||||
b2_to_u16(unsigned char *b)
|
||||
{
|
||||
unsigned short l;
|
||||
l = b[0];
|
||||
l += (unsigned)b[1] << 8;
|
||||
// static unsigned short
|
||||
// b2_to_u16(unsigned char *b)
|
||||
// {
|
||||
// unsigned short l;
|
||||
// l = b[0];
|
||||
// l += (unsigned)b[1] << 8;
|
||||
|
||||
return l;
|
||||
}
|
||||
// return l;
|
||||
// }
|
||||
|
||||
static int stk500v2_send_mk2(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||
{
|
||||
|
@ -399,16 +399,16 @@ static int stk500v2_send_mk2(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static unsigned short get_jtagisp_return_size(unsigned char cmd)
|
||||
{
|
||||
int i;
|
||||
// static unsigned short get_jtagisp_return_size(unsigned char cmd)
|
||||
// {
|
||||
// int i;
|
||||
|
||||
for (i = 0; i < sizeof jtagispcmds / sizeof jtagispcmds[0]; i++)
|
||||
if (jtagispcmds[i].cmd == cmd)
|
||||
return jtagispcmds[i].size;
|
||||
// for (i = 0; i < sizeof jtagispcmds / sizeof jtagispcmds[0]; i++)
|
||||
// if (jtagispcmds[i].cmd == cmd)
|
||||
// return jtagispcmds[i].size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
/*
|
||||
* Send the data as a JTAG ICE mkII encapsulated ISP packet.
|
||||
|
@ -504,7 +504,7 @@ static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
|||
|
||||
buf[0] = MESSAGE_START;
|
||||
buf[1] = PDATA(pgm)->command_sequence;
|
||||
buf[2] = len / 256;
|
||||
buf[2] = (char)(len / 256);
|
||||
buf[3] = len % 256;
|
||||
buf[4] = TOKEN;
|
||||
memcpy(buf+5, data, len);
|
||||
|
@ -1128,7 +1128,8 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
{
|
||||
unsigned char buf[16];
|
||||
char msg[100]; /* see remarks above about size needed */
|
||||
int rv, tries;
|
||||
int rv;
|
||||
// int tries;
|
||||
|
||||
PDATA(pgm)->lastpart = p;
|
||||
|
||||
|
@ -1143,7 +1144,7 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
/* Activate AVR-style (low active) RESET */
|
||||
stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01);
|
||||
|
||||
tries = 0;
|
||||
// tries = 0;
|
||||
// retry:
|
||||
buf[0] = CMD_ENTER_PROGMODE_ISP;
|
||||
buf[1] = p->timeout;
|
||||
|
@ -1882,7 +1883,7 @@ static int stk500hv_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
buf[1] = addr;
|
||||
buf[1] = (char)addr;
|
||||
}
|
||||
|
||||
avrdude_message(MSG_NOTICE2, "%s: stk500hv_read_byte(): Sending read memory command: ",
|
||||
|
@ -2137,7 +2138,7 @@ static int stk500hv_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
buf[1] = addr;
|
||||
buf[1] = (char)addr;
|
||||
buf[2] = data;
|
||||
if (mode == PPMODE) {
|
||||
buf[3] = pulsewidth;
|
||||
|
@ -2298,7 +2299,7 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
{
|
||||
static int page = 0;
|
||||
// static int page = 0;
|
||||
unsigned int block_size, last_addr, addrshift, use_ext_addr;
|
||||
unsigned int maxaddr = addr + n_bytes;
|
||||
unsigned char commandbuf[10];
|
||||
|
@ -2833,10 +2834,10 @@ static int stk500v2_set_fosc(PROGRAMMER * pgm, double v)
|
|||
progname, v, unit, STK500V2_XTAL / 2e6);
|
||||
fosc = STK500V2_XTAL / 2;
|
||||
} else
|
||||
fosc = (unsigned)v;
|
||||
fosc = (int)v;
|
||||
|
||||
for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
|
||||
if (fosc >= STK500V2_XTAL / (256 * ps[idx] * 2)) {
|
||||
if (fosc >= (int)(STK500V2_XTAL / (256 * ps[idx] * 2))) {
|
||||
/* this prescaler value can handle our frequency */
|
||||
prescale = idx + 1;
|
||||
cmatch = (unsigned)(STK500V2_XTAL / (2 * fosc * ps[idx])) - 1;
|
||||
|
@ -3065,8 +3066,8 @@ static int stk600_set_fosc(PROGRAMMER * pgm, double v)
|
|||
{
|
||||
unsigned int oct, dac;
|
||||
|
||||
oct = 1.443 * log(v / 1039.0);
|
||||
dac = 2048 - (2078.0 * pow(2, (double)(10 + oct))) / v;
|
||||
oct = (unsigned)(1.443 * log(v / 1039.0));
|
||||
dac = (unsigned)(2048.0 - (2078.0 * pow(2, (double)(10 + oct))) / v);
|
||||
|
||||
return stk500v2_setparm2(pgm, PARAM2_CLOCK_CONF, (oct << 12) | (dac << 2));
|
||||
}
|
||||
|
@ -3075,7 +3076,7 @@ static int stk600_set_sck_period(PROGRAMMER * pgm, double v)
|
|||
{
|
||||
unsigned int sck;
|
||||
|
||||
sck = ceil((16e6 / (2 * 1.0 / v)) - 1);
|
||||
sck = (unsigned)ceil((16e6 / (2 * 1.0 / v)) - 1);
|
||||
|
||||
if (sck >= 4096)
|
||||
sck = 4095;
|
||||
|
@ -3093,7 +3094,7 @@ static int stk500v2_jtag3_set_sck_period(PROGRAMMER * pgm, double v)
|
|||
else if (v > 1E-3)
|
||||
sck = 1;
|
||||
else
|
||||
sck = 1.0 / (1000.0 * v);
|
||||
sck = (unsigned)(1.0 / (1000.0 * v));
|
||||
|
||||
value[0] = CMD_SET_SCK;
|
||||
value[1] = sck & 0xff;
|
||||
|
@ -3143,7 +3144,7 @@ static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned
|
|||
|
||||
static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value)
|
||||
{
|
||||
unsigned char current_value;
|
||||
unsigned char current_value = 0;
|
||||
int res;
|
||||
|
||||
res = stk500v2_getparm(pgm, parm, ¤t_value);
|
||||
|
@ -3214,8 +3215,15 @@ static const char *stk600_get_cardname(const struct carddata *table,
|
|||
|
||||
static void stk500v2_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
unsigned char maj, min, hdw, topcard, maj_s1, min_s1, maj_s2, min_s2;
|
||||
unsigned int rev;
|
||||
unsigned char maj = 0;
|
||||
unsigned char min = 0;
|
||||
unsigned char hdw = 0;
|
||||
unsigned char topcard = 0;
|
||||
unsigned char maj_s1 = 0;
|
||||
unsigned char min_s1 = 0;
|
||||
unsigned char maj_s2 = 0;
|
||||
unsigned char min_s2 = 0;
|
||||
unsigned int rev = 0;
|
||||
const char *topcard_name, *pgmname;
|
||||
|
||||
switch (PDATA(pgm)->pgmtype) {
|
||||
|
@ -3294,13 +3302,20 @@ f_to_kHz_MHz(double f, const char **unit)
|
|||
|
||||
static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
unsigned char vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration =0; //XXX 0 is not correct, check caller
|
||||
unsigned int sck_stk600, clock_conf, dac, oct, varef;
|
||||
unsigned char vtarget_jtag[4];
|
||||
unsigned char vtarget = 0;
|
||||
unsigned char vadjust = 0;
|
||||
unsigned char sck_duration = 0;
|
||||
unsigned char osc_pscale = 0;
|
||||
unsigned char osc_cmatch = 0;
|
||||
unsigned varef = 0;
|
||||
unsigned sck_stk600 = 0;
|
||||
unsigned clock_conf = 0;
|
||||
unsigned dac, oct;
|
||||
// unsigned char vtarget_jtag[4];
|
||||
int prescale;
|
||||
double f;
|
||||
const char *unit;
|
||||
void *mycookie;
|
||||
// void *mycookie;
|
||||
|
||||
if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) {
|
||||
return;
|
||||
|
@ -3963,10 +3978,10 @@ static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
b[0] = XPRG_CMD_WRITE_MEM;
|
||||
b[1] = memcode;
|
||||
b[2] = 0; /* pagemode: non-paged write */
|
||||
b[3] = addr >> 24;
|
||||
b[4] = addr >> 16;
|
||||
b[5] = addr >> 8;
|
||||
b[6] = addr;
|
||||
b[3] = (char)(addr >> 24);
|
||||
b[4] = (char)(addr >> 16);
|
||||
b[5] = (char)(addr >> 8);
|
||||
b[6] = (char)addr;
|
||||
b[7] = 0;
|
||||
b[8] = write_size;
|
||||
b[9] = data;
|
||||
|
@ -4011,10 +4026,10 @@ static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
addr += mem->offset;
|
||||
|
||||
b[0] = XPRG_CMD_READ_MEM;
|
||||
b[2] = addr >> 24;
|
||||
b[3] = addr >> 16;
|
||||
b[4] = addr >> 8;
|
||||
b[5] = addr;
|
||||
b[2] = (char)(addr >> 24);
|
||||
b[3] = (char)(addr >> 16);
|
||||
b[4] = (char)(addr >> 8);
|
||||
b[5] = (char)addr;
|
||||
b[6] = 0;
|
||||
b[7] = 1;
|
||||
if (stk600_xprog_command(pgm, b, 8, 3) < 0) {
|
||||
|
|
|
@ -281,7 +281,7 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
|
|||
|
||||
maxsize = mem->size;
|
||||
|
||||
if (addr >= maxsize) {
|
||||
if (addr >= (unsigned long)maxsize) {
|
||||
if (argc == 2) {
|
||||
/* wrap around */
|
||||
addr = 0;
|
||||
|
@ -294,7 +294,7 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
|
|||
}
|
||||
|
||||
/* trim len if nessary to not read past the end of memory */
|
||||
if ((addr + len) > maxsize)
|
||||
if ((addr + len) > (unsigned long)maxsize)
|
||||
len = maxsize - addr;
|
||||
|
||||
buf = malloc(len);
|
||||
|
@ -303,7 +303,7 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
|
|||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
for (i = 0; i < (unsigned long)len; i++) {
|
||||
rc = pgm->read_byte(pgm, p, mem, addr+i, &buf[i]);
|
||||
if (rc != 0) {
|
||||
avrdude_message(MSG_INFO, "error reading %s address 0x%05lx of part %s\n",
|
||||
|
@ -364,7 +364,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (addr > maxsize) {
|
||||
if (addr > (unsigned long)maxsize) {
|
||||
avrdude_message(MSG_INFO, "%s (write): address 0x%05lx is out of range for %s memory\n",
|
||||
progname, addr, memtype);
|
||||
return -1;
|
||||
|
@ -373,7 +373,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
|
|||
/* number of bytes to write at the specified address */
|
||||
len = argc - 3;
|
||||
|
||||
if ((addr + len) > maxsize) {
|
||||
if ((addr + len) > (unsigned long)maxsize) {
|
||||
avrdude_message(MSG_INFO, "%s (write): selected address and # bytes exceed "
|
||||
"range for %s memory\n",
|
||||
progname, memtype);
|
||||
|
@ -386,8 +386,8 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
|
|||
return -1;
|
||||
}
|
||||
|
||||
for (i=3; i<argc; i++) {
|
||||
buf[i-3] = strtoul(argv[i], &e, 0);
|
||||
for (i = 3; i < (unsigned long)argc; i++) {
|
||||
buf[i-3] = (char)strtoul(argv[i], &e, 0);
|
||||
if (*e || (e == argv[i])) {
|
||||
avrdude_message(MSG_INFO, "%s (write): can't parse byte \"%s\"\n",
|
||||
progname, argv[i]);
|
||||
|
@ -397,7 +397,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
|
|||
}
|
||||
|
||||
pgm->err_led(pgm, OFF);
|
||||
for (werror=0, i=0; i<len; i++) {
|
||||
for (werror = 0, i = 0; i < (unsigned long)len; i++) {
|
||||
|
||||
rc = avr_write_byte(pgm, p, mem, addr+i, buf[i]);
|
||||
if (rc) {
|
||||
|
@ -462,7 +462,7 @@ static int cmd_send(PROGRAMMER * pgm, struct avrpart * p,
|
|||
|
||||
/* load command bytes */
|
||||
for (i=1; i<argc; i++) {
|
||||
cmd[i-1] = strtoul(argv[i], &e, 0);
|
||||
cmd[i-1] = (char)strtoul(argv[i], &e, 0);
|
||||
if (*e || (e == argv[i])) {
|
||||
avrdude_message(MSG_INFO, "%s (send): can't parse byte \"%s\"\n",
|
||||
progname, argv[i]);
|
||||
|
@ -789,7 +789,7 @@ static int tokenize(char * s, char *** argv)
|
|||
char * nbuf;
|
||||
char ** av;
|
||||
|
||||
slen = strlen(s);
|
||||
slen = (int)strlen(s);
|
||||
|
||||
/*
|
||||
* initialize allow for 20 arguments, use realloc to grow this if
|
||||
|
@ -812,7 +812,7 @@ static int tokenize(char * s, char *** argv)
|
|||
nexttok(r, &q, &r);
|
||||
strcpy(nbuf, q);
|
||||
bufv[n] = nbuf;
|
||||
len = strlen(q);
|
||||
len = (int)strlen(q);
|
||||
l += len + 1;
|
||||
nbuf += len + 1;
|
||||
nbuf[0] = 0;
|
||||
|
@ -841,7 +841,7 @@ static int tokenize(char * s, char *** argv)
|
|||
q = (char *)&av[n+1];
|
||||
memcpy(q, buf, l);
|
||||
for (i=0; i<n; i++) {
|
||||
offset = bufv[i] - buf;
|
||||
offset = (int)(bufv[i] - buf);
|
||||
av[i] = q + offset;
|
||||
}
|
||||
av[i] = NULL;
|
||||
|
@ -862,7 +862,7 @@ static int do_cmd(PROGRAMMER * pgm, struct avrpart * p,
|
|||
int hold;
|
||||
int len;
|
||||
|
||||
len = strlen(argv[0]);
|
||||
len = (int)strlen(argv[0]);
|
||||
hold = -1;
|
||||
for (i=0; i<NCMDS; i++) {
|
||||
if (strcasecmp(argv[0], cmd[i].name) == 0) {
|
||||
|
|
|
@ -63,6 +63,11 @@ extern "C" {
|
|||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
|
||||
#if defined(_MSC_VER) && defined(__clang__)
|
||||
#include <stdint.h>
|
||||
struct timezone;
|
||||
struct timeval;
|
||||
#else
|
||||
#ifndef __cplusplus
|
||||
/* should be in some equivalent to <sys/types.h> */
|
||||
typedef __int8 int8_t;
|
||||
|
@ -74,6 +79,7 @@ typedef unsigned __int16 uint16_t;
|
|||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
int usleep(unsigned usec);
|
||||
|
|
|
@ -19,6 +19,6 @@ add_library(nowide STATIC
|
|||
nowide/windows.hpp
|
||||
)
|
||||
|
||||
target_include_directories(nowide SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(nowide PUBLIC boost_headeronly)
|
||||
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ protected:
|
|||
#ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
|
||||
return from - save_from;
|
||||
#else
|
||||
return save_max - max;
|
||||
return int(save_max - max);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
39
src/build-utils/CMakeLists.txt
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
add_executable(encoding-check encoding-check.cpp)
|
||||
|
||||
# A global no-op target which depends on all encodings checks,
|
||||
# and on which in turn all checked targets depend.
|
||||
# This is done to make encoding checks the first thing to be
|
||||
# performed before actually compiling any sources of the checked targets
|
||||
# to make the check fail as early as possible.
|
||||
add_custom_target(global-encoding-check
|
||||
ALL
|
||||
DEPENDS encoding-check
|
||||
)
|
||||
|
||||
# Function that adds source file encoding check to a target
|
||||
# using the above encoding-check binary
|
||||
|
||||
function(encoding_check TARGET)
|
||||
# Obtain target source files
|
||||
get_target_property(T_SOURCES ${TARGET} SOURCES)
|
||||
|
||||
# Define top-level encoding check target for this ${TARGET}
|
||||
add_custom_target(encoding-check-${TARGET}
|
||||
DEPENDS encoding-check ${T_SOURCES}
|
||||
COMMENT "Checking source files encodings for target ${TARGET}"
|
||||
)
|
||||
|
||||
# Add checking of each source file as a subcommand of encoding-check-${TARGET}
|
||||
foreach(file ${T_SOURCES})
|
||||
add_custom_command(TARGET encoding-check-${TARGET}
|
||||
COMMAND $<TARGET_FILE:encoding-check> ${TARGET} ${file}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# This adds dependency on encoding-check-${TARGET} to ${TARET}
|
||||
# via the global-encoding-check
|
||||
add_dependencies(global-encoding-check encoding-check-${TARGET})
|
||||
add_dependencies(${TARGET} global-encoding-check)
|
||||
endfunction()
|
119
src/build-utils/encoding-check.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
/*
|
||||
* The utf8_check() function scans the '\0'-terminated string starting
|
||||
* at s. It returns a pointer to the first byte of the first malformed
|
||||
* or overlong UTF-8 sequence found, or NULL if the string contains
|
||||
* only correct UTF-8. It also spots UTF-8 sequences that could cause
|
||||
* trouble if converted to UTF-16, namely surrogate characters
|
||||
* (U+D800..U+DFFF) and non-Unicode positions (U+FFFE..U+FFFF). This
|
||||
* routine is very likely to find a malformed sequence if the input
|
||||
* uses any other encoding than UTF-8. It therefore can be used as a
|
||||
* very effective heuristic for distinguishing between UTF-8 and other
|
||||
* encodings.
|
||||
*
|
||||
* I wrote this code mainly as a specification of functionality; there
|
||||
* are no doubt performance optimizations possible for certain CPUs.
|
||||
*
|
||||
* Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> -- 2005-03-30
|
||||
* License: http://www.cl.cam.ac.uk/~mgk25/short-license.html
|
||||
*/
|
||||
|
||||
unsigned char *utf8_check(unsigned char *s)
|
||||
{
|
||||
while (*s) {
|
||||
if (*s < 0x80) {
|
||||
// 0xxxxxxx
|
||||
s++;
|
||||
} else if ((s[0] & 0xe0) == 0xc0) {
|
||||
// 110xxxxx 10xxxxxx
|
||||
if ((s[1] & 0xc0) != 0x80 ||
|
||||
(s[0] & 0xfe) == 0xc0) { // overlong?
|
||||
return s;
|
||||
} else {
|
||||
s += 2;
|
||||
}
|
||||
} else if ((s[0] & 0xf0) == 0xe0) {
|
||||
// 1110xxxx 10xxxxxx 10xxxxxx
|
||||
if ((s[1] & 0xc0) != 0x80 ||
|
||||
(s[2] & 0xc0) != 0x80 ||
|
||||
(s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || // overlong?
|
||||
(s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || // surrogate?
|
||||
(s[0] == 0xef && s[1] == 0xbf &&
|
||||
(s[2] & 0xfe) == 0xbe)) { // U+FFFE or U+FFFF?
|
||||
return s;
|
||||
} else {
|
||||
s += 3;
|
||||
}
|
||||
} else if ((s[0] & 0xf8) == 0xf0) {
|
||||
// 11110xxX 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
if ((s[1] & 0xc0) != 0x80 ||
|
||||
(s[2] & 0xc0) != 0x80 ||
|
||||
(s[3] & 0xc0) != 0x80 ||
|
||||
(s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || // overlong?
|
||||
(s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) { // > U+10FFFF?
|
||||
return s;
|
||||
} else {
|
||||
s += 4;
|
||||
}
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " <program/library> <file>" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* target = argv[1];
|
||||
const char* filename = argv[2];
|
||||
|
||||
const auto error_exit = [=](const char* error) {
|
||||
std::cerr << "\n\tError: " << error << ": " << filename << "\n"
|
||||
<< "\tTarget: " << target << "\n"
|
||||
<< std::endl;
|
||||
std::exit(-2);
|
||||
};
|
||||
|
||||
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
||||
const auto size = file.tellg();
|
||||
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::beg);
|
||||
std::vector<char> buffer(size);
|
||||
|
||||
if (file.read(buffer.data(), size)) {
|
||||
buffer.push_back('\0');
|
||||
|
||||
// Check UTF-8 validity
|
||||
if (utf8_check(reinterpret_cast<unsigned char*>(buffer.data())) != nullptr) {
|
||||
error_exit("Source file does not contain (valid) UTF-8");
|
||||
}
|
||||
|
||||
// Check against a BOM mark
|
||||
if (buffer.size() >= 3
|
||||
&& buffer[0] == '\xef'
|
||||
&& buffer[1] == '\xbb'
|
||||
&& buffer[2] == '\xbf') {
|
||||
error_exit("Source file is valid UTF-8 but contains a BOM mark");
|
||||
}
|
||||
} else {
|
||||
error_exit("Could not read source file");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_SORTABLE_ROW_H
|
||||
#define IGL_SORTABLE_ROW_H
|
||||
|
||||
// Simple class to contain a rowvector which allows rowwise sorting and
|
||||
// reordering
|
||||
#include <Eigen/Core>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
// Templates:
|
||||
// T should be a matrix that implements .size(), and operator(int i)
|
||||
template <typename T>
|
||||
class SortableRow
|
||||
{
|
||||
public:
|
||||
T data;
|
||||
public:
|
||||
SortableRow():data(){};
|
||||
SortableRow(const T & data):data(data){};
|
||||
bool operator<(const SortableRow & that) const
|
||||
{
|
||||
// Get reference so that I can use parenthesis
|
||||
const SortableRow<T> & THIS = *this;
|
||||
// Lexicographical
|
||||
int minc = (THIS.data.size() < that.data.size()?
|
||||
THIS.data.size() : that.data.size());
|
||||
// loop over columns
|
||||
for(int i = 0;i<minc;i++)
|
||||
{
|
||||
if(THIS.data(i) == that.data(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return THIS.data(i) < that.data(i);
|
||||
}
|
||||
// All characters the same, comes done to length
|
||||
return THIS.data.size()<that.data.size();
|
||||
};
|
||||
bool operator==(const SortableRow & that) const
|
||||
{
|
||||
// Get reference so that I can use parenthesis
|
||||
const SortableRow<T> & THIS = *this;
|
||||
if(THIS.data.size() != that.data.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for(int i = 0;i<THIS.data.size();i++)
|
||||
{
|
||||
if(THIS.data(i) != that.data(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
bool operator!=(const SortableRow & that) const
|
||||
{
|
||||
return !(*this == that);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
14
src/libigl/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
project(libigl)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
add_library(libigl INTERFACE)
|
||||
|
||||
find_package(libigl QUIET)
|
||||
|
||||
if(libigl_FOUND)
|
||||
message(STATUS "IGL found, using system version...")
|
||||
target_link_libraries(libigl INTERFACE igl::core)
|
||||
else()
|
||||
message(STATUS "IGL NOT found, using bundled version...")
|
||||
target_include_directories(libigl SYSTEM BEFORE INTERFACE ${LIBDIR}/libigl)
|
||||
endif()
|