1 """
2 Carve is a script to carve a shape into svg slice layers. It creates the perimeter contours
3
4 Credits:
5 Original Author: Enrique Perez (http://skeinforge.com)
6 Contributors: Please see the documentation in Skeinforge
7 Modifed as SFACT: Ahmet Cem Turan (github.com/ahmetcemturan/SFACT)
8
9 License:
10 GNU Affero General Public License http://www.gnu.org/licenses/agpl.html
11 """
12
13 from config import config
14 from fabmetheus_utilities import archive, svg_writer, vector3
15 import logging
16 import math
17
18 name = 'carve'
19 logger = logging.getLogger(name)
20
21
33
35 "A class to carve a 3D model."
36
38 'Initialize'
39 self.slicedModel = slicedModel
40 self.layerHeight = config.getfloat(name, 'layer.height')
41 self.extrusionWidth = config.getfloat(name, 'extrusion.width')
42 self.infillBridgeDirection = config.getboolean(name, 'infill.bridge.direction')
43 self.importCoarsenessRatio = config.getfloat(name, 'import.coarseness.ratio')
44 self.correctMesh = config.getboolean(name, 'mesh.correct')
45 self.decimalPlaces = config.getint('general', 'decimal.places')
46 self.layerPrintFrom = config.getint(name, 'layer.print.from')
47 self.layerPrintTo = config.getint(name, 'layer.print.to')
48
49 - def carve(self, carving):
50 "Parse 3D model file and store the carved slicedModel."
51
52 carving.setCarveInfillInDirectionOfBridge(self.infillBridgeDirection)
53 carving.setCarveLayerThickness(self.layerHeight)
54 importRadius = 0.5 * self.importCoarsenessRatio * abs(self.extrusionWidth)
55 carving.setCarveImportRadius(max(importRadius, 0.001 * self.layerHeight))
56 carving.setCarveIsCorrectMesh(self.correctMesh)
57
58 rotatedLoopLayers = carving.getCarveRotatedBoundaryLayers()
59
60 if len(rotatedLoopLayers) < 1:
61 logger.warning('There are no slices for the model, this could be because the model is too small for the Layer Thickness.')
62 return
63
64 self.slicedModel.carvingCornerMaximum = carving.getCarveCornerMaximum()
65 self.slicedModel.carvingCornerMinimum = carving.getCarveCornerMinimum()
66
67 toBePrintedLayers = rotatedLoopLayers[self.layerPrintFrom : self.layerPrintTo]
68 for toBePrintedLayer in toBePrintedLayers:
69 sortedLoops = []
70 for toBePrintedLayerLoop in toBePrintedLayer.loops:
71 lowerLeftPoint = self.getLowerLeftCorner(toBePrintedLayerLoop)
72 lowerLeftIndex = toBePrintedLayerLoop.index(lowerLeftPoint)
73 sortedLoops.append(toBePrintedLayerLoop[lowerLeftIndex:] + toBePrintedLayerLoop[:lowerLeftIndex])
74 toBePrintedLayer.loops = sortedLoops
75
76 self.slicedModel.rotatedLoopLayers = toBePrintedLayers
77
78 if config.getboolean(name, 'debug'):
79 filename = self.slicedModel.runtimeParameters.inputFilename
80 svgFilename = filename[: filename.rfind('.')] + '.svg'
81 svgWriter = svg_writer.SVGWriter(
82 True,
83 self.slicedModel.carvingCornerMaximum,
84 self.slicedModel.carvingCornerMinimum,
85 self.slicedModel.runtimeParameters.decimalPlaces,
86 self.slicedModel.runtimeParameters.layerHeight,
87 self.slicedModel.runtimeParameters.layerThickness)
88 archive.writeFileText(svgFilename , svgWriter.getReplacedSVGTemplate(self.slicedModel.runtimeParameters.inputFilename, '', self.slicedModel.rotatedLoopLayers))
89 logger.info("Carving SVG written to %s", svgFilename)
90
92 'Get the lower left corner point from a set of points.'
93 lowerLeftCorner = None
94 lowestRealPlusImaginary = 987654321.0
95 for point in points:
96 realPlusImaginary = point.real + point.imag
97 if realPlusImaginary < lowestRealPlusImaginary:
98 lowestRealPlusImaginary = realPlusImaginary
99 lowerLeftCorner = point
100 return lowerLeftCorner
101