Esempio n. 1
0
    def invoke(self, context, event):
        bpy.ops.object.duplicate_move()
        bpy.context.object.name = bpy.context.object.name.replace("_HP.001", "_LP")
        bpy.ops.object.modifier_add(type='DECIMATE')
        bpy.context.object.modifiers["Decimate"].ratio = 0.006
        bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Decimate")
        bpy.ops.object.editmode_toggle()
        bpy.context.tool_settings.mesh_select_mode = (False, False, True)
        obj = bpy.context.active_object
        bm = bmesh.from_edit_mesh(obj.data)
        for face in bm.faces:
            if face.select == False:
                face.select = True
            elif face.select == True:
                face.select = True
                continue
        bpy.ops.uv.smart_project(island_margin=0.005)
        bpy.ops.uv.seams_from_islands()
        bpy.context.tool_settings.mesh_select_mode = (False, True, False)
        bpy.ops.mesh.select_all()
        obj = bpy.context.active_object
        bm = bmesh.from_edit_mesh(obj.data)
        for edge in bm.edges:
            if edge.seam == 1:
                edge.select = True
                continue
        bpy.ops.mesh.mark_sharp()
        bpy.ops.mesh.mark_seam(clear=True)
        bpy.ops.object.editmode_toggle()

        bpy.ops.object.modifier_add(type='EDGE_SPLIT')
        bpy.context.object.modifiers["EdgeSplit"].use_edge_angle = False

        return {"FINISHED"}
def defReconst(self, OFFSET): 
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    bpy.context.tool_settings.mesh_select_mode = (True, True, True)
    ob = bpy.context.active_object
    bm = bmesh.from_edit_mesh(ob.data)
    bm.select_flush(False)
    for vertice in bm.verts[:]:
        if abs(vertice.co[0]) < OFFSET:
            vertice.co[0] = 0            
    for vertice in bm.verts[:]:
      if vertice.co[0] < 0:
        bm.verts.remove(vertice)
        bmesh.update_edit_mesh(ob.data) 
    mod = ob.modifiers.new("Mirror","MIRROR")
    uv = ob.data.uv_textures.new(name="SYMMETRICAL")
    for v in bm.faces: v.select = 1
    bmesh.update_edit_mesh(ob.data)
    ob.data.uv_textures.active = ob.data.uv_textures['SYMMETRICAL']
    bpy.ops.uv.unwrap(method='ANGLE_BASED', fill_holes=True, correct_aspect=False, use_subsurf_data=0)
    bpy.ops.object.mode_set(mode="OBJECT", toggle= False)
    bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Mirror")
    bpy.ops.object.mode_set(mode="EDIT", toggle= False)
    bm = bmesh.from_edit_mesh(ob.data)
    bm.select_flush(0)
    uv = ob.data.uv_textures.new(name="ASYMMETRICAL")
    ob.data.uv_textures.active = ob.data.uv_textures['ASYMMETRICAL']
    bpy.ops.uv.unwrap(method='ANGLE_BASED', fill_holes=True, correct_aspect=False, use_subsurf_data=0)
Esempio n. 3
0
 def invoke(self, context, event):
     bpy.ops.object.editmode_toggle()
     bpy.context.tool_settings.mesh_select_mode = (False, False, True)
     obj = bpy.context.active_object
     bm = bmesh.from_edit_mesh(obj.data)
     for face in bm.faces:
         if face.select == False:
             face.select = True
         elif face.select == True:
             face.select = True
             continue
     bpy.ops.uv.seams_from_islands()
     bpy.context.tool_settings.mesh_select_mode = (False, True, False)
     bpy.ops.mesh.select_all()
     obj = bpy.context.active_object
     bm = bmesh.from_edit_mesh(obj.data)
     for edge in bm.edges:
         if edge.seam == 1:
             edge.select = True
             continue
     bpy.ops.mesh.mark_sharp()
     bpy.ops.mesh.mark_seam(clear=True)
     bpy.ops.object.editmode_toggle()
     bpy.ops.object.modifier_add(type='EDGE_SPLIT')
     bpy.context.object.modifiers["EdgeSplit"].use_edge_angle = False
     return {"FINISHED"}
Esempio n. 4
0
def defReconst(self, OFFSET):
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    bpy.context.tool_settings.mesh_select_mode = (True, False, False)
    OBJETO = bpy.context.active_object
    OBDATA = bmesh.from_edit_mesh(OBJETO.data)
    OBDATA.select_flush(False)
    for vertice in OBDATA.verts[:]:
        if abs(vertice.co[0]) < OFFSET:
            vertice.co[0] = 0
    bpy.ops.mesh.select_all(action="DESELECT")
    for vertices in OBDATA.verts[:]:
      if vertices.co[0] < 0:
        vertices.select = 1
    bpy.ops.mesh.delete()
    bpy.ops.object.modifier_add(type='MIRROR')
    bpy.ops.mesh.select_all(action="SELECT")
    bpy.ops.mesh.uv_texture_add()
    LENUVLISTSIM = len(bpy.data.objects[OBJETO.name].data.uv_textures)
    LENUVLISTSIM = LENUVLISTSIM - 1
    OBJETO.data.uv_textures[LENUVLISTSIM:][0].name = "SYMMETRICAL"
    bpy.ops.uv.unwrap(method='ANGLE_BASED', fill_holes=True, correct_aspect=False, use_subsurf_data=0)
    bpy.ops.object.mode_set(mode="OBJECT", toggle= False)
    bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Mirror")
    bpy.ops.object.mode_set(mode="EDIT", toggle= False)
    OBDATA = bmesh.from_edit_mesh(OBJETO.data)
    OBDATA.select_flush(0)
    bpy.ops.mesh.uv_texture_add()
    LENUVLISTASIM = len(OBJETO.data.uv_textures)
    LENUVLISTASIM = LENUVLISTASIM  - 1
    OBJETO.data.uv_textures[LENUVLISTASIM:][0].name = "ASYMMETRICAL"
    OBJETO.data.uv_textures.active = OBJETO.data.uv_textures["ASYMMETRICAL"]
    bpy.ops.uv.unwrap(method='ANGLE_BASED', fill_holes=True, correct_aspect=False, use_subsurf_data=0)
Esempio n. 5
0
    def update_references(self):
        """
        This method tries to update references at bmesh, when  old bmesh was removed
        """

        if self.bmesh is None:
            if bpy.context.edit_object is not None and \
                    bpy.context.edit_object.data == self.mesh:
                self.bmesh = bmesh.from_edit_mesh(self.mesh)
                self.bm_from_edit_mesh = True
            else:
                self.bmesh = bmesh.new()
                self.bmesh.from_mesh(self.mesh)
                self.bm_from_edit_mesh = False
        else:
            try:
                self.bmesh.verts
            except ReferenceError:
                if bpy.context.edit_object is not None and \
                        bpy.context.edit_object.data == self.mesh:
                    self.bmesh = bmesh.from_edit_mesh(self.mesh)
                    self.bm_from_edit_mesh = True
                else:
                    self.bmesh = bmesh.new()
                    self.bmesh.from_mesh(self.mesh)
                    self.bm_from_edit_mesh = False
                self.clear_ID_cache()
Esempio n. 6
0
def prepare(self, context, remove_start_faces = True):
    """Start for a face selected change of faces
       select an object of type mesh, with  activated severel (all) faces
    """
    #print("prepare called")
    obj = bpy.context.scene.objects.active
    #objmode = obj.mode
    bpy.ops.object.mode_set(mode='OBJECT')
    selectedpolygons = [el for el in obj.data.polygons if el.select]
    #edge_index_list = [[el.index for el in face.edges  ] for face in selectedpolygons]
    #print("start edge_index_list", edge_index_list)
    #PKHG>INFO copies of the vectors are needed, otherwise Blender crashes!
    centers = [face.center for face in selectedpolygons]
    centers_copy = [Vector((el[0],el[1],el[2])) for el in centers]
    normals = [face.normal for face in selectedpolygons]
    normals_copy = [Vector((el[0],el[1],el[2])) for el in normals]
    vertindicesofpolgons = [[vert for vert in face.vertices] for face in selectedpolygons]
    vertVectorsOfSelectedFaces = [[obj.data.vertices[ind].co for ind in  vertIndiceofface]\
                    for vertIndiceofface in  vertindicesofpolgons]
    vertVectorsOfSelectedFaces_copy = [[Vector((el[0],el[1],el[2])) for el in listofvecs]\
                         for listofvecs in vertVectorsOfSelectedFaces]
   
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    selected_bm_faces = [ ele for ele in bm.faces if ele.select]
    selected_edges_per_face_ind = [[ele.index for ele in face.edges] for face in selected_bm_faces]
    #print("\n\nPKHG>DBG selected_edges_per_face", selected_edges_per_face_ind)
    indices = [el.index for el in selectedpolygons]
    #print("indices", indices, bm.faces[:])
    selected_faces_areas = [bm.faces[:][i] for i in indices ]
    tmp_area =  [el.calc_area() for el in selected_faces_areas]
    
    #PKHG>INFO, selected faces are removed, only their edges are used!
    if remove_start_faces:    
        bpy.ops.mesh.delete(type='ONLY_FACE')
        bpy.ops.object.mode_set(mode='OBJECT')
        obj.data.update()
        bpy.ops.object.mode_set(mode='EDIT')
        bm = bmesh.from_edit_mesh(obj.data)
        bm.verts.ensure_lookup_table()
        bm.faces.ensure_lookup_table()

    start_ring_raw = [[bm.verts[ind].index for ind in  vertIndiceofface]  \
                    for vertIndiceofface in  vertindicesofpolgons]
    start_ring = []
    
    for el in start_ring_raw:
        #el.sort()
        start_ring.append(set(el))
    bm.edges.ensure_lookup_table()

    bm_selected_edges_l_l = [[bm.edges[i] for i in bm_ind_list  ] for bm_ind_list in  selected_edges_per_face_ind]            

    result = {'obj': obj, 'centers':centers_copy, 'normals': normals_copy,\
              'rings': vertVectorsOfSelectedFaces_copy, 'bm': bm ,\
              'areas': tmp_area,'startBMRingVerts':start_ring,\
              'base_edges':bm_selected_edges_l_l}
    return result
	def execute(self, context):
		# if self.target_length == 0:
			# return {'FINISHED'}	
			
		self.count += 1
		if self.count == 1:
			# 初始化
			ob = context.edit_object

			# 准备
			self.me = ob.data
			
			self.switch_point = False
			
			bm = bmesh.from_edit_mesh(self.me)
			# 选择顺序 重新判断长度是为了识别模式切换
			if len(bm.select_history) > 1 and isinstance(bm.select_history[-1], bmesh.types.BMVert):
				self.vts_sequence = [i.index for i in [bm.select_history[j] for j in (-2,-1)]]
			elif len(bm.select_history) > 0 and isinstance(bm.select_history[-1], bmesh.types.BMEdge):
				self.vts_sequence = [i.index for i in bm.select_history[-1].verts]
			else:
				self.report({'ERROR'}, '0,1 edge OR 2 points; 1,don\'t support Face mode; 2,Changing select mode will Lost select-history')
				return {'CANCELLED'}
			
			# 当前长度
			if abs(self.target_length) < 0.000000000001:
				if self.switch_point:
					tmp_vts_sequence = [self.vts_sequence[-1], self.vts_sequence[-2]]
				else:
					tmp_vts_sequence = self.vts_sequence
				vector = bm.verts[tmp_vts_sequence[-2]].co - bm.verts[tmp_vts_sequence[-1]].co
				self.target_length = vector.length
			self.execute(context)
		else:
			bm = bmesh.from_edit_mesh(self.me)
			
			if self.switch_point:
				tmp_vts_sequence = [self.vts_sequence[-1], self.vts_sequence[-2]]
			else:
				tmp_vts_sequence = self.vts_sequence
			
			vector = bm.verts[tmp_vts_sequence[-2]].co - bm.verts[tmp_vts_sequence[-1]].co
			vector.length = abs(self.target_length)
			if self.target_length > 0:
				bm.verts[tmp_vts_sequence[-1]].co = bm.verts[tmp_vts_sequence[-2]].co - vector
			elif self.target_length < 0:
				bm.verts[tmp_vts_sequence[-1]].co = bm.verts[tmp_vts_sequence[-2]].co + vector
			# 刷新视窗数据
			bmesh.update_edit_mesh(self.me, True)
		return {'FINISHED'}
    def execute(self, context):
        # create connection
        socket_connection = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        # socket_connection.sendto(bytes(context.active_object.name,'utf-8'),addr)
        mess = "number of vertices: "+str(len(context.active_object.data.vertices))
        # socket_connection.sendto(bytes(mess,'utf-8'),addr)
        sel_vert = []
        if context.active_object.mode == "EDIT":
            blender_mesh = bmesh.from_edit_mesh(context.active_object.data)
            for v in blender_mesh.verts:
                if v.select is True:
                    sel_vert.append(v)
        else:
            blender_mesh = context.active_object.data
            for v in blender_mesh.vertices:
                if v.select is True:
                    sel_vert.append(v)

        # extract coordinate data from all vertices
        all_vert = context.active_object.data.vertices
        vertex_coordinates = [[v.co.x, v.co.y, v.co.z] for v in all_vert]
        vertex_normals = [[v.normal.x, v.normal.y, v.normal.z] for v in all_vert]

        # extract selected edges
        selected_edges = []
        if context.active_object.mode == "EDIT":
            # the syntax is a little different depending on if we are in EDIT mode or not
            blender_mesh = bmesh.from_edit_mesh(context.active_object.data)
            for v in blender_mesh.edges:
                if v.select is True:
                    selected_edges.append(v)
                    edges = [(e.verts[0].index, e.verts[1].index) for e in selected_edges]
        else:
            # if we are not in edit mode things are a bit easier
            blender_mesh = context.active_object.data
            for v in blender_mesh.edges:
                if v.select is True:
                    selected_edges.append(v)
                    edges = [(e.vertices[0], e.vertices[1]) for e in selected_edges]

        # extract vertex index data from selected edges

        mess = {'edges': edges, 'vert_loc': vertex_coordinates, 'vert_norm': vertex_normals}
        mess = json.dumps(mess)
        addr = (self.IP, self.port)
        socket_connection.sendto(bytes(mess, "utf-8"), addr)
        self.report({'INFO'}, "sent message to: "+self.IP+" port: "+str(self.port))
        # this lets blender know the operator finished successfully.
        return {'FINISHED'}
Esempio n. 9
0
    def execute(self, context):
        obj = context.active_object
        bm = bmesh.from_edit_mesh(obj.data)
        if common.check_version(2, 73, 0) >= 0:
            bm.faces.ensure_lookup_table()
        uv_layer = bm.loops.layers.uv.verify()

        if context.tool_settings.use_uv_select_sync:
            sel_faces = [f for f in bm.faces]
        else:
            sel_faces = [f for f in bm.faces if f.select]

        overlapped_info = common.get_overlapped_uv_info(bm, sel_faces,
                                                        uv_layer, 'FACE')

        for info in overlapped_info:
            if context.tool_settings.use_uv_select_sync:
                info["subject_face"].select = True
            else:
                for l in info["subject_face"].loops:
                    l[uv_layer].select = True

        bmesh.update_edit_mesh(obj.data)

        return {'FINISHED'}
Esempio n. 10
0
def create_ground(pos_z, length, width):
	mat_ground = createMaterial('ground.png')
	
	bpy.ops.mesh.primitive_cube_add(location=(0,0,pos_z))
	ground = bpy.context.active_object
	ground_data = ground.data
	
	bpy.ops.object.mode_set(mode='EDIT')
	mesh = bmesh.from_edit_mesh(ground_data)
	
	extrude_face(mesh, 2, length, 0, 0)
	mesh.faces[1].select = True
	mesh.faces[9].select = True
	extrude_face_simple(mesh, 0, width, 0)
	
	mesh.faces[1].select = True
	mesh.faces[9].select = True
	bpy.ops.mesh.subdivide()
	bpy.ops.mesh.subdivide()
	bpy.ops.mesh.subdivide()
	bpy.ops.mesh.select_all(action="DESELECT")  
	
	setMaterial(ground, mat_ground)
	bpy.ops.uv.smart_project()
	
	bpy.ops.object.mode_set(mode='OBJECT')
	bpy.ops.object.shade_smooth()
 def filter_items_empty_vgroups(self, context, vgroups):
     # This helper function checks vgroups to find out whether they are empty, and what's their average weights.
     # TODO: This should be RNA helper actually (a vgroup prop like "raw_data: ((vidx, vweight), etc.)").
     #       Too slow for python!
     obj_data = context.active_object.data
     ret = {vg.index: [True, 0.0] for vg in vgroups}
     if hasattr(obj_data, "vertices"):  # Mesh data
         if obj_data.is_editmode:
             import bmesh
             bm = bmesh.from_edit_mesh(obj_data)
             # only ever one deform weight layer
             dvert_lay = bm.verts.layers.deform.active
             fact = 1 / len(bm.verts)
             if dvert_lay:
                 for v in bm.verts:
                     for vg_idx, vg_weight in v[dvert_lay].items():
                         ret[vg_idx][0] = False
                         ret[vg_idx][1] += vg_weight * fact
         else:
             fact = 1 / len(obj_data.vertices)
             for v in obj_data.vertices:
                 for vg in v.groups:
                     ret[vg.group][0] = False
                     ret[vg.group][1] += vg.weight * fact
     elif hasattr(obj_data, "points"):  # Lattice data
         # XXX no access to lattice editdata?
         fact = 1 / len(obj_data.points)
         for v in obj_data.points:
             for vg in v.groups:
                 ret[vg.group][0] = False
                 ret[vg.group][1] += vg.weight * fact
     return ret
 def draw(self, context):
     ob = bpy.context.object
     
     if ob is None:
         return
     
     if ob.type != 'MESH':
         raise TypeError("Active object is not a Mesh")
     
     me = ob.data
     
     if me.is_editmode:
         # Gain direct access to the mesh
         bm = bmesh.from_edit_mesh(me)
     else:
         # Create a bmesh from mesh
         # (won't affect mesh, unless explicitly written back)
         bm = bmesh.new()
         bm.from_mesh(me)
     
     # Get active face
     face = bm.faces.active
     
     if face is None:
         return
     
     arxFaceType = bm.faces.layers.int.get('arx_facetype')
     arxTransVal = bm.faces.layers.float.get('arx_transval')
     
     faceType = PolyTypeFlag()
     faceType.asUInt = face[arxFaceType]
     
     transval = face[arxTransVal]
     
     obj = bpy.context.active_object
     
     layout = self.layout
     
     layout.label(text="transval: " + str(transval))
     layout.label(text="POLY_NO_SHADOW: " + str(faceType.POLY_NO_SHADOW))
     layout.label(text="POLY_DOUBLESIDED: " + str(faceType.POLY_DOUBLESIDED))
     layout.label(text="POLY_TRANS: " + str(faceType.POLY_TRANS))
     layout.label(text="POLY_WATER: " + str(faceType.POLY_WATER))
     layout.label(text="POLY_GLOW: " + str(faceType.POLY_GLOW))
     layout.label(text="POLY_IGNORE: " + str(faceType.POLY_IGNORE))
     layout.label(text="POLY_QUAD: " + str(faceType.POLY_QUAD))
     layout.label(text="POLY_METAL: " + str(faceType.POLY_METAL))
     layout.label(text="POLY_HIDE: " + str(faceType.POLY_HIDE))
     layout.label(text="POLY_STONE: " + str(faceType.POLY_STONE))
     layout.label(text="POLY_WOOD: " + str(faceType.POLY_WOOD))
     layout.label(text="POLY_GRAVEL: " + str(faceType.POLY_GRAVEL))
     layout.label(text="POLY_EARTH: " + str(faceType.POLY_EARTH))
     layout.label(text="POLY_NOCOL: " + str(faceType.POLY_NOCOL))
     layout.label(text="POLY_LAVA: " + str(faceType.POLY_LAVA))
     layout.label(text="POLY_CLIMB: " + str(faceType.POLY_CLIMB))
     layout.label(text="POLY_FALL: " + str(faceType.POLY_FALL))
     layout.label(text="POLY_NOPATH: " + str(faceType.POLY_NOPATH))
     layout.label(text="POLY_NODRAW: " + str(faceType.POLY_NODRAW))
     layout.label(text="POLY_PRECISE_PATH: " + str(faceType.POLY_PRECISE_PATH))
     layout.label(text="POLY_LATE_MIP: " + str(faceType.POLY_LATE_MIP))
Esempio n. 13
0
def do_polyredux(self):

    global bm, me

    # Gets the current scene, there can be many scenes in 1 blend file.
    sce = bpy.context.scene

    # Get the active object, there can only ever be 1
    # and the active object is always the editmode object.
    mode = "EDIT"
    if bpy.context.mode == "OBJECT":
        mode = "OBJECT"
        bpy.ops.object.editmode_toggle()
    ob_act = bpy.context.active_object
    if not ob_act or ob_act.type != "MESH":
        return
    me = ob_act.data
    bm = bmesh.from_edit_mesh(me)

    t = time.time()

    # Run the mesh editing function
    my_mesh_util()
    me.update(calc_edges=True, calc_tessface=True)
    bm.free()

    # Restore editmode if it was enabled
    if mode == "OBJECT":
        bpy.ops.object.editmode_toggle()
    else:
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.editmode_toggle()

        # Timing the script is a good way to be aware on any speed hits when scripting
    print("My Script finished in %.2f seconds" % (time.time() - t))
Esempio n. 14
0
    def __init__(self, obj, create_tris, create_edges, create_looseverts):
        self.tri_verts = self.edge_verts = self.looseverts = None
        self.tris_co = self.edges_co = self.looseverts_co = None
        if obj.type == 'MESH':
            me = obj.data
            if me.is_editmode:
                bm = bmesh.from_edit_mesh(me)
                bm.verts.ensure_lookup_table()

                self.verts_co = get_bmesh_vert_co_array(bm)

                if create_tris:
                    self.tri_verts = get_bmesh_tri_verts_array(bm)
                if create_edges:
                    self.edge_verts = get_bmesh_edge_verts_array(bm)
                if create_looseverts:
                    self.looseverts = get_bmesh_loosevert_array(bm)
            else:
                self.verts_co = get_mesh_vert_co_array(me)

                if create_tris:
                    self.tri_verts = get_mesh_tri_verts_array(me)
                if create_edges:
                    self.edge_verts = get_mesh_edge_verts_array(me)
                if create_looseverts:
                    edge_verts = self.edge_verts
                    if edge_verts is None:
                        edge_verts = get_mesh_edge_verts_array(me)
                    self.looseverts = get_mesh_loosevert_array(me, edge_verts)
                    del edge_verts

        else: #TODO
            self.verts_co = np.zeros((1,3), 'f4')
            self.looseverts = np.zeros(1, 'i4')
Esempio n. 15
0
def get_selected_vertex(myobject):
    mylist = []
    # if not mesh, no vertex
    if myobject.type != "MESH":
        return mylist
    # --------------------
    # meshes
    # --------------------
    oldobj = bpy.context.object
    bpy.context.scene.objects.active = myobject
    flag = False
    if myobject.mode != 'EDIT':
        bpy.ops.object.mode_set(mode='EDIT')
        flag = True

    bm = bmesh.from_edit_mesh(myobject.data)
    tv = len(bm.verts)
    for v in bm.verts:
        if v.select:
            mylist.extend([v.index])

    if flag is True:
        bpy.ops.object.editmode_toggle()
    # Back context object
    bpy.context.scene.objects.active = oldobj

    # if select all vertices, then use origin
    if  tv == len(mylist):
        return []

    return mylist
Esempio n. 16
0
def callback_save_pre(dummy):
    """ファイルのセーブ前に実行。ロック座標用の頂点レイヤーを削除"""
    for me in bpy.data.meshes:
        if me.is_editmode:
            bm = bmesh.from_edit_mesh(me)
        else:
            skip = True
            if LAYER_LOCK in me.vertex_layers_int:
                skip = False
            for name in (LAYER_X, LAYER_Y, LAYER_Z,
                         LAYER_GX, LAYER_GY, LAYER_GZ):
                if name in me.vertex_layers_float:
                    skip = False
            if skip:
                continue
            bm = bmesh.new()
            bm.from_mesh(me)
        for name in (LAYER_X, LAYER_Y, LAYER_Z):
            layer = bm.verts.layers.float.get(name)
            if layer:
                bm.verts.layers.float.remove(layer)
        # 0.2.0で追加した分
        for name in (LAYER_GX, LAYER_GY, LAYER_GZ):
            layer = bm.verts.layers.float.get(name)
            if layer:
                bm.verts.layers.float.remove(layer)
        if not me.is_editmode:
            bm.to_mesh(me)
Esempio n. 17
0
def sw_clipping(obj, autoclip, clipcenter):
    if "Mirror" in bpy.data.objects[obj].modifiers:
        obj = bpy.context.active_object
        bm = bmesh.from_edit_mesh(obj.data)
        vcount = 0
        EPSILON = 1.0e-3

        if clipcenter == True:
            EPSILON_sel = 1.0e-1
            for v in bm.verts:
                if -EPSILON_sel <= v.co.x <= EPSILON_sel:
                    if v.select == True:
                        v.co.x = 0
        else:
            if autoclip == True:
                bpy.ops.mesh.select_all(action='DESELECT')
                for v in bm.verts:
                    if -EPSILON <= v.co.x <= EPSILON:
                        v.select = True
                        bm.select_history.add(v)
                        v1 = v
                        vcount += 1
                    if vcount > 1:
                        bpy.ops.mesh.select_axis(mode='ALIGNED')
                        bpy.ops.mesh.loop_multi_select()
                        for v in bm.verts:
                            if v.select == True:
                                v.co.x = 0
                        break
Esempio n. 18
0
    def execute(self, context):
        global activePath
        pathEntry = context.scene.cm_paths.coll[activePath]
        bm = bmesh.from_edit_mesh(context.active_object.data)

        fringe = {v for v in bm.verts if v.select}
        seen = {v for v in bm.verts if v.select}
        while len(fringe) > 0:
            nextFrige = set()
            for v in fringe:
                for e in v.link_edges:
                    other = e.other_vert(v)
                    if other not in seen:
                        indexStr = str(e.index)
                        if v.index == e.verts[0].index:
                            if indexStr in pathEntry.revDirec:
                                toRm = pathEntry.revDirec.find(indexStr)
                                pathEntry.revDirec.remove(toRm)
                        else:
                            if indexStr not in pathEntry.revDirec:
                                revEdge = pathEntry.revDirec.add()
                                revEdge.name = indexStr
                        nextFrige.add(other)
                seen.add(v)
            fringe = nextFrige

        # Hack to force redraw
        context.scene.objects.active = context.scene.objects.active
        return {'FINISHED'}
Esempio n. 19
0
 def get_bmesh(self):
   bpy.data.objects[self.seed_geom].select = True
   #bpy.ops.object.select_pattern(pattern=self.seed_geom)
   self.obj = bpy.context.active_object
   bpy.ops.object.mode_set(mode='EDIT')
   bm = bmesh.from_edit_mesh(self.obj.data)
   return bm
Esempio n. 20
0
    def main(self, context, chboxhide, chboxshow):

        obj = bpy.context.object
        me = obj.data
        bm = bmesh.from_edit_mesh(me)
        try:
            v1 = [v for v in bm.verts if (v.select == True and v.hide == False)]

            e1 = [e for e in bm.edges if (e.select == True and e.hide == False)]

            f1 = [f for f in bm.faces if (f.select == True and f.hide == False)]

            if len(v1) > 0 or len(e1) > 0 or f1 > 0:
                if chboxhide:
                    bpy.ops.mesh.select_all(action='INVERT')
                    bpy.ops.mesh.hide(unselected=False)
                    bpy.ops.mesh.select_all(action='SELECT')

                elif chboxshow:
                    bpy.ops.mesh.reveal()
        except:

            if chboxshow:
                bpy.ops.mesh.reveal()

        bmesh.update_edit_mesh(me, True)
def create_streets(offset_val):
    #grab selection, etc.
    mode("EDIT")
    mode("FACE")
    obj = bpy.context.edit_object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)
    for i in bm.faces:
        i.select = True
    #bevel out streets
    bpy.ops.mesh.bevel(
        offset_type = "WIDTH",
        offset = offset_val,
        clamp_overlap = True
    )
    for i in bm.faces:
        if i.select:
            i.material_index = 1
            bpy.ops.object.material_slot_assign
        else:
            i.material_index = 0
            bpy.ops.object.material_slot_assign
    bpy.ops.object.material_slot_assign
    mode("EDIT")
    bmesh.update_edit_mesh(me)
def view_3d_context_visuals():
    obj = bpy.context.edit_object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)
    toggle_index("FACE")
    for i in bm.faces:
        i.select = True
    def execute(self, context):
        ob = context.active_object
        me = ob.data
        bm = bmesh.from_edit_mesh(me)
        #print(self.available_vgroups)

        # Save current selection
        selected_verts = []
        for v in bm.verts:
            if v.select is True:
                selected_verts.append(v.index)
                if v.index != self.vertex:
                    v.select = False

        weight = context.tool_settings.vertex_group_weight
        context.tool_settings.vertex_group_weight = 1.0
        if self.available_vgroups == "-1":
            bpy.ops.object.vertex_group_assign(new=True) #XXX Assumes self.vertex is the active vertex
        else:
            bpy.ops.object.vertex_group_set_active(group = self.available_vgroups)
            bpy.ops.object.vertex_group_assign() #XXX Assumes self.vertex is the active vertex
        context.tool_settings.vertex_group_weight = weight

        # Re-select vertices
        for v in bm.verts:
            if v.index in selected_verts:
                v.select = True

        #XXX Hacky, but there's no other way to update the UI panels
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.editmode_toggle()
        return {'FINISHED'}
Esempio n. 24
0
 def __find_uv(self, context):
     bm = bmesh.from_edit_mesh(context.object.data)
     topology_dict = []
     first = True
     diff = 0
     uvs = []
     active_uv = bm.loops.layers.uv.active
     for fidx, f in enumerate(bm.faces):
         for vidx, v in enumerate(f.verts):
             if v.select:
                 uvs.append(f.loops[vidx][active_uv].uv.copy())
                 topology_dict.append([fidx, vidx])
                 if first:
                     v1 = v.link_loops[0].vert.co
                     sv1 = view3d_utils.location_3d_to_region_2d(
                         context.region,
                         context.space_data.region_3d,
                         v1)
                     v2 = v.link_loops[0].link_loop_next.vert.co
                     sv2 = view3d_utils.location_3d_to_region_2d(
                         context.region,
                         context.space_data.region_3d,
                         v2)
                     vres = sv2 - sv1
                     va = vres.angle(Vector((0.0, 1.0)))
                     
                     uv1 = v.link_loops[0][active_uv].uv
                     uv2 = v.link_loops[0].link_loop_next[active_uv].uv
                     uvres = uv2 - uv1
                     uva = uvres.angle(Vector((0.0,1.0)))
                     diff = uva - va
                     first = False
                     
     return topology_dict, uvs 
Esempio n. 25
0
    def execute(self, context):
        if context.object.mode == 'EDIT':
            verts = [i.index for i in bmesh.from_edit_mesh(bpy.context.active_object.data).verts if i.select]
            if len(verts) > 0:
                context.object["boundary_condition"] = verts

        return {'FINISHED'}
Esempio n. 26
0
    def modal(self, context, event):
        ob = context.object
        obj_data = bmesh.from_edit_mesh(ob.data)
        div = 10000
        self.offsetuv += Vector(((event.mouse_region_x - self.first_mouse.x) / div,
                                 (event.mouse_region_y - self.first_mouse.y) / div))

        o = self.offsetuv
        oo = self.old_offsetuv
        for i, j in self.l:
            d = obj_data.faces[i].loops[j][obj_data.loops.layers.uv.active]
            vec = Vector((o.x - o.y, o.x + o.y))
            d.uv = d.uv - Vector((oo.x, oo.y)) + vec

        self.old_offsetuv = vec
        self.first_mouse = Vector((event.mouse_region_x, event.mouse_region_y))
        ob.data.update()

        if context.user_preferences.inputs.select_mouse == 'LEFT':
            mb = 'LEFTMOUSE'
        else:
            mb = 'RIGHTMOUSE'

        if event.type == mb and event.value == 'RELEASE':
            return {'FINISHED'}
        if event.type == 'ESC' and event.value == 'RELEASE':
            return {'CANCELLED'}
        return {'RUNNING_MODAL'}
    def execute(self, context):
        ob = context.active_object
        me = ob.data
        bm = bmesh.from_edit_mesh(me)

        # Save current selection
        selected_verts = []
        for v in bm.verts:
            if v.select is True:
                selected_verts.append(v.index)
                if v.index != self.vert_and_group[0]:
                    v.select = False

        ob.vertex_groups.active_index = self.vert_and_group[1]
        bpy.ops.object.vertex_group_remove_from()

        # Re-select vertices
        for v in bm.verts:
            if v.index in selected_verts:
                v.select = True

        #XXX Hacky, but there's no other way to update the UI panels
        bpy.ops.object.editmode_toggle()
        bpy.ops.object.editmode_toggle()
        return {'FINISHED'}
Esempio n. 28
0
def find_uv(context):
    obj_data = bmesh.from_edit_mesh(context.object.data)
    l = []
    first = 0
    diff = 0
    for f, face in enumerate(obj_data.faces):
        for v, vertex in enumerate(face.verts):
            if vertex.select:
                l.append([f, v])
                if first == 0:
                    v1 = vertex.link_loops[0].vert.co
                    sv1 = loc3d2d(context.region, context.space_data.region_3d, v1)
                    v2 = vertex.link_loops[0].link_loop_next.vert.co
                    sv2 = loc3d2d(context.region, context.space_data.region_3d, v2)
                    vres = sv2 - sv1
                    va = vres.angle(Vector((0.0, 1.0)))

                    uv1 = vertex.link_loops[0][obj_data.loops.layers.uv.active].uv
                    uv2 = vertex.link_loops[0].link_loop_next[obj_data.loops.layers.uv.active].uv
                    uvres = uv2 - uv1
                    uva = uvres.angle(Vector((0.0, 1.0)))
                    diff = uva - va
                    first += 1

    return l, diff
    def offset_profile(self, ob_edit, info_profile):
        me = ob_edit.data
        bm = bmesh.from_edit_mesh(me)

        if self.caches_valid and self._cache_offset_infos:
            offset_infos, edges_orig = self.get_caches(bm)
        else:
            offset_infos, edges_orig = self.get_offset_infos(bm, ob_edit)
            if offset_infos is False:
                return {'CANCELLED'}
            self.save_caches(offset_infos, edges_orig)

        ref_verts = [v for v, _, _ in offset_infos]
        edges = edges_orig
        for width, depth, _ in info_profile:
            exverts, exedges, _ = self.extrude_and_pairing(bm, edges, ref_verts)
            self.move_verts(bm, me, width * self.magni_w, depth * self.magni_d, offset_infos,
                            exverts, update=False)
            ref_verts = exverts
            edges = exedges

        bm.normal_update()
        bmesh.update_edit_mesh(me)

        self.caches_valid = False

        return {'FINISHED'}
Esempio n. 30
0
def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifiers=False):
    """
    Returns a transformed, triangulated copy of the mesh
    """

    assert(obj.type == 'MESH')

    if apply_modifiers and obj.modifiers:
        import bpy
        me = obj.to_mesh(bpy.context.scene, True, 'PREVIEW', calc_tessface=False)
        bm = bmesh.new()
        bm.from_mesh(me)
        bpy.data.meshes.remove(me)
        del bpy
    else:
        me = obj.data
        if obj.mode == 'EDIT':
            bm_orig = bmesh.from_edit_mesh(me)
            bm = bm_orig.copy()
        else:
            bm = bmesh.new()
            bm.from_mesh(me)

    # TODO. remove all customdata layers.
    # would save ram

    if transform:
        bm.transform(obj.matrix_world)

    if triangulate:
        bmesh.ops.triangulate(bm, faces=bm.faces)

    return bm
Esempio n. 31
0
def GeraModeloFotoSMVSDef(self, context):

    scn = context.scene

    tmpdir = tempfile.mkdtemp()
    tmpOBJface = tmpdir + '/scene/scene_dense_mesh_texture2.obj'
    #    subprocess.call(['rm /tmp/DIRETORIO_FOTOS.txt'],  shell=True)

    homeall = expanduser("~")

    if scn.my_tool.path == "":
        ERROTermFoto()
        bpy.context.window_manager.popup_menu(ERROruntimeFotosDef,
                                              title="Attention!",
                                              icon='INFO')

    else:
        if platform.system() == "Linux":
            SMVSPath = homeall + "/Programs/OrtogOnBlender/SMVS/"
            subprocess.call(['rm', '-rf', tmpdir + '/scene'])
            subprocess.call([
                SMVSPath + './makescene', '-i', scn.my_tool.path,
                tmpdir + '/scene'
            ])
            subprocess.call([SMVSPath + './sfmrecon', tmpdir + '/scene'])
            subprocess.call(
                [SMVSPath + './smvsrecon', '-s2', tmpdir + '/scene'])
            subprocess.call([
                'meshlabserver', '-i', tmpdir + '/scene/smvs-B2.ply', '-o',
                tmpdir + '/scene/meshlab.ply', '-s',
                SMVSPath + 'SMVSmeshlab.mlx', '-om'
            ])
            subprocess.call([
                SMVSPath + './texrecon', '--data_term=area',
                '--skip_global_seam_leveling',
                '--outlier_removal=gauss_damping',
                tmpdir + '/scene::undistorted', tmpdir + '/scene/meshlab.ply',
                tmpdir + '/scene/scene_dense_mesh_texture2'
            ])
            bpy.ops.import_scene.obj(filepath=tmpOBJface,
                                     filter_glob="*.obj;*.mtl")
            scene_dense_mesh_texture2 = bpy.data.objects[
                'scene_dense_mesh_texture2']
            bpy.ops.object.select_all(action='DESELECT')
            bpy.context.scene.objects.active = scene_dense_mesh_texture2
            bpy.data.objects['scene_dense_mesh_texture2'].select = True
            bpy.ops.view3d.view_all(center=False)
            bpy.ops.file.pack_all()

        if platform.system() == "Windows":
            SMVSPath = 'C:/OrtogOnBlender/SMVS/'
            #            shutil.rmtree(tmpdir+'/scene')
            subprocess.call([
                SMVSPath + './makescene', '-i', scn.my_tool.path,
                tmpdir + '/scene'
            ])
            subprocess.call([SMVSPath + './sfmrecon', tmpdir + '/scene'])
            subprocess.call(
                [SMVSPath + './smvsrecon', '-s2', tmpdir + '/scene'])
            subprocess.call([
                SMVSPath + './fssrecon', tmpdir + '/scene/smvs-B2.ply',
                tmpdir + '/scene/smvs-surface.ply'
            ])
            subprocess.call([
                SMVSPath + './meshclean', '-p10',
                tmpdir + '/scene/smvs-surface.ply',
                tmpdir + '/scene/smvs-surface-clean.ply'
            ])
            tmpPLYface = tmpdir + '/scene/smvs-surface-clean.ply'
            bpy.ops.import_mesh.ply(filepath=tmpPLYface, filter_glob="*.ply")
            smvs_surface_clean = bpy.data.objects['smvs-surface-clean']
            bpy.ops.object.select_all(action='DESELECT')
            bpy.context.scene.objects.active = smvs_surface_clean
            bpy.data.objects['smvs-surface-clean'].select = True
            bpy.ops.view3d.view_all(center=False)
            bpy.ops.file.pack_all()

        if platform.system() == "Darwin":
            homemac = expanduser("~")
            SMVSPath = '/OrtogOnBlender/SMVSMAC/'

            subprocess.call(['rm', '-Rf', tmpdir + '/scene'])
            subprocess.call([
                SMVSPath + './makescene', '-i', scn.my_tool.path,
                tmpdir + '/scene'
            ])
            subprocess.call([SMVSPath + './sfmrecon', tmpdir + '/scene'])
            subprocess.call(
                [SMVSPath + './smvsrecon', '-s2', tmpdir + '/scene'])
            subprocess.call([
                SMVSPath + './fssrecon', '-s4', tmpdir + '/scene/smvs-B2.ply',
                tmpdir + '/scene/smvs-surface.ply'
            ])
            subprocess.call([
                SMVSPath + './meshclean', '-p10',
                tmpdir + '/scene/smvs-surface.ply',
                tmpdir + '/scene/smvs-clean.ply'
            ])
            subprocess.call(['rm', '-Rf', tmpdir + '/scene/tmp'])
            subprocess.call([
                SMVSPath + './texrecon', '--data_term=area',
                '--skip_global_seam_leveling',
                '--outlier_removal=gauss_damping',
                tmpdir + '/scene::undistorted',
                tmpdir + '/scene/smvs-clean.ply',
                tmpdir + '/scene/scene_dense_mesh_texture2'
            ])

            bpy.ops.import_scene.obj(filepath=tmpOBJface,
                                     filter_glob="*.obj;*.mtl")
            scene_dense_mesh_texture2 = bpy.data.objects[
                'scene_dense_mesh_texture2']
            bpy.ops.object.select_all(action='DESELECT')
            bpy.context.scene.objects.active = scene_dense_mesh_texture2
            bpy.data.objects['scene_dense_mesh_texture2'].select = True
            bpy.ops.view3d.view_all(center=False)
            bpy.ops.file.pack_all()

    print("FIX SMVS SURFACE AND MAP")

    photogrammetry_original = bpy.context.active_object

    #bpy.ops.object.duplicate()

    bpy.ops.object.duplicate_move()

    photogrammetry_original.select = True
    photogrammetry_copy = bpy.context.active_object

    print(photogrammetry_original)
    print(photogrammetry_copy)

    bpy.ops.object.modifier_add(type='DECIMATE')
    #bpy.context.object.modifiers["Decimate"].ratio = 0.25
    bpy.context.object.modifiers["Decimate"].ratio = 0.50
    bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Decimate")

    # Entra em modo de edição e seleciona todos os vértices
    ob = bpy.context.active_object
    bpy.ops.object.mode_set(mode='EDIT')
    mesh = bmesh.from_edit_mesh(ob.data)
    for v in mesh.verts:
        v.select = True

    # Cria UV map com espaço entre os grupos
    bpy.ops.uv.smart_project(island_margin=0.03)
    #    bpy.ops.uv.smart_project(island_margin=0.3)

    # Faz o bake
    #bpy.context.scene.render.use_bake_selected_to_active = True
    #bpy.context.scene.render.bake_type = 'TEXTURE'
    #bpy.context.scene.render.bake_margin = 4
    #bpy.ops.object.bake_image()

    #Cria imagem
    bpy.ops.image.new(name='UV_FACE',
                      width=4096,
                      height=4096,
                      color=(0.5, 0.5, 0.5, 1),
                      alpha=True,
                      generated_type='BLANK',
                      float=False,
                      gen_context='NONE',
                      use_stereo_3d=False)

    # BAKE
    bpy.context.scene.render.bake_margin = 2
    bpy.context.scene.render.use_bake_selected_to_active = True

    ob.data.uv_textures['UVMap'].active = True

    bpy.data.scenes["Scene"].render.bake_type = "TEXTURE"

    bpy.ops.object.mode_set(mode='OBJECT')

    for d in ob.data.uv_textures['UVMap'].data:
        d.image = bpy.data.images['UV_FACE']

    bpy.ops.object.mode_set(mode='EDIT')

    bpy.ops.mesh.select_all(action='SELECT')

    bpy.ops.object.bake_image()

    bpy.ops.object.mode_set(mode='OBJECT')

    # Oculta original
    photogrammetry_original.hide = True

    # MODIFICADORES

    # Smooth
    bpy.ops.object.modifier_add(type='SMOOTH')
    bpy.context.object.modifiers["Smooth"].factor = 2
    bpy.context.object.modifiers["Smooth"].iterations = 3
    bpy.context.object.modifiers["Smooth"].show_viewport = False

    # MultRes
    bpy.ops.object.modifier_add(type='MULTIRES')
    bpy.context.object.modifiers["Multires"].show_viewport = False
    bpy.ops.object.multires_subdivide(modifier="Multires")

    context = bpy.context
    obj = context.active_object

    heightTex = bpy.data.textures.new('Texture name', type='IMAGE')
    heightTex.image = bpy.data.images['UV_FACE']
    dispMod = obj.modifiers.new("Displace", type='DISPLACE')
    dispMod.texture = heightTex
    bpy.context.object.modifiers["Displace"].texture_coords = 'UV'
    bpy.context.object.modifiers["Displace"].strength = 2.2
    bpy.context.object.modifiers["Displace"].mid_level = 0.5
    bpy.context.object.modifiers["Displace"].show_viewport = False

    #Comprime modificadores
    bpy.context.object.modifiers["Smooth"].show_expanded = False
    bpy.context.object.modifiers["Multires"].show_expanded = False
    bpy.context.object.modifiers["Displace"].show_expanded = False

    bpy.ops.object.shade_smooth()

    #    bpy.ops.file.unpack_item(id_name="UV_FACE")
    #    bpy.data.images["UV_FACE"].filepath = tmpdir+'/UV_FACE.png'
    #    bpy.data.images["UV_FACE"].save()

    #    bpy.ops.file.pack_all()
    bpy.data.images["UV_FACE"].pack(as_png=True)
Esempio n. 32
0
def DisplaceSMVSDef(self, context):

    scn = context.scene

    print("FIX SMVS SURFACE AND MAP")

    photogrammetry_original = bpy.context.active_object

    #bpy.ops.object.duplicate()

    bpy.ops.object.duplicate_move()

    photogrammetry_original.select = True
    photogrammetry_copy = bpy.context.active_object

    print(photogrammetry_original)
    print(photogrammetry_copy)

    bpy.ops.object.modifier_add(type='DECIMATE')
    #bpy.context.object.modifiers["Decimate"].ratio = 0.25
    bpy.context.object.modifiers["Decimate"].ratio = 0.50
    bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Decimate")

    # Entra em modo de edição e seleciona todos os vértices
    ob = bpy.context.active_object
    bpy.ops.object.mode_set(mode='EDIT')
    mesh = bmesh.from_edit_mesh(ob.data)
    for v in mesh.verts:
        v.select = True

    # Cria UV map com espaço entre os grupos
    bpy.ops.uv.smart_project(island_margin=0.03)
    #    bpy.ops.uv.smart_project(island_margin=0.3)

    # Faz o bake
    #bpy.context.scene.render.use_bake_selected_to_active = True
    #bpy.context.scene.render.bake_type = 'TEXTURE'
    #bpy.context.scene.render.bake_margin = 4
    #bpy.ops.object.bake_image()

    #Cria imagem
    bpy.ops.image.new(name='UV_NEW',
                      width=4096,
                      height=4096,
                      color=(0.5, 0.5, 0.5, 1),
                      alpha=True,
                      generated_type='BLANK',
                      float=False,
                      gen_context='NONE',
                      use_stereo_3d=False)

    # BAKE
    bpy.context.scene.render.bake_margin = 2
    bpy.context.scene.render.use_bake_selected_to_active = True

    ob.data.uv_textures['UVMap'].active = True

    bpy.data.scenes["Scene"].render.bake_type = "TEXTURE"

    bpy.ops.object.mode_set(mode='OBJECT')

    for d in ob.data.uv_textures['UVMap'].data:
        d.image = bpy.data.images['UV_NEW']

    bpy.ops.object.mode_set(mode='EDIT')

    bpy.ops.mesh.select_all(action='SELECT')

    bpy.ops.object.bake_image()

    bpy.ops.object.mode_set(mode='OBJECT')

    # Oculta original
    photogrammetry_original.hide = True

    # MODIFICADORES

    # Smooth
    bpy.ops.object.modifier_add(type='SMOOTH')
    bpy.context.object.modifiers["Smooth"].factor = 2
    bpy.context.object.modifiers["Smooth"].iterations = 3
    bpy.context.object.modifiers["Smooth"].show_viewport = False

    # MultRes
    bpy.ops.object.modifier_add(type='MULTIRES')
    bpy.context.object.modifiers["Multires"].show_viewport = False
    bpy.ops.object.multires_subdivide(modifier="Multires")

    context = bpy.context
    obj = context.active_object

    heightTex = bpy.data.textures.new('Texture name', type='IMAGE')
    heightTex.image = bpy.data.images['UV_NEW']
    dispMod = obj.modifiers.new("Displace", type='DISPLACE')
    dispMod.texture = heightTex
    bpy.context.object.modifiers["Displace"].texture_coords = 'UV'
    bpy.context.object.modifiers["Displace"].strength = 2.2
    bpy.context.object.modifiers["Displace"].mid_level = 0.5
    bpy.context.object.modifiers["Displace"].show_viewport = False

    #Comprime modificadores
    bpy.context.object.modifiers["Smooth"].show_expanded = False
    bpy.context.object.modifiers["Multires"].show_expanded = False
    bpy.context.object.modifiers["Displace"].show_expanded = False

    bpy.ops.object.shade_smooth()

    bpy.data.images["UV_NEW"].pack(as_png=True)
    bpy.ops.file.pack_all()
Esempio n. 33
0
    def execute(self, context):

        # enableing the auto execute

        bpy.context.user_preferences.system.use_scripts_auto_execute = True

        # saving the orignal object name
        object_name = bpy.context.active_object.name
        object_new_name = "Spin_" + object_name
        # separating objects If needed
        obj = bpy.context.active_object
        if bpy.context.mode == 'EDIT_MESH':
            bm = bmesh.from_edit_mesh(obj.data)
            selected_vertex = [v.index for v in bm.verts if v.select]
        else:
            selected_vertex = [v.index for v in obj.data.vertices if v.select]

        selected_vertex = len(selected_vertex)
        total_vertex = (len(obj.data.vertices))
        # If we need separation
        if total_vertex - selected_vertex > 0:
            bpy.ops.mesh.select_all(action='INVERT')
            bpy.ops.mesh.separate(type='SELECTED')
            bpy.ops.object.mode_set(mode='OBJECT')
            bpy.data.objects[object_name].select = False
            for obj in bpy.context.scene.objects:
                obj.select = (obj == bpy.context.scene.objects.active)
            active_object = bpy.context.active_object
            active_object.name = object_new_name
        # If we don't need separation
        else:
            bpy.ops.object.mode_set(mode='OBJECT')
            active_object = bpy.context.active_object
            active_object.name = object_new_name

        # Apply rotation and scale
        bpy.ops.object.transform_apply(location=False,
                                       rotation=True,
                                       scale=True)
        # set the origin of the object to the 3d cursor
        bpy.ops.object.origin_set(type='ORIGIN_CURSOR')

        # add the main empty(the one which is going to be rotated with the driver)
        bpy.ops.object.empty_add(type='PLAIN_AXES')

        # rename the main empty
        active_object = bpy.context.active_object
        active_object.name = "Object offset_main"

        # add the array offset object_child
        bpy.ops.object.empty_add(type='PLAIN_AXES')

        # change the name of the array offset object_child
        active_object = bpy.context.active_object
        active_object.name = "Object offset_child"

        # add the array offset object_parent
        for area in bpy.context.screen.areas:
            if area.type == 'VIEW_3D':
                for region in area.regions:
                    if region.type == 'WINDOW':
                        ctx = bpy.context.copy()
                        ctx['area'] = area
                        ctx['region'] = region
                        bpy.ops.object.empty_add(ctx,
                                                 type='PLAIN_AXES',
                                                 view_align=True)

        # change the name of the array offset_parent
        active_object = bpy.context.active_object
        active_object.name = "Object offset_parent"

        # add the copy rotation constraint

        bpy.ops.object.constraint_add(type='COPY_ROTATION')
        bpy.context.object.constraints[
            "Copy Rotation"].target = bpy.data.objects["Object offset_main"]
        bpy.context.object.constraints["Copy Rotation"].use_x = False
        bpy.context.object.constraints["Copy Rotation"].use_y = False
        bpy.context.object.constraints["Copy Rotation"].use_z = True
        bpy.context.object.constraints["Copy Rotation"].owner_space = 'LOCAL'

        # make the parent relation

        child_object = bpy.data.objects["Object offset_child"]
        parent_object = bpy.data.objects["Object offset_parent"]

        bpy.ops.object.select_all(action='DESELECT')

        child_object.select = True
        parent_object.select = True

        bpy.context.scene.objects.active = parent_object

        bpy.ops.object.parent_set()

        # select the spin object
        bpy.context.scene.objects.active = bpy.data.objects[object_new_name]
        for obj in bpy.context.scene.objects:
            obj.select = (obj == bpy.context.scene.objects.active)

        # add the array modifier
        bpy.ops.object.modifier_add(type='ARRAY')
        bpy.context.object.modifiers["Array"].use_relative_offset = False
        bpy.context.object.modifiers["Array"].use_object_offset = True
        bpy.context.object.modifiers["Array"].offset_object = bpy.data.objects[
            "Object offset_child"]

        # add the array count custom property
        active_object = bpy.context.active_object
        active_object["Array count"] = 6
        active_object["_RNA_UI"] = {"Array count": {"min": 2}}

        # add the driver to the array count
        myDriver = bpy.context.object.driver_add('modifiers["Array"].count')
        myDriver.driver.expression = "Array_count"
        newVar = myDriver.driver.variables.new()
        newVar.name = "Array_count"
        newVar.type = 'SINGLE_PROP'
        newVar.targets[0].id = bpy.data.objects[object_new_name]
        newVar.targets[0].data_path = '["Array count"]'

        # select the main empty
        bpy.context.scene.objects.active = bpy.data.objects[
            "Object offset_main"]
        for obj in bpy.context.scene.objects:
            obj.select = (obj == bpy.context.scene.objects.active)

        # add the driver to the main empty

        myDriver = bpy.context.object.driver_add('rotation_euler', 2)
        myDriver.driver.expression = "360/Array * pi/180"
        newVar = myDriver.driver.variables.new()
        newVar.name = "Array"
        newVar.type = 'SINGLE_PROP'
        newVar.targets[0].id = bpy.data.objects[object_new_name]
        newVar.targets[0].data_path = 'modifiers["Array"].count'

        # select the spin object
        bpy.context.scene.objects.active = bpy.data.objects[object_new_name]
        for obj in bpy.context.scene.objects:
            obj.select = (obj == bpy.context.scene.objects.active)

        # cleaning the scene

        bpy.data.objects["Object offset_main"].hide = True
        bpy.data.objects["Object offset_child"].hide = True

        return {'FINISHED'}
Esempio n. 34
0
    def toggle_subd(self, context, obj, subds, toggle_type='TOGGLE'):
        self.mode = 'SUBD'

        if obj.mode == 'EDIT':
            bm = bmesh.from_edit_mesh(obj.data)
            bm.normal_update()
            bm.faces.ensure_lookup_table()

        else:
            bm = bmesh.new()
            bm.from_mesh(obj.data)
            bm.normal_update()
            bm.faces.ensure_lookup_table()

        overlay = context.space_data.overlay

        for subd in subds:
            if not subd.show_on_cage:
                subd.show_on_cage = True

        # ENABLE

        if not (subds[0].show_in_editmode and subds[0].show_viewport):
            if toggle_type in ['TOGGLE', 'ENABLE']:

                # enable face smoothing if necessary
                if not bm.faces[0].smooth:
                    for f in bm.faces:
                        f.smooth = True

                    if obj.mode == 'EDIT':
                        bmesh.update_edit_mesh(obj.data)
                    else:
                        bm.to_mesh(obj.data)
                        bm.free()

                    obj.M3.has_smoothed = True

                for subd in subds:
                    subd.show_in_editmode = True
                    subd.show_viewport = True

                # disable overlays, prevent doing it multiple times when batch smoothing
                if self.toggle_subd_overlays and toggle_type == 'TOGGLE':
                    overlay.show_overlays = False
                return 'ENABLE'


        # DISABLE

        else:
            if toggle_type in ['TOGGLE', 'DISABLE']:

                # disable face smoothing if it was enabled before
                if obj.M3.has_smoothed:
                    for f in bm.faces:
                        f.smooth = False

                    if obj.mode == 'EDIT':
                        bmesh.update_edit_mesh(obj.data)

                    else:
                        bm.to_mesh(obj.data)
                        bm.free()

                    obj.M3.has_smoothed = False


                for subd in subds:
                    subd.show_in_editmode = False
                    subd.show_viewport = False

                # re-enable overlays, prevent doing it multiple times when batch smoothing
                if toggle_type == 'TOGGLE':
                    overlay.show_overlays = True
                return 'DISABLE'

        print(f" INFO: SubD Smoothing is {'enabled' if toggle_type == 'ENABLE' else 'disabled'} already for {obj.name}")
        return toggle_type
Esempio n. 35
0
    def execute(self, context):
        ob = bpy.context.active_object
        me = ob.data
        bm = bmesh.from_edit_mesh(me)

        # Get the selected curve object and the required spline
        cuob = context.scene.objects[int(self.curveob)]
        cu = cuob.data

        self.splineidx = min(self.splineidx, len(cu.splines) - 1)
        p = cu.splines[self.splineidx].bezier_points

        # Get the property values
        res = self.resolution
        scale = self.scale
        rotation = self.rotation
        dscale = (1 - scale) / res
        drot = rotation / res

        # Get the matrices to convert between spaces
        cmat = ob.matrix_world.inverted() * cuob.matrix_world
        ctanmat = cmat.to_3x3().inverted().transposed()

        # The list of parameter values to evaluate the bezier curve at
        tvals = [t / res for t in range(res + 1)]

        # Get the first selected face, if none, cancel
        for f in bm.faces:
            if f.select:
                break
        else:
            return {'CANCELLED'}

        # Get the position vecs on the curve and tangent values
        bezval = [eval_bez(cmat, p, t) for t in tvals]
        beztan = [eval_bez_tan(ctanmat, p, t) for t in tvals]
        bezquat = [0] * len(tvals)

        # Using curve only
        bezquat[0] = beztan[0].to_track_quat('Z', 'Y')
        fquat = bezquat[0].inverted()

        # Calculate the min twist orientations
        for i in range(1, res + 1):
            ang = beztan[i - 1].angle(beztan[i], 0.0)
            if ang > 0.0:
                axis = beztan[i - 1].cross(beztan[i])
                q = Quaternion(axis, ang)
                bezquat[i] = q * bezquat[i - 1]
            else:
                bezquat[i] = bezquat[i - 1].copy()

        # Get the faces to be modified
        fprev = f
        # no = f.normal.copy()
        faces = [f.copy() for i in range(res)]

        # Offset if we need to snap to the face
        offset = Vector() if not self.snapto else (f.calc_center_median() -
                                                   bezval[0])

        # For each of the faces created, set their vert positions and create side faces
        for i, data in enumerate(zip(faces, bezval[1:], bezquat[1:])):

            fn, pos, quat = data
            cen = fn.calc_center_median()

            rotquat = Quaternion((0, 0, 1), i * drot)

            for v in fn.verts:
                v.co = quat * rotquat * fquat * (v.co - cen) * (
                    1 - (i + 1) * dscale) + pos + offset

            for ll, ul in zip(fprev.loops, fn.loops):
                ff = bm.faces.new((ll.vert, ll.link_loop_next.vert,
                                   ul.link_loop_next.vert, ul.vert))
                ff.normal_update()

            bm.faces.remove(fprev)
            fprev = fn

        me.calc_tessface()
        me.calc_normals()
        me.update()

        return {'FINISHED'}
def main(
    context,
    island_margin,
    projection_limit,
    user_area_weight,
    use_aspect,
    stretch_to_bounds,
):
    global USER_FILL_HOLES
    global USER_FILL_HOLES_QUALITY
    global USER_STRETCH_ASPECT
    global USER_ISLAND_MARGIN

    from math import cos
    import time

    global dict_matrix
    dict_matrix = {}

    # Constants:
    # Takes a list of faces that make up a UV island and rotate
    # until they optimally fit inside a square.
    global ROTMAT_2D_POS_90D
    global ROTMAT_2D_POS_45D
    global RotMatStepRotation
    main_consts()

    # Create the variables.
    USER_PROJECTION_LIMIT = projection_limit
    USER_ONLY_SELECTED_FACES = True
    USER_SHARE_SPACE = 1  # Only for hole filling.
    USER_STRETCH_ASPECT = stretch_to_bounds
    USER_ISLAND_MARGIN = island_margin  # Only for hole filling.
    USER_FILL_HOLES = 0
    USER_FILL_HOLES_QUALITY = 50  # Only for hole filling.
    USER_VIEW_INIT = 0  # Only for hole filling.

    is_editmode = (context.active_object.mode == 'EDIT')
    if is_editmode:
        obList = [
            ob for ob in [context.active_object] if ob and ob.type == 'MESH'
        ]
    else:
        obList = [
            ob for ob in context.selected_editable_objects
            if ob and ob.type == 'MESH'
        ]
        USER_ONLY_SELECTED_FACES = False

    if not obList:
        raise Exception("error, no selected mesh objects")

    # Reuse variable
    if len(obList) == 1:
        ob = "Unwrap %i Selected Mesh"
    else:
        ob = "Unwrap %i Selected Meshes"

    # HACK, loop until mouse is lifted.
    '''
    while Window.GetMouseButtons() != 0:
        time.sleep(10)
    '''

    # ~ XXX	if not Draw.PupBlock(ob % len(obList), pup_block):
    # ~ XXX		return
    # ~ XXX	del ob

    # Convert from being button types

    USER_PROJECTION_LIMIT_CONVERTED = cos(USER_PROJECTION_LIMIT * DEG_TO_RAD)
    USER_PROJECTION_LIMIT_HALF_CONVERTED = cos(
        (USER_PROJECTION_LIMIT / 2) * DEG_TO_RAD)

    # Toggle Edit mode
    is_editmode = (context.active_object.mode == 'EDIT')
    if is_editmode:
        bpy.ops.object.mode_set(mode='OBJECT')
    # Assume face select mode! an annoying hack to toggle face select mode because Mesh doesn't like faceSelectMode.

    if USER_SHARE_SPACE:
        # Sort by data name so we get consistent results
        obList.sort(key=lambda ob: ob.data.name)
        collected_islandList = []

# XXX	Window.WaitCursor(1)

    time1 = time.time()

    # Tag as False so we don't operate on the same mesh twice.
    # XXX	bpy.data.meshes.tag = False
    for me in bpy.data.meshes:
        me.tag = False

    for ob in obList:
        me = ob.data

        if me.tag or me.library:
            continue

        # Tag as used
        me.tag = True

        if not me.uv_layers:  # Mesh has no UV Coords, don't bother.
            me.uv_layers.new()

        uv_layer = me.uv_layers.active.data
        me_verts = list(me.vertices)

        if USER_ONLY_SELECTED_FACES:
            meshFaces = [
                thickface(f, uv_layer, me_verts)
                for i, f in enumerate(me.polygons) if f.select
            ]
        else:
            meshFaces = [
                thickface(f, uv_layer, me_verts)
                for i, f in enumerate(me.polygons)
            ]

# XXX		Window.DrawProgressBar(0.1, 'SmartProj UV Unwrapper, mapping "%s", %i faces.' % (me.name, len(meshFaces)))

# =======
# Generate a projection list from face normals, this is meant to be smart :)

# make a list of face props that are in sync with meshFaces
# Make a Face List that is sorted by area.
# meshFaces = []

# meshFaces.sort( lambda a, b: cmp(b.area , a.area) ) # Biggest first.
        meshFaces.sort(key=lambda a: -a.area)

        # remove all zero area faces
        while meshFaces and meshFaces[-1].area <= SMALL_NUM:
            # Set their UV's to 0,0
            for uv in meshFaces[-1].uv:
                uv.zero()
            meshFaces.pop()

        if not meshFaces:
            continue

        # Smallest first is slightly more efficient, but if the user cancels early then its better we work on the larger data.

        # Generate Projection Vecs
        # 0d is   1.0
        # 180 IS -0.59846

        # Initialize projectVecs
        if USER_VIEW_INIT:
            # Generate Projection
            projectVecs = [
                Vector(Window.GetViewVector()) *
                ob.matrix_world.inverted().to_3x3()
            ]  # We add to this along the way
        else:
            projectVecs = []

        newProjectVec = meshFaces[0].no
        newProjectMeshFaces = []  # Popping stuffs it up.

        # Pretend that the most unique angle is ages away to start the loop off
        mostUniqueAngle = -1.0

        # This is popped
        tempMeshFaces = meshFaces[:]

        # This while only gathers projection vecs, faces are assigned later on.
        while 1:
            # If theres none there then start with the largest face

            # add all the faces that are close.
            for fIdx in range(len(tempMeshFaces) - 1, -1, -1):
                # Use half the angle limit so we don't overweight faces towards this
                # normal and hog all the faces.
                if newProjectVec.dot(tempMeshFaces[fIdx].no
                                     ) > USER_PROJECTION_LIMIT_HALF_CONVERTED:
                    newProjectMeshFaces.append(tempMeshFaces.pop(fIdx))

            # Add the average of all these faces normals as a projectionVec
            averageVec = Vector((0.0, 0.0, 0.0))
            if user_area_weight == 0.0:
                for fprop in newProjectMeshFaces:
                    averageVec += fprop.no
            elif user_area_weight == 1.0:
                for fprop in newProjectMeshFaces:
                    averageVec += fprop.no * fprop.area
            else:
                for fprop in newProjectMeshFaces:
                    averageVec += fprop.no * ((fprop.area * user_area_weight) +
                                              (1.0 - user_area_weight))

            if averageVec.x != 0 or averageVec.y != 0 or averageVec.z != 0:  # Avoid NAN
                projectVecs.append(averageVec.normalized())

            # Get the next vec!
            # Pick the face thats most different to all existing angles :)
            mostUniqueAngle = 1.0  # 1.0 is 0d. no difference.
            mostUniqueIndex = 0  # dummy

            for fIdx in range(len(tempMeshFaces) - 1, -1, -1):
                angleDifference = -1.0  # 180d difference.

                # Get the closest vec angle we are to.
                for p in projectVecs:
                    temp_angle_diff = p.dot(tempMeshFaces[fIdx].no)

                    if angleDifference < temp_angle_diff:
                        angleDifference = temp_angle_diff

                if angleDifference < mostUniqueAngle:
                    # We have a new most different angle
                    mostUniqueIndex = fIdx
                    mostUniqueAngle = angleDifference

            if mostUniqueAngle < USER_PROJECTION_LIMIT_CONVERTED:
                # print 'adding', mostUniqueAngle, USER_PROJECTION_LIMIT, len(newProjectMeshFaces)
                # Now weight the vector to all its faces, will give a more direct projection
                # if the face its self was not representative of the normal from surrounding faces.

                newProjectVec = tempMeshFaces[mostUniqueIndex].no
                newProjectMeshFaces = [tempMeshFaces.pop(mostUniqueIndex)]

            else:
                if len(projectVecs) >= 1:  # Must have at least 2 projections
                    break

        # If there are only zero area faces then its possible
        # there are no projectionVecs
        if not len(projectVecs):
            Draw.PupMenu(
                'error, no projection vecs where generated, 0 area faces can cause this.'
            )
            return

        faceProjectionGroupList = [[] for i in range(len(projectVecs))]

        # MAP and Arrange # We know there are 3 or 4 faces here

        for fIdx in range(len(meshFaces) - 1, -1, -1):
            fvec = meshFaces[fIdx].no
            i = len(projectVecs)

            # Initialize first
            bestAng = fvec.dot(projectVecs[0])
            bestAngIdx = 0

            # Cycle through the remaining, first already done
            while i - 1:
                i -= 1

                newAng = fvec.dot(projectVecs[i])
                if newAng > bestAng:  # Reverse logic for dotvecs
                    bestAng = newAng
                    bestAngIdx = i

            # Store the area for later use.
            faceProjectionGroupList[bestAngIdx].append(meshFaces[fIdx])

        # Cull faceProjectionGroupList,

        # Now faceProjectionGroupList is full of faces that face match the project Vecs list
        for i in range(len(projectVecs)):
            # Account for projectVecs having no faces.
            if not faceProjectionGroupList[i]:
                continue

            # Make a projection matrix from a unit length vector.
            MatQuat = VectoQuat(projectVecs[i])

            # Get the faces UV's from the projected vertex.
            for f in faceProjectionGroupList[i]:
                f_uv = f.uv
                for j, v in enumerate(f.v):
                    # XXX - note, between mathutils in 2.4 and 2.5 the order changed.
                    f_uv[j][:] = (MatQuat * v.co).xy

        if USER_SHARE_SPACE:
            # Should we collect and pack later?
            islandList = getUvIslands(faceProjectionGroupList, me)
            collected_islandList.extend(islandList)

        else:
            # Should we pack the islands for this 1 object?
            islandList = getUvIslands(faceProjectionGroupList, me)
            packIslands(islandList)

        # update the mesh here if we need to.

    # We want to pack all in 1 go, so pack now
    if USER_SHARE_SPACE:
        # XXX        Window.DrawProgressBar(0.9, "Box Packing for all objects...")
        packIslands(collected_islandList)

    print("Smart Projection time: %.2f" % (time.time() - time1))
    # Window.DrawProgressBar(0.9, "Smart Projections done, time: %.2f sec" % (time.time() - time1))

    # aspect correction is only done in edit mode - and only smart unwrap supports currently
    if is_editmode:
        bpy.ops.object.mode_set(mode='EDIT')

        if use_aspect:
            import bmesh
            aspect = context.scene.uvedit_aspect(context.active_object)
            if aspect[0] > aspect[1]:
                aspect[0] = aspect[1] / aspect[0]
                aspect[1] = 1.0
            else:
                aspect[1] = aspect[0] / aspect[1]
                aspect[0] = 1.0

            bm = bmesh.from_edit_mesh(me)

            uv_act = bm.loops.layers.uv.active

            faces = [f for f in bm.faces if f.select]

            for f in faces:
                for l in f.loops:
                    l[uv_act].uv[0] *= aspect[0]
                    l[uv_act].uv[1] *= aspect[1]

    dict_matrix.clear()
Esempio n. 37
0
    def toggle_korean_bevel(self, context, obj, toggle_type='TOGGLE'):
        self.mode = 'KOREAN'

        overlay = context.space_data.overlay

        # enabled auto_smooth if it isn't already
        if not obj.data.use_auto_smooth:
            obj.data.use_auto_smooth = True

        # get the currentl auto smooth angle
        angle = obj.data.auto_smooth_angle

        if obj.mode == 'EDIT':
            bm = bmesh.from_edit_mesh(obj.data)
            bm.normal_update()
            bm.faces.ensure_lookup_table()

        else:
            bm = bmesh.new()
            bm.from_mesh(obj.data)
            bm.normal_update()
            bm.faces.ensure_lookup_table()


        # ENABLE

        if degrees(angle) < 180:
            if toggle_type in ['TOGGLE', 'ENABLE']:
                obj.M3.smooth_angle = angle

                # change the auto-smooth angle
                obj.data.auto_smooth_angle = radians(180)

                # enable face smoothing if necessary
                if not bm.faces[0].smooth:
                    for f in bm.faces:
                        f.smooth = True

                    if obj.mode == 'EDIT':
                        bmesh.update_edit_mesh(obj.data)
                    else:
                        bm.to_mesh(obj.data)
                        bm.free()

                    obj.M3.has_smoothed = True

                # disable overlays
                if self.toggle_korean_bevel_overlays and toggle_type == 'TOGGLE':
                    overlay.show_overlays = False
                return 'ENABLE'


        # DISABLE

        else:
            if toggle_type in ['TOGGLE', 'DISABLE']:

                # change the auto-smooth angle
                obj.data.auto_smooth_angle = obj.M3.smooth_angle

                # disable face smoothing if it was enabled before
                if obj.M3.has_smoothed:
                    for f in bm.faces:
                        f.smooth = False

                    if obj.mode == 'EDIT':
                        bmesh.update_edit_mesh(obj.data)

                    else:
                        bm.to_mesh(obj.data)
                        bm.free()

                    obj.M3.has_smoothed = False

                # re-enable overlays
                if toggle_type == 'TOGGLE':
                    overlay.show_overlays = True
                return 'DISABLE'

        print(f" INFO: Korean Bevel Smoothing is {'enabled' if toggle_type == 'ENABLE' else 'disabled'} already for {obj.name}")
        return toggle_type
    def create_mesh(self):
        try:
            bpy.ops.object.mode_set(mode='OBJECT')
        except:
            ok = True
        
        try:
            bpy.ops.object.select_all(action='DESELECT')
        except:
            ok = True
        
        z = self.z_mesh
        
        z.mesh = bpy.data.meshes.new(name=z.name)
        z.mesh.from_pydata(z.vertices, z.edges, z.faces)
        z.mesh.update(calc_tessface=True)
        # Safety Duplicate Name Check.
        z.name = z.mesh.name

        object_data_add(context, z.mesh)
        
        bpy.ops.object.select_pattern(pattern=z.name)
        z.object = bpy.context.active_object
        z.mesh = z.object.data
        
        bpy.ops.object.mode_set(mode = 'EDIT')
        # UV Assignments
        bm = bmesh.from_edit_mesh(z.mesh)
        uv_layer = bm.loops.layers.uv.verify()
        bm.faces.layers.tex.verify()
        voffset = 0
        for f in bm.faces:
            index = f.index
            uv_array = z.face_uvs[index]
            vo = 0
            for l in f.loops:
                luv = l[uv_layer]
                luv.uv = uv_array[vo]
                vo += 1
        bmesh.update_edit_mesh(z.mesh)
        
        if z.has_armature:
            bpy.ops.object.mode_set(mode = 'OBJECT')
            if self.lock_model_on_armature_detection:
                z.object.lock_location = z.object.lock_rotation = z.object.lock_scale = [True, True, True]
            
            
            print(z.skeleton.object)
            old_active = bpy.context.active_object     
            self.scene.objects.active = z.skeleton.object 
            z.object.select = True                          
            bpy.ops.object.parent_set(type='ARMATURE')                       
            self.scene.objects.active = old_active                    
            z.object.select = False                         
           
            bpy.ops.object.mode_set(mode = 'OBJECT')

            # Weight Assignments
            for bone in z.skeleton.armature.bones:
                bpy.ops.object.vertex_group_add()
                vertex_group      = z.object.vertex_groups.active    
                vertex_group.name = bone.name
                bone_import_index = int(z.skeleton.object[bone.name])

                offset_vert = 0
                for vertex in z.mesh.vertices:
                    vertex_weight_ids = z.weight_indexes[offset_vert]
                    vertex_weights    = z.weight_values[offset_vert]
                    
                    offset = 0
                    for vert_weight_id in vertex_weight_ids:
                        if vert_weight_id == bone_import_index:
                            verts = []
                            verts.append(vertex.index)
                            vertex_group.add(verts, vertex_weights[offset], 'REPLACE')
                        offset += 1
                    offset_vert += 1
        
        if self.optimize_model:
            bpy.ops.object.mode_set(mode = 'EDIT')
            bpy.ops.mesh.remove_doubles()
            bpy.ops.mesh.tris_convert_to_quads()
            bpy.ops.object.mode_set(mode = 'OBJECT')
Esempio n. 39
0
def main(square=False, snapToClosest=False):

    startTime = time.clock()
    obj = bpy.context.active_object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)
    uv_layers = bm.loops.layers.uv.verify()
    # bm.faces.layers.tex.verify()  # currently blender needs both layers.

    face_act = bm.faces.active
    targetFace = face_act

    #if len(bm.faces) > allowedFaces:
    #    operator.report({'ERROR'}, "selected more than " +str(allowedFaces) +" allowed faces.")
    #   return

    edgeVerts, filteredVerts, selFaces, nonQuadFaces, vertsDict, noEdge = ListsOfVerts(
        uv_layers, bm)

    if len(filteredVerts) is 0: return
    if len(filteredVerts) is 1:
        SnapCursorToClosestSelected(filteredVerts)
        return

    cursorClosestTo = CursorClosestTo(filteredVerts)
    #line is selected

    if len(selFaces) is 0:
        if snapToClosest is True:
            SnapCursorToClosestSelected(filteredVerts)
            return

        VertsDictForLine(uv_layers, bm, filteredVerts, vertsDict)

        if AreVectsLinedOnAxis(filteredVerts) is False:
            ScaleTo0OnAxisAndCursor(filteredVerts, vertsDict, cursorClosestTo)
            return SuccessFinished(me, startTime)

        MakeEqualDistanceBetweenVertsInLine(filteredVerts, vertsDict,
                                            cursorClosestTo)
        return SuccessFinished(me, startTime)

    #else:

    #active face checks
    if targetFace is None or targetFace.select is False or len(
            targetFace.verts) is not 4:
        targetFace = selFaces[0]
    else:
        for l in targetFace.loops:
            if l[uv_layers].select is False:
                targetFace = selFaces[0]
                break

    ShapeFace(uv_layers, operator, targetFace, vertsDict, square)

    for nf in nonQuadFaces:
        for l in nf.loops:
            luv = l[uv_layers]
            luv.select = False

    if square: FollowActiveUV(operator, me, targetFace, selFaces, 'EVEN')
    else: FollowActiveUV(operator, me, targetFace, selFaces)

    if noEdge is False:
        #edge has ripped so we connect it back
        for ev in edgeVerts:
            key = (round(ev.uv.x, precision), round(ev.uv.y, precision))
            if key in vertsDict:
                ev.uv = vertsDict[key][0].uv
                ev.select = True

    return SuccessFinished(me, startTime)
Esempio n. 40
0
def FollowActiveUV(operator, me, f_act, faces, EXTEND_MODE='LENGTH_AVERAGE'):
    bm = bmesh.from_edit_mesh(me)
    uv_act = bm.loops.layers.uv.active

    # our own local walker
    def walk_face_init(faces, f_act):
        # first tag all faces True (so we dont uvmap them)
        for f in bm.faces:
            f.tag = True
        # then tag faces arg False
        for f in faces:
            f.tag = False
        # tag the active face True since we begin there
        f_act.tag = True

    def walk_face(f):
        # all faces in this list must be tagged
        f.tag = True
        faces_a = [f]
        faces_b = []

        while faces_a:
            for f in faces_a:
                for l in f.loops:
                    l_edge = l.edge
                    if (l_edge.is_manifold is True) and (l_edge.seam is False):
                        l_other = l.link_loop_radial_next
                        f_other = l_other.face
                        if not f_other.tag:
                            yield (f, l, f_other)
                            f_other.tag = True
                            faces_b.append(f_other)
            # swap
            faces_a, faces_b = faces_b, faces_a
            faces_b.clear()

    def walk_edgeloop(l):
        """
		Could make this a generic function
		"""
        e_first = l.edge
        e = None
        while True:
            e = l.edge
            yield e

            # don't step past non-manifold edges
            if e.is_manifold:
                # welk around the quad and then onto the next face
                l = l.link_loop_radial_next
                if len(l.face.verts) == 4:
                    l = l.link_loop_next.link_loop_next
                    if l.edge is e_first:
                        break
                else:
                    break
            else:
                break

    def extrapolate_uv(fac, l_a_outer, l_a_inner, l_b_outer, l_b_inner):
        l_b_inner[:] = l_a_inner
        l_b_outer[:] = l_a_inner + ((l_a_inner - l_a_outer) * fac)

    def apply_uv(f_prev, l_prev, f_next):
        l_a = [None, None, None, None]
        l_b = [None, None, None, None]

        l_a[0] = l_prev
        l_a[1] = l_a[0].link_loop_next
        l_a[2] = l_a[1].link_loop_next
        l_a[3] = l_a[2].link_loop_next

        #  l_b
        #  +-----------+
        #  |(3)        |(2)
        #  |           |
        #  |l_next(0)  |(1)
        #  +-----------+
        #        ^
        #  l_a   |
        #  +-----------+
        #  |l_prev(0)  |(1)
        #  |    (f)    |
        #  |(3)        |(2)
        #  +-----------+
        #  copy from this face to the one above.

        # get the other loops
        l_next = l_prev.link_loop_radial_next
        if l_next.vert != l_prev.vert:
            l_b[1] = l_next
            l_b[0] = l_b[1].link_loop_next
            l_b[3] = l_b[0].link_loop_next
            l_b[2] = l_b[3].link_loop_next
        else:
            l_b[0] = l_next
            l_b[1] = l_b[0].link_loop_next
            l_b[2] = l_b[1].link_loop_next
            l_b[3] = l_b[2].link_loop_next

        l_a_uv = [l[uv_act].uv for l in l_a]
        l_b_uv = [l[uv_act].uv for l in l_b]

        if EXTEND_MODE == 'LENGTH_AVERAGE':
            fac = edge_lengths[l_b[2].edge.index][0] / edge_lengths[
                l_a[1].edge.index][0]
        elif EXTEND_MODE == 'LENGTH':
            a0, b0, c0 = l_a[3].vert.co, l_a[0].vert.co, l_b[3].vert.co
            a1, b1, c1 = l_a[2].vert.co, l_a[1].vert.co, l_b[2].vert.co

            d1 = (a0 - b0).length + (a1 - b1).length
            d2 = (b0 - c0).length + (b1 - c1).length
            try:
                fac = d2 / d1
            except ZeroDivisionError:
                fac = 1.0
        else:
            fac = 1.0

        extrapolate_uv(fac, l_a_uv[3], l_a_uv[0], l_b_uv[3], l_b_uv[0])

        extrapolate_uv(fac, l_a_uv[2], l_a_uv[1], l_b_uv[2], l_b_uv[1])

    # -------------------------------------------
    # Calculate average length per loop if needed

    if EXTEND_MODE == 'LENGTH_AVERAGE':
        bm.edges.index_update()
        edge_lengths = [None] * len(
            bm.edges)  #NoneType times the length of edges list

        for f in faces:
            # we know its a quad
            l_quad = f.loops[:]
            l_pair_a = (l_quad[0], l_quad[2])
            l_pair_b = (l_quad[1], l_quad[3])

            for l_pair in (l_pair_a, l_pair_b):
                if edge_lengths[l_pair[0].edge.index] is None:

                    edge_length_store = [-1.0]
                    edge_length_accum = 0.0
                    edge_length_total = 0

                    for l in l_pair:
                        if edge_lengths[l.edge.index] is None:
                            for e in walk_edgeloop(l):
                                if edge_lengths[e.index] is None:
                                    edge_lengths[e.index] = edge_length_store
                                    edge_length_accum += e.calc_length()
                                    edge_length_total += 1

                    edge_length_store[
                        0] = edge_length_accum / edge_length_total

    # done with average length
    # ------------------------

    walk_face_init(faces, f_act)
    for f_triple in walk_face(f_act):
        apply_uv(*f_triple)

    bmesh.update_edit_mesh(me, False)
Esempio n. 41
0
	def execute(self, context):
		active = context.active_object
		bm=bmesh.from_edit_mesh(active.data)
		# re select element under cursor
		bpy.ops.view3d.select(extend=True, deselect=self.deselect, toggle=False, location=self.loc)
  
		if issubclass(type(bm.select_history.active),bmesh.types.BMEdge):
			active_edge=bm.select_history.active
			#print(active_edge)
			# bpy.ops.mesh.loop_multi_select(ring=False)
			# active.data.update()
			# bm=bmesh.from_edit_mesh(active.data)

			# new_selection=[a.index for a in bm.edges if a.select]
			# deselect_all()
			# active_edge=bm.edges[active_edge_index]
			# active_edge.select=True
			og_edge=active_edge
			if active_edge and len(active_edge.link_faces)==2:
				angle=active_edge.calc_face_angle_signed()
				vert=active_edge.other_vert(active_edge.verts[0])
				og_vert=vert
				other_vert=active_edge.verts[0]
				used=[]
				used.append(active_edge.verts[0])
				used.append(active_edge.verts[1])
				while vert:
					#sorted_edge=sorted([e for e in vert.link_edges],key =lambda x:True if [f for f in x.link_faces if f in active_edge.link_faces] else False)
					sorted_edge=sorted([e for e in vert.link_edges],key =lambda x:get_angle(x,active_edge,vert))
					
					l=filter(lambda x:get_angle(x,active_edge,vert)<self.edge_threshold,sorted_edge)
					
					for e in l:
						if e!=active_edge and len(e.link_faces)==2:
							
							if abs(e.calc_face_angle_signed()-angle)<self.face_threshold:
								e.select = not self.deselect
								active_edge=e
								vert=[v for v in e.verts if v!=vert and v not in used]
								if vert:
									vert=vert[0]
									used.append(vert)
								break
					else:
								vert=None
				vert=other_vert
				active_edge=og_edge
				while vert:
					sorted_edge=sorted([e for e in vert.link_edges],key =lambda x:get_angle(x,active_edge,vert))
					
					l=filter(lambda x:get_angle(x,active_edge,vert)<self.edge_threshold,sorted_edge)
					for e in l:
						if e!=active_edge  and len(e.link_faces)==2:
							if abs(e.calc_face_angle_signed()-angle)<self.face_threshold:
								e.select=not self.deselect
								active_edge=e
								vert=[v for v in e.verts if v!=vert and v not in used]
								if vert:
									vert=vert[0]
									used.append(vert)
								break
					else:
								vert=None
				selected_verts=[v for v in bm.verts if v.select]
				vert=other_vert
				active_edge=og_edge
				#print(vert)
				split_verts=get_split_vert(vert,active_edge)
				edges_to_deselect=[]
				if split_verts:

					for split_vert in split_verts:
						
						deselect=False
						
						for e in split_vert.link_edges:
							if e.select:
								(length,edges)=get_path_to_self(vert,e,split_vert)
								
								if length<99999:
									deselect=True
								else:
									edges_to_deselect.append((length,edges))
					edges_to_deselect=sorted(edges_to_deselect,key=lambda x : x[0])
					if deselect:
						for i,e in enumerate(edges_to_deselect):
								for edge in e[1]:
									edge.select=False
				vert=og_vert
				active_edge=og_edge
				#print(vert)
				split_verts=get_split_vert(vert,active_edge)
				edges_to_deselect=[]
				if split_verts:

					for split_vert in split_verts:
						
						deselect=False
						
						for e in split_vert.link_edges:
							if e.select:
								(length,edges)=get_path_to_self(vert,e,split_vert)
								
								if length<99999:
									deselect=True
								else:
									edges_to_deselect.append((length,edges))
					edges_to_deselect=sorted(edges_to_deselect,key=lambda x : x[0])
					if deselect:
						for i,e in enumerate(edges_to_deselect):
								for edge in e[1]:
									edge.select=False
				if self.deselect:
					bpy.ops.view3d.select(deselect=True, extend=False, location=self.loc)
     
				context.active_object.data.update()
			else:
				self.report({'WARNING'},'Edge has more than 2 adjacent faces')
		else:
			self.report({'WARNING'},'Active element must be an edge!')
		return {'FINISHED'}
Esempio n. 42
0
    def mesh_to_bin_and_dic(self):
        self.json_dic["meshes"] = []
        for id, mesh in enumerate([
                obj for obj in bpy.context.selected_objects
                if obj.type == "MESH"
        ]):
            is_skin_mesh = True
            if len([m for m in mesh.modifiers if m.type == "ARMATURE"]) == 0:
                if mesh.parent is not None:
                    if mesh.parent.type == "ARMATURE":
                        if mesh.parent_bone != None:
                            is_skin_mesh = False
            node_dic = OrderedDict({
                "name":
                mesh.name,
                "translation":
                self.axis_blender_to_glb(
                    mesh.location),  #原点にいてほしいけどね, vectorのままだとjsonに出来ないからこうする
                "rotation": [0, 0, 0, 1],  #このへんは規約なので
                "scale": [1, 1, 1],  #このへんは規約なので
                "mesh":
                id,
            })
            if is_skin_mesh:
                node_dic[
                    "skin"] = 0  #TODO: 決め打ちってどうよ:一体のモデルなのだから2つもあっては困る(から決め打ち(やめろ(やだ))
            self.json_dic["nodes"].append(node_dic)

            mesh_node_id = len(self.json_dic["nodes"]) - 1

            if is_skin_mesh:
                self.json_dic["scenes"][0]["nodes"].append(mesh_node_id)
            else:
                parent_node = [
                    node for node in self.json_dic["nodes"]
                    if node["name"] == mesh.parent_bone
                ][0]
                if "children" in parent_node.keys():
                    parent_node["children"].append(mesh_node_id)
                else:
                    parent_node["children"] = [mesh_node_id]
                relate_pos = [
                    mesh.location[i] -
                    self.armature.data.bones[mesh.parent_bone].head_local[i]
                    for i in range(3)
                ]
                self.json_dic["nodes"][mesh_node_id][
                    "translation"] = self.axis_blender_to_glb(relate_pos)

            #region hell
            bpy.ops.object.mode_set(mode='OBJECT')
            mesh.hide_viewport = False
            mesh.hide_select = False
            bpy.context.view_layer.objects.active = mesh
            bpy.ops.object.mode_set(mode='EDIT')
            bm = bmesh.from_edit_mesh(mesh.data)

            #region tempolary_used
            mat_id_dic = {
                mat["name"]: i
                for i, mat in enumerate(self.json_dic["materials"])
            }
            material_slot_dic = {
                i: mat.name
                for i, mat in enumerate(mesh.material_slots)
            }
            node_id_dic = {
                node["name"]: i
                for i, node in enumerate(self.json_dic["nodes"])
            }

            def joint_id_from_node_name_solver(node_name):
                try:
                    node_id = node_id_dic[node_name]
                    joint_id = self.json_dic["skins"][0]["joints"].index(
                        node_id)
                except ValueError:
                    joint_id = -1  #存在しないボーンを指してる場合は-1を返す
                    print("{} bone may be not exist".format(node_name))
                return joint_id

            v_group_name_dic = {
                i: vg.name
                for i, vg in enumerate(mesh.vertex_groups)
            }
            fmin, fmax = float_info.min, float_info.max
            unique_vertex_id = 0
            unique_vertex_id_dic = {
            }  #loop verts id : base vertex id (uv違いを同じ頂点番号で管理されているので)
            unique_vertex_dic = {
            }  # {(uv...,vertex_index):unique_vertex_id} (uvと頂点番号が同じ頂点は同じものとして省くようにする)
            uvlayers_dic = {
                i: uvlayer.name
                for i, uvlayer in enumerate(mesh.data.uv_layers)
            }

            def fetch_morph_vertex_normal_difference():  #TODO 実装
                morph_normal_diff_dic = {}
                vert_base_normal_dic = OrderedDict()
                for kb in mesh.data.shape_keys.key_blocks:
                    vert_base_normal_dic.update(
                        {kb.name: kb.normals_vertex_get()})
                for k, v in vert_base_normal_dic.items():
                    if k == "Basis":
                        continue
                    values = []
                    for vert_morph_normal, vert_base_normal in zip(
                            zip(*[iter(v)] * 3),
                            zip(*[iter(vert_base_normal_dic["Basis"])] * 3)):
                        values.append([
                            vert_morph_normal[i] - vert_base_normal[i]
                            for i in range(3)
                        ])
                    morph_normal_diff_dic.update({k: values})
                return morph_normal_diff_dic

            #endregion  tempolary_used
            primitive_index_bin_dic = OrderedDict(
                {mat_id_dic[mat.name]: b""
                 for mat in mesh.material_slots})
            primitive_index_vertex_count = OrderedDict(
                {mat_id_dic[mat.name]: 0
                 for mat in mesh.material_slots})
            if mesh.data.shape_keys is None:
                shape_pos_bin_dic = {}
                shape_normal_bin_dic = {}
                shape_min_max_dic = {}
                morph_normal_diff_dic = {}
            else:
                shape_pos_bin_dic = OrderedDict({
                    shape.name: b""
                    for shape in mesh.data.shape_keys.key_blocks[1:]
                })  #0番目Basisは省く
                shape_normal_bin_dic = OrderedDict({
                    shape.name: b""
                    for shape in mesh.data.shape_keys.key_blocks[1:]
                })
                shape_min_max_dic = OrderedDict({
                    shape.name: [[fmax, fmax, fmax], [fmin, fmin, fmin]]
                    for shape in mesh.data.shape_keys.key_blocks[1:]
                })
                morph_normal_diff_dic = fetch_morph_vertex_normal_difference(
                )  #{morphname:{vertexid:[diff_X,diff_y,diff_z]}}
            position_bin = b""
            position_min_max = [[fmax, fmax, fmax], [fmin, fmin, fmin]]
            normal_bin = b""
            joints_bin = b""
            weights_bin = b""
            texcord_bins = {id: b"" for id in uvlayers_dic.keys()}
            f_vec4_packer = struct.Struct("<ffff").pack
            f_vec3_packer = struct.Struct("<fff").pack
            f_pair_packer = struct.Struct("<ff").pack
            I_scalar_packer = struct.Struct("<I").pack
            H_vec4_packer = struct.Struct("<HHHH").pack

            def min_max(minmax, position):
                for i in range(3):
                    minmax[0][i] = position[
                        i] if position[i] < minmax[0][i] else minmax[0][i]
                    minmax[1][i] = position[
                        i] if position[i] > minmax[1][i] else minmax[1][i]
                return

            for face in bm.faces:
                #このへん絶対超遅い
                for loop in face.loops:
                    uv_list = []
                    for uvlayer_name in uvlayers_dic.values():
                        uv_layer = bm.loops.layers.uv[uvlayer_name]
                        uv_list += [loop[uv_layer].uv[0], loop[uv_layer].uv[1]]
                    cached_vert_id = unique_vertex_dic.get(
                        (*uv_list, loop.vert.index))  #keyがなければNoneを返す
                    if cached_vert_id is not None:
                        primitive_index_bin_dic[mat_id_dic[material_slot_dic[
                            face.material_index]]] += I_scalar_packer(
                                cached_vert_id)
                        primitive_index_vertex_count[mat_id_dic[
                            material_slot_dic[face.material_index]]] += 1
                        continue
                    else:
                        unique_vertex_dic[(*uv_list,
                                           loop.vert.index)] = unique_vertex_id
                    for id, uvlayer_name in uvlayers_dic.items():
                        uv_layer = bm.loops.layers.uv[uvlayer_name]
                        uv = loop[uv_layer].uv
                        texcord_bins[id] += f_pair_packer(
                            uv[0], -uv[1])  #blenderとglbのuvは上下逆
                    for shape_name in shape_pos_bin_dic.keys():
                        shape_layer = bm.verts.layers.shape[shape_name]
                        morph_pos = self.axis_blender_to_glb([
                            loop.vert[shape_layer][i] - loop.vert.co[i]
                            for i in range(3)
                        ])
                        shape_pos_bin_dic[shape_name] += f_vec3_packer(
                            *morph_pos)
                        shape_normal_bin_dic[shape_name] += f_vec3_packer(
                            *self.axis_blender_to_glb(
                                morph_normal_diff_dic[shape_name][
                                    loop.vert.index]))
                        min_max(shape_min_max_dic[shape_name], morph_pos)
                    if is_skin_mesh:
                        magic = 0
                        joints = [magic, magic, magic, magic]
                        weights = [0.0, 0.0, 0.0, 0.0]
                        if len(mesh.data.vertices[
                                loop.vert.index].groups) >= 5:
                            print(
                                "vertex weights are less than 4 in {}".format(
                                    mesh.name))
                            raise Exception
                        for v_group in mesh.data.vertices[
                                loop.vert.index].groups:
                            joint_id = joint_id_from_node_name_solver(
                                v_group_name_dic[v_group.group])
                            if joint_id == -1:  #存在しないボーンを指してる場合は-1を返されてるので、その場合は飛ばす
                                continue
                            weights.pop(3)
                            weights.insert(0, v_group.weight)
                            joints.pop(3)
                            joints.insert(0, joint_id)
                        nomalize_fact = sum(weights)
                        try:
                            weights = [
                                weights[i] / nomalize_fact for i in range(4)
                            ]
                        except ZeroDivisionError:
                            print("vertex has no weight in {}".format(
                                mesh.name))
                            raise ZeroDivisionError
                        if sum(weights) < 1:
                            weights[0] += 1 - sum(weights)
                        joints_bin += H_vec4_packer(*joints)
                        weights_bin += f_vec4_packer(*weights)

                    vert_location = self.axis_blender_to_glb(loop.vert.co)
                    position_bin += f_vec3_packer(*vert_location)
                    min_max(position_min_max, vert_location)
                    normal_bin += f_vec3_packer(
                        *self.axis_blender_to_glb(loop.vert.normal))
                    unique_vertex_id_dic[unique_vertex_id] = loop.vert.index
                    primitive_index_bin_dic[mat_id_dic[material_slot_dic[
                        face.material_index]]] += I_scalar_packer(
                            unique_vertex_id)
                    primitive_index_vertex_count[mat_id_dic[material_slot_dic[
                        face.material_index]]] += 1
                    unique_vertex_id += 1

            #DONE :index position, uv, normal, position morph,JOINT WEIGHT
            #TODO: morph_normal, v_color...?
            primitive_glbs_dic = OrderedDict({
                mat_id: Glb_bin(index_bin, "SCALAR", GL_CONSTANS.UNSIGNED_INT,
                                primitive_index_vertex_count[mat_id], None,
                                self.glb_bin_collector)
                for mat_id, index_bin in primitive_index_bin_dic.items()
                if index_bin != b""
            })
            pos_glb = Glb_bin(position_bin, "VEC3", GL_CONSTANS.FLOAT,
                              unique_vertex_id, position_min_max,
                              self.glb_bin_collector)
            nor_glb = Glb_bin(normal_bin, "VEC3", GL_CONSTANS.FLOAT,
                              unique_vertex_id, None, self.glb_bin_collector)
            uv_glbs = [
                Glb_bin(texcood_bin, "VEC2", GL_CONSTANS.FLOAT,
                        unique_vertex_id, None, self.glb_bin_collector)
                for texcood_bin in texcord_bins.values()
            ]
            if is_skin_mesh:
                joints_glb = Glb_bin(joints_bin, "VEC4",
                                     GL_CONSTANS.UNSIGNED_SHORT,
                                     unique_vertex_id, None,
                                     self.glb_bin_collector)
                weights_glb = Glb_bin(weights_bin, "VEC4", GL_CONSTANS.FLOAT,
                                      unique_vertex_id, None,
                                      self.glb_bin_collector)
            if len(shape_pos_bin_dic.keys()) != 0:
                morph_pos_glbs = [
                    Glb_bin(morph_pos_bin, "VEC3", GL_CONSTANS.FLOAT,
                            unique_vertex_id, morph_minmax,
                            self.glb_bin_collector)
                    for morph_pos_bin, morph_minmax in zip(
                        shape_pos_bin_dic.values(), shape_min_max_dic.values())
                ]
                morph_normal_glbs = [
                    Glb_bin(morph_normal_bin, "VEC3", GL_CONSTANS.FLOAT,
                            unique_vertex_id, None, self.glb_bin_collector)
                    for morph_normal_bin in shape_normal_bin_dic.values()
                ]
            primitive_list = []
            for primitive_id, index_glb in primitive_glbs_dic.items():
                primitive = OrderedDict({"mode": 4})
                primitive["material"] = primitive_id
                primitive["indices"] = index_glb.accessor_id
                primitive["attributes"] = {
                    "POSITION": pos_glb.accessor_id,
                    "NORMAL": nor_glb.accessor_id,
                }
                if is_skin_mesh:
                    primitive["attributes"].update({
                        "JOINTS_0":
                        joints_glb.accessor_id,
                        "WEIGHTS_0":
                        weights_glb.accessor_id
                    })
                primitive["attributes"].update({
                    "TEXCOORD_{}".format(i): uv_glb.accessor_id
                    for i, uv_glb in enumerate(uv_glbs)
                })
                if len(shape_pos_bin_dic.keys()) != 0:
                    primitive["targets"] = [{
                        "POSITION":
                        morph_pos_glb.accessor_id,
                        "NORMAL":
                        morph_normal_glb.accessor_id
                    } for morph_pos_glb, morph_normal_glb in zip(
                        morph_pos_glbs, morph_normal_glbs)]
                    primitive["extras"] = {
                        "targetNames": [
                            shape_name
                            for shape_name in shape_pos_bin_dic.keys()
                        ]
                    }
                primitive_list.append(primitive)
            self.json_dic["meshes"].append(
                OrderedDict({
                    "name": mesh.name,
                    "primitives": primitive_list
                }))
            #endregion hell
        bpy.ops.object.mode_set(mode='OBJECT')

        return
Esempio n. 43
0
    def modal(self, context, event):
        context.area.tag_redraw()

        preferences = context.preferences
        addon_prefs = preferences.addons[__package__].preferences
        lin_def_settings = context.scene.mi_ldeformer_settings

        region = context.region
        rv3d = context.region_data
        m_coords = event.mouse_region_x, event.mouse_region_y
        active_obj = context.active_object
        bm = bmesh.from_edit_mesh(active_obj.data)

        # update check
        if lin_def_settings.manual_update is True:
            if event.type == 'U':
                if event.value == 'PRESS':
                    self.do_update = True
                else:
                    self.do_update = False
        else:
            self.do_update = True

        # tooltip
        tooltip_text = None
        if lin_def_settings.manual_update is True and self.tool_mode not in {
                'IDLE', 'MOVE_POINT'
        }:
            tooltip_text = "Press U key to udate!"
        else:
            tooltip_text = "I:Invert, Z:Z-Constraint, X:X-Constraint, S:Scale, Shift-S:ScaleForward, G:Move, R:Rotate, B:Bend, Shift-B:BendSpiral, T:Tape, Shift-T:Twist, Ctrl+Z:Undo, Ctrl+Shift+Z:Redo"
        context.area.header_text_set(tooltip_text)

        keys_pass = mi_inputs.get_input_pass(mi_inputs.pass_keys,
                                             addon_prefs.key_inputs, event)

        # key pressed
        if self.tool_mode == 'IDLE' and event.value == 'PRESS' and keys_pass is False:
            if event.type in {'LEFTMOUSE', 'SELECTMOUSE'}:
                if self.lw_tool:
                    # pick linear widget point
                    picked_point = l_widget.pick_lw_point(
                        context, m_coords, self.lw_tool)
                    if picked_point:
                        self.deform_mouse_pos = Vector(m_coords)
                        self.active_lw_point = picked_point

                        self.tool_mode = 'MOVE_POINT'
                else:
                    picked_point = ut_base.get_mouse_on_plane(
                        context, self.start_work_center, None, m_coords)
                    if picked_point:
                        self.lw_tool = l_widget.MI_Linear_Widget()

                        self.lw_tool.start_point = l_widget.MI_LW_Point(
                            picked_point.copy())
                        self.lw_tool.middle_point = l_widget.MI_LW_Point(
                            picked_point.copy())
                        self.lw_tool.end_point = l_widget.MI_LW_Point(
                            picked_point)

                        self.active_lw_point = self.lw_tool.end_point

                        self.tool_mode = 'MOVE_POINT'

            elif event.type in {'S', 'G', 'R', 'B', 'T'}:
                # set tool type
                if event.type == 'S':
                    if event.shift:
                        self.tool_mode = 'SCALE_FRONT'
                    else:
                        self.tool_mode = 'SCALE_ALL'
                elif event.type == 'R':
                    self.tool_mode = 'ROTATE_ALL'
                elif event.type == 'G':
                    self.tool_mode = 'MOVE_ALL'
                elif event.type == 'B':
                    if event.shift:
                        self.tool_mode = 'BEND_SPIRAL'
                    else:
                        self.tool_mode = 'BEND_ALL'
                elif event.type == 'T':
                    if event.shift:
                        self.tool_mode = 'TWIST'
                    else:
                        self.tool_mode = 'TAPE'

                # get tool verts
                if self.tool_mode in {'SCALE_FRONT', 'TAPE'}:
                    # do not clamp for SCALE_FRONT mode
                    self.apply_tool_verts = l_widget.get_tool_verts(
                        self.lw_tool, self.work_verts, bm, active_obj, False,
                        True)
                else:
                    self.apply_tool_verts = l_widget.get_tool_verts(
                        self.lw_tool, self.work_verts, bm, active_obj, True,
                        True)

                # set some settings for tools
                if self.tool_mode in {'SCALE_ALL', 'SCALE_FRONT', 'TAPE'}:
                    self.deform_mouse_pos = Vector(m_coords)

                elif self.tool_mode == 'MOVE_ALL':
                    mouse_pos_3d = ut_base.get_mouse_on_plane(
                        context, self.lw_tool.start_point.position, None,
                        m_coords)
                    self.deform_vec_pos = mouse_pos_3d  # 3d location

                elif self.tool_mode in {
                        'ROTATE_ALL', 'TWIST', 'BEND_ALL', 'BEND_SPIRAL'
                }:
                    start_2d = view3d_utils.location_3d_to_region_2d(
                        region, rv3d, self.lw_tool.start_point.position)
                    self.deform_vec_pos = (
                        Vector(m_coords) -
                        start_2d).normalized()  # 2d direction
                    self.deform_mouse_pos = 0.0  # we will use it as angle counter

                    if self.tool_mode in {'BEND_SPIRAL', 'BEND_ALL'}:
                        self.bend_scale_len = (Vector(m_coords) -
                                               start_2d).length

                #return {'RUNNING_MODAL'}

            elif event.type in {'Z', 'X'} and self.lw_tool:
                if event.type == 'Z' and event.ctrl:
                    if event.shift:
                        redo_history(bm, self.h_undo, self.h_redo, active_obj)
                    else:
                        undo_history(bm, self.h_undo, self.h_redo, active_obj)

                else:
                    pre_verts = [bm.verts[v_id] for v_id in self.work_verts]
                    if event.type == 'X':
                        if self.lw_tool_axis:
                            if self.lw_tool_axis == 'X':
                                l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                       active_obj, pre_verts,
                                                       'X_Left', 1.0)
                                self.lw_tool_axis = 'X_Left'
                            elif self.lw_tool_axis == 'X_Left':
                                l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                       active_obj, pre_verts,
                                                       'X_Right', 1.0)

                                ## revert direction
                                #stp = self.lw_tool.start_point.position.copy()
                                #self.lw_tool.start_point.position = self.lw_tool.end_point.position
                                #self.lw_tool.end_point.position = stp

                                self.lw_tool_axis = 'X_Right'
                            elif self.lw_tool_axis == 'X_Right':
                                l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                       active_obj, pre_verts,
                                                       'X', 1.0)
                                self.lw_tool_axis = 'X'
                            else:
                                l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                       active_obj, pre_verts,
                                                       'X', 1.0)
                                self.lw_tool_axis = 'X'
                        else:
                            l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                   active_obj, pre_verts, 'X',
                                                   1.0)
                            self.lw_tool_axis = 'X'
                    else:
                        if self.lw_tool_axis:
                            if self.lw_tool_axis == 'Z':
                                l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                       active_obj, pre_verts,
                                                       'Z_Top', 1.0)
                                self.lw_tool_axis = 'Z_Top'
                            elif self.lw_tool_axis == 'Z_Top':
                                l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                       active_obj, pre_verts,
                                                       'Z_Bottom', 1.0)

                                ## revert direction
                                #stp = self.lw_tool.start_point.position.copy()
                                #self.lw_tool.start_point.position = self.lw_tool.end_point.position
                                #self.lw_tool.end_point.position = stp

                                self.lw_tool_axis = 'Z_Bottom'
                            elif self.lw_tool_axis == 'Z_Bottom':
                                l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                       active_obj, pre_verts,
                                                       'Z', 1.0)
                                self.lw_tool_axis = 'Z'
                            else:
                                l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                       active_obj, pre_verts,
                                                       'Z', 1.0)
                                self.lw_tool_axis = 'Z'
                        else:
                            l_widget.setup_lw_tool(rv3d, self.lw_tool,
                                                   active_obj, pre_verts, 'Z',
                                                   1.0)
                            self.lw_tool_axis = 'Z'

            elif event.type == 'I' and self.lw_tool:
                start_copy = self.lw_tool.start_point.position.copy()
                self.lw_tool.start_point.position = self.lw_tool.end_point.position
                self.lw_tool.end_point.position = start_copy

        # TOOL WORK!
        if self.tool_mode == 'MOVE_POINT':
            if event.value == 'RELEASE':
                self.tool_mode = 'IDLE'
                return {'RUNNING_MODAL'}
            else:
                # move points
                new_point_pos = ut_base.get_mouse_on_plane(
                    context, self.active_lw_point.position, None, m_coords)
                if self.active_lw_point.position == self.lw_tool.start_point.position or self.active_lw_point.position == self.lw_tool.end_point.position:
                    self.active_lw_point.position = new_point_pos
                    l_widget.update_middle_point(self.lw_tool)
                elif self.active_lw_point.position == self.lw_tool.middle_point.position:
                    self.lw_tool.start_point.position += new_point_pos - self.active_lw_point.position
                    self.lw_tool.end_point.position += new_point_pos - self.active_lw_point.position
                    self.lw_tool.middle_point.position = new_point_pos

                return {'RUNNING_MODAL'}

        elif self.tool_mode in {'SCALE_ALL', 'SCALE_FRONT', 'TAPE'}:
            if event.value == 'RELEASE' and event.type in {
                    'LEFTMOUSE', 'SELECTMOUSE'
            }:
                bm.normal_update()

                # add to undo history
                self.h_redo.clear()
                pre_work_verts = [bm.verts[v_id] for v_id in self.work_verts]
                add_history(pre_work_verts, self.h_undo)

                self.tool_mode = 'IDLE'

            elif self.do_update:
                # move points
                start_point_2d = view3d_utils.location_3d_to_region_2d(
                    region, rv3d, self.lw_tool.start_point.position)
                if start_point_2d:
                    tool_dist = (start_point_2d - self.deform_mouse_pos).length
                    now_dist = (start_point_2d - Vector(m_coords)).length
                    apply_value = (now_dist - tool_dist) / tool_dist
                    if apply_value != 0.0:
                        tool_orig = active_obj.matrix_world.inverted(
                        ) @ self.lw_tool.start_point.position
                        tool_end = active_obj.matrix_world.inverted(
                        ) @ self.lw_tool.end_point.position
                        tool_vec = tool_end - tool_orig
                        tool_dir = (tool_end - tool_orig).normalized()
                        for vert_data in self.apply_tool_verts:
                            scale_vec = None
                            scale_value = vert_data[1]

                            if self.tool_mode == 'SCALE_ALL':
                                scale_vec = (vert_data[2] - tool_orig)
                            elif self.tool_mode == 'SCALE_FRONT':
                                scale_vec = (tool_end - tool_orig)
                            else:
                                # TAPE
                                scale_vec = vert_data[2] - (
                                    tool_orig + (tool_dir * vert_data[1] *
                                                 (tool_vec).length))
                                scale_value = min(1.0, vert_data[1])

                            bm.verts[vert_data[0]].co = vert_data[2] + (
                                scale_vec * (scale_value * apply_value))

                        bm.normal_update()
                        bmesh.update_edit_mesh(active_obj.data)

            self.do_update = False
            return {'RUNNING_MODAL'}

        elif self.tool_mode == 'MOVE_ALL':
            if event.value == 'RELEASE' and event.type in {
                    'LEFTMOUSE', 'SELECTMOUSE'
            }:
                bm.normal_update()

                # add to undo history
                self.h_redo.clear()
                pre_work_verts = [bm.verts[v_id] for v_id in self.work_verts]
                add_history(pre_work_verts, self.h_undo)

                self.tool_mode = 'IDLE'

            elif self.do_update:
                mouse_pos_3d = ut_base.get_mouse_on_plane(
                    context, self.lw_tool.start_point.position, None, m_coords)
                mouse_pos_3d = active_obj.matrix_world.inverted(
                ) @ mouse_pos_3d
                start_pos = active_obj.matrix_world.inverted(
                ) @ self.lw_tool.start_point.position
                orig_pos = active_obj.matrix_world.inverted(
                ) @ self.deform_vec_pos
                orig_vec = orig_pos - start_pos
                move_vec = (mouse_pos_3d - start_pos) - orig_vec

                for vert_data in self.apply_tool_verts:
                    move_value = vert_data[1]
                    bm.verts[vert_data[0]].co = vert_data[2] + (move_vec *
                                                                move_value)

                bm.normal_update()
                bmesh.update_edit_mesh(active_obj.data)
                self.do_update = False

            return {'RUNNING_MODAL'}

        elif self.tool_mode in {
                'ROTATE_ALL', 'TWIST', 'BEND_ALL', 'BEND_SPIRAL'
        }:
            if event.value == 'RELEASE' and event.type in {
                    'LEFTMOUSE', 'SELECTMOUSE'
            }:
                bm.normal_update()

                # add to undo history
                self.h_redo.clear()
                pre_work_verts = [bm.verts[v_id] for v_id in self.work_verts]
                add_history(pre_work_verts, self.h_undo)

                self.tool_mode = 'IDLE'

            elif self.do_update:
                m_coords = Vector(
                    m_coords)  # convert into vector for operations
                start_2d = view3d_utils.location_3d_to_region_2d(
                    region, rv3d, self.lw_tool.start_point.position)
                new_vec_dir = (m_coords - start_2d).normalized()
                rot_angle = new_vec_dir.angle(self.deform_vec_pos)

                start_3d = self.lw_tool.start_point.position
                end_3d = self.lw_tool.end_point.position

                if rot_angle != 0.0:
                    # check for left or right direction to rotate
                    vec_check_1 = Vector((new_vec_dir[0], new_vec_dir[1], 0))
                    vec_check_2 = Vector(
                        (new_vec_dir[0] - self.deform_vec_pos[0],
                         new_vec_dir[1] - self.deform_vec_pos[1], 0))
                    checker_side_dir = vec_check_1.cross(
                        vec_check_2).normalized()[2]
                    if checker_side_dir > 0.0:
                        rot_angle = -rot_angle

                    start_pos = self.lw_tool.start_point.position
                    rot_dir = None
                    if self.tool_mode == 'ROTATE_FRONT' or self.tool_mode == 'TWIST':
                        # ROTATE_FRONT code
                        rot_dir = (end_3d - start_3d).normalized()
                    else:
                        rot_dir = (rv3d.view_rotation @ Vector(
                            (0.0, 0.0, -1.0))).normalized()

                    rot_angle += self.deform_mouse_pos  # add rot angle

                    bend_side_dir = None
                    faloff_len = None
                    spiral_value = 0.0  # only for BEND_SPIRAL
                    bend_scale_value = 1.0  # only for BEND_ALL

                    if self.tool_mode == 'BEND_ALL' or self.tool_mode == 'BEND_SPIRAL':
                        bend_side_dir = (((end_3d - start_3d).normalized()
                                          ).cross(rot_dir)).normalized()
                        faloff_len = end_3d - start_3d

                        if self.tool_mode == 'BEND_SPIRAL':
                            val_scale = None
                            if rot_angle > 0.0:
                                val_scale = (1.0 -
                                             ((m_coords - start_2d).length /
                                              self.bend_scale_len))
                            else:
                                val_scale = (((m_coords - start_2d).length /
                                              self.bend_scale_len))

                            spiral_value = 1.0 - (faloff_len.length *
                                                  val_scale)

                        else:
                            val_scale = (((m_coords - start_2d).length /
                                          self.bend_scale_len))
                            bend_scale_value = ((val_scale))

                    do_bend = False
                    if self.tool_mode == 'BEND_ALL' or self.tool_mode == 'BEND_SPIRAL':
                        do_bend = True

                    for vert_data in self.apply_tool_verts:
                        apply_value = vert_data[1]
                        final_apply_value = rot_angle * apply_value

                        # do rotation
                        if final_apply_value != 0.0:
                            rot_mat = Matrix.Rotation(final_apply_value, 3,
                                                      rot_dir)
                            vert = bm.verts[vert_data[0]]

                            if do_bend:
                                vert_temp = (
                                    active_obj.matrix_world @ vert_data[2]) - (
                                        (faloff_len) * apply_value)

                                back_offset = (
                                    ((faloff_len).length /
                                     (final_apply_value)) + spiral_value) * (
                                         apply_value * bend_scale_value)
                                vert_temp += bend_side_dir * back_offset
                                vert.co = vert_temp
                            else:
                                # set original position
                                vert.co[0] = vert_data[2][0]
                                vert.co[1] = vert_data[2][1]
                                vert.co[2] = vert_data[2][2]

                            # ROTATE VERTS!
                            if do_bend:
                                vert.co = rot_mat @ (
                                    (vert.co) - start_pos) + start_pos
                                back_offset = (
                                    (faloff_len).length /
                                    (final_apply_value)) * (apply_value *
                                                            bend_scale_value)
                                vert.co = active_obj.matrix_world.inverted(
                                ) @ (vert.co - (bend_side_dir * back_offset))
                            else:
                                vert.co = active_obj.matrix_world.inverted(
                                ) @ (rot_mat @ (
                                    (active_obj.matrix_world @ vert.co) -
                                    start_pos) + start_pos)

                    self.deform_vec_pos = new_vec_dir
                    self.deform_mouse_pos = rot_angle  # set new angle rotation for next step

                    bm.normal_update()
                    bmesh.update_edit_mesh(active_obj.data)
                self.do_update = False

            return {'RUNNING_MODAL'}

        else:
            if event.value == 'RELEASE' and event.type in {
                    'LEFTMOUSE', 'SELECTMOUSE'
            }:
                self.tool_mode = 'IDLE'
                return {'RUNNING_MODAL'}

        # get keys
        if keys_pass is True:
            # allow navigation
            return {'PASS_THROUGH'}

        elif event.type in {'RIGHTMOUSE', 'ESC'}:
            context.space_data.show_gizmo = self.manipulator

            # bpy.types.SpaceView3D.draw_handler_remove(self.lin_deform_handle_3d, 'WINDOW')
            bpy.types.SpaceView3D.draw_handler_remove(
                self.lin_deform_handle_2d, 'WINDOW')

            context.area.header_text_set(None)

            return {'FINISHED'}

        return {'RUNNING_MODAL'}
Esempio n. 44
0
 def elem_count(context):
     bm = bmesh.from_edit_mesh(context.edit_object.data)
     return len(bm.verts), len(bm.edges), len(bm.faces)
Esempio n. 45
0
def getPercent(obj, flip_p, per_v, data, scene):
    """Calculates a Percentage Distance between 2 Vectors.

    Calculates a point that lies a set percentage between two given points
    using standard Numpy Routines.

    Works for either 2 vertices for an object in Edit mode
    or 2 selected objects in Object mode.

    Args:
        obj: The Object under consideration
        flip_p: Setting this to True measures the percentage starting from the second vector
        per_v: Percentage Input Value
        data: pg.flip, pg.percent scene variables & Operational Mode
        scene: Context Scene

    Returns:
        World Vector.
    """

    pg = scene.pdt_pg

    if obj.mode == "EDIT":
        bm = bmesh.from_edit_mesh(obj.data)
        verts = [v for v in bm.verts if v.select]
        if len(verts) == 2:
            actV = verts[0].co
            othV = verts[1].co
            if actV is None:
                pg.error = PDT_ERR_VERT_MODE
                bpy.context.window_manager.popup_menu(oops,
                                                      title="Error",
                                                      icon="ERROR")
                return None
        else:
            pg.error = PDT_ERR_SEL_2_V_1_E + str(len(verts)) + " Vertices"
            bpy.context.window_manager.popup_menu(oops,
                                                  title="Error",
                                                  icon="ERROR")
            return None
        p1 = np.array([actV.x, actV.y, actV.z])
        p2 = np.array([othV.x, othV.y, othV.z])
    if obj.mode == "OBJECT":
        objs = bpy.context.view_layer.objects.selected
        if len(objs) != 2:
            pg.error = PDT_ERR_SEL_2_OBJS + str(len(objs)) + ")"
            bpy.context.window_manager.popup_menu(oops,
                                                  title="Error",
                                                  icon="ERROR")
            return None
        p1 = np.array([
            objs[-1].matrix_world.decompose()[0].x,
            objs[-1].matrix_world.decompose()[0].y,
            objs[-1].matrix_world.decompose()[0].z,
        ])
        p2 = np.array([
            objs[-2].matrix_world.decompose()[0].x,
            objs[-2].matrix_world.decompose()[0].y,
            objs[-2].matrix_world.decompose()[0].z,
        ])
    p4 = np.array([0, 0, 0])
    p3 = p2 - p1
    _per_v = per_v
    if (flip_p and data != "MV") or data == "MV":
        _per_v = 100 - per_v
    V = (p4 + p3) * (_per_v / 100) + p1
    return Vector((V[0], V[1], V[2]))
import bpy
import bmesh

obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)

# notice in Bmesh polygons are called faces
bm.faces[4].select = True  # select index 4

# Show the updates in the viewport
bmesh.update_edit_mesh(me, True)

bpy.ops.mesh.select_linked(limit=True)
bpy.ops.mesh.separate()
Esempio n. 47
0
def get_orientation(context):
    obj = bpy.context.view_layer.objects.active
    bm = bmesh.from_edit_mesh(obj.data)
    uv_layer = bm.loops.layers.uv.verify()
    faces = list()
    #MAKE FACE LIST
    for face in bm.faces:
        if face.select:
            faces.append(face)

    for face in faces:
        xmin, xmax = face.loops[0][uv_layer].uv.x, face.loops[0][uv_layer].uv.x
        ymin, ymax = face.loops[0][uv_layer].uv.y, face.loops[0][uv_layer].uv.y

    for vert in face.loops:
        xmin = min(xmin, vert[uv_layer].uv.x)
        xmax = max(xmax, vert[uv_layer].uv.x)
        ymin = min(ymin, vert[uv_layer].uv.y)
        ymax = max(ymax, vert[uv_layer].uv.y)

    # corners:
    # 3 2
    # 0 1

    bound0 = Vector((xmin, ymin))
    bound1 = Vector((xmax, ymin))
    bound2 = Vector((xmax, ymax))
    bound3 = Vector((xmin, ymax))
    middle = Vector(
        (((xmax + xmin) / 2) - bound0.x, ((ymax + ymin) / 2) - bound0.y))

    print("find corner 0:")
    distance = middle.length
    corner0 = faces[0].loops[0]
    for f in faces:
        for loop in f.loops:
            loop_uv = loop[uv_layer]
            vertuv = Vector((loop_uv.uv.x - bound0.x, loop_uv.uv.y - bound0.y))
            tempdistance = vertuv.length
            if tempdistance <= distance:
                distance = tempdistance
                corner0 = loop
    print(corner0[uv_layer].uv)

    print("find corner 1:")
    distance = middle.length
    corner1 = faces[0].loops[0]
    for f in faces:
        for loop in f.loops:
            loop_uv = loop[uv_layer]
            vertuv = Vector((loop_uv.uv.x - bound1.x, loop_uv.uv.y - bound1.y))
            tempdistance = vertuv.length
            if tempdistance <= distance:
                distance = tempdistance
                corner1 = loop
    print(corner1[uv_layer].uv)

    print("find corner 2:")
    distance = middle.length
    corner2 = faces[0].loops[0]
    for f in faces:
        for loop in f.loops:
            loop_uv = loop[uv_layer]
            vertuv = Vector((loop_uv.uv.x - bound2.x, loop_uv.uv.y - bound2.y))
            tempdistance = vertuv.length
            if tempdistance <= distance:
                distance = tempdistance
                corner2 = loop
    print(corner2[uv_layer].uv)

    print("find corner 3:")
    distance = middle.length
    corner3 = faces[0].loops[0]
    for f in faces:
        for loop in f.loops:
            loop_uv = loop[uv_layer]
            vertuv = Vector((loop_uv.uv.x - bound3.x, loop_uv.uv.y - bound3.y))
            tempdistance = vertuv.length
            if tempdistance <= distance:
                distance = tempdistance
                corner3 = loop
    print(corner3[uv_layer].uv)

    #orientations:
    # 3 2   0 3   1 0   2 1
    # 0 1   1 2   2 3   3 0

    #1st case:
    if corner3.vert.co.z >= corner0.vert.co.z and corner2.vert.co.z >= corner1.vert.co.z and corner3.vert.co.z >= corner1.vert.co.z and corner2.vert.co.z >= corner0.vert.co.z:
        print("case1")

    if corner0.vert.co.z >= corner1.vert.co.z and corner3.vert.co.z >= corner2.vert.co.z and corner0.vert.co.z >= corner2.vert.co.z and corner3.vert.co.z >= corner1.vert.co.z:
        print("case2")
        for face in faces:
            for loop in face.loops:
                newx = loop[uv_layer].uv.y
                newy = -loop[uv_layer].uv.x
                loop[uv_layer].uv.x = newx
                loop[uv_layer].uv.y = newy

    if corner1.vert.co.z >= corner2.vert.co.z and corner0.vert.co.z >= corner3.vert.co.z and corner1.vert.co.z >= corner3.vert.co.z and corner0.vert.co.z >= corner2.vert.co.z:
        print("case3")
        for face in faces:
            for loop in face.loops:
                newx = -loop[uv_layer].uv.x
                newy = -loop[uv_layer].uv.y
                loop[uv_layer].uv.x = newx
                loop[uv_layer].uv.y = newy

    if corner2.vert.co.z >= corner3.vert.co.z and corner1.vert.co.z >= corner0.vert.co.z and corner2.vert.co.z >= corner0.vert.co.z and corner1.vert.co.z >= corner3.vert.co.z:
        print("case4")
        for face in faces:
            for loop in face.loops:
                newx = -loop[uv_layer].uv.y
                newy = loop[uv_layer].uv.x
                loop[uv_layer].uv.x = newx
                loop[uv_layer].uv.y = newy

    return None
Esempio n. 48
0
def command_parse(context):
    """Parse Command Input.

    Args:
        context: Blender bpy.context instance.

    Returns:
        pg: PDT Parameters Group - our variables
        values_out: The Output Values as a list of numbers
        obj: The Active Object
        obj_loc: The object's location in 3D space
        bm: The object's Bmesh
        verts: The object's selected vertices, or selected history vertices.
    """
    scene = context.scene
    pg = scene.pdt_pg
    command = pg.command.strip()
    operation = command[0].upper()
    mode = command[1].lower()
    values = command[2:].split(",")
    mode_sel = pg.select
    obj = context.view_layer.objects.active
    ind = 0
    for v in values:
        try:
            _ = float(v)
            good = True
        except ValueError:
            values[ind] = "0.0"
        ind = ind + 1
    if mode == "n":
        # View relative mode
        if pg.plane == "XZ":
            values = [0.0, values[0], 0.0]
        elif pg.plane == "YZ":
            values = [values[0], 0.0, 0.0]
        elif pg.plane == "XY":
            values = [0.0, 0.0, values[0]]
        else:
            if "-" in values[0]:
                values = [0.0, 0.0, values[0][1:]]
            else:
                values = [0.0, 0.0, f"-{values[0]}"]
    # Apply System Rounding
    decimal_places = context.preferences.addons[
        __package__].preferences.pdt_input_round
    values_out = [str(round(float(v), decimal_places)) for v in values]
    bm = "No Bmesh"
    obj_loc = Vector((0, 0, 0))
    verts = []

    if mode_sel == 'REL' and operation not in {"C", "P"}:
        pg.select = 'SEL'
        mode_sel = 'SEL'

    if mode == "a" and operation not in {"C", "P"}:
        # Place new Vertex, or Extrude Vertices by Absolute Coords.
        if mode_sel == 'REL':
            pg.select = 'SEL'
            mode_sel = 'SEL'
        if obj is not None:
            if obj.mode == "EDIT":
                bm = bmesh.from_edit_mesh(obj.data)
                obj_loc = obj.matrix_world.decompose()[0]
                verts = []
            else:
                if operation != "G":
                    pg.error = PDT_OBJ_MODE_ERROR
                    context.window_manager.popup_menu(oops,
                                                      title="Error",
                                                      icon="ERROR")
                    raise PDT_ObjectModeError
        else:
            pg.error = PDT_ERR_NO_ACT_OBJ
            context.window_manager.popup_menu(oops,
                                              title="Error",
                                              icon="ERROR")
            raise PDT_NoObjectError

    if mode_sel == 'SEL' and mode not in {"a"}:
        # All other options except Cursor or Pivot by Absolute
        # These options require no object, etc.
        bm, good = obj_check(obj, scene, operation)
        if good and obj.mode == 'EDIT':
            obj_loc = obj.matrix_world.decompose()[0]
            if len(bm.select_history) == 0 or operation == "G":
                verts = [v for v in bm.verts if v.select]
                if len(verts) == 0:
                    pg.error = PDT_ERR_NO_SEL_GEOM
                    context.window_manager.popup_menu(oops,
                                                      title="Error",
                                                      icon="ERROR")
                    raise PDT_SelectionError
            else:
                verts = bm.select_history

    debug(f"command: {operation}{mode}{values_out}")
    debug(f"obj: {obj}, bm: {bm}, obj_loc: {obj_loc}")

    return pg, values_out, obj, obj_loc, bm, verts
Esempio n. 49
0
    def execute(self, context):
        area, _, space = common.get_space('IMAGE_EDITOR', 'WINDOW',
                                          'IMAGE_EDITOR')
        if compat.check_version(2, 80, 0) < 0:
            bd_size = common.get_uvimg_editor_board_size(area)
        else:
            bd_size = [1.0, 1.0]

        large_value = 1e7
        if self.base == 'UV':
            objs = common.get_uv_editable_objects(context)
            no_selected_face = True
            if objs:
                max_ = Vector((-large_value, -large_value))
                min_ = Vector((large_value, large_value))
                for obj in objs:
                    bm = bmesh.from_edit_mesh(obj.data)
                    if not bm.loops.layers.uv:
                        return None
                    uv_layer = bm.loops.layers.uv.verify()

                    for f in bm.faces:
                        if not f.select:
                            continue
                        for l in f.loops:
                            uv = l[uv_layer].uv
                            max_.x = max(max_.x, uv.x)
                            max_.y = max(max_.y, uv.y)
                            min_.x = min(min_.x, uv.x)
                            min_.y = min(min_.y, uv.y)
                            no_selected_face = False
            if no_selected_face:
                max_ = Vector((1.0, 1.0))
                min_ = Vector((0.0, 0.0))
            center = Vector(((max_.x + min_.x) / 2.0, (max_.y + min_.y) / 2.0))

        # pylint: disable=R1702
        elif self.base == 'UV_SEL':
            objs = common.get_uv_editable_objects(context)
            no_selected_face = True
            if objs:
                max_ = Vector((-large_value, -large_value))
                min_ = Vector((large_value, large_value))
                for obj in objs:
                    bm = bmesh.from_edit_mesh(obj.data)
                    if not bm.loops.layers.uv:
                        return None
                    uv_layer = bm.loops.layers.uv.verify()

                    for f in bm.faces:
                        if not f.select:
                            continue
                        for l in f.loops:
                            if not l[uv_layer].select:
                                continue
                            uv = l[uv_layer].uv
                            max_.x = max(max_.x, uv.x)
                            max_.y = max(max_.y, uv.y)
                            min_.x = min(min_.x, uv.x)
                            min_.y = min(min_.y, uv.y)
                            no_selected_face = False
            if no_selected_face:
                max_ = Vector((1.0, 1.0))
                min_ = Vector((0.0, 0.0))
            center = Vector(((max_.x + min_.x) / 2.0, (max_.y + min_.y) / 2.0))

        elif self.base == 'TEXTURE':
            min_ = Vector((0.0, 0.0))
            max_ = Vector((1.0, 1.0))
            center = Vector((0.5, 0.5))
        else:
            self.report({'ERROR'}, "Unknown Operation")
            return {'CANCELLED'}

        if self.position == 'CENTER':
            cx = center.x
            cy = center.y
        elif self.position == 'LEFT_TOP':
            cx = min_.x
            cy = max_.y
        elif self.position == 'LEFT_MIDDLE':
            cx = min_.x
            cy = center.y
        elif self.position == 'LEFT_BOTTOM':
            cx = min_.x
            cy = min_.y
        elif self.position == 'MIDDLE_TOP':
            cx = center.x
            cy = max_.y
        elif self.position == 'MIDDLE_BOTTOM':
            cx = center.x
            cy = min_.y
        elif self.position == 'RIGHT_TOP':
            cx = max_.x
            cy = max_.y
        elif self.position == 'RIGHT_MIDDLE':
            cx = max_.x
            cy = center.y
        elif self.position == 'RIGHT_BOTTOM':
            cx = max_.x
            cy = min_.y
        else:
            self.report({'ERROR'}, "Unknown Operation")
            return {'CANCELLED'}

        cx = cx * bd_size[0]
        cy = cy * bd_size[1]

        space.cursor_location = Vector((cx, cy))

        return {'FINISHED'}
Esempio n. 50
0
def square_fit(context):
    obj = bpy.context.view_layer.objects.active
    bm = bmesh.from_edit_mesh(obj.data)

    uv_layer = bm.loops.layers.uv.verify()

    faces = list()

    #MAKE FACE LIST
    for face in bm.faces:
        if face.select:
            faces.append(face)

    #TEST IF QUADS OR NOT

    quadmethod = True
    #EXPERIMENTAL! TO MUCH SKEWING TEST:
    distorted = False

    for face in faces:
        if len(face.loops) is not 4:
            quadmethod = False
            #print('no quad!')

    #SLOW HERE, find faster way to test if selection is ring shaped

    #Unwrap and get the edge verts
    bmesh.update_edit_mesh(obj.data)
    bpy.ops.uv.unwrap(method='CONFORMAL', margin=0.001)
    bpy.ops.mesh.region_to_loop()

    obj = bpy.context.edit_object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)

    edge_list = list()
    for e in bm.edges:
        if e.select is True:
            edge_list.append(e)
            #print(e)

    #select faces again
    for f in faces:
        f.select = True
    #get start loop (this makes sure we loop in the right direction)
    startloop = None

    if (len(edge_list) == 0):
        print("weird! - means no mesh was sent?")
        return distorted

    for l in edge_list[0].link_loops:
        if l.face.select is True:
            startloop = l
    #create sorted verts from start loop
    sorted_vert_list = list()
    for f in faces:
        f.select = False
    for e in edge_list:
        e.select = True

    sorted_vert_list.append(startloop.vert)
    startloop.edge.select = False
    sorted_vert_list.append(startloop.link_loop_next.vert)

    for i in range(1, len(edge_list) - 1):
        #catch if a patch is donut shaped:
        if i >= len(sorted_vert_list):
            for f in faces:
                f.select = True
            bmesh.update_edit_mesh(obj.data)
            return False

        for e in sorted_vert_list[i].link_edges:
            if e.select is True:
                sorted_vert_list.append(e.other_vert(sorted_vert_list[i]))
                e.select = False

    #select faces again
    for f in faces:
        f.select = True

    #get UV
    sorted_uv_list = list()
    uv_layer = bm.loops.layers.uv.active
    for v in sorted_vert_list:
        for l in v.link_loops:
            if l.face.select is True:
                sorted_uv_list.append(l[uv_layer])
                break

    #get all angles
    sorted_angle_list = list()

    for i in range(len(sorted_uv_list)):
        prev = (i - 1) % len(sorted_uv_list)
        next = (i + 1) % len(sorted_uv_list)
        vector1 = Vector((sorted_uv_list[prev].uv.y - sorted_uv_list[i].uv.y,
                          sorted_uv_list[prev].uv.x - sorted_uv_list[i].uv.x))
        vector2 = Vector((sorted_uv_list[next].uv.y - sorted_uv_list[i].uv.y,
                          sorted_uv_list[next].uv.x - sorted_uv_list[i].uv.x))
        #check failcase of zero length vector:
        if vector1.length == 0 or vector2.length == 0:
            bmesh.update_edit_mesh(obj.data)
            return False
        angle = -math.degrees(vector1.angle_signed(vector2))
        if angle < 0:
            angle += 360
        sorted_angle_list.append(angle)

    #find concaves:
    for i in range(len(sorted_angle_list)):
        #print(sorted_angle_list[i])
        if sorted_angle_list[i] > 230:
            distorted = True
            bmesh.update_edit_mesh(obj.data)
            return False

    #angle test:
    #print("angles")
    #test if more than 4 90 degrees:
    NCount = 0
    for i in range(len(sorted_angle_list)):
        #print(sorted_angle_list[i])
        if sorted_angle_list[i] < 100:
            NCount += 1
    if NCount > 4:
        distorted = True

    #now find top 4 angles
    topangles = list()
    for o in range(4):
        top = 360
        topindex = -1
        for i in range(len(sorted_angle_list)):
            if sorted_angle_list[i] < top:
                top = sorted_angle_list[i]
                topindex = i
        #print(sorted_angle_list[topindex])

        if o is 3:
            if sorted_angle_list[topindex] > 120:
                distorted = True

        topangles.append(topindex)
        sorted_angle_list[topindex] = 999  #lol

    sorted_corner_list = list()
    for i in range(len(sorted_uv_list)):
        sorted_corner_list.append(False)
    sorted_corner_list[topangles[0]] = True
    sorted_corner_list[topangles[1]] = True
    sorted_corner_list[topangles[2]] = True
    sorted_corner_list[topangles[3]] = True

    #find bottom left corner (using distance method seems to work well)
    distance = 2
    closest = 0
    for t in topangles:
        l = sorted_uv_list[t].uv.length
        if l < distance:
            distance = l
            closest = t

    #rotate lists to get clostest corner at start:
    for i in range(closest):
        sorted_corner_list.append(sorted_corner_list.pop(0))
        sorted_uv_list.append(sorted_uv_list.pop(0))
        sorted_vert_list.append(sorted_vert_list.pop(0))

    print("THESE ARE THE CORNERS")
    print(sorted_corner_list)
    #create coord list:

    cornerz = list()

    for i in range(len(sorted_vert_list)):
        if sorted_corner_list[i] is True:
            print(sorted_vert_list[i].co.z)
            cornerz.append(sorted_vert_list[i].co.z)

    print(cornerz)
    #avgedge1 = cornerz[0] + cornerz[1]
    #avgedge2 = cornerz[0] + cornerz[3]
    #print(avgedge1)
    #print(avgedge2)

    sorted_edge_ratios = list()

    #get edge lenghts
    edge = list()
    for i in range(len(sorted_vert_list)):
        if sorted_corner_list[i] is True:
            sorted_edge_ratios.append(0)
            if i is not 0:
                l = (sorted_vert_list[i - 1].co.xyz -
                     sorted_vert_list[i].co.xyz).length
                edge.append(sorted_edge_ratios[i - 1] + l)

        if sorted_corner_list[i] is False:
            l = (sorted_vert_list[i - 1].co.xyz -
                 sorted_vert_list[i].co.xyz).length
            sorted_edge_ratios.append(sorted_edge_ratios[i - 1] + l)
        if i is (len(sorted_vert_list) - 1):
            l = (sorted_vert_list[i].co.xyz -
                 sorted_vert_list[0].co.xyz).length
            edge.append(sorted_edge_ratios[i] + l)

    if quadmethod:
        #MAP FIRST QUAD
        edge1 = (faces[0].loops[0].vert.co.xyz -
                 faces[0].loops[1].vert.co.xyz).length
        edge2 = (faces[0].loops[1].vert.co.xyz -
                 faces[0].loops[2].vert.co.xyz).length

        faces[0].loops[0][uv_layer].uv.x = 0
        faces[0].loops[0][uv_layer].uv.y = 0
        faces[0].loops[1][uv_layer].uv.x = edge1
        faces[0].loops[1][uv_layer].uv.y = 0
        faces[0].loops[2][uv_layer].uv.x = edge1
        faces[0].loops[2][uv_layer].uv.y = edge2
        faces[0].loops[3][uv_layer].uv.x = 0
        faces[0].loops[3][uv_layer].uv.y = edge2

        bm.faces.active = faces[0]

        #UNWRAP ADJACENT
        bmesh.update_edit_mesh(obj.data)
        bpy.ops.uv.follow_active_quads()
        obj = bpy.context.view_layer.objects.active
        bm = bmesh.from_edit_mesh(obj.data)
        uv_layer = bm.loops.layers.uv.verify()

        #return
        edge1 = (edge[0] + edge[2]) * .5
        edge2 = (edge[1] + edge[3]) * .5

        #FIT TO 0-1 range
        xmin, xmax = faces[0].loops[0][uv_layer].uv.x, faces[0].loops[0][
            uv_layer].uv.x
        ymin, ymax = faces[0].loops[0][uv_layer].uv.y, faces[0].loops[0][
            uv_layer].uv.y

        for face in faces:
            for vert in face.loops:
                xmin = min(xmin, vert[uv_layer].uv.x)
                xmax = max(xmax, vert[uv_layer].uv.x)
                ymin = min(ymin, vert[uv_layer].uv.y)
                ymax = max(ymax, vert[uv_layer].uv.y)

        #return

        #prevent divide by 0:
        if (xmax - xmin) == 0:
            xmin = .1
        if (ymax - ymin) == 0:
            ymin = .1

        for face in faces:
            for loop in face.loops:
                loop[uv_layer].uv.x -= xmin
                loop[uv_layer].uv.y -= ymin
                loop[uv_layer].uv.x /= (xmax - xmin)
                loop[uv_layer].uv.y /= (ymax - ymin)

        #shift extents to be positive only:
        xmax = xmax - xmin
        ymax = ymax - ymin

        #now fit to correct edge lengths:
        if (edge1 < edge2):
            #flip them:
            tedge = edge1
            edge1 = edge2
            edge2 = tedge

        if xmax >= ymax:
            for face in faces:
                for loop in face.loops:
                    loop[uv_layer].uv.x *= edge1
                    loop[uv_layer].uv.y *= edge2
        if xmax < ymax:
            for face in faces:
                for loop in face.loops:
                    loop[uv_layer].uv.x *= edge2
                    loop[uv_layer].uv.y *= edge1

        bmesh.update_edit_mesh(obj.data)

    if quadmethod is False:

        if distorted is False:
            #NOW LAY OUT ALL EDGE UVs
            i = 0
            #EDGE 1
            for l in sorted_vert_list[i].link_loops:
                if l.face.select is True:
                    l[uv_layer].uv = Vector((0, 0))
            i += 1
            while sorted_corner_list[i] is False:
                for l in sorted_vert_list[i].link_loops:
                    if l.face.select is True:
                        l[uv_layer].uv = Vector(
                            (sorted_edge_ratios[i] / edge[0], 0))
                i += 1
            #EDGE 2
            for l in sorted_vert_list[i].link_loops:
                if l.face.select is True:
                    l[uv_layer].uv = Vector((1, 0))
            i += 1
            while sorted_corner_list[i] is False:
                for l in sorted_vert_list[i].link_loops:
                    if l.face.select is True:
                        l[uv_layer].uv = Vector(
                            (1, sorted_edge_ratios[i] / edge[1]))
                i += 1
            #EDGE 3
            for l in sorted_vert_list[i].link_loops:
                if l.face.select is True:
                    l[uv_layer].uv = Vector((1, 1))
            i += 1
            while sorted_corner_list[i] is False:
                for l in sorted_vert_list[i].link_loops:
                    if l.face.select is True:
                        l[uv_layer].uv = Vector(
                            (1 - (sorted_edge_ratios[i] / edge[2]), 1))
                i += 1
            #EDGE 4
            for l in sorted_vert_list[i].link_loops:
                if l.face.select is True:
                    l[uv_layer].uv = Vector((0, 1))
            i += 1
            for o in range(i, len(sorted_vert_list)):
                for l in sorted_vert_list[o].link_loops:
                    if l.face.select is True:
                        l[uv_layer].uv = Vector(
                            (0, 1 - (sorted_edge_ratios[o] / edge[3])))

            #set proper aspect ratio

            for f in bm.faces:
                if f.select is True:
                    for loop in f.loops:
                        loop_uv = loop[uv_layer]
                        loop_uv.uv.x *= edge[0]
                        loop_uv.uv.y *= edge[1]

        bmesh.update_edit_mesh(me, True)
        bpy.ops.uv.select_all(action='SELECT')
        #expand middle verts
        bpy.ops.uv.minimize_stretch(iterations=100)
        #return true if rect fit was succesful
        return not distorted
Esempio n. 51
0
    def init_edgegrow(self, context):

        self.change = True

        self.area = context.area
        self.region = context.region
        self.rv3d = context.space_data.region_3d
        self.selobj = context.active_object
        self.mesh = self.selobj.data
        self.bm = bmesh.from_edit_mesh(self.mesh)
        self.actedge = self.bm.select_history.active
        # get transf matrix
        self.getmatrix()

        # vsellist, essellist: remember selection for reselecting later
        self.selset = set([])
        self.vsellist = []
        self.esellist = []
        for edge in self.bm.edges:
            if edge.select:
                self.selset.add(edge)
                self.esellist.append(edge)
        for vert in self.bm.verts:
            if vert.select:
                self.vsellist.append(vert)

        def addstart(vert):

            # recursive: adds to initial edgelist at start
            for e in vert.link_edges:
                if e in self.selset:
                    self.selset.discard(e)
                    v = e.other_vert(vert)
                    self.edgelist[posn].insert(0, e)
                    addstart(v)
                    break

        def addend(vert):

            # recursive: adds to initial edgelist at end
            for e in vert.link_edges:
                if e in self.selset:
                    self.selset.discard(e)
                    v = e.other_vert(vert)
                    self.edgelist[posn].append(e)
                    addend(v)
                    break

        self.state = []
        self.oldstate = []
        self.cursor = []
        self.startcur = []
        self.endcur = []
        self.check = []
        self.activedir = []
        self.singledir = {}
        self.singledir[0] = None
        self.startlen = []
        self.edgelist = []
        posn = 0
        while len(self.selset) > 0:
            # INITialize next edgesnake
            self.state.append('INIT')
            self.oldstate.append('INIT')
            self.cursor.append(None)
            self.startcur.append(None)
            self.endcur.append(None)
            self.check.append(0)
            self.activedir.append("")

            self.edgelist.append([])
            elem = self.selset.pop()
            vert = elem.verts[0]
            self.selset.add(elem)
            # add to START and END of arbitrary START vert
            addstart(vert)
            addend(vert)
            self.startlen.append(len(self.edgelist[posn]))
            posn += 1
        if len(self.edgelist) == 1:
            if len(self.edgelist[0]) == 1:
                # must store leftmost vert as startingvert when only one edge selected
                x1, y = self.getscreencoords(self.edgelist[0][0].verts[0].co)
                x2, y = self.getscreencoords(self.edgelist[0][0].verts[1].co)
                if x1 < x2:
                    self.singledir[0] = self.edgelist[0][0].verts[0]
                else:
                    self.singledir[0] = self.edgelist[0][0].verts[1]

        # orient first edgesnake from left(start) to right(end)
        x1, y = self.getscreencoords(self.edgelist[0][0].verts[0].co)
        x2, y = self.getscreencoords(self.edgelist[0][len(self.edgelist[0]) -
                                                      1].verts[0].co)
        if x1 > x2:
            self.edgelist[0].reverse()

        #
        # orient edge and vertlists parallel - reverse if necessary
        for i in range(len(self.edgelist) - 1):
            bpy.ops.mesh.select_all(action='DESELECT')
            # get first vert and edge for two adjacent snakes
            for v in self.edgelist[i][0].verts:
                if len(self.edgelist[i]) == 1:
                    if i == 0:
                        x1, y = self.getscreencoords(v.co)
                        x2, y = self.getscreencoords(
                            edgelist[i][0].other_vert(v).co)
                        if x1 < x2:
                            self.singledir[0] = v
                        else:
                            self.singledir[0] = self.edgelist[i][0].other_vert(
                                v)
                    vt = self.singledir[i]
                    vt.select = True
                    self.bm.select_history.add(vt)
                    v1 = vt
                    e1 = self.edgelist[i][0]
                    break
                elif not (v in self.edgelist[i][1].verts):
                    v.select = True
                    self.bm.select_history.add(v)
                    v1 = v
                    e1 = self.edgelist[i][0]
            for v in self.edgelist[i + 1][0].verts:
                if len(self.edgelist[i + 1]) == 1:
                    v.select = True
                    self.bm.select_history.add(v)
                    v2 = v
                    e2 = self.edgelist[i + 1][0]
                    break
                elif not (v in self.edgelist[i + 1][1].verts):
                    v.select = True
                    self.bm.select_history.add(v)
                    v2 = v
                    e2 = self.edgelist[i + 1][0]
            self.singledir[i + 1] = v2
            self.bm.select_history.validate()
            # get path between startverts for checking orientation
            bpy.ops.mesh.shortest_path_select()

            for e in self.bm.edges:
                if e.verts[0].select and e.verts[1].select:
                    e.select = True

            # correct selected path when not connected neatly to vert from left or right(cant know direction)
            def correctsel(e1, v1, lst):
                found = False
                while not (found):
                    found = True
                    for edge in e1.other_vert(v1).link_edges:
                        if edge.select and edge != e1:
                            if lst.index(e1) < len(lst) - 1:
                                v1.select = False
                                e1.select = False
                                v1 = e1.other_vert(v1)
                                e1 = lst[lst.index(e1) + 1]
                            else:
                                templ = list(e1.other_vert(v1).link_faces)
                                for f in e1.link_faces:
                                    templ.pop(templ.index(f))
                                for edge in e1.other_vert(v1).link_edges:
                                    if edge in templ[
                                            0].edges and edge in templ[1].edges:
                                        v1.select = False
                                        e1.select = False
                                        v1 = e1.other_vert(v1)
                                        e1 = edge
                            found = False

                # check situation where left/right connection is on vert thats outside slice
                found = False
                while not (found):
                    templ = list(v1.link_faces)
                    for f in e1.link_faces:
                        templ.pop(templ.index(f))
                    found = True
                    for edge in v1.link_edges:
                        if edge in templ[0].edges and edge in templ[1].edges:
                            if edge.other_vert(v1).select:
                                v1.select = False
                                edge.select = False
                                v1 = edge.other_vert(v1)
                                e1 = edge
                                found = False
                return e1, v1

            e1, v1 = correctsel(e1, v1, self.edgelist[i])
            e2, v2 = correctsel(e2, v2, self.edgelist[i + 1])

            # do all the checking to see if the checked lists must be reversed
            brk = False
            for face1 in e1.link_faces:
                for edge1 in face1.edges:
                    if edge1.select:
                        for loop1 in face1.loops:
                            if loop1.vert == v1:
                                if loop1.edge == e1:
                                    turn = loop1
                                elif loop1.link_loop_next.edge == e1:
                                    turn = loop1.link_loop_next
                                else:
                                    turn = loop1.link_loop_prev
                                # check if turning in one direction
                                if turn.link_loop_next.edge.select:
                                    for face2 in e2.link_faces:
                                        for edge2 in face2.edges:
                                            if edge2.select:
                                                for loop2 in face2.loops:
                                                    if loop2.vert == v2:
                                                        if loop2.edge == e2:
                                                            turn = loop2
                                                        elif loop2.link_loop_next.edge == e2:
                                                            turn = loop2.link_loop_next
                                                        else:
                                                            turn = loop2.link_loop_prev
                                                        if turn.link_loop_next.edge.select:
                                                            self.singledir[
                                                                i +
                                                                1] = e2.other_vert(
                                                                    v2)
                                                            self.edgelist[
                                                                i +
                                                                1].reverse()
                                                        break
                                                brk = True
                                                break
                                        if brk == True:
                                            break
                                # and the other
                                elif loop1.link_loop_prev.edge.select:
                                    for face2 in e2.link_faces:
                                        for edge2 in face2.edges:
                                            if edge2.select:
                                                for loop2 in face2.loops:
                                                    if loop2.vert == v2:
                                                        if loop2.edge == e2:
                                                            turn = loop2
                                                        elif loop2.link_loop_next.edge == e2:
                                                            turn = loop2.link_loop_next
                                                        else:
                                                            turn = loop2.link_loop_prev
                                                        if turn.link_loop_prev.edge.select:
                                                            self.singledir[
                                                                i +
                                                                1] = e2.other_vert(
                                                                    v2)
                                                            self.edgelist[
                                                                i +
                                                                1].reverse()
                                                        break
                                                brk = True
                                                break
                                        if brk == True:
                                            break
                                break
                        break

        for posn in range(len(self.edgelist)):
            if self.edgelist[posn][0] == self.actedge:
                for posn in range(len(self.edgelist)):
                    self.edgelist[posn].reverse()

        bpy.ops.mesh.select_all(action='DESELECT')
        for v in self.vsellist:
            v.select = True
        for e in self.esellist:
            e.select = True

        self.region.tag_redraw()
Esempio n. 52
0
    def execute(self, context):
        mode = context.mode
        if mode == 'EDIT_MESH':
            mode = 'EDIT'
        act = context.active_object
        if mode != 'OBJECT':
            sel = [act]
            bpy.ops.object.mode_set(mode='OBJECT')
        else:
            sel = context.selected_objects
        doneMeshes = []

        for ob0 in sel:
            if ob0.type != 'MESH':
                continue
            if ob0.data.name in doneMeshes:
                continue
            ob = ob0
            mesh_name = ob0.data.name

            # store linked objects
            clones = []
            n_users = ob0.data.users
            count = 0
            for o in bpy.data.objects:
                if o.type != 'MESH':
                    continue
                if o.data.name == mesh_name:
                    count += 1
                    clones.append(o)
                if count == n_users:
                    break

            if self.apply_modifiers:
                bpy.ops.object.convert(target='MESH')
            ob.data = ob.data.copy()
            bpy.ops.object.select_all(action='DESELECT')
            ob.select_set(True)
            context.view_layer.objects.active = ob0
            bpy.ops.object.mode_set(mode='EDIT')

            # prevent borders erosion
            bpy.ops.mesh.select_mode(use_extend=False,
                                     use_expand=False,
                                     type='EDGE')
            bpy.ops.mesh.select_non_manifold(extend=False,
                                             use_wire=False,
                                             use_boundary=True,
                                             use_multi_face=False,
                                             use_non_contiguous=False,
                                             use_verts=False)
            bpy.ops.mesh.extrude_region_move(
                MESH_OT_extrude_region={"mirror": False},
                TRANSFORM_OT_translate={"value": (0, 0, 0)})

            bpy.ops.mesh.select_mode(use_extend=False,
                                     use_expand=False,
                                     type='VERT',
                                     action='TOGGLE')
            bpy.ops.mesh.select_all(action='SELECT')
            bpy.ops.mesh.quads_convert_to_tris(quad_method=self.quad_method,
                                               ngon_method=self.polygon_method)
            bpy.ops.mesh.select_all(action='DESELECT')
            bpy.ops.object.mode_set(mode='OBJECT')
            bpy.ops.object.modifier_add(type='SUBSURF')
            ob.modifiers[-1].name = "dual_mesh_subsurf"
            while True:
                bpy.ops.object.modifier_move_up(modifier="dual_mesh_subsurf")
                if ob.modifiers[0].name == "dual_mesh_subsurf":
                    break

            bpy.ops.object.modifier_apply(apply_as='DATA',
                                          modifier='dual_mesh_subsurf')

            bpy.ops.object.mode_set(mode='EDIT')
            bpy.ops.mesh.select_all(action='DESELECT')

            verts = ob.data.vertices

            bpy.ops.object.mode_set(mode='OBJECT')
            verts[-1].select = True
            bpy.ops.object.mode_set(mode='EDIT')
            bpy.ops.mesh.select_more(use_face_step=False)

            bpy.ops.mesh.select_similar(type='EDGE',
                                        compare='EQUAL',
                                        threshold=0.01)
            bpy.ops.mesh.select_all(action='INVERT')

            bpy.ops.mesh.dissolve_verts()
            bpy.ops.mesh.select_all(action='DESELECT')

            bpy.ops.mesh.select_non_manifold(extend=False,
                                             use_wire=False,
                                             use_boundary=True,
                                             use_multi_face=False,
                                             use_non_contiguous=False,
                                             use_verts=False)
            bpy.ops.mesh.select_more()

            # find boundaries
            bpy.ops.object.mode_set(mode='OBJECT')
            bound_v = [v.index for v in ob.data.vertices if v.select]
            bound_e = [e.index for e in ob.data.edges if e.select]
            bound_p = [p.index for p in ob.data.polygons if p.select]
            bpy.ops.object.mode_set(mode='EDIT')

            # select quad faces
            context.tool_settings.mesh_select_mode = (False, False, True)
            bpy.ops.mesh.select_face_by_sides(number=4, extend=False)

            # deselect boundaries
            bpy.ops.object.mode_set(mode='OBJECT')
            for i in bound_v:
                context.active_object.data.vertices[i].select = False
            for i in bound_e:
                context.active_object.data.edges[i].select = False
            for i in bound_p:
                context.active_object.data.polygons[i].select = False

            bpy.ops.object.mode_set(mode='EDIT')

            context.tool_settings.mesh_select_mode = (False, False, True)
            bpy.ops.mesh.edge_face_add()
            context.tool_settings.mesh_select_mode = (True, False, False)
            bpy.ops.mesh.select_all(action='DESELECT')

            # delete boundaries
            bpy.ops.mesh.select_non_manifold(extend=False,
                                             use_wire=True,
                                             use_boundary=True,
                                             use_multi_face=False,
                                             use_non_contiguous=False,
                                             use_verts=True)
            bpy.ops.mesh.delete(type='VERT')

            # remove middle vertices
            bm = bmesh.from_edit_mesh(ob.data)
            for v in bm.verts:
                if len(v.link_edges) == 2 and len(v.link_faces) < 3:
                    v.select = True

            # dissolve
            bpy.ops.mesh.dissolve_verts()
            bpy.ops.mesh.select_all(action='DESELECT')

            # remove border faces
            if not self.preserve_borders:
                bpy.ops.mesh.select_non_manifold(extend=False,
                                                 use_wire=False,
                                                 use_boundary=True,
                                                 use_multi_face=False,
                                                 use_non_contiguous=False,
                                                 use_verts=False)
                bpy.ops.mesh.select_more()
                bpy.ops.mesh.delete(type='FACE')

            # clean wires
            bpy.ops.mesh.select_non_manifold(extend=False,
                                             use_wire=True,
                                             use_boundary=False,
                                             use_multi_face=False,
                                             use_non_contiguous=False,
                                             use_verts=False)
            bpy.ops.mesh.delete(type='EDGE')

            bpy.ops.object.mode_set(mode='OBJECT')
            ob0.data.name = mesh_name
            doneMeshes.append(mesh_name)

            for o in clones:
                o.data = ob.data
            bm.free()

        for o in sel:
            o.select_set(True)

        context.view_layer.objects.active = act
        bpy.ops.object.mode_set(mode=mode)

        return {'FINISHED'}
Esempio n. 53
0
    def execute(self, context):
        obj_name = self.name_source_object
        face_type = self.face_types

        is_selected = check_is_selected()

        if not is_selected:
            self.report({'WARNING'},
                        "Operation Cancelled. No selected Faces found on the Active Object")
            return {'CANCELLED'}

        if face_type == "spiked":
            Spiked(spike_base_width=self.spike_base_width,
                   base_height_inset=self.base_height_inset,
                   top_spike=self.top_spike, top_relative=self.use_relative)

        elif face_type == "boxed":
            startinfo = prepare(self, context, self.remove_start_faces)
            bm = startinfo['bm']
            top = self.top_spike
            obj = startinfo['obj']
            obj_matrix_local = obj.matrix_local

            distance = None
            base_heights = None
            t = self.move_inside
            areas = startinfo['areas']
            base_height = self.base_height

            if self.use_relative:
                distance = [min(t * area, 1.0) for i, area in enumerate(areas)]
                base_heights = [base_height * area for i, area in enumerate(areas)]
            else:
                distance = [t] * len(areas)
                base_heights = [base_height] * len(areas)

            rings = startinfo['rings']
            centers = startinfo['centers']
            normals = startinfo['normals']
            for i in range(len(rings)):
                make_one_inset(self, context, bm=bm, ringvectors=rings[i],
                               center=centers[i], normal=normals[i],
                               t=distance[i], base_height=base_heights[i])
                bpy.ops.mesh.select_mode(type="EDGE")
                bpy.ops.mesh.select_more()
                bpy.ops.mesh.select_more()
            bpy.ops.object.mode_set(mode='OBJECT')
            # PKHG>INFO base extrusion done and set to the mesh

            # PKHG>INFO if the extrusion is NOT  done ... it'll look strange soon!
            if not self.strange_boxed_effect:
                bpy.ops.object.mode_set(mode='EDIT')
                obj = context.active_object
                bm = bmesh.from_edit_mesh(obj.data)
                bmfaces = [face for face in bm.faces if face.select]
                res = extrude_faces(self, context, bm=bm, face_l=bmfaces)
                ring_edges = [face.edges[:] for face in res]

            bpy.ops.object.mode_set(mode='OBJECT')

            # PKHG>INFO now the extruded facec have to move in normal direction
            bpy.ops.object.mode_set(mode='EDIT')
            obj = bpy.context.view_layer.objects.active
            bm = bmesh.from_edit_mesh(obj.data)
            todo_faces = [face for face in bm.faces if face.select]
            for face in todo_faces:
                bmesh.ops.translate(bm, vec=face.normal * top, space=obj_matrix_local,
                                    verts=face.verts)
            bpy.ops.object.mode_set(mode='OBJECT')

        elif face_type == "stepped":
            Stepped(spike_base_width=self.spike_base_width,
                    base_height_inset=self.base_height_inset,
                    top_spike=self.second_height,
                    top_extra_height=self.top_extra_height,
                    use_relative_offset=self.use_relative, with_spike=self.step_with_real_spike)

        elif face_type == "open_inset":
            startinfo = prepare(self, context, self.remove_start_faces)
            bm = startinfo['bm']

            # PKHG>INFO adjust for relative, via areas
            t = self.move_inside
            areas = startinfo['areas']
            base_height = self.base_height
            base_heights = None
            distance = None
            if self.use_relative:
                distance = [min(t * area, 1.0) for i, area in enumerate(areas)]
                base_heights = [base_height * area for i, area in enumerate(areas)]
            else:
                distance = [t] * len(areas)
                base_heights = [base_height] * len(areas)

            rings = startinfo['rings']
            centers = startinfo['centers']
            normals = startinfo['normals']
            for i in range(len(rings)):
                make_one_inset(self, context, bm=bm, ringvectors=rings[i],
                               center=centers[i], normal=normals[i],
                               t=distance[i], base_height=base_heights[i])
            bpy.ops.object.mode_set(mode='OBJECT')

        elif face_type == "with_base":
            startinfo = prepare(self, context, self.remove_start_faces)
            bm = startinfo['bm']
            obj = startinfo['obj']
            object_matrix = obj.matrix_local

            # PKHG>INFO for relative (using areas)
            t = self.move_inside
            areas = startinfo['areas']
            base_height = self.base_height
            distance = None
            base_heights = None

            if self.use_relative:
                distance = [min(t * area, 1.0) for i, area in enumerate(areas)]
                base_heights = [base_height * area for i, area in enumerate(areas)]
            else:
                distance = [t] * len(areas)
                base_heights = [base_height] * len(areas)

            next_rings = []
            rings = startinfo['rings']
            centers = startinfo['centers']
            normals = startinfo['normals']
            for i in range(len(rings)):
                next_rings.append(make_one_inset(self, context, bm=bm, ringvectors=rings[i],
                                                 center=centers[i], normal=normals[i],
                                                 t=distance[i], base_height=base_heights[i]))

            prepare_ring = extrude_edges(self, context, bm=bm, edge_l_l=next_rings)

            second_height = self.second_height
            width = self.width
            vectors = [[ele.verts[:] for ele in edge] for edge in prepare_ring]
            n_ring_vecs = []

            for rings in vectors:
                v = []
                for edgv in rings:
                    v.extend(edgv)
                # PKHF>INFO no double verts allowed, coming from two adjacents edges!
                bm.verts.ensure_lookup_table()
                vv = list(set([ele.index for ele in v]))

                vvv = [bm.verts[i].co for i in vv]
                n_ring_vecs.append(vvv)

            for i, ring in enumerate(n_ring_vecs):
                make_one_inset(self, context, bm=bm, ringvectors=ring,
                               center=centers[i], normal=normals[i],
                               t=width, base_height=base_heights[i] + second_height)
            bpy.ops.object.mode_set(mode='OBJECT')

        else:
            if face_type == "clsd_vertical":
                obj_name = context.active_object.name
                ClosedVertical(name=obj_name, base_height=self.base_height,
                               use_relative_base_height=self.use_relative)

            elif face_type == "open_vertical":
                obj_name = context.active_object.name
                OpenVertical(name=obj_name, base_height=self.base_height,
                             use_relative_base_height=self.use_relative)

            elif face_type == "bar":
                startinfo = prepare(self, context, self.remove_start_faces)

                result = []
                bm = startinfo['bm']
                rings = startinfo['rings']
                centers = startinfo['centers']
                normals = startinfo['normals']
                spike_base_width = self.spike_base_width
                for i, ring in enumerate(rings):
                    result.append(make_one_inset(self, context, bm=bm,
                                                 ringvectors=ring, center=centers[i],
                                                 normal=normals[i], t=spike_base_width))

                next_ring_edges_list = extrude_edges(self, context, bm=bm,
                                                     edge_l_l=result)
                top_spike = self.top_spike
                fac = top_spike
                object_matrix = startinfo['obj'].matrix_local
                for i in range(len(next_ring_edges_list)):
                    translate_ONE_ring(
                            self, context, bm=bm,
                            object_matrix=object_matrix,
                            ring_edges=next_ring_edges_list[i],
                            normal=normals[i], distance=fac
                            )
                next_ring_edges_list_2 = extrude_edges(self, context, bm=bm,
                                                       edge_l_l=next_ring_edges_list)

                top_extra_height = self.top_extra_height
                for i in range(len(next_ring_edges_list_2)):
                    move_corner_vecs_outside(
                            self, context, bm=bm,
                            edge_list=next_ring_edges_list_2[i],
                            center=centers[i], normal=normals[i],
                            base_height_erlier=fac + top_extra_height,
                            distance=fac
                            )
                bpy.ops.mesh.select_mode(type="VERT")
                bpy.ops.mesh.select_more()

                bpy.ops.object.mode_set(mode='OBJECT')

        return {'FINISHED'}
Esempio n. 54
0
def prepare(self, context, remove_start_faces=True):
    """
       Start for a face selected change of faces
       select an object of type mesh, with activated several (all) faces
    """
    obj = bpy.context.view_layer.objects.active
    bpy.ops.object.mode_set(mode='OBJECT')
    selectedpolygons = [el for el in obj.data.polygons if el.select]

    # PKHG>INFO copies of the vectors are needed, otherwise Blender crashes!
    centers = [face.center for face in selectedpolygons]
    centers_copy = [Vector((el[0], el[1], el[2])) for el in centers]
    normals = [face.normal for face in selectedpolygons]
    normals_copy = [Vector((el[0], el[1], el[2])) for el in normals]

    vertindicesofpolgons = [
            [vert for vert in face.vertices] for face in selectedpolygons
            ]
    vertVectorsOfSelectedFaces = [
            [obj.data.vertices[ind].co for ind in vertIndiceofface] for
            vertIndiceofface in vertindicesofpolgons
            ]
    vertVectorsOfSelectedFaces_copy = [
            [Vector((el[0], el[1], el[2])) for el in listofvecs] for
            listofvecs in vertVectorsOfSelectedFaces
            ]

    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    selected_bm_faces = [ele for ele in bm.faces if ele.select]

    selected_edges_per_face_ind = [
            [ele.index for ele in face.edges] for face in selected_bm_faces
            ]
    indices = [el.index for el in selectedpolygons]
    selected_faces_areas = [bm.faces[:][i] for i in indices]
    tmp_area = [el.calc_area() for el in selected_faces_areas]

    # PKHG>INFO, selected faces are removed, only their edges are used!
    if remove_start_faces:
        bpy.ops.mesh.delete(type='ONLY_FACE')
        bpy.ops.object.mode_set(mode='OBJECT')
        obj.data.update()
        bpy.ops.object.mode_set(mode='EDIT')
        bm = bmesh.from_edit_mesh(obj.data)
        bm.verts.ensure_lookup_table()
        bm.faces.ensure_lookup_table()

    start_ring_raw = [
            [bm.verts[ind].index for ind in vertIndiceofface] for
            vertIndiceofface in vertindicesofpolgons
            ]
    start_ring = []

    for el in start_ring_raw:
        start_ring.append(set(el))
    bm.edges.ensure_lookup_table()

    bm_selected_edges_l_l = [
            [bm.edges[i] for i in bm_ind_list] for
            bm_ind_list in selected_edges_per_face_ind
            ]
    result = {
            'obj': obj, 'centers': centers_copy, 'normals': normals_copy,
            'rings': vertVectorsOfSelectedFaces_copy, 'bm': bm,
            'areas': tmp_area, 'startBMRingVerts': start_ring,
            'base_edges': bm_selected_edges_l_l
            }

    return result
def create_snowflake(o, iterations=2):

    # Create rotation matrices
    rot_matrix = Matrix.Rotation(radians(90), 3, 'Z')
    turn_around_matrix = Matrix.Rotation(radians(180), 3, 'Z')

    # Select object and set it as active object
    o.select = True
    bpy.context.scene.objects.active = o

    # Ensure we're in edit mode and in vertex selection mode
    if o.mode != 'EDIT': bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_mode(type='VERT')

    for i in range(iterations):
        # Refresh object data and edge list (which changes with each iterations)
        d = o.data
        bm = bmesh.from_edit_mesh(d)
        bv = bm.verts
        edges = {e.index: [v.index for v in e.verts] for e in bm.edges}

        for edge_index, edge in enumerate(edges):
            # Go to vert selection mode
            bpy.ops.mesh.select_mode(type='VERT')

            # Deselect all verts
            bpy.ops.mesh.select_all(action='DESELECT')

            # Select current edge (by selecting its verts)
            bm.verts.ensure_lookup_table()  # Update verts list

            for v in edges[edge]:
                bv[v].select = True

            bm.select_flush(True)

            # Subdivide edge
            result = bpy.ops.mesh.subdivide(number_cuts=2)

            bm.select_flush(True)

            # Find innermost edge
            selected_edges = {
                e.index : set([ v.index for v in e.verts ]) \
                for e in bm.edges if e.select
            }

            # Innermost edge shares both its verts with the other edges
            mid = 42  # out-of-range index to to indicate if procedure worked
            for i in selected_edges.keys():
                other_edges = set(selected_edges.keys()) - set([i])

                # check how many joint verts this edge has with the others
                num_of_joint_verts = 0
                for oe in other_edges:
                    if selected_edges[i] & selected_edges[oe]:
                        num_of_joint_verts += 1

                # The middle edge will have two joint verts
                if num_of_joint_verts == 2:
                    mid = i
                    break

            # Select innermost edge (by selecting its verts)
            bm.verts.ensure_lookup_table()  # Update verts list

            bpy.ops.mesh.select_all(action='DESELECT')
            for v in selected_edges[mid]:
                bv[v].select = True

            bm.select_flush(True)

            # Subdivide it once
            bpy.ops.mesh.subdivide(number_cuts=1)

            # Select innermost vert (joint vert between both edges)
            selected_edges_verts = [
                set([v.index for v in e.verts]) for e in bm.edges if e.select
            ]

            # Find common vert by intersecting both vert sets
            joint_vert = list(selected_edges_verts[0]
                              & selected_edges_verts[1]).pop()

            # Find the verts that aren't joint (via set symmetrical_difference)
            other_verts = list(selected_edges_verts[0]
                               ^ selected_edges_verts[1])

            # Make sure vertices are in right order
            if (other_verts[0] > other_verts[1]):
                other_verts[0], other_verts[1] = other_verts[1], other_verts[0]

            # Calculate its new position: should create an equilateral triangle
            bm.verts.ensure_lookup_table()  # Update verts list

            vdiff = bv[other_verts[1]].co - bv[other_verts[0]].co
            vdiff[0] *= sqrt(3) / 2.0
            vdiff[1] *= sqrt(3) / 2.0
            vrot = vdiff * rot_matrix

            new_pos = bv[joint_vert].co + vrot

            # Select middle vert and translate it by the rotate vector
            bpy.ops.mesh.select_all(action='DESELECT')
            bv[joint_vert].select = True

            bm.select_flush(True)

            bpy.ops.transform.translate(value=tuple(vrot))

    # Return to object mode
    bpy.ops.object.mode_set(mode='OBJECT')
Esempio n. 56
0
def Twist(self, context):
    global L,LBSPhi,K,Links,RefFrm,TwistLbsFrm,LbsSFrm,TwstAxsAngl,AxsAngl,CnsVrt,FrVrt
    ########################## Selection ########################
    bpy.data.objects['MySkelPose'].select_set(True)
    bpy.context.view_layer.objects.active = bpy.data.objects['MySkelPose']
    obj=bpy.context.object
    bm=bmesh.from_edit_mesh(obj.data)
    SelVrt=[]
    for vs in bm.verts:
        if vs.select:
            SelVrt.append(vs.index)
    
    Id=0
    NFrm=len(Links)
    #AxsAnglTmp=np.zeros((NFrm,3))
    for j in Links:
        if SelVrt == j:
            
            theta=(context.scene.TwistAngle1)*(np.pi/180)
            C=np.cos(theta)
            S=np.sin(theta)
            T=1-C
                
            #########  LBS  ######
            w=LbsSFrm[:,4*Id]
            R=np.array([[T*(w[0]**2)+C,T*w[0]*w[1]-S*w[2], T*w[0]*w[2]+S*w[1]],
                        [T*w[0]*w[1]+S*w[2],T*(w[1]**2)+C,T*w[1]*w[2]-S*w[0]],
                        [T*w[0]*w[2]-S*w[1],T*w[1]*w[2]+S*w[0],T*(w[2]**2)+C]])
            TwistLbsFrm[:,4*Id:4*Id+3]=R.dot(LbsSFrm[:,4*Id:4*Id+3])
            ######################
            w=RefFrm[:,4*Id]
            TwstAxsAngl[Id]=theta*w    
            Id+=1
            break

        Id+=1
    
    Ncl=len(JntInd)
    JntPrFace=len(JntInd[0])
    G=np.zeros((3,3*Ncl))
    Theta=np.ones(7)
    for c in range(Ncl):
        Ind=JntInd[c]
        R=0
        for i in range(JntPrFace):
            Y=W[3*c:3*c+3,3*i:3*i+3].dot(TwstAxsAngl[Ind[i]]+AxsAngl[Ind[i]])
            R=R+Wgts[c,i]*AnglAxisToRotMat(Y)
            Theta[3*i:3*i+3]=AxsAngl[Ind[i]]
        G[:,3*c:3*c+3]=R.dot(np.reshape(H[9*c:9*c+9].dot(Theta),(3,3)))

    X=np.zeros((3,len(CnsVrt)+len(FrVrt)))
    X[:,CnsVrt]=TwistLbsFrm.dot(LBSPhi)
    X[:,FrVrt]=G.dot(L)-X[:,CnsVrt].dot(K)
    
    bpy.data.objects['MyMeshPose'].select_set(True)
    bpy.context.view_layer.objects.active = bpy.data.objects['MyMeshPose']
    obj = bpy.context.active_object
    j=0
    for v in obj.data.vertices:
        v.co=[X[0,j],-X[2,j],X[1,j]]
        j+=1
            
    bpy.data.objects['MySkelPose'].select_set(True)
    bpy.context.view_layer.objects.active = bpy.data.objects['MySkelPose']

    return
Esempio n. 57
0
    def invoke(self, context, event):
        if context.space_data.type == 'VIEW_3D':
            #print('name', __name__, __package__)
            preferences = context.user_preferences.addons[__name__].preferences
            create_new_obj = preferences.create_new_obj
            if context.mode == 'OBJECT' and (create_new_obj
                                             or context.object == None
                                             or context.object.type != 'MESH'):

                mesh = bpy.data.meshes.new("")
                obj = bpy.data.objects.new("", mesh)
                context.scene.objects.link(obj)
                context.scene.objects.active = obj

            #bgl.glEnable(bgl.GL_POINT_SMOOTH)
            self.is_editmode = bpy.context.object.data.is_editmode
            bpy.ops.object.mode_set(mode='EDIT')
            context.space_data.use_occlude_geometry = True

            self.scale = context.scene.unit_settings.scale_length
            self.unit_system = context.scene.unit_settings.system
            self.separate_units = context.scene.unit_settings.use_separate
            self.uinfo = get_units_info(self.scale, self.unit_system,
                                        self.separate_units)

            grid = context.scene.unit_settings.scale_length / context.space_data.grid_scale
            relative_scale = preferences.relative_scale
            self.scale = grid / relative_scale
            self.rd = bpy.utils.units.to_value(self.unit_system, 'LENGTH',
                                               str(1 / self.scale))

            incremental = preferences.incremental
            self.incremental = bpy.utils.units.to_value(
                self.unit_system, 'LENGTH', str(incremental))

            self.use_rotate_around_active = context.user_preferences.view.use_rotate_around_active
            context.user_preferences.view.use_rotate_around_active = True

            self.select_mode = context.tool_settings.mesh_select_mode[:]
            context.tool_settings.mesh_select_mode = (True, True, True)

            self.region = context.region
            self.rv3d = context.region_data
            self.rotMat = self.rv3d.view_matrix.copy()
            self.obj = bpy.context.active_object
            self.obj_matrix = self.obj.matrix_world.copy()
            self.bm = bmesh.from_edit_mesh(self.obj.data)

            self.location = Vector()
            self.list_verts = []
            self.list_verts_co = []
            self.bool_update = False
            self.vector_constrain = ()
            self.keytab = False
            self.keyf8 = False
            self.type = 'OUT'
            self.len = 0
            self.length_entered = ""
            self.line_pos = 0

            self.out_color = preferences.out_color
            self.face_color = preferences.face_color
            self.edge_color = preferences.edge_color
            self.vert_color = preferences.vert_color
            self.center_color = preferences.center_color
            self.perpendicular_color = preferences.perpendicular_color
            self.constrain_shift_color = preferences.constrain_shift_color

            self.axis_x_color = tuple(
                context.user_preferences.themes[0].user_interface.axis_x)
            self.axis_y_color = tuple(
                context.user_preferences.themes[0].user_interface.axis_y)
            self.axis_z_color = tuple(
                context.user_preferences.themes[0].user_interface.axis_z)

            self.intersect = preferences.intersect
            self.create_face = preferences.create_face
            self.outer_verts = preferences.outer_verts
            self.snap_to_grid = preferences.increments_grid

            self._handle = bpy.types.SpaceView3D.draw_handler_add(
                self.draw_callback_px, (context, ), 'WINDOW', 'POST_VIEW')
            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "Active space must be a View3d")
            return {'CANCELLED'}
Esempio n. 58
0
    def modal(self, context, event):
        if context.area:
            context.area.tag_redraw()

        if event.ctrl and event.type == 'Z' and event.value == 'PRESS':
            bpy.ops.ed.undo()
            self.vector_constrain = None
            self.list_verts_co = []
            self.list_verts = []
            self.list_edges = []
            self.list_faces = []
            self.obj = bpy.context.active_object
            self.obj_matrix = self.obj.matrix_world.copy()
            self.bm = bmesh.from_edit_mesh(self.obj.data)
            return {'RUNNING_MODAL'}

        if event.type == 'MOUSEMOVE' or self.bool_update:
            if self.rv3d.view_matrix != self.rotMat:
                self.rotMat = self.rv3d.view_matrix.copy()
                self.bool_update = True
            else:
                self.bool_update = False

            if self.bm.select_history:
                self.geom = self.bm.select_history[0]
            else:  #See IndexError or AttributeError:
                self.geom = None

            x, y = (event.mouse_region_x, event.mouse_region_y)
            if self.geom:
                self.geom.select = False
                self.bm.select_history.clear()

            bpy.ops.view3d.select(location=(x, y))

            if self.list_verts != []:
                previous_vert = self.list_verts[-1]
            else:
                previous_vert = None

            outer_verts = self.outer_verts and not self.keytab

            snap_utilities(
                self,
                context,
                self.obj_matrix,
                self.geom,
                self.bool_update,
                (x, y),
                outer_verts=self.outer_verts,
                constrain=self.vector_constrain,
                previous_vert=previous_vert,
                ignore_obj=self.obj,
                increment=self.incremental,
            )

            if self.snap_to_grid and self.type == 'OUT':
                loc = self.location / self.rd
                self.location = Vector(
                    (round(loc.x), round(loc.y), round(loc.z))) * self.rd

            if self.keyf8 and self.list_verts_co:
                lloc = self.list_verts_co[-1]
                orig, view_vec = region_2d_to_orig_and_view_vector(
                    self.region, self.rv3d, (x, y))
                location = intersect_point_line(lloc, orig, (orig + view_vec))
                vec = (location[0] - lloc)
                ax, ay, az = abs(vec.x), abs(vec.y), abs(vec.z)
                vec.x = ax > ay > az or ax > az > ay
                vec.y = ay > ax > az or ay > az > ax
                vec.z = az > ay > ax or az > ax > ay
                if vec == Vector():
                    self.vector_constrain = None
                else:
                    vc = lloc + vec
                    try:
                        if vc != self.vector_constrain[1]:
                            type = 'X' if vec.x else 'Y' if vec.y else 'C' if vec.y else 'Z' if vec.z else 'shift'  ##cme Y から C に変更
                            self.vector_constrain = [lloc, vc, type]
                    except:
                        type = 'X' if vec.x else 'Y' if vec.y else 'C' if vec.y else 'Z' if vec.z else 'shift'  ##cme Y から C に変更
                        self.vector_constrain = [lloc, vc, type]

        if event.value == 'PRESS':
            if self.list_verts_co and (event.ascii in CharMap.ascii
                                       or event.type in CharMap.type):
                CharMap.modal(self, context, event)

            elif event.type in self.constrain_keys:
                self.bool_update = True
                if self.vector_constrain and self.vector_constrain[
                        2] == event.type:
                    self.vector_constrain = ()

                else:
                    if event.shift:
                        if isinstance(self.geom, bmesh.types.BMEdge):
                            if self.list_verts:
                                loc = self.list_verts_co[-1]
                                self.vector_constrain = (
                                    loc, loc + self.geom.verts[1].co -
                                    self.geom.verts[0].co, event.type)
                            else:
                                self.vector_constrain = [
                                    self.obj_matrix * v.co
                                    for v in self.geom.verts
                                ] + [event.type]
                    else:
                        if self.list_verts:
                            loc = self.list_verts_co[-1]
                        else:
                            loc = self.location
                        self.vector_constrain = [
                            loc, loc + self.constrain_keys[event.type]
                        ] + [event.type]

            elif event.type == 'LEFTMOUSE':
                # SNAP 2D
                snap_3d = self.location
                Lsnap_3d = self.obj_matrix.inverted() * snap_3d
                Snap_2d = location_3d_to_region_2d(self.region, self.rv3d,
                                                   snap_3d)
                if self.vector_constrain and isinstance(
                        self.geom, bmesh.types.BMVert):  # SELECT FIRST
                    bpy.ops.view3d.select(location=(int(Snap_2d[0]),
                                                    int(Snap_2d[1])))
                    try:
                        geom2 = self.bm.select_history[0]
                    except:  # IndexError or AttributeError:
                        geom2 = None
                else:
                    geom2 = self.geom
                self.vector_constrain = None
                self.list_verts_co = draw_line(self, self.obj, self.bm, geom2,
                                               Lsnap_3d)
                bpy.ops.ed.undo_push(message="Undo draw line*")
#
#             elif event.type == 'TAB':
#                 self.keytab = self.keytab == False
#                 if self.keytab:
#                     context.tool_settings.mesh_select_mode = (False, False, True)
#                 else:
#                     context.tool_settings.mesh_select_mode = (True, True, True)

            elif event.type == 'F8':
                self.vector_constrain = None
                self.keyf8 = self.keyf8 == False

        elif event.value == 'RELEASE':
            if event.type in {'NUMPAD_ENTER'}:  ##cme 'RET'を削除して終了にした
                if self.length_entered != "" and self.list_verts_co:
                    try:
                        text_value = bpy.utils.units.to_value(
                            self.unit_system, 'LENGTH', self.length_entered)
                        vector = (self.location -
                                  self.list_verts_co[-1]).normalized()
                        location = (self.list_verts_co[-1] +
                                    (vector * text_value))
                        G_location = self.obj_matrix.inverted() * location
                        self.list_verts_co = draw_line(self, self.obj, self.bm,
                                                       self.geom, G_location)
                        self.length_entered = ""
                        self.vector_constrain = None

                    except:  # ValueError:
                        self.report({'INFO'}, "Operation not supported yet")
##cme 'MIDDLEMOUSE', 'A', 'SPACE', 'RET' を追加
            elif event.type in {
                    'RIGHTMOUSE', 'ESC', 'MIDDLEMOUSE', 'A', 'SPACE', 'RET'
            }:
                #                 if self.list_verts_co == [] or event.type == 'ESC':
                bpy.types.SpaceView3D.draw_handler_remove(
                    self._handle, 'WINDOW')
                context.tool_settings.mesh_select_mode = self.select_mode
                context.area.header_text_set()
                context.user_preferences.view.use_rotate_around_active = self.use_rotate_around_active
                ##cme 無駄なポリゴンを削除
                # bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
                # bpy.ops.mesh.select_non_manifold(extend=False, use_wire=True, use_boundary=False)
                # bpy.ops.mesh.delete(type='EDGE')
                # bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
                # bpy.ops.mesh.select_loose(extend=True)
                # bpy.ops.mesh.delete(type='VERT')

                if not self.is_editmode:
                    bpy.ops.object.editmode_toggle()
                return {'FINISHED'}


#             else:
#                 self.vector_constrain = None
#                 self.list_verts = []
#                 self.list_verts_co = []
#                 self.list_faces = []

        a = "...... Finish = Esc, Return, Space, A "
        if self.list_verts_co:
            if self.length_entered:
                pos = self.line_pos
                a = 'length: ' + self.length_entered[:
                                                     pos] + '|' + self.length_entered[
                                                         pos:]
            else:
                length = self.len
                length = convert_distance(length, self.uinfo)
                a = 'length: ' + length
        context.area.header_text_set(
            "hit: %.3f %.3f %.3f %s" %
            (self.location[0], self.location[1], self.location[2], a))

        self.modal_navigation(context, event)
        return {'RUNNING_MODAL'}
Esempio n. 59
0
import bpy
import bmesh

#Debemos estar en modo objeto, fallara si la escena esta vacia
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

#Creamos un cubo y entramos al modo edicion
bpy.ops.mesh.primitive_cube_add(radius=1, location=(0, 0, 0))
bpy.ops.object.mode_set(mode='EDIT')

#Almacena una referencia al mesh datablock
mesh_datablock = bpy.context.object.data

#Creamos un objetos bmesh llamado bm para usarlo
bm = bmesh.from_edit_mesh(mesh_datablock)

#Imprime el objeto bmesh
print(bm)
Esempio n. 60
0
 def poll(cls, context):
     if context.mode == 'EDIT_MESH':
         bm = bmesh.from_edit_mesh(context.active_object.data)
         return bm.faces
     elif context.mode == 'OBJECT':
         return [obj for obj in context.selected_objects if obj.type == 'MESH' and obj.data.polygons]