#include "BMF_BitmapFont.h"
-#ifdef __APPLE__
-#include <stdio.h>
-
-static int needs_nvidia_rasterpos_workaround(void)
-{
- static int well_is_it= -1;
-
- if (well_is_it==-1)
- {
- well_is_it= (strncmp((char *)glGetString(GL_RENDERER), "NVIDIA GeForce 6800", 18) == 0);
- if ( well_is_it != 0)
- {
- const GLubyte* vers = glGetString(GL_VERSION);
- const GLubyte* v = vers;
- int major = 0, minor = 0, sub = 0;
-
- //advance to the '-'
- while ((*v != 0) && (*v!='-'))
- v++;
-
- if (*v == '-')
- {
- int i = 0;
- v++;
-
- while ((v[i] <= '9') && (v[i] >= '0'))
- {
- major *=10;
- major += v[i]-'0';
- i++;
- }
-
- if (v[i] == '.')
- {
- i++;
- while ((v[i] <= '9') && (v[i] >= '0'))
- {
- minor *=10;
- minor += v[i]-'0';
- i++;
- }
- }
- else
- major = -1;
-
- if (v[i] == '.')
- {
- i++;
- while ((v[i] <= '9') && (v[i] >= '0'))
- {
- sub *=10;
- sub += v[i]-'0';
- i++;
- }
- }
- else
- minor = -1;
- }
-
- //OS X 10.4.3 is the first version that contained the fix for this problem
- // and the 6800's driver version in it is 1.4.16. So anything after that
- // doesn't need the workaround
-
- if ( (major == -1) || (minor == -1))
- //If anything went wrong don't do the workaround
- //
- well_is_it = 0;
- else if ( (major <= 1) && (minor <= 4) && (sub < 16))
- well_is_it = 1;
- else
- well_is_it = 0;
- }
- }
-
- return well_is_it;
-}
-
-
-#endif
-
BMF_BitmapFont::BMF_BitmapFont(BMF_FontData* fontData)
: m_fontData(fontData)
{
GLint alignment;
unsigned char c;
-#ifdef __APPLE__
- GLint vp[4]; // hack stuff
- GLubyte nullm = 0; // hack stuff
-
- if(needs_nvidia_rasterpos_workaround()) { // was is_a_really_crappy_nvidia_card()
- glGetIntegerv(GL_VIEWPORT, vp); // hack stuff
-
- glBitmap(1, 1, 0, 0, -vp[0], vp[1], &nullm);
-
- }
- #endif
-
- glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
+ glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
while ( (c = (unsigned char) *str++) ) {
* @param facesB set of faces from object B
*/
void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB)
-{
+{
for(unsigned int idxFaceA=0;idxFaceA<facesA->size();idxFaceA++) {
BOP_Face *faceA = (*facesA)[idxFaceA];
MT_Plane3 planeA = faceA->getPlane();
idxFaceB<facesB->size() && (faceA->getTAG() != BROKEN) && (faceA->getTAG() != PHANTOM);) {
BOP_Face *faceB = (*facesB)[idxFaceB];
if ((faceB->getTAG() != BROKEN) && (faceB->getTAG() != PHANTOM)) {
- BOP_BBox boxB(mesh->getVertex(faceB->getVertex(0))->getPoint(),
- mesh->getVertex(faceB->getVertex(1))->getPoint(),
- mesh->getVertex(faceB->getVertex(2))->getPoint());
- if (boxA.intersect(boxB)) {
+ BOP_BBox boxB(mesh->getVertex(faceB->getVertex(0))->getPoint(),
+ mesh->getVertex(faceB->getVertex(1))->getPoint(),
+ mesh->getVertex(faceB->getVertex(2))->getPoint());
+ if (boxA.intersect(boxB)) {
- MT_Plane3 planeB = faceB->getPlane();
- if (BOP_containsPoint(planeB,p1) &&
- BOP_containsPoint(planeB,p2) &&
- BOP_containsPoint(planeB,p3)) {
- if (BOP_orientation(planeB,planeA)>0) {
- BOP_intersectCoplanarFaces(mesh,facesB,faceA,faceB,false);
- }
- }
- else {
- BOP_intersectNonCoplanarFaces(mesh,facesA,facesB,faceA,faceB);
- }
- }
+ MT_Plane3 planeB = faceB->getPlane();
+ if (BOP_containsPoint(planeB,p1) &&
+ BOP_containsPoint(planeB,p2) &&
+ BOP_containsPoint(planeB,p3)) {
+ if (BOP_orientation(planeB,planeA)>0) {
+ BOP_intersectCoplanarFaces(mesh,facesB,faceA,faceB,false);
+ }
+ }
+ else {
+ BOP_intersectNonCoplanarFaces(mesh,facesA,facesB,faceA,faceB);
+ }
+ }
}
if (faceB->getTAG()==BROKEN){
- facesB->erase(facesB->begin()+idxFaceB);
+ facesB->erase(facesB->begin()+idxFaceB);
}else
- idxFaceB++;
+ idxFaceB++;
}
}
CSG_VertexIteratorDescriptor obBVertices,
CSG_InterpolateUserFaceVertexDataFunc interpFunc)
{
-#ifdef DEBUG
+ #ifdef DEBUG
cout << "BEGIN BOP_performBooleanOperation" << endl;
-#endif
+ #endif
// Set invert flags depending on boolean operation type:
// INTERSECTION: A^B = and(A,B)
// Add B-mesh into C-mesh
BOP_addMesh(&meshC, &meshBFacesId, &materials, obBProps, obBFaces, obBVertices, invertMeshB);
- if (!meshC.isClosedMesh())
- return BOP_NO_SOLID;
-
// Perform the intersection boolean operation.
BoolOpState result = BOP_intersectionBoolOp(&meshC, &meshAFacesId, &meshBFacesId,
invertMeshA, invertMeshB);
// Invert the output mesh if is required
*outputMesh = BOP_exportMesh(&meshC, &materials, outputProps, invertMeshC);
-#ifdef DEBUG
+ #ifdef DEBUG
cout << "END BOP_performBooleanOperation" << endl;
-#endif
+ #endif
return result;
}
bool invertMeshA,
bool invertMeshB)
{
-#ifdef DEBUG
+ #ifdef DEBUG
BOP_Chrono chrono;
float t = 0.0f;
float c = 0.0f;
chrono.start();
cout << "---" << endl;
-#endif
+ #endif
// Create BSPs trees for mesh A & B
BOP_BSPTree bspA;
bspB.addMesh(meshC, *facesB);
bspB.computeBox();
-#ifdef DEBUG
+ #ifdef DEBUG
c = chrono.stamp(); t += c;
cout << "Create BSP " << c << endl;
-#endif
+ #endif
unsigned int numVertices = meshC->getNumVertexs();
if ((0.25*facesB->size()) > bspA.getDeep())
BOP_meshFilter(meshC, facesB, &bspA);
-#ifdef DEBUG
+ #ifdef DEBUG
c = chrono.stamp(); t += c;
cout << "mesh Filter " << c << endl;
-#endif
+ #endif
// Face 2 Face
BOP_Face2Face(meshC,facesA,facesB);
-#ifdef DEBUG
+ #ifdef DEBUG
c = chrono.stamp(); t += c;
cout << "Face2Face " << c << endl;
-#endif
+ #endif
// BSP classification
BOP_meshClassify(meshC,facesA,&bspB);
BOP_meshClassify(meshC,facesB,&bspA);
-#ifdef DEBUG
+ #ifdef DEBUG
c = chrono.stamp(); t += c;
cout << "Classification " << c << endl;
-#endif
+ #endif
// Process overlapped faces
BOP_removeOverlappedFaces(meshC,facesA,facesB);
-#ifdef DEBUG
+ #ifdef DEBUG
c = chrono.stamp(); t += c;
cout << "Remove overlap " << c << endl;
-#endif
+ #endif
// Sew two meshes
BOP_sew(meshC,facesA,facesB);
-#ifdef DEBUG
+ #ifdef DEBUG
c = chrono.stamp(); t += c;
cout << "Sew " << c << endl;
-#endif
+ #endif
// Merge faces
BOP_Merge::getInstance().mergeFaces(meshC,numVertices);
-#ifdef DEBUG
+ #ifdef DEBUG
c = chrono.stamp(); t += c;
cout << "Merge faces " << c << endl;
cout << "Total " << t << endl;
// Test integrity
meshC->testMesh();
-#endif
+ #endif
return BOP_OK;
}
return newIndex;
}
-bool BOP_Mesh::isClosedMesh()
-{
- for(unsigned int i=0; i<m_edges.size(); i++) {
- BOP_Edge *edge = m_edges[i];
- BOP_Indexs faces = edge->getFaces();
- unsigned int count = 0;
- const BOP_IT_Indexs facesEnd = faces.end();
- for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) {
- if (m_faces[*it]->getTAG()!=BROKEN)
- count++;
- }
-
- if ((count%2)!=0) return false;
- }
-
- return true;
-}
/** ***************************************************************************
unsigned int getNumVertexs(BOP_TAG tag);
unsigned int getNumFaces(BOP_TAG tag);
BOP_Index replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex);
- bool isClosedMesh();
// Debug functions
void print();
/**
* Compute the boolean operation, UNION, INTERSECION or DIFFERENCE
*/
-int
+ int
CSG_PerformBooleanOperation(
- CSG_BooleanOperation *operation,
- CSG_OperationType op_type,
- CSG_FaceIteratorDescriptor obAFaces,
- CSG_VertexIteratorDescriptor obAVertices,
- CSG_FaceIteratorDescriptor obBFaces,
- CSG_VertexIteratorDescriptor obBVertices,
- CSG_InterpolateUserFaceVertexDataFunc interp_func
+ CSG_BooleanOperation *operation,
+ CSG_OperationType op_type,
+ CSG_FaceIteratorDescriptor obAFaces,
+ CSG_VertexIteratorDescriptor obAVertices,
+ CSG_FaceIteratorDescriptor obBFaces,
+ CSG_VertexIteratorDescriptor obBVertices,
+ CSG_InterpolateUserFaceVertexDataFunc interp_func
){
if (operation == NULL) return 0;
BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
switch( op_type ) {
case e_csg_union:
- boolType = BOP_UNION;
- break;
+ boolType = BOP_UNION;
+ break;
case e_csg_difference:
- boolType = BOP_DIFFERENCE;
- break;
+ boolType = BOP_DIFFERENCE;
+ break;
default:
- boolType = BOP_INTERSECTION;
- break;
+ boolType = BOP_INTERSECTION;
+ break;
}
- BoolOpState boolOpResult;
try {
- boolOpResult= BOP_performBooleanOperation( boolType,
- mesh_info->output_descriptor,
- (BSP_CSGMesh**) &(mesh_info->output_mesh),
- mesh_info->obB_descriptor,
- obBFaces,
- obBVertices,
- mesh_info->obA_descriptor,
- obAFaces,
- obAVertices,
- interp_func );
+ BOP_performBooleanOperation( boolType,
+ mesh_info->output_descriptor,
+ (BSP_CSGMesh**) &(mesh_info->output_mesh),
+ mesh_info->obB_descriptor,
+ obBFaces,
+ obBVertices,
+ mesh_info->obA_descriptor,
+ obAFaces,
+ obAVertices,
+ interp_func );
}
catch(...) {
return 0;
}
- switch (boolOpResult) {
- case BOP_OK: return 1;
- case BOP_NO_SOLID: return -2;
- case BOP_ERROR: return 0;
- default: return 1;
- }
+ return success;
}
int
if use_fluidsim=='false':
# print "El'Beem Fluid Simulation Disabled..." # debug
elbeem_env.Append (CPPPATH = user_options_dict['PNG_INCLUDE'])
- elbeem_env.Append (CPPPATH = user_options_dict['SDL_INCLUDE'])
- elbeem_env.Append(CPPDEFINES= 'ELBEEM_DUMMIES');
# dummy interface build
Sources = [
"intern/utilities.cpp",
*
*****************************************************************************/
-#ifdef ELBEEM_DUMMIES
-
#include <stdlib.h>
-#include "ntl_vector3dim.h"
extern "C"
int performElbeemSimulation(char *cfgfilename) {
- return 1; // dummy
+ return 1;
};
-// dummies from intern/elbeem/intern/solver_interface.cpp
-// for utilities.cpp
-
-void initGridSizes(int &sizex, int &sizey, int &sizez,
- ntlVec3Gfx &geoStart, ntlVec3Gfx &geoEnd,
- int mMaxRefine, bool parallel)
-{
- // dummy
-}
-
-void calculateMemreqEstimate( int resx,int resy,int resz, int refine,
- double *reqret, string *reqstr) {
- *reqret = 0.0; // dummy
-}
-
-#endif // ELBEEM_DUMMIES
# PROP Target_Dir ""
LINK32=link.exe -lib
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../../../lib/windows/sdl/include" /I "../../../../../lib/windows/zlib/include" /I "../../../../../lib/windows/png/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "NOGUI" /D "ELBEEM_BLENDER" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../../../lib/windows/sdl/include" /I "../../../../../lib/windows/zlib/include" /I "../../../../../lib/windows/png/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "NOGUI" /D "ELBEEM_BLENDER" /YX /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
<File
RelativePath="..\..\intern\ntl_scene.cpp">
</File>
- <File
- RelativePath="..\..\intern\ntl_world.cpp">
- </File>
<File
RelativePath="..\..\intern\parametrizer.cpp">
</File>
<File
RelativePath="..\..\intern\simulation_object.cpp">
</File>
- <File
- RelativePath="..\..\intern\solver_init.cpp">
- </File>
- <File
- RelativePath="..\..\intern\solver_interface.cpp">
- </File>
- <File
- RelativePath="..\..\intern\solver_main.cpp">
- </File>
- <File
- RelativePath="..\..\intern\solver_util.cpp">
- </File>
<File
RelativePath="..\..\intern\utilities.cpp">
</File>
<File
RelativePath="..\..\intern\cfgparser.h">
</File>
- <File
- RelativePath="..\..\intern\elbeem.h">
- </File>
<File
RelativePath="..\..\intern\globals.h">
</File>
<File
RelativePath="..\..\intern\ntl_vector3dim.h">
</File>
- <File
- RelativePath="..\..\intern\ntl_world.h">
- </File>
<File
RelativePath="..\..\intern\parametrizer.h">
</File>
<File
RelativePath="..\..\intern\simulation_object.h">
</File>
- <File
- RelativePath="..\..\intern\solver_class.h">
- </File>
- <File
- RelativePath="..\..\intern\solver_dimenions.h">
- </File>
- <File
- RelativePath="..\..\intern\solver_interface.h">
- </File>
- <File
- RelativePath="..\..\intern\solver_relax.h">
- </File>
<File
RelativePath="..\..\intern\utilities.h">
</File>
case kEventWindowActivated:
m_windowManager->setActiveWindow(window);
window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
- window->updateDrawingContext();
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) );
break;
case kEventWindowDeactivated:
break;
case kEventWindowUpdate:
//if (getFullScreen()) GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen update event\n");
- window->updateDrawingContext();
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
break;
case kEventWindowBoundsChanged:
#define NL_SYMMETRIC 0x106
#define NL_ERROR 0x108
-/* Enable / Disable */
-
-#define NL_NORMALIZE_ROWS 0x400
-
/* Row parameters */
#define NL_RIGHT_HAND_SIDE 0x500
/* Solve */
-NLboolean nlSolve(void);
+void nlPrintMatrix(void);
+NLboolean nlSolve();
+NLboolean nlSolveAdvanced(NLint *permutation, NLboolean solveAgain);
#ifdef __cplusplus
}
*
* Contact: Bruno Levy
*
- * levy@loria.fr
+ * levy@loria.fr
*
- * ISA Project
- * LORIA, INRIA Lorraine,
- * Campus Scientifique, BP 239
- * 54506 VANDOEUVRE LES NANCY CEDEX
- * FRANCE
+ * ISA Project
+ * LORIA, INRIA Lorraine,
+ * Campus Scientifique, BP 239
+ * 54506 VANDOEUVRE LES NANCY CEDEX
+ * FRANCE
*
* Note that the GNU General Public License does not permit incorporating
* the Software into proprietary programs.
static void __nl_assertion_failed(char* cond, char* file, int line) {
- fprintf(
- stderr,
- "OpenNL assertion failed: %s, file:%s, line:%d\n",
- cond,file,line
- );
- abort();
+ fprintf(
+ stderr,
+ "OpenNL assertion failed: %s, file:%s, line:%d\n",
+ cond,file,line
+ );
+ abort();
}
static void __nl_range_assertion_failed(
- float x, float min_val, float max_val, char* file, int line
+ float x, float min_val, float max_val, char* file, int line
) {
- fprintf(
- stderr,
- "OpenNL range assertion failed: %f in [ %f ... %f ], file:%s, line:%d\n",
- x, min_val, max_val, file,line
- );
- abort();
+ fprintf(
+ stderr,
+ "OpenNL range assertion failed: %f in [ %f ... %f ], file:%s, line:%d\n",
+ x, min_val, max_val, file,line
+ );
+ abort();
}
static void __nl_should_not_have_reached(char* file, int line) {
- fprintf(
- stderr,
- "OpenNL should not have reached this point: file:%s, line:%d\n",
- file,line
- );
- abort();
+ fprintf(
+ stderr,
+ "OpenNL should not have reached this point: file:%s, line:%d\n",
+ file,line
+ );
+ abort();
}
-#define __nl_assert(x) { \
- if(!(x)) { \
- __nl_assertion_failed(#x,__FILE__, __LINE__); \
- } \
+#define __nl_assert(x) { \
+ if(!(x)) { \
+ __nl_assertion_failed(#x,__FILE__, __LINE__); \
+ } \
}
-#define __nl_range_assert(x,min_val,max_val) { \
- if(((x) < (min_val)) || ((x) > (max_val))) { \
- __nl_range_assertion_failed(x, min_val, max_val, \
- __FILE__, __LINE__ \
- ); \
- } \
+#define __nl_range_assert(x,min_val,max_val) { \
+ if(((x) < (min_val)) || ((x) > (max_val))) { \
+ __nl_range_assertion_failed(x, min_val, max_val, \
+ __FILE__, __LINE__ \
+ ); \
+ } \
}
-#define __nl_assert_not_reached { \
- __nl_should_not_have_reached(__FILE__, __LINE__); \
+#define __nl_assert_not_reached { \
+ __nl_should_not_have_reached(__FILE__, __LINE__); \
}
#ifdef NL_DEBUG
/************************************************************************************/
/* memory management */
-#define __NL_NEW(T) (T*)(calloc(1, sizeof(T)))
-#define __NL_NEW_ARRAY(T,NB) (T*)(calloc((NB),sizeof(T)))
+#define __NL_NEW(T) (T*)(calloc(1, sizeof(T)))
+#define __NL_NEW_ARRAY(T,NB) (T*)(calloc((NB),sizeof(T)))
#define __NL_RENEW_ARRAY(T,x,NB) (T*)(realloc(x,(NB)*sizeof(T)))
-#define __NL_DELETE(x) free(x); x = NULL
-#define __NL_DELETE_ARRAY(x) free(x); x = NULL
+#define __NL_DELETE(x) free(x); x = NULL
+#define __NL_DELETE_ARRAY(x) free(x); x = NULL
-#define __NL_CLEAR(T, x) memset(x, 0, sizeof(T))
+#define __NL_CLEAR(T, x) memset(x, 0, sizeof(T))
#define __NL_CLEAR_ARRAY(T,x,NB) memset(x, 0, (NB)*sizeof(T))
/************************************************************************************/
/* Dynamic arrays for sparse row/columns */
typedef struct {
- NLuint index;
- NLfloat value;
+ NLuint index;
+ NLfloat value;
} __NLCoeff;
typedef struct {
- NLuint size;
- NLuint capacity;
- __NLCoeff* coeff;
+ NLuint size;
+ NLuint capacity;
+ __NLCoeff* coeff;
} __NLRowColumn;
static void __nlRowColumnConstruct(__NLRowColumn* c) {
- c->size = 0;
- c->capacity = 0;
- c->coeff = NULL;
+ c->size = 0;
+ c->capacity = 0;
+ c->coeff = NULL;
}
static void __nlRowColumnDestroy(__NLRowColumn* c) {
- __NL_DELETE_ARRAY(c->coeff);
+ __NL_DELETE_ARRAY(c->coeff);
#ifdef NL_PARANOID
- __NL_CLEAR(__NLRowColumn, c);
+ __NL_CLEAR(__NLRowColumn, c);
#endif
}
static void __nlRowColumnGrow(__NLRowColumn* c) {
- if(c->capacity != 0) {
- c->capacity = 2 * c->capacity;
- c->coeff = __NL_RENEW_ARRAY(__NLCoeff, c->coeff, c->capacity);
- } else {
- c->capacity = 4;
- c->coeff = __NL_NEW_ARRAY(__NLCoeff, c->capacity);
- }
+ if(c->capacity != 0) {
+ c->capacity = 2 * c->capacity;
+ c->coeff = __NL_RENEW_ARRAY(__NLCoeff, c->coeff, c->capacity);
+ } else {
+ c->capacity = 4;
+ c->coeff = __NL_NEW_ARRAY(__NLCoeff, c->capacity);
+ }
}
static void __nlRowColumnAdd(__NLRowColumn* c, NLint index, NLfloat value) {
- NLuint i;
- for(i=0; i<c->size; i++) {
- if(c->coeff[i].index == (NLuint)index) {
- c->coeff[i].value += value;
- return;
- }
- }
- if(c->size == c->capacity) {
- __nlRowColumnGrow(c);
- }
- c->coeff[c->size].index = index;
- c->coeff[c->size].value = value;
- c->size++;
+ NLuint i;
+ for(i=0; i<c->size; i++) {
+ if(c->coeff[i].index == (NLuint)index) {
+ c->coeff[i].value += value;
+ return;
+ }
+ }
+ if(c->size == c->capacity) {
+ __nlRowColumnGrow(c);
+ }
+ c->coeff[c->size].index = index;
+ c->coeff[c->size].value = value;
+ c->size++;
}
/* Does not check whether the index already exists */
static void __nlRowColumnAppend(__NLRowColumn* c, NLint index, NLfloat value) {
- if(c->size == c->capacity) {
- __nlRowColumnGrow(c);
- }
- c->coeff[c->size].index = index;
- c->coeff[c->size].value = value;
- c->size++;
+ if(c->size == c->capacity) {
+ __nlRowColumnGrow(c);
+ }
+ c->coeff[c->size].index = index;
+ c->coeff[c->size].value = value;
+ c->size++;
}
static void __nlRowColumnZero(__NLRowColumn* c) {
- c->size = 0;
+ c->size = 0;
}
static void __nlRowColumnClear(__NLRowColumn* c) {
- c->size = 0;
- c->capacity = 0;
- __NL_DELETE_ARRAY(c->coeff);
+ c->size = 0;
+ c->capacity = 0;
+ __NL_DELETE_ARRAY(c->coeff);
}
/************************************************************************************/
/* SparseMatrix data structure */
-#define __NL_ROWS 1
+#define __NL_ROWS 1
#define __NL_COLUMNS 2
#define __NL_SYMMETRIC 4
typedef struct {
- NLuint m;
- NLuint n;
- NLuint diag_size;
- NLenum storage;
- __NLRowColumn* row;
- __NLRowColumn* column;
- NLfloat* diag;
+ NLuint m;
+ NLuint n;
+ NLuint diag_size;
+ NLenum storage;
+ __NLRowColumn* row;
+ __NLRowColumn* column;
+ NLfloat* diag;
} __NLSparseMatrix;
static void __nlSparseMatrixConstruct(
- __NLSparseMatrix* M, NLuint m, NLuint n, NLenum storage
+ __NLSparseMatrix* M, NLuint m, NLuint n, NLenum storage
) {
- NLuint i;
- M->m = m;
- M->n = n;
- M->storage = storage;
- if(storage & __NL_ROWS) {
- M->row = __NL_NEW_ARRAY(__NLRowColumn, m);
- for(i=0; i<n; i++) {
- __nlRowColumnConstruct(&(M->row[i]));
- }
- } else {
- M->row = NULL;
- }
-
- if(storage & __NL_COLUMNS) {
- M->column = __NL_NEW_ARRAY(__NLRowColumn, n);
- for(i=0; i<n; i++) {
- __nlRowColumnConstruct(&(M->column[i]));
- }
- } else {
- M->column = NULL;
- }
-
- M->diag_size = MIN(m,n);
- M->diag = __NL_NEW_ARRAY(NLfloat, M->diag_size);
+ NLuint i;
+ M->m = m;
+ M->n = n;
+ M->storage = storage;
+ if(storage & __NL_ROWS) {
+ M->row = __NL_NEW_ARRAY(__NLRowColumn, m);
+ for(i=0; i<n; i++) {
+ __nlRowColumnConstruct(&(M->row[i]));
+ }
+ } else {
+ M->row = NULL;
+ }
+
+ if(storage & __NL_COLUMNS) {
+ M->column = __NL_NEW_ARRAY(__NLRowColumn, n);
+ for(i=0; i<n; i++) {
+ __nlRowColumnConstruct(&(M->column[i]));
+ }
+ } else {
+ M->column = NULL;
+ }
+
+ M->diag_size = MIN(m,n);
+ M->diag = __NL_NEW_ARRAY(NLfloat, M->diag_size);
}
static void __nlSparseMatrixDestroy(__NLSparseMatrix* M) {
- NLuint i;
- __NL_DELETE_ARRAY(M->diag);
- if(M->storage & __NL_ROWS) {
- for(i=0; i<M->m; i++) {
- __nlRowColumnDestroy(&(M->row[i]));
- }
- __NL_DELETE_ARRAY(M->row);
- }
- if(M->storage & __NL_COLUMNS) {
- for(i=0; i<M->n; i++) {
- __nlRowColumnDestroy(&(M->column[i]));
- }
- __NL_DELETE_ARRAY(M->column);
- }
+ NLuint i;
+ __NL_DELETE_ARRAY(M->diag);
+ if(M->storage & __NL_ROWS) {
+ for(i=0; i<M->m; i++) {
+ __nlRowColumnDestroy(&(M->row[i]));
+ }
+ __NL_DELETE_ARRAY(M->row);
+ }
+ if(M->storage & __NL_COLUMNS) {
+ for(i=0; i<M->n; i++) {
+ __nlRowColumnDestroy(&(M->column[i]));
+ }
+ __NL_DELETE_ARRAY(M->column);
+ }
#ifdef NL_PARANOID
- __NL_CLEAR(__NLSparseMatrix,M);
+ __NL_CLEAR(__NLSparseMatrix,M);
#endif
}
static void __nlSparseMatrixAdd(
- __NLSparseMatrix* M, NLuint i, NLuint j, NLfloat value
+ __NLSparseMatrix* M, NLuint i, NLuint j, NLfloat value
) {
- __nl_parano_range_assert(i, 0, M->m - 1);
- __nl_parano_range_assert(j, 0, M->n - 1);
- if((M->storage & __NL_SYMMETRIC) && (j > i)) {
- return;
- }
- if(i == j) {
- M->diag[i] += value;
- }
- if(M->storage & __NL_ROWS) {
- __nlRowColumnAdd(&(M->row[i]), j, value);
- }
- if(M->storage & __NL_COLUMNS) {
- __nlRowColumnAdd(&(M->column[j]), i, value);
- }
+ __nl_parano_range_assert(i, 0, M->m - 1);
+ __nl_parano_range_assert(j, 0, M->n - 1);
+ if((M->storage & __NL_SYMMETRIC) && (j > i)) {
+ return;
+ }
+ if(i == j) {
+ M->diag[i] += value;
+ }
+ if(M->storage & __NL_ROWS) {
+ __nlRowColumnAdd(&(M->row[i]), j, value);
+ }
+ if(M->storage & __NL_COLUMNS) {
+ __nlRowColumnAdd(&(M->column[j]), i, value);
+ }
}
static void __nlSparseMatrixClear( __NLSparseMatrix* M) {
- NLuint i;
- if(M->storage & __NL_ROWS) {
- for(i=0; i<M->m; i++) {
- __nlRowColumnClear(&(M->row[i]));
- }
- }
- if(M->storage & __NL_COLUMNS) {
- for(i=0; i<M->n; i++) {
- __nlRowColumnClear(&(M->column[i]));
- }
- }
- __NL_CLEAR_ARRAY(NLfloat, M->diag, M->diag_size);
+ NLuint i;
+ if(M->storage & __NL_ROWS) {
+ for(i=0; i<M->m; i++) {
+ __nlRowColumnClear(&(M->row[i]));
+ }
+ }
+ if(M->storage & __NL_COLUMNS) {
+ for(i=0; i<M->n; i++) {
+ __nlRowColumnClear(&(M->column[i]));
+ }
+ }
+ __NL_CLEAR_ARRAY(NLfloat, M->diag, M->diag_size);
}
/* Returns the number of non-zero coefficients */
static NLuint __nlSparseMatrixNNZ( __NLSparseMatrix* M) {
- NLuint nnz = 0;
- NLuint i;
- if(M->storage & __NL_ROWS) {
- for(i = 0; i<M->m; i++) {
- nnz += M->row[i].size;
- }
- } else if (M->storage & __NL_COLUMNS) {
- for(i = 0; i<M->n; i++) {
- nnz += M->column[i].size;
- }
- } else {
- __nl_assert_not_reached;
- }
- return nnz;
+ NLuint nnz = 0;
+ NLuint i;
+ if(M->storage & __NL_ROWS) {
+ for(i = 0; i<M->m; i++) {
+ nnz += M->row[i].size;
+ }
+ } else if (M->storage & __NL_COLUMNS) {
+ for(i = 0; i<M->n; i++) {
+ nnz += M->column[i].size;
+ }
+ } else {
+ __nl_assert_not_reached;
+ }
+ return nnz;
}
/************************************************************************************/
/* SparseMatrix x Vector routines, internal helper routines */
static void __nlSparseMatrix_mult_rows_symmetric(
- __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+ __NLSparseMatrix* A, NLfloat* x, NLfloat* y
) {
- NLuint m = A->m;
- NLuint i,ij;
- __NLRowColumn* Ri = NULL;
- __NLCoeff* c = NULL;
- for(i=0; i<m; i++) {
- y[i] = 0;
- Ri = &(A->row[i]);
- for(ij=0; ij<Ri->size; ij++) {
- c = &(Ri->coeff[ij]);
- y[i] += c->value * x[c->index];
- if(i != c->index) {
- y[c->index] += c->value * x[i];
- }
- }
- }
+ NLuint m = A->m;
+ NLuint i,ij;
+ __NLRowColumn* Ri = NULL;
+ __NLCoeff* c = NULL;
+ for(i=0; i<m; i++) {
+ y[i] = 0;
+ Ri = &(A->row[i]);
+ for(ij=0; ij<Ri->size; ij++) {
+ c = &(Ri->coeff[ij]);
+ y[i] += c->value * x[c->index];
+ if(i != c->index) {
+ y[c->index] += c->value * x[i];
+ }
+ }
+ }
}
static void __nlSparseMatrix_mult_rows(
- __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+ __NLSparseMatrix* A, NLfloat* x, NLfloat* y
) {
- NLuint m = A->m;
- NLuint i,ij;
- __NLRowColumn* Ri = NULL;
- __NLCoeff* c = NULL;
- for(i=0; i<m; i++) {
- y[i] = 0;
- Ri = &(A->row[i]);
- for(ij=0; ij<Ri->size; ij++) {
- c = &(Ri->coeff[ij]);
- y[i] += c->value * x[c->index];
- }
- }
+ NLuint m = A->m;
+ NLuint i,ij;
+ __NLRowColumn* Ri = NULL;
+ __NLCoeff* c = NULL;
+ for(i=0; i<m; i++) {
+ y[i] = 0;
+ Ri = &(A->row[i]);
+ for(ij=0; ij<Ri->size; ij++) {
+ c = &(Ri->coeff[ij]);
+ y[i] += c->value * x[c->index];
+ }
+ }
}
static void __nlSparseMatrix_mult_cols_symmetric(
- __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+ __NLSparseMatrix* A, NLfloat* x, NLfloat* y
) {
- NLuint n = A->n;
- NLuint j,ii;
- __NLRowColumn* Cj = NULL;
- __NLCoeff* c = NULL;
- for(j=0; j<n; j++) {
- y[j] = 0;
- Cj = &(A->column[j]);
- for(ii=0; ii<Cj->size; ii++) {
- c = &(Cj->coeff[ii]);
- y[c->index] += c->value * x[j];
- if(j != c->index) {
- y[j] += c->value * x[c->index];
- }
- }
- }
+ NLuint n = A->n;
+ NLuint j,ii;
+ __NLRowColumn* Cj = NULL;
+ __NLCoeff* c = NULL;
+ for(j=0; j<n; j++) {
+ y[j] = 0;
+ Cj = &(A->column[j]);
+ for(ii=0; ii<Cj->size; ii++) {
+ c = &(Cj->coeff[ii]);
+ y[c->index] += c->value * x[j];
+ if(j != c->index) {
+ y[j] += c->value * x[c->index];
+ }
+ }
+ }
}
static void __nlSparseMatrix_mult_cols(
- __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+ __NLSparseMatrix* A, NLfloat* x, NLfloat* y
) {
- NLuint n = A->n;
- NLuint j,ii;
- __NLRowColumn* Cj = NULL;
- __NLCoeff* c = NULL;
- __NL_CLEAR_ARRAY(NLfloat, y, A->m);
- for(j=0; j<n; j++) {
- Cj = &(A->column[j]);
- for(ii=0; ii<Cj->size; ii++) {
- c = &(Cj->coeff[ii]);
- y[c->index] += c->value * x[j];
- }
- }
+ NLuint n = A->n;
+ NLuint j,ii;
+ __NLRowColumn* Cj = NULL;
+ __NLCoeff* c = NULL;
+ __NL_CLEAR_ARRAY(NLfloat, y, A->m);
+ for(j=0; j<n; j++) {
+ Cj = &(A->column[j]);
+ for(ii=0; ii<Cj->size; ii++) {
+ c = &(Cj->coeff[ii]);
+ y[c->index] += c->value * x[j];
+ }
+ }
}
/************************************************************************************/
/* SparseMatrix x Vector routines, main driver routine */
static void __nlSparseMatrixMult(__NLSparseMatrix* A, NLfloat* x, NLfloat* y) {
- if(A->storage & __NL_ROWS) {
- if(A->storage & __NL_SYMMETRIC) {
- __nlSparseMatrix_mult_rows_symmetric(A, x, y);
- } else {
- __nlSparseMatrix_mult_rows(A, x, y);
- }
- } else {
- if(A->storage & __NL_SYMMETRIC) {
- __nlSparseMatrix_mult_cols_symmetric(A, x, y);
- } else {
- __nlSparseMatrix_mult_cols(A, x, y);
- }
- }
+ if(A->storage & __NL_ROWS) {
+ if(A->storage & __NL_SYMMETRIC) {
+ __nlSparseMatrix_mult_rows_symmetric(A, x, y);
+ } else {
+ __nlSparseMatrix_mult_rows(A, x, y);
+ }
+ } else {
+ if(A->storage & __NL_SYMMETRIC) {
+ __nlSparseMatrix_mult_cols_symmetric(A, x, y);
+ } else {
+ __nlSparseMatrix_mult_cols(A, x, y);
+ }
+ }
}
/************************************************************************************/
typedef void(*__NLMatrixFunc)(float* x, float* y);
typedef struct {
- NLfloat value;
- NLboolean locked;
- NLuint index;
+ NLfloat value;
+ NLboolean locked;
+ NLuint index;
} __NLVariable;
-#define __NL_STATE_INITIAL 0
-#define __NL_STATE_SYSTEM 1
-#define __NL_STATE_MATRIX 2
-#define __NL_STATE_ROW 3
-#define __NL_STATE_MATRIX_CONSTRUCTED 4
-#define __NL_STATE_SYSTEM_CONSTRUCTED 5
-#define __NL_STATE_SOLVED 6
+#define __NL_STATE_INITIAL 0
+#define __NL_STATE_SYSTEM 1
+#define __NL_STATE_MATRIX 2
+#define __NL_STATE_ROW 3
+#define __NL_STATE_MATRIX_CONSTRUCTED 4
+#define __NL_STATE_SYSTEM_CONSTRUCTED 5
+#define __NL_STATE_SYSTEM_SOLVED 7
typedef struct {
- NLenum state;
- __NLVariable* variable;
- NLuint n;
- __NLSparseMatrix M;
- __NLRowColumn af;
- __NLRowColumn al;
- __NLRowColumn xl;
- NLfloat* x;
- NLfloat* b;
- NLfloat right_hand_side;
- NLfloat row_scaling;
- NLuint nb_variables;
- NLuint current_row;
- NLboolean least_squares;
- NLboolean symmetric;
- NLboolean normalize_rows;
- NLboolean alloc_M;
- NLboolean alloc_af;
- NLboolean alloc_al;
- NLboolean alloc_xl;
- NLboolean alloc_variable;
- NLboolean alloc_x;
- NLboolean alloc_b;
- NLfloat error;
- __NLMatrixFunc matrix_vector_prod;
+ NLenum state;
+ __NLVariable* variable;
+ NLuint n;
+ __NLSparseMatrix M;
+ __NLRowColumn af;
+ __NLRowColumn al;
+ NLfloat* x;
+ NLfloat* b;
+ NLfloat right_hand_side;
+ NLuint nb_variables;
+ NLuint current_row;
+ NLboolean least_squares;
+ NLboolean symmetric;
+ NLboolean solve_again;
+ NLboolean alloc_M;
+ NLboolean alloc_af;
+ NLboolean alloc_al;
+ NLboolean alloc_variable;
+ NLboolean alloc_x;
+ NLboolean alloc_b;
+ NLfloat error;
+ __NLMatrixFunc matrix_vector_prod;
+
+ struct __NLSuperLUContext {
+ NLboolean alloc_slu;
+ SuperMatrix L, U;
+ NLint *perm_c, *perm_r;
+ SuperLUStat_t stat;
+ } slu;
} __NLContext;
static __NLContext* __nlCurrentContext = NULL;
static void __nlMatrixVectorProd_default(NLfloat* x, NLfloat* y) {
- __nlSparseMatrixMult(&(__nlCurrentContext->M), x, y);
+ __nlSparseMatrixMult(&(__nlCurrentContext->M), x, y);
}
NLContext nlNewContext(void) {
- __NLContext* result = __NL_NEW(__NLContext);
- result->state = __NL_STATE_INITIAL;
- result->row_scaling = 1.0;
- result->right_hand_side = 0.0;
- result->matrix_vector_prod = __nlMatrixVectorProd_default;
- nlMakeCurrent(result);
- return result;
+ __NLContext* result = __NL_NEW(__NLContext);
+ result->state = __NL_STATE_INITIAL;
+ result->right_hand_side = 0.0;
+ result->matrix_vector_prod = __nlMatrixVectorProd_default;
+ nlMakeCurrent(result);
+ return result;
}
+static void __nlFree_SUPERLU(__NLContext *context);
+
void nlDeleteContext(NLContext context_in) {
- __NLContext* context = (__NLContext*)(context_in);
- if(__nlCurrentContext == context) {
- __nlCurrentContext = NULL;
- }
- if(context->alloc_M) {
- __nlSparseMatrixDestroy(&context->M);
- }
- if(context->alloc_af) {
- __nlRowColumnDestroy(&context->af);
- }
- if(context->alloc_al) {
- __nlRowColumnDestroy(&context->al);
- }
- if(context->alloc_xl) {
- __nlRowColumnDestroy(&context->xl);
- }
- if(context->alloc_variable) {
- __NL_DELETE_ARRAY(context->variable);
- }
- if(context->alloc_x) {
- __NL_DELETE_ARRAY(context->x);
- }
- if(context->alloc_b) {
- __NL_DELETE_ARRAY(context->b);
- }
+ __NLContext* context = (__NLContext*)(context_in);
+ if(__nlCurrentContext == context) {
+ __nlCurrentContext = NULL;
+ }
+ if(context->alloc_M) {
+ __nlSparseMatrixDestroy(&context->M);
+ }
+ if(context->alloc_af) {
+ __nlRowColumnDestroy(&context->af);
+ }
+ if(context->alloc_al) {
+ __nlRowColumnDestroy(&context->al);
+ }
+ if(context->alloc_variable) {
+ __NL_DELETE_ARRAY(context->variable);
+ }
+ if(context->alloc_x) {
+ __NL_DELETE_ARRAY(context->x);
+ }
+ if(context->alloc_b) {
+ __NL_DELETE_ARRAY(context->b);
+ }
+ if (context->slu.alloc_slu) {
+ __nlFree_SUPERLU(context);
+ }
#ifdef NL_PARANOID
- __NL_CLEAR(__NLContext, context);
+ __NL_CLEAR(__NLContext, context);
#endif
- __NL_DELETE(context);
+ __NL_DELETE(context);
}
void nlMakeCurrent(NLContext context) {
- __nlCurrentContext = (__NLContext*)(context);
+ __nlCurrentContext = (__NLContext*)(context);
}
NLContext nlGetCurrent(void) {
- return __nlCurrentContext;
+ return __nlCurrentContext;
}
static void __nlCheckState(NLenum state) {
- __nl_assert(__nlCurrentContext->state == state);
+ __nl_assert(__nlCurrentContext->state == state);
}
static void __nlTransition(NLenum from_state, NLenum to_state) {
- __nlCheckState(from_state);
- __nlCurrentContext->state = to_state;
+ __nlCheckState(from_state);
+ __nlCurrentContext->state = to_state;
}
/************************************************************************************/
/* Get/Set parameters */
void nlSolverParameterf(NLenum pname, NLfloat param) {
- __nlCheckState(__NL_STATE_INITIAL);
- switch(pname) {
- case NL_NB_VARIABLES: {
- __nl_assert(param > 0);
- __nlCurrentContext->nb_variables = (NLuint)param;
- } break;
- case NL_LEAST_SQUARES: {
- __nlCurrentContext->least_squares = (NLboolean)param;
- } break;
- case NL_SYMMETRIC: {
- __nlCurrentContext->symmetric = (NLboolean)param;
- }
- default: {
- __nl_assert_not_reached;
- } break;
- }
+ __nlCheckState(__NL_STATE_INITIAL);
+ switch(pname) {
+ case NL_NB_VARIABLES: {
+ __nl_assert(param > 0);
+ __nlCurrentContext->nb_variables = (NLuint)param;
+ } break;
+ case NL_LEAST_SQUARES: {
+ __nlCurrentContext->least_squares = (NLboolean)param;
+ } break;
+ case NL_SYMMETRIC: {
+ __nlCurrentContext->symmetric = (NLboolean)param;
+ }
+ default: {
+ __nl_assert_not_reached;
+ } break;
+ }
}
void nlSolverParameteri(NLenum pname, NLint param) {
- __nlCheckState(__NL_STATE_INITIAL);
- switch(pname) {
- case NL_NB_VARIABLES: {
- __nl_assert(param > 0);
- __nlCurrentContext->nb_variables = (NLuint)param;
- } break;
- case NL_LEAST_SQUARES: {
- __nlCurrentContext->least_squares = (NLboolean)param;
- } break;
- case NL_SYMMETRIC: {
- __nlCurrentContext->symmetric = (NLboolean)param;
- }
- default: {
- __nl_assert_not_reached;
- } break;
- }
+ __nlCheckState(__NL_STATE_INITIAL);
+ switch(pname) {
+ case NL_NB_VARIABLES: {
+ __nl_assert(param > 0);
+ __nlCurrentContext->nb_variables = (NLuint)param;
+ } break;
+ case NL_LEAST_SQUARES: {
+ __nlCurrentContext->least_squares = (NLboolean)param;
+ } break;
+ case NL_SYMMETRIC: {
+ __nlCurrentContext->symmetric = (NLboolean)param;
+ }
+ default: {
+ __nl_assert_not_reached;
+ } break;
+ }
}
void nlRowParameterf(NLenum pname, NLfloat param) {
- __nlCheckState(__NL_STATE_MATRIX);
- switch(pname) {
- case NL_RIGHT_HAND_SIDE: {
- __nlCurrentContext->right_hand_side = param;
- } break;
- case NL_ROW_SCALING: {
- __nlCurrentContext->row_scaling = param;
- } break;
- }
+ __nlCheckState(__NL_STATE_MATRIX);
+ switch(pname) {
+ case NL_RIGHT_HAND_SIDE: {
+ __nlCurrentContext->right_hand_side = param;
+ } break;
+ }
}
void nlRowParameteri(NLenum pname, NLint param) {
- __nlCheckState(__NL_STATE_MATRIX);
- switch(pname) {
- case NL_RIGHT_HAND_SIDE: {
- __nlCurrentContext->right_hand_side = (NLfloat)param;
- } break;
- case NL_ROW_SCALING: {
- __nlCurrentContext->row_scaling = (NLfloat)param;
- } break;
- }
+ __nlCheckState(__NL_STATE_MATRIX);
+ switch(pname) {
+ case NL_RIGHT_HAND_SIDE: {
+ __nlCurrentContext->right_hand_side = (NLfloat)param;
+ } break;
+ }
}
void nlGetBooleanv(NLenum pname, NLboolean* params) {
- switch(pname) {
- case NL_LEAST_SQUARES: {
- *params = __nlCurrentContext->least_squares;
- } break;
- case NL_SYMMETRIC: {
- *params = __nlCurrentContext->symmetric;
- } break;
- default: {
- __nl_assert_not_reached;
- } break;
- }
+ switch(pname) {
+ case NL_LEAST_SQUARES: {
+ *params = __nlCurrentContext->least_squares;
+ } break;
+ case NL_SYMMETRIC: {
+ *params = __nlCurrentContext->symmetric;
+ } break;
+ default: {
+ __nl_assert_not_reached;
+ } break;
+ }
}
void nlGetFloatv(NLenum pname, NLfloat* params) {
- switch(pname) {
- case NL_NB_VARIABLES: {
- *params = (NLfloat)(__nlCurrentContext->nb_variables);
- } break;
- case NL_LEAST_SQUARES: {
- *params = (NLfloat)(__nlCurrentContext->least_squares);
- } break;
- case NL_SYMMETRIC: {
- *params = (NLfloat)(__nlCurrentContext->symmetric);
- } break;
- case NL_ERROR: {
- *params = (NLfloat)(__nlCurrentContext->error);
- } break;
- default: {
- __nl_assert_not_reached;
- } break;
- }
+ switch(pname) {
+ case NL_NB_VARIABLES: {
+ *params = (NLfloat)(__nlCurrentContext->nb_variables);
+ } break;
+ case NL_LEAST_SQUARES: {
+ *params = (NLfloat)(__nlCurrentContext->least_squares);
+ } break;
+ case NL_SYMMETRIC: {
+ *params = (NLfloat)(__nlCurrentContext->symmetric);
+ } break;
+ case NL_ERROR: {
+ *params = (NLfloat)(__nlCurrentContext->error);
+ } break;
+ default: {
+ __nl_assert_not_reached;
+ } break;
+ }
}
void nlGetIntergerv(NLenum pname, NLint* params) {
- switch(pname) {
- case NL_NB_VARIABLES: {
- *params = (NLint)(__nlCurrentContext->nb_variables);
- } break;
- case NL_LEAST_SQUARES: {
- *params = (NLint)(__nlCurrentContext->least_squares);
- } break;
- case NL_SYMMETRIC: {
- *params = (NLint)(__nlCurrentContext->symmetric);
- } break;
- default: {
- __nl_assert_not_reached;
- } break;
- }
+ switch(pname) {
+ case NL_NB_VARIABLES: {
+ *params = (NLint)(__nlCurrentContext->nb_variables);
+ } break;
+ case NL_LEAST_SQUARES: {
+ *params = (NLint)(__nlCurrentContext->least_squares);
+ } break;
+ case NL_SYMMETRIC: {
+ *params = (NLint)(__nlCurrentContext->symmetric);
+ } break;
+ default: {
+ __nl_assert_not_reached;
+ } break;
+ }
}
/************************************************************************************/
/* Enable / Disable */
void nlEnable(NLenum pname) {
- switch(pname) {
- case NL_NORMALIZE_ROWS: {
- __nl_assert(__nlCurrentContext->state != __NL_STATE_ROW);
- __nlCurrentContext->normalize_rows = NL_TRUE;
- } break;
- default: {
- __nl_assert_not_reached;
- }
- }
+ switch(pname) {
+ default: {
+ __nl_assert_not_reached;
+ }
+ }
}
void nlDisable(NLenum pname) {
- switch(pname) {
- case NL_NORMALIZE_ROWS: {
- __nl_assert(__nlCurrentContext->state != __NL_STATE_ROW);
- __nlCurrentContext->normalize_rows = NL_FALSE;
- } break;
- default: {
- __nl_assert_not_reached;
- }
- }
+ switch(pname) {
+ default: {
+ __nl_assert_not_reached;
+ }
+ }
}
NLboolean nlIsEnabled(NLenum pname) {
- switch(pname) {
- case NL_NORMALIZE_ROWS: {
- return __nlCurrentContext->normalize_rows;
- } break;
- default: {
- __nl_assert_not_reached;
- }
- }
- return NL_FALSE;
+ switch(pname) {
+ default: {
+ __nl_assert_not_reached;
+ }
+ }
+ return NL_FALSE;
}
/************************************************************************************/
/* Get/Set Lock/Unlock variables */
void nlSetVariable(NLuint index, NLfloat value) {
- __nlCheckState(__NL_STATE_SYSTEM);
- __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
- __nlCurrentContext->variable[index].value = value;
+ __nlCheckState(__NL_STATE_SYSTEM);
+ __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
+ __nlCurrentContext->variable[index].value = value;
}
NLfloat nlGetVariable(NLuint index) {
- __nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL);
- __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
- return __nlCurrentContext->variable[index].value;
+ __nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL);
+ __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
+ return __nlCurrentContext->variable[index].value;
}
void nlLockVariable(NLuint index) {
- __nlCheckState(__NL_STATE_SYSTEM);
- __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
- __nlCurrentContext->variable[index].locked = NL_TRUE;
+ __nlCheckState(__NL_STATE_SYSTEM);
+ __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
+ __nlCurrentContext->variable[index].locked = NL_TRUE;
}
void nlUnlockVariable(NLuint index) {
- __nlCheckState(__NL_STATE_SYSTEM);
- __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
- __nlCurrentContext->variable[index].locked = NL_FALSE;
+ __nlCheckState(__NL_STATE_SYSTEM);
+ __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
+ __nlCurrentContext->variable[index].locked = NL_FALSE;
}
NLboolean nlVariableIsLocked(NLuint index) {
- __nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL);
- __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
- return __nlCurrentContext->variable[index].locked;
+ __nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL);
+ __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
+ return __nlCurrentContext->variable[index].locked;
}
/************************************************************************************/
/* System construction */
static void __nlVariablesToVector() {
- NLuint i;
- __nl_assert(__nlCurrentContext->alloc_x);
- __nl_assert(__nlCurrentContext->alloc_variable);
- for(i=0; i<__nlCurrentContext->nb_variables; i++) {
- __NLVariable* v = &(__nlCurrentContext->variable[i]);
- if(!v->locked) {
- __nl_assert(v->index < __nlCurrentContext->n);
- __nlCurrentContext->x[v->index] = v->value;
- }
- }
+ NLuint i;
+ __nl_assert(__nlCurrentContext->alloc_x);
+ __nl_assert(__nlCurrentContext->alloc_variable);
+ for(i=0; i<__nlCurrentContext->nb_variables; i++) {
+ __NLVariable* v = &(__nlCurrentContext->variable[i]);
+ if(!v->locked) {
+ __nl_assert(v->index < __nlCurrentContext->n);
+ __nlCurrentContext->x[v->index] = v->value;
+ }
+ }
}
static void __nlVectorToVariables() {
- NLuint i;
- __nl_assert(__nlCurrentContext->alloc_x);
- __nl_assert(__nlCurrentContext->alloc_variable);
- for(i=0; i<__nlCurrentContext->nb_variables; i++) {
- __NLVariable* v = &(__nlCurrentContext->variable[i]);
- if(!v->locked) {
- __nl_assert(v->index < __nlCurrentContext->n);
- v->value = __nlCurrentContext->x[v->index];
- }
- }
+ NLuint i;
+ __nl_assert(__nlCurrentContext->alloc_x);
+ __nl_assert(__nlCurrentContext->alloc_variable);
+ for(i=0; i<__nlCurrentContext->nb_variables; i++) {
+ __NLVariable* v = &(__nlCurrentContext->variable[i]);
+ if(!v->locked) {
+ __nl_assert(v->index < __nlCurrentContext->n);
+ v->value = __nlCurrentContext->x[v->index];
+ }
+ }
}
-
static void __nlBeginSystem() {
- __nlTransition(__NL_STATE_INITIAL, __NL_STATE_SYSTEM);
- __nl_assert(__nlCurrentContext->nb_variables > 0);
- __nlCurrentContext->variable = __NL_NEW_ARRAY(
- __NLVariable, __nlCurrentContext->nb_variables
- );
- __nlCurrentContext->alloc_variable = NL_TRUE;
+ __nl_assert(__nlCurrentContext->nb_variables > 0);
+
+ if (__nlCurrentContext->solve_again)
+ __nlTransition(__NL_STATE_SYSTEM_SOLVED, __NL_STATE_SYSTEM);
+ else {
+ __nlTransition(__NL_STATE_INITIAL, __NL_STATE_SYSTEM);
+
+ __nlCurrentContext->variable = __NL_NEW_ARRAY(
+ __NLVariable, __nlCurrentContext->nb_variables
+ );
+ __nlCurrentContext->alloc_variable = NL_TRUE;
+ }
}
static void __nlEndSystem() {
- __nlTransition(__NL_STATE_MATRIX_CONSTRUCTED, __NL_STATE_SYSTEM_CONSTRUCTED);
+ __nlTransition(__NL_STATE_MATRIX_CONSTRUCTED, __NL_STATE_SYSTEM_CONSTRUCTED);
}
static void __nlBeginMatrix() {
- NLuint i;
- NLuint n = 0;
- NLenum storage = __NL_ROWS;
-
- __nlTransition(__NL_STATE_SYSTEM, __NL_STATE_MATRIX);
-
- for(i=0; i<__nlCurrentContext->nb_variables; i++) {
- if(!__nlCurrentContext->variable[i].locked) {
- __nlCurrentContext->variable[i].index = n;
- n++;
- } else {
- __nlCurrentContext->variable[i].index = ~0;
- }
- }
-
- __nlCurrentContext->n = n;
-
- /* a least squares problem results in a symmetric matrix */
- if(__nlCurrentContext->least_squares) {
- __nlCurrentContext->symmetric = NL_TRUE;
- }
-
- if(__nlCurrentContext->symmetric) {
- storage = (storage | __NL_SYMMETRIC);
- }
-
- /* SuperLU storage does not support symmetric storage */
- storage = (storage & ~__NL_SYMMETRIC);
-
- __nlSparseMatrixConstruct(&__nlCurrentContext->M, n, n, storage);
- __nlCurrentContext->alloc_M = NL_TRUE;
-
- __nlCurrentContext->x = __NL_NEW_ARRAY(NLfloat, n);
- __nlCurrentContext->alloc_x = NL_TRUE;
-
- __nlCurrentContext->b = __NL_NEW_ARRAY(NLfloat, n);
- __nlCurrentContext->alloc_b = NL_TRUE;
-
- __nlVariablesToVector();
-
- __nlRowColumnConstruct(&__nlCurrentContext->af);
- __nlCurrentContext->alloc_af = NL_TRUE;
- __nlRowColumnConstruct(&__nlCurrentContext->al);
- __nlCurrentContext->alloc_al = NL_TRUE;
- __nlRowColumnConstruct(&__nlCurrentContext->xl);
- __nlCurrentContext->alloc_xl = NL_TRUE;
-
- __nlCurrentContext->current_row = 0;
+ NLuint i;
+ NLuint n = 0;
+ NLenum storage = __NL_ROWS;
+
+ __nlTransition(__NL_STATE_SYSTEM, __NL_STATE_MATRIX);
+
+ if (!__nlCurrentContext->solve_again) {
+ for(i=0; i<__nlCurrentContext->nb_variables; i++) {
+ if(!__nlCurrentContext->variable[i].locked)
+ __nlCurrentContext->variable[i].index = n++;
+ else
+ __nlCurrentContext->variable[i].index = ~0;
+ }
+
+ __nlCurrentContext->n = n;
+
+ /* a least squares problem results in a symmetric matrix */
+ if(__nlCurrentContext->least_squares)
+ __nlCurrentContext->symmetric = NL_TRUE;
+
+ if(__nlCurrentContext->symmetric)
+ storage = (storage | __NL_SYMMETRIC);
+
+ /* SuperLU storage does not support symmetric storage */
+ storage = (storage & ~__NL_SYMMETRIC);
+
+ __nlSparseMatrixConstruct(&__nlCurrentContext->M, n, n, storage);
+ __nlCurrentContext->alloc_M = NL_TRUE;
+
+ __nlCurrentContext->x = __NL_NEW_ARRAY(NLfloat, n);
+ __nlCurrentContext->alloc_x = NL_TRUE;
+
+ __nlCurrentContext->b = __NL_NEW_ARRAY(NLfloat, n);
+ __nlCurrentContext->alloc_b = NL_TRUE;
+ }
+ else {
+ /* need to recompute b only, A is not constructed anymore */
+ __NL_CLEAR_ARRAY(NLfloat, __nlCurrentContext->b, __nlCurrentContext->n);
+ }
+
+ __nlVariablesToVector();
+
+ __nlRowColumnConstruct(&__nlCurrentContext->af);
+ __nlCurrentContext->alloc_af = NL_TRUE;
+ __nlRowColumnConstruct(&__nlCurrentContext->al);
+ __nlCurrentContext->alloc_al = NL_TRUE;
+
+ __nlCurrentContext->current_row = 0;
}
static void __nlEndMatrix() {
- __nlTransition(__NL_STATE_MATRIX, __NL_STATE_MATRIX_CONSTRUCTED);
-
- __nlRowColumnDestroy(&__nlCurrentContext->af);
- __nlCurrentContext->alloc_af = NL_FALSE;
- __nlRowColumnDestroy(&__nlCurrentContext->al);
- __nlCurrentContext->alloc_al = NL_FALSE;
- __nlRowColumnDestroy(&__nlCurrentContext->xl);
- __nlCurrentContext->alloc_al = NL_FALSE;
-
+ __nlTransition(__NL_STATE_MATRIX, __NL_STATE_MATRIX_CONSTRUCTED);
+
+ __nlRowColumnDestroy(&__nlCurrentContext->af);
+ __nlCurrentContext->alloc_af = NL_FALSE;
+ __nlRowColumnDestroy(&__nlCurrentContext->al);
+ __nlCurrentContext->alloc_al = NL_FALSE;
+
#if 0
- if(!__nlCurrentContext->least_squares) {
- __nl_assert(
- __nlCurrentContext->current_row ==
- __nlCurrentContext->n
- );
- }
+ if(!__nlCurrentContext->least_squares) {
+ __nl_assert(
+ __nlCurrentContext->current_row ==
+ __nlCurrentContext->n
+ );
+ }
#endif
}
static void __nlBeginRow() {
- __nlTransition(__NL_STATE_MATRIX, __NL_STATE_ROW);
- __nlRowColumnZero(&__nlCurrentContext->af);
- __nlRowColumnZero(&__nlCurrentContext->al);
- __nlRowColumnZero(&__nlCurrentContext->xl);
-}
-
-static void __nlScaleRow(NLfloat s) {
- __NLRowColumn* af = &__nlCurrentContext->af;
- __NLRowColumn* al = &__nlCurrentContext->al;
- NLuint nf = af->size;
- NLuint nl = al->size;
- NLuint i;
- for(i=0; i<nf; i++) {
- af->coeff[i].value *= s;
- }
- for(i=0; i<nl; i++) {
- al->coeff[i].value *= s;
- }
- __nlCurrentContext->right_hand_side *= s;
-}
-
-static void __nlNormalizeRow(NLfloat weight) {
- __NLRowColumn* af = &__nlCurrentContext->af;
- __NLRowColumn* al = &__nlCurrentContext->al;
- NLuint nf = af->size;
- NLuint nl = al->size;
- NLuint i;
- NLfloat norm = 0.0;
- for(i=0; i<nf; i++) {
- norm += af->coeff[i].value * af->coeff[i].value;
- }
- for(i=0; i<nl; i++) {
- norm += al->coeff[i].value * al->coeff[i].value;
- }
- norm = sqrt(norm);
- __nlScaleRow(weight / norm);
+ __nlTransition(__NL_STATE_MATRIX, __NL_STATE_ROW);
+ __nlRowColumnZero(&__nlCurrentContext->af);
+ __nlRowColumnZero(&__nlCurrentContext->al);
}
static void __nlEndRow() {
- __NLRowColumn* af = &__nlCurrentContext->af;
- __NLRowColumn* al = &__nlCurrentContext->al;
- __NLRowColumn* xl = &__nlCurrentContext->xl;
- __NLSparseMatrix* M = &__nlCurrentContext->M;
- NLfloat* b = __nlCurrentContext->b;
- NLuint nf = af->size;
- NLuint nl = al->size;
- NLuint current_row = __nlCurrentContext->current_row;
- NLuint i;
- NLuint j;
- NLfloat S;
- __nlTransition(__NL_STATE_ROW, __NL_STATE_MATRIX);
-
- if(__nlCurrentContext->normalize_rows) {
- __nlNormalizeRow(__nlCurrentContext->row_scaling);
- } else {
- __nlScaleRow(__nlCurrentContext->row_scaling);
- }
-
- if(__nlCurrentContext->least_squares) {
- for(i=0; i<nf; i++) {
- for(j=0; j<nf; j++) {
- __nlSparseMatrixAdd(
- M, af->coeff[i].index, af->coeff[j].index,
- af->coeff[i].value * af->coeff[j].value
- );
- }
- }
- S = -__nlCurrentContext->right_hand_side;
- for(j=0; j<nl; j++) {
- S += al->coeff[j].value * xl->coeff[j].value;
- }
- for(i=0; i<nf; i++) {
- b[ af->coeff[i].index ] -= af->coeff[i].value * S;
- }
- } else {
- for(i=0; i<nf; i++) {
- __nlSparseMatrixAdd(
- M, current_row, af->coeff[i].index, af->coeff[i].value
- );
- }
- b[current_row] = -__nlCurrentContext->right_hand_side;
- for(i=0; i<nl; i++) {
- b[current_row] -= al->coeff[i].value * xl->coeff[i].value;
- }
- }
- __nlCurrentContext->current_row++;
- __nlCurrentContext->right_hand_side = 0.0;
- __nlCurrentContext->row_scaling = 1.0;
+ __NLRowColumn* af = &__nlCurrentContext->af;
+ __NLRowColumn* al = &__nlCurrentContext->al;
+ __NLSparseMatrix* M = &__nlCurrentContext->M;
+ NLfloat* b = __nlCurrentContext->b;
+ NLuint nf = af->size;
+ NLuint nl = al->size;
+ NLuint current_row = __nlCurrentContext->current_row;
+ NLuint i;
+ NLuint j;
+ NLfloat S;
+ __nlTransition(__NL_STATE_ROW, __NL_STATE_MATRIX);
+
+ if(__nlCurrentContext->least_squares) {
+ if (!__nlCurrentContext->solve_again) {
+ for(i=0; i<nf; i++) {
+ for(j=0; j<nf; j++) {
+ __nlSparseMatrixAdd(
+ M, af->coeff[i].index, af->coeff[j].index,
+ af->coeff[i].value * af->coeff[j].value
+ );
+ }
+ }
+ }
+
+ S = -__nlCurrentContext->right_hand_side;
+ for(j=0; j<nl; j++)
+ S += al->coeff[j].value;
+
+ for(i=0; i<nf; i++)
+ b[ af->coeff[i].index ] -= af->coeff[i].value * S;
+ } else {
+ if (!__nlCurrentContext->solve_again) {
+ for(i=0; i<nf; i++) {
+ __nlSparseMatrixAdd(
+ M, current_row, af->coeff[i].index, af->coeff[i].value
+ );
+ }
+ }
+ b[current_row] = -__nlCurrentContext->right_hand_side;
+ for(i=0; i<nl; i++) {
+ b[current_row] -= al->coeff[i].value;
+ }
+ }
+ __nlCurrentContext->current_row++;
+ __nlCurrentContext->right_hand_side = 0.0;
}
void nlMatrixAdd(NLuint row, NLuint col, NLfloat value)
{
- __NLSparseMatrix* M = &__nlCurrentContext->M;
- __nlCheckState(__NL_STATE_MATRIX);
- __nl_range_assert(row, 0, __nlCurrentContext->n - 1);
- __nl_range_assert(col, 0, __nlCurrentContext->nb_variables - 1);
+ __NLSparseMatrix* M = &__nlCurrentContext->M;
+ __nlCheckState(__NL_STATE_MATRIX);
+ __nl_range_assert(row, 0, __nlCurrentContext->n - 1);
+ __nl_range_assert(col, 0, __nlCurrentContext->nb_variables - 1);
__nl_assert(!__nlCurrentContext->least_squares);
__nlSparseMatrixAdd(M, row, col, value);
void nlRightHandSideAdd(NLuint index, NLfloat value)
{
- NLfloat* b = __nlCurrentContext->b;
+ NLfloat* b = __nlCurrentContext->b;
- __nlCheckState(__NL_STATE_MATRIX);
- __nl_range_assert(index, 0, __nlCurrentContext->n - 1);
+ __nlCheckState(__NL_STATE_MATRIX);
+ __nl_range_assert(index, 0, __nlCurrentContext->n - 1);
__nl_assert(!__nlCurrentContext->least_squares);
b[index] += value;
}
void nlCoefficient(NLuint index, NLfloat value) {
- __NLVariable* v;
+ __NLVariable* v;
unsigned int zero= 0;
- __nlCheckState(__NL_STATE_ROW);
- __nl_range_assert(index, zero, __nlCurrentContext->nb_variables - 1);
- v = &(__nlCurrentContext->variable[index]);
- if(v->locked) {
- __nlRowColumnAppend(&(__nlCurrentContext->al), 0, value);
- __nlRowColumnAppend(&(__nlCurrentContext->xl), 0, v->value);
- } else {
- __nlRowColumnAppend(&(__nlCurrentContext->af), v->index, value);
- }
+ __nlCheckState(__NL_STATE_ROW);
+ __nl_range_assert(index, zero, __nlCurrentContext->nb_variables - 1);
+ v = &(__nlCurrentContext->variable[index]);
+ if(v->locked)
+ __nlRowColumnAppend(&(__nlCurrentContext->al), 0, value*v->value);
+ else
+ __nlRowColumnAppend(&(__nlCurrentContext->af), v->index, value);
}
void nlBegin(NLenum prim) {
- switch(prim) {
- case NL_SYSTEM: {
- __nlBeginSystem();
- } break;
- case NL_MATRIX: {
- __nlBeginMatrix();
- } break;
- case NL_ROW: {
- __nlBeginRow();
- } break;
- default: {
- __nl_assert_not_reached;
- }
- }
+ switch(prim) {
+ case NL_SYSTEM: {
+ __nlBeginSystem();
+ } break;
+ case NL_MATRIX: {
+ __nlBeginMatrix();
+ } break;
+ case NL_ROW: {
+ __nlBeginRow();
+ } break;
+ default: {
+ __nl_assert_not_reached;
+ }
+ }
}
void nlEnd(NLenum prim) {
- switch(prim) {
- case NL_SYSTEM: {
- __nlEndSystem();
- } break;
- case NL_MATRIX: {
- __nlEndMatrix();
- } break;
- case NL_ROW: {
- __nlEndRow();
- } break;
- default: {
- __nl_assert_not_reached;
- }
- }
+ switch(prim) {
+ case NL_SYSTEM: {
+ __nlEndSystem();
+ } break;
+ case NL_MATRIX: {
+ __nlEndMatrix();
+ } break;
+ case NL_ROW: {
+ __nlEndRow();
+ } break;
+ default: {
+ __nl_assert_not_reached;
+ }
+ }
}
/************************************************************************/
/* SuperLU wrapper */
-/* Note: SuperLU is difficult to call, but it is worth it. */
+/* Note: SuperLU is difficult to call, but it is worth it. */
/* Here is a driver inspired by A. Sheffer's "cow flattener". */
-static NLboolean __nlSolve_SUPERLU( NLboolean do_perm) {
-
- /* OpenNL Context */
- __NLSparseMatrix* M = &(__nlCurrentContext->M);
- NLfloat* b = __nlCurrentContext->b;
- NLfloat* x = __nlCurrentContext->x;
-
- /* Compressed Row Storage matrix representation */
- NLuint n = __nlCurrentContext->n;
- NLuint nnz = __nlSparseMatrixNNZ(M); /* Number of Non-Zero coeffs */
- NLint* xa = __NL_NEW_ARRAY(NLint, n+1);
- NLfloat* rhs = __NL_NEW_ARRAY(NLfloat, n);
- NLfloat* a = __NL_NEW_ARRAY(NLfloat, nnz);
- NLint* asub = __NL_NEW_ARRAY(NLint, nnz);
-
- /* Permutation vector */
- NLint* perm_r = __NL_NEW_ARRAY(NLint, n);
- NLint* perm = __NL_NEW_ARRAY(NLint, n);
-
- /* SuperLU variables */
- SuperMatrix A, B; /* System */
- SuperMatrix L, U; /* Inverse of A */
- NLint info; /* status code */
- DNformat *vals = NULL; /* access to result */
- float *rvals = NULL; /* access to result */
-
- /* SuperLU options and stats */
- superlu_options_t options;
- SuperLUStat_t stat;
-
-
- /* Temporary variables */
- __NLRowColumn* Ri = NULL;
- NLuint i,jj,count;
-
- __nl_assert(!(M->storage & __NL_SYMMETRIC));
- __nl_assert(M->storage & __NL_ROWS);
- __nl_assert(M->m == M->n);
-
-
- /*
- * Step 1: convert matrix M into SuperLU compressed column
- * representation.
- * -------------------------------------------------------
- */
-
- count = 0;
- for(i=0; i<n; i++) {
- Ri = &(M->row[i]);
- xa[i] = count;
- for(jj=0; jj<Ri->size; jj++) {
- a[count] = Ri->coeff[jj].value;
- asub[count] = Ri->coeff[jj].index;
- count++;
- }
- }
- xa[n] = nnz;
-
- /* Save memory for SuperLU */
- __nlSparseMatrixClear(M);
-
-
- /*
- * Rem: symmetric storage does not seem to work with
- * SuperLU ... (->deactivated in main SLS::Solver driver)
- */
- sCreate_CompCol_Matrix(
- &A, n, n, nnz, a, asub, xa,
- SLU_NR, /* Row_wise, no supernode */
- SLU_S, /* floats */
- SLU_GE /* general storage */
- );
-
- /* Step 2: create vector */
- sCreate_Dense_Matrix(
- &B, n, 1, b, n,
- SLU_DN, /* Fortran-type column-wise storage */
- SLU_S, /* floats */
- SLU_GE /* general */
- );
-
-
- /* Step 3: get permutation matrix
- * ------------------------------
- * com_perm: 0 -> no re-ordering
- * 1 -> re-ordering for A^t.A
- * 2 -> re-ordering for A^t+A
- * 3 -> approximate minimum degree ordering
- */
- get_perm_c(do_perm ? 3 : 0, &A, perm);
-
- /* Step 4: call SuperLU main routine
- * ---------------------------------
- */
-
- set_default_options(&options);
- options.ColPerm = MY_PERMC;
- StatInit(&stat);
-
- sgssv(&options, &A, perm, perm_r, &L, &U, &B, &stat, &info);
-
- /* Step 5: get the solution
- * ------------------------
- * Fortran-type column-wise storage
- */
- vals = (DNformat*)B.Store;
- rvals = (float*)(vals->nzval);
- if(info == 0) {
- for(i = 0; i < n; i++){
- x[i] = rvals[i];
- }
- }
-
- /* Step 6: cleanup
- * ---------------
- */
-
- /*
- * For these two ones, only the "store" structure
- * needs to be deallocated (the arrays have been allocated
- * by us).
- */
- Destroy_SuperMatrix_Store(&A);
- Destroy_SuperMatrix_Store(&B);
-
-
- /*
- * These ones need to be fully deallocated (they have been
- * allocated by SuperLU).
- */
- Destroy_SuperNode_Matrix(&L);
- Destroy_CompCol_Matrix(&U);
-
- StatFree(&stat);
-
- __NL_DELETE_ARRAY(xa);
- __NL_DELETE_ARRAY(rhs);
- __NL_DELETE_ARRAY(a);
- __NL_DELETE_ARRAY(asub);
- __NL_DELETE_ARRAY(perm_r);
- __NL_DELETE_ARRAY(perm);
-
- return (info == 0);
+static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation) {
+
+ /* OpenNL Context */
+ __NLSparseMatrix* M = &(context->M);
+ NLuint n = context->n;
+ NLuint nnz = __nlSparseMatrixNNZ(M); /* number of non-zero coeffs */
+
+ /* Compressed Row Storage matrix representation */
+ NLint *xa = __NL_NEW_ARRAY(NLint, n+1);
+ NLfloat *rhs = __NL_NEW_ARRAY(NLfloat, n);
+ NLfloat *a = __NL_NEW_ARRAY(NLfloat, nnz);
+ NLint *asub = __NL_NEW_ARRAY(NLint, nnz);
+ NLint *etree = __NL_NEW_ARRAY(NLint, n);
+
+ /* SuperLU variables */
+ SuperMatrix At, AtP;
+ NLint info, panel_size, relax;
+ superlu_options_t options;
+
+ /* Temporary variables */
+ __NLRowColumn* Ri = NULL;
+ NLuint i, jj, count;
+
+ __nl_assert(!(M->storage & __NL_SYMMETRIC));
+ __nl_assert(M->storage & __NL_ROWS);
+ __nl_assert(M->m == M->n);
+
+ /* Convert M to compressed column format */
+ for(i=0, count=0; i<n; i++) {
+ __NLRowColumn *Ri = M->row + i;
+ xa[i] = count;
+
+ for(jj=0; jj<Ri->size; jj++, count++) {
+ a[count] = Ri->coeff[jj].value;
+ asub[count] = Ri->coeff[jj].index;
+ }
+ }
+ xa[n] = nnz;
+
+ /* Free M, don't need it anymore at this point */
+ __nlSparseMatrixClear(M);
+
+ /* Create superlu A matrix transposed */
+ sCreate_CompCol_Matrix(
+ &At, n, n, nnz, a, asub, xa,
+ SLU_NC, /* Colum wise, no supernode */
+ SLU_S, /* floats */
+ SLU_GE /* general storage */
+ );
+
+ /* Set superlu options */
+ set_default_options(&options);
+ options.ColPerm = MY_PERMC;
+ options.Fact = DOFACT;
+
+ StatInit(&(context->slu.stat));
+
+ panel_size = sp_ienv(1); /* sp_ienv give us the defaults */
+ relax = sp_ienv(2);
+
+ /* Compute permutation and permuted matrix */
+ context->slu.perm_r = __NL_NEW_ARRAY(NLint, n);
+ context->slu.perm_c = __NL_NEW_ARRAY(NLint, n);
+
+ if ((permutation == NULL) || (*permutation == -1)) {
+ get_perm_c(3, &At, context->slu.perm_c);
+
+ if (permutation)
+ memcpy(permutation, context->slu.perm_c, sizeof(NLint)*n);
+ }
+ else
+ memcpy(context->slu.perm_c, permutation, sizeof(NLint)*n);
+
+ sp_preorder(&options, &At, context->slu.perm_c, etree, &AtP);
+
+ /* Decompose into L and U */
+ sgstrf(&options, &AtP, relax, panel_size,
+ etree, NULL, 0, context->slu.perm_c, context->slu.perm_r,
+ &(context->slu.L), &(context->slu.U), &(context->slu.stat), &info);
+
+ /* Cleanup */
+
+ Destroy_SuperMatrix_Store(&At);
+ Destroy_SuperMatrix_Store(&AtP);
+
+ __NL_DELETE_ARRAY(etree);
+ __NL_DELETE_ARRAY(xa);
+ __NL_DELETE_ARRAY(rhs);
+ __NL_DELETE_ARRAY(a);
+ __NL_DELETE_ARRAY(asub);
+
+ context->slu.alloc_slu = NL_TRUE;
+
+ return (info == 0);
+}
+
+static NLboolean __nlInvert_SUPERLU(__NLContext *context) {
+
+ /* OpenNL Context */
+ NLfloat* b = context->b;
+ NLfloat* x = context->x;
+ NLuint n = context->n;
+
+ /* SuperLU variables */
+ SuperMatrix B;
+ NLint info;
+
+ /* Create superlu array for B */
+ sCreate_Dense_Matrix(
+ &B, n, 1, b, n,
+ SLU_DN, /* Fortran-type column-wise storage */
+ SLU_S, /* floats */
+ SLU_GE /* general */
+ );
+
+ /* Forward/Back substitution to compute x */
+ sgstrs(TRANS, &(context->slu.L), &(context->slu.U),
+ context->slu.perm_c, context->slu.perm_r, &B,
+ &(context->slu.stat), &info);
+
+ if(info == 0)
+ memcpy(x, ((DNformat*)B.Store)->nzval, sizeof(*x)*n);
+
+ Destroy_SuperMatrix_Store(&B);
+
+ return (info == 0);
+}
+
+static void __nlFree_SUPERLU(__NLContext *context) {
+
+ Destroy_SuperNode_Matrix(&(context->slu.L));
+ Destroy_CompCol_Matrix(&(context->slu.U));
+
+ StatFree(&(context->slu.stat));
+
+ __NL_DELETE_ARRAY(context->slu.perm_r);
+ __NL_DELETE_ARRAY(context->slu.perm_c);
+
+ context->slu.alloc_slu = NL_FALSE;
}
+void nlPrintMatrix(void) {
+ __NLSparseMatrix* M = &(__nlCurrentContext->M);
+ float *b = __nlCurrentContext->b;
+ NLuint i, jj, k;
+ NLuint n = __nlCurrentContext->n;
+ __NLRowColumn* Ri = NULL;
+ float *value = malloc(sizeof(*value)*n);
+
+ printf("A:\n");
+ for(i=0; i<n; i++) {
+ Ri = &(M->row[i]);
+
+ memset(value, 0.0, sizeof(*value)*n);
+ for(jj=0; jj<Ri->size; jj++)
+ value[Ri->coeff[jj].index] = Ri->coeff[jj].value;
+
+ for (k = 0; k<n; k++)
+ printf("%.3f ", value[k]);
+ printf("\n");
+ }
+
+ printf("b:\n");
+ for(i=0; i<n; i++)
+ printf("%f ", b[i]);
+ printf("\n");
+
+ free(value);
+}
/************************************************************************/
/* nlSolve() driver routine */
-NLboolean nlSolve(void) {
- NLboolean result = NL_TRUE;
+NLboolean nlSolveAdvanced(NLint *permutation, NLboolean solveAgain) {
+ NLboolean result = NL_TRUE;
+
+ __nlCheckState(__NL_STATE_SYSTEM_CONSTRUCTED);
+
+ if (!__nlCurrentContext->solve_again)
+ result = __nlFactorize_SUPERLU(__nlCurrentContext, permutation);
+
+ if (result) {
+ result = __nlInvert_SUPERLU(__nlCurrentContext);
- __nlCheckState(__NL_STATE_SYSTEM_CONSTRUCTED);
- result = __nlSolve_SUPERLU(NL_TRUE);
+ if (result) {
+ __nlVectorToVariables();
- __nlVectorToVariables();
- __nlTransition(__NL_STATE_SYSTEM_CONSTRUCTED, __NL_STATE_SOLVED);
+ if (solveAgain)
+ __nlCurrentContext->solve_again = NL_TRUE;
+
+ __nlTransition(__NL_STATE_SYSTEM_CONSTRUCTED, __NL_STATE_SYSTEM_SOLVED);
+ }
+ }
+
+ return result;
+}
- return result;
+NLboolean nlSolve() {
+ return nlSolveAdvanced(NULL, NL_FALSE);
}
MTL=midl.exe
LINK32=link.exe -lib
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\source\blender\imbuf\intern" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\include" /I "..\..\..\..\lib\windows\jpeg\include" /I "..\..\..\..\lib\windows\zlib\include" /I "..\..\..\..\lib\windows\png\include" /I "..\..\..\source\blender\makesdna" /I "..\..\..\..\lib\windows\tiff\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_QUICKTIME" /YX /FD /I /GZ "..\..\..\source\blender\imbuf" /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\source\blender\imbuf\intern" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\include" /I "..\..\..\..\lib\windows\jpeg\include" /I "..\..\..\..\lib\windows\zlib\include" /I "..\..\..\..\lib\windows\png\include" /I "..\..\..\source\blender\makesdna..\..\..\lib\windows\\" /I "..\..\..\..\lib\windows\tiff\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_QUICKTIME" /YX /FD /I /GZ "..\..\..\source\blender\imbuf" /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
XCOPY /Y ..\..\..\lib\windows\python\lib\python24.dll ..\..\bin
XCOPY /Y ..\..\..\lib\windows\gettext\lib\*.dll ..\..\bin
XCOPY /Y ..\..\..\lib\windows\sdl\lib\*.dll ..\..\bin
-XCOPY /Y ..\..\..\lib\windows\tiff\lib\libtiff.dll ..\..\bin
ECHO Copying language folder
ECHO Done
"/>
XCOPY /Y ..\..\..\lib\windows\sdl\lib\*.dll ..\..\bin\debug
XCOPY /Y ..\..\..\lib\windows\python\lib\python24_d.dll ..\..\bin\debug
XCOPY /Y ..\..\..\lib\windows\CRTL\lib\msvcrtd.dll ..\..\bin\debug
-XCOPY /Y ..\..\..\lib\windows\tiff\lib\libtiff.dll ..\..\bin\debug
ECHO Copying language folder
IF NOT EXIST ..\..\bin\debug\.blender MKDIR ..\..\bin\debug\.blender
XCOPY /Y ..\..\bin\.blender ..\..\bin\debug\.blender /E
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="_DEBUG,WIN32,_LIB,WITH_QUICKTIME"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,WITH_QUICKTIME"
StringPooling="TRUE"
RuntimeLibrary="2"
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,WITH_QUICKTIME"
StringPooling="TRUE"
RuntimeLibrary="0"
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="_DEBUG,WIN32,_LIB,WITH_QUICKTIME"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,WITH_QUICKTIME"
StringPooling="TRUE"
RuntimeLibrary="0"
<File
RelativePath="..\..\..\source\blender\imbuf\intern\divers.c">
</File>
- <File
- RelativePath="..\..\..\source\blender\imbuf\intern\dynlibtiff.c">
- </File>
<File
RelativePath="..\..\..\source\blender\imbuf\intern\filter.c">
</File>
<File
RelativePath="..\..\..\source\blender\imbuf\intern\targa.c">
</File>
- <File
- RelativePath="..\..\..\source\blender\imbuf\intern\tiff.c">
- </File>
<File
RelativePath="..\..\..\source\blender\imbuf\intern\util.c">
</File>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
- <File
- RelativePath="..\..\..\source\blender\imbuf\intern\dynlibtiff.h">
- </File>
<File
RelativePath="..\..\..\source\blender\imbuf\intern\IMB_allocimbuf.h">
</File>
<File
RelativePath="..\..\..\source\blender\imbuf\intern\IMB_targa.h">
</File>
- <File
- RelativePath="..\..\..\source\blender\imbuf\intern\IMB_tiff.h">
- </File>
<File
RelativePath="..\..\..\source\blender\imbuf\intern\imbuf.h">
</File>
ifeq ($(CPU),alpha)
@$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
COMPRESS="gzip -f --best" EXT2=".gz"
- else
+ endif
+ ifeq ($(CPU),i386)
+ @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
+ COMPRESS="gzip -f --best" EXT2=".gz"
+ @$(MAKE) pkg TYPE="-static" TAR="tar cf" EXT1=".tar" \
+ COMPRESS="gzip -f --best" EXT2=".gz"
+ endif
+ ifeq ($(CPU),powerpc)
@$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
COMPRESS="gzip -f --best" EXT2=".gz"
@$(MAKE) pkg TYPE="-static" TAR="tar cf" EXT1=".tar" \
return (nco,vec)
def get_vert(old, dir):
- """ Look in NV if a vertex corresponding to the vertex old and the
+ """ Look in NV if a vertice corresponding to the vertex old and the
direction dir already exists, and create one otherwise"""
(nco, vec) = parall_coord(old, dir)
v = is_in_NV(old,vec)
is_in_v = lambda x:x in V
eed = [filter(is_in_v, l) for l in q]
#
- # We will add the edges coming from faces where only one vertex is selected.
+ # We will add the edges coming from faces where only one vertice is selected.
# They are stocked in NC.
if v in NC.keys():
eed = eed+NC[v]
"""
Name: 'Motion Capture (.bvh)...'
-Blender: 239
+Blender: 236
Group: 'Import'
Tip: 'Import a (.bvh) motion capture file'
"""
__author__ = "Campbell Barton"
-__url__ = ("blender", "elysiun")
-__version__ = "1.0.4 05/12/04"
+__url__ = ("blender", "elysiun", "http://jmsoler.free.fr/util/blenderfile/py/bvh_import.py")
+__version__ = "1.0.2 04/12/28"
__bpydoc__ = """\
This script imports BVH motion capture data to Blender.
Known issues:<br>
Notes:<br>
- Jean-Michel Soler improved importer to support Poser 3.01 files;<br>
- Jean-Baptiste Perin wrote a script to create an armature out of the
+ Jean-Michel Soler improved importer to support Poser 3.01 files;<br>
+ Jean-Baptiste Perin wrote a script to create an armature out of the
Empties created by this importer, it's in the Scripts window -> Scripts -> Animation menu.
"""
# $Id$
#
-#===============================================#
-# BVH Import script 1.05 patched by Campbell #
-# Modified to use Mathutils for matrix math, #
-# Fixed possible joint naming bug, #
-# Imports BVH's with bad EOF gracefully #
-# Fixed duplicate joint names, make them unique #
-# Use \r as well as \n for newlines #
-# Added suppot for nodes with 0 motion channels #
-# Rotation IPOs never cross more then 180d #
-# fixes sub frame tweening and time scaling #
-# 5x overall speedup. #
-# 06/12/2005, #
-#===============================================#
-
-#===============================================#
-# BVH Import script 1.04 patched by jms #
-# Small modif for blender 2.40 #
-# 04/12/2005, #
-#===============================================#
-
#===============================================#
# BVH Import script 1.03 patched by Campbell #
# Small optimizations and scale input #
-# 01/01/2005, #
+# 01/01/2005, #
#===============================================#
#===============================================#
# BVH Import script 1.02 patched by Jm Soler #
-# to the Poser 3.01 bvh file #
-# 28/12/2004, #
+# to the Poser 3.01 bvh file #
+# 28/12/2004, #
#===============================================#
#===============================================#
# BVH Import script 1.0 by Campbell Barton #
# 25/03/2004, euler rotation code taken from #
# Reevan Mckay's BVH import script v1.1 #
-# if you have any questions about this scrip. #
-# email me cbarton@metavr.com #
+# if you have any questions about this script #
+# email me ideasman@linuxmail.org #
#===============================================#
#===============================================#
#===============================================#
# --------------------------------------------------------------------------
-# BVH Import v1.05 by Campbell Barton (AKA Ideasman)
+# BVH Import v0.9 by Campbell Barton (AKA Ideasman)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
#
# 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
+# 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.
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
+
+import string
+import math
import Blender
from Blender import Window, Object, Scene, Ipo, Draw
from Blender.Scene import Render
-# Attempt to load psyco, speed things up
-try:
- import psyco
- psyco.full()
- print 'using psyco to speed up BVH importing'
-except:
- #print 'psyco is not present on this system'
- pass
-
-
-
-def main():
- global scale
- scale = None
-
- # Update as we load?
- debug = 0
-
- def getScale():
- return Draw.PupFloatInput('BVH Scale: ', 0.01, 0.001, 10.0, 0.1, 3)
-
-
- #===============================================#
- # MAIN FUNCTION - All things are done from here #
- #===============================================#
- def loadBVH(filename):
- global scale
- print '\nBVH Importer 1.05 by Campbell Barton (Ideasman) - cbarton@metavr.com'
-
- objectCurveMapping = {}
- objectNameMapping = {}
- objectMotiondataMapping = {}
-
- # Here we store the Ipo curves in the order they load.
- channelCurves = []
-
- # Object list
- # We need this so we can loop through the objects and edit there IPO's
- # Chenging there rotation to EULER rotation
- objectList = []
-
- if scale == None:
- tempscale = getScale()
- if tempscale:
- scale = tempscale
- else:
- scale = 0.01
-
- Window.WaitCursor(1)
- # Unique names, dont reuse any of these names.
- uniqueObNames = [ob.name for ob in Object.Get()]
-
-
- # FUNCTIONS ====================================#
- def getUniqueObName(name):
- i = 0
- newname = name[:min(len(name), 12)] # Concatinate to 12 chars
- while newname in uniqueObNames:
- newname = name + str(i)
- i+=1
- return newname
-
- # Change the order rotation is applied.
- RotationMatrix = Blender.Mathutils.RotationMatrix
- MATRIX_IDENTITY_3x3 = Blender.Mathutils.Matrix([1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0])
- def eulerRotate(x,y,z):
- x,y,z = x%360,y%360,z%360 # Clamp all values between 0 and 360, values outside this raise an error.
- xmat = RotationMatrix(x,3,'x')
- ymat = RotationMatrix(y,3,'y')
- zmat = RotationMatrix(z,3,'z')
- # Standard BVH multiplication order, apply the rotation in the order Z,X,Y
- return (ymat*(xmat * (zmat * MATRIX_IDENTITY_3x3))).toEuler()
-
-
- currentFrame = 1 # Set the initial frame to import all data to.
-
- #===============================================#
- # makeJoint: Here we use the node data #
- # from the BVA file to create an empty #
- #===============================================#
- BVH2BLEND_TX_NAME = {'Xposition':'LocX','Yposition':'LocY','Zposition':'LocZ','Xrotation':'RotX','Yrotation':'RotY','Zrotation':'RotZ'}
- def makeJoint(name, parent, offset, channels):
- ob = Object.New('Empty', name) # New object, ob is shorter and nicer to use.
-
- objectNameMapping[name] = ob
- scn.link(ob) # place the object in the current scene
- ob.sel = 1
-
- # Make me a child of another empty.
- # Vale of None will make the empty a root node (no parent)
- if parent[-1]: # != None
- obParent = objectNameMapping[parent[-1]] # We use this a bit so refrence it here.
- obParent.makeParent([ob], 1, 0) #ojbs, noninverse, 1 = not fast.
-
- # Offset Empty from BVH's initial joint location.
- ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale)
-
- # Add Ipo's for necessary channels
- newIpo = Ipo.New('Object', name)
- ob.setIpo(newIpo)
- obname = ob.name
- for channelType in channels:
- channelType = BVH2BLEND_TX_NAME[channelType]
- curve = newIpo.addCurve(channelType)
- curve.setInterpolation('Linear')
- objectCurveMapping[(obname, channelType)] = curve
-
- # Add to object list
- objectList.append(ob)
-
- # Redraw if debugging
- if debug: Blender.Redraw()
-
-
- #===============================================#
- # makeEnd: Here we make an end node #
- # This is needed when adding the last bone #
- #===============================================#
- def makeEnd(parent, offset):
- new_name = parent[-1] + '_end'
- ob = Object.New('Empty', new_name) # New object, ob is shorter and nicer to use.
- objectNameMapping[new_name] = ob
- scn.link(ob)
- ob.sel = 1
-
- # Dont check for a parent, an end node MUST have a parent
- obParent = objectNameMapping[parent[-1]] # We use this a bit so refrence it here.
- obParent.makeParent([ob], 1, 0) #ojbs, noninverse, 1 = not fast.
-
- # Offset Empty
- ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale)
-
- # Redraw if debugging
- if debug: Blender.Redraw()
- # END FUNCTION DEFINITIONS ====================================#
-
-
-
-
- time1 = Blender.sys.time()
-
- # Get the current scene.
- scn = Scene.GetCurrent()
- #context = scn.getRenderingContext()
-
- # DeSelect All
- for ob in scn.getChildren():
- ob.sel = 0
-
- # File loading stuff
- # Open the file for importing
- file = open(filename, 'r')
-
- # Seperate into a list of lists, each line a list of words.
- lines = file.readlines()
- # Non standard carrage returns?
- if len(lines) == 1:
- lines = lines[0].split('\r')
-
- # Split by whitespace.
- lines =[ll for ll in [ [w for w in l.split() if w != '\n' ] for l in lines] if ll]
- # End file loading code
-
-
-
- # Create Hirachy as empties
- if lines[0][0] == 'HIERARCHY':
- print 'Importing the BVH Hierarchy for:', filename
- else:
- return 'ERROR: This is not a BVH file'
-
- # A liniar list of ancestors to keep track of a single objects heratage
- # at any one time, this is appended and removed, dosent store tree- just a liniar list.
- # ZERO is a place holder that means we are a root node. (no parents)
- parent = [None]
-
- #channelList, sync with objectList: [[channelType1, channelType2...], [channelType1, channelType2...)]
- channelList = []
- channelIndex = -1
-
- lineIdx = 0 # An index for the file.
- while lineIdx < len(lines) -1:
- #...
- if lines[lineIdx][0] == 'ROOT' or lines[lineIdx][0] == 'JOINT':
-
- # Join spaces into 1 word with underscores joining it.
- if len(lines[lineIdx]) > 2:
- lines[lineIdx][1] = '_'.join(lines[lineIdx][1:])
- lines[lineIdx] = lines[lineIdx][:2]
-
- # MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
-
- # Make sure the names are unique- Object names will match joint names exactly and both will be unique.
- name = getUniqueObName(lines[lineIdx][1])
- uniqueObNames.append(name)
-
- print '%snode: %s, parent: %s' % (len(parent) * ' ', name, parent[-1])
-
- lineIdx += 2 # Incriment to the next line (Offset)
- offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
- lineIdx += 1 # Incriment to the next line (Channels)
-
- # newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
- # newChannel references indecies to the motiondata,
- # if not assigned then -1 refers to the last value that will be added on loading at a value of zero, this is appended
- # We'll add a zero value onto the end of the MotionDATA so this is always refers to a value.
- newChannel = [-1, -1, -1, -1, -1, -1]
- for channel in lines[lineIdx][2:]:
- channelIndex += 1 # So the index points to the right channel
- if channel == 'Xposition':
- newChannel[0] = channelIndex
- elif channel == 'Yposition':
- newChannel[1] = channelIndex
- elif channel == 'Zposition':
- newChannel[2] = channelIndex
- elif channel == 'Xrotation':
- newChannel[3] = channelIndex
- elif channel == 'Yrotation':
- newChannel[4] = channelIndex
- elif channel == 'Zrotation':
- newChannel[5] = channelIndex
-
- channelList.append(newChannel)
-
- channels = lines[lineIdx][2:]
-
- # Call funtion that uses the gatrhered data to make an empty.
- makeJoint(name, parent, offset, channels)
-
- # If we have another child then we can call ourselves a parent, else
- parent.append(name)
-
- # Account for an end node
- if lines[lineIdx][0] == 'End' and lines[lineIdx][1] == 'Site': # There is somtimes a name after 'End Site' but we will ignore it.
- lineIdx += 2 # Incriment to the next line (Offset)
- offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
- makeEnd(parent, offset)
-
- # Just so we can remove the Parents in a uniform way- End end never has kids
- # so this is a placeholder
- parent.append(None)
-
- if len(lines[lineIdx]) == 1 and lines[lineIdx][0] == '}': # == ['}']
- parent.pop() # Remove the last item
-
- #=============================================#
- # BVH Structure loaded, Now import motion #
- #=============================================#
- if len(lines[lineIdx]) == 1 and lines[lineIdx][0] == 'MOTION':
- print '\nImporting motion data'
- lineIdx += 3 # Set the cursor to the first frame
-
- #=============================================#
- # Add a ZERO keyframe, this keeps the rig #
- # so when we export we know where all the #
- # joints start from #
- #=============================================#
-
- for obIdx, ob in enumerate(objectList):
- obname = ob.name
- if channelList[obIdx][0] != -1:
- objectCurveMapping[obname, 'LocX'].addBezier((currentFrame,0))
- objectMotiondataMapping[obname, 'LocX'] = []
- if channelList[obIdx][1] != -1:
- objectCurveMapping[obname, 'LocY'].addBezier((currentFrame,0))
- objectMotiondataMapping[obname, 'LocY'] = []
- if channelList[obIdx][2] != -1:
- objectCurveMapping[obname, 'LocZ'].addBezier((currentFrame,0))
- objectMotiondataMapping[obname, 'LocZ'] = []
- if\
- channelList[obIdx][3] != -1 or\
- channelList[obIdx][4] != -1 or\
- channelList[obIdx][5] != -1:
- objectMotiondataMapping[obname, 'RotX'] = []
- objectMotiondataMapping[obname, 'RotY'] = []
- objectMotiondataMapping[obname, 'RotZ'] = []
-
- #=============================================#
- # Loop through frames, each line a frame #
- #=============================================#
- MOTION_DATA_LINE_LEN = len(lines[lineIdx])
- while lineIdx < len(lines):
- line = lines[lineIdx]
- if MOTION_DATA_LINE_LEN != len(line):
- print 'ERROR: Incomplete motion data on line %i, finishing import.' % lineIdx
- break
-
- # Exit loop if we are past the motiondata.
- # Some BVH's have extra tags like 'CONSTRAINTS and MOTIONTAGS'
- # I dont know what they do and I dont care, they'll be ignored here.
- if len(line) < len(objectList):
- print '...ending on unknown tags'
- break
-
-
- currentFrame += 1 # Incriment to next frame
-
- #=============================================#
- # Import motion data and assign it to an IPO #
- #=============================================#
- line.append(0.0) # Use this as a dummy var for objects that dont have a loc/rotate channel.
-
- if debug: Blender.Redraw()
- for obIdx, ob in enumerate(objectList):
- obname = ob.name
- obChannel = channelList[obIdx]
- if channelList[obIdx][0] != -1:
- objectMotiondataMapping[obname, 'LocX'].append((currentFrame, scale * float( line[obChannel[0]] )))
-
- if channelList[obIdx][1] != -1:
- objectMotiondataMapping[obname, 'LocY'].append((currentFrame, scale * float( line[obChannel[1]] )))
-
- if channelList[obIdx][2] != -1:
- objectMotiondataMapping[obname, 'LocZ'].append((currentFrame, scale * float( line[obChannel[2]] )))
-
- if obChannel[3] != -1 or obChannel[4] != -1 or obChannel[5] != -1:
- x, y, z = eulerRotate(float( line[obChannel[3]] ), float( line[obChannel[4]] ), float( line[obChannel[5]] ))
- x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d
- motionMappingRotX = objectMotiondataMapping[obname, 'RotX']
- motionMappingRotY = objectMotiondataMapping[obname, 'RotY']
- motionMappingRotZ = objectMotiondataMapping[obname, 'RotZ']
-
- # Make interpolation not cross between 180d, thjis fixes sub frame interpolation and time scaling.
- # Will go from (355d to 365d) rather then to (355d to 5d) - inbetween these 2 there will now be a correct interpolation.
- if len(motionMappingRotX) > 1:
- while (motionMappingRotX[-1][1] - x) > 18: x+=36
- while (motionMappingRotX[-1][1] - x) < -18: x-=36
-
- while (motionMappingRotY[-1][1] - y) > 18: y+=36
- while (motionMappingRotY[-1][1] - y) < -18: y-=36
-
- while (motionMappingRotZ[-1][1] - z) > 18: z+=36
- while (motionMappingRotZ[-1][1] - z) < -18: z-=36
-
- motionMappingRotX.append((currentFrame, x))
- motionMappingRotY.append((currentFrame, y))
- motionMappingRotZ.append((currentFrame, z))
- # Done importing motion data #
-
- lineIdx += 1
-
- #=======================================#
- # Now Write the motion to the IPO's #
- #=======================================#
- for key, motion_data in objectMotiondataMapping.iteritems():
-
- # Strip the motion data where all the points have the same falue.
- i = len(motion_data) -2
- while i > 0 and len(motion_data) > 2:
- if motion_data[i][1] == motion_data[i-1][1] == motion_data[i+1][1]:
- motion_data.pop(i)
- i-=1
- # Done stripping.
-
- obname, tx_type = key
- curve = objectCurveMapping[obname, tx_type]
- for point_data in motion_data:
- curve.addBezier( point_data )
- # Imported motion to an IPO
-
- # No point in looking further, when this loop is done
- # There is nothine else left to do
- break
-
- # Main file loop
- lineIdx += 1
-
- print 'bvh import time for %i frames: %.6f' % (currentFrame, Blender.sys.time() - time1)
- Window.RedrawAll()
- Window.WaitCursor(0)
-
- Blender.Window.FileSelector(loadBVH, "Import BVH")
-
- #=============#
- # TESTING #
- #=============#
- '''
- #loadBVH('/metavr/mocap/bvh/boxer.bvh')
- #loadBVH('/metavr/mocap/bvh/dg-306-g.bvh') # Incompleate EOF
- #loadBVH('/metavr/mocap/bvh/wa8lk.bvh') # duplicate joint names, \r line endings.
- #loadBVH('/metavr/mocap/bvh/walk4.bvh') # 0 channels
- scale = 0.01
- import os
- DIR = '/metavr/mocap/bvh/'
- for f in os.listdir(DIR):
- if f.endswith('.bvh'):
- s = Scene.New(f)
- s.makeCurrent()
- loadBVH(DIR + f)
- '''
-if __name__ == '__main__':
- main()
\ No newline at end of file
+# # PSYCO IS CRASHING ON MY SYSTEM
+# # Attempt to load psyco, speed things up
+# try:
+# print 'using psyco to speed up BVH importing'
+# import psyco
+# psyco.full()
+#
+# except:
+# print 'psyco is not present on this system'
+
+# Default scale
+scale = 0.01
+
+# Update as we load?
+debug = 0
+
+# Get the current scene.
+scn = Scene.GetCurrent()
+context = scn.getRenderingContext()
+
+# Here we store the Ipo curves in the order they load.
+channelCurves = []
+
+# Object list
+# We need this so we can loop through the objects and edit there IPO's
+# Chenging there rotation to EULER rotation
+objectList = []
+
+def getScale():
+ return Draw.PupFloatInput('BVH Scale: ', 0.01, 0.001, 10.0, 0.1, 3)
+
+def MAT(m):
+ if len(m) == 3:
+ return Blender.Mathutils.Matrix(m[0], m[1], m[2])
+ elif len(m) == 4:
+ return Blender.Mathutils.Matrix(m[0], m[1], m[2], m[3])
+
+
+
+#===============================================#
+# eulerRotation: converts X, Y, Z rotation #
+# to eular Rotation. This entire function #
+# is copied from Reevan Mckay's BVH script #
+#===============================================#
+# Vars used in eular rotation funtcion
+DEG_TO_RAD = math.pi/180.0
+RAD_TO_DEG = 180.0/math.pi
+PI=3.14159
+
+def eulerRotate(x,y,z):
+ #=================================
+ def RVMatMult3 (mat1,mat2):
+ #=================================
+ mat3=[[0.0,0.0,0.0],[0.0,0.0,0.0],[0.0,0.0,0.0]]
+ for i in range(3):
+ for k in range(3):
+ for j in range(3):
+ mat3[i][k]=mat3[i][k]+mat1[i][j]*mat2[j][k]
+ return mat3
+
+
+ #=================================
+ def RVAxisAngleToMat3 (rot4):
+ # Takes a direction vector and
+ # a rotation (in rads) and
+ # returns the rotation matrix.
+ # Graphics Gems I p. 466:
+ #=================================
+ mat3=[[0.0,0.0,0.0],[0.0,0.0,0.0],[0.0,0.0,0.0]]
+ if math.fabs(rot4[3])>0.01:
+ s=math.sin(rot4[3])
+ c=math.cos(rot4[3])
+ t=1.0-math.cos(rot4[3])
+ else:
+ s=rot4[3]
+ c=1.0
+ t=0.0
+
+ x=rot4[0]; y=rot4[1]; z=rot4[2]
+
+ mat3[0][0]=t*x*x+c
+ mat3[0][1]=t*x*y+s*z
+ mat3[0][2]=t*x*z-s*y
+
+ mat3[1][0]=t*x*y-s*z
+ mat3[1][1]=t*y*y+c
+ mat3[1][2]=t*y*z+s*x
+
+ mat3[2][0]=t*x*z+s*y
+ mat3[2][1]=t*y*z-s*x
+ mat3[2][2]=t*z*z+c
+
+ return mat3
+
+ eul = [x,y,z]
+
+ for jj in range(3):
+ while eul[jj] < 0:
+ eul[jj] = eul[jj] + 360.0
+ while eul[jj] >= 360.0:
+ eul[jj] = eul[jj] - 360.0
+
+ eul[0] = eul[0]*DEG_TO_RAD
+ eul[1] = eul[1]*DEG_TO_RAD
+ eul[2] = eul[2]*DEG_TO_RAD
+
+ xmat=RVAxisAngleToMat3([1,0,0,eul[0]])
+ ymat=RVAxisAngleToMat3([0,1,0,eul[1]])
+ zmat=RVAxisAngleToMat3([0,0,1,eul[2]])
+
+ mat=[[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]]
+
+ # Standard BVH multiplication order
+ mat=RVMatMult3 (zmat,mat)
+ mat=RVMatMult3 (xmat,mat)
+ mat=RVMatMult3 (ymat,mat)
+
+
+ '''
+ # Screwy Animation Master BVH multiplcation order
+ mat=RVMatMult3 (ymat,mat)
+ mat=RVMatMult3 (xmat,mat)
+ mat=RVMatMult3 (zmat,mat)
+ '''
+ mat = MAT(mat)
+
+ eul = mat.toEuler()
+ x =- eul[0]/-10
+ y =- eul[1]/-10
+ z =- eul[2]/-10
+
+ return x, y, z # Returm euler roration values.
+
+
+
+#===============================================#
+# makeJoint: Here we use the node data #
+# from the BVA file to create an empty #
+#===============================================#
+def makeJoint(name, parent, prefix, offset, channels):
+ global scale
+ # Make Empty, with the prefix in front of the name
+ ob = Object.New('Empty', prefix + name) # New object, ob is shorter and nicer to use.
+ scn.link(ob) # place the object in the current scene
+
+ # Offset Empty
+ ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale)
+
+ # Make me a child of another empty.
+ # Vale of None will make the empty a root node (no parent)
+ if parent[-1] != None:
+ obParent = Object.Get(prefix + parent[-1]) # We use this a bit so refrence it here.
+ obParent.makeParent([ob], 0, 1) #ojbs, noninverse, 1 = not fast.
+
+ # Add Ipo's for necessary channels
+ newIpo = Ipo.New('Object', prefix + name)
+ ob.setIpo(newIpo)
+ for channelType in channels:
+ if channelType == 'Xposition':
+ newIpo.addCurve('LocX')
+ newIpo.getCurve('LocX').setInterpolation('Linear')
+ if channelType == 'Yposition':
+ newIpo.addCurve('LocY')
+ newIpo.getCurve('LocY').setInterpolation('Linear')
+ if channelType == 'Zposition':
+ newIpo.addCurve('LocZ')
+ newIpo.getCurve('LocZ').setInterpolation('Linear')
+
+ if channelType == 'Zrotation':
+ newIpo.addCurve('RotZ')
+ newIpo.getCurve('RotZ').setInterpolation('Linear')
+ if channelType == 'Yrotation':
+ newIpo.addCurve('RotY')
+ newIpo.getCurve('RotY').setInterpolation('Linear')
+ if channelType == 'Xrotation':
+ newIpo.addCurve('RotX')
+ newIpo.getCurve('RotX').setInterpolation('Linear')
+
+ # Add to object list
+ objectList.append(ob)
+
+ # Redraw if debugging
+ if debug: Blender.Redraw()
+
+
+#===============================================#
+# makeEnd: Here we make an end node #
+# This is needed when adding the last bone #
+#===============================================#
+def makeEnd(parent, prefix, offset):
+ # Make Empty, with the prefix in front of the name, end nodes have no name so call it its parents name+'_end'
+ ob = Object.New('Empty', prefix + parent[-1] + '_end') # New object, ob is shorter and nicer to use.
+ scn.link(ob)
+
+ # Dont check for a parent, an end node MUST have a parent
+ obParent = Object.Get(prefix + parent[-1]) # We use this a bit so refrence it here.
+ obParent.makeParent([ob], 0, 1) #ojbs, noninverse, 1 = not fast.
+
+ # Offset Empty
+ ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale)
+
+ # Redraw if debugging
+ if debug: Blender.Redraw()
+
+
+
+
+#===============================================#
+# MAIN FUNCTION - All things are done from here #
+#===============================================#
+def loadBVH(filename):
+ global scale
+ print ''
+ print 'BVH Importer 1.0 by Campbell Barton (Ideasman) - ideasman@linuxmail.org'
+ alpha='abcdefghijklmnopqrstuvewxyz'
+ ALPHA=alpha+alpha.upper()
+ ALPHA+=' 0123456789+-{}. '
+ time1 = Blender.sys.time()
+ tmpScale = getScale()
+ if tmpScale != None:
+ scale = tmpScale
+
+ # File loading stuff
+ # Open the file for importing
+ file = open(filename, 'r')
+ fileData = file.readlines()
+ # Make a list of lines
+ lines = []
+ for fileLine in fileData:
+ fileLine=fileLine.replace('..','.')
+ newLine = string.split(fileLine)
+ if newLine != []:
+ t=[]
+ for n in newLine:
+ for n0 in n:
+ if n0 not in ALPHA:
+ n=n.replace(n0,'')
+ t.append(n)
+ lines.append(t)
+
+
+ del fileData
+ # End file loading code
+
+ # Call object names with this prefix, mainly for scenes with multiple BVH's - Can imagine most partr names are the same
+ # So in future
+ #prefix = str(len(lines)) + '_'
+
+ prefix = '_'
+
+ # Create Hirachy as empties
+ if lines[0][0] == 'HIERARCHY':
+ print 'Importing the BVH Hierarchy for:', filename
+ else:
+ return 'ERROR: This is not a BVH file'
+
+ # A liniar list of ancestors to keep track of a single objects heratage
+ # at any one time, this is appended and removed, dosent store tree- just a liniar list.
+ # ZERO is a place holder that means we are a root node. (no parents)
+ parent = [None]
+
+ #channelList [(<objectName>, [channelType1, channelType2...]), (<objectName>, [channelType1, channelType2...)]
+ channelList = []
+ channelIndex = -1
+
+
+
+ lineIdx = 1 # An index for the file.
+ while lineIdx < len(lines) -1:
+ #...
+ if lines[lineIdx][0] == 'ROOT' or lines[lineIdx][0] == 'JOINT':
+ if lines[lineIdx][0] == 'JOINT' and len(lines[lineIdx])>2:
+ for j in range(2,len(lines[lineIdx])) :
+ lines[lineIdx][1]+='_'+lines[lineIdx][j]
+
+ # MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
+
+ print len(parent) * ' ' + 'node:',lines[lineIdx][1],' parent:',parent[-1]
+ print lineIdx
+ name = lines[lineIdx][1]
+ print name,lines[lineIdx+1],lines[lineIdx+2]
+ lineIdx += 2 # Incriment to the next line (Offset)
+ offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
+ lineIdx += 1 # Incriment to the next line (Channels)
+
+ # newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
+ # newChannel has Indecies to the motiondata,
+ # -1 refers to the last value that will be added on loading at a value of zero
+ # We'll add a zero value onto the end of the MotionDATA so this is always refers to a value.
+ newChannel = [-1, -1, -1, -1, -1, -1]
+ for channel in lines[lineIdx][2:]:
+ channelIndex += 1 # So the index points to the right channel
+ if channel == 'Xposition':
+ newChannel[0] = channelIndex
+ elif channel == 'Yposition':
+ newChannel[1] = channelIndex
+ elif channel == 'Zposition':
+ newChannel[2] = channelIndex
+ elif channel == 'Xrotation':
+ newChannel[3] = channelIndex
+ elif channel == 'Yrotation':
+ newChannel[4] = channelIndex
+ elif channel == 'Zrotation':
+ newChannel[5] = channelIndex
+
+ channelList.append(newChannel)
+
+ channels = lines[lineIdx][2:]
+
+ # Call funtion that uses the gatrhered data to make an empty.
+ makeJoint(name, parent, prefix, offset, channels)
+
+ # If we have another child then we can call ourselves a parent, else
+ parent.append(name)
+
+ # Account for an end node
+ if lines[lineIdx][0] == 'End' and lines[lineIdx][1] == 'Site': # There is somtimes a name afetr 'End Site' but we will ignore it.
+ lineIdx += 2 # Incriment to the next line (Offset)
+ offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
+ makeEnd(parent, prefix, offset)
+
+ # Just so we can remove the Parents in a uniform way- End end never has kids
+ # so this is a placeholder
+ parent.append(None)
+
+ if lines[lineIdx] == ['}']:
+ parent = parent[:-1] # Remove the last item
+
+
+ #=============================================#
+ # BVH Structure loaded, Now import motion #
+ #=============================================#
+ if lines[lineIdx] == ['MOTION']:
+ print '\nImporting motion data'
+ lineIdx += 3 # Set the cursor to the forst frame
+
+ #=============================================#
+ # Loop through frames, each line a frame #
+ #=============================================#
+ currentFrame = 1
+ print 'frames: ',
+
+
+ #=============================================#
+ # Add a ZERO keyframe, this keeps the rig #
+ # so when we export we know where all the #
+ # joints start from #
+ #=============================================#
+ obIdx = 0
+ while obIdx < len(objectList) -1:
+ if channelList[obIdx][0] != -1:
+ objectList[obIdx].getIpo().getCurve('LocX').addBezier((currentFrame,0))
+ if channelList[obIdx][1] != -1:
+ objectList[obIdx].getIpo().getCurve('LocY').addBezier((currentFrame,0))
+ if channelList[obIdx][2] != -1:
+ objectList[obIdx].getIpo().getCurve('LocZ').addBezier((currentFrame,0))
+ if channelList[obIdx][3] != '-1' or channelList[obIdx][4] != '-1' or channelList[obIdx][5] != '-1':
+ objectList[obIdx].getIpo().getCurve('RotX').addBezier((currentFrame,0))
+ objectList[obIdx].getIpo().getCurve('RotY').addBezier((currentFrame,0))
+ objectList[obIdx].getIpo().getCurve('RotZ').addBezier((currentFrame,0))
+ obIdx += 1
+
+ while lineIdx < len(lines):
+
+ # Exit loop if we are past the motiondata.
+ # Some BVH's have extra tags like 'CONSTRAINTS and MOTIONTAGS'
+ # I dont know what they do and I dont care, they'll be ignored here.
+ if len(lines[lineIdx]) < len(objectList):
+ print '...ending on unknown tags'
+ break
+
+
+ currentFrame += 1 # Incriment to next frame
+
+ #=============================================#
+ # Import motion data and assign it to an IPO #
+ #=============================================#
+ lines[lineIdx].append('0') # Use this as a dummy var for objects that dont have a rotate channel.
+ obIdx = 0
+ if debug: Blender.Redraw()
+ while obIdx < len(objectList) -1:
+ if channelList[obIdx][0] != -1:
+ VAL0=lines[lineIdx][channelList[obIdx][0]]
+ if VAL0.find('.')==-1:
+ VAL0=VAL0[:len(VAL0)-6]+'.'+VAL0[-6:]
+ objectList[obIdx].getIpo().getCurve('LocX').addBezier((currentFrame, scale * float(VAL0)))
+
+ if channelList[obIdx][1] != -1:
+ VAL1=lines[lineIdx][channelList[obIdx][1]]
+ if VAL1.find('.')==-1:
+ VAL1=VAL1[:len(VAL1)-6]+'.'+VAL1[-6:]
+ objectList[obIdx].getIpo().getCurve('LocY').addBezier((currentFrame, scale * float(VAL1)))
+
+ if channelList[obIdx][2] != -1:
+ VAL2=lines[lineIdx][channelList[obIdx][2]]
+ if VAL2.find('.')==-1:
+ VAL2=VAL2[:len(VAL2)-6]+'.'+VAL2[-6:]
+ objectList[obIdx].getIpo().getCurve('LocZ').addBezier((currentFrame, scale * float(VAL2)))
+
+ if channelList[obIdx][3] != '-1' or channelList[obIdx][4] != '-1' or channelList[obIdx][5] != '-1':
+ VAL3=lines[lineIdx][channelList[obIdx][3]]
+ if VAL3.find('.')==-1:
+ VAL3=VAL3[:len(VAL3)-6]+'.'+VAL3[-6:]
+
+ VAL4=lines[lineIdx][channelList[obIdx][4]]
+ if VAL4.find('.')==-1:
+ VAL4=VAL4[:len(VAL4)-6]+'.'+VAL4[-6:]
+
+ VAL5=lines[lineIdx][channelList[obIdx][5]]
+ if VAL5.find('.')==-1:
+ VAL5=VAL5[:len(VAL5)-6]+'.'+VAL5[-6:]
+
+ x, y, z = eulerRotate(float(VAL3), float(VAL4), float(VAL5))
+
+ objectList[obIdx].getIpo().getCurve('RotX').addBezier((currentFrame, x))
+ objectList[obIdx].getIpo().getCurve('RotY').addBezier((currentFrame, y))
+ objectList[obIdx].getIpo().getCurve('RotZ').addBezier((currentFrame, z))
+
+ obIdx += 1
+ # Done importing motion data #
+
+ # lines[lineIdx] = None # Scrap old motion data, save some memory?
+ lineIdx += 1
+ # We have finished now
+ print currentFrame, 'done.'
+
+ # No point in looking further, when this loop is done
+ # There is nothine else left to do
+ print 'Imported ', currentFrame, ' frames'
+ break
+
+ # Main file loop
+ lineIdx += 1
+ print "bvh import time: ", Blender.sys.time() - time1
+
+Blender.Window.FileSelector(loadBVH, "Import BVH")
__author__ = "Campbell Barton AKA Ideasman"
__url__ = ["http://members.iinet.net.au/~cpbarton/ideasman/", "blender", "elysiun"]
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
import Blender
from Blender import *
import sys as python_sys
this function will fail
"""
- if not list: return ()
+ if len(list) == 0: return ()
l = []
for t in range(len(list[0])):
l.append(map( lambda x,t=t: x[t], list ))
# Dont bother with this data.
continue
- if type(dirItem) != types.StringType:
+ if type(dirItem) != type('str'):
print dirItem, type(dirItem)
if dirItem not in COLLECTED_VAR_NAMES.keys():
#print type(dirItem)
#if type(dirData) == types.ClassType or \
# type(dirData) == types.ModuleType:
- type_dirData = type(dirData)
- if type_dirData != types.StringType and\
- type_dirData != types.DictType and\
- type_dirData != types.DictionaryType and\
- type_dirData != types.FloatType and\
- type_dirData != types.IntType and\
- type_dirData != types.NoneType and\
- type_dirData != types.StringTypes and\
- type_dirData != types.TypeType and\
- type_dirData != types.TupleType and\
- type_dirData != types.BuiltinFunctionType:
+
+ if type(dirData) != types.StringType and\
+ type(dirData) != types.DictType and\
+ type(dirData) != types.DictionaryType and\
+ type(dirData) != types.FloatType and\
+ type(dirData) != types.IntType and\
+ type(dirData) != types.NoneType and\
+ type(dirData) != types.StringTypes and\
+ type(dirData) != types.TypeType and\
+ type(dirData) != types.TupleType and\
+ type(dirData) != types.BuiltinFunctionType:
# print type(dirData), dirItem
# Dont loop up dirs for strings ints etc.
if dirItem not in dirStringSplit:
menuList.sort()
choice = PupMenuLess( # Menu for the user to choose the autocompleate
- 'Choices (Shift for local name, Ctrl for Docs)%t|' + # Title Text
+ 'Choices (Shift for Whole name, Ctrl for Docs)%t|' + # Title Text
'|'.join(['%s, %s' % m for m in menuList])) # Use Absolute names m[0]
if choice != -1:
if Window.GetKeyQualifiers() & Window.Qual.CTRL: # Help
cmdBuffer[-1].cmd = ('help(%s%s) ' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0]))
elif Window.GetKeyQualifiers() & Window.Qual.SHIFT: # Put in the long name
- cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][1], cmdBuffer[-1].cmd[cursor:]))
- else: # Only paste in the Short name
cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0], cmdBuffer[-1].cmd[cursor:]))
-
+ else: # Only paste in the Short name
+ cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][1], cmdBuffer[-1].cmd[cursor:]))
else:
# print 'NO EDITVAR'
# Quit from menu only
#if (evt == Draw.ESCKEY and not val):
# Draw.Exit()
- if evt == Draw.MOUSEX or evt == Draw.MOUSEY: # AVOID TOO MANY REDRAWS.
- return
+ if evt == Draw.MOUSEX: # AVOID TOO MANY REDRAWS.
+ return
+ elif evt == Draw.MOUSEY:
+ return
+
global cursor
def main():
Draw.Register(draw_gui, handle_event, handle_button_event)
-main()
\ No newline at end of file
+main()
# init value is: object_list = [[None, {}, [], [], {}, {}, 0, {}, {}]]
#0 - objname #original name
#1 - obj_dict = {TAG} #objects created
- #2 - verts = [] #object vertices
- #3 - faces = [] #object faces (associations poly -> vertices)
+ #2 - verts = [] #object vertexes
+ #3 - faces = [] #object faces (associations poly -> vertexes)
#4 - obj_dim_dict = {TAG} #tuples size and pos in local object coords - used for NON-UV mappings
#5 - polytag_dict = {TAG} #tag to polygon mapping
#6 - patch_flag #0 = surf; 1 = patch (subdivision surface) - it was the image list
if object_list[object_index][3] != []:
object_list.append([object_list[object_index][0], #update name
{}, #init
- copy.deepcopy(object_list[object_index][2]), #same vertices
+ copy.deepcopy(object_list[object_index][2]), #same vertexes
[], #no faces
{}, #no need to copy - filled at runtime
{}, #polygon tagging will follow
Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Verts")
x, y, z = struct.unpack(">fff", data.read(12))
verts[i] = (x, z, y)
- tobj.pprint("read %d vertices" % (i+1))
+ tobj.pprint("read %d vertexes" % (i+1))
return verts
# enddef read_verts
# ======================
def read_vmap(uvcoords_dict, facesuv_dict, faces, maxvertnum, lwochunk):
if maxvertnum == 0:
- tobj.pprint ("Found VMAP but no vertices to map!")
+ tobj.pprint ("Found VMAP but no vertexes to map!")
return uvcoords_dict, facesuv_dict
data = cStringIO.StringIO(lwochunk.read())
map_type = data.read(4)
vertnum, vnum_size = read_vx(data)
u, v = struct.unpack(">ff", data.read(8))
if vertnum >= maxvertnum:
- tobj.pprint ("Hem: more uvmap than vertices? ignoring uv data for vertex %d" % vertnum)
+ tobj.pprint ("Hem: more uvmap than vertexes? ignoring uv data for vertex %d" % vertnum)
else:
my_uv_list[vertnum] = (u, v)
i += 8 + vnum_size
def read_vmad(uvcoords_dict, facesuv_dict, faces, maxvertnum, lwochunk):
maxfacenum = len(faces)
if maxvertnum == 0 or maxfacenum == 0:
- tobj.pprint ("Found VMAD but no vertices to map!")
+ tobj.pprint ("Found VMAD but no vertexes to map!")
return uvcoords_dict, facesuv_dict
data = cStringIO.StringIO(lwochunk.read())
map_type = data.read(4)
i += vnum_size
u, v = struct.unpack(">ff", data.read(8))
if polynum >= maxfacenum or vertnum >= maxvertnum:
- tobj.pprint ("Hem: more uvmap than vertices? ignorig uv data for vertex %d" % vertnum)
+ tobj.pprint ("Hem: more uvmap than vertexes? ignorig uv data for vertex %d" % vertnum)
else:
my_uv_list.append( (u,v) )
newindex = len(my_uv_list) - 1
for vi in range(len(my_facesuv_list[polynum])): #polynum starting from 1 or from 0?
if my_facesuv_list[polynum][vi] == vertnum:
my_facesuv_list[polynum][vi] = newindex
- #end loop on current face vertices
+ #end loop on current face vertexes
i += 8
#end loop on uv pairs
uvcoords_dict[name] = my_uv_list
facesuv_dict[name] = my_facesuv_list
- tobj.pprint ("updated %d vertices data" % (newindex-lastindex))
+ tobj.pprint ("updated %d vertexes data" % (newindex-lastindex))
return uvcoords_dict, facesuv_dict
# ================
def find_ear(normal, list_dict, verts, face):
nv = len(list_dict['MF'])
- #looping through vertices trying to find an ear
+ #looping through vertexes trying to find an ear
#most likely in case of panic
mlc = 0
mla = 1
concave_inside = 1
break
#endif found a concave vertex
- #end loop looking for concave vertices
+ #end loop looking for concave vertexes
if (concave == 0) or (concave_inside == 0):
- #no concave vertices in polygon (should not be): return immediately
- #looped all concave vertices and no one inside found
+ #no concave vertexes in polygon (should not be): return immediately
+ #looped all concave vertexes and no one inside found
return [c, a, b]
#no convex vertex, try another one
#end loop to find a suitable base vertex for ear
list_dict['P'] = [None] * nv
#list of distances
for mvi in list_dict['MF']:
- #vector between two vertices
+ #vector between two vertexes
mvi_hiend = (mvi+1) % nv #last-to-first
vi_hiend = face[mvi_hiend] #vertex
vi = face[mvi]
list_dict['D'][mvi] = dist_vector(verts[vi_hiend], verts[vi])
- #list of cross products - normals evaluated into vertices
+ #list of cross products - normals evaluated into vertexes
for vi in range(nv):
list_dict['X'][vi] = Blender.Mathutils.CrossVecs(list_dict['D'][vi], list_dict['D'][vi-1])
my_face_normal = Blender.Mathutils.Vector([list_dict['X'][0][0], list_dict['X'][0][1], list_dict['X'][0][2]])
list_dict['P'].pop(ct[1])
one_concave = reduce(lambda x, y: (x) or (y<0.0), list_dict['P'], 0)
nv -=1
- else: #here if no more concave vertices
- if nv == 4: break #quads only if no concave vertices
+ else: #here if no more concave vertexes
+ if nv == 4: break #quads only if no concave vertexes
decomposition_list.append([list_dict['MF'][0], list_dict['MF'][1], list_dict['MF'][2]])
#physical removal
list_dict['MF'].pop(1)
mesh = Blender.NMesh.GetRaw()
- #append vertices
+ #append vertexes
jj = 0
for i in range(len(complete_vertlist)):
if vertex_map[i] == 1:
mesh.verts.append(Blender.NMesh.Vert(x, y, z))
vertex_map[i] = jj
jj += 1
- #end sweep over vertices
+ #end sweep over vertexes
#append faces
for i in range(len(cur_ptag_faces)):
#for vi in cur_ptag_faces[i]:
index = vertex_map[vi]
face.v.append(mesh.verts[index])
- #end sweep over vertices
+ #end sweep over vertexes
mesh.faces.append(face)
#end sweep over faces
__author__ = "Martin 'theeth' Poirier"
__url__ = ("http://www.blender.org", "http://www.elysiun.com")
-__version__ = "1.4"
+__version__ = "1.3a"
__bpydoc__ = """\
This script exports the UV face layout of the selected mesh object to
use object's name and more.
Notes:<br>
- Jean-Michel Soler (jms) wrote TGA functions used by this script.<br>
- Zaz added the default path code and Selected Face option.<br>
- Macouno fixed a rounding error in the step calculations<br>
+ Jean-Michel Soler (jms) wrote TGA functions used by this script.
+ Zaz added the default path code and Selected Face option.
"""
# Communicate problems and errors on:
# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
# --------------------------
-# Version 1.1
+# Version 1.1
# Clear a bug that crashed the script when UV coords overlapped in the same faces
# --------------------------
-# Version 1.2
+# Version 1.2
# Now with option to use the object's name as filename
# --------------------------
-# Version 1.3 Updates by Zaz from Elysiun.com
+# Version 1.3 Updates by Zaz from Elysiun.com
# Default path is now the directory of the last saved .blend
# New options: Work on selected face only & Scale image when face wraps
# --------------------------
-# Version 1.3a
+# Version 1.3a
# Corrected a minor typo and added the tga extension to both export call
# --------------------------
-# Version 1.4 Updates by Macouno from Elysiun.com
-# Fixed rounding error that can cause breaks in lines.
-# --------------------------
import Blender
from math import *
UV_Export(bSize.val, bWSize.val, bFile.val + ".tga")
def Buffer(height=16, width=16, profondeur=3,rvb=255 ):
- """
- reserve l'espace memoire necessaire
- """
- p=[rvb]
- b=p*height*width*profondeur
- return b
+ """
+ reserve l'espace memoire necessaire
+ """
+ p=[rvb]
+ b=p*height*width*profondeur
+ return b
def write_tgafile(loc2,bitmap,width,height,profondeur):
- f=open(loc2,'wb')
+ f=open(loc2,'wb')
- Origine_en_haut_a_gauche=32
- Origine_en_bas_a_gauche=0
+ Origine_en_haut_a_gauche=32
+ Origine_en_bas_a_gauche=0
- Data_Type_2=2
- RVB=profondeur*8
- RVBA=32
- entete0=[]
- for t in range(18):
- entete0.append(chr(0))
+ Data_Type_2=2
+ RVB=profondeur*8
+ RVBA=32
+ entete0=[]
+ for t in range(18):
+ entete0.append(chr(0))
- entete0[2]=chr(Data_Type_2)
- entete0[13]=chr(width/256)
- entete0[12]=chr(width % 256)
- entete0[15]=chr(height/256)
- entete0[14]=chr(height % 256)
- entete0[16]=chr(RVB)
- entete0[17]=chr(Origine_en_bas_a_gauche)
+ entete0[2]=chr(Data_Type_2)
+ entete0[13]=chr(width/256)
+ entete0[12]=chr(width % 256)
+ entete0[15]=chr(height/256)
+ entete0[14]=chr(height % 256)
+ entete0[16]=chr(RVB)
+ entete0[17]=chr(Origine_en_bas_a_gauche)
- #Origine_en_haut_a_gauche
+ #Origine_en_haut_a_gauche
- for t in entete0:
- f.write(t)
+ for t in entete0:
+ f.write(t)
- for t in bitmap:
- f.write(chr(t))
- f.close()
+ for t in bitmap:
+ f.write(chr(t))
+ f.close()
def UV_Export(size, wsize, file):
obj = Blender.Object.GetSelected()
co2 = f[index + 1]
else:
co2 = f[0]
-
- step = int(ceil(size*sqrt((co1[0]-co2[0])**2+(co1[1]-co2[1])**2)))
+ step = int(size*sqrt((co1[0]-co2[0])**2+(co1[1]-co2[1])**2))
if step:
- for t in range(step):
- x = int(floor((co1[0] + t*(co2[0]-co1[0])/step) * size))
- y = int(floor((co1[1] + t*(co2[1]-co1[1])/step) * size))
+ for t in range(step + 1):
+ x = int((co1[0] + t*(co2[0]-co1[0])/step) * size)
+ y = int((co1[1] + t*(co2[1]-co1[1])/step) * size)
if bWrap.val:
x = x % wrapSize
x = int ((x - minx) * scale)
y = int ((y - miny) * scale)
- co = x * 3 + y * 3 * size;
-
+ co = x * 3 + y * 3 * size
img[co] = 0
img[co+1] = 0
- img[co+2] = 0
+ img[co+2] = 255
if wsize > 1:
for x in range(-1*wsize + 1,wsize):
for y in range(-1*wsize,wsize):
img[co + 3 * x + y * 3 * size] = 0
img[co + 3 * x + y * 3 * size +1] = 0
- img[co + 3 * x + y * 3 * size +2] = 0
+ img[co + 3 * x + y * 3 * size +2] = 255
for v in f:
x = int(v[0] * size)
co = x * 3 + y * 3 * size
img[co] = 0
img[co+1] = 0
- img[co+2] = 255
+ img[co+2] = 0
+
write_tgafile(file,img,size,size,3)
struct MVert;
struct Object;
+struct TFace;
struct EditMesh;
struct DispListMesh;
struct ModifierData;
/* Draw all faces uses TFace
* o Drawing options too complicated to enumerate, look at code.
*/
- void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(TFace *tf, int matnr));
+ void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(struct TFace *tf, int matnr));
/* Draw mapped faces (no color, or texture)
* o Only if !setDrawOptions or setDrawOptions(userData, mapped-face-index, drawSmooth_r) returns true
struct PartEff;
struct Scene;
+typedef struct DupliObject {
+ struct DupliObject *next, *prev;
+ struct Object *ob;
+ float mat[4][4], omat[4][4];
+} DupliObject;
+
void free_path(struct Path *path);
void calc_curvepath(struct Object *ob);
int interval_test(int min, int max, int p1, int cycl);
int where_on_path(struct Object *ob, float ctime, float *vec, float *dir);
-void frames_duplilist(struct Object *ob);
-void vertex_duplilist(struct Scene *sce, struct Object *par);
-void particle_duplilist(struct Scene *sce, struct Object *par, struct PartEff *paf);
-void free_duplilist(void);
-void make_duplilist(struct Scene *sce, struct Object *ob);
+
+ListBase *object_duplilist(struct Scene *sce, struct Object *ob);
int count_duplilist(struct Object *ob);
#endif
float Toon_Diff(float *n, float *l, float *v, float a, float b);
float OrenNayar_Diff(float *n, float *l, float *v, float rough);
float Minnaert_Diff(float nl, float *n, float *v, float a);
+float Fresnel_Diff(float *vn, float *lv, float *view, float ior, float fac);
void add_to_diffuse(float *, ShadeInput *, float, float, float, float);
void ramp_diffuse_result(float *diff, ShadeInput *shi);
void externtex(struct MTex *mtex, float *vec, float *tin, float *tr,
float *tg, float *tb, float *ta);
void init_render_textures(void);
-void end_render_textures(void);
void RE_free_envmap(struct EnvMap *env);
void RE_free_envmapdata(struct EnvMap *env);
void DAG_object_flush_update(struct Scene *sce, struct Object *ob, short flag);
void DAG_pose_sort(struct Object *ob);
-
+
#endif
/* prototypes */
+struct Base;
struct Object;
struct Curve;
struct ListBase;
extern void makeDispListSurf(struct Object *ob, struct ListBase *dispbase, int forRender);
extern void makeDispListCurveTypes(struct Object *ob, int forOrco);
extern void makeDispListMBall(struct Object *ob);
-extern void shadeDispList(struct Object *ob);
+extern void shadeDispList(struct Base *base);
void freefastshade(void);
void imagestodisplist(void);
void reshadeall_displist(void);
#ifndef BKE_EFFECT_H
#define BKE_EFFECT_H
+#include "DNA_object_types.h"
+
struct Effect;
struct ListBase;
-struct Object;
struct PartEff;
-struct MTex;
-struct Mesh;
-struct WaveEff;
struct Particle;
+struct Group;
+
+typedef struct pEffectorCache {
+ struct pEffectorCache *next, *prev;
+ Object *ob;
+
+ /* precalculated variables */
+ float oldloc[3], oldspeed[3];
+ float scale, time_scale;
+ float guide_dist;
+
+ Object obcopy; /* for restoring transformation data */
+} pEffectorCache;
+
struct Effect *add_effect(int type);
void free_effect(struct Effect *eff);
/* particle deflector */
#define PE_WIND_AS_SPEED 0x00000001
-struct ListBase *pdInitEffectors(struct Object *ob);
+struct ListBase *pdInitEffectors(struct Object *obsrc, struct Group *group);
void pdEndEffectors(struct ListBase *lb);
void pdDoEffectors(struct ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags);
struct Curve;
struct objfnt;
+struct chartrans {
+ float xof, yof;
+ float rot;
+ short linenr,charnr;
+ char dobreak;
+};
+
typedef struct SelBox {
float x, y, w, h;
} SelBox;
struct chartrans *text_to_curve(struct Object *ob, int mode);
int style_to_sel(int style, int toggle);
int mat_to_sel(void);
-void font_duplilist(struct Object *par);
+
int getselection(int *start, int *end);
void chtoutf8(unsigned long c, char *o);
#define BKE_GROUP_H
struct Group;
-struct GroupKey;
struct GroupObject;
-struct ObjectKey;
struct Object;
+struct bAction;
-void free_object_key(struct ObjectKey *ok);
-void free_group_object(struct GroupObject *go);
-void free_group(struct Group *group);
+void free_group_object(struct GroupObject *go);
+void free_group(struct Group *group);
+void unlink_group(struct Group *group);
struct Group *add_group(void);
-void object_to_obkey(struct Object *ob, struct ObjectKey *ok);
-void obkey_to_object(struct ObjectKey *ok, struct Object *ob);
-void add_object_key(struct GroupObject *go, struct GroupKey *gk);
-void add_to_group(struct Group *group, struct Object *ob);
-void rem_from_group(struct Group *group, struct Object *ob);
-void add_group_key(struct Group *group);
-void set_object_key(struct Object *ob, struct ObjectKey *ok);
-void set_group_key(struct Group *group);
+void add_to_group(struct Group *group, struct Object *ob);
+void rem_from_group(struct Group *group, struct Object *ob);
struct Group *find_group(struct Object *ob);
-void set_group_key_name(struct Group *group, char *name);
-void set_group_key_frame(struct Group *group, float frame);
+int object_in_group(struct Object *ob, struct Group *group);
+
+void group_tag_recalc(struct Group *group);
+void group_handle_recalc_and_update(struct Object *parent, struct Group *group);
+struct Object *group_get_member_with_action(struct Group *group, struct bAction *act);
#endif
struct Material *add_material(char *name);
struct Material *copy_material(struct Material *ma);
void make_local_material(struct Material *ma);
+
struct Material ***give_matarar(struct Object *ob);
short *give_totcolp(struct Object *ob);
struct Material *give_current_material(struct Object *ob, int act);
ID *material_from(struct Object *ob, int act);
void assign_material(struct Object *ob, struct Material *ma, int act);
void new_material_to_objectdata(struct Object *ob);
+
+struct Material *get_active_matlayer(struct Material *ma);
void init_render_material(struct Material *ma);
void init_render_materials(void);
-void end_render_material(struct Material *ma);
-void end_render_materials(void);
+
void automatname(struct Material *ma);
void delete_material_index(void);
void free_scene(struct Scene *me);
struct Scene *add_scene(char *name);
-int object_in_scene(struct Object *ob, struct Scene *sce);
+struct Base *object_in_scene(struct Object *ob, struct Scene *sce);
void set_scene_bg(struct Scene *sce);
void set_scene_name(char *name);
-/* util defines -- might go away ?*/
-
/*
$Id$
#define ELEM7(a, b, c, d, e, f, g, h) ( ELEM3(a, b, c, d) || ELEM4(a, e, f, g, h) )
#define ELEM8(a, b, c, d, e, f, g, h, i) ( ELEM4(a, b, c, d, e) || ELEM4(a, f, g, h, i) )
-/* pointer magic, only to be used for the max 16 Gig mem period */
-/* note that int is signed! */
-#define POINTER_TO_INT(poin) (int)( ((long)(poin))>>3 )
-#define INT_TO_POINTER(int) (void *)( ((long)(int))<<3 )
-
/* string compare */
#define STREQ(str, a) ( strcmp((str), (a))==0 )
#define STREQ2(str, a, b) ( STREQ(str, a) || STREQ(str, b) )
#define VECADD(v1,v2,v3) {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);}
#define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);}
+#define VECADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac);}
#define INPR(v1, v2) ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] )
float Toon_Diff(float *n, float *l, float *v, float a, float b){return 0;}
float OrenNayar_Diff(float *n, float *l, float *v, float rough){return 0;}
float Minnaert_Diff(float nl, float *n, float *v, float a){return 0;}
+float Fresnel_Diff(float *vn, float *lv, float *view, float ior, float fac){return 0;}
void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b){}
void ramp_diffuse_result(float *diff, ShadeInput *shi){}
void do_material_tex(ShadeInput *shi){}
void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta){}
-void init_render_textures(void){}
-void end_render_textures(void){}
void RE_free_envmap(struct EnvMap *env){}
struct EnvMap *RE_copy_envmap(struct EnvMap *env){ return env;}
void RE_free_envmapdata(struct EnvMap *env){}
+void init_render_textures(void){}
int RE_envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt){
return 0;
Mesh *me = ob->data;
float min[3], max[3];
- if(ob->flag&OB_FROMDUPLI) return;
-
clear_mesh_caches(ob);
if(ob!=G.obedit) {
/* If not, create it and add it */
chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
- strcpy (chan->name, name);
+ strncpy (chan->name, name, 31);
/* init vars to prevent mat errors */
chan->quat[0] = 1.0F;
chan->size[0] = chan->size[1] = chan->size[2] = 1.0F;
if(chan==NULL) {
if (!chan) {
chan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
- strcpy (chan->name, name);
+ strncpy (chan->name, name, 31);
BLI_addtail (&act->chanbase, chan);
}
}
actlength = strip->actend-strip->actstart;
striptime = (G.scene->r.cfra-(strip->start)) / length;
stripframe = (G.scene->r.cfra-(strip->start)) ;
-
+
if (striptime>=0.0){
if(blocktype==ID_AR)
void do_all_object_actions(Object *ob)
{
if(ob==NULL) return;
+ if(ob->dup_group) return; /* prevent conflicts, might add smarter check later */
/* Do local action */
if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
#include "BLI_arithb.h"
#include "DNA_listBase.h"
-#include "DNA_object_types.h"
#include "DNA_curve_types.h"
-#include "DNA_key_types.h"
-#include "DNA_view3d_types.h"
#include "DNA_effect_types.h"
+#include "DNA_group_types.h"
+#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_vfont_types.h"
+#include "BKE_anim.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_font.h"
+#include "BKE_group.h"
#include "BKE_global.h"
-#include "BKE_utildefines.h"
-#include "BKE_anim.h"
#include "BKE_ipo.h"
-#include "BKE_object.h"
-#include "BKE_displist.h"
#include "BKE_key.h"
-#include "BKE_font.h"
-#include "BKE_effect.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
#include "BKE_bad_level_calls.h"
return 1;
}
-static Object *new_dupli_object(ListBase *lb, Object *ob, Object *par)
+/* ****************** DUPLICATOR ************** */
+
+static void new_dupli_object(ListBase *lb, Object *ob, float mat[][4])
{
- Object *newob;
-
- newob= MEM_mallocN(sizeof(Object), "newobj dupli");
+ DupliObject *dob= MEM_mallocN(sizeof(DupliObject), "dupliobject");
+ BLI_addtail(lb, dob);
+ dob->ob= ob;
+ Mat4CpyMat4(dob->mat, mat);
+ Mat4CpyMat4(dob->omat, ob->obmat);
+}
- memcpy(newob, ob, sizeof(Object));
- newob->flag |= OB_FROMDUPLI;
- newob->id.newid= (ID *)par; /* store duplicator */
+static void group_duplilist(ListBase *lb, Object *ob)
+{
+ GroupObject *go;
+ float mat[4][4];
- /* only basis-ball gets displist */
- if(newob->type==OB_MBALL) newob->disp.first= newob->disp.last= NULL;
-
- if(ob!=par) { // dupliverts, particle
- newob->parent= NULL;
- newob->track= NULL;
- }
- BLI_addtail(lb, newob);
+ if(ob->dup_group==NULL) return;
- return newob;
+ /* handles animated groups, and */
+ /* we need to check update for objects that are not in scene... */
+ group_handle_recalc_and_update(ob, ob->dup_group);
+
+ for(go= ob->dup_group->gobject.first; go; go= go->next) {
+ if(go->ob!=ob) {
+ Mat4MulMat4(mat, go->ob->obmat, ob->obmat);
+ new_dupli_object(lb, go->ob, mat);
+ }
+ }
}
-void frames_duplilist(Object *ob)
+static void frames_duplilist(ListBase *lb, Object *ob)
{
extern int enable_cu_speed; /* object.c */
- Object *newob, copyob;
+ Object copyob;
int cfrao, ok;
cfrao= G.scene->r.cfra;
else ok= 0;
}
if(ok) {
- newob= new_dupli_object(&duplilist, ob, ob);
-
- do_ob_ipo(newob);
- where_is_object_time(newob, (float)G.scene->r.cfra);
+ do_ob_ipo(ob);
+ where_is_object_time(ob, (float)G.scene->r.cfra);
+ new_dupli_object(lb, ob, ob->obmat);
}
}
}
struct vertexDupliData {
+ ListBase *lb;
float pmat[4][4];
Object *ob, *par;
};
static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
struct vertexDupliData *vdd= userData;
- Object *newob;
- float vec[3], *q2, mat[3][3], tmat[4][4];
+ float vec[3], *q2, mat[3][3], tmat[4][4], obmat[4][4];
VECCOPY(vec, co);
Mat4MulVecfl(vdd->pmat, vec);
VecSubf(vec, vec, vdd->pmat[3]);
VecAddf(vec, vec, vdd->ob->obmat[3]);
- newob= new_dupli_object(&duplilist, vdd->ob, vdd->par);
- VECCOPY(newob->obmat[3], vec);
+ Mat4CpyMat4(obmat, vdd->ob->obmat);
+ VECCOPY(obmat[3], vec);
if(vdd->par->transflag & OB_DUPLIROT) {
q2= vectoquat(vec, vdd->ob->trackflag, vdd->ob->upflag);
QuatToMat3(q2, mat);
- Mat4CpyMat4(tmat, newob->obmat);
- Mat4MulMat43(newob->obmat, tmat, mat);
+ Mat4CpyMat4(tmat, obmat);
+ Mat4MulMat43(obmat, tmat, mat);
}
-
+ new_dupli_object(vdd->lb, vdd->ob, obmat);
}
-void vertex_duplilist(Scene *sce, Object *par)
+static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par)
{
Object *ob;
Base *base;
struct vertexDupliData vdd;
ob= base->object;
+ vdd.lb= lb;
vdd.ob= ob;
vdd.par= par;
Mat4CpyMat4(vdd.pmat, pmat);
dm->release(dm);
}
-
-void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
+static void particle_duplilist(ListBase *lb, Scene *sce, Object *par, PartEff *paf)
{
- Object *ob, *newob;
+ Object *ob, copyob;
Base *base;
Particle *pa;
float ctime, vec1[3];
}
ctime= bsystem_time(par, 0, (float)G.scene->r.cfra, 0.0);
-
+
lay= G.scene->lay;
- base= sce->base.first;
- while(base) {
-
+ for(base= sce->base.first; base; base= base->next) {
if(base->object->type>0 && (base->lay & lay) && G.obedit!=base->object) {
ob= base->object->parent;
while(ob) {
if(ob==par) {
ob= base->object;
+ /* temp copy, to have ipos etc to work OK */
+ copyob= *ob;
- pa= paf->keys;
- for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
+ for(a=0, pa= paf->keys; a<paf->totpart; a++, pa+=paf->totkey) {
if(paf->flag & PAF_STATIC) {
float mtime;
mtime= pa->time+pa->lifetime;
for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
- newob= new_dupli_object(&duplilist, ob, par);
/* make sure hair grows until the end.. */
if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
/* to give ipos in object correct offset */
- where_is_object_time(newob, ctime-pa->time);
+ where_is_object_time(ob, ctime-pa->time);
where_is_particle(paf, pa, ctime, vec); // makes sure there's always a vec
Mat4MulVecfl(par->obmat, vec);
q2= vectoquat(vec1, ob->trackflag, ob->upflag);
QuatToMat3(q2, mat);
- Mat4CpyMat4(tmat, newob->obmat);
- Mat4MulMat43(newob->obmat, tmat, mat);
+ Mat4CpyMat4(tmat, ob->obmat);
+ Mat4MulMat43(ob->obmat, tmat, mat);
}
- VECCOPY(newob->obmat[3], vec);
+ VECCOPY(ob->obmat[3], vec);
+ new_dupli_object(lb, ob, ob->obmat);
}
}
else { // non static particles
if((paf->flag & PAF_DIED)==0 && ctime > pa->time+pa->lifetime) continue;
//if(ctime < pa->time+pa->lifetime) {
- newob= new_dupli_object(&duplilist, ob, par);
/* to give ipos in object correct offset */
- where_is_object_time(newob, ctime-pa->time);
+ where_is_object_time(ob, ctime-pa->time);
where_is_particle(paf, pa, ctime, vec);
if(paf->stype==PAF_VECT) {
q2= vectoquat(vec1, ob->trackflag, ob->upflag);
QuatToMat3(q2, mat);
- Mat4CpyMat4(tmat, newob->obmat);
- Mat4MulMat43(newob->obmat, tmat, mat);
+ Mat4CpyMat4(tmat, ob->obmat);
+ Mat4MulMat43(ob->obmat, tmat, mat);
}
- VECCOPY(newob->obmat[3], vec);
+ VECCOPY(ob->obmat[3], vec);
+ new_dupli_object(lb, ob, ob->obmat);
}
}
+ /* temp copy, to have ipos etc to work OK */
+ *ob= copyob;
+
break;
}
ob= ob->parent;
}
}
- base= base->next;
}
}
-
-void free_duplilist()
+static Object *find_family_object(Object **obar, char *family, char ch)
{
Object *ob;
+ int flen;
- while( (ob= duplilist.first) ) {
- BLI_remlink(&duplilist, ob);
- MEM_freeN(ob);
+ if( obar[ch] ) return obar[ch];
+
+ flen= strlen(family);
+
+ ob= G.main->object.first;
+ while(ob) {
+ if( ob->id.name[flen+2]==ch ) {
+ if( strncmp(ob->id.name+2, family, flen)==0 ) break;
+ }
+ ob= ob->id.next;
}
+ obar[ch]= ob;
+
+ return ob;
}
-void make_duplilist(Scene *sce, Object *ob)
+
+static void font_duplilist(ListBase *lb, Object *par)
{
- PartEff *paf;
+ Object *ob, *obar[256];
+ Curve *cu;
+ struct chartrans *ct, *chartransdata;
+ float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof;
+ int slen, a;
+
+ Mat4CpyMat4(pmat, par->obmat);
+
+ /* in par the family name is stored, use this to find the other objects */
+
+ chartransdata= text_to_curve(par, FO_DUPLI);
+ if(chartransdata==0) return;
+
+ memset(obar, 0, 256*sizeof(void *));
+
+ cu= par->data;
+ slen= strlen(cu->str);
+ fsize= cu->fsize;
+ xof= cu->xof;
+ yof= cu->yof;
+
+ ct= chartransdata;
+
+ for(a=0; a<slen; a++, ct++) {
+
+ ob= find_family_object(obar, cu->family, cu->str[a]);
+ if(ob) {
+ vec[0]= fsize*(ct->xof - xof);
+ vec[1]= fsize*(ct->yof - yof);
+ vec[2]= 0.0;
+
+ Mat4MulVecfl(pmat, vec);
+
+ Mat4CpyMat4(obmat, par->obmat);
+ VECCOPY(obmat[3], vec);
+
+ new_dupli_object(lb, ob, obmat);
+ }
+
+ }
+
+ MEM_freeN(chartransdata);
+}
+/* ***************************** */
+
+ListBase *object_duplilist(Scene *sce, Object *ob)
+{
+ static ListBase duplilist={NULL, NULL};
+
+ if(duplilist.first) {
+ printf("wrong call to object_duplilist\n");
+ return &duplilist;
+ }
+ duplilist.first= duplilist.last= NULL;
+
if(ob->transflag & OB_DUPLI) {
if(ob->transflag & OB_DUPLIVERTS) {
if(ob->type==OB_MESH) {
if(ob->transflag & OB_DUPLIVERTS) {
- if( (paf=give_parteff(ob)) ) particle_duplilist(sce, ob, paf);
- else vertex_duplilist(sce, ob);
+ PartEff *paf;
+ if( (paf=give_parteff(ob)) ) particle_duplilist(&duplilist, sce, ob, paf);
+ else vertex_duplilist(&duplilist, sce, ob);
}
}
else if(ob->type==OB_FONT) {
- font_duplilist(ob);
+ font_duplilist(&duplilist, ob);
}
}
- else if(ob->transflag & OB_DUPLIFRAMES) frames_duplilist(ob);
+ else if(ob->transflag & OB_DUPLIFRAMES)
+ frames_duplilist(&duplilist, ob);
+ else if(ob->transflag & OB_DUPLIGROUP)
+ group_duplilist(&duplilist, ob);
}
+
+ return &duplilist;
}
+
int count_duplilist(Object *ob)
{
if(ob->transflag & OB_DUPLI) {
arm= alloc_libblock (&G.main->armature, ID_AR, "Armature");
arm->deformflag = ARM_DEF_VGROUP|ARM_DEF_ENVELOPE;
+ arm->layer= 1;
return arm;
}
#include "DNA_curve_types.h"
#include "DNA_ID.h"
#include "DNA_effect_types.h"
+#include "DNA_group_types.h"
#include "DNA_lattice_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_key.h"
+#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
}
}
-struct DagForest *build_dag(struct Scene *sce, short mask)
+static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int mask)
{
- Base *base;
- Object *ob;
bConstraint *con;
DagNode * node;
DagNode * node2;
DagNode * node3;
- DagNode * scenenode;
- DagForest *dag;
- DagAdjList *itA;
Key *key;
-
- dag = sce->theDag;
- sce->dagisvalid=1;
- if ( dag)
- free_forest( dag );
- else {
- dag = dag_init();
- sce->theDag = dag;
- }
+ int addtoroot= 1;
- /* add base node for scene. scene is always the first node in DAG */
- scenenode = dag_add_node(dag, sce);
+ node = dag_get_node(dag, ob);
- for(base = sce->base.first; base; base= base->next) {
- int addtoroot = 1;
- ob= (Object *) base->object;
-
- node = dag_get_node(dag,ob);
-
- if ((ob->data) && (mask&DAG_RL_DATA)) {
- node2 = dag_get_node(dag,ob->data);
- dag_add_relation(dag,node,node2,DAG_RL_DATA);
- node2->first_ancestor = ob;
- node2->ancestor_count += 1;
- }
-
- if (ob->type == OB_ARMATURE) {
- if (ob->pose){
- bPoseChannel *pchan;
- bConstraint *con;
- Object * target;
- char *subtarget;
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
- for (con = pchan->constraints.first; con; con=con->next){
- if (constraint_has_target(con)) {
+ if ((ob->data) && (mask&DAG_RL_DATA)) {
+ node2 = dag_get_node(dag,ob->data);
+ dag_add_relation(dag,node,node2,DAG_RL_DATA);
+ node2->first_ancestor = ob;
+ node2->ancestor_count += 1;
+ }
+
+ if (ob->type == OB_ARMATURE) {
+ if (ob->pose){
+ bPoseChannel *pchan;
+ bConstraint *con;
+ Object * target;
+ char *subtarget;
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
+ for (con = pchan->constraints.first; con; con=con->next){
+ if (constraint_has_target(con)) {
+
+ target = get_constraint_target(con, &subtarget);
+ if (target!=ob) {
+ // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name);
+ node3 = dag_get_node(dag, target);
+
+ if(subtarget && subtarget[0])
+ dag_add_relation(dag,node3,node, DAG_RL_OB_DATA|DAG_RL_DATA_DATA);
+ else
+ dag_add_relation(dag,node3,node, DAG_RL_OB_DATA);
- target = get_constraint_target(con, &subtarget);
- if (target!=ob) {
- // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name);
- node3 = dag_get_node(dag, target);
-
- if(subtarget && subtarget[0])
- dag_add_relation(dag,node3,node, DAG_RL_OB_DATA|DAG_RL_DATA_DATA);
- else
- dag_add_relation(dag,node3,node, DAG_RL_OB_DATA);
-
- }
}
}
}
}
}
-
- /* driver dependencies */
- if(ob->ipo)
- dag_add_driver_relation(ob->ipo, dag, node, 0);
-
- key= ob_get_key(ob);
- if(key && key->ipo)
- dag_add_driver_relation(key->ipo, dag, node, 1);
-
- if(ob->action) {
- bActionChannel *chan;
- for (chan = ob->action->chanbase.first; chan; chan=chan->next){
- if(chan->ipo)
- dag_add_driver_relation(chan->ipo, dag, node, 1);
- }
- }
- if(ob->nlastrips.first) {
- bActionStrip *strip;
- bActionChannel *chan;
- for(strip= ob->nlastrips.first; strip; strip= strip->next) {
- if(strip->act && strip->act!=ob->action)
- for (chan = strip->act->chanbase.first; chan; chan=chan->next)
- if(chan->ipo)
- dag_add_driver_relation(chan->ipo, dag, node, 1);
- }
+ }
+
+ /* driver dependencies */
+ if(ob->ipo)
+ dag_add_driver_relation(ob->ipo, dag, node, 0);
+
+ key= ob_get_key(ob);
+ if(key && key->ipo)
+ dag_add_driver_relation(key->ipo, dag, node, 1);
+
+ if(ob->action) {
+ bActionChannel *chan;
+ for (chan = ob->action->chanbase.first; chan; chan=chan->next){
+ if(chan->ipo)
+ dag_add_driver_relation(chan->ipo, dag, node, 1);
}
- if (ob->modifiers.first) {
- ModifierData *md;
-
- for(md=ob->modifiers.first; md; md=md->next) {
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-
- if (mti->updateDepgraph) mti->updateDepgraph(md, dag, ob, node);
- }
+ }
+ if(ob->nlastrips.first) {
+ bActionStrip *strip;
+ bActionChannel *chan;
+ for(strip= ob->nlastrips.first; strip; strip= strip->next) {
+ if(strip->act && strip->act!=ob->action)
+ for (chan = strip->act->chanbase.first; chan; chan=chan->next)
+ if(chan->ipo)
+ dag_add_driver_relation(chan->ipo, dag, node, 1);
}
- if (ob->parent) {
- node2 = dag_get_node(dag,ob->parent);
+ }
+ if (ob->modifiers.first) {
+ ModifierData *md;
+
+ for(md=ob->modifiers.first; md; md=md->next) {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- switch(ob->partype) {
+ if (mti->updateDepgraph) mti->updateDepgraph(md, dag, ob, node);
+ }
+ }
+ if (ob->parent) {
+ node2 = dag_get_node(dag,ob->parent);
+
+ switch(ob->partype) {
case PARSKEL:
dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_OB);
break;
else
dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
}
- else
- dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
+ else
+ dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
+ }
+ addtoroot = 0;
+ }
+ if (ob->track) {
+ node2 = dag_get_node(dag,ob->track);
+ dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
+ addtoroot = 0;
+ }
+
+ if (ob->transflag & OB_DUPLI) {
+ if((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
+ GroupObject *go;
+ for(go= ob->dup_group->gobject.first; go; go= go->next) {
+ if(go->ob) {
+ node2 = dag_get_node(dag, go->ob);
+ /* node2 changes node1, this keeps animations updated in groups?? not logical? */
+ dag_add_relation(dag, node2, node, DAG_RL_OB_OB);
+ }
}
- addtoroot = 0;
}
- if (ob->track) {
- node2 = dag_get_node(dag,ob->track);
- dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
- addtoroot = 0;
+ }
+
+ if (ob->type==OB_MBALL) {
+ Object *mom= find_basis_mball(ob);
+ if(mom!=ob) {
+ node2 = dag_get_node(dag, mom);
+ dag_add_relation(dag,node,node2,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); // mom depends on children!
}
-
- if (ob->type==OB_MBALL) {
- Object *mom= find_basis_mball(ob);
- if(mom!=ob) {
- node2 = dag_get_node(dag, mom);
- dag_add_relation(dag,node,node2,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); // mom depends on children!
- }
+ }
+ else if (ob->type==OB_CURVE) {
+ Curve *cu= ob->data;
+ if(cu->bevobj) {
+ node2 = dag_get_node(dag, cu->bevobj);
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
}
- else if (ob->type==OB_CURVE) {
- Curve *cu= ob->data;
- if(cu->bevobj) {
- node2 = dag_get_node(dag, cu->bevobj);
- dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
- }
- if(cu->taperobj) {
- node2 = dag_get_node(dag, cu->taperobj);
- dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
- }
+ if(cu->taperobj) {
+ node2 = dag_get_node(dag, cu->taperobj);
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
}
- else if(ob->type==OB_FONT) {
- Curve *cu= ob->data;
- if(cu->textoncurve) {
- node2 = dag_get_node(dag, cu->textoncurve);
- dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
- }
+ }
+ else if(ob->type==OB_FONT) {
+ Curve *cu= ob->data;
+ if(cu->textoncurve) {
+ node2 = dag_get_node(dag, cu->textoncurve);
+ dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
}
- else if(ob->type==OB_MESH) {
- PartEff *paf= give_parteff(ob);
- if(paf) {
- Base *base1;
-
- /* ob location depends on itself */
- if((paf->flag & PAF_STATIC)==0)
- dag_add_relation(dag, node, node, DAG_RL_OB_DATA);
-
- /* force fields, warning for loop inside loop... */
- for(base1 = G.scene->base.first; base1; base1= base1->next) {
- if( (base1->lay & base->lay) && base1->object->pd) {
- Object *ob1= base1->object;
- PartDeflect *pd= ob1->pd;
+ }
+ else if(ob->type==OB_MESH) {
+ PartEff *paf= give_parteff(ob);
+ if(paf) {
+ ListBase *listb;
+ pEffectorCache *ec;
+
+ /* ob location depends on itself */
+ if((paf->flag & PAF_STATIC)==0)
+ dag_add_relation(dag, node, node, DAG_RL_OB_DATA);
+
+ listb= pdInitEffectors(ob, paf->group); /* note, makes copy... */
+ if(listb) {
+ for(ec= listb->first; ec; ec= ec->next) {
+ Object *ob1= ec->ob;
+ PartDeflect *pd= ob1->pd;
- if(pd->forcefield) {
- node2 = dag_get_node(dag, ob1);
- if(pd->forcefield==PFIELD_GUIDE)
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
- else
- dag_add_relation(dag, node2, node, DAG_RL_OB_DATA);
- }
+ if(pd->forcefield) {
+ node2 = dag_get_node(dag, ob1);
+ if(pd->forcefield==PFIELD_GUIDE)
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
+ else
+ dag_add_relation(dag, node2, node, DAG_RL_OB_DATA);
}
}
+
+ pdEndEffectors(listb); /* restores copy... */
}
}
-
- for (con = ob->constraints.first; con; con=con->next){
- if (constraint_has_target(con)) {
- char *str;
- Object *obt= get_constraint_target(con, &str);
-
- node2 = dag_get_node(dag, obt);
- if(con->type==CONSTRAINT_TYPE_FOLLOWPATH)
+ }
+
+ for (con = ob->constraints.first; con; con=con->next){
+ if (constraint_has_target(con)) {
+ char *str;
+ Object *obt= get_constraint_target(con, &str);
+
+ node2 = dag_get_node(dag, obt);
+ if(con->type==CONSTRAINT_TYPE_FOLLOWPATH)
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
+ else {
+ if(obt->type==OB_ARMATURE && str[0])
dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
- else {
- if(obt->type==OB_ARMATURE && str[0])
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
- else
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB);
- }
- addtoroot = 0;
+ else
+ dag_add_relation(dag, node2, node, DAG_RL_OB_OB);
}
+ addtoroot = 0;
}
+ }
+
+ if (addtoroot == 1 )
+ dag_add_relation(dag,scenenode,node,DAG_RL_SCENE);
+}
+
+struct DagForest *build_dag(struct Scene *sce, short mask)
+{
+ Base *base;
+ Object *ob;
+ Group *group;
+ GroupObject *go;
+ DagNode *node;
+ DagNode *scenenode;
+ DagForest *dag;
+ DagAdjList *itA;
+
+ dag = sce->theDag;
+ sce->dagisvalid=1;
+ if ( dag)
+ free_forest( dag );
+ else {
+ dag = dag_init();
+ sce->theDag = dag;
+ }
+
+ /* add base node for scene. scene is always the first node in DAG */
+ scenenode = dag_add_node(dag, sce);
+
+ /* add current scene objects */
+ for(base = sce->base.first; base; base= base->next) {
+ ob= base->object;
- if (addtoroot == 1 )
- dag_add_relation(dag,scenenode,node,DAG_RL_SCENE);
+ build_dag_object(dag, scenenode, ob, mask);
+
+ /* handled in next loop */
+ if(ob->dup_group)
+ ob->dup_group->id.flag |= LIB_DOIT;
+ }
+
+ /* add groups used in current scene objects */
+ for(group= G.main->group.first; group; group= group->id.next) {
+ if(group->id.flag & LIB_DOIT) {
+ for(go= group->gobject.first; go; go= go->next) {
+ build_dag_object(dag, scenenode, go->ob, mask);
+ }
+ group->id.flag &= ~LIB_DOIT;
+ }
}
/* Now all relations were built, but we need to solve 1 exceptional case;
time++;
base = sce->base.first;
- while (base->object != node->ob)
+ while (base && base->object != node->ob)
base = base->next;
- BLI_remlink(&sce->base,base);
- BLI_addhead(&tempbase,base);
+ if(base) {
+ BLI_remlink(&sce->base,base);
+ BLI_addhead(&tempbase,base);
+ }
}
}
}
return 0;
}
+static void dag_object_time_update_flags(Object *ob)
+{
+
+ if(ob->ipo) ob->recalc |= OB_RECALC_OB;
+ else if(ob->constraints.first) ob->recalc |= OB_RECALC_OB;
+ else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB;
+ else if(ob->parent) {
+ /* motion path or bone child */
+ if(ob->parent->type==OB_CURVE || ob->parent->type==OB_ARMATURE) ob->recalc |= OB_RECALC_OB;
+ }
+
+ if(ob->action || ob->nlastrips.first) {
+ /* since actions now are mixed, we set the recalcs on the safe side */
+ ob->recalc |= OB_RECALC_OB;
+ if(ob->type==OB_ARMATURE)
+ ob->recalc |= OB_RECALC_DATA;
+ else if(exists_channel(ob, "Shape"))
+ ob->recalc |= OB_RECALC_DATA;
+
+ }
+ else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA;
+ else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
+ else {
+ Mesh *me;
+ Curve *cu;
+ Lattice *lt;
+
+ switch(ob->type) {
+ case OB_MESH:
+ me= ob->data;
+ if(me->key) {
+ if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
+ ob->recalc |= OB_RECALC_DATA;
+ ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+ }
+ }
+ else if(ob->effect.first) {
+ Effect *eff= ob->effect.first;
+ PartEff *paf= give_parteff(ob);
+
+ if(eff->type==EFF_WAVE)
+ ob->recalc |= OB_RECALC_DATA;
+ if(paf && paf->keys==NULL)
+ ob->recalc |= OB_RECALC_DATA;
+ }
+ if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) {
+ // fluidsimSettings might not be initialized during load...
+ if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
+ ob->recalc |= OB_RECALC_DATA; // NT
+ }
+ }
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ cu= ob->data;
+ if(cu->key) {
+ if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
+ ob->recalc |= OB_RECALC_DATA;
+ ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+ }
+ }
+ break;
+ case OB_LATTICE:
+ lt= ob->data;
+ if(lt->key) {
+ if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
+ ob->recalc |= OB_RECALC_DATA;
+ ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+ }
+ }
+ break;
+ case OB_MBALL:
+ if(ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA;
+ break;
+ }
+ }
+}
+
/* flag all objects that need recalc, for changes in time for example */
void DAG_scene_update_flags(Scene *sce, unsigned int lay)
{
Base *base;
Object *ob;
+ Group *group;
+ GroupObject *go;
/* set ob flags where animated systems are */
for(base= sce->base.first; base; base= base->next) {
+ ob= base->object;
/* now if DagNode were part of base, the node->lay could be checked... */
/* we do all now, since the scene_flush checks layers and clears recalc flags even */
- ob= base->object;
+ dag_object_time_update_flags(ob);
- if(ob->ipo) ob->recalc |= OB_RECALC_OB;
- else if(ob->constraints.first) ob->recalc |= OB_RECALC_OB;
- else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB;
- else if(ob->parent) {
- if(ob->parent->type==OB_CURVE) ob->recalc |= OB_RECALC_OB;
- }
+ /* handled in next loop */
+ if(ob->dup_group)
+ ob->dup_group->id.flag |= LIB_DOIT;
- if(ob->action || ob->nlastrips.first) {
- /* since actions now are mixed, we set the recalcs on the safe side */
- ob->recalc |= OB_RECALC_OB;
- if(ob->type==OB_ARMATURE)
- ob->recalc |= OB_RECALC_DATA;
- else if(exists_channel(ob, "Shape"))
- ob->recalc |= OB_RECALC_DATA;
-
- }
- else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA;
- else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
- else {
- Mesh *me;
- Curve *cu;
- Lattice *lt;
-
- switch(ob->type) {
- case OB_MESH:
- me= ob->data;
- if(me->key) {
- if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
- ob->recalc |= OB_RECALC_DATA;
- ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
- }
- }
- else if(ob->effect.first) {
- Effect *eff= ob->effect.first;
- if(eff->type==EFF_WAVE) ob->recalc |= OB_RECALC_DATA;
- }
- if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) {
- // fluidsimSettings might not be initialized during load...
- if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
- ob->recalc |= OB_RECALC_DATA; // NT
- }
- }
- break;
- case OB_CURVE:
- case OB_SURF:
- cu= ob->data;
- if(cu->key) {
- if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
- ob->recalc |= OB_RECALC_DATA;
- ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
- }
- }
- break;
- case OB_LATTICE:
- lt= ob->data;
- if(lt->key) {
- if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
- ob->recalc |= OB_RECALC_DATA;
- ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
- }
- }
- break;
- case OB_MBALL:
- if(ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA;
- break;
+ }
+
+ /* we do groups each once */
+ for(group= G.main->group.first; group; group= group->id.next) {
+ if(group->id.flag & LIB_DOIT) {
+ for(go= group->gobject.first; go; go= go->next) {
+ dag_object_time_update_flags(go->ob);
}
}
}
+
DAG_scene_flush_update(sce, lay);
+
+ /* and store the info in groubobject */
+ for(group= G.main->group.first; group; group= group->id.next) {
+ if(group->id.flag & LIB_DOIT) {
+ for(go= group->gobject.first; go; go= go->next) {
+ go->recalc= go->ob->recalc;
+// printf("ob %s recalc %d\n", go->ob->id.name, go->recalc);
+ }
+ group->id.flag &= ~LIB_DOIT;
+ }
+ }
+
}
/* for depgraph updating, all layers visible in a screen */
if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(nor, lv, shi.view, ma->roughness);
else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(nor, lv, shi.view, ma->param[0], ma->param[1]);
else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(is, nor, shi.view, ma->darkness);
+ else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(nor, lv, shi.view, ma->param[0], ma->param[1]);
}
back= 0;
}
}
}
-static void end_fastshade_for_ob(Object *ob)
-{
- int a;
-
- for(a=0; a<ob->totcol; a++) {
- Material *ma= give_current_material(ob, a+1);
- &nbs