1 """
2 Multiplies the 3D model into an array of copies arranged in a table.
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, euclidean
15 from fabmetheus_utilities.vector3 import Vector3
16 import copy
17 import logging
18
19 logger = logging.getLogger(__name__)
20 name = 'multiply'
21
28
30 'A class to multiply a skein of extrusions.'
32 self.slicedModel = slicedModel
33 self.isExtrusionActive = False
34 self.layerIndex = 0
35 self.layerLines = []
36 self.lineIndex = 0
37 self.lines = None
38 self.oldLocation = None
39 self.rowIndex = 0
40 self.shouldAccumulate = True
41
42 self.centerX = config.getfloat(name, 'center.x')
43 self.centerY = config.getfloat(name, 'center.y')
44 self.numberOfColumns = config.getint(name, 'columns')
45 self.numberOfRows = config.getint(name, 'rows')
46 self.reverseSequenceEveryOddLayer = config.getboolean(name, 'sequence.reverse.odd.layers')
47 self.separationOverPerimeterWidth = config.getfloat(name, 'separation.over.perimeter.width')
48 self.extrusionWidth = config.getfloat('carve', 'extrusion.width')
49 self.centerOffset = complex(self.centerX, self.centerY)
50 cornerMaximumComplex = self.slicedModel.carvingCornerMaximum.dropAxis()
51 cornerMinimumComplex = self.slicedModel.carvingCornerMinimum.dropAxis()
52
53 self.extent = cornerMaximumComplex - cornerMinimumComplex
54 self.shapeCenter = 0.5 * (cornerMaximumComplex + cornerMinimumComplex)
55 self.separation = self.separationOverPerimeterWidth * abs(self.extrusionWidth)
56 self.extentPlusSeparation = self.extent + complex(self.separation, self.separation)
57 columnsMinusOne = self.numberOfColumns - 1
58 rowsMinusOne = self.numberOfRows - 1
59 self.arrayExtent = complex(self.extentPlusSeparation.real * columnsMinusOne, self.extentPlusSeparation.imag * rowsMinusOne)
60 self.arrayCenter = 0.5 * self.arrayExtent
61
63 'Multiply the 3D model.'
64
65 elementOffsets = self.getElementOffsets()
66 elementOffsetsCount = len(elementOffsets)
67 self.slicedModel.elementOffsets = elementOffsets
68
69 for key in self.slicedModel.layers.iterkeys():
70 layer = self.slicedModel.layers[key]
71 offsetNestedRings = []
72 for nestedRing in layer.nestedRings:
73 for (index,elementOffset) in enumerate(elementOffsets):
74 offsetNestedRing = copy.deepcopy(nestedRing)
75 offsetNestedRing.offset(elementOffset)
76 offsetNestedRings.append(offsetNestedRing)
77 layer.nestedRings = offsetNestedRings
78
80 'Returns a list of coordinates for the center of each copied layer'
81 elementOffsets = []
82 offset = self.centerOffset - self.arrayCenter - self.shapeCenter
83 for rowIndex in xrange(self.numberOfRows):
84 yRowOffset = float(rowIndex) * self.extentPlusSeparation.imag
85
86
87 for columnIndex in xrange(self.numberOfColumns):
88 xColumnOffset = float(columnIndex) * self.extentPlusSeparation.real
89 if self.rowIndex % 2 == 1:
90 xColumnOffset = self.arrayExtent.real - xColumnOffset
91 elementOffsets.append(complex(offset.real + xColumnOffset, offset.imag + yRowOffset))
92 self.rowIndex += 1
93 return elementOffsets
94