Cleanup: trailing space
[blender-addons.git] / add_mesh_extra_objects / Wallfactory.py
blobcbdb4c139c803d4e2f099dfc6d24ce8479dccdf6
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # authors: dudecon, jambay
5 # This module contains the UI definition, display,
6 # and processing (create mesh) functions.
7 # The routines to generate the vertices for the wall
8 # are found in the "Blocks" module.
11 import bpy
12 from bpy.types import Operator
13 from bpy.props import (
14 BoolProperty,
15 FloatProperty,
16 StringProperty,
18 from .Blocks import (
19 NOTZERO, PI,
20 dims,
21 settings,
22 shelfSpecs,
23 stepSpecs,
24 createWall,
25 radialized,
26 slope,
27 openingSpecs,
28 bigBlock,
29 shelfExt,
30 stepMod,
31 stepLeft,
32 shelfBack,
33 stepOnly,
34 stepBack,
36 from bpy_extras import object_utils
38 class add_mesh_wallb(Operator, object_utils.AddObjectHelper):
39 bl_idname = "mesh.wall_add"
40 bl_label = "Add a Masonry Wall"
41 bl_description = "Create a block (masonry) wall mesh"
42 bl_options = {'REGISTER', 'UNDO'}
44 # UI items - API for properties - User accessible variables...
45 # not all options are via UI, and some operations just don't work yet
47 Wall : BoolProperty(name = "Wall",
48 default = True,
49 description = "Wall")
51 #### change properties
52 name : StringProperty(name = "Name",
53 description = "Name")
55 change : BoolProperty(name = "Change",
56 default = False,
57 description = "change Wall")
59 # only create object when True
60 # False allows modifying several parameters without creating object
61 ConstructTog: BoolProperty(
62 name="Construct",
63 description="Generate the object",
64 default=True
66 # need to modify so radial makes a tower (normal);
67 # want "flat" setting to make disk (alternate)
68 # make the wall circular - if not sloped it's a flat disc
69 RadialTog: BoolProperty(
70 name="Radial",
71 description="Make masonry radial",
72 default=False
74 # curve the wall - if radial creates dome.
75 SlopeTog: BoolProperty(
76 name="Curved",
77 description="Make masonry sloped, or curved",
78 default=False
80 # need to review defaults and limits for all of these UI objects
82 # wall area/size
83 WallStart: FloatProperty(
84 name="Start",
85 description="Left side, or start angle",
86 default=-10.0,
87 min=-100, max=100.0
89 WallEnd: FloatProperty(
90 name="End",
91 description="Right side, or end angle",
92 default=10.0,
93 min=0.0, max=100.0
95 WallBottom: FloatProperty(
96 name="Bottom",
97 description="Lower height or radius",
98 default=0.0,
99 min=-100, max=100
101 WallTop: FloatProperty(
102 name="Top",
103 description="Upper height or radius",
104 default=15.0,
105 min=0.0, max=100.0
107 EdgeOffset: FloatProperty(
108 name="Edging",
109 description="Block staggering on wall sides",
110 default=0.6, min=0.0, max=100.0
112 # block sizing
113 Width: FloatProperty(
114 name="Width",
115 description="Average width of each block",
116 default=1.5,
117 min=0.01, max=100.0
119 WidthVariance: FloatProperty(
120 name="Variance",
121 description="Random variance of block width",
122 default=0.5,
123 min=0.0, max=100.0
125 WidthMinimum: FloatProperty(
126 name="Minimum",
127 description="Absolute minimum block width",
128 default=0.5,
129 min=0.01, max=100.0
131 Height: FloatProperty(
132 name="Height",
133 description="Average Height of each block",
134 default=0.7,
135 min=0.01, max=100.0
137 HeightVariance: FloatProperty(
138 name="Variance",
139 description="Random variance of block Height",
140 default=0.3,
141 min=0.0, max=100.0
143 HeightMinimum: FloatProperty(
144 name="Minimum",
145 description="Absolute minimum block Height",
146 default=0.25,
147 min=0.01, max=100.0
149 Depth: FloatProperty(
150 name="Depth",
151 description="Average Depth of each block",
152 default=2.0,
153 min=0.01, max=100.0
155 DepthVariance: FloatProperty(
156 name="Variance",
157 description="Random variance of block Depth",
158 default=0.1,
159 min=0.0, max=100.0
161 DepthMinimum: FloatProperty(
162 name="Minimum",
163 description="Absolute minimum block Depth",
164 default=1.0,
165 min=0.01, max=100.0
167 MergeBlock: BoolProperty(
168 name="Merge Blocks",
169 description="Make big blocks (merge closely adjoining blocks)",
170 default=False
172 # edging for blocks
173 Grout: FloatProperty(
174 name="Thickness",
175 description="Distance between blocks",
176 default=0.1,
177 min=-10.0, max=10.0
179 GroutVariance: FloatProperty(
180 name="Variance",
181 description="Random variance of block Grout",
182 default=0.03,
183 min=0.0, max=100.0
185 GroutDepth: FloatProperty(
186 name="Depth",
187 description="Grout Depth from the face of the blocks",
188 default=0.1,
189 min=0.0001, max=10.0
191 GroutDepthVariance: FloatProperty(
192 name="Variance",
193 description="Random variance of block Grout Depth",
194 default=0.03,
195 min=0.0, max=100.0
197 GroutEdge: BoolProperty(
198 name="Edging",
199 description="Grout perimiter",
200 default=False
202 # properties for openings
203 Opening1Tog: BoolProperty(
204 name="Opening(s)",
205 description="Make windows or doors",
206 default=True
208 Opening1Width: FloatProperty(
209 name="Width",
210 description="The Width of the first opening",
211 default=2.5,
212 min=0.01, max=100.0
214 Opening1Height: FloatProperty(
215 name="Height",
216 description="The Height of the first opening",
217 default=3.5,
218 min=0.01, max=100.0
220 Opening1X: FloatProperty(
221 name="Indent",
222 description="The x position or spacing of the first opening",
223 default=5.0,
224 min=-100, max=100.0
226 Opening1Z: FloatProperty(
227 name="Bottom",
228 description="The z position of the First opening",
229 default=5.0,
230 min=-100, max=100.0
232 Opening1Repeat: BoolProperty(
233 name="Repeat",
234 description="make multiple openings, with spacing X1",
235 default=False
237 Opening1TopArchTog: BoolProperty(
238 name="Top Arch",
239 description="Add an arch to the top of the first opening",
240 default=True
242 Opening1TopArch: FloatProperty(
243 name="Curve",
244 description="Height of the arch on the top of the opening",
245 default=2.5,
246 min=0.001, max=100.0
248 Opening1TopArchThickness: FloatProperty(
249 name="Thickness",
250 description="Thickness of the arch on the top of the opening",
251 default=0.75,
252 min=0.001, max=100.0
254 Opening1BtmArchTog: BoolProperty(
255 name="Bottom Arch",
256 description="Add an arch to the bottom of opening 1",
257 default=False
259 Opening1BtmArch: FloatProperty(
260 name="Curve",
261 description="Height of the arch on the bottom of the opening",
262 default=1.0,
263 min=0.01, max=100.0
265 Opening1BtmArchThickness: FloatProperty(
266 name="Thickness",
267 description="Thickness of the arch on the bottom of the opening",
268 default=0.5,
269 min=0.01, max=100.0
271 Opening1Bevel: FloatProperty(
272 name="Bevel",
273 description="Angle block face",
274 default=0.25,
275 min=-10.0, max=10.0
277 # openings on top of wall
278 CrenelTog: BoolProperty(
279 name="Crenels",
280 description="Make openings along top of wall",
281 default=False
283 CrenelXP: FloatProperty(
284 name="Width",
285 description="Gap width in wall based the percentage of wall width",
286 default=0.25,
287 min=0.10, max=1.0,
288 subtype="PERCENTAGE"
290 CrenelZP: FloatProperty(
291 name="Height",
292 description="Crenel Height as the percentage of wall height",
293 default=0.10,
294 min=0.10, max=1.0,
295 subtype="PERCENTAGE"
297 # narrow openings in wall.
298 # need to prevent overlap with arch openings - though inversion is an interesting effect.
299 SlotTog: BoolProperty(
300 name="Slots",
301 description="Make narrow openings in wall",
302 default=False
304 SlotRpt: BoolProperty(
305 name="Repeat",
306 description="Repeat slots along wall",
307 default=False
309 SlotWdg: BoolProperty(
310 name="Wedged (n/a)",
311 description="Bevel edges of slots",
312 default=False
314 SlotX: FloatProperty(
315 name="Indent",
316 description="The x position or spacing of slots",
317 default=0.0, min=-100, max=100.0
319 SlotGap: FloatProperty(
320 name="Opening",
321 description="The opening size of slots",
322 default=0.5, min=0.10, max=100.0
324 SlotV: BoolProperty(
325 name="Vertical",
326 description="Vertical slots",
327 default=True
329 SlotVH: FloatProperty(
330 name="Height",
331 description="Height of vertical slot",
332 default=3.5,
333 min=0.10, max=100.0
335 SlotVBtm: FloatProperty(
336 name="Bottom",
337 description="Z position for slot",
338 default=5.00,
339 min=-100.0, max=100.0
341 SlotH: BoolProperty(
342 name="Horizontal",
343 description="Horizontal slots",
344 default=False
346 SlotHW: FloatProperty(
347 name="Width",
348 description="Width of horizontal slot",
349 default=2.5,
350 min=0.10, max=100.0
352 # this should offset from VBtm... maybe make a % like crenels?
353 SlotHBtm: FloatProperty(
354 name="Bottom",
355 description="Z position for horizontal slot",
356 default=5.50,
357 min=-100.0, max=100.0
359 # properties for shelf (extend blocks in area)
360 ShelfTog: BoolProperty(
361 name="Shelf",
362 description="Add blocks in area by depth to make shelf/platform",
363 default=False
365 ShelfX: FloatProperty(
366 name="Left",
367 description="The x position of Shelf",
368 default=-5.00,
369 min=-100, max=100.0
371 ShelfZ: FloatProperty(
372 name="Bottom",
373 description="The z position of Shelf",
374 default=10.0,
375 min=-100, max=100.0
377 ShelfH: FloatProperty(
378 name="Height",
379 description="The Height of Shelf area",
380 default=1.0,
381 min=0.01, max=100.0
383 ShelfW: FloatProperty(
384 name="Width",
385 description="The Width of shelf area",
386 default=5.0,
387 min=0.01, max=100.0
389 ShelfD: FloatProperty(
390 name="Depth",
391 description="Depth of each block for shelf (from cursor + 1/2 wall depth)",
392 default=2.0,
393 min=0.01, max=100.0
395 ShelfBack: BoolProperty(
396 name="Backside",
397 description="Shelf on backside of wall",
398 default=False
400 # properties for steps (extend blocks in area, progressive width)
401 StepTog: BoolProperty(
402 name="Steps",
403 description="Add blocks in area by depth with progressive width to make steps",
404 default=False
406 StepX: FloatProperty(
407 name="Left",
408 description="The x position of steps",
409 default=-9.00,
410 min=-100, max=100.0
412 StepZ: FloatProperty(
413 name="Bottom",
414 description="The z position of steps",
415 default=0.0,
416 min=-100, max=100.0
418 StepH: FloatProperty(
419 name="Height",
420 description="The Height of step area",
421 default=10.0,
422 min=0.01, max=100.0
424 StepW: FloatProperty(
425 name="Width",
426 description="The Width of step area",
427 default=8.0,
428 min=0.01, max=100.0
430 StepD: FloatProperty(
431 name="Depth",
432 description="Depth of each block for steps (from cursor + 1/2 wall depth)",
433 default=1.0,
434 min=0.01, max=100.0
436 StepV: FloatProperty(
437 name="Riser",
438 description="Height of each step",
439 default=0.70,
440 min=0.01, max=100.0
442 StepT: FloatProperty(
443 name="Tread",
444 description="Width of each step",
445 default=1.0,
446 min=0.01, max=100.0
448 StepLeft: BoolProperty(
449 name="Direction",
450 description="If checked, flip steps direction towards the -X axis",
451 default=False
453 StepOnly: BoolProperty(
454 name="Steps Only",
455 description="Steps only, no supporting blocks",
456 default=False
458 StepBack: BoolProperty(
459 name="Backside",
460 description="Steps on backside of wall",
461 default=False
464 # Display the toolbox options
465 def draw(self, context):
466 layout = self.layout
468 box = layout.box()
469 box.prop(self, 'ConstructTog')
471 # Wall area (size/position)
472 box = layout.box()
473 box.label(text="Wall Size (area)")
475 col = box.column(align=True)
476 col.prop(self, "WallStart")
477 col.prop(self, "WallEnd")
479 col = box.column(align=True)
480 col.prop(self, "WallBottom")
481 col.prop(self, "WallTop")
482 box.prop(self, "EdgeOffset")
484 # Wall block sizing
485 box = layout.box()
486 box.label(text="Block Sizing")
487 box.prop(self, "MergeBlock")
489 # add checkbox for "fixed" sizing (ignore variance) a.k.a. bricks
490 col = box.column(align=True)
491 col.prop(self, "Width")
492 col.prop(self, "WidthVariance")
493 col.prop(self, "WidthMinimum")
495 col = box.column(align=True)
496 col.prop(self, "Height")
497 col.prop(self, "HeightVariance")
498 col.prop(self, "HeightMinimum")
500 col = box.column(align=True)
501 col.prop(self, "Depth")
502 col.prop(self, "DepthVariance")
503 col.prop(self, "DepthMinimum")
505 # grout settings
506 box = layout.box()
507 box.label(text="Grout")
509 col = box.column(align=True)
510 col.prop(self, "Grout")
511 col.prop(self, "GroutVariance")
513 col = box.column(align=True)
514 col.prop(self, "GroutDepth")
515 col.prop(self, "GroutDepthVariance")
517 # Wall shape modifiers
518 box = layout.box()
519 box.label(text="Wall Shape")
520 row = box.row(align=True)
521 row.prop(self, "RadialTog", toggle=True)
522 row.prop(self, "SlopeTog", toggle=True)
524 # Openings (doors, windows; arched)
525 box = layout.box()
526 box.prop(self, 'Opening1Tog')
527 if self.Opening1Tog:
528 col = box.column(align=True)
529 col.prop(self, "Opening1Width")
530 col.prop(self, "Opening1Height")
531 col.prop(self, "Opening1X")
532 col.prop(self, "Opening1Z")
533 col.prop(self, "Opening1Bevel")
535 box.prop(self, "Opening1Repeat", toggle=True)
537 sub_box = box.box()
538 sub_box.prop(self, "Opening1TopArchTog")
539 if self.Opening1TopArchTog:
540 col = sub_box.column(align=True)
541 col.prop(self, "Opening1TopArch")
542 col.prop(self, "Opening1TopArchThickness")
544 sub_box = box.box()
545 sub_box.prop(self, "Opening1BtmArchTog")
546 if self.Opening1BtmArchTog:
547 col = sub_box.column(align=True)
548 col.prop(self, "Opening1BtmArch")
549 col.prop(self, "Opening1BtmArchThickness")
551 # Slots (narrow openings)
552 box = layout.box()
553 box.prop(self, "SlotTog")
554 if self.SlotTog:
555 col = box.column(align=True)
556 col.prop(self, "SlotX")
557 col.prop(self, "SlotGap")
559 box.prop(self, "SlotRpt", toggle=True)
561 sub_box = box.box()
562 sub_box.prop(self, "SlotV")
563 if self.SlotV:
564 col = sub_box.column(align=True)
565 col.prop(self, "SlotVH")
566 col.prop(self, "SlotVBtm")
568 sub_box = box.box()
569 sub_box.prop(self, "SlotH")
570 if self.SlotH:
571 col = sub_box.column(align=True)
572 col.prop(self, "SlotHW")
573 col.prop(self, "SlotHBtm")
575 # Crenels, gaps in top of wall
576 box = layout.box()
577 box.prop(self, "CrenelTog")
578 if self.CrenelTog:
579 col = box.column(align=True)
580 col.prop(self, "CrenelXP")
581 col.prop(self, "CrenelZP")
583 # Shelfing (protrusions)
584 box = layout.box()
585 box.prop(self, 'ShelfTog')
586 if self.ShelfTog:
587 col = box.column(align=True)
588 col.prop(self, "ShelfX")
589 col.prop(self, "ShelfZ")
591 col = box.column(align=True)
592 col.prop(self, "ShelfW")
593 col.prop(self, "ShelfH")
594 col.prop(self, "ShelfD")
596 box.prop(self, "ShelfBack")
598 # Steps
599 box = layout.box()
600 box.prop(self, 'StepTog')
601 if self.StepTog:
602 col = box.column(align=True)
603 col.prop(self, "StepX")
604 col.prop(self, "StepZ")
606 col = box.column(align=True)
607 col.prop(self, "StepH")
608 col.prop(self, "StepW")
609 col.prop(self, "StepD")
611 col = box.column(align=True)
612 col.prop(self, "StepV")
613 col.prop(self, "StepT")
615 col = box.column(align=True)
616 row = col.row(align=True)
617 row.prop(self, "StepLeft", toggle=True)
618 row.prop(self, "StepOnly", toggle=True)
619 col.prop(self, "StepBack", toggle=True)
621 if self.change == False:
622 # generic transform props
623 box = layout.box()
624 box.prop(self, 'align', expand=True)
625 box.prop(self, 'location', expand=True)
626 box.prop(self, 'rotation', expand=True)
628 # Respond to UI - get the properties set by user.
629 # Check and process UI settings to generate masonry
631 def execute(self, context):
632 global radialized
633 global slope
634 global openingSpecs
635 global bigBlock
636 global shelfExt
637 global stepMod
638 global stepLeft
639 global shelfBack
640 global stepOnly
641 global stepBack
643 # Create the wall when enabled (skip regen iterations when off)
644 if not self.ConstructTog:
645 return {'FINISHED'}
647 # turn off 'Enter Edit Mode'
648 use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode
649 bpy.context.preferences.edit.use_enter_edit_mode = False
651 # enter the settings for the wall dimensions (area)
652 # start can't be zero - min/max don't matter [if max less than end] but zero don't workie.
653 # start can't exceed end.
654 if not self.WallStart or self.WallStart >= self.WallEnd:
655 self.WallStart = NOTZERO # Reset UI if input out of bounds...
657 dims['s'] = self.WallStart
658 dims['e'] = self.WallEnd
659 dims['b'] = self.WallBottom
660 dims['t'] = self.WallTop
662 settings['eoff'] = self.EdgeOffset
664 # retrieve the settings for the wall block properties
665 settings['w'] = self.Width
666 settings['wv'] = self.WidthVariance
667 settings['wm'] = self.WidthMinimum
669 if not radialized:
670 settings['sdv'] = settings['w']
671 else:
672 settings['sdv'] = 0.12
674 settings['h'] = self.Height
675 settings['hv'] = self.HeightVariance
676 settings['hm'] = self.HeightMinimum
678 settings['d'] = self.Depth
679 settings['dv'] = self.DepthVariance
680 settings['dm'] = self.DepthMinimum
682 if self.MergeBlock:
683 bigBlock = 1
684 else:
685 bigBlock = 0
687 settings['g'] = self.Grout
688 settings['gv'] = self.GroutVariance
689 settings['gd'] = self.GroutDepth
690 settings['gdv'] = self.GroutDepthVariance
692 if self.GroutEdge:
693 settings['ge'] = 1
694 else:
695 settings['ge'] = 0
697 # set wall shape modifiers
698 if self.RadialTog:
699 radialized = 1
700 # eliminate to allow user control for start/completion?
701 dims['s'] = 0.0 # complete radial
702 if dims['e'] > PI * 2:
703 dims['e'] = PI * 2 # max end for circle
704 if dims['b'] < settings['g']:
705 dims['b'] = settings['g'] # min bottom for grout extension
706 else:
707 radialized = 0
709 if self.SlopeTog:
710 slope = 1
711 else:
712 slope = 0
714 shelfExt = 0
715 shelfBack = 0
717 # Add shelf if enabled
718 if self.ShelfTog:
719 shelfExt = 1
720 shelfSpecs['h'] = self.ShelfH
721 shelfSpecs['w'] = self.ShelfW
722 shelfSpecs['d'] = self.ShelfD
723 shelfSpecs['x'] = self.ShelfX
724 shelfSpecs['z'] = self.ShelfZ
726 if self.ShelfBack:
727 shelfBack = 1
728 stepMod = 0
729 stepLeft = 0
730 stepOnly = 0
731 stepBack = 0
733 # Make steps if enabled
734 if self.StepTog:
735 stepMod = 1
736 stepSpecs['x'] = self.StepX
737 stepSpecs['z'] = self.StepZ
738 stepSpecs['h'] = self.StepH
739 stepSpecs['w'] = self.StepW
740 stepSpecs['d'] = self.StepD
741 stepSpecs['v'] = self.StepV
742 stepSpecs['t'] = self.StepT
744 if self.StepLeft:
745 stepLeft = 1
747 if self.StepOnly:
748 stepOnly = 1
750 if self.StepBack:
751 stepBack = 1
753 # enter the settings for the openings
754 # when openings overlap they create inverse stonework - interesting but not the desired effect :)
755 # if opening width == indent * 2 the edge blocks fail (row of blocks cross opening) - bug.
756 openingSpecs = []
757 openingIdx = 0 # track opening array references for multiple uses
759 # general openings with arch options - can be windows or doors.
760 if self.Opening1Tog:
761 # set defaults...
762 openingSpecs += [{'w': 0.5, 'h': 0.5, 'x': 0.8, 'z': 2.7, 'rp': 1,
763 'b': 0.0, 'v': 0, 'vl': 0, 't': 0, 'tl': 0}]
765 openingSpecs[openingIdx]['w'] = self.Opening1Width
766 openingSpecs[openingIdx]['h'] = self.Opening1Height
767 openingSpecs[openingIdx]['x'] = self.Opening1X
768 openingSpecs[openingIdx]['z'] = self.Opening1Z
769 openingSpecs[openingIdx]['rp'] = self.Opening1Repeat
771 if self.Opening1TopArchTog:
772 openingSpecs[openingIdx]['v'] = self.Opening1TopArch
773 openingSpecs[openingIdx]['t'] = self.Opening1TopArchThickness
775 if self.Opening1BtmArchTog:
776 openingSpecs[openingIdx]['vl'] = self.Opening1BtmArch
777 openingSpecs[openingIdx]['tl'] = self.Opening1BtmArchThickness
779 openingSpecs[openingIdx]['b'] = self.Opening1Bevel
781 openingIdx += 1 # count window/door/arch openings
783 # Slots (narrow openings)
784 if self.SlotTog:
786 if self.SlotV: # vertical slots
787 # set defaults...
788 openingSpecs += [{'w': 0.5, 'h': 0.5, 'x': 0.0, 'z': 2.7, 'rp': 0,
789 'b': 0.0, 'v': 0, 'vl': 0, 't': 0, 'tl': 0}]
791 openingSpecs[openingIdx]['w'] = self.SlotGap
792 openingSpecs[openingIdx]['h'] = self.SlotVH
793 openingSpecs[openingIdx]['x'] = self.SlotX
794 openingSpecs[openingIdx]['z'] = self.SlotVBtm
795 openingSpecs[openingIdx]['rp'] = self.SlotRpt
797 # make them pointy...
798 openingSpecs[openingIdx]['v'] = self.SlotGap
799 openingSpecs[openingIdx]['t'] = self.SlotGap / 2
800 openingSpecs[openingIdx]['vl'] = self.SlotGap
801 openingSpecs[openingIdx]['tl'] = self.SlotGap / 2
803 openingIdx += 1 # count vertical slot openings
805 # need to handle overlap of H and V slots...
807 if self.SlotH: # Horizontal slots
808 # set defaults...
809 openingSpecs += [{'w': 0.5, 'h': 0.5, 'x': 0.0, 'z': 2.7, 'rp': 0,
810 'b': 0.0, 'v': 0, 'vl': 0, 't': 0, 'tl': 0}]
812 openingSpecs[openingIdx]['w'] = self.SlotHW
813 openingSpecs[openingIdx]['h'] = self.SlotGap
814 openingSpecs[openingIdx]['x'] = self.SlotX
815 openingSpecs[openingIdx]['z'] = self.SlotHBtm
816 # horizontal repeat isn't same spacing as vertical...
817 openingSpecs[openingIdx]['rp'] = self.SlotRpt
819 # make them pointy...
820 openingIdx += 1 # count horizontal slot openings
822 # Crenellations (top row openings)
823 if self.CrenelTog:
825 # add bottom arch option?
826 # perhaps a repeat toggle...
827 # if crenel opening overlaps with arch opening it fills with blocks...
829 # set defaults...
830 openingSpecs += [{'w': 0.5, 'h': 0.5, 'x': 0.0, 'z': 2.7, 'rp': 1,
831 'b': 0.0, 'v': 0, 'vl': 0, 't': 0, 'tl': 0}]
833 wallW = self.WallEnd - self.WallStart
834 crenelW = wallW * self.CrenelXP # Width % opening.
836 wallH = self.WallTop - self.WallBottom
837 crenelH = wallH * self.CrenelZP # % proportional height.
839 openingSpecs[openingIdx]['w'] = crenelW
840 openingSpecs[openingIdx]['h'] = crenelH
842 # calculate the spacing between openings.
843 # this isn't the absolute start (left),
844 # it's opening center offset relative to cursor (space between openings)...
845 openingSpecs[openingIdx]['x'] = crenelW * 2 - 1 # assume standard spacing
847 if not radialized: # normal wall?
848 # set indent 0 (center) if opening is 50% or more of wall width, no repeat.
849 if crenelW * 2 >= wallW:
850 openingSpecs[openingIdx]['x'] = 0
851 openingSpecs[openingIdx]['rp'] = 0
852 # set bottom of opening (center of hole)
853 openingSpecs[openingIdx]['z'] = self.WallTop - (crenelH / 2)
855 openingIdx += 1 # count crenel openings
857 # Process the user settings to generate a wall
858 # generate the list of vertices for the wall...
859 verts_array, faces_array = createWall(
860 radialized, slope, openingSpecs, bigBlock,
861 shelfExt, shelfBack, stepMod, stepLeft, stepOnly,
862 stepBack
865 if bpy.context.mode == "OBJECT":
866 if context.selected_objects != [] and context.active_object and \
867 (context.active_object.data is not None) and ('Wall' in context.active_object.data.keys()) and \
868 (self.change == True):
869 obj = context.active_object
870 oldmesh = obj.data
871 oldmeshname = obj.data.name
872 mesh = bpy.data.meshes.new("Wall")
873 mesh.from_pydata(verts_array, [], faces_array)
874 obj.data = mesh
875 for material in oldmesh.materials:
876 obj.data.materials.append(material)
877 bpy.data.meshes.remove(oldmesh)
878 obj.data.name = oldmeshname
879 else:
880 mesh = bpy.data.meshes.new("Wall")
881 mesh.from_pydata(verts_array, [], faces_array)
882 obj = object_utils.object_data_add(context, mesh, operator=self)
884 mesh.update()
886 obj.data["Wall"] = True
887 obj.data["change"] = False
888 for prm in WallParameters():
889 obj.data[prm] = getattr(self, prm)
891 if bpy.context.mode == "EDIT_MESH":
892 active_object = context.active_object
893 name_active_object = active_object.name
894 bpy.ops.object.mode_set(mode='OBJECT')
895 mesh = bpy.data.meshes.new("TMP")
896 mesh.from_pydata(verts_array, [], faces_array)
897 obj = object_utils.object_data_add(context, mesh, operator=self)
898 obj.select_set(True)
899 active_object.select_set(True)
900 bpy.context.view_layer.objects.active = active_object
901 bpy.ops.object.join()
902 context.active_object.name = name_active_object
903 bpy.ops.object.mode_set(mode='EDIT')
905 if use_enter_edit_mode:
906 bpy.ops.object.mode_set(mode = 'EDIT')
908 # restore pre operator state
909 bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode
911 return {'FINISHED'}
913 def WallParameters():
914 WallParameters = [
915 "ConstructTog",
916 "RadialTog",
917 "SlopeTog",
918 "WallStart",
919 "WallEnd",
920 "WallBottom",
921 "WallTop",
922 "EdgeOffset",
923 "Width",
924 "WidthVariance",
925 "WidthMinimum",
926 "Height",
927 "HeightVariance",
928 "HeightMinimum",
929 "Depth",
930 "DepthVariance",
931 "DepthMinimum",
932 "MergeBlock",
933 "Grout",
934 "GroutVariance",
935 "GroutDepth",
936 "GroutDepthVariance",
937 "GroutEdge",
938 "Opening1Tog",
939 "Opening1Width",
940 "Opening1Height",
941 "Opening1X",
942 "Opening1Z",
943 "Opening1Repeat",
944 "Opening1TopArchTog",
945 "Opening1TopArch",
946 "Opening1TopArchThickness",
947 "Opening1BtmArchTog",
948 "Opening1BtmArch",
949 "Opening1BtmArchThickness",
950 "CrenelTog",
951 "CrenelXP",
952 "CrenelZP",
953 "SlotTog",
954 "SlotRpt",
955 "SlotWdg",
956 "SlotX",
957 "SlotGap",
958 "SlotV",
959 "SlotVH",
960 "SlotVBtm",
961 "SlotH",
962 "SlotHW",
963 "SlotHBtm",
964 "ShelfTog",
965 "ShelfX",
966 "ShelfZ",
967 "ShelfH",
968 "ShelfW",
969 "ShelfD",
970 "ShelfBack",
971 "StepTog",
972 "StepX",
973 "StepZ",
974 "StepH",
975 "StepW",
976 "StepD",
977 "StepV",
978 "StepT",
979 "StepLeft",
980 "StepOnly",
981 "StepBack",
983 return WallParameters