soc-2008-mxcurioni: merged changes to revision 14798, compilation works for rendering/ directry. Still needs to figure out how to compile on non-Unix machines.

This commit is contained in:
Maxime Curioni 2008-05-11 20:28:47 +00:00
commit c785d7493e
45 changed files with 2715 additions and 1703 deletions

@ -73,7 +73,9 @@ GHOST_NDOFManager::deviceOpen(GHOST_IWindow* window,
if (ndofLibraryInit && ndofDeviceOpen)
{
Pid= ndofLibraryInit();
#if 0
printf("%i client \n", Pid);
#endif
#if defined(_WIN32) || defined(__APPLE__)
m_DeviceHandle = ndofDeviceOpen((void *)&currentNdofValues);
#else

@ -283,9 +283,11 @@ GHOST_TSuccess GHOST_System::init()
m_eventManager = new GHOST_EventManager ();
m_ndofManager = new GHOST_NDOFManager();
#if 0
if(m_ndofManager)
printf("ndof manager \n");
#endif
#ifdef GHOST_DEBUG
if (m_eventManager) {
m_eventManager->addConsumer(&m_eventPrinter);

@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
"""
Name: '3D Studio (.3ds)...'
Blender: 243

@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
""" Registration info for Blender menus
Name: 'Bevel Center'
Blender: 243

@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
"""
Name: 'BlenderLipSynchro'
Blender: 242

@ -1,4 +1,5 @@
#!BPY
# coding: utf-8
""" Registration info for Blender menus:
Name: 'M3G (.m3g, .java)...'
Blender: 244
@ -3069,4 +3070,5 @@ def file_callback_m3g(filename):
Window.RedrawAll()
if __name__ == '__main__':
gui()
gui()

@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
""" Registration info for Blender menus:
Name: 'HotKey and MouseAction Reference'
Blender: 242
@ -918,4 +918,4 @@ def bevent(evt):
Blender.Window.Redraw()
if __name__ == '__main__':
Register(draw, event, bevent)
Register(draw, event, bevent)

@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
"""
Name: 'Autodesk DXF (.dxf)'
Blender: 244
@ -5942,4 +5942,5 @@ if 1:
main(_dxf)
print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
"""
"""

@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
"""
Name: 'Paths (.svg, .ps, .eps, .ai, Gimp)'
Blender: 233
@ -92,4 +92,5 @@ elif argv=='Gimp_2_0':
fonctionSELECT = functionSELECT # can they all be called function?
text = 'Import %s' % argv
Blender.Window.FileSelector (fonctionSELECT, text)
Blender.Window.FileSelector (fonctionSELECT, text)

@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
""" Registration info for Blender menus: <- these words are ignored
Name: 'Deformed mesh to Rvk'
Blender: 243
@ -270,4 +270,4 @@ def deform2rvk():
EDITMODE=Blender.Window.EditMode()
Blender.Window.EditMode(0)
deform2rvk()
Blender.Window.EditMode(EDITMODE)
Blender.Window.EditMode(EDITMODE)

@ -1054,7 +1054,11 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys)
psysn->childcache= NULL;
psysn->edit= NULL;
psysn->effectors.first= psysn->effectors.last= 0;
psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL;
psysn->reactevents.first = psysn->reactevents.last = NULL;
psysn->renderdata = NULL;
psysn->pointcache= BKE_ptcache_copy(psys->pointcache);
id_us_plus((ID *)psysn->part);

@ -45,6 +45,12 @@ prefix = 'intern/stroke'
stroke_sources = env.Glob(prefix + '/*.cpp')
# rendering
prefix = 'intern/rendering'
stroke_sources = env.Glob(prefix + '/GL*.cpp')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
stroke_sources = env.Glob(prefix + '/extgl.cpp')
# app
sources = system_sources + image_sources + geometry_sources + scene_graph_sources + \

@ -281,7 +281,7 @@ void GLRenderer::visitLineRep( LineRep& iLine)
}
const vector<Vec3r>& vertices = iLine.vertices();
float step=1.f/vertices.size();
//soc unused float step=1.f/vertices.size();
vector<Vec3r>::const_iterator v;
for(v=vertices.begin(); v!=vertices.end(); v++)

@ -19,12 +19,18 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <qimage.h>
#include <qfileinfo.h>
#include <qgl.h>
#include <qfile.h>
#include "GLStrokeRenderer.h"
//soc
// #include <qimage.h>
// #include <qfileinfo.h>
// #include <qgl.h>
// #include <qfile.h>
#include "BLI_blenlib.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "../system/StringUtils.h"
#ifdef WIN32
# include "extgl.h"
#endif // WIN32
@ -77,7 +83,7 @@ void GLStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
// renderNoTexture(iStrokeRep);
// return;
// }
int i;
//soc unused - int i;
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -150,8 +156,8 @@ void GLStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
void GLStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
{
glPushAttrib(GL_COLOR_BUFFER_BIT);
Stroke::MediumType strokeType = iStrokeRep->getMediumType();
int i;
//soc unused - Stroke::MediumType strokeType = iStrokeRep->getMediumType();
//soc unused - int i;
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -273,7 +279,7 @@ GLTextureManager::loadPapers ()
_papertexname = new unsigned[size];
GLuint *tmp = new GLuint[size];
glGenTextures(size, tmp);
for(int i=0;i<size;++i){
for(unsigned i=0;i<size;++i){
_papertexname[i] = tmp[i];
}
delete [] tmp;
@ -308,13 +314,14 @@ GLTextureManager::loadBrush(string sname, Stroke::MediumType mediumType)
glGenTextures(1, &texId);
bool found = false;
vector<string> pathnames;
QString path;
string path; //soc
StringUtils::getPathName(TextureManager::Options::getBrushesPath(),
sname,
pathnames);
for (vector<string>::const_iterator j = pathnames.begin(); j != pathnames.end(); j++) {
path = j->c_str();
if(QFile::exists(path)){
//soc if(QFile::exists(path)){
if( BLI_exists( const_cast<char *>(path.c_str()) ) ) {
found = true;
break;
}
@ -325,12 +332,14 @@ GLTextureManager::loadBrush(string sname, Stroke::MediumType mediumType)
cout << "Loading brush texture..." << endl;
switch(mediumType){
case Stroke::DRY_MEDIUM:
prepareTextureLuminance((const char*)path.toAscii(), texId);
//soc prepareTextureLuminance((const char*)path.toAscii(), texId);
prepareTextureLuminance(StringUtils::toAscii(path), texId);
break;
case Stroke::HUMID_MEDIUM:
case Stroke::OPAQUE_MEDIUM:
default:
prepareTextureAlpha((const char*)path.toAscii(), texId);
//soc prepareTextureAlpha((const char*)path.toAscii(), texId);
prepareTextureAlpha(StringUtils::toAscii(path), texId);
break;
}
cout << "Done." << endl << endl;
@ -341,18 +350,26 @@ GLTextureManager::loadBrush(string sname, Stroke::MediumType mediumType)
bool
GLTextureManager::prepareTextureAlpha (string sname, GLuint itexname)
{
const char * name = sname.c_str();
QImage qim(name);
QFileInfo fi(name);
QString filename = fi.fileName();
if (qim.isNull())
//soc const char * name = sname.c_str();
char * name = (char *) sname.c_str();
//soc
// QImage qim(name);
// QFileInfo fi(name);
// QString filename = fi.fileName();
ImBuf *qim = IMB_loadiffname(name, 0);
char filename[FILE_MAXFILE];
BLI_splitdirstring(name, filename);
//soc if (qim.isNull())
if( qim )
{
cerr << " Error: unable to read \"" << name << "\"" << endl;
return false;
}
if (qim.depth()>8)
if( qim->depth > 8) //soc
{
cerr<<" Error: \""<< name <<"\" has "<<qim.depth()<<" bits/pixel"<<endl;
cerr<<" Error: \""<< name <<"\" has "<< qim->depth <<" bits/pixel"<<endl; //soc
return false;
}
// qim=QGLWidget::convertToGLFormat( qimOri );
@ -369,11 +386,12 @@ GLTextureManager::prepareTextureAlpha (string sname, GLuint itexname)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, qim.width(), qim.height(), 0,
GL_ALPHA, GL_UNSIGNED_BYTE, qim.bits());
cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl;
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, qim->x, qim->y, 0,
GL_ALPHA, GL_UNSIGNED_BYTE, qim->rect); //soc
//soc cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl;
cout << " \"" << StringUtils::toAscii(filename) << "\" loaded with "<< qim->depth << " bits per pixel" << endl;
return true;
}
@ -381,18 +399,25 @@ GLTextureManager::prepareTextureAlpha (string sname, GLuint itexname)
bool
GLTextureManager::prepareTextureLuminance (string sname, GLuint itexname)
{
const char * name = sname.c_str();
QImage qim(name);
QFileInfo fi(name);
QString filename = fi.fileName();
if (qim.isNull())
//soc const char * name = sname.c_str();
char * name = (char *) sname.c_str();
//soc
// QImage qim(name);
// QFileInfo fi(name);
// QString filename = fi.fileName();
ImBuf *qim = IMB_loadiffname(name, 0);
char filename[FILE_MAXFILE];
BLI_splitdirstring(name, filename);
if (qim) //soc
{
cerr << " Error: unable to read \"" << name << "\"" << endl;
return false;
}
if (qim.depth() > 8)
if (qim->depth > 8) //soc
{
cerr<<" Error: \""<<name<<"\" has "<<qim.depth()<<" bits/pixel"<<endl;
cerr<<" Error: \""<<name<<"\" has "<<qim->depth <<" bits/pixel"<<endl;//soc
return false;
}
@ -408,11 +433,12 @@ GLTextureManager::prepareTextureLuminance (string sname, GLuint itexname)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, qim.width(), qim.height(), 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, qim.bits());
cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl;
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, qim->x, qim->y, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, qim->rect); //soc
//soc cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl;
cout << " \"" << StringUtils::toAscii(filename) << "\" loaded with "<< qim->depth << " bits per pixel" << endl;
return true;
}
@ -420,18 +446,25 @@ GLTextureManager::prepareTextureLuminance (string sname, GLuint itexname)
bool
GLTextureManager::prepareTextureLuminanceAndAlpha (string sname, GLuint itexname)
{
const char * name = sname.c_str();
QImage qim(name);
QFileInfo fi(name);
QString filename = fi.fileName();
if (qim.isNull())
//soc const char * name = sname.c_str();
char * name = (char *) sname.c_str();
//soc
// QImage qim(name);
// QFileInfo fi(name);
// QString filename = fi.fileName();
ImBuf *qim = IMB_loadiffname(name, 0);
char filename[FILE_MAXFILE];
BLI_splitdirstring(name, filename);
if (qim) //soc
{
cerr << " Error: unable to read \"" << name << "\"" << endl;
return false;
}
if (qim.depth() > 8)
if (qim->depth > 8) //soc
{
cerr<<" Error: \""<<name<<"\" has "<<qim.depth()<<" bits/pixel"<<endl;
cerr<<" Error: \""<<name<<"\" has "<<qim->depth<<" bits/pixel"<<endl; //soc
return false;
}
@ -447,12 +480,13 @@ GLTextureManager::prepareTextureLuminanceAndAlpha (string sname, GLuint itexname
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, qim.width(), qim.height(), 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, qim.bits());
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, qim.width(), qim.height(), 0,
GL_ALPHA, GL_UNSIGNED_BYTE, qim.bits());
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, qim->x, qim->y, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, qim->rect); //soc
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, qim->x, qim->y, 0,
GL_ALPHA, GL_UNSIGNED_BYTE, qim->rect); //soc
cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl;
//soc cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl;
cout << " \"" << StringUtils::toAscii(filename) << "\" loaded with "<< qim->depth << " bits per pixel" << endl;
return true;
@ -461,20 +495,25 @@ GLTextureManager::prepareTextureLuminanceAndAlpha (string sname, GLuint itexname
bool
GLTextureManager::preparePaper (const char *name, GLuint itexname)
{
QImage qim(name);
QFileInfo fi(name);
QString filename = fi.fileName();
if (qim.isNull())
//soc
// QImage qim(name);
// QFileInfo fi(name);
// QString filename = fi.fileName();
ImBuf *qim = IMB_loadiffname(name, 0);
char filename[FILE_MAXFILE];
BLI_splitdirstring((char *)name, filename);
if (qim) //soc
{
cerr << " Error: unable to read \"" << name << "\"" << endl;
return false;
}
if (qim.depth()!=32)
if (qim->depth !=32) //soc
{
cerr<<" Error: \""<<name<<"\" has "<<qim.depth()<<" bits/pixel"<<endl;
cerr<<" Error: \""<<name<<"\" has "<<qim->depth<<" bits/pixel"<<endl; //soc
return false;
}
QImage qim2=QGLWidget::convertToGLFormat( qim );
//soc QImage qim2=QGLWidget::convertToGLFormat( qim );
glBindTexture(GL_TEXTURE_2D, itexname);
@ -485,11 +524,11 @@ GLTextureManager::preparePaper (const char *name, GLuint itexname)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, qim.width(), qim.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, qim2.bits());
cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, qim->x, qim->y, 0,
GL_RGBA, GL_UNSIGNED_BYTE, qim->rect); //soc: here qim->rect, not qim2->rect, used
//cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl;
cout << " \"" << StringUtils::toAscii(filename) << "\" loaded with "<< qim->depth << " bits per pixel" << endl;
return true;
}

@ -63,6 +63,8 @@ void *glutils_extgl_GetProcAddress(const char *name)
#ifdef _WIN32
void *t = wglGetProcAddress(name);
return t;
#else
return NULL;
#endif
}

@ -1,86 +0,0 @@
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef WIN32
# include "GLRenderer.h"
# include "GLXOffscreenViewer.h"
GLXOffscreenViewer::GLXOffscreenViewer(int w, int h){
_offscreenArea = new OffScreenArea(OffScreenArea::PIXMAP_OFFSCREEN_TYPE);
_offscreenArea->AllocateOffScreenArea(w,h);
_RootNode.SetLightingEnabled(false);
_RootNode.SetLineWidth(1.0);
_pGLRenderer = new GLRenderer;
}
GLXOffscreenViewer::~GLXOffscreenViewer(){
if(_offscreenArea)
delete _offscreenArea;
if(_pGLRenderer)
delete _pGLRenderer;
_RootNode.destroy();
}
void GLXOffscreenViewer::AddNode(Node* iNode){
_RootNode.AddChild(iNode);
}
void GLXOffscreenViewer::DetachNode(Node* iNode){
_RootNode.DetachChild(iNode);
}
void GLXOffscreenViewer::init(){
glClearColor(_clearColor[0],_clearColor[1],_clearColor[2],1);
}
void GLXOffscreenViewer::readPixels(int x,
int y,
int width,
int height,
float *pixels){
_offscreenArea->MakeCurrent();
glReadBuffer(GL_FRONT);
GLenum glformat = GL_RED;
glReadPixels(x,y,width, height, glformat, GL_FLOAT, (GLfloat*)pixels);
}
void GLXOffscreenViewer::draw()
{
_offscreenArea->MakeCurrent();
glPushAttrib(GL_ALL_ATTRIB_BITS);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//Modelview Matrix
//================
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glDisable(GL_DEPTH_TEST);
_RootNode.accept(*_pGLRenderer);
glFlush();
glPopAttrib();
}
#endif

@ -1,545 +0,0 @@
//
// Copyright (C) : Please refer to the COPYRIGHT file distributed
// with this source distribution.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GLXOFFSCREENVIEWER_H
# define GLXOFFSCREENVIEWER_H
# ifdef 0
//#ifndef WIN32
//
// @(#)OffScreen.h 1.4 10/11/00
//
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <malloc.h>
#include <math.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/times.h>
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
namespace OFFSCREEN { // I put this here to avoid conflicts between Qt and
// X11 in the definition of INT32
/*! \namespace OFFSCREEN
* \bugs attention a la restauration de context quand il n'avait rien avant l'OffScreenArea !!
*/
static bool OutOfMemory = false ;
static XErrorHandler oldHandler = NULL ;
static int myXErrorHandler (Display *_d, XErrorEvent *_xee)
{
OutOfMemory = True;
if(oldHandler)
{
return (*oldHandler)(_d,_xee);
}
else
{
return false;
}
return 0;
}
class OffScreenArea
{
public:
static const int UNKNOWN_OFFSCREEN_TYPE = 0 ;
static const int PIXMAP_OFFSCREEN_TYPE = 1 ;
static const int PBUFFER_OFFSCREEN_TYPE = 2 ;
static const int KEEP_PIXMAP = 1 ;
OffScreenArea (int type = UNKNOWN_OFFSCREEN_TYPE,GLXContext shareCtx = NULL)
{
DefaultType = type ;
i_Screen = -1;
i_Height = 0;
i_Width = 0;
i_OffScreenAreaType = UNKNOWN_OFFSCREEN_TYPE ;
i_GLContext = NULL;
i_Drawable = GLXDrawable(0);
i_XPix = Pixmap(0);
i_pXVisual = NULL;
i_pDisplay = NULL;
SetDisplayAndScreen((Display *)NULL,(int)-1) ;
}
GLXContext GetGLXContext() { return i_GLContext ; }
~OffScreenArea ()
{
DestroyOffScreenArea();
}
/*
* 0 : cannot allocate
* 1 : allocation done
* FIRST : try to allocate PixelBuffer (Single, double buffer)
* SECOND : try to allocate GLXPixmap if PixelBuffer is not available
*/
/*
* Here, we try to allocate an OffScreen Area
* first, with PBuffer (if this GLX_ext. is
* available and we can create one)
* second, with a pixmap
*/
int AllocateOffScreenArea(int width,int height)
{
save_GLContext = glXGetCurrentContext();
save_pDisplay = glXGetCurrentDisplay();
save_Drawable = glXGetCurrentDrawable();
int AlreadyThere = 0;
#ifdef A_VIRER
static int AlreadyThere = 0;
if ( ( width != i_Width ) || ( height != i_Height ) )
{
AlreadyThere = 0;
DestroyOffScreenArea();
}
#endif
if(!AlreadyThere)
{
AlreadyThere = 1;
/** Before to use a Pixmap, we try with pbuffer **/
if(TryPBuffer(false,width,height))
{
#ifdef DEBUG
fprintf(stderr, "Using single-buffer PBuffer for off-screen rendering.\n") ;
#endif
return true ;
}
fprintf(stderr, "Cannot use a single-buffer PBuffer, trying double buffer.\n") ;
if(TryPBuffer(true,width,height))
{
#ifdef DEBUG
fprintf(stderr, "Using double-buffer PBuffer for off-screen rendering.\n") ;
#endif
return true ;
}
#ifdef DEBUG
fprintf(stderr, "Warning : cannot create a PBuffer, trying Pixmap\n");
#endif
if(TryPixmap(width,height))
{
#ifdef DEBUG
fprintf(stderr, "Notice : using Pixmap for offScreen rendering\n");
#endif
return true ;
}
#ifdef DEBUG
fprintf (stderr, "Warning : cannot create a Pixmap\n");
#endif
return false;
}
return true ;
}
void MakeCurrent()
{
glXMakeCurrent(i_pDisplay,i_Drawable,i_GLContext);
}
protected:
inline Display * XServer ( void ) { return i_pDisplay; }
inline GLXContext GraphicContext ( void ) { return i_GLContext; }
inline GLXDrawable Drawable ( void ) { return i_Drawable; }
inline XVisualInfo * XVisual ( void ) { return i_pXVisual; }
int DefaultType ;
int i_OffScreenAreaType;
int i_Height;
int i_Width;
GLXContext save_GLContext;
Display * save_pDisplay;
GLXDrawable save_Drawable;
Display * i_pDisplay;
int i_Screen;
GLXContext i_GLContext;
GLXContext i_shareContext;
GLXDrawable i_Drawable;
Pixmap i_XPix;
XVisualInfo * i_pXVisual;
/*
* Define Display and screen
* IF display == NULL THEN try to open default Display
* IF screenNumber is < 0 THEN take default Screen
*/
void SetDisplayAndScreen ( Display *pDisplay , int Screen )
{
if ( pDisplay == NULL )
i_pDisplay = XOpenDisplay ( NULL );
else
i_pDisplay = pDisplay;
if ( Screen < 0 )
i_Screen = DefaultScreen ( i_pDisplay );
else
i_Screen = Screen;
}
//
// Creates a PBuffer
//
// <Return Values>
// 0 : failure
// 1 : succeed
//
bool CreatePBuffer (unsigned int width, unsigned int height , int * pAttribList)
{
#ifdef DEBUG
int error = 0 ;
while((error = glGetError()) > 0)
std::cerr << "GLError " << (void *)error << " encountered." << std::endl ;
#endif
GLXFBConfig *pfbConfigs;
int nbConfigs;
static int pbAttribs[] = { GLX_LARGEST_PBUFFER, true,
GLX_PRESERVED_CONTENTS, true,
GLX_PBUFFER_WIDTH,0,
GLX_PBUFFER_HEIGHT,0,
None };
pbAttribs[5] = width ;
pbAttribs[7] = height ;
// Looks for a config that matches pAttribList
pfbConfigs = glXChooseFBConfig(i_pDisplay,i_Screen,pAttribList,&nbConfigs) ;
#ifdef DEBUG
std::cout << nbConfigs << " found for pbuffer." << std::endl ;
#endif
if(pfbConfigs == NULL)
return false ;
i_pXVisual = glXGetVisualFromFBConfig(i_pDisplay,pfbConfigs[0]);
i_OffScreenAreaType = PBUFFER_OFFSCREEN_TYPE;
// Sets current error handler
OutOfMemory = False;
oldHandler = XSetErrorHandler( myXErrorHandler );
i_Drawable = glXCreatePbuffer(i_pDisplay,pfbConfigs[0],pbAttribs);
if(i_Drawable == 0)
{
i_pXVisual = NULL;
return false ;
}
unsigned int w=0,h=0;
glXQueryDrawable(i_pDisplay,i_Drawable,GLX_WIDTH,&w) ;
glXQueryDrawable(i_pDisplay,i_Drawable,GLX_HEIGHT,&h) ;
if((w != width)||(h != height))
{
#ifdef DEBUG
std::cerr << "Could not allocate Pbuffer. Only size " << w << "x" << h << " found." << std::endl ;
#endif
return false ;
}
#ifdef DEBUG
else
std::cerr << "Could allocate Pbuffer. Size " << w << "x" << h << " found." << std::endl ;
#endif
#ifdef DEBUG
while((error = glGetError()) > 0)
std::cerr << "GLError " << (void *)error << " encountered." << std::endl ;
#endif
// now create GLXContext
if((i_GLContext = glXCreateContext(i_pDisplay,i_pXVisual,NULL,true)) == NULL)
{
DestroyOffScreenArea() ;
return false ;
}
/* Restore original X error handler */
(void) XSetErrorHandler( oldHandler );
if(!OutOfMemory)
{
i_Height = height;
i_Width = width;
return true ;
}
else
return false ;
}
//
// Creates a Pixmap
//
// <Return Values>
// false : failure
// true : succeed
//
bool CreatePixmap (int width, int height , int * pAttribList)
{
int depth;
int totdepth=0;
XErrorHandler oldHandler;
XVisualInfo * pvisP;
pvisP = glXChooseVisual ( i_pDisplay, i_Screen , pAttribList);
if ( pvisP == NULL)
{
fprintf( stderr , "Warning : no 24-bit true color visual available\n" );
return false ;
}
OutOfMemory = False;
oldHandler = XSetErrorHandler(myXErrorHandler);
if(i_XPix == Pixmap(NULL))
{
depth = 0;
for (unsigned int i=0,j=0; (pAttribList[i] != None) && (j<3) ; i++ )
{
switch ( pAttribList[i] )
{
case GLX_RED_SIZE: glXGetConfig(i_pDisplay,pvisP,GLX_RED_SIZE,&depth) ;
totdepth += depth ;
i++ ;
j++ ;
break;
case GLX_GREEN_SIZE: glXGetConfig(i_pDisplay,pvisP,GLX_GREEN_SIZE,&depth) ;
totdepth += depth ;
i++ ;
j++ ;
break;
case GLX_BLUE_SIZE: glXGetConfig(i_pDisplay,pvisP,GLX_BLUE_SIZE,&depth) ;
totdepth += depth ;
i++ ;
j++ ;
break;
default:
break;
}
}
fprintf(stderr,"%d bits color buffer found\n",depth) ;
i_XPix = XCreatePixmap(i_pDisplay,RootWindow (i_pDisplay,0),width,height,totdepth);
XSync(i_pDisplay,False);
if(OutOfMemory)
{
i_XPix = Pixmap(0);
XSetErrorHandler(oldHandler);
oldHandler = NULL ;
fprintf(stderr,"Warning : could not allocate Pixmap\n");
return false ;
}
}
// Perhaps should we verify th type of Area (Pixmap) ?
if ( i_Drawable == GLXDrawable(NULL) )
{
// i_Drawable = i_XPix;
i_Drawable = glXCreateGLXPixmap ( i_pDisplay , pvisP , i_XPix );
XSync ( i_pDisplay , False );
if(OutOfMemory)
{
i_Drawable = GLXDrawable(0);
DestroyOffScreenArea();
fprintf ( stderr , "Warning : could not allocate GLX Pixmap\n");
return false ;
}
else
{
if(i_GLContext != NULL)
{
glXDestroyContext ( i_pDisplay , i_GLContext );
i_GLContext = NULL;
}
if((i_GLContext = glXCreateContext(i_pDisplay,pvisP,NULL,GL_FALSE)) == NULL)
{
DestroyOffScreenArea();
fprintf(stderr, "Warning : could not create rendering context");
}
}
}
XSetErrorHandler(oldHandler);
i_pXVisual = (i_Drawable != GLXDrawable(NULL) ? pvisP : NULL);
i_Height = height;
i_Width = width;
if(i_Drawable != GLXDrawable(NULL))
{
i_OffScreenAreaType = PIXMAP_OFFSCREEN_TYPE;
return true ;
}
return false ;
}
bool TryPixmap(int width,int height)
{
int attrList[30];
int n = 0;
attrList[n++] = GLX_RED_SIZE;
attrList[n++] = 8;
attrList[n++] = GLX_GREEN_SIZE;
attrList[n++] = 8;
attrList[n++] = GLX_BLUE_SIZE;
attrList[n++] = 8;
attrList[n++] = GLX_RGBA;
attrList[n++] = GLX_DEPTH_SIZE;
attrList[n++] = 16;
attrList[n++] = GLX_STENCIL_SIZE;
attrList[n++] = 1;
attrList[n++] = None;
return CreatePixmap(width,height,attrList) ;
}
bool TryPBuffer(bool double_buffer,int width,int height)
{
int attrList[30];
int n = 0;
attrList[n++] = GLX_RENDER_TYPE;
attrList[n++] = GLX_RGBA_BIT;
attrList[n++] = GLX_DRAWABLE_TYPE;
attrList[n++] = GLX_PBUFFER_BIT;
attrList[n++] = GLX_RED_SIZE;
attrList[n++] = 8;
attrList[n++] = GLX_GREEN_SIZE;
attrList[n++] = 8;
attrList[n++] = GLX_BLUE_SIZE;
attrList[n++] = 8;
attrList[n++] = GLX_DEPTH_SIZE;
attrList[n++] = 8;
attrList[n++] = GLX_DOUBLEBUFFER;
attrList[n++] = double_buffer;
attrList[n++] = None;
return CreatePBuffer(width,height,attrList) ;
}
void DestroyOffScreenArea()
{
glXMakeCurrent(save_pDisplay,save_Drawable,save_GLContext);
switch ( i_OffScreenAreaType )
{
case PIXMAP_OFFSCREEN_TYPE : if(i_Drawable != 0)
glXDestroyGLXPixmap(i_pDisplay,i_Drawable);
if (i_XPix != 0)
{
XFreePixmap (i_pDisplay,i_XPix);
i_XPix = 0;
}
break;
case PBUFFER_OFFSCREEN_TYPE : if(i_Drawable != 0)
glXDestroyPbuffer(i_pDisplay,i_Drawable);
break;
default: break;
}
if (i_GLContext != NULL)
{
glXDestroyContext(i_pDisplay,i_GLContext);
i_GLContext = NULL;
}
i_Drawable = 0;
i_OffScreenAreaType = UNKNOWN_OFFSCREEN_TYPE;
}
} ;
}
#include "Geom.h"
#include "NodeDrawingStyle.h"
using namespace Geometry;
//using namespace OFFSCREEN;
class GLXOffscreenViewer{
public:
GLXOffscreenViewer(int w, int h);
virtual ~GLXOffscreenViewer();
/*! Adds a node directly under the root node */
void AddNode(Node* iNode);
/*! Detach the node iNode which must
* be directly under the root node.
*/
void DetachNode(Node *iNode);
/*! reads the frame buffer pixels as luminance .
* \param x
* The lower-left corner x-coordinate of the
* rectangle we want to grab.
* \param y
* The lower-left corner y-coordinate of the
* rectangle we want to grab.
* \param width
* The width of the rectangle we want to grab.
* \param height
* The height of the rectangle we want to grab.
* \params pixels
* The array of float (of size width*height) in which
* the read values are stored.
*/
void readPixels(int x,int y,int width,int height,float *pixels) ;
inline void SetClearColor(const Vec3f& c) {_clearColor = c;}
inline Vec3f getClearColor() const {return _clearColor;}
void init();
void draw();
protected:
OffScreenArea *_offscreenArea;
NodeDrawingStyle _RootNode;
Vec3f _clearColor;
GLRenderer *_pGLRenderer;
};
#endif // WIN32
#endif

@ -1,4 +1,4 @@
#include <pbuffer.h>
#include "pbuffer.h"
#include <memory.h>

@ -1,13 +1,12 @@
#ifndef PBUFFERS_H
#define PBUFFERS_H
#ifndef WIN32
# ifdef __MACH__
# ifdef __MACH__
# include <OpenGL/gl.h>
# else
# else
# include <GL/gl.h>
# include <GL/glx.h>
# endif
# endif
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Interface of PBuffer
@ -74,4 +73,3 @@ private:
};
#endif //PBUFFERS_H
#endif //WIN32

@ -23,10 +23,6 @@
#include "FreestyleConfig.h"
#include "StringUtils.h"
//soc
#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
namespace StringUtils {
void getPathName(const string& path, const string& base, vector<string>& pathnames) {
@ -45,7 +41,7 @@ namespace StringUtils {
char cleaned[FILE_MAX];
BLI_strncpy(cleaned, dir.c_str(), FILE_MAX);
BLI_cleanup_file(NULL, cleaned);
string res(cleaned);
string res = toAscii( string(cleaned) );
if (!base.empty())
res += Config::DIR_SEP + base;
@ -53,4 +49,22 @@ namespace StringUtils {
}
}
string toAscii( const string &str ){
stringstream out("");
char s;
for(uint i=0; i < str.size() ; i++){
s = ((char)(str.at(i) & 0x7F));
out << s;
}
return out.str();
}
const char* toAscii( const char *str ){
return toAscii(string(str)).c_str();
}
} // end of namespace StringUtils

@ -30,14 +30,21 @@
# include <vector>
# include <string>
# include <sstream>
# include "FreestyleConfig.h"
//soc
#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
using namespace std;
namespace StringUtils {
LIB_SYSTEM_EXPORT
void getPathName(const string& path, const string& base, vector<string>& pathnames);
string toAscii( const string &str );
const char* toAscii( const char *str );
// STL related
struct ltstr{

@ -168,7 +168,7 @@ typedef struct ParticleSettings {
struct PartDeflect *pd;
} ParticleSettings;
typedef struct ParticleSystem{
typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in copy_particlesystem */
struct ParticleSystem *next, *prev;
ParticleSettings *part; /* particle settings */
@ -199,7 +199,7 @@ typedef struct ParticleSystem{
char bb_uvname[3][32]; /* billboard uv name */
/* if you change these remember to update array lengths to PSYS_TOT_VG! */
short vgroup[11], vg_neg, rt3[2]; /* vertex groups */
short vgroup[12], vg_neg, rt3; /* vertex groups */
/* temporary storage during render */
void *renderdata;

@ -96,6 +96,7 @@ struct ID; /*keep me up here */
#include "Window.h"
#include "World.h"
#include "Types.h"
#include "Particle.h"
/**********************************************************/
/* Python API function prototypes for the Blender module. */
@ -1074,6 +1075,7 @@ void M_Blender_Init(void)
PyDict_SetItemString(dict, "Node", Node_Init());
PyDict_SetItemString(dict, "Noise", Noise_Init());
PyDict_SetItemString(dict, "Object", Object_Init());
PyDict_SetItemString(dict, "Particle", ParticleSys_Init());
PyDict_SetItemString(dict, "Group", Group_Init());
PyDict_SetItemString(dict, "Registry", Registry_Init());
PyDict_SetItemString(dict, "Scene", Scene_Init());

@ -27,7 +27,7 @@
*
* Contributor(s): Michel Selten, Willian Germano, Jacques Guignot,
* Joseph Gilbert, Stephen Swaney, Bala Gi, Campbell Barton, Johnny Matthews,
* Ken Hughes, Alex Mole, Jean-Michel Soler
* Ken Hughes, Alex Mole, Jean-Michel Soler, Cedric Paille
*
* ***** END GPL LICENSE BLOCK *****
*/
@ -68,6 +68,8 @@ struct rctf;
#include "BKE_object.h"
#include "BKE_key.h" /* for setting the activeShape */
#include "BKE_displist.h"
#include "BKE_pointcache.h"
#include "BKE_particle.h"
#include "BSE_editipo.h"
#include "BSE_edit.h"
@ -117,6 +119,7 @@ struct rctf;
#include "EXPP_interface.h"
#include "BIF_editkey.h"
#include "IDProp.h"
#include "Particle.h"
/* Defines for insertIpoKey */
@ -336,6 +339,9 @@ struct PyMethodDef M_Object_methods[] = {
static int setupSB(Object* ob); /*Make sure Softbody Pointer is initialized */
static int setupPI(Object* ob);
static PyObject *Object_getParticleSys( BPy_Object * self );
/* fixme Object_newParticleSys( self, default-partsys-name ) */
static PyObject *Object_newParticleSys( BPy_Object * self );
static PyObject *Object_buildParts( BPy_Object * self );
static PyObject *Object_clearIpo( BPy_Object * self );
static PyObject *Object_clrParent( BPy_Object * self, PyObject * args );
@ -465,6 +471,10 @@ static PyObject *Object_upAxis(BPy_Object * self);
/*****************************************************************************/
static PyMethodDef BPy_Object_methods[] = {
/* name, method, flags, doc */
{"getParticleSystems", ( PyCFunction ) Object_getParticleSys, METH_NOARGS,
"Return a list of particle systems"},
{"newParticleSystem", ( PyCFunction ) Object_newParticleSys, METH_NOARGS,
"Create and link a new particle system"},
{"buildParts", ( PyCFunction ) Object_buildParts, METH_NOARGS,
"Recalcs particle system (if any), (depricated, will always return an empty list in version 2.46)"},
{"getIpo", ( PyCFunction ) Object_getIpo, METH_NOARGS,
@ -1026,6 +1036,79 @@ static PyObject *M_Object_Duplicate( PyObject * self_unused,
/* Python BPy_Object methods: */
/*****************************************************************************/
PyObject *Object_getParticleSys( BPy_Object * self ){
ParticleSystem *blparticlesys = 0;
Object *ob = self->object;
PyObject *partsyslist,*current;
blparticlesys = ob->particlesystem.first;
partsyslist = PyList_New( 0 );
if (!blparticlesys)
return partsyslist;
/* fixme: for(;;) */
current = ParticleSys_CreatePyObject( blparticlesys, ob );
PyList_Append(partsyslist,current);
while((blparticlesys = blparticlesys->next)){
current = ParticleSys_CreatePyObject( blparticlesys, ob );
PyList_Append(partsyslist,current);
}
return partsyslist;
}
PyObject *Object_newParticleSys( BPy_Object * self ){
ParticleSystem *psys = 0;
ParticleSystem *rpsys = 0;
ModifierData *md;
ParticleSystemModifierData *psmd;
Object *ob = self->object;
/* char *name = NULL; optional name param */
ID *id;
int nr;
id = (ID *)psys_new_settings("PSys", G.main);
psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
psys->pointcache = BKE_ptcache_add();
psys->flag |= PSYS_ENABLED;
BLI_addtail(&ob->particlesystem,psys);
md = modifier_new(eModifierType_ParticleSystem);
sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
psmd = (ParticleSystemModifierData*) md;
psmd->psys=psys;
BLI_addtail(&ob->modifiers, md);
psys->part=(ParticleSettings*)id;
psys->totpart=0;
psys->flag=PSYS_ENABLED|PSYS_CURRENT;
psys->cfra=bsystem_time(ob,(float)G.scene->r.cfra+1,0.0);
rpsys = psys;
/* check need for dupliobjects */
nr=0;
for(psys=ob->particlesystem.first; psys; psys=psys->next){
if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
nr++;
}
if(nr)
ob->transflag |= OB_DUPLIPARTS;
else
ob->transflag &= ~OB_DUPLIPARTS;
BIF_undo_push("Browse Particle System");
DAG_scene_sort(G.scene);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
return ParticleSys_CreatePyObject(rpsys,ob);
}
static PyObject *Object_buildParts( BPy_Object * self )
{
/* This is now handles by modifiers */

File diff suppressed because it is too large Load Diff

@ -22,43 +22,32 @@
*
* This is a new part of Blender.
*
* Contributor(s): Jacques Guignot
* Contributor(s): Jacques Guignot, Cedric Paille
*
* ***** END GPL LICENSE BLOCK *****
*/
*/
#ifndef EXPP_PARTICLE_H
#define EXPP_PARTICLE_H
#ifndef EXPP_PARTICLESYS_H
#define EXPP_PARTICLESYS_H
#include <Python.h>
#include "DNA_effect_types.h"
#include "DNA_particle_types.h"
#include "DNA_object_types.h"
extern PyTypeObject Particle_Type;
extern PyTypeObject ParticleSys_Type;
#define BPy_Particle_Check(v) ((v)->ob_type==&Particle_Type)
#define BPy_ParticleSys_Check(v) \
((v)->ob_type == &ParticleSys_Type) /* for type checking */
/* Python BPy_Particle structure definition */
/* Python BPy_Effect structure definition */
typedef struct {
PyObject_HEAD /* required py macro */
Effect * particle;
} BPy_Particle;
ParticleSystem *psys;
Object *object; /* fixeme: if this points back to the parent object,it is wrong */
} BPy_PartSys;
#include "Effect.h"
/*****************************************************************************/
/* Python Particle_Type callback function prototypes: */
/*****************************************************************************/
#if 0
void ParticleDeAlloc( BPy_Particle * msh );
//int ParticlePrint (BPy_Particle *msh, FILE *fp, int flags);
int ParticleSetAttr( BPy_Particle * msh, char *name, PyObject * v );
PyObject *ParticleGetAttr( BPy_Particle * msh, char *name );
PyObject *ParticleRepr( void );
PyObject *ParticleCreatePyObject( struct Effect *particle );
int ParticleCheckPyObject( PyObject * py_obj );
struct Particle *ParticleFromPyObject( PyObject * py_obj );
#endif
PyObject *ParticleSys_Init( void );
PyObject *ParticleSys_CreatePyObject( ParticleSystem * psystem, Object *ob );
#endif /* EXPP_PARTICLE_H */
#endif /* EXPP_EFFECT_H */

@ -29,7 +29,7 @@ The Blender Python API Reference
- L{Group} (*)
- L{Image} (*)
- L{Ipo} (*)
- L{IpoCurve} (*)
- L{IpoCurve} (*)
- L{Key} (*)
- L{Lamp}
- L{Lattice} (*)
@ -46,6 +46,7 @@ The Blender Python API Reference
- L{Pose} (*)
- L{Constraint} (*)
- L{ActionStrips<NLA>} (*)
- L{Particle}
- L{Registry}
- L{Scene} (*)
- L{Radio}

@ -641,7 +641,16 @@ class Object:
@ivar upAxis: Up axis. Return string 'Y' | 'Y' | 'Z' (readonly)
@type upAxis: string
"""
def getParticleSystems():
"""
Return a list of particle systems linked to this object (see Blender.Particle).
"""
def newParticleSystem():
"""
Link a new particle system (see Blender.Particle).
"""
def buildParts():
"""
Recomputes the particle system. This method only applies to an Object of

@ -0,0 +1,367 @@
# Blender.Object module and the Object PyType object
"""
The Blender.Particle submodule
Particle
========
This module provides access to the B{Particle} in Blender.
@type TYPE: readonly dictionary
@var TYPE: Constant dict used for with L{Particle.TYPE}
- HAIR: set particle system to hair mode.
- REACTOR: set particle system to reactor mode.
- EMITTER: set particle system to emitter mode.
@type DISTRIBUTION: readonly dictionary
@var DISTRIBUTION: Constant dict used for with L{Particle.DISTRIBUTION}
- GRID: set grid distribution.
- RANDOM: set random distribution.
- JITTERED: set jittered distribution.
@type EMITFROM: readonly dictionary
@var EMITFROM: Constant dict used for with L{Particle.EMITFROM}
- VERTS: set particles emit from vertices
- FACES: set particles emit from faces
- VOLUME: set particles emit from volume
- PARTICLE: set particles emit from particles
@type REACTON: readonly dictionary
@var REACTON: Constant dict used for with L{Particle.REACTON}
- NEAR: react on near
- COLLISION: react on collision
- DEATH: react on death
@type DRAWAS: readonly dictionary
@var DRAWAS: Constant dict used for with L{Particle.DRAWAS}
- NONE: Don't draw
- POINT: Draw as point
- CIRCLE: Draw as circles
- CROSS: Draw as crosses
- AXIS: Draw as axis
- LINE: Draw as lines
- PATH: Draw pathes
- OBJECT: Draw object
- GROUP: Draw goup
- BILLBOARD: Draw as billboard
"""
class Particle:
"""
The Particle object
===================
This object gives access to paticles data.
@ivar seed: Set an offset in the random table.
@type seed: int
@ivar type: Type of particle system ( Particle.TYPE[ 'HAIR' | 'REACTOR' | 'EMITTER' ] ).
@type type: int
@ivar resolutionGrid: The resolution of the particle grid.
@type resolutionGrid: int
@ivar startFrame: Frame # to start emitting particles.
@type startFrame: float
@ivar endFrame: Frame # to stop emitting particles.
@type endFrame: float
@ivar editable: Finalize hair to enable editing in particle mode.
@type editable: int
@ivar amount: The total number of particles.
@type amount: int
@ivar multireact: React multiple times ( Paricle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] ).
@type multireact: int
@ivar reactshape: Power of reaction strength dependence on distance to target.
@type reactshape: float
@ivar hairSegments: Amount of hair segments.
@type hairSegments: int
@ivar lifetime: Specify the life span of the particles.
@type lifetime: float
@ivar randlife: Give the particle life a random variation.
@type randlife: float
@ivar randemission: Give the particle life a random variation
@type randemission: int
@ivar particleDistribution: Where to emit particles from Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )
@type particleDistribution: int
@ivar evenDistribution: Use even distribution from faces based on face areas or edge lengths.
@type evenDistribution: int
@ivar distribution: How to distribute particles on selected element Paricle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] ).
@type distribution: int
@ivar jitterAmount: Amount of jitter applied to the sampling.
@type jitterAmount: float
@ivar pf: Emission locations / face (0 = automatic).
@type pf:int
@ivar invert: Invert what is considered object and what is not.
@type invert: int
@ivar targetObject: The object that has the target particle system (empty if same object).
@type targetObject: Blender object
@ivar targetpsys: The target particle system number in the object.
@type targetpsys: int
@ivar 2d: Constrain boids to a surface.
@type 2d: float
@ivar maxvel: Maximum velocity.
@type maxvel: float
@ivar avvel: The usual speed % of max velocity.
@type avvel: float
@ivar latacc: Lateral acceleration % of max velocity
@type latacc: float
@ivar tanacc: Tangential acceleration % of max velocity
@type tanacc: float
@ivar groundz: Default Z value.
@type groundz: float
@ivar object: Constrain boids to object's surface.
@type object: Blender Object
@ivar renderEmitter: Render emitter object.
@type renderEmitter: int
@ivar displayPercentage: Particle display percentage.
@type displayPercentage: int
@ivar hairDisplayStep: How many steps paths are drawn with (power of 2) in visu mode.
@type hairDisplayStep: int
@ivar hairRenderStep: How many steps paths are rendered with (power of 2) in render mode."
@type hairRenderStep: int
@ivar duplicateObject: Get the duplicate object.
@type duplicateObject: Blender Object
@ivar drawAs: Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ]).
@type drawAs: int
"""
def freeEdit():
"""
Free edit mode.
@return: None
"""
def getLoc(all=0,id=0):
"""
Get the particles locations.
A list of tuple is returned in particle mode.
A list of list of tuple is returned in hair mode.
The tuple is a vector list of 3 or 4 floats in world space (x,y,z, optionnaly the particle's id).
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died)particles exported as None).
@type id: int
@param id: add the particle id in the end of the vector tuple
@rtype: list of vectors (tuple of 3 floats and optionnaly the id) or list of list of vectors
@return: list of vectors or list of list of vectors (hair mode)
"""
def getRot(all=0,id=0):
"""
Get the particles rotations as quaternion.
A list of tuple is returned in particle mode.
The tuple is a vector list of 4 or 5 floats (x,y,z,w, optionnaly the id of the particle).
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
@type id: int
@param id: add the particle id in the return tuple
@rtype: list of tuple of 4 or 5 elements (if id is not zero)
@return: list of 4-tuples
"""
def getMat():
"""
Get the particles material.
@rtype: Blender Material
@return: The marterial assigned to particles
"""
def getSize(all=0,id=0):
"""
Get the particles size.
A list of float or list of tuple (particle's size,particle's id).
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
@type id: int
@param id: add the particle id in the return tuple
@rtype: list of floats
@return: list of floats or list of tuples if id is not zero (size,id).
"""
def getAge(all=0,id=0):
"""
Get the particles age.
A list of float or list of tuple (particle's age,particle's id).
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
@type id: int
@param id: add the particle id in the return tuple
@rtype: list of floats
@return: list of floats or list of tuples if id is not zero (size,id).
"""
# Blender.Object module and the Object PyType object
"""
The Blender.Particle submodule
Particle
========
This module provides access to the B{Particle} in Blender.
@type TYPE: readonly dictionary
@var TYPE: Constant dict used for with L{Particle.TYPE}
- HAIR: set particle system to hair mode.
- REACTOR: set particle system to reactor mode.
- EMITTER: set particle system to emitter mode.
@type DISTRIBUTION: readonly dictionary
@var DISTRIBUTION: Constant dict used for with L{Particle.DISTRIBUTION}
- GRID: set grid distribution.
- RANDOM: set random distribution.
- JITTERED: set jittered distribution.
@type EMITFROM: readonly dictionary
@var EMITFROM: Constant dict used for with L{Particle.EMITFROM}
- VERTS: set particles emit from vertices
- FACES: set particles emit from faces
- VOLUME: set particles emit from volume
- PARTICLE: set particles emit from particles
@type REACTON: readonly dictionary
@var REACTON: Constant dict used for with L{Particle.REACTON}
- NEAR: react on near
- COLLISION: react on collision
- DEATH: react on death
@type DRAWAS: readonly dictionary
@var DRAWAS: Constant dict used for with L{Particle.DRAWAS}
- NONE: Don't draw
- POINT: Draw as point
- CIRCLE: Draw as circles
- CROSS: Draw as crosses
- AXIS: Draw as axis
- LINE: Draw as lines
- PATH: Draw pathes
- OBJECT: Draw object
- GROUP: Draw goup
- BILLBOARD: Draw as billboard
"""
def Get(name):
"""
Get the particle system of the object "name".
@type name: string
@return: The particle system of the object.
"""
def New(name):
"""
Assign a new particle system to the object "name".
@type name: string
@return: The newly created particle system.
"""
class Particle:
"""
The Particle object
===================
This object gives access to paticles data.
@ivar seed: Set an offset in the random table.
@type seed: int
@ivar type: Type of particle system ( Particle.TYPE[ 'HAIR' | 'REACTOR' | 'EMITTER' ] ).
@type type: int
@ivar resolutionGrid: The resolution of the particle grid.
@type resolutionGrid: int
@ivar startFrame: Frame # to start emitting particles.
@type startFrame: float
@ivar endFrame: Frame # to stop emitting particles.
@type endFrame: float
@ivar editable: Finalize hair to enable editing in particle mode.
@type editable: int
@ivar amount: The total number of particles.
@type amount: int
@ivar multireact: React multiple times ( Paricle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] ).
@type multireact: int
@ivar reactshape: Power of reaction strength dependence on distance to target.
@type reactshape: float
@ivar hairSegments: Amount of hair segments.
@type hairSegments: int
@ivar lifetime: Specify the life span of the particles.
@type lifetime: float
@ivar randlife: Give the particle life a random variation.
@type randlife: float
@ivar randemission: Give the particle life a random variation
@type randemission: int
@ivar particleDistribution: Where to emit particles from Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )
@type particleDistribution: int
@ivar evenDistribution: Use even distribution from faces based on face areas or edge lengths.
@type evenDistribution: int
@ivar distribution: How to distribute particles on selected element Paricle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] ).
@type distribution: int
@ivar jitterAmount: Amount of jitter applied to the sampling.
@type jitterAmount: float
@ivar pf: Emission locations / face (0 = automatic).
@type pf:int
@ivar invert: Invert what is considered object and what is not.
@type invert: int
@ivar targetObject: The object that has the target particle system (empty if same object).
@type targetObject: Blender object
@ivar targetpsys: The target particle system number in the object.
@type targetpsys: int
@ivar 2d: Constrain boids to a surface.
@type 2d: float
@ivar maxvel: Maximum velocity.
@type maxvel: float
@ivar avvel: The usual speed % of max velocity.
@type avvel: float
@ivar latacc: Lateral acceleration % of max velocity
@type latacc: float
@ivar tanacc: Tangential acceleration % of max velocity
@type tanacc: float
@ivar groundz: Default Z value.
@type groundz: float
@ivar object: Constrain boids to object's surface.
@type object: Blender Object
@ivar renderEmitter: Render emitter object.
@type renderEmitter: int
@ivar displayPercentage: Particle display percentage.
@type displayPercentage: int
@ivar hairDisplayStep: How many steps paths are drawn with (power of 2) in visu mode.
@type hairDisplayStep: int
@ivar hairRenderStep: How many steps paths are rendered with (power of 2) in render mode."
@type hairRenderStep: int
@ivar duplicateObject: Get the duplicate object.
@type duplicateObject: Blender Object
@ivar drawAs: Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ]).
@type drawAs: int
"""
def freeEdit():
"""
Free edit mode.
@return: None
"""
def getLoc(all=0,id=0):
"""
Get the particles locations.
A list of tuple is returned in particle mode.
A list of list of tuple is returned in hair mode.
The tuple is a vector list of 3 floats in world space.
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died)particles exported as None).
@type id: int
@param id: add the particle id in the end of the vector tuple
@rtype: list of vectors (tuple of 3 floats and optionnaly the id) or list of list of vectors
@return: list of vectors or list of list of vectors (hair mode)
"""
def getRot(all=0,id=0):
"""
Get the particles rotations as quaternion.
A list of tuple is returned in particle mode.
The tuple is a vector list of 4 floats (quaternion).
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
@type id: int
@param id: add the particle id in the return tuple
@rtype: list of tuple of 4 or 5 elements (if id is not zero)
@return: list of 4-tuples
"""
def getMat():
"""
Get the particles material.
@rtype: Blender Material
@return: The marterial assigned to particles
"""
def getSize(all=0,id=0):
"""
Get the particles size.
A list of float.
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
@type id: int
@param id: add the particle id in the return tuple
@rtype: list of floats
@return: list of floats or list of tuples if id is not zero (size,id).
"""

@ -2723,7 +2723,7 @@ static void object_panel_draw(Object *ob)
uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
/* LAYERS */
xco= 80;
xco= 65;
dx= 35;
dy= 30;
@ -2745,7 +2745,10 @@ static void object_panel_draw(Object *ob)
uiBlockEndAlign(block);
/* Object Color */
uiDefButF(block, COL, REDRAWVIEW3D, "", 270, 165,30, 30, ob->col, 0, 0, 0, 0, "Object color, used when faces have the ObCol mode enabled");
uiBlockBeginAlign(block);
uiDefButF(block, COL, REDRAWVIEW3D, "", 250, 180, 50, 15, ob->col, 0, 0, 0, 0, "Object color, used when faces have the ObCol mode enabled");
uiDefButF(block, NUM, REDRAWVIEW3D, "A:", 250, 165, 50, 15, &ob->col[3], 0.0f, 1.0f, 10, 2, "Object alpha, used when faces have the ObCol mode enabled");
uiBlockEndAlign(block);
uiDefBut(block, LABEL, 0, "Drawtype", 10,120,100,20, NULL, 0, 0, 0, 0, "");

@ -2652,7 +2652,7 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
uiDefButF(block, NUM,B_LAMPREDRAW,"Soft:", 200,40,100,19, &la->soft,1.0,100.0, 100, 0, "Sets the size of the shadow sample area");
}
else { /* LA_SHADBUF_IRREGULAR */
uiDefButF(block, NUM,B_LAMPREDRAW,"Bias:", 100,40,100,19, &la->bias, 0.01, 5.0, 1, 0, "Sets the shadow map sampling bias");
uiDefButF(block, NUM,B_LAMPREDRAW,"Bias:", 100,40,100,19, &la->bias, 0.001, 5.0, 1, 0, "Sets the shadow map sampling bias");
}
uiBlockBeginAlign(block);

@ -857,15 +857,18 @@ static void draw_image_seq(ScrArea *sa)
zoom = -1.0/sseq->zoom;
}
/* calc location */
x1= (sa->winx-zoom*ibuf->x)/2 + sseq->xof;
y1= (sa->winy-zoom*ibuf->y)/2 + sseq->yof;
/* needed for gla draw */
glaDefine2DArea(&curarea->winrct);
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
zoomx = zoom * ((float)G.scene->r.xasp / (float)G.scene->r.yasp);
zoomy = zoom;
} else {
zoomx = zoomy = zoom;
}
zoomx = zoom * ((float)G.scene->r.xasp / (float)G.scene->r.yasp);
zoomy = zoom;
/* calc location */
x1= (sa->winx-zoomx*ibuf->x)/2 + sseq->xof;
y1= (sa->winy-zoomy*ibuf->y)/2 + sseq->yof;
glPixelZoom(zoomx, zoomy);

@ -3731,8 +3731,20 @@ int play_anim(int mode)
else if(G.qual & LR_CTRLKEY) viewmove(2);
else viewmove(0);
}
}
else if(event==MKEY) {
} else if (event==WHEELDOWNMOUSE || (val && event==PADMINUS)) { /* copied from persptoetsen */
/* this min and max is also in viewmove() */
if(G.vd->persp==V3D_CAMOB) {
G.vd->camzoom-= 10;
if(G.vd->camzoom<-30) G.vd->camzoom= -30;
}
else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
} else if (event==WHEELUPMOUSE || (val && event==PADPLUSKEY)) { /* copied from persptoetsen */
if(G.vd->persp==V3D_CAMOB) {
G.vd->camzoom+= 10;
if(G.vd->camzoom>300) G.vd->camzoom= 300;
}
else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
} else if(event==MKEY) {
if(val) add_marker(CFRA-1);
}
}

@ -180,7 +180,7 @@ void make_boneList(ListBase *list, ListBase *bones, EditBone *parent)
/* Add children if necessary */
if (curBone->childbase.first)
make_boneList (list, &curBone->childbase, eBone);
make_boneList(list, &curBone->childbase, eBone);
}
}
@ -549,7 +549,7 @@ int join_armature(void)
bPoseChannel *pchan, *pchann;
ListBase ebbase, eblist;
EditBone *curbone;
float mat[4][4], imat[4][4];
float mat[4][4], oimat[4][4];
/* Ensure we're not in editmode and that the active object is an armature*/
/* if(G.obedit) return; */ /* Alredy checked in join_menu() */
@ -565,7 +565,11 @@ int join_armature(void)
/* Get editbones of active armature to add editbones to */
ebbase.first=ebbase.last= NULL;
make_boneList(&ebbase, &arm->bonebase, NULL);
/* get pose of active object and move it out of posemode */
pose= ob->pose;
ob->flag &= ~OB_POSEMODE;
BASACT->flag &= ~OB_POSEMODE;
for (base=FIRSTBASE; base; base=nextbase) {
nextbase = base->next;
@ -577,10 +581,12 @@ int join_armature(void)
/* Get Pose of current armature */
opose= base->object->pose;
base->object->flag &= ~OB_POSEMODE;
BASACT->flag &= ~OB_POSEMODE;
/* Find the difference matrix */
Mat4Invert(imat, ob->obmat);
Mat4MulMat4(mat, base->object->obmat, imat);
Mat4Invert(oimat, ob->obmat);
Mat4MulMat4(mat, base->object->obmat, oimat);
/* Copy bones and posechannels from the object to the edit armature */
for (pchan=opose->chanbase.first; pchan; pchan=pchann) {
@ -600,25 +606,24 @@ int join_armature(void)
float delta[3];
/* Get the premat */
VecSubf (delta, curbone->tail, curbone->head);
VecSubf(delta, curbone->tail, curbone->head);
vec_roll_to_mat3(delta, curbone->roll, temp);
Mat4MulMat34 (premat, temp, mat);
Mat4MulMat34(premat, temp, mat);
Mat4MulVecfl(mat, curbone->head);
Mat4MulVecfl(mat, curbone->tail);
/* Get the postmat */
VecSubf (delta, curbone->tail, curbone->head);
VecSubf(delta, curbone->tail, curbone->head);
vec_roll_to_mat3(delta, curbone->roll, temp);
Mat4CpyMat3(postmat, temp);
/* Find the roll */
Mat4Invert (imat, premat);
Mat4MulMat4 (difmat, postmat, imat);
Mat4Invert(imat, premat);
Mat4MulMat4(difmat, postmat, imat);
curbone->roll -= atan2(difmat[2][0], difmat[2][2]);
}
/* Fix Constraints and Other Links to this Bone and Armature */
@ -651,12 +656,15 @@ int join_armature(void)
}
/* Helper function for armature separating - link fixing */
static void separated_armature_fix_links(Object *origArm, Object *newArm, ListBase *edbo)
static void separated_armature_fix_links(Object *origArm, Object *newArm)
{
Object *ob;
bPoseChannel *pchan;
bPoseChannel *pchan, *pcha, *pchb;
bConstraint *con;
EditBone *ebo, *ebn;
ListBase *npchans;
/* get reference to list of bones in new armature */
npchans= &newArm->pose->chanbase;
/* let's go through all objects in database */
for (ob= G.main->object.first; ob; ob= ob->id.next) {
@ -675,27 +683,21 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm, ListBa
for (ct= targets.first; ct; ct= ct->next) {
/* any targets which point to original armature are redirected to the new one only if:
* - the target isn't the original armature itself
* - the target is one of the bones which were moved into newArm
* - the target is one that can be found in newArm
*/
if ((ct->tar == origArm) && (ct->subtarget[0] != 0)) {
for (ebo=edbo->first, ebn=edbo->last; ebo && ebn; ebo=ebo->next, ebn=ebn->prev) {
for (pcha=npchans->first, pchb=npchans->last; pcha && pchb; pcha=pcha->next, pchb=pchb->prev) {
/* check if either one matches */
if ( (strcmp(ebo->name, ct->subtarget)==0) ||
(strcmp(ebn->name, ct->subtarget)==0) )
if ( (strcmp(pcha->name, ct->subtarget)==0) ||
(strcmp(pchb->name, ct->subtarget)==0) )
{
ct->tar= newArm;
printf("arm = '%s' pchan = '%s', ebo = '%s', YES \n", ob->id.name+2, pchan->name, ebo->name);
printf("arm = '%s' pchan = '%s', ebn = '%s', YES \n", ob->id.name+2, pchan->name, ebn->name);
break;
}
else {
printf("arm = '%s' pchan = '%s', ebo = '%s', NOT\n", ob->id.name+2, pchan->name, ebo->name);
printf("arm = '%s' pchan = '%s', ebn = '%s', NOT \n", ob->id.name+2, pchan->name, ebn->name);
}
/* check if both ends have met (to stop checking) */
if (ebo == ebn) break;
}
if (pcha == pchb) break;
}
}
}
@ -723,17 +725,17 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm, ListBa
* - the target is one of the bones which were moved into newArm
*/
if ((ct->tar == origArm) && (ct->subtarget[0] != 0)) {
for (ebo=edbo->first, ebn=edbo->last; ebo && ebn; ebo=ebo->next, ebn=ebn->prev) {
for (pcha=npchans->first, pchb=npchans->last; pcha && pchb; pcha=pcha->next, pchb=pchb->prev) {
/* check if either one matches */
if ( (strcmp(ebo->name, ct->subtarget)==0) ||
(strcmp(ebn->name, ct->subtarget)==0) )
if ( (strcmp(pcha->name, ct->subtarget)==0) ||
(strcmp(pchb->name, ct->subtarget)==0) )
{
ct->tar= newArm;
break;
}
/* check if both ends have met (to stop checking) */
if (ebo == ebn) break;
if (pcha == pchb) break;
}
}
}
@ -749,37 +751,89 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm, ListBa
/* Is object parented to a bone of this src armature? */
if (ob->partype==PARBONE) {
/* bone name in object */
for (ebo=edbo->first, ebn=edbo->last; ebo && ebn; ebo=ebo->next, ebn=ebn->prev) {
for (pcha=npchans->first, pchb=npchans->last; pcha && pchb; pcha=pcha->next, pchb=pchb->prev) {
/* check if either one matches */
if ( (strcmp(ebo->name, ob->parsubstr)==0) ||
(strcmp(ebn->name, ob->parsubstr)==0) )
if ( (strcmp(pcha->name, ob->parsubstr)==0) ||
(strcmp(pchb->name, ob->parsubstr)==0) )
{
ob->parent= newArm;
break;
}
/* check if both ends have met (to stop checking) */
if (ebo == ebn) break;
if (pcha == pchb) break;
}
}
}
}
}
/* Helper function for armature separating - remove certain bones from the given armature
* sel: remove selected bones from the armature, otherwise the unselected bones are removed
*/
static void separate_armature_bones (Object *ob, short sel)
{
ListBase edbo = {NULL, NULL};
bArmature *arm= (bArmature *)ob->data;
bPoseChannel *pchan, *pchann;
EditBone *curbone;
/* make local set of editbones to manipulate here */
make_boneList(&edbo, &arm->bonebase, NULL);
/* go through pose-channels, checking if a bone should be removed */
for (pchan=ob->pose->chanbase.first; pchan; pchan=pchann) {
pchann= pchan->next;
curbone= editbone_name_exists(&edbo, pchan->name);
/* check if bone needs to be removed */
if ( (sel && (curbone->flag & BONE_SELECTED)) ||
(!sel && !(curbone->flag & BONE_SELECTED)) )
{
EditBone *ebo;
bPoseChannel *pchn;
/* clear the bone->parent var of any bone that had this as its parent */
for (ebo= edbo.first; ebo; ebo= ebo->next) {
if (ebo->parent == curbone) {
ebo->parent= NULL;
ebo->temp= NULL; /* this is needed to prevent random crashes with in editbones_to_armature */
ebo->flag &= ~BONE_CONNECTED;
}
}
/* clear the pchan->parent var of any pchan that had this as its parent */
for (pchn= ob->pose->chanbase.first; pchn; pchn=pchn->next) {
if (pchn->parent == pchan)
pchn->parent= NULL;
}
/* free any of the extra-data this pchan might have */
if (pchan->path) MEM_freeN(pchan->path);
free_constraints(&pchan->constraints);
/* get rid of unneeded bone */
BLI_freelinkN(&edbo, curbone);
BLI_freelinkN(&ob->pose->chanbase, pchan);
}
}
/* exit editmode (recalculates pchans too) */
editbones_to_armature(&edbo, ob);
BLI_freelistN(&edbo);
}
void separate_armature (void)
{
EditBone *ebo, *ebn;
Object *oldob;
Base *base, *oldbase;
Object *oldob, *newob;
Base *base, *oldbase, *newbase;
bArmature *arm;
ListBase edbo = {NULL, NULL};
// 31Mar08 - Aligorith:
// this tool is currently not ready for production use, as it will still
// crash in some cases, and also constraint relinking isn't working yet
// 31 Mar 08 \ 11 May 08 - Aligorith:
// currently, this is still too unstable to be enabled for general consumption.
// remove the following two lines to test this tool... you have been warned!
okee("Not implemented (WIP)");
return;
// okee("Not implemented (WIP)");
// return;
if ( G.vd==0 || (G.vd->lay & G.obedit->lay)==0 ) return;
if ( okee("Separate")==0 ) return;
@ -788,83 +842,68 @@ void separate_armature (void)
arm= G.obedit->data;
/* we are going to trick everything as follows:
* 1. duplicate base: this is the new one, remember old pointer
* 2. set aside all NOT selected bones
* 3. load_editArmature(): this will be the new base
* 4. freelist and restore old armature
/* we are going to do this as follows (unlike every other instance of separate):
* 1. exit editmode +posemode for active armature/base. Take note of what this is.
* 2. duplicate base - BASACT is the new one now
* 3. for each of the two armatures, enter editmode -> remove appropriate bones -> exit editmode + recalc
* 4. fix constraint links
* 5. make original armature active and enter editmode
*/
/* only edit-base selected */
/* 1) only edit-base selected */
base= FIRSTBASE;
while(base) {
if(base->lay & G.vd->lay) {
if(base->object==G.obedit) base->flag |= 1;
for (base= FIRSTBASE; base; base= base->next) {
if (base->lay & G.vd->lay) {
if (base->object==G.obedit) base->flag |= 1;
else base->flag &= ~1;
}
base= base->next;
}
/* set aside: everything that is not selected */
for (ebo= G.edbo.first; ebo; ebo= ebn) {
ebn= ebo->next;
/* remove from original, and move to duplicate if not-selected */
if ((ebo->flag & BONE_SELECTED)==0) {
EditBone *curbone;
/* need to make sure children don't still refer to this only if they are selected
* - potentially slow O(n*n) situation here...
*/
for (curbone= G.edbo.first; curbone; curbone=curbone->next) {
if ((curbone->parent == ebo) && (curbone->flag & BONE_SELECTED)) {
curbone->parent= ebo->parent;
curbone->flag &= ~BONE_CONNECTED;
}
}
BLI_remlink(&G.edbo, ebo);
BLI_addtail(&edbo, ebo);
}
}
/* 1) store starting settings and exit editmode */
oldob= G.obedit;
oldbase= BASACT;
adduplicate(1, 0); /* no transform and zero so do get a linked dupli */
G.obedit= BASACT->object; /* basact is set in adduplicate() */
G.obedit->data= copy_armature(arm);
/* because new armature is a copy: reduce user count */
arm->id.us--;
oldob->flag &= ~OB_POSEMODE;
oldbase->flag &= ~OB_POSEMODE;
load_editArmature();
free_editArmature();
BASACT->flag &= ~SELECT;
/* 2) duplicate base */
adduplicate(1, USER_DUP_ARM); /* no transform and zero so do get a linked dupli */
/* fix links before depsgraph flushes */ // err... or after?
printf("oldob = %p, obact = %p \n", oldob, G.obedit);
separated_armature_fix_links(oldob, G.obedit, &G.edbo);
newbase= BASACT; /* basact is set in adduplicate() */
newob= newbase->object;
newbase->flag &= ~SELECT;
if (G.edbo.first) free_editArmature();
G.edbo = edbo;
/* 3) remove bones that shouldn't still be around on both armatures */
separate_armature_bones(oldob, 1);
separate_armature_bones(newob, 0);
/* 4) fix links before depsgraph flushes */ // err... or after?
separated_armature_fix_links(oldob, newob);
G.obedit= 0; /* displists behave different in edit mode */ // needed?
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); /* this is the separated one */
DAG_object_flush_update(G.scene, oldob, OB_RECALC_DATA); /* this is the original one */
DAG_object_flush_update(G.scene, newob, OB_RECALC_DATA); /* this is the separated one */
/* 5) restore original conditions */
G.obedit= oldob;
BASACT= oldbase;
BASACT->flag |= SELECT;
make_editArmature();
/* recalc/redraw + cleanup */
waitcursor(0);
countall();
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWOOPS, 0);
BIF_undo_push("Separate Armature");
}
/* **************** END tools on Editmode Armature **************** */
@ -1442,9 +1481,10 @@ void delete_armature(void)
for (curBone=G.edbo.first;curBone;curBone=next) {
next=curBone->next;
if (arm->layer & curBone->layer)
if (arm->layer & curBone->layer) {
if (curBone->flag & BONE_SELECTED)
delete_bone(curBone);
}
}

@ -33,11 +33,15 @@
#include "MEM_guardedalloc.h"
#include "DNA_cloth_types.h"
#include "DNA_curve_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_particle_types.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
@ -256,6 +260,66 @@ void duplicate_defgroup ( Object *ob )
}
}
static void del_defgroup_update_users(Object *ob, int id)
{
ExplodeModifierData *emd;
ModifierData *md;
ParticleSystem *psys;
ClothModifierData *clmd;
ClothSimSettings *clsim;
int a;
/* these cases don't use names to refer to vertex groups, so when
* they get deleted the numbers get out of synce, this corrects that */
if(ob->soft) {
if(ob->soft->vertgroup == id)
ob->soft->vertgroup= 0;
else if(ob->soft->vertgroup > id)
ob->soft->vertgroup--;
}
for(md=ob->modifiers.first; md; md=md->next) {
if(md->type == eModifierType_Explode) {
emd= (ExplodeModifierData*)md;
if(emd->vgroup == id)
emd->vgroup= 0;
else if(emd->vgroup > id)
emd->vgroup--;
}
else if(md->type == eModifierType_Cloth) {
clmd= (ClothModifierData*)md;
clsim= clmd->sim_parms;
if(clsim) {
if(clsim->vgroup_mass == id)
clsim->vgroup_mass= 0;
else if(clsim->vgroup_mass > id)
clsim->vgroup_mass--;
if(clsim->vgroup_bend == id)
clsim->vgroup_bend= 0;
else if(clsim->vgroup_bend > id)
clsim->vgroup_bend--;
if(clsim->vgroup_struct == id)
clsim->vgroup_struct= 0;
else if(clsim->vgroup_struct > id)
clsim->vgroup_struct--;
}
}
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
for(a=0; a<PSYS_TOT_VG; a++)
if(psys->vgroup[a] == id)
psys->vgroup[a]= 0;
else if(psys->vgroup[a] > id)
psys->vgroup[a]--;
}
}
void del_defgroup_in_object_mode ( Object *ob )
{
bDeformGroup *dg;
@ -291,6 +355,8 @@ void del_defgroup_in_object_mode ( Object *ob )
}
}
del_defgroup_update_users(ob, ob->actdef);
/* Update the active deform index if necessary */
if (ob->actdef == BLI_countlist(&ob->defbase))
ob->actdef--;
@ -348,6 +414,8 @@ void del_defgroup (Object *ob)
}
}
del_defgroup_update_users(ob, ob->actdef);
/* Update the active deform index if necessary */
if (ob->actdef==BLI_countlist(&ob->defbase))
ob->actdef--;

@ -151,6 +151,7 @@ int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect)
return 1;
}
#if 0 // not used
/* returns 0 if not found, otherwise 1 */
static int facesel_edge_pick(Mesh *me, short *mval, unsigned int *index)
{
@ -175,6 +176,7 @@ static int facesel_edge_pick(Mesh *me, short *mval, unsigned int *index)
return 1;
}
#endif
/* only operates on the edit object - this is all thats needed at the moment */
static void uv_calc_center_vector(float *result, Object *ob, EditMesh *em)
@ -958,7 +960,6 @@ int edgetag_shortest_path(EditEdge *source, EditEdge *target)
EditVert *ev;
Heap *heap;
EdgeHash *ehash;
float *cost;
int a, totvert=0, totedge=0, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0;

@ -2548,6 +2548,10 @@ void hide_mesh(int swap)
efa->e2->f1 |= a;
efa->e3->f1 |= a;
if(efa->e4) efa->e4->f1 |= a;
/* When edges are not delt with in their own loop, we need to explicitly re-selct select edges that are joined to unselected faces */
if (swap && (G.scene->selectmode == SCE_SELECT_FACE) && (efa->f & SELECT)) {
EM_select_face(efa, 1);
}
}
}
@ -2751,7 +2755,7 @@ void reveal_tface_uv(void)
for (efa= em->faces.first; efa; efa= efa->next) {
if (!(efa->h) && !(efa->f & SELECT)) {
tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
efa->f |= SELECT;
EM_select_face(efa, 1);
tface->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4;
}
}

@ -3964,7 +3964,7 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Fill Between Joints|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Separate|Ctrl Shift P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Separate|Ctrl Alt P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");

@ -1194,7 +1194,14 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(event==UI_BUT_EVENT) do_butspace(val); /* temporal, view3d deserves own queue? */
/* we consider manipulator a button, defaulting to leftmouse */
if(event==LEFTMOUSE) if(BIF_do_manipulator(sa)) return;
if(event==LEFTMOUSE) {
/* run any view3d event handler script links */
if (event && sa->scriptlink.totscript)
if (BPY_do_spacehandlers(sa, event, SPACEHANDLER_VIEW3D_EVENT))
return; /* return if event was processed (swallowed) by handler(s) */
if(BIF_do_manipulator(sa)) return;
}
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
@ -2404,7 +2411,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
clear_bone_parent();
else if((G.qual==0) && (G.obedit->type==OB_ARMATURE))
select_bone_parent();
else if((G.qual==(LR_CTRLKEY|LR_SHIFTKEY)) && (G.obedit->type==OB_ARMATURE))
else if((G.qual==(LR_CTRLKEY|LR_ALTKEY)) && (G.obedit->type==OB_ARMATURE))
separate_armature();
else if((G.qual==0) && G.obedit->type==OB_MESH)
separatemenu();

@ -106,7 +106,7 @@
#include "mydevice.h"
#include "BIF_poseobject.h"
#include "transform.h"
#define VIEW_ZOOM_OUT_FACTOR (1.15f)
#define VIEW_ZOOM_IN_FACTOR (1.0f/VIEW_ZOOM_OUT_FACTOR)
@ -322,6 +322,7 @@ void persptoetsen(unsigned short event)
if(((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) || (G.qual & LR_SHIFTKEY)) {
void setcameratoview3d(void); // view.c
setcameratoview3d();
autokeyframe_ob_cb_func(G.scene->camera, TFM_TRANSLATION|TFM_ROTATION);
DAG_object_flush_update(G.scene, G.scene->camera, OB_RECALC_OB);
BIF_undo_push("View to Camera position");
allqueue(REDRAWVIEW3D, 0);

@ -2726,9 +2726,10 @@ static void createTransNlaData(TransInfo *t)
if (base->object->action) {
/* exclude if strip is selected too */
for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
if (strip->flag & ACTSTRIP_SELECT)
if (strip->flag & ACTSTRIP_SELECT) {
if (strip->act == base->object->action)
break;
}
}
if (strip==NULL) {
cfra = get_action_frame(base->object, CFRA);
@ -2790,9 +2791,10 @@ static void createTransNlaData(TransInfo *t)
if (base->object->action) {
/* exclude if strip that active action belongs to is selected too */
for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
if (strip->flag & ACTSTRIP_SELECT)
if (strip->flag & ACTSTRIP_SELECT) {
if (strip->act == base->object->action)
break;
}
}
/* can include if no strip found */

@ -39,6 +39,7 @@
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_nla_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_particle_types.h"
@ -303,10 +304,50 @@ void recalcData(TransInfo *t)
if (base->object->recalc)
base->object->ctime= -1234567.0f; // eveil!
/* recalculate scale of selected nla-strips */
if (base->object->nlastrips.first) {
Object *bob= base->object;
bActionStrip *strip;
for (strip= bob->nlastrips.first; strip; strip= strip->next) {
if (strip->flag & ACTSTRIP_SELECT) {
float actlen= strip->actend - strip->actstart;
float len= strip->end - strip->start;
strip->scale= len / (actlen * strip->repeat);
}
}
}
}
DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
}
else {
for (base=G.scene->base.first; base; base=base->next) {
/* recalculate scale of selected nla-strips */
if (base->object->nlastrips.first) {
Object *bob= base->object;
bActionStrip *strip;
for (strip= bob->nlastrips.first; strip; strip= strip->next) {
if (strip->flag & ACTSTRIP_SELECT) {
float actlen= strip->actend - strip->actstart;
float len= strip->end - strip->start;
/* prevent 'negative' scaling */
if (len < 0) {
SWAP(float, strip->start, strip->end);
len= fabs(len);
}
/* calculate new scale */
strip->scale= len / (actlen * strip->repeat);
}
}
}
}
}
}
else if (t->spacetype == SPACE_IPO) {
EditIpo *ei;

@ -562,13 +562,13 @@ int main(int argc, char** argv)
STR_String exitstring = "";
GPG_Application app(system, NULL, exitstring);
bool firstTimeRunning = true;
char *filename = get_filename(argc, argv);
char *titlename;
char pathname[160];
do
{
// Read the Blender file
char *filename = get_filename(argc, argv);
char *titlename;
char pathname[160];
BlendFileData *bfd;
// if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
@ -582,6 +582,17 @@ int main(int argc, char** argv)
BLI_convertstringcode(basedpath, pathname);
bfd = load_game_data(basedpath);
if (!bfd)
{
// just add "//" in front of it
char temppath[242];
strcpy(temppath, "//");
strcat(temppath, basedpath);
BLI_convertstringcode(temppath, pathname);
bfd = load_game_data(temppath);
}
}
else
{
@ -607,7 +618,6 @@ int main(int argc, char** argv)
#endif // WIN32
Main *maggie = bfd->main;
Scene *scene = bfd->curscene;
strcpy (pathname, maggie->name);
char *startscenename = scene->id.name + 2;
G.fileflags = bfd->fileflags;
@ -651,7 +661,12 @@ int main(int argc, char** argv)
if (firstTimeRunning)
{
firstTimeRunning = false;
// set the filename only the first time as in KetsjiEmbedded
strcpy (pathname, maggie->name);
// also copy here (used by GameLogic.getBaseDirectory)
strcpy (G.sce, maggie->name);
if (fullScreen)
{
#ifdef WIN32

@ -88,6 +88,10 @@
//#include "BPY_extern.h"
#endif
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BLI_blenlib.h"
static void setSandbox(TPythonSecurityLevel level);
@ -140,6 +144,32 @@ static PyObject* gPySetGravity(PyObject*,
return NULL;
}
static char gPyExpandPath_doc[] =
"(path) - Converts a blender internal path into a proper file system path.\n\
path - the string path to convert.\n\n\
Use / as directory separator in path\n\
You can use '//' at the start of the string to define a relative path;\n\
Blender replaces that string by the directory of the startup .blend or runtime\n\
file to make a full path name (doesn't change during the game, even if you load\n\
other .blend).\n\
The function also converts the directory separator to the local file system format.";
static PyObject* gPyExpandPath(PyObject*,
PyObject* args,
PyObject*)
{
char expanded[FILE_MAXDIR + FILE_MAXFILE];
char* filename;
if (PyArg_ParseTuple(args,"s",&filename))
{
BLI_strncpy(expanded, filename, FILE_MAXDIR + FILE_MAXFILE);
BLI_convertstringcode(expanded, G.sce);
return PyString_FromString(expanded);
}
return NULL;
}
static bool usedsp = false;
@ -361,6 +391,7 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)
static struct PyMethodDef game_methods[] = {
{"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, gPyExpandPath_doc},
{"getCurrentController",
(PyCFunction) SCA_PythonController::sPyGetCurrentController,
METH_VARARGS, SCA_PythonController::sPyGetCurrentController__doc__},

@ -221,3 +221,18 @@ def setPhysicsTicRate(ticrate):
@type ticrate: float
"""
def expandPath(path):
"""
Converts a blender internal path into a proper file system path.
Use / as directory separator in path
You can use '//' at the start of the string to define a relative path;
Blender replaces that string by the directory of the startup .blend or runtime file
to make a full path name (doesn't change during the game, even if you load other .blend).
The function also converts the directory separator to the local file system format.
@param path: The path string to be converted/expanded.
@type path: string
@return: The converted string
@rtype: string
"""