Comparar commits

..

33 Commits

Autor SHA1 Mensagem Data
Simon Edwards f660f3cd2d Use the static runtime when compiling with MSVC. 2016-11-04 16:29:21 +01:00
Tim Kuipers 54fd9c1f5b cleanup: code conventions for alloca (CURA-2614) 2016-11-04 16:29:21 +01:00
Seva Alekseyev 72ce68ac33 Now builds with MSVC 2015. Changes are:
- Global define NOMINMAX in CMakeLists.txt
 - #ifndef around strings.h, unistd.h, sys/time.h, libgen.h
 - Variable-length arrays replaced with alloca() (it's not a C++ feature)
 - Homegrown implementation of dirname() using Win32's GetFileFullPath()
 - Rogue "or" replaced with ||
 - References to macros __WIN32, _WIN32 replaced with WIN32

There will be a HUGE lot of warnings, since the cmake-generated project file specifies the "all warnings" option. Feel free to reduce the warning level to your own liking.

You still need to patch and rebuild protobuf, or you'll get three "unresolved symbol" errors. Functions google::protobuf::internal::GetEmptyString(), GetEmptyStringAlreadyInited() in generated_message_util.h should be declared as non-inline and moved to a source file (generated_message_util.cc is a good place).
2016-11-04 16:29:06 +01:00
Ghostkeeper 6bed19c295 Merge branch 'feature_infill_support' 2016-11-03 13:37:07 +01:00
Tim Kuipers f312f15813 Merge branch 'master' into feature_infill_support 2016-11-01 11:04:13 +01:00
Ghostkeeper 406ea7155c Merge pull request #408 from thopiekar/master-gcc6-fix
Adding <numeric> for GCC 6.x
2016-11-01 10:21:16 +01:00
Thomas Karl Pietrowski f0f23ed732 Adding <numeric> for GCC 6.x
Otherwise you will get something like:

In file included from /<<PKGBUILDDIR>>/src/FffPolygonGenerator.cpp:7:0:
/<<PKGBUILDDIR>>/src/utils/algorithm.h: In function ‘std::vector<long unsigned int> cura::order(const std::vector<_Tp>&)’:
/<<PKGBUILDDIR>>/src/utils/algorithm.h:30:5: error: ‘iota’ is not a member of ‘std’
     std::iota(order.begin(), order.end(), 0); // fill vector with 1, 2, 3,.. etc
     ^~~
2016-11-01 09:48:46 +01:00
Ghostkeeper 0a59a059f4 Merge branch 'feature_nozzle_off_after_use' 2016-10-31 13:31:37 +01:00
Thomas Karl Pietrowski 47984afb5f Fixing formatting in README.md 2016-10-25 20:08:49 +02:00
Ghostkeeper 4d34cbc66b Merge branch 'bugfix_double_to_stream' 2016-10-21 17:28:58 +02:00
Tim Kuipers a29af7f791 Revert "Revert "feat: setting for carveMultipleVolumes (CURA-2712)""
This reverts commit d50f67e583.

Reapplies b2d837efde
2016-10-21 16:22:45 +02:00
Tim Kuipers f304c09db4 Merge branch '2.3' 2016-10-21 16:22:30 +02:00
Tim Kuipers d50f67e583 Revert "feat: setting for carveMultipleVolumes (CURA-2712)"
This reverts commit b2d837efde.
2016-10-21 16:22:16 +02:00
Tim Kuipers b2d837efde feat: setting for carveMultipleVolumes (CURA-2712) 2016-10-21 16:05:15 +02:00
Ghostkeeper 5c680b312b Indent broken-up lines
So that you can see that the line is broken up into multiple lines.

Contributes to issue CURA-1103.
2016-10-21 15:52:22 +02:00
Ghostkeeper 0a683ff05e Transform order algorithm to our code style
Lukasz needs to obey the rulesz!

Contributes to issue CURA-1103.
2016-10-21 15:39:19 +02:00
Tim Kuipers 4e96d9cbe6 feat: infill_hollow (CURA-2748) 2016-10-19 18:13:38 +02:00
Tim Kuipers 478bd31d02 Merge branch 'bugfix_double_to_stream' of github.com:Ultimaker/CuraEngine into bugfix_double_to_stream 2016-10-18 11:02:37 +02:00
Tim Kuipers faab907bab fix: int64_t and double formatting (CURA-2627) 2016-10-17 17:51:38 +02:00
Tim Kuipers dff554863c fix: nozzle was never turned off (CURA-1103) 2016-10-17 17:25:18 +02:00
Tim Kuipers f2222f97fd fix: PrimeTower::extruder_count wasn't set (CUTA-1103) 2016-10-17 17:20:25 +02:00
Tim Kuipers aa18e7bd08 feat: turn nozzle off after last layer switch (CUTA-1103) 2016-10-17 17:12:15 +02:00
Tim Kuipers 07dc53765a fix: removeEmptyFirstLayers invalidated mesh.layer_nr_max_filled_layer (CURA-1103) 2016-10-17 17:11:37 +02:00
Tim Kuipers 559deb8914 refactor: moved max_print_height_second_to_last_extruder to FffPolygonGenerator (CURA-1103) 2016-10-17 17:10:57 +02:00
Tim Kuipers 421ff6d818 feat: prime tower max print height calculation more generic (CURA-1103)
Also fix for platform adhesion in registering the max height an extruder is used.
2016-10-17 15:32:26 +02:00
Tim Kuipers e85a1004cd feat: algorithm::order function (CURA-1103) 2016-10-17 14:46:07 +02:00
Tim Kuipers 627848bc41 refactor: max_object_height_second_to_last_extruder ==> max_print_height_second_to_last_extruder (CURA-1103) 2016-10-17 11:30:53 +02:00
Ghostkeeper eccc62cf1d Add whitespace around binary operators
As per our code style.

Contributes to issue CURA-2627.
2016-10-17 11:06:22 +02:00
Tim Kuipers 58e2e1a4e1 fix: better buffer for double to stream and more tests (CURA-2627) 2016-10-13 17:39:59 +02:00
Tim Kuipers 4ebbceb3e3 Merge branch '2.3' 2016-10-11 16:43:05 +02:00
Tim Kuipers ace0045109 Merge branch '2.3' 2016-10-11 16:14:44 +02:00
Tim Kuipers 7a4a7fe46a Merge branch '2.3' 2016-10-11 15:01:03 +02:00
Tim Kuipers 977d02a9a2 Updated link to code conventions 2016-10-11 09:22:02 +02:00
25 arquivos alterados com 381 adições e 95 exclusões
+14
Ver Arquivo
@@ -42,6 +42,20 @@ if(NOT APPLE AND NOT WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++")
endif()
if(WIN32)
add_definitions(/DNOMINMAX)
if (MSVC)
# Switch the runtime to use static linking on MSVC
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
endif()
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR} libs)
add_library(clipper STATIC libs/clipper/clipper.cpp)
+1
Ver Arquivo
@@ -31,6 +31,7 @@ CMake compilation:
4. ```$ make```
Project files generation:
1. Navigate to the CuraEngine directory and execute the following commands
2. ```cmake . -G "CodeBlocks - Unix Makefiles"```
3. (for a list of supported IDE's see http://www.cmake.org/Wiki/CMake_Generator_Specific_Information#Code::Blocks_Generator)
+1 -1
Ver Arquivo
@@ -7,4 +7,4 @@ This is the documentation for CuraEngine, the back-end slicer of Cura.
[Glossary](documentation/glossary.md)
[Code Conventions](documentation/code_conventions.md)
[Code Conventions](https://github.com/Ultimaker/Meta/blob/master/code_conventions.md)
+53 -6
Ver Arquivo
@@ -4,6 +4,7 @@
#include <map> // multimap (ordered map allowing duplicate keys)
#include "utils/math.h"
#include "utils/algorithm.h"
#include "slicer.h"
#include "utils/gettime.h"
#include "utils/logoutput.h"
@@ -115,7 +116,10 @@ bool FffPolygonGenerator::sliceModel(MeshGroup* meshgroup, TimeKeeper& timeKeepe
Progress::messageProgressStage(Progress::Stage::PARTS, &timeKeeper);
carveMultipleVolumes(slicerList);
if (storage.getSettingBoolean("carve_multiple_volumes"))
{
carveMultipleVolumes(slicerList);
}
generateMultipleVolumesOverlap(slicerList);
storage.meshes.reserve(slicerList.size()); // causes there to be no resize in meshes so that the pointers in sliceMeshStorage._config to retraction_config don't get invalidated.
@@ -256,8 +260,9 @@ void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper&
}
*/
computePrintHeightStatistics(storage);
// handle helpers
storage.primeTower.computePrimeTowerMax(storage);
storage.primeTower.generatePaths(storage, print_layer_count);
logDebug("Processing ooze shield\n");
@@ -492,6 +497,7 @@ void FffPolygonGenerator::removeEmptyFirstLayers(SliceDataStorage& storage, cons
{
layer.printZ -= n_empty_first_layers * layer_height;
}
mesh.layer_nr_max_filled_layer -= n_empty_first_layers;
}
total_layers -= n_empty_first_layers;
}
@@ -521,6 +527,47 @@ void FffPolygonGenerator::processSkinsAndInfill(SliceMeshStorage& mesh, unsigned
}
}
void FffPolygonGenerator::computePrintHeightStatistics(SliceDataStorage& storage)
{
int extruder_count = storage.meshgroup->getExtruderCount();
std::vector<int>& max_print_height_per_extruder = storage.max_print_height_per_extruder;
assert(max_print_height_per_extruder.size() == 0 && "storage.max_print_height_per_extruder shouldn't have been initialized yet!");
max_print_height_per_extruder.resize(extruder_count, -1); // unitialize all as -1
{ // compute max_object_height_per_extruder
for (SliceMeshStorage& mesh : storage.meshes)
{
unsigned int extr_nr = mesh.getSettingAsIndex("extruder_nr");
max_print_height_per_extruder[extr_nr] =
std::max( max_print_height_per_extruder[extr_nr]
, mesh.layer_nr_max_filled_layer );
}
int support_infill_extruder_nr = storage.getSettingAsIndex("support_infill_extruder_nr"); // TODO: support extruder should be configurable per object
max_print_height_per_extruder[support_infill_extruder_nr] =
std::max( max_print_height_per_extruder[support_infill_extruder_nr]
, storage.support.layer_nr_max_filled_layer );
int support_skin_extruder_nr = storage.getSettingAsIndex("support_interface_extruder_nr"); // TODO: support skin extruder should be configurable per object
max_print_height_per_extruder[support_skin_extruder_nr] =
std::max( max_print_height_per_extruder[support_skin_extruder_nr]
, storage.support.layer_nr_max_filled_layer );
int adhesion_extruder_nr = storage.getSettingAsIndex("adhesion_extruder_nr");
max_print_height_per_extruder[adhesion_extruder_nr] =
std::max(0, max_print_height_per_extruder[support_skin_extruder_nr]);
}
storage.max_print_height_order = order(max_print_height_per_extruder);
if (extruder_count >= 2)
{
int second_highest_extruder = storage.max_print_height_order[extruder_count - 2];
storage.max_print_height_second_to_last_extruder = max_print_height_per_extruder[second_highest_extruder];
}
else
{
storage.max_print_height_second_to_last_extruder = -1;
}
}
void FffPolygonGenerator::processOozeShield(SliceDataStorage& storage)
{
if (!getSettingBoolean("ooze_shield_enabled"))
@@ -530,7 +577,7 @@ void FffPolygonGenerator::processOozeShield(SliceDataStorage& storage)
const int ooze_shield_dist = getSettingInMicrons("ooze_shield_dist");
for (int layer_nr = 0; layer_nr <= storage.max_object_height_second_to_last_extruder; layer_nr++)
for (int layer_nr = 0; layer_nr <= storage.max_print_height_second_to_last_extruder; layer_nr++)
{
storage.oozeShield.push_back(storage.getLayerOutlines(layer_nr, true).offset(ooze_shield_dist, ClipperLib::jtRound));
}
@@ -539,18 +586,18 @@ void FffPolygonGenerator::processOozeShield(SliceDataStorage& storage)
if (angle <= 89)
{
int allowed_angle_offset = tan(getSettingInAngleRadians("ooze_shield_angle")) * getSettingInMicrons("layer_height"); // Allow for a 60deg angle in the oozeShield.
for (int layer_nr = 1; layer_nr <= storage.max_object_height_second_to_last_extruder; layer_nr++)
for (int layer_nr = 1; layer_nr <= storage.max_print_height_second_to_last_extruder; layer_nr++)
{
storage.oozeShield[layer_nr] = storage.oozeShield[layer_nr].unionPolygons(storage.oozeShield[layer_nr - 1].offset(-allowed_angle_offset));
}
for (int layer_nr = storage.max_object_height_second_to_last_extruder; layer_nr > 0; layer_nr--)
for (int layer_nr = storage.max_print_height_second_to_last_extruder; layer_nr > 0; layer_nr--)
{
storage.oozeShield[layer_nr - 1] = storage.oozeShield[layer_nr - 1].unionPolygons(storage.oozeShield[layer_nr].offset(-allowed_angle_offset));
}
}
const float largest_printed_area = 1.0; // TODO: make var a parameter, and perhaps even a setting?
for (int layer_nr = 0; layer_nr <= storage.max_object_height_second_to_last_extruder; layer_nr++)
for (int layer_nr = 0; layer_nr <= storage.max_print_height_second_to_last_extruder; layer_nr++)
{
storage.oozeShield[layer_nr].removeSmallAreas(largest_printed_area);
}
+8 -1
Ver Arquivo
@@ -118,7 +118,14 @@ private:
* \param total_layers The total number of layers
*/
void removeEmptyFirstLayers(SliceDataStorage& storage, const int layer_height, unsigned int& total_layers);
/*!
* Set \ref SliceDataStorage::max_print_height_per_extruder and \ref SliceDataStorage::max_print_height_order and \ref SliceDataStorage::max_print_height_second_to_last_extruder
*
* \param[in,out] storage Where to retrieve mesh and support etc settings from and where the print height statistics are saved.
*/
void computePrintHeightStatistics(SliceDataStorage& storage);
/*!
* Generate the inset polygons which form the walls.
* \param mesh Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
+2
Ver Arquivo
@@ -1,6 +1,8 @@
/** Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License */
#include <string.h>
#ifndef WIN32
#include <strings.h>
#endif
#include <stdio.h>
#include "MeshGroup.h"
+4 -58
Ver Arquivo
@@ -50,61 +50,6 @@ void PrimeTower::setConfigs(const MeshGroup* meshgroup, const int layer_thicknes
}
}
void PrimeTower::computePrimeTowerMax(SliceDataStorage& storage)
{ // compute storage.max_object_height_second_to_last_extruder, which is used to determine the highest point in the prime tower
extruder_count = storage.meshgroup->getExtruderCount();
int max_object_height_per_extruder[extruder_count];
std::fill_n(max_object_height_per_extruder, extruder_count, -1); // unitialize all as -1
{ // compute max_object_height_per_extruder
for (SliceMeshStorage& mesh : storage.meshes)
{
unsigned int extr_nr = mesh.getSettingAsIndex("extruder_nr");
max_object_height_per_extruder[extr_nr] =
std::max( max_object_height_per_extruder[extr_nr]
, mesh.layer_nr_max_filled_layer );
}
int support_infill_extruder_nr = storage.getSettingAsIndex("support_infill_extruder_nr"); // TODO: support extruder should be configurable per object
max_object_height_per_extruder[support_infill_extruder_nr] =
std::max( max_object_height_per_extruder[support_infill_extruder_nr]
, storage.support.layer_nr_max_filled_layer );
int support_skin_extruder_nr = storage.getSettingAsIndex("support_interface_extruder_nr"); // TODO: support skin extruder should be configurable per object
max_object_height_per_extruder[support_skin_extruder_nr] =
std::max( max_object_height_per_extruder[support_skin_extruder_nr]
, storage.support.layer_nr_max_filled_layer );
}
{ // // compute max_object_height_second_to_last_extruder
int extruder_max_object_height = 0;
for (int extruder_nr = 1; extruder_nr < extruder_count; extruder_nr++)
{
if (max_object_height_per_extruder[extruder_nr] > max_object_height_per_extruder[extruder_max_object_height])
{
extruder_max_object_height = extruder_nr;
}
}
int extruder_second_max_object_height = -1;
for (int extruder_nr = 0; extruder_nr < extruder_count; extruder_nr++)
{
if (extruder_nr == extruder_max_object_height) { continue; }
if (extruder_second_max_object_height == -1 || max_object_height_per_extruder[extruder_nr] > max_object_height_per_extruder[extruder_second_max_object_height])
{
extruder_second_max_object_height = extruder_nr;
}
}
if (extruder_second_max_object_height < 0)
{
storage.max_object_height_second_to_last_extruder = -1;
}
else
{
storage.max_object_height_second_to_last_extruder = max_object_height_per_extruder[extruder_second_max_object_height];
}
}
}
void PrimeTower::generateGroundpoly(const SliceDataStorage& storage)
{
PolygonRef p = ground_poly.newPoly();
@@ -122,7 +67,8 @@ void PrimeTower::generateGroundpoly(const SliceDataStorage& storage)
void PrimeTower::generatePaths(const SliceDataStorage& storage, unsigned int total_layers)
{
if (storage.max_object_height_second_to_last_extruder >= 0 && storage.getSettingBoolean("prime_tower_enable"))
extruder_count = storage.meshgroup->getExtruderCount();
if (storage.max_print_height_second_to_last_extruder >= 0 && storage.getSettingBoolean("prime_tower_enable"))
{
generatePaths_denseInfill(storage);
generateWipeLocations(storage);
@@ -160,7 +106,7 @@ void PrimeTower::generatePaths_denseInfill(const SliceDataStorage& storage)
void PrimeTower::addToGcode(const SliceDataStorage& storage, GCodePlanner& gcodeLayer, const GCodeExport& gcode, const int layer_nr, const int prev_extruder, bool wipe)
{
if (!( storage.max_object_height_second_to_last_extruder >= 0 && storage.getSettingInMicrons("prime_tower_size") > 0) )
if (!( storage.max_print_height_second_to_last_extruder >= 0 && storage.getSettingInMicrons("prime_tower_size") > 0) )
{
return;
}
@@ -174,7 +120,7 @@ void PrimeTower::addToGcode(const SliceDataStorage& storage, GCodePlanner& gcode
return;
}
if (layer_nr > storage.max_object_height_second_to_last_extruder + 1)
if (layer_nr > storage.max_print_height_second_to_last_extruder + 1)
{
return;
}
-7
Ver Arquivo
@@ -75,13 +75,6 @@ public:
*/
void generatePaths(const SliceDataStorage& storage, unsigned int total_layers);
/*!
* Compute the maximum layer at which a layer switch will occur and store the result in \ref SliceDataStorage::max_object_height_second_to_last_extruder
*
* \param[in,out] storage Where to retrieve area data and extruder settings for those areas; where to store the max_object_height_second_to_last_extruder
*/
void computePrimeTowerMax(SliceDataStorage& storage);
PrimeTower(); //!< basic constructor
/*!
+2
Ver Arquivo
@@ -2,7 +2,9 @@
#include <cmath> // sqrt
#include <fstream> // debug IO
#ifndef WIN32
#include <unistd.h>
#endif
#include "progress/Progress.h"
#include "weaveDataStorage.h"
+1 -1
Ver Arquivo
@@ -14,7 +14,7 @@
#include <string> // stoi
#ifdef _WIN32
#ifdef WIN32
#include <windows.h>
#endif
+7 -1
Ver Arquivo
@@ -652,7 +652,13 @@ void GCodePlanner::writeGCode(GCodeExport& gcode)
if (extruder_plan.prev_extruder_standby_temp)
{ // turn off previous extruder
constexpr bool wait = false;
gcode.writeTemperatureCommand(prev_extruder, *extruder_plan.prev_extruder_standby_temp, wait);
double prev_extruder_temp = *extruder_plan.prev_extruder_standby_temp;
int prev_layer_nr = (extruder_plan_idx == 0)? layer_nr - 1 : layer_nr;
if (prev_layer_nr == storage.max_print_height_per_extruder[prev_extruder])
{
prev_extruder_temp = 0; // TODO ? should there be a setting for extruder_off_temperature ?
}
gcode.writeTemperatureCommand(prev_extruder, prev_extruder_temp, wait);
}
}
gcode.writeFanCommand(extruder_plan.getFanSpeed());
+2
Ver Arquivo
@@ -2,7 +2,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <sys/time.h>
#endif
#include <signal.h>
#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
#include <execinfo.h>
+2 -2
Ver Arquivo
@@ -13,7 +13,7 @@ namespace cura {
*/
void PathOrderOptimizer::optimize()
{
bool picked[polygons.size()];
bool *picked = static_cast<bool*>(alloca(sizeof(bool) * polygons.size()));
memset(picked, false, sizeof(bool) * polygons.size());/// initialized as falses
for (PolygonRef poly : polygons) /// find closest point to initial starting point within each polygon +initialize picked
@@ -154,7 +154,7 @@ void LineOrderOptimizer::optimize()
{
int gridSize = 5000; // the size of the cells in the hash grid. TODO
SparsePointGridInclusive<unsigned int> line_bucket_grid(gridSize);
bool picked[polygons.size()];
bool *picked = static_cast<bool*>(alloca(sizeof(bool) * polygons.size()));
memset(picked, false, sizeof(bool) * polygons.size());/// initialized as falses
for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++) /// find closest point to initial starting point within each polygon +initialize picked
+17 -1
Ver Arquivo
@@ -3,7 +3,11 @@
#include <sstream>
#include <iostream> // debug IO
#ifndef WIN32
#include <libgen.h> // dirname
#else
extern char *dirname(char *path);
#endif
#include <string>
#include <cstring> // strtok (split string using delimiters) strcpy
#include <fstream> // ifstream (to see if file exists)
@@ -151,7 +155,7 @@ int SettingRegistry::loadJSONsettings(std::string filename, SettingsBase* settin
if (err) { return err; }
{ // add parent folder to search paths
char filename_cstr[filename.size()];
char *filename_cstr = static_cast<char*>(alloca(filename.size()));
std::strcpy(filename_cstr, filename.c_str()); // copy the string because dirname(.) changes the input string!!!
std::string folder_name = std::string(dirname(filename_cstr));
search_paths.emplace(folder_name);
@@ -381,3 +385,15 @@ void SettingRegistry::_loadSettingValues(SettingConfig* config, const rapidjson:
}
}//namespace cura
#ifdef WIN32
#include <windows.h>
char *dirname(char *path)
{
static char folder_name[MAX_PATH + 1], *p;
GetFullPathNameA(path, _countof(folder_name), folder_name, &p);
p[-1] = 0;
return folder_name;
}
#endif
+4
Ver Arquivo
@@ -6,7 +6,11 @@
#include <stdio.h> // for file output
#include <sstream>
#include <iostream> // debug IO
#ifndef WIN32
#include <libgen.h> // dirname
#else
extern char *dirname(char *path);
#endif
#include <string>
#include <algorithm> // find_if
#include <regex> // regex_search
+1 -1
Ver Arquivo
@@ -180,7 +180,7 @@ bool SettingsBaseVirtual::getSettingBoolean(std::string key) const
return true;
if (value == "yes")
return true;
if (value == "true" or value == "True") //Python uses "True"
if (value == "true" || value == "True") //Python uses "True"
return true;
int num = atoi(value.c_str());
return num != 0;
+11 -2
Ver Arquivo
@@ -162,8 +162,17 @@ void generateInfill(int layerNr, SliceMeshStorage& mesh, const int innermost_wal
}
}
infill.removeSmallAreas(MIN_AREA_SIZE);
part.infill_area = infill.offset(infill_skin_overlap);
Polygons final_infill = infill.offset(infill_skin_overlap);
if (mesh.getSettingBoolean("infill_hollow"))
{
part.print_outline = part.print_outline.difference(final_infill);
}
else
{
part.infill_area = final_infill;
}
}
}
+1 -1
Ver Arquivo
@@ -105,7 +105,7 @@ SliceDataStorage::SliceDataStorage(MeshGroup* meshgroup) : SettingsMessenger(mes
raft_surface_config(PrintFeatureType::SupportInterface),
support_config(PrintFeatureType::Support),
support_skin_config(PrintFeatureType::SupportInterface),
max_object_height_second_to_last_extruder(-1)
max_print_height_second_to_last_extruder(-1)
{
}
+4 -1
Ver Arquivo
@@ -195,7 +195,10 @@ public:
Polygons skirt_brim[MAX_EXTRUDERS]; //!< Skirt and brim polygons per extruder, ordered from inner to outer polygons.
Polygons raftOutline; //Storage for the outline of the raft. Will be filled with lines when the GCode is generated.
int max_object_height_second_to_last_extruder; //!< Used in multi-extrusion: the layer number beyond which all models are printed with the same extruder
int max_print_height_second_to_last_extruder; //!< Used in multi-extrusion: the layer number beyond which all models are printed with the same extruder
std::vector<int> max_print_height_per_extruder; //!< For each extruder the highest layer number at which it is used.
std::vector<size_t> max_print_height_order; //!< Ordered indices into max_print_height_per_extruder: back() will return the extruder number with the highest print height.
PrimeTower primeTower;
std::vector<Polygons> oozeShield; //oozeShield per layer
+47
Ver Arquivo
@@ -0,0 +1,47 @@
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#ifndef UTILS_ALGORITHM_H
#define UTILS_ALGORITHM_H
#include <algorithm>
#include <vector>
#include <functional>
#include <numeric>
// extensions to algorithm.h from the standard library
namespace cura
{
/*!
* Get the order of a vector: the sorted indices of a vector
*
* {1.6, 1.8, 1.7} returns {1, 3, 2} meaning {in[1], in[3], in[2]} is a sorted
* vector
*
* Thanks to Lukasz Wiklendt
*
* \param in The vector for which to get the order
* \return An ordered vector of indices into \p in
*/
template<typename T>
std::vector<size_t> order(const std::vector<T> &in)
{
// initialize original index locations
std::vector<size_t> order(in.size());
std::iota(order.begin(), order.end(), 0); // fill vector with 1, 2, 3,.. etc
// sort indexes based on comparing values in v
std::sort(order.begin(), order.end(),
[&in](size_t i1, size_t i2)
{
return in[i1] < in[i2];
}
);
return order;
}
} // namespace cura
#endif // UTILS_ALGORITHM_H
+5 -5
Ver Arquivo
@@ -2,14 +2,14 @@
#ifndef GETTIME_H
#define GETTIME_H
#ifdef __WIN32
#ifdef WIN32
#include <windows.h>
#else
#include <sys/time.h>
#ifdef USE_CPU_TIME
#include <sys/resource.h>
#endif
#include <sys/time.h>
#include <stddef.h>
#include <cassert>
#endif
@@ -18,9 +18,9 @@ namespace cura
{
static inline double getTime()
{
#ifdef __WIN32
#ifdef WIN32
return double(GetTickCount()) / 1000.0;
#else // not __WIN32
#else // not WIN32
#if USE_CPU_TIME // Use cpu usage time if available, otherwise wall clock time
struct rusage usage;
#ifdef DEBUG
@@ -38,7 +38,7 @@ static inline double getTime()
gettimeofday(&tv, nullptr);
return double(tv.tv_sec) + double(tv.tv_usec) / 1000000.0;
#endif // USE_CPU_TIME
#endif // __WIN32
#endif // WIN32
}
class TimeKeeper
+2 -2
Ver Arquivo
@@ -119,9 +119,9 @@ unsigned int Polygons::findInside(Point p, bool border_result)
return false;
}
int64_t min_x[size()];
int64_t *min_x = static_cast<int64_t*>(alloca(sizeof(int64_t) * size()));
std::fill_n(min_x, size(), std::numeric_limits<int64_t>::max()); // initialize with int.max
int crossings[size()];
int *crossings = static_cast<int*>(alloca(sizeof(int) * size()));
std::fill_n(crossings, size(), 0); // initialize with zeros
for (unsigned int poly_idx = 0; poly_idx < size(); poly_idx++)
+31 -5
Ver Arquivo
@@ -5,6 +5,10 @@
#include <cstdio> // sprintf
#include <sstream> // ostringstream
#include <cinttypes> // PRId64
#include "logoutput.h"
namespace cura
{
@@ -29,8 +33,19 @@ static inline int stringcasecompare(const char* a, const char* b)
*/
static inline void writeInt2mm(const int64_t coord, std::ostream& ss)
{
char buffer[24];
int char_count = sprintf(buffer, "%ld", coord); // convert int to string
constexpr size_t buffer_size = 24;
char buffer[buffer_size];
int char_count = sprintf(buffer, "%" PRId64, coord); // convert int to string
#ifdef DEBUG
if (char_count + 1 >= int(buffer_size)) // + 1 for the null character
{
logError("Cannot write %ld to buffer of size %i", coord, buffer_size);
}
if (char_count < 0)
{
logError("Encoding error while writing %ld", coord);
}
#endif // DEBUG
int end_pos = char_count; // the first character not to write any more
int trailing_zeros = 1;
while (trailing_zeros < 4 && buffer[char_count - trailing_zeros] == '0')
@@ -103,10 +118,21 @@ struct MMtoStream
*/
static inline void writeDoubleToStream(const unsigned int precision, const double coord, std::ostream& ss)
{
char format[5] = "%.xf"; // write a float with [x] digits after the dot
char format[5] = "%.xF"; // write a float with [x] digits after the dot
format[2] = '0' + precision; // set [x]
char buffer[24];
int char_count = snprintf(buffer, 24, format, coord);
constexpr size_t buffer_size = 400;
char buffer[buffer_size];
int char_count = sprintf(buffer, format, coord);
#ifdef DEBUG
if (char_count + 1 >= int(buffer_size)) // + 1 for the null character
{
logError("Cannot write %f to buffer of size %i", coord, buffer_size);
}
if (char_count < 0)
{
logError("Encoding error while writing %f", coord);
}
#endif // DEBUG
if (char_count <= 0)
{
return;
+112
Ver Arquivo
@@ -3,10 +3,12 @@
#include "StringTest.h"
#include <iomanip>
#include <sstream> // ostringstream
#include <../src/utils/intpoint.h>
#include <../src/utils/string.h>
namespace cura
{
CPPUNIT_TEST_SUITE_REGISTRATION(StringTest);
@@ -69,13 +71,25 @@ void StringTest::writeInt2mmTest123456789()
{
writeInt2mmAssert(123456789);
}
void StringTest::writeInt2mmTestMax()
{
writeInt2mmAssert(std::numeric_limits<int64_t>::max() / 1001); // divide by 1001, because MM2INT first converts to int and then multiplies by 1000, which causes overflow for the highest integer.
}
void StringTest::writeInt2mmAssert(int64_t in)
{
std::ostringstream ss;
writeInt2mm(in, ss);
ss.flush();
std::string str = ss.str();
if (!ss.good())
{
char buffer[200];
sprintf(buffer, "The integer %ld was printed as '%s' which was a bad string!", in, str.c_str());
CPPUNIT_ASSERT_MESSAGE(std::string(buffer), false);
}
int64_t out = MM2INT(strtod(str.c_str(), nullptr));
char buffer[200];
@@ -84,4 +98,102 @@ void StringTest::writeInt2mmAssert(int64_t in)
}
void StringTest::writeDoubleToStreamTest10000Negative()
{
writeDoubleToStreamAssert(-10.000);
}
void StringTest::writeDoubleToStreamTest1000Negative()
{
writeDoubleToStreamAssert(-1.000);
}
void StringTest::writeDoubleToStreamTest100Negative()
{
writeDoubleToStreamAssert(-.100);
}
void StringTest::writeDoubleToStreamTest10Negative()
{
writeDoubleToStreamAssert(-.010);
}
void StringTest::writeDoubleToStreamTest1Negative()
{
writeDoubleToStreamAssert(-.001);
}
void StringTest::writeDoubleToStreamTest0()
{
writeDoubleToStreamAssert(0.000);
}
void StringTest::writeDoubleToStreamTest1()
{
writeDoubleToStreamAssert(.001);
}
void StringTest::writeDoubleToStreamTest10()
{
writeDoubleToStreamAssert(.010);
}
void StringTest::writeDoubleToStreamTest100()
{
writeDoubleToStreamAssert(.100);
}
void StringTest::writeDoubleToStreamTest1000()
{
writeDoubleToStreamAssert(1.000);
}
void StringTest::writeDoubleToStreamTest10000()
{
writeDoubleToStreamAssert(10.000);
}
void StringTest::writeDoubleToStreamTest123456789()
{
writeDoubleToStreamAssert(123456.789);
}
void StringTest::writeDoubleToStreamTestMin()
{
writeDoubleToStreamAssert(std::numeric_limits<double>::min());
}
void StringTest::writeDoubleToStreamTestMax()
{
writeDoubleToStreamAssert(std::numeric_limits<double>::max());
}
void StringTest::writeDoubleToStreamTestLowest()
{
writeDoubleToStreamAssert(std::numeric_limits<double>::lowest());
}
void StringTest::writeDoubleToStreamTestLowestNeg()
{
writeDoubleToStreamAssert(-std::numeric_limits<double>::lowest());
}
void StringTest::writeDoubleToStreamTestLow()
{
writeDoubleToStreamAssert(0.00000001d);
}
void StringTest::writeDoubleToStreamAssert(double in, unsigned int precision)
{
std::ostringstream ss;
writeDoubleToStream(precision, in, ss);
ss.flush();
std::string str = ss.str();
if (!ss.good())
{
char buffer[8000];
sprintf(buffer, "The double %f was printed as '%s' which was a bad string!", in, str.c_str());
CPPUNIT_ASSERT_MESSAGE(std::string(buffer), false);
}
double out = strtod(str.c_str(), nullptr);
std::ostringstream in_ss;
in_ss << std::fixed << std::setprecision(precision) << in;
std::string in_str = in_ss.str();
double in_reinterpreted = strtod(in_str.c_str(), nullptr);
char buffer[8000];
sprintf(buffer, "The double %f was printed as '%s' which was interpreted as %f rather than %f!", in, str.c_str(), out, in_reinterpreted);
if (in_reinterpreted != out) std::cerr << buffer << "\n";
CPPUNIT_ASSERT_MESSAGE(std::string(buffer), in_reinterpreted == out);
}
}
+49
Ver Arquivo
@@ -25,6 +25,25 @@ class StringTest : public CppUnit::TestFixture
CPPUNIT_TEST(writeInt2mmTest1000);
CPPUNIT_TEST(writeInt2mmTest10000);
CPPUNIT_TEST(writeInt2mmTest123456789);
CPPUNIT_TEST(writeInt2mmTestMax);
CPPUNIT_TEST(writeDoubleToStreamTest10000Negative);
CPPUNIT_TEST(writeDoubleToStreamTest1000Negative);
CPPUNIT_TEST(writeDoubleToStreamTest100Negative);
CPPUNIT_TEST(writeDoubleToStreamTest10Negative);
CPPUNIT_TEST(writeDoubleToStreamTest1Negative);
CPPUNIT_TEST(writeDoubleToStreamTest0);
CPPUNIT_TEST(writeDoubleToStreamTest1);
CPPUNIT_TEST(writeDoubleToStreamTest10);
CPPUNIT_TEST(writeDoubleToStreamTest100);
CPPUNIT_TEST(writeDoubleToStreamTest1000);
CPPUNIT_TEST(writeDoubleToStreamTest10000);
CPPUNIT_TEST(writeDoubleToStreamTest123456789);
CPPUNIT_TEST(writeDoubleToStreamTestMin);
CPPUNIT_TEST(writeDoubleToStreamTestMax);
CPPUNIT_TEST(writeDoubleToStreamTestLowest);
CPPUNIT_TEST(writeDoubleToStreamTestLowestNeg);
CPPUNIT_TEST(writeDoubleToStreamTestLow);
CPPUNIT_TEST_SUITE_END();
public:
@@ -57,6 +76,25 @@ public:
void writeInt2mmTest1000();
void writeInt2mmTest10000();
void writeInt2mmTest123456789();
void writeInt2mmTestMax();
void writeDoubleToStreamTest10000Negative();
void writeDoubleToStreamTest1000Negative();
void writeDoubleToStreamTest100Negative();
void writeDoubleToStreamTest10Negative();
void writeDoubleToStreamTest1Negative();
void writeDoubleToStreamTest0();
void writeDoubleToStreamTest1();
void writeDoubleToStreamTest10();
void writeDoubleToStreamTest100();
void writeDoubleToStreamTest1000();
void writeDoubleToStreamTest10000();
void writeDoubleToStreamTest123456789();
void writeDoubleToStreamTestMin();
void writeDoubleToStreamTestMax();
void writeDoubleToStreamTestLowest();
void writeDoubleToStreamTestLowestNeg();
void writeDoubleToStreamTestLow();
private:
@@ -69,6 +107,17 @@ private:
* \param in the integer to check
*/
void writeInt2mmAssert(int64_t in);
/*!
* \brief Performs the actual assertion for the getDist2FromLineSegmentTest.
*
* This is essentially a parameterised version of all unit tests pertaining
* to the writeInt2mm tests.
*
* \param in the double to check
* \param precision the (maximum) number of digits after the decimal mark to print
*/
void writeDoubleToStreamAssert(double in, unsigned int precision = 4);
};
}