mirror of
				https://code.rhodecode.com/u/OOOOOOOOOOOOOOOO/OOOOOOOOOOOOOOOO/0080-0-8-088-00-080-00-880-8-0-0800
				synced 2025-10-25 23:10:57 +00:00 
			
		
		
		
	Delete MESH_SOLIDIFY_WIREFRAME.PY
This commit is contained in:
		| @@ -1,298 +0,0 @@ | ||||
| #!BPY | ||||
|  | ||||
| bl_info = { | ||||
|     "name": "Solidify Wireframe", | ||||
|     "author": "Yorik van Havre, Alejandro Sierra, Howard Trickey", | ||||
|     "description": "Turns the selected edges of a mesh into solid geometry", | ||||
|     "version": (2, 3), | ||||
|     "blender": (2, 5, 8), | ||||
|     "category": "Mesh", | ||||
|     "location": "Mesh > Solidify Wireframe", | ||||
|     "warning": '', | ||||
|     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Modeling/Solidify_Wireframe", | ||||
|     "tracker_url": "http://projects.blender.org/tracker/?func=detail&group_id=153&aid=26997&atid=467", | ||||
|     } | ||||
|  | ||||
| # ***** BEGIN GPL LICENSE BLOCK ***** | ||||
| # | ||||
| # This program is free software; you can redistribute it and/or | ||||
| # modify it under the terms of the GNU General Public License | ||||
| # as published by the Free Software Foundation; either version 2 | ||||
| # of the License, or (at your option) any later version. | ||||
| # | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See th | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program; if not, write to the Free Software Foundation, | ||||
| # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
| # | ||||
| # ***** END GPL LICENCE BLOCK ***** | ||||
|  | ||||
| import bpy, mathutils | ||||
|  | ||||
| cube_faces = [ [0,3,2,1], [5,6,7,4], [0,1,5,4], | ||||
|                [7,6,2,3], [2,6,5,1], [0,4,7,3] ] | ||||
| cube_normals = [ mathutils.Vector((0,0,-1)), | ||||
|                  mathutils.Vector((0,0,1)), | ||||
|                  mathutils.Vector((0,-1,0)), | ||||
|                  mathutils.Vector((0,1,0)), | ||||
|                  mathutils.Vector((1,0,0)), | ||||
|                  mathutils.Vector((-1,0,0)) ] | ||||
|  | ||||
| def create_cube(me, v, d): | ||||
|     x = v.co.x | ||||
|     y = v.co.y | ||||
|     z = v.co.z | ||||
|     coords=[ [x-d,y-d,z-d], [x+d,y-d,z-d], [x+d,y+d,z-d], [x-d,y+d,z-d], | ||||
|          [x-d,y-d,z+d], [x+d,y-d,z+d], [x+d,y+d,z+d], [x-d,y+d,z+d] ] | ||||
|     for coord in coords: | ||||
|         me.vertices.add(1) | ||||
|         me.vertices[-1].co = mathutils.Vector(coord) | ||||
|  | ||||
| def norm_dot(e, k, fnorm, me): | ||||
|     v = me.vertices[e[1]].co - me.vertices[e[0]].co | ||||
|     if k == 1: | ||||
|         v = -v | ||||
|     v.normalize() | ||||
|     return v * fnorm | ||||
|  | ||||
| def fill_cube_face(me, index, f): | ||||
|     return [index + cube_faces[f][i] for i in range(4)] | ||||
|  | ||||
| # Coords of jth point of face f in cube instance i | ||||
| def cube_face_v(me, f, i, j): | ||||
|     return me.vertices[i + cube_faces[f][j]].co | ||||
|  | ||||
| def cube_face_center(me, f, i): | ||||
|     return 0.5 * (cube_face_v(me, f, i, 0) + \ | ||||
|                   cube_face_v(me, f, i, 2)) | ||||
|  | ||||
| # Return distance between points on two faces when | ||||
| # each point is projected onto the plane that goes through | ||||
| # the face center and is perpendicular to the line | ||||
| # through the face centers. | ||||
| def projected_dist(me, i1, i2, f1, f2, j1, j2): | ||||
|     f1center = cube_face_center(me, f1, i1) | ||||
|     f2center = cube_face_center(me, f2, i2) | ||||
|     axis_norm = (f2center - f1center).normalized() | ||||
|     v1 = cube_face_v(me, f1, i1, j1) | ||||
|     v2 = cube_face_v(me, f2, i2, j2) | ||||
|     v1proj = v1 - (axis_norm * (v1 - f1center)) * axis_norm | ||||
|     v2proj = v2 - (axis_norm * (v2 - f2center)) * axis_norm | ||||
|     return (v2proj - v1proj).length | ||||
|  | ||||
| def skin_edges(me, i1, i2, f1, f2): | ||||
|     # Connect verts starting at i1 forming cube face f1 | ||||
|     # to those starting at i2 forming cube face f2. | ||||
|     # Need to find best alignment to avoid a twist. | ||||
|     shortest_length = 1e6 | ||||
|     f2_start_index = 0 | ||||
|     for i in range(4): | ||||
|         x = projected_dist(me, i1, i2, f1, f2, 0, i) | ||||
|         if x < shortest_length: | ||||
|             shortest_length = x | ||||
|             f2_start_index = i | ||||
|     ans = [] | ||||
|     j = f2_start_index | ||||
|     for i in range(4): | ||||
|         fdata = [i1 + cube_faces[f1][i], | ||||
|                  i2 + cube_faces[f2][j], | ||||
|                  i2 + cube_faces[f2][(j + 1) % 4], | ||||
|                  i1 + cube_faces[f1][(i - 1) % 4]] | ||||
|         if fdata[3] == 0: | ||||
|             fdata = [fdata[3]] + fdata[0:3] | ||||
|         ans.extend(fdata) | ||||
|         j = (j - 1) % 4 | ||||
|     return ans | ||||
|              | ||||
|  | ||||
| # Return map: v -> list of length len(node_normals) where | ||||
| # each element of the list is either None (no assignment) | ||||
| # or ((v0, v1), 0 or 1) giving an edge and direction that face is assigned to. | ||||
| def find_assignment(me, edges, vert_edges, node_normals): | ||||
|     nf = len(node_normals) | ||||
|     feasible = {} | ||||
|     for e in edges: | ||||
|         for k in (0, 1): | ||||
|             fds = [(f, norm_dot(e, k, node_normals[f], me)) for f in range(nf)] | ||||
|             feasible[(e, k)] = [fd for fd in fds if fd[1] > 0.01] | ||||
|     assignment = {} | ||||
|     for v, ves in vert_edges.items(): | ||||
|         assignment[v] = best_assignment(ves, feasible, nf) | ||||
|     return assignment | ||||
|  | ||||
| def best_assignment(ves, feasible, nf): | ||||
|     apartial = [ None ] * nf | ||||
|     return best_assign_help(ves, feasible, apartial, 0.0)[0] | ||||
|  | ||||
| def best_assign_help(ves, feasible, apartial, sumpartial): | ||||
|     if len(ves) == 0: | ||||
|         return (apartial, sumpartial) | ||||
|     else: | ||||
|         ek0 = ves[0] | ||||
|         vesrest = ves[1:] | ||||
|         feas = feasible[ek0] | ||||
|         bestsum = 0 | ||||
|         besta = None | ||||
|         for (f, d) in feas: | ||||
|             if apartial[f] is None: | ||||
|                 ap = apartial[:] | ||||
|                 ap[f] = ek0 | ||||
|                 # sum up d**2 to penalize smaller d's more | ||||
|                 sp = sumpartial + d*d | ||||
|                 (a, s) = best_assign_help(vesrest, feasible, ap, sp) | ||||
|                 if s > bestsum: | ||||
|                     bestsum = s | ||||
|                     besta = a | ||||
|         if besta: | ||||
|             return (besta, bestsum) | ||||
|         else: | ||||
|             # not feasible to assign e0, k0; try to assign rest | ||||
|             return best_assign_help(vesrest, feasible, apartial, sumpartial) | ||||
|  | ||||
| def assigned_face(e, assignment): | ||||
|     (v0, v1), dir = e | ||||
|     a = assignment[v1] | ||||
|     for j, ee in enumerate(a): | ||||
|         if e == ee: | ||||
|             return j | ||||
|     return -1 | ||||
|  | ||||
| def create_wired_mesh(me2, me, thick): | ||||
|     edges = [] | ||||
|     vert_edges = {} | ||||
|     for be in me.edges: | ||||
|         if be.select and not be.hide: | ||||
|             e = (be.key[0], be.key[1]) | ||||
|             edges.append(e) | ||||
|             for k in (0, 1): | ||||
|                 if e[k] not in vert_edges: | ||||
|                     vert_edges[e[k]] = [] | ||||
|                 vert_edges[e[k]].append((e, k)) | ||||
|  | ||||
|     assignment = find_assignment(me, edges, vert_edges, cube_normals) | ||||
|  | ||||
|     # Create the geometry | ||||
|     n_idx = {}    | ||||
|     for v in assignment: | ||||
|         vpos = me.vertices[v] | ||||
|         index = len(me2.vertices) | ||||
|         # We need to associate each node with the new geometry | ||||
|         n_idx[v] = index    | ||||
|         # Geometry for the nodes, each one a cube | ||||
|         create_cube(me2, vpos, thick) | ||||
|  | ||||
|     # Skin using the new geometry  | ||||
|     cfaces = []   | ||||
|     for k, f in assignment.items(): | ||||
|         # Skin the nodes | ||||
|         for i in range(len(cube_faces)): | ||||
|             if f[i] is None: | ||||
|                 cfaces.extend(fill_cube_face(me2, n_idx[k], i)) | ||||
|             else: | ||||
|                 (v0, v1), dir = f[i] | ||||
|                 # only skin between edges in forward direction | ||||
|                 # to avoid making doubles | ||||
|                 if dir == 1: | ||||
|                     # but first make sure other end actually assigned | ||||
|                     i2 = assigned_face(((v0, v1), 0), assignment) | ||||
|                     if i2 == -1: | ||||
|                         cfaces.extend(fill_cube_face(me2, n_idx[k], i)) | ||||
|                     continue | ||||
|                 i2 = assigned_face(((v0, v1), 1), assignment) | ||||
|                 if i2 != -1: | ||||
|                     cfaces.extend(skin_edges(me2, n_idx[v0], n_idx[v1], i, i2)) | ||||
|                 else: | ||||
|                     # assignment failed for this edge | ||||
|                     cfaces.extend(fill_cube_face(me2, n_idx[k], i)) | ||||
|  | ||||
|     # adding faces to the mesh | ||||
|     me2.faces.add(len(cfaces) // 4) | ||||
|     me2.faces.foreach_set("vertices_raw", cfaces) | ||||
|     me2.update(calc_edges=True) | ||||
|  | ||||
| # panel containing tools | ||||
| class VIEW3D_PT_tools_SolidifyWireframe(bpy.types.Panel): | ||||
|     bl_space_type = 'VIEW_3D' | ||||
|     bl_region_type = 'TOOLS' | ||||
|     bl_context = "mesh_edit" | ||||
|     bl_label = "Solidify Wireframe" | ||||
|  | ||||
|     def draw(self, context): | ||||
|         active_obj = context.active_object | ||||
|         layout = self.layout | ||||
|         col = layout.column(align=True) | ||||
|         col.operator("mesh.solidify_wireframe", text="Solidify") | ||||
|         col.prop(context.scene, "swThickness") | ||||
|         col.prop(context.scene, "swSelectNew") | ||||
|  | ||||
| # a class for your operator | ||||
| class SolidifyWireframe(bpy.types.Operator): | ||||
|     '''Turns the selected edges of a mesh into solid objects''' | ||||
|     bl_idname = "mesh.solidify_wireframe" | ||||
|     bl_label = "Solidify Wireframe" | ||||
|     bl_options = {'REGISTER', 'UNDO'} | ||||
|      | ||||
|     def invoke(self, context, event): | ||||
|         return self.execute(context) | ||||
|  | ||||
|     @classmethod | ||||
|     def poll(cls, context): | ||||
|         ob = context.active_object | ||||
|         return ob and ob.type == 'MESH' | ||||
|  | ||||
|     def execute(self, context): | ||||
|         # Get the active object | ||||
|         ob_act = context.active_object | ||||
|         # getting current edit mode | ||||
|         currMode = ob_act.mode | ||||
|         # switching to object mode | ||||
|         bpy.ops.object.mode_set(mode='OBJECT') | ||||
|         bpy.ops.object.select_all(action='DESELECT') | ||||
|         # getting mesh data | ||||
|         mymesh = ob_act.data | ||||
|         #getting new mesh | ||||
|         newmesh = bpy.data.meshes.new(mymesh.name + " wire") | ||||
|         obj = bpy.data.objects.new(newmesh.name,newmesh) | ||||
|         obj.location = ob_act.location | ||||
|         obj.rotation_euler = ob_act.rotation_euler | ||||
|         obj.scale = ob_act.scale | ||||
|         context.scene.objects.link(obj) | ||||
|         create_wired_mesh(newmesh, mymesh, context.scene.swThickness) | ||||
|  | ||||
|         # restoring original editmode if needed | ||||
|         if context.scene.swSelectNew: | ||||
|             obj.select = True | ||||
|             context.scene.objects.active = obj | ||||
|         else: | ||||
|             bpy.ops.object.mode_set(mode=currMode) | ||||
|  | ||||
|         # returning after everything is done | ||||
|         return {'FINISHED'} | ||||
|  | ||||
| # Register the operator | ||||
| def solidifyWireframe_menu_func(self, context): | ||||
|         self.layout.operator(SolidifyWireframe.bl_idname, text="Solidify Wireframe", icon='PLUGIN') | ||||
|  | ||||
| # Add "Solidify Wireframe" menu to the "Mesh" menu. | ||||
| def register(): | ||||
|         bpy.utils.register_module(__name__) | ||||
|         bpy.types.Scene.swThickness = bpy.props.FloatProperty(name="Thickness", | ||||
|                                                               description="Thickness of the skinned edges", | ||||
|                                                               default=0.02) | ||||
|         bpy.types.Scene.swSelectNew = bpy.props.BoolProperty(name="Select wire", | ||||
|                                                              description="If checked, the wire object will be selected after creation", | ||||
|                                                              default=True) | ||||
|         bpy.types.VIEW3D_MT_edit_mesh_edges.append(solidifyWireframe_menu_func) | ||||
|  | ||||
| # Remove "Solidify Wireframe" menu entry from the "Mesh" menu. | ||||
| def unregister(): | ||||
|         bpy.utils.register_module(__name__) | ||||
|         del bpy.types.Scene.swThickness | ||||
|         bpy.types.VIEW3D_MT_edit_mesh_edges.remove(solidifyWireframe_menu_func) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|         register() | ||||
		Reference in New Issue
	
	Block a user
	 0000OOOO0000
					0000OOOO0000