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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Luc Peurière <jlp@nerim.net>2008-03-21 20:00:40 +0300
committerJean-Luc Peurière <jlp@nerim.net>2008-03-21 20:00:40 +0300
commit32b5138e6459df5298ca50865dafab4d22a4aeed (patch)
tree8ba947a61d91fe051e9c3a864f5e0ca61968bca1
parent473ba6ac718bc32b4fc6c6aee4d03673cf62936c (diff)
parentdf1ba7da75f9b82f81693d5e0adfec29b2f4a424 (diff)
update to trunk r14199ndof
-rw-r--r--SConstruct2
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp18
-rw-r--r--intern/guardedalloc/intern/mallocn.c4
-rw-r--r--release/scripts/flt_defaultp.py2
-rw-r--r--release/scripts/flt_import.py39
-rw-r--r--release/scripts/flt_toolbar.py210
-rw-r--r--source/blender/blenkernel/BKE_bad_level_calls.h2
-rw-r--r--source/blender/blenkernel/BKE_bmesh.h2
-rw-r--r--source/blender/blenkernel/BKE_collision.h3
-rw-r--r--source/blender/blenkernel/BKE_particle.h2
-rw-r--r--source/blender/blenkernel/BKE_sculpt.h3
-rw-r--r--source/blender/blenkernel/bad_level_call_stubs/stubs.c5
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c2
-rw-r--r--source/blender/blenkernel/intern/action.c6
-rw-r--r--source/blender/blenkernel/intern/armature.c18
-rw-r--r--source/blender/blenkernel/intern/cloth.c16
-rw-r--r--source/blender/blenkernel/intern/collision.c30
-rw-r--r--source/blender/blenkernel/intern/curve.c5
-rw-r--r--source/blender/blenkernel/intern/implicit.c6
-rw-r--r--source/blender/blenkernel/intern/kdop.c29
-rw-r--r--source/blender/blenkernel/intern/material.c14
-rw-r--r--source/blender/blenkernel/intern/mesh.c8
-rw-r--r--source/blender/blenkernel/intern/modifier.c39
-rw-r--r--source/blender/blenkernel/intern/node.c112
-rw-r--r--source/blender/blenkernel/intern/particle.c7
-rw-r--r--source/blender/blenkernel/intern/particle_system.c5
-rw-r--r--source/blender/blenkernel/intern/script.c9
-rw-r--r--source/blender/blenkernel/intern/texture.c20
-rw-r--r--source/blender/blenlib/BLI_arithb.h10
-rw-r--r--source/blender/blenlib/intern/BLI_storage.h2
-rw-r--r--source/blender/blenlib/intern/arithb.c73
-rw-r--r--source/blender/blenlib/intern/threads.c4
-rw-r--r--source/blender/blenloader/BLO_readfile.h2
-rw-r--r--source/blender/blenloader/intern/readfile.c57
-rw-r--r--source/blender/blenloader/intern/writefile.c4
-rw-r--r--source/blender/imbuf/intern/tiff.c4
-rw-r--r--source/blender/include/BIF_transform.h2
-rw-r--r--source/blender/include/BSE_drawview.h2
-rw-r--r--source/blender/include/BSE_edit.h1
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h9
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h10
-rw-r--r--source/blender/makesdna/DNA_node_types.h3
-rw-r--r--source/blender/makesdna/DNA_scene_types.h8
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h2
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_math.c1
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c2
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c80
-rw-r--r--source/blender/python/BPY_extern.h4
-rw-r--r--source/blender/python/BPY_interface.c53
-rw-r--r--source/blender/python/api2_2x/Blender.c11
-rw-r--r--source/blender/python/api2_2x/Constraint.c193
-rw-r--r--source/blender/python/api2_2x/Draw.c7
-rw-r--r--source/blender/python/api2_2x/Library.c20
-rw-r--r--source/blender/python/api2_2x/Mesh.c178
-rw-r--r--source/blender/python/api2_2x/Node.c658
-rw-r--r--source/blender/python/api2_2x/Node.h21
-rw-r--r--source/blender/python/api2_2x/SurfNurb.c63
-rw-r--r--source/blender/python/api2_2x/Window.c20
-rw-r--r--source/blender/python/api2_2x/doc/Constraint.py22
-rw-r--r--source/blender/python/api2_2x/doc/Curve.py4
-rw-r--r--source/blender/python/api2_2x/doc/IpoCurve.py2
-rw-r--r--source/blender/python/api2_2x/doc/Mesh.py38
-rw-r--r--source/blender/python/api2_2x/doc/Render.py1
-rw-r--r--source/blender/python/api2_2x/sceneRender.c6
-rw-r--r--source/blender/radiosity/intern/source/radrender.c1
-rw-r--r--source/blender/render/intern/include/render_types.h1
-rw-r--r--source/blender/render/intern/include/rendercore.h4
-rw-r--r--source/blender/render/intern/source/convertblender.c74
-rw-r--r--source/blender/render/intern/source/rayshade.c10
-rw-r--r--source/blender/render/intern/source/shadeinput.c6
-rw-r--r--source/blender/render/intern/source/texture.c28
-rw-r--r--source/blender/src/butspace.c2
-rw-r--r--source/blender/src/buttons_editing.c61
-rw-r--r--source/blender/src/buttons_object.c12
-rw-r--r--source/blender/src/drawaction.c44
-rw-r--r--source/blender/src/drawipo.c5
-rw-r--r--source/blender/src/drawnode.c8
-rw-r--r--source/blender/src/drawobject.c2
-rw-r--r--source/blender/src/drawtext.c2
-rw-r--r--source/blender/src/drawview.c117
-rw-r--r--source/blender/src/edit.c16
-rw-r--r--source/blender/src/editaction.c21
-rw-r--r--source/blender/src/editarmature.c128
-rw-r--r--source/blender/src/editipo.c47
-rw-r--r--source/blender/src/editmesh_loop.c4
-rw-r--r--source/blender/src/editnode.c11
-rw-r--r--source/blender/src/editobject.c52
-rw-r--r--source/blender/src/editseq.c203
-rw-r--r--source/blender/src/editview.c79
-rw-r--r--source/blender/src/header_action.c2
-rw-r--r--source/blender/src/header_image.c2
-rw-r--r--source/blender/src/header_view3d.c9
-rw-r--r--source/blender/src/headerbuttons.c114
-rw-r--r--source/blender/src/imagepaint.c4
-rw-r--r--source/blender/src/interface_panel.c4
-rw-r--r--source/blender/src/meshtools.c20
-rw-r--r--source/blender/src/sculptmode.c4
-rw-r--r--source/blender/src/seqaudio.c59
-rw-r--r--source/blender/src/seqeffects.c4
-rw-r--r--source/blender/src/space.c26
-rw-r--r--source/blender/src/transform.c38
-rw-r--r--source/blender/src/transform_orientations.c9
-rw-r--r--source/blender/src/view.c2
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp13
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp83
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h22
-rw-r--r--source/nan_compile.mk5
-rw-r--r--source/nan_link.mk4
-rwxr-xr-xtools/btools.py11
110 files changed, 2592 insertions, 978 deletions
diff --git a/SConstruct b/SConstruct
index 3ee56f7cff1..f8eef60a117 100644
--- a/SConstruct
+++ b/SConstruct
@@ -286,7 +286,7 @@ Help(opts.GenerateHelpText(env))
# default is new quieter output, but if you need to see the
# commands, do 'scons BF_QUIET=0'
bf_quietoutput = B.arguments.get('BF_QUIET', '1')
-if bf_quietoutput=='1':
+if env['BF_QUIET']:
B.set_quiet_output(env)
else:
if toolset=='msvc':
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 47bcb76441f..1b0d4448f1d 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -976,7 +976,7 @@ getClipboard(int flag
Primary_atom = XInternAtom(m_display, "CLIPBOARD", False);
owner = XGetSelectionOwner(m_display, Primary_atom);
if (owner == m_window) {
- data = (unsigned char*) malloc(strlen(txt_cut_buffer));
+ data = (unsigned char*) malloc(strlen(txt_cut_buffer)+1);
strcpy((char*)data, txt_cut_buffer);
return (GHOST_TUns8*)data;
} else if (owner == None) {
@@ -986,7 +986,7 @@ getClipboard(int flag
Primary_atom = XInternAtom(m_display, "PRIMARY", False);
owner = XGetSelectionOwner(m_display, Primary_atom);
if (owner == m_window) {
- data = (unsigned char*) malloc(strlen(txt_select_buffer));
+ data = (unsigned char*) malloc(strlen(txt_select_buffer)+1);
strcpy((char*)data, txt_select_buffer);
return (GHOST_TUns8*)data;
} else if (owner == None) {
@@ -1007,10 +1007,12 @@ getClipboard(int flag
XNextEvent(m_display, &xevent);
if(xevent.type == SelectionNotify) {
if(XGetWindowProperty(m_display, m_window, xevent.xselection.property, 0L, 4096L, False, AnyPropertyType, &rtype, &bits, &len, &bytes, &data) == Success) {
- tmp_data = (unsigned char*) malloc(strlen((char*)data));
- strcpy((char*)tmp_data, (char*)data);
- XFree(data);
- return (GHOST_TUns8*)tmp_data;
+ if (data) {
+ tmp_data = (unsigned char*) malloc(strlen((char*)data)+1);
+ strcpy((char*)tmp_data, (char*)data);
+ XFree(data);
+ return (GHOST_TUns8*)tmp_data;
+ }
}
return NULL;
}
@@ -1031,13 +1033,13 @@ GHOST_TInt8 *buffer, int flag) const
Primary_atom = XInternAtom(m_display, "CLIPBOARD", False);
if(txt_cut_buffer) { free((void*)txt_cut_buffer); }
- txt_cut_buffer = (char*) malloc(strlen(buffer));
+ txt_cut_buffer = (char*) malloc(strlen(buffer)+1);
strcpy(txt_cut_buffer, buffer);
} else {
Primary_atom = XInternAtom(m_display, "PRIMARY", False);
if(txt_select_buffer) { free((void*)txt_select_buffer); }
- txt_select_buffer = (char*) malloc(strlen(buffer));
+ txt_select_buffer = (char*) malloc(strlen(buffer)+1);
strcpy(txt_select_buffer, buffer);
}
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 20d3a5b07fc..af9443428f7 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -114,8 +114,8 @@ static const char *check_memlist(MemHead *memh);
volatile int totblock= 0;
volatile unsigned long mem_in_use= 0, mmap_in_use= 0;
-volatile static struct localListBase _membase;
-volatile static struct localListBase *membase = &_membase;
+static volatile struct localListBase _membase;
+static volatile struct localListBase *membase = &_membase;
static void (*error_callback)(char *) = NULL;
static void (*thread_lock_callback)(void) = NULL;
static void (*thread_unlock_callback)(void) = NULL;
diff --git a/release/scripts/flt_defaultp.py b/release/scripts/flt_defaultp.py
index 5dca8ba63d7..5c44fe29a6f 100644
--- a/release/scripts/flt_defaultp.py
+++ b/release/scripts/flt_defaultp.py
@@ -1 +1 @@
-pal = [-256,0,16711680,-16777216,-19529984,-19726592,-19923200,-20119808,-20316416,-20578560,-20840704,-21102848,-21364992,-21692672,-22020352,-22413568,-22806784,-23200000,-23658752,-24117504,-24641792,-25166080,-25755904,-26411264,-27066624,-27787520,-28573952,-29425920,-30343424,-31326464,-32375040,-33489152,-354550016,-371458304,-388366592,-405274880,-422183168,-439156992,-456130816,-473104640,-506855680,-540672256,-574488832,-608305408,-642121984,-676004096,-709886208,-760611072,-811335936,-862060800,-912851200,-980418816,-1048051968,-1115685120,-1183383808,-1267925248,-1352466688,-1453850880,-1555300608,-1656815872,-1775173888,-1893597440,-2028863744,2130771712,-1010376448,-1043996416,-1077681920,-1111367424,-1145052928,-1178738432,-1229201152,-1279663872,-1330126592,-1380654848,-1431183104,-1498488576,-1565794048,-1633165056,-1700536064,-1784684288,-1868832512,-1969823488,-2070814464,2123096320,2005262592,1887428864,1752752384,1601298688,1449779456,1281417472,1096278272,911073536,709026048,490201344,254533888,2023680,-1380857856,-1397700608,-1431320576,-1464940544,-1498560512,-1532180480,-1565865984,-1599551488,-1650014208,-1700476928,-1750939648,-1801402368,-1851865088,-1919170560,-1986476032,-2053781504,-2121086976,2089797632,2005649408,1904723968,1803798528,1686030336,1568262144,1450493952,1315883008,1164494848,1013041152,844810240,659736576,457885696,239192064,3655680,-1767919872,-1784762624,-1801605376,-1818448128,-1852068096,-1885688064,-1919308032,-1952928000,-1986547968,-2020167936,-2070565120,-2120962304,2123542272,2073079552,2022616832,1955376896,1888136960,1820897024,1736879872,1652797184,1568714496,1467854592,1366994688,1249357568,1131654912,997175040,862695168,711372544,560049920,391950080,207007488,5287680,2139657728,2122880512,2106103296,2089326080,2072548864,2055771648,2022217216,1988662784,1955108352,1921553920,1887933952,1854313984,1803916800,1753519616,1703122432,1652725248,1602328064,1535153664,1467979264,1400804864,1316853248,1232901632,1148950016,1048221184,947426816,846632448,729060864,611489280,477140480,326014464,174888448,6919680,1837268224,1820491008,1803713792,1786936576,1770159360,1753382144,1736604928,1719827712,1686273280,1652718848,1619164416,1585609984,1552055552,1518501120,1468169472,1417837824,1367506176,1317174528,1266842880,1199734016,1132625152,1065516288,998407424,914521344,830635264,729971968,629308672,528645376,411204864,293764352,159546624,8551680,-2086957824,-2103735040,-2120512256,-2137289472,2140900608,2107346176,2073791744,2040237056,2006682368,1973127680,1939572992,1906018304,1855686400,1805354496,1755022592,1704690688,1654358784,1587249664,1520140544,1453031424,1369145088,1285258496,1201371904,1100708096,1000044288,882603264,765162240,630943744,496725248,345729536,177956608,10183680,-1699438080,-1716215552,-1732993024,-1766547712,-1800102400,-1833657088,-1867211776,-1900766464,-1934321152,-1967875840,-2018207744,-2068539904,-2118872064,2125763072,2058653696,1991544320,1924434944,1857325568,1773438720,1689551872,1588887808,1488223744,1387559424,1270117888,1152676352,1018457600,884238592,733242368,565468672,397694976,213144064,11815680,-1311918848,-1345473536,-1379028224,-1412582912,-1446137600,-1479692544,-1513247488,-1546802432,-1597134592,-1647466752,-1697798912,-1748131072,-1798463488,-1865573120,-1932682752,-1999792384,-2083679232,2127400960,2043513856,1942849536,1842184960,1724743168,1607301376,1473082112,1338862848,1187866112,1020092160,852317952,667766528,466437632,248331264,13447680,-924399104,-957954048,-991508992,-1025063936,-1058618880,-1092173824,-1142505984,-1192838144,-1243170560,-1293502976,-1343835392,-1410945024,-1478054656,-1545164544,-1629051648,-1712938752,-1796826112,-1897490688,-1998155264,-2098820096,2078705152,1961262848,1827043328,1676046336,1525049344,1357274880,1172722944,971393792,753287168,518403072,283518720,15079680,-570434304,-603989248,-637544192,-671099136,-704654080,-754986496,-805318912,-855651328,-905983744,-973093632,-1040203520,-1107313408,-1174423296,-1258310656,-1342198016,-1442862848,-1543527680,-1644192512,-1761634816,-1879077120,-2013296896,2147450624,1996453376,1828678656,1660903936,1476351744,1275022080,1056914944,822030336,570368256,301928704,16711680,-503325440,-536880384,-570435328,-603990272,-637545216,-671100416,-721432832,-771765248,-822097664,-872430336,-922763008,-989872896,-1056982784,-1124092928,-1191203072,-1275090688,-1358978304,-1459643136,-1560308224,-1660973312,-1778415872,-1895858432,-2030078464,2113891328,1962893824,1795118848,1610566400,1426013696,1224683520,1006575872,771690752,520028160,-452993792,-469771520,-503326464,-536881408,-570436352,-603991552,-637546752,-671101952,-721434368,-771767040,-822099712,-872432384,-922765056,-989875200,-1056985344,-1124095744,-1191206144,-1275093760,-1358981632,-1459646720,-1560312064,-1677754624,-1795197440,-1912640512,-2046860800,2097108736,1946110720,1778335232,1593782272,1392451840,1174343936,939458560,-419439360,-436217088,-452994816,-469772544,-503327488,-536882688,-570437888,-603993088,-637548288,-671103744,-721436416,-771769088,-822101760,-872434688,-922767616,-989878016,-1056988416,-1124098816,-1207986688,-1291874560,-1375762688,-1476428032,-1577093632,-1694536704,-1811979776,-1946200320,-2080421120,2063547904,1912549376,1744773376,1560219904,1358888960,-385884928,-402662656,-419440384,-436218112,-452995840,-469773824,-503329024,-536884224,-570439424,-603994880,-637550336,-671105792,-721438464,-771771392,-822104320,-872437504,-922770688,-989881088,-1056991744,-1124102400,-1191213312,-1275101440,-1358989824,-1459655680,-1560321536,-1677764864,-1795208448,-1912652288,-2046873600,2097094912,1946095872,1778319360,-335553280,-352331008,-369108736,-385886464,-402664192,-419442176,-436220160,-452998144,-486553344,-520108800,-553664256,-587219712,-620775168,-654330880,-687886592,-738219776,-788552960,-838886144,-889219584,-939553024,-1006663936,-1073774848,-1140886016,-1224774656,-1308663296,-1392552192,-1493218560,-1593885184,-1711329280,-1828773632,-1962995456,-2097217536,-285221632,-301999360,-318777088,-335554816,-352332544,-369110528,-385888512,-402666496,-419444480,-436222720,-453000960,-469779200,-503334656,-536890368,-570446080,-604002048,-637558016,-671113984,-721447424,-771780864,-822114560,-872448256,-922782208,-989893632,-1057005056,-1124116736,-1191228672,-1275118080,-1359007744,-1459674880,-1560342272,-1677787136,-234889984,-234890496,-251668224,-268445952,-285223680,-302001664,-318779648,-335557632,-352335616,-369113856,-385892096,-402670336,-419448576,-436227072,-453005568,-469784320,-503340288,-536896256,-570452480,-604008704,-637565184,-671121664,-704678400,-755012608,-805346816,-855681280,-906016000,-973128192,-1040240640,-1107353344,-1174466304,-1258356736,-234889984,-234890496,-234891008,-234891520,-234892032,-234892800,-234893568,-234894336,-234895104,-251673344,-268451584,-285229824,-302008064,-318786560,-335565056,-352343808,-369122560,-385901312,-402680320,-419459328,-436238592,-453017856,-486574592,-520131584,-553688576,-587245824,-620803328,-654361088,-687919104,-738254592,-788590336,-838926336,-234889984,-234890496,-234891008,-234891520,-234892032,-234892800,-234893568,-234894336,-234895104,-234896128,-234897152,-234898176,-234899200,-234900480,-234901760,-234903296,-234904832,-234906368,-234908160,-234909952,-234912000,-251691264,-268470784,-285250560,-302030336,-318810368,-335590656,-352371200,-369152000,-385933056,-402714368,-419495936,-8960,-9472,-9984,-10496,-11008,-11776,-12544,-13312,-14080,-15104,-16128,-17152,-18176,-19456,-20736,-22272,-23808,-25344,-27136,-28928,-30976,-33024,-35328,-37888,-40448,-43264,-46336,-49664,-53248,-57088,-61184,-65536,-926464,-926976,-927488,-928000,-928512,-929280,-930048,-930816,-931584,-932608,-933632,-934656,-935680,-936960,-938240,-939776,-941312,-1008384,-1075712,-1143040,-1210624,-1278208,-1346048,-1414144,-1482240,-1550592,-1619200,-1688064,-1757184,-1826560,-1896192,-2031616,-926464,-926976,-927488,-928000,-928512,-929280,-930048,-996352,-1062656,-1129216,-1195776,-1262336,-1328896,-1395712,-1462528,-1529600,-1596672,-1663744,-1731072,-1798400,-1865984,-1999104,-2132480,-2266112,-2399744,-2533632,-2667776,-2867712,-3067904,-3268352,-3469056,-3670016,-926464,-992512,-1058560,-1124608,-1190656,-1256960,-1323264,-1389568,-1455872,-1522432,-1588992,-1655552,-1722112,-1788928,-1855744,-1988352,-2120960,-2253568,-2386432,-2519296,-2652416,-2785536,-2984448,-3183616,-3382784,-3582208,-3847424,-4112896,-4378624,-4644608,-4976384,-5308416,-1188608,-1254656,-1320704,-1386752,-1452800,-1519104,-1585408,-1651712,-1718016,-1784576,-1851136,-1983232,-2115328,-2247680,-2380032,-2512640,-2645248,-2777856,-2976256,-3174656,-3373312,-3571968,-3836416,-4101120,-4365824,-4630784,-4961536,-5292544,-5689344,-6086400,-6483712,-6946816,-1385216,-1451264,-1517312,-1583360,-1649408,-1715712,-1782016,-1848320,-1980160,-2112256,-2244352,-2376448,-2508544,-2640896,-2838784,-3036928,-3235072,-3433216,-3631616,-3895552,-4159744,-4423936,-4688384,-5018624,-5348864,-5744896,-6141184,-6537728,-7000064,-7462656,-7991040,-8585216,-1581824,-1647872,-1713920,-1779968,-1846016,-1977856,-2109696,-2241536,-2373376,-2505472,-2637568,-2769664,-2967296,-3165184,-3363072,-3561216,-3759360,-4023040,-4286976,-4550912,-4880640,-5210368,-5540352,-5936128,-6331904,-6793472,-7255296,-7782912,-8310784,-8904448,-9563904,-10223616,-1712896,-1778944,-1844992,-1976576,-2108160,-2240000,-2371840,-2503680,-2635520,-2767616,-2965248,-3162880,-3360512,-3558400,-3821824,-4085504,-4349184,-4612864,-4942336,-5271808,-5667072,-6062336,-6457856,-6919168,-7380480,-7907584,-8434944,-9028096,-9687040,-10346240,-11071232,-11862016,-1843968,-1975552,-2107136,-2238720,-2370304,-2502144,-2633984,-2765824,-2963200,-3160832,-3358464,-3556096,-3753728,-4017152,-4280576,-4544256,-4873472,-5202688,-5532160,-5927168,-6322432,-6783232,-7244288,-7771136,-8297984,-8890624,-9549056,-10207744,-10932224,-11722496,-12578560,-13500416,-1975040,-2106624,-2238208,-2369792,-2501376,-2633216,-2830592,-3027968,-3225344,-3422976,-3620608,-3883776,-4146944,-4410368,-4673792,-5003008,-5332224,-5726976,-6121984,-6582528,-7043328,-7504128,-8030720,-8623104,-9215488,-9873664,-10597632,-11387392,-12242944,-13164288,-14085888,-15138816,-2237184,-2368768,-2500352,-2631936,-2763520,-2960896,-3158272,-3355648,-3553024,-3816192,-4079360,-4342528,-4605696,-4934656,-5263616,-5658368,-6053120,-6447872,-6908416,-7368960,-7895296,-8421632,-9013760,-9671680,-10329600,-11053312,-11842816,-12698112,-13619200,-14606080,-15658752,-16777216] \ No newline at end of file
+pal = [-1,255,16711935,-16776961,-19529729,-19726337,-19922945,-20119553,-20316161,-20578305,-20840449,-21102593,-21364737,-21692417,-22020097,-22413313,-22806529,-23199745,-23658497,-24117249,-24641537,-25165825,-25755649,-26411009,-27066369,-27787265,-28573697,-29425665,-30343169,-31326209,-32374785,-33488897,-354549761,-371458049,-388366337,-405274625,-422182913,-439156737,-456130561,-473104385,-506855425,-540672001,-574488577,-608305153,-642121729,-676003841,-709885953,-760610817,-811335681,-862060545,-912850945,-980418561,-1048051713,-1115684865,-1183383553,-1267924993,-1352466433,-1453850625,-1555300353,-1656815617,-1775173633,-1893597185,-2028863489,2130771967,-1010376193,-1043996161,-1077681665,-1111367169,-1145052673,-1178738177,-1229200897,-1279663617,-1330126337,-1380654593,-1431182849,-1498488321,-1565793793,-1633164801,-1700535809,-1784684033,-1868832257,-1969823233,-2070814209,2123096575,2005262847,1887429119,1752752639,1601298943,1449779711,1281417727,1096278527,911073791,709026303,490201599,254534143,2023935,-1380857601,-1397700353,-1431320321,-1464940289,-1498560257,-1532180225,-1565865729,-1599551233,-1650013953,-1700476673,-1750939393,-1801402113,-1851864833,-1919170305,-1986475777,-2053781249,-2121086721,2089797887,2005649663,1904724223,1803798783,1686030591,1568262399,1450494207,1315883263,1164495103,1013041407,844810495,659736831,457885951,239192319,3655935,-1767919617,-1784762369,-1801605121,-1818447873,-1852067841,-1885687809,-1919307777,-1952927745,-1986547713,-2020167681,-2070564865,-2120962049,2123542527,2073079807,2022617087,1955377151,1888137215,1820897279,1736880127,1652797439,1568714751,1467854847,1366994943,1249357823,1131655167,997175295,862695423,711372799,560050175,391950335,207007743,5287935,2139657983,2122880767,2106103551,2089326335,2072549119,2055771903,2022217471,1988663039,1955108607,1921554175,1887934207,1854314239,1803917055,1753519871,1703122687,1652725503,1602328319,1535153919,1467979519,1400805119,1316853503,1232901887,1148950271,1048221439,947427071,846632703,729061119,611489535,477140735,326014719,174888703,6919935,1837268479,1820491263,1803714047,1786936831,1770159615,1753382399,1736605183,1719827967,1686273535,1652719103,1619164671,1585610239,1552055807,1518501375,1468169727,1417838079,1367506431,1317174783,1266843135,1199734271,1132625407,1065516543,998407679,914521599,830635519,729972223,629308927,528645631,411205119,293764607,159546879,8551935,-2086957569,-2103734785,-2120512001,-2137289217,2140900863,2107346431,2073791999,2040237311,2006682623,1973127935,1939573247,1906018559,1855686655,1805354751,1755022847,1704690943,1654359039,1587249919,1520140799,1453031679,1369145343,1285258751,1201372159,1100708351,1000044543,882603519,765162495,630943999,496725503,345729791,177956863,10183935,-1699437825,-1716215297,-1732992769,-1766547457,-1800102145,-1833656833,-1867211521,-1900766209,-1934320897,-1967875585,-2018207489,-2068539649,-2118871809,2125763327,2058653951,1991544575,1924435199,1857325823,1773438975,1689552127,1588888063,1488223999,1387559679,1270118143,1152676607,1018457855,884238847,733242623,565468927,397695231,213144319,11815935,-1311918593,-1345473281,-1379027969,-1412582657,-1446137345,-1479692289,-1513247233,-1546802177,-1597134337,-1647466497,-1697798657,-1748130817,-1798463233,-1865572865,-1932682497,-1999792129,-2083678977,2127401215,2043514111,1942849791,1842185215,1724743423,1607301631,1473082367,1338863103,1187866367,1020092415,852318207,667766783,466437887,248331519,13447935,-924398849,-957953793,-991508737,-1025063681,-1058618625,-1092173569,-1142505729,-1192837889,-1243170305,-1293502721,-1343835137,-1410944769,-1478054401,-1545164289,-1629051393,-1712938497,-1796825857,-1897490433,-1998155009,-2098819841,2078705407,1961263103,1827043583,1676046591,1525049599,1357275135,1172723199,971394047,753287423,518403327,283518975,15079935,-570434049,-603988993,-637543937,-671098881,-704653825,-754986241,-805318657,-855651073,-905983489,-973093377,-1040203265,-1107313153,-1174423041,-1258310401,-1342197761,-1442862593,-1543527425,-1644192257,-1761634561,-1879076865,-2013296641,2147450879,1996453631,1828678911,1660904191,1476351999,1275022335,1056915199,822030591,570368511,301928959,16711935,-503325185,-536880129,-570435073,-603990017,-637544961,-671100161,-721432577,-771764993,-822097409,-872430081,-922762753,-989872641,-1056982529,-1124092673,-1191202817,-1275090433,-1358978049,-1459642881,-1560307969,-1660973057,-1778415617,-1895858177,-2030078209,2113891583,1962894079,1795119103,1610566655,1426013951,1224683775,1006576127,771691007,520028415,-452993537,-469771265,-503326209,-536881153,-570436097,-603991297,-637546497,-671101697,-721434113,-771766785,-822099457,-872432129,-922764801,-989874945,-1056985089,-1124095489,-1191205889,-1275093505,-1358981377,-1459646465,-1560311809,-1677754369,-1795197185,-1912640257,-2046860545,2097108991,1946110975,1778335487,1593782527,1392452095,1174344191,939458815,-419439105,-436216833,-452994561,-469772289,-503327233,-536882433,-570437633,-603992833,-637548033,-671103489,-721436161,-771768833,-822101505,-872434433,-922767361,-989877761,-1056988161,-1124098561,-1207986433,-1291874305,-1375762433,-1476427777,-1577093377,-1694536449,-1811979521,-1946200065,-2080420865,2063548159,1912549631,1744773631,1560220159,1358889215,-385884673,-402662401,-419440129,-436217857,-452995585,-469773569,-503328769,-536883969,-570439169,-603994625,-637550081,-671105537,-721438209,-771771137,-822104065,-872437249,-922770433,-989880833,-1056991489,-1124102145,-1191213057,-1275101185,-1358989569,-1459655425,-1560321281,-1677764609,-1795208193,-1912652033,-2046873345,2097095167,1946096127,1778319615,-335553025,-352330753,-369108481,-385886209,-402663937,-419441921,-436219905,-452997889,-486553089,-520108545,-553664001,-587219457,-620774913,-654330625,-687886337,-738219521,-788552705,-838885889,-889219329,-939552769,-1006663681,-1073774593,-1140885761,-1224774401,-1308663041,-1392551937,-1493218305,-1593884929,-1711329025,-1828773377,-1962995201,-2097217281,-285221377,-301999105,-318776833,-335554561,-352332289,-369110273,-385888257,-402666241,-419444225,-436222465,-453000705,-469778945,-503334401,-536890113,-570445825,-604001793,-637557761,-671113729,-721447169,-771780609,-822114305,-872448001,-922781953,-989893377,-1057004801,-1124116481,-1191228417,-1275117825,-1359007489,-1459674625,-1560342017,-1677786881,-234889729,-234890241,-251667969,-268445697,-285223425,-302001409,-318779393,-335557377,-352335361,-369113601,-385891841,-402670081,-419448321,-436226817,-453005313,-469784065,-503340033,-536896001,-570452225,-604008449,-637564929,-671121409,-704678145,-755012353,-805346561,-855681025,-906015745,-973127937,-1040240385,-1107353089,-1174466049,-1258356481,-234889729,-234890241,-234890753,-234891265,-234891777,-234892545,-234893313,-234894081,-234894849,-251673089,-268451329,-285229569,-302007809,-318786305,-335564801,-352343553,-369122305,-385901057,-402680065,-419459073,-436238337,-453017601,-486574337,-520131329,-553688321,-587245569,-620803073,-654360833,-687918849,-738254337,-788590081,-838926081,-234889729,-234890241,-234890753,-234891265,-234891777,-234892545,-234893313,-234894081,-234894849,-234895873,-234896897,-234897921,-234898945,-234900225,-234901505,-234903041,-234904577,-234906113,-234907905,-234909697,-234911745,-251691009,-268470529,-285250305,-302030081,-318810113,-335590401,-352370945,-369151745,-385932801,-402714113,-419495681,-8705,-9217,-9729,-10241,-10753,-11521,-12289,-13057,-13825,-14849,-15873,-16897,-17921,-19201,-20481,-22017,-23553,-25089,-26881,-28673,-30721,-32769,-35073,-37633,-40193,-43009,-46081,-49409,-52993,-56833,-60929,-65281,-926209,-926721,-927233,-927745,-928257,-929025,-929793,-930561,-931329,-932353,-933377,-934401,-935425,-936705,-937985,-939521,-941057,-1008129,-1075457,-1142785,-1210369,-1277953,-1345793,-1413889,-1481985,-1550337,-1618945,-1687809,-1756929,-1826305,-1895937,-2031361,-926209,-926721,-927233,-927745,-928257,-929025,-929793,-996097,-1062401,-1128961,-1195521,-1262081,-1328641,-1395457,-1462273,-1529345,-1596417,-1663489,-1730817,-1798145,-1865729,-1998849,-2132225,-2265857,-2399489,-2533377,-2667521,-2867457,-3067649,-3268097,-3468801,-3669761,-926209,-992257,-1058305,-1124353,-1190401,-1256705,-1323009,-1389313,-1455617,-1522177,-1588737,-1655297,-1721857,-1788673,-1855489,-1988097,-2120705,-2253313,-2386177,-2519041,-2652161,-2785281,-2984193,-3183361,-3382529,-3581953,-3847169,-4112641,-4378369,-4644353,-4976129,-5308161,-1188353,-1254401,-1320449,-1386497,-1452545,-1518849,-1585153,-1651457,-1717761,-1784321,-1850881,-1982977,-2115073,-2247425,-2379777,-2512385,-2644993,-2777601,-2976001,-3174401,-3373057,-3571713,-3836161,-4100865,-4365569,-4630529,-4961281,-5292289,-5689089,-6086145,-6483457,-6946561,-1384961,-1451009,-1517057,-1583105,-1649153,-1715457,-1781761,-1848065,-1979905,-2112001,-2244097,-2376193,-2508289,-2640641,-2838529,-3036673,-3234817,-3432961,-3631361,-3895297,-4159489,-4423681,-4688129,-5018369,-5348609,-5744641,-6140929,-6537473,-6999809,-7462401,-7990785,-8584961,-1581569,-1647617,-1713665,-1779713,-1845761,-1977601,-2109441,-2241281,-2373121,-2505217,-2637313,-2769409,-2967041,-3164929,-3362817,-3560961,-3759105,-4022785,-4286721,-4550657,-4880385,-5210113,-5540097,-5935873,-6331649,-6793217,-7255041,-7782657,-8310529,-8904193,-9563649,-10223361,-1712641,-1778689,-1844737,-1976321,-2107905,-2239745,-2371585,-2503425,-2635265,-2767361,-2964993,-3162625,-3360257,-3558145,-3821569,-4085249,-4348929,-4612609,-4942081,-5271553,-5666817,-6062081,-6457601,-6918913,-7380225,-7907329,-8434689,-9027841,-9686785,-10345985,-11070977,-11861761,-1843713,-1975297,-2106881,-2238465,-2370049,-2501889,-2633729,-2765569,-2962945,-3160577,-3358209,-3555841,-3753473,-4016897,-4280321,-4544001,-4873217,-5202433,-5531905,-5926913,-6322177,-6782977,-7244033,-7770881,-8297729,-8890369,-9548801,-10207489,-10931969,-11722241,-12578305,-13500161,-1974785,-2106369,-2237953,-2369537,-2501121,-2632961,-2830337,-3027713,-3225089,-3422721,-3620353,-3883521,-4146689,-4410113,-4673537,-5002753,-5331969,-5726721,-6121729,-6582273,-7043073,-7503873,-8030465,-8622849,-9215233,-9873409,-10597377,-11387137,-12242689,-13164033,-14085633,-15138561,-2236929,-2368513,-2500097,-2631681,-2763265,-2960641,-3158017,-3355393,-3552769,-3815937,-4079105,-4342273,-4605441,-4934401,-5263361,-5658113,-6052865,-6447617,-6908161,-7368705,-7895041,-8421377,-9013505,-9671425,-10329345,-11053057,-11842561,-12697857,-13618945,-14605825,-15658497,-16776961] \ No newline at end of file
diff --git a/release/scripts/flt_import.py b/release/scripts/flt_import.py
index 3ba118c0d18..1df7c937842 100644
--- a/release/scripts/flt_import.py
+++ b/release/scripts/flt_import.py
@@ -6,6 +6,8 @@ Group: 'Import'
Tip: 'Import OpenFlight (.flt)'
"""
+
+
__author__ = "Greg MacDonald, Campbell Barton, Geoffrey Bantle"
__version__ = "2.0 11/21/07"
__url__ = ("blender", "elysiun", "Author's homepage, http://sourceforge.net/projects/blight/")
@@ -952,8 +954,12 @@ class InterNode(Node):
except: #horrible...
pass
+
if self.parent and self.parent.object and (self.header.scene == self.parent.header.scene):
- self.parent.object.makeParent([self.object])
+ self.parent.object.makeParent([self.object],1)
+
+ if self.matrix:
+ self.object.setMatrix(self.matrix)
if self.vis == False:
self.object.restrictDisplay = True
@@ -979,8 +985,6 @@ class InterNode(Node):
min= LODmin(min,lodlist[i])
min.vis = True
- if self.matrix:
- self.object.setMatrix(self.matrix)
Node.blender_import(self) # Attach faces to self.faceLs
@@ -1324,11 +1328,17 @@ class XRef(InterNode):
self.props['comment'] = ''
self.parse_record()
- xref_filename = self.props['3t200!filename']
+ xref_filename = self.props['3t200!filename'] #I dont even think there is a reason to keep this around...
+
+ if not os.path.isabs(xref_filename):
+ absname = os.path.join(os.path.dirname(self.header.filename), xref_filename)
+ else:
+ absname = xref_filename
+
self.props['id'] = 'X: ' + Blender.sys.splitext(Blender.sys.basename(xref_filename))[0] #this is really wrong as well....
- if global_prefs['doxrefs'] and os.path.exists(xref_filename) and not self.header.grr.xrefs.has_key(xref_filename):
- self.xref = Database(xref_filename, self.header.grr, self)
+ if global_prefs['doxrefs'] and os.path.exists(absname) and not self.header.grr.xrefs.has_key(xref_filename):
+ self.xref = Database(absname, self.header.grr, self)
self.header.grr.xrefs[xref_filename] = self.xref
else:
self.xref = None
@@ -1348,8 +1358,15 @@ class XRef(InterNode):
except:
pass
+
+
+
if self.parent and self.parent.object:
- self.parent.object.makeParent([self.object])
+ self.parent.object.makeParent([self.object],1)
+
+ if self.matrix:
+ self.object.setMatrix(self.matrix)
+
#id props import
self.object.properties['FLT'] = dict()
@@ -1361,8 +1378,7 @@ class XRef(InterNode):
self.object.Layer = current_layer
self.object.sel = 1
- if self.matrix:
- self.object.setMatrix(self.matrix)
+
Node.blender_import(self)
@@ -1843,6 +1859,9 @@ class Database(InterNode):
print 'Parsing:', filename
print
+ #check to see if filename is a relative path
+ #filename = os.path.abspath(filename)
+
self.fw = flt_filewalker.FltIn(filename)
self.filename = filename
self.bname = os.path.splitext(os.path.basename(filename))[0]
@@ -1902,7 +1921,7 @@ def fixscale(root,childhash):
for child in childhash[root]:
fixscale(child,childhash)
location = Blender.Mathutils.Vector(root.getLocation('worldspace'))
- if location[0] != 0.0 and location[1] != 0.0 and location[2] != 0.0:
+ if location[0] != 0.0 or location[1] != 0.0 or location[2] != 0.0:
#direction = Blender.Mathutils.Vector(0-location[0],0-location[1],0-location[2]) #reverse vector
smat = Blender.Mathutils.ScaleMatrix(global_prefs['scale'],4)
root.setLocation(location * smat)
diff --git a/release/scripts/flt_toolbar.py b/release/scripts/flt_toolbar.py
index 213fac1bb3c..249c3f83dfc 100644
--- a/release/scripts/flt_toolbar.py
+++ b/release/scripts/flt_toolbar.py
@@ -76,7 +76,8 @@ evcode = {
"IDPROP_COPY" : 501,
"IDPROP_KILL" : 502,
"CLIGHT_MAKE" : 700,
- "DFROMACT" : 701
+ "DFROMACT" : 701,
+ "FIXCOL" : 702
}
XREF_PREFIX = None
@@ -92,6 +93,44 @@ IDPROP_COPY = None
SCENE_UPDATE = None
CLIGHT_MAKE = None
DFROMACT = None
+FIXCOL = None
+
+
+def RGBtoHSV( r, g, b):
+ cmin = min( r, g, b )
+ cmax = max( r, g, b )
+ v = cmax
+
+ if(cmax!=0.0):
+ s = (cmax-cmin)/cmax
+ else:
+ s = 0.0
+ h = 0.0
+
+ if(s == 0.0):
+ h = -1.0
+ else:
+ cdelta = cmax-cmin
+ rc = (cmax-r)/cdelta
+ gc = (cmax-g)/cdelta
+ bc = (cmax-b)/cdelta
+ if(r==cmax):
+ h = bc-gc
+ else:
+ if(g==cmax):
+ h = 2.0+rc-bc
+ else:
+ h = 4.0+gc-rc
+ h = h*60.0
+ if(h<0.0):
+ h += 360.0
+
+
+ h = h/360.0
+ if(h < 0.0):
+ h = 0.0
+ return (h,s,v)
+
def update_state():
state = dict()
@@ -141,24 +180,130 @@ def idprops_copy(source):
for key in source.properties['FLT']:
object.properties['FLT'][key] = source.properties['FLT'][key]
-def update_all():
+def unpack_color(color):
+ return struct.unpack('>BBBB',struct.pack('>I',color))
+
+
+def findColorKey(colordict, hsv):
+ hdelta = 0.001
+ for key in colordict:
+ if not (((hsv[0] < (key[0] + hdelta)) and (hsv[0] > (key[0] - hdelta))) and ((hsv[1] < (key[1] + hdelta)) and (hsv[1] > (key[1] - hdelta)))):
+ return key
+ return None
+
+def hsvsort(a, b):
+ (index1, mag1) = a
+ (index2, mag2) = b
+ if mag1 > mag2:
+ return 1
+ elif mag1 < mag2:
+ return -1
+ return 0
+
+def fix_colors():
+
+ editmode = 0
+ if Blender.Window.EditMode():
+ Blender.Window.EditMode(0)
+ editmode = 1
state = update_state()
- #update the baked FLT colors for all meshes.
- for object in state["activeScene"].objects:
- if object.type == "Mesh":
+
+ scene = state["activeScene"]
+ colors = None
+ if state["activeScene"].properties.has_key('FLT'):
+ try:
+ colors = state["activeScene"].properties['FLT']['Color Palette']
+ except:
+ pass
+ if not colors:
+ return
+
+ #first build a HSV version of our palette
+ hsvpalette = list()
+ for swatch in colors:
+ color = unpack_color(swatch)
+ hsv = RGBtoHSV(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0)
+ hsvpalette.append(hsv)
+
+ #collect all of our meshes
+ meshes = list()
+ for object in scene.objects.context:
+ if object.sel and object.type == 'Mesh':
mesh = object.getData(mesh=True)
- if 'FLT_COL' in mesh.faces.properties:
- mesh.activeColorLayer = "FLT_Fcol"
- for face in mesh.faces:
- (index,intensity) = unpack_face_index(face.getProperty('FLT_COL'))
- color = struct.unpack('>BBBB',struct.pack('>I',state["colors"][index]))
- #update the vertex colors for this face
- for col in face.col:
- col.r = int(color[0] * intensity)
- col.g = int(color[1] * intensity)
- col.b = int(color[2] * intensity)
- col.a = 255
+ if "FLT_COL" in mesh.faces.properties:
+ meshes.append(mesh)
+
+
+ #Now go through our meshes, and build a dictionary of face lists keyed according to (hue,saturation) of the baked color
+ colordict = dict()
+ for mesh in meshes:
+ for face in mesh.faces:
+ hsv = RGBtoHSV(face.col[0].r/255.0, face.col[0].g/255.0, face.col[0].b/255.0) #retrieve baked color
+ if colordict.has_key((hsv[0],hsv[1])):
+ colordict[(hsv[0],hsv[1])].append(face)
+ else:
+ colordict[(hsv[0],hsv[1])] = [face]
+
+ #for each color key in the color dict, build a list of distances from it to the values in hsvpalette and then quicksort them for closest match
+ for key in colordict:
+ maglist = list()
+ for i, hsv in enumerate(hsvpalette):
+ norm = Blender.Mathutils.Vector(hsv[0], hsv[1]) - Blender.Mathutils.Vector(key[0],key[1])
+ maglist.append((i,norm.length))
+ maglist.sort(hsvsort)
+ print maglist[0]
+ for face in colordict[key]:
+ (index, intensity) = unpack_face_index(face.getProperty("FLT_COL"))
+ newfindex = pack_face_index(maglist[0][0],intensity)
+ face.setProperty("FLT_COL", int(newfindex))
+
+ for mesh in meshes:
+ update_mesh_colors(colors,mesh)
+
+ if editmode:
+ Blender.Window.EditMode(1)
+
+
+def update_mesh_colors(colors, mesh):
+ if 'FLT_COL' in mesh.faces.properties:
+ mesh.activeColorLayer = "FLT_Fcol"
+ for face in mesh.faces:
+ (index,intensity) = unpack_face_index(face.getProperty('FLT_COL'))
+ color = struct.unpack('>BBBB',struct.pack('>I',colors[index]))
+
+ if index == 0 and intensity == 0:
+ color = (255,255,255)
+ intensity = 1.0
+ #update the vertex colors for this face
+ for col in face.col:
+ col.r = int(color[0] * intensity)
+ col.g = int(color[1] * intensity)
+ col.b = int(color[2] * intensity)
+ col.a = 255
+
+
+def update_all():
+
+ editmode = 0
+ if Blender.Window.EditMode():
+ Blender.Window.EditMode(0)
+ editmode = 1
+ state = update_state()
+
+ if state["activeScene"].properties.has_key('FLT'):
+ try:
+ colors = state["activeScene"].properties['FLT']['Color Palette']
+ except:
+ colors = None
+ if colors:
+ #update the baked FLT colors for all meshes.
+ for object in state["activeScene"].objects:
+ if object.type == "Mesh":
+ mesh = object.getData(mesh=True)
+ update_mesh_colors(colors,mesh)
+ if editmode:
+ Blender.Window.EditMode(1)
#Change this to find the deep parent
def xref_create():
@@ -528,6 +673,8 @@ def but_event(evt):
clight_make()
if evt == evcode["DFROMACT"]:
dfromact()
+ if evt == evcode["FIXCOL"]:
+ fix_colors()
Draw.Redraw(1)
Blender.Window.RedrawAll()
@@ -582,17 +729,20 @@ def draw_postcommon(x,y,finaly):
def draw_propsheet(x,y):
- global XREF_PREFIX
- global XREF_MAKE
- global XREF_EDIT
- global XREF_SELECT
- global XREF_POP
- global FACE_MAKESUB
- global FACE_SELSUB
- global FACE_KILLSUB
- global IDPROP_KILL
- global IDPROP_COPY
- global SCENE_UPDATE
+ global XREF_PREFIX
+ global XREF_MAKE
+ global XREF_EDIT
+ global XREF_SELECT
+ global XREF_POP
+ global FACE_MAKESUB
+ global FACE_SELSUB
+ global FACE_KILLSUB
+ global IDPROP_KILL
+ global IDPROP_COPY
+ global SCENE_UPDATE
+ global DFROMACT
+ global FIXCOL
+
global CLIGHT_MAKE
global xrefprefix
global xrefstack
@@ -643,11 +793,13 @@ def draw_propsheet(x,y):
y=y-20
DFROMACT = Blender.Draw.PushButton("Dof from Active", evcode["DFROMACT"],x,y,width,20,"Get Dof origin from active object")
- draw_postcommon(origx, origy,y)
+ y=y-20
+ FIXCOL = Blender.Draw.PushButton("Fix Colors", evcode["FIXCOL"],x,y,width,20,"Fix baked FLT colors of selected meshes")
+ draw_postcommon(origx, origy,y)
def gui():
#draw the propsheet/toolbox.
- psheety = 280
+ psheety = 300
#psheetx = psheety + 10
draw_propsheet(0,psheety)
Draw.Register(gui,event,but_event)
diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h
index 0a042c1612a..ae4cdbe1cfe 100644
--- a/source/blender/blenkernel/BKE_bad_level_calls.h
+++ b/source/blender/blenkernel/BKE_bad_level_calls.h
@@ -89,7 +89,7 @@ int EXPP_dict_set_item_str(struct PyObject *dict, char *key, struct PyObject *va
void Node_SetStack(struct BPy_Node *self, struct bNodeStack **stack, int type);
void InitNode(struct BPy_Node *self, struct bNode *node);
void Node_SetShi(struct BPy_Node *self, struct ShadeInput *shi);
-struct BPy_NodeSockets *Node_CreateSockets(struct bNode *node);
+struct BPy_NodeSockets *Node_CreateSocketLists(struct bNode *node);
int pytype_is_pynode(struct PyObject *pyob);
/* writefile.c */
struct Oops;
diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h
index ca40295515b..9229397e674 100644
--- a/source/blender/blenkernel/BKE_bmesh.h
+++ b/source/blender/blenkernel/BKE_bmesh.h
@@ -93,7 +93,7 @@ typedef struct BME_Edge
void *data; /*custom edge data*/
int eflag1, eflag2; /*reserved for use by eulers*/
int tflag1, tflag2; /*reserved for use by tools*/
- unsigned char flag, h;
+ unsigned short flag, h;
float crease, bweight;
} BME_Edge;
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index 463254b8e4f..3889721b8c9 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -172,7 +172,8 @@ void bvh_free ( BVH * bvh );
// checks two bounding volume hierarchies for potential collisions and returns some list with those
-// update bounding volumes, needs updated positions in bvh->x
+// update bounding volumes, needs updated positions in bvh->current_xold (static)
+// and also bvh->current_x if moving==1
void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving);
void bvh_update(BVH * bvh, int moving);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index e0b935fc106..53960a71470 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -212,7 +212,7 @@ int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
void psys_free_settings(struct ParticleSettings *part);
void free_child_path_cache(struct ParticleSystem *psys);
void psys_free_path_cache(struct ParticleSystem *psys);
-void free_hair(struct ParticleSystem *psys);
+void free_hair(struct ParticleSystem *psys, int softbody);
void free_keyed_keys(struct ParticleSystem *psys);
void psys_free(struct Object * ob, struct ParticleSystem * psys);
void psys_free_children(struct ParticleSystem *psys);
diff --git a/source/blender/blenkernel/BKE_sculpt.h b/source/blender/blenkernel/BKE_sculpt.h
index e03e38bab75..5d7ed28f561 100644
--- a/source/blender/blenkernel/BKE_sculpt.h
+++ b/source/blender/blenkernel/BKE_sculpt.h
@@ -59,9 +59,6 @@ typedef struct SculptSession {
struct RadialControl *radialcontrol;
- /* For rotating around a pivot point */
- vec3f pivot;
-
struct SculptStroke *stroke;
} SculptSession;
diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
index 1da46149eac..d0d6a892a81 100644
--- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c
+++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
@@ -128,7 +128,7 @@ int EXPP_dict_set_item_str(struct PyObject *dict, char *key, struct PyObject *va
void Node_SetStack(struct BPy_Node *self, struct bNodeStack **stack, int type){}
void InitNode(struct BPy_Node *self, struct bNode *node){}
void Node_SetShi(struct BPy_Node *self, struct ShadeInput *shi){}
-struct BPy_NodeSockets *Node_CreateSockets(struct bNode *node)
+struct BPy_NodeSockets *Node_CreateSocketLists(struct bNode *node)
{
return 0;
}
@@ -367,3 +367,6 @@ void harmonic_coordinates_bind(struct MeshDeformModifierData *mmd,
void PE_free_particle_edit(struct ParticleSystem *psys) {}
void PE_get_colors(char sel[4], char nosel[4]) {}
void PE_recalc_world_cos(struct Object *ob, struct ParticleSystem *psys) {}
+
+/* text.c */
+void txt_copy_clipboard (struct Text *text){}
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 4e00e29029c..9dcb6b6e7fa 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -1293,7 +1293,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
VertDataMulN(nCo, 1.0f/numEdges);
}
- if ((sharpCount>1 && v->numFaces) || seam) {
+ if (sharpCount>1 || seam) {
VertDataZero(q);
if (seam) {
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index b8c05f3bb7b..3b4de305545 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -295,7 +295,7 @@ void copy_pose(bPose **dst, bPose *src, int copycon)
outPose= MEM_callocN(sizeof(bPose), "pose");
- duplicatelist (&outPose->chanbase, &src->chanbase);
+ duplicatelist(&outPose->chanbase, &src->chanbase);
if (copycon) {
for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) {
@@ -314,11 +314,11 @@ void free_pose_channels(bPose *pose)
if (pose->chanbase.first) {
for (pchan = pose->chanbase.first; pchan; pchan=pchan->next){
- if(pchan->path)
+ if (pchan->path)
MEM_freeN(pchan->path);
free_constraints(&pchan->constraints);
}
- BLI_freelistN (&pose->chanbase);
+ BLI_freelistN(&pose->chanbase);
}
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 7ec56bd08ab..4bb31c1e9b9 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1389,18 +1389,26 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
bPoseChannel *pchan, *pchanp, pchanw;
bConstraint *con;
- if(frompose==NULL) return;
+ if (frompose==NULL) return;
/* exception, armature local layer should be proxied too */
- if(pose->proxy_layer)
+ if (pose->proxy_layer)
((bArmature *)ob->data)->layer= pose->proxy_layer;
/* clear all transformation values from library */
rest_pose(frompose);
- pchan= pose->chanbase.first;
- for(; pchan; pchan= pchan->next) {
- if(pchan->bone->layer & layer_protected) {
+ /* copy over all of the proxy's bone groups */
+ /* TODO for later - implement 'local' bone groups as for constraints
+ * Note: this isn't trivial, as bones reference groups by index not by pointer,
+ * so syncing things correctly needs careful attention
+ */
+ BLI_freelistN(&pose->agroups);
+ duplicatelist(&pose->agroups, &frompose->agroups);
+ pose->active_group= frompose->active_group;
+
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (pchan->bone->layer & layer_protected) {
ListBase proxylocal_constraints = {NULL, NULL};
pchanp= get_pose_channel(frompose, pchan->name);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index d2834571316..a58fdab8c91 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -190,11 +190,6 @@ BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon)
// springs = cloth->springs;
// numsprings = cloth->numsprings;
-
- bvh->flags = 0;
- bvh->leaf_tree = NULL;
- bvh->leaf_root = NULL;
- bvh->tree = NULL;
bvh->epsilon = epsilon;
bvh->numfaces = cloth->numfaces;
@@ -211,20 +206,9 @@ BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon)
return NULL;
}
- bvh->current_xold = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_xold" );
-
- if (bvh->current_xold == NULL)
- {
- printf("bvh: Out of memory.\n");
- MEM_freeN(bvh->current_x);
- MEM_freeN(bvh);
- return NULL;
- }
-
for(i = 0; i < bvh->numverts; i++)
{
VECCOPY(bvh->current_x[i].co, verts[i].tx);
- VECCOPY(bvh->current_xold[i].co, verts[i].txold);
}
bvh_build (bvh);
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index a1c49ac4655..61f2288f8e8 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -69,6 +69,7 @@ void collision_move_object(CollisionModifierData *collmd, float step, float prev
VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
VECSUB(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
}
+ bvh_update_from_mvert(collmd->bvh, collmd->current_x, collmd->numverts, collmd->current_xnew, 1);
}
/* build bounding volume hierarchy from mverts (see kdop.c for whole BVH code) */
@@ -86,11 +87,6 @@ BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsig
// in the moment, return zero if no faces there
if(!numfaces)
return NULL;
-
- bvh->flags = 0;
- bvh->leaf_tree = NULL;
- bvh->leaf_root = NULL;
- bvh->tree = NULL;
bvh->epsilon = epsilon;
bvh->numfaces = numfaces;
@@ -103,8 +99,7 @@ BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsig
}
bvh->numverts = numverts;
- bvh->current_x = MEM_dupallocN(x);
- bvh->current_xold = MEM_dupallocN(x);
+ bvh->current_x = MEM_dupallocN(x);
bvh_build(bvh);
@@ -432,6 +427,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa
float w1, w2, w3, u1, u2, u3;
float v1[3], v2[3], relativeVelocity[3];
float magrelVel;
+ float epsilon2 = collmd->bvh->epsilon;
cloth1 = clmd->clothObject;
@@ -515,7 +511,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa
// Apply repulse impulse if distance too short
// I_r = -min(dt*kd, m(0,1d/dt - v_n))
- d = clmd->coll_parms->epsilon*8.0/9.0 - collpair->distance;
+ d = clmd->coll_parms->epsilon*8.0/9.0 + epsilon2*8.0/9.0 - collpair->distance;
if((magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame) && (d > ALMOST_ZERO))
{
repulse = MIN2(d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel);
@@ -562,6 +558,7 @@ void cloth_collision_static(ModifierData *md1, ModifierData *md2, CollisionTree
ClothVertex *verts1=NULL;
double distance = 0;
float epsilon = clmd->coll_parms->epsilon;
+ float epsilon2 = ((CollisionModifierData *)md2)->bvh->epsilon;
unsigned int i = 0;
for(i = 0; i < 4; i++)
@@ -646,9 +643,9 @@ void cloth_collision_static(ModifierData *md1, ModifierData *md2, CollisionTree
verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa,collpair->pb,collpair->vector);
#else
// just be sure that we don't add anything
- distance = 2.0 * (epsilon + ALMOST_ZERO);
+ distance = 2.0 * (epsilon + epsilon2 + ALMOST_ZERO);
#endif
- if (distance <= (epsilon + ALMOST_ZERO))
+ if (distance <= (epsilon + epsilon2 + ALMOST_ZERO))
{
// printf("dist: %f\n", (float)distance);
@@ -973,12 +970,15 @@ int cloth_bvh_objcollisions_do(ClothModifierData * clmd, CollisionModifierData *
verts = cloth->verts;
- if (collmd->tree)
+ if (collmd->bvh)
{
- BVH *coll_bvh = collmd->tree;
-
+ /* get pointer to bounding volume hierarchy */
+ BVH *coll_bvh = collmd->bvh;
+
+ /* move object to position (step) in time */
collision_move_object(collmd, step + dt, step);
-
+
+ /* search for overlapping collision pairs */
bvh_traverse((ModifierData *)clmd, (ModifierData *)collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static, 0);
}
else
@@ -993,7 +993,7 @@ int cloth_bvh_objcollisions_do(ClothModifierData * clmd, CollisionModifierData *
{
result = 0;
- if (collmd->tree)
+ if (collmd->bvh)
result += cloth_collision_response_static(clmd, collmd);
// apply impulses in parallel
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index dcd8bc6d9eb..0b33cc3a75b 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -1976,13 +1976,16 @@ float calc_curve_subdiv_radius(Curve *cu, Nurb *nu, int cursubdiv)
if ( ((nu->type & 7)==CU_NURBS) && (nu->flagu & CU_CYCLIC)) {
if (bp >= bplast) bp = bpfirst;
else bp++;
+ } else if ( bp > bplast ) {
+ /* this can happen in rare cases, refer to bug [#8596] */
+ bp = bplast;
}
rad = prevrad = bp->radius;
if ((bp == bplast) && (nu->flagu & CU_CYCLIC)) { /* loop around */
bp= bpfirst;
- } else if (bp != bplast) {
+ } else if (bp < bplast) {
bp++;
}
nextrad = bp->radius;
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 21e58f88aad..4c39f36800c 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -37,13 +37,11 @@
#include "DNA_cloth_types.h"
#include "DNA_scene_types.h"
-
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_cloth.h"
#include "BKE_utildefines.h"
-
#ifdef _WIN32
#include <windows.h>
static LARGE_INTEGER _itstart, _itend;
@@ -1458,11 +1456,11 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
speed[0] = speed[1] = speed[2] = 0.0;
if(mfaces[i].v4)
{
- pdDoEffectors(effectors, lX[i], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+ pdDoEffectors(effectors, lX[mfaces[i].v4], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
VECCOPY(wind_normalized, speed);
Normalize(wind_normalized);
VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal) * verts[mfaces[i].v4].mass);
- VECADDS(lF[i], lF[i], wind_normalized, 0.25);
+ VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], wind_normalized, 0.25);
}
}
diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c
index 79a9559250f..9fb476614d3 100644
--- a/source/blender/blenkernel/intern/kdop.c
+++ b/source/blender/blenkernel/intern/kdop.c
@@ -476,14 +476,15 @@ static void bvh_div_env_node(BVH *bvh, CollisionTree *tree, CollisionTree **face
// Sort along longest axis
if(laxis!=lastaxis)
bvh_sort_along_axis(face_list, start, end, laxis);
-
+
+ // maximum is 4 since we have a quad tree
max_nodes = MIN2((end-start + 1 ),4);
for (i = 0; i < max_nodes; i++)
{
tree->count_nodes++;
- if(end-start > 4)
+ if(end-start+1 > 4)
{
int quarter = ((float)((float)(end - start + 1) / 4.0f));
tstart = start + i * quarter;
@@ -537,18 +538,32 @@ void bvh_build (BVH *bvh)
CollisionTree *tree=NULL;
LinkNode *nlink = NULL;
+ bvh->flags = 0;
+ bvh->leaf_tree = NULL;
+ bvh->leaf_root = NULL;
+ bvh->tree = NULL;
+
+ if(!bvh->current_x)
+ {
+ bvh_free(bvh);
+ return;
+ }
+
+ bvh->current_xold = MEM_dupallocN(bvh->current_x);
+
tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
- // TODO: check succesfull alloc
- BLI_linklist_append(&bvh->tree, tree);
-
- nlink = bvh->tree;
-
+
if (tree == NULL)
{
printf("bvh_build: Out of memory for nodes.\n");
bvh_free(bvh);
return;
}
+
+ BLI_linklist_append(&bvh->tree, tree);
+
+ nlink = bvh->tree;
+
bvh->root = bvh->tree->link;
bvh->root->isleaf = 0;
bvh->root->parent = NULL;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 42cac46c241..1b95ae14ecf 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -633,9 +633,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
if(ma->flarec==0) ma->flarec= 1;
- /* add all texcoflags from mtex */
- ma->texco= 0;
- ma->mapto= 0;
+ /* add all texcoflags from mtex, texco and mapto were cleared in advance */
for(a=0; a<MAX_MTEX; a++) {
/* separate tex switching */
@@ -730,6 +728,16 @@ void init_render_materials(int r_mode, float *amb)
{
Material *ma;
+ /* clear these flags before going over materials, to make sure they
+ * are cleared only once, otherwise node materials contained in other
+ * node materials can go wrong */
+ for(ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if(ma->id.us) {
+ ma->texco= 0;
+ ma->mapto= 0;
+ }
+ }
+
/* two steps, first initialize, then or the flags for layers */
for(ma= G.main->mat.first; ma; ma= ma->id.next) {
/* is_used flag comes back in convertblender.c */
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 3bfd605cf27..9155a5ee444 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1109,9 +1109,13 @@ float (*mesh_getRefKeyCos(Mesh *me, int *numVerts_r))[3]
if(me->key && me->key->refkey) {
if(numVerts_r) *numVerts_r= me->totvert;
- cos= MEM_mallocN(sizeof(*cos)*me->totvert, "vertexcos1");
-
+
kb= me->key->refkey;
+
+ /* prevent accessing invalid memory */
+ if (me->totvert > kb->totelem) cos= MEM_callocN(sizeof(*cos)*me->totvert, "vertexcos1");
+ else cos= MEM_mallocN(sizeof(*cos)*me->totvert, "vertexcos1");
+
totvert= MIN2(kb->totelem, me->totvert);
memcpy(cos, kb->data, sizeof(*cos)*totvert);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 4db391ddc95..4aa69daa6d0 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -5037,8 +5037,8 @@ static void clothModifier_initData(ModifierData *md)
{
ClothModifierData *clmd = (ClothModifierData*) md;
- clmd->sim_parms = MEM_callocN(sizeof(SimulationSettings), "cloth sim parms");
- clmd->coll_parms = MEM_callocN(sizeof(CollisionSettings), "cloth coll parms");
+ clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
+ clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
/* check for alloc failing */
if(!clmd->sim_parms || !clmd->coll_parms)
@@ -5055,7 +5055,12 @@ static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob,
/* check for alloc failing */
if(!clmd->sim_parms || !clmd->coll_parms)
- return derivedData;
+ {
+ clothModifier_initData(md);
+
+ if(!clmd->sim_parms || !clmd->coll_parms)
+ return derivedData;
+ }
result = clothModifier_do(clmd, ob, derivedData, useRenderParams, isFinalCalc);
@@ -5090,7 +5095,7 @@ static void clothModifier_updateDepgraph(
}
}
}
- }
+ }
}
CustomDataMask clothModifier_requiredDataMask(ModifierData *md)
@@ -5156,7 +5161,7 @@ static void collisionModifier_initData(ModifierData *md)
collmd->current_v = NULL;
collmd->time = -1;
collmd->numverts = 0;
- collmd->tree = NULL;
+ collmd->bvh = NULL;
}
static void collisionModifier_freeData(ModifierData *md)
@@ -5165,8 +5170,8 @@ static void collisionModifier_freeData(ModifierData *md)
if (collmd)
{
- if(collmd->tree)
- bvh_free(collmd->tree);
+ if(collmd->bvh)
+ bvh_free(collmd->bvh);
if(collmd->x)
MEM_freeN(collmd->x);
if(collmd->xnew)
@@ -5188,7 +5193,7 @@ static void collisionModifier_freeData(ModifierData *md)
collmd->current_v = NULL;
collmd->time = -1;
collmd->numverts = 0;
- collmd->tree = NULL;
+ collmd->bvh = NULL;
collmd->mfaces = NULL;
}
}
@@ -5258,7 +5263,7 @@ static void collisionModifier_deformVerts(
// TODO: epsilon
// create bounding box hierarchy
- collmd->tree = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sbift);
+ collmd->bvh = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft);
collmd->time = current_time;
}
@@ -5281,14 +5286,14 @@ static void collisionModifier_deformVerts(
memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert));
/* happens on file load (ONLY when i decomment changes in readfile.c */
- if(!collmd->tree)
+ if(!collmd->bvh)
{
- collmd->tree = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sbift);
+ collmd->bvh = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
}
else
{
// recalc static bounding boxes
- bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0);
+ bvh_update_from_mvert(collmd->bvh, collmd->current_x, numverts, NULL, 0);
}
collmd->time = current_time;
@@ -5527,6 +5532,7 @@ static void particleSystemModifier_deformVerts(
/* make new dm */
psmd->dm=CDDM_copy(dm);
+ CDDM_apply_vert_coords(psmd->dm, vertexCos);
CDDM_calc_normals(psmd->dm);
if(needsFree){
@@ -6747,7 +6753,7 @@ static void meshdeformModifier_do(
float (*vertexCos)[3], int numVerts)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
- float imat[4][4], cagemat[4][4], icagemat[4][4], iobmat[3][3];
+ float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
int a, b, totvert, totcagevert, defgrp_index;
DerivedMesh *tmpdm, *cagedm;
@@ -6773,8 +6779,9 @@ static void meshdeformModifier_do(
/* compute matrices to go in and out of cage object space */
Mat4Invert(imat, mmd->object->obmat);
Mat4MulMat4(cagemat, ob->obmat, imat);
- Mat4Invert(icagemat, cagemat);
- Mat3CpyMat4(iobmat, icagemat);
+ Mat4MulMat4(cmat, cagemat, mmd->bindmat);
+ Mat4Invert(iobmat, cmat);
+ Mat3CpyMat4(icagemat, iobmat);
/* bind weights if needed */
if(!mmd->bindcos)
@@ -6872,7 +6879,7 @@ static void meshdeformModifier_do(
if(totweight > 0.0f) {
VecMulf(co, fac/totweight);
- Mat3MulVecfl(iobmat, co);
+ Mat3MulVecfl(icagemat, co);
if(G.rt != 527)
VECADD(vertexCos[b], vertexCos[b], co)
else
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index bc9aa23ee15..6c3775bcbaa 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -534,6 +534,14 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
break;
}
}
+
+ /* set socket own_index to zero since it can still have a value
+ * from being in a group before, otherwise it doesn't get a unique
+ * index in group_verify_own_indices */
+ for(sock= node->inputs.first; sock; sock= sock->next)
+ sock->own_index= 0;
+ for(sock= node->outputs.first; sock; sock= sock->next)
+ sock->own_index= 0;
}
}
@@ -589,6 +597,10 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
}
}
}
+
+ /* update node levels */
+ ntreeSolveOrder(ntree);
+
return gnode;
}
@@ -1356,11 +1368,21 @@ bNode *nodeGetActiveID(bNodeTree *ntree, short idtype)
bNode *node;
if(ntree==NULL) return NULL;
+
+ /* check for group edit */
+ for(node= ntree->nodes.first; node; node= node->next)
+ if(node->flag & NODE_GROUP_EDIT)
+ break;
+
+ if(node)
+ ntree= (bNodeTree*)node->id;
+ /* now find active node with this id */
for(node= ntree->nodes.first; node; node= node->next)
if(node->id && GS(node->id->name)==idtype)
if(node->flag & NODE_ACTIVE_ID)
break;
+
return node;
}
@@ -1781,7 +1803,7 @@ static void composit_begin_exec(bNodeTree *ntree, int is_group)
if(is_group==0) {
for(sock= node->outputs.first; sock; sock= sock->next) {
- bNodeStack *ns= ntree->stack[0] + sock->stack_index;
+ bNodeStack *ns= ntree->stack + sock->stack_index;
if(sock->ns.data) {
ns->data= sock->ns.data;
@@ -1814,7 +1836,7 @@ static void composit_end_exec(bNodeTree *ntree, int is_group)
bNodeSocket *sock;
for(sock= node->outputs.first; sock; sock= sock->next) {
- ns= ntree->stack[0] + sock->stack_index;
+ ns= ntree->stack + sock->stack_index;
if(ns->data) {
sock->ns.data= ns->data;
ns->data= NULL;
@@ -1832,7 +1854,7 @@ static void composit_end_exec(bNodeTree *ntree, int is_group)
if(is_group==0) {
/* internally, group buffers are not stored */
- for(ns= ntree->stack[0], a=0; a<ntree->stacksize; a++, ns++) {
+ for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) {
if(ns->data) {
printf("freed leftover buffer from stack\n");
free_compbuf(ns->data);
@@ -1873,15 +1895,47 @@ static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack)
/* per tree (and per group) unique indices are created */
/* the index_ext we need to be able to map from groups to the group-node own stack */
+typedef struct bNodeThreadStack {
+ struct bNodeThreadStack *next, *prev;
+ bNodeStack *stack;
+ int used;
+} bNodeThreadStack;
+
+static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread)
+{
+ ListBase *lb= &ntree->threadstack[thread];
+ bNodeThreadStack *nts;
+
+ for(nts=lb->first; nts; nts=nts->next) {
+ if(!nts->used) {
+ nts->used= 1;
+ return nts;
+ }
+ }
+
+ nts= MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
+ nts->stack= MEM_dupallocN(ntree->stack);
+ nts->used= 1;
+ BLI_addtail(lb, nts);
+
+ return nts;
+}
+
+static void ntreeReleaseThreadStack(bNodeThreadStack *nts)
+{
+ nts->used= 0;
+}
+
void ntreeBeginExecTree(bNodeTree *ntree)
{
/* let's make it sure */
if(ntree->init & NTREE_EXEC_INIT)
return;
-
- /* allocate the stack pointer array */
- ntree->stack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(void *), "stack array");
-
+
+ /* allocate the thread stack listbase array */
+ if(ntree->type!=NTREE_COMPOSIT)
+ ntree->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array");
+
/* goes recursive over all groups */
ntree->stacksize= ntree_begin_exec_tree(ntree);
@@ -1891,7 +1945,7 @@ void ntreeBeginExecTree(bNodeTree *ntree)
int a;
/* allocate the base stack */
- ns=ntree->stack[0]= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack");
+ ns=ntree->stack= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack");
/* tag inputs, the get_stack() gives own socket stackdata if not in use */
for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
@@ -1901,7 +1955,7 @@ void ntreeBeginExecTree(bNodeTree *ntree)
bNodeSocket *sock;
for(sock= node->inputs.first; sock; sock= sock->next) {
if(sock->link) {
- ns= ntree->stack[0] + sock->link->fromsock->stack_index;
+ ns= ntree->stack + sock->link->fromsock->stack_index;
ns->hasoutput= 1;
ns->sockettype= sock->link->fromsock->type;
}
@@ -1909,16 +1963,11 @@ void ntreeBeginExecTree(bNodeTree *ntree)
sock->ns.sockettype= sock->type;
}
if(node->type==NODE_GROUP && node->id)
- group_tag_used_outputs(node, ntree->stack[0]);
+ group_tag_used_outputs(node, ntree->stack);
}
- /* composite does 1 node per thread, so no multiple stacks needed */
if(ntree->type==NTREE_COMPOSIT)
composit_begin_exec(ntree, 0);
- else {
- for(a=1; a<BLENDER_MAX_THREADS; a++)
- ntree->stack[a]= MEM_dupallocN(ntree->stack[0]);
- }
}
ntree->init |= NTREE_EXEC_INIT;
@@ -1928,6 +1977,7 @@ void ntreeEndExecTree(bNodeTree *ntree)
{
if(ntree->init & NTREE_EXEC_INIT) {
+ bNodeThreadStack *nts;
int a;
/* another callback candidate! */
@@ -1935,14 +1985,21 @@ void ntreeEndExecTree(bNodeTree *ntree)
composit_end_exec(ntree, 0);
if(ntree->stack) {
- for(a=0; a<BLENDER_MAX_THREADS; a++)
- if(ntree->stack[a])
- MEM_freeN(ntree->stack[a]);
-
MEM_freeN(ntree->stack);
ntree->stack= NULL;
}
+ if(ntree->threadstack) {
+ for(a=0; a<BLENDER_MAX_THREADS; a++) {
+ for(nts=ntree->threadstack[a].first; nts; nts=nts->next)
+ MEM_freeN(nts->stack);
+ BLI_freelistN(&ntree->threadstack[a]);
+ }
+
+ MEM_freeN(ntree->threadstack);
+ ntree->threadstack= NULL;
+ }
+
ntree->init &= ~NTREE_EXEC_INIT;
}
}
@@ -1971,12 +2028,20 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *stack;
+ bNodeThreadStack *nts = NULL;
/* only when initialized */
if((ntree->init & NTREE_EXEC_INIT)==0)
ntreeBeginExecTree(ntree);
- stack= ntree->stack[thread];
+ /* composite does 1 node per thread, so no multiple stacks needed */
+ if(ntree->type==NTREE_COMPOSIT) {
+ stack= ntree->stack;
+ }
+ else {
+ nts= ntreeGetThreadStack(ntree, thread);
+ stack= nts->stack;
+ }
for(node= ntree->nodes.first; node; node= node->next) {
if(node->typeinfo->execfunc) {
@@ -1988,6 +2053,9 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
node_group_execute(stack, callerdata, node, nsin, nsout);
}
}
+
+ if(nts)
+ ntreeReleaseThreadStack(nts);
}
@@ -2169,7 +2237,7 @@ static void freeExecutableNode(bNodeTree *ntree)
for(node= ntree->nodes.first; node; node= node->next) {
if(node->exec & NODE_FREEBUFS) {
for(sock= node->outputs.first; sock; sock= sock->next) {
- bNodeStack *ns= ntree->stack[0] + sock->stack_index;
+ bNodeStack *ns= ntree->stack + sock->stack_index;
if(ns->data) {
free_compbuf(ns->data);
ns->data= NULL;
@@ -2223,7 +2291,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
/* setup callerdata for thread callback */
thdata.rd= rd;
- thdata.stack= ntree->stack[0];
+ thdata.stack= ntree->stack;
/* fixed seed, for example noise texture */
BLI_srandom(rd->cfra);
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 27c4091e36f..04e9d63b9b5 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -275,7 +275,8 @@ void psys_free_settings(ParticleSettings *part)
if(part->pd)
MEM_freeN(part->pd);
}
-void free_hair(ParticleSystem *psys)
+
+void free_hair(ParticleSystem *psys, int softbody)
{
ParticleData *pa;
int i, totpart=psys->totpart;
@@ -288,7 +289,7 @@ void free_hair(ParticleSystem *psys)
psys->flag &= ~PSYS_HAIR_DONE;
- if(psys->soft) {
+ if(softbody && psys->soft) {
sbFree(psys->soft);
psys->soft = NULL;
}
@@ -342,7 +343,7 @@ void psys_free(Object *ob, ParticleSystem * psys)
psys_free_path_cache(psys);
- free_hair(psys);
+ free_hair(psys, 1);
free_keyed_keys(psys);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 568a3a34d91..b48bfc4f2b8 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -4476,7 +4476,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
part->rotfrom = PART_ROT_IINCR;
}
else
- free_hair(psys);
+ free_hair(psys, 1);
psys->softflag= 0;
psys->recalc &= ~PSYS_TYPE;
@@ -4656,7 +4656,8 @@ void particle_system_update(Object *ob, ParticleSystem *psys){
if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)){
float hcfra=0.0f;
int i;
- free_hair(psys);
+
+ free_hair(psys, 0);
/* first step is negative so particles get killed and reset */
psys->cfra=1.0f;
diff --git a/source/blender/blenkernel/intern/script.c b/source/blender/blenkernel/intern/script.c
index 099fedf460a..2836f5fd507 100644
--- a/source/blender/blenkernel/intern/script.c
+++ b/source/blender/blenkernel/intern/script.c
@@ -60,12 +60,5 @@
void free_script (Script *script)
{
if (!script) return;
-
- if (script->py_globaldict || script->py_button ||
- script->py_event || script->py_draw)
- {
- BPY_clear_script(script);
- }
-
- return;
+ BPY_clear_script(script);
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 3b8292a791c..ab0aecdd363 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -55,6 +55,7 @@
#include "DNA_image_types.h"
#include "DNA_world_types.h"
#include "DNA_brush_types.h"
+#include "DNA_node_types.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -75,6 +76,7 @@
#include "BKE_icons.h"
#include "BKE_ipo.h"
#include "BKE_brush.h"
+#include "BKE_node.h"
/* ------------------------------------------------------------------------- */
@@ -729,6 +731,7 @@ Tex *give_current_texture(Object *ob, int act)
Lamp *la = 0;
MTex *mtex = 0;
Tex *tex = 0;
+ bNode *node;
if(ob==0) return 0;
if(ob->totcol==0) return 0;
@@ -739,7 +742,6 @@ Tex *give_current_texture(Object *ob, int act)
mtex= la->mtex[(int)(la->texact)];
if(mtex) tex= mtex->tex;
}
- else tex= 0;
} else {
if(act>ob->totcol) act= ob->totcol;
else if(act==0) act= 1;
@@ -752,13 +754,25 @@ Tex *give_current_texture(Object *ob, int act)
if(matarar && *matarar) ma= (*matarar)[act-1];
else ma= 0;
-
+ }
+
+ if(ma && ma->use_nodes && ma->nodetree) {
+ node= nodeGetActiveID(ma->nodetree, ID_TE);
+
+ if(node) {
+ tex= (Tex *)node->id;
+ ma= NULL;
+ }
+ else {
+ node= nodeGetActiveID(ma->nodetree, ID_MA);
+ if(node)
+ ma= (Material*)node->id;
+ }
}
if(ma) {
mtex= ma->mtex[(int)(ma->texact)];
if(mtex) tex= mtex->tex;
}
- else tex= 0;
}
return tex;
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index 99e30bc91c0..3055f62ae3d 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -400,6 +400,16 @@ void DQuatNormalize(DualQuat *dq, float totweight);
void DQuatMulVecfl(DualQuat *dq, float *co, float mat[][3]);
void DQuatCpyDQuat(DualQuat *dq1, DualQuat *dq2);
+/* Tangent stuff */
+typedef struct VertexTangent {
+ float tang[3], uv[2];
+ struct VertexTangent *next;
+} VertexTangent;
+
+void sum_or_add_vertex_tangent(void *arena, VertexTangent **vtang, float *tang, float *uv);
+float *find_vertex_tangent(VertexTangent *vtang, float *uv);
+void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, float *co3, float *n, float *tang);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/intern/BLI_storage.h b/source/blender/blenlib/intern/BLI_storage.h
index 9cbdfa327cd..2c9932b6507 100644
--- a/source/blender/blenlib/intern/BLI_storage.h
+++ b/source/blender/blenlib/intern/BLI_storage.h
@@ -31,10 +31,12 @@
#ifndef BLI_STORAGE_H
#define BLI_STORAGE_H
+#ifndef __APPLE__
#ifndef WIN32
#define _LARGEFILE_SOURCE 1
#define _FILE_OFFSET_BITS 64
#endif
+#endif
#include "BLI_storage_types.h"
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index cd7de83b9c0..3514e695f59 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -57,6 +57,7 @@
#include <stdio.h>
#include "BLI_arithb.h"
+#include "BLI_memarena.h"
/* A few small defines. Keep'em local! */
#define SMALL_NUMBER 1.e-8
@@ -4268,3 +4269,75 @@ void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3
mat[3][1] = loc[1];
mat[3][2] = loc[2];
}
+
+/* Tangents */
+
+/* For normal map tangents we need to detect uv boundaries, and only average
+ * tangents in case the uvs are connected. Alternative would be to store 1
+ * tangent per face rather than 4 per face vertex, but that's not compatible
+ * with games */
+
+
+/* from BKE_mesh.h */
+#define STD_UV_CONNECT_LIMIT 0.0001f
+
+void sum_or_add_vertex_tangent(void *arena, VertexTangent **vtang, float *tang, float *uv)
+{
+ VertexTangent *vt;
+
+ /* find a tangent with connected uvs */
+ for(vt= *vtang; vt; vt=vt->next) {
+ if(fabs(uv[0]-vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabs(uv[1]-vt->uv[1]) < STD_UV_CONNECT_LIMIT) {
+ VecAddf(vt->tang, vt->tang, tang);
+ return;
+ }
+ }
+
+ /* if not found, append a new one */
+ vt= BLI_memarena_alloc((MemArena *)arena, sizeof(VertexTangent));
+ VecCopyf(vt->tang, tang);
+ vt->uv[0]= uv[0];
+ vt->uv[1]= uv[1];
+
+ if(*vtang)
+ vt->next= *vtang;
+ *vtang= vt;
+}
+
+float *find_vertex_tangent(VertexTangent *vtang, float *uv)
+{
+ VertexTangent *vt;
+ static float nulltang[3] = {0.0f, 0.0f, 0.0f};
+
+ for(vt= vtang; vt; vt=vt->next)
+ if(fabs(uv[0]-vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabs(uv[1]-vt->uv[1]) < STD_UV_CONNECT_LIMIT)
+ return vt->tang;
+
+ return nulltang; /* shouldn't happen, except for nan or so */
+}
+
+void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, float *co3, float *n, float *tang)
+{
+ float tangv[3], ct[3], e1[3], e2[3], s1, t1, s2, t2, det;
+
+ s1= uv2[0] - uv1[0];
+ s2= uv3[0] - uv1[0];
+ t1= uv2[1] - uv1[1];
+ t2= uv3[1] - uv1[1];
+ det= 1.0f / (s1 * t2 - s2 * t1);
+
+ /* normals in render are inversed... */
+ VecSubf(e1, co1, co2);
+ VecSubf(e2, co1, co3);
+ tang[0] = (t2*e1[0] - t1*e2[0])*det;
+ tang[1] = (t2*e1[1] - t1*e2[1])*det;
+ tang[2] = (t2*e1[2] - t1*e2[2])*det;
+ tangv[0] = (s1*e2[0] - s2*e1[0])*det;
+ tangv[1] = (s1*e2[1] - s2*e1[1])*det;
+ tangv[2] = (s1*e2[2] - s2*e1[2])*det;
+ Crossf(ct, tang, tangv);
+
+ /* check flip */
+ if ((ct[0]*n[0] + ct[1]*n[1] + ct[2]*n[2]) < 0.0f)
+ VecMulf(tang, -1.0f);
+}
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index f4a44b3a0db..92fad291e83 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -1,6 +1,6 @@
/**
*
- * $Id:
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -250,6 +250,8 @@ int BLI_system_thread_count( void )
mib[1] = HW_NCPU;
len = sizeof(t);
sysctl(mib, 2, &t, &len, NULL, 0);
+# elif defined(__sgi)
+ t = sysconf(_SC_NPROC_ONLN);
# else
t = (int)sysconf(_SC_NPROCESSORS_ONLN);
# endif
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 09edfe90d02..b54d42080b0 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -238,7 +238,7 @@ char *BLO_gethome(void);
int BLO_has_bfile_extension(char *str);
void BLO_library_append(struct SpaceFile *sfile, char *dir, int idcode);
void BLO_library_append_(BlendHandle **libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode);
-void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode, short flag, struct Scene *scene);
+void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Scene *scene);
BlendFileData* blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1557e970306..330ae84f922 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3051,11 +3051,14 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_LOADED;
- clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
-
- if(clmd->sim_parms->presets > 10)
- clmd->sim_parms->presets = 0;
+ if(clmd->sim_parms)
+ {
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_LOADED;
+ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
+
+ if(clmd->sim_parms->presets > 10)
+ clmd->sim_parms->presets = 0;
+ }
}
else if (md->type==eModifierType_Collision) {
@@ -3080,7 +3083,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
collmd->current_v = NULL;
collmd->time = -1;
collmd->numverts = 0;
- collmd->tree = NULL;
+ collmd->bvh = NULL;
collmd->mfaces = NULL;
}
@@ -7794,7 +7797,8 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
* user.blend, lib.blend and lib_indirect.blend - if user.blend alredy references a "tree" from
* lib_indirect.blend but lib.blend does too, linking in a Scene or Group from lib.blend can result in an
* empty without the dupli group referenced. Once you save and reload the group would appier. - Campbell */
- oldnewmap_insert(fd->libmap, bhead->old, id, 1);
+ /* This crashes files, must look further into it */
+ /*oldnewmap_insert(fd->libmap, bhead->old, id, 1);*/
change_idid_adr_fd(fd, bhead->old, id);
if(G.f & G_DEBUG) printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name);
@@ -8577,38 +8581,38 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
/* common routine to append/link something from a library */
static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
- int totsel, FileData *fd, struct direntry* filelist, int totfile, short flag)
+ int totsel, FileData **fd, struct direntry* filelist, int totfile, short flag)
{
Main *mainl;
Library *curlib;
/* make mains */
- blo_split_main(&fd->mainlist, G.main);
+ blo_split_main(&(*fd)->mainlist, G.main);
/* which one do we need? */
- mainl = blo_find_main(fd, &fd->mainlist, dir, G.sce);
+ mainl = blo_find_main(*fd, &(*fd)->mainlist, dir, G.sce);
- mainl->versionfile= fd->fileversion; /* needed for do_version */
+ mainl->versionfile= (*fd)->fileversion; /* needed for do_version */
curlib= mainl->curlib;
if(totsel==0) {
- append_named_part(fd, mainl, scene, file, idcode, flag);
+ append_named_part(*fd, mainl, scene, file, idcode, flag);
}
else {
int a;
for(a=0; a<totfile; a++) {
if(filelist[a].flags & ACTIVE) {
- append_named_part(fd, mainl, scene, filelist[a].relname, idcode, flag);
+ append_named_part(*fd, mainl, scene, filelist[a].relname, idcode, flag);
}
}
}
/* make main consistant */
- expand_main(fd, mainl);
+ expand_main(*fd, mainl);
/* do this when expand found other libs */
- read_libraries(fd, &fd->mainlist);
+ read_libraries(*fd, &(*fd)->mainlist);
if(flag & FILE_STRINGCODE) {
@@ -8619,10 +8623,10 @@ static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
BLI_makestringcode(G.sce, mainl->curlib->name);
}
- blo_join_main(&fd->mainlist);
- G.main= fd->mainlist.first;
+ blo_join_main(&(*fd)->mainlist);
+ G.main= (*fd)->mainlist.first;
- lib_link_all(fd, G.main);
+ lib_link_all(*fd, G.main);
lib_verify_nodetree(G.main, 0);
fix_relpaths_library(G.sce, G.main); /* make all relative paths, relative to the open blend file */
@@ -8641,8 +8645,9 @@ static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
/* 20041208: put back. It only linked direct, not indirect objects (ton) */
/* patch to prevent switch_endian happens twice */
- if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
- blo_freefiledata( fd );
+ if((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
+ blo_freefiledata( *fd );
+ *fd = NULL;
}
return curlib;
@@ -8653,11 +8658,11 @@ static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
/* append to G.scene */
/* this should probably be moved into the Python code anyway */
-void BLO_script_library_append(BlendHandle *bh, char *dir, char *name,
+void BLO_script_library_append(BlendHandle **bh, char *dir, char *name,
int idcode, short flag, Scene *scene )
{
/* try to append the requested object */
- library_append( scene, name, dir, idcode, 0, (FileData *)bh, NULL, 0, flag );
+ library_append( scene, name, dir, idcode, 0, (FileData **)bh, NULL, 0, flag );
/* do we need to do this? */
DAG_scene_sort(G.scene);
@@ -8673,6 +8678,7 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode)
{
FileData *fd= (FileData*) (*libfiledata);
+ int lastflags = fd->flags;
Library *curlib;
Base *centerbase;
Object *ob;
@@ -8705,12 +8711,7 @@ void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, i
if(flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
- curlib = library_append( G.scene, file, dir, idcode, totsel, fd, filelist, totfile,flag );
-
- /* patch to prevent switch_endian happens twice */
- if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
- (*libfiledata)= 0;
- }
+ curlib = library_append( G.scene, file, dir, idcode, totsel, (FileData**) libfiledata, filelist, totfile,flag );
/* when not linking (appending)... */
if((flag & FILE_LINK)==0) {
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index d70fe17c67f..4d8544ec09d 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -859,8 +859,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
else if(md->type==eModifierType_Cloth) {
ClothModifierData *clmd = (ClothModifierData*) md;
- writestruct(wd, DATA, "SimulationSettings", 1, clmd->sim_parms);
- writestruct(wd, DATA, "CollisionSettings", 1, clmd->coll_parms);
+ writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms);
+ writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms);
}
else if (md->type==eModifierType_Collision) {
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index dfa4e5831ba..eaa80865f08 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -484,7 +484,7 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
/* allocate array for pixel data */
npixels = ibuf->x * ibuf->y;
- if(ibuf->ftype & TIF_16BIT)
+ if(bitspersample == 16)
pixels16 = (unsigned short*)libtiff__TIFFmalloc(npixels *
samplesperpixel * sizeof(unsigned short));
else
@@ -499,7 +499,7 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
}
/* setup pointers */
- if(ibuf->ftype & TIF_16BIT) {
+ if(bitspersample == 16) {
fromf = ibuf->rect_float;
to16 = pixels16;
}
diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h
index 82d6bb84281..40c4df37f71 100644
--- a/source/blender/include/BIF_transform.h
+++ b/source/blender/include/BIF_transform.h
@@ -107,7 +107,7 @@ int BIF_menuselectTransformOrientation(void);
void BIF_selectTransformOrientation(struct TransformOrientation *ts);
void BIF_selectTransformOrientationFromIndex(int index);
-char * BIF_menustringTransformOrientation(); /* the returned value was allocated and needs to be freed after use */
+char * BIF_menustringTransformOrientation(char *title); /* the returned value was allocated and needs to be freed after use */
int BIF_countTransformOrientation();
/* Drawing callbacks */
diff --git a/source/blender/include/BSE_drawview.h b/source/blender/include/BSE_drawview.h
index c425cbc62ea..294c0ceb047 100644
--- a/source/blender/include/BSE_drawview.h
+++ b/source/blender/include/BSE_drawview.h
@@ -59,6 +59,8 @@ unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsi
void drawview3dspace(struct ScrArea *sa, void *spacedata);
void drawview3d_render(struct View3D *v3d, int winx, int winy, float winmat[][4]);
+void draw_depth(struct ScrArea *sa, void *spacedata);
+void view3d_update_depths(struct View3D *v3d);
int update_time(void);
void calc_viewborder(struct View3D *v3d, struct rctf *viewborder_r);
diff --git a/source/blender/include/BSE_edit.h b/source/blender/include/BSE_edit.h
index 71f6b275fd8..cac022ab6c2 100644
--- a/source/blender/include/BSE_edit.h
+++ b/source/blender/include/BSE_edit.h
@@ -40,6 +40,7 @@ int get_border(struct rcti *rect, short col);
void countall(void);
void snapmenu(void);
void mergemenu(void);
+void alignmenu(void);
void delete_context_selected(void);
void duplicate_context_selected(void);
void toggle_shading(void);
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 4ba1f4f02e8..53fbd1ff72c 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -44,7 +44,8 @@
* as in stepsPerFrame comapred to the time step in the paper, I've used
* variables with different names to minimize confusion.
**/
-typedef struct SimulationSettings
+
+typedef struct ClothSimSettings
{
short vgroup_mass; /* optional vertexgroup name for assigning weight.*/
short vgroup_struct; /* vertex group for scaling structural stiffness */
@@ -87,10 +88,10 @@ typedef struct SimulationSettings
short pad;
int pad2;
}
-SimulationSettings;
+ClothSimSettings;
-typedef struct CollisionSettings
+typedef struct ClothCollSettings
{
float epsilon; /* min distance for collisions. */
float self_friction; /* Fiction/damping with self contact. */
@@ -101,7 +102,7 @@ typedef struct CollisionSettings
int flags; /* collision flags defined in BKE_cloth.h */
float selfepsilon; /* for selfcollision */
}
-CollisionSettings;
+ClothCollSettings;
/**
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index dd1d8eb01b3..c62d012643a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -369,8 +369,8 @@ typedef struct ClothModifierData {
ModifierData modifier;
struct Cloth *clothObject; /* The internal data structure for cloth. */
- struct SimulationSettings *sim_parms; /* definition is in DNA_cloth_types.h */
- struct CollisionSettings *coll_parms; /* definition is in DNA_cloth_types.h */
+ struct ClothSimSettings *sim_parms; /* definition is in DNA_cloth_types.h */
+ struct ClothCollSettings *coll_parms; /* definition is in DNA_cloth_types.h */
} ClothModifierData;
typedef struct CollisionModifierData {
@@ -381,15 +381,15 @@ typedef struct CollisionModifierData {
struct MVert *xold; /* unsued atm, but was discussed during sprint */
struct MVert *current_xnew; /* new position at the actual inter-frame step */
struct MVert *current_x; /* position at the actual inter-frame step */
- struct MVert *current_v; /* position at the actual inter-frame step */
+ struct MVert *current_v; /* (xnew - x) at the actual inter-frame step */
struct MFace *mfaces; /* object face data */
unsigned int numverts;
unsigned int numfaces;
int pad;
- float time;
- struct BVH *tree; /* collision tree for this cloth object */
+ float time; /* cfra time of modifier */
+ struct BVH *bvh; /* bounding volume hierarchy for this cloth object */
} CollisionModifierData;
typedef enum {
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index f74e858c0e4..eda37d952c1 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -162,7 +162,8 @@ typedef struct bNodeTree {
ListBase nodes, links;
- bNodeStack **stack; /* stack is only while executing, no read/write in file */
+ bNodeStack *stack; /* stack is only while executing, no read/write in file */
+ struct ListBase *threadstack; /* same as above */
int type, init; /* set init on fileread */
int stacksize; /* amount of elements in stack */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 869f1cb426d..f31f9fff142 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -468,6 +468,10 @@ typedef struct SculptData
/* Settings for each brush */
BrushData drawbrush, smoothbrush, pinchbrush, inflatebrush, grabbrush, layerbrush, flattenbrush;
+
+ /* For rotating around a pivot point */
+ float pivot[3];
+
short brush_type;
/* For the Brush Shape */
@@ -486,10 +490,10 @@ typedef struct SculptData
/* Symmetry is separate from the other BrushData because the same
settings are always used for all brush types */
char symm;
-
+
/* Added to store if the 'Rake' setting has been set */
char rake;
- char pad[7];
+ char pad[3];
} SculptData;
typedef struct Scene {
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 180cbd2af37..df9ea872caa 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -103,7 +103,7 @@ typedef struct View3D {
/**
* The drawing mode for the 3d display. Set to OB_WIRE, OB_SOLID,
- * OB_SHADED or OB_TEXTURED */
+ * OB_SHADED or OB_TEXTURE */
short drawtype;
short localview;
int lay, layact;
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
index cf2af9bbc11..e317998b5fc 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
@@ -142,7 +142,6 @@ static void node_composit_exec_math(void *data, bNode *node, bNodeStack **in, bN
CompBuf *stackbuf;
/* check for inputs and outputs for early out*/
- if(in[0]->hasinput==0 && in[1]->hasinput==0) return;
if(out[0]->hasoutput==0) return;
/* no image-color operation */
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c b/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c
index 662d8e8dde9..5e1803a6774 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c
@@ -63,7 +63,7 @@ static float avgLogLum(CompBuf *src, float* auto_key, float* Lav, float* Cav)
}
-void static tonemap(NodeTonemap* ntm, CompBuf* dst, CompBuf* src)
+static void tonemap(NodeTonemap* ntm, CompBuf* dst, CompBuf* src)
{
int x, y;
float dr, dg, db, al, igm = (ntm->gamma==0.f) ? 1 : (1.f / ntm->gamma);
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
index ec3a9f3e5d6..36a3bd5b171 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
@@ -59,14 +59,6 @@ static PyObject *init_dynamicdict(void) {
return newscriptdict;
}
-/* unused for now
-static void free_dynamicdict(PyObject *dict) {
- if (dict!=NULL) {
- Py_DECREF(dict);
- }
-}
-*/
-
static bNodeType *node_dynamic_find_typeinfo(ListBase *list, ID *id)
{
bNodeType *ntype = list->first;
@@ -309,68 +301,6 @@ int nodeDynamicUnlinkText(ID *txtid) {
return 0; /* no pynodes used this text */
}
-/*
-static void node_dynamic_free_all_typeinfos(ListBase *list)
-{
- bNodeType *ntype, *ntnext;
-
- ntype = list->first;
-
- while (ntype) {
- ntnext = ntype->next;
- if (ntype->type == NODE_DYNAMIC && ntype->id) {
- BLI_remlink(list, ntype);
- node_dynamic_free_typeinfo_sockets(ntype);
- node_dynamic_free_typeinfo(ntype);
- }
- ntype = ntnext;
- }
-}
-*/
-/* Unload all pynodes: since the Game Engine restarts Python, we need
- * to recreate pynodes dicts and objects. First we get rid of them here: */
-/*
-void nodeDynamicUnloadAll(void)
-{
- Material *ma;
- bNode *nd;
- PyGILState_STATE gilstate = PyGILState_Ensure();
-
- for (ma= G.main->mat.first; ma; ma= ma->id.next) {
- if (ma->nodetree) {
- for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
- if ((nd->type == NODE_DYNAMIC) && nd->id) {
- node_dynamic_free_storage_cb(nd);
- nd->typeinfo = NULL;
- nd->custom1 = 0;
- nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_LOADED);
- }
- }
- }
- }
-
- node_dynamic_free_all_typeinfos(&node_all_shaders);
-
- PyGILState_Release(gilstate);
-}
-
-void nodeDynamicReloadAll(void)
-{
- Material *ma;
- bNode *nd;
-
- for (ma= G.main->mat.first; ma; ma= ma->id.next) {
- if (ma->nodetree) {
- for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
- if ((nd->type == NODE_DYNAMIC) && nd->id) {
- node_dynamic_setup(nd);
- }
- }
- }
- }
-}
-*/
-
static void node_dynamic_pyerror_print(bNode *node)
{
PyGILState_STATE gilstate = PyGILState_Ensure();
@@ -426,15 +356,17 @@ static int node_dynamic_parse(struct bNode *node)
while (PyDict_Next( (PyObject *)(nsd->dict), &pos, &key, &value)) {
/* look for the node object */
+ if (strcmp("Socket", PyString_AsString(key)) == 0)
+ continue; /* XXX ugly, fix it */
if (PyObject_TypeCheck(value, &PyType_Type)==1) {
- BPy_NodeSockets *sockets = Node_CreateSockets(node);
+ BPy_NodeSocketLists *socklists = Node_CreateSocketLists(node);
- args = Py_BuildValue("(O)", sockets);
+ args = Py_BuildValue("(O)", socklists);
/* init it to get the input and output sockets */
pynode = PyObject_Call(value, args, NULL);
- Py_DECREF(sockets);
+ Py_DECREF(socklists);
Py_DECREF(args);
if (!PyErr_Occurred() && pynode && pytype_is_pynode(pynode)) {
@@ -466,7 +398,7 @@ static int node_dynamic_parse(struct bNode *node)
node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY);
break;
}
- break;
+ //break;
}
}
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index d7bd4f22fc6..bf7c4d7ad62 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -128,7 +128,9 @@ extern "C" {
void BPY_clear_script( struct Script *script );
void BPY_free_finished_script( struct Script *script );
void BPY_scripts_clear_pyobjects( void );
-
+
+ void error_pyscript( void );
+
/* void BPY_Err_Handle(struct Text *text); */
/* void BPY_clear_bad_scriptlink(struct ID *id, struct Text *byebye); */
/* void BPY_clear_bad_scriptlist(struct ListBase *, struct Text *byebye); */
diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c
index febf5e3ff31..1f028e49070 100644
--- a/source/blender/python/BPY_interface.c
+++ b/source/blender/python/BPY_interface.c
@@ -261,6 +261,7 @@ void BPY_start_python( int argc, char **argv )
void BPY_end_python( void )
{
Script *script = NULL;
+ Script *next_script = NULL;
PyGILState_Ensure(); /* finalizing, no need to grab the state */
@@ -281,8 +282,8 @@ void BPY_end_python( void )
/* Freeing all scripts here prevents problems with the order in which
* Python is finalized and G.main is freed in exit_usiblender() */
- for (script = G.main->script.first; script; script = script->id.next) {
- BPY_clear_script(script);
+ for (script = G.main->script.first; script; script = next_script) {
+ next_script = script->id.next;
free_libblock( &G.main->script, script );
}
@@ -691,8 +692,7 @@ int BPY_txt_do_python_Text( struct Text *text )
BPY_Err_Handle( textname );
ReleaseGlobalDictionary( py_dict );
script->py_globaldict = NULL;
- if( G.main->script.first )
- free_libblock( &G.main->script, script );
+ free_libblock( &G.main->script, script );
PyGILState_Release(gilstate);
return 0;
} else {
@@ -785,14 +785,23 @@ int BPY_run_script(Script *script)
char fname[FILE_MAX];
char fpath[FILE_MAX];
char ftmp[FILE_MAX];
+ char *bpyhome = bpy_gethome(1);
- strcpy(ftmp, script->scriptname);
- BLI_split_dirfile(ftmp, fpath, fname);
- BLI_make_file_string("/", fpath, bpy_gethome(1), fname);
+ if (bpyhome) {
+ BLI_strncpy(ftmp, script->scriptname, sizeof(ftmp));
+ BLI_split_dirfile(ftmp, fpath, fname); /* get the filename only - fname */
+ BLI_strncpy(fpath, bpy_gethome(1), sizeof(fpath));
+ BLI_add_slash(fpath);
+ strcat(fpath, fname);
- if (BLI_exists(fpath)) {
- strncpy(script->scriptname, fpath, sizeof(script->scriptname));
- } else if (U.pythondir[0]) {
+ if (BLI_exists(fpath)) {
+ strncpy(script->scriptname, fpath, sizeof(script->scriptname));
+ } else {
+ bpyhome = NULL; /* a bit dodgy, this is so the line below runs */
+ }
+ }
+
+ if (bpyhome == NULL && U.pythondir[0]) {
BLI_make_file_string("/", fpath, U.pythondir, fname);
if (BLI_exists(fpath)) {
strncpy(script->scriptname, fpath, sizeof(script->scriptname));
@@ -812,11 +821,13 @@ int BPY_run_script(Script *script)
Py_INCREF( Py_None );
pyarg = Py_None;
} else {
- fp = fopen( script->scriptname, "rb" );
+ if (BLI_exists(script->scriptname)) {
+ fp = fopen( script->scriptname, "rb" );
+ }
+
if( !fp ) {
printf( "Error loading script: couldn't open file %s\n", script->scriptname );
- if( G.main->script.first )
- free_libblock( &G.main->script, script );
+ free_libblock( &G.main->script, script );
PyGILState_Release(gilstate);
return 0;
}
@@ -842,8 +853,7 @@ int BPY_run_script(Script *script)
if( !setup_armature_weakrefs()){
printf("Oops - weakref dict\n");
- if( G.main->script.first )
- free_libblock( &G.main->script, script );
+ free_libblock( &G.main->script, script );
ReleaseGlobalDictionary( py_dict );
MEM_freeN( buffer );
PyGILState_Release(gilstate);
@@ -910,9 +920,8 @@ int BPY_run_script(Script *script)
BPY_Err_Handle( script->id.name + 2 );
ReleaseGlobalDictionary( py_dict );
script->py_globaldict = NULL;
- if( G.main->script.first )
- free_libblock( &G.main->script, script );
- error( "Python script error: check console" );
+ free_libblock( &G.main->script, script );
+ error_pyscript( );
PyGILState_Release(gilstate);
return 0;
@@ -1110,7 +1119,7 @@ void BPY_free_finished_script( Script * script )
if( PyErr_Occurred( ) ) { /* if script ended after filesel */
PyErr_Print( ); /* eventual errors are handled now */
- error( "Python script error: check console" );
+ error_pyscript( );
}
PyGILState_Release(gilstate);
@@ -1146,6 +1155,7 @@ static void unlink_script( Script * script )
}
}
+/* This is called from free_libblock( &G.main->script, script ); */
void BPY_clear_script( Script * script )
{
PyObject *dict;
@@ -2015,6 +2025,7 @@ float BPY_pydriver_eval(IpoDriver *driver)
}
result = ( float )PyFloat_AsDouble( retval );
+ Py_DECREF(retval);
if (result == -1 && PyErr_Occurred()) {
result = pydriver_error(driver);
@@ -2961,3 +2972,7 @@ void BPY_scripts_clear_pyobjects( void )
SCRIPT_SET_NULL(script)
}
}
+void error_pyscript( void )
+{
+ error("Python script error: check console");
+}
diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c
index d520dded486..dbcd21f04f3 100644
--- a/source/blender/python/api2_2x/Blender.c
+++ b/source/blender/python/api2_2x/Blender.c
@@ -865,8 +865,15 @@ static PyObject *Blender_Run(PyObject *self, PyObject *value)
if (script) script->flags |= SCRIPT_RUNNING; /* set */
- if (!is_blender_text) free_libblock(&G.main->text, text);
-
+ if (!is_blender_text) {
+
+ /* nice to remember the original filename, so the script can run on reload */
+ if (script) {
+ strncpy(script->scriptname, fname, sizeof(script->scriptname));
+ script->scriptarg[0] = '\0';
+ }
+ free_libblock(&G.main->text, text);
+ }
Py_RETURN_NONE;
}
diff --git a/source/blender/python/api2_2x/Constraint.c b/source/blender/python/api2_2x/Constraint.c
index 9ca0d8d2545..844b9cc99ad 100644
--- a/source/blender/python/api2_2x/Constraint.c
+++ b/source/blender/python/api2_2x/Constraint.c
@@ -114,6 +114,8 @@ enum constraint_constants {
EXPP_CONSTR_LIMIT,
EXPP_CONSTR_CLAMP,
+ EXPP_CONSTR_MODE,
+
EXPP_CONSTR_LIMXMIN = LIMIT_XMIN,
EXPP_CONSTR_LIMXMAX = LIMIT_XMAX,
EXPP_CONSTR_LIMYMIN = LIMIT_YMIN,
@@ -904,6 +906,56 @@ static int stretchto_setter( BPy_Constraint *self, int type, PyObject *value )
}
}
+static PyObject *distlimit_getter( BPy_Constraint * self, int type )
+{
+ bDistLimitConstraint *con = (bDistLimitConstraint *)(self->con->data);
+
+ switch( type ) {
+ case EXPP_CONSTR_TARGET:
+ return Object_CreatePyObject( con->tar );
+ case EXPP_CONSTR_BONE:
+ return PyString_FromString( con->subtarget );
+ case EXPP_CONSTR_RESTLENGTH:
+ return PyFloat_FromDouble( (double)con->dist );
+ case EXPP_CONSTR_MODE:
+ return PyInt_FromLong( (long)con->mode );
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+}
+
+static int distlimit_setter( BPy_Constraint *self, int type, PyObject *value )
+{
+ bDistLimitConstraint *con = (bDistLimitConstraint *)(self->con->data);
+
+ switch( type ) {
+ case EXPP_CONSTR_TARGET: {
+ Object *obj = (( BPy_Object * )value)->object;
+ if( !BPy_Object_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected BPy object argument" );
+ con->tar = obj;
+ return 0;
+ }
+ case EXPP_CONSTR_BONE: {
+ char *name = PyString_AsString( value );
+ if( !name )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected string arg" );
+
+ BLI_strncpy( con->subtarget, name, sizeof( con->subtarget ) );
+
+ return 0;
+ }
+ case EXPP_CONSTR_RESTLENGTH:
+ return EXPP_setFloatClamped( value, &con->dist, 0.0, 100.0 );
+ case EXPP_CONSTR_MODE:
+ return EXPP_setIValueRange( value, &con->mode, LIMITDIST_INSIDE, LIMITDIST_ONSURFACE, 'i' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+}
+
static PyObject *followpath_getter( BPy_Constraint * self, int type )
{
bFollowPathConstraint *con = (bFollowPathConstraint *)(self->con->data);
@@ -1391,11 +1443,40 @@ static PyObject *script_getter( BPy_Constraint * self, int type )
bPythonConstraint *con = (bPythonConstraint *)(self->con->data);
switch( type ) {
- // FIXME!!!
- //case EXPP_CONSTR_TARGET:
- // return Object_CreatePyObject( con->tar );
- //case EXPP_CONSTR_BONE:
- // return PyString_FromString( con->subtarget );
+ case EXPP_CONSTR_TARGET:
+ case EXPP_CONSTR_BONE:
+ {
+ bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_PYTHON);
+ bConstraintTarget *ct;
+ PyObject *tlist=NULL, *val;
+
+ if (cti) {
+ /* change space of targets */
+ if (cti->get_constraint_targets) {
+ ListBase targets = {NULL, NULL};
+ int num_tars=0, i=0;
+
+ /* get targets, and create py-list for use temporarily */
+ num_tars= cti->get_constraint_targets(self->con, &targets);
+ if (num_tars) {
+ tlist= PyList_New(num_tars);
+
+ for (ct=targets.first; ct; ct=ct->next, i++) {
+ if (type == EXPP_CONSTR_BONE)
+ val= PyString_FromString(ct->subtarget);
+ else
+ val= Object_CreatePyObject(ct->tar);
+ PyList_SET_ITEM(tlist, i, val);
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(self->con, &targets, 1);
+ }
+ }
+
+ return tlist;
+ }
case EXPP_CONSTR_SCRIPT:
return Text_CreatePyObject( con->text );
case EXPP_CONSTR_PROPS:
@@ -1410,25 +1491,73 @@ static int script_setter( BPy_Constraint *self, int type, PyObject *value )
bPythonConstraint *con = (bPythonConstraint *)(self->con->data);
switch( type ) {
- // FIXME!!!
- //case EXPP_CONSTR_TARGET: {
- // Object *obj = (( BPy_Object * )value)->object;
- // if( !BPy_Object_Check( value ) )
- // return EXPP_ReturnIntError( PyExc_TypeError,
- // "expected BPy object argument" );
- // con->tar = obj;
- // return 0;
- // }
- //case EXPP_CONSTR_BONE: {
- // char *name = PyString_AsString( value );
- // if( !name )
- // return EXPP_ReturnIntError( PyExc_TypeError,
- // "expected string arg" );
- //
- // BLI_strncpy( con->subtarget, name, sizeof( con->subtarget ) );
- //
- // return 0;
- // }
+ case EXPP_CONSTR_TARGET:
+ case EXPP_CONSTR_BONE:
+ {
+ bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_PYTHON);
+ bConstraintTarget *ct;
+ int ok= 0;
+
+ if (cti) {
+ /* change space of targets */
+ if (cti->get_constraint_targets) {
+ ListBase targets = {NULL, NULL};
+ int num_tars=0, i=0;
+
+ /* get targets, and extract values from the given list */
+ num_tars= cti->get_constraint_targets(self->con, &targets);
+ if (num_tars) {
+ if ((PySequence_Check(value) == 0) || (PySequence_Size(value) != num_tars)) {
+ char errorstr[64];
+ sprintf(errorstr, "expected sequence of %d integer(s)", num_tars);
+ return EXPP_ReturnIntError(PyExc_TypeError, errorstr);
+ }
+
+ for (ct=targets.first; ct; ct=ct->next, i++) {
+ PyObject *val= PySequence_ITEM(value, i);
+
+ if (type == EXPP_CONSTR_BONE) {
+ char *name = PyString_AsString(val);
+
+ if (name == NULL) {
+ // hrm... should we break here instead?
+ ok = EXPP_ReturnIntError(PyExc_TypeError,
+ "expected string arg as member of list");
+ Py_DECREF(val);
+
+ break;
+ }
+
+ BLI_strncpy(ct->subtarget, name, sizeof(ct->subtarget));
+ }
+ else {
+ Object *obj = (( BPy_Object * )val)->object;
+
+ if ( !BPy_Object_Check(value) ) {
+ // hrm... should we break here instead?
+ ok = EXPP_ReturnIntError(PyExc_TypeError,
+ "expected BPy object argument as member of list");
+ Py_DECREF(val);
+
+ break;
+ }
+
+ ct->tar = obj;
+ }
+
+ Py_DECREF(val);
+ }
+ }
+
+ /* only flush changes to real constraints if all were successful */
+ if ((cti->flush_constraint_targets) && (ok == 0))
+ cti->flush_constraint_targets(self->con, &targets, 0);
+ }
+ }
+
+ return ok;
+ }
+ break;
case EXPP_CONSTR_SCRIPT: {
Text *text = (( BPy_Text * )value)->text;
if( !BPy_Object_Check( value ) )
@@ -1806,6 +1935,8 @@ static PyObject *Constraint_getData( BPy_Constraint * self, PyObject * key )
return loclimit_getter( self, setting );
case CONSTRAINT_TYPE_SIZELIMIT:
return sizelimit_getter( self, setting );
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ return distlimit_getter( self, setting );
case CONSTRAINT_TYPE_RIGIDBODYJOINT:
return rigidbody_getter( self, setting );
case CONSTRAINT_TYPE_CLAMPTO:
@@ -1883,6 +2014,9 @@ static int Constraint_setData( BPy_Constraint * self, PyObject * key,
case CONSTRAINT_TYPE_SIZELIMIT:
result = sizelimit_setter( self, key_int, arg);
break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ result = distlimit_setter( self, key_int, arg);
+ break;
case CONSTRAINT_TYPE_RIGIDBODYJOINT:
result = rigidbody_setter( self, key_int, arg);
break;
@@ -2370,6 +2504,8 @@ static PyObject *M_Constraint_TypeDict( void )
PyInt_FromLong( CONSTRAINT_TYPE_ROTLIMIT ) );
PyConstant_Insert( d, "LIMITSIZE",
PyInt_FromLong( CONSTRAINT_TYPE_SIZELIMIT ) );
+ PyConstant_Insert( d, "LIMITDIST",
+ PyInt_FromLong( CONSTRAINT_TYPE_DISTLIMIT ) );
PyConstant_Insert( d, "RIGIDBODYJOINT",
PyInt_FromLong( CONSTRAINT_TYPE_RIGIDBODYJOINT ) );
PyConstant_Insert( d, "CLAMPTO",
@@ -2563,6 +2699,15 @@ static PyObject *M_Constraint_SettingsDict( void )
PyConstant_Insert( d, "LOCK",
PyInt_FromLong( EXPP_CONSTR_LOCK ) );
+
+ PyConstant_Insert( d, "LIMITMODE",
+ PyInt_FromLong( EXPP_CONSTR_MODE ) );
+ PyConstant_Insert( d, "LIMIT_INSIDE",
+ PyInt_FromLong( LIMITDIST_INSIDE ) );
+ PyConstant_Insert( d, "LIMIT_OUTSIDE",
+ PyInt_FromLong( LIMITDIST_OUTSIDE ) );
+ PyConstant_Insert( d, "LIMIT_ONSURFACE",
+ PyInt_FromLong( LIMITDIST_ONSURFACE ) );
PyConstant_Insert( d, "COPY",
PyInt_FromLong( EXPP_CONSTR_COPY ) );
diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c
index a4bbeba65ac..76e33a1bcb7 100644
--- a/source/blender/python/api2_2x/Draw.c
+++ b/source/blender/python/api2_2x/Draw.c
@@ -617,7 +617,8 @@ static void exit_pydraw( SpaceScript * sc, short err )
if( err ) {
PyErr_Print( );
script->flags = 0; /* mark script struct for deletion */
- error( "Python script error: check console" );
+ SCRIPT_SET_NULL(script);
+ error_pyscript();
scrarea_queue_redraw( sc->area );
}
@@ -837,7 +838,7 @@ static void exec_but_callback(void *pyobj, void *data)
if (!result) {
Py_DECREF(pyvalue);
PyErr_Print( );
- error( "Python script error: check console" );
+ error_pyscript( );
}
Py_XDECREF( result );
}
@@ -1109,7 +1110,7 @@ static PyObject *Method_UIBlock( PyObject * self, PyObject * args )
if (!result) {
PyErr_Print( );
- error( "Python script error: check console" );
+ error_pyscript( );
} else {
/* copied from do_clever_numbuts in toolbox.c */
diff --git a/source/blender/python/api2_2x/Library.c b/source/blender/python/api2_2x/Library.c
index 1aacaf56786..12e2ce3055b 100644
--- a/source/blender/python/api2_2x/Library.c
+++ b/source/blender/python/api2_2x/Library.c
@@ -175,7 +175,7 @@ static PyObject *M_Library_Open( PyObject * self, PyObject * value )
BLI_strncpy(filename, G.sce, sizeof(filename));
bpy_openlib = BLO_blendhandle_from_file( fname1 );
BLI_strncpy(G.sce, filename, sizeof(filename));
-
+
if( !bpy_openlib )
return EXPP_ReturnPyObjError( PyExc_IOError, "file not found" );
@@ -344,6 +344,7 @@ static PyObject *oldM_Library_Load( PyObject * self, PyObject * args )
int blocktype = 0;
int linked = 0;
+
if( !bpy_openlib ) {
return EXPP_ReturnPyObjError( PyExc_IOError,
"no library file: you need to open one, first." );
@@ -359,12 +360,19 @@ static PyObject *oldM_Library_Load( PyObject * self, PyObject * args )
if( !blocktype )
return EXPP_ReturnPyObjError( PyExc_NameError,
"no such Blender datablock type" );
-
+
if (linked)
- BLO_script_library_append( bpy_openlib, bpy_openlibname, name, blocktype, FILE_LINK, G.scene);
+ BLO_script_library_append( &bpy_openlib, bpy_openlibname, name, blocktype, FILE_LINK, G.scene);
else
- BLO_script_library_append( bpy_openlib, bpy_openlibname, name, blocktype, 0, G.scene);
-
+ BLO_script_library_append( &bpy_openlib, bpy_openlibname, name, blocktype, 0, G.scene);
+
+ /*
+ NOTE: BLO_script_library_append() can close the library if there is
+ an endian issue. if this happened, reopen for the next call.
+ */
+ if ( !bpy_openlib )
+ bpy_openlib = BLO_blendhandle_from_file( bpy_openlibname );
+
if( update ) {
M_Library_Update( self );
Py_DECREF( Py_None ); /* incref'ed by above function */
@@ -610,7 +618,7 @@ PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name,
}
/* import from the libary */
- BLO_script_library_append( openlib, longFilename, name, self->type, mode,
+ BLO_script_library_append( &openlib, longFilename, name, self->type, mode,
scene );
/*
diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c
index 803c0b96ef3..f9a23ed37b2 100644
--- a/source/blender/python/api2_2x/Mesh.c
+++ b/source/blender/python/api2_2x/Mesh.c
@@ -75,6 +75,7 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
+#include "BLI_memarena.h"
#include "blendef.h"
#include "mydevice.h"
@@ -7494,6 +7495,179 @@ static PyObject *Mesh_pointInside( BPy_Mesh * self, PyObject * args, PyObject *k
}
+/* This is a bit nasty, Blenders tangents are computed for rendering, and this isnt compatible with a normal Mesh
+ * so we have to rewrite parts of it here, make sure these stay in sync */
+
+static PyObject *Mesh_getTangents( BPy_Mesh * self )
+{
+ /* python stuff */
+ PyObject *py_tanlist;
+ PyObject *py_tuple;
+
+
+ PyObject *py_vector;
+#if 0 /* BI-TANGENT */
+ PyObject *py_bivector;
+ PyObject *py_pair;
+
+ float no[3];
+#endif
+ /* mesh vars */
+ Mesh *mesh = self->mesh;
+ MTFace *tf = mesh->mtface;
+ MFace *mf = mesh->mface;
+ MVert *v1, *v2, *v3, *v4;
+ int mf_vi[4];
+
+ /* See convertblender.c */
+ float *uv1, *uv2, *uv3, *uv4;
+ float fno[3];
+ float tang[3];
+ float uv[4][2];
+ float *vtang;
+
+ float (*orco)[3] = NULL;
+
+ MemArena *arena= NULL;
+ VertexTangent **vtangents= NULL;
+ int i, j, len;
+
+
+ if(!mesh->mtface) {
+ if (!self->object)
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError, "cannot get tangents when there are not UV's, or the mesh has no link to an object");
+
+ orco = (float(*)[3])get_mesh_orco_verts(self->object);
+
+ if (!orco)
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError, "cannot get orco's for this objects tangents");
+ }
+
+ /* vertex normals */
+ arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ BLI_memarena_use_calloc(arena);
+ vtangents= MEM_callocN(sizeof(VertexTangent*)*mesh->totvert, "VertexTangent");
+
+ for( i = 0, tf = mesh->mtface, mf = mesh->mface; i < mesh->totface; mf++, tf++, i++ ) {
+ v1 = &mesh->mvert[mf->v1];
+ v2 = &mesh->mvert[mf->v2];
+ v3 = &mesh->mvert[mf->v3];
+ if (mf->v4) {
+ v4 = &mesh->mvert[mf->v4];
+
+ CalcNormFloat4( v1->co, v2->co, v3->co, v4->co, fno );
+ } else {
+ CalcNormFloat( v1->co, v2->co, v3->co, fno );
+ }
+
+ if(mesh->mtface) {
+ uv1= tf->uv[0];
+ uv2= tf->uv[1];
+ uv3= tf->uv[2];
+ uv4= tf->uv[3];
+ } else {
+ uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
+ spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]);
+ spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]);
+ spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]);
+ if(v4)
+ spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]);
+ }
+
+ tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang);
+ sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
+ sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2);
+ sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
+
+ if (mf->v4) {
+ v4 = &mesh->mvert[mf->v4];
+
+ tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang);
+ sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
+ sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
+ sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4);
+ }
+ }
+
+
+ py_tanlist = PyList_New(mesh->totface);
+
+ for( i = 0, tf = mesh->mtface, mf = mesh->mface; i < mesh->totface; mf++, tf++, i++ ) {
+
+ len = mf->v4 ? 4 : 3;
+
+ if(mesh->mtface) {
+ uv1= tf->uv[0];
+ uv2= tf->uv[1];
+ uv3= tf->uv[2];
+ uv4= tf->uv[3];
+ } else {
+ uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
+ spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]);
+ spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]);
+ spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]);
+ if(len==4)
+ spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]);
+ }
+
+ mf_vi[0] = mf->v1;
+ mf_vi[1] = mf->v2;
+ mf_vi[2] = mf->v3;
+ mf_vi[3] = mf->v4;
+
+#if 0 /* BI-TANGENT */
+ /* now calculate the bitangent */
+ if (mf->flag & ME_SMOOTH) {
+ no[0] = (float)(mesh->mvert[mf_vi[j]]->no[0] / 32767.0);
+ no[1] = (float)(mesh->mvert[mf_vi[j]]->no[1] / 32767.0);
+ no[2] = (float)(mesh->mvert[mf_vi[j]]->no[2] / 32767.0);
+ } else {
+ /* calc face normal */
+ if (len==4) CalcNormFloat4( mesh->mvert[0]->co, mesh->mvert[1]->co, mesh->mvert[2]->co, mesh->mvert[3]->co, no );
+ else CalcNormFloat4( mesh->mvert[0]->co, mesh->mvert[1]->co, mesh->mvert[2]->co, no );
+ }
+#endif
+
+ py_tuple = PyTuple_New( len );
+
+ for (j=0; j<len; j++) {
+ vtang= find_vertex_tangent(vtangents[mf_vi[j]], mesh->mtface ? tf->uv[j] : uv[j]); /* mf_vi[j] == mf->v1, uv[j] == tf->uv[0] */
+
+ py_vector = newVectorObject( vtang, 3, Py_NEW );
+ Normalize(((VectorObject *)py_vector)->vec);
+
+#if 0 /* BI-TANGENT */
+ py_pair = PyTuple_New( 2 );
+ PyTuple_SetItem( py_pair, 0, py_vector );
+ PyTuple_SetItem( py_pair, 1, py_bivector );
+
+ /* qdn: tangent space */
+ /* copied from texture.c */
+ float B[3], tv[3];
+ Crossf(B, shi->vn, shi->nmaptang); /* bitangent */
+ /* transform norvec from tangent space to object surface in camera space */
+ tv[0] = texres.nor[0]*shi->nmaptang[0] + texres.nor[1]*B[0] + texres.nor[2]*shi->vn[0];
+ tv[1] = texres.nor[0]*shi->nmaptang[1] + texres.nor[1]*B[1] + texres.nor[2]*shi->vn[1];
+ tv[2] = texres.nor[0]*shi->nmaptang[2] + texres.nor[1]*B[2] + texres.nor[2]*shi->vn[2];
+ shi->vn[0]= facm*shi->vn[0] + fact*tv[0];
+ shi->vn[1]= facm*shi->vn[1] + fact*tv[1];
+ shi->vn[2]= facm*shi->vn[2] + fact*tv[2];
+ PyTuple_SetItem( py_tuple, j, py_pair );
+#else
+ PyTuple_SetItem( py_tuple, j, py_vector );
+#endif
+ }
+
+ PyList_SetItem( py_tanlist, i, py_tuple );
+ }
+
+ BLI_memarena_free(arena);
+ if (orco) MEM_freeN( orco );
+ MEM_freeN( vtangents );
+
+ return py_tanlist;
+}
+
/*
* "__copy__" return a copy of the mesh
*/
@@ -7571,7 +7745,9 @@ static struct PyMethodDef BPy_Mesh_methods[] = {
"Recalculates inside or outside normals (experimental)"},
{"pointInside", (PyCFunction)Mesh_pointInside, METH_VARARGS|METH_KEYWORDS,
"Recalculates inside or outside normals (experimental)"},
-
+ {"getTangents", (PyCFunction)Mesh_getTangents, METH_VARARGS|METH_KEYWORDS,
+ "Return a list of face tangents"},
+
/* mesh custom data layers */
{"addUVLayer", (PyCFunction)Mesh_addUVLayer, METH_VARARGS,
"adds a UV layer to this mesh"},
diff --git a/source/blender/python/api2_2x/Node.c b/source/blender/python/api2_2x/Node.c
index 0a68509d287..0ceb6b3c2a2 100644
--- a/source/blender/python/api2_2x/Node.c
+++ b/source/blender/python/api2_2x/Node.c
@@ -43,6 +43,7 @@
#include "BLI_blenlib.h"
#include "gen_utils.h"
+#include "vector.h"
static PyObject *Node_repr( BPy_Node * self );
static int Node_compare(BPy_Node *a, BPy_Node *b);
@@ -50,101 +51,369 @@ static PyObject *ShadeInput_repr( BPy_ShadeInput * self );
static int ShadeInput_compare(BPy_ShadeInput *a, BPy_ShadeInput *b);
static BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi);
+/* node socket type */
+
+static PyObject *NodeSocket_getName(BPy_NodeSocket *self, void *unused)
+{
+ return PyString_FromString(self->name);
+}
+
+static int NodeSocket_setName(BPy_NodeSocket *self, PyObject *value, void *unused)
+{
+ char *name = NULL;
+
+ if (!PyString_Check(value))
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a string" );
+
+ name = PyString_AsString(value);
+
+ if (!name)
+ return EXPP_ReturnIntError(PyExc_RuntimeError,
+ "couldn't convert value to string!");
+
+ BLI_strncpy(self->name, name, NODE_MAXSTR);
+
+ return 0;
+}
+
+static PyObject *NodeSocket_getVal(BPy_NodeSocket *self, void *unused)
+{
+ PyObject *pyret = NULL;
+
+ if (self->type == SOCK_VALUE) {
+ pyret = PyFloat_FromDouble(self->val[0]);
+ }
+ else { /* VECTOR or RGBA */
+ pyret = newVectorObject(self->val, self->type, Py_NEW);
+
+ if (!pyret)
+ return EXPP_ReturnPyObjError(PyExc_RuntimeError,
+ "couldn't create vector object!");
+ }
+
+ return pyret;
+}
+
+static int NodeSocket_setVal(BPy_NodeSocket *self, PyObject *value, void *unused)
+{
+ int error = 0;
+
+ if (PySequence_Check(value)) {
+ PyObject *item, *fpyval;
+ int i, len;
+
+ len = PySequence_Size(value);
+
+ if (len == 3 || len == 4) {
+ for (i = 0; i < len; i++) {
+ item = PySequence_GetItem(value, i);
+ fpyval = PyNumber_Float(item);
+ if (!fpyval) {
+ Py_DECREF(item);
+ error = 1;
+ break;
+ }
+ self->val[i] = (float)PyFloat_AsDouble(fpyval);
+ Py_DECREF(item);
+ Py_DECREF(fpyval);
+ }
+ if (len == 3)
+ self->type = SOCK_VECTOR;
+ else /* len == 4 */
+ self->type = SOCK_RGBA;
+ }
+ else error = 1;
+ }
+ else if (VectorObject_Check(value)) {
+ VectorObject *vecOb = (VectorObject *)value;
+ short vlen = vecOb->size;
+
+ if (vlen == 3 || vlen == 4) {
+ VECCOPY(self->val, vecOb->vec); /* copies 3 values */
+ if (vlen == 3)
+ self->type = SOCK_VECTOR;
+ else {
+ self->val[3] = vecOb->vec[3];
+ self->type = SOCK_RGBA;
+ }
+ }
+ else error = 1;
+ }
+ else if (PyNumber_Check(value)) {
+ self->val[0] = (float)PyFloat_AsDouble(value);
+ self->type = SOCK_VALUE;
+ }
+ else error = 1;
+
+ if (error)
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a float or a sequence (or vector) of 3 or 4 floats" );
+ return 0;
+}
+
+static PyObject *NodeSocket_getMin(BPy_NodeSocket *self, void *unused)
+{
+ return PyFloat_FromDouble(self->min);
+}
+
+static int NodeSocket_setMin(BPy_NodeSocket *self, PyObject *value, void *unused)
+{
+ PyObject *pyval = PyNumber_Float(value);
+
+ if (!pyval)
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a float number" );
+
+ self->min = (float)PyFloat_AsDouble(pyval);
+ Py_DECREF(pyval);
+
+ return 0;
+}
+
+static PyObject *NodeSocket_getMax(BPy_NodeSocket *self, void *unused)
+{
+ return PyFloat_FromDouble(self->max);
+}
+
+static int NodeSocket_setMax(BPy_NodeSocket *self, PyObject *value, void *unused)
+{
+ PyObject *pyval = PyNumber_Float(value);
+
+ if (!pyval)
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a float number" );
+
+ self->max = (float)PyFloat_AsDouble(pyval);
+ Py_DECREF(pyval);
+
+ return 0;
+}
+
+static PyGetSetDef NodeSocket_getseters[] = {
+ {"name", (getter)NodeSocket_getName, (setter)NodeSocket_setName,
+ "This socket's name", NULL},
+ {"val", (getter)NodeSocket_getVal, (setter)NodeSocket_setVal,
+ "This socket's data value(s)", NULL},
+ {"min", (getter)NodeSocket_getMin, (setter)NodeSocket_setMin,
+ "This socket's min possible value (lower range limit)", NULL},
+ {"max", (getter)NodeSocket_getMax, (setter)NodeSocket_setMax,
+ "This socket's max possible value (upper range limit)", NULL},
+ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
+};
+
+static void NodeSocket_dealloc(BPy_NodeSocket *self)
+{
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *NodeSocket_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *pysocket = type->tp_alloc(type, 0);
+
+ if (!pysocket)
+ return EXPP_ReturnPyObjError(PyExc_RuntimeError, "couldn't create socket type!");
+
+ return pysocket;
+}
+
+static int NodeSocket_init(BPy_NodeSocket *self, PyObject *args, PyObject *kwargs)
+{
+ char *name = NULL;
+ float min = 0.0f, max = 1.0f;
+ PyObject *val = NULL;
+ static char *kwlist[] = {"name", "val", "min", "max", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Off", kwlist, &name, &val, &min, &max)){
+ return EXPP_ReturnIntError(PyExc_AttributeError, "expected a string and optionally:\n1) a float or a sequence (or vector) of 3 or 4 floats and\n2) two floats");
+ }
+
+ BLI_strncpy(self->name, name, NODE_MAXSTR);
+
+ self->min = min;
+ self->max = max;
+
+ if (val)
+ return NodeSocket_setVal(self, val, NULL);
+ /* else */
+ self->type = SOCK_VALUE;
+ self->val[0] = 0.0f;
+
+ return 0;
+}
+
+static PyObject *NodeSocket_copy(BPy_NodeSocket *self)
+{
+ BPy_NodeSocket *copied;
+
+ copied = (BPy_NodeSocket*)NodeSocket_new(&NodeSocket_Type, NULL, NULL);
+
+ if (!copied) return NULL; /* error already set in NodeSocket_new */
+
+ BLI_strncpy(copied->name, self->name, NODE_MAXSTR);
+ copied->min = self->min;
+ copied->max = self->max;
+ copied->type = self->type;
+ memcpy(copied->val, self->val, 4*sizeof(float));
+
+ return (PyObject *)copied;
+}
+
+static PyMethodDef BPy_NodeSocket_methods[] = {
+ {"__copy__", ( PyCFunction ) NodeSocket_copy, METH_NOARGS,
+ "() - Makes a copy of this node socket."},
+ {"copy", ( PyCFunction ) NodeSocket_copy, METH_NOARGS,
+ "() - Makes a copy of this node socket."},
+ {NULL, NULL, 0, NULL}
+};
+
+PyTypeObject NodeSocket_Type = {
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+ /* For printing, in format "<module>.<name>" */
+ "Blender.Node.Socket", /* char *tp_name; */
+ sizeof( BPy_NodeSocket ), /* int tp_basicsize; */
+ 0, /* tp_itemsize; For allocation */
+
+ /* Methods to implement standard operations */
+
+ (destructor)NodeSocket_dealloc,/* destructor tp_dealloc; */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* cmpfunc tp_compare; */
+ NULL, /* reprfunc tp_repr; */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ NULL, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/input buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset; */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ 0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */
+ 0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ BPy_NodeSocket_methods, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ NodeSocket_getseters, /* struct PyGetSetDef *tp_getset; */
+ NULL, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ (initproc)NodeSocket_init, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ NodeSocket_new, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+};
+
/**
- * Take the descriptions from list and create sockets for those in socks
+ * Take the descriptions from tuple and create sockets for those in socks
* socks is a socketstack from a bNodeTypeInfo
*/
-static int list_socks_to_typeinfo(PyObject *tuple, bNodeSocketType **socks, int stage, int limit) {
+static int pysockets_to_blendersockets(PyObject *tuple, bNodeSocketType **socks, int stage, int limit) {
int len = 0, a = 0, pos = 0, retval = 0;
- //wPyObject *key = NULL, *value = NULL;
- PyObject *item, *arg;
- bNodeSocketType *newsocks = NULL;
- char *s_name = NULL;
- int s_type = SOCK_VALUE;
- float s_val[4], s_min, s_max;
+ short stype;
+ BPy_NodeSocket *pysock;
+ bNodeSocketType *nsocks = NULL;
if (BTST2(stage, NODE_DYNAMIC_READY, NODE_DYNAMIC_ADDEXIST))
return 0; /* already has sockets */
len = PyTuple_Size(tuple);
- newsocks = MEM_callocN(sizeof(bNodeSocketType)*(len+1), "bNodeSocketType in Node.c");
+ nsocks = MEM_callocN(sizeof(bNodeSocketType)*(len+1), "bNodeSocketType in Node.c");
for (pos = 0, a = 0; pos< len; pos++, a++) {
- /* default socket values: */
- s_name = NULL;
- s_type = SOCK_VALUE;
- s_min = 0.0f;
- s_max = 1.0f;
- s_val[0] = s_val[1] = s_val[2] = s_val[3] = 1.0f;
-
- item = PyTuple_GetItem(tuple, pos);
+ pysock = (BPy_NodeSocket *)PyTuple_GetItem(tuple, pos);/*borrowed*/
- if (!PySequence_Check(item)) {
- PyErr_SetString(PyExc_AttributeError, "a socket must be a List of Lists or Tuples");
+ if (!BPy_NodeSocket_Check(pysock)) {
+ PyErr_SetString(PyExc_AttributeError, "expected a sequence of node sockets");
retval = -1;
break;
}
- arg = PySequence_Tuple(item);
+ stype = pysock->type;
- if (!PyArg_ParseTuple(arg, "s|iffffff", &s_name, &s_type,
- &s_min, &s_max,
- &s_val[0], &s_val[1], &s_val[2], &s_val[3] )) {
- PyErr_SetString(PyExc_AttributeError, "socket definitions require a string and optionally an int and 6 floats");
- retval = -1;
- Py_DECREF(arg);
- break;
- }
+ nsocks[a].type = stype;
+ nsocks[a].limit = limit;
+
+ nsocks[a].name = BLI_strdupn(pysock->name, NODE_MAXSTR);
+
+ nsocks[a].min = pysock->min;
+ nsocks[a].max = pysock->max;
+
+ if (stype > SOCK_VALUE) {
+ float *vec = pysock->val;
- newsocks[a].name = BLI_strdupn(s_name, NODE_MAXSTR);
- newsocks[a].type = s_type;
- newsocks[a].min = s_min;
- newsocks[a].max = s_max;
- newsocks[a].val1 = s_val[0];
- newsocks[a].val2 = s_val[1];
- newsocks[a].val3 = s_val[2];
- newsocks[a].val4 = s_val[3];
- newsocks[a].limit = limit;
-
- Py_DECREF(arg);
+ nsocks[a].val1 = vec[0];
+ nsocks[a].val2 = vec[1];
+ nsocks[a].val3 = vec[2];
+
+ if (stype == SOCK_RGBA)
+ nsocks[a].val4 = vec[3];
+ }
+ else /* SOCK_VALUE */
+ nsocks[a].val1 = pysock->val[0];
}
- newsocks[a].type = -1;
+ nsocks[a].type = -1;
- *socks = newsocks;
+ *socks = nsocks;
return retval;
}
-/* Get number of complying entries in a list.
- *
- */
-/* unused
-static int num_list_sockets(PyObject *list) {
- int size = 0;
- int i = 0, count = 0;
- PyObject *element = NULL;
-
- size = PyList_Size(list);
- for(i = 0; i < size; i++) {
- element = PyList_GetItem(list, i);
- //wPy_INCREF(element);
- if(PyList_Check(element) && PyList_Size(element) == 8)
- count++;
- //wPy_DECREF(element);
- }
- return count;
-}
-*/
-static void NodeSockets_dealloc(BPy_NodeSockets *self)
+static void NodeSocketLists_dealloc(BPy_NodeSocketLists *self)
{
Py_DECREF(self->input);
Py_DECREF(self->output);
self->ob_type->tp_free((PyObject *)self);
}
-static PyObject *Map_socketdef_getter(BPy_NodeSockets *self, void *closure)
+static PyObject *Map_socketdef_getter(BPy_NodeSocketLists *self, void *closure)
{
PyObject *sockets = NULL;
@@ -167,7 +436,7 @@ static PyObject *Map_socketdef_getter(BPy_NodeSockets *self, void *closure)
return sockets;
}
-static int Map_socketdef(BPy_NodeSockets *self, PyObject *args, void *closure)
+static int Map_socketdef(BPy_NodeSocketLists *self, PyObject *args, void *closure)
{
bNode *node = NULL;
PyObject *tuple = NULL;
@@ -187,7 +456,8 @@ static int Map_socketdef(BPy_NodeSockets *self, PyObject *args, void *closure)
if (args) {
if(PySequence_Check(args)) {
tuple = PySequence_Tuple(args);
- list_socks_to_typeinfo(tuple, &(node->typeinfo->inputs), node->custom1, 1);
+ pysockets_to_blendersockets(tuple,
+ &(node->typeinfo->inputs), node->custom1, 1);
Py_DECREF(self->input);
self->input = tuple;
} else {
@@ -199,7 +469,8 @@ static int Map_socketdef(BPy_NodeSockets *self, PyObject *args, void *closure)
if (args) {
if(PyList_Check(args)) {
tuple = PySequence_Tuple(args);
- list_socks_to_typeinfo(tuple, &(node->typeinfo->outputs), node->custom1, 0);
+ pysockets_to_blendersockets(tuple,
+ &(node->typeinfo->outputs), node->custom1, 0);
Py_DECREF(self->output);
self->output = tuple;
} else {
@@ -214,7 +485,7 @@ static int Map_socketdef(BPy_NodeSockets *self, PyObject *args, void *closure)
return 0;
}
-static PyGetSetDef NodeSockets_getseters[] = {
+static PyGetSetDef NodeSocketLists_getseters[] = {
{"input", (getter)Map_socketdef_getter, (setter)Map_socketdef,
"Set this node's input sockets (list of lists or tuples)",
(void *)'I'},
@@ -230,17 +501,17 @@ static PyGetSetDef NodeSockets_getseters[] = {
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
-PyTypeObject NodeSockets_Type = {
+PyTypeObject NodeSocketLists_Type = {
PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /* ob_size */
/* For printing, in format "<module>.<name>" */
- "Blender.Node.Sockets", /* char *tp_name; */
- sizeof( BPy_NodeSockets ), /* int tp_basicsize; */
+ "Blender.Node.SocketLists", /* char *tp_name; */
+ sizeof( BPy_NodeSocketLists ), /* int tp_basicsize; */
0, /* tp_itemsize; For allocation */
/* Methods to implement standard operations */
- (destructor)NodeSockets_dealloc,/* destructor tp_dealloc; */
+ (destructor)NodeSocketLists_dealloc,/* destructor tp_dealloc; */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
@@ -290,7 +561,7 @@ PyTypeObject NodeSockets_Type = {
/*** Attribute descriptor and subclassing stuff ***/
0, //BPy_MVertSeq_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
- NodeSockets_getseters, /* struct PyGetSetDef *tp_getset; */
+ NodeSocketLists_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
@@ -312,17 +583,17 @@ PyTypeObject NodeSockets_Type = {
NULL
};
-BPy_NodeSockets *Node_CreateSockets(bNode *node) {
- BPy_NodeSockets *sockets = PyObject_NEW(BPy_NodeSockets, &NodeSockets_Type);
- sockets->node = node;
- sockets->input = PyList_New(0);
- sockets->output = PyList_New(0);
- return sockets;
+BPy_NodeSocketLists *Node_CreateSocketLists(bNode *node) {
+ BPy_NodeSocketLists *socklists = PyObject_NEW(BPy_NodeSocketLists, &NodeSocketLists_Type);
+ socklists->node = node;
+ socklists->input = PyList_New(0);
+ socklists->output = PyList_New(0);
+ return socklists;
}
/***************************************/
-static int sockinmap_len ( BPy_SockMap * self) {
+static int Sockinmap_len ( BPy_SockMap * self) {
bNode *node = self->node;
bNodeType *tinfo;
int a = 0;
@@ -340,16 +611,14 @@ static int sockinmap_len ( BPy_SockMap * self) {
return a;
}
-static int sockinmap_has_key( BPy_SockMap *self, PyObject *key) {
+static int sockinmap_has_key( BPy_SockMap *self, char *strkey) {
bNode *node = self->node;
bNodeType *tinfo;
- char *strkey = NULL;
int a = 0;
- if (!node) return -1;
+ if (!node || !strkey) return -1;
tinfo = node->typeinfo;
- strkey = PyString_AsString(key);
if(tinfo && tinfo->inputs){
while(self->node->typeinfo->inputs[a].type!=-1) {
@@ -362,17 +631,17 @@ static int sockinmap_has_key( BPy_SockMap *self, PyObject *key) {
return -1;
}
-PyObject *sockinmap_subscript(BPy_SockMap *self, PyObject *pyidx) {
+PyObject *Sockinmap_subscript(BPy_SockMap *self, PyObject *pyidx) {
int idx;
if (!self->node)
return EXPP_ReturnPyObjError(PyExc_RuntimeError, "no access to Blender node data!");
if (PyString_Check(pyidx)) {
- idx = sockinmap_has_key(self, pyidx);
+ idx = sockinmap_has_key(self, PyString_AsString(pyidx));
}
else if(PyInt_Check(pyidx)) {
- int len = sockinmap_len(self);
+ int len = Sockinmap_len(self);
idx = (int)PyInt_AsLong(pyidx);
if (idx < 0 || idx >= len)
return EXPP_ReturnPyObjError(PyExc_IndexError, "index out of range");
@@ -405,10 +674,37 @@ PyObject *sockinmap_subscript(BPy_SockMap *self, PyObject *pyidx) {
Py_RETURN_NONE;
}
+static PyObject *Sockinmap_getAttr(BPy_SockMap *self, char *attr)
+{
+ PyObject *pyob = NULL;
+ int idx;
+
+ idx = sockinmap_has_key(self, attr);
+
+ if (idx < 0)
+ return EXPP_ReturnPyObjError(PyExc_AttributeError, "unknown input socket name");
+
+ switch(self->node->typeinfo->inputs[idx].type) {
+ case SOCK_VALUE:
+ pyob = Py_BuildValue("f", self->stack[idx]->vec[0]);
+ break;
+ case SOCK_VECTOR:
+ pyob = Py_BuildValue("(fff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2]);
+ break;
+ case SOCK_RGBA:
+ pyob = Py_BuildValue("(ffff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2], self->stack[idx]->vec[3]);
+ break;
+ default:
+ break;
+ }
+
+ return pyob;
+}
+
/* read only */
-static PyMappingMethods sockinmap_as_mapping = {
- ( inquiry ) sockinmap_len, /* mp_length */
- ( binaryfunc ) sockinmap_subscript, /* mp_subscript */
+static PyMappingMethods Sockinmap_as_mapping = {
+ ( inquiry ) Sockinmap_len, /* mp_length */
+ ( binaryfunc ) Sockinmap_subscript, /* mp_subscript */
( objobjargproc ) 0 /* mp_ass_subscript */
};
@@ -424,7 +720,7 @@ PyTypeObject SockInMap_Type = {
NULL,/* destructor tp_dealloc; */
NULL, /* printfunc tp_print; */
- NULL, /* getattrfunc tp_getattr; */
+ (getattrfunc) Sockinmap_getAttr,/* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
NULL, /* cmpfunc tp_compare; */
NULL, /* reprfunc tp_repr; */
@@ -433,7 +729,7 @@ PyTypeObject SockInMap_Type = {
NULL, /* PyNumberMethods *tp_as_number; */
NULL, /* PySequenceMethods *tp_as_sequence; */
- &sockinmap_as_mapping, /* PyMappingMethods *tp_as_mapping; */
+ &Sockinmap_as_mapping, /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
@@ -494,7 +790,7 @@ PyTypeObject SockInMap_Type = {
NULL
};
-static int sockoutmap_len ( BPy_SockMap * self) {
+static int Sockoutmap_len ( BPy_SockMap * self) {
bNode *node = self->node;
bNodeType *tinfo;
int a = 0;
@@ -510,16 +806,14 @@ static int sockoutmap_len ( BPy_SockMap * self) {
return a;
}
-static int sockoutmap_has_key( BPy_SockMap *self, PyObject *key) {
+static int sockoutmap_has_key(BPy_SockMap *self, char *strkey) {
bNode *node = self->node;
bNodeType *tinfo;
int a = 0;
- char *strkey = NULL;
if (!node) return -1;
tinfo = node->typeinfo;
- strkey = PyString_AsString(key);
if(tinfo && tinfo->outputs){
while(self->node->typeinfo->outputs[a].type!=-1) {
@@ -532,8 +826,8 @@ static int sockoutmap_has_key( BPy_SockMap *self, PyObject *key) {
return -1;
}
-static int sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObject *value) {
- int i, idx, len, wanted_len = 0, ret = -1;
+static int Sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObject *value) {
+ int i, idx, len, type, wanted_len = 0;
PyObject *val;
PyObject *items[4];
@@ -542,11 +836,11 @@ static int sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObj
if (PyInt_Check(pyidx)) {
idx = (int)PyInt_AsLong(pyidx);
- if (idx < 0 || idx >= sockinmap_len(self))
+ if (idx < 0 || idx >= Sockinmap_len(self))
return EXPP_ReturnIntError(PyExc_IndexError, "index out of range");
}
else if (PyString_Check(pyidx)) {
- idx = sockoutmap_has_key(self, pyidx);
+ idx = sockoutmap_has_key(self, PyString_AsString(pyidx));
}
else if (PySlice_Check(pyidx)) {
return EXPP_ReturnIntError(PyExc_ValueError, "slices not yet implemented");
@@ -557,70 +851,129 @@ static int sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObj
if (idx < 0)
return EXPP_ReturnIntError(PyExc_IndexError, "index must be a positive int or a string");
- val = PySequence_Fast(value, "expected a numeric tuple or list");
- if (!val) return -1;
+ type = self->node->typeinfo->outputs[idx].type;
- len = PySequence_Fast_GET_SIZE(val);
-
- if (len == 0) {
+ if (type == SOCK_VALUE) {
+ val = PyNumber_Float(value);
+ if (!val)
+ return EXPP_ReturnIntError(PyExc_AttributeError, "expected a float value");
+ self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(val);
Py_DECREF(val);
- return EXPP_ReturnIntError(PyExc_AttributeError, "expected a non-empty numeric tuple or list");
}
+ else {
+ val = PySequence_Fast(value, "expected a numeric tuple or list");
+ if (!val) return -1;
+
+ len = PySequence_Fast_GET_SIZE(val);
- for (i = 0; i < len; i++) {
- items[i] = PySequence_Fast_GET_ITEM(val, i); /* borrowed */
- if (!PyNumber_Check(items[i])) {
+ if (type == SOCK_VECTOR) {
+ wanted_len = 3;
+ } else { /* SOCK_RGBA */
+ wanted_len = 4;
+ }
+
+ if (len != wanted_len) {
Py_DECREF(val);
- return EXPP_ReturnIntError(PyExc_AttributeError, "expected a *numeric* tuple or list");
+ PyErr_SetString(PyExc_AttributeError, "wrong number of items in list or tuple");
+ fprintf(stderr, "\nExpected %d numeric values, got %d.", wanted_len, len);
+ return -1;
}
- }
- switch(self->node->typeinfo->outputs[idx].type) {
- case SOCK_VALUE:
- wanted_len = 1;
- if (len == 1) {
- self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
- ret = 0;
+ for (i = 0; i < len; i++) {
+ items[i] = PySequence_Fast_GET_ITEM(val, i); /* borrowed */
+ if (!PyNumber_Check(items[i])) {
+ Py_DECREF(val);
+ return EXPP_ReturnIntError(PyExc_AttributeError, "expected a *numeric* tuple or list");
}
- break;
- case SOCK_VECTOR:
+ }
+
+ self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
+ self->stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
+ self->stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
+
+ if (type == SOCK_RGBA)
+ self->stack[idx]->vec[3] = (float)PyFloat_AsDouble(items[3]);
+
+ Py_DECREF(val);
+ }
+
+ return 0;
+}
+
+static int sockoutmap_set_attr(bNodeStack **stack, short type, short idx, PyObject *value)
+{
+ PyObject *val;
+ PyObject *items[4];
+ int i;
+ short len, wanted_len;
+
+ if (type == SOCK_VALUE) {
+ val = PyNumber_Float(value);
+ if (!val)
+ return EXPP_ReturnIntError(PyExc_AttributeError, "expected a float value");
+ stack[idx]->vec[0] = (float)PyFloat_AsDouble(val);
+ Py_DECREF(val);
+ }
+ else {
+ val = PySequence_Fast(value, "expected a numeric tuple or list");
+ if (!val) return -1;
+
+ len = PySequence_Fast_GET_SIZE(val);
+
+ if (type == SOCK_VECTOR) {
wanted_len = 3;
- if (len == 3) {
- self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
- self->stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
- self->stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
- ret = 0;
- }
- break;
- case SOCK_RGBA:
+ } else { /* SOCK_RGBA */
wanted_len = 4;
- if (len == 4) {
- self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
- self->stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
- self->stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
- self->stack[idx]->vec[3] = (float)PyFloat_AsDouble(items[3]);
- ret = 0;
+ }
+
+ if (len != wanted_len) {
+ Py_DECREF(val);
+ PyErr_SetString(PyExc_AttributeError, "wrong number of items in list or tuple");
+ fprintf(stderr, "\nExpected %d numeric values, got %d.", wanted_len, len);
+ return -1;
+ }
+
+ for (i = 0; i < len; i++) {
+ items[i] = PySequence_Fast_GET_ITEM(val, i); /* borrowed */
+ if (!PyNumber_Check(items[i])) {
+ Py_DECREF(val);
+ return EXPP_ReturnIntError(PyExc_AttributeError, "expected a *numeric* tuple or list");
}
- break;
- default:
- break;
- }
+ }
+
+ stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
+ stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
+ stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
- Py_DECREF(val);
+ if (type == SOCK_RGBA)
+ stack[idx]->vec[3] = (float)PyFloat_AsDouble(items[3]);
- if (ret == -1) {
- PyErr_SetString(PyExc_AttributeError, "wrong number of items in list or tuple");
- fprintf(stderr, "\nExpected %d numeric values, got %d.", wanted_len, len);
+ Py_DECREF(val);
}
- return ret;
+ return 0;
}
+static int Sockoutmap_setAttr(BPy_SockMap *self, char *name, PyObject *value) {
+ short idx, type;
+
+ if (!self->node)
+ return EXPP_ReturnIntError(PyExc_RuntimeError, "no access to Blender node data!");
+
+ idx = sockoutmap_has_key(self, name);
+
+ if (idx < 0)
+ return EXPP_ReturnIntError(PyExc_AttributeError, "unknown output socket name");
+
+ type = self->node->typeinfo->outputs[idx].type;
+
+ return sockoutmap_set_attr(self->stack, type, idx, value);
+}
/* write only */
-static PyMappingMethods sockoutmap_as_mapping = {
- ( inquiry ) sockoutmap_len, /* mp_length */
+static PyMappingMethods Sockoutmap_as_mapping = {
+ ( inquiry ) Sockoutmap_len, /* mp_length */
( binaryfunc ) 0, /* mp_subscript */
- ( objobjargproc ) sockoutmap_assign_subscript /* mp_ass_subscript */
+ ( objobjargproc ) Sockoutmap_assign_subscript /* mp_ass_subscript */
};
PyTypeObject SockOutMap_Type = {
@@ -636,7 +989,7 @@ PyTypeObject SockOutMap_Type = {
NULL,/* destructor tp_dealloc; */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
+ (setattrfunc) Sockoutmap_setAttr,/* setattrfunc tp_setattr; */
NULL, /* cmpfunc tp_compare; */
NULL, /* reprfunc tp_repr; */
@@ -644,7 +997,7 @@ PyTypeObject SockOutMap_Type = {
NULL, /* PyNumberMethods *tp_as_number; */
NULL, /* PySequenceMethods *tp_as_sequence; */
- &sockoutmap_as_mapping, /* PyMappingMethods *tp_as_mapping; */
+ &Sockoutmap_as_mapping, /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
@@ -850,7 +1203,6 @@ static PyObject *Node_GetShi(BPy_Node *self) {
static PyObject *node_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *self;
- assert(type!=NULL && type->tp_alloc!=NULL);
self = type->tp_alloc(type, 1);
return self;
}
@@ -1161,7 +1513,9 @@ PyObject *Node_Init(void)
return NULL;
if( PyType_Ready( &ShadeInput_Type ) < 0 )
return NULL;
- if( PyType_Ready( &NodeSockets_Type ) < 0 )
+ if( PyType_Ready( &NodeSocket_Type ) < 0 )
+ return NULL;
+ if( PyType_Ready( &NodeSocketLists_Type ) < 0 )
return NULL;
if( PyType_Ready( &SockInMap_Type ) < 0 )
return NULL;
@@ -1173,11 +1527,13 @@ PyObject *Node_Init(void)
PyModule_AddIntConstant(submodule, "RGBA", SOCK_RGBA);
PyModule_AddIntConstant(submodule, "VECTOR", SOCK_VECTOR);
+ Py_INCREF(&NodeSocket_Type);
+ PyModule_AddObject(submodule, "Socket", (PyObject *)&NodeSocket_Type);
+
Py_INCREF(&Node_Type);
- PyModule_AddObject(submodule, "node", (PyObject *)&Node_Type);
+ PyModule_AddObject(submodule, "Scripted", (PyObject *)&Node_Type);
return submodule;
-
}
static int Node_compare(BPy_Node *a, BPy_Node *b)
@@ -1189,7 +1545,7 @@ static int Node_compare(BPy_Node *a, BPy_Node *b)
static PyObject *Node_repr(BPy_Node *self)
{
return PyString_FromFormat( "[Node \"%s\"]",
- self->node ? self->node->id->name+2 : "empty node");
+ self->node ? self->node->id->name+2 : "empty node");
}
BPy_Node *Node_CreatePyObject(bNode *node)
diff --git a/source/blender/python/api2_2x/Node.h b/source/blender/python/api2_2x/Node.h
index e229e678fe9..49626599887 100644
--- a/source/blender/python/api2_2x/Node.h
+++ b/source/blender/python/api2_2x/Node.h
@@ -40,11 +40,19 @@
#include "RE_shader_ext.h" /* <- ShadeInput Shaderesult TexResult */
extern PyTypeObject Node_Type;
+extern PyTypeObject NodeSocket_Type;
+extern PyTypeObject NodeSocketLists_Type;
extern PyTypeObject ShadeInput_Type;
#define BPy_Node_Check(v) \
((v)->ob_type == &Node_Type)
+#define BPy_NodeSocket_Check(v) \
+ ((v)->ob_type == &NodeSocket_Type)
+
+#define BPy_NodeSocketLists_Check(v) \
+ ((v)->ob_type == &NodeSocketLists_Type)
+
#define BPy_ShadeInput_Check(v) \
((v)->ob_type == &ShadeInput_Type)
@@ -64,7 +72,7 @@ typedef struct {
bNode *node;
PyObject *input;
PyObject *output;
-} BPy_NodeSockets;
+} BPy_NodeSocketLists;
typedef struct BPy_Node {
PyObject_HEAD
@@ -74,10 +82,19 @@ typedef struct BPy_Node {
ShadeInput *shi;
} BPy_Node;
+typedef struct BPy_NodeSocket {
+ PyObject_HEAD
+ char name[NODE_MAXSTR];
+ float min;
+ float max;
+ float val[4];
+ short type; /* VALUE, VECTOR or RGBA */
+} BPy_NodeSocket;
+
extern PyObject *Node_Init(void);
extern void InitNode(BPy_Node *self, bNode *node);
extern BPy_Node *Node_CreatePyObject(bNode *node);
-extern BPy_NodeSockets *Node_CreateSockets(bNode *node);
+extern BPy_NodeSocketLists *Node_CreateSocketLists(bNode *node);
extern void Node_SetStack(BPy_Node *self, bNodeStack **stack, int type);
extern void Node_SetShi(BPy_Node *self, ShadeInput *shi);
extern int pytype_is_pynode(PyObject *pyob);
diff --git a/source/blender/python/api2_2x/SurfNurb.c b/source/blender/python/api2_2x/SurfNurb.c
index 3499ec09936..f1c038fc33c 100644
--- a/source/blender/python/api2_2x/SurfNurb.c
+++ b/source/blender/python/api2_2x/SurfNurb.c
@@ -46,6 +46,8 @@ static int SurfNurb_setPoint( BPy_SurfNurb * self, int index, PyObject * ob );
static int SurfNurb_length( PyInstanceObject * inst );
static PyObject *SurfNurb_getIter( BPy_SurfNurb * self );
static PyObject *SurfNurb_iterNext( BPy_SurfNurb * self );
+static PyObject *SurfNurb_getKnotsU( BPy_SurfNurb * self );
+static PyObject *SurfNurb_getKnotsV( BPy_SurfNurb * self );
PyObject *SurfNurb_append( BPy_SurfNurb * self, PyObject * args );
char M_SurfNurb_doc[] = "SurfNurb";
@@ -487,6 +489,58 @@ static int SurfNurb_setCyclicV( BPy_SurfNurb * self, PyObject * value )
return 0;
}
+/*
+ * SurfNurb_getKnotsU
+ *
+ * Returns surface's knotsU in a tuple. Empty tuple is returned if
+ * surface isn't Nurbs or it doesn't have knots in U
+ */
+
+static PyObject *SurfNurb_getKnotsU( BPy_SurfNurb * self )
+{
+ if(self->nurb->knotsu) {
+ int len = KNOTSU(self->nurb);
+ int i;
+ PyObject *knotsu = PyTuple_New(len);
+ if( !knotsu )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "could not get SurfNurb.knotsU attribute" );
+
+ for(i = 0; i < len; ++i)
+ PyTuple_SetItem(knotsu, i,
+ PyFloat_FromDouble(self->nurb->knotsu[i]));
+
+ return knotsu;
+ }
+ return PyTuple_New(0);
+}
+
+/*
+ * SurfNurb_getKnotsV
+ *
+ * Returns surface's knotsV in a tuple. Empty tuple is returned if
+ * curve doesn't have knots in V
+ */
+
+static PyObject *SurfNurb_getKnotsV( BPy_SurfNurb * self )
+{
+ if(self->nurb->knotsv) {
+ int len = KNOTSV(self->nurb);
+ int i;
+ PyObject *knotsv = PyTuple_New(len);
+ if( !knotsv )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "could not get SurfNurb.knotsV index" );
+
+ for(i = 0; i < len; ++i)
+ PyTuple_SetItem(knotsv, i,
+ PyFloat_FromDouble(self->nurb->knotsv[i] ));
+
+ return knotsv;
+ }
+ return PyTuple_New(0);
+}
+
/*
* SurfNurb_getIter
@@ -723,6 +777,15 @@ static PyGetSetDef BPy_SurfNurb_getseters[] = {
{"orderV",
(getter)SurfNurb_getOrderV, (setter)SurfNurb_setOrderV,
"order setting for V direction", NULL},
+ {"knotsU",
+ (getter)SurfNurb_getKnotsU, (setter)NULL,
+ "The The knot vector in the U direction",
+ NULL},
+ {"knotsV",
+ (getter)SurfNurb_getKnotsV, (setter)NULL,
+ "The The knot vector in the V direction",
+ NULL},
+
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
diff --git a/source/blender/python/api2_2x/Window.c b/source/blender/python/api2_2x/Window.c
index 5cfe796add8..b4a14cc6ac8 100644
--- a/source/blender/python/api2_2x/Window.c
+++ b/source/blender/python/api2_2x/Window.c
@@ -47,6 +47,7 @@
#include "BIF_space.h"
#include "BIF_drawtext.h"
#include "BIF_poseobject.h"
+#include "BIF_toolbox.h" /* for error() */
#include "DNA_view3d_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
@@ -513,6 +514,14 @@ static void getSelectedFile( char *name )
script = sc->script;
}
}
+ /* If 'script' is null,
+ * The script must have had an error and closed,
+ * but the fileselector was left open, show an error and exit */
+ if (!script) {
+ error("Python script error: script quit, cannot run callback");
+ return;
+ }
+
pycallback = script->py_browsercallback;
@@ -526,10 +535,17 @@ static void getSelectedFile( char *name )
fprintf(stderr, "BPy error: Callback call failed!\n");
}
else Py_DECREF(result);
-
+
+
+
if (script->py_browsercallback == pycallback) {
- SCRIPT_SET_NULL(script);
+ if (script->flags & SCRIPT_GUI) {
+ script->py_browsercallback = NULL;
+ } else {
+ SCRIPT_SET_NULL(script);
+ }
}
+
/* else another call to selector was made inside pycallback */
Py_DECREF(pycallback);
diff --git a/source/blender/python/api2_2x/doc/Constraint.py b/source/blender/python/api2_2x/doc/Constraint.py
index 61ee3c36700..0f9e4b5e07a 100644
--- a/source/blender/python/api2_2x/doc/Constraint.py
+++ b/source/blender/python/api2_2x/doc/Constraint.py
@@ -31,17 +31,21 @@ Or to print all the constraints attached to each bone in a pose::
@var Type: Constant Constraint dict used by L{Constraints.append()} and
for comparison with L{Constraint.type}. Values are
TRACKTO, IKSOLVER, FOLLOWPATH, COPYROT, COPYLOC, COPYSIZE, ACTION,
- LOCKTRACK, STRETCHTO, FLOOR, LIMITLOC, LIMITROT, LIMITSIZE, CLAMPTO,
- PYTHON, CHILDOF, TRANSFORM, NULL
+ LOCKTRACK, STRETCHTO, FLOOR, LIMITLOC, LIMITROT, LIMITSIZE, LIMITDIST,
+ CLAMPTO, PYTHON, CHILDOF, TRANSFORM, NULL
@type Settings: readonly dictionary
@var Settings: Constant dict used for changing constraint settings.
- - Used for all constraints
- - TARGET (Object) (Note: not used by Limit Location (LIMITLOC),
- Limit Rotation (LIMITROT), Limit Scale (LIMITSIZE))
- - BONE (string): name of Bone sub-target (for armature targets) (Note: not
- used by Stretch To (STRETCHTO), Limit Location (LIMITLOC), Limit Rotation
- (LIMITROT), Limit Scale (LIMITSIZE), Follow Path (FOLLOWPATH), Clamp To (CLAMPTO))
+ - Used for all single-target constraints
+ (TRACKTO, FOLLOWPATH, COPYROT, COPYLOC, COPYSIZE, ACTION, LOCKTRACK, STRETCHTO, FLOOR, CLAMPTO, CHILDOF, TRANSFORM, LIMITDIST)
+ - TARGET (Object): target object
+ - BONE (string): name of Bone sub-target (for Armature targets), or name of Vertex Group sub-target
+ (for Geometry targets)
+ - Used for all multiple-target constraints
+ (PYTHON)
+ - TARGET (list of Objects): list of target objects, with one list slot = one target slot
+ - BONE (list of strings): list of names of Bone sub-target (for Armature targets) or name of Vertex Group
+ sub-targets (for Geometry targets)
- Used by some constraints:
- OWNERSPACE (int): for TRACKTO, COPYLOC, COPYROT, COPYSIZE, LIMITLOC, LIMITROT, LIMITSIZE, PYTHON, TRANSFORM
If the owner is an object, values are SPACE_WORLD, SPACE_LOCAL
@@ -123,6 +127,8 @@ Or to print all the constraints attached to each bone in a pose::
- YMAX (float): clamped to [0.0001,1000.0]
- ZMIN (float): clamped to [0.0001,1000.0]
- ZMAX (float): clamped to [0.0001,1000.0]
+ - Used by Limit Distance (LIMITDIST) constraint:
+ - LIMITMODE (int): any one of LIMIT_INSIDE, LIMIT_OUTSIDE, LIMIT_ONSURFACE
- Used by Python Script (PYTHON) constraint:
- SCRIPT (Text): script to use
- PROPERTIES (IDProperties): ID-Properties of constraint
diff --git a/source/blender/python/api2_2x/doc/Curve.py b/source/blender/python/api2_2x/doc/Curve.py
index c3760bc2c1d..ba8d6d21970 100644
--- a/source/blender/python/api2_2x/doc/Curve.py
+++ b/source/blender/python/api2_2x/doc/Curve.py
@@ -694,6 +694,10 @@ class SurfNurb:
@ivar orderV: The order setting for the V direction. Values are clamped
to the range [2:6] and not greater than the V dimension.
@type orderV: int
+ @ivar knotsU: The The knot vector in the U direction
+ @type knotsU: tuple
+ @ivar knotsV: The The knot vector in the V direction
+ @type knotsV: tuple
"""
def __setitem__( n, point ):
diff --git a/source/blender/python/api2_2x/doc/IpoCurve.py b/source/blender/python/api2_2x/doc/IpoCurve.py
index 873888cffb4..54d9136ec1e 100644
--- a/source/blender/python/api2_2x/doc/IpoCurve.py
+++ b/source/blender/python/api2_2x/doc/IpoCurve.py
@@ -11,6 +11,8 @@ This module provides access to the IpoCurve data in Blender. An Ipo is
composed of several IpoCurves, and an IpoCurve are composed of several
BezTriples.
+@warning: Ipo curves store euler rotations as degrees/10.0 so 180.0 would be 18.0
+
Example::
import Blender
ipo = Blender.Ipo.Get('ObIpo') # retrieves an Ipo object
diff --git a/source/blender/python/api2_2x/doc/Mesh.py b/source/blender/python/api2_2x/doc/Mesh.py
index 0690b94712b..8b49ce29d54 100644
--- a/source/blender/python/api2_2x/doc/Mesh.py
+++ b/source/blender/python/api2_2x/doc/Mesh.py
@@ -844,6 +844,44 @@ class Mesh:
@note: Only returns a valid result for mesh data that has no holes.
@note: Bubbles in the mesh work as expect.
"""
+ def getTangents():
+ """
+ Calculates tangents for this mesh, returning a list of tuples,
+ each with 3 or 4 tangent vectors, these are alligned with the meshes faces.
+
+ Example::
+ # Display the tangents as edges over a the active mesh object
+ from Blender import *
+ sce = Scene.GetCurrent()
+ ob = sce.objects.active
+
+ me = ob.getData(mesh=1)
+ ts = me.getTangents()
+ me_disp = Mesh.New()
+
+ verts = []
+ edges = []
+ for i, f in enumerate(me.faces):
+ ft = ts[i]
+ for j, v in enumerate(f):
+ tan = ft[j]
+ print tan
+ co = v.co
+
+ verts.append(co)
+ verts.append(co+tan)
+
+ i = len(verts)
+ edges.append((i-1, i-2))
+
+ me_disp.verts.extend( verts )
+ me_disp.edges.extend( edges )
+
+ sce.objects.new( me_disp )
+
+ @note: The tangents are computed using the active UV layer, if there are no UV layers, orco coords are used.
+ """
+
def transform(matrix, recalc_normals = False, selected_only=False):
"""
diff --git a/source/blender/python/api2_2x/doc/Render.py b/source/blender/python/api2_2x/doc/Render.py
index 42fd5b564fe..97c7c0ecc44 100644
--- a/source/blender/python/api2_2x/doc/Render.py
+++ b/source/blender/python/api2_2x/doc/Render.py
@@ -440,6 +440,7 @@ class RenderData:
@type filename: string
@since: 2.40
@requires: You must have an image currently rendered before calling this method
+ @warning: This wont work in background mode. use renderAnim instead.
"""
def play():
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index 4bf823bc938..d0440e11b52 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -534,7 +534,11 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
if( !PyArg_ParseTuple( args, "s|i", &name_str, &zbuff ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a filename (string) and optional int" );
-
+
+ if (G.background)
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "saveRenderedImage does not work in background mode, use renderAnim() instead" );
+
if( strlen(self->renderContext->pic) + strlen(name_str)
>= sizeof(filepath) )
return EXPP_ReturnPyObjError( PyExc_ValueError,
diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c
index aca5a0885f4..88c5e2197f9 100644
--- a/source/blender/radiosity/intern/source/radrender.c
+++ b/source/blender/radiosity/intern/source/radrender.c
@@ -121,6 +121,7 @@ static void findshoot_rr(Render *re, VlakRen **shoot_p, RadFace **shootrf_p)
if(maxenergy<RG.convergence) {
*shoot_p= NULL;
*shootrf_p= NULL;
+ return;
}
shootrf->flag |= RAD_SHOOT;
}
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 2aa6cc10468..22fb2e70d87 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -497,6 +497,7 @@ typedef struct LampRen {
#define R_GLOB_NOPUNOFLIP 16
#define R_NEED_TANGENT 32
#define R_SKIP_MULTIRES 64
+#define R_BAKE_TRACE 128
/* vlakren->flag (vlak = face in dutch) char!!! */
#define R_SMOOTH 1
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index cf1eeae58ec..cdc348279e5 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -40,8 +40,8 @@
/* vector defines */
-#define CROSS(dest, a, b) dest[0]= a[1] * b[2] - a[2] * b[1]; dest[1]= a[2] * b[0] - a[0] * b[2]; dest[2]= a[0] * b[1] - a[1] * b[0]
-#define VECMUL(dest, f) dest[0]*= f; dest[1]*= f; dest[2]*= f
+#define CROSS(dest, a, b) { dest[0]= a[1] * b[2] - a[2] * b[1]; dest[1]= a[2] * b[0] - a[0] * b[2]; dest[2]= a[0] * b[1] - a[1] * b[0]; }
+#define VECMUL(dest, f) { dest[0]*= f; dest[1]*= f; dest[2]*= f; }
struct HaloRen;
struct ShadeInput;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 933125202be..42191ff35ad 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -451,77 +451,6 @@ static void calc_edge_stress(Render *re, ObjectRen *obr, Mesh *me)
MEM_freeN(accum);
}
-void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, float *co3, float *n, float *tang)
-{
- float tangv[3], ct[3], e1[3], e2[3], s1, t1, s2, t2, det;
-
- s1= uv2[0] - uv1[0];
- s2= uv3[0] - uv1[0];
- t1= uv2[1] - uv1[1];
- t2= uv3[1] - uv1[1];
- det= 1.0f / (s1 * t2 - s2 * t1);
-
- /* normals in render are inversed... */
- VecSubf(e1, co1, co2);
- VecSubf(e2, co1, co3);
- tang[0] = (t2*e1[0] - t1*e2[0])*det;
- tang[1] = (t2*e1[1] - t1*e2[1])*det;
- tang[2] = (t2*e1[2] - t1*e2[2])*det;
- tangv[0] = (s1*e2[0] - s2*e1[0])*det;
- tangv[1] = (s1*e2[1] - s2*e1[1])*det;
- tangv[2] = (s1*e2[2] - s2*e1[2])*det;
- Crossf(ct, tang, tangv);
-
- /* check flip */
- if ((ct[0]*n[0] + ct[1]*n[1] + ct[2]*n[2]) < 0.0f)
- VecMulf(tang, -1.0f);
-}
-
-/* For normal map tangents we need to detect uv boundaries, and only average
- * tangents in case the uvs are connected. Alternative would be to store 1
- * tangent per face rather than 4 per face vertex, but that's not compatible
- * with games */
-
-typedef struct VertexTangent {
- float tang[3], uv[2];
- struct VertexTangent *next;
-} VertexTangent;
-
-static void sum_or_add_vertex_tangent(MemArena *arena, VertexTangent **vtang, float *tang, float *uv)
-{
- VertexTangent *vt;
-
- /* find a tangent with connected uvs */
- for(vt= *vtang; vt; vt=vt->next) {
- if(fabs(uv[0]-vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabs(uv[1]-vt->uv[1]) < STD_UV_CONNECT_LIMIT) {
- VECADD(vt->tang, vt->tang, tang);
- return;
- }
- }
-
- /* if not found, append a new one */
- vt= BLI_memarena_alloc(arena, sizeof(VertexTangent));
- VECCOPY(vt->tang, tang);
- vt->uv[0]= uv[0];
- vt->uv[1]= uv[1];
-
- if(*vtang)
- vt->next= *vtang;
- *vtang= vt;
-}
-
-static float *find_vertex_tangent(VertexTangent *vtang, float *uv)
-{
- VertexTangent *vt;
- static float nulltang[3] = {0.0f, 0.0f, 0.0f};
-
- for(vt= vtang; vt; vt=vt->next)
- if(fabs(uv[0]-vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabs(uv[1]-vt->uv[1]) < STD_UV_CONNECT_LIMIT)
- return vt->tang;
-
- return nulltang; /* shouldn't happen, except for nan or so */
-}
-
/* gets tangent from tface or orco */
static void calc_tangent_vector(ObjectRen *obr, VertexTangent **vtangents, MemArena *arena, VlakRen *vlr, int do_nmap_tangent, int do_tangent)
{
@@ -5318,7 +5247,6 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
ListBase oldtable= {NULL, NULL}, newtable= {NULL, NULL};
ListBase strandsurface;
int step;
- ModifierData *md = NULL;
re->i.infostr= "Calculating previous vectors";
re->r.mode |= R_SPEED;
@@ -5453,6 +5381,8 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
re->excludeob= actob;
if(type == RE_BAKE_LIGHT)
re->flag |= R_SKIP_MULTIRES;
+ if(actob)
+ re->flag |= R_BAKE_TRACE;
if(type==RE_BAKE_NORMALS && re->r.bake_normal_space==R_BAKE_SPACE_TANGENT)
re->flag |= R_NEED_TANGENT;
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index d0f9be3fd79..d423abefe96 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -82,6 +82,11 @@ static int vlr_check_intersect(Isect *is, int ob, RayFace *face)
ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)is->userdata, ob);
VlakRen *vlr = (VlakRen*)face;
+ /* for baking selected to active non-traceable materials might still
+ * be in the raytree */
+ if(!(vlr->mat->mode & MA_TRACEBLE))
+ return 0;
+
/* I know... cpu cycle waste, might do smarter once */
if(is->mode==RE_RAY_MIRROR)
return !(vlr->mat->mode & MA_ONLYCAST);
@@ -125,7 +130,8 @@ void makeraytree(Render *re)
for(v=0;v<obr->totvlak;v++) {
if((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak;
else vlr++;
- if(vlr->mat->mode & MA_TRACEBLE) {
+ /* baking selected to active needs non-traceable too */
+ if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE)) {
if((vlr->mat->mode & MA_WIRE)==0) {
VECCOPY(co1, vlr->v1->co);
VECCOPY(co2, vlr->v2->co);
@@ -186,7 +192,7 @@ void makeraytree(Render *re)
}
else vlr++;
- if(vlr->mat->mode & MA_TRACEBLE)
+ if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE))
if((vlr->mat->mode & MA_WIRE)==0)
RE_ray_tree_add_face(re->raytree, RAY_OBJECT_SET(re, obi), vlr);
}
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index bedce5e36ee..35e0815cc69 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -826,9 +826,9 @@ void shade_input_set_shade_texco(ShadeInput *shi)
else {
/* qdn: flat faces have tangents too,
could pick either one, using average here */
- tl= 1.0f;
- tu= 1.0f/3.0f;
- tv= 1.0f/3.0f;
+ tl= 1.0f/3.0f;
+ tu= -1.0f/3.0f;
+ tv= -1.0f/3.0f;
}
shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index 377d72325f0..6af3b711028 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -2488,21 +2488,29 @@ int externtex(MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *t
void render_realtime_texture(ShadeInput *shi, Image *ima)
{
TexResult texr;
- static Tex tex1, tex2; // threadsafe
+ static Tex imatex[BLENDER_MAX_THREADS]; // threadsafe
static int firsttime= 1;
Tex *tex;
float texvec[3], dx[2], dy[2];
ShadeInputUV *suv= &shi->uv[shi->actuv];
+ int a;
if(firsttime) {
- firsttime= 0;
- default_tex(&tex1);
- default_tex(&tex2);
- tex1.type= TEX_IMAGE;
- tex2.type= TEX_IMAGE;
+ BLI_lock_thread(LOCK_IMAGE);
+ if(firsttime) {
+ for(a=0; a<BLENDER_MAX_THREADS; a++) {
+ memset(&imatex[a], 0, sizeof(Tex));
+ default_tex(&imatex[a]);
+ imatex[a].type= TEX_IMAGE;
+ }
+
+ firsttime= 0;
+ }
+ BLI_unlock_thread(LOCK_IMAGE);
}
- if(shi->ys & 1) tex= &tex1; else tex= &tex2; // threadsafe
+ tex= &imatex[shi->thread];
+ tex->iuser.ok= ima->ok;
texvec[0]= 0.5+0.5*suv->uv[0];
texvec[1]= 0.5+0.5*suv->uv[1];
@@ -2519,12 +2527,6 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
if(shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr);
else imagewrap(tex, ima, NULL, texvec, &texr);
- if (tex->ima && tex->ima->flag & IMA_DO_PREMUL) {
- texr.tr *= texr.ta;
- texr.tg *= texr.ta;
- texr.tb *= texr.ta;
- }
-
shi->vcol[0]*= texr.tr;
shi->vcol[1]*= texr.tg;
shi->vcol[2]*= texr.tb;
diff --git a/source/blender/src/butspace.c b/source/blender/src/butspace.c
index e8062422e2a..cdc46cde8b7 100644
--- a/source/blender/src/butspace.c
+++ b/source/blender/src/butspace.c
@@ -319,6 +319,7 @@ static void curvemap_buttons_zoom_out(void *cumap_v, void *unused)
d1= cumap->curr.xmin - cumap->clipr.xmin;
cumap->curr.xmin-= d1;
+ d1= d;
if(cumap->flag & CUMA_DO_CLIP)
if(cumap->curr.xmax+d > cumap->clipr.xmax)
d1= -cumap->curr.xmax + cumap->clipr.xmax;
@@ -331,6 +332,7 @@ static void curvemap_buttons_zoom_out(void *cumap_v, void *unused)
d1= cumap->curr.ymin - cumap->clipr.ymin;
cumap->curr.ymin-= d1;
+ d1= d;
if(cumap->flag & CUMA_DO_CLIP)
if(cumap->curr.ymax+d > cumap->clipr.ymax)
d1= -cumap->curr.ymax + cumap->clipr.ymax;
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index edd9a2ff827..7dd9f2aa765 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -1254,9 +1254,9 @@ static void modifiers_convertParticles(void *obv, void *mdv)
ParticleCacheKey *key, **cache;
Mesh *me;
MVert *mvert;
- MFace *mface;
+ MEdge *medge;
int a, k, kmax;
- int totvert=0, totface=0, cvert=0;
+ int totvert=0, totedge=0, cvert=0;
int totpart=0, totchild=0;
if(md->type != eModifierType_ParticleSystem) return;
@@ -1277,15 +1277,15 @@ static void modifiers_convertParticles(void *obv, void *mdv)
cache= psys->pathcache;
for(a=0; a<totpart; a++) {
key= cache[a];
- totvert+= (int)(key->col[3])+1;
- totface+= (int)(key->col[3]);
+ totvert+= key->steps+1;
+ totedge+= key->steps;
}
cache= psys->childcache;
for(a=0; a<totchild; a++) {
key= cache[a];
- totvert+= (int)(key->col[3])+1;
- totface+= (int)(key->col[3]);
+ totvert+= key->steps+1;
+ totedge+= key->steps;
}
if(totvert==0) return;
@@ -1295,25 +1295,27 @@ static void modifiers_convertParticles(void *obv, void *mdv)
me= obn->data;
me->totvert= totvert;
- me->totface= totface;
+ me->totedge= totedge;
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
- me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, totface);
+ me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+ me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
mvert= me->mvert;
- mface= me->mface;
+ medge= me->medge;
/* copy coordinates */
cache= psys->pathcache;
- for(a=0; a<totpart; a++){
+ for(a=0; a<totpart; a++) {
key= cache[a];
- kmax= (int)(key->col[3]);
+ kmax= key->steps;
for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
VECCOPY(mvert->co,key->co);
- if(k){
- mface->v1= cvert-1;
- mface->v2= cvert;
- mface++;
+ if(k) {
+ medge->v1= cvert-1;
+ medge->v2= cvert;
+ medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
+ medge++;
}
}
}
@@ -1321,18 +1323,21 @@ static void modifiers_convertParticles(void *obv, void *mdv)
cache=psys->childcache;
for(a=0; a<totchild; a++) {
key=cache[a];
- kmax=(int)(key->col[3]);
+ kmax=key->steps;
for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
VECCOPY(mvert->co,key->co);
- if(k){
- mface->v1=cvert-1;
- mface->v2=cvert;
- mface++;
+ if(k) {
+ medge->v1=cvert-1;
+ medge->v2=cvert;
+ medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
+ medge++;
}
}
}
- make_edges(me, 0);
+
+ DAG_scene_sort(G.scene);
}
+
static void modifiers_applyModifier(void *obv, void *mdv)
{
Object *ob = obv;
@@ -2686,7 +2691,7 @@ static void load_buts_vfont(char *name)
static void set_unicode_text_fs(char *file)
{
- if (file > 0) paste_unicodeText(file);
+ if (file) paste_unicodeText(file);
}
void do_fontbuts(unsigned short event)
@@ -5244,10 +5249,10 @@ static void editing_panel_links(Object *ob)
std_libbuttons(block, 143, 130, 0, NULL, B_POSELIB_BROWSE, ID_AC, 0, (ID *)act, (ID *)ob, &(G.buts->menunr), B_POSELIB_ALONE, 0, B_POSELIB_DELETE, 0, 0);
uiBlockSetCol(block, TH_AUTO);
- uiDefBut(block, BUT, B_POSELIB_VALIDATE, "Auto-Sync PoseLib", xco,110,160,20, 0, 0, 0, 0, 0, "Syncs the current PoseLib with the poses available");
-
/* PoseLib - Pose editing controls */
if (act) {
+ uiDefBut(block, BUT, B_POSELIB_VALIDATE, "Auto-Sync PoseLib", xco,110,160,20, 0, 0, 0, 0, 0, "Syncs the current PoseLib with the poses available");
+
uiBlockBeginAlign(block);
/* currently 'active' pose */
if (act->markers.first) {
@@ -6195,6 +6200,9 @@ static void editing_panel_mesh_texface(void)
uiDefButC(block, ROW, REDRAWVIEW3D, "Add", 660,80,60,19, &tf->transp, 2.0, (float)TF_ADD, 0, 0, "Render face transparent and add color of face");
uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha", 720,80,60,19, &tf->transp, 2.0, (float)TF_ALPHA,0, 0, "Render polygon transparent, depending on alpha channel of the texture");
}
+ else
+ uiDefBut(block,LABEL,B_NOP, "(No Active Face)", 10,200,150,19,0,0,0,0,0,"");
+
}
void do_uvcalculationbuts(unsigned short event)
@@ -6464,7 +6472,10 @@ void editing_panels()
editing_panel_mesh_tools(ob, ob->data);
editing_panel_mesh_tools1(ob, ob->data);
uiNewPanelTabbed("Mesh Tools 1", "Editing");
- editing_panel_mesh_skgen(ob, ob->data);
+
+ if (G.rt == 42) /* hidden for now, no time for docs */
+ editing_panel_mesh_skgen(ob, ob->data);
+
editing_panel_mesh_uvautocalculation();
if (EM_texFaceCheck())
editing_panel_mesh_texface();
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 8fb4fab4a92..7a0d00c0593 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -2470,18 +2470,24 @@ static uiBlock *add_groupmenu(void *arg_unused)
{
uiBlock *block;
Group *group;
- short yco= 0;
+ short xco=0, yco= 0, index=0;
char str[32];
block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
uiBlockSetButmFunc(block, do_add_groupmenu, NULL);
uiDefBut(block, BUTM, B_NOP, "ADD NEW", 0, 20, 160, 19, NULL, 0.0, 0.0, 1, -1, "");
- for(group= G.main->group.first; group; group= group->id.next, yco++) {
+ for(group= G.main->group.first; group; group= group->id.next, index++) {
if(group->id.lib) strcpy(str, "L ");
else strcpy(str, " ");
strcat(str, group->id.name+2);
- uiDefBut(block, BUTM, B_NOP, str, 0, -20*yco, 160, 19, NULL, 0.0, 0.0, 1, yco, "");
+ uiDefBut(block, BUTM, B_NOP, str, xco*160, -20*yco, 160, 19, NULL, 0.0, 0.0, 1, index, "");
+
+ yco++;
+ if(yco>24) {
+ yco= 0;
+ xco++;
+ }
}
uiTextBoundsBlock(block, 50);
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index 9dbcd656df6..1d3ece58db7 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -168,7 +168,7 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
for (i=1; i < key->totkey; i++) {
make_rvk_slider(block, ob, i,
x, y, SLIDERWIDTH-2, CHANNELHEIGHT-1, "Slider to control Shape Keys");
-
+
y-=CHANNELHEIGHT+CHANNELSKIP;
/* see sliderval array in editkey.c */
@@ -176,7 +176,6 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
}
}
uiDrawBlock(block);
-
}
static void icu_slider_func(void *voidicu, void *voidignore)
@@ -238,7 +237,7 @@ static void make_icu_slider(uiBlock *block, IpoCurve *icu,
/* create a slider for the ipo-curve*/
uiBut *but;
- if(icu==NULL) return;
+ if(icu == NULL) return;
if (IS_EQ(icu->slide_max, icu->slide_min)) {
if (IS_EQ(icu->ymax, icu->ymin)) {
@@ -359,7 +358,7 @@ static void action_icu_buts(SpaceAction *saction)
// TODO...
}
break;
- }
+ }
}
/* adjust y-position for next one */
@@ -905,7 +904,7 @@ void do_actionbuts(unsigned short event)
}
}
-
+// currently not used...
static void action_panel_properties(short cntrl) // ACTION_HANDLER_PROPERTIES
{
uiBlock *block;
@@ -913,10 +912,10 @@ static void action_panel_properties(short cntrl) // ACTION_HANDLER_PROPERTIES
block= uiNewBlock(&curarea->uiblocks, "action_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(ACTION_HANDLER_PROPERTIES); // for close and esc
- if(uiNewPanel(curarea, block, "Transform Properties", "Action", 10, 230, 318, 204)==0) return;
+ if (uiNewPanel(curarea, block, "Transform Properties", "Action", 10, 230, 318, 204)==0)
+ return;
uiDefBut(block, LABEL, 0, "test text", 10,180,300,19, 0, 0, 0, 0, 0, "");
-
}
static void action_blockhandlers(ScrArea *sa)
@@ -924,17 +923,17 @@ static void action_blockhandlers(ScrArea *sa)
SpaceAction *sact= sa->spacedata.first;
short a;
- for(a=0; a<SPACE_MAXHANDLER; a+=2) {
+ for (a=0; a<SPACE_MAXHANDLER; a+=2) {
switch(sact->blockhandler[a]) {
-
- case ACTION_HANDLER_PROPERTIES:
- action_panel_properties(sact->blockhandler[a+1]);
- break;
-
+ case ACTION_HANDLER_PROPERTIES:
+ action_panel_properties(sact->blockhandler[a+1]);
+ break;
}
+
/* clear action value for event */
sact->blockhandler[a+1]= 0;
}
+
uiDrawBlocksPanels(sa, 0);
}
@@ -959,7 +958,6 @@ void drawactionspace(ScrArea *sa, void *spacedata)
/* only try to refresh action that's displayed if not pinned */
if (G.saction->pin==0) {
- /* TODO: allow more than one active action sometime? */
if (OBACT)
G.saction->action = OBACT->action;
else
@@ -1508,14 +1506,16 @@ void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks, Act
if (agrp) {
/* loop through action channels */
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
- /* firstly, add keys from action channel's ipo block */
- if (achan->ipo)
- ipo_to_keylist(achan->ipo, keys, blocks, aki);
-
- /* then, add keys from constraint channels */
- for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (conchan->ipo)
- ipo_to_keylist(conchan->ipo, keys, blocks, aki);
+ if (VISIBLE_ACHAN(achan)) {
+ /* firstly, add keys from action channel's ipo block */
+ if (achan->ipo)
+ ipo_to_keylist(achan->ipo, keys, blocks, aki);
+
+ /* then, add keys from constraint channels */
+ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
+ if (conchan->ipo)
+ ipo_to_keylist(conchan->ipo, keys, blocks, aki);
+ }
}
}
}
diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c
index c94df84c7f7..e13d0f4d0cd 100644
--- a/source/blender/src/drawipo.c
+++ b/source/blender/src/drawipo.c
@@ -2220,8 +2220,9 @@ void drawipospace(ScrArea *sa, void *spacedata)
/* ipokeys */
if(sipo->showkey) {
- if(sipo->ipokey.first==0) make_ipokey();
- else update_ipokey_val();
+ //if(sipo->ipokey.first==0) make_ipokey();
+ //else update_ipokey_val();
+ make_ipokey();
draw_ipokey(sipo);
}
diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c
index 2fe89727c43..cea33685744 100644
--- a/source/blender/src/drawnode.c
+++ b/source/blender/src/drawnode.c
@@ -356,9 +356,11 @@ static int node_buts_time(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *b
curvemap_buttons(block, node->storage, 's', B_NODE_EXEC+node->nr, B_REDR, butr);
- if(cumap) cumap->flag |= CUMA_DRAW_CFRA;
- if(node->custom1<node->custom2)
- cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1);
+ if(cumap) {
+ cumap->flag |= CUMA_DRAW_CFRA;
+ if(node->custom1<node->custom2)
+ cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1);
+ }
uiBlockBeginAlign(block);
uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Sta:",
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 260b0ab6656..9ddf5e405dd 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -1995,7 +1995,7 @@ static void draw_em_measure_stats(Object *ob, EditMesh *em)
Mat4MulVecfl(ob->obmat, v1);
Mat4MulVecfl(ob->obmat, v2);
Mat4MulVecfl(ob->obmat, v3);
- if (efa->v4) Mat4MulVecfl(ob->obmat, v4);
+ Mat4MulVecfl(ob->obmat, v4);
}
e1= efa->e1;
diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c
index 73b1aa9856c..327fcb341c7 100644
--- a/source/blender/src/drawtext.c
+++ b/source/blender/src/drawtext.c
@@ -1442,7 +1442,7 @@ void run_python_script(SpaceText *st)
if (!st->text) return;
if (!strcmp(py_filename, st->text->id.name+2)) {
- error("Python script error, check console");
+ error_pyscript( );
if (lineno >= 0) {
txt_move_toline(text, lineno-1, 0);
txt_sel_line(text);
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index c4c221bcdf6..e0919c7ba1c 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -1580,7 +1580,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
EditEdge *eed;
MDeformVert *dvert=NULL;
TransformProperties *tfp= G.vd->properties_storage;
- float median[5];
+ float median[5], ve_median[5];
int tot, totw, totweight, totedge;
char defstr[320];
@@ -1773,15 +1773,16 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
}
else { // apply
+ memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
if(G.vd->flag & V3D_GLOBAL_STATS) {
Mat4Invert(ob->imat, ob->obmat);
Mat4MulVecfl(ob->imat, median);
- Mat4MulVecfl(ob->imat, tfp->ve_median);
+ Mat4MulVecfl(ob->imat, ve_median);
}
- VecSubf(median, tfp->ve_median, median);
- median[3]= tfp->ve_median[3]-median[3];
- median[4]= tfp->ve_median[4]-median[4];
+ VecSubf(median, ve_median, median);
+ median[3]= ve_median[3]-median[3];
+ median[4]= ve_median[4]-median[4];
if(ob->type==OB_MESH) {
@@ -1796,8 +1797,8 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
for(eed= em->edges.first; eed; eed= eed->next) {
if(eed->f & SELECT) {
/* ensure the median can be set to zero or one */
- if(tfp->ve_median[3]==0.0f) eed->crease= 0.0f;
- else if(tfp->ve_median[3]==1.0f) eed->crease= 1.0f;
+ if(ve_median[3]==0.0f) eed->crease= 0.0f;
+ else if(ve_median[3]==1.0f) eed->crease= 1.0f;
else {
eed->crease+= median[3];
CLAMP(eed->crease, 0.0, 1.0);
@@ -2888,6 +2889,108 @@ static void draw_sculpt_depths(View3D *v3d)
}
}
+void draw_depth(ScrArea *sa, void *spacedata)
+{
+ View3D *v3d= spacedata;
+ Base *base;
+ Scene *sce;
+ short drawtype, zbuf, flag;
+ float glalphaclip;
+ /* temp set drawtype to solid */
+
+ /* Setting these temporarily is not nice */
+ drawtype = v3d->drawtype;
+ zbuf = v3d->zbuf;
+ flag = v3d->flag;
+ glalphaclip = U.glalphaclip;
+
+ U.glalphaclip = 0.5; /* not that nice but means we wont zoom into billboards */
+ v3d->flag &= ~V3D_SELECT_OUTLINE;
+ if ((v3d->drawtype != OB_SOLID) && (v3d->drawtype != OB_TEXTURE))
+ v3d->drawtype = OB_SOLID;
+
+ setwinmatrixview3d(sa->winx, sa->winy, NULL); /* 0= no pick rect */
+ setviewmatrixview3d(); /* note: calls where_is_object for camera... */
+
+ Mat4MulMat4(v3d->persmat, v3d->viewmat, sa->winmat);
+ Mat4Invert(v3d->persinv, v3d->persmat);
+ Mat4Invert(v3d->viewinv, v3d->viewmat);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ myloadmatrix(v3d->viewmat);
+ persp(PERSP_STORE); // store correct view for persp(PERSP_VIEW) calls
+
+ if(v3d->flag & V3D_CLIPPING) {
+ view3d_set_clipping(v3d);
+ }
+
+ v3d->zbuf= TRUE;
+ glEnable(GL_DEPTH_TEST);
+
+ /* draw set first */
+ if(G.scene->set) {
+ for(SETLOOPER(G.scene->set, base)) {
+ if(v3d->lay & base->lay) {
+ draw_object(base, 0);
+ if(base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects_color(v3d, base, TH_WIRE);
+ }
+ }
+ }
+ }
+
+ for(base= G.scene->base.first; base; base= base->next) {
+ if(v3d->lay & base->lay) {
+
+ /* dupli drawing */
+ if(base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects(v3d, base);
+ }
+ draw_object(base, 0);
+ }
+ }
+
+ /* this isnt that nice, draw xray objects as if they are normal */
+ if (v3d->afterdraw.first) {
+ View3DAfter *v3da, *next;
+ int num = 0;
+ v3d->xray= TRUE;
+
+ glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */
+ for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
+ next= v3da->next;
+ if(v3da->type==V3D_XRAY) {
+ draw_object(v3da->base, 0);
+ num++;
+ }
+ /* dont remove this time */
+ }
+ v3d->xray= FALSE;
+
+ glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */
+ for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
+ next= v3da->next;
+ if(v3da->type==V3D_XRAY) {
+ v3d->xray= TRUE; v3d->transp= FALSE;
+ } else if (v3da->type==V3D_TRANSP) {
+ v3d->xray= FALSE; v3d->transp= TRUE;
+ }
+
+ draw_object(v3da->base, 0); /* Draw Xray or Transp objects normally */
+ BLI_remlink(&v3d->afterdraw, v3da);
+ MEM_freeN(v3da);
+ }
+ v3d->xray= FALSE;
+ v3d->transp= FALSE;
+ }
+
+ v3d->drawtype = drawtype;
+ v3d->zbuf = zbuf;
+ U.glalphaclip = glalphaclip;
+ v3d->flag = flag;
+}
+
static void draw_viewport_fps(ScrArea *sa);
diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c
index ecd546a6780..9190b3263f0 100644
--- a/source/blender/src/edit.c
+++ b/source/blender/src/edit.c
@@ -1856,6 +1856,22 @@ void snapmenu()
}
}
+void alignmenu()
+{
+ short val;
+ char *str_menu = BIF_menustringTransformOrientation("Align");
+ val= pupmenu(str_menu);
+ MEM_freeN(str_menu);
+
+ if (val >= 0)
+ {
+ short old_val = G.vd->twmode;
+ G.vd->twmode = val;
+ initTransform(TFM_ALIGN, CTX_NO_PET|CTX_AUTOCONFIRM);
+ Transform();
+ G.vd->twmode = old_val;
+ }
+}
#define MERGELIMIT 0.001
void mergemenu(void)
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index d6d748f2213..1a1bb9f4fb1 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -1088,7 +1088,7 @@ void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
return;
if (name[0] == 0)
return;
-
+
/* try to get the channels */
pchan= get_pose_channel(pose, name);
if (pchan == NULL) return;
@@ -1432,6 +1432,7 @@ void insertkey_action(void)
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
}
/* delete selected keyframes */
@@ -1529,7 +1530,7 @@ void delete_action_channels (void)
bConstraintChannel *conchan, *cnext;
next= ale->next;
- /* release reference to ipo users */
+ /* release references to ipo users */
if (achan->ipo)
achan->ipo->id.us--;
@@ -1540,12 +1541,16 @@ void delete_action_channels (void)
conchan->ipo->id.us--;
}
+ /* remove action-channel from group(s) */
+ if (achan->grp)
+ action_groups_removeachan(act, achan);
+
/* free memory */
BLI_freelistN(&achan->constraintChannels);
BLI_freelinkN(&act->chanbase, achan);
BLI_freelinkN(&act_data, ale);
}
-
+
remake_action_ipos(data);
BIF_undo_push("Delete Action Channels");
@@ -1867,7 +1872,7 @@ void paste_actdata ()
/* check if we have a corresponding action channel */
if ((no_name) || (strcmp(achan->name, achant->name)==0)) {
actname= achan->name;
-
+
/* check if this is a constraint channel */
if (ale->type == ACTTYPE_CONCHAN) {
bConstraintChannel *conchant= ale->data;
@@ -1901,12 +1906,12 @@ void paste_actdata ()
/* this shouldn't happen, but it might */
if (ELEM(NULL, ipo_src, ipo_dst))
continue;
-
+
/* loop over curves, pasting keyframes */
for (ico= ipo_src->curve.first; ico; ico= ico->next) {
icu= verify_ipocurve((ID*)OBACT, ico->blocktype, actname, conname, "", ico->adrcode);
-
- if(icu) {
+
+ if (icu) {
/* just start pasting, with the the first keyframe on the current frame, and so on */
for (i=0, bezt=ico->bezt; i < ico->totvert; i++, bezt++) {
/* temporarily apply offset to src beztriple while copying */
@@ -4233,7 +4238,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
*/
if (IN_2D_VERT_SCROLL(mval))
selectall_action_keys(mval, 0, select_mode);
-
+
/* Clicking in the horizontal scrollbar selects
* all of the keys within 0.5 of the nearest integer
* frame
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index 55ed6252dae..a93d81e04af 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -2843,23 +2843,56 @@ void clear_armature(Object *ob, char mode)
bPoseChannel *pchan;
bArmature *arm;
- arm=get_armature(ob);
-
- if (!arm)
+ arm= get_armature(ob);
+ if (arm == NULL)
return;
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
- if(arm->layer & pchan->bone->layer) {
+ /* only clear those channels that are not locked */
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
+ if (arm->layer & pchan->bone->layer) {
switch (mode) {
case 'r':
- pchan->quat[1]=pchan->quat[2]=pchan->quat[3]=0.0F; pchan->quat[0]=1.0F;
+ if (pchan->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ)) {
+ float eul[3], oldeul[3], quat1[4];
+
+ QUATCOPY(quat1, pchan->quat);
+ QuatToEul(pchan->quat, oldeul);
+ eul[0]= eul[1]= eul[2]= 0.0f;
+
+ if (pchan->protectflag & OB_LOCK_ROTX)
+ eul[0]= oldeul[0];
+ if (pchan->protectflag & OB_LOCK_ROTY)
+ eul[1]= oldeul[1];
+ if (pchan->protectflag & OB_LOCK_ROTZ)
+ eul[2]= oldeul[2];
+
+ EulToQuat(eul, pchan->quat);
+ /* quaternions flip w sign to accumulate rotations correctly */
+ if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) {
+ QuatMulf(pchan->quat, -1.0f);
+ }
+ }
+ else {
+ pchan->quat[1]=pchan->quat[2]=pchan->quat[3]=0.0F;
+ pchan->quat[0]=1.0F;
+ }
break;
case 'g':
- pchan->loc[0]=pchan->loc[1]=pchan->loc[2]=0.0F;
+ if ((pchan->protectflag & OB_LOCK_LOCX)==0)
+ pchan->loc[0]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_LOCY)==0)
+ pchan->loc[1]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_LOCZ)==0)
+ pchan->loc[2]= 0.0f;
break;
case 's':
- pchan->size[0]=pchan->size[1]=pchan->size[2]=1.0F;
+ if ((pchan->protectflag & OB_LOCK_SCALEX)==0)
+ pchan->size[0]= 1.0f;
+ if ((pchan->protectflag & OB_LOCK_SCALEY)==0)
+ pchan->size[1]= 1.0f;
+ if ((pchan->protectflag & OB_LOCK_SCALEZ)==0)
+ pchan->size[2]= 1.0f;
break;
}
@@ -3003,7 +3036,6 @@ void deselectall_posearmature (Object *ob, int test, int doundo)
int bone_looper(Object *ob, Bone *bone, void *data,
int (*bone_func)(Object *, Bone *, void *))
{
-
/* We want to apply the function bone_func to every bone
* in an armature -- feed bone_looper the first bone and
* a pointer to the bone_func and watch it go!. The int count
@@ -3013,19 +3045,15 @@ int bone_looper(Object *ob, Bone *bone, void *data,
int count = 0;
if (bone) {
-
- /* only do bone_func if the bone is non null
- */
+ /* only do bone_func if the bone is non null */
count += bone_func(ob, bone, data);
-
- /* try to execute bone_func for the first child
- */
- count += bone_looper(ob, bone->childbase.first, data,
- bone_func);
-
- /* try to execute bone_func for the next bone at this
- * depth of the recursion.
- */
+
+ /* try to execute bone_func for the first child */
+ count += bone_looper(ob, bone->childbase.first, data, bone_func);
+
+ /* try to execute bone_func for the next bone at this
+ * depth of the recursion.
+ */
count += bone_looper(ob, bone->next, data, bone_func);
}
@@ -3063,15 +3091,15 @@ static int bone_skinnable(Object *ob, Bone *bone, void *datap)
if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
if (!(bone->flag & BONE_NO_DEFORM)) {
- if(data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
+ if (data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
segments = bone->segments;
else
segments = 1;
-
+
if (data->list != NULL) {
hbone = (Bone ***) &data->list;
- for(a=0; a<segments; a++) {
+ for (a=0; a<segments; a++) {
**hbone = bone;
++*hbone;
}
@@ -3085,9 +3113,9 @@ static int bone_skinnable(Object *ob, Bone *bone, void *datap)
static int add_defgroup_unique_bone(Object *ob, Bone *bone, void *data)
{
/* This group creates a vertex group to ob that has the
- * same name as bone (provided the bone is skinnable).
+ * same name as bone (provided the bone is skinnable).
* If such a vertex group aleady exist the routine exits.
- */
+ */
if (!(bone->flag & BONE_NO_DEFORM)) {
if (!get_named_vertexgroup(ob,bone->name)) {
add_defgroup_name(ob, bone->name);
@@ -3126,19 +3154,19 @@ static int dgroup_skinnable(Object *ob, Bone *bone, void *datap)
int a, segments;
struct { Object *armob; void *list; int heat; } *data= datap;
- if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
+ if (!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
if (!(bone->flag & BONE_NO_DEFORM)) {
- if(data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
+ if (data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
segments = bone->segments;
else
segments = 1;
-
- if(!(defgroup = get_named_vertexgroup(ob, bone->name)))
+
+ if (!(defgroup = get_named_vertexgroup(ob, bone->name)))
defgroup = add_defgroup_name(ob, bone->name);
-
+
if (data->list != NULL) {
hgroup = (bDeformGroup ***) &data->list;
-
+
for(a=0; a<segments; a++) {
**hgroup = defgroup;
++*hgroup;
@@ -3170,15 +3198,15 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i
/* for each vertex in the mesh */
for (i=0; i < mesh->totvert; i++) {
iflip = (dgroupflip)? mesh_get_x_mirror_vert(ob, i): 0;
-
+
/* for each skinnable bone */
for (j=0; j < numbones; ++j) {
if(!selected[j])
continue;
-
+
bone = bonelist[j];
dgroup = dgrouplist[j];
-
+
/* store the distance-factor from the vertex to the bone */
distance = distfactor_to_bone (verts[i], root[j], tip[j],
bone->rad_head * scale, bone->rad_tail * scale, bone->dist * scale);
@@ -3188,7 +3216,7 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i
add_vert_to_defgroup (ob, dgroup, i, distance, WEIGHT_REPLACE);
else
remove_vert_defgroup (ob, dgroup, i);
-
+
/* do same for mirror */
if (dgroupflip && dgroupflip[j] && iflip >= 0) {
if (distance!=0.0)
@@ -3273,7 +3301,7 @@ void add_verts_to_dgroups(Object *ob, Object *par, int heat, int mirror)
if(segments == 0) {
segments = 1;
bbone = NULL;
-
+
if(par->pose && (pchan=get_pose_channel(par->pose, bone->name))) {
if(bone->segments > 1) {
segments = bone->segments;
@@ -3281,10 +3309,10 @@ void add_verts_to_dgroups(Object *ob, Object *par, int heat, int mirror)
}
}
}
-
+
segments--;
}
-
+
/* compute root and tip */
if(bbone) {
VECCOPY(root[j], bbone[segments].mat[3]);
@@ -3300,10 +3328,10 @@ void add_verts_to_dgroups(Object *ob, Object *par, int heat, int mirror)
VECCOPY(root[j], bone->arm_head);
VECCOPY(tip[j], bone->arm_tail);
}
-
+
Mat4MulVecfl(par->obmat, root[j]);
Mat4MulVecfl(par->obmat, tip[j]);
-
+
/* set selected */
if(wpmode) {
if ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))
@@ -3311,7 +3339,7 @@ void add_verts_to_dgroups(Object *ob, Object *par, int heat, int mirror)
}
else
selected[j] = 1;
-
+
/* find flipped group */
if(mirror) {
char name[32];
@@ -3319,11 +3347,11 @@ void add_verts_to_dgroups(Object *ob, Object *par, int heat, int mirror)
BLI_strncpy(name, dgroup->name, 32);
// 0 = don't strip off number extensions
bone_flip_name(name, 0);
-
+
for (curdg = ob->defbase.first; curdg; curdg=curdg->next)
if (!strcmp(curdg->name, name))
break;
-
+
dgroupflip[j] = curdg;
}
}
@@ -3335,12 +3363,12 @@ void add_verts_to_dgroups(Object *ob, Object *par, int heat, int mirror)
if (wpmode) {
/* if in weight paint mode, use final verts from derivedmesh */
DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
-
+
if(dm->foreachMappedVert) {
dm->foreachMappedVert(dm, add_vgroups__mapFunc, (void*)verts);
vertsfilled = 1;
}
-
+
dm->release(dm);
}
else if (modifiers_findByType(ob, eModifierType_Subsurf)) {
@@ -3406,9 +3434,9 @@ void create_vgroups_from_armature(Object *ob, Object *par)
add_defgroup_unique_bone);
if (ob->type == OB_MESH)
create_dverts(ob->data);
-
+
break;
-
+
case 3:
case 4:
/* Traverse the bone list, trying to create vertex groups
@@ -3444,7 +3472,7 @@ void hide_selected_pose_bones(void)
bone_looper(OBACT, arm->bonebase.first, NULL,
hide_selected_pose_bone);
-
+
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWACTION, 0);
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index ef656281d75..fe68e0818bb 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -1815,7 +1815,7 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char
if(achan) {
/* automatically assign achan to act-group based on pchan's grouping */
if (blocktype == ID_PO)
- verify_pchan2achan_grouping(ob->action, ob->pose, actname);
+ verify_pchan2achan_grouping(ob->action, ob->pose, actname);
/* constraint exception */
if(blocktype==ID_CO) {
@@ -2268,14 +2268,14 @@ void add_vert_ipo(void)
BIF_undo_push("Add Ipo vertex");
}
-static void *get_context_ipo_poin(ID *id, int blocktype, char *actname, IpoCurve *icu, int *vartype)
+static void *get_context_ipo_poin(ID *id, int blocktype, char *actname, char *constname, IpoCurve *icu, int *vartype)
{
- if(blocktype==ID_PO) {
- if(GS(id->name)==ID_OB) {
+ if (blocktype==ID_PO) {
+ if (GS(id->name)==ID_OB) {
Object *ob= (Object *)id;
bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
- if(pchan) {
+ if (pchan) {
*vartype= IPO_FLOAT;
return get_pchan_ipo_poin(pchan, icu->adrcode);
}
@@ -2284,6 +2284,35 @@ static void *get_context_ipo_poin(ID *id, int blocktype, char *actname, IpoCurve
}
return NULL;
}
+ else if (blocktype==ID_CO) {
+ if ((GS(id->name)==ID_OB) && (constname && constname[0])) {
+ Object *ob= (Object *)id;
+ bConstraint *con;
+
+ /* assume that we only want the influence (as only used for Constraint Channels) */
+ if ((ob->ipoflag & OB_ACTION_OB) && !strcmp(actname, "Object")) {
+ for (con= ob->constraints.first; con; con= con->next) {
+ if (strcmp(constname, con->name)==0) {
+ *vartype= IPO_FLOAT;
+ return &con->enforce;
+ }
+ }
+ }
+ else if (ob->pose) {
+ bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
+
+ if (pchan) {
+ for (con= pchan->constraints.first; con; con= con->next) {
+ if (strcmp(constname, con->name)==0) {
+ *vartype= IPO_FLOAT;
+ return &con->enforce;
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+ }
else
return get_ipo_poin(id, icu, vartype);
@@ -2420,7 +2449,7 @@ static void insertkey_nonrecurs(ID *id, int blocktype, char *actname, char *cons
if(icu) {
- poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype);
+ poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
if(poin) {
curval= read_ipo_poin(poin, vartype);
@@ -2641,7 +2670,7 @@ void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcod
if(icu) {
- poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype);
+ poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
if(poin) {
curval= read_ipo_poin(poin, vartype);
@@ -2683,7 +2712,7 @@ void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, in
if(icu) {
- poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype);
+ poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
if(poin) {
curval= read_ipo_poin(poin, vartype);
@@ -2735,7 +2764,7 @@ void insertfloatkey(ID *id, int blocktype, char *actname, char *constname, int a
if(icu) {
- poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype);
+ poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
if(poin) {
diff --git a/source/blender/src/editmesh_loop.c b/source/blender/src/editmesh_loop.c
index b99710f782f..ca47741b6f1 100644
--- a/source/blender/src/editmesh_loop.c
+++ b/source/blender/src/editmesh_loop.c
@@ -488,11 +488,11 @@ static CutCurve *get_mouse_trail(int *len, char mode, char cutmode, struct GHash
{
CutCurve *curve,*temp;
EditVert *snapvert;
- float *scr, mval[2]={0.0,0.0}, lastx=0, lasty=0;
+ float *scr, mval[2]={0.0,0.0}, lastx=0, lasty=0, lockx=0, locky=0;
int i=0, j, blocks=1, lasti=0;
int dist, tolerance;
short event, val, qual, vsnap=0, ldown=0, restart=0, rubberband=0;
- short mval1[2], lockaxis=0, lockx=0, locky=0, oldmode;
+ short mval1[2], lockaxis=0, oldmode;
*len=0;
tolerance = 75;
diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c
index a308b428894..ab2a36aa2d3 100644
--- a/source/blender/src/editnode.c
+++ b/source/blender/src/editnode.c
@@ -1138,16 +1138,7 @@ void node_rename(SpaceNode *snode)
/* used in buttons to check context, also checks for edited groups */
bNode *editnode_get_active_idnode(bNodeTree *ntree, short id_code)
{
- bNode *node;
-
- /* check for edited group */
- for(node= ntree->nodes.first; node; node= node->next)
- if(node->flag & NODE_GROUP_EDIT)
- break;
- if(node)
- return nodeGetActiveID((bNodeTree *)node->id, id_code);
- else
- return nodeGetActiveID(ntree, id_code);
+ return nodeGetActiveID(ntree, id_code);
}
/* used in buttons to check context, also checks for edited groups */
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 1a3775ac301..07973926503 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -1030,18 +1030,31 @@ void clear_object(char mode)
* - with a mesh in weightpaint mode, it's related armature needs to be cleared
* - with clearing transform of object being edited at the time
*/
- if ((G.f & G_WEIGHTPAINT) || ob==OBACT) {
+ if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
clear_armature(ob, mode);
armature_clear= 1; /* silly system to prevent another dag update, so no action applied */
}
}
else if((G.f & G_WEIGHTPAINT)==0) {
-
- if(mode=='r') {
- memset(ob->rot, 0, 3*sizeof(float));
- memset(ob->drot, 0, 3*sizeof(float));
+ /* only clear transforms of 'normal' (not armature) object if:
+ * - not in weightpaint mode or editmode
+ * - if that object's transform locks are not enabled (this is done on a per-channel basis)
+ */
+ if (mode=='r') {
+ /* eulers can only get cleared if they are not protected */
+ if ((ob->protectflag & OB_LOCK_ROTX)==0)
+ ob->rot[0]= ob->drot[0]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_ROTY)==0)
+ ob->rot[1]= ob->drot[1]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_ROTZ)==0)
+ ob->rot[2]= ob->drot[2]= 0.0f;
+
+ /* quats here are not really used anymore anywhere, so it probably doesn't
+ * matter to not clear them whether the euler-based rotation is used
+ */
QuatOne(ob->quat);
QuatOne(ob->dquat);
+
#ifdef WITH_VERSE
if(ob->vnode) {
struct VNode *vnode = (VNode*)ob->vnode;
@@ -1051,9 +1064,14 @@ void clear_object(char mode)
#endif
}
- else if(mode=='g') {
- memset(ob->loc, 0, 3*sizeof(float));
- memset(ob->dloc, 0, 3*sizeof(float));
+ else if (mode=='g') {
+ if ((ob->protectflag & OB_LOCK_LOCX)==0)
+ ob->loc[0]= ob->dloc[0]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_LOCY)==0)
+ ob->loc[1]= ob->dloc[1]= 0.0f;
+ if ((ob->protectflag & OB_LOCK_LOCZ)==0)
+ ob->loc[2]= ob->dloc[2]= 0.0f;
+
#ifdef WITH_VERSE
if(ob->vnode) {
struct VNode *vnode = (VNode*)ob->vnode;
@@ -1063,11 +1081,19 @@ void clear_object(char mode)
#endif
}
- else if(mode=='s') {
- memset(ob->dsize, 0, 3*sizeof(float));
- ob->size[0]= 1.0;
- ob->size[1]= 1.0;
- ob->size[2]= 1.0;
+ else if (mode=='s') {
+ if ((ob->protectflag & OB_LOCK_SCALEX)==0) {
+ ob->dsize[0]= 0.0f;
+ ob->size[0]= 1.0f;
+ }
+ if ((ob->protectflag & OB_LOCK_SCALEY)==0) {
+ ob->dsize[1]= 0.0f;
+ ob->size[1]= 1.0f;
+ }
+ if ((ob->protectflag & OB_LOCK_SCALEZ)==0) {
+ ob->dsize[2]= 0.0f;
+ ob->size[2]= 1.0f;
+ }
#ifdef WITH_VERSE
if(ob->vnode) {
struct VNode *vnode = (VNode*)ob->vnode;
diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c
index 10d6187fc76..d40d76785b4 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -176,7 +176,7 @@ Sequence *get_forground_frame_seq(int frame)
/* seq funcs's for transforming internally
notice the difference between start/end and left/right.
- left and right are the bounds at which the setuence is rendered,
+ left and right are the bounds at which the sequence is rendered,
start and end are from the start and fixed length of the sequence.
*/
int seq_tx_get_start(Sequence *seq) {
@@ -2245,6 +2245,22 @@ static Sequence *dupli_seq(Sequence *seq)
return seqn;
}
+static Sequence * deep_dupli_seq(Sequence * seq)
+{
+ Sequence * seqn = dupli_seq(seq);
+ if (seq->type == SEQ_META) {
+ Sequence * s;
+ for(s= seq->seqbase.first; s; s = s->next) {
+ Sequence * n = deep_dupli_seq(s);
+ if (n) {
+ BLI_addtail(&seqn->seqbase, n);
+ }
+ }
+ }
+ return seqn;
+}
+
+
static void recurs_dupli_seq(ListBase *old, ListBase *new)
{
Sequence *seq;
@@ -2271,15 +2287,98 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
}
}
+static Sequence * cut_seq(Sequence * seq, int cutframe)
+{
+ TransSeq ts;
+ Sequence *seqn = 0;
+ int skip_dup = FALSE;
+
+ /* backup values */
+ ts.start= seq->start;
+ ts.machine= seq->machine;
+ ts.startstill= seq->startstill;
+ ts.endstill= seq->endstill;
+ ts.startdisp= seq->startdisp;
+ ts.enddisp= seq->enddisp;
+ ts.startofs= seq->startofs;
+ ts.endofs= seq->endofs;
+ ts.len= seq->len;
+
+ /* First Strip! */
+ /* strips with extended stillfames before */
+
+ if ((seq->startstill) && (cutframe <seq->start)) {
+ /* don't do funny things with METAs ... */
+ if (seq->type == SEQ_META) {
+ skip_dup = TRUE;
+ seq->startstill = seq->start - cutframe;
+ } else {
+ seq->start= cutframe -1;
+ seq->startstill= cutframe -seq->startdisp -1;
+ seq->endofs = seq->len - 1;
+ seq->endstill= 0;
+ }
+ }
+ /* normal strip */
+ else if ((cutframe >=seq->start)&&(cutframe <=(seq->start+seq->len))) {
+ seq->endofs = (seq->start+seq->len) - cutframe;
+ }
+ /* strips with extended stillframes after */
+ else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
+ seq->endstill -= seq->enddisp - cutframe;
+ /* don't do funny things with METAs ... */
+ if (seq->type == SEQ_META) {
+ skip_dup = TRUE;
+ }
+ }
+
+ calc_sequence(seq);
+
+ if (!skip_dup) {
+ /* Duplicate AFTER the first change */
+ seqn = deep_dupli_seq(seq);
+ }
+
+ if (seqn) { /* should never fail */
+ seqn->flag |= SELECT;
+
+ /* Second Strip! */
+ /* strips with extended stillframes before */
+ if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
+ seqn->start = ts.start;
+ seqn->startstill= ts.start- cutframe;
+ seqn->endofs = ts.endofs;
+ seqn->endstill = ts.endstill;
+ }
+
+ /* normal strip */
+ else if ((cutframe>=seqn->start)&&(cutframe<=(seqn->start+seqn->len))) {
+ seqn->startstill = 0;
+ seqn->startofs = cutframe - ts.start;
+ seqn->endofs = ts.endofs;
+ seqn->endstill = ts.endstill;
+ }
+
+ /* strips with extended stillframes after */
+ else if (((seqn->start+seqn->len) < cutframe) && (seqn->endstill)) {
+ seqn->start = cutframe - ts.len +1;
+ seqn->startofs = ts.len-1;
+ seqn->endstill = ts.enddisp - cutframe -1;
+ seqn->startstill = 0;
+ }
+
+ calc_sequence(seqn);
+ }
+ return seqn;
+}
+
/* like duplicate, but only duplicate and cut overlapping strips,
* strips to the left of the cutframe are ignored and strips to the right are moved into the new list */
-static void recurs_cut_seq(ListBase *old, ListBase *new, int cutframe)
+static int cut_seq_list(ListBase *old, ListBase *new, int cutframe)
{
+ int did_something = FALSE;
Sequence *seq, *seq_next;
- Sequence *seqn = 0;
- TransSeq ts;
-
seq= old->first;
while(seq) {
@@ -2287,87 +2386,13 @@ static void recurs_cut_seq(ListBase *old, ListBase *new, int cutframe)
seq->tmp= NULL;
if(seq->flag & SELECT) {
- if(cutframe > seq->startdisp && cutframe < seq->enddisp) {
-
- /* backup values */
- ts.start= seq->start;
- ts.machine= seq->machine;
- ts.startstill= seq->startstill;
- ts.endstill= seq->endstill;
- ts.startdisp= seq->startdisp;
- ts.enddisp= seq->enddisp;
- ts.startofs= seq->startofs;
- ts.endofs= seq->endofs;
- ts.len= seq->len;
-
- /* First Strip! */
- /* strips with extended stillfames before */
- if(seq->type!=SEQ_META) {
-
- if ((seq->startstill) && (cutframe <seq->start)) {
- seq->start= cutframe -1;
- seq->startstill= cutframe -seq->startdisp -1;
- seq->len= 1;
- seq->endstill= 0;
- }
-
- /* normal strip */
- else if ((cutframe >=seq->start)&&(cutframe <=(seq->start+seq->len))) {
- seq->endofs = (seq->start+seq->len) - cutframe;
- }
-
- /* strips with extended stillframes after */
- else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
- seq->endstill -= seq->enddisp - cutframe;
- }
-
- calc_sequence(seq);
- }
-
- /* Duplicate AFTER the first change */
- seqn = dupli_seq(seq);
-
- if (seqn) { /* should never fail */
- seqn->flag |= SELECT;
-
-
+ if(cutframe > seq->startdisp &&
+ cutframe < seq->enddisp) {
+ Sequence * seqn = cut_seq(seq, cutframe);
+ if (seqn) {
BLI_addtail(new, seqn);
-
- /* dont transform meta's - just do their children then recalc */
- if(seq->type==SEQ_META) {
- recurs_cut_seq(&seq->seqbase,&seqn->seqbase, cutframe);
- } else {
- /* Second Strip! */
- /* strips with extended stillframes before */
- if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
- seqn->start = ts.start;
- seqn->startstill= ts.start- cutframe;
- seqn->len = ts.len;
- seqn->endstill = ts.endstill;
- }
-
- /* normal strip */
- else if ((cutframe>=seqn->start)&&(cutframe<=(seqn->start+seqn->len))) {
- seqn->startstill = 0;
- seqn->startofs = cutframe - ts.start;
- seqn->endofs = ts.endofs;
- seqn->endstill = ts.endstill;
- }
-
- /* strips with extended stillframes after */
- else if (((seqn->start+seqn->len) < cutframe) && (seqn->endstill)) {
- seqn->start = cutframe - ts.len +1;
- seqn->startofs = ts.len-1;
- seqn->endstill = ts.enddisp - cutframe -1;
- seqn->startstill = 0;
- }
- }
-
- if(seq->type==SEQ_META) /* account for strips within changing */
- calc_sequence(seq);
-
- calc_sequence(seqn);
}
+ did_something = TRUE;
} else if (seq->enddisp <= cutframe) {
/* do nothing */
} else if (seq->startdisp >= cutframe) {
@@ -2378,6 +2403,7 @@ static void recurs_cut_seq(ListBase *old, ListBase *new, int cutframe)
}
seq = seq_next;
}
+ return did_something;
}
void seq_cut(int cutframe)
@@ -2385,14 +2411,16 @@ void seq_cut(int cutframe)
Editing *ed;
ListBase newlist;
char side;
+ int did_something;
+
ed= G.scene->ed;
if(ed==0) return;
newlist.first= newlist.last= NULL;
- recurs_cut_seq(ed->seqbasep, &newlist, cutframe);
+ did_something = cut_seq_list(ed->seqbasep, &newlist, cutframe);
- if (newlist.first) { /* simple check to see if anything was done */
+ if (newlist.first) { /* got new strips ? */
Sequence *seq;
addlisttolist(ed->seqbasep, &newlist);
@@ -2415,7 +2443,8 @@ void seq_cut(int cutframe)
/* as last: */
sort_seq();
-
+ }
+ if (did_something) {
allqueue(REDRAWSEQ, 0);
BIF_undo_push("Cut Strips, Sequencer");
}
diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c
index edaec5fb268..42e438b2022 100644
--- a/source/blender/src/editview.c
+++ b/source/blender/src/editview.c
@@ -2197,13 +2197,75 @@ void view3d_border_zoom(void)
float new_dist;
float new_ofs[3];
- /* doesn't work fine for perspective */
- if(G.vd->persp==1)
- return;
-
val = get_border(&rect, 3); //box select input
- if(val)
- {
+ if(!val) return;
+
+ if (G.vd->persp==1) { /* perspective */
+ View3D *v3d = G.vd;
+ bglMats mats;
+ float depth, depth_close= MAXFLOAT;
+ double cent[2], p[3], p_corner[3];
+ int xs, ys, had_depth = 0;
+
+ /* convert border to 3d coordinates */
+ bgl_get_mats(&mats);
+
+ draw_depth(curarea, (void *)v3d);
+
+ /* force updating */
+ if (v3d->depths) {
+ had_depth = 1;
+ v3d->depths->damaged = 1;
+ }
+
+ view3d_update_depths(v3d);
+
+ /* Constrain rect to depth bounds */
+ if (rect.xmin < 0) rect.xmin = 0;
+ if (rect.ymin < 0) rect.ymin = 0;
+ if (rect.xmax >= G.vd->depths->w) rect.xmax = G.vd->depths->w-1;
+ if (rect.ymax >= G.vd->depths->h) rect.ymax = G.vd->depths->h-1;
+
+ for (xs=rect.xmin; xs < rect.xmax; xs++) {
+ for (ys=rect.ymin; ys < rect.ymax; ys++) {
+ depth= v3d->depths->depths[ys*v3d->depths->w+xs];
+ if(depth < v3d->depths->depth_range[1] && depth > v3d->depths->depth_range[0]) {
+ if (depth_close > depth) {
+ depth_close = depth;
+ }
+ }
+ }
+ }
+
+ if (had_depth==0) {
+ MEM_freeN(v3d->depths->depths);
+ v3d->depths->depths = NULL;
+ }
+ v3d->depths->damaged = 1;
+
+ /* no depths to use*/
+ if (depth_close==MAXFLOAT)
+ return;
+
+ cent[0] = (((double)rect.xmin)+((double)rect.xmax)) / 2;
+ cent[1] = (((double)rect.ymin)+((double)rect.ymax)) / 2;
+
+ if (( !gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, mats.viewport, &p[0], &p[1], &p[2])) ||
+ ( !gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close, mats.modelview, mats.projection, mats.viewport, &p_corner[0], &p_corner[1], &p_corner[2])))
+ return;
+
+ dvec[0] = p[0]-p_corner[0];
+ dvec[1] = p[1]-p_corner[1];
+ dvec[2] = p[2]-p_corner[2];
+
+ new_dist = VecLength(dvec);
+ if(new_dist <= G.vd->near*1.5) new_dist= G.vd->near*1.5;
+
+ new_ofs[0] = -p[0];
+ new_ofs[1] = -p[1];
+ new_ofs[2] = -p[2];
+
+ } else { /* othographic */
/* find the current window width and height */
vb[0] = G.vd->area->winx;
vb[1] = G.vd->area->winy;
@@ -2228,10 +2290,9 @@ void view3d_border_zoom(void)
/* zoom in as required, or as far as we can go */
new_dist = ((new_dist*scale) >= 0.001*G.vd->grid)? new_dist*scale:0.001*G.vd->grid;
-
- smooth_view(G.vd, new_ofs, NULL, &new_dist, NULL);
-
}
+
+ smooth_view(G.vd, new_ofs, NULL, &new_dist, NULL);
}
void fly(void)
diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c
index a31f92c4b68..4bbb9f18263 100644
--- a/source/blender/src/header_action.c
+++ b/source/blender/src/header_action.c
@@ -1528,7 +1528,7 @@ void action_buttons(void)
xco= std_libbuttons(block, xco, 0, B_ACTPIN, &G.saction->pin,
B_ACTIONBROWSE, ID_AC, 0, (ID*)G.saction->action,
from, &(G.saction->actnr), B_ACTALONE,
- B_ACTLOCAL, B_ACTIONDELETE, 0, 0);
+ B_ACTLOCAL, B_ACTIONDELETE, 0, B_KEEPDATA);
uiClearButLock();
diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c
index b5abf0947e4..5bb9ffcba4e 100644
--- a/source/blender/src/header_image.c
+++ b/source/blender/src/header_image.c
@@ -617,7 +617,7 @@ static uiBlock *image_selectmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse|Ctrl I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unlink Selection|Alt L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index b8d13b493bb..5ec730bd097 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -934,7 +934,7 @@ static uiBlock *view3d_select_objectmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse|Ctrl I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Random", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiDefIconTextBlockBut(block, view3d_select_object_layermenu, NULL, ICON_RIGHTARROW_THIN, "Select All by Layer", 0, yco-=20, 120, 19, "");
@@ -1787,8 +1787,7 @@ static void do_view3d_transformmenu(void *arg, int event)
G.scene->snap_target = SCE_SNAP_TARGET_ACTIVE;
break;
case 21:
- initTransform(TFM_ALIGN, CTX_NO_PET|CTX_AUTOCONFIRM);
- Transform();
+ alignmenu();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -1977,7 +1976,7 @@ static uiBlock *view3d_edit_object_transformmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_object_transformmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_edit_object_transformmenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Scale/Rotationr to ObData|Ctrl A, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Scale/Rotation to ObData|Ctrl A, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Visual Transform|Ctrl A, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Deformation|Ctrl Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Duplicates Real|Ctrl Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
@@ -5638,7 +5637,7 @@ void view3d_buttons(void)
xco+= XIC;
}
- str_menu = BIF_menustringTransformOrientation();
+ str_menu = BIF_menustringTransformOrientation("Orientation");
uiDefButS(block, MENU, B_MAN_MODE, str_menu,xco,0,70,YIC, &G.vd->twmode, 0, 0, 0, 0, "Transform Orientation (ALT+Space)");
MEM_freeN(str_menu);
diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c
index dde5a512de9..43ca45ffb67 100644
--- a/source/blender/src/headerbuttons.c
+++ b/source/blender/src/headerbuttons.c
@@ -364,14 +364,13 @@ int std_libbuttons(uiBlock *block, short xco, short yco,
}
if(del) {
-
uiSetButLock (pin && *pinpoin, "Can't unlink pinned data");
if(parid && parid->lib);
else {
uiDefIconBut(block, BUT, del, ICON_X, xco,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes link to this Datablock");
xco+= XIC;
}
-
+
uiClearButLock();
}
@@ -385,7 +384,10 @@ int std_libbuttons(uiBlock *block, short xco, short yco,
}
if(keepbut) {
- uiDefBut(block, BUT, keepbut, "F", xco,yco,XIC,YIC, 0, 0, 0, 0, 0, "Saves this datablock even if it has no users");
+ if(id->flag & LIB_FAKEUSER)
+ uiDefBut(block, BUT, keepbut, "F", xco,yco,XIC,YIC, 0, 0, 0, 0, 0, "Don't save this datablock even if it has no users");
+ else
+ uiDefBut(block, BUT, keepbut, "F", xco,yco,XIC,YIC, 0, 0, 0, 0, 0, "Saves this datablock even if it has no users");
xco+= XIC;
}
}
@@ -918,23 +920,30 @@ void do_global_buttons(unsigned short event)
}
break;
case B_ACTIONDELETE:
- act=ob->action;
-
- if (act)
- act->id.us--;
- ob->action=NULL;
- if(ob->pose) { // clear flag, also used for draw colors
- bPoseChannel *pchan;
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
- pchan->flag= 0;
- }
- BIF_undo_push("Unlink Action");
-
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWBUTSEDIT, 0);
+ /* only available when not pinned */
+ if (G.saction->pin == 0) {
+ act= ob->action;
+
+ /* decrement user-count of action (as ob no longer uses it) */
+ if (act)
+ act->id.us--;
+
+ /* make sure object doesn't hold reference to it anymore */
+ ob->action=NULL;
+ if (ob->pose) { /* clear flag (POSE_LOC/ROT/SIZE), also used for draw colors */
+ bPoseChannel *pchan;
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
+ pchan->flag= 0;
+ }
+
+ BIF_undo_push("Unlink Action");
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
break;
case B_ACTIONBROWSE:
if (!ob)
@@ -947,18 +956,16 @@ void do_global_buttons(unsigned short event)
return;
}
- if(G.saction->actnr < 0) break;
+ if (G.saction->actnr < 0) break;
/* See if we have selected a valid action */
for (idtest= G.main->action.first; idtest; idtest= idtest->next) {
- if(nr==G.saction->actnr) {
- break;
- }
- nr++;
-
+ if (nr==G.saction->actnr)
+ break;
+ nr++;
}
- if(G.saction->pin) {
+ if (G.saction->pin) {
if (idtest == NULL) {
/* assign new/copy of pinned action only - messy as it doesn't assign to any obj's */
if (G.saction->action)
@@ -972,9 +979,8 @@ void do_global_buttons(unsigned short event)
allqueue(REDRAWACTION, 0);
}
else {
-
/* Store current action */
- if (!idtest) {
+ if (idtest == NULL) {
/* 'Add New' option:
* - make a copy of an exisiting action
* - or make a new empty action if no existing action
@@ -983,10 +989,37 @@ void do_global_buttons(unsigned short event)
idtest= (ID *)copy_action(act);
}
else {
- if (ID_OB==ob->type) {
- /* for empties */
- idtest=(ID *)add_empty_action("ObAction");
- }
+ if ((ob->ipo) && (ob->ipoflag & OB_ACTION_OB)==0) {
+ /* object ipo - like if B_IPO_ACTION_OB is triggered */
+ bActionChannel *achan;
+
+ if (has_ipo_code(ob->ipo, OB_LAY))
+ notice("Note: Layer Ipo doesn't work in Actions");
+
+ ob->ipoflag |= OB_ACTION_OB;
+
+ act = add_empty_action("ObAction");
+ idtest=(ID *)act;
+
+
+ achan= verify_action_channel(act, "Object");
+ achan->flag = (ACHAN_HILIGHTED|ACHAN_SELECTED|ACHAN_EXPANDED|ACHAN_SHOWIPO);
+
+ if (achan->ipo==NULL) {
+ achan->ipo= ob->ipo;
+ ob->ipo= NULL;
+
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWOOPS, 0);
+ }
+
+ /* object constraints */
+ if (ob->constraintChannels.first) {
+ free_constraint_channels(&achan->constraintChannels);
+ achan->constraintChannels= ob->constraintChannels;
+ ob->constraintChannels.first= ob->constraintChannels.last= NULL;
+ }
+ }
else if (ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) {
/* shapekey - like if B_IPO_ACTION_KEY is triggered */
bActionChannel *achan;
@@ -1000,11 +1033,10 @@ void do_global_buttons(unsigned short event)
achan= verify_action_channel(act, "Shape");
achan->flag = (ACHAN_HILIGHTED|ACHAN_SELECTED|ACHAN_EXPANDED|ACHAN_SHOWIPO);
- if(achan->ipo==NULL && key->ipo) {
+ if ((achan->ipo==NULL) && (key->ipo)) {
achan->ipo= key->ipo;
key->ipo= NULL;
- allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWOOPS, 0);
}
@@ -1018,15 +1050,15 @@ void do_global_buttons(unsigned short event)
}
- if(idtest!=id && ob) {
+ if ((idtest!=id) && (ob)) {
act= (bAction *)idtest;
ob->action= act;
id_us_plus(idtest);
- if(id) id->us--;
+ if (id) id->us--;
- // Update everything
+ /* Update everything */
BIF_undo_push("Browse Action");
do_global_buttons (B_NEWFRAME);
allqueue(REDRAWVIEW3D, 0);
@@ -1096,7 +1128,7 @@ void do_global_buttons(unsigned short event)
}
if(idtest!=id && from) {
spaceipo_assign_ipo(G.sipo, (Ipo *)idtest);
-
+
BIF_undo_push("Browse Ipo");
}
}
@@ -1613,7 +1645,9 @@ void do_global_buttons(unsigned short event)
id = (ID *)G.sipo->ipo;
} else if(curarea->spacetype==SPACE_NODE) {
id = ((SpaceNode *)curarea->spacedata.first)->id;
- } /* similar for other spacetypes ? */
+ } else if(curarea->spacetype==SPACE_ACTION) {
+ id= (ID *)G.saction->action;
+ }/* similar for other spacetypes ? */
if (id) {
if( id->flag & LIB_FAKEUSER) {
id->flag -= LIB_FAKEUSER;
diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c
index 7b8efd0ed75..539fde5b14d 100644
--- a/source/blender/src/imagepaint.c
+++ b/source/blender/src/imagepaint.c
@@ -593,8 +593,10 @@ static void imapaint_paint_stroke(ImagePaintState *s, BrushPainter *painter, sho
if(ibuf && ibuf->rect)
texpaint_pick_uv(s->ob, s->me, newfaceindex, mval, newuv);
- else
+ else {
newimage = NULL;
+ newuv[0] = newuv[1] = 0.0f;
+ }
}
else
newuv[0] = newuv[1] = 0.0f;
diff --git a/source/blender/src/interface_panel.c b/source/blender/src/interface_panel.c
index 0752a5dd198..de1e70caeec 100644
--- a/source/blender/src/interface_panel.c
+++ b/source/blender/src/interface_panel.c
@@ -606,7 +606,9 @@ static int panel_has_tabs(Panel *panel)
if(panel==NULL) return 0;
while(pa) {
- if(pa->paneltab==panel) return 1;
+ if(pa->active && pa->paneltab==panel) {
+ return 1;
+ }
pa= pa->next;
}
return 0;
diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c
index 8ac0a1f2558..f40ecb74948 100644
--- a/source/blender/src/meshtools.c
+++ b/source/blender/src/meshtools.c
@@ -1097,15 +1097,17 @@ void objects_bake_render(short event, char **error_msg)
if(bkr.ready)
break;
- g_break= blender_test_break();
-
- timer++;
- if(area && timer==20) {
- Image *ima= RE_bake_shade_get_image();
- if(ima) ((SpaceImage *)area->spacedata.first)->image= ima;
- scrarea_do_windraw(area);
- myswapbuffers();
- timer= 0;
+ if (!G.background) {
+ g_break= blender_test_break();
+
+ timer++;
+ if(area && timer==20) {
+ Image *ima= RE_bake_shade_get_image();
+ if(ima) ((SpaceImage *)area->spacedata.first)->image= ima;
+ scrarea_do_windraw(area);
+ myswapbuffers();
+ timer= 0;
+ }
}
}
BLI_end_threads(&threads);
diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c
index 3fda71bf828..715a0f47afa 100644
--- a/source/blender/src/sculptmode.c
+++ b/source/blender/src/sculptmode.c
@@ -1231,7 +1231,7 @@ void init_brushaction(BrushAction *a, short *mouse, short *pr_mouse)
/* Set the pivot to allow the model to rotate around the center of the brush */
if(get_depth(mouse[0],mouse[1]) < 1.0)
- VecCopyf(&sculpt_session()->pivot.x, a->symm.center_3d);
+ VecCopyf(sd->pivot, a->symm.center_3d);
/* Now project the Up, Right, and Out normals from view to model coords */
unproject(zero_loc, 0, 0, 0);
@@ -1692,7 +1692,7 @@ void sculpt(void)
}
else {
do_symmetrical_brush_actions(a, mouse, mvalo);
- unproject(&ss->pivot.x, mouse[0], mouse[1], a->depth);
+ unproject(sd->pivot, mouse[0], mouse[1], a->depth);
}
if(modifier_calculations || ob_get_keyblock(ob))
diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c
index 8b669d034d0..eb362f7187e 100644
--- a/source/blender/src/seqaudio.c
+++ b/source/blender/src/seqaudio.c
@@ -359,37 +359,53 @@ static void audio_fill_hd_sound(Sequence *seq,
}
static void audio_fill_seq(Sequence * seq, void * mixdown,
- Uint8 *sstream, int len)
+ Uint8 *sstream, int len, int advance_only)
{
while(seq) {
if (seq->type == SEQ_META &&
(!(seq->flag & SEQ_MUTE))) {
- audio_fill_seq(seq->seqbase.first,
- mixdown, sstream, len);
+ if (seq->startdisp <= CFRA && seq->enddisp > CFRA) {
+ audio_fill_seq(seq->seqbase.first,
+ mixdown, sstream, len,
+ advance_only);
+ } else {
+ audio_fill_seq(seq->seqbase.first,
+ mixdown, sstream, len,
+ 1);
+ }
}
if ( (seq->type == SEQ_RAM_SOUND) &&
(seq->sound) &&
(!(seq->flag & SEQ_MUTE))) {
- audio_fill_ram_sound(seq, mixdown, sstream, len);
+ if (advance_only) {
+ seq->curpos += len;
+ } else {
+ audio_fill_ram_sound(
+ seq, mixdown, sstream, len);
+ }
}
if ( (seq->type == SEQ_HD_SOUND) &&
(!(seq->flag & SEQ_MUTE))) {
- if (!seq->hdaudio) {
- char name[FILE_MAXDIR+FILE_MAXFILE];
-
- strncpy(name, seq->strip->dir,
- FILE_MAXDIR-1);
- strncat(name,
- seq->strip->stripdata->name,
- FILE_MAXFILE-1);
- BLI_convertstringcode(name, G.sce,
- G.scene->r.cfra);
+ if (advance_only) {
+ seq->curpos += len;
+ } else {
+ if (!seq->hdaudio) {
+ char name[FILE_MAXDIR+FILE_MAXFILE];
+
+ strncpy(name, seq->strip->dir,
+ FILE_MAXDIR-1);
+ strncat(name,
+ seq->strip->stripdata->name,
+ FILE_MAXFILE-1);
+ BLI_convertstringcode(name, G.sce,
+ G.scene->r.cfra);
- seq->hdaudio= sound_open_hdaudio(name);
- }
- if (seq->hdaudio) {
- audio_fill_hd_sound(seq, mixdown,
- sstream, len);
+ seq->hdaudio= sound_open_hdaudio(name);
+ }
+ if (seq->hdaudio) {
+ audio_fill_hd_sound(seq, mixdown,
+ sstream, len);
+ }
}
}
seq = seq->next;
@@ -404,7 +420,7 @@ void audio_fill(void *mixdown, Uint8 *sstream, int len)
ed = G.scene->ed;
if((ed) && (!(G.scene->audio.flag & AUDIO_MUTE))) {
seq = ed->seqbasep->first;
- audio_fill_seq(seq, mixdown, sstream, len);
+ audio_fill_seq(seq, mixdown, sstream, len, 0);
}
audio_pos += len;
@@ -501,7 +517,8 @@ void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown)
desired.format=AUDIO_S16SYS;
desired.channels=2;
desired.samples=U.mixbufsize;
- desired.userdata=0;
+ desired.userdata=0;
+
if (audio_init(&desired)==0) {
U.mixbufsize = 0; /* no audio */
}
diff --git a/source/blender/src/seqeffects.c b/source/blender/src/seqeffects.c
index 95cae4c888d..85693546789 100644
--- a/source/blender/src/seqeffects.c
+++ b/source/blender/src/seqeffects.c
@@ -986,7 +986,7 @@ static void do_gammacross_effect_float(float facf0, float facf1,
float *rect1, float *rect2,
float *out)
{
- float fac1, fac2, col;
+ float fac1, fac2;
int xo;
float *rt1, *rt2, *rt;
@@ -1015,7 +1015,7 @@ static void do_gammacross_effect_float(float facf0, float facf1,
x= xo * 4;
while(x--) {
- col= gammaCorrect(
+ *rt= gammaCorrect(
fac1*invGammaCorrect(*rt1)
+ fac2*invGammaCorrect(*rt2));
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 15ed21d3d1a..0cc1764854a 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -1793,10 +1793,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case AKEY:
if (G.obedit == 0 && G.qual == (LR_CTRLKEY|LR_ALTKEY)) {
- if(okee("Align to Transform Orientation")) {
- initTransform(TFM_ALIGN, CTX_NO_PET|CTX_AUTOCONFIRM);
- Transform();
- }
+ alignmenu();
}
else if(G.qual & LR_CTRLKEY) { /* also with shift! */
apply_object();
@@ -2156,18 +2153,17 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case IKEY:
- if(G.obedit) {
- if(G.qual==LR_CTRLKEY)
+ if(G.qual==LR_CTRLKEY) {
+ if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
+ pose_add_IK();
+ else if(ob && G.obedit)
selectswap_mesh();
- } else if(G.qual==LR_CTRLKEY) {
- if(ob && ob->type==OB_ARMATURE)
- if(ob->flag & OB_POSEMODE)
- pose_add_IK();
+ else
+ selectswap();
}
else if(G.qual==LR_ALTKEY) {
- if(ob && ob->type==OB_ARMATURE)
- if(ob->flag & OB_POSEMODE)
- pose_clear_IK();
+ if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
+ pose_clear_IK();
}
break;
@@ -5321,6 +5317,10 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if((G.qual==0))
hide_tface_uv(0);
break;
+ case IKEY:
+ if(G.qual==LR_CTRLKEY)
+ select_invert_tface_uv();
+ break;
case LKEY:
if(G.qual==0)
select_linked_tface_uv(0);
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index d846ba2c197..5838a09e160 100644
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -467,7 +467,7 @@ static void viewRedrawPost(TransInfo *t)
void BIF_selectOrientation() {
short val;
- char *str_menu = BIF_menustringTransformOrientation();
+ char *str_menu = BIF_menustringTransformOrientation("Orientation");
val= pupmenu(str_menu);
MEM_freeN(str_menu);
@@ -1288,21 +1288,43 @@ void ManipulatorTransform()
}
if(val) {
switch(event) {
- case WHEELDOWNMOUSE:
case PADPLUSKEY:
- if(Trans.flag & T_PROP_EDIT) {
+ if(G.qual & LR_ALTKEY && Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 1.1f;
calculatePropRatio(&Trans);
- Trans.redraw= 1;
}
+ Trans.redraw= 1;
+ break;
+ case PAGEUPKEY:
+ case WHEELDOWNMOUSE:
+ if (Trans.flag & T_AUTOIK) {
+ transform_autoik_update(&Trans, 1);
+ }
+ else if(Trans.flag & T_PROP_EDIT) {
+ Trans.propsize*= 1.1f;
+ calculatePropRatio(&Trans);
+ }
+ else view_editmove(event);
+ Trans.redraw= 1;
break;
- case WHEELUPMOUSE:
case PADMINUS:
- if(Trans.flag & T_PROP_EDIT) {
+ if(G.qual & LR_ALTKEY && Trans.flag & T_PROP_EDIT) {
+ Trans.propsize*= 0.90909090f;
+ calculatePropRatio(&Trans);
+ }
+ Trans.redraw= 1;
+ break;
+ case PAGEDOWNKEY:
+ case WHEELUPMOUSE:
+ if (Trans.flag & T_AUTOIK) {
+ transform_autoik_update(&Trans, -1);
+ }
+ else if (Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 0.90909090f;
calculatePropRatio(&Trans);
- Trans.redraw= 1;
}
+ else view_editmove(event);
+ Trans.redraw= 1;
break;
}
@@ -2126,7 +2148,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
VecMulf(vec, td->factor);
- if (t->flag & T_OBJECT) {
+ if (t->flag & (T_OBJECT|T_POSE)) {
Mat3MulVecfl(td->smtx, vec);
}
diff --git a/source/blender/src/transform_orientations.c b/source/blender/src/transform_orientations.c
index 1502ea70582..849644e3791 100644
--- a/source/blender/src/transform_orientations.c
+++ b/source/blender/src/transform_orientations.c
@@ -313,18 +313,19 @@ void BIF_selectTransformOrientationFromIndex(int index) {
G.vd->twmode = V3D_MANIP_CUSTOM + index;
}
-char * BIF_menustringTransformOrientation() {
- char menu[] = "Orientation%t|Global%x0|Local%x1|Normal%x2|View%x3";
+char * BIF_menustringTransformOrientation(char *title) {
+ char menu[] = "%t|Global%x0|Local%x1|Normal%x2|View%x3";
ListBase *transform_spaces = &G.scene->transform_spaces;
TransformOrientation *ts;
int i = V3D_MANIP_CUSTOM;
char *str_menu, *p;
- str_menu = MEM_callocN(strlen(menu) + 40 * BIF_countTransformOrientation(), "UserTransSpace from matrix");
+ str_menu = MEM_callocN(strlen(menu) + strlen(title) + 40 * BIF_countTransformOrientation(), "UserTransSpace from matrix");
p = str_menu;
- p += sprintf(str_menu, "%s", menu);
+ p += sprintf(str_menu, "%s", title);
+ p += sprintf(p, "%s", menu);
for (ts = transform_spaces->first; ts; ts = ts->next) {
p += sprintf(p, "|%s%%x%d", ts->name, i++);
diff --git a/source/blender/src/view.c b/source/blender/src/view.c
index 7491fc6fbc8..24ee2f96479 100644
--- a/source/blender/src/view.c
+++ b/source/blender/src/view.c
@@ -777,7 +777,7 @@ void viewmove(int mode)
use_sel= 1;
VecCopyf(ofs, G.vd->ofs);
- VecCopyf(obofs,&sculpt_session()->pivot.x);
+ VecCopyf(obofs, sculpt_data()->pivot);
Mat4MulVecfl(ob->obmat, obofs);
obofs[0]= -obofs[0];
obofs[1]= -obofs[1];
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 271385bb144..5a7423e00b1 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1670,7 +1670,7 @@ static KX_GameObject *gameobject_from_blenderobject(
break;
}
}
-
+ gameobj->SetPhysicsEnvironment(kxscene->GetPhysicsEnvironment());
return gameobj;
}
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 465a021cd43..ebbca137c5a 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -888,6 +888,10 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
{
ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
}
+ if (objprop->m_ghost)
+ {
+ ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
+ }
ci.m_MotionState = motionstate;
ci.m_gravity = btVector3(0,0,0);
@@ -1141,10 +1145,11 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
if (objprop->m_disableSleeping)
rbody->setActivationState(DISABLE_DEACTIVATION);
- if (objprop->m_ghost)
- {
- rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
- }
+ //Now done directly in ci.m_collisionFlags so that it propagates to replica
+ //if (objprop->m_ghost)
+ //{
+ // rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
+ //}
if (objprop->m_dyna && !objprop->m_angular_rigidbody)
{
/*
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index bc608d26c50..6f172a11005 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -61,6 +61,7 @@ typedef unsigned long uint_ptr;
#include "SG_Controller.h"
#include "KX_ClientObjectInfo.h"
#include "RAS_BucketManager.h"
+#include "KX_RayCast.h"
#include "KX_PyMath.h"
@@ -80,7 +81,9 @@ KX_GameObject::KX_GameObject(
m_bUseObjectColor(false),
m_bVisible(true),
m_pPhysicsController1(NULL),
- m_isDeformable(false)
+ m_pPhysicsEnvironment(NULL),
+ m_isDeformable(false),
+ m_pHitObject(NULL)
{
m_ignore_activity_culling = false;
m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR);
@@ -657,6 +660,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
{"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS},
KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
+ KX_PYMETHODTABLE(KX_GameObject, rayCastTo),
{NULL,NULL} //Sentinel
};
@@ -1176,6 +1180,83 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo,
return NULL;
}
+bool KX_GameObject::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
+{
+
+ KX_GameObject* hitKXObj = client->m_gameobject;
+
+ if (client->m_type > KX_ClientObjectInfo::ACTOR)
+ {
+ // false hit
+ return false;
+ }
+
+ if (m_testPropName.Length() == 0 || hitKXObj->GetProperty(m_testPropName) != NULL)
+ {
+ m_pHitObject = hitKXObj;
+ return true;
+ }
+
+ return false;
+
+}
+
+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"
+" 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")
+{
+ MT_Point3 toPoint;
+ PyObject* pyarg;
+ float dist = 0.0f;
+ char *propName = NULL;
+
+ if (!PyArg_ParseTuple(args,"O|fs", &pyarg, &dist, &propName))
+ return NULL;
+
+ if (!PyVecTo(pyarg, toPoint))
+ {
+ KX_GameObject *other;
+ PyErr_Clear();
+ if (!PyType_IsSubtype(pyarg->ob_type, &KX_GameObject::Type))
+ return NULL;
+ other = static_cast<KX_GameObject*>(pyarg);
+ toPoint = other->NodeGetWorldPosition();
+ }
+ MT_Point3 fromPoint = NodeGetWorldPosition();
+ if (dist != 0.0f)
+ {
+ MT_Vector3 toDir = toPoint-fromPoint;
+ toDir.normalize();
+ toPoint = fromPoint + (dist) * toDir;
+ }
+
+ MT_Point3 resultPoint;
+ MT_Vector3 resultNormal;
+ PHY_IPhysicsEnvironment* pe = GetPhysicsEnvironment();
+ KX_IPhysicsController *spc = GetPhysicsController();
+ KX_GameObject *parent = GetParent();
+ if (!spc && parent)
+ spc = parent->GetPhysicsController();
+ if (parent)
+ parent->Release();
+
+ m_pHitObject = NULL;
+ if (propName)
+ m_testPropName = propName;
+ else
+ m_testPropName.SetLength(0);
+ KX_RayCast::RayTest(spc, pe, fromPoint, toPoint, resultPoint, resultNormal, KX_RayCast::Callback<KX_GameObject>(this));
+
+ if (m_pHitObject)
+ {
+ m_pHitObject->AddRef();
+ return m_pHitObject;
+ }
+ 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 db910a46a81..945b769d8be 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -57,6 +57,7 @@
struct KX_ClientObjectInfo;
class RAS_MeshObject;
class KX_IPhysicsController;
+class PHY_IPhysicsEnvironment;
/**
@@ -82,6 +83,11 @@ protected:
bool m_bVisible;
KX_IPhysicsController* m_pPhysicsController1;
+ // used for ray casting
+ PHY_IPhysicsEnvironment* m_pPhysicsEnvironment;
+ STR_String m_testPropName;
+ KX_GameObject* m_pHitObject;
+
SG_Node* m_pSGNode;
MT_CmMatrix4x4 m_OpenGL_4x4Matrix;
@@ -262,6 +268,19 @@ public:
/**
+ * @return a pointer to the physics environment in use during the game, for rayCasting
+ */
+ PHY_IPhysicsEnvironment* GetPhysicsEnvironment()
+ {
+ return m_pPhysicsEnvironment;
+ }
+
+ void SetPhysicsEnvironment(PHY_IPhysicsEnvironment* physicsEnvironment)
+ {
+ m_pPhysicsEnvironment = physicsEnvironment;
+ }
+
+ /**
* @return a pointer to the physics controller owned by this class.
*/
@@ -341,6 +360,8 @@ public:
return m_bDyna;
}
+ bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+
/**
* @section Physics accessors for this node.
@@ -608,6 +629,7 @@ public:
KX_PYMETHOD(KX_GameObject,GetMesh);
KX_PYMETHOD(KX_GameObject,GetParent);
KX_PYMETHOD(KX_GameObject,GetPhysicsId);
+ KX_PYMETHOD_DOC(KX_GameObject,rayCastTo);
KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo);
private :
diff --git a/source/nan_compile.mk b/source/nan_compile.mk
index afea7a01239..665fdd3939b 100644
--- a/source/nan_compile.mk
+++ b/source/nan_compile.mk
@@ -50,6 +50,11 @@ else
CPPFLAGS += -DNO_KETSJI
endif
+ifeq ($(WITH_BF_OPENMP), true)
+ CFLAGS += -fopenmp
+ CCFLAGS += -fopenmp
+endif
+
ifdef NAN_DEBUG
CFLAGS += $(NAN_DEBUG)
CCFLAGS += $(NAN_DEBUG)
diff --git a/source/nan_link.mk b/source/nan_link.mk
index e0745e9c1d4..f4a90b0f927 100644
--- a/source/nan_link.mk
+++ b/source/nan_link.mk
@@ -173,4 +173,8 @@ ifeq ($(INTERNATIONAL),true)
LLIBS += $(NAN_GETTEXT_LIB)
endif
+ifeq ($(WITH_BF_OPENMP),true)
+ LLIBS += -lgomp
+endif
+
LLIBS += $(NAN_PYTHON_LIB)
diff --git a/tools/btools.py b/tools/btools.py
index a1a953296d9..35b9682f6a3 100755
--- a/tools/btools.py
+++ b/tools/btools.py
@@ -6,7 +6,7 @@ import SCons.Options.BoolOption
try:
import subprocess
except ImportError:
- pass
+ pass
import string
import glob
import shutil
@@ -59,7 +59,7 @@ def validate_arguments(args, bc):
'WITHOUT_BF_INSTALL',
'WITH_BF_OPENMP',
'WITHOUT_BF_INSTALL',
- 'BF_FANCY',
+ 'BF_FANCY', 'BF_QUIET'
]
arg_list = ['BF_DEBUG', 'BF_QUIET', 'BF_CROSS', 'BF_UPDATE',
@@ -251,7 +251,7 @@ def read_opts(cfg, args):
('BF_FREETYPE_LIB', 'Freetype library', ''),
('BF_FREETYPE_LIBPATH', 'Freetype library path', ''),
- (BoolOption('WITH_BF_OPENMP', 'Use OpenMP if true', 'false')),
+ (BoolOption('WITH_BF_OPENMP', 'Use OpenMP if true', 'false')),
(BoolOption('WITH_BF_QUICKTIME', 'Use QuickTime if true', 'false')),
('BF_QUICKTIME', 'QuickTime base path', ''),
@@ -293,7 +293,7 @@ def read_opts(cfg, args):
('BF_DEBUG_FLAGS', 'Debug flags', ''),
(BoolOption('BF_BSC', 'Create .bsc files (msvc only)', 'true')),
-
+
('BF_BUILDDIR', 'Build dir', ''),
('BF_INSTALLDIR', 'Installation dir', ''),
@@ -306,7 +306,8 @@ def read_opts(cfg, args):
(BoolOption('BF_SPLIT_SRC', 'Split src lib into several chunks if true', 'false')),
(BoolOption('WITHOUT_BF_INSTALL', 'dont install if true', 'false')),
(BoolOption('BF_FANCY', 'Enable fancy output if true', 'true')),
- (BoolOption('WITH_BF_BINRELOC', 'Enable relocatable binary (linux only)', 'false')),
+ (BoolOption('BF_QUIET', 'Enable silent output if true', 'true')),
+ (BoolOption('WITH_BF_BINRELOC', 'Enable relocatable binary (linux only)', 'false')),
) # end of opts.AddOptions()