Comparar commits

...

8 Commits

Autor SHA1 Mensagem Data
Tim Kuipers d36934e35b bugfix: sliceDataStorage.meshes reallocation due to size change 2015-08-07 15:32:19 +02:00
Tim Kuipers 41f7258e25 bugfix: retraction count max 2015-08-05 14:30:57 +02:00
Tim Kuipers 24cb4fbb36 bugfix for combined infill lines 2015-07-28 14:00:51 +02:00
Tim Kuipers 6fa022013d bugfix: infill overlap for 100% infill 2015-07-22 15:30:45 +02:00
Tim Kuipers 9274846970 merge 2015-07-22 13:03:54 +02:00
Tim Kuipers 9050f8da53 cleanup debug shite last bugfix 2015-07-20 14:37:59 +02:00
Tim Kuipers f7039848c2 bugfix: remove degenerate verts: verts connected to overlapping line segments 2015-07-20 14:18:14 +02:00
Arjen Hiemstra d4e27d8bbb Force using clang libc++ on MacOSX to prevent issues with linking 2015-07-16 15:58:00 +02:00
11 arquivos alterados com 168 adições e 22 exclusões
+5
Ver Arquivo
@@ -15,6 +15,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
if(NOT APPLE AND NOT WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++")
elseif(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR} libs)
@@ -58,6 +60,9 @@ protobuf_generate_cpp(engine_PB_SRCS engine_PB_HEADERS Cura.proto)
add_executable(CuraEngine ${engine_SRCS} ${engine_PB_SRCS})
target_link_libraries(CuraEngine clipper Arcus)
add_executable(Test src/test.cpp)
target_link_libraries(Test clipper)
if (UNIX)
target_link_libraries(CuraEngine pthread)
endif()
+8 -2
Ver Arquivo
@@ -183,7 +183,7 @@ private:
}
gcode.setFlavor(getSettingAsGCodeFlavor("machine_gcode_flavor"));
gcode.setRetractionSettings(getSettingInMicrons("machine_switch_extruder_retraction_amount"), getSettingInMillimetersPerSecond("material_switch_extruder_retraction_speed"), getSettingInMillimetersPerSecond("material_switch_extruder_prime_speed"), getSettingInMicrons("retraction_extrusion_window"), getSettingInMicrons("retraction_count_max"));
gcode.setRetractionSettings(getSettingInMicrons("machine_switch_extruder_retraction_amount"), getSettingInMillimetersPerSecond("material_switch_extruder_retraction_speed"), getSettingInMillimetersPerSecond("material_switch_extruder_prime_speed"), getSettingInMicrons("retraction_extrusion_window"), getSettingAsCount("retraction_count_max"));
}
bool prepareModel(SliceDataStorage& storage, PrintObject* object) /// slices the model
@@ -260,6 +260,7 @@ private:
object->clear();///Clear the mesh data, it is no longer needed after this point, and it saves a lot of memory.
log("Generating layer parts...\n");
storage.meshes.reserve(slicerList.size());
for(unsigned int meshIdx=0; meshIdx < slicerList.size(); meshIdx++)
{
storage.meshes.emplace_back(&object->meshes[meshIdx]);
@@ -450,7 +451,12 @@ private:
generateSkins(layer_nr, mesh, extrusionWidth, mesh.settings->getSettingAsCount("bottom_layers"), mesh.settings->getSettingAsCount("top_layers"), mesh.settings->getSettingAsCount("skin_outline_count"), mesh.settings->getSettingBoolean("wall_overlap_avoid_enabled"));
if (mesh.settings->getSettingInMicrons("infill_line_distance") > 0)
{
generateSparse(layer_nr, mesh, extrusionWidth, mesh.settings->getSettingAsCount("bottom_layers"), mesh.settings->getSettingAsCount("top_layers"));
int infill_skin_overlap = 0;
if (mesh.settings->getSettingInMicrons("infill_line_distance") > mesh.settings->getSettingInMicrons("infill_line_width") + 10)
{
infill_skin_overlap = extrusionWidth / 2;
}
generateSparse(layer_nr, mesh, extrusionWidth, infill_skin_overlap);
if (mesh.settings->getSettingString("fill_perimeter_gaps") == "Skin")
{
generatePerimeterGaps(layer_nr, mesh, extrusionWidth, mesh.settings->getSettingAsCount("bottom_layers"), mesh.settings->getSettingAsCount("top_layers"));
+3 -3
Ver Arquivo
@@ -88,7 +88,7 @@ void GCodeExport::setRetractionSettings(int extruderSwitchRetraction, int extrud
this->extruderSwitchRetractionSpeed = extruderSwitchRetractionSpeed;
this->extruderSwitchPrimeSpeed = extruderSwitchPrimeSpeed;
this->retraction_extrusion_window = INT2MM(retraction_extrusion_window);
this->retraction_count_max = INT2MM(retraction_count_max);
this->retraction_count_max = retraction_count_max;
}
void GCodeExport::setZ(int z)
@@ -337,7 +337,7 @@ void GCodeExport::writeRetraction(RetractionConfig* config, bool force)
if (config->amount <= 0)
return;
if (!force && retraction_count_max > 0 && extrusion_amount_at_previous_n_retractions.size() == retraction_count_max - 1
if (!force && retraction_count_max > 0 && int(extrusion_amount_at_previous_n_retractions.size()) == retraction_count_max - 1
&& extrusion_amount < extrusion_amount_at_previous_n_retractions.back() + retraction_extrusion_window)
return;
@@ -362,7 +362,7 @@ void GCodeExport::writeRetraction(RetractionConfig* config, bool force)
isZHopped = true;
}
extrusion_amount_at_previous_n_retractions.push_front(extrusion_amount);
if (extrusion_amount_at_previous_n_retractions.size() == retraction_count_max)
if (int(extrusion_amount_at_previous_n_retractions.size()) == retraction_count_max)
{
extrusion_amount_at_previous_n_retractions.pop_back();
}
+1 -1
Ver Arquivo
@@ -99,7 +99,7 @@ private:
int extruderSwitchRetractionSpeed;
int extruderSwitchPrimeSpeed;
double retraction_extrusion_window;
double retraction_count_max;
int retraction_count_max;
std::deque<double> extrusion_amount_at_previous_n_retractions; // in mm or mm^3
Point3 currentPosition;
Point3 startPosition;
+5 -5
Ver Arquivo
@@ -238,13 +238,13 @@ void GCodePlanner::writeGCode(bool liftHeadIfNeeded, int layerThickness)
p0 = gcode.getPositionXY();
for(unsigned int x=n; x<i-1; x+=2)
{
int64_t oldLen = vSize(p0 - paths[x].points[0]);
int64_t new_width = vSize(p0 - paths[x].points[0]); // = old_length
Point newPoint = (paths[x].points[0] + paths[x+1].points[0]) / 2;
int64_t newLen = vSize(gcode.getPositionXY() - newPoint);
if (newLen > 0)
int64_t old_width = path->config->getLineWidth();
if (old_width > 0)
{
if (oldLen > 0)
gcode.writeMove(newPoint, speed * newLen / oldLen, path->config->getExtrusionMM3perMM());
if (new_width > 0)
gcode.writeMove(newPoint, speed * old_width / new_width, path->config->getExtrusionMM3perMM() * new_width / old_width);
else
gcode.writeMove(newPoint, speed, path->config->getExtrusionMM3perMM());
}
+3 -4
Ver Arquivo
@@ -95,14 +95,13 @@ void generateSkinInsets(SliceLayerPart* part, int extrusionWidth, int insetCount
}
}
void generateSparse(int layerNr, SliceMeshStorage& storage, int extrusionWidth, int downSkinCount, int upSkinCount)
void generateSparse(int layerNr, SliceMeshStorage& storage, int extrusionWidth, int infill_skin_overlap)
{
int extra_sparse_inset_during_clipping = extrusionWidth / 2;
SliceLayer& layer = storage.layers[layerNr];
for(SliceLayerPart& part : layer.parts)
{
Polygons sparse = part.insets.back().offset(-extrusionWidth / 2 - extra_sparse_inset_during_clipping);
Polygons sparse = part.insets.back().offset(-extrusionWidth / 2 - infill_skin_overlap);
for(SliceLayerPart& part2 : layer.parts)
{
@@ -116,7 +115,7 @@ void generateSparse(int layerNr, SliceMeshStorage& storage, int extrusionWidth,
}
sparse.removeSmallAreas(3.0);//(2 * M_PI * INT2MM(config.extrusionWidth) * INT2MM(config.extrusionWidth)) * 3;
part.sparse_outline.push_back(sparse.offset(extra_sparse_inset_during_clipping));
part.sparse_outline.push_back(sparse.offset(infill_skin_overlap));
}
}
+8 -2
Ver Arquivo
@@ -53,8 +53,14 @@ void generateSkinAreas(int layerNr, SliceMeshStorage& storage, int extrusionWidt
*/
void generateSkinInsets(SliceLayerPart* part, int extrusionWidth, int insetCount, bool avoidOverlappingPerimeters);
void generateSparse(int layerNr, SliceMeshStorage& storage, int extrusionWidth, int downSkinCount, int upSkinCount);
/*!
* Generate Infill
* \param layerNr The index of the layer for which to generate the infill
* \param part The part where the insets (input) are stored and where the infill (output) is stored.
* \param extrusionWidth width of the wall lines
* \param infill_skin_overlap overlap distance between infill and skin
*/
void generateSparse(int layerNr, SliceMeshStorage& storage, int extrusionWidth, int infill_skin_overlap);
void combineSparseLayers(int layerNr, SliceMeshStorage& storage, int amount);
}//namespace cura
+4 -1
Ver Arquivo
@@ -271,6 +271,7 @@ void SlicerLayer::makePolygons(Mesh* mesh, bool keep_none_closed, bool extensive
polygonList.add(openPolygonList[n]);
}
}
for(unsigned int i=0;i<openPolygonList.size();i++)
{
if (openPolygonList[i].size() > 0)
@@ -298,7 +299,9 @@ void SlicerLayer::makePolygons(Mesh* mesh, bool keep_none_closed, bool extensive
//Finally optimize all the polygons. Every point removed saves time in the long run.
optimizePolygons(polygonList);
polygonList = polygonList.removeDegenerateVerts(); // remove verts connected to overlapping line segments
int xy_offset = mesh->getSettingInMicrons("xy_offset");
if (xy_offset != 0)
{
+1 -2
Ver Arquivo
@@ -31,7 +31,6 @@ void generateSupportAreas(SliceDataStorage& storage, SliceMeshStorage* object, i
double supportAngle = object->settings->getSettingInAngleRadians("support_angle");
bool supportOnBuildplateOnly = support_type == Support_PlatformOnly;
int supportXYDistance = object->settings->getSettingInMicrons("support_xy_distance");
int supportZDistance = object->settings->getSettingInMicrons("support_z_distance");
int supportZDistanceBottom = object->settings->getSettingInMicrons("support_bottom_distance");
int supportZDistanceTop = object->settings->getSettingInMicrons("support_top_distance");
@@ -50,7 +49,7 @@ void generateSupportAreas(SliceDataStorage& storage, SliceMeshStorage* object, i
int layerThickness = object->settings->getSettingInMicrons("layer_height");
int extrusionWidth = object->settings->getSettingInMicrons("wall_line_width_x"); // TODO check for layer0extrusionWidth!
int supportXYDistance = object->settings->getSettingInMicrons("support_xy_distance") + extrusionWidth / 2;
+42 -1
Ver Arquivo
@@ -163,6 +163,7 @@ void test_BucketGrid2D()
//bg.debug();
}*/
/*
#include <math.h>
#include "utils/gettime.h"
void test_findClosestConnection()
@@ -264,8 +265,48 @@ void test_findClosestConnection()
std::cerr << "evalTime : " << evalTime << std::endl;
std::cerr << "totalLength : " << totalLength << std::endl;
}
*/
void test_clipper()
{
Polygon p;
p.emplace_back(0, 11004);
p.emplace_back(0, 10129);
p.emplace_back(0, 9185);
p.emplace_back(0, 8477);
p.emplace_back(1, 8491);
p.emplace_back(418, 8861);
p.emplace_back(1080, 9389);
p.emplace_back(2106, 10142);
p.emplace_back(3000, 10757);
p.emplace_back(3000, 12010);
p.emplace_back(3000, 12790);
p.emplace_back(3000, 13485);
p.emplace_back(3000, 14088);
p.emplace_back(3000, 14601);
p.emplace_back(3000, 15354);
p.emplace_back(3000, 24867);
p.emplace_back(3000, 25469);
p.emplace_back(3000, 26303);
p.emplace_back(3000, 27421);
p.emplace_back(3000, 28242);
p.emplace_back(2107, 28856);
p.emplace_back(1080, 29610);
p.emplace_back(608, 29986);
p.emplace_back(1, 30508);
p.emplace_back(1, 30522);
p.emplace_back(0, 11772);
Polygons polys;
polys.add(p);
polys.debugOutputHTML("output/problem_test.html", true);
polys.offset(-400).debugOutputHTML("output/problem_test_offset.html", true);
polys = polys.removeDegenerateVerts();
polys.offset(-400).debugOutputHTML("output/problem_test_offset_solved.html", true);
}
int main(int argc, char **argv)
{
test_findClosestConnection();
// test_findClosestConnection();
test_clipper();
}
+88 -1
Ver Arquivo
@@ -66,6 +66,12 @@ public:
{
polygon->push_back(p);
}
template <typename... Args>
void emplace_back(Args... args)
{
polygon->emplace_back(args...);
}
void remove(unsigned int index)
{
@@ -344,11 +350,16 @@ public:
}
}
void pop_back()
{
polygon->pop_back();
}
ClipperLib::Path::reference back() const
{
return polygon->back();
}
ClipperLib::Path::iterator begin()
{
return polygon->begin();
@@ -559,6 +570,47 @@ public:
}
}
}
/*!
* Removes overlapping consecutive line segments which don't delimit a positive area.
*/
Polygons removeDegenerateVerts()
{
Polygons ret;
for (PolygonRef poly : *this)
{
Polygon result;
auto isDegenerate = [](Point& last, Point& now, Point& next)
{
Point last_line = now - last;
Point next_line = next - now;
return dot(last_line, next_line) == -1 * vSize(last_line) * vSize(next_line);
};
for (unsigned int idx = 0; idx < poly.size(); idx++)
{
Point& last = (result.size() == 0) ? poly.back() : result.back();
if (idx+1 == poly.size() && result.size() == 0) { break; }
Point& next = (idx+1 == poly.size())? result[0] : poly[idx+1];
if ( isDegenerate(last, poly[idx], next) )
{ // lines are in the opposite direction
// don't add vert to the result
while (result.size() > 1 && isDegenerate(result[result.size()-2], result.back(), next) )
{
result.pop_back();
}
}
else
{
result.add(poly[idx]);
}
}
if (result.size() > 2) { ret.add(result); }
}
return ret;
}
/*!
* Removes the same polygons from this set (and also empty polygons).
* Polygons are considered the same if all points lie within [same_distance] of their counterparts.
@@ -709,6 +761,41 @@ public:
}
}
}
void debugOutputHTML(const char* filename, bool dotTheVertices = false)
{
FILE* out = fopen(filename, "w");
fprintf(out, "<!DOCTYPE html><html><body>");
Point modelSize = max() - min();
modelSize.X = std::max(modelSize.X, modelSize.Y);
modelSize.Y = std::max(modelSize.X, modelSize.Y);
Point modelMin = min();
fprintf(out, "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" style=\"width: 500px; height:500px\">\n");
for(Polygons& parts : splitIntoParts())
{
for(unsigned int j=0;j<parts.size();j++)
{
Polygon poly = parts[j];
fprintf(out, "<polygon points=\"");
for(Point& p : poly)
{
fprintf(out, "%f,%f ", float(p.X - modelMin.X)/modelSize.X*500, float(p.Y - modelMin.Y)/modelSize.Y*500);
}
if (j == 0)
fprintf(out, "\" style=\"fill:gray; stroke:black;stroke-width:1\" />\n");
else
fprintf(out, "\" style=\"fill:red; stroke:black;stroke-width:1\" />\n");
if (dotTheVertices)
for(Point& p : poly)
fprintf(out, "<circle cx=\"%f\" cy=\"%f\" r=\"2\" stroke=\"black\" stroke-width=\"3\" fill=\"black\" />", float(p.X - modelMin.X)/modelSize.X*500, float(p.Y - modelMin.Y)/modelSize.Y*500);
}
}
fprintf(out, "</svg>\n");
fprintf(out, "</body></html>");
fclose(out);
}
};
/* Axis aligned boundary box */