diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 81ce5df818..7ec0c2aca1 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -94,6 +94,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++) @@ -144,11 +145,14 @@ bool FffPolygonGenerator::sliceModel(MeshGroup* meshgroup, TimeKeeper& timeKeepe void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper& time_keeper) { // compute layer count and remove first empty layers -// Progress::messageProgressStage(Progress::Stage::INSET_SKIN, &time_keeper); // there is no separate progress stage for removeEmptyFisrtLayer + // there is no separate progress stage for removeEmptyFisrtLayer (TODO) unsigned int total_layers = 0; for (SliceMeshStorage& mesh : storage.meshes) { - total_layers = std::max(total_layers, mesh.layers.size()); + if (!mesh.getSettingBoolean("infill_mesh")) + { + total_layers = std::max(total_layers, mesh.layers.size()); + } } // handle meshes @@ -162,8 +166,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++) { - SliceMeshStorage& mesh = storage.meshes[mesh_idx]; - processBasicWallsSkinInfill(mesh, time_keeper, total_layers, inset_skin_progress_estimate); + processBasicWallsSkinInfill(storage, mesh_idx, total_layers, inset_skin_progress_estimate); + Progress::messageProgress(Progress::Stage::INSET_SKIN, mesh_idx + 1, storage.meshes.size()); } //layerparts2HTML(storage, "output/output.html"); @@ -208,12 +212,19 @@ void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper& // meshes post processing for (SliceMeshStorage& mesh : storage.meshes) { - processDerivedWallsSkinInfill(mesh, time_keeper, total_layers); + processDerivedWallsSkinInfill(mesh, total_layers); } } -void FffPolygonGenerator::processBasicWallsSkinInfill(SliceMeshStorage& mesh, TimeKeeper& time_keeper, unsigned int total_layers, ProgressStageEstimator& inset_skin_progress_estimate) +void FffPolygonGenerator::processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_idx, size_t total_layers, ProgressStageEstimator& inset_skin_progress_estimate) { + + 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 std::vector walls_vs_skin_timing({22.953, 48.858}); @@ -253,7 +264,66 @@ void FffPolygonGenerator::processBasicWallsSkinInfill(SliceMeshStorage& mesh, Ti Progress::messageProgress(Progress::Stage::INSET_SKIN, progress * 100, 100); } } -void FffPolygonGenerator::processDerivedWallsSkinInfill(SliceMeshStorage& mesh, TimeKeeper& time_keeper, size_t 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 < mesh.layers.size(); layer_idx++) + { + SliceLayer& layer = mesh.layers[layer_idx]; + std::vector new_parts; + + 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]; + + for (SliceLayerPart& part : layer.parts) + { + for (SliceLayerPart& other_part : other_layer.parts) + { + if (!part.boundaryBox.hit(other_part.boundaryBox)) + { + continue; + } + Polygons& infill = other_part.infill_area[0]; + 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(); + for (PolygonsPart& part : new_parts) + { + layer.parts.emplace_back(); + layer.parts.back().outline = part; + } + } + +} + +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 c1c6c36f98..f17df7bcb2 100644 --- a/src/FffPolygonGenerator.h +++ b/src/FffPolygonGenerator.h @@ -70,16 +70,29 @@ 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 timeKeeper Object which keeps track of timings of each stage. + * \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 * \param inset_skin_progress_estimate The progress stage estimate calculator */ - void processBasicWallsSkinInfill(SliceMeshStorage& storage, TimeKeeper& timeKeeper, unsigned int total_layers, ProgressStageEstimator& inset_skin_progress_estimate); + void processBasicWallsSkinInfill(SliceDataStorage& storage, unsigned int mesh_idx, size_t total_layers, ProgressStageEstimator& inset_skin_progress_estimate); + + /*! + * 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 + * 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.