Comparar commits
8 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| d36934e35b | |||
| 41f7258e25 | |||
| 24cb4fbb36 | |||
| 6fa022013d | |||
| 9274846970 | |||
| 9050f8da53 | |||
| f7039848c2 | |||
| d4e27d8bbb |
@@ -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()
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário