-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathcreate_box.py
210 lines (152 loc) · 7.52 KB
/
create_box.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
'''Creates the wires and part objects'''
import FreeCAD
import Mesh
import lithophane_utils
from utils.resource_utils import iconPath
from boolean_mesh import BooleanMesh
from boolean_mesh import ViewProviderBooleanMesh
from create_geometry_base import CreateGeometryBase
class ProcessingParameters(object):
def __init__(self, image):
self.image = image
self.box = None
self.imagePlane = None
self.blockBase = None
self.bottomRectangle = None
class BoxLithophane(BooleanMesh):
def __init__(self, obj):
super().__init__(obj)
def getDescription(self):
return 'CreateBox'
def getIcon(self):
return iconPath('CreateBox.svg')
def getBaseProcessingSteps(self, obj):
return [('Image Plane', self.makeImagePlane),
('Image Base', self.makeBlockBase),
('Bottom Plane', self.createBottomRectangle),
('Merge Meshes', self.mergeMeshes),
('Optimize Mesh', self.optimizeMesh)]
def extractBaseMesh(self, obj, processingParameters):
return processingParameters.box
def makeImagePlane(self, obj, image):
processingParameters = ProcessingParameters(image)
lines = processingParameters.image.lines
facets = []
for lineNumber, actualLine in enumerate(lines):
# No need to perform operations on the last line at all
if lineNumber == len(lines) - 1:
break
nextLine = lines[lineNumber + 1]
for rowNumber, actualPoint in enumerate(actualLine):
# No need to perform operations on the last row
if rowNumber == len(actualLine) - 1:
break
bottomLeft = actualPoint
bottomRight = actualLine[rowNumber + 1] # next row same line
topRight = nextLine[rowNumber + 1] # next row next line
topLeft = nextLine[rowNumber] # same row next line
facets.extend([bottomLeft, bottomRight, topLeft])
facets.extend([bottomRight, topRight, topLeft])
processingParameters.imagePlane = Mesh.Mesh(facets)
return processingParameters
def makeBlockBase(self, obj, processingParameters):
lines = processingParameters.image.lines
facets = []
# add the bottom rectangle
# bottomLeftCorner = lithophane_utils.vectorAtGround(lines[0][0])
# bottomRightCorner = lithophane_utils.vectorAtGround(lines[0][-1])
# topRightCorner = lithophane_utils.vectorAtGround(lines[-1][-1])
# topLeftCorner = lithophane_utils.vectorAtGround(lines[-1][0])
# facets.extend([bottomLeftCorner, topLeftCorner, bottomRightCorner])
# facets.extend([bottomRightCorner, topLeftCorner, topRightCorner])
for lineNumber, actualLine in enumerate(lines):
# Need to process all the points on the first and last line
if lineNumber == 0 or lineNumber == len(lines) - 1:
for rowNumber, actualPoint in enumerate(actualLine):
# No need to perform operations on the last row
if rowNumber == len(actualLine) - 1:
break
nextPoint = actualLine[rowNumber + 1]
bottomLeft = lithophane_utils.vectorAtGround(actualPoint)
bottomRight = lithophane_utils.vectorAtGround(nextPoint)
topRight = nextPoint
topLeft = actualPoint
facets.extend([bottomLeft, bottomRight, topLeft])
facets.extend([bottomRight, topRight, topLeft])
# Only use the first and last point for all other rows
if lineNumber > 0:
previousLine = lines[lineNumber - 1]
firstPoint = actualLine[0]
prevFirstPoint = previousLine[0]
lastPoint = actualLine[-1]
prevLastPoint = previousLine[-1]
bottomLeft1 = lithophane_utils.vectorAtGround(firstPoint)
bottomRight1 = lithophane_utils.vectorAtGround(prevFirstPoint)
topRight1 = prevFirstPoint
topLeft1 = firstPoint
facets.extend([bottomRight1, topRight1, bottomLeft1])
facets.extend([topRight1, topLeft1, bottomLeft1])
bottomLeft2 = lithophane_utils.vectorAtGround(prevLastPoint)
bottomRight2 = lithophane_utils.vectorAtGround(lastPoint)
topRight2 = lastPoint
topLeft2 = prevLastPoint
facets.extend([bottomLeft2, bottomRight2, topLeft2])
facets.extend([bottomRight2, topRight2, topLeft2])
processingParameters.blockBase = Mesh.Mesh(facets)
return processingParameters
def createBottomRectangle(self, obj, processingParameters):
lines = processingParameters.image.lines
facets = []
for lineNumber, actualLine in enumerate(lines):
# No need to perform operations on the last line at all
if lineNumber == len(lines) - 1:
break
nextLine = lines[lineNumber + 1]
for rowNumber, actualPoint in enumerate(actualLine):
# No need to perform operations on the last row
if rowNumber == len(actualLine) - 1:
break
bottomLeft = lithophane_utils.vectorAtGround(actualPoint)
bottomRight = lithophane_utils.vectorAtGround(
actualLine[rowNumber + 1]) # next row same line
topRight = lithophane_utils.vectorAtGround(
nextLine[rowNumber + 1]) # next row next line
topLeft = lithophane_utils.vectorAtGround(
nextLine[rowNumber]) # same row next line
facets.extend([bottomLeft, bottomRight, topLeft])
facets.extend([bottomRight, topRight, topLeft])
processingParameters.bottomRectangle = Mesh.Mesh(facets)
return processingParameters
def mergeMeshes(self, obj, processingParameters):
processingParameters.box = Mesh.Mesh()
processingParameters.box.addMesh(processingParameters.imagePlane)
processingParameters.box.addMesh(processingParameters.blockBase)
processingParameters.box.addMesh(processingParameters.bottomRectangle)
return processingParameters
def optimizeMesh(self, obj, processingParameters):
processingParameters.box.removeDuplicatedPoints()
processingParameters.box.harmonizeNormals()
return processingParameters
class CreateGeometryCommand(CreateGeometryBase):
toolbarName = 'Image_Tools'
commandName = 'Create_Box'
def GetResources(self):
return {'MenuText': "Create Box",
'ToolTip': "Creates the geometry of the selected Lithophane Image in the shape of a box",
'Pixmap': iconPath('CreateBox.svg')}
def createGeometryInstance(self, documentObject, imageLabel):
obj = FreeCAD.ActiveDocument.addObject(
"App::FeaturePython", imageLabel + '_Mesh')
BoxLithophane(obj)
ViewProviderBooleanMesh(obj.ViewObject)
obj.LithophaneImage = documentObject
if __name__ == "__main__":
command = CreateGeometryCommand()
if command.IsActive():
command.Activated()
else:
import utils.qtutils as qtutils
qtutils.showInfo("No open Document", "There is no open document")
else:
import toolbars
toolbars.toolbarManager.registerCommand(CreateGeometryCommand())