Exemplo n.º 1
0
    def execute(self, context):

        if self.use_abso == True:
            extra_helper = (self.abso_major_rad - self.abso_minor_rad) * 0.5
            self.major_radius = self.abso_minor_rad + extra_helper
            self.minor_radius = extra_helper

        verts_loc, faces = add_torus(self.major_radius,
                                    self.minor_radius,
                                    self.major_segments,
                                    self.minor_segments)

        mesh = bpy.data.meshes.new("Torus")

        mesh.vertices.add(len(verts_loc) // 3)
        mesh.faces.add(len(faces) // 4)

        mesh.vertices.foreach_set("co", verts_loc)
        mesh.faces.foreach_set("vertices_raw", faces)
        mesh.update()

        import add_object_utils
        add_object_utils.object_data_add(context, mesh, operator=self)

        return {'FINISHED'}
Exemplo n.º 2
0
def create_mesh_object(context, verts, edges, faces, name, operator=None):

    # Create new mesh
    mesh = bpy.data.meshes.new(name)

    # Make a mesh from a list of verts/edges/faces.
    mesh.from_pydata(verts, edges, faces)

    # Update mesh geometry after adding stuff.
    mesh.update()

    return object_data_add(context, mesh, operator)
Exemplo n.º 3
0
def create_mesh_object(context, verts, edges, faces, name, operator=None):

    # Create new mesh
    mesh = bpy.data.meshes.new(name)

    # Make a mesh from a list of verts/edges/faces.
    mesh.from_pydata(verts, edges, faces)

    # Update mesh geometry after adding stuff.
    mesh.update()

    return object_data_add(context, mesh, operator)
Exemplo n.º 4
0
    def execute(self, context):

        verts_loc, faces = add_box(self.width,
                                     self.height,
                                     self.depth,
                                     )

        mesh = bpy.data.meshes.new("Box")

        mesh.vertices.add(len(verts_loc) // 3)
        mesh.faces.add(len(faces) // 4)

        mesh.vertices.foreach_set("co", verts_loc)
        mesh.faces.foreach_set("vertices_raw", faces)
        mesh.update()

        # add the mesh as an object into the scene with this utility module
        import add_object_utils
        add_object_utils.object_data_add(context, mesh, operator=self)

        return {'FINISHED'}
    def execute(self, context):

        verts_loc, faces = add_box(
            self.width,
            self.height,
            self.depth,
        )

        mesh = bpy.data.meshes.new("Box")

        mesh.vertices.add(len(verts_loc) // 3)
        mesh.faces.add(len(faces) // 4)

        mesh.vertices.foreach_set("co", verts_loc)
        mesh.faces.foreach_set("vertices_raw", faces)
        mesh.update()

        # add the mesh as an object into the scene with this utility module
        import add_object_utils
        add_object_utils.object_data_add(context, mesh, operator=self)

        return {'FINISHED'}
Exemplo n.º 6
0
    def execute(self, context):

        if self.use_abso == True:
            extra_helper = (self.abso_major_rad - self.abso_minor_rad) * 0.5
            self.major_radius = self.abso_minor_rad + extra_helper
            self.minor_radius = extra_helper

        verts_loc, faces = add_torus(self.major_radius, self.minor_radius,
                                     self.major_segments, self.minor_segments)

        mesh = bpy.data.meshes.new("Torus")

        mesh.vertices.add(len(verts_loc) // 3)
        mesh.faces.add(len(faces) // 4)

        mesh.vertices.foreach_set("co", verts_loc)
        mesh.faces.foreach_set("vertices_raw", faces)
        mesh.update()

        import add_object_utils
        add_object_utils.object_data_add(context, mesh, operator=self)

        return {'FINISHED'}
Exemplo n.º 7
0
def create_mesh_object(context, verts, edges, faces, name):
    scene = context.scene
    obj_act = scene.objects.active

    # Create new mesh
    mesh = bpy.data.meshes.new(name)

    # Make a mesh from a list of verts/edges/faces.
    mesh.from_pydata(verts, edges, faces)

    # Update mesh geometry after adding stuff.
    mesh.update()

    import add_object_utils
    return add_object_utils.object_data_add(context, mesh, operator=None)
Exemplo n.º 8
0
def create_mesh_object(context, verts, edges, faces, name):
    scene = context.scene
    obj_act = scene.objects.active

    # Create new mesh
    mesh = bpy.data.meshes.new(name)

    # Make a mesh from a list of verts/edges/faces.
    mesh.from_pydata(verts, edges, faces)

    # Update mesh geometry after adding stuff.
    mesh.update()

    import add_object_utils
    return add_object_utils.object_data_add(context, mesh, operator=None)
Exemplo n.º 9
0
def create_mesh_object(context, verts, edges, faces, name):

    # Create new mesh
    mesh = bpy.data.meshes.new(name)

    # Make a mesh from a list of verts/edges/faces.
    mesh.from_pydata(verts, edges, faces)

    # Remove doubles
    #bpy.ops.mesh.remove_doubles(threshold=0.0001, use_unselected=True)

    # Update mesh geometry after adding stuff.
    mesh.update()

    v = bpy.app.version
    if (v[0] == 2 and v[1] > 57) or (v[0] > 2):
        # Blender 2.58 and 2.63a or future versions...
        from bpy_extras.object_utils import object_data_add
        return object_data_add(context, mesh, operator=None)
    else:
        # Blender 2.57
        import add_object_utils
        return add_object_utils.object_data_add(context, mesh, operator=None)
Exemplo n.º 10
0
def create_mesh_object(context, verts, edges, faces, name):
    
    # Create new mesh
    mesh = bpy.data.meshes.new(name)

    # Make a mesh from a list of verts/edges/faces.
    mesh.from_pydata(verts, edges, faces)

    # Remove doubles
    #bpy.ops.mesh.remove_doubles(threshold=0.0001, use_unselected=True)

    # Update mesh geometry after adding stuff.
    mesh.update()
    
    v = bpy.app.version
    if (v[0] == 2 and v[1] > 57) or (v[0] > 2):
        # Blender 2.58 and 2.63a or future versions...
        from bpy_extras.object_utils import object_data_add
        return object_data_add(context, mesh, operator=None)
    else:
        # Blender 2.57
        import add_object_utils
        return add_object_utils.object_data_add(context, mesh, operator=None)
Exemplo n.º 11
0
    def execute(self, context):
        # only keep image if using it
        if not self.image_based:
            if self.image:
                if self.image.users:
                    self.image.user_clear()
                if self.image.name in bpy.data.images:
                    bpy.data.images.remove(self.image)
                self.image = None
        # Toggle Edit mode
        try:
            is_editmode = (context.active_object.mode == 'EDIT')
        except:
            is_editmode = False
        if is_editmode:
            bpy.ops.object.mode_set(mode='OBJECT')

        verts_u = self.faces_u + 1
        verts_v = self.faces_v + 1
        if self.wrap_u and self.faces_u == 1:
            verts_u += 1
        if self.wrap_v and self.faces_v == 1:
            verts_v += 1
        uvgrid_u = []
        uvgrid_v = []
        uvgrid_s = []
        uvgrid_t = []
        if self.sculpty:
            # get settings from sculpty map size function
            s, t, w, h, clean_s, clean_t = map_size(verts_u - 1, verts_v - 1,
                                                    self.subdivision)
        else:
            # fixed u v spacing
            w = h = 1
            s = verts_u - 1
            t = verts_v - 1
            clean_s = False
            clean_t = False
        verts_u = s + 1
        verts_v = t + 1
        actual_u = verts_u - self.wrap_u
        actual_v = verts_v - self.wrap_v
        clean_s = clean_s & self.sculpty_clean
        clean_t = clean_t & self.sculpty_clean
        level_mask = 0xFFFE
        for i in range(self.subdivision):
            level_mask = level_mask << 1
        # uvgrid_s and uvgrid_t will hold uv layout positions
        for i in range(s):
            p = w * i / float(s)
            if clean_s:
                p = int(p) & level_mask
            if p:
                p = p / float(w)
            uvgrid_s.append(p)
        uvgrid_s.append(1.0)
        for i in range(t):
            p = h * i / float(t)
            if clean_t:
                p = int(p) & level_mask
            if p:
                p = p / float(h)
            uvgrid_t.append(p)
        uvgrid_t.append(1.0)

        # build list of 3D locations for vertices
        verts = []
        for self.v in range(actual_v):
            for self.u in range(actual_u):
                vec_u = self.u / (verts_u - 1)
                if self.wrap_u:
                    vec_u += self.rotate_u / 360.0
                vec_v = self.v / (verts_v - 1)
                if self.wrap_v:
                    vec_v += self.rotate_v / 360.0
                verts.append(self.get_vector(vec_u, vec_v))

        # build list of faces
        faces = []
        first_row = range(actual_u)
        for v in range(1, actual_v):
            second_row = [idx + actual_u for idx in first_row]
            faces.extend(createFaces(first_row, second_row, self.wrap_u))
            first_row = second_row
        if self.wrap_v:
            faces.extend(createFaces(second_row, range(actual_u), self.wrap_u))

        # build list of seams - these should be all edges with
        # u=0 and/or with v=0 depending on wrap settings
        seams = []
        if self.wrap_u:
            first_vertex = 0
            for i in range(actual_v - 1):
                second_vertex = first_vertex + actual_u
                seams.append((first_vertex, second_vertex))
                first_vertex = second_vertex
            if self.wrap_v:
                seams.append((0, first_vertex))
        if self.wrap_v:
            first_vertex = 0
            for i in range(actual_u - 1):
                second_vertex = first_vertex + 1
                seams.append((first_vertex, second_vertex))
                first_vertex = second_vertex
            if self.wrap_u:
                seams.append((0, first_vertex))

        create_mesh_object(context, verts, [], faces, self.obj_name, self)
        obj = context.active_object
        # end up in edit mode here if set in preferences, so set back.
        bpy.ops.object.mode_set(mode='OBJECT')
        markSeams(obj.data, seams)

        # build list of uv faces
        uvfaces = []
        first_row = [(uvgrid_s[u], 0.0) for u in range(verts_u)]
        for v in range(1, verts_v):
            second_row = [(uvgrid_s[u], uvgrid_t[v]) for u in range(verts_u)]
            faces = createFaces(first_row, second_row, False)
            if self.wrap_u:
                # match face order of wrapped mesh
                faces = [faces[-1]] + faces[:-1]
                # correct vert order for wrapped face
                fix = faces[0]
                faces[0] = (fix[2], fix[3], fix[0], fix[1])
            uvfaces.extend(faces)
            first_row = second_row

        # create UVTex layout
        uvtex = obj.data.uv_textures.new()
        for face_idx in range(len(uvfaces)):
            uvtex.data[face_idx].uv1 = uvfaces[face_idx][0]
            uvtex.data[face_idx].uv2 = uvfaces[face_idx][1]
            uvtex.data[face_idx].uv3 = uvfaces[face_idx][2]
            uvtex.data[face_idx].uv4 = uvfaces[face_idx][3]

        if self.sculpty:
            if self.uvtex:
                s_map = obj.data.uv_textures.new(name="sculptie")
            else:
                s_map = uvtex
                s_map.name = "sculptie"
            if self.image == None:
                if not config.minimise_map:
                    levels = self.subdivision
                    while w * h <= 1024:
                        levels += 1
                        s, t, w, h, cs, ct = map_size(uc, vc, levels)
                self.image = bpy.data.images.new(name=self.obj_name,
                                                 width=w,
                                                 height=h,
                                                 alpha=True)
            for f in s_map.data:
                f.image = self.image
                f.use_image = True
            obj.prim.type = 'PRIM_TYPE_SCULPT'
            obj.prim.sculpt_type = self.sculpt_type

        if self.subdivision:
            bpy.ops.object.modifier_add(type=self.subdivision_mod)
            if self.subdivision_mod == 'MULTIRES':
                m = obj.modifiers['Multires']
                m.subdivision_type = self.subdivision_type
                if self.sculpty:
                    uv_layer = 'sculptie'
                else:
                    uv_layer = 'UVTex'
                for i in range(self.subdivision):
                    bpy.ops.object.multires_subdivide(modifier="Multires")
                hires = obj.to_mesh(context.scene, True, 'RENDER')
                for v, uv in vertex_uvs(hires, uv_layer):
                    vec_u = uv[0]
                    if self.wrap_u:
                        vec_u += self.rotate_u / 360.0
                    vec_v = uv[1]
                    if self.wrap_v:
                        vec_v += self.rotate_v / 360.0
                    v.co = self.get_vector(vec_u, vec_v)
                object_data_add(context, hires, self)
                obj2 = context.active_object
                context.scene.objects.active = obj
                bpy.ops.object.multires_reshape(modifier="Multires")
                context.scene.objects.unlink(obj2)
                bpy.data.objects.remove(obj2)
                bpy.data.meshes.remove(hires)
                bpy.ops.object.multires_base_apply(modifier="Multires")
            else:
                m = obj.modifiers['Subsurf']
                m.subdivision_type = self.subdivision_type
                m.levels = self.subdivision
                m.render_levels = self.subdivision
                m.use_subsurf_uv = False
                m.show_on_cage = True

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

        # blender bug: inside not working when set to self.flip_normals
        bpy.ops.mesh.normals_make_consistent(inside=False)
        if self.flip_normals:
            bpy.ops.mesh.flip_normals()
            # arrgh.. still not flipping cone normals correctly..
            # works if done manually.. test again when bug fixed..
        if self.smooth:
            bpy.ops.mesh.faces_shade_smooth()

        if not (is_editmode or \
            context.user_preferences.edit.use_enter_edit_mode):
            bpy.ops.object.mode_set(mode='OBJECT')

        return {'FINISHED'}
Exemplo n.º 12
0
    def execute(self, context):
        # only keep image if using it
        if not self.image_based:
            if self.image:
                if self.image.users:
                    self.image.user_clear()
                if self.image.name in bpy.data.images:
                    bpy.data.images.remove(self.image)
                self.image = None
        # Toggle Edit mode
        try:
            is_editmode = (context.active_object.mode == 'EDIT')
        except:
            is_editmode = False
        if is_editmode:
            bpy.ops.object.mode_set(mode='OBJECT')

        verts_u = self.faces_u + 1
        verts_v = self.faces_v + 1
        if self.wrap_u and self.faces_u == 1:
            verts_u += 1
        if self.wrap_v and self.faces_v == 1:
            verts_v += 1
        uvgrid_u = []
        uvgrid_v = []
        uvgrid_s = []
        uvgrid_t = []
        if self.sculpty:
            # get settings from sculpty map size function
            s, t, w, h, clean_s, clean_t = map_size(
                verts_u - 1, verts_v - 1, self.subdivision)
        else:
            # fixed u v spacing
            w = h = 1
            s = verts_u - 1
            t = verts_v - 1
            clean_s = False
            clean_t = False
        verts_u = s + 1
        verts_v = t + 1
        actual_u = verts_u - self.wrap_u
        actual_v = verts_v - self.wrap_v
        clean_s = clean_s & self.sculpty_clean
        clean_t = clean_t & self.sculpty_clean
        level_mask = 0xFFFE
        for i in range(self.subdivision):
            level_mask = level_mask << 1
        # uvgrid_s and uvgrid_t will hold uv layout positions
        for i in range(s):
            p = w * i / float(s)
            if clean_s:
                p = int(p) & level_mask
            if p:
                p = p / float(w)
            uvgrid_s.append(p)
        uvgrid_s.append(1.0)
        for i in range(t):
            p = h * i / float(t)
            if clean_t:
                p = int(p) & level_mask
            if p:
                p = p / float(h)
            uvgrid_t.append(p)
        uvgrid_t.append(1.0)

        # build list of 3D locations for vertices
        verts = []
        for self.v in range(actual_v):
            for self.u in range(actual_u):
                vec_u = self.u / (verts_u - 1)
                if self.wrap_u:
                    vec_u += self.rotate_u / 360.0
                vec_v = self.v / (verts_v - 1)
                if self.wrap_v:
                    vec_v += self.rotate_v / 360.0
                verts.append(self.get_vector(vec_u, vec_v))

        # build list of faces
        faces = []
        first_row = range(actual_u)
        for v in range(1, actual_v):
            second_row = [idx + actual_u for idx in first_row]
            faces.extend(createFaces(first_row, second_row, self.wrap_u))
            first_row = second_row
        if self.wrap_v:
            faces.extend(createFaces(second_row, range(actual_u), self.wrap_u))

        # build list of seams - these should be all edges with
        # u=0 and/or with v=0 depending on wrap settings
        seams = []
        if self.wrap_u:
            first_vertex = 0
            for i in range(actual_v - 1):
                second_vertex = first_vertex + actual_u
                seams.append((first_vertex, second_vertex))
                first_vertex = second_vertex
            if self.wrap_v:
                seams.append((0, first_vertex))
        if self.wrap_v:
            first_vertex = 0
            for i in range(actual_u - 1):
                second_vertex = first_vertex + 1
                seams.append((first_vertex, second_vertex))
                first_vertex = second_vertex
            if self.wrap_u:
                seams.append((0, first_vertex))

        create_mesh_object(context, verts, [], faces, self.obj_name, self)
        obj = context.active_object
        # end up in edit mode here if set in preferences, so set back.
        bpy.ops.object.mode_set(mode='OBJECT')
        markSeams(obj.data, seams)

        # build list of uv faces
        uvfaces = []
        first_row = [(uvgrid_s[u], 0.0) for u in range(verts_u)]
        for v in range(1, verts_v):
            second_row = [(uvgrid_s[u], uvgrid_t[v]) for u in range(verts_u)]
            faces = createFaces(first_row, second_row, False)
            if self.wrap_u:
                # match face order of wrapped mesh
                faces = [faces[-1]] + faces[:-1]
                # correct vert order for wrapped face
                fix = faces[0]
                faces[0] = (fix[2], fix[3], fix[0], fix[1])
            uvfaces.extend(faces)
            first_row = second_row

        # create UVTex layout
        uvtex = obj.data.uv_textures.new()
        for face_idx in range(len(uvfaces)):
            uvtex.data[face_idx].uv1 = uvfaces[face_idx][0]
            uvtex.data[face_idx].uv2 = uvfaces[face_idx][1]
            uvtex.data[face_idx].uv3 = uvfaces[face_idx][2]
            uvtex.data[face_idx].uv4 = uvfaces[face_idx][3]

        if self.sculpty:
            if self.uvtex:
                s_map = obj.data.uv_textures.new(name="sculptie")
            else:
                s_map = uvtex
                s_map.name = "sculptie"
            if self.image == None:
                if not config.minimise_map:
                    levels = self.subdivision
                    while w * h <= 1024:
                        levels += 1
                        s, t, w, h, cs, ct = map_size(uc, vc, levels)
                self.image = bpy.data.images.new(name=self.obj_name,
                    width=w,
                    height=h,
                    alpha=True)
            for f in s_map.data:
                f.image = self.image
                f.image!=None
            obj.prim.type = 'PRIM_TYPE_SCULPT'
            obj.prim.sculpt_type = self.sculpt_type

        if self.subdivision:
            bpy.ops.object.modifier_add(type=self.subdivision_mod)
            if self.subdivision_mod == 'MULTIRES':
                m = obj.modifiers['Multires']
                m.subdivision_type = self.subdivision_type
                if  self.sculpty:
                    uv_layer = 'sculptie'
                else:
                    uv_layer = 'UVTex'
                for i in range(self.subdivision):
                    bpy.ops.object.multires_subdivide(modifier="Multires")
                hires = obj.to_mesh(context.scene, True, 'RENDER')
                for v, uv in vertex_uvs(hires, uv_layer):
                    vec_u = uv[0]
                    if self.wrap_u:
                        vec_u += self.rotate_u / 360.0
                    vec_v = uv[1]
                    if self.wrap_v:
                        vec_v += self.rotate_v / 360.0
                    v.co = self.get_vector(vec_u, vec_v)
                object_data_add(context, hires, self)
                obj2 = context.active_object
                context.scene.objects.active = obj
                bpy.ops.object.multires_reshape(modifier="Multires")
                context.scene.objects.unlink(obj2)
                bpy.data.objects.remove(obj2)
                bpy.data.meshes.remove(hires)
                bpy.ops.object.multires_base_apply(modifier="Multires")
            else:
                m = obj.modifiers['Subsurf']
                m.subdivision_type = self.subdivision_type
                m.levels = self.subdivision
                m.render_levels = self.subdivision
                m.use_subsurf_uv = False
                m.show_on_cage = True

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

        # blender bug: inside not working when set to self.flip_normals
        bpy.ops.mesh.normals_make_consistent(inside=False)
        if self.flip_normals:
            bpy.ops.mesh.flip_normals()
            # arrgh.. still not flipping cone normals correctly..
            # works if done manually.. test again when bug fixed..
        if self.smooth:
            bpy.ops.mesh.faces_shade_smooth()

        if not (is_editmode or \
            context.user_preferences.edit.use_enter_edit_mode):
            bpy.ops.object.mode_set(mode='OBJECT')

        return {'FINISHED'}
Exemplo n.º 13
0
def Cells(object, cell, solid = False):
    print("L130 ===Cells called=== object is =",object.name," cell is", cell.name)    
    t0 = time()
    
    es = [Vector((1.0, 0.0, 0.0)),
            Vector((0.0, 1.0, 0.0)),
            Vector((0.0, 0.0, 1.0))]

    # transform object/mesh (to get cell-alignment right)
    ######################################################
    
    cm  = cell.matrix_local.copy()
    cmi = cm.inverted() # is different matrix!

    om = object.matrix_local.copy()
    omi = om.inverted()
    
    tm  = om * cmi
    tmi = cm * omi
    
    mesh = object.data
        
    # transform mesh to align with cell
    mesh.transform(tm)
    
    # calculate cell dimensions
    ########################### boundingbox is a box with (0 1 2 3)(4 5 6 7)
    # 0 and 6 are diagonal 1 7, 2 4, 3 5 too 
        
    cell_gbb_min = cell.bound_box[0]
#for debug pkhg    print("L153 cellinfo =",type(cell_gbb_min),cell_gbb_min)
    cell_lbb_min = Vector(cell_gbb_min).to_4d() * cmi
    cell_lbb_max = cell.bound_box[6]
    cell_lbb_max = Vector(cell_lbb_max).to_4d() * cmi


    cell_dimensions = cell_lbb_max - cell_lbb_min
    cell_dimension_x,cell_dimension_y,cell_dimension_z = cell_dimensions[0:3]

    # bin vertices
    ##############
    # everything in object's local coordinates (aligned with cell)
    
    v_cells = {}        
        
    for vert in mesh.vertices:
        coords = vert.co
        v_cells[vert.index] = (int(round(coords[0] / cell_dimension_x)),
                              int(round(coords[1] / cell_dimension_y)),
                              int(round(coords[2] / cell_dimension_z)))
#dbg pkhg        print("L161 v_CELLS",v_cells)
    # bin faces
    ###########
    # everything in object's local coordinates (aligned with cell)
    
    f_cells = {}
        
    for face in mesh.faces:
        
        verts = face.vertices
#dbg pkhg        print("L190 verts",verts[:])
        fidxs = [v_cells[vert][0] for vert in verts] 
#dbg pkhg        print("l192 fidxs ",fidxs,min(fidxs))
        fidxs.sort()          
        min_fidx = fidxs[0]
        max_fidx = fidxs[-1]           
        fidys = [v_cells[vert][1] for vert in verts]
        fidys.sort()
        min_fidy = fidys[0]
        max_fidy = fidys[-1]
        fidzs = [v_cells[vert][2] for vert in verts]
        fidzs.sort()
        min_fidz = fidzs[0]
        max_fidz = fidzs[-1]
                
        # fast path for special cases (especially small faces spanning a single cell only)

        category = 0
        if (max_fidx > min_fidx): 
            category |= 1
        if (max_fidy > min_fidy): 
            category |= 2
        if (max_fidz > min_fidz): 
            category |= 4
        
        if category == 0: # single cell
            f_cells.setdefault((min_fidx, min_fidy, min_fidz), set()).add(face)
            continue
        
        if category == 1: # multiple cells in x-, single cell in y- and z-direction
            for fidx in range(min_fidx, max_fidx + 1):
                f_cells.setdefault((fidx, min_fidy, min_fidz), set()).add(face)
            continue
        
        if category == 2: # multiple cells in y-, single cell in x- and z-direction
            for fidy in range(min_fidy, max_fidy + 1):
                f_cells.setdefault((min_fidx, fidy, min_fidz), set()).add(face)
            continue

        if category == 4: # multiple cells in z-, single cell in x- and y-direction
            for fidz in range(min_fidz, max_fidz + 1):
                f_cells.setdefault((min_fidx, min_fidy, fidz), set()).add(face)
            continue
                        
        # long path (face spans multiple cells in more than one direction)
########### pkhg ???? I think I have not checked this??? possible? ##########
        a0 = face.normal

        r0 =  0.5 * (fabs(a0[0]) * cell_dimension_x +
                         fabs(a0[1]) * cell_dimension_y +
                         fabs(a0[2]) * cell_dimension_z)
                                            
#xrange -> range?!          
        cc = Vector((0.0, 0.0, 0.0))          
        for fidx in range(min_fidx, max_fidx + 1):
            cc[0] = fidx * cell_dimensions[0]
            for fidy in range(min_fidy, max_fidy + 1):
                cc[1] = fidy * cell_dimensions[1]
                for fidz in range(min_fidz, max_fidz + 1):
                    cc[2] = fidz * cell_dimensions[2]
                        
                    if not solid and (fidx, fidy, fidz) in f_cells: 
                        continue 
                        # cell already populated -> no further processing needed for hollow model
                    vertsNew = [mesh.vertices[el] for el in verts] 
#dbg pkhg                    print("L261-----------\n verts vertsNew",verts[:], vertsNew[:])   
                    vs = [vert.co - cc for vert in vertsNew]
                                                            
                    if not (-r0 <= a0 * vs[0] <= r0): continue # cell not intersecting face hyperplane

                    # check overlap of cell with face (separating axis theorem)
                                                
                    fs = [vs[1] - vs[0],
                            vs[2] - vs[1],
                            vs[0] - vs[2]]
                                                
                    overlap = True

                    for f in fs:
                        if not overlap: 
                            break

                        for e in es:
                            if not overlap: 
                                break
                            
#                            a = CrossVecs(e, f)
                            a = e.cross(f)
                            
                            r = 0.5 * (fabs(a[0]) * cell_dimension_x +
                                          fabs(a[1]) * cell_dimension_y +
                                          fabs(a[2]) * cell_dimension_z)                        

                            ds = [a * v for v in vs] 
                            ds.sort()
                                                            
                            if (ds[0] > r or ds[-1] < -r): 
                                overlap = False
                                                    
                    if overlap:
                        f_cells.setdefault((fidx, fidy, fidz), set()).add(face)
    
    # the hollow voxel representation is complete
#dbg pkhg    print("L301 f_cells = ",f_cells)
#dbg    for i,el in enumerate(f_cells.keys()):
#dbg       tmp = [t.index  for t in f_cells[el]]
#dbg       print("L298",tmp)
      
    # fill
    ######

    if solid:
        
        # find min, max cells in x, y, z
##### ERROR f_cell may contain only two elments!???? for open?        
        idxs = [id[0] for id in f_cells]
        min_idx = min(idxs)
        max_idx = max(idxs)
        idys = [id[1] for id in f_cells]
        min_idy = min(idys)
        max_idy = max(idys)
        idzs = [id[2] for id in f_cells]
        min_idz = min(idzs)
        max_idz = max(idzs)

        testpoint = Vector((0.0, 0.0, 0.0))
        
        # for x,y
        
        for idx in range(min_idx, max_idx + 1):
            testpoint[0] = idx * cell_dimension_x   
            for idy in range(min_idy, max_idy + 1):
                testpoint[1] = idy * cell_dimension_y

                odd_parity = False

                tested_faces = set()

                # walk the z pile and keep track of parity
                
                for idz in range(min_idz, max_idz + 1):
                
                    fs = f_cells.get((idx, idy, idz), set()) - tested_faces
                    
                    # cell contains faces                    
                    if fs:
                        # categorize faces in this cell by normal    
                        pfaces = []
                        nfaces = []
                        
                        for f in fs:
                            fnoz = f.normal[2] #was no pkhg
                            if fnoz >= 0.0:
                                pfaces.append(f)
                            if fnoz <= 0.0:
                                nfaces.append(f)                        
                            tested_faces.add(f)
                        
                        # check if testpoint inside z projections
                                                        
                        if pfaces:
#,mesh added in InsideZProjection pkhg
                            if InsideZProjection(testpoint, pfaces,mesh): 
                                odd_parity = not odd_parity
                                
                        if nfaces:
                            if InsideZProjection(testpoint, nfaces,mesh): 
                                odd_parity = not odd_parity

                    # cell contains no faces (empty cell)
                    
                    else:
                        if odd_parity:  
                            f_cells[(idx, idy, idz)] = 1 # odd parity -> empty cell inside object
                                
    # create new object
    ###################
            
    mesh_new = bpy.data.meshes.new("Cells("+object.name+")")
    vertexList = [[(id[0] * cell_dimension_x,id[1] * cell_dimension_y,
       id[2] * cell_dimension_z)] for id in f_cells]
#### debug ??? #####
#    print("L386===============================\n f_cells=",f_cells)
#    print("L369 =========\n vertexList =",vertexList)
#    for el in vertexList:print(el)
#    scene = Scene.GetCurrent()
    scene = bpy.context.scene                
    mesh_new = bpy.data.meshes.new("Cells("+object.name+")")
#####startpkhg added
    edges = []
    faces = []
    verts = []
    for el in vertexList:
        verts.extend(el)
    mesh_new.from_pydata(verts, edges, faces)

    # Update mesh geometry after adding stuff.
    mesh_new.update()
    import add_object_utils
    add_object_utils.object_data_add(bpy.context, mesh_new, operator=None)
    object_new = bpy.context.active_object
#dbg pkhg    print("\n---------L409 object_new",object_new,object_new.name)

########end pkhg added
    object_new.layers = object.layers
    object_new.name = "Cells("+object.name+")"

    # transform objects/meshes back
    ###############################

    object_new.matrix_local = om
    mesh.transform(tmi)
    mesh_new.transform(tmi)

    # parent new object to cell for dupliverts
    ###########################################
    

    cell.location  = object.location

    cell.layers = object_new.layers
    scene.update()   
#???    object.select = True   
#    object_new.select = False
#    cell.select = False
    #??? bpy.ops.object.editmode_toggle()
    #co oc  no 
#    cell.select = True
#    object_new.select = True

#    bpy.ops.object.editmode_toggle()
#    bpy.ops.object.editmode_toggle()

#    bpy.context.scene.objects.active = cell
#    bpy.ops.object.select_all(action='TOGGLE')
#    cell.select = True
#    object_new.select = True
    
    #bpy.ops.object.parent_set(type='OBJECT')
#    object_new.makeParent([cell])
    object_new.dupli_type = "VERTS"
    
    # select
    ########
    
    object.select = False
    cell.select= False
#    object_new.select= True
        
    # done
    ######
    
    t1 = time()
    
    print(str(len(mesh.faces))+" faces ... "+str(len(f_cells))+" cells: "+str(round(t1-t0, 3))+" s")

    bpy.context.scene.update()
    return object_new 
Exemplo n.º 14
0
def Cells(object, cell, solid=False):
    print("L130 ===Cells called=== object is =", object.name, " cell is",
          cell.name)
    t0 = time()

    es = [
        Vector((1.0, 0.0, 0.0)),
        Vector((0.0, 1.0, 0.0)),
        Vector((0.0, 0.0, 1.0))
    ]

    # transform object/mesh (to get cell-alignment right)
    ######################################################

    cm = cell.matrix_local.copy()
    cmi = cm.inverted()  # is different matrix!

    om = object.matrix_local.copy()
    omi = om.inverted()

    tm = om * cmi
    tmi = cm * omi

    mesh = object.data

    # transform mesh to align with cell
    mesh.transform(tm)

    # calculate cell dimensions
    ########################### boundingbox is a box with (0 1 2 3)(4 5 6 7)
    # 0 and 6 are diagonal 1 7, 2 4, 3 5 too

    cell_gbb_min = cell.bound_box[0]
    #for debug pkhg    print("L153 cellinfo =",type(cell_gbb_min),cell_gbb_min)
    cell_lbb_min = Vector(cell_gbb_min).to_4d() * cmi
    cell_lbb_max = cell.bound_box[6]
    cell_lbb_max = Vector(cell_lbb_max).to_4d() * cmi

    cell_dimensions = cell_lbb_max - cell_lbb_min
    cell_dimension_x, cell_dimension_y, cell_dimension_z = cell_dimensions[0:3]

    # bin vertices
    ##############
    # everything in object's local coordinates (aligned with cell)

    v_cells = {}

    for vert in mesh.vertices:
        coords = vert.co
        v_cells[vert.index] = (int(round(coords[0] / cell_dimension_x)),
                               int(round(coords[1] / cell_dimension_y)),
                               int(round(coords[2] / cell_dimension_z)))
#dbg pkhg        print("L161 v_CELLS",v_cells)
# bin faces
###########
# everything in object's local coordinates (aligned with cell)

    f_cells = {}

    for face in mesh.faces:

        verts = face.vertices
        #dbg pkhg        print("L190 verts",verts[:])
        fidxs = [v_cells[vert][0] for vert in verts]
        #dbg pkhg        print("l192 fidxs ",fidxs,min(fidxs))
        fidxs.sort()
        min_fidx = fidxs[0]
        max_fidx = fidxs[-1]
        fidys = [v_cells[vert][1] for vert in verts]
        fidys.sort()
        min_fidy = fidys[0]
        max_fidy = fidys[-1]
        fidzs = [v_cells[vert][2] for vert in verts]
        fidzs.sort()
        min_fidz = fidzs[0]
        max_fidz = fidzs[-1]

        # fast path for special cases (especially small faces spanning a single cell only)

        category = 0
        if (max_fidx > min_fidx):
            category |= 1
        if (max_fidy > min_fidy):
            category |= 2
        if (max_fidz > min_fidz):
            category |= 4

        if category == 0:  # single cell
            f_cells.setdefault((min_fidx, min_fidy, min_fidz), set()).add(face)
            continue

        if category == 1:  # multiple cells in x-, single cell in y- and z-direction
            for fidx in range(min_fidx, max_fidx + 1):
                f_cells.setdefault((fidx, min_fidy, min_fidz), set()).add(face)
            continue

        if category == 2:  # multiple cells in y-, single cell in x- and z-direction
            for fidy in range(min_fidy, max_fidy + 1):
                f_cells.setdefault((min_fidx, fidy, min_fidz), set()).add(face)
            continue

        if category == 4:  # multiple cells in z-, single cell in x- and y-direction
            for fidz in range(min_fidz, max_fidz + 1):
                f_cells.setdefault((min_fidx, min_fidy, fidz), set()).add(face)
            continue

        # long path (face spans multiple cells in more than one direction)
########### pkhg ???? I think I have not checked this??? possible? ##########
        a0 = face.normal

        r0 = 0.5 * (fabs(a0[0]) * cell_dimension_x + fabs(a0[1]) *
                    cell_dimension_y + fabs(a0[2]) * cell_dimension_z)

        #xrange -> range?!
        cc = Vector((0.0, 0.0, 0.0))
        for fidx in range(min_fidx, max_fidx + 1):
            cc[0] = fidx * cell_dimensions[0]
            for fidy in range(min_fidy, max_fidy + 1):
                cc[1] = fidy * cell_dimensions[1]
                for fidz in range(min_fidz, max_fidz + 1):
                    cc[2] = fidz * cell_dimensions[2]

                    if not solid and (fidx, fidy, fidz) in f_cells:
                        continue
                        # cell already populated -> no further processing needed for hollow model
                    vertsNew = [mesh.vertices[el] for el in verts]
                    #dbg pkhg                    print("L261-----------\n verts vertsNew",verts[:], vertsNew[:])
                    vs = [vert.co - cc for vert in vertsNew]

                    if not (-r0 <= a0 * vs[0] <= r0):
                        continue  # cell not intersecting face hyperplane

                    # check overlap of cell with face (separating axis theorem)

                    fs = [vs[1] - vs[0], vs[2] - vs[1], vs[0] - vs[2]]

                    overlap = True

                    for f in fs:
                        if not overlap:
                            break

                        for e in es:
                            if not overlap:
                                break

#                            a = CrossVecs(e, f)
                            a = e.cross(f)

                            r = 0.5 * (fabs(a[0]) * cell_dimension_x +
                                       fabs(a[1]) * cell_dimension_y +
                                       fabs(a[2]) * cell_dimension_z)

                            ds = [a * v for v in vs]
                            ds.sort()

                            if (ds[0] > r or ds[-1] < -r):
                                overlap = False

                    if overlap:
                        f_cells.setdefault((fidx, fidy, fidz), set()).add(face)

    # the hollow voxel representation is complete
#dbg pkhg    print("L301 f_cells = ",f_cells)
#dbg    for i,el in enumerate(f_cells.keys()):
#dbg       tmp = [t.index  for t in f_cells[el]]
#dbg       print("L298",tmp)

# fill
######

    if solid:

        # find min, max cells in x, y, z
        ##### ERROR f_cell may contain only two elments!???? for open?
        idxs = [id[0] for id in f_cells]
        min_idx = min(idxs)
        max_idx = max(idxs)
        idys = [id[1] for id in f_cells]
        min_idy = min(idys)
        max_idy = max(idys)
        idzs = [id[2] for id in f_cells]
        min_idz = min(idzs)
        max_idz = max(idzs)

        testpoint = Vector((0.0, 0.0, 0.0))

        # for x,y

        for idx in range(min_idx, max_idx + 1):
            testpoint[0] = idx * cell_dimension_x
            for idy in range(min_idy, max_idy + 1):
                testpoint[1] = idy * cell_dimension_y

                odd_parity = False

                tested_faces = set()

                # walk the z pile and keep track of parity

                for idz in range(min_idz, max_idz + 1):

                    fs = f_cells.get((idx, idy, idz), set()) - tested_faces

                    # cell contains faces
                    if fs:
                        # categorize faces in this cell by normal
                        pfaces = []
                        nfaces = []

                        for f in fs:
                            fnoz = f.normal[2]  #was no pkhg
                            if fnoz >= 0.0:
                                pfaces.append(f)
                            if fnoz <= 0.0:
                                nfaces.append(f)
                            tested_faces.add(f)

                        # check if testpoint inside z projections

                        if pfaces:
                            #,mesh added in InsideZProjection pkhg
                            if InsideZProjection(testpoint, pfaces, mesh):
                                odd_parity = not odd_parity

                        if nfaces:
                            if InsideZProjection(testpoint, nfaces, mesh):
                                odd_parity = not odd_parity

                    # cell contains no faces (empty cell)

                    else:
                        if odd_parity:
                            f_cells[(
                                idx, idy, idz
                            )] = 1  # odd parity -> empty cell inside object

    # create new object
    ###################

    mesh_new = bpy.data.meshes.new("Cells(" + object.name + ")")
    vertexList = [[(id[0] * cell_dimension_x, id[1] * cell_dimension_y,
                    id[2] * cell_dimension_z)] for id in f_cells]
    #### debug ??? #####
    #    print("L386===============================\n f_cells=",f_cells)
    #    print("L369 =========\n vertexList =",vertexList)
    #    for el in vertexList:print(el)
    #    scene = Scene.GetCurrent()
    scene = bpy.context.scene
    mesh_new = bpy.data.meshes.new("Cells(" + object.name + ")")
    #####startpkhg added
    edges = []
    faces = []
    verts = []
    for el in vertexList:
        verts.extend(el)
    mesh_new.from_pydata(verts, edges, faces)

    # Update mesh geometry after adding stuff.
    mesh_new.update()
    import add_object_utils
    add_object_utils.object_data_add(bpy.context, mesh_new, operator=None)
    object_new = bpy.context.active_object
    #dbg pkhg    print("\n---------L409 object_new",object_new,object_new.name)

    ########end pkhg added
    object_new.layers = object.layers
    object_new.name = "Cells(" + object.name + ")"

    # transform objects/meshes back
    ###############################

    object_new.matrix_local = om
    mesh.transform(tmi)
    mesh_new.transform(tmi)

    # parent new object to cell for dupliverts
    ###########################################

    cell.location = object.location

    cell.layers = object_new.layers
    scene.update()
    #???    object.select = True
    #    object_new.select = False
    #    cell.select = False
    #??? bpy.ops.object.editmode_toggle()
    #co oc  no
    #    cell.select = True
    #    object_new.select = True

    #    bpy.ops.object.editmode_toggle()
    #    bpy.ops.object.editmode_toggle()

    #    bpy.context.scene.objects.active = cell
    #    bpy.ops.object.select_all(action='TOGGLE')
    #    cell.select = True
    #    object_new.select = True

    #bpy.ops.object.parent_set(type='OBJECT')
    #    object_new.makeParent([cell])
    object_new.dupli_type = "VERTS"

    # select
    ########

    object.select = False
    cell.select = False
    #    object_new.select= True

    # done
    ######

    t1 = time()

    print(
        str(len(mesh.faces)) + " faces ... " + str(len(f_cells)) + " cells: " +
        str(round(t1 - t0, 3)) + " s")

    bpy.context.scene.update()
    return object_new