1 # ***** BEGIN GPL LICENSE BLOCK *****
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # ***** END GPL LICENCE BLOCK *****
21 "name": "Custom Normals Tools",
22 "author": "Bastien Montagne (mont29)",
24 "blender": (2, 75, 0),
25 "location": "3DView > Tools",
26 "description": "Various tools/helpers for custom normals",
28 "support": 'OFFICIAL',
36 class MESH_OT_flip_custom_normals(bpy
.types
.Operator
):
37 """Flip active mesh's normals, including custom ones (only in Object mode)"""
38 bl_idname
= "mesh.flip_custom_normals"
39 bl_label
= "Flip Custom Normals"
43 def poll(cls
, context
):
44 return context
.object and context
.object.type == 'MESH' and context
.object.mode
== 'OBJECT'
46 def execute(self
, context
):
47 me
= context
.object.data
49 if me
.has_custom_normals
:
50 me
.calc_normals_split()
51 clnors
= [0.0] * 3 * len(me
.loops
)
52 me
.loops
.foreach_get("normal", clnors
)
54 bpy
.ops
.object.mode_set(mode
='EDIT')
55 bpy
.ops
.mesh
.select_all(action
='SELECT')
56 bpy
.ops
.mesh
.flip_normals()
57 bpy
.ops
.object.mode_set(mode
='OBJECT')
59 me
= context
.object.data
60 if me
.has_custom_normals
:
61 clnors
[:] = list(zip(*[(-n
for n
in clnors
)] * 3))
62 # We also have to take in account that the winding was reverted...
65 le
= ls
+ p
.loop_total
- 1
66 clnors
[ls
:le
] = reversed(clnors
[ls
:le
])
67 me
.normals_split_custom_set(clnors
)
69 context
.scene
.update()
73 def flip_custom_normals_draw_func(self
, context
):
74 if isinstance(self
, bpy
.types
.Panel
):
75 self
.layout
.label("Custom Normal Tools:")
76 self
.layout
.operator(MESH_OT_flip_custom_normals
.bl_idname
)
80 bpy
.utils
.register_module(__name__
)
81 bpy
.types
.VIEW3D_PT_tools_object
.append(flip_custom_normals_draw_func
)
85 bpy
.types
.VIEW3D_PT_tools_object
.remove(flip_custom_normals_draw_func
)
86 bpy
.utils
.unregister_module(__name__
)
89 if __name__
== "__main__":