From 7f10f5f66f6b29a7a4e508da7b3c80a50d00618d Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 24 May 2008 08:34:04 +0000 Subject: fix BGE bug #8646: unusable anaglyph settings The best rules for stereo rendering are now applied to Blender. Here is the new situation: 1) The focal distance is now settable through the GUI: select the camera (each camera can have a different setting) and go to the camera data (F9): the "Dof Dist" and "Dof Ob" can be used to set the focal distance for that camera. The "Dof Ob" is interesting because it sets the focal distance so that the center this object will appear at the surface of the screen when running the game. 2) The eye separation is automatically set to focal_distance/30, which is considered to be a reasonable value. If you need a different value, you can always use Python scripting. Notes: - If you switch camera during the game, the focal distance will also change unless you have set the focal distance by scripting, in which case it overwrites the focal distance setting of all cameras. - If you don't set the focal distance in the camera data or by scripting, the default value will be used. The default value corresponds more of less to the near clipping plane which means that all the objects will be very far with little 3D effect. - If you don't set the eye separation by scripting, it is automatically computed as focal_distance/30, regardless on how the focal distance was set. --- source/gameengine/Converter/BL_BlenderDataConversion.cpp | 8 +++++--- source/gameengine/Ketsji/KX_Camera.cpp | 5 +++++ source/gameengine/Ketsji/KX_Camera.h | 4 +++- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 5 +++-- source/gameengine/Rasterizer/RAS_CameraData.h | 5 ++++- source/gameengine/Rasterizer/RAS_IRasterizer.h | 1 + .../Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | 6 ++++-- .../Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h | 1 + 8 files changed, 26 insertions(+), 9 deletions(-) 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(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(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/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_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/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_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 ); -- cgit v1.2.3 From 459b4ea5be5471eac9d20c13d8dc35f6b81b90ee Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 24 May 2008 12:22:53 +0000 Subject: fix for [#12797] FBX Exporter Exports Incorrect Matterial EmissiveFactor and DiffuseFactor - own error, swapped diffuse and emit factors --- release/scripts/export_fbx.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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)) -- cgit v1.2.3 From cc6dac8c425bf0914df1cf3422577c28c617fbc4 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 24 May 2008 18:06:58 +0000 Subject: BGE patch: add rayCastToEx(), an extended version of rayCastTo() for use in game script --- source/gameengine/Ketsji/KX_GameObject.cpp | 86 +++++++++++++++++++++++++++++- source/gameengine/Ketsji/KX_GameObject.h | 1 + source/gameengine/PyDoc/KX_GameObject.py | 31 ++++++++++- 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index fb636b23082..6b4fd565495 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -743,6 +743,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, rayCastToEx), {NULL,NULL} //Sentinel }; @@ -1325,7 +1326,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 +1381,89 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, Py_Return; } +KX_PYMETHODDEF_DOC(KX_GameObject, rayCastToEx, +"rayCastToEx(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(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(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(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..9e35e45270c 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -665,6 +665,7 @@ public: KX_PYMETHOD(KX_GameObject,RemoveParent); KX_PYMETHOD(KX_GameObject,GetPhysicsId); KX_PYMETHOD_DOC(KX_GameObject,rayCastTo); + KX_PYMETHOD_DOC(KX_GameObject,rayCastToEx); KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo); private : diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index 8ef82b4943b..b0f55b4ad7a 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 rayCastToEx() 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 rayCastToEx(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 object hit. + Ex: + # shoot along the axis gun-gunAim (gunAim should be collision-free) + ob,point,normal = gun.rayCastToEx(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 -- cgit v1.2.3 From 7b069b9b6041ca2e5170414a0d4082ba78ca1380 Mon Sep 17 00:00:00 2001 From: Geoffrey Bantle Date: Sat, 24 May 2008 18:43:02 +0000 Subject: -> FLT import: Zero area N-gon bug fix FLT importer would throw errors when importing ngons with zero area. These faces are now ignored --- release/scripts/flt_import.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) 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 -- cgit v1.2.3 From e2a9590a15c807c391ec7eff05c7168a8025ab7a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 24 May 2008 22:50:31 +0000 Subject: BGE patch: rename rayCastToEx() to rayCast() - better name --- source/gameengine/Ketsji/KX_GameObject.cpp | 6 +++--- source/gameengine/Ketsji/KX_GameObject.h | 2 +- source/gameengine/PyDoc/KX_GameObject.py | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 6b4fd565495..5fd5d2d5492 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -743,7 +743,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, rayCastToEx), + KX_PYMETHODTABLE(KX_GameObject, rayCast), {NULL,NULL} //Sentinel }; @@ -1381,8 +1381,8 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, Py_Return; } -KX_PYMETHODDEF_DOC(KX_GameObject, rayCastToEx, -"rayCastToEx(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" +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" diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 9e35e45270c..6e765978821 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -665,7 +665,7 @@ public: KX_PYMETHOD(KX_GameObject,RemoveParent); KX_PYMETHOD(KX_GameObject,GetPhysicsId); KX_PYMETHOD_DOC(KX_GameObject,rayCastTo); - KX_PYMETHOD_DOC(KX_GameObject,rayCastToEx); + KX_PYMETHOD_DOC(KX_GameObject,rayCast); KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo); private : diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index b0f55b4ad7a..fbd896a55d1 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -174,7 +174,7 @@ 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 rayCastToEx() if you need to retrieve the hit 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 3-tuple @@ -185,13 +185,13 @@ class KX_GameObject: @rtype: L{KX_GameObject} @return: the first object hit or None if no object or object does not match prop """ - def rayCastToEx(to,from,dist,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 object hit. + 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.rayCastToEx(gunAim,None,50) + ob,point,normal = gun.rayCast(gunAim,None,50) if ob: # hit something -- cgit v1.2.3 From 55f1b6baa71068a8a156bad0261875441ee4b077 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 25 May 2008 13:48:36 +0000 Subject: for for [bf-blender-Bug Tracker][11843] 3DS importer imports broken meshes --- release/scripts/3ds_import.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 -- cgit v1.2.3 From 31ec51df42b4401210202ff4d0c41ffa447d4732 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 25 May 2008 14:32:26 +0000 Subject: Apply BGE patch 12799: Fix quad buffer stereo mode for Windows --- intern/ghost/intern/GHOST_WindowWin32.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 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; } -- cgit v1.2.3 From f680b56ebfc1415334598e619ec9310ccce472c2 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 25 May 2008 14:32:59 +0000 Subject: [#11119] Tool tips correction Patch by Olivier Saraja --- source/blender/src/buttons_shading.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index c6847508806..490180ed021 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2887,8 +2887,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; -- cgit v1.2.3 From da1f38f99d3b8a07ed4ddd905f8e7d7c6e25f945 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 25 May 2008 14:37:39 +0000 Subject: Apply BGE patch 11137: Render objects with negative scaling correctly (as in Blender) --- .../gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp | 16 ++++++++++++++++ .../gameengine/BlenderRoutines/KX_BlenderRenderTools.h | 2 ++ source/gameengine/GamePlayer/common/GPC_RenderTools.cpp | 16 ++++++++++++++++ source/gameengine/GamePlayer/common/GPC_RenderTools.h | 2 ++ source/gameengine/Ketsji/KX_GameObject.cpp | 3 ++- source/gameengine/Ketsji/KX_GameObject.h | 9 +++++++++ source/gameengine/Rasterizer/RAS_IRenderTools.h | 1 + source/gameengine/Rasterizer/RAS_MaterialBucket.cpp | 2 ++ 8 files changed, 50 insertions(+), 1 deletion(-) 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/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_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 5fd5d2d5492..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); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 6e765978821..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 @@ -598,6 +599,14 @@ public: void ); + /** + * Get the negative scaling state + */ + bool + IsNegativeScaling( + void + ) { return m_bIsNegativeScaling; } + /** * @section Logic bubbling methods. */ 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); } -- cgit v1.2.3 From 03ccc38ddfad7a7156d9c0f4b30e4dfc8f32f72f Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 25 May 2008 14:39:55 +0000 Subject: [#11124] Hide Threshold button when Constant QMC sampling enabled Patch by Olivier Saraja --- source/blender/src/buttons_shading.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 490180ed021..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", -- cgit v1.2.3 From 20b4bf4abaff8723421fb2fed96eff90e9ed1a00 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 25 May 2008 16:07:32 +0000 Subject: == Sequencer == Fixes [#12106] Memory leak in sequencer (>10MB/frame) in parts: inner contents of meta strips are freed up after calculation making more room for the cache. Actually have to think of a mechanism, that remembers, which output frames are asked for and caches only those. --- source/blender/src/sequence.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) 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); -- cgit v1.2.3 From b306aaccb950c11afea79b3be7289def7853ea62 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 25 May 2008 16:39:57 +0000 Subject: patch [#11491] Fix for bug 11362: Blender.Draw.Image() method does not clip properly fixing [#11362] Blender.Draw.Image() method does not clip properly also return silently on zero zoomlevel rather then raising an error, only raise an error on negative values. --- source/blender/python/api2_2x/Draw.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) 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; } -- cgit v1.2.3 From 7f6fc12d8c348689774b4f681728174db62d3abb Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 25 May 2008 21:05:13 +0000 Subject: Bug fix in X-Mirror for armatures When a bone in a mirrored chain wasn't named properly, it would leave the head or tail in an invalid state. Now it applies the mirror to connected joints that are mirrored. --- source/blender/src/editarmature.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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; -- cgit v1.2.3 From 5263021aa8608252a6db44208f2bee89bdc7e4de Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Sun, 25 May 2008 21:11:34 +0000 Subject: Commit patch #9059 by gsrb3d Unnecesary include path in Makefile. --- source/blender/nodes/intern/Makefile | 2 -- 1 file changed, 2 deletions(-) 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 -- cgit v1.2.3 From b7c6da39aedecb59b01ba8f833a8dc61afa89903 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 25 May 2008 23:05:13 +0000 Subject: the last selected nurbs curve lastnu could become an invalid pointer in places, access this via functions now and store an index rather then a pointer so if it becomes invalid it will just return a NULL pointer. --- source/blender/include/BDR_editcurve.h | 3 ++ source/blender/src/buttons_editing.c | 11 +++--- source/blender/src/editcurve.c | 66 +++++++++++++++++++--------------- 3 files changed, 46 insertions(+), 34 deletions(-) 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/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 592a8c1b7aa..8a37f713164 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3071,7 +3071,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; @@ -3147,7 +3146,7 @@ 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; @@ -3273,7 +3272,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; @@ -3309,8 +3307,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/editcurve.c b/source/blender/src/editcurve.c index 7572391b383..7f9ba2cb8d2 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 */ @@ -325,7 +342,7 @@ void load_editNurb() } - 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 */ @@ -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"); @@ -913,7 +928,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"); @@ -971,7 +986,7 @@ 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 = @@ -1015,7 +1030,7 @@ void adduplicateflagNurb(short flag) nu= nu->prev; } - /* lastnu changed */ + /* actnu changed */ allqueue(REDRAWBUTSEDIT, 0); } @@ -2481,7 +2496,7 @@ void merge_nurb() BLI_freelistN(&nsortbase); countall(); - lastnu= NULL; + set_actNurb(NULL); DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); @@ -2594,7 +2609,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 +2647,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 +2719,8 @@ void mouse_nurb() rightmouse_transform(); - if(nu!=lastnu) { - lastnu= nu; + if(nu!=get_actNurb()) { + set_actNurb(nu); allqueue(REDRAWBUTSEDIT, 0); } @@ -3638,7 +3653,7 @@ void delNurb() } if(a==0) { BLI_remlink(&editNurb, nu); - freeNurb(nu); + freeNurb(nu); nu= NULL; } } } @@ -3654,13 +3669,13 @@ 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)) { + if ((nu!= NULL) && ((nu->type & 7)==CU_NURBS) && (nu->pntsu < nu->orderu)) { nu->orderu = nu->pntsu; } nu= next; @@ -3790,7 +3805,7 @@ 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 */ bezt = @@ -3832,7 +3847,7 @@ 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 */ bp = @@ -4592,10 +4607,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 +4615,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) -- cgit v1.2.3 From 0a90a52442071b8c346b8efade465eff714c37d8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 May 2008 09:50:46 +0000 Subject: * The displist would be uninitialized when nurbs bezieru/v was set and the order wasnt 3 or 4. add a function that checks nurbs can produce a valid line. check_valid_nurb_u/v * when check_valid_nurb_u/v fails, no curve is allocated or drawn. * knotsu/v could be NULL but some functions didn't check for this, make sure this is checked for everywhere. * The interface didnt change check the order when the bezier u/v flag was set, added functions clamp_nurb_order_u/v that takes into accound the number of points and the bezier u/v flag. --- source/blender/blenkernel/BKE_curve.h | 7 ++ source/blender/blenkernel/intern/curve.c | 80 ++++++++++++++-- source/blender/blenkernel/intern/displist.c | 2 +- source/blender/blenkernel/intern/font.c | 4 +- source/blender/src/buttons_editing.c | 8 +- source/blender/src/editcurve.c | 138 +++++++++++++++------------- 6 files changed, 162 insertions(+), 77 deletions(-) diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 60444675047..edb4721de4e 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -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..d2028e653c5 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;atype & 7)==CU_NURBS ) { 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); @@ -563,7 +567,7 @@ void makeknots(Nurb *nu, short uv, short type) /* 0: uniform, 1: endpoints, 2: b } 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); @@ -645,7 +649,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; @@ -803,7 +807,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; @@ -1478,7 +1482,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; @@ -2608,3 +2612,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->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->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->pntsuorderu) { + nu->orderu= nu->pntsu; + change= 1; + } + if((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->pntsvorderv) { + nu->orderv= nu->pntsv; + change= 1; + } + if((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..a8f300f4315 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 */ 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/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 8a37f713164..6e57736845e 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3106,11 +3106,13 @@ void do_curvebuts(unsigned short event) if(eventflagu &= 1; 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); + clamp_nurb_order_v(nu); makeknots(nu, 2, nu->flagv>>1); } } @@ -3148,13 +3150,11 @@ void do_curvebuts(unsigned short event) if(G.obedit) { 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); diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c index 7f9ba2cb8d2..3cb951c319b 100644 --- a/source/blender/src/editcurve.c +++ b/source/blender/src/editcurve.c @@ -335,7 +335,7 @@ 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); } } } @@ -689,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); } @@ -729,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); } @@ -946,7 +946,7 @@ void adduplicateflagNurb(short flag) } /* knots */ - newnu->knotsu= 0; + newnu->knotsu= NULL; makeknots(newnu, 1, newnu->flagu>>1); } bp++; @@ -991,9 +991,11 @@ void adduplicateflagNurb(short flag) 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; apntsv; a++) { @@ -1005,23 +1007,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); } @@ -2154,9 +2153,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; @@ -2185,7 +2184,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; @@ -3042,26 +3041,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--; + 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; - 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) { @@ -3078,26 +3079,34 @@ void makecyclicNurb() if(nu->flagu & CU_CYCLIC) nu->flagu--; 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; + 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; @@ -3674,10 +3683,13 @@ void delNurb() } } - /* Never allow the order to exceed the number of points */ - if ((nu!= NULL) && ((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 */ @@ -3725,10 +3737,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); } -- cgit v1.2.3 From 3b4873250eb72aff424fc001b125b52195410e8d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 May 2008 12:50:00 +0000 Subject: when cyclic is enabled the knots would always be generated with uniform nurbs but after, cyclic nurbs would be incorrect if the bezier or endpoint u/v was set. also replaced some numbers with constants. --- source/blender/blenkernel/BKE_curve.h | 4 +- source/blender/blenkernel/intern/curve.c | 78 ++++++++++++++++------------ source/blender/blenkernel/intern/displist.c | 8 +-- source/blender/blenlib/intern/freetypefont.c | 2 +- source/blender/blenlib/intern/psfont.c | 2 +- source/blender/src/buttons_editing.c | 8 +-- source/blender/src/editcurve.c | 74 +++++++++++++------------- 7 files changed, 95 insertions(+), 81 deletions(-) diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index edb4721de4e..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); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index d2028e653c5..396bdda9c10 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -533,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) { @@ -553,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(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(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; } } } @@ -683,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; @@ -710,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; @@ -824,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; @@ -1429,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; @@ -1497,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; @@ -1516,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); } @@ -1599,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]; @@ -1615,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); @@ -2213,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; @@ -2221,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++; @@ -2620,7 +2630,7 @@ int check_valid_nurb_u( struct Nurb *nu ) if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */ if (nu->pntsu < nu->orderu) return 0; - if ((nu->flagu>>1) & 2) { /* Bezier U Endpoints */ + 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 */ @@ -2634,7 +2644,7 @@ int check_valid_nurb_v( struct Nurb *nu) if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */ if (nu->pntsv < nu->orderv) return 0; - if ((nu->flagv>>1) & 2) { /* Bezier V Endpoints */ + 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 */ @@ -2649,7 +2659,7 @@ int clamp_nurb_order_u( struct Nurb *nu ) nu->orderu= nu->pntsu; change= 1; } - if((nu->flagu>>1)&2) { + if(((nu->flag & CU_CYCLIC)==0) && (nu->flagu>>1)&2) { CLAMP(nu->orderu, 3,4); change= 1; } @@ -2663,7 +2673,7 @@ int clamp_nurb_order_v( struct Nurb *nu) nu->orderv= nu->pntsv; change= 1; } - if((nu->flagv>>1)&2) { + if(((nu->flag & CU_CYCLIC)==0) && (nu->flagv>>1)&2) { CLAMP(nu->orderv, 3,4); change= 1; } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index a8f300f4315..298e4b81d5b 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -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/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/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 6e57736845e..1365baf075a 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3104,14 +3104,14 @@ void do_curvebuts(unsigned short event) if(isNurbsel(nu)) { if((nu->type & 7)==CU_NURBS) { if(eventflagu &= 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); } diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c index 3cb951c319b..bd0abe83ee4 100644 --- a/source/blender/src/editcurve.c +++ b/source/blender/src/editcurve.c @@ -906,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++; @@ -941,8 +943,10 @@ 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 */ @@ -1583,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); @@ -1604,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); @@ -1636,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; @@ -1649,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; @@ -1666,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); @@ -1688,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); @@ -1715,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; @@ -2089,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; @@ -2140,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); } @@ -2541,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) { @@ -2822,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); } } @@ -3020,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++; @@ -3032,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++; @@ -3046,9 +3050,9 @@ void makecyclicNurb() bp= nu->bp; while(a--) { if( bp->f1 & SELECT ) { - if(nu->flagu & CU_CYCLIC) nu->flagu--; + if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC; else { - nu->flagu++; + nu->flagu |= CU_CYCLIC; nu->flagu &= ~2; /* endpoint flag, fixme */ fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); b= (nu->orderu+nu->pntsu); @@ -3076,9 +3080,9 @@ 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++; + nu->flagu |= CU_CYCLIC; if (check_valid_nurb_u(nu)) { fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN"); b= (nu->orderu+nu->pntsu); @@ -3765,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); @@ -3792,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); @@ -3821,14 +3825,14 @@ void delNurb() BLI_remlink(&editNurb, 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); } @@ -3863,14 +3867,14 @@ void delNurb() BLI_remlink(&editNurb, 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 */ @@ -4180,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++) { @@ -4229,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++) { -- cgit v1.2.3 From ae2a0bb2739ee0f45e882789aaa26bdc8cabc0a9 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 26 May 2008 12:52:28 +0000 Subject: Bug fix Force proportional editing flag off in object mode. While it didn't have any effect on objects themselves, it could display the falloff mode (Smooth) in the header. The bug was purely cosmetic. --- source/blender/src/transform_conversions.c | 1 + 1 file changed, 1 insertion(+) 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; } -- cgit v1.2.3 From a2298cb980cc9f5294375cf9b14d68054d5e4ad5 Mon Sep 17 00:00:00 2001 From: Stephen Swaney Date: Mon, 26 May 2008 15:12:20 +0000 Subject: bugfix for crasher from Cedric Paille via bf-committers. --- source/blender/python/api2_2x/Particle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; -- cgit v1.2.3 From c0a40125bb89791e54468219e30e986b0291d29d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 26 May 2008 20:43:35 +0000 Subject: bugfix, copy posebone constraints didnt update properly, canceling transform would not reset the bone back to its original state. need to set teh flag "ob->pose->flag |= POSE_RECALC", which is alredy done on adding a constraint. back to --- source/blender/src/poseobject.c | 8 ++++++++ 1 file changed, 8 insertions(+) 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 -- cgit v1.2.3 From 54572ccc228f2401b11fce7bcfea444b66c8cdce Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 May 2008 08:51:47 +0000 Subject: bugfix for view naming, pressing numpad5 would clear the V3D_OPP_DIRECTION_NAME flag even though it wont switch the view direction. --- source/blender/src/toets.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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; -- cgit v1.2.3 From eb26992c25ab626f1538e5cf7848582c96f1ee95 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 May 2008 09:41:43 +0000 Subject: Fix for bug #12806: compositor nodes with use nodes disabled didn't properly redraw the node window on changes. --- source/blender/src/editnode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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); } } -- cgit v1.2.3 From be215f74f3b08655dc01abba9f60e68153c4396a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 May 2008 09:46:35 +0000 Subject: removing this script, should have been removed for 2.46 since the functionality is avalable in the UV snap menu. --- release/scripts/uv_from_adjacent.py | 129 ------------------------------------ 1 file changed, 129 deletions(-) delete mode 100644 release/scripts/uv_from_adjacent.py 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 -- cgit v1.2.3 From 027b9a7e96de86be24df76dca1479d0f0a6ae565 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 May 2008 11:01:31 +0000 Subject: Fix for bug #12533: color picker didn't always redraw rgb/hsv/hex values. --- source/blender/src/interface.c | 1 + 1 file changed, 1 insertion(+) 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); -- cgit v1.2.3 From 4fd54681fc852ac1b62fd63a858b75862f171467 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 May 2008 11:05:33 +0000 Subject: Fix for #12526: still didn't get dupli transform in envmaps correct. --- source/blender/render/intern/source/envmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); -- cgit v1.2.3 From c25b845abe39f82a35e1cdd83fa2f4533768769f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 May 2008 13:26:52 +0000 Subject: Fix for bug #12463: hair didn't draw z-buffered in wireframe mode. Instead of making it an exception compared to other objects which don't draw z-buffered either, it now draws without lighting in the wire color like it did before. --- source/blender/src/drawobject.c | 124 +++++++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 40 deletions(-) diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 045b98bb784..3ef14574bc8 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2885,7 +2885,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; @@ -3334,14 +3334,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; @@ -3350,9 +3360,13 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) for(a=0, pa=psys->particles; aco); - 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); } @@ -3360,15 +3374,21 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) for(a=0; aco); - 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); @@ -3389,7 +3409,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); @@ -3412,7 +3432,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); @@ -3466,7 +3486,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; @@ -3479,6 +3499,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); @@ -3493,11 +3514,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; @@ -3511,41 +3534,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; ico); - 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; ico); - 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; ico); + 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){ @@ -3619,6 +3662,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); @@ -5011,12 +5055,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); -- cgit v1.2.3 From 0eb8ea7429ad09fd463211550b3ab089de2630fb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 May 2008 13:32:10 +0000 Subject: bugfix, edges with no faces raised an error. --- release/scripts/uv_seams_from_islands.py | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) 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(): -- cgit v1.2.3 From 056f0564c2ccf391d5a2c114c24e58f00a2a24a0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 May 2008 15:14:35 +0000 Subject: bugfix for zero area faces and adding uv layers was not checking if the UV layer existed alredy. --- release/scripts/uvcalc_lightmap.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) 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 -- cgit v1.2.3 From 83a7fbf499ee51051f66bfa5fe23caa96cb262b7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 May 2008 15:36:36 +0000 Subject: Another fix for bug #11140: explode modifier was still using more memory than needed. --- source/blender/blenkernel/intern/modifier.c | 115 +++++++++++++++------------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index b867b8d22bb..f9f17e7762d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6485,12 +6485,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; @@ -6505,34 +6507,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; itime) - 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); @@ -6541,45 +6545,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; jgetVert(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; itime) - 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); @@ -6618,9 +6626,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); -- cgit v1.2.3 From c1874b3cee1fdb2220f26f75e676942aee4be561 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 27 May 2008 20:02:38 +0000 Subject: [#10223] a new object function to add vertex group from an armature Patch from Jean-Michel Soler (with slight modifs) Small BPy feature to help script writers deal with armatures and vertex groups (calls the bone heat method to create and assign groups) --- source/blender/python/api2_2x/Object.c | 39 +++++++++++++++++++++++++++++ source/blender/python/api2_2x/doc/Object.py | 7 ++++++ 2 files changed, 46 insertions(+) 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/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 -- cgit v1.2.3