diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2008-05-28 03:15:08 +0400 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2008-05-28 03:15:08 +0400 |
commit | 6a802f63b66508d3945714f59f1234843f251c1d (patch) | |
tree | a97437fea4961dbb6812a46294c9d51a3da09539 | |
parent | ed42c9a6768712c1eeba3b36af09620f668d663b (diff) | |
parent | c1874b3cee1fdb2220f26f75e676942aee4be561 (diff) |
Merging revisions 14946-15020 of https://svn.blender.org/svnroot/bf-blender/trunk/blender
49 files changed, 844 insertions, 469 deletions
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 230df02c359..905b2f7ac63 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -871,12 +871,25 @@ static int EnumPixelFormats(HDC hdc) { for(i=1; i<=n; i++) { /* not the idiom, but it's right */ ::DescribePixelFormat( hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd ); w = WeightPixelFormat(pfd); - if(w > weight) { - weight = w; - iPixelFormat = i; + // be strict on stereo + if (!((sPreferredFormat.dwFlags ^ pfd.dwFlags) & PFD_STEREO)) { + if(w > weight) { + weight = w; + iPixelFormat = i; + } + } + } + if (weight == 0) { + // we could find the correct stereo setting, just find any suitable format + for(i=1; i<=n; i++) { /* not the idiom, but it's right */ + ::DescribePixelFormat( hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd ); + w = WeightPixelFormat(pfd); + if(w > weight) { + weight = w; + iPixelFormat = i; + } } } - return iPixelFormat; } diff --git a/release/scripts/3ds_import.py b/release/scripts/3ds_import.py index 8c7c93018db..028b9633606 100644 --- a/release/scripts/3ds_import.py +++ b/release/scripts/3ds_import.py @@ -419,7 +419,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH): ob.setMatrix(contextMatrix_rot) importedObjects.append(ob) - + bmesh.calcNormals() for matName, faces in myContextMeshMaterials.iteritems(): makeMeshMaterialCopy(matName, faces) @@ -664,9 +664,8 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH): #print contextLamp.name, elif (new_chunk.ID==OBJECT_MESH): - ## @@ PATCH - print 'Found an OBJECT_MESH chunk' - + # print 'Found an OBJECT_MESH chunk' + pass elif (new_chunk.ID==OBJECT_VERTICES): ''' Worldspace vertex locations diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 99d036b38bc..2d8859aa8fb 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -1101,12 +1101,12 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t\tProperty: "ShadingModel", "KString", "", "%s"' % mat_shader) file.write('\n\t\t\tProperty: "MultiLayer", "bool", "",0') file.write('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) # emit and diffuse color are he same in blender - file.write('\n\t\t\tProperty: "EmissiveFactor", "double", "",%.4f' % mat_dif) + file.write('\n\t\t\tProperty: "EmissiveFactor", "double", "",%.4f' % mat_emit) file.write('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_colamb) file.write('\n\t\t\tProperty: "AmbientFactor", "double", "",%.4f' % mat_amb) file.write('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) - file.write('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.4f' % mat_emit) + file.write('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.4f' % mat_dif) file.write('\n\t\t\tProperty: "Bump", "Vector3D", "",0,0,0') file.write('\n\t\t\tProperty: "TransparentColor", "ColorRGB", "",1,1,1') file.write('\n\t\t\tProperty: "TransparencyFactor", "double", "",%.4f' % (1.0 - mat_alpha)) diff --git a/release/scripts/flt_import.py b/release/scripts/flt_import.py index 74cd4c036a8..f8d31f7bb57 100644 --- a/release/scripts/flt_import.py +++ b/release/scripts/flt_import.py @@ -16,7 +16,7 @@ This script imports OpenFlight files into Blender. OpenFlight is a registered trademark of MultiGen-Paradigm, Inc. Feature overview and more availible at: -http://wiki.blender.org/index.php/Scripts/Manual/Import/openflight_flt +http://wiki.blender.org/index.php/Scripts/Manual/Import/openflight_fltss Note: This file is a grab-bag of old and new code. It needs some cleanup still. """ @@ -44,6 +44,7 @@ import BPyMesh import BPyImage import flt_filewalker import flt_properties +import sys reload(flt_properties) from flt_properties import * @@ -1036,8 +1037,9 @@ class InterNode(Node): else: # fgon mesh_face_indicies = [i+vert_index for i in xrange(face_len)] tri_ngons= ngon(self.mesh, mesh_face_indicies) - new_faces.extend([ [mesh_face_indicies[t] for t in tri] for tri in tri_ngons]) - new_faces_props.extend( [ (None, image, (uvs[tri[0]], uvs[tri[1]], uvs[tri[2]]), [flt_face.uverts[tri[0]], flt_face.uverts[tri[1]], flt_face.uverts[tri[2]]], flt_face.uvlayers, flt_face.color_index, flt_face.props,FLT_OrigIndex,1, flt_face.subfacelevel) for tri in tri_ngons ]) + if len(tri_ngons) != 1: + new_faces.extend([ [mesh_face_indicies[t] for t in tri] for tri in tri_ngons]) + new_faces_props.extend( [ (None, image, (uvs[tri[0]], uvs[tri[1]], uvs[tri[2]]), [flt_face.uverts[tri[0]], flt_face.uverts[tri[1]], flt_face.uverts[tri[2]]], flt_face.uvlayers, flt_face.color_index, flt_face.props,FLT_OrigIndex,1, flt_face.subfacelevel) for tri in tri_ngons ]) vert_index+= face_len FLT_OrigIndex+=1 @@ -2296,7 +2298,6 @@ def fixscale(root,childhash): for v in rmesh.verts: v.co = v.co * smat - def reparent(root,childhash,sce): for child in childhash[root]: reparent(child,childhash,sce) @@ -2452,7 +2453,7 @@ def but_event(evt): select_file(global_prefs['fltfile'], GRR) except: import traceback - FLTWarn = Draw.PupBlock("Export Error", ["See console for output!"]) + FLTWarn = Draw.PupBlock("Ixport Error", ["See console for output!"]) traceback.print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback) #choose base path for export diff --git a/release/scripts/uv_from_adjacent.py b/release/scripts/uv_from_adjacent.py deleted file mode 100644 index 285cca97d8b..00000000000 --- a/release/scripts/uv_from_adjacent.py +++ /dev/null @@ -1,129 +0,0 @@ -#!BPY -""" -Name: 'UVs from unselected adjacent' -Blender: 242 -Group: 'UVCalculation' -Tooltip: 'Assign UVs to selected faces from surrounding unselected faces.' -""" -__author__ = "Campbell Barton" -__url__ = ("blender", "blenderartists.org") -__version__ = "1.0 2006/02/07" - -__bpydoc__ = """\ -This script sets the UV mapping and image of selected faces from adjacent unselected faces. - -Use this script in face select mode for texturing between textured faces. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -from Blender import * -import bpy - -def mostUsedImage(imageList): # Returns the image most used in the list. - if not imageList: - return None - elif len(imageList) < 3: - return imageList[0] - - # 3+ Images, Get the most used image for surrounding faces. - imageCount = {} - for image in imageList: - if image: - image_key= image.name - else: - image_key = None - - try: - imageCount[image_key]['imageCount'] +=1 # an extra user of this image - except: - imageCount[image_key] = {'imageCount':1, 'blenderImage':image} # start with 1 user. - - # Now a list of tuples, (imageName, {imageCount, image}) - imageCount = imageCount.items() - - try: imageCount.sort(key=lambda a: a[1]) - except: imageCount.sort(lambda a,b: cmp(a[1], b[1])) - - - return imageCount[-1][1]['blenderImage'] - - -def main(): - sce = bpy.data.scenes.active - ob = sce.objects.active - - if ob == None or ob.type != 'Mesh': - Draw.PupMenu('ERROR: No mesh object in face select mode.') - return - me = ob.getData(mesh=1) - - if not me.faceUV: - Draw.PupMenu('ERROR: No mesh object in face select mode.') - return - - selfaces = [f for f in me.faces if f.sel] - unselfaces = [f for f in me.faces if not f.sel] - - - # Gather per Vert UV and Image, store in vertUvAverage - vertUvAverage = [[[],[]] for i in xrange(len(me.verts))] - - for f in unselfaces: # Unselected faces only. - fuv = f.uv - for i,v in enumerate(f): - vertUvAverage[v.index][0].append(fuv[i]) - vertUvAverage[v.index][1].append(f.image) - - # Average per vectex UV coords - for vertUvData in vertUvAverage: - uvList = vertUvData[0] - if uvList: - # Convert from a list of vectors into 1 vector. - vertUvData[0] = reduce(lambda a,b: a+b, uvList, Mathutils.Vector(0,0)) * (1.0/len(uvList)) - else: - vertUvData[0] = None - - # Assign to selected faces - TEX_FLAG = Mesh.FaceModes['TEX'] - for f in selfaces: - uvlist = [] - imageList = [] - for i,v in enumerate(f): - uv, vImages = vertUvAverage[v.index] - uvlist.append( uv ) - imageList.extend(vImages) - - if None not in uvlist: - # all the faces images used by this faces vert. some faces will be added twice but thats ok. - # Get the most used image and assign to the face. - image = mostUsedImage(imageList) - f.uv = uvlist - - if image: - f.image = image - f.mode |= TEX_FLAG - Window.RedrawAll() - -if __name__ == '__main__': - main()
\ No newline at end of file diff --git a/release/scripts/uv_seams_from_islands.py b/release/scripts/uv_seams_from_islands.py index 241f38fc4aa..7f156efde7d 100644 --- a/release/scripts/uv_seams_from_islands.py +++ b/release/scripts/uv_seams_from_islands.py @@ -1,12 +1,31 @@ #!BPY """ Name: 'Seams from Islands' -Blender: 243 +Blender: 246 Group: 'UV' Tooltip: 'Add seams onto the mesh at the bounds of UV islands' """ -# Add a licence here if you wish to re-distribute, we recommend the GPL +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Campbell Barton +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- from Blender import Scene, Mesh, Window, sys import BPyMessages @@ -37,8 +56,11 @@ def seams_from_islands(me): # add seams SEAM = Mesh.EdgeFlags.SEAM for ed in me.edges: - if len(set(edge_uvs[ed.key])) > 1: - ed.flag |= SEAM + try: # the edge might not be in a face + if len(set(edge_uvs[ed.key])) > 1: + ed.flag |= SEAM + except: + pass def main(): diff --git a/release/scripts/uvcalc_lightmap.py b/release/scripts/uvcalc_lightmap.py index 5f9f88a241d..37423b7197e 100644 --- a/release/scripts/uvcalc_lightmap.py +++ b/release/scripts/uvcalc_lightmap.py @@ -41,6 +41,12 @@ import BPyMesh from math import sqrt +def AngleBetweenVecs(a1,a2): + try: + return Mathutils.AngleBetweenVecs(a1,a2) + except: + return 180.0 + class prettyface(object): __slots__ = 'uv', 'width', 'height', 'children', 'xoff', 'yoff', 'has_parent', 'rot' def __init__(self, data): @@ -148,9 +154,9 @@ class prettyface(object): if len(uv) == 2: # match the order of angle sizes of the 3d verts with the UV angles and rotate. def get_tri_angles(v1,v2,v3): - a1= Mathutils.AngleBetweenVecs(v2-v1,v3-v1) - a2= Mathutils.AngleBetweenVecs(v1-v2,v3-v2) - a3 = 180 - (a1+a2) #a3= Mathutils.AngleBetweenVecs(v2-v3,v1-v3) + a1= AngleBetweenVecs(v2-v1,v3-v1) + a2= AngleBetweenVecs(v1-v2,v3-v2) + a3 = 180 - (a1+a2) #a3= AngleBetweenVecs(v2-v3,v1-v3) return [(a1,0),(a2,1),(a3,2)] @@ -237,8 +243,17 @@ PREF_MARGIN_DIV= 512): face_groups.append(faces) if PREF_NEW_UVLAYER: - me.addUVLayer('lightmap') - me.activeUVLayer = 'lightmap' + uvname_org = uvname = 'lightmap' + uvnames = me.getUVLayerNames() + i = 1 + while uvname in uvnames: + uvname = '%s.%03d' % (uvname_org, i) + i+=1 + + me.addUVLayer(uvname) + me.activeUVLayer = uvname + + del uvnames, uvname_org, uvname for face_sel in face_groups: print "\nStarting unwrap" @@ -402,11 +417,14 @@ PREF_MARGIN_DIV= 512): # ...limiting this is needed or you end up with bug unused texture spaces # ...however if its too high, boxpacking is way too slow for high poly meshes. float_to_int_factor = lengths_to_ints[0][0] - max_int_dimension = int(((side_len / float_to_int_factor)) / PREF_BOX_DIV) - + if float_to_int_factor > 0: + max_int_dimension = int(((side_len / float_to_int_factor)) / PREF_BOX_DIV) + ok = True + else: + max_int_dimension = 0.0 # wont be used + ok = False # RECURSIVE prettyface grouping - ok = True while ok: ok = False diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 60444675047..45d8193b16f 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -39,8 +39,8 @@ struct ListBase; struct BezTriple; struct BevList; -#define KNOTSU(nu) ( (nu)->orderu+ (nu)->pntsu+ (nu->orderu-1)*((nu)->flagu & 1) ) -#define KNOTSV(nu) ( (nu)->orderv+ (nu)->pntsv+ (nu->orderv-1)*((nu)->flagv & 1) ) +#define KNOTSU(nu) ( (nu)->orderu+ (nu)->pntsu+ (nu->orderu-1)*((nu)->flagu & CU_CYCLIC) ) +#define KNOTSV(nu) ( (nu)->orderv+ (nu)->pntsv+ (nu->orderv-1)*((nu)->flagv & CU_CYCLIC) ) void unlink_curve( struct Curve *cu); @@ -84,5 +84,12 @@ void switchdirectionNurb( struct Nurb *nu); float (*curve_getVertexCos(struct Curve *cu, struct ListBase *lb, int *numVerts_r))[3]; void curve_applyVertexCos(struct Curve *cu, struct ListBase *lb, float (*vertexCos)[3]); +/* nurb checks if they can be drawn, also clamp order func */ +int check_valid_nurb_u( struct Nurb *nu); +int check_valid_nurb_v( struct Nurb *nu); + +int clamp_nurb_order_u( struct Nurb *nu); +int clamp_nurb_order_v( struct Nurb *nu); + #endif diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index d02a7c0ab9e..396bdda9c10 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -348,9 +348,9 @@ void freeNurb(Nurb *nu) if(nu->bp) MEM_freeN(nu->bp); nu->bp= 0; if(nu->knotsu) MEM_freeN(nu->knotsu); - nu->knotsu= 0; + nu->knotsu= NULL; if(nu->knotsv) MEM_freeN(nu->knotsv); - nu->knotsv= 0; + nu->knotsv= NULL; /* if(nu->trim.first) freeNurblist(&(nu->trim)); */ MEM_freeN(nu); @@ -393,7 +393,7 @@ Nurb *duplicateNurb(Nurb *nu) (BPoint*)MEM_mallocN((len)* sizeof(BPoint),"duplicateNurb3"); memcpy(newnu->bp, nu->bp, len*sizeof(BPoint)); - newnu->knotsu=newnu->knotsv= 0; + newnu->knotsu= newnu->knotsv= NULL; if(nu->knotsu) { len= KNOTSU(nu); @@ -506,6 +506,7 @@ static void calcknots(float *knots, short aantal, short order, short type) } } else if(type==2) { + /* Warning, the order MUST be 2 or 4, if this is not enforced, the displist will be corrupt */ if(order==4) { k= 0.34; for(a=0;a<t;a++) { @@ -520,6 +521,9 @@ static void calcknots(float *knots, short aantal, short order, short type) knots[a]= (float)floor(k); } } + else { + printf("bez nurb curve order is not 3 or 4, should never happen\n"); + } } } @@ -529,7 +533,8 @@ static void makecyclicknots(float *knots, short pnts, short order) int a, b, order2, c; if(knots==0) return; - order2=order-1; + + order2=order-1; /* do first long rows (order -1), remove identical knots at endpoints */ if(order>2) { @@ -549,26 +554,35 @@ static void makecyclicknots(float *knots, short pnts, short order) } -void makeknots(Nurb *nu, short uv, short type) /* 0: uniform, 1: endpoints, 2: bezier */ +/* type - 0: uniform, 1: endpoints, 2: bezier, note, cyclic nurbs are always uniform */ +void makeknots(Nurb *nu, short uv, short type) { if( (nu->type & 7)==CU_NURBS ) { - if(uv & 1) { + if(uv == 1) { if(nu->knotsu) MEM_freeN(nu->knotsu); - if(nu->pntsu>1) { + if(check_valid_nurb_u(nu)) { nu->knotsu= MEM_callocN(4+sizeof(float)*KNOTSU(nu), "makeknots"); - calcknots(nu->knotsu, nu->pntsu, nu->orderu, type); - if(nu->flagu & 1) makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu); + if(nu->flagu & CU_CYCLIC) { + calcknots(nu->knotsu, nu->pntsu, nu->orderu, 0); /* cyclic should be uniform */ + makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu); + } else { + calcknots(nu->knotsu, nu->pntsu, nu->orderu, type); + } } - else nu->knotsu= 0; - } - if(uv & 2) { + else nu->knotsu= NULL; + + } else if(uv == 2) { if(nu->knotsv) MEM_freeN(nu->knotsv); - if(nu->pntsv>1) { + if(check_valid_nurb_v(nu)) { nu->knotsv= MEM_callocN(4+sizeof(float)*KNOTSV(nu), "makeknots"); - calcknots(nu->knotsv, nu->pntsv, nu->orderv, type); - if(nu->flagv & 1) makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv); + if(nu->flagv & CU_CYCLIC) { + calcknots(nu->knotsv, nu->pntsv, nu->orderv, 0); /* cyclic should be uniform */ + makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv); + } else { + calcknots(nu->knotsv, nu->pntsv, nu->orderv, type); + } } - else nu->knotsv= 0; + else nu->knotsv= NULL; } } } @@ -645,7 +659,7 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride) int i, j, iofs, jofs, cycl, len, resolu, resolv; int istart, iend, jsta, jen, *jstart, *jend, ratcomp; - if(nu->knotsu==0 || nu->knotsv==0) return; + if(nu->knotsu==NULL || nu->knotsv==NULL) return; if(nu->orderu>nu->pntsu) return; if(nu->orderv>nu->pntsv) return; if(data==0) return; @@ -679,24 +693,24 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride) fp= nu->knotsu; ustart= fp[nu->orderu-1]; - if(nu->flagu & 1) uend= fp[nu->pntsu+nu->orderu-1]; + if(nu->flagu & CU_CYCLIC) uend= fp[nu->pntsu+nu->orderu-1]; else uend= fp[nu->pntsu]; - ustep= (uend-ustart)/(resolu-1+(nu->flagu & 1)); + ustep= (uend-ustart)/(resolu-1+(nu->flagu & CU_CYCLIC)); basisu= (float *)MEM_mallocN(sizeof(float)*KNOTSU(nu), "makeNurbfaces3"); fp= nu->knotsv; vstart= fp[nu->orderv-1]; - if(nu->flagv & 1) vend= fp[nu->pntsv+nu->orderv-1]; + if(nu->flagv & CU_CYCLIC) vend= fp[nu->pntsv+nu->orderv-1]; else vend= fp[nu->pntsv]; - vstep= (vend-vstart)/(resolv-1+(nu->flagv & 1)); + vstep= (vend-vstart)/(resolv-1+(nu->flagv & CU_CYCLIC)); len= KNOTSV(nu); basisv= (float *)MEM_mallocN(sizeof(float)*len*resolv, "makeNurbfaces3"); jstart= (int *)MEM_mallocN(sizeof(float)*resolv, "makeNurbfaces4"); jend= (int *)MEM_mallocN(sizeof(float)*resolv, "makeNurbfaces5"); /* precalculation of basisv and jstart,jend */ - if(nu->flagv & 1) cycl= nu->orderv-1; + if(nu->flagv & CU_CYCLIC) cycl= nu->orderv-1; else cycl= 0; v= vstart; basis= basisv; @@ -706,7 +720,7 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride) v+= vstep; } - if(nu->flagu & 1) cycl= nu->orderu-1; + if(nu->flagu & CU_CYCLIC) cycl= nu->orderu-1; else cycl= 0; in= data; u= ustart; @@ -803,7 +817,7 @@ void makeNurbcurve(Nurb *nu, float *data, int resolu, int dim) float *basisu, *sum, *fp, *in; int i, len, istart, iend, cycl; - if(nu->knotsu==0) return; + if(nu->knotsu==NULL) return; if(nu->orderu>nu->pntsu) return; if(data==0) return; @@ -820,12 +834,12 @@ void makeNurbcurve(Nurb *nu, float *data, int resolu, int dim) fp= nu->knotsu; ustart= fp[nu->orderu-1]; - if(nu->flagu & 1) uend= fp[nu->pntsu+nu->orderu-1]; + if(nu->flagu & CU_CYCLIC) uend= fp[nu->pntsu+nu->orderu-1]; else uend= fp[nu->pntsu]; - ustep= (uend-ustart)/(resolu-1+(nu->flagu & 1)); + ustep= (uend-ustart)/(resolu-1+(nu->flagu & CU_CYCLIC)); basisu= (float *)MEM_mallocN(sizeof(float)*KNOTSU(nu), "makeNurbcurve3"); - if(nu->flagu & 1) cycl= nu->orderu-1; + if(nu->flagu & CU_CYCLIC) cycl= nu->orderu-1; else cycl= 0; in= data; @@ -1425,14 +1439,14 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float * /* returns a point */ if(prevbezt==nu->bezt) { - if(nu->flagu & 1) pprev= last; + if(nu->flagu & CU_CYCLIC) pprev= last; else pprev= prevbezt; } else pprev= prevbezt-1; /* next point */ if(bezt==last) { - if(nu->flagu & 1) next= nu->bezt; + if(nu->flagu & CU_CYCLIC) next= nu->bezt; else next= bezt; } else next= bezt+1; @@ -1478,7 +1492,7 @@ void makeBevelList(Object *ob) while(nu) { /* check we are a single point? also check we are not a surface and that the orderu is sane, * enforced in the UI but can go wrong possibly */ - if(nu->pntsu<2 || ((nu->type & 7)==CU_NURBS && nu->pntsu < nu->orderu)) { + if(!check_valid_nurb_u(nu)) { bl= MEM_callocN(sizeof(BevList)+1*sizeof(BevPoint), "makeBevelList"); BLI_addtail(&(cu->bev), bl); bl->nr= 0; @@ -1493,7 +1507,7 @@ void makeBevelList(Object *ob) bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList"); BLI_addtail(&(cu->bev), bl); - if(nu->flagu & 1) bl->poly= 0; + if(nu->flagu & CU_CYCLIC) bl->poly= 0; else bl->poly= -1; bl->nr= len; bl->flag= 0; @@ -1512,17 +1526,17 @@ void makeBevelList(Object *ob) } else if((nu->type & 7)==CU_BEZIER) { - len= resolu*(nu->pntsu+ (nu->flagu & 1) -1)+1; /* in case last point is not cyclic */ + len= resolu*(nu->pntsu+ (nu->flagu & CU_CYCLIC) -1)+1; /* in case last point is not cyclic */ bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList"); BLI_addtail(&(cu->bev), bl); - if(nu->flagu & 1) bl->poly= 0; + if(nu->flagu & CU_CYCLIC) bl->poly= 0; else bl->poly= -1; bevp= (BevPoint *)(bl+1); a= nu->pntsu-1; bezt= nu->bezt; - if(nu->flagu & 1) { + if(nu->flagu & CU_CYCLIC) { a++; prevbezt= nu->bezt+(nu->pntsu-1); } @@ -1595,7 +1609,7 @@ void makeBevelList(Object *ob) MEM_freeN(data); MEM_freeN(data_a); - if((nu->flagu & 1)==0) { /* not cyclic: endpoint */ + if((nu->flagu & CU_CYCLIC)==0) { /* not cyclic: endpoint */ bevp->x= prevbezt->vec[1][0]; bevp->y= prevbezt->vec[1][1]; bevp->z= prevbezt->vec[1][2]; @@ -1611,7 +1625,7 @@ void makeBevelList(Object *ob) BLI_addtail(&(cu->bev), bl); bl->nr= len; bl->flag= 0; - if(nu->flagu & 1) bl->poly= 0; + if(nu->flagu & CU_CYCLIC) bl->poly= 0; else bl->poly= -1; bevp= (BevPoint *)(bl+1); @@ -2209,7 +2223,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */ a= nu->pntsu; bezt= nu->bezt; - if(nu->flagu & 1) prev= bezt+(a-1); + if(nu->flagu & CU_CYCLIC) prev= bezt+(a-1); else prev= 0; next= bezt+1; @@ -2217,7 +2231,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */ calchandleNurb(bezt, prev, next, 0); prev= bezt; if(a==1) { - if(nu->flagu & 1) next= nu->bezt; + if(nu->flagu & CU_CYCLIC) next= nu->bezt; else next= 0; } else next++; @@ -2608,3 +2622,63 @@ void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3]) } } } + +int check_valid_nurb_u( struct Nurb *nu ) +{ + if (nu==NULL) return 0; + if (nu->pntsu <= 1) return 0; + if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */ + + if (nu->pntsu < nu->orderu) return 0; + if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagu>>1) & 2)) { /* Bezier U Endpoints */ + if (nu->orderu==4) { + if (nu->pntsu < 5) return 0; /* bezier with 4 orderu needs 5 points */ + } else if (nu->orderu != 3) return 0; /* order must be 3 or 4 */ + } + return 1; +} +int check_valid_nurb_v( struct Nurb *nu) +{ + if (nu==NULL) return 0; + if (nu->pntsv <= 1) return 0; + if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */ + + if (nu->pntsv < nu->orderv) return 0; + if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagv>>1) & 2)) { /* Bezier V Endpoints */ + if (nu->orderv==4) { + if (nu->pntsv < 5) return 0; /* bezier with 4 orderu needs 5 points */ + } else if (nu->orderv != 3) return 0; /* order must be 3 or 4 */ + } + return 1; +} + +int clamp_nurb_order_u( struct Nurb *nu ) +{ + int change = 0; + if(nu->pntsu<nu->orderu) { + nu->orderu= nu->pntsu; + change= 1; + } + if(((nu->flag & CU_CYCLIC)==0) && (nu->flagu>>1)&2) { + CLAMP(nu->orderu, 3,4); + change= 1; + } + return change; +} + +int clamp_nurb_order_v( struct Nurb *nu) +{ + int change = 0; + if(nu->pntsv<nu->orderv) { + nu->orderv= nu->pntsv; + change= 1; + } + if(((nu->flag & CU_CYCLIC)==0) && (nu->flagv>>1)&2) { + CLAMP(nu->orderv, 3,4); + change= 1; + } + return change; +} + + + diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index aa436441056..298e4b81d5b 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -783,7 +783,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) else resolu= nu->resolu; - if(nu->pntsu<2 || ((nu->type & 7)==CU_NURBS && nu->pntsu < nu->orderu)); + if(!check_valid_nurb_u(nu)); else if((nu->type & 7)==CU_BEZIER) { /* count */ @@ -816,7 +816,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) data= dl->verts; - if(nu->flagu & 1) { + if(nu->flagu & CU_CYCLIC) { dl->type= DL_POLY; a= nu->pntsu; } @@ -863,7 +863,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) dl->charidx = nu->charidx; data= dl->verts; - if(nu->flagu & 1) dl->type= DL_POLY; + if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; makeNurbcurve(nu, data, resolu, 3); } @@ -878,7 +878,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) dl->charidx = nu->charidx; data= dl->verts; - if(nu->flagu & 1) dl->type= DL_POLY; + if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; a= len; @@ -1330,7 +1330,7 @@ void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender) dl->rt= nu->flag; data= dl->verts; - if(nu->flagu & 1) dl->type= DL_POLY; + if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; makeNurbcurve(nu, data, nu->resolu, 3); diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 09c93962990..52275e507dd 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -440,7 +440,7 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i if (nu2 == NULL) return; nu2->resolu= cu->resolu; nu2->bezt = NULL; - nu2->knotsu = nu2->knotsv = 0; + nu2->knotsu = nu2->knotsv = NULL; nu2->flag= 0; nu2->charidx = charidx+1000; if (mat_nr > 0) nu2->mat_nr= mat_nr-1; @@ -529,7 +529,7 @@ static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float memcpy(nu2, nu1, sizeof(struct Nurb)); nu2->resolu= cu->resolu; nu2->bp = 0; - nu2->knotsu = nu2->knotsv = 0; + nu2->knotsu = nu2->knotsv = NULL; nu2->flag= CU_SMOOTH; nu2->charidx = charidx; if (info->mat_nr) { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index fa54b0458d5..067108ac8cb 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6568,12 +6568,14 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, MFace *mf=0; MVert *dupvert=0; ParticleSettings *part=psmd->psys->part; - ParticleData *pa, *pars=psmd->psys->particles; + ParticleData *pa=NULL, *pars=psmd->psys->particles; ParticleKey state; + EdgeHash *vertpahash; + EdgeHashIterator *ehi; float *vertco=0, imat[4][4]; float loc0[3], nor[3]; float timestep, cfra; - int *facepa=emd->facepa, *vertpa=0; + int *facepa=emd->facepa; int totdup=0,totvert=0,totface=0,totpart=0; int i, j, v, mindex=0; @@ -6588,34 +6590,36 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, else cfra=bsystem_time(ob,(float)G.scene->r.cfra,0.0); - /* table for vertice <-> particle relations (row totpart+1 is for yet unexploded verts) */ - vertpa = MEM_callocN(sizeof(int)*(totpart+1)*totvert, "explode_vertpatab"); - for(i=0; i<(totpart+1)*totvert; i++) - vertpa[i] = -1; + /* hash table for vertice <-> particle relations */ + vertpahash= BLI_edgehash_new(); for (i=0; i<totface; i++) { + /* do mindex + totvert to ensure the vertex index to be the first + * with BLI_edgehashIterator_getKey */ if(facepa[i]==totpart || cfra <= (pars+facepa[i])->time) - mindex = totpart*totvert; + mindex = totvert+totpart; else - mindex = facepa[i]*totvert; + mindex = totvert+facepa[i]; mf=CDDM_get_face(dm,i); - /*set face vertices to exist in particle group*/ - vertpa[mindex+mf->v1] = 1; - vertpa[mindex+mf->v2] = 1; - vertpa[mindex+mf->v3] = 1; + /* set face vertices to exist in particle group */ + BLI_edgehash_insert(vertpahash, mf->v1, mindex, NULL); + BLI_edgehash_insert(vertpahash, mf->v2, mindex, NULL); + BLI_edgehash_insert(vertpahash, mf->v3, mindex, NULL); if(mf->v4) - vertpa[mindex+mf->v4] = 1; + BLI_edgehash_insert(vertpahash, mf->v4, mindex, NULL); } - /*make new vertice indexes & count total vertices after duplication*/ - for(i=0; i<(totpart+1)*totvert; i++){ - if(vertpa[i] != -1) - vertpa[i] = totdup++; + /* make new vertice indexes & count total vertices after duplication */ + ehi= BLI_edgehashIterator_new(vertpahash); + for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { + BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totdup)); + totdup++; } + BLI_edgehashIterator_free(ehi); - /*the final duplicated vertices*/ + /* the final duplicated vertices */ explode= CDDM_from_template(dm, totdup, 0,totface); dupvert= CDDM_get_verts(explode); @@ -6624,45 +6628,49 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, psmd->psys->lattice = psys_get_lattice(ob, psmd->psys); - /*duplicate & displace vertices*/ - for(i=0, pa=pars; i<=totpart; i++, pa++){ - if(i!=totpart){ + /* duplicate & displace vertices */ + ehi= BLI_edgehashIterator_new(vertpahash); + for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { + MVert source; + MVert *dest; + + /* get particle + vertex from hash */ + BLI_edgehashIterator_getKey(ehi, &j, &i); + i -= totvert; + v= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); + + dm->getVert(dm, j, &source); + dest = CDDM_get_vert(explode,v); + + DM_copy_vert_data(dm,explode,j,v,1); + *dest = source; + + if(i!=totpart) { + /* get particle */ + pa= pars+i; + + /* get particle state */ psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0); Mat4MulVecfl(ob->obmat,loc0); state.time=cfra; psys_get_particle_state(ob,psmd->psys,i,&state,1); - } - - for(j=0; j<totvert; j++){ - v=vertpa[i*totvert+j]; - if(v != -1) { - MVert source; - MVert *dest; - - dm->getVert(dm, j, &source); - dest = CDDM_get_vert(explode,v); - - DM_copy_vert_data(dm,explode,j,v,1); - *dest = source; - if(i!=totpart){ - vertco=CDDM_get_vert(explode,v)->co; - - Mat4MulVecfl(ob->obmat,vertco); + vertco=CDDM_get_vert(explode,v)->co; + + Mat4MulVecfl(ob->obmat,vertco); - VECSUB(vertco,vertco,loc0); + VECSUB(vertco,vertco,loc0); - /* apply rotation, size & location */ - QuatMulVecf(state.rot,vertco); - VecMulf(vertco,pa->size); - VECADD(vertco,vertco,state.co); + /* apply rotation, size & location */ + QuatMulVecf(state.rot,vertco); + VecMulf(vertco,pa->size); + VECADD(vertco,vertco,state.co); - Mat4MulVecfl(imat,vertco); - } - } + Mat4MulVecfl(imat,vertco); } } + BLI_edgehashIterator_free(ehi); /*map new vertices to faces*/ for (i=0; i<totface; i++) { @@ -6684,15 +6692,15 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, orig_v4 = source.v4; if(facepa[i]!=totpart && cfra <= pa->time) - mindex = totpart*totvert; + mindex = totvert+totpart; else - mindex = facepa[i]*totvert; + mindex = totvert+facepa[i]; - source.v1 = vertpa[mindex+source.v1]; - source.v2 = vertpa[mindex+source.v2]; - source.v3 = vertpa[mindex+source.v3]; + source.v1 = edgesplit_get(vertpahash, source.v1, mindex); + source.v2 = edgesplit_get(vertpahash, source.v2, mindex); + source.v3 = edgesplit_get(vertpahash, source.v3, mindex); if(source.v4) - source.v4 = vertpa[mindex+source.v4]; + source.v4 = edgesplit_get(vertpahash, source.v4, mindex); DM_copy_face_data(dm,explode,i,i,1); @@ -6701,9 +6709,10 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, test_index_face(mf, &explode->faceData, i, (mf->v4 ? 4 : 3)); } + MEM_printmemlist_stats(); /* cleanup */ - if(vertpa) MEM_freeN(vertpa); + BLI_edgehash_free(vertpahash, NULL); /* finalization */ CDDM_calc_edges(explode); diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 464f97d294d..8b979f9ed23 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -150,7 +150,7 @@ void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) nu->type= CU_BEZIER+CU_2D; nu->pntsu = onpoints[j]; nu->resolu= 8; - nu->flagu= 1; + nu->flagu= CU_CYCLIC; nu->bezt = bezt; //individual curve loop, start-end diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c index 8cdc0601c7e..498c87cdef9 100644 --- a/source/blender/blenlib/intern/psfont.c +++ b/source/blender/blenlib/intern/psfont.c @@ -2017,7 +2017,7 @@ static VFontData *objfnt_to_vfontdata(objfnt *fnt) nu->type= CU_BEZIER+CU_2D; nu->pntsu = count; nu->resolu= 8; - nu->flagu= 1; + nu->flagu= CU_CYCLIC; nu->bezt = bezt; stop = 0; diff --git a/source/blender/include/BDR_editcurve.h b/source/blender/include/BDR_editcurve.h index 9e25550ce04..4604359fcc9 100644 --- a/source/blender/include/BDR_editcurve.h +++ b/source/blender/include/BDR_editcurve.h @@ -37,6 +37,9 @@ struct BezTriple; struct BPoint; struct BezTripleNurb; +void set_actNurb(struct Nurb *nu); +struct Nurb * get_actNurb( void ); + short isNurbsel(struct Nurb *nu); int isNurbsel_count(struct Nurb *nu); void printknots(void); diff --git a/source/blender/nodes/intern/Makefile b/source/blender/nodes/intern/Makefile index 12b3616df25..7cf2411ed84 100644 --- a/source/blender/nodes/intern/Makefile +++ b/source/blender/nodes/intern/Makefile @@ -35,8 +35,6 @@ include nan_compile.mk CFLAGS += $(LEVEL_1_C_WARNINGS) -CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -CPPFLAGS += -I../../python CPPFLAGS += -I../../blenkernel CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../makesdna diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c index cd7ec781b2b..3d4546613be 100644 --- a/source/blender/python/api2_2x/Draw.c +++ b/source/blender/python/api2_2x/Draw.c @@ -2063,22 +2063,22 @@ static PyObject *Method_Image( PyObject * self, PyObject * args ) /*GLfloat scissorBox[4];*/ /* parse the arguments passed-in from Python */ - if( !PyArg_ParseTuple( args, "Off|ffiiii", &pyObjImage, + if( !PyArg_ParseTuple( args, "O!ff|ffiiii", &Image_Type, &pyObjImage, &originX, &originY, &zoomX, &zoomY, &clipX, &clipY, &clipW, &clipH ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a Blender.Image and 2 floats, and " \ "optionally 2 floats and 4 ints as arguments" ); - /* check that the first PyObject is actually a Blender.Image */ - if( !BPy_Image_Check( pyObjImage ) ) - return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected a Blender.Image and 2 floats, and " \ - "optionally 2 floats and 4 ints as arguments" ); /* check that the zoom factors are valid */ - if( ( zoomX <= 0.0 ) || ( zoomY <= 0.0 ) ) + if( ( zoomX < 0.0 ) || ( zoomY < 0.0 ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, - "invalid zoom factors - they must be >= 0.0" ); - + "invalid zoom factors - they must be > 0.0" ); + if ((zoomX == 0.0 ) || ( zoomY == 0.0 )) { + /* sometimes python doubles can be converted from small values to a zero float, in this case just dont draw */ + Py_RETURN_NONE; + } + + /* fetch a C Image pointer from the passed-in Python object */ py_img = ( BPy_Image * ) pyObjImage; image = py_img->image; @@ -2101,9 +2101,9 @@ static PyObject *Method_Image( PyObject * self, PyObject * args ) * the image as they can. */ clipX = EXPP_ClampInt( clipX, 0, ibuf->x ); clipY = EXPP_ClampInt( clipY, 0, ibuf->y ); - if( ( clipW < 0 ) || ( clipW > ( ibuf->x - clipW ) ) ) + if( ( clipW < 0 ) || ( clipX+clipW > ibuf->x ) ) clipW = ibuf->x - clipX; - if( ( clipH < 0 ) || ( clipH > ( ibuf->y - clipH ) ) ) + if( ( clipH < 0 ) || ( clipY+clipH > ibuf->y ) ) clipH = ibuf->y - clipY; /* -- we are "Go" to Draw! -- */ @@ -2165,8 +2165,7 @@ static PyObject *Method_Image( PyObject * self, PyObject * args ) glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 ); glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); - Py_INCREF( Py_None ); - return Py_None; + Py_RETURN_NONE; } diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 82f99adcdb1..1a806932bdb 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -341,6 +341,7 @@ static int setupPI(Object* ob); static PyObject *Object_getParticleSys( BPy_Object * self ); /* fixme Object_newParticleSys( self, default-partsys-name ) */ +static PyObject *Object_addVertexGroupsFromArmature( BPy_Object * self, PyObject * args); static PyObject *Object_newParticleSys( BPy_Object * self ); static PyObject *Object_buildParts( BPy_Object * self ); static PyObject *Object_clearIpo( BPy_Object * self ); @@ -475,6 +476,8 @@ static PyMethodDef BPy_Object_methods[] = { "Return a list of particle systems"}, {"newParticleSystem", ( PyCFunction ) Object_newParticleSys, METH_NOARGS, "Create and link a new particle system"}, + {"addVertexGroupsFromArmature" , ( PyCFunction ) Object_addVertexGroupsFromArmature, METH_VARARGS, + "Add vertex groups from armature using the bone heat method"}, {"buildParts", ( PyCFunction ) Object_buildParts, METH_NOARGS, "Recalcs particle system (if any), (depricated, will always return an empty list in version 2.46)"}, {"getIpo", ( PyCFunction ) Object_getIpo, METH_NOARGS, @@ -1109,6 +1112,42 @@ PyObject *Object_newParticleSys( BPy_Object * self ){ return ParticleSys_CreatePyObject(rpsys,ob); } +/*****************************************************************************/ +/* attribute: addVertexGroupsFromArmature */ +/* Description: evaluate and add vertex groups to the current object */ +/* for each bone of the selected armature */ +/* Data: self Object, Bpy armature */ +/* Return: nothing */ +/*****************************************************************************/ +static PyObject *Object_addVertexGroupsFromArmature( BPy_Object * self, PyObject * args) +{ + + Object *ob = self->object; + BPy_Object *arm; + + if( ob->type != OB_MESH ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "Only useable on Mesh type Objects" ); + + if( G.obedit != NULL) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "Not useable when inside edit mode" ); + + /* Check if the arguments passed to makeParent are valid. */ + if( !PyArg_ParseTuple( args, "O!",&Object_Type, &arm ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "An armature object is expected." ); + + if( arm->object->type != OB_ARMATURE ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "An armature object is expected." ); + + add_verts_to_dgroups(ob, arm->object, 1, 0); + ob->recalc |= OB_RECALC_OB; + + Py_RETURN_NONE; +} + static PyObject *Object_buildParts( BPy_Object * self ) { /* This is now handles by modifiers */ diff --git a/source/blender/python/api2_2x/Particle.c b/source/blender/python/api2_2x/Particle.c index 15307cc2be5..f0a32db0623 100644 --- a/source/blender/python/api2_2x/Particle.c +++ b/source/blender/python/api2_2x/Particle.c @@ -828,7 +828,7 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){ /* little hack to calculate hair steps in render mode */ psys->renderdata = (void*)(int)1; - psys_cache_paths(ob, psys, cfra, 0); + psys_cache_paths(ob, psys, cfra, 1); psys->renderdata = NULL; diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index 521be3b0cea..09167c0e117 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -651,6 +651,13 @@ class Object: Link a new particle system (see Blender.Particle). """ + def addVertexGroupsFromArmature(object): + """ + Add vertex groups from armature using the bone heat method + This method can be only used with an Object of the type Mesh when NOT in edit mode. + @type object: a bpy armature + """ + def buildParts(): """ Recomputes the particle system. This method only applies to an Object of diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 73db5c4b0be..aa4e40739da 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -241,7 +241,7 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) /* append or set matrix depending on dupli */ if(obi->flag & R_DUPLI_TRANSFORMED) { Mat4CpyMat4(tmpmat, obi->mat); - Mat4MulMat4(obi->mat, tmat, tmpmat); + Mat4MulMat4(obi->mat, tmpmat, tmat); } else if(mode==1) Mat4CpyMat4(obi->mat, tmat); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index bcd373ddbc3..d2f798d0b6e 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3075,7 +3075,6 @@ static void editing_panel_font_type(Object *ob, Curve *cu) void do_curvebuts(unsigned short event) { - extern Nurb *lastnu; extern ListBase editNurb; /* from editcurve */ Object *ob; Curve *cu; @@ -3109,13 +3108,15 @@ void do_curvebuts(unsigned short event) if(isNurbsel(nu)) { if((nu->type & 7)==CU_NURBS) { if(event<B_UNIFV) { - nu->flagu &= 1; - nu->flagu += ((event-B_UNIFU)<<1); + nu->flagu &= CU_CYCLIC; /* disable all flags except for CU_CYCLIC */ + nu->flagu |= ((event-B_UNIFU)<<1); + clamp_nurb_order_u(nu); makeknots(nu, 1, nu->flagu>>1); } else if(nu->pntsv>1) { - nu->flagv &= 1; - nu->flagv += ((event-B_UNIFV)<<1); + nu->flagv &= CU_CYCLIC; /* disable all flags except for CU_CYCLIC */ + nu->flagv |= ((event-B_UNIFV)<<1); + clamp_nurb_order_v(nu); makeknots(nu, 2, nu->flagv>>1); } } @@ -3151,15 +3152,13 @@ void do_curvebuts(unsigned short event) break; case B_SETORDER: if(G.obedit) { - nu= lastnu; + nu= get_actNurb(); if(nu && (nu->type & 7)==CU_NURBS ) { - if(nu->orderu>nu->pntsu) { - nu->orderu= nu->pntsu; + if(clamp_nurb_order_u(nu)) { scrarea_queue_winredraw(curarea); } makeknots(nu, 1, nu->flagu>>1); - if(nu->orderv>nu->pntsv) { - nu->orderv= nu->pntsv; + if(clamp_nurb_order_v(nu)) { scrarea_queue_winredraw(curarea); } makeknots(nu, 2, nu->flagv>>1); @@ -3277,7 +3276,6 @@ static void editing_panel_curve_tools(Object *ob, Curve *cu) { Nurb *nu; extern ListBase editNurb; /* from editcurve */ - extern Nurb *lastnu; uiBlock *block; short *sp; @@ -3313,8 +3311,11 @@ static void editing_panel_curve_tools(Object *ob, Curve *cu) uiBlockEndAlign(block); if(ob==G.obedit) { - nu= lastnu; - if(nu==NULL) nu= lastnu= editNurb.first; + nu= get_actNurb(); + if(nu==NULL && editNurb.first) { + nu= editNurb.first; + set_actNurb(nu); + } if(nu) { if (ob->type==OB_CURVE) { uiDefBut(block, LABEL, 0, "Tilt", diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index c6847508806..04a497ffdea 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2681,7 +2681,8 @@ static void lamp_panel_spot(Object *ob, Lamp *la) uiDefButF(block, NUM,B_LAMPREDRAW,"Soft Size", 100,80,200,19, &la->area_size, 0.01, 100.0, 10, 0, "Area light size, doesn't affect energy amount"); uiDefButS(block, NUM,0,"Samples:", 100,60,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)"); - uiDefButF(block, NUM,0,"Threshold:", 100,40,200,19, &la->adapt_thresh, 0.0, 1.0, 100, 0, "Threshold for adaptive sampling, to control what level is considered already in shadow"); + if (la->ray_samp_method == LA_SAMP_HALTON) + uiDefButF(block, NUM,0,"Threshold:", 100,40,200,19, &la->adapt_thresh, 0.0, 1.0, 100, 0, "Threshold for adaptive sampling, to control what level is considered already in shadow"); } else if (la->type == LA_AREA) { uiDefButS(block, MENU, B_REDR, "Adaptive QMC %x1|Constant QMC %x2|Constant Jittered %x0", @@ -2887,8 +2888,8 @@ static void lamp_panel_lamp(Object *ob, Lamp *la) uiBlockBeginAlign(block); if (ELEM(la->type, LA_LOCAL, LA_SPOT) && (la->falloff_type == LA_FALLOFF_SLIDERS)) { - uiDefButF(block, NUMSLI,B_LAMPPRV,"Linear ", 120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the linear distance attenuatation for a quad lamp"); - uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad ", 120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the quadratic distance attenuatation for a quad lamp"); + uiDefButF(block, NUMSLI,B_LAMPPRV,"Linear ", 120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the linear distance attenuation for a Lin/Quad Weighted lamp"); + uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad ", 120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the quadratic distance attenuation for a Lin/Quad Weighted lamp"); } else if(la->type==LA_AREA) { if(la->k==0.0) la->k= 1.0; diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index d5b1f023d70..0b042fc542f 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2905,7 +2905,7 @@ static int drawDispList(Base *base, int dt) /* 5. start filling the arrays */ /* 6. draw the arrays */ /* 7. clean up */ -static void draw_new_particle_system(Base *base, ParticleSystem *psys) +static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) { View3D *v3d= G.vd; Object *ob=base->object; @@ -3354,14 +3354,24 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) float *cd2=0,*cdata2=0; glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); + if(dt > OB_WIRE) { + glEnableClientState(GL_NORMAL_ARRAY); + + if(part->draw&PART_DRAW_MAT_COL) + glEnableClientState(GL_COLOR_ARRAY); + + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + } + else { + glDisableClientState(GL_NORMAL_ARRAY); - if(part->draw&PART_DRAW_MAT_COL) - glEnableClientState(GL_COLOR_ARRAY); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + BIF_ThemeColor(TH_WIRE); + } if(totchild && (part->draw&PART_DRAW_PARENT)==0) totpart=0; @@ -3370,9 +3380,13 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) for(a=0, pa=psys->particles; a<totpart; a++, pa++){ path=cache[a]; glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); - if(part->draw&PART_DRAW_MAT_COL) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + + if(dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); + if(part->draw&PART_DRAW_MAT_COL) + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + } + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } @@ -3380,15 +3394,21 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) for(a=0; a<totchild; a++){ path=cache[a]; glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); - if(part->draw&PART_DRAW_MAT_COL) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + + if(dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); + if(part->draw&PART_DRAW_MAT_COL) + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + } + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } - if(part->draw&PART_DRAW_MAT_COL) - glDisable(GL_COLOR_ARRAY); - glDisable(GL_COLOR_MATERIAL); + if(dt > OB_WIRE) { + if(part->draw&PART_DRAW_MAT_COL) + glDisable(GL_COLOR_ARRAY); + glDisable(GL_COLOR_MATERIAL); + } if(cdata2) MEM_freeN(cdata2); @@ -3409,7 +3429,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) else glDisableClientState(GL_VERTEX_ARRAY); - if(ndata && MIN2(G.vd->drawtype, ob->dt)>OB_WIRE){ + if(ndata && dt>OB_WIRE){ glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, 0, ndata); glEnable(GL_LIGHTING); @@ -3432,7 +3452,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) glDrawArrays(GL_LINES, 0, 2*totpoint); break; case PART_DRAW_BB: - if(MIN2(G.vd->drawtype, ob->dt)<=OB_WIRE) + if(dt<=OB_WIRE) glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glDrawArrays(GL_QUADS, 0, 4*totpoint); @@ -3486,7 +3506,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) mymultmatrix(ob->obmat); // bring back local matrix for dtx } -static void draw_particle_edit(Object *ob, ParticleSystem *psys) +static void draw_particle_edit(Object *ob, ParticleSystem *psys, int dt) { ParticleEdit *edit = psys->edit; ParticleData *pa; @@ -3499,6 +3519,7 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys) float nosel_col[3]; char val[32]; + /* create path and child path cache if it doesn't exist already */ if(psys->pathcache==0){ PE_hide_keys_time(psys,CFRA); psys_cache_paths(ob,psys,CFRA,0); @@ -3513,11 +3534,13 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys) else if(!(pset->flag & PE_SHOW_CHILD) && psys->childcache) free_child_path_cache(psys); + /* opengl setup */ if((G.vd->flag & V3D_ZBUF_SELECT)==0) glDisable(GL_DEPTH_TEST); myloadmatrix(G.vd->viewmat); + /* get selection theme colors */ BIF_GetThemeColor3ubv(TH_VERTEX_SELECT, sel); BIF_GetThemeColor3ubv(TH_VERTEX, nosel); sel_col[0]=(float)sel[0]/255.0f; @@ -3531,41 +3554,61 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys) totchild = psys->totchildcache; /* draw paths */ - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); if(timed) glEnable(GL_BLEND); - if(pset->brushtype == PE_BRUSH_WEIGHT){ - glLineWidth(2.0f); + glEnableClientState(GL_VERTEX_ARRAY); + + if(dt > OB_WIRE) { + /* solid shaded with lighting */ + glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); + + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + } + else { + /* flat wire color */ + glDisableClientState(GL_NORMAL_ARRAY); glDisable(GL_LIGHTING); + BIF_ThemeColor(TH_WIRE); } - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - - for(i=0, pa=psys->particles, path = psys->pathcache; i<totpart; i++, pa++, path++){ - glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co); - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); - - glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); - } + /* only draw child paths with lighting */ + if(dt > OB_WIRE) + glEnable(GL_LIGHTING); - glEnable(GL_LIGHTING); if(psys->part->draw_as == PART_DRAW_PATH) { for(i=0, path=psys->childcache; i<totchild; i++,path++){ glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co); - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + if(dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + } glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); } } - glDisable(GL_COLOR_MATERIAL); + if(dt > OB_WIRE) + glDisable(GL_LIGHTING); + + if(pset->brushtype == PE_BRUSH_WEIGHT) { + glLineWidth(2.0f); + glEnableClientState(GL_COLOR_ARRAY); + glDisable(GL_LIGHTING); + } + + /* draw parents last without lighting */ + for(i=0, pa=psys->particles, path = psys->pathcache; i<totpart; i++, pa++, path++){ + glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co); + if(dt > OB_WIRE) + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); + if(dt > OB_WIRE || pset->brushtype == PE_BRUSH_WEIGHT) + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + + glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); + } /* draw edit vertices */ if(G.scene->selectmode!=SCE_SELECT_PATH){ @@ -3639,6 +3682,7 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys) glDisable(GL_BLEND); glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); glDisableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnable(GL_DEPTH_TEST); @@ -5031,12 +5075,12 @@ void draw_object(Base *base, int flag) glDepthMask(GL_FALSE); for(psys=ob->particlesystem.first; psys; psys=psys->next) - draw_new_particle_system(base, psys); + draw_new_particle_system(base, psys, dt); if(G.f & G_PARTICLEEDIT && ob==OBACT) { psys= PE_get_current(ob); if(psys && !G.obedit && psys_in_edit_mode(psys)) - draw_particle_edit(ob, psys); + draw_particle_edit(ob, psys, dt); } glDepthMask(GL_TRUE); if(col) cpack(col); diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index 172e06f5add..c166a9df762 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -4097,16 +4097,34 @@ void transform_armature_mirror_update(void) if (eboflip) { /* we assume X-axis flipping for now */ if (ebo->flag & BONE_TIPSEL) { + EditBone *children; + eboflip->tail[0]= -ebo->tail[0]; eboflip->tail[1]= ebo->tail[1]; eboflip->tail[2]= ebo->tail[2]; eboflip->rad_tail= ebo->rad_tail; + + /* Also move connected children, in case children's name aren't mirrored properly */ + for (children=G.edbo.first; children; children=children->next) { + if (children->parent == eboflip && children->flag & BONE_CONNECTED) { + VECCOPY(children->head, eboflip->tail); + children->rad_head = ebo->rad_tail; + } + } } if (ebo->flag & BONE_ROOTSEL) { eboflip->head[0]= -ebo->head[0]; eboflip->head[1]= ebo->head[1]; eboflip->head[2]= ebo->head[2]; eboflip->rad_head= ebo->rad_head; + + /* Also move connected parent, in case parent's name isn't mirrored properly */ + if (eboflip->parent && eboflip->flag & BONE_CONNECTED) + { + EditBone *parent = eboflip->parent; + VECCOPY(parent->tail, eboflip->head); + parent->rad_tail = ebo->rad_head; + } } if (ebo->flag & BONE_SELECTED) { eboflip->dist= ebo->dist; diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c index 7572391b383..bd0abe83ee4 100644 --- a/source/blender/src/editcurve.c +++ b/source/blender/src/editcurve.c @@ -99,7 +99,7 @@ ListBase editNurb; BPoint *lastselbp; -Nurb *lastnu; /* for selected */ +int actnu; /* for selected */ /* void freeNurblist(ListBase *lb); already declared in the kernel */ @@ -109,6 +109,23 @@ float nurbcircle[8][2]= { {0.0, 1.0}, { 1.0, 1.0}, { 1.0, 0.0}, { 1.0, -1.0} }; + +/* this replaces the active flag used in uv/face mode */ +void set_actNurb(Nurb *nu) +{ + if (nu==NULL) { + actnu = -1; + } else { + actnu = BLI_findindex(&editNurb, nu); + } +} + +Nurb * get_actNurb( void ) +{ + return BLI_findlink(&editNurb, actnu); +} + + /* ******************* SELECTION FUNCTIONS ********************* */ /* returns 1 in case (de)selection was successful */ @@ -318,14 +335,14 @@ void load_editNurb() BLI_addtail(&(cu->nurb), newnu); if((nu->type & 7)==CU_NURBS) { - if(nu->pntsu < nu->orderu) nu->orderu= nu->pntsu; + clamp_nurb_order_u(nu); } } } } - lastnu= NULL; /* for selected */ + set_actNurb(NULL); } void make_editNurb() @@ -361,8 +378,7 @@ void make_editNurb() else G.obedit= NULL; countall(); - - lastnu= NULL; /* for selected */ + set_actNurb(NULL); } void remake_editNurb() @@ -457,8 +473,7 @@ void separate_nurb() countall(); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); - - lastnu= NULL; /* for selected */ + set_actNurb(NULL); } /* ******************* FLAGS ********************* */ @@ -640,7 +655,7 @@ void deleteflagNurb(short flag) } if(a==0) { BLI_remlink(&editNurb, nu); - freeNurb(nu); + freeNurb(nu); nu=NULL; } else { /* is nurb in U direction selected */ @@ -674,7 +689,7 @@ void deleteflagNurb(short flag) nu->pntsv= newv; MEM_freeN(nu->bp); nu->bp= newbp; - if(nu->orderv>nu->pntsv) nu->orderv= nu->pntsv; + clamp_nurb_order_v(nu); makeknots(nu, 2, nu->flagv>>1); } @@ -714,13 +729,13 @@ void deleteflagNurb(short flag) nu->pntsu= nu->pntsv; nu->pntsv= 1; SWAP(short, nu->orderu, nu->orderv); - if(nu->orderu>nu->pntsu) nu->orderu= nu->pntsu; + clamp_nurb_order_u(nu); if(nu->knotsv) MEM_freeN(nu->knotsv); - nu->knotsv= 0; + nu->knotsv= NULL; } else { nu->pntsu= newu; - if(nu->orderu>nu->pntsu) nu->orderu= nu->pntsu; + clamp_nurb_order_u(nu); } makeknots(nu, 1, nu->flagu>>1); } @@ -878,7 +893,7 @@ void adduplicateflagNurb(short flag) newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN"); memcpy(newnu, nu, sizeof(Nurb)); BLI_addtail(&editNurb, newnu); - lastnu= newnu; + set_actNurb(newnu); newnu->pntsu= enda-starta+1; newnu->bezt= (BezTriple*)MEM_mallocN((enda - starta + 1) * sizeof(BezTriple), "adduplicateN"); @@ -891,8 +906,10 @@ void adduplicateflagNurb(short flag) bezt1++; } - if(nu->flagu & 1) { - if(starta!=0 || enda!=nu->pntsu-1) newnu->flagu--; + if(nu->flagu & CU_CYCLIC) { + if(starta!=0 || enda!=nu->pntsu-1) { + newnu->flagu &= ~CU_CYCLIC; + } } } bezt++; @@ -913,7 +930,7 @@ void adduplicateflagNurb(short flag) if(enda>=starta) { newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN3"); memcpy(newnu, nu, sizeof(Nurb)); - lastnu= newnu; + set_actNurb(newnu); BLI_addtail(&editNurb, newnu); newnu->pntsu= enda-starta+1; newnu->bp = (BPoint*)MEM_mallocN((enda-starta+1) * sizeof(BPoint), "adduplicateN4"); @@ -926,12 +943,14 @@ void adduplicateflagNurb(short flag) bp1++; } - if(nu->flagu & 1) { - if(starta!=0 || enda!=nu->pntsu-1) newnu->flagu--; + if(nu->flagu & CU_CYCLIC) { + if(starta!=0 || enda!=nu->pntsu-1) { + newnu->flagu &= ~CU_CYCLIC; + } } /* knots */ - newnu->knotsu= 0; + newnu->knotsu= NULL; makeknots(newnu, 1, newnu->flagu>>1); } bp++; @@ -971,14 +990,16 @@ void adduplicateflagNurb(short flag) newnu = (Nurb*)MEM_mallocN(sizeof(Nurb), "adduplicateN5"); memcpy(newnu, nu, sizeof(Nurb)); BLI_addtail(&editNurb, newnu); - lastnu= newnu; + set_actNurb(newnu); newnu->pntsu= newu; newnu->pntsv= newv; newnu->bp = (BPoint*)MEM_mallocN(newu * newv * sizeof(BPoint), "adduplicateN6"); - newnu->orderu= MIN2(nu->orderu, newu); - newnu->orderv= MIN2(nu->orderv, newv); - + clamp_nurb_order_u(newnu); + clamp_nurb_order_v(newnu); + + newnu->knotsu= newnu->knotsv= NULL; + bp= newnu->bp; bp1= nu->bp; for(a=0; a<nu->pntsv; a++) { @@ -990,23 +1011,20 @@ void adduplicateflagNurb(short flag) } } } - if(nu->pntsu==newnu->pntsu) { - newnu->knotsu= MEM_mallocN(sizeof(float)*KNOTSU(nu), "adduplicateN6"); - memcpy(newnu->knotsu, nu->knotsu, sizeof(float)*KNOTSU(nu)); - } - else { - newnu->knotsu= 0; - makeknots(newnu, 1, newnu->flagu>>1); - } - if(nu->pntsv==newnu->pntsv) { - newnu->knotsv= MEM_mallocN(sizeof(float)*KNOTSV(nu), "adduplicateN7"); - memcpy(newnu->knotsv, nu->knotsv, sizeof(float)*KNOTSV(nu)); + if (check_valid_nurb_u(newnu)) { + if(nu->pntsu==newnu->pntsu && nu->knotsu) { + newnu->knotsu= MEM_dupallocN( nu->knotsu ); + } else { + makeknots(newnu, 1, newnu->flagu>>1); + } } - else { - newnu->knotsv= 0; - makeknots(newnu, 2, newnu->flagv>>1); + if (check_valid_nurb_v(newnu)) { + if(nu->pntsv==newnu->pntsv && nu->knotsv) { + newnu->knotsv= MEM_dupallocN( nu->knotsv ); + } else { + makeknots(newnu, 2, newnu->flagv>>1); + } } - } MEM_freeN(usel); } @@ -1015,7 +1033,7 @@ void adduplicateflagNurb(short flag) nu= nu->prev; } - /* lastnu changed */ + /* actnu changed */ allqueue(REDRAWBUTSEDIT, 0); } @@ -1569,7 +1587,7 @@ void subdivideNurb() newly created. Old points are discarded. */ /* count */ - if(nu->flagu & 1) { + if(nu->flagu & CU_CYCLIC) { a= nu->pntsu; bezt= nu->bezt; prevbezt= bezt+(a-1); @@ -1590,7 +1608,7 @@ void subdivideNurb() beztnew = (BezTriple*)MEM_mallocN((amount + nu->pntsu) * sizeof(BezTriple), "subdivNurb"); beztn= beztnew; - if(nu->flagu & 1) { + if(nu->flagu & CU_CYCLIC) { a= nu->pntsu; bezt= nu->bezt; prevbezt= bezt+(a-1); @@ -1622,7 +1640,7 @@ void subdivideNurb() VecMidf(beztn->vec[1], vec+9, vec+12); VECCOPY(beztn->vec[2], vec+12); /* handle of next bezt */ - if(a==0 && (nu->flagu & 1)) {VECCOPY(beztnew->vec[0], vec+6);} + if(a==0 && (nu->flagu & CU_CYCLIC)) {VECCOPY(beztnew->vec[0], vec+6);} else {VECCOPY(bezt->vec[0], vec+6);} beztn->radius = (prevbezt->radius + bezt->radius)/2.0f; @@ -1635,7 +1653,7 @@ void subdivideNurb() bezt++; } /* last point */ - if((nu->flagu & 1)==0) memcpy(beztn, prevbezt, sizeof(BezTriple)); + if((nu->flagu & CU_CYCLIC)==0) memcpy(beztn, prevbezt, sizeof(BezTriple)); MEM_freeN(nu->bezt); nu->bezt= beztnew; @@ -1652,7 +1670,7 @@ void subdivideNurb() stable... nzc 30-5-'00 */ /* count */ - if(nu->flagu & 1) { + if(nu->flagu & CU_CYCLIC) { a= nu->pntsu*nu->pntsv; bp= nu->bp; prevbp= bp+(a-1); @@ -1674,7 +1692,7 @@ void subdivideNurb() (BPoint*)MEM_mallocN((amount + nu->pntsu) * sizeof(BPoint), "subdivNurb2"); bpn= bpnew; - if(nu->flagu & 1) { + if(nu->flagu & CU_CYCLIC) { a= nu->pntsu; bp= nu->bp; prevbp= bp+(a-1); @@ -1701,7 +1719,7 @@ void subdivideNurb() prevbp= bp; bp++; } - if((nu->flagu & 1)==0) memcpy(bpn, prevbp, sizeof(BPoint)); /* last point */ + if((nu->flagu & CU_CYCLIC)==0) memcpy(bpn, prevbp, sizeof(BPoint)); /* last point */ MEM_freeN(nu->bp); nu->bp= bpnew; @@ -2075,7 +2093,7 @@ int convertspline(short type, Nurb *nu) nu->type &= ~7; nu->type+= 4; nu->orderu= 4; - nu->flagu &= 1; + nu->flagu &= CU_CYCLIC; /* disable all flags except for cyclic */ nu->flagu += 4; makeknots(nu, 1, nu->flagu>>1); a= nu->pntsu*nu->pntsv; @@ -2126,10 +2144,10 @@ int convertspline(short type, Nurb *nu) nu->orderv= 1; nu->type &= ~7; nu->type+= type; - if(nu->flagu & 1) c= nu->orderu-1; + if(nu->flagu & CU_CYCLIC) c= nu->orderu-1; else c= 0; if(type== 4) { - nu->flagu &= 1; + nu->flagu &= CU_CYCLIC; /* disable all flags except for cyclic */ nu->flagu += 4; makeknots(nu, 1, nu->flagu>>1); } @@ -2139,9 +2157,9 @@ int convertspline(short type, Nurb *nu) if(type==0) { /* to Poly */ nu->type &= ~7; if(nu->knotsu) MEM_freeN(nu->knotsu); /* python created nurbs have a knotsu of zero */ - nu->knotsu= 0; + nu->knotsu= NULL; if(nu->knotsv) MEM_freeN(nu->knotsv); - nu->knotsv= 0; + nu->knotsv= NULL; } else if(type==CU_BEZIER) { /* to Bezier */ nr= nu->pntsu/3; @@ -2170,7 +2188,7 @@ int convertspline(short type, Nurb *nu) MEM_freeN(nu->bp); nu->bp= 0; MEM_freeN(nu->knotsu); - nu->knotsu= 0; + nu->knotsu= NULL; nu->pntsu= nr; nu->type &= ~7; nu->type+= 1; @@ -2481,7 +2499,7 @@ void merge_nurb() BLI_freelistN(&nsortbase); countall(); - lastnu= NULL; + set_actNurb(NULL); DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); @@ -2527,7 +2545,7 @@ void addsegment_nurb() /* find both nurbs and points, nu1 will be put behind nu2 */ for(nu= editNurb.first; nu; nu= nu->next) { - if((nu->flagu & 1)==0) { /* not cyclic */ + if((nu->flagu & CU_CYCLIC)==0) { /* not cyclic */ if( (nu->type & 7)==CU_BEZIER ) { bezt= nu->bezt; if(nu1==0) { @@ -2594,7 +2612,7 @@ void addsegment_nurb() nu1->bezt= bezt; nu1->pntsu+= nu2->pntsu; BLI_remlink(&editNurb, nu2); - freeNurb(nu2); + freeNurb(nu2); nu2= NULL; calchandlesNurb(nu1); } else { @@ -2632,11 +2650,11 @@ void addsegment_nurb() } } } - freeNurb(nu2); + freeNurb(nu2); nu2= NULL; } } - lastnu= NULL; /* for selected */ + set_actNurb(NULL); /* for selected */ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); @@ -2704,8 +2722,8 @@ void mouse_nurb() rightmouse_transform(); - if(nu!=lastnu) { - lastnu= nu; + if(nu!=get_actNurb()) { + set_actNurb(nu); allqueue(REDRAWBUTSEDIT, 0); } @@ -2808,7 +2826,7 @@ static void spin_nurb(float *dvec, short mode) for(nu= editNurb.first; nu; nu= nu->next) { if(isNurbsel(nu)) { nu->orderv= 4; - nu->flagv |= 1; + nu->flagv |= CU_CYCLIC; makeknots(nu, 2, nu->flagv>>1); } } @@ -3006,8 +3024,8 @@ void makecyclicNurb() bp= nu->bp; while(a--) { if( bp->f1 & SELECT ) { - if(nu->flagu & CU_CYCLIC) nu->flagu--; - else nu->flagu++; + if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC; + else nu->flagu |= CU_CYCLIC; break; } bp++; @@ -3018,8 +3036,8 @@ void makecyclicNurb() bezt= nu->bezt; while(a--) { if( BEZSELECTED_HIDDENHANDLES(bezt) ) { - if(nu->flagu & CU_CYCLIC) nu->flagu--; - else nu->flagu++; + if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC; + else nu->flagu |= CU_CYCLIC; break; } bezt++; @@ -3027,26 +3045,28 @@ void makecyclicNurb() calchandlesNurb(nu); } else if(nu->pntsv==1 && (nu->type & 7)==CU_NURBS) { - a= nu->pntsu; - bp= nu->bp; - while(a--) { - if( bp->f1 & SELECT ) { - if(nu->flagu & CU_CYCLIC) nu->flagu--; - else { - nu->flagu++; - nu->flagu &= ~2; /* endpoint flag, fixme */ - fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); - b= (nu->orderu+nu->pntsu); - memcpy(fp, nu->knotsu, sizeof(float)*b); - MEM_freeN(nu->knotsu); - nu->knotsu= fp; + if (nu->knotsu) { /* if check_valid_nurb_u fails the knotsu can be NULL */ + a= nu->pntsu; + bp= nu->bp; + while(a--) { + if( bp->f1 & SELECT ) { + if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC; + else { + nu->flagu |= CU_CYCLIC; + nu->flagu &= ~2; /* endpoint flag, fixme */ + fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); + b= (nu->orderu+nu->pntsu); + memcpy(fp, nu->knotsu, sizeof(float)*b); + MEM_freeN(nu->knotsu); + nu->knotsu= fp; - makeknots(nu, 1, 0); /* 1==u 0==uniform */ + makeknots(nu, 1, 0); /* 1==u 0==uniform */ + } + break; } - break; + bp++; } - bp++; } } else if(nu->type==CU_NURBS) { @@ -3060,29 +3080,37 @@ void makecyclicNurb() if( bp->f1 & SELECT) { if(cyclmode==1 && nu->pntsu>1) { - if(nu->flagu & CU_CYCLIC) nu->flagu--; + if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC; else { - nu->flagu++; - fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); - b= (nu->orderu+nu->pntsu); - memcpy(fp, nu->knotsu, sizeof(float)*b); - MEM_freeN(nu->knotsu); - nu->knotsu= fp; + nu->flagu |= CU_CYCLIC; + if (check_valid_nurb_u(nu)) { + fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); + b= (nu->orderu+nu->pntsu); + if (nu->knotsu) { /* null if check_valid_nurb_u failed before but is valid now */ + memcpy(fp, nu->knotsu, sizeof(float)*b); + MEM_freeN(nu->knotsu); + } + nu->knotsu= fp; - makeknots(nu, 1, 0); /* 1==u 0==uniform */ + makeknots(nu, 1, 0); /* 1==u 0==uniform */ + } } } if(cyclmode==2 && nu->pntsv>1) { if(nu->flagv & 1) nu->flagv--; else { nu->flagv++; - fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN"); - b= (nu->orderv+nu->pntsv); - memcpy(fp, nu->knotsv, sizeof(float)*b); - MEM_freeN(nu->knotsv); - nu->knotsv= fp; + if (check_valid_nurb_v(nu)) { + fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN"); + b= (nu->orderv+nu->pntsv); + if (nu->knotsv) { /* null if check_valid_nurb_v failed before but is valid now */ + memcpy(fp, nu->knotsv, sizeof(float)*b); + MEM_freeN(nu->knotsv); + } + nu->knotsv= fp; - makeknots(nu, 2, 0); /* 2==v 0==uniform */ + makeknots(nu, 2, 0); /* 2==v 0==uniform */ + } } } break; @@ -3638,7 +3666,7 @@ void delNurb() } if(a==0) { BLI_remlink(&editNurb, nu); - freeNurb(nu); + freeNurb(nu); nu= NULL; } } } @@ -3654,15 +3682,18 @@ void delNurb() } if(a==0) { BLI_remlink(&editNurb, nu); - freeNurb(nu); + freeNurb(nu); nu= NULL; } } } - /* Never allow the order to exceed the number of points */ - if ((nu->type & 7)==CU_NURBS && (nu->pntsu < nu->orderu)) { - nu->orderu = nu->pntsu; + /* Never allow the order to exceed the number of points + - note, this is ok but changes unselected nurbs, disable for now */ + /* + if ((nu!= NULL) && ((nu->type & 7)==CU_NURBS)) { + clamp_nurb_order_u(nu); } + */ nu= next; } /* 2nd loop, delete small pieces: just for curves */ @@ -3710,10 +3741,12 @@ void delNurb() MEM_freeN(nu->bp); nu->bp= bp1; - /* Never allow the order to exceed the number of points */ - if ((nu->type & 7)==CU_NURBS && (nu->pntsu < nu->orderu)) { - nu->orderu = nu->pntsu; - } + /* Never allow the order to exceed the number of points\ + - note, this is ok but changes unselected nurbs, disable for now */ + /* + if ((nu->type & 7)==CU_NURBS) { + clamp_nurb_order_u(nu); + }*/ } makeknots(nu, 1, nu->flagu>>1); } @@ -3736,10 +3769,10 @@ void delNurb() bezt2= bezt+1; if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) ; else { /* maybe do not make cyclic */ - if(a==0 && (nu->flagu & 1) ) { + if(a==0 && (nu->flagu & CU_CYCLIC) ) { bezt2= bezt+(nu->pntsu-1); if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) { - nu->flagu--; + nu->flagu &= ~CU_CYCLIC; DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -3763,10 +3796,10 @@ void delNurb() bp2= bp+1; if( bp2->f1 & 1 ) ; else { /* maybe do not make cyclic */ - if(a==0 && (nu->flagu & 1) ) { + if(a==0 && (nu->flagu & CU_CYCLIC) ) { bp2= bp+(nu->pntsu-1); - if( bp2->f1 & 1 ) { - nu->flagu--; + if( bp2->f1 & SELECT ) { + nu->flagu &= ~CU_CYCLIC; DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -3790,16 +3823,16 @@ void delNurb() if(bezt1) { if(nu1->pntsu==2) { /* remove completely */ BLI_remlink(&editNurb, nu); - freeNurb(nu); + freeNurb(nu); nu = NULL; } - else if(nu1->flagu & 1) { /* cyclic */ + else if(nu1->flagu & CU_CYCLIC) { /* cyclic */ bezt = (BezTriple*)MEM_mallocN((cut+1) * sizeof(BezTriple), "delNurb1"); memcpy(bezt, nu1->bezt,(cut+1)*sizeof(BezTriple)); a= nu1->pntsu-cut-1; memcpy(nu1->bezt, bezt2, a*sizeof(BezTriple)); memcpy(nu1->bezt+a, bezt, (cut+1)*sizeof(BezTriple)); - nu1->flagu--; + nu1->flagu &= ~CU_CYCLIC; MEM_freeN(bezt); calchandlesNurb(nu); } @@ -3832,16 +3865,16 @@ void delNurb() else if(bp1) { if(nu1->pntsu==2) { /* remove completely */ BLI_remlink(&editNurb, nu); - freeNurb(nu); + freeNurb(nu); nu= NULL; } - else if(nu1->flagu & 1) { /* cyclic */ + else if(nu1->flagu & CU_CYCLIC) { /* cyclic */ bp = (BPoint*)MEM_mallocN((cut+1) * sizeof(BPoint), "delNurb5"); memcpy(bp, nu1->bp,(cut+1)*sizeof(BPoint)); a= nu1->pntsu-cut-1; memcpy(nu1->bp, bp2, a*sizeof(BPoint)); memcpy(nu1->bp+a, bp, (cut+1)*sizeof(BPoint)); - nu1->flagu--; + nu1->flagu &= ~CU_CYCLIC; MEM_freeN(bp); } else { /* add new curve */ @@ -4151,7 +4184,7 @@ Nurb *addNurbprim(int type, int stype, int newname) if((type & 7)==CU_BEZIER) { nu->pntsu= 4; nu->bezt= callocstructN(BezTriple, 4, "addNurbprim1"); - nu->flagu= 1; + nu->flagu= CU_CYCLIC; bezt= nu->bezt; for(a=0;a<3;a++) { @@ -4200,7 +4233,7 @@ Nurb *addNurbprim(int type, int stype, int newname) nu->pntsv= 1; nu->orderu= 4; nu->bp= callocstructN(BPoint, 8, "addNurbprim6"); - nu->flagu= 1; + nu->flagu= CU_CYCLIC; bp= nu->bp; for(a=0; a<8; a++) { @@ -4592,10 +4625,6 @@ static void undoCurve_to_editCurve(void *lbv) { ListBase *lb= lbv; Nurb *nu, *newnu; - int nr, lastnunr= 0; - - /* we try to restore lastnu too, for buttons */ - for(nu= editNurb.first; nu; nu = nu->next, lastnunr++) if(nu==lastnu) break; freeNurblist(&editNurb); @@ -4604,9 +4633,6 @@ static void undoCurve_to_editCurve(void *lbv) newnu= duplicateNurb(nu); BLI_addtail(&editNurb, newnu); } - /* restore */ - for(nr=0, lastnu= editNurb.first; lastnu; lastnu = lastnu->next, nr++) if(nr==lastnunr) break; - } static void *editCurve_to_undoCurve(void) diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c index afafc4f2590..9057556b796 100644 --- a/source/blender/src/editnode.c +++ b/source/blender/src/editnode.c @@ -166,13 +166,14 @@ static void snode_handle_recalc(SpaceNode *snode) snode->nodetree->test_break= NULL; waitcursor(0); - allqueue(REDRAWNODE, 1); allqueue(REDRAWIMAGE, 1); if(G.scene->r.scemode & R_DOCOMP) { BIF_redraw_render_rect(); /* seems to screwup display? */ mywinset(curarea->win); } } + + allqueue(REDRAWNODE, 1); } } diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index ab8e53c3cb3..6582866d9a1 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -3394,6 +3394,7 @@ static int ui_do_but_HSVCUBE(uiBut *but) /* we redraw the entire block */ for (bt= but->block->buttons.first; bt; bt= bt->next) { if(but->poin == bt->poin) VECCOPY(bt->hsv, but->hsv); + ui_check_but(bt); ui_draw_but(bt); } ui_block_flush_back(but->block); diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index 4c97a8fdbdf..dcceea971f7 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -659,6 +659,10 @@ void pose_copy_menu(void) free_constraints(&pchan->constraints); copy_constraints(&pchan->constraints, &pchanact->constraints); pchan->constflag = pchanact->constflag; + + if (ob->pose) { + ob->pose->flag |= POSE_RECALC; + } } break; case 6: /* Transform Locks */ @@ -741,6 +745,10 @@ void pose_copy_menu(void) } BLI_freelistN(&const_copy); update_pose_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */ + + if (ob->pose) { + ob->pose->flag |= POSE_RECALC; + } } DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); // and all its relations diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 1aca097e373..bf519dd6e9c 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -1632,6 +1632,36 @@ static void copy_to_ibuf_still(Sequence * seq, TStripElem * se) } } +static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown) +{ + Sequence* seq_arr[MAXSEQ+1]; + int i; + TStripElem* se = 0; + + evaluate_seq_frame_gen(seq_arr, seqbasep, cfra); + + for (i = 0; i < MAXSEQ; i++) { + if (!video_seq_is_rendered(seq_arr[i])) { + continue; + } + se = give_tstripelem(seq_arr[i], cfra); + if (se) { + if (se->ibuf) { + IMB_freeImBuf(se->ibuf); + + se->ibuf= 0; + se->ok= STRIPELEM_OK; + } + + if (se->ibuf_comp) { + IMB_freeImBuf(se->ibuf_comp); + + se->ibuf_comp = 0; + } + } + } + +} static TStripElem* do_build_seq_array_recursively( ListBase *seqbasep, int cfra, int chanshown); @@ -1682,6 +1712,10 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, use_limiter = TRUE; } } + if (meta_se) { + free_metastrip_imbufs( + &seq->seqbase, seq->start + se->nr, 0); + } if (use_limiter) { input_preprocess(seq, se, cfra); diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 5b6af61949f..5f80f14d069 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -228,8 +228,8 @@ void persptoetsen(unsigned short event) } else { /* Indicate that this view is not inverted. - * Don't do this for PADMINUS/PADPLUSKEY, though. (jobbe)*/ - if (event != PADMINUS && event != PADPLUSKEY) + * Don't do this for PADMINUS/PADPLUSKEY/PAD5, though. (jobbe)*/ + if (! ELEM3(event, PADMINUS, PADPLUSKEY, PAD5) ) G.vd->flag2 &= ~V3D_OPP_DIRECTION_NAME; diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index f69218664ea..4be525f4945 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -4054,6 +4054,7 @@ void createTransData(TransInfo *t) t->flag |= T_POINTS; } else { + t->flag &= ~T_PROP_EDIT; /* no proportional edit in object mode */ createTransObject(t); t->flag |= T_OBJECT; } diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index a656c5e5523..ffd66655069 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -125,6 +125,22 @@ void KX_BlenderRenderTools::BeginFrame(RAS_IRasterizer* rasty) } +void KX_BlenderRenderTools::SetClientObject(void* obj) +{ + if (m_clientobject != obj) + { + if (obj == NULL || !((KX_GameObject*)obj)->IsNegativeScaling()) + { + glFrontFace(GL_CCW); + } else + { + glFrontFace(GL_CW); + } + m_clientobject = obj; + m_modified = true; + } +} + bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data) { double* const oglmatrix = (double* const) data; diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h index 662f5bd9af1..31eaa14d66b 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h @@ -105,6 +105,8 @@ public: virtual void Render2DFilters(RAS_ICanvas* canvas); + virtual void SetClientObject(void* obj); + }; #endif //__KX_BLENDERRENDERTOOLS diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 089af9a68e7..82d16ffa181 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -87,6 +87,7 @@ #include "DNA_action_types.h" #include "BKE_main.h" #include "BKE_global.h" +#include "BKE_object.h" #include "BL_SkinMeshObject.h" #include "BL_SkinDeformer.h" #include "BL_MeshDeformer.h" @@ -1571,8 +1572,9 @@ static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX return gamelight; } -static KX_Camera *gamecamera_from_bcamera(Camera *ca, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) { - RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP); +static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) { + Camera* ca = static_cast<Camera*>(ob->data); + RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob)); KX_Camera *gamecamera; gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata); @@ -1607,7 +1609,7 @@ static KX_GameObject *gameobject_from_blenderobject( case OB_CAMERA: { - KX_Camera* gamecamera = gamecamera_from_bcamera(static_cast<Camera*>(ob->data), kxscene, converter); + KX_Camera* gamecamera = gamecamera_from_bcamera(ob, kxscene, converter); gameobj = gamecamera; //don't add a reference: the camera list in kxscene->m_cameras is not released at the end diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index edda7657ef9..885981a2898 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -462,6 +462,22 @@ int GPC_RenderTools::applyLights(int objectlayer) } +void GPC_RenderTools::SetClientObject(void* obj) +{ + if (m_clientobject != obj) + { + if (obj == NULL || !((KX_GameObject*)obj)->IsNegativeScaling()) + { + glFrontFace(GL_CCW); + } else + { + glFrontFace(GL_CW); + } + m_clientobject = obj; + m_modified = true; + } +} + bool GPC_RenderTools::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data) { double* const oglmatrix = (double* const) data; diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h index 9b86869af73..ee0212da643 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h @@ -153,6 +153,8 @@ public: virtual void Render2DFilters(RAS_ICanvas* canvas); + virtual void SetClientObject(void* obj); + protected: /** * Copied from KX_BlenderGL.cpp in KX_blenderhook diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 09eb2053bfe..27e47d72bbe 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -204,6 +204,11 @@ float KX_Camera::GetCameraFar() const return m_camdata.m_clipend; } +float KX_Camera::GetFocalLength() const +{ + return m_camdata.m_focallength; +} + RAS_CameraData* KX_Camera::GetCameraData() diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 4cc8c049f91..75d574cd697 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -184,12 +184,14 @@ public: */ const MT_Matrix4x4& GetModelviewMatrix() const; - /** Gets the focal length. */ + /** Gets the aperture. */ float GetLens() const; /** Gets the near clip distance. */ float GetCameraNear() const; /** Gets the far clip distance. */ float GetCameraFar() const; + /** Gets the focal length (only used for stereo rendering) */ + float GetFocalLength() const; /** Gets all camera data. */ RAS_CameraData* GetCameraData(); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index fb636b23082..dada47e2fa4 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -77,6 +77,7 @@ KX_GameObject::KX_GameObject( m_layer(0), m_bSuspendDynamics(false), m_bUseObjectColor(false), + m_bIsNegativeScaling(false), m_bVisible(true), m_pPhysicsController1(NULL), m_pPhysicsEnvironment(NULL), @@ -335,7 +336,7 @@ double* KX_GameObject::GetOpenGLMatrix() trans.setBasis(GetSGNode()->GetWorldOrientation()); MT_Vector3 scaling = GetSGNode()->GetWorldScaling(); - + m_bIsNegativeScaling = ((scaling[0] < 0.0) ^ (scaling[1] < 0.0) ^ (scaling[2] < 0.0)) ? true : false; trans.scale(scaling[0], scaling[1], scaling[2]); trans.getValue(fl); @@ -743,6 +744,7 @@ PyMethodDef KX_GameObject::Methods[] = { {"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS}, KX_PYMETHODTABLE(KX_GameObject, getDistanceTo), KX_PYMETHODTABLE(KX_GameObject, rayCastTo), + KX_PYMETHODTABLE(KX_GameObject, rayCast), {NULL,NULL} //Sentinel }; @@ -1325,7 +1327,7 @@ bool KX_GameObject::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT } KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, -"rayCastTo(other,dist,prop): look towards another point/KX_GameObject and return first object hit within dist that match prop\n" +"rayCastTo(other,dist,prop): look towards another point/KX_GameObject and return first object hit within dist that matches prop\n" " prop = property name that object must have; can be omitted => detect any object\n" " dist = max distance to look (can be negative => look behind); 0 or omitted => detect up to other\n" " other = 3-tuple or object reference") @@ -1380,6 +1382,89 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, Py_Return; } +KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, +"rayCast(to,from,dist,prop): cast a ray and return tuple (object,hit,normal) of contact point with object within dist that matches prop or None if no hit\n" +" prop = property name that object must have; can be omitted => detect any object\n" +" dist = max distance to look (can be negative => look behind); 0 or omitted => detect up to to\n" +" from = 3-tuple or object reference for origin of ray (if object, use center of object)\n" +" Can None or omitted => start from self object center\n" +" to = 3-tuple or object reference for destination of ray (if object, use center of object)\n" +"Note: the object on which you call this method matters: the ray will ignore it if it goes through it\n") +{ + MT_Point3 toPoint; + MT_Point3 fromPoint; + PyObject* pyto; + PyObject* pyfrom = NULL; + float dist = 0.0f; + char *propName = NULL; + KX_GameObject *other; + + if (!PyArg_ParseTuple(args,"O|Ofs", &pyto, &pyfrom, &dist, &propName)) + return NULL; + + if (!PyVecTo(pyto, toPoint)) + { + PyErr_Clear(); + if (!PyType_IsSubtype(pyto->ob_type, &KX_GameObject::Type)) + return NULL; + other = static_cast<KX_GameObject*>(pyto); + toPoint = other->NodeGetWorldPosition(); + } + if (!pyfrom || pyfrom == Py_None) + { + fromPoint = NodeGetWorldPosition(); + } + else if (!PyVecTo(pyfrom, fromPoint)) + { + PyErr_Clear(); + if (!PyType_IsSubtype(pyfrom->ob_type, &KX_GameObject::Type)) + return NULL; + other = static_cast<KX_GameObject*>(pyfrom); + fromPoint = other->NodeGetWorldPosition(); + } + + if (dist != 0.0f) + { + MT_Vector3 toDir = toPoint-fromPoint; + toDir.normalize(); + toPoint = fromPoint + (dist) * toDir; + } + + MT_Point3 resultPoint; + MT_Vector3 resultNormal; + PHY_IPhysicsEnvironment* pe = GetPhysicsEnvironment(); + KX_IPhysicsController *spc = GetPhysicsController(); + KX_GameObject *parent = GetParent(); + if (!spc && parent) + spc = parent->GetPhysicsController(); + if (parent) + parent->Release(); + + m_pHitObject = NULL; + if (propName) + m_testPropName = propName; + else + m_testPropName.SetLength(0); + KX_RayCast::RayTest(spc, pe, fromPoint, toPoint, resultPoint, resultNormal, KX_RayCast::Callback<KX_GameObject>(this)); + + if (m_pHitObject) + { + PyObject* returnValue = PyTuple_New(3); + if (!returnValue) + return NULL; + PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->AddRef()); + PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(resultPoint)); + PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(resultNormal)); + return returnValue; + //return Py_BuildValue("(O,(fff),(fff))", + // m_pHitObject->AddRef(), // trick: KX_GameObject are not true Python object, they use a difference reference count system + // resultPoint[0], resultPoint[1], resultPoint[2], + // resultNormal[0], resultNormal[1], resultNormal[2]); + } + return Py_BuildValue("OOO", Py_None, Py_None, Py_None); + //Py_Return; +} + /* --------------------------------------------------------------------- * Some stuff taken from the header * --------------------------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 5dae59d1d63..3758651f53d 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -75,6 +75,7 @@ protected: bool m_bSuspendDynamics; bool m_bUseObjectColor; + bool m_bIsNegativeScaling; MT_Vector4 m_objectColor; // Is this object set to be visible? Only useful for the @@ -599,6 +600,14 @@ public: ); /** + * Get the negative scaling state + */ + bool + IsNegativeScaling( + void + ) { return m_bIsNegativeScaling; } + + /** * @section Logic bubbling methods. */ @@ -665,6 +674,7 @@ public: KX_PYMETHOD(KX_GameObject,RemoveParent); KX_PYMETHOD(KX_GameObject,GetPhysicsId); KX_PYMETHOD_DOC(KX_GameObject,rayCastTo); + KX_PYMETHOD_DOC(KX_GameObject,rayCast); KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo); private : diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index c098f37efa8..1e3393d59a8 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -890,7 +890,7 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam) // update graphics void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) { - float left, right, bottom, top, nearfrust, farfrust; + float left, right, bottom, top, nearfrust, farfrust, focallength; const float ortho = 100.0; // KX_Camera* cam = scene->GetActiveCamera(); @@ -913,6 +913,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) float lens = cam->GetLens(); nearfrust = cam->GetCameraNear(); farfrust = cam->GetCameraFar(); + focallength = cam->GetFocalLength(); if (!cam->GetCameraData()->m_perspective) { @@ -939,7 +940,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) farfrust = frustum.camfar; MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( - left, right, bottom, top, nearfrust, farfrust); + left, right, bottom, top, nearfrust, farfrust, focallength); cam->SetProjectionMatrix(projmat); diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index 8ef82b4943b..fbd896a55d1 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -174,9 +174,10 @@ class KX_GameObject: The ray is always casted from the center of the object, ignoring the object itself. The ray is casted towards the center of another object or an explicit [x,y,z] point. + Use rayCast() if you need to retrieve the hit point @param other: [x,y,z] or object towards which the ray is casted - @type other: L{KX_GameObject} or string + @type other: L{KX_GameObject} or 3-tuple @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to other @type dist: float @param prop: property name that object must have; can be omitted => detect any object @@ -184,4 +185,32 @@ class KX_GameObject: @rtype: L{KX_GameObject} @return: the first object hit or None if no object or object does not match prop """ + def rayCast(to,from,dist,prop): + """ + Look from a point/object to another point/object and find first object hit within dist that matches prop. + Returns a 3-tuple with object reference, hit point and hit normal or (None,None,None) if no hit. + Ex: + # shoot along the axis gun-gunAim (gunAim should be collision-free) + ob,point,normal = gun.rayCast(gunAim,None,50) + if ob: + # hit something + + Notes: + The ray ignores the object on which the method is called. + If is casted from/to object center or explicit [x,y,z] points. + The ray does not have X-Ray capability: the first object hit (other than self object) stops the ray + If a property was specified and the first object hit does not have that property, there is no hit + The ray ignores collision-free objects + + @param to: [x,y,z] or object to which the ray is casted + @type to: L{KX_GameObject} or 3-tuple + @param from: [x,y,z] or object from which the ray is casted; None or omitted => use self object center + @type from: L{KX_GameObject} or 3-tuple or None + @param dist: max distance to look (can be negative => look behind); 0 or omitted => detect up to to + @type dist: float + @param prop: property name that object must have; can be omitted => detect any object + @type prop: string + @rtype: 3-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz)) + @return: (object,hitpoint,hitnormal) or (None,None,None) + """
\ No newline at end of file diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h index 99c0c412cf7..6aa9b34962b 100644 --- a/source/gameengine/Rasterizer/RAS_CameraData.h +++ b/source/gameengine/Rasterizer/RAS_CameraData.h @@ -40,13 +40,16 @@ struct RAS_CameraData int m_viewportbottom; int m_viewportright; int m_viewporttop; + float m_focallength; RAS_CameraData(float lens = 35., float clipstart = 0.1, float clipend = 100., bool perspective = true, - bool viewport = false, int viewportleft = 0, int viewportbottom = 0, int viewportright = 0, int viewporttop = 0) : + float focallength = 0.0f, bool viewport = false, int viewportleft = 0, int viewportbottom = 0, + int viewportright = 0, int viewporttop = 0) : m_lens(lens), m_clipstart(clipstart), m_clipend(clipend), m_perspective(perspective), + m_focallength(focallength), m_viewport(viewport), m_viewportleft(viewportleft), m_viewportbottom(viewportbottom), diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 5e8b5ad8276..18a7f261c94 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -344,6 +344,7 @@ public: float top, float frustnear, float frustfar, + float focallength = 0.0f, bool perspective = true )=0; /** diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h index 16e15653c82..bcbf907741b 100644 --- a/source/gameengine/Rasterizer/RAS_IRenderTools.h +++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h @@ -146,6 +146,7 @@ public: int layer )=0; + virtual void SetClientObject( void* obj diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 02e84f8a243..96ce220ae4d 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -325,6 +325,8 @@ void RAS_MaterialBucket::Render(const MT_Transform& cameratrans, while (ActivateMaterial(cameratrans, rasty, rendertools, drawmode)) RenderMeshSlot(cameratrans, rasty, rendertools, *it, drawmode); } + // to reset the eventual GL_CW mode + rendertools->SetClientObject(NULL); } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index ea41b2f7d13..f99121e5b7c 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -1802,6 +1802,7 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( float top, float frustnear, float frustfar, + float focallength, bool ){ MT_Matrix4x4 result; @@ -1813,9 +1814,10 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( float near_div_focallength; // next 2 params should be specified on command line and in Blender publisher if (!m_setfocallength) - m_focallength = 1.5 * right; // derived from example + m_focallength = (focallength == 0.f) ? 1.5 * right // derived from example + : focallength; if (!m_seteyesep) - m_eyeseparation = 0.18 * right; // just a guess... + m_eyeseparation = m_focallength/30; // reasonable value... near_div_focallength = frustnear / m_focallength; switch(m_curreye) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index c63a7b80b7c..23714a12151 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -246,6 +246,7 @@ public: float top, float frustnear, float frustfar, + float focallength, bool perspective ); |