void Weaver::createHorizontalFill(Polygons& lower_top_parts, WeaveLayer& layer, Polygons& layer_above, int z1) { int64_t bridgable_dist = connectionHeight; Polygons& polys_below = lower_top_parts; Polygons& polys_here = layer.supported; Polygons& polys_above = layer_above; { // roofs Polygons to_be_supported = polys_above.offset(bridgable_dist); fillRoofs(polys_here, to_be_supported, -1, layer.z1, layer.roofs); } { // floors Polygons to_be_supported = polys_above.offset(-bridgable_dist); fillFloors(polys_here, to_be_supported, 1, layer.z1, layer.roofs); } {// optimize away doubly printed regions (boundaries of holes in layer etc.) for (WeaveRoofPart& inset : layer.roofs.roof_insets) connections2moves(inset); } }
void Weaver::createHorizontalFill(WeaveLayer& layer, Polygons& layer_above) { const coord_t bridgable_dist = Application::getInstance().current_slice->scene.current_mesh_group->settings.get<coord_t>("wireframe_height"); // Polygons& polys_below = lower_top_parts; Polygons& polys_here = layer.supported; Polygons& polys_above = layer_above; { // roofs Polygons to_be_supported = polys_above.offset(bridgable_dist); fillRoofs(polys_here, to_be_supported, -1, layer.z1, layer.roofs); } { // floors Polygons to_be_supported = polys_above.offset(-bridgable_dist); fillFloors(polys_here, to_be_supported, 1, layer.z1, layer.roofs); } {// optimize away doubly printed regions (boundaries of holes in layer etc.) for (WeaveRoofPart& inset : layer.roofs.roof_insets) connections2moves(inset); } }
void Weaver::weave(PrintObject* object, CommandSocket* commandSocket) { int maxz = object->max().z; int layer_count = (maxz - initial_layer_thickness) / connectionHeight + 1; DEBUG_SHOW(layer_count); std::vector<cura::Slicer*> slicerList; for(Mesh& mesh : object->meshes) { cura::Slicer* slicer = new cura::Slicer(&mesh, initial_layer_thickness, connectionHeight, layer_count, mesh.getSettingBoolean("meshfix_keep_open_polygons"), mesh.getSettingBoolean("meshfix_extensive_stitching")); slicerList.push_back(slicer); } int starting_layer_idx; { // find first non-empty layer for (starting_layer_idx = 0; starting_layer_idx < layer_count; starting_layer_idx++) { Polygons parts; for (cura::Slicer* slicer : slicerList) parts.add(slicer->layers[starting_layer_idx].polygonList); if (parts.size() > 0) break; } if (starting_layer_idx > 0) { logError("First %i layers are empty!\n", starting_layer_idx); } } std::cerr<< "chainifying layers..." << std::endl; { int starting_z = -1; for (cura::Slicer* slicer : slicerList) wireFrame.bottom_outline.add(slicer->layers[starting_layer_idx].polygonList); if (commandSocket) commandSocket->sendPolygons(Inset0Type, 0, wireFrame.bottom_outline); wireFrame.z_bottom = slicerList[0]->layers[starting_layer_idx].z; Point starting_point_in_layer; if (wireFrame.bottom_outline.size() > 0) starting_point_in_layer = (wireFrame.bottom_outline.max() + wireFrame.bottom_outline.min()) / 2; else starting_point_in_layer = (Point(0,0) + object->max() + object->min()) / 2; for (int layer_idx = starting_layer_idx + 1; layer_idx < layer_count; layer_idx++) { logProgress("inset", layer_idx+1, layer_count); // abuse the progress system of the normal mode of CuraEngine Polygons parts1; for (cura::Slicer* slicer : slicerList) parts1.add(slicer->layers[layer_idx].polygonList); Polygons chainified; chainify_polygons(parts1, starting_point_in_layer, chainified, false); if (commandSocket) commandSocket->sendPolygons(Inset0Type, layer_idx - starting_layer_idx, chainified); if (chainified.size() > 0) { if (starting_z == -1) starting_z = slicerList[0]->layers[layer_idx-1].z; wireFrame.layers.emplace_back(); WeaveLayer& layer = wireFrame.layers.back(); layer.z0 = slicerList[0]->layers[layer_idx-1].z - starting_z; layer.z1 = slicerList[0]->layers[layer_idx].z - starting_z; layer.supported = chainified; starting_point_in_layer = layer.supported.back().back(); } } } std::cerr<< "finding horizontal parts..." << std::endl; { Polygons* lower_top_parts = &wireFrame.bottom_outline; for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++) { logProgress("skin", layer_idx+1, wireFrame.layers.size()); // abuse the progress system of the normal mode of CuraEngine WeaveLayer& layer = wireFrame.layers[layer_idx]; Polygons empty; Polygons& layer_above = (layer_idx+1 < wireFrame.layers.size())? wireFrame.layers[layer_idx+1].supported : empty; createHorizontalFill(*lower_top_parts, layer, layer_above, layer.z1); lower_top_parts = &layer.supported; } } // at this point layer.supported still only contains the polygons to be connected // when connecting layers, we further add the supporting polygons created by the roofs std::cerr<< "connecting layers..." << std::endl; { Polygons* lower_top_parts = &wireFrame.bottom_outline; int last_z = wireFrame.z_bottom; for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++) // use top of every layer but the last { WeaveLayer& layer = wireFrame.layers[layer_idx]; connect_polygons(*lower_top_parts, last_z, layer.supported, layer.z1, layer); layer.supported.add(layer.roofs.roof_outlines); lower_top_parts = &layer.supported; last_z = layer.z1; } } { // roofs: WeaveLayer& top_layer = wireFrame.layers.back(); Polygons to_be_supported; // empty for the top layer fillRoofs(top_layer.supported, to_be_supported, -1, top_layer.z1, top_layer.roofs); } { // bottom: Polygons to_be_supported; // is empty for the bottom layer, cause the order of insets doesn't really matter (in a sense everything is to be supported) fillRoofs(wireFrame.bottom_outline, to_be_supported, -1, wireFrame.layers.front().z0, wireFrame.bottom_infill); } }
void Weaver::weave(MeshGroup* meshgroup) { wireFrame.meshgroup = meshgroup; const coord_t maxz = meshgroup->max().z; const Settings& mesh_group_settings = Application::getInstance().current_slice->scene.current_mesh_group->settings; const coord_t initial_layer_thickness = mesh_group_settings.get<coord_t>("layer_height_0"); const coord_t connection_height = mesh_group_settings.get<coord_t>("wireframe_height"); const size_t layer_count = (maxz - initial_layer_thickness) / connection_height + 1; std::vector<AdaptiveLayer> layer_thicknesses; log("Layer count: %i\n", layer_count); std::vector<cura::Slicer*> slicerList; for(Mesh& mesh : meshgroup->meshes) { constexpr bool variable_layer_heights = false; cura::Slicer* slicer = new cura::Slicer(&mesh, connection_height, layer_count, variable_layer_heights, &layer_thicknesses); slicerList.push_back(slicer); } LayerIndex starting_layer_idx; { // find first non-empty layer for (starting_layer_idx = 0; starting_layer_idx < LayerIndex(layer_count); starting_layer_idx++) { Polygons parts; for (cura::Slicer* slicer : slicerList) parts.add(slicer->layers[starting_layer_idx].polygons); if (parts.size() > 0) break; } if (starting_layer_idx > 0) { logWarning("First %i layers are empty!\n", starting_layer_idx); } } log("Chainifying layers...\n"); { int starting_z = -1; for (cura::Slicer* slicer : slicerList) wireFrame.bottom_outline.add(slicer->layers[starting_layer_idx].polygons); Application::getInstance().communication->sendPolygons(PrintFeatureType::OuterWall, wireFrame.bottom_outline, 1, 1, 1); if (slicerList.empty()) //Wait, there is nothing to slice. { wireFrame.z_bottom = 0; } else { wireFrame.z_bottom = slicerList[0]->layers[starting_layer_idx].z; } Point starting_point_in_layer; if (wireFrame.bottom_outline.size() > 0) { starting_point_in_layer = (wireFrame.bottom_outline.max() + wireFrame.bottom_outline.min()) / 2; } else { starting_point_in_layer = (Point(0,0) + meshgroup->max() + meshgroup->min()) / 2; } Progress::messageProgressStage(Progress::Stage::INSET_SKIN, nullptr); for (LayerIndex layer_idx = starting_layer_idx + 1; layer_idx < LayerIndex(layer_count); layer_idx++) { Progress::messageProgress(Progress::Stage::INSET_SKIN, layer_idx+1, layer_count); // abuse the progress system of the normal mode of CuraEngine Polygons parts1; for (cura::Slicer* slicer : slicerList) parts1.add(slicer->layers[layer_idx].polygons); Polygons chainified; chainify_polygons(parts1, starting_point_in_layer, chainified); Application::getInstance().communication->sendPolygons(PrintFeatureType::OuterWall, chainified, 1, 1, 1); if (chainified.size() > 0) { if (starting_z == -1) starting_z = slicerList[0]->layers[layer_idx-1].z; wireFrame.layers.emplace_back(); WeaveLayer& layer = wireFrame.layers.back(); layer.z0 = slicerList[0]->layers[layer_idx-1].z - starting_z; layer.z1 = slicerList[0]->layers[layer_idx].z - starting_z; layer.supported = chainified; starting_point_in_layer = layer.supported.back().back(); } } } log("Finding horizontal parts...\n"); { Progress::messageProgressStage(Progress::Stage::SUPPORT, nullptr); for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++) { Progress::messageProgress(Progress::Stage::SUPPORT, layer_idx+1, wireFrame.layers.size()); // abuse the progress system of the normal mode of CuraEngine WeaveLayer& layer = wireFrame.layers[layer_idx]; Polygons empty; Polygons& layer_above = (layer_idx+1 < wireFrame.layers.size())? wireFrame.layers[layer_idx+1].supported : empty; createHorizontalFill(layer, layer_above); } } // at this point layer.supported still only contains the polygons to be connected // when connecting layers, we further add the supporting polygons created by the roofs log("Connecting layers...\n"); { Polygons* lower_top_parts = &wireFrame.bottom_outline; int last_z = wireFrame.z_bottom; for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++) // use top of every layer but the last { WeaveLayer& layer = wireFrame.layers[layer_idx]; connect_polygons(*lower_top_parts, last_z, layer.supported, layer.z1, layer); layer.supported.add(layer.roofs.roof_outlines); lower_top_parts = &layer.supported; last_z = layer.z1; } } { // roofs: if (!wireFrame.layers.empty()) //If there are no layers, create no roof. { WeaveLayer& top_layer = wireFrame.layers.back(); Polygons to_be_supported; // empty for the top layer fillRoofs(top_layer.supported, to_be_supported, -1, top_layer.z1, top_layer.roofs); } } { // bottom: if (!wireFrame.layers.empty()) //If there are no layers, create no bottom. { Polygons to_be_supported; // is empty for the bottom layer, cause the order of insets doesn't really matter (in a sense everything is to be supported) fillRoofs(wireFrame.bottom_outline, to_be_supported, -1, wireFrame.layers.front().z0, wireFrame.bottom_infill); } } }
void Weaver::weave(MeshGroup* meshgroup) { wireFrame.meshgroup = meshgroup; int maxz = meshgroup->max().z; int layer_count = (maxz - initial_layer_thickness) / connectionHeight + 1; std::cerr << "Layer count: " << layer_count << "\n"; std::vector<cura::Slicer*> slicerList; for(Mesh& mesh : meshgroup->meshes) { cura::Slicer* slicer = new cura::Slicer(&mesh, initial_layer_thickness, connectionHeight, layer_count, mesh.getSettingBoolean("meshfix_keep_open_polygons"), mesh.getSettingBoolean("meshfix_extensive_stitching")); slicerList.push_back(slicer); } int starting_layer_idx; { // find first non-empty layer for (starting_layer_idx = 0; starting_layer_idx < layer_count; starting_layer_idx++) { Polygons parts; for (cura::Slicer* slicer : slicerList) parts.add(slicer->layers[starting_layer_idx].polygons); if (parts.size() > 0) break; } if (starting_layer_idx > 0) { logWarning("First %i layers are empty!\n", starting_layer_idx); } } std::cerr<< "chainifying layers..." << std::endl; { int starting_z = -1; for (cura::Slicer* slicer : slicerList) wireFrame.bottom_outline.add(slicer->layers[starting_layer_idx].polygons); CommandSocket::sendPolygons(PrintFeatureType::OuterWall, /*0,*/ wireFrame.bottom_outline, 1); if (slicerList.empty()) //Wait, there is nothing to slice. { wireFrame.z_bottom = 0; } else { wireFrame.z_bottom = slicerList[0]->layers[starting_layer_idx].z; } Point starting_point_in_layer; if (wireFrame.bottom_outline.size() > 0) starting_point_in_layer = (wireFrame.bottom_outline.max() + wireFrame.bottom_outline.min()) / 2; else starting_point_in_layer = (Point(0,0) + meshgroup->max() + meshgroup->min()) / 2; Progress::messageProgressStage(Progress::Stage::INSET_SKIN, nullptr); for (int layer_idx = starting_layer_idx + 1; layer_idx < layer_count; layer_idx++) { Progress::messageProgress(Progress::Stage::INSET_SKIN, layer_idx+1, layer_count); // abuse the progress system of the normal mode of CuraEngine Polygons parts1; for (cura::Slicer* slicer : slicerList) parts1.add(slicer->layers[layer_idx].polygons); Polygons chainified; chainify_polygons(parts1, starting_point_in_layer, chainified, false); CommandSocket::sendPolygons(PrintFeatureType::OuterWall, /*layer_idx - starting_layer_idx,*/ chainified, 1); if (chainified.size() > 0) { if (starting_z == -1) starting_z = slicerList[0]->layers[layer_idx-1].z; wireFrame.layers.emplace_back(); WeaveLayer& layer = wireFrame.layers.back(); layer.z0 = slicerList[0]->layers[layer_idx-1].z - starting_z; layer.z1 = slicerList[0]->layers[layer_idx].z - starting_z; layer.supported = chainified; starting_point_in_layer = layer.supported.back().back(); } } } std::cerr<< "finding horizontal parts..." << std::endl; { Polygons* lower_top_parts = &wireFrame.bottom_outline; Progress::messageProgressStage(Progress::Stage::SUPPORT, nullptr); for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++) { Progress::messageProgress(Progress::Stage::SUPPORT, layer_idx+1, wireFrame.layers.size()); // abuse the progress system of the normal mode of CuraEngine WeaveLayer& layer = wireFrame.layers[layer_idx]; Polygons empty; Polygons& layer_above = (layer_idx+1 < wireFrame.layers.size())? wireFrame.layers[layer_idx+1].supported : empty; createHorizontalFill(*lower_top_parts, layer, layer_above, layer.z1); lower_top_parts = &layer.supported; } } // at this point layer.supported still only contains the polygons to be connected // when connecting layers, we further add the supporting polygons created by the roofs std::cerr<< "connecting layers..." << std::endl; { Polygons* lower_top_parts = &wireFrame.bottom_outline; int last_z = wireFrame.z_bottom; for (unsigned int layer_idx = 0; layer_idx < wireFrame.layers.size(); layer_idx++) // use top of every layer but the last { WeaveLayer& layer = wireFrame.layers[layer_idx]; connect_polygons(*lower_top_parts, last_z, layer.supported, layer.z1, layer); layer.supported.add(layer.roofs.roof_outlines); lower_top_parts = &layer.supported; last_z = layer.z1; } } { // roofs: if (!wireFrame.layers.empty()) //If there are no layers, create no roof. { WeaveLayer& top_layer = wireFrame.layers.back(); Polygons to_be_supported; // empty for the top layer fillRoofs(top_layer.supported, to_be_supported, -1, top_layer.z1, top_layer.roofs); } } { // bottom: if (!wireFrame.layers.empty()) //If there are no layers, create no bottom. { Polygons to_be_supported; // is empty for the bottom layer, cause the order of insets doesn't really matter (in a sense everything is to be supported) fillRoofs(wireFrame.bottom_outline, to_be_supported, -1, wireFrame.layers.front().z0, wireFrame.bottom_infill); } } }