private void processSliceData(SliceDataStorage storage) { if (config.continuousSpiralOuterPerimeter) { config.numberOfTopLayers = 0; config.infillPercent = 0; } MultiVolumes.RemoveVolumesIntersections(storage.volumes); MultiVolumes.OverlapMultipleVolumesSlightly(storage.volumes, config.multiVolumeOverlapPercent); #if False LayerPart.dumpLayerparts(storage, "output.html"); #endif int totalLayers = storage.volumes[0].layers.Count; #if DEBUG for (int volumeIndex = 1; volumeIndex < storage.volumes.Count; volumeIndex++) { if (totalLayers != storage.volumes[volumeIndex].layers.Count) { throw new Exception("All the valumes must have the same number of layers (they just can have empty layers)."); } } #endif for (int layerIndex = 0; layerIndex < totalLayers; layerIndex++) { for (int volumeIndex = 0; volumeIndex < storage.volumes.Count; volumeIndex++) { if (MatterSlice.Canceled) { return; } int insetCount = config.numberOfPerimeters; if (config.continuousSpiralOuterPerimeter && (int)(layerIndex) < config.numberOfBottomLayers && layerIndex % 2 == 1) { //Add extra insets every 2 layers when spiralizing, this makes bottoms of cups watertight. insetCount += 5; } SliceLayer layer = storage.volumes[volumeIndex].layers[layerIndex]; int extrusionWidth = config.extrusionWidth_um; if (layerIndex == 0) { extrusionWidth = config.firstLayerExtrusionWidth_um; } Inset.generateInsets(layer, extrusionWidth, insetCount); } LogOutput.Log("Creating Insets {0}/{1}\n".FormatWith(layerIndex + 1, totalLayers)); } if (config.wipeShieldDistanceFromShapes_um > 0) { CreateWipeShields(storage, totalLayers); } LogOutput.Log("Generated inset in {0:0.0}s\n".FormatWith(timeKeeper.Elapsed.Seconds)); timeKeeper.Restart(); for (int layerIndex = 0; layerIndex < totalLayers; layerIndex++) { if (MatterSlice.Canceled) { return; } //Only generate bottom and top layers and infill for the first X layers when spiralize is choosen. if (!config.continuousSpiralOuterPerimeter || (int)(layerIndex) < config.numberOfBottomLayers) { for (int volumeIndex = 0; volumeIndex < storage.volumes.Count; volumeIndex++) { int extrusionWidth = config.extrusionWidth_um; if (layerIndex == 0) { extrusionWidth = config.firstLayerExtrusionWidth_um; } TopsAndBottoms.GenerateTopAndBottom(layerIndex, storage.volumes[volumeIndex], extrusionWidth, config.numberOfBottomLayers, config.numberOfTopLayers); } } LogOutput.Log("Creating Top & Bottom Layers {0}/{1}\n".FormatWith(layerIndex + 1, totalLayers)); } LogOutput.Log("Generated top bottom layers in {0:0.0}s\n".FormatWith(timeKeeper.Elapsed.Seconds)); timeKeeper.Restart(); if (config.wipeTowerSize_um > 0) { Polygon p = new Polygon(); storage.wipeTower.Add(p); p.Add(new IntPoint(storage.modelMin.x - 3000, storage.modelMax.y + 3000)); p.Add(new IntPoint(storage.modelMin.x - 3000, storage.modelMax.y + 3000 + config.wipeTowerSize_um)); p.Add(new IntPoint(storage.modelMin.x - 3000 - config.wipeTowerSize_um, storage.modelMax.y + 3000 + config.wipeTowerSize_um)); p.Add(new IntPoint(storage.modelMin.x - 3000 - config.wipeTowerSize_um, storage.modelMax.y + 3000)); storage.wipePoint = new IntPoint(storage.modelMin.x - 3000 - config.wipeTowerSize_um / 2, storage.modelMax.y + 3000 + config.wipeTowerSize_um / 2); } if (config.enableRaft) { Raft.GenerateRaftOutlines(storage, config.raftExtraDistanceAroundPart_um, config); Skirt.generateSkirt(storage, config.skirtDistance_um + config.raftBaseLineSpacing_um, config.raftBaseLineSpacing_um, config.numberOfSkirtLoops, config.skirtMinLength_um, config.raftBaseThickness_um, config); } else { Skirt.generateSkirt(storage, config.skirtDistance_um, config.firstLayerExtrusionWidth_um, config.numberOfSkirtLoops, config.skirtMinLength_um, config.firstLayerThickness_um, config); } }