From 4ff00a8f73914ed02e458cfde91c19b150271c9e Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 11 Feb 2016 18:25:45 +0100 Subject: [PATCH 1/7] first approximation infill meshes (CURA-833) --- src/FffPolygonGenerator.cpp | 59 +++++++++++++++++++++++++++++++++++-- src/FffPolygonGenerator.h | 12 +++++++- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 126a53819f..6cc5e1758a 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -93,6 +93,7 @@ bool FffPolygonGenerator::sliceModel(MeshGroup* meshgroup, TimeKeeper& timeKeepe Progress::messageProgressStage(Progress::Stage::PARTS, &timeKeeper); //carveMultipleVolumes(storage.meshes); generateMultipleVolumesOverlap(slicerList, getSettingInMicrons("multiple_mesh_overlap")); + // TODO!!! dont generate multi volume overlap with infill meshes! 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. for(unsigned int meshIdx=0; meshIdx < slicerList.size(); meshIdx++) @@ -157,9 +158,9 @@ void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper& // handle meshes Progress::messageProgressStage(Progress::Stage::INSET_SKIN, &time_keeper); - for (SliceMeshStorage& mesh : storage.meshes) + for (unsigned int mesh_idx = 0; mesh_idx < storage.meshes.size(); mesh_idx++) { - processBasicWallsSkinInfill(mesh, time_keeper, total_layers); + processBasicWallsSkinInfill(storage, mesh_idx, time_keeper, total_layers); } //layerparts2HTML(storage, "output/output.html"); @@ -200,8 +201,15 @@ void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper& } } -void FffPolygonGenerator::processBasicWallsSkinInfill(SliceMeshStorage& mesh, TimeKeeper& time_keeper, size_t total_layers) +void FffPolygonGenerator::processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_idx, TimeKeeper& time_keeper, size_t total_layers) { + + SliceMeshStorage& mesh = storage.meshes[mesh_idx]; + if (mesh.getSettingBoolean("infill_mesh")) + { + processInfillMesh(storage, mesh_idx, total_layers); + } + // TODO: make progress more accurate!! // note: estimated time for insets : skins = 22.953 : 48.858 @@ -228,6 +236,51 @@ void FffPolygonGenerator::processBasicWallsSkinInfill(SliceMeshStorage& mesh, Ti // Progress::messageProgress(Progress::Stage::SKIN, layer_number+1, total_layers); } } + +void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, unsigned int mesh_idx, size_t total_layers) +{ + SliceMeshStorage& mesh = storage.meshes[mesh_idx]; + + for (unsigned int layer_idx = 0; layer_idx < total_layers; layer_idx++) + { + SliceLayer& layer = mesh.layers[layer_idx]; + Polygons new_outlines; // TODO: don't split into parts before this point (for infill meshes)! + + for (unsigned int other_mesh_idx = 0; other_mesh_idx < mesh_idx; other_mesh_idx++) + { + SliceMeshStorage& other_mesh = storage.meshes[other_mesh_idx]; + + int other_mesh_infill_overlap = other_mesh.getSettingInMicrons("infill_overlap"); + + SliceLayer& other_layer = other_mesh.layers[layer_idx]; + + for (SliceLayerPart& part : layer.parts) + { + for (SliceLayerPart& other_part : other_layer.parts) + { + if (!part.boundaryBox.hit(other_part.boundaryBox)) + { + continue; + } + Polygons non_overlapping_infill = other_part.infill_area[0].offset(-other_mesh_infill_overlap); + other_part.infill_area[0] = non_overlapping_infill.difference(part.outline).offset(other_mesh_infill_overlap); + + new_outlines.add(part.outline.intersection(non_overlapping_infill)); + } + } + } + + layer.parts.clear(); + std::vector parts = new_outlines.splitIntoParts(); + for (PolygonsPart& part : parts) + { + layer.parts.emplace_back(); + layer.parts.back().outline = part; + } + } + +} + void FffPolygonGenerator::processDerivedWallsSkinInfill(SliceMeshStorage& mesh, TimeKeeper& time_keeper, size_t total_layers) { // combine infill diff --git a/src/FffPolygonGenerator.h b/src/FffPolygonGenerator.h index 59bc58b14f..daf833f3f9 100644 --- a/src/FffPolygonGenerator.h +++ b/src/FffPolygonGenerator.h @@ -68,10 +68,20 @@ class FffPolygonGenerator : public SettingsMessenger, NoCopy * Processes the outline information as stored in the \p storage: generates inset perimeter polygons, skin and infill * * \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage + * \param mesh_idx The index of the mesh to process in the vector of meshes in \p storage * \param timeKeeper Object which keeps track of timings of each stage. * \param total_layers The total number of layers over all objects */ - void processBasicWallsSkinInfill(SliceMeshStorage& storage, TimeKeeper& timeKeeper, size_t total_layers); + void processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_idx, TimeKeeper& timeKeeper, size_t total_layers); + + /*! + * Process the mesh to be an infill mesh: limit all outlines to within the infill of normal meshes and subtract their volume from the infill of those meshes + * + * \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage + * \param mesh_idx The index of the mesh to process in the vector of meshes in \p storage + * \param total_layers The total number of layers over all objects + */ + void processInfillMesh(SliceDataStorage& storage, unsigned int mesh_idx, size_t total_layers); /*! * TODO From 30df9853e41463aa2ed1e5231b4d3986510b92d9 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 11 Feb 2016 18:59:46 +0100 Subject: [PATCH 2/7] bugfix: infill meshes had too much infill overlap (CURA-833) --- src/FffPolygonGenerator.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 6cc5e1758a..a71969795e 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -244,14 +244,12 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, unsigned for (unsigned int layer_idx = 0; layer_idx < total_layers; layer_idx++) { SliceLayer& layer = mesh.layers[layer_idx]; - Polygons new_outlines; // TODO: don't split into parts before this point (for infill meshes)! + Polygons new_outlines; // TODO: don't split into parts before this point (for infill meshes) ??? for (unsigned int other_mesh_idx = 0; other_mesh_idx < mesh_idx; other_mesh_idx++) { SliceMeshStorage& other_mesh = storage.meshes[other_mesh_idx]; - int other_mesh_infill_overlap = other_mesh.getSettingInMicrons("infill_overlap"); - SliceLayer& other_layer = other_mesh.layers[layer_idx]; for (SliceLayerPart& part : layer.parts) @@ -262,10 +260,9 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, unsigned { continue; } - Polygons non_overlapping_infill = other_part.infill_area[0].offset(-other_mesh_infill_overlap); - other_part.infill_area[0] = non_overlapping_infill.difference(part.outline).offset(other_mesh_infill_overlap); - - new_outlines.add(part.outline.intersection(non_overlapping_infill)); + Polygons& infill = other_part.infill_area[0]; + new_outlines.add(part.outline.intersection(infill)); + infill = infill.difference(part.outline); } } } From d4844d08f2e2dc6f5ee93a28315881b10f3484fb Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 11 Feb 2016 19:46:06 +0100 Subject: [PATCH 3/7] lil refactor: processDerivedWallSkinInfill doesn't have argument TimeKeeper anymore (CURA-833) --- src/FffPolygonGenerator.cpp | 4 ++-- src/FffPolygonGenerator.h | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index a71969795e..e03ffae1a7 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -197,7 +197,7 @@ void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper& { SliceMeshStorage& mesh = storage.meshes[mesh_idx]; Progress::messageProgress(Progress::Stage::INSET_SKIN, mesh_idx, storage.meshes.size()); // TODO: make progress more accurate!! - processDerivedWallsSkinInfill(mesh, time_keeper, total_layers); + processDerivedWallsSkinInfill(mesh, total_layers); } } @@ -278,7 +278,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, unsigned } -void FffPolygonGenerator::processDerivedWallsSkinInfill(SliceMeshStorage& mesh, TimeKeeper& time_keeper, size_t total_layers) +void FffPolygonGenerator::processDerivedWallsSkinInfill(SliceMeshStorage& mesh, size_t total_layers) { // combine infill unsigned int combined_infill_layers = mesh.getSettingInMicrons("infill_sparse_thickness") / std::max(mesh.getSettingInMicrons("layer_height"), 1); //How many infill layers to combine to obtain the requested sparse thickness. diff --git a/src/FffPolygonGenerator.h b/src/FffPolygonGenerator.h index daf833f3f9..56383eb5d4 100644 --- a/src/FffPolygonGenerator.h +++ b/src/FffPolygonGenerator.h @@ -84,9 +84,13 @@ class FffPolygonGenerator : public SettingsMessenger, NoCopy void processInfillMesh(SliceDataStorage& storage, unsigned int mesh_idx, size_t total_layers); /*! - * TODO + * Process features which are derived from the basic walls, skin, and infill: + * fuzzy skin, infill combine + * + * \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage + * \param total_layers The total number of layers over all objects */ - void processDerivedWallsSkinInfill(SliceMeshStorage& storage, TimeKeeper& timeKeeper, size_t total_layers); + void processDerivedWallsSkinInfill(SliceMeshStorage& storage, size_t total_layers); /*! * Remove all bottom layers which are empty. From 60e1f30c60e311117733af8683f9047a252899e4 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 11 Feb 2016 19:47:56 +0100 Subject: [PATCH 4/7] lil optimization: less splitIntoParts in processInfillMesh (CURA-833) --- src/FffPolygonGenerator.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index e03ffae1a7..541c4677d6 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -244,7 +244,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, unsigned for (unsigned int layer_idx = 0; layer_idx < total_layers; layer_idx++) { SliceLayer& layer = mesh.layers[layer_idx]; - Polygons new_outlines; // TODO: don't split into parts before this point (for infill meshes) ??? + std::vector new_parts; for (unsigned int other_mesh_idx = 0; other_mesh_idx < mesh_idx; other_mesh_idx++) { @@ -261,15 +261,28 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, unsigned continue; } Polygons& infill = other_part.infill_area[0]; - new_outlines.add(part.outline.intersection(infill)); + Polygons new_outline = part.outline.intersection(infill); + if (new_outline.size() == 1) + { + PolygonsPart outline_part_here; + outline_part_here.add(new_outline[0]); + new_parts.push_back(outline_part_here); + } + else if (new_outline.size() > 1) + { + std::vector new_parts_here = new_outline.splitIntoParts(); + for (PolygonsPart& new_part_here : new_parts_here) + { + new_parts.push_back(new_part_here); + } + } infill = infill.difference(part.outline); } } } layer.parts.clear(); - std::vector parts = new_outlines.splitIntoParts(); - for (PolygonsPart& part : parts) + for (PolygonsPart& part : new_parts) { layer.parts.emplace_back(); layer.parts.back().outline = part; From e93770017f596ea8c235f1eb941b1f5e7319c399 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 11 Feb 2016 19:56:15 +0100 Subject: [PATCH 5/7] refactor+cleanup for infill mehses (CURA-833) --- src/FffPolygonGenerator.cpp | 6 +++--- src/FffPolygonGenerator.h | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 541c4677d6..309cd4e5e0 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -160,7 +160,8 @@ void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper& Progress::messageProgressStage(Progress::Stage::INSET_SKIN, &time_keeper); for (unsigned int mesh_idx = 0; mesh_idx < storage.meshes.size(); mesh_idx++) { - processBasicWallsSkinInfill(storage, mesh_idx, time_keeper, total_layers); + processBasicWallsSkinInfill(storage, mesh_idx, total_layers); + Progress::messageProgress(Progress::Stage::INSET_SKIN, mesh_idx + 1, storage.meshes.size()); // TODO: make progress more accurate!! } //layerparts2HTML(storage, "output/output.html"); @@ -196,12 +197,11 @@ void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper& for (unsigned int mesh_idx = 0; mesh_idx < storage.meshes.size(); mesh_idx++) { SliceMeshStorage& mesh = storage.meshes[mesh_idx]; - Progress::messageProgress(Progress::Stage::INSET_SKIN, mesh_idx, storage.meshes.size()); // TODO: make progress more accurate!! processDerivedWallsSkinInfill(mesh, total_layers); } } -void FffPolygonGenerator::processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_idx, TimeKeeper& time_keeper, size_t total_layers) +void FffPolygonGenerator::processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_idx, size_t total_layers) { SliceMeshStorage& mesh = storage.meshes[mesh_idx]; diff --git a/src/FffPolygonGenerator.h b/src/FffPolygonGenerator.h index 56383eb5d4..6918a0f6ab 100644 --- a/src/FffPolygonGenerator.h +++ b/src/FffPolygonGenerator.h @@ -69,10 +69,9 @@ class FffPolygonGenerator : public SettingsMessenger, NoCopy * * \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage * \param mesh_idx The index of the mesh to process in the vector of meshes in \p storage - * \param timeKeeper Object which keeps track of timings of each stage. * \param total_layers The total number of layers over all objects */ - void processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_idx, TimeKeeper& timeKeeper, size_t total_layers); + void processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_idx, size_t total_layers); /*! * Process the mesh to be an infill mesh: limit all outlines to within the infill of normal meshes and subtract their volume from the infill of those meshes From 18c7c6bdb9460b67cac24ce0647d2535ae8026e2 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 11 Feb 2016 20:01:38 +0100 Subject: [PATCH 6/7] fix: more secure layer indexing in infill mehses (CURA-833) --- src/FffPolygonGenerator.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 309cd4e5e0..edd3cc34f1 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -241,7 +241,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, unsigned { SliceMeshStorage& mesh = storage.meshes[mesh_idx]; - for (unsigned int layer_idx = 0; layer_idx < total_layers; layer_idx++) + for (unsigned int layer_idx = 0; layer_idx < mesh.layers.size(); layer_idx++) { SliceLayer& layer = mesh.layers[layer_idx]; std::vector new_parts; @@ -249,6 +249,10 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, unsigned for (unsigned int other_mesh_idx = 0; other_mesh_idx < mesh_idx; other_mesh_idx++) { SliceMeshStorage& other_mesh = storage.meshes[other_mesh_idx]; + if (layer_idx >= other_mesh.layers.size()) + { + continue; + } SliceLayer& other_layer = other_mesh.layers[layer_idx]; From d3f0a06ee042d1ecfcd284c5d2f355474c04a849 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 12 Feb 2016 12:09:37 +0100 Subject: [PATCH 7/7] lil TODO (CURA-833) --- src/FffPolygonGenerator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index e9069cb61f..7c0cdfc848 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -95,6 +95,7 @@ bool FffPolygonGenerator::sliceModel(MeshGroup* meshgroup, TimeKeeper& timeKeepe Progress::messageProgressStage(Progress::Stage::PARTS, &timeKeeper); //carveMultipleVolumes(storage.meshes); generateMultipleVolumesOverlap(slicerList, getSettingInMicrons("multiple_mesh_overlap")); + // TODO!!! dont generate multi volume overlap with infill meshes! 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. for(unsigned int meshIdx=0; meshIdx < slicerList.size(); meshIdx++)