cqfantasy 2.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. cqfantasy/arch/BasicArch.py +117 -0
  2. cqfantasy/arch/StoneArch.py +267 -0
  3. cqfantasy/arch/__init__.py +3 -0
  4. cqfantasy/arch/arch.py +32 -0
  5. cqfantasy/corner/AshlarCorner.py +155 -0
  6. cqfantasy/corner/__init__.py +1 -0
  7. cqfantasy/door/ArchDoor.py +73 -0
  8. cqfantasy/door/VDoor.py +133 -0
  9. cqfantasy/door/__init__.py +2 -0
  10. cqfantasy/fence/BarGreebled.py +110 -0
  11. cqfantasy/fence/BaseBrick.py +115 -0
  12. cqfantasy/fence/BasicBarDecoration.py +133 -0
  13. cqfantasy/fence/BasicBase.py +68 -0
  14. cqfantasy/fence/BasicFence.py +113 -0
  15. cqfantasy/fence/BasicPillar.py +68 -0
  16. cqfantasy/fence/PillarBrick.py +151 -0
  17. cqfantasy/fence/__init__.py +7 -0
  18. cqfantasy/fireplace/Chimney.py +78 -0
  19. cqfantasy/fireplace/ChimneyTiled.py +147 -0
  20. cqfantasy/fireplace/FireBox.py +86 -0
  21. cqfantasy/fireplace/FireBoxTiled.py +159 -0
  22. cqfantasy/fireplace/FireTop.py +108 -0
  23. cqfantasy/fireplace/Fireplace.py +175 -0
  24. cqfantasy/fireplace/FireplaceTiled.py +30 -0
  25. cqfantasy/fireplace/Hearth.py +71 -0
  26. cqfantasy/fireplace/HearthTiled.py +111 -0
  27. cqfantasy/fireplace/HearthTiledTwo.py +126 -0
  28. cqfantasy/fireplace/__init__.py +10 -0
  29. cqfantasy/house/Body.py +73 -0
  30. cqfantasy/house/BodyGreebled.py +257 -0
  31. cqfantasy/house/House.py +444 -0
  32. cqfantasy/house/PyramidRoof.py +150 -0
  33. cqfantasy/house/PyramidRoofShingle.py +94 -0
  34. cqfantasy/house/Roof.py +171 -0
  35. cqfantasy/house/ShingleRoof.py +93 -0
  36. cqfantasy/house/SnowyRoof.py +159 -0
  37. cqfantasy/house/StuccoBrickBody.py +153 -0
  38. cqfantasy/house/TileGenerator.py +99 -0
  39. cqfantasy/house/TudorBody.py +145 -0
  40. cqfantasy/house/TudorSplitBody.py +270 -0
  41. cqfantasy/house/__init__.py +12 -0
  42. cqfantasy/house_wall/LogWall.py +99 -0
  43. cqfantasy/house_wall/RubbleWall.py +118 -0
  44. cqfantasy/house_wall/WallSplit.py +83 -0
  45. cqfantasy/house_wall/WallStuccoBrick.py +102 -0
  46. cqfantasy/house_wall/WallTudor.py +110 -0
  47. cqfantasy/house_wall/WallTudorPaneling.py +181 -0
  48. cqfantasy/house_wall/__init__.py +7 -0
  49. cqfantasy/house_wall/tudor_wall.py +162 -0
  50. cqfantasy/tower/BaseSection.py +291 -0
  51. cqfantasy/tower/FrameWindow.py +68 -0
  52. cqfantasy/tower/LatticeWindow.py +85 -0
  53. cqfantasy/tower/RoundBlockAltGenerator.py +111 -0
  54. cqfantasy/tower/RoundBlockGenerator.py +191 -0
  55. cqfantasy/tower/RoundBlockUnevenGenerator.py +79 -0
  56. cqfantasy/tower/RoundBlockUnevenStuccoGenerator.py +190 -0
  57. cqfantasy/tower/TileGenerator.py +101 -0
  58. cqfantasy/tower/Tower.py +67 -0
  59. cqfantasy/tower/TowerBase.py +149 -0
  60. cqfantasy/tower/TowerDoor.py +116 -0
  61. cqfantasy/tower/TowerMid.py +133 -0
  62. cqfantasy/tower/TowerTop.py +186 -0
  63. cqfantasy/tower/TowerWindow.py +125 -0
  64. cqfantasy/tower/__init__.py +19 -0
  65. cqfantasy/tower/cut_cylinder.py +29 -0
  66. cqfantasy/tower/magnets.py +28 -0
  67. cqfantasy/wall/TileGenerator.py +96 -0
  68. cqfantasy/wall/__init__.py +1 -0
  69. cqfantasy/watchtower/TowerBase.py +46 -0
  70. cqfantasy/watchtower/TowerBody.py +46 -0
  71. cqfantasy/watchtower/TowerBodyreebled.py +219 -0
  72. cqfantasy/watchtower/TowerDoor.py +42 -0
  73. cqfantasy/watchtower/TowerTop.py +46 -0
  74. cqfantasy/watchtower/TowerTopGreebled.py +134 -0
  75. cqfantasy/watchtower/WatchTower.py +80 -0
  76. cqfantasy/watchtower/__init__.py +7 -0
  77. cqfantasy/window/CasementWindow.py +108 -0
  78. cqfantasy/window/__init__.py +1 -0
  79. cqfantasy-2.3.0.dist-info/METADATA +31 -0
  80. cqfantasy-2.3.0.dist-info/RECORD +83 -0
  81. cqfantasy-2.3.0.dist-info/WHEEL +5 -0
  82. cqfantasy-2.3.0.dist-info/licenses/LICENSE +201 -0
  83. cqfantasy-2.3.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,117 @@
1
+ # Copyright 2025 James Adams
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import math
16
+ import cadquery as cq
17
+ from cadqueryhelper import Base
18
+ from . import arch
19
+
20
+
21
+ class BasicArch(Base):
22
+ def __init__(self):
23
+ super().__init__()
24
+
25
+ # parameters
26
+ self.length:float = 30
27
+ self.width:float = 5
28
+ self.height:float = 75
29
+ self.outside_margin:float = 10
30
+ self.inside_margin:float = 5
31
+
32
+ # shapes
33
+ self.outline:cq.Workplane|None = None
34
+ self.outside_outline:cq.Workplane|None = None
35
+ self.inside_outline:cq.Workplane|None = None
36
+ self.column_outline:cq.Workplane|None = None
37
+
38
+ def calculate_column_height(self) -> float:
39
+ return (self.height)-self.length/2
40
+
41
+ def calculate_perimeter(self) -> float:
42
+ perimeter = 2*math.pi*self.length/2
43
+ return perimeter
44
+
45
+ def calculate_inside_perimeter(self) -> float:
46
+ perimeter = 2*math.pi*(self.length-self.inside_margin*2)/2
47
+ return perimeter
48
+
49
+ def calculate_outside_perimeter(self) -> float:
50
+ perimeter = 2*math.pi*(self.length+self.outside_margin*2)/2
51
+ return perimeter
52
+
53
+
54
+ def make_outline(self):
55
+ self.outline = arch(
56
+ self.length,
57
+ self.width,
58
+ self.height
59
+ )
60
+
61
+ def make_outside_outline(self):
62
+ self.outside_outline = arch(
63
+ self.length+self.outside_margin*2,
64
+ self.width,
65
+ self.height+self.outside_margin
66
+ ).translate((0,0,self.outside_margin/2))
67
+
68
+ def make_inside_outline(self):
69
+ self.inside_outline = arch(
70
+ self.length-self.inside_margin*2,
71
+ self.width,
72
+ self.height-self.inside_margin
73
+ ).translate((0,0,-self.inside_margin/2))
74
+
75
+ def make_column_outline(self):
76
+ height = self.calculate_column_height()
77
+ outline = (
78
+ cq.Workplane("XY")
79
+ .box(
80
+ self.length+self.outside_margin*2,
81
+ self.width,
82
+ height
83
+ )
84
+ .translate((0,0,-self.height/2+height/2))
85
+ )
86
+ self.column_outline = outline
87
+
88
+ def make(self, parent=None):
89
+ super().make(parent)
90
+ self.make_outline()
91
+ self.make_outside_outline()
92
+ self.make_inside_outline()
93
+ self.make_column_outline()
94
+
95
+ def build(self) -> cq.Workplane:
96
+ super().build()
97
+ scene = (
98
+ cq.Workplane("XY")
99
+ )
100
+
101
+ if self.outline:
102
+ scene = scene.add(self.outline)
103
+
104
+ if self.outside_outline:
105
+ scene = scene.add(self.outside_outline)
106
+
107
+ if self.inside_outline:
108
+ scene = scene.cut(self.inside_outline)
109
+
110
+ return scene
111
+
112
+ def build_outline(self) -> cq.Workplane:
113
+ scene = cq.Workplane("XY")
114
+
115
+ if self.outline:
116
+ scene = scene.union(self.outline)
117
+ return scene
@@ -0,0 +1,267 @@
1
+ # Copyright 2025 James Adams
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import cadquery as cq
16
+ from . import BasicArch, arch
17
+
18
+ class StoneArch(BasicArch):
19
+ def __init__(self):
20
+ super().__init__()
21
+
22
+ # parameters
23
+ self.stone_count:int = 8
24
+ self.stone_arch_count:int = 4
25
+
26
+ self.stone_margin:float = .5
27
+ self.width_margin:float = .5
28
+ self.stone_modulus:int = 2
29
+ self.outside_stone_position:int = 0
30
+ self.stone_arch_modulus:int = 2
31
+ self.outside_stone_arch_position:int = 1
32
+
33
+ # shapes
34
+ self.inside_stone:cq.Workplane|None = None
35
+ self.outside_stone:cq.Workplane|None = None
36
+ self.column_stones:cq.Workplane|None = None
37
+
38
+ self.inside_arch_stone:cq.Workplane|None = None
39
+ self.outside_arch_stone:cq.Workplane|None = None
40
+ self.arch_stones:cq.Workplane|None = None
41
+
42
+ self.margin_outline:cq.Workplane|None = None
43
+ self.outside_margin_outline:cq.Workplane|None = None
44
+ self.inside_margin_outline:cq.Workplane|None = None
45
+
46
+ def calculate_stone_height(self) -> float:
47
+ column_height = self.calculate_column_height()
48
+ stone_height = column_height / self.stone_count
49
+ return stone_height
50
+
51
+ def calculate_stone_margin_height(self) -> float:
52
+ stone_height = self.calculate_stone_height()
53
+ return stone_height - self.stone_margin
54
+
55
+ def calculate_arch_stone_height(self) -> float:
56
+ perimeter = self.calculate_perimeter() / 2
57
+ height = perimeter / self.stone_arch_count
58
+ return height
59
+
60
+ def calculate_arch_stone_margin_height(self) -> float:
61
+ height = self.calculate_arch_stone_height()
62
+ return height - self.stone_margin
63
+
64
+ def calculate_inside_arch_stone_height(self) -> float:
65
+ perimeter = self.calculate_inside_perimeter() / 2
66
+ height = perimeter / self.stone_arch_count
67
+ return height
68
+
69
+ def calculate_inside_arch_stone_margin_height(self) -> float:
70
+ height = self.calculate_inside_arch_stone_height()
71
+ return height - self.stone_margin
72
+
73
+ def calculate_outside_arch_stone_height(self) -> float:
74
+ perimeter = self.calculate_outside_perimeter() / 2
75
+ height = perimeter / self.stone_arch_count
76
+ return height
77
+
78
+ def calculate_outside_arch_stone_margin_height(self) -> float:
79
+ height = self.calculate_outside_arch_stone_height()
80
+ return height - self.stone_margin
81
+
82
+ def make_inside_stone(self):
83
+ stone_height = self.calculate_stone_margin_height()
84
+ self.inside_stone = cq.Workplane("XY").box(
85
+ self.inside_margin,
86
+ self.width,
87
+ stone_height
88
+ ).rotate((1,0,0),(0,0,0),90)
89
+
90
+ def make_outside_stone(self):
91
+ stone_height = self.calculate_stone_margin_height()
92
+ length = self.inside_margin+self.outside_margin
93
+ self.outside_stone = cq.Workplane("XY").box(
94
+ length,
95
+ self.width,
96
+ stone_height
97
+ ).translate((-length/2+self.inside_margin/2,0,0)).rotate((1,0,0),(0,0,0),90)
98
+
99
+ def make_column_stones(self):
100
+ def add_stone():
101
+ count = 0
102
+ def add_stone_count(loc:cq.Location) -> cq.Shape:
103
+ nonlocal count
104
+ stone = self.inside_stone
105
+
106
+ if count % self.stone_modulus == self.outside_stone_position and self.outside_stone:
107
+ stone = (
108
+ self.outside_stone
109
+ .translate((
110
+ 0,
111
+ 0,
112
+ 0)
113
+ )
114
+ )
115
+ count += 1
116
+ #log(f'test {count}')
117
+ return stone.val().located(loc) #type:ignore
118
+ return add_stone_count
119
+
120
+ stone_height = self.calculate_stone_height()
121
+
122
+ stones = (
123
+ cq.Workplane("XY")
124
+ .rarray(
125
+ xSpacing = stone_height,
126
+ ySpacing = stone_height,
127
+ xCount = 1,
128
+ yCount= self.stone_count,
129
+ center = True)
130
+ .eachpoint(add_stone())
131
+ ).rotate((1,0,0),(0,0,0),90)
132
+
133
+ self.column_stones = stones
134
+
135
+ def make_margin_outline(self):
136
+ self.margin_outline = arch(
137
+ self.length-self.width_margin,
138
+ self.width-self.width_margin*2,
139
+ self.height
140
+ )
141
+
142
+ def make_outside_margin_outline(self):
143
+ self.outside_margin_outline = arch(
144
+ self.length+self.outside_margin*2,
145
+ self.width-self.width_margin*2,
146
+ self.height+self.outside_margin
147
+ ).translate((0,0,self.outside_margin/2))
148
+
149
+ def make_inside_margin_outline(self):
150
+ self.inside_margin_outline = arch(
151
+ self.length-self.inside_margin*2+self.width_margin,
152
+ self.width-self.width_margin*2,
153
+ self.height-self.inside_margin
154
+ ).translate((0,0,-self.inside_margin/2))
155
+
156
+ def make_inside_arch_stone(self):
157
+ height = self.calculate_arch_stone_margin_height()
158
+ inside_height = self.calculate_inside_arch_stone_margin_height()
159
+
160
+ pts = [
161
+ (0,0),
162
+ (0,height),
163
+ (self.inside_margin,height-(height-inside_height)/2),
164
+ (self.inside_margin,(height-inside_height)/2)
165
+ ]
166
+
167
+ stone = (
168
+ cq.Workplane("XZ")
169
+ .center(-self.inside_margin/2,-height/2)
170
+ .polyline(pts)
171
+ .close()
172
+ .extrude(self.width)
173
+ .translate((-self.length/2+self.inside_margin/2,self.width/2,0))
174
+ )
175
+
176
+ self.inside_arch_stone = stone
177
+
178
+ def make_outside_arch_stone(self):
179
+ length = self.inside_margin+self.outside_margin
180
+ height = self.calculate_outside_arch_stone_margin_height()
181
+ inside_height = self.calculate_inside_arch_stone_margin_height()
182
+ inside_length = self.length-self.inside_margin*2
183
+
184
+ pts = [
185
+ (0,0),
186
+ (0,height),
187
+ (length,height-(height-inside_height)/2),
188
+ (length,(height-inside_height)/2)
189
+ ]
190
+
191
+ stone = (
192
+ cq.Workplane("XZ")
193
+ .center(-length,-height/2)
194
+ .polyline(pts)
195
+ .close()
196
+ .extrude(self.width)
197
+ .translate((-inside_length/2,self.width/2,0))
198
+ )
199
+
200
+ self.outside_arch_stone = stone
201
+
202
+ def make_arch_stones(self):
203
+ rotate_degrees = 180 / self.stone_arch_count
204
+
205
+ arch_stones = cq.Workplane("XY")
206
+ for i in range(self.stone_arch_count+1):
207
+ stone = cq.Workplane("XY")
208
+
209
+ if self.inside_arch_stone:
210
+ stone = self.inside_arch_stone
211
+
212
+ if i % self.stone_arch_modulus == self.outside_stone_arch_position:
213
+ stone = self.outside_arch_stone
214
+
215
+ arch_stones.add(stone.rotate((0,1,0),(0,0,0),-rotate_degrees*i)) #type:ignore
216
+
217
+ self.arch_stones = arch_stones
218
+
219
+ def make(self, parent=None):
220
+ super().make(parent)
221
+ self.make_inside_stone()
222
+ self.make_outside_stone()
223
+ self.make_column_stones()
224
+
225
+ self.make_margin_outline()
226
+ self.make_outside_margin_outline()
227
+ self.make_inside_margin_outline()
228
+
229
+ self.make_inside_arch_stone()
230
+ self.make_outside_arch_stone()
231
+ self.make_arch_stones()
232
+
233
+ def build(self) -> cq.Workplane:
234
+ super().build()
235
+ column_height = self.calculate_column_height()
236
+
237
+ scene = (
238
+ cq.Workplane("XY")
239
+ #.add(self.outside_margin_outline)
240
+ #.add(self.inside_stone)
241
+ #.add(self.outside_stone)
242
+ #.add(self.inside_arch_stone)
243
+ #.add(self.outside_arch_stone)
244
+ #.add(self.column_outline)
245
+ )
246
+
247
+ if self.margin_outline:
248
+ scene = scene.add(self.margin_outline)
249
+
250
+ if self.inside_margin_outline:
251
+ scene = scene.cut(self.inside_margin_outline)
252
+
253
+ if self.column_stones:
254
+ scene = (
255
+ scene
256
+ .add(self.column_stones.translate((-self.length/2+self.inside_margin/2,0,-self.height/2+column_height/2)))
257
+ .add(self.column_stones.translate((-self.length/2+self.inside_margin/2,0,-self.height/2+column_height/2)).rotate((0,0,1),(0,0,0),180))
258
+ )
259
+
260
+ if self.arch_stones and self.column_outline:
261
+ arch_stones = (
262
+ self.arch_stones.translate((0,0,self.height/2-self.length/2))
263
+ .cut(self.column_outline)
264
+ )
265
+ scene = scene.add(arch_stones)
266
+
267
+ return scene
@@ -0,0 +1,3 @@
1
+ from .arch import arch
2
+ from .BasicArch import BasicArch
3
+ from .StoneArch import StoneArch
cqfantasy/arch/arch.py ADDED
@@ -0,0 +1,32 @@
1
+ # Copyright 2025 James Adams
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import cadquery as cq
16
+
17
+ def arch(
18
+ length:float = 30,
19
+ width:float = 5,
20
+ height:float = 75
21
+ ) -> cq.Workplane:
22
+ if length > height:
23
+ raise Exception(f'{length=} is greater than {height=}')
24
+ cylinder = cq.Workplane("XZ").cylinder(width, length/2)
25
+ base = cq.Workplane("XY").box(length, width, height-length/2)
26
+
27
+ combined_arch = (
28
+ base
29
+ .union(cylinder.translate((0,0,height/2-length/4)))
30
+ .translate((0,0,-length/4))
31
+ )
32
+ return combined_arch
@@ -0,0 +1,155 @@
1
+ import cadquery as cq
2
+ from cadqueryhelper import Base
3
+ import math
4
+
5
+ class AshlarCorner(Base):
6
+ def __init__(self):
7
+ super().__init__()
8
+ #parameter
9
+ self.length:float = 30
10
+ self.width:float = 30
11
+ self.height:float = 75
12
+ self.stone_height = 5
13
+ self.chamfer:float = 1
14
+ self.corner_cut_length:float|None = 3
15
+ self.corner_cut_width:float|None = 3
16
+
17
+ #shapes
18
+ self.outline:cq.Workplane|None = None
19
+ self.small_stone = None
20
+ self.large_stone = None
21
+ self.stones = None
22
+ self.mirror_stones = None
23
+ self.corner_cut = None
24
+
25
+
26
+ def make_outline(self):
27
+ outline = cq.Workplane("XY").box(
28
+ self.length,
29
+ self.width,
30
+ self.height
31
+ )
32
+
33
+ self.outline = outline
34
+
35
+ def calculate_stone_count(self):
36
+ return math.floor(self.height / self.stone_height)
37
+
38
+ def make_small_stone(self):
39
+ length = self.length / 2
40
+ width = self.width / 2
41
+ height = self.stone_height
42
+ small_stone = (
43
+ cq.Workplane("XY")
44
+ .box(length,width,height)
45
+ .translate((length/2,width/2,0))
46
+ )
47
+
48
+ if self.chamfer:
49
+ small_stone = small_stone.chamfer(self.chamfer)
50
+
51
+ self.small_stone = small_stone
52
+
53
+ def make_large_stone(self):
54
+ length = self.length
55
+ width = self.width
56
+ height = self.stone_height
57
+ large_stone = cq.Workplane("XY").box(length,width,height)
58
+
59
+ if self.chamfer:
60
+ large_stone = large_stone.chamfer(self.chamfer)
61
+
62
+ self.large_stone = large_stone
63
+
64
+ def make_corner_cut(self):
65
+ # cut stone
66
+ length = self.length / 2
67
+ width = self.width / 2
68
+
69
+ if self.corner_cut_length:
70
+ length = self.length - self.corner_cut_length
71
+
72
+ if self.corner_cut_width:
73
+ width = self.width - self.corner_cut_width
74
+
75
+ height = self.height
76
+ x_translate = self.length/2 - length/2
77
+ y_translate = self.width/2 - width/2
78
+
79
+ corner_cut = (
80
+ cq.Workplane("XY")
81
+ .box(length,width,height)
82
+ .translate((-x_translate,-y_translate,self.height/2))
83
+ )
84
+
85
+ self.corner_cut = corner_cut
86
+
87
+ def make_stones(self):
88
+ stones = cq.Workplane("XY")
89
+ stone_count = self.calculate_stone_count()
90
+
91
+ for i in range(stone_count):
92
+ if i % 2 == 0:
93
+ stones = stones.add(self.large_stone.translate((0,0,i * self.stone_height)))
94
+ else:
95
+ stones = stones.add(self.small_stone.translate((0,0,i * self.stone_height)))
96
+
97
+ self.stones = stones
98
+
99
+ def make_mirror_stones(self):
100
+ stones = cq.Workplane("XY")
101
+ stone_count = self.calculate_stone_count()
102
+ small_length = self.length / 2
103
+
104
+ for i in range(stone_count):
105
+ if i % 2 == 0:
106
+ stones = stones.add(self.large_stone.translate((0,0,i * self.stone_height)))
107
+ else:
108
+ stones = stones.add(self.small_stone.translate((-small_length,0,i * self.stone_height)))
109
+
110
+ self.mirror_stones = stones
111
+
112
+ def make(self):
113
+ super().make()
114
+ self.make_outline()
115
+ self.make_small_stone()
116
+ self.make_large_stone()
117
+ self.make_stones()
118
+ self.make_mirror_stones()
119
+ self.make_corner_cut()
120
+
121
+ def build_outline(self)->cq.Workplane:
122
+ super().build()
123
+
124
+ part = cq.Workplane("XY")
125
+
126
+ if self.outline:
127
+ part = part.add(self.outline.translate((0,0,self.height/2)))
128
+
129
+ return part
130
+
131
+ def build(self)->cq.Workplane:
132
+ super().build()
133
+
134
+ part = cq.Workplane("XY")
135
+
136
+ if self.stones:
137
+ part = part.add(self.stones.translate((0,0,self.stone_height/2)))
138
+
139
+ if self.corner_cut:
140
+ part = part.cut(self.corner_cut)
141
+
142
+ return part.rotate((0,0,1),(0,0,0),180)
143
+
144
+ def build_mirror(self)->cq.Workplane:
145
+ super().build()
146
+
147
+ part = cq.Workplane("XY")
148
+
149
+ if self.stones:
150
+ part = part.add(self.mirror_stones.translate((0,0,self.stone_height/2)))
151
+
152
+ if self.corner_cut:
153
+ part = part.cut(self.corner_cut.translate((self.corner_cut_length,0,0)))
154
+
155
+ return part.rotate((0,0,1),(0,0,0),180)
@@ -0,0 +1 @@
1
+ from .AshlarCorner import AshlarCorner
@@ -0,0 +1,73 @@
1
+ # Copyright 2025 James Adams
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import cadquery as cq
16
+ from cadqueryhelper import Base
17
+ from ..arch import StoneArch
18
+ from . import VDoor
19
+
20
+ class ArchDoor(Base):
21
+ def __init__(self):
22
+ super().__init__()
23
+
24
+ self.length:float = 50
25
+ self.width:float = 7
26
+ self.height:float = 75
27
+ self.door_inset:float = 2
28
+
29
+ #blueprints
30
+ self.bp_arch = StoneArch()
31
+ self.bp_arch.outside_margin = 5
32
+ self.bp_arch.outside_stone_position = 0
33
+ self.bp_arch.stone_arch_count = 6
34
+ self.bp_arch.stone_arch_modulus = 2
35
+
36
+ self.bp_door = VDoor()
37
+
38
+ def make_arch(self):
39
+ if self.bp_arch:
40
+ self.bp_arch.length = self.length
41
+ self.bp_arch.width = self.width
42
+ self.bp_arch.height = self.height
43
+ self.bp_arch.make()
44
+
45
+ def make_door(self):
46
+ if self.bp_door:
47
+ self.bp_door.length = self.length - self.bp_arch.inside_margin*2
48
+ self.bp_door.width = self.width - self.door_inset
49
+ self.bp_door.height = self.height - self.bp_arch.inside_margin
50
+ self.bp_door.make()
51
+
52
+ def make(self, parent=None):
53
+ super().make(parent)
54
+ self.make_arch()
55
+ self.make_door()
56
+
57
+
58
+ def build(self):
59
+ super().build()
60
+ scene = cq.Workplane("XY")
61
+
62
+ if self.bp_arch:
63
+ ex_arch = self.bp_arch.build()
64
+ scene = scene.add(ex_arch)
65
+
66
+ if self.bp_door:
67
+ ex_door = self.bp_door.build()
68
+ scene = scene.add(ex_door.translate((0,0,- self.bp_arch.inside_margin/2)))
69
+
70
+ return scene
71
+
72
+ def build_outline(self):
73
+ return self.bp_arch.build_outline()