Update for changes in Blender's API
[blender-addons.git] / archimesh / achm_column_maker.py
blob6bae7efa744c91b6d88f4e49f73a5bd243da95a7
1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
19 # <pep8 compliant>
21 # ----------------------------------------------------------
22 # Automatic generation of columns
23 # Author: Antonio Vazquez (antonioya)
25 # ----------------------------------------------------------
26 # noinspection PyUnresolvedReferences
27 import bpy
28 from math import cos, sin, radians, atan, sqrt
29 from .achm_tools import *
32 # ------------------------------------------------------------------
33 # Define UI class
34 # Columns
35 # ------------------------------------------------------------------
36 class AchmColumn(bpy.types.Operator):
37 bl_idname = "mesh.archimesh_column"
38 bl_label = "Column"
39 bl_description = "Columns Generator"
40 bl_category = 'Archimesh'
41 bl_options = {'REGISTER', 'UNDO'}
43 # Define properties
44 model = bpy.props.EnumProperty(
45 name="Model",
46 items=(
47 ('1', "Circular", ""),
48 ('2', "Rectangular", ""),
50 description="Type of column",
52 keep_size = bpy.props.BoolProperty(
53 name="Keep radius equal",
54 description="Keep all radius (top, mid and bottom) to the same size",
55 default=True,
58 rad_top = bpy.props.FloatProperty(
59 name='Top radius',
60 min=0.001, max=10, default=0.15, precision=3,
61 description='Radius of the column in the top',
63 rad_mid = bpy.props.FloatProperty(
64 name='Middle radius',
65 min=0.001, max=10, default=0.15, precision=3,
66 description='Radius of the column in the middle',
68 shift = bpy.props.FloatProperty(
69 name='',
70 min=-1, max=1, default=0, precision=3,
71 description='Middle displacement',
74 rad_bottom = bpy.props.FloatProperty(
75 name='Bottom radius',
76 min=0.001, max=10, default=0.15, precision=3,
77 description='Radius of the column in the bottom',
80 col_height = bpy.props.FloatProperty(
81 name='Total height',
82 min=0.001, max=10, default=2.4, precision=3,
83 description='Total height of column, including bases and tops',
85 col_sx = bpy.props.FloatProperty(
86 name='X size',
87 min=0.001, max=10, default=0.30, precision=3,
88 description='Column size for x axis',
90 col_sy = bpy.props.FloatProperty(
91 name='Y size',
92 min=0.001, max=10, default=0.30, precision=3,
93 description='Column size for y axis',
96 cir_base = bpy.props.BoolProperty(
97 name="Include circular base",
98 description="Include a base with circular form",
99 default=False,
101 cir_base_r = bpy.props.FloatProperty(
102 name='Radio',
103 min=0.001, max=10, default=0.08, precision=3,
104 description='Rise up radio of base',
106 cir_base_z = bpy.props.FloatProperty(
107 name='Height',
108 min=0.001, max=10, default=0.05, precision=3,
109 description='Size for z axis',
112 cir_top = bpy.props.BoolProperty(
113 name="Include circular top",
114 description="Include a top with circular form",
115 default=False,
117 cir_top_r = bpy.props.FloatProperty(
118 name='Radio',
119 min=0.001, max=10, default=0.08, precision=3,
120 description='Rise up radio of top',
122 cir_top_z = bpy.props.FloatProperty(
123 name='Height',
124 min=0.001, max=10, default=0.05, precision=3,
125 description='Size for z axis',
128 box_base = bpy.props.BoolProperty(
129 name="Include rectangular base",
130 description="Include a base with rectangular form",
131 default=True,
133 box_base_x = bpy.props.FloatProperty(
134 name='X size',
135 min=0.001, max=10, default=0.40, precision=3,
136 description='Size for x axis',
138 box_base_y = bpy.props.FloatProperty(
139 name='Y size',
140 min=0.001, max=10, default=0.40, precision=3,
141 description='Size for y axis',
143 box_base_z = bpy.props.FloatProperty(
144 name='Height',
145 min=0.001, max=10, default=0.05, precision=3,
146 description='Size for z axis',
149 box_top = bpy.props.BoolProperty(
150 name="Include rectangular top",
151 description="Include a top with rectangular form",
152 default=True,
154 box_top_x = bpy.props.FloatProperty(
155 name='X size',
156 min=0.001, max=10, default=0.40, precision=3,
157 description='Size for x axis',
159 box_top_y = bpy.props.FloatProperty(
160 name='Y size',
161 min=0.001, max=10, default=0.40, precision=3,
162 description='Size for y axis',
164 box_top_z = bpy.props.FloatProperty(
165 name='Height',
166 min=0.001, max=10, default=0.05, precision=3,
167 description='Size for z axis',
170 arc_top = bpy.props.BoolProperty(
171 name="Create top arch",
172 description="Include an arch in the top of the column",
173 default=False,
175 arc_radio = bpy.props.FloatProperty(
176 name='Arc Radio',
177 min=0.001, max=10, default=1, precision=1,
178 description='Radio of the arch',
180 arc_width = bpy.props.FloatProperty(
181 name='Thickness',
182 min=0.01, max=10, default=0.15, precision=2,
183 description='Thickness of the arch wall',
185 arc_gap = bpy.props.FloatProperty(
186 name='Arc gap',
187 min=0.01, max=10, default=0.25, precision=2,
188 description='Size of the gap in the arch sides',
191 crt_mat = bpy.props.BoolProperty(
192 name="Create default Cycles materials",
193 description="Create default materials for Cycles render",
194 default=True,
196 crt_array = bpy.props.BoolProperty(
197 name="Create array of elements",
198 description="Create a modifier array for all elemnst",
199 default=False,
201 array_num_x = bpy.props.IntProperty(
202 name='Count X',
203 min=0, max=100, default=3,
204 description='Number of elements in array',
206 array_space_x = bpy.props.FloatProperty(
207 name='Distance X',
208 min=0.000, max=10, default=1, precision=3,
209 description='Distance between elements (only arc disabled)',
211 array_num_y = bpy.props.IntProperty(
212 name='Count Y',
213 min=0, max=100, default=0,
214 description='Number of elements in array',
216 array_space_y = bpy.props.FloatProperty(
217 name='Distance Y',
218 min=0.000, max=10, default=1, precision=3,
219 description='Distance between elements (only arc disabled)',
221 array_space_z = bpy.props.FloatProperty(
222 name='Distance Z',
223 min=-10, max=10, default=0, precision=3,
224 description='Combined X/Z distance between elements (only arc disabled)',
226 ramp = bpy.props.BoolProperty(
227 name="Deform",
228 description="Deform top base with Z displacement", default=True,
230 array_space_factor = bpy.props.FloatProperty(
231 name='Move Y center',
232 min=0.00, max=1, default=0.0, precision=3,
233 description='Move the center of the arch in Y axis. (0 centered)',
236 # -----------------------------------------------------
237 # Draw (create UI interface)
238 # -----------------------------------------------------
239 # noinspection PyUnusedLocal
240 def draw(self, context):
241 layout = self.layout
242 space = bpy.context.space_data
243 if not space.local_view:
244 # Imperial units warning
245 if bpy.context.scene.unit_settings.system == "IMPERIAL":
246 row = layout.row()
247 row.label("Warning: Imperial units not supported", icon='COLOR_RED')
248 box = layout.box()
249 box.prop(self, 'model')
250 # Circular
251 if self.model == "1":
252 box.prop(self, 'keep_size')
253 box.prop(self, 'rad_top')
254 if self.keep_size is False:
255 row = box.row()
256 row.prop(self, 'rad_mid')
257 row.prop(self, 'shift')
258 box.prop(self, 'rad_bottom')
260 # Rectangular
261 if self.model == "2":
262 box.prop(self, 'col_sx')
263 box.prop(self, 'col_sy')
265 box.prop(self, 'col_height')
267 box = layout.box()
268 box.prop(self, 'box_base')
269 if self.box_base is True:
270 row = box.row()
271 row.prop(self, 'box_base_x')
272 row.prop(self, 'box_base_y')
273 row.prop(self, 'box_base_z')
275 box = layout.box()
276 box.prop(self, 'box_top')
277 if self.box_top is True:
278 row = box.row()
279 row.prop(self, 'box_top_x')
280 row.prop(self, 'box_top_y')
281 row.prop(self, 'box_top_z')
283 box = layout.box()
284 box.prop(self, 'cir_base')
285 if self.cir_base is True:
286 row = box.row()
287 row.prop(self, 'cir_base_r')
288 row.prop(self, 'cir_base_z')
290 box = layout.box()
291 box.prop(self, 'cir_top')
292 if self.cir_top is True:
293 row = box.row()
294 row.prop(self, 'cir_top_r')
295 row.prop(self, 'cir_top_z')
297 box = layout.box()
298 box.prop(self, 'arc_top')
299 if self.arc_top is True:
300 row = box.row()
301 row.prop(self, 'arc_radio')
302 row.prop(self, 'arc_width')
303 row = box.row()
304 row.prop(self, 'arc_gap')
305 row.prop(self, 'array_space_factor')
307 box = layout.box()
308 box.prop(self, 'crt_array')
309 if self.crt_array is True:
310 row = box.row()
311 row.prop(self, 'array_num_x')
312 row.prop(self, 'array_num_y')
313 if self.arc_top is True:
314 box.label("Use arch radio and thickness to set distances")
316 if self.arc_top is False:
317 row = box.row()
318 row.prop(self, 'array_space_x')
319 row.prop(self, 'array_space_y')
320 row = box.row()
321 row.prop(self, 'array_space_z')
322 row.prop(self, 'ramp')
324 box = layout.box()
325 if not context.scene.render.engine == 'CYCLES':
326 box.enabled = False
327 box.prop(self, 'crt_mat')
328 else:
329 row = layout.row()
330 row.label("Warning: Operator does not work in local view mode", icon='ERROR')
332 # -----------------------------------------------------
333 # Execute
334 # -----------------------------------------------------
335 # noinspection PyUnusedLocal
336 def execute(self, context):
337 if bpy.context.mode == "OBJECT":
338 create_column_mesh(self)
339 return {'FINISHED'}
340 else:
341 self.report({'WARNING'}, "Archimesh: Option only valid in Object mode")
342 return {'CANCELLED'}
345 # ------------------------------------------------------------------------------
346 # Generate mesh data
347 # All custom values are passed using self container (self.myvariable)
348 # ------------------------------------------------------------------------------
349 def create_column_mesh(self):
350 myarc = None
351 cir_top = None
352 cir_bottom = None
353 box_top = None
354 box_bottom = None
355 mycolumn = None
356 # deactivate others
357 for o in bpy.data.objects:
358 if o.select is True:
359 o.select = False
361 bpy.ops.object.select_all(False)
363 radio_top = self.rad_top
364 if self.keep_size is True:
365 radio_mid = radio_top
366 radio_bottom = radio_top
367 else:
368 radio_mid = self.rad_mid
369 radio_bottom = self.rad_bottom
371 # Calculate height
372 height = self.col_height
373 if self.box_base:
374 height = height - self.box_base_z
375 if self.box_top:
376 height = height - self.box_top_z
377 # ------------------------
378 # Create circular column
379 # ------------------------
380 if self.model == "1":
381 bpy.ops.object.select_all(False)
382 mycolumn = create_circular_column(self, "Column", radio_top, radio_mid, radio_bottom, height)
383 mycolumn.select = True
384 bpy.context.scene.objects.active = mycolumn
385 # Subsurf
386 set_smooth(mycolumn)
387 set_modifier_subsurf(mycolumn)
388 # ------------------------
389 # Create rectangular column
390 # ------------------------
391 if self.model == "2":
392 mycolumn = create_rectangular_base(self, "Column", self.col_sx, self.col_sy, height)
393 bpy.ops.object.select_all(False)
394 mycolumn.select = True
395 bpy.context.scene.objects.active = mycolumn
396 set_normals(mycolumn)
397 # ------------------------
398 # Circular base
399 # ------------------------
400 if self.cir_base is True:
401 cir_bottom = create_torus("Column_cir_bottom", radio_bottom, self.cir_base_r, self.cir_base_z)
402 bpy.ops.object.select_all(False)
403 cir_bottom.select = True
404 bpy.context.scene.objects.active = cir_bottom
405 set_modifier_subsurf(cir_bottom)
406 set_smooth(cir_bottom)
407 cir_bottom.location.x = 0.0
408 cir_bottom.location.y = 0.0
409 cir_bottom.location.z = self.cir_base_z / 2
410 cir_bottom.parent = mycolumn
412 # ------------------------
413 # Rectangular base
414 # ------------------------
415 if self.box_base is True:
416 box_bottom = create_rectangular_base(self, "Column_box_bottom", self.box_base_x, self.box_base_y,
417 self.box_base_z)
418 bpy.ops.object.select_all(False)
419 box_bottom.select = True
420 bpy.context.scene.objects.active = box_bottom
421 box_bottom.parent = mycolumn
422 set_normals(box_bottom)
423 box_bottom.location.x = 0.0
424 box_bottom.location.y = 0.0
425 box_bottom.location.z = - self.box_base_z
426 # move column
427 mycolumn.location.z += self.box_base_z
429 # ------------------------
430 # Circular top
431 # ------------------------
432 if self.cir_top is True:
433 cir_top = create_torus("Column_cir_top", radio_top, self.cir_top_r, self.cir_top_z)
434 bpy.ops.object.select_all(False)
435 cir_top.select = True
436 bpy.context.scene.objects.active = cir_top
437 set_modifier_subsurf(cir_top)
438 set_smooth(cir_top)
439 cir_top.parent = mycolumn
440 cir_top.location.x = 0.0
441 cir_top.location.y = 0.0
442 cir_top.location.z = height - self.cir_top_z / 2
444 # ------------------------
445 # Rectangular top
446 # ------------------------
447 if self.box_top is True:
448 box_top = create_rectangular_base(self, "Column_box_top", self.box_top_x, self.box_top_y,
449 self.box_top_z, self.ramp)
450 bpy.ops.object.select_all(False)
451 box_top.select = True
452 bpy.context.scene.objects.active = box_top
453 set_normals(box_top)
454 box_top.parent = mycolumn
455 box_top.location.x = 0.0
456 box_top.location.y = 0.0
457 box_top.location.z = height
459 # ------------------------
460 # Create arc
461 # ------------------------
462 if self.arc_top:
463 myarc = create_arc("Column_arch", self.arc_radio, self.arc_gap, self.arc_width,
464 self.array_space_factor)
465 myarc.parent = mycolumn
466 bpy.ops.object.select_all(False)
467 myarc.select = True
468 bpy.context.scene.objects.active = myarc
469 set_normals(myarc)
470 set_modifier_mirror(myarc, "X")
471 myarc.location.x = self.arc_radio + self.arc_gap
472 myarc.location.y = 0.0
473 if self.box_top is True:
474 myarc.location.z = height + self.box_top_z
475 else:
476 myarc.location.z = height
477 # ------------------------
478 # Create Array X
479 # ------------------------
480 if self.array_num_x > 0:
481 if self.arc_top:
482 distance = ((self.arc_radio + self.arc_gap) * 2)
483 zmove = 0
484 else:
485 distance = self.array_space_x
486 zmove = self.array_space_z
488 if self.crt_array:
489 set_modifier_array(mycolumn, "X", 0, self.array_num_x, True, distance, zmove)
491 if self.box_base is True:
492 set_modifier_array(box_bottom, "X", 0, self.array_num_x, True, distance, zmove)
493 if self.box_top is True:
494 set_modifier_array(box_top, "X", 0, self.array_num_x, True, distance, zmove)
496 if self.cir_base is True:
497 set_modifier_array(cir_bottom, "X", 0, self.array_num_x, True, distance, zmove)
498 if self.cir_top is True:
499 set_modifier_array(cir_top, "X", 0, self.array_num_x, True, distance, zmove)
501 if self.arc_top:
502 if self.array_num_x > 1:
503 set_modifier_array(myarc, "X", 1, self.array_num_x - 1) # one arc minus
504 # ------------------------
505 # Create Array Y
506 # ------------------------
507 if self.array_num_y > 0:
508 if self.arc_top:
509 distance = self.arc_width
510 else:
511 distance = self.array_space_y
513 if self.crt_array:
514 set_modifier_array(mycolumn, "Y", 0, self.array_num_y, True, distance)
516 if self.box_base is True:
517 set_modifier_array(box_bottom, "Y", 0, self.array_num_y, True, distance)
518 if self.box_top is True:
519 set_modifier_array(box_top, "Y", 0, self.array_num_y, True, distance)
521 if self.cir_base is True:
522 set_modifier_array(cir_bottom, "Y", 0, self.array_num_y, True, distance)
523 if self.cir_top is True:
524 set_modifier_array(cir_top, "Y", 0, self.array_num_y, True, distance)
526 if self.arc_top:
527 if self.array_num_y > 1:
528 set_modifier_array(myarc, "Y", 1, self.array_num_y - 1) # one less
530 # ------------------------
531 # Create materials
532 # ------------------------
533 if self.crt_mat and bpy.context.scene.render.engine == 'CYCLES':
534 # Column material
535 mat = create_diffuse_material("Column_material", False, 0.748, 0.734, 0.392, 0.573, 0.581, 0.318)
536 set_material(mycolumn, mat)
538 if self.box_base is True or self.box_top is True:
539 mat = create_diffuse_material("Column_rect", False, 0.56, 0.56, 0.56, 0.56, 0.56, 0.56)
540 if self.box_base is True:
541 set_material(box_bottom, mat)
542 if self.box_top is True:
543 set_material(box_top, mat)
545 if self.cir_base is True or self.cir_top is True:
546 mat = create_diffuse_material("Column_cir", False, 0.65, 0.65, 0.65, 0.65, 0.65, 0.65)
547 if self.cir_base is True:
548 set_material(cir_bottom, mat)
549 if self.cir_top is True:
550 set_material(cir_top, mat)
552 if self.arc_top:
553 mat = create_diffuse_material("Column_arch", False, 0.8, 0.8, 0.8)
554 set_material(myarc, mat)
556 bpy.ops.object.select_all(False)
557 mycolumn.select = True
558 bpy.context.scene.objects.active = mycolumn
560 return
563 # ------------------------------------------------------------------------------
564 # Create Column
565 # ------------------------------------------------------------------------------
566 def create_circular_column(self, objname, radio_top, radio_mid, radio_bottom, height):
567 myvertex = []
568 myfaces = []
569 pies = [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330] # circle
571 # Add bottom circle
572 for pie in pies:
573 x = cos(radians(pie)) * radio_bottom
574 y = sin(radians(pie)) * radio_bottom
575 mypoint = [(x, y, 0.0)]
576 myvertex.extend(mypoint)
577 # Add middle circle
578 for pie in pies:
579 x = cos(radians(pie)) * radio_mid
580 y = sin(radians(pie)) * radio_mid
581 mypoint = [(x, y, (height / 2) + ((height / 2) * self.shift))]
582 myvertex.extend(mypoint)
583 # Add top circle
584 for pie in pies:
585 x = cos(radians(pie)) * radio_top
586 y = sin(radians(pie)) * radio_top
587 mypoint = [(x, y, height)]
588 myvertex.extend(mypoint)
589 # -------------------------------------
590 # Faces
591 # -------------------------------------
592 t = 1
593 for n in range(0, len(pies) * 2):
594 t += 1
595 if t > len(pies):
596 t = 1
597 myface = [(n, n - len(pies) + 1, n + 1, n + len(pies))]
598 myfaces.extend(myface)
599 else:
600 myface = [(n, n + 1, n + len(pies) + 1, n + len(pies))]
601 myfaces.extend(myface)
603 mesh = bpy.data.meshes.new(objname)
604 myobject = bpy.data.objects.new(objname, mesh)
606 myobject.location = bpy.context.scene.cursor_location
607 bpy.context.scene.objects.link(myobject)
609 mesh.from_pydata(myvertex, [], myfaces)
610 mesh.update(calc_edges=True)
612 return myobject
615 # ------------------------------------------------------------------------------
616 # Create Torus
617 # ------------------------------------------------------------------------------
618 def create_torus(objname, radio_inside, radio_outside, height):
619 myvertex = []
620 myfaces = []
621 pies = [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330] # circle
622 segments = [80, 60, 30, 0, 330, 300, 280] # section
624 radio_mid = radio_outside + radio_inside - (height / 2)
625 # Add internal circles Top
626 for pie in pies:
627 x = cos(radians(pie)) * radio_inside
628 y = sin(radians(pie)) * radio_inside
629 mypoint = [(x, y, height / 2)]
630 myvertex.extend(mypoint)
631 # Add external circles Top
632 for pie in pies:
633 x = cos(radians(pie)) * radio_mid
634 y = sin(radians(pie)) * radio_mid
635 mypoint = [(x, y, height / 2)]
636 myvertex.extend(mypoint)
637 # Add Intermediate lines
638 for segment in segments:
639 for pie in pies:
640 radio_externo = radio_mid + (height * cos(radians(segment)))
641 x = cos(radians(pie)) * radio_externo
642 y = sin(radians(pie)) * radio_externo
643 z = sin(radians(segment)) * (height / 2)
645 mypoint = [(x, y, z)]
646 myvertex.extend(mypoint)
648 # Add internal circles Bottom
649 for pie in pies:
650 x = cos(radians(pie)) * radio_inside
651 y = sin(radians(pie)) * radio_inside
652 mypoint = [(x, y, height / 2 * -1)]
653 myvertex.extend(mypoint)
654 # Add external circles bottom
655 for pie in pies:
656 x = cos(radians(pie)) * radio_mid
657 y = sin(radians(pie)) * radio_mid
658 mypoint = [(x, y, height / 2 * -1)]
659 myvertex.extend(mypoint)
661 # -------------------------------------
662 # Faces
663 # -------------------------------------
664 t = 1
665 for n in range(0, len(pies) * len(segments) + (len(pies) * 2)):
666 t += 1
667 if t > len(pies):
668 t = 1
669 myface = [(n, n - len(pies) + 1, n + 1, n + len(pies))]
670 myfaces.extend(myface)
671 else:
672 myface = [(n, n + 1, n + len(pies) + 1, n + len(pies))]
673 myfaces.extend(myface)
675 mesh = bpy.data.meshes.new(objname)
676 myobject = bpy.data.objects.new(objname, mesh)
678 myobject.location = bpy.context.scene.cursor_location
679 bpy.context.scene.objects.link(myobject)
681 mesh.from_pydata(myvertex, [], myfaces)
682 mesh.update(calc_edges=True)
684 return myobject
687 # ------------------------------------------------------------------------------
688 # Create rectangular base
689 # ------------------------------------------------------------------------------
690 def create_rectangular_base(self, objname, x, y, z, ramp=False):
691 elements = self.array_num_x - 1
692 height = self.array_space_z * elements
693 width = self.array_space_x * elements
694 if width > 0:
695 angle = atan(height / width)
696 else:
697 angle = 0
699 radio = sqrt((x * x) + (self.array_space_z * self.array_space_z))
700 disp = radio * sin(angle)
702 if ramp is False or self.arc_top:
703 addz1 = 0
704 addz2 = 0
705 else:
706 if self.array_space_z >= 0:
707 addz1 = 0
708 addz2 = disp
709 else:
710 addz1 = disp * -1
711 addz2 = 0
713 myvertex = [(-x / 2, -y / 2, 0.0),
714 (-x / 2, y / 2, 0.0),
715 (x / 2, y / 2, 0.0),
716 (x / 2, -y / 2, 0.0),
717 (-x / 2, -y / 2, z + addz1),
718 (-x / 2, y / 2, z + addz1),
719 (x / 2, y / 2, z + addz2),
720 (x / 2, -y / 2, z + addz2)]
722 myfaces = [(0, 1, 2, 3), (0, 1, 5, 4), (1, 2, 6, 5), (2, 6, 7, 3), (5, 6, 7, 4), (0, 4, 7, 3)]
724 mesh = bpy.data.meshes.new(objname)
725 myobject = bpy.data.objects.new(objname, mesh)
727 myobject.location = bpy.context.scene.cursor_location
728 bpy.context.scene.objects.link(myobject)
730 mesh.from_pydata(myvertex, [], myfaces)
731 mesh.update(calc_edges=True)
733 return myobject
736 # ------------------------------------------------------------------------------
737 # Create arc
738 # ------------------------------------------------------------------------------
739 def create_arc(objname, radio, gap, thickness, center):
740 myvertex = []
742 half = (thickness / 2)
743 move = half * center
745 listdata = [half + move, -half + move]
746 for pos_y in listdata:
747 # --------------------------------
748 # First vertices
749 # --------------------------------
750 myvertex.extend([(-radio - gap, pos_y, radio + radio / 10)])
751 # Flat cuts
752 angle = 13 * (180 / 16)
753 for i in range(1, 4):
754 z = sin(radians(angle)) * radio
755 mypoint = [(-radio - gap, pos_y, z)]
756 myvertex.extend(mypoint)
757 angle += 180 / 16
759 myvertex.extend([(-radio - gap, pos_y, 0.0)])
760 # --------------------------------
761 # Arc points
762 # --------------------------------
763 angle = 180
764 for i in range(0, 9):
765 x = cos(radians(angle)) * radio
766 z = sin(radians(angle)) * radio
767 mypoint = [(x, pos_y, z)]
768 myvertex.extend(mypoint)
770 angle -= 180 / 16
771 # --------------------------------
772 # vertical cut points
773 # --------------------------------
774 angle = 8 * (180 / 16)
775 for i in range(1, 5):
776 x = cos(radians(angle)) * radio
777 mypoint = [(x, pos_y, radio + radio / 10)]
778 myvertex.extend(mypoint)
780 angle += 180 / 16
782 myfaces = [(23, 24, 21, 22), (24, 25, 20, 21), (25, 26, 19, 20), (27, 18, 19, 26), (18, 27, 28, 35),
783 (28, 29, 34, 35), (29, 30, 33, 34), (30, 31, 32, 33), (12, 13, 31, 30), (29, 11, 12, 30),
784 (11, 29, 28, 10), (10, 28, 27, 9), (9, 27, 26, 8), (25, 7, 8, 26), (24, 6, 7, 25),
785 (23, 5, 6, 24), (22, 4, 5, 23), (5, 4, 3, 6), (6, 3, 2, 7), (7, 2, 1, 8),
786 (8, 1, 0, 9), (9, 0, 17, 10), (10, 17, 16, 11), (11, 16, 15, 12), (14, 13, 12, 15),
787 (21, 3, 4, 22), (20, 2, 3, 21), (19, 1, 2, 20), (1, 19, 18, 0), (0, 18, 35, 17),
788 (17, 35, 34, 16), (33, 15, 16, 34), (32, 14, 15, 33)]
790 mesh = bpy.data.meshes.new(objname)
791 myobject = bpy.data.objects.new(objname, mesh)
793 myobject.location = bpy.context.scene.cursor_location
794 bpy.context.scene.objects.link(myobject)
796 mesh.from_pydata(myvertex, [], myfaces)
797 mesh.update(calc_edges=True)
799 return myobject