Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Genrich <daniel.genrich@gmx.net>2008-05-28 03:15:08 +0400
committerDaniel Genrich <daniel.genrich@gmx.net>2008-05-28 03:15:08 +0400
commit6a802f63b66508d3945714f59f1234843f251c1d (patch)
treea97437fea4961dbb6812a46294c9d51a3da09539
parented42c9a6768712c1eeba3b36af09620f668d663b (diff)
parentc1874b3cee1fdb2220f26f75e676942aee4be561 (diff)
Merging revisions 14946-15020 of https://svn.blender.org/svnroot/bf-blender/trunk/blender
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp21
-rw-r--r--release/scripts/3ds_import.py7
-rw-r--r--release/scripts/export_fbx.py4
-rw-r--r--release/scripts/flt_import.py11
-rw-r--r--release/scripts/uv_from_adjacent.py129
-rw-r--r--release/scripts/uv_seams_from_islands.py30
-rw-r--r--release/scripts/uvcalc_lightmap.py34
-rw-r--r--source/blender/blenkernel/BKE_curve.h11
-rw-r--r--source/blender/blenkernel/intern/curve.c150
-rw-r--r--source/blender/blenkernel/intern/displist.c10
-rw-r--r--source/blender/blenkernel/intern/font.c4
-rw-r--r--source/blender/blenkernel/intern/modifier.c115
-rw-r--r--source/blender/blenlib/intern/freetypefont.c2
-rw-r--r--source/blender/blenlib/intern/psfont.c2
-rw-r--r--source/blender/include/BDR_editcurve.h3
-rw-r--r--source/blender/nodes/intern/Makefile2
-rw-r--r--source/blender/python/api2_2x/Draw.c25
-rw-r--r--source/blender/python/api2_2x/Object.c39
-rw-r--r--source/blender/python/api2_2x/Particle.c2
-rw-r--r--source/blender/python/api2_2x/doc/Object.py7
-rw-r--r--source/blender/render/intern/source/envmap.c2
-rw-r--r--source/blender/src/buttons_editing.c27
-rw-r--r--source/blender/src/buttons_shading.c7
-rw-r--r--source/blender/src/drawobject.c124
-rw-r--r--source/blender/src/editarmature.c18
-rw-r--r--source/blender/src/editcurve.c272
-rw-r--r--source/blender/src/editnode.c3
-rw-r--r--source/blender/src/interface.c1
-rw-r--r--source/blender/src/poseobject.c8
-rw-r--r--source/blender/src/sequence.c34
-rw-r--r--source/blender/src/toets.c4
-rw-r--r--source/blender/src/transform_conversions.c1
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp16
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h2
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp8
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp16
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.h2
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h4
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp89
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h10
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp5
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py31
-rw-r--r--source/gameengine/Rasterizer/RAS_CameraData.h5
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h1
-rw-r--r--source/gameengine/Rasterizer/RAS_IRenderTools.h1
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp2
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp6
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h1
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
);