8 "location": "View3D > Tools > PKHG (tab)",
9 "description": "Faces selected will become added faces of different style",
17 from bpy
.types
import Operator
18 from mathutils
import Vector
19 from bpy
.props
import (
28 class MESH_OT_add_faces_to_object(Operator
):
29 bl_idname
= "mesh.add_faces_to_object"
30 bl_label
= "Face Extrude"
31 bl_description
= "Set parameters and build object with added faces"
32 bl_options
= {'REGISTER', 'UNDO', 'PRESET'}
34 reverse_faces
= BoolProperty(
37 description
="Revert the normals of selected faces"
39 name_source_object
= StringProperty(
41 description
="Choose a Source Mesh",
44 remove_start_faces
= BoolProperty(
45 name
="Remove Start Faces",
47 description
="Make a choice about removal of Original Faces"
49 base_height
= FloatProperty(
54 description
="Set general Base Height"
56 use_relative_base_height
= BoolProperty(
57 name
="Relative Base Height",
59 description
="Relative or absolute Base Height"
61 second_height
= FloatProperty(
62 name
="2nd height", min=-5,
65 description
="Second height for various shapes"
67 width
= FloatProperty(
71 description
="Set general width"
73 repeat_extrude
= IntProperty(
77 description
="For longer base"
79 move_inside
= FloatProperty(
84 description
="How much move to inside"
86 thickness
= FloatProperty(
89 soft_max
=5.0, max=20.0,
92 depth
= FloatProperty(
95 soft_max
=5.0, max=20.0,
98 collapse_edges
= BoolProperty(
101 description
="Collapse the vertices of edges"
103 spike_base_width
= FloatProperty(
104 name
="Spike Base Width",
108 description
="Base width of a spike"
110 base_height_inset
= FloatProperty(
111 name
="Base Height Inset",
114 description
="To elevate or drop the Base height Inset"
116 top_spike
= FloatProperty(
120 description
="The Base Height of a spike"
122 top_extra_height
= FloatProperty(
123 name
="Top Extra Height",
126 description
="Add extra height"
128 step_with_real_spike
= BoolProperty(
129 name
="Step with Real Spike",
131 description
="In stepped, use a real spike"
133 use_relative
= BoolProperty(
136 description
="Change size using area, min or max"
138 face_types
= EnumProperty(
140 description
="Different types of Faces",
143 ('no', "Pick an Option", "Choose one of the available options"),
144 ('open_inset', "Open Inset", "Inset without closing faces (holes)"),
145 ('with_base', "With Base", "Base and ..."),
146 ('clsd_vertical', "Closed Vertical", "Closed Vertical"),
147 ('open_vertical', "Open Vertical", "Open Vertical"),
148 ('spiked', "Spiked", "Spike"),
149 ('stepped', "Stepped", "Stepped"),
150 ('boxed', "Boxed", "Boxed"),
151 ('bar', "Bar", "Bar"),
154 strange_boxed_effect
= BoolProperty(
155 name
="Strange Effect",
157 description
="Do not show one extrusion"
159 use_boundary
= BoolProperty(
163 use_even_offset
= BoolProperty(
167 use_relative_offset
= BoolProperty(
168 name
="Relative Offset",
171 use_edge_rail
= BoolProperty(
175 use_outset
= BoolProperty(
179 use_select_inset
= BoolProperty(
183 use_interpolate
= BoolProperty(
189 def poll(cls
, context
):
191 active_object
= context
.active_object
193 mesh_objects_name
= [el
.name
for el
in bpy
.data
.objects
if el
.type == "MESH"]
194 if active_object
.name
in mesh_objects_name
:
199 def draw(self
, context
):
201 col
= layout
.column()
204 col
.label(text
="Using Active Object", icon
="INFO")
206 col
.label("Face Types:")
207 col
.prop(self
, "face_types", text
="")
209 col
.prop(self
, "use_relative")
211 if self
.face_types
== "open_inset":
212 col
.prop(self
, "move_inside")
213 col
.prop(self
, "base_height")
215 elif self
.face_types
== "with_base":
216 col
.prop(self
, "move_inside")
217 col
.prop(self
, "base_height")
218 col
.prop(self
, "second_height")
219 col
.prop(self
, "width")
221 elif self
.face_types
== "clsd_vertical":
222 col
.prop(self
, "base_height")
224 elif self
.face_types
== "open_vertical":
225 col
.prop(self
, "base_height")
227 elif self
.face_types
== "boxed":
228 col
.prop(self
, "move_inside")
229 col
.prop(self
, "base_height")
230 col
.prop(self
, "top_spike")
231 col
.prop(self
, "strange_boxed_effect")
233 elif self
.face_types
== "spiked":
234 col
.prop(self
, "spike_base_width")
235 col
.prop(self
, "base_height_inset")
236 col
.prop(self
, "top_spike")
238 elif self
.face_types
== "bar":
239 col
.prop(self
, "spike_base_width")
240 col
.prop(self
, "top_spike")
241 col
.prop(self
, "top_extra_height")
243 elif self
.face_types
== "stepped":
244 col
.prop(self
, "spike_base_width")
245 col
.prop(self
, "base_height_inset")
246 col
.prop(self
, "top_extra_height")
247 col
.prop(self
, "second_height")
248 col
.prop(self
, "step_with_real_spike")
250 def execute(self
, context
):
251 obj_name
= self
.name_source_object
252 face_type
= self
.face_types
254 is_selected
= check_is_selected()
257 self
.report({'WARNING'},
258 "Operation Cancelled. No selected Faces found on the Active Object")
261 if face_type
== "spiked":
262 Spiked(spike_base_width
=self
.spike_base_width
,
263 base_height_inset
=self
.base_height_inset
,
264 top_spike
=self
.top_spike
, top_relative
=self
.use_relative
)
266 elif face_type
== "boxed":
267 startinfo
= prepare(self
, context
, self
.remove_start_faces
)
270 obj
= startinfo
['obj']
271 obj_matrix_local
= obj
.matrix_local
276 areas
= startinfo
['areas']
277 base_height
= self
.base_height
279 if self
.use_relative
:
280 distance
= [min(t
* area
, 1.0) for i
, area
in enumerate(areas
)]
281 base_heights
= [base_height
* area
for i
, area
in enumerate(areas
)]
283 distance
= [t
] * len(areas
)
284 base_heights
= [base_height
] * len(areas
)
286 rings
= startinfo
['rings']
287 centers
= startinfo
['centers']
288 normals
= startinfo
['normals']
289 for i
in range(len(rings
)):
290 make_one_inset(self
, context
, bm
=bm
, ringvectors
=rings
[i
],
291 center
=centers
[i
], normal
=normals
[i
],
292 t
=distance
[i
], base_height
=base_heights
[i
])
293 bpy
.ops
.mesh
.select_mode(type="EDGE")
294 bpy
.ops
.mesh
.select_more()
295 bpy
.ops
.mesh
.select_more()
296 bpy
.ops
.object.mode_set(mode
='OBJECT')
297 # PKHG>INFO base extrusion done and set to the mesh
299 # PKHG>INFO if the extrusion is NOT done ... it'll look strange soon!
300 if not self
.strange_boxed_effect
:
301 bpy
.ops
.object.mode_set(mode
='EDIT')
302 obj
= context
.active_object
303 bm
= bmesh
.from_edit_mesh(obj
.data
)
304 bmfaces
= [face
for face
in bm
.faces
if face
.select
]
305 res
= extrude_faces(self
, context
, bm
=bm
, face_l
=bmfaces
)
306 ring_edges
= [face
.edges
[:] for face
in res
]
308 bpy
.ops
.object.mode_set(mode
='OBJECT')
310 # PKHG>INFO now the extruded facec have to move in normal direction
311 bpy
.ops
.object.mode_set(mode
='EDIT')
312 obj
= bpy
.context
.scene
.objects
.active
313 bm
= bmesh
.from_edit_mesh(obj
.data
)
314 todo_faces
= [face
for face
in bm
.faces
if face
.select
]
315 for face
in todo_faces
:
316 bmesh
.ops
.translate(bm
, vec
=face
.normal
* top
, space
=obj_matrix_local
,
318 bpy
.ops
.object.mode_set(mode
='OBJECT')
320 elif face_type
== "stepped":
321 Stepped(spike_base_width
=self
.spike_base_width
,
322 base_height_inset
=self
.base_height_inset
,
323 top_spike
=self
.second_height
,
324 top_extra_height
=self
.top_extra_height
,
325 use_relative_offset
=self
.use_relative
, with_spike
=self
.step_with_real_spike
)
327 elif face_type
== "open_inset":
328 startinfo
= prepare(self
, context
, self
.remove_start_faces
)
331 # PKHG>INFO adjust for relative, via areas
333 areas
= startinfo
['areas']
334 base_height
= self
.base_height
337 if self
.use_relative
:
338 distance
= [min(t
* area
, 1.0) for i
, area
in enumerate(areas
)]
339 base_heights
= [base_height
* area
for i
, area
in enumerate(areas
)]
341 distance
= [t
] * len(areas
)
342 base_heights
= [base_height
] * len(areas
)
344 rings
= startinfo
['rings']
345 centers
= startinfo
['centers']
346 normals
= startinfo
['normals']
347 for i
in range(len(rings
)):
348 make_one_inset(self
, context
, bm
=bm
, ringvectors
=rings
[i
],
349 center
=centers
[i
], normal
=normals
[i
],
350 t
=distance
[i
], base_height
=base_heights
[i
])
351 bpy
.ops
.object.mode_set(mode
='OBJECT')
353 elif face_type
== "with_base":
354 startinfo
= prepare(self
, context
, self
.remove_start_faces
)
356 obj
= startinfo
['obj']
357 object_matrix
= obj
.matrix_local
359 # PKHG>INFO for relative (using areas)
361 areas
= startinfo
['areas']
362 base_height
= self
.base_height
366 if self
.use_relative
:
367 distance
= [min(t
* area
, 1.0) for i
, area
in enumerate(areas
)]
368 base_heights
= [base_height
* area
for i
, area
in enumerate(areas
)]
370 distance
= [t
] * len(areas
)
371 base_heights
= [base_height
] * len(areas
)
374 rings
= startinfo
['rings']
375 centers
= startinfo
['centers']
376 normals
= startinfo
['normals']
377 for i
in range(len(rings
)):
378 next_rings
.append(make_one_inset(self
, context
, bm
=bm
, ringvectors
=rings
[i
],
379 center
=centers
[i
], normal
=normals
[i
],
380 t
=distance
[i
], base_height
=base_heights
[i
]))
382 prepare_ring
= extrude_edges(self
, context
, bm
=bm
, edge_l_l
=next_rings
)
384 second_height
= self
.second_height
386 vectors
= [[ele
.verts
[:] for ele
in edge
] for edge
in prepare_ring
]
389 for rings
in vectors
:
393 # PKHF>INFO no double verts allowed, coming from two adjacents edges!
394 bm
.verts
.ensure_lookup_table()
395 vv
= list(set([ele
.index
for ele
in v
]))
397 vvv
= [bm
.verts
[i
].co
for i
in vv
]
398 n_ring_vecs
.append(vvv
)
400 for i
, ring
in enumerate(n_ring_vecs
):
401 make_one_inset(self
, context
, bm
=bm
, ringvectors
=ring
,
402 center
=centers
[i
], normal
=normals
[i
],
403 t
=width
, base_height
=base_heights
[i
] + second_height
)
404 bpy
.ops
.object.mode_set(mode
='OBJECT')
407 if face_type
== "clsd_vertical":
408 obj_name
= context
.active_object
.name
409 ClosedVertical(name
=obj_name
, base_height
=self
.base_height
,
410 use_relative_base_height
=self
.use_relative
)
412 elif face_type
== "open_vertical":
413 obj_name
= context
.active_object
.name
414 OpenVertical(name
=obj_name
, base_height
=self
.base_height
,
415 use_relative_base_height
=self
.use_relative
)
417 elif face_type
== "bar":
418 startinfo
= prepare(self
, context
, self
.remove_start_faces
)
422 rings
= startinfo
['rings']
423 centers
= startinfo
['centers']
424 normals
= startinfo
['normals']
425 spike_base_width
= self
.spike_base_width
426 for i
, ring
in enumerate(rings
):
427 result
.append(make_one_inset(self
, context
, bm
=bm
,
428 ringvectors
=ring
, center
=centers
[i
],
429 normal
=normals
[i
], t
=spike_base_width
))
431 next_ring_edges_list
= extrude_edges(self
, context
, bm
=bm
,
433 top_spike
= self
.top_spike
435 object_matrix
= startinfo
['obj'].matrix_local
436 for i
in range(len(next_ring_edges_list
)):
438 self
, context
, bm
=bm
,
439 object_matrix
=object_matrix
,
440 ring_edges
=next_ring_edges_list
[i
],
441 normal
=normals
[i
], distance
=fac
443 next_ring_edges_list_2
= extrude_edges(self
, context
, bm
=bm
,
444 edge_l_l
=next_ring_edges_list
)
446 top_extra_height
= self
.top_extra_height
447 for i
in range(len(next_ring_edges_list_2
)):
448 move_corner_vecs_outside(
449 self
, context
, bm
=bm
,
450 edge_list
=next_ring_edges_list_2
[i
],
451 center
=centers
[i
], normal
=normals
[i
],
452 base_height_erlier
=fac
+ top_extra_height
,
455 bpy
.ops
.mesh
.select_mode(type="VERT")
456 bpy
.ops
.mesh
.select_more()
458 bpy
.ops
.object.mode_set(mode
='OBJECT')
463 def find_one_ring(sel_vertices
):
464 ring0
= sel_vertices
.pop(0)
467 for i
, edge
in enumerate(sel_vertices
):
469 if len(ring0
- edge
) < len_nu
:
471 ring0
= ring0
.union(edge
)
478 return (ring0
, sel_vertices
)
482 def __init__(self
, spike_base_width
=0.5, base_height_inset
=0.0, top_spike
=0.2,
483 top_relative
=False, top_extra_height
=0, use_relative_offset
=False,
486 bpy
.ops
.object.mode_set(mode
='EDIT')
488 use_boundary
=True, use_even_offset
=True, use_relative_offset
=False,
489 use_edge_rail
=False, thickness
=spike_base_width
, depth
=0, use_outset
=True,
490 use_select_inset
=False, use_individual
=True, use_interpolate
=True
493 use_boundary
=True, use_even_offset
=True, use_relative_offset
=use_relative_offset
,
494 use_edge_rail
=False, thickness
=top_extra_height
, depth
=base_height_inset
,
495 use_outset
=True, use_select_inset
=False, use_individual
=True, use_interpolate
=True
498 use_boundary
=True, use_even_offset
=True, use_relative_offset
=use_relative_offset
,
499 use_edge_rail
=False, thickness
=spike_base_width
, depth
=0, use_outset
=True,
500 use_select_inset
=False, use_individual
=True, use_interpolate
=True
503 use_boundary
=True, use_even_offset
=True, use_relative_offset
=False,
504 use_edge_rail
=False, thickness
=0, depth
=top_spike
, use_outset
=True,
505 use_select_inset
=False, use_individual
=True, use_interpolate
=True
508 bpy
.ops
.mesh
.merge(type='COLLAPSE')
510 bpy
.ops
.object.mode_set(mode
='OBJECT')
514 def __init__(self
, spike_base_width
=0.5, base_height_inset
=0.0, top_spike
=0.2, top_relative
=False):
516 obj
= bpy
.context
.active_object
517 bpy
.ops
.object.mode_set(mode
='EDIT')
519 use_boundary
=True, use_even_offset
=True, use_relative_offset
=False,
520 use_edge_rail
=False, thickness
=spike_base_width
, depth
=base_height_inset
,
521 use_outset
=True, use_select_inset
=False, use_individual
=True, use_interpolate
=True
524 use_boundary
=True, use_even_offset
=True, use_relative_offset
=top_relative
,
525 use_edge_rail
=False, thickness
=0, depth
=top_spike
, use_outset
=True,
526 use_select_inset
=False, use_individual
=True, use_interpolate
=True
529 bm
= bmesh
.from_edit_mesh(obj
.data
)
530 bpy
.ops
.mesh
.merge(type='COLLAPSE')
531 bpy
.ops
.object.mode_set(mode
='OBJECT')
534 class ClosedVertical
:
535 def __init__(self
, name
="Plane", base_height
=1, use_relative_base_height
=False):
536 obj
= bpy
.data
.objects
[name
]
539 bm
.from_mesh(obj
.data
)
540 # PKHG>INFO deselect chosen faces
541 sel
= [f
for f
in bm
.faces
if f
.select
]
544 res
= bmesh
.ops
.extrude_discrete_faces(bm
, faces
=sel
)
545 # PKHG>INFO select extruded faces
546 for f
in res
['faces']:
550 for face
in res
['faces']:
551 if use_relative_base_height
:
552 area
= face
.calc_area()
553 factor
= area
* base_height
556 for el
in face
.verts
:
557 tmp
= el
.co
+ face
.normal
* factor
560 me
= bpy
.data
.meshes
[name
]
566 def __init__(self
, name
="Plane", base_height
=1, use_relative_base_height
=False):
568 obj
= bpy
.data
.objects
[name
]
570 bm
.from_mesh(obj
.data
)
571 # PKHG>INFO deselect chosen faces
572 sel
= [f
for f
in bm
.faces
if f
.select
]
575 res
= bmesh
.ops
.extrude_discrete_faces(bm
, faces
=sel
)
576 # PKHG>INFO select extruded faces
577 for f
in res
['faces']:
580 # PKHG>INFO adjust extrusion by a vector
582 for face
in res
['faces']:
583 if use_relative_base_height
:
584 area
= face
.calc_area()
585 factor
= area
* base_height
588 for el
in face
.verts
:
589 tmp
= el
.co
+ face
.normal
* factor
592 me
= bpy
.data
.meshes
[name
]
596 bpy
.ops
.object.editmode_toggle()
597 bpy
.ops
.mesh
.delete(type='FACE')
598 bpy
.ops
.object.editmode_toggle()
602 def __init__(self
, use_boundary
=True, use_even_offset
=True, use_relative_offset
=False,
603 use_edge_rail
=True, thickness
=0.0, depth
=0.0, use_outset
=False,
604 use_select_inset
=False, use_individual
=True, use_interpolate
=True):
606 bpy
.ops
.object.mode_set(mode
='EDIT')
608 use_boundary
=use_boundary
, use_even_offset
=True, use_relative_offset
=False,
609 use_edge_rail
=True, thickness
=thickness
, depth
=depth
, use_outset
=use_outset
,
610 use_select_inset
=use_select_inset
, use_individual
=use_individual
,
611 use_interpolate
=use_interpolate
614 bpy
.ops
.object.mode_set(mode
='OBJECT')
616 # PKHG>IMFO only 3 parameters inc execution context supported!!
619 use_boundary
, use_even_offset
, use_relative_offset
, use_edge_rail
,
620 thickness
, depth
, use_outset
, use_select_inset
, use_individual
,
625 use_boundary
=True, use_even_offset
=True, use_relative_offset
=False,
626 use_edge_rail
=True, thickness
=thickness
, depth
=depth
, use_outset
=False,
627 use_select_inset
=False, use_individual
=True, use_interpolate
=True
631 use_boundary
=True, use_even_offset
=True, use_relative_offset
=False,
632 use_edge_rail
=True, thickness
=thickness
, depth
=depth
, use_outset
=False,
633 use_select_inset
=False, use_individual
=True, use_interpolate
=False
635 bpy
.ops
.mesh
.delete(type='FACE')
639 use_boundary
=True, use_even_offset
=False, use_relative_offset
=True,
640 use_edge_rail
=True, thickness
=thickness
, depth
=depth
, use_outset
=False,
641 use_select_inset
=False, use_individual
=True, use_interpolate
=False
644 bpy
.ops
.mesh
.delete(type='FACE')
648 use_boundary
=True, use_even_offset
=False, use_relative_offset
=True,
649 use_edge_rail
=True, thickness
=depth
, depth
=thickness
, use_outset
=False,
650 use_select_inset
=False, use_individual
=True, use_interpolate
=True
652 bpy
.ops
.mesh
.delete(type='FACE')
655 use_boundary
=True, use_even_offset
=False, use_relative_offset
=True,
656 use_edge_rail
=True, thickness
=thickness
, depth
=depth
, use_outset
=True,
657 use_select_inset
=False, use_individual
=True, use_interpolate
=True
660 use_boundary
=True, use_even_offset
=False, use_relative_offset
=True,
661 use_edge_rail
=True, thickness
=thickness
, depth
=depth
, use_outset
=True,
662 use_select_inset
=False, use_individual
=True, use_interpolate
=True
664 bpy
.ops
.mesh
.delete(type='FACE')
666 bpy
.ops
.object.mode_set(mode
='OBJECT')
669 def check_is_selected():
671 for face
in bpy
.context
.active_object
.data
.polygons
:
678 def prepare(self
, context
, remove_start_faces
=True):
680 Start for a face selected change of faces
681 select an object of type mesh, with activated several (all) faces
683 obj
= bpy
.context
.scene
.objects
.active
684 bpy
.ops
.object.mode_set(mode
='OBJECT')
685 selectedpolygons
= [el
for el
in obj
.data
.polygons
if el
.select
]
687 # PKHG>INFO copies of the vectors are needed, otherwise Blender crashes!
688 centers
= [face
.center
for face
in selectedpolygons
]
689 centers_copy
= [Vector((el
[0], el
[1], el
[2])) for el
in centers
]
690 normals
= [face
.normal
for face
in selectedpolygons
]
691 normals_copy
= [Vector((el
[0], el
[1], el
[2])) for el
in normals
]
693 vertindicesofpolgons
= [
694 [vert
for vert
in face
.vertices
] for face
in selectedpolygons
696 vertVectorsOfSelectedFaces
= [
697 [obj
.data
.vertices
[ind
].co
for ind
in vertIndiceofface
] for
698 vertIndiceofface
in vertindicesofpolgons
700 vertVectorsOfSelectedFaces_copy
= [
701 [Vector((el
[0], el
[1], el
[2])) for el
in listofvecs
] for
702 listofvecs
in vertVectorsOfSelectedFaces
705 bpy
.ops
.object.mode_set(mode
='EDIT')
706 bm
= bmesh
.from_edit_mesh(obj
.data
)
707 selected_bm_faces
= [ele
for ele
in bm
.faces
if ele
.select
]
709 selected_edges_per_face_ind
= [
710 [ele
.index
for ele
in face
.edges
] for face
in selected_bm_faces
712 indices
= [el
.index
for el
in selectedpolygons
]
713 selected_faces_areas
= [bm
.faces
[:][i
] for i
in indices
]
714 tmp_area
= [el
.calc_area() for el
in selected_faces_areas
]
716 # PKHG>INFO, selected faces are removed, only their edges are used!
717 if remove_start_faces
:
718 bpy
.ops
.mesh
.delete(type='ONLY_FACE')
719 bpy
.ops
.object.mode_set(mode
='OBJECT')
721 bpy
.ops
.object.mode_set(mode
='EDIT')
722 bm
= bmesh
.from_edit_mesh(obj
.data
)
723 bm
.verts
.ensure_lookup_table()
724 bm
.faces
.ensure_lookup_table()
727 [bm
.verts
[ind
].index
for ind
in vertIndiceofface
] for
728 vertIndiceofface
in vertindicesofpolgons
732 for el
in start_ring_raw
:
733 start_ring
.append(set(el
))
734 bm
.edges
.ensure_lookup_table()
736 bm_selected_edges_l_l
= [
737 [bm
.edges
[i
] for i
in bm_ind_list
] for
738 bm_ind_list
in selected_edges_per_face_ind
741 'obj': obj
, 'centers': centers_copy
, 'normals': normals_copy
,
742 'rings': vertVectorsOfSelectedFaces_copy
, 'bm': bm
,
743 'areas': tmp_area
, 'startBMRingVerts': start_ring
,
744 'base_edges': bm_selected_edges_l_l
750 def make_one_inset(self
, context
, bm
=None, ringvectors
=None, center
=None,
751 normal
=None, t
=None, base_height
=0):
752 # a face will get 'inserted' faces to create (normally) a hole if t is > 0 and < 1)
755 for el
in ringvectors
:
756 tmp
.append((el
* (1 - t
) + center
* t
) + normal
* base_height
)
758 tmp
= [bm
.verts
.new(v
) for v
in tmp
] # the new corner bmvectors
759 # PKHG>INFO so to say sentinells, to use ONE for ...
761 vectorsFace_i
= [bm
.verts
.new(v
) for v
in ringvectors
]
762 vectorsFace_i
.append(vectorsFace_i
[0])
764 for ii
in range(len(vectorsFace_i
) - 1):
765 # PKHG>INFO next line: sequence is important! for added edge
766 bmvecs
= [vectorsFace_i
[ii
], vectorsFace_i
[ii
+ 1], tmp
[ii
+ 1], tmp
[ii
]]
767 res
= bm
.faces
.new(bmvecs
)
768 myres
.append(res
.edges
[2])
769 myres
[-1].select
= True # PKHG>INFO to be used later selected!
773 def extrude_faces(self
, context
, bm
=None, face_l
=None):
774 # to make a ring extrusion
775 res
= bmesh
.ops
.extrude_discrete_faces(bm
, faces
=face_l
)['faces']
782 def extrude_edges(self
, context
, bm
=None, edge_l_l
=None):
783 # to make a ring extrusion
785 for edge_l
in edge_l_l
:
788 res
= bmesh
.ops
.extrude_edge_only(bm
, edges
=edge_l
)
789 tmp
= [ele
for ele
in res
['geom'] if isinstance(ele
, bmesh
.types
.BMEdge
)]
792 all_results
.append(tmp
)
796 def translate_ONE_ring(self
, context
, bm
=None, object_matrix
=None, ring_edges
=None,
797 normal
=(0, 0, 1), distance
=0.5):
798 # translate a ring in given (normal?!) direction with given (global) amount
800 for edge
in ring_edges
:
801 tmp
.extend(edge
.verts
[:])
802 # PKHG>INFO no double vertices allowed by bmesh!
805 bmesh
.ops
.translate(bm
, vec
=normal
* distance
, space
=object_matrix
, verts
=tmp
)
806 # PKHG>INFO relevant edges will stay selected
810 def move_corner_vecs_outside(self
, context
, bm
=None, edge_list
=None, center
=None,
811 normal
=None, base_height_erlier
=0.5, distance
=0.5):
812 # move corners (outside meant mostly) dependent on the parameters
814 for edge
in edge_list
:
815 tmp
.extend([ele
for ele
in edge
.verts
if isinstance(ele
, bmesh
.types
.BMVert
)])
816 # PKHG>INFO to remove vertices, they are all used twice in the ring!
820 for i
in range(len(tmp
)):
822 direction
= vec
+ (vec
- (normal
* base_height_erlier
+ center
)) * distance
823 tmp
[i
].co
= direction
827 bpy
.utils
.register_module(__name__
)
831 bpy
.utils
.unregister_module(__name__
)
834 if __name__
== "__main__":