Update for changes in Blender's API
[blender-addons.git] / archimesh / achm_lamp_maker.py
bloba6b154356a85f9a88abbda1ef5486453f7da87c2
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 lamps
23 # Author: Antonio Vazquez (antonioya)
25 # ----------------------------------------------------------
26 import bpy
27 from math import cos, sin, radians
28 from copy import copy
29 from bpy.types import Operator
30 from bpy.props import EnumProperty, FloatProperty, IntProperty, BoolProperty, FloatVectorProperty
31 from .achm_tools import *
34 # ------------------------------------------------------
35 # set predefined designs
37 # self: self container
38 # ------------------------------------------------------
39 def set_preset(self):
40 # -----------------------
41 # Sphere
42 # -----------------------
43 if self.preset == "1":
44 self.base_height = 0.22
45 self.base_segments = 16
46 self.base_rings = 6
47 self.smooth = True
48 self.subdivide = True
49 self.br01 = 0.05
50 self.br02 = 0.07
51 self.br03 = 0.11
52 self.br04 = 0.11
53 self.br05 = 0.07
54 self.br06 = 0.03
56 self.bz01 = 0
57 self.bz02 = -1
58 self.bz03 = -0.456
59 self.bz04 = 0.089
60 self.bz05 = -0.038
61 self.bz06 = -0.165
62 # -----------------------
63 # Pear
64 # -----------------------
65 if self.preset == "2":
66 self.base_height = 0.20
67 self.base_segments = 16
68 self.base_rings = 6
69 self.smooth = True
70 self.subdivide = True
71 self.br01 = 0.056
72 self.br02 = 0.062
73 self.br03 = 0.072
74 self.br04 = 0.090
75 self.br05 = 0.074
76 self.br06 = 0.03
78 self.bz01 = 0
79 self.bz02 = 0
80 self.bz03 = 0
81 self.bz04 = 0
82 self.bz05 = 0
83 self.bz06 = 0
84 # -----------------------
85 # Vase
86 # -----------------------
87 if self.preset == "3":
88 self.base_height = 0.20
89 self.base_segments = 8
90 self.base_rings = 6
91 self.smooth = True
92 self.subdivide = True
93 self.br01 = 0.05
94 self.br02 = 0.11
95 self.br03 = 0.15
96 self.br04 = 0.07
97 self.br05 = 0.05
98 self.br06 = 0.03
100 self.bz01 = 0
101 self.bz02 = 0
102 self.bz03 = 0
103 self.bz04 = 0
104 self.bz05 = 0
105 self.bz06 = 0
106 # -----------------------
107 # Rectangular
108 # -----------------------
109 if self.preset == "4":
110 self.base_height = 0.15
111 self.base_segments = 4
112 self.base_rings = 5
113 self.smooth = False
114 self.subdivide = False
115 self.br01 = 0.08
116 self.br02 = 0.08
117 self.br03 = 0.08
118 self.br04 = 0.08
119 self.br05 = 0.03
121 self.bz01 = 0
122 self.bz02 = 0
123 self.bz03 = 0
124 self.bz04 = 0.25
125 self.bz05 = 0
128 # ------------------------------------------------------------------
129 # Define UI class
130 # Lamps
131 # ------------------------------------------------------------------
132 class AchmLamp(Operator):
133 bl_idname = "mesh.archimesh_lamp"
134 bl_label = "Lamp"
135 bl_description = "Lamp Generator"
136 bl_category = 'Archimesh'
137 bl_options = {'REGISTER', 'UNDO'}
138 # preset
139 preset = EnumProperty(
140 items=(
141 ('0', "None", ""),
142 ('1', "Sphere", ""),
143 ('2', "Pear", ""),
144 ('3', "Vase", ""),
145 ('4', "Rectangular", ""),
147 name="Predefined",
148 description="Apply predefined design",
150 oldpreset = preset
152 base_height = FloatProperty(
153 name='Height',
154 min=0.01, max=10, default=0.20, precision=3,
155 description='lamp base height',
157 base_segments = IntProperty(
158 name='Segments',
159 min=3, max=128, default=16,
160 description='Number of segments (vertical)',
162 base_rings = IntProperty(
163 name='Rings',
164 min=2, max=12, default=6,
165 description='Number of rings (horizontal)',
167 holder = FloatProperty(
168 name='Lampholder',
169 min=0.001, max=10, default=0.02, precision=3,
170 description='Lampholder height',
172 smooth = BoolProperty(
173 name="Smooth",
174 description="Use smooth shader",
175 default=True,
177 subdivide = BoolProperty(
178 name="Subdivide",
179 description="Add subdivision modifier",
180 default=True,
183 bz01 = FloatProperty(name='S1', min=-1, max=1, default=0, precision=3, description='Z shift factor')
184 bz02 = FloatProperty(name='S2', min=-1, max=1, default=0, precision=3, description='Z shift factor')
185 bz03 = FloatProperty(name='S3', min=-1, max=1, default=0, precision=3, description='Z shift factor')
186 bz04 = FloatProperty(name='S4', min=-1, max=1, default=0, precision=3, description='Z shift factor')
187 bz05 = FloatProperty(name='S5', min=-1, max=1, default=0, precision=3, description='Z shift factor')
188 bz06 = FloatProperty(name='S6', min=-1, max=1, default=0, precision=3, description='Z shift factor')
189 bz07 = FloatProperty(name='S7', min=-1, max=1, default=0, precision=3, description='Z shift factor')
190 bz08 = FloatProperty(name='S8', min=-1, max=1, default=0, precision=3, description='Z shift factor')
191 bz09 = FloatProperty(name='S9', min=-1, max=1, default=0, precision=3, description='Z shift factor')
192 bz10 = FloatProperty(name='S10', min=-1, max=1, default=0, precision=3, description='Z shift factor')
193 bz11 = FloatProperty(name='S11', min=-1, max=1, default=0, precision=3, description='Z shift factor')
194 bz12 = FloatProperty(name='S12', min=-1, max=1, default=0, precision=3, description='Z shift factor')
196 br01 = FloatProperty(name='R1', min=0.001, max=10, default=0.06, precision=3, description='Ring radio')
197 br02 = FloatProperty(name='R2', min=0.001, max=10, default=0.08, precision=3, description='Ring radio')
198 br03 = FloatProperty(name='R3', min=0.001, max=10, default=0.09, precision=3, description='Ring radio')
199 br04 = FloatProperty(name='R4', min=0.001, max=10, default=0.08, precision=3, description='Ring radio')
200 br05 = FloatProperty(name='R5', min=0.001, max=10, default=0.06, precision=3, description='Ring radio')
201 br06 = FloatProperty(name='R6', min=0.001, max=10, default=0.03, precision=3, description='Ring radio')
202 br07 = FloatProperty(name='R7', min=0.001, max=10, default=0.10, precision=3, description='Ring radio')
203 br08 = FloatProperty(name='R8', min=0.001, max=10, default=0.10, precision=3, description='Ring radio')
204 br09 = FloatProperty(name='R9', min=0.001, max=10, default=0.10, precision=3, description='Ring radio')
205 br10 = FloatProperty(name='R10', min=0.001, max=10, default=0.10, precision=3, description='Ring radio')
206 br11 = FloatProperty(name='R11', min=0.001, max=10, default=0.10, precision=3, description='Ring radio')
207 br12 = FloatProperty(name='R12', min=0.001, max=10, default=0.10, precision=3, description='Ring radio')
209 top_height = FloatProperty(
210 name='Height', min=0.01, max=10,
211 default=0.20, precision=3,
212 description='lampshade height',
214 top_segments = IntProperty(
215 name='Segments', min=3, max=128,
216 default=32,
217 description='Number of segments (vertical)',
219 tr01 = FloatProperty(
220 name='R1', min=0.001, max=10,
221 default=0.16, precision=3,
222 description='lampshade bottom radio',
224 tr02 = FloatProperty(name='R2', min=0.001, max=10,
225 default=0.08, precision=3,
226 description='lampshade top radio')
227 pleats = BoolProperty(
228 name="Pleats", description="Create pleats in the lampshade",
229 default=False,
231 tr03 = FloatProperty(
232 name='R3', min=0.001, max=1,
233 default=0.01, precision=3, description='Pleats size',
235 energy = FloatProperty(
236 name='Light', min=0.00, max=1000,
237 default=15, precision=3,
238 description='Light intensity',
240 opacity = FloatProperty(
241 name='Translucency', min=0.00, max=1,
242 default=0.3, precision=3,
243 description='Lampshade translucency factor (1 completely translucent)',
246 # Materials
247 crt_mat = BoolProperty(
248 name="Create default Cycles materials",
249 description="Create default materials for Cycles render",
250 default=True,
252 objcol = FloatVectorProperty(
253 name="Color",
254 description="Color for material",
255 default=(1.0, 1.0, 1.0, 1.0),
256 min=0.1, max=1,
257 subtype='COLOR',
258 size=4,
261 # -----------------------------------------------------
262 # Draw (create UI interface)
263 # -----------------------------------------------------
264 # noinspection PyUnusedLocal
265 def draw(self, context):
266 layout = self.layout
267 space = bpy.context.space_data
268 if not space.local_view:
269 # Imperial units warning
270 if bpy.context.scene.unit_settings.system == "IMPERIAL":
271 row = layout.row()
272 row.label("Warning: Imperial units not supported", icon='COLOR_RED')
274 box = layout.box()
275 box.label("Lamp base")
276 row = box.row()
277 row.prop(self, 'preset')
278 row = box.row()
279 row.prop(self, 'base_height')
280 row.prop(self, 'base_segments')
281 row.prop(self, 'base_rings')
282 row = box.row()
283 row.prop(self, 'smooth')
284 row.prop(self, 'subdivide')
285 row = box.row()
286 row.prop(self, 'holder')
288 if self.base_rings >= 1:
289 row = box.row()
290 row.prop(self, 'br01')
291 row.prop(self, 'bz01', slider=True)
292 if self.base_rings >= 2:
293 row = box.row()
294 row.prop(self, 'br02')
295 row.prop(self, 'bz02', slider=True)
296 if self.base_rings >= 3:
297 row = box.row()
298 row.prop(self, 'br03')
299 row.prop(self, 'bz03', slider=True)
301 if self.base_rings >= 4:
302 row = box.row()
303 row.prop(self, 'br04')
304 row.prop(self, 'bz04', slider=True)
305 if self.base_rings >= 5:
306 row = box.row()
307 row.prop(self, 'br05')
308 row.prop(self, 'bz05', slider=True)
309 if self.base_rings >= 6:
310 row = box.row()
311 row.prop(self, 'br06')
312 row.prop(self, 'bz06', slider=True)
314 if self.base_rings >= 7:
315 row = box.row()
316 row.prop(self, 'br07')
317 row.prop(self, 'bz07', slider=True)
318 if self.base_rings >= 8:
319 row = box.row()
320 row.prop(self, 'br08')
321 row.prop(self, 'bz08', slider=True)
322 if self.base_rings >= 9:
323 row = box.row()
324 row.prop(self, 'br09')
325 row.prop(self, 'bz09', slider=True)
327 if self.base_rings >= 10:
328 row = box.row()
329 row.prop(self, 'br10')
330 row.prop(self, 'bz10', slider=True)
331 if self.base_rings >= 11:
332 row = box.row()
333 row.prop(self, 'br11')
334 row.prop(self, 'bz11', slider=True)
335 if self.base_rings >= 12:
336 row = box.row()
337 row.prop(self, 'br12')
338 row.prop(self, 'bz12', slider=True)
340 box = layout.box()
341 box.label("Lampshade")
342 row = box.row()
343 row.prop(self, 'top_height')
344 row.prop(self, 'top_segments')
345 row = box.row()
346 row.prop(self, 'tr01')
347 row.prop(self, 'tr02')
348 row = box.row()
349 row.prop(self, 'energy')
350 row.prop(self, 'opacity', slider=True)
351 row = box.row()
352 row.prop(self, 'pleats')
353 if self.pleats:
354 row.prop(self, 'tr03')
356 box = layout.box()
357 if not context.scene.render.engine == 'CYCLES':
358 box.enabled = False
359 box.prop(self, 'crt_mat')
360 if self.crt_mat:
361 row = box.row()
362 row.prop(self, 'objcol')
363 else:
364 row = layout.row()
365 row.label("Warning: Operator does not work in local view mode", icon='ERROR')
367 # -----------------------------------------------------
368 # Execute
369 # -----------------------------------------------------
370 # noinspection PyUnusedLocal
371 def execute(self, context):
372 if bpy.context.mode == "OBJECT":
373 if self.oldpreset != self.preset:
374 set_preset(self)
375 self.oldpreset = self.preset
377 # Create lamp
378 create_lamp_mesh(self)
379 return {'FINISHED'}
380 else:
381 self.report({'WARNING'}, "Archimesh: Option only valid in Object mode")
382 return {'CANCELLED'}
385 # ------------------------------------------------------------------------------
386 # Generate mesh data
387 # All custom values are passed using self container (self.myvariable)
388 # ------------------------------------------------------------------------------
389 def create_lamp_mesh(self):
390 # deactivate others
391 for o in bpy.data.objects:
392 if o.select is True:
393 o.select = False
394 bpy.ops.object.select_all(False)
395 generate_lamp(self)
397 return
400 # ------------------------------------------------------------------------------
401 # Generate lamps
402 # All custom values are passed using self container (self.myvariable)
403 # ------------------------------------------------------------------------------
404 def generate_lamp(self):
405 location = bpy.context.scene.cursor_location
406 myloc = copy(location) # copy location to keep 3D cursor position
407 # ---------------------
408 # Lamp base
409 # ---------------------
410 mydata = create_lamp_base("Lamp_base", self.base_height,
411 myloc.x, myloc.y, myloc.z,
412 self.base_segments, self.base_rings,
413 [self.br01, self.br02, self.br03, self.br04, self.br05, self.br06,
414 self.br07, self.br08, self.br09, self.br10, self.br11, self.br12],
415 (self.bz01, self.bz02, self.bz03, self.bz04, self.bz05, self.bz06,
416 self.bz07, self.bz08, self.bz09, self.bz10, self.bz11, self.bz12),
417 self.subdivide,
418 self.crt_mat, self.objcol)
419 mybase = mydata[0]
420 posz = mydata[1]
421 # refine
422 remove_doubles(mybase)
423 set_normals(mybase)
424 # Smooth
425 if self.smooth:
426 set_smooth(mybase)
427 if self.subdivide:
428 set_modifier_subsurf(mybase)
429 # ---------------------
430 # Lampholder
431 # ---------------------
432 myholder = create_lampholder("Lampholder", self.holder,
433 myloc.x, myloc.y, myloc.z,
434 self.crt_mat)
435 # refine
436 remove_doubles(myholder)
437 set_normals(myholder)
438 set_smooth(myholder)
440 myholder.parent = mybase
441 myholder.location.x = 0
442 myholder.location.y = 0
443 myholder.location.z = posz
444 # ---------------------
445 # Lamp strings
446 # ---------------------
447 mystrings = create_lampholder_strings("Lampstrings", self.holder,
448 myloc.x, myloc.y, myloc.z,
449 self.tr02,
450 self.top_height,
451 self.crt_mat)
452 # refine
453 remove_doubles(mystrings)
454 set_normals(mystrings)
456 mystrings.parent = myholder
457 mystrings.location.x = 0
458 mystrings.location.y = 0
459 mystrings.location.z = 0.03
460 # ---------------------
461 # Lampshade
462 # ---------------------
463 mytop = create_lampshade("Lampshade", self.top_height,
464 myloc.x, myloc.y, myloc.z,
465 self.top_segments,
466 self.tr01, self.tr02,
467 self.pleats, self.tr03,
468 self.opacity,
469 self.crt_mat)
470 # refine
471 remove_doubles(mytop)
472 set_normals(mytop)
473 if self.pleats is False:
474 set_smooth(mytop)
476 mytop.parent = mybase
477 mytop.location.x = 0
478 mytop.location.y = 0
479 mytop.location.z = posz + self.holder
480 # ---------------------
481 # Light bulb
482 # ---------------------
483 radbulb = 0.02
484 bpy.ops.mesh.primitive_uv_sphere_add(segments=16, size=radbulb)
485 mybulb = bpy.data.objects[bpy.context.active_object.name]
486 mybulb.name = "Lamp_Bulb"
487 mybulb.parent = myholder
488 mybulb.location = (0, 0, radbulb + self.holder + 0.04)
489 if self.crt_mat and bpy.context.scene.render.engine == 'CYCLES':
490 mat = create_emission_material(mybulb.name, True, 0.8, 0.8, 0.8, self.energy)
491 set_material(mybulb, mat)
493 # deactivate others
494 for o in bpy.data.objects:
495 if o.select is True:
496 o.select = False
498 mybase.select = True
499 bpy.context.scene.objects.active = mybase
501 return
504 # ------------------------------------------------------------------------------
505 # Create lamp base
507 # objName: Name for the new object
508 # height: Size in Z axis
509 # pX: position X axis
510 # pY: position Y axis
511 # pZ: position Z axis
512 # segments: number of segments
513 # rings: number of rings
514 # radios: ring radios
515 # ratios: Z shift ratios
516 # subdivide: Subdivision flag
517 # mat: Flag for creating materials
518 # objcol: Color
519 # ------------------------------------------------------------------------------
520 def create_lamp_base(objname, height, px, py, pz, segments, rings, radios, ratios, subdivide, mat, objcol):
521 # Calculate heights
522 h = height / (rings - 1)
523 listheight = []
524 z = 0
525 for f in range(0, rings):
526 listheight.extend([z + (z * ratios[f])])
527 z += h
529 mydata = create_cylinder_data(segments, listheight,
530 radios,
531 True, True, False, 0, subdivide)
532 myvertex = mydata[0]
533 myfaces = mydata[1]
535 mymesh = bpy.data.meshes.new(objname)
536 mycylinder = bpy.data.objects.new(objname, mymesh)
537 bpy.context.scene.objects.link(mycylinder)
539 mymesh.from_pydata(myvertex, [], myfaces)
540 mymesh.update(calc_edges=True)
541 # Position
542 mycylinder.location.x = px
543 mycylinder.location.y = py
544 mycylinder.location.z = pz
545 # Materials
546 if mat and bpy.context.scene.render.engine == 'CYCLES':
547 rgb = objcol
548 mymat = create_diffuse_material(mycylinder.name + "_material", True, rgb[0], rgb[1], rgb[2], rgb[0], rgb[1],
549 rgb[2], 0.1)
550 set_material(mycylinder, mymat)
552 return mycylinder, listheight[len(listheight) - 1]
555 # ------------------------------------------------------------------------------
556 # Create lampholder
558 # objName: Name for the new object
559 # height: Size in Z axis
560 # pX: position X axis
561 # pY: position Y axis
562 # pZ: position Z axis
563 # mat: Flag for creating materials
564 # ------------------------------------------------------------------------------
565 def create_lampholder(objname, height, px, py, pz, mat):
566 mydata = create_cylinder_data(16, [0, height, height + 0.005, height + 0.008, height + 0.05],
567 [0.005, 0.005, 0.010, 0.018, 0.018],
568 False, False, False, 0, False)
569 myvertex = mydata[0]
570 myfaces = mydata[1]
572 mymesh = bpy.data.meshes.new(objname)
573 mycylinder = bpy.data.objects.new(objname, mymesh)
574 bpy.context.scene.objects.link(mycylinder)
576 mymesh.from_pydata(myvertex, [], myfaces)
577 mymesh.update(calc_edges=True)
578 # Position
579 mycylinder.location.x = px
580 mycylinder.location.y = py
581 mycylinder.location.z = pz
583 # Materials
584 if mat and bpy.context.scene.render.engine == 'CYCLES':
585 mat = create_diffuse_material(mycylinder.name + "_material", True, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.1)
586 set_material(mycylinder, mat)
588 return mycylinder
591 # ------------------------------------------------------------------------------
592 # Create lampholder strings
594 # objName: Name for the new object
595 # height: Size in Z axis
596 # pX: position X axis
597 # pY: position Y axis
598 # pZ: position Z axis
599 # radio: radio of lampshade
600 # shadeh: height of lampshader
601 # mat: Flag for creating materials
602 # ------------------------------------------------------------------------------
603 def create_lampholder_strings(objname, height, px, py, pz, radio, shadeh, mat):
604 mydata = create_cylinder_data(32, [height + 0.005, height + 0.005, height + 0.006, height + 0.006],
605 [0.018, 0.025, 0.025, 0.018],
606 False, False, False, 0, False)
607 myvertex = mydata[0]
608 myfaces = mydata[1]
610 mymesh = bpy.data.meshes.new(objname)
611 mycylinder = bpy.data.objects.new(objname, mymesh)
612 bpy.context.scene.objects.link(mycylinder)
614 mymesh.from_pydata(myvertex, [], myfaces)
615 mymesh.update(calc_edges=True)
616 # Position
617 mycylinder.location.x = px
618 mycylinder.location.y = py
619 mycylinder.location.z = pz
620 # Box1
621 box1 = create_box_segments("Lamp_B1", shadeh - 0.036, radio - 0.023)
622 box1.parent = mycylinder
623 box1.location = (0.021, 0, height + 0.004)
624 # Box2
625 box2 = create_box_segments("Lamp_B2", shadeh - 0.036, -radio + 0.023)
626 box2.parent = mycylinder
627 box2.location = (-0.021, 0, height + 0.004)
629 # Materials
630 if mat and bpy.context.scene.render.engine == 'CYCLES':
631 mat = create_diffuse_material(mycylinder.name + "_material", True, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.1)
632 set_material(mycylinder, mat)
633 set_material(box1, mat)
634 set_material(box2, mat)
636 return mycylinder
639 # ------------------------------------------------------------------------------
640 # Create lampshade
642 # objName: Name for the new object
643 # height: Size in Z axis
644 # pX: position X axis
645 # pY: position Y axis
646 # pZ: position Z axis
647 # segments: number of segments
648 # radio1: ring radio 1
649 # radio2: ring radio 2
650 # pleats: flag for pleats
651 # pleatsize: difference in radios (less)
652 # opacity: opacity factor
653 # mat: Flag for creating materials
654 # ------------------------------------------------------------------------------
655 def create_lampshade(objname, height, px, py, pz, segments, radio1, radio2, pleats, pleatsize, opacity, mat):
656 gap = 0.002
657 radios = [radio1 - gap, radio1 - gap, radio1, radio2, radio2 - gap, radio2 - gap]
658 heights = [gap * 2, 0, 0, height, height, height - (gap * 2)]
659 mydata = create_cylinder_data(segments, heights,
660 radios,
661 False, False, pleats, pleatsize, False)
662 myvertex = mydata[0]
663 myfaces = mydata[1]
665 mymesh = bpy.data.meshes.new(objname)
666 mycylinder = bpy.data.objects.new(objname, mymesh)
667 bpy.context.scene.objects.link(mycylinder)
669 mymesh.from_pydata(myvertex, [], myfaces)
670 mymesh.update(calc_edges=True)
671 # Position
672 mycylinder.location.x = px
673 mycylinder.location.y = py
674 mycylinder.location.z = pz
675 # materials
676 if mat and bpy.context.scene.render.engine == 'CYCLES':
677 mymat = create_translucent_material(mycylinder.name + "_material", True, 0.8, 0.65, 0.45, 0.8, 0.65, 0.45,
678 opacity)
679 set_material(mycylinder, mymat)
681 return mycylinder
684 # ------------------------------------------------------------------------------
685 # Create box segments
687 # objName: Name for the new object
688 # height: Size in Z axis
689 # shift: Shift movement
690 # ------------------------------------------------------------------------------
691 def create_box_segments(objname, height, shift):
692 gap = 0.001
693 myvertex = [(0, 0, 0), (0, gap, 0), (gap, gap, 0), (gap, 0, 0),
694 (shift, 0, height),
695 (shift, gap, height),
696 (shift + gap, gap, height),
697 (shift + gap, 0, height)]
698 myfaces = [(6, 5, 1, 2), (7, 6, 2, 3), (4, 7, 3, 0), (1, 5, 4, 0)]
700 mymesh = bpy.data.meshes.new(objname)
701 mysegment = bpy.data.objects.new(objname, mymesh)
702 bpy.context.scene.objects.link(mysegment)
704 mymesh.from_pydata(myvertex, [], myfaces)
705 mymesh.update(calc_edges=True)
706 # Position
707 mysegment.location.x = 0
708 mysegment.location.y = 0
709 mysegment.location.z = 0
711 return mysegment
714 # ------------------------------------------------------------------------------
715 # Create cylinders data
717 # segments: Number of pies
718 # listHeight: list of heights
719 # listRadio: list of radios
720 # top: top face flag
721 # bottom: bottom face flag
722 # pleats: flag for pleats
723 # pleatsize: difference in radios (less)
724 # subdiv: fix subdivision problem
725 # ------------------------------------------------------------------------------
726 def create_cylinder_data(segments, listheight, listradio, bottom, top, pleats, pleatsize, subdiv):
727 myvertex = []
728 myfaces = []
729 if subdiv:
730 # Add at element 0 to fix subdivision problems
731 listheight.insert(0, listheight[0] + 0.001)
732 listradio.insert(0, listradio[0])
733 # Add at last element to fix subdivision problems
734 e = len(listheight) - 1
735 listheight.insert(e, listheight[e] + 0.001)
736 listradio.insert(e, listradio[e])
737 # -------------------------------------
738 # Vertices
739 # -------------------------------------
740 idx = 0
741 rp = 0
742 for z in listheight:
743 seg = 0
744 for i in range(segments):
745 x = cos(radians(seg)) * (listradio[idx] + rp)
746 y = sin(radians(seg)) * (listradio[idx] + rp)
747 mypoint = [(x, y, z)]
748 myvertex.extend(mypoint)
749 seg += 360 / segments
750 # pleats
751 if pleats is True and rp == 0:
752 rp = -pleatsize
753 else:
754 rp = 0
756 idx += 1
757 # -------------------------------------
758 # Faces
759 # -------------------------------------
760 for r in range(0, len(listheight) - 1):
761 s = r * segments
762 t = 1
763 for n in range(0, segments):
764 t += 1
765 if t > segments:
766 t = 1
767 myface = [(n + s, n + s - segments + 1, n + s + 1, n + s + segments)]
768 myfaces.extend(myface)
769 else:
770 myface = [(n + s, n + s + 1, n + s + segments + 1, n + s + segments)]
771 myfaces.extend(myface)
773 # -----------------
774 # bottom face
775 # -----------------
776 if bottom:
777 fa = []
778 for f in range(0, segments):
779 fa.extend([f])
780 myfaces.extend([fa])
781 # -----------------
782 # top face
783 # -----------------
784 if top:
785 fa = []
786 for f in range(len(myvertex) - segments, len(myvertex)):
787 fa.extend([f])
788 myfaces.extend([fa])
790 return myvertex, myfaces