示例#1
0
 def blenderstructure(self, ):
     for i in range(len(self.xyz.atomtypes)):
         me = Mesh.Primitives.Icosphere(spheresubdivisions,
                                        atomicradii[self.xyz.atomtypes[i]])
         me.materials = [materials[self.xyz.atomtypes[i]]]
         for face in me.faces:
             face.smooth = True
         obj = self.scene.objects.new(me, 'Mesh')
         obj.setLocation(self.xyz.coord[i][0], self.xyz.coord[i][1],
                         self.xyz.coord[i][2])
     for i in range(len(self.xyz.atomtypes)):
         for j in range(i + 1, len(self.xyz.atomtypes)):
             vec1 = Mathutils.Vector(self.xyz.coord[i])
             vec2 = Mathutils.Vector(self.xyz.coord[j])
             vec = vec2 - vec1
             distcovalent = covalentradii[self.xyz.atomtypes[
                 i]] + covalentradii[self.xyz.atomtypes[j]]
             if (vec.length - distcovalent) <= 0.10 * distcovalent:
                 me = Mesh.Primitives.Tube(32, stickradius, vec.length)
                 for face in me.faces:
                     face.smooth = True
                 obj = self.scene.objects.new(me, 'Cylinder')
                 axis = Mathutils.CrossVecs(Vector([0, 0, 1]), vec)
                 angle = Mathutils.AngleBetweenVecs(Vector([0, 0, 1]), vec)
                 rotmat = Mathutils.RotationMatrix(angle, 4, "R", axis)
                 obj.setMatrix(obj.matrix * rotmat)
                 obj.setLocation((vec1 + vec2) * 0.5)
示例#2
0
def terrain_clamp(event, value):

    sce = bpy.data.scenes.active
    if GLOBALS['GROUND_SOURCE'][0].val:
        obs_terrain = [sce.objects.active]
        if not obs_terrain[0]:
            error_noact()
            return
    else:
        try:
            obs_terrain = bpy.data.groups[
                GLOBALS['GROUND_GROUP_NAME'].val].objects
        except:
            error_nogroup()
            return

    obs_clamp = [
        ob for ob in sce.objects.context
        if ob not in obs_terrain and not ob.lib
    ]
    if not obs_clamp:
        error_no_obs()
        return

    terrain_tris = collect_terrain_triangles(obs_terrain)
    if not terrain_tris:
        error_noground()
        return

    if GLOBALS['DROP_AXIS'][0].val:
        axis = Vector(0, 0, -1)
    else:
        axis = Vector(Window.GetViewVector())

    do_orient = GLOBALS['DROP_ORIENT'].val
    do_orient_val = GLOBALS['DROP_ORIENT_VALUE'].val / 100.0
    if not do_orient_val: do_orient = False

    for ob in obs_clamp:
        loc, no = calc_drop_loc(ob, terrain_tris, axis)
        if loc:
            if do_orient:
                try:
                    ang = AngleBetweenVecs(no, axis)
                except:
                    ang = 0.0
                if ang > 90.0:
                    no = -no
                    ang = 180.0 - ang

                if ang > 0.0001:
                    ob_matrix = ob.matrixWorld * RotationMatrix(
                        ang * do_orient_val, 4, 'r', axis.cross(no))
                    ob.setMatrix(ob_matrix)

            ob.loc = loc

    # to make the while loop exist
    GLOBALS['EVENT'] = EVENT_EXIT
示例#3
0
def terrain_clamp(event, value):

    sce = bpy.data.scenes.active
    if GLOBALS["GROUND_SOURCE"][0].val:
        obs_terrain = [sce.objects.active]
        if not obs_terrain[0]:
            error_noact()
            return
    else:
        try:
            obs_terrain = bpy.data.groups[GLOBALS["GROUND_GROUP_NAME"].val].objects
        except:
            error_nogroup()
            return

    obs_clamp = [ob for ob in sce.objects.context if ob not in obs_terrain and not ob.lib]
    if not obs_clamp:
        error_no_obs()
        return

    terrain_tris = collect_terrain_triangles(obs_terrain)
    if not terrain_tris:
        error_noground()
        return

    if GLOBALS["DROP_AXIS"][0].val:
        axis = Vector(0, 0, -1)
    else:
        axis = Vector(Window.GetViewVector())

    do_orient = GLOBALS["DROP_ORIENT"].val
    do_orient_val = GLOBALS["DROP_ORIENT_VALUE"].val / 100.0
    if not do_orient_val:
        do_orient = False

    for ob in obs_clamp:
        loc, no = calc_drop_loc(ob, terrain_tris, axis)
        if loc:
            if do_orient:
                try:
                    ang = AngleBetweenVecs(no, axis)
                except:
                    ang = 0.0
                if ang > 90.0:
                    no = -no
                    ang = 180.0 - ang

                if ang > 0.0001:
                    ob_matrix = ob.matrixWorld * RotationMatrix(ang * do_orient_val, 4, "r", axis.cross(no))
                    ob.setMatrix(ob_matrix)

            ob.loc = loc

            # to make the while loop exist
    GLOBALS["EVENT"] = EVENT_EXIT
def VectoMat(vec):
    a3 = vec.__copy__().normalize()

    up = Vector(0, 0, 1)
    if abs(a3.dot(up)) == 1.0:
        up = Vector(0, 1, 0)

    a1 = a3.cross(up).normalize()
    a2 = a3.cross(a1)
    return Matrix([a1[0], a1[1], a1[2]], [a2[0], a2[1], a2[2]],
                  [a3[0], a3[1], a3[2]])
示例#5
0
def selectedVertices(object):
    verts = []
    mat = object.getMatrix("worldspace")
    for v in object.getData().verts:
        if not v.sel:
            continue
        vec = Vector([v[0], v[1], v[2]])
        vec.resize4D()
        vec *= mat
        v[0], v[1], v[2] = vec[0], vec[1], vec[2]
        verts.append(v)
    return verts
def selectedVertices(object):
	verts = []
	mat = object.getMatrix('worldspace')
	for v in object.getData().verts:
		if not v.sel:
			continue
		vec = Vector([v[0], v[1], v[2]])
		vec.resize4D()
		vec *= mat
		v[0], v[1], v[2] = vec[0], vec[1], vec[2]
		verts.append(v)
	return verts
示例#7
0
        def test_point(x0, y0, i, j):

            x = x0 + 0.0625 * (i + 0.5)
            y = y0 + 0.0625 * (j + 0.5)

            ray, orig = Vector(0, 0, 1), Vector(x, y, 0)

            for face in mesh.faces:
                verts = [v.co + obj_loc for v in face.verts]

                if Intersect(verts[0], verts[1], verts[2], ray, orig, 1) or \
                 ( len(face.verts) == 4 and \
                   Intersect(verts[0], verts[2], verts[3], ray, orig, 1) ):
                    return True

            return False
示例#8
0
 def delRegion(self, img):
     r = self.isRegion(img)
     if not r: return False
     (n, x1, y1, width, height) = r
     mesh = self.obj.getData(mesh=True)
     panelimage = mesh.faces[0].image
     try:
         (pwidth, pheight) = panelimage.size
         xoff = float(x1) / pwidth
         yoff = float(y1) / pheight
         xscale = float(width) / pwidth
         yscale = float(height) / pheight
     except:
         xoff = yoff = 0
         xscale = yscale = 1
     # Reassign UV mappings back to panel image
     for obj in Scene.GetCurrent().objects:
         if obj != self.obj and obj.getType() == "Mesh":
             mesh2 = obj.getData(mesh=True)
             if mesh2.faceUV:
                 for face in mesh2.faces:
                     if face.image == img:
                         face.image = panelimage
                         face.uv = [
                             Vector(
                                 [xoff + v.x * xscale, yoff + v.y * yscale])
                             for v in face.uv
                         ]
             mesh2.update()
     mesh.faces[n].image = panelimage
     img.reload()  # blank old region
     self.obj.removeProperty('x%d' % n)
     self.obj.removeProperty('y%d' % n)
     return True
示例#9
0
def calc_drop_loc(ob, terrain_tris, axis):
    pt = Vector(ob.loc)

    isect = None
    isect_best = None
    isect_best_no = None
    isect_best_len = 0.0

    for t1, t2, t3, no in terrain_tris:
        #if Geometry.PointInTriangle2D(pt, t1,t2,t3):
        isect = Mathutils.Intersect(t1, t2, t3, axis, pt, 1)  # 1==clip
        if isect:
            if not GLOBALS['DROP_OVERLAP_CHECK'].val:
                # Find the first location
                return isect, no
            else:
                if isect_best:
                    isect_len = (pt - isect).length
                    if isect_len < isect_best_len:
                        isect_best_len = isect_len
                        isect_best = isect
                        isect_best_no = no

                else:
                    isect_best_len = (pt - isect).length
                    isect_best = isect
                    isect_best_no = no

    return isect_best, isect_best_no
def island2Edge(island):

    # Vert index edges
    edges = {}

    unique_points = {}

    for f in island:
        f_uvkey = map(tuple, f.uv)

        for vIdx, edkey in enumerate(f.edge_keys):
            unique_points[f_uvkey[vIdx]] = f.uv[vIdx]

            if f.v[vIdx].index > f.v[vIdx - 1].index:
                i1 = vIdx - 1
                i2 = vIdx
            else:
                i1 = vIdx
                i2 = vIdx - 1

            try:
                edges[f_uvkey[i1], f_uvkey[
                    i2]] *= 0  # sets eny edge with more then 1 user to 0 are not returned.
            except:
                edges[f_uvkey[i1], f_uvkey[i2]] = (f.uv[i1] - f.uv[i2]).length,

    # If 2 are the same then they will be together, but full [a,b] order is not correct.

    # Sort by length

    length_sorted_edges = [(Vector(key[0]), Vector(key[1]), value)
                           for key, value in edges.iteritems() if value != 0]

    try:
        length_sorted_edges.sort(key=lambda A: -A[2])  # largest first
    except:
        length_sorted_edges.sort(lambda A, B: cmp(B[2], A[2]))

    # Its okay to leave the length in there.
    #for e in length_sorted_edges:
    #	e.pop(2)

    # return edges and unique points
    return length_sorted_edges, [
        v.__copy__().resize3D() for v in unique_points.itervalues()
    ]
示例#11
0
 def toVector(self, n):
     v = [self.x, self.y]
     if n == 3:
         v.append(self.z)
     elif n == 4:
         v.extend([self.z, 1.0])
     else:
         raise AttributeError
     return Vector(v)
示例#12
0
    def addRegion(self, xoff, yoff, width, height):
        mesh = self.obj.getData(mesh=True)
        panelimage = mesh.faces[0].image
        name = 'PanelRegion'
        for img in Image.get():
            # try to re-use existing deleted panel region
            if img.size == [
                    width, height
            ] and img.source == Image.Sources.GENERATED and img.filename == name and not self.isRegion(
                    img):
                break
        else:
            img = Image.New(name, width, height, 24)
        for y in range(height):
            for x in range(width):
                rgba = panelimage.getPixelI(xoff + x, yoff + y)
                if not rgba[3]:
                    img.setPixelI(x, y,
                                  (102, 102, 255, 255))  # hilite transparent
                else:
                    img.setPixelI(x, y, rgba[:3] + [255])
        img.pack()

        for n in range(1, PanelRegionHandler.REGIONCOUNT + 1):
            if mesh.faces[n].image == panelimage:
                mesh.faces[n].image = img
                self.obj.addProperty('x%d' % n, xoff)
                self.obj.addProperty('y%d' % n, yoff)
                (width, height) = img.size
                (pwidth, pheight) = panelimage.size
                xoff = float(xoff) / pwidth
                yoff = float(yoff) / pheight
                xscale = float(pwidth) / width
                yscale = float(pheight) / height
                # Assign UV mappings from panel image
                for obj in Scene.GetCurrent().objects:
                    if obj != self.obj and obj.getType() == "Mesh":
                        mesh2 = obj.getData(mesh=True)
                        if mesh2.faceUV:
                            for face in mesh2.faces:
                                if face.image == panelimage:
                                    uv = []
                                    for v in face.uv:
                                        x = (v.x - xoff) * xscale
                                        y = (v.y - yoff) * yscale
                                        if not -UV.LIMIT <= x <= 1 + UV.LIMIT or not -UV.LIMIT <= y <= 1 + UV.LIMIT:
                                            break
                                        uv.append(
                                            Vector(min(max(x, 0), 1),
                                                   min(max(y, 0), 1)))
                                    else:
                                        face.uv = uv
                                        face.image = img
                            mesh2.update()
                break
        return img
示例#13
0
def pointInIsland(pt, island):
	vec1 = Vector(); vec2 = Vector(); vec3 = Vector()	
	for f in island:
		vec1.x, vec1.y = f.uv[0]
		vec2.x, vec2.y = f.uv[1]
		vec3.x, vec3.y = f.uv[2]

		if pointInTri2D(pt, vec1, vec2, vec3):
			return True
		
		if len(f.v) == 4:
			vec1.x, vec1.y = f.uv[0]
			vec2.x, vec2.y = f.uv[2]
			vec3.x, vec3.y = f.uv[3]			
			if pointInTri2D(pt, vec1, vec2, vec3):
				return True
	return False
示例#14
0
 def to_mesh(self, name, image):
     self.remove_degenerate_faces()
     self.duplicate_verts_with_multiple_normals()
     mesh = Blender.Mesh.New()
     mesh.properties['joename'] = name
     mesh.verts.extend([Vector(v.co()) for v in self.verts])
     # set normals
     for f in self.faces:
         for i in range(3):
             mesh.verts[f.vertex_index[i]].no = Vector(
                 self.normals[f.normal_index[i]].co())
     # set faces
     mesh.faces.extend([f.vertex_index for f in self.faces],
                       ignoreDups=True)
     # set texture coordinates
     for i in range(len(mesh.faces)):
         sf = self.faces[i]
         mf = mesh.faces[i]
         # fix face indices ordering
         i = (0, 1, 2)
         if mf.v[0].index == sf.vertex_index[1]: i = (1, 2, 0)
         elif mf.v[0].index == sf.vertex_index[2]: i = (2, 0, 1)
         # set coordinates
         ti = sf.texture_index[i[0]], sf.texture_index[
             i[1]], sf.texture_index[i[2]]
         uv = [
             Vector(self.texcoords[ti[0]].uv()),
             Vector(self.texcoords[ti[1]].uv()),
             Vector(self.texcoords[ti[2]].uv())
         ]
         mf.uv = uv
         mf.smooth = 1
         if image != None:
             mf.image = image
     # add to scene
     scn = Blender.Scene.GetCurrent()
     if name:
         return scn.objects.new(mesh, name)
     else:
         return scn.objects.new(mesh)
示例#15
0
    def blenderstructure(self, ):
        nat = len(self.xyz.atomtypes)
        # create atoms
        for i in range(0, nat):
            loc = Mathutils.Vector(self.xyz.coord[i])
            me = Mesh.Primitives.Icosphere(spheresubdivisions,
                                           atomicradii[self.xyz.atomtypes[i]])
            me.materials = [materials[self.xyz.atomtypes[i]]]
            for face in me.faces:
                face.smooth = True
            obj = self.scene.objects.new(me, 'Atom')
            obj.setLocation(loc)
        # form bonds between atoms
        for i in range(0, nat):
            for j in range(i + 1, nat):
                vec1 = Mathutils.Vector(self.xyz.coord[i])
                vec2 = Mathutils.Vector(self.xyz.coord[j])
                vec = vec2 - vec1
                distcovalent = covalentradii[self.xyz.atomtypes[
                    i]] + covalentradii[self.xyz.atomtypes[j]]
                print "vec.length = %s  distcovalent = %s" % (vec.length,
                                                              distcovalent)
                if (vec.length - distcovalent) <= 0.10 * distcovalent:
                    me = Mesh.Primitives.Tube(32, stickradius, vec.length)
                    for face in me.faces:
                        face.smooth = True
                    obj = self.scene.objects.new(me, 'Bond')
                    axis = Mathutils.CrossVecs(Vector([0, 0, 1]), vec)
                    angle = Mathutils.AngleBetweenVecs(Vector([0, 0, 1]), vec)
                    rotmat = Mathutils.RotationMatrix(angle, 4, "R", axis)
                    obj.setMatrix(obj.matrix * rotmat)
                    obj.setLocation((vec1 + vec2) * 0.5)

    # vectors
        scale = 1.0  #1000.0 #1.0 #1000.0
        for i in range(0, nat):
            loc = Mathutils.Vector(self.xyz.coord[i])
            vec = Mathutils.Vector(self.xyz.vectors[i]) * scale
            # arrow tail
            me = Mesh.Primitives.Tube(32, arrowradius, vec.length)
            me.materials = [materials["arrow"]]
            for face in me.faces:
                face.smooth = True
            obj = self.scene.objects.new(me, "Arrow-Tail")
            axis = Mathutils.CrossVecs(Vector([0, 0, 1]), vec)
            angle = Mathutils.AngleBetweenVecs(Vector([0, 0, 1]), vec)
            rotmat = Mathutils.RotationMatrix(angle, 4, "R", axis)
            obj.setMatrix(obj.matrix * rotmat)
            obj.setLocation(loc + 0.5 * vec)
            # arrow head
            me = Mesh.Primitives.Cone(32, 2 * arrowradius, 0.5)
            me.materials = [materials["arrow"]]
            for face in me.faces:
                face.smooth = True
            obj = self.scene.objects.new(me, "Arrow-Head")
            axis = Mathutils.CrossVecs(Vector([0, 0, 1]), vec)
            angle = Mathutils.AngleBetweenVecs(Vector([0, 0, 1]), vec)
            rotmat = Mathutils.RotationMatrix(angle + 180.0, 4, "R", axis)
            obj.setMatrix(obj.matrix * rotmat)
            obj.setLocation(loc + vec)
示例#16
0
def pointBounds(points):
    '''
	Takes a list of points and returns the
	area, center, bounds
	'''
    ymax = xmax = -BIGNUM
    ymin = xmin = BIGNUM

    for p in points:
        x = p.x
        y = p.y

        if x > xmax: xmax = x
        if y > ymax: ymax = y

        if x < xmin: xmin = x
        if y < ymin: ymin = y

    # area and center
    return\
    (xmax-xmin) * (ymax-ymin),\
    Vector((xmin+xmax)/2, (ymin+ymax)/2),\
    (xmin, ymin, xmax, ymax)
示例#17
0
def makeVNormal(me, vert, origEdgeLen):
	vNormal = Vector([0,0,0])
	eIdx = 0
	while eIdx < origEdgeLen:
		
		e = me.edges[eIdx]
		
		if e.v1 == vert or e.v2 == vert:
			pass
		else:
			eIdx+=1
			continue
			
		v1 = -1
		if vert == e.v1: v1 = False
		if vert == e.v2: v1 = 1
		if v1 == -1:
			eIdx+=1
			continue
			
		# one of the verts in the face is the same as the vert that we are finding teyh normal for.
		# Make a vector from the edge v1 and v2 are the indivies for this edge
		v2 = (not v1)
		
		ev = [e.v1, e.v2]
		
		newVec = Vector([\
			ev[v1].co[0]-ev[v2].co[0],\
			ev[v1].co[1]-ev[v2].co[1],\
			ev[v1].co[2]-ev[v2].co[2]] )
		
		newVec.normalize()
		vNormal = vNormal + newVec
		eIdx+=1
		
	vNormal.normalize()
	return vNormal
def mergeUvIslands(islandList):
    global USER_FILL_HOLES
    global USER_FILL_HOLES_QUALITY

    # Pack islands to bottom LHS
    # Sync with island

    #islandTotFaceArea = [] # A list of floats, each island area
    #islandArea = [] # a list of tuples ( area, w,h)

    decoratedIslandList = []

    islandIdx = len(islandList)
    while islandIdx:
        islandIdx -= 1
        minx, miny, maxx, maxy = boundsIsland(islandList[islandIdx])
        w, h = maxx - minx, maxy - miny

        totFaceArea = 0
        offset = Vector(minx, miny)
        for f in islandList[islandIdx]:
            for uv in f.uv:
                uv -= offset

            totFaceArea += f.area

        islandBoundsArea = w * h
        efficiency = abs(islandBoundsArea - totFaceArea)

        # UV Edge list used for intersections as well as unique points.
        edges, uniqueEdgePoints = island2Edge(islandList[islandIdx])

        decoratedIslandList.append([
            islandList[islandIdx], totFaceArea, efficiency, islandBoundsArea,
            w, h, edges, uniqueEdgePoints
        ])

    # Sort by island bounding box area, smallest face area first.
    # no.. chance that to most simple edge loop first.
    decoratedIslandListAreaSort = decoratedIslandList[:]

    try:
        decoratedIslandListAreaSort.sort(key=lambda A: A[3])
    except:
        decoratedIslandListAreaSort.sort(lambda A, B: cmp(A[3], B[3]))

    # sort by efficiency, Least Efficient first.
    decoratedIslandListEfficSort = decoratedIslandList[:]
    # decoratedIslandListEfficSort.sort(lambda A, B: cmp(B[2], A[2]))

    try:
        decoratedIslandListEfficSort.sort(key=lambda A: -A[2])
    except:
        decoratedIslandListEfficSort.sort(lambda A, B: cmp(B[2], A[2]))

    # ================================================== THESE CAN BE TWEAKED.
    # This is a quality value for the number of tests.
    # from 1 to 4, generic quality value is from 1 to 100
    USER_STEP_QUALITY = ((USER_FILL_HOLES_QUALITY - 1) / 25.0) + 1

    # If 100 will test as long as there is enough free space.
    # this is rarely enough, and testing takes a while, so lower quality speeds this up.

    # 1 means they have the same quality
    USER_FREE_SPACE_TO_TEST_QUALITY = 1 + ((
        (100 - USER_FILL_HOLES_QUALITY) / 100.0) * 5)

    #print 'USER_STEP_QUALITY', USER_STEP_QUALITY
    #print 'USER_FREE_SPACE_TO_TEST_QUALITY', USER_FREE_SPACE_TO_TEST_QUALITY

    removedCount = 0

    areaIslandIdx = 0
    ctrl = Window.Qual.CTRL
    BREAK = False
    while areaIslandIdx < len(decoratedIslandListAreaSort) and not BREAK:
        sourceIsland = decoratedIslandListAreaSort[areaIslandIdx]
        # Alredy packed?
        if not sourceIsland[0]:
            areaIslandIdx += 1
        else:
            efficIslandIdx = 0
            while efficIslandIdx < len(
                    decoratedIslandListEfficSort) and not BREAK:

                if Window.GetKeyQualifiers() & ctrl:
                    BREAK = True
                    break

                # Now we have 2 islands, is the efficience of the islands lowers theres an
                # increasing likely hood that we can fit merge into the bigger UV island.
                # this ensures a tight fit.

                # Just use figures we have about user/unused area to see if they might fit.

                targetIsland = decoratedIslandListEfficSort[efficIslandIdx]


                if sourceIsland[0] == targetIsland[0] or\
                not targetIsland[0] or\
                not sourceIsland[0]:
                    pass
                else:

                    # ([island, totFaceArea, efficiency, islandArea, w,h])
                    # Waisted space on target is greater then UV bounding island area.

                    # if targetIsland[3] > (sourceIsland[2]) and\ #
                    # print USER_FREE_SPACE_TO_TEST_QUALITY, 'ass'
                    if targetIsland[2] > (sourceIsland[1] * USER_FREE_SPACE_TO_TEST_QUALITY) and\
                    targetIsland[4] > sourceIsland[4] and\
                    targetIsland[5] > sourceIsland[5]:

                        # DEBUG # print '%.10f  %.10f' % (targetIsland[3], sourceIsland[1])

                        # These enough spare space lets move the box until it fits

                        # How many times does the source fit into the target x/y
                        blockTestXUnit = targetIsland[4] / sourceIsland[4]
                        blockTestYUnit = targetIsland[5] / sourceIsland[5]

                        boxLeft = 0

                        # Distllllance we can move between whilst staying inside the targets bounds.
                        testWidth = targetIsland[4] - sourceIsland[4]
                        testHeight = targetIsland[5] - sourceIsland[5]

                        # Increment we move each test. x/y
                        xIncrement = (testWidth /
                                      (blockTestXUnit *
                                       ((USER_STEP_QUALITY / 50) + 0.1)))
                        yIncrement = (testHeight /
                                      (blockTestYUnit *
                                       ((USER_STEP_QUALITY / 50) + 0.1)))

                        # Make sure were not moving less then a 3rg of our width/height
                        if xIncrement < sourceIsland[4] / 3:
                            xIncrement = sourceIsland[4]
                        if yIncrement < sourceIsland[5] / 3:
                            yIncrement = sourceIsland[5]

                        boxLeft = 0  # Start 1 back so we can jump into the loop.
                        boxBottom = 0  #-yIncrement

                        ##testcount= 0

                        while boxBottom <= testHeight:
                            # Should we use this? - not needed for now.
                            #if Window.GetKeyQualifiers() & ctrl:
                            #	BREAK= True
                            #	break

                            ##testcount+=1
                            #print 'Testing intersect'
                            Intersect = islandIntersectUvIsland(
                                sourceIsland, targetIsland,
                                Vector(boxLeft, boxBottom))
                            #print 'Done', Intersect
                            if Intersect == 1:  # Line intersect, dont bother with this any more
                                pass

                            if Intersect == 2:  # Source inside target
                                '''
								We have an intersection, if we are inside the target 
								then move us 1 whole width accross,
								Its possible this is a bad idea since 2 skinny Angular faces
								could join without 1 whole move, but its a lot more optimal to speed this up
								since we have alredy tested for it.
								
								It gives about 10% speedup with minimal errors.
								'''
                                #print 'ass'
                                # Move the test allong its width + SMALL_NUM
                                #boxLeft += sourceIsland[4] + SMALL_NUM
                                boxLeft += sourceIsland[4]
                            elif Intersect == 0:  # No intersection?? Place it.
                                # Progress
                                removedCount += 1
                                Window.DrawProgressBar(
                                    0.0,
                                    'Merged: %i islands, Ctrl to finish early.'
                                    % removedCount)

                                # Move faces into new island and offset
                                targetIsland[0].extend(sourceIsland[0])
                                offset = Vector(boxLeft, boxBottom)

                                for f in sourceIsland[0]:
                                    for uv in f.uv:
                                        uv += offset

                                sourceIsland[0][:] = []  # Empty

                                # Move edge loop into new and offset.
                                # targetIsland[6].extend(sourceIsland[6])
                                #while sourceIsland[6]:
                                targetIsland[6].extend( [ (\
                                  (e[0]+offset, e[1]+offset, e[2])\
                                ) for e in sourceIsland[6] ] )

                                sourceIsland[6][:] = []  # Empty

                                # Sort by edge length, reverse so biggest are first.

                                try:
                                    targetIsland[6].sort(key=lambda A: A[2])
                                except:
                                    targetIsland[6].sort(
                                        lambda B, A: cmp(A[2], B[2]))

                                targetIsland[7].extend(sourceIsland[7])
                                offset = Vector(boxLeft, boxBottom, 0)
                                for p in sourceIsland[7]:
                                    p += offset

                                sourceIsland[7][:] = []

                                # Decrement the efficiency
                                targetIsland[1] += sourceIsland[
                                    1]  # Increment totFaceArea
                                targetIsland[2] -= sourceIsland[
                                    1]  # Decrement efficiency
                                # IF we ever used these again, should set to 0, eg
                                sourceIsland[
                                    2] = 0  # No area if anyone wants to know

                                break

                            # INCREMENR NEXT LOCATION
                            if boxLeft > testWidth:
                                boxBottom += yIncrement
                                boxLeft = 0.0
                            else:
                                boxLeft += xIncrement
                        ##print testcount

                efficIslandIdx += 1
        areaIslandIdx += 1

    # Remove empty islands
    i = len(islandList)
    while i:
        i -= 1
        if not islandList[i]:
            del islandList[i]  # Can increment islands removed here.
示例#19
0
	def build_hierarchy(self):
		blmatrix = AC_TO_BLEND_MATRIX

		olist = self.objlist[1:]
		olist.reverse()

		scene = self.scene

		newlist = []

		for o in olist:
			kids = o.kids
			if kids:
				children = newlist[-kids:]
				newlist = newlist[:-kids]
				if o.type == AC_GROUP:
					parent = self.found_parent(o.name, children)
					if parent:
						children.remove(parent)
						o.bl_obj = parent.bl_obj
					else: # not found, use an empty
						empty = scene.objects.new('Empty', o.name)
						o.bl_obj = empty

				bl_children = [c.bl_obj for c in children if c.bl_obj != None]
				
				o.bl_obj.makeParent(bl_children, 0, 1)
				for child in children:
					blob = child.bl_obj
					if not blob: continue
					if child.rot:
						eul = euler_in_radians(child.rot.toEuler())
						blob.setEuler(eul)
					if child.size:
						blob.size = child.size
					if not child.loc:
						child.loc = Vector(0.0, 0.0, 0.0)
					blob.setLocation(child.loc)

			newlist.append(o)

		for o in newlist: # newlist now only has objs w/o parents
			blob = o.bl_obj
			if not blob:
				continue
			if o.size:
				o.bl_obj.size = o.size
			if not o.rot:
				blob.setEuler([1.5707963267948966, 0, 0])
			else:
				matrix = o.rot * blmatrix
				eul = euler_in_radians(matrix.toEuler())
				blob.setEuler(eul)
			if o.loc:
				o.loc *= blmatrix
			else:
				o.loc = Vector(0.0, 0.0, 0.0)
			blob.setLocation(o.loc) # forces DAG update, so we do it even for 0, 0, 0

		# XXX important: until we fix the BPy API so it doesn't increase user count
		# when wrapping a Blender object, this piece of code is needed for proper
		# object (+ obdata) deletion in Blender:
		for o in self.objlist:
			if o.bl_obj:
				o.bl_obj = None
示例#20
0
def load_md2(md2_filename, texture_filename):
    #read the file in
    file = open(md2_filename, "rb")
    WaitCursor(1)
    DrawProgressBar(0.0, 'Loading MD2')
    md2 = md2_obj()
    md2.load(file)
    #md2.dump()
    file.close()

    ######### Creates a new mesh
    mesh = Mesh.New()

    uv_coord = []
    #uv_list=[]
    verts_extend = []
    #load the textures to use later
    #-1 if there is no texture to load
    mesh_image = load_textures(md2, texture_filename)
    if mesh_image == -1 and texture_filename:
        print 'MD2 Import, Warning, texture "%s" could not load'

    ######### Make the verts
    DrawProgressBar(0.25, "Loading Vertex Data")
    frame = md2.frames[0]
    scale = g_scale.val

    def tmp_get_vertex(i):
        #use the first frame for the mesh vertices
        x = (frame.scale[0] * frame.vertices[i].vertices[0] +
             frame.translate[0]) * scale
        y = (frame.scale[1] * frame.vertices[i].vertices[1] +
             frame.translate[1]) * scale
        z = (frame.scale[2] * frame.vertices[i].vertices[2] +
             frame.translate[2]) * scale
        return y, -x, z

    mesh.verts.extend([tmp_get_vertex(i) for i in xrange(0, md2.num_vertices)])
    del tmp_get_vertex

    ######## Make the UV list
    DrawProgressBar(0.50, "Loading UV Data")

    w = float(md2.skin_width)
    h = float(md2.skin_height)
    if w <= 0.0: w = 1.0
    if h <= 0.0: h = 1.0
    #for some reason quake2 texture maps are upside down, flip that
    uv_list = [Vector(co.u / w, 1 - (co.v / h)) for co in md2.tex_coords]
    del w, h

    ######### Make the faces
    DrawProgressBar(0.75, "Loading Face Data")
    faces = []
    face_uvs = []
    for md2_face in md2.faces:
        f = md2_face.vertex_index[0], md2_face.vertex_index[
            2], md2_face.vertex_index[1]
        uv = uv_list[md2_face.texture_index[0]], uv_list[
            md2_face.texture_index[2]], uv_list[md2_face.texture_index[1]]

        if f[2] == 0:
            # EEKADOODLE :/
            f = f[1], f[2], f[0]
            uv = uv[1], uv[2], uv[0]

        #ditto in reverse order with the texture verts
        faces.append(f)
        face_uvs.append(uv)

    face_mapping = mesh.faces.extend(faces, indexList=True)
    print len(faces)
    print len(mesh.faces)
    mesh.faceUV = True  #turn on face UV coordinates for this mesh
    mesh_faces = mesh.faces
    for i, uv in enumerate(face_uvs):
        if face_mapping[i] != None:
            f = mesh_faces[face_mapping[i]]
            f.uv = uv
            if (mesh_image != -1):
                f.image = mesh_image

    scn = Blender.Scene.GetCurrent()
    mesh_obj = scn.objects.new(mesh)
    animate_md2(md2, mesh)
    DrawProgressBar(0.98, "Loading Animation Data")

    #locate the Object containing the mesh at the cursor location
    cursor_pos = Blender.Window.GetCursorPos()
    mesh_obj.setLocation(float(cursor_pos[0]), float(cursor_pos[1]),
                         float(cursor_pos[2]))
    DrawProgressBar(1.0, "")
    WaitCursor(0)
def pointInIsland(pt, island):
    vec1 = Vector()
    vec2 = Vector()
    vec3 = Vector()
    for f in island:
        vec1.x, vec1.y = f.uv[0]
        vec2.x, vec2.y = f.uv[1]
        vec3.x, vec3.y = f.uv[2]

        if pointInTri2D(pt, vec1, vec2, vec3):
            return True

        if len(f.v) == 4:
            vec1.x, vec1.y = f.uv[0]
            vec2.x, vec2.y = f.uv[2]
            vec3.x, vec3.y = f.uv[3]
            if pointInTri2D(pt, vec1, vec2, vec3):
                return True
    return False
示例#22
0
    for i in items:
        path=i[3].split('/')[:-1]
        extend_pop_for(pop_list,path)
        if len(path):
            append_to_inner(pop_list,(i[3].split('/')[-1],items.index(i)))
        else:
            pop_list.append((i[3].split('/')[-1],items.index(i)))


    r = Draw.PupTreeMenu(pop_list)
    if r >= 0:
        print items[r]
        set_pref_key('xplane.tools','annotate.last_item',items[r])
        cur = Window.GetCursorPos()
        mm = TranslationMatrix(Vector([0,0,0])).resize4x4()
        #mm = TranslationMatrix(Vector(Window.GetCursorPos())).resize4x4()
        importer=OBJimport(items[r][1],mm)
        importer.verbose=1
        try:
            sel = Blender.Scene.GetCurrent().objects.selected
            old_objs = set(Blender.Scene.GetCurrent().objects)
            obj_list = importer.doimport()
            new_objs = set(Blender.Scene.GetCurrent().objects)
            wrapper=Blender.Object.New('Empty','OBJ%s' % items[r][0].split('/')[-1])
            Blender.Scene.GetCurrent().objects.link(wrapper)
            added = new_objs-old_objs
            wrapper.makeParent(list(added),1,0)
            if len(sel) == 1:
                sel[0].makeParent([wrapper],1,0)
                base = sel[0].getLocation('worldspace')
示例#23
0
def readDSF(path):
    baddsf=(0, "Invalid DSF file", path)

    h=file(path, 'rb')
    h.seek(0, 2)
    hlen=h.tell()
    h.seek(0, 0)
    if h.read(8)!='XPLNEDSF' or unpack('<I',h.read(4))!=(1,) or h.read(4)!='DAEH':
        raise IOError, baddsf
    (l,)=unpack('<I', h.read(4))
    headend=h.tell()+l-8
    if h.read(4)!='PORP':
        raise IOError, baddsf
    (l,)=unpack('<I', h.read(4))
    properties=[]
    c=h.read(l-9).split('\0')
    h.read(1)
    overlay=0
    for i in range(0, len(c)-1, 2):
        if c[i]=='sim/overlay': overlay=int(c[i+1])
        elif c[i]=='sim/south': lat=int(c[i+1])
        elif c[i]=='sim/west': lon=int(c[i+1])
        properties.append((c[i],c[i+1]))
    h.seek(headend)
    if overlay:
        # Overlay DSF - bail early
        h.close()
        raise IOError, (0, "This is an overlay DSF", path)

    # Definitions Atom
    if h.read(4)!='NFED':
        raise IOError, baddsf
    (l,)=unpack('<I', h.read(4))
    defnend=h.tell()+l-8
    terrain=objects=polygons=network=[]
    while h.tell()<defnend:
        c=h.read(4)
        (l,)=unpack('<I', h.read(4))
        if l==8:
            pass	# empty
        elif c=='TRET':
            terrain=h.read(l-9).replace('\\','/').replace(':','/').split('\0')
            h.read(1)
        elif c=='TJBO':
            objects=h.read(l-9).replace('\\','/').replace(':','/').split('\0')
            h.read(1)
        elif c=='YLOP':
            polygons=h.read(l-9).replace('\\','/').replace(':','/').split('\0')
            h.read(1)
        elif c=='WTEN':
            networks=h.read(l-9).replace('\\','/').replace(':','/').split('\0')
            h.read(1)
        else:
            h.seek(l-8, 1)

    # Geodata Atom
    if h.read(4)!='DOEG':
        raise IOError, baddsf
    (l,)=unpack('<I', h.read(4))
    geodend=h.tell()+l-8
    pool=[]
    scal=[]
    while h.tell()<geodend:
        c=h.read(4)
        (l,)=unpack('<I', h.read(4))
        if c=='LOOP':
            thispool=[]
            (n,)=unpack('<I', h.read(4))
            (p,)=unpack('<B', h.read(1))
            for i in range(p):
                thisplane=[]
                (e,)=unpack('<B', h.read(1))
                if e==0 or e==1:
                    last=0
                    for j in range(n):
                        (d,)=unpack('<H', h.read(2))
                        if e==1: d=(last+d)&65535
                        thisplane.append(d)
                        last=d
                elif e==2 or e==3:
                    last=0
                    while(len(thisplane))<n:
                        (r,)=unpack('<B', h.read(1))
                        if (r&128):
                            (d,)=unpack('<H', h.read(2))
                            for j in range(r&127):
                                if e==3:
                                    thisplane.append((last+d)&65535)
                                    last=(last+d)&65535
                                else:
                                    thisplane.append(d)
                        else:
                            for j in range(r):
                                (d,)=unpack('<H', h.read(2))
                                if e==3: d=(last+d)&65535
                                thisplane.append(d)
                                last=d
                else:
                    raise IOError, baddsf
                thispool.append(thisplane)
            pool.append(thispool)
        elif c=='LACS':
            thisscal=[]
            for i in range(0, l-8, 8):
                d=unpack('<2f', h.read(8))
                thisscal.append(d)
            scal.append(thisscal)
        else:
            h.seek(l-8, 1)

    # Rescale pool and transform to one list per entry
    if len(scal)!=len(pool): raise(IOError)
    newpool=[]
    for i in range(len(pool)):
        curpool=pool[i]
        n=len(curpool[0])
        newpool=[[] for j in range(n)]
        for plane in range(len(curpool)):
            (scale,offset)=scal[i][plane]
            scale=scale/65535
            for j in range(n):
                newpool[j].append(curpool[plane][j]*scale+offset)
        pool[i]=newpool

    # Commands Atom
    if h.read(4)!='SDMC':
        raise IOError, baddsf
    (l,)=unpack('<I', h.read(4))
    cmdsend=h.tell()+l-8
    curpool=0
    idx=0
    near=0
    far=-1
    flags=0	# 0=physical, 1=overlay
    f=[[[],[]] for i in range(len(terrain))]
    v=[[[],[]] for i in range(len(terrain))]
    t=[[[],[]] for i in range(len(terrain))]
    pscale=99.0/(hlen-geodend)
    progress=0
    while h.tell()<cmdsend:
        now=int((h.tell()-geodend)*pscale)
        if progress!=now:
            progress=now
            Window.DrawProgressBar(progress/100.0, "Importing %2d%%"%progress)

        (c,)=unpack('<B', h.read(1))
        if c==1:	# Coordinate Pool Select
            (curpool,)=unpack('<H', h.read(2))

        elif c==2:	# Junction Offset Select
            h.read(4)	# not implemented

        elif c==3:	# Set Definition
            (idx,)=unpack('<B', h.read(1))

        elif c==4:	# Set Definition
            (idx,)=unpack('<H', h.read(2))

        elif c==5:	# Set Definition
            (idx,)=unpack('<I', h.read(4))

        elif c==6:	# Set Road Subtype
            h.read(1)	# not implemented

        elif c==7:	# Object
            h.read(2)	# not implemented

        elif c==8:	# Object Range
            h.read(4)	# not implemented

        elif c==9:	# Network Chain
            (l,)=unpack('<B', h.read(1))
            h.read(l*2)	# not implemented

        elif c==10:	# Network Chain Range
            h.read(4)	# not implemented

        elif c==11:	# Network Chain
            (l,)=unpack('<B', h.read(1))
            h.read(l*4)	# not implemented

        elif c==12:	# Polygon
            (param,l)=unpack('<HB', h.read(3))
            h.read(l*2)	# not implemented

        elif c==13:	# Polygon Range (DSF2Text uses this one)
            (param,first,last)=unpack('<HHH', h.read(6))	# not implemented

        elif c==14:	# Nested Polygon
            (param,n)=unpack('<HB', h.read(3))
            for i in range(n):
                (l,)=unpack('<B', h.read(1))
                h.read(l*2)	# not implemented

        elif c==15:	# Nested Polygon Range (DSF2Text uses this one too)
            (param,n)=unpack('<HB', h.read(3))
            h.read((n+1)*2)	# not implemented

        elif c==16:	# Terrain Patch
            pass

        elif c==17:	# Terrain Patch w/ flags
            (flags,)=unpack('<B', h.read(1))
            flags-=1

        elif c==18:	# Terrain Patch w/ flags & LOD
            (flags,near,far)=unpack('<Bff', h.read(9))
            flags-=1

        elif c==23:	# Patch Triangle
            (l,)=unpack('<B', h.read(1))
            n=len(v[idx][flags])
            for i in range(n,n+l,3):
                f[idx][flags].append([i+2,i+1,i])
            for i in range(l):
                (d,)=unpack('<H', h.read(2))
                p=pool[curpool][d]
                v[idx][flags].append([(p[0]-lon)*hscale,
                                      (p[1]-lat)*hscale, p[2]*vscale])
                if len(p)>=7:
                    t[idx][flags].append([p[5],p[6]])


        elif c==24:	# Patch Triangle - cross-pool
            (l,)=unpack('<B', h.read(1))
            n=len(v[idx][flags])
            for i in range(n,n+l,3):
                f[idx][flags].append([i+2,i+1,i])
            for i in range(l):
                (c,d)=unpack('<HH', h.read(4))
                p=pool[c][d]
                v[idx][flags].append([(p[0]-lon)*hscale,
                                      (p[1]-lat)*hscale, p[2]*vscale])
                if len(p)>=7:
                    t[idx][flags].append([p[5],p[6]])

        elif c==25:	# Patch Triangle Range
            (first,last)=unpack('<HH', h.read(4))
            n=len(v[idx][flags])
            for i in range(n,n+last-first,3):
                f[idx][flags].append([i+2,i+1,i])
            for d in range(first,last):
                p=pool[curpool][d]
                v[idx][flags].append([(p[0]-lon)*hscale,
                                      (p[1]-lat)*hscale, p[2]*vscale])
                if len(p)>=7:
                    t[idx][flags].append([p[5],p[6]])

        #elif c==26:	# Patch Triangle Strip (not used by DSF2Text)
        #elif c==27:
        #elif c==28:

        elif c==29:	# Patch Triangle Fan
            (l,)=unpack('<B', h.read(1))
            n=len(v[idx][flags])
            for i in range(1,l-1):
                f[idx][flags].append([n+i+1,n+i,n])
            for i in range(l):
                (d,)=unpack('<H', h.read(2))
                p=pool[curpool][d]
                v[idx][flags].append([(p[0]-lon)*hscale,
                                      (p[1]-lat)*hscale, p[2]*vscale])
                if len(p)>=7:
                    t[idx][flags].append([p[5],p[6]])

        elif c==30:	# Patch Triangle Fan - cross-pool
            (l,)=unpack('<B', h.read(1))
            n=len(v[idx][flags])
            for i in range(1,l-1):
                f[idx][flags].append([n+i+1,n+i,n])
            for i in range(l):
                (c,d)=unpack('<HH', h.read(4))
                p=pool[c][d]
                v[idx][flags].append([(p[0]-lon)*hscale,
                                      (p[1]-lat)*hscale, p[2]*vscale])
                if len(p)>=7:
                    t[idx][flags].append([p[5],p[6]])

        elif c==31:	# Patch Triangle Fan Range
            (first,last)=unpack('<HH', h.read(4))
            n=len(v[idx][flags])
            for i in range(1,last-first-1):
                f[idx][flags].append([n+i+1,n+i,n])
            for d in range(first, last):
                p=pool[curpool][d]
                v[idx][flags].append([(p[0]-lon)*hscale,
                                      (p[1]-lat)*hscale, p[2]*vscale])
                if len(p)>=7:
                    t[idx][flags].append([p[5],p[6]])

        elif c==32:	# Comment
            (l,)=unpack('<B', h.read(1))
            h.read(l)

        elif c==33:	# Comment
            (l,)=unpack('<H', h.read(2))
            h.read(l)

        elif c==34:	# Comment
            (l,)=unpack('<I', h.read(4))
            h.read(l)

        else:
            raise IOError, (c, "Unrecognised command (%d)" % c, c)

    h.close()

    Window.DrawProgressBar(0.99, "Realising")

    scene=Scene.GetCurrent()
    scene.layers=[1,2]

    for flags in [0]:# was [1,0]:	# overlay first so overlays
        for idx in range(len(terrain)):
            if not f[idx][flags]: continue
            if idx:
                name=basename(terrain[idx])[:-4]
                if flags: name=name+'.2'
                if terrain[idx] in libterrain:
                    (texture, angle, xscale, zscale)=readTER(libterrain[terrain[idx]])
                elif exists(join(dirname(path), pardir, pardir, terrain[idx])):
                    (texture, angle, xscale, zscale)=readTER(abspath(join(dirname(path), pardir, pardir, terrain[idx])))
                else:
                    raise IOError(0, 'Terrain %s not found' % terrain[idx], terrain[idx])
                try:
                    mat=Material.Get(name)
                except:
                    mat=Material.New(name)
                    mat.rgbCol=[1.0, 1.0, 1.0]
                    mat.spec=0
                    try:
                        img=Image.Get(basename(texture))
                    except:
                        img=Image.Load(texture)
                    tex=Texture.New(name)
                    tex.setType('Image')
                    tex.image=img
                    mat.setTexture(0, tex)
                    if flags:
                        mat.zOffset=1
                        mat.mode |= Material.Modes.ZTRANSP
                    mtex=mat.getTextures()[0]
                    mtex.size=(xscale*250, zscale*250, 0)
                    mtex.zproj=Texture.Proj.NONE
                    if t[idx][flags]:
                        mtex.texco=Texture.TexCo.UV
                    else:
                        mtex.texco=Texture.TexCo.GLOB
            else:
                name=terrain[idx]
                mat=Material.New(terrain[idx])
                mat.rgbCol=[0.1, 0.1, 0.2]
                mat.spec=0

            mesh=Mesh.New(name)
            mesh.mode &= ~(Mesh.Modes.TWOSIDED|Mesh.Modes.AUTOSMOOTH)
            mesh.mode |= Mesh.Modes.NOVNORMALSFLIP
            mesh.materials += [mat]
            mesh.verts.extend(v[idx][flags])
            mesh.faces.extend(f[idx][flags])
            if t[idx][flags]:
                faceno=0
                for face in mesh.faces:
                    face.uv=[Vector(t[idx][flags][i][0], t[idx][flags][i][1]) for i in f[idx][flags][faceno]]
                    face.image=img
                    faceno+=1
            mesh.update()

            ob = Object.New("Mesh", name)
            ob.link(mesh)
            scene.objects.link(ob)
            ob.Layer=flags+1
            ob.addProperty('terrain', terrain[idx])

            mesh.sel=True
            mesh.remDoubles(0.001)	# must be after linked to object
            mesh.sel=False

        if 0:	# Unreliable
            for face in mesh.faces:
                for v in face.verts:
                    if v.co[2]!=0.0:
                        break
                else:
                    face.mat=1	# water

    lamp=Lamp.New("Lamp", "Sun")
    ob = Object.New("Lamp", "Sun")
    ob.link(lamp)
    scene.objects.link(ob)
    lamp.type=1
    ob.Layer=3
    ob.setLocation(500, 500, 1000)
示例#24
0
    def animatedensity(self, filenamelist, renderingpath, isovalue):
        context = self.scene.getRenderingContext()
        context.extensions = True
        context.renderPath = renderingpath
        #context.imageType=Render.JPEG
        context.sFrame = 1
        context.eFrame = 1
        context.sizeX = width
        context.sizeY = height

        cubeobject = cube(filenamelist[0])
        cubeobject.readCube()
        atoms = []
        ipokeytypeloc = Object.IpoKeyTypes.LOC
        ipokeytyperot = Object.IpoKeyTypes.ROT
        for i in range(len(cubeobject.atomtypes)):
            me = Mesh.Primitives.Icosphere(
                spheresubdivisions,
                atomicradii.get(cubeobject.atomtypes[i], 2.0))
            me.materials = [
                materials.get(cubeobject.atomtypes[i], materials["default"])
            ]
            for face in me.faces:
                face.smooth = True
            obj = self.scene.objects.new(me, 'Atom')
            obj.setLocation(cubeobject.coord[i][0], cubeobject.coord[i][1],
                            cubeobject.coord[i][2])
            atoms.append(obj)

        bonds = []
        for i in range(len(cubeobject.atomtypes)):
            for j in range(i + 1, len(cubeobject.atomtypes)):
                vec1 = Mathutils.Vector(cubeobject.coord[i])
                vec2 = Mathutils.Vector(cubeobject.coord[j])
                vec = vec2 - vec1
                distcovalent = covalentradii.get(
                    cubeobject.atomtypes[i], 2.0) + covalentradii.get(
                        cubeobject.atomtypes[j], 2.0)
                if (vec.length - distcovalent) <= 0.10 * distcovalent:
                    me = Mesh.Primitives.Tube(32, stickradius, vec.length)
                    for face in me.faces:
                        face.smooth = True
                    obj = self.scene.objects.new(me, 'Cylinder')
                    axis = Mathutils.CrossVecs(Vector([0, 0, 1]), vec)
                    angle = Mathutils.AngleBetweenVecs(Vector([0, 0, 1]), vec)
                    rotmat = Mathutils.RotationMatrix(angle, 4, "R", axis)
                    obj.setMatrix(obj.matrix * rotmat)
                    obj.setLocation((vec1 + vec2) * 0.5)
                    bonds.append([i, j, vec, obj, vec.length])
        self.isosurface(cubeobject, isovalue)
        context.render()
        filename = "RENDER/image_0000.jpg"
        context.saveRenderedImage(filename)

        for j in range(1, len(filenamelist)):
            print(("Rendering:", j))
            filename = "RENDER/image_%04d.jpg" % (j)
            for ob in self.scene.objects:
                if "Lobe" in ob.name:
                    self.scene.unlink(ob)
            cubeobject = cube(filenamelist[j])
            cubeobject.readCube()
            for i in range(len(atoms)):
                atoms[i].setLocation(cubeobject.coord[i][0],
                                     cubeobject.coord[i][1],
                                     cubeobject.coord[i][2])
                atoms[i].insertIpoKey(ipokeytypeloc)
            for i in range(len(bonds)):
                vec1 = Mathutils.Vector(cubeobject.coord[bonds[i][0]])
                vec2 = Mathutils.Vector(cubeobject.coord[bonds[i][1]])
                vec = vec2 - vec1
                dist = vec.length
                axis = Mathutils.CrossVecs(bonds[i][2], vec)
                angle = Mathutils.AngleBetweenVecs(bonds[i][2], vec)
                rotmat = Mathutils.RotationMatrix(angle, 4, "R", axis)
                bonds[i][3].setMatrix(bonds[i][3].matrix * rotmat)
                bonds[i][3].setLocation((vec1 + vec2) * 0.5)
                bonds[i][3].setSize(1.0, 1.0, dist / bonds[i][4])
                bonds[i][3].insertIpoKey(ipokeytypeloc)
                bonds[i][3].insertIpoKey(ipokeytyperot)
                bonds[i][2] = vec
                bonds[i][4] = dist
            self.isosurface(cubeobject, isovalue)
            context.render()
            context.saveRenderedImage(filename)
示例#25
0
def wireMesh(me):
	globalSize = Draw.PupFloatInput('wire width', 0.1, -10.0, 10.0, 0.01, 4)
	if globalSize == None:
		return
	globalHalfsz =globalSize/2
	
	ratio = Draw.PupMenu('Edge Width%t|Fixed Width|Scale with edge len')
	
	normalMethod = Draw.PupMenu('Use Normal%t|Vertex Normal|Edge Normal')
	
	if ratio == -1 or normalMethod == -1:
		return
	
	t = sys.time()
	origEdgeLen = len(me.edges)
	origFaceLen = len(me.faces)
	eIdx = 0
	while eIdx < origEdgeLen:
		
		e = me.edges[eIdx]
		if not e.flag & NMesh.EdgeFlags['SELECT']:
			eIdx+=1
			continue
		
		
		if ratio == 1:
			size = globalSize
			halfsz = globalHalfsz
		else:
			size = globalSize * measure(e.v1, e.v2)
			halfsz = size/2
		
		
		if normalMethod == 1: # vertex normal
			v1nor = makeVNormal(me, e.v1, origEdgeLen)
			v2nor = makeVNormal(me, e.v2, origEdgeLen)
			
			newPt1 = Vector( e.v1.co[0] + (v1nor[0]*size), e.v1.co[1] + (v1nor[1]*size), e.v1.co[2] + (v1nor[2]*size) )
			newPt2 = Vector( e.v2.co[0] + (v2nor[0]*size), e.v2.co[1] + (v2nor[1]*size), e.v2.co[2] + (v2nor[2]*size) )
			
		if normalMethod == 2: # Face Normal
			edgeNormal = Vector([e.v1.no[0] + e.v2.no[0], e.v1.no[1]+e.v2.no[1], e.v1.no[2]+e.v2.no[2] ])
			edgeNormal.normalize()
			
			newPt1 = Vector( e.v1.co[0] + (edgeNormal[0]*size), e.v1.co[1] + (edgeNormal[1]*size), e.v1.co[2] + (edgeNormal[2]*size) )
			newPt2 = Vector( e.v2.co[0] + (edgeNormal[0]*size), e.v2.co[1] + (edgeNormal[1]*size), e.v2.co[2] + (edgeNormal[2]*size) )			
		
		#		#~ newPt1************newPt2
		#		#~ *                      *
		#		#~ *                      *
		#		#~ *                      *
		#	#~ ****vert1**************Vert2**** * * * *
		norA = TriangleNormal(e.v1.co, e.v2.co, newPt1)
		norB = TriangleNormal(e.v2.co, newPt2, newPt1)
		nor1 = norA + norB
		nor1.normalize()
		
		# make face A
		me.verts.append(NMesh.Vert(e.v1.co[0] + (nor1[0]*halfsz), e.v1.co[1] + (nor1[1]*halfsz), e.v1.co[2] + (nor1[2]*halfsz)) )
		me.verts.append(NMesh.Vert(e.v2.co[0] + (nor1[0]*halfsz), e.v2.co[1] + (nor1[1]*halfsz), e.v2.co[2] + (nor1[2]*halfsz)) )
		
		me.verts.append(NMesh.Vert(newPt2[0] + (nor1[0]*halfsz), newPt2[1] + (nor1[1]*halfsz), newPt2[2] + (nor1[2]*halfsz)) )
		me.verts.append(NMesh.Vert(newPt1[0] + (nor1[0]*halfsz), newPt1[1] + (nor1[1]*halfsz), newPt1[2] + (nor1[2]*halfsz)) )
		
		fA = NMesh.Face(me.verts[-4:])		
		
		# make face B
		me.verts.append(NMesh.Vert(e.v1.co[0] + (nor1[0]*-halfsz), e.v1.co[1] + (nor1[1]*-halfsz), e.v1.co[2] + (nor1[2]*-halfsz)) )
		me.verts.append(NMesh.Vert(e.v2.co[0] + (nor1[0]*-halfsz), e.v2.co[1] + (nor1[1]*-halfsz), e.v2.co[2] + (nor1[2]*-halfsz)) )
		
		me.verts.append(NMesh.Vert(newPt2[0] + (nor1[0]*-halfsz), newPt2[1] + (nor1[1]*-halfsz), newPt2[2] + (nor1[2]*-halfsz)) )
		me.verts.append(NMesh.Vert(newPt1[0] + (nor1[0]*-halfsz), newPt1[1] + (nor1[1]*-halfsz), newPt1[2] + (nor1[2]*-halfsz)) )
		
		fB = NMesh.Face([me.verts[-1], me.verts[-2], me.verts[-3], me.verts[-4]])
		
		# make face C- top
		fC = NMesh.Face([fB.v[1], fB.v[0], fA.v[3], fA.v[2]])
		
		# make face D- bottom
		fD = NMesh.Face([fA.v[1], fA.v[0], fB.v[3], fB.v[2]])
		
		
		# a negative number is used for an inset wire- this flips the normals the wrong way- For easyness this is a simple way to fix the problem.
		if globalSize < 0:
			fA.v.reverse()
			fB.v.reverse()
			fC.v.reverse()
			fD.v.reverse()
		
		me.faces.extend([fA, fB, fC, fD])
		eIdx+=1
	print 'Wire Time: %.6f' % (sys.time()-t)
示例#26
0
def docyl(S, R, P0, P1):
    coords = []
    p0 = Vector(P0[0], P0[1], P0[2])
    p1 = Vector(P1[0], P1[1], P1[2])
    t = Vector(P1[0] - P0[0], P1[1] - P0[1], P1[2] - P0[2])
    t.normalize()
    if t * Vector(1, 0, 0) < 0.8:
        n = Vector(1, 0, 0) - (Vector(1, 0, 0) * t) * t
    else:
        n = Vector(0, 1, 0) - (Vector(0, 1, 0) * t) * t
    n.normalize()

    b = Vector(t[1] * n[2] - t[2] * n[1], t[2] * n[0] - t[0] * n[2],
               t[0] * n[1] - t[1] * n[0])
    b.normalize()

    for i in xrange(S):
        angle = float(i) * 2. * pi / float(S)
        vec = cos(angle) * R * n + sin(angle) * R * b

        c0 = p0 + vec
        c1 = p1 + vec
        coords += [[c0[0], c0[1], c0[2]]]
        coords += [[c1[0], c1[1], c1[2]]]

    faces = []
    for i in xrange(S):
        faces += [[
            2 * i, (2 * i + 1) % (2 * S), (2 * i + 3) % (2 * S),
            (2 * i + 2) % (2 * S)
        ]]

    me = Mesh.New('Strut')
    me.verts.extend(coords)
    me.faces.extend(faces)
    return Scene.GetCurrent().objects.new(me)
def uvcalc_main(obList):
    global USER_FILL_HOLES
    global USER_FILL_HOLES_QUALITY
    global USER_STRETCH_ASPECT
    global USER_ISLAND_MARGIN

    # objects= bpy.data.scenes.active.objects

    # we can will tag them later.
    # obList =  [ob for ob in objects.context if ob.type == 'Mesh']

    # Face select object may not be selected.
    # ob = objects.active
    # if ob and ob.sel == 0 and ob.type == 'Mesh':
    # 	# Add to the list
    # 	obList =[ob]
    # del objects

    if not obList:
        Draw.PupMenu("error, no selected mesh objects")
        return

        # Create the variables.
    USER_PROJECTION_LIMIT = Draw.Create(66)
    USER_ONLY_SELECTED_FACES = Draw.Create(1)
    USER_SHARE_SPACE = Draw.Create(1)  # Only for hole filling.
    USER_STRETCH_ASPECT = Draw.Create(1)  # Only for hole filling.
    USER_ISLAND_MARGIN = Draw.Create(0.0)  # Only for hole filling.
    USER_FILL_HOLES = Draw.Create(0)
    USER_FILL_HOLES_QUALITY = Draw.Create(50)  # Only for hole filling.
    USER_VIEW_INIT = Draw.Create(0)  # Only for hole filling.
    USER_AREA_WEIGHT = Draw.Create(1)  # Only for hole filling.

    pup_block = [
        "Projection",
        ("Angle Limit:", USER_PROJECTION_LIMIT, 1, 89, "lower for more projection groups, higher for less distortion."),
        ("Selected Faces Only", USER_ONLY_SELECTED_FACES, "Use only selected faces from all selected meshes."),
        ("Init from view", USER_VIEW_INIT, "The first projection will be from the view vector."),
        ("Area Weight", USER_AREA_WEIGHT, "Weight projections vector by face area."),
        "",
        "",
        "",
        "UV Layout",
        ("Share Tex Space", USER_SHARE_SPACE, "Objects Share texture space, map all objects into 1 uvmap."),
        ("Stretch to bounds", USER_STRETCH_ASPECT, "Stretch the final output to texture bounds."),
        ("Island Margin:", USER_ISLAND_MARGIN, 0.0, 0.5, "Margin to reduce bleed from adjacent islands."),
        "Fill in empty areas",
        ("Fill Holes", USER_FILL_HOLES, "Fill in empty areas reduced texture waistage (slow)."),
        (
            "Fill Quality:",
            USER_FILL_HOLES_QUALITY,
            1,
            100,
            "Depends on fill holes, how tightly to fill UV holes, (higher is slower)",
        ),
    ]

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

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

        # Convert from being button types
    USER_PROJECTION_LIMIT = USER_PROJECTION_LIMIT.val
    USER_ONLY_SELECTED_FACES = USER_ONLY_SELECTED_FACES.val
    USER_SHARE_SPACE = USER_SHARE_SPACE.val
    USER_STRETCH_ASPECT = USER_STRETCH_ASPECT.val
    USER_ISLAND_MARGIN = USER_ISLAND_MARGIN.val
    USER_FILL_HOLES = USER_FILL_HOLES.val
    USER_FILL_HOLES_QUALITY = USER_FILL_HOLES_QUALITY.val
    USER_VIEW_INIT = USER_VIEW_INIT.val
    USER_AREA_WEIGHT = USER_AREA_WEIGHT.val

    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 = Window.EditMode()
    # if is_editmode:
    # 	Window.EditMode(0)
    # Assume face select mode! an annoying hack to toggle face select mode because Mesh dosent like faceSelectMode.

    if USER_SHARE_SPACE:
        # Sort by data name so we get consistant results
        try:
            obList.sort(key=lambda ob: ob.getData(name_only=1))
        except:
            obList.sort(lambda ob1, ob2: cmp(ob1.getData(name_only=1), ob2.getData(name_only=1)))

        collected_islandList = []

        # Window.WaitCursor(1)

    time1 = sys.time()

    # Tag as False se we dont operate on teh same mesh twice.
    bpy.data.meshes.tag = False

    for ob in obList:
        me = ob.getData(mesh=1)

        if me.tag or me.lib:
            continue

            # Tag as used
        me.tag = True

        if not me.faceUV:  # Mesh has no UV Coords, dont bother.
            me.faceUV = True

        if USER_ONLY_SELECTED_FACES:
            meshFaces = [thickface(f) for f in me.faces if f.sel]
        else:
            meshFaces = map(thickface, me.faces)

        if not meshFaces:
            continue

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

            # =======
            # Generate a projection list from face normals, this is ment 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.
        try:
            meshFaces.sort(key=lambda a: -a.area)
        except:
            meshFaces.sort(lambda a, b: cmp(b.area, 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()

            # 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.matrixWorld.copy().invert().rotationPart()
            ]  # We add to this allong the way
        else:
            projectVecs = []

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

        # Predent that the most unique angke 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 xrange(len(tempMeshFaces) - 1, -1, -1):
                # Use half the angle limit so we dont 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)
            if USER_AREA_WEIGHT:
                for fprop in newProjectMeshFaces:
                    averageVec += fprop.no * fprop.area
            else:
                for fprop in newProjectMeshFaces:
                    averageVec += fprop.no

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

                # 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 xrange(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 representive 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 xrange(len(projectVecs))]

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

        for fIdx in xrange(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 alredy 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 xrange(len(projectVecs)):
            # Account for projectVecs having no faces.
            if not faceProjectionGroupList[i]:
                continue

                # Make a projection matrix from a unit length vector.
            MatProj = VectoMat(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):
                    f_uv[j][:] = (MatProj * v.co)[:2]

        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:
        # Window.DrawProgressBar(0.9, "Box Packing for all objects...")
        packIslands(collected_islandList)

    print "Smart Projection time: %.2f" % (sys.time() - time1)
示例#28
0
		def makeMeshMaterialCopy(matName, faces):			
			'''
			Make a new mesh with only face the faces that use this material.
			faces can be any iterable object - containing ints.
			'''
			
			faceVertUsers = [False] * len(myContextMesh_vertls)
			ok=0
			for fIdx in faces:
				for vindex in myContextMesh_facels[fIdx]:
					faceVertUsers[vindex] = True
					if matName != None: # if matName is none then this is a set(), meaning we are using the untextured faces and do not need to store textured faces.
						materialFaces.add(fIdx)
					ok=1
			
			if not ok:
				return
					
			myVertMapping = {}
			vertMappingIndex = 0
			
			vertsToUse = [i for i in xrange(len(myContextMesh_vertls)) if faceVertUsers[i]]
			myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] )
			
			tempName= '%s_%s' % (contextObName, matName) # matName may be None.
			bmesh = bpy.data.meshes.new(tempName)
			
			if matName == None:
				img= None
			else:
				bmat = MATDICT[matName][1]
				bmesh.materials= [bmat]
				try:	img= TEXTURE_DICT[bmat.name]
				except:	img= None
				
			bmesh_verts = bmesh.verts
			bmesh_verts.extend( [Vector()] )
			bmesh_verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
			# +1 because of DUMMYVERT
			face_mapping= bmesh.faces.extend( [ [ bmesh_verts[ myVertMapping[vindex]+1] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces ], indexList=True )
			
			if bmesh.faces and (contextMeshUV or img):
				bmesh.faceUV= 1
				for ii, i in enumerate(faces):
					
					# Mapped index- faces may have not been added- if so, then map to the correct index
					# BUGGY API - face_mapping is not always the right length
					map_index= face_mapping[ii]
					
					if map_index != None:
						targetFace= bmesh.faces[map_index]
						if contextMeshUV:
							# v.index-1 because of the DUMMYVERT
							targetFace.uv= [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
						if img:
							targetFace.image= img
			
			# bmesh.transform(contextMatrix)
			ob = SCN_OBJECTS.new(bmesh, tempName)
			'''
			if contextMatrix_tx:
				ob.setMatrix(contextMatrix_tx)
			'''
			
			if contextMatrix_rot:
				ob.setMatrix(contextMatrix_rot)
			
			importedObjects.append(ob)
			bmesh.calcNormals()
示例#29
0
def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE,
                            PREF_KEEP_ASPECT,
                            PREF_IMAGE_MARGIN):  #, PREF_SIZE_FROM_UV=True):
    '''
	Main packing function
	
	All meshes from mesh_list must have faceUV else this function will fail.
	'''
    face_groups = {}

    for me in mesh_list:
        for f in me.faces:
            if f.mode & TEXMODE:
                image = f.image
                if image:
                    try:
                        face_groups[
                            image.name]  # will fail if teh groups not added.
                    except:
                        try:
                            size = image.size
                        except:
                            B.Draw.PupMenu(
                                'Aborting: Image cold not be loaded|' +
                                image.name)
                            return

                        face_groups[image.name] = faceGroup(
                            mesh_list, image, size, PREF_IMAGE_MARGIN)

    if not face_groups:
        B.Draw.PupMenu('No Images found in mesh(es). Aborting!')
        return

    if len(face_groups) < 2:
        B.Draw.PupMenu(
            'Only 1 image found|Select a mesh(es) using 2 or more images.')
        return
    '''
	if PREF_SIZE_FROM_UV:
		for fg in face_groups.itervalues():
			fg.set_worldspace_scale()
	'''

    # RENDER THE FACES.
    render_scn = B.Scene.New()
    render_scn.makeCurrent()
    render_context = render_scn.getRenderingContext()
    render_context.setRenderPath(
        '')  # so we can ignore any existing path and save to the abs path.

    PREF_IMAGE_PATH_EXPAND = B.sys.expandpath(PREF_IMAGE_PATH) + '.png'

    # TEST THE FILE WRITING.
    try:
        # Can we write to this file???
        f = open(PREF_IMAGE_PATH_EXPAND, 'w')
        f.close()
    except:
        B.Draw.PupMenu('Error%t|Could not write to path|' +
                       PREF_IMAGE_PATH_EXPAND)
        return

    render_context.imageSizeX(PREF_IMAGE_SIZE)
    render_context.imageSizeY(PREF_IMAGE_SIZE)
    render_context.enableOversampling(True)
    render_context.setOversamplingLevel(16)
    render_context.setRenderWinSize(100)
    render_context.setImageType(Render.PNG)
    render_context.enableExtensions(True)
    render_context.enablePremultiply()  # No alpha needed.
    render_context.enableRGBAColor()
    render_context.threads = 2

    #Render.EnableDispView() # Broken??

    # New Mesh and Object
    render_mat = B.Material.New()
    render_mat.mode |= \
      B.Material.Modes.SHADELESS | \
      B.Material.Modes.TEXFACE | \
      B.Material.Modes.TEXFACE_ALPHA | \
      B.Material.Modes.ZTRANSP

    render_mat.setAlpha(0.0)

    render_me = B.Mesh.New()
    render_me.verts.extend([Vector(
        0, 0, 0)])  # Stupid, dummy vert, preverts errors. when assigning UV's/
    render_ob = B.Object.New('Mesh')
    render_ob.link(render_me)
    render_scn.link(render_ob)
    render_me.materials = [render_mat]

    # New camera and object
    render_cam_data = B.Camera.New('ortho')
    render_cam_ob = B.Object.New('Camera')
    render_cam_ob.link(render_cam_data)
    render_scn.link(render_cam_ob)
    render_scn.objects.camera = render_cam_ob

    render_cam_data.type = 'ortho'
    render_cam_data.scale = 1.0

    # Position the camera
    render_cam_ob.LocZ = 1.0
    render_cam_ob.LocX = 0.5
    render_cam_ob.LocY = 0.5

    # List to send to to boxpack function.
    boxes2Pack = [fg.box_pack for fg in face_groups.itervalues()]
    packWidth, packHeight = B.Geometry.BoxPack2D(boxes2Pack)

    if PREF_KEEP_ASPECT:
        packWidth = packHeight = max(packWidth, packHeight)

    # packedLs is a list of [(anyUniqueID, left, bottom, width, height)...]
    # Re assign the face groups boxes to the face_group.
    for box in boxes2Pack:
        face_groups[box[4]].box_pack = box  # box[4] is the ID (image name)

    # Add geometry to the mesh
    for fg in face_groups.itervalues():
        # Add verts clockwise from the bottom left.
        _x = fg.box_pack[0] / packWidth
        _y = fg.box_pack[1] / packHeight
        _w = fg.box_pack[2] / packWidth
        _h = fg.box_pack[3] / packHeight

        render_me.verts.extend([\
        Vector(_x, _y, 0),\
        Vector(_x, _y +_h, 0),\
        Vector(_x + _w, _y +_h, 0),\
        Vector(_x + _w, _y, 0),\
        ])

        render_me.faces.extend([\
        render_me.verts[-1],\
        render_me.verts[-2],\
        render_me.verts[-3],\
        render_me.verts[-4],\
        ])

        target_face = render_me.faces[-1]
        target_face.image = fg.image
        target_face.mode |= TEXMODE

        # Set the UV's, we need to flip them HOZ?
        target_face.uv[0].x = target_face.uv[1].x = fg.xmax
        target_face.uv[2].x = target_face.uv[3].x = fg.xmin

        target_face.uv[0].y = target_face.uv[3].y = fg.ymin
        target_face.uv[1].y = target_face.uv[2].y = fg.ymax

        for uv in target_face.uv:
            uv_rot = ((uv - fg.cent) * fg.rot_mat[1]) + fg.cent
            uv.x = uv_rot.x
            uv.y = uv_rot.y

    render_context.render()
    Render.CloseRenderWindow()
    render_context.saveRenderedImage(PREF_IMAGE_PATH_EXPAND)

    #if not B.sys.exists(PREF_IMAGE_PATH_EXPAND):
    #	raise 'Error!!!'

    # NOW APPLY THE SAVED IMAGE TO THE FACES!
    #print PREF_IMAGE_PATH_EXPAND
    try:
        target_image = B.Image.Load(PREF_IMAGE_PATH_EXPAND)
    except:
        B.Draw.PupMenu('Error: Could not render or load the image at path|' +
                       PREF_IMAGE_PATH_EXPAND)
        return

    # Set to the 1 image.
    for me in mesh_list:
        for f in me.faces:
            if f.mode & TEXMODE and f.image:
                f.image = target_image

    for fg in face_groups.itervalues():
        fg.move2packed(packWidth, packHeight)

    scn.makeCurrent()
    render_me.verts = None  # free a tiny amount of memory.
    B.Scene.Unlink(render_scn)
    target_image.makeCurrent()
示例#30
0
	def __init__(self, loop, me, closed): # Vert loop
		# Use next and prev, nextDist, prevDist
		
		# Get Loops centre.
		fac= len(loop)
		verts = me.verts
		self.centre= reduce(lambda a,b: a+verts[b].co/fac, loop, Vector())
		
		# Convert Vert loop to Edges.
		self.edges = [edge(verts[loop[vIdx-1]], verts[loop[vIdx]]) for vIdx in xrange(len(loop))]
		
		if not closed:
			self.edges[0].fake = True # fake edge option
			
		self.closed = closed
			
		
		# Assign linked list
		for eIdx in xrange(len(self.edges)-1):
			self.edges[eIdx].next = self.edges[eIdx+1]
			self.edges[eIdx].prev = self.edges[eIdx-1]
		# Now last
		self.edges[-1].next = self.edges[0]
		self.edges[-1].prev = self.edges[-2]
		
		
		
		# GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP.
		self.normal = Vector()
		for e in self.edges:
			n = (self.centre-e.co1).cross(self.centre-e.co2)
			# Do we realy need tot normalize?
			n.normalize()
			self.normal += n
			
			# Generate the angle
			va= e.cent - e.prev.cent
			vb= e.next.cent - e.cent
			
			e.angle= AngleBetweenVecs(va, vb)
		
		# Blur the angles
		#for e in self.edges:
		#	e.angle= (e.angle+e.next.angle)/2
		
		# Blur the angles
		#for e in self.edges:
		#	e.angle= (e.angle+e.prev.angle)/2
			
		self.normal.normalize()
		
		# Generate a normal for each edge.
		for e in self.edges:
			
			n1 = e.co1
			n2 = e.co2
			n3 = e.prev.co1
			
			a = n1-n2
			b = n1-n3
			normal1 = a.cross(b)
			normal1.normalize()
			
			n1 = e.co2
			n3 = e.next.co2
			n2 = e.co1
			
			a = n1-n2
			b = n1-n3
			
			normal2 = a.cross(b)
			normal2.normalize()
			
			# Reuse normal1 var
			normal1 += normal1 + normal2
			normal1.normalize()
			
			e.normal = normal1
def main():
    global USER_FILL_HOLES
    global USER_FILL_HOLES_QUALITY
    global USER_STRETCH_ASPECT
    global USER_ISLAND_MARGIN

    objects = bpy.data.scenes.active.objects

    # we can will tag them later.
    obList = [ob for ob in objects.context if ob.type == 'Mesh']

    # Face select object may not be selected.
    ob = objects.active
    if ob and ob.sel == 0 and ob.type == 'Mesh':
        # Add to the list
        obList = [ob]
    del objects

    if not obList:
        Draw.PupMenu('error, no selected mesh objects')
        return

    # Create the variables.
    USER_PROJECTION_LIMIT = Draw.Create(66)
    USER_ONLY_SELECTED_FACES = Draw.Create(1)
    USER_SHARE_SPACE = Draw.Create(1)  # Only for hole filling.
    USER_STRETCH_ASPECT = Draw.Create(1)  # Only for hole filling.
    USER_ISLAND_MARGIN = Draw.Create(0.0)  # Only for hole filling.
    USER_FILL_HOLES = Draw.Create(0)
    USER_FILL_HOLES_QUALITY = Draw.Create(50)  # Only for hole filling.
    USER_VIEW_INIT = Draw.Create(0)  # Only for hole filling.
    USER_AREA_WEIGHT = Draw.Create(1)  # Only for hole filling.


    pup_block = [\
    'Projection',\
    ('Angle Limit:', USER_PROJECTION_LIMIT, 1, 89, 'lower for more projection groups, higher for less distortion.'),\
    ('Selected Faces Only', USER_ONLY_SELECTED_FACES, 'Use only selected faces from all selected meshes.'),\
    ('Init from view', USER_VIEW_INIT, 'The first projection will be from the view vector.'),\
    ('Area Weight', USER_AREA_WEIGHT, 'Weight projections vector by face area.'),\
    '',\
    '',\
    '',\
    'UV Layout',\
    ('Share Tex Space', USER_SHARE_SPACE, 'Objects Share texture space, map all objects into 1 uvmap.'),\
    ('Stretch to bounds', USER_STRETCH_ASPECT, 'Stretch the final output to texture bounds.'),\
    ('Island Margin:', USER_ISLAND_MARGIN, 0.0, 0.5, 'Margin to reduce bleed from adjacent islands.'),\
    'Fill in empty areas',\
    ('Fill Holes', USER_FILL_HOLES, 'Fill in empty areas reduced texture waistage (slow).'),\
    ('Fill Quality:', USER_FILL_HOLES_QUALITY, 1, 100, 'Depends on fill holes, how tightly to fill UV holes, (higher is slower)'),\
    ]

    # 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:
		sys.sleep(10)
	'''

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

    # Convert from being button types
    USER_PROJECTION_LIMIT = USER_PROJECTION_LIMIT.val
    USER_ONLY_SELECTED_FACES = USER_ONLY_SELECTED_FACES.val
    USER_SHARE_SPACE = USER_SHARE_SPACE.val
    USER_STRETCH_ASPECT = USER_STRETCH_ASPECT.val
    USER_ISLAND_MARGIN = USER_ISLAND_MARGIN.val
    USER_FILL_HOLES = USER_FILL_HOLES.val
    USER_FILL_HOLES_QUALITY = USER_FILL_HOLES_QUALITY.val
    USER_VIEW_INIT = USER_VIEW_INIT.val
    USER_AREA_WEIGHT = USER_AREA_WEIGHT.val

    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 = Window.EditMode()
    if is_editmode:
        Window.EditMode(0)
    # Assume face select mode! an annoying hack to toggle face select mode because Mesh dosent like faceSelectMode.

    if USER_SHARE_SPACE:
        # Sort by data name so we get consistant results
        try:
            obList.sort(key=lambda ob: ob.getData(name_only=1))
        except:
            obList.sort(lambda ob1, ob2: cmp(ob1.getData(name_only=1),
                                             ob2.getData(name_only=1)))

        collected_islandList = []

    Window.WaitCursor(1)

    time1 = sys.time()

    # Tag as False se we dont operate on teh same mesh twice.
    bpy.data.meshes.tag = False

    for ob in obList:
        me = ob.getData(mesh=1)

        if me.tag or me.lib:
            continue

        # Tag as used
        me.tag = True

        if not me.faceUV:  # Mesh has no UV Coords, dont bother.
            me.faceUV = True

        if USER_ONLY_SELECTED_FACES:
            meshFaces = [thickface(f) for f in me.faces if f.sel]
        else:
            meshFaces = map(thickface, me.faces)

        if not meshFaces:
            continue

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

        # =======
        # Generate a projection list from face normals, this is ment 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.
        try:
            meshFaces.sort(key=lambda a: -a.area)
        except:
            meshFaces.sort(lambda a, b: cmp(b.area, 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()

        # 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.matrixWorld.copy().invert().rotationPart()
            ]  # We add to this allong the way
        else:
            projectVecs = []

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

        # Predent that the most unique angke 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 xrange(len(tempMeshFaces) - 1, -1, -1):
                # Use half the angle limit so we dont 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)
            if USER_AREA_WEIGHT:
                for fprop in newProjectMeshFaces:
                    averageVec += (fprop.no * fprop.area)
            else:
                for fprop in newProjectMeshFaces:
                    averageVec += fprop.no

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

            # 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 xrange(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 representive 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 xrange(len(projectVecs))]

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

        for fIdx in xrange(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 alredy 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 xrange(len(projectVecs)):
            # Account for projectVecs having no faces.
            if not faceProjectionGroupList[i]:
                continue

            # Make a projection matrix from a unit length vector.
            MatProj = VectoMat(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):
                    f_uv[j][:] = (MatProj * v.co)[:2]

        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:
        Window.DrawProgressBar(0.9, "Box Packing for all objects...")
        packIslands(collected_islandList)

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

    if is_editmode:
        Window.EditMode(1)

    Window.DrawProgressBar(1.0, "")
    Window.WaitCursor(0)
    Window.RedrawAll()
示例#32
0
def generate_footprint():

    # get mesh objects
    objects = filter(
        lambda obj: obj.type == 'Mesh' and obj.name.lower().startswith(
            'footprint'), scene.objects)

    if not objects:
        error(
            'Error! Object list is empty. (No mesh objects whose names begin with "footprint".)'
        )
        return False

    # check whether visual transforms applied
    v = [
        obj for obj in objects
        if tuple(obj.rot) != (0, 0, 0) or tuple(obj.size) != (1, 1, 1)
    ]
    if v:
        error('Error! The following mesh ' +
              ('objects have' if len(v) > 1 else 'object has') +
              ' non-applied visual transforms:')
        for obj in v:
            error('\x20\x20%s -> rot: %s, size: %s' %
                  (str(obj), str(obj.rot), str(obj.size)))
        error('Solution: apply visual transforms.')
        return False

    footprint = []

    for obj in objects:

        log(str(obj))

        mesh = obj.getData(mesh=True)

        obj_loc = obj.matrix[3].xyz + Vector(0.5, 0.5, 0)

        name = obj.name.split('.')
        name = name[1] if len(name) > 1 else "0"

        def test_point(x0, y0, i, j):

            x = x0 + 0.0625 * (i + 0.5)
            y = y0 + 0.0625 * (j + 0.5)

            ray, orig = Vector(0, 0, 1), Vector(x, y, 0)

            for face in mesh.faces:
                verts = [v.co + obj_loc for v in face.verts]

                if Intersect(verts[0], verts[1], verts[2], ray, orig, 1) or \
                 ( len(face.verts) == 4 and \
                   Intersect(verts[0], verts[2], verts[3], ray, orig, 1) ):
                    return True

            return False

        # bounding box
        box = obj.getBoundBox(1)
        X, Y, Z = zip(*map(tuple, box))
        Z = None  # not used

        minx, maxx = int(floor(min(X) + 0.5)), int(ceil(max(X) + 0.5))
        miny, maxy = int(floor(min(Y) + 0.5)), int(ceil(max(Y) + 0.5))

        data = [(0x02, 'minx', minx), (0x02, 'maxx', maxx - 1),
                (0x02, 'miny', miny), (0x02, 'maxy', maxy - 1)]

        log('--Name: "%s"' % name)
        log('--Size: %i x %i' % (maxx - minx, maxy - miny))

        for x, y in product(xrange(minx, maxx), xrange(miny, maxy)):

            key = '(%i,%i)' % (x, y)

            s = ''

            for j in xrange(16):
                a = sum(2**i for i in xrange(16) if test_point(x, y, i, j))
                s += pack('<H', a)
            data.append((0x09, key, s))

        footprint.append((0x07, name, data))

    #<- objects

    return (0x07, 'footprint', footprint)
示例#33
0
class edgeLoop(object):
    __slots__ = 'centre', 'edges', 'normal', 'closed', 'backup_edges'

    def __init__(self, loop, me, closed):  # Vert loop
        # Use next and prev, nextDist, prevDist

        # Get Loops centre.
        fac = len(loop)
        verts = me.verts
        self.centre = reduce(lambda a, b: a + verts[b].co / fac, loop,
                             Vector())

        # Convert Vert loop to Edges.
        self.edges = [
            edge(verts[loop[vIdx - 1]], verts[loop[vIdx]])
            for vIdx in xrange(len(loop))
        ]

        if not closed:
            self.edges[0].fake = True  # fake edge option

        self.closed = closed

        # Assign linked list
        for eIdx in xrange(len(self.edges) - 1):
            self.edges[eIdx].next = self.edges[eIdx + 1]
            self.edges[eIdx].prev = self.edges[eIdx - 1]
        # Now last
        self.edges[-1].next = self.edges[0]
        self.edges[-1].prev = self.edges[-2]

        # GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP.
        self.normal = Vector()
        for e in self.edges:
            n = (self.centre - e.co1).cross(self.centre - e.co2)
            # Do we realy need tot normalize?
            n.normalize()
            self.normal += n

            # Generate the angle
            va = e.cent - e.prev.cent
            vb = e.next.cent - e.cent

            e.angle = AngleBetweenVecs(va, vb)

        # Blur the angles
        #for e in self.edges:
        #	e.angle= (e.angle+e.next.angle)/2

        # Blur the angles
        #for e in self.edges:
        #	e.angle= (e.angle+e.prev.angle)/2

        self.normal.normalize()

        # Generate a normal for each edge.
        for e in self.edges:

            n1 = e.co1
            n2 = e.co2
            n3 = e.prev.co1

            a = n1 - n2
            b = n1 - n3
            normal1 = a.cross(b)
            normal1.normalize()

            n1 = e.co2
            n3 = e.next.co2
            n2 = e.co1

            a = n1 - n2
            b = n1 - n3

            normal2 = a.cross(b)
            normal2.normalize()

            # Reuse normal1 var
            normal1 += normal1 + normal2
            normal1.normalize()

            e.normal = normal1
            #print e.normal

    def backup(self):
        # Keep a backup of the edges
        self.backup_edges = self.edges[:]

    def restore(self):
        self.edges = self.backup_edges[:]
        for e in self.edges:
            e.removed = 0

    def reverse(self):
        self.edges.reverse()
        self.normal.negate()

        for e in self.edges:
            e.normal.negate()
            e.v1, e.v2 = e.v2, e.v1
            e.co1, e.co2 = e.co2, e.co1
            e.next, e.prev = e.prev, e.next

    def removeSmallest(self, cullNum, otherLoopLen):
        '''
		Removes N Smallest edges and backs up the loop,
		this is so we can loop between 2 loops as if they are the same length,
		backing up and restoring incase the loop needs to be skinned with another loop of a different length.
		'''
        global CULL_METHOD
        if CULL_METHOD == 1:  # Shortest edge
            eloopCopy = self.edges[:]

            # Length sort, smallest first
            try:
                eloopCopy.sort(key=lambda e1: e1.length)
            except:
                eloopCopy.sort(lambda e1, e2: cmp(e1.length, e2.length))

            # Dont use atm
            #eloopCopy.sort(lambda e1, e2: cmp(e1.angle*e1.length, e2.angle*e2.length)) # Length sort, smallest first
            #eloopCopy.sort(lambda e1, e2: cmp(e1.angle, e2.angle)) # Length sort, smallest first

            remNum = 0
            for i, e in enumerate(eloopCopy):
                if not e.fake:
                    e.removed = 1
                    self.edges.remove(
                        e)  # Remove from own list, still in linked list.
                    remNum += 1

                    if not remNum < cullNum:
                        break

        else:  # CULL METHOD is even

            culled = 0

            step = int(otherLoopLen / float(cullNum)) * 2

            currentEdge = self.edges[0]
            while culled < cullNum:

                # Get the shortest face in the next STEP
                step_count = 0
                bestAng = 360.0
                smallestEdge = None
                while step_count <= step or smallestEdge == None:
                    step_count += 1
                    if not currentEdge.removed:  # 0 or -1 will not be accepted
                        if currentEdge.angle < bestAng and not currentEdge.fake:
                            smallestEdge = currentEdge
                            bestAng = currentEdge.angle

                    currentEdge = currentEdge.next

                # In that stepping length we have the smallest edge.remove it
                smallestEdge.removed = 1
                self.edges.remove(smallestEdge)

                # Start scanning from the edge we found? - result is over fanning- no good.
                #currentEdge= smallestEdge.next

                culled += 1
示例#34
0
			def getuv():
				temp_data=file.read(STRUCT_SIZE_2FLOAT)
				new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each
				return Vector( unpack('<2f', temp_data) )
示例#35
0
文件: wire.py 项目: mcarlen/libbiarc
def docyl(S, R, Pts):
    coords = []
    p0 = Vector(Pts[0][0], Pts[0][1], Pts[0][2])
    p1 = Vector(Pts[1][0], Pts[1][1], Pts[1][2])
    t = Vector(Pts[1][0] - Pts[0][0], Pts[1][1] - Pts[0][1],
               Pts[1][2] - Pts[0][2])
    t.normalize()
    if t * Vector(1, 0, 0) < 0.8:
        n = Vector(1, 0, 0) - (Vector(1, 0, 0) * t) * t
    else:
        n = Vector(0, 1, 0) - (Vector(0, 1, 0) * t) * t
    n.normalize()

    b = Vector(t[1] * n[2] - t[2] * n[1], t[2] * n[0] - t[0] * n[2],
               t[0] * n[1] - t[1] * n[0])
    b.normalize()

    for i in xrange(S):
        angle = float(i) * 2. * pi / float(S)
        vec = cos(angle) * R * n + sin(angle) * R * b

        c0 = p0 + vec
        c1 = p1 + vec
        coords += [[c0[0], c0[1], c0[2]]]
        coords += [[c1[0], c1[1], c1[2]]]

    faces = []
    for i in xrange(S):
        faces += [[
            2 * i, (2 * i + 2) % (2 * S), (2 * i + 3) % (2 * S),
            (2 * i + 1) % (2 * S)
        ]]

    # midpoints
    coords += [[p0[0], p0[1], p0[2]]]
    coords += [[p1[0], p1[1], p1[2]]]

    cid0 = len(coords) - 2
    cid1 = len(coords) - 1
    for i in xrange(S):
        idx = []
        idx2 = []
        idx.append(2 * i + 0)
        idx.append(cid0)
        idx.append(2 * ((i + 1) % S))
        idx2.append(2 * i + 1)
        idx2.append(2 * ((i + 1) % S) + 1)
        idx2.append(cid1)
        faces += [idx]
        faces += [idx2]
    print faces

    me = Mesh.New('Strut')
    me.verts.extend(coords)
    me.faces.extend(faces)

    # Add new object to scene and return it
    return Scene.GetCurrent().objects.new(me)
示例#36
0
class edgeLoop(object):
	__slots__ = 'centre', 'edges', 'normal', 'closed', 'backup_edges'
	def __init__(self, loop, me, closed): # Vert loop
		# Use next and prev, nextDist, prevDist
		
		# Get Loops centre.
		fac= len(loop)
		verts = me.verts
		self.centre= reduce(lambda a,b: a+verts[b].co/fac, loop, Vector())
		
		# Convert Vert loop to Edges.
		self.edges = [edge(verts[loop[vIdx-1]], verts[loop[vIdx]]) for vIdx in xrange(len(loop))]
		
		if not closed:
			self.edges[0].fake = True # fake edge option
			
		self.closed = closed
			
		
		# Assign linked list
		for eIdx in xrange(len(self.edges)-1):
			self.edges[eIdx].next = self.edges[eIdx+1]
			self.edges[eIdx].prev = self.edges[eIdx-1]
		# Now last
		self.edges[-1].next = self.edges[0]
		self.edges[-1].prev = self.edges[-2]
		
		
		
		# GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP.
		self.normal = Vector()
		for e in self.edges:
			n = (self.centre-e.co1).cross(self.centre-e.co2)
			# Do we realy need tot normalize?
			n.normalize()
			self.normal += n
			
			# Generate the angle
			va= e.cent - e.prev.cent
			vb= e.next.cent - e.cent
			
			e.angle= AngleBetweenVecs(va, vb)
		
		# Blur the angles
		#for e in self.edges:
		#	e.angle= (e.angle+e.next.angle)/2
		
		# Blur the angles
		#for e in self.edges:
		#	e.angle= (e.angle+e.prev.angle)/2
			
		self.normal.normalize()
		
		# Generate a normal for each edge.
		for e in self.edges:
			
			n1 = e.co1
			n2 = e.co2
			n3 = e.prev.co1
			
			a = n1-n2
			b = n1-n3
			normal1 = a.cross(b)
			normal1.normalize()
			
			n1 = e.co2
			n3 = e.next.co2
			n2 = e.co1
			
			a = n1-n2
			b = n1-n3
			
			normal2 = a.cross(b)
			normal2.normalize()
			
			# Reuse normal1 var
			normal1 += normal1 + normal2
			normal1.normalize()
			
			e.normal = normal1
			#print e.normal


		
	def backup(self):
		# Keep a backup of the edges
		self.backup_edges = self.edges[:]
			
	def restore(self):
		self.edges = self.backup_edges[:]
		for e in self.edges:
			e.removed = 0
		
	def reverse(self):
		self.edges.reverse()
		self.normal.negate()
		
		for e in self.edges:
			e.normal.negate()
			e.v1, e.v2 = e.v2, e.v1
			e.co1, e.co2 = e.co2, e.co1
			e.next, e.prev = e.prev, e.next
		
	
	def removeSmallest(self, cullNum, otherLoopLen):
		'''
		Removes N Smallest edges and backs up the loop,
		this is so we can loop between 2 loops as if they are the same length,
		backing up and restoring incase the loop needs to be skinned with another loop of a different length.
		'''
		global CULL_METHOD
		if CULL_METHOD == 1: # Shortest edge
			eloopCopy = self.edges[:]
			
			# Length sort, smallest first
			try:	eloopCopy.sort(key = lambda e1: e1.length)
			except:	eloopCopy.sort(lambda e1, e2: cmp(e1.length, e2.length ))
			
			# Dont use atm
			#eloopCopy.sort(lambda e1, e2: cmp(e1.angle*e1.length, e2.angle*e2.length)) # Length sort, smallest first
			#eloopCopy.sort(lambda e1, e2: cmp(e1.angle, e2.angle)) # Length sort, smallest first
			
			remNum = 0
			for i, e in enumerate(eloopCopy):
				if not e.fake:
					e.removed = 1
					self.edges.remove( e ) # Remove from own list, still in linked list.
					remNum += 1
				
					if not remNum < cullNum:
						break
			
		else: # CULL METHOD is even
				
			culled = 0
			
			step = int(otherLoopLen / float(cullNum)) * 2
			
			currentEdge = self.edges[0]
			while culled < cullNum:
				
				# Get the shortest face in the next STEP
				step_count= 0
				bestAng= 360.0
				smallestEdge= None
				while step_count<=step or smallestEdge==None:
					step_count+=1
					if not currentEdge.removed: # 0 or -1 will not be accepted
						if currentEdge.angle<bestAng and not currentEdge.fake:
							smallestEdge= currentEdge
							bestAng= currentEdge.angle
					
					currentEdge = currentEdge.next
				
				# In that stepping length we have the smallest edge.remove it
				smallestEdge.removed = 1
				self.edges.remove(smallestEdge)
				
				# Start scanning from the edge we found? - result is over fanning- no good.
				#currentEdge= smallestEdge.next
				
				culled+=1
示例#37
0
    def __init__(self, loop, me, closed):  # Vert loop
        # Use next and prev, nextDist, prevDist

        # Get Loops centre.
        fac = len(loop)
        verts = me.verts
        self.centre = reduce(lambda a, b: a + verts[b].co / fac, loop,
                             Vector())

        # Convert Vert loop to Edges.
        self.edges = [
            edge(verts[loop[vIdx - 1]], verts[loop[vIdx]])
            for vIdx in xrange(len(loop))
        ]

        if not closed:
            self.edges[0].fake = True  # fake edge option

        self.closed = closed

        # Assign linked list
        for eIdx in xrange(len(self.edges) - 1):
            self.edges[eIdx].next = self.edges[eIdx + 1]
            self.edges[eIdx].prev = self.edges[eIdx - 1]
        # Now last
        self.edges[-1].next = self.edges[0]
        self.edges[-1].prev = self.edges[-2]

        # GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP.
        self.normal = Vector()
        for e in self.edges:
            n = (self.centre - e.co1).cross(self.centre - e.co2)
            # Do we realy need tot normalize?
            n.normalize()
            self.normal += n

            # Generate the angle
            va = e.cent - e.prev.cent
            vb = e.next.cent - e.cent

            e.angle = AngleBetweenVecs(va, vb)

        # Blur the angles
        #for e in self.edges:
        #	e.angle= (e.angle+e.next.angle)/2

        # Blur the angles
        #for e in self.edges:
        #	e.angle= (e.angle+e.prev.angle)/2

        self.normal.normalize()

        # Generate a normal for each edge.
        for e in self.edges:

            n1 = e.co1
            n2 = e.co2
            n3 = e.prev.co1

            a = n1 - n2
            b = n1 - n3
            normal1 = a.cross(b)
            normal1.normalize()

            n1 = e.co2
            n3 = e.next.co2
            n2 = e.co1

            a = n1 - n2
            b = n1 - n3

            normal2 = a.cross(b)
            normal2.normalize()

            # Reuse normal1 var
            normal1 += normal1 + normal2
            normal1.normalize()

            e.normal = normal1
示例#38
0
def mkpkfmesh(pkffile,N,S,R):

  # Here we use the biarc client included in the libbiarc tools directory
  # to recover a mesh
  cli2 = popen2("env")
  for i in cli2[1].readlines():
    print i
  cli2[1].flush()
  del cli2
  cli = popen2("biarccli %s" % pkffile)
  if cli[1].readline().strip()!='OK':
    return
  cli[0].write('closed\n')
  cli[0].flush()
  cli[1].readline()
  cli[0].write("mesh:%i:%i:%f\n" % (N,S,R) )
  cli[0].flush()

  # Skip first dot '.'
  cli[1].readline()

  coords = []
  for i in xrange(N+1):
    for j in xrange(S+1):
      x,y,z = map(lambda v: float(v),cli[1].readline().strip().split())
      if j==S: continue
      coords += [[x,y,z]]

  cli[0].write('exit\n')
  del cli

  def idx(i,j):
    return (i)*S+j

  faces = []
  for i in xrange(N):
    for j in xrange(S):
      faces += [[idx(i,j),idx(i,(j+1)%S),
                 idx((i+1)%(N),(j+1)%S),idx((i+1)%(N),j)]]

  # Glue the Ends
  def distance(a,b):
    x,y,z=a[0]-b[0],a[1]-b[1],a[2]-b[2]
    return (x*x+y*y+z*z)

  # XXX Permutation index disabled in mesh generation (libbiarc)
  # Find permutation index
 #  pidx = 0
 # cdist = distance(coords[0],coords[idx(N-1,0)])
 # for i in xrange(1,S):
 #   d = distance(coords[i],coords[idx(N-1,0)])
 #   if d<cdist:
 #     cdist = d
 #     pidx = i

#  for j in xrange(S):
#    faces += [[ idx(N-2,j),idx(N-2,(j+1)%S),
#                idx(0,(j+1+pidx)%S),idx(0,(j+pidx)%S) ]]

  

  me = Mesh.New('myMesh')

  # We remove the last row of coords (same as first)
  # The face indexing is correct (c.f. above permutation index)
  me.verts.extend(coords[:S*N])
  me.faces.extend(faces)

  print me.getUVLayerNames()

  # Init texture coordinates
  for i in xrange(N):
    for j in xrange(S):
      t0,s0 = float(j)/float(S), float(i)/float(N)
      t1,s1 = float(j+1)/float(S), float(i+1)/float(N)
      n = i*S+j
      me.faces[n].uv = [ Vector(s0,t0), Vector(s0,t1),
                         Vector(s1,t1), Vector(s1,t0) ]


  print 'Tex coords'
  for i in me.faces:
    print i.uv

  scn = Scene.GetCurrent()   # link object to current scene
  ob = scn.objects.new(me, 'PKFMesh')

  return ob