Merged 15771:15912 from trunk

This commit is contained in:
2008-08-01 23:39:52 +00:00
139 changed files with 3133 additions and 1475 deletions
+1
View File
@@ -20,3 +20,4 @@ Romanian:ro
Arabic:ar
Bulgarian:bg
Greek:el
Korean:kr
+43
View File
@@ -75,4 +75,47 @@ void BOP_Edge::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
else if (m_vertexs[1] == oldIndex) m_vertexs[1] = newIndex;
}
#ifdef BOP_NEW_MERGE
/**
* Returns if this edge contains the specified face index.
* @param i face index
* @return true if this edge contains the specified face index, false otherwise
*/
bool BOP_Edge::removeFace(BOP_Index i)
{
int pos=0;
for(BOP_IT_Indexs it = m_faces.begin();it!=m_faces.end();pos++,it++) {
if ((*it) == i) {
m_faces.erase(it);
return true;
}
}
return false;
}
#endif
#ifdef BOP_DEBUG
#include <iostream>
using namespace std;
/**
* Implements operator <<.
*/
ostream &operator<<(ostream &stream, BOP_Edge *e)
{
stream << "Edge[" << e->getVertex1() << "," << e->getVertex2();
#ifdef BOP_NEW_MERGE
if(e->m_used)
stream << "] (used)";
else
stream << "] (unused)";
#endif
return stream;
}
#endif
+13
View File
@@ -29,12 +29,16 @@
#define BOP_EDGE_H
#include "BOP_Indexs.h"
#include "BOP_Misc.h"
class BOP_Edge
{
private:
BOP_Index m_vertexs[2];
BOP_Indexs m_faces;
#ifdef BOP_NEW_MERGE
bool m_used;
#endif
bool containsFace(BOP_Index i);
@@ -47,6 +51,15 @@ public:
inline unsigned int getNumFaces(){return m_faces.size();};
inline BOP_Indexs &getFaces(){return m_faces;};
void addFace(BOP_Index face);
#ifdef BOP_NEW_MERGE
bool removeFace(BOP_Index i);
bool getUsed() { return m_used;};
void setUsed(bool setting) { m_used=setting;};
#endif
#ifdef BOP_DEBUG
friend ostream &operator<<(ostream &stream, BOP_Edge *e);
#endif
};
#endif
+2
View File
@@ -402,6 +402,7 @@ bool BOP_Face4::getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e)
return true;
}
#ifdef BOP_DEBUG
/**
* Implements operator <<.
*/
@@ -421,3 +422,4 @@ ostream &operator<<(ostream &stream, BOP_Face *f)
return stream;
}
#endif
+3
View File
@@ -32,6 +32,7 @@
#include "MT_Plane3.h"
#include "BOP_Indexs.h"
#include "BOP_BBox.h"
#include "BOP_Misc.h"
#include <iostream>
#include <vector>
using namespace std;
@@ -80,7 +81,9 @@ public:
virtual void replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) = 0;
virtual bool containsVertex(BOP_Index v) = 0;
#ifdef BOP_DEBUG
friend ostream &operator<<(ostream &stream, BOP_Face *f);
#endif
};
class BOP_Face3: public BOP_Face
+29 -1
View File
@@ -33,9 +33,12 @@
#include "BOP_Mesh.h"
#include "BOP_Face2Face.h"
#include "BOP_Merge.h"
#include "BOP_Merge2.h"
#include "BOP_Chrono.h"
//#define DEBUG
#if defined(BOP_ORIG_MERGE) && defined(BOP_NEW_MERGE)
#include "../../source/blender/blenkernel/BKE_global.h"
#endif
BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC,
BOP_Faces* facesA,
@@ -208,7 +211,32 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC,
#endif
// Merge faces
#ifdef BOP_ORIG_MERGE
#ifndef BOP_NEW_MERGE
BOP_Merge::getInstance().mergeFaces(meshC,numVertices);
#endif
#endif
#ifdef BOP_NEW_MERGE
#ifndef BOP_ORIG_MERGE
BOP_Merge2::getInstance().mergeFaces(meshC,numVertices);
#else
static int state = -1;
if (G.rt == 100) {
if( state != 1 ) {
cout << "Boolean code using old merge technique." << endl;
state = 1;
}
BOP_Merge::getInstance().mergeFaces(meshC,numVertices);
} else {
if( state != 0 ) {
cout << "Boolean code using new merge technique." << endl;
state = 0;
}
BOP_Merge2::getInstance().mergeFaces(meshC,numVertices);
}
#endif
#endif
#ifdef DEBUG
c = chrono.stamp(); t += c;
+3
View File
@@ -30,6 +30,7 @@
#include "BOP_Merge.h"
#ifdef BOP_ORIG_MERGE
#ifdef _MSC_VER
#if _MSC_VER < 1300
@@ -802,3 +803,5 @@ void BOP_Merge::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, B
}
}
}
#endif /* BOP_ORIG_MERGE */
+5
View File
@@ -28,6 +28,9 @@
#ifndef BOP_MERGE_H
#define BOP_MERGE_H
#include "BOP_Misc.h"
#ifdef BOP_ORIG_MERGE
#include "BOP_Mesh.h"
#include "BOP_Tag.h"
#include "BOP_MathUtils.h"
@@ -68,4 +71,6 @@ class BOP_Merge {
void mergeFaces(BOP_Mesh *m, BOP_Index v);
};
#endif /* BOP_ORIG_MERGE */
#endif
+944
View File
@@ -0,0 +1,944 @@
/**
*
* $Id: BOP_Merge22.cpp 14444 2008-04-16 22:40:48Z hos $
*
* ***** 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.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Marc Freixas, Ken Hughes
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "BOP_Merge2.h"
#ifdef BOP_NEW_MERGE
static void deleteFace(BOP_Mesh *m, BOP_Face *face);
/**
* SINGLETON (use method BOP_Merge2.getInstance).
*/
BOP_Merge2 BOP_Merge2::SINGLETON;
#ifdef BOP_DEBUG
void dumpmesh ( BOP_Mesh *m, bool force )
{
unsigned int nonmanifold = 0;
{
BOP_Edges edges = m->getEdges();
int count = 0;
for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
++count, ++edge) {
if (!(*edge)->getUsed() && (*edge)->getFaces().size() == 0 ) continue;
BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());
if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
int fcount = 0;
BOP_Indexs faces = (*edge)->getFaces();
for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
BOP_Face *f = m->getFace(*face);
if(f->getTAG()== UNCLASSIFIED) ++fcount;
}
if(fcount !=0 && fcount !=2 ) {
++nonmanifold;
}
}
}
if (!force && nonmanifold == 0) return;
}
if( nonmanifold )
cout << nonmanifold << " edges detected" << endl;
#ifdef DEBUG
cout << "---------------------------" << endl;
BOP_Edges edges = m->getEdges();
int count = 0;
for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
++count, ++edge) {
BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());
if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
int fcount = 0;
BOP_Indexs faces = (*edge)->getFaces();
cout << count << ", " << (*edge) << ", " << faces.size() << endl;
for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
BOP_Face *f = m->getFace(*face);
if(f->getTAG()== UNCLASSIFIED) ++fcount;
cout << " face " << f << endl;
}
if(fcount !=0 && fcount !=2 )
cout << " NON-MANIFOLD" << endl;
}
}
BOP_Faces faces = m->getFaces();
count = 0;
for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) {
if( count < 12*2 || (*face)->getTAG() != BROKEN ) {
cout << count << ", " << *face << endl;
}
++count;
}
BOP_Vertexs verts = m->getVertexs();
count = 0;
for (BOP_IT_Vertexs vert = verts.begin(); vert != verts.end(); vert++) {
cout << count++ << ", " << *vert << " " << (*vert)->getNumEdges() << endl;
BOP_Indexs edges = (*vert)->getEdges();
for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
BOP_Edge *edge = m->getEdge(*it);
cout << " " << edge << endl;
}
}
cout << "===========================" << endl;
#endif
}
#endif
/**
* Simplifies a mesh, merging its faces.
* @param m mesh
* @param v index of the first mergeable vertex (can be removed by merge)
*/
void BOP_Merge2::mergeFaces(BOP_Mesh *m, BOP_Index v)
{
m_mesh = m;
#ifdef DEBUG
cout << "##############################" << endl;
#endif
cleanup( );
m_firstVertex = v;
bool cont = false;
// Merge faces
mergeFaces();
do {
// Add quads ...
cont = createQuads();
// ... and merge new faces
if( cont ) cont = mergeFaces();
#ifdef DEBUG
cout << "called mergeFaces " << cont << endl;
#endif
// ... until the merge is not succesful
} while(cont);
}
void clean_nonmanifold( BOP_Mesh *m )
{
return;
BOP_Edges nme;
BOP_Edges e = m->getEdges();
for( BOP_IT_Edges it = e.begin(); it != e.end(); ++it ) {
BOP_Indexs faces = (*it)->getFaces();
if( faces.size() & ~2 )
nme.push_back(*it);
}
if (nme.size() == 0) return;
for( BOP_IT_Edges it = nme.begin(); it != nme.end(); ++it ) {
if( (*it)->getFaces().size() > 1 ) {
BOP_Indexs faces = (*it)->getFaces();
for( BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face ) {
MT_Point3 vertex1 = m->getVertex(m->getFace(*face)->getVertex(0))->getPoint();
MT_Point3 vertex2 = m->getVertex(m->getFace(*face)->getVertex(1))->getPoint();
MT_Point3 vertex3 = m->getVertex(m->getFace(*face)->getVertex(2))->getPoint();
if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle
deleteFace(m,m->getFace(*face));
}
continue;
}
BOP_Face *oface1 = m->getFace((*it)->getFaces().front());
BOP_Face *oface2, *tmpface;
BOP_Index first =(*it)->getVertex1();
BOP_Index next =(*it)->getVertex2();
BOP_Index last = first;
unsigned short facecount = 0;
bool found = false;
BOP_Indexs vertList;
#ifdef DEBUG
cout << " first edge is " << (*it) << endl;
#endif
vertList.push_back(first);
BOP_Edge *edge;
while(true) {
BOP_Vertex *vert = m->getVertex(next);
BOP_Indexs edges = vert->getEdges();
edge = NULL;
for( BOP_IT_Indexs eit = edges.begin(); eit != edges.end(); ++eit) {
edge = m->getEdge(*eit);
if( edge->getFaces().size() > 1) {
edge = NULL;
continue;
}
if( edge->getVertex1() == next && edge->getVertex2() != last ) {
last = next;
next = edge->getVertex2();
break;
}
if( edge->getVertex2() == next && edge->getVertex1() != last ) {
last = next;
next = edge->getVertex1();
break;
}
edge = NULL;
}
if( !edge ) break;
#ifdef DEBUG
cout << " next edge is " << edge << endl;
#endif
tmpface = m->getFace(edge->getFaces().front());
if( oface1->getOriginalFace() != tmpface->getOriginalFace() )
oface2 = tmpface;
else
++facecount;
vertList.push_back(last);
if( vertList.size() > 3 ) break;
if( next == first ) {
found = true;
break;
}
}
if(found) {
edge = *it;
#ifdef DEBUG
cout << " --> found a loop" << endl;
#endif
if( vertList.size() == 3 ) {
BOP_Face3 *face = (BOP_Face3 *)m->getFace(edge->getFaces().front());
face->getNeighbours(first,last,next);
} else if( vertList.size() == 4 ) {
BOP_Face4 *face = (BOP_Face4 *)m->getFace(edge->getFaces().front());
face->getNeighbours(first,last,next,last);
} else {
#ifdef DEBUG
cout << "loop has " << vertList.size() << "verts";
#endif
continue;
}
if(facecount == 1) oface1 = oface2;
next = vertList[1];
last = vertList[2];
if( edge->getVertex2() == next ) {
BOP_Face3 *f = new BOP_Face3(next,first,last,
oface1->getPlane(),oface1->getOriginalFace());
m->addFace( f );
#ifdef DEBUG
cout << " face is backward: " << f << endl;
#endif
} else {
BOP_Face3 *f = new BOP_Face3(last,first,next,
oface1->getPlane(),oface1->getOriginalFace());
m->addFace( f );
#ifdef DEBUG
cout << " face is forward: " << f << endl;
#endif
}
}
}
}
/**
* Runs through mesh and makes sure vert/face/edge data is consistent. Most
* importantly:
* (1) mark edges which are no longer used
* (2) remove broken faces from edges
* (3) remove faces from mesh which have a single edge belonging to no other
* face (non-manifold edges)
*/
void BOP_Merge2::cleanup( void )
{
BOP_Edges edges = m_mesh->getEdges();
for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); ++edge) {
BOP_Indexs faces = (*edge)->getFaces();
for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face) {
BOP_Face *f = m_mesh->getFace(*face);
if(f->getTAG()== UNCLASSIFIED) ;
else (*edge)->removeFace(*face);
}
if( (*edge)->getFaces().size() == 0) (*edge)->setUsed(false);
}
BOP_Vertexs v = m_mesh->getVertexs();
for( BOP_IT_Vertexs it = v.begin(); it != v.end(); ++it ) {
if( (*it)->getTAG() != BROKEN) {
BOP_Indexs edges = (*it)->getEdges();
for(BOP_IT_Indexs i = edges.begin();i!=edges.end();i++)
if( m_mesh->getEdge((*i))->getUsed( ) == false) (*it)->removeEdge( *i );
if( (*it)->getEdges().size() == 0 ) (*it)->setTAG(BROKEN);
}
}
// clean_nonmanifold( m_mesh );
}
/**
* Simplifies a mesh, merging its faces.
*/
bool BOP_Merge2::mergeFaces()
{
BOP_Indexs mergeVertices;
BOP_Vertexs vertices = m_mesh->getVertexs();
BOP_IT_Vertexs v = vertices.begin();
const BOP_IT_Vertexs verticesEnd = vertices.end();
// Advance to first mergeable vertex
advance(v,m_firstVertex);
BOP_Index pos = m_firstVertex;
// Add unbroken vertices to the list
while(v!=verticesEnd) {
if ((*v)->getTAG() != BROKEN) {
mergeVertices.push_back(pos);
}
v++;
pos++;
}
// Merge faces with that vertices
return mergeFaces(mergeVertices);
}
/**
* remove edges from vertices when the vertex is removed
*/
void BOP_Merge2::freeVerts(BOP_Index v, BOP_Vertex *vert)
{
BOP_Indexs edges = vert->getEdges();
BOP_Vertex *other;
for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
BOP_Edge *edge = m_mesh->getEdge(*it);
BOP_Indexs edges2;
if( edge->getVertex1() != v )
other = m_mesh->getVertex( edge->getVertex1() );
else
other = m_mesh->getVertex( edge->getVertex2() );
other->removeEdge(*it);
vert->removeEdge(*it);
}
}
/**
* Simplifies a mesh, merging the faces with the specified vertices.
* @param mergeVertices vertices to test
* @return true if a face merge was performed
*/
bool BOP_Merge2::mergeFaces(BOP_Indexs &mergeVertices)
{
// Check size > 0!
if (mergeVertices.size() == 0) return false;
bool didMerge = false;
for( BOP_Index i = 0; i < mergeVertices.size(); ++i ) {
BOP_LFaces facesByOriginalFace;
BOP_Index v = mergeVertices[i];
BOP_Vertex *vert = m_mesh->getVertex(v);
#ifdef DEBUG
cout << "i = " << i << ", v = " << v << ", vert = " << vert << endl;
if (v==48)
cout << "found vert 48" << endl;
#endif
if ( vert->getTAG() != BROKEN ) {
getFaces(facesByOriginalFace,v);
switch (facesByOriginalFace.size()) {
case 0:
// v has no unbroken faces (so it's a new BROKEN vertex)
freeVerts( v, vert );
vert->setTAG(BROKEN);
break;
case 2: {
#ifdef DEBUG
cout << "size of fBOF = " << facesByOriginalFace.size() << endl;
#endif
BOP_Faces ff = facesByOriginalFace.front();
BOP_Faces fb = facesByOriginalFace.back();
BOP_Index eindexs[2];
int ecount = 0;
// look for two edges adjacent to v which contain both ofaces
BOP_Indexs edges = vert->getEdges();
#ifdef DEBUG
cout << " ff has " << ff.size() << " faces" << endl;
cout << " fb has " << fb.size() << " faces" << endl;
cout << " v has " << edges.size() << " edges" << endl;
#endif
for(BOP_IT_Indexs it = edges.begin(); it != edges.end();
++it ) {
BOP_Edge *edge = m_mesh->getEdge(*it);
BOP_Indexs faces = edge->getFaces();
#ifdef DEBUG
cout << " " << edge << " has " << edge->getFaces().size() << " faces" << endl;
#endif
if( faces.size() == 2 ) {
BOP_Face *f0 = m_mesh->getFace(faces[0]);
BOP_Face *f1 = m_mesh->getFace(faces[1]);
if( f0->getOriginalFace() != f1->getOriginalFace() ) {
#ifdef DEBUG
cout << " " << f0 << endl;
cout << " " << f1 << endl;
#endif
eindexs[ecount++] = (*it);
}
}
}
if(ecount == 2) {
#ifdef DEBUG
cout << " edge indexes are " << eindexs[0];
cout << " and " << eindexs[1] << endl;
#endif
BOP_Edge *edge = m_mesh->getEdge(eindexs[0]);
BOP_Index N = edge->getVertex1();
if(N == v) N = edge->getVertex2();
#ifdef DEBUG
cout << " ## OK, replace "<<v<<" with "<<N << endl;
#endif
mergeVertex(ff , v, N );
mergeVertex(fb , v, N );
// now remove v and its edges
vert->setTAG(BROKEN);
for(BOP_IT_Indexs it = edges.begin(); it != edges.end();
++it ) {
BOP_Edge *edge = m_mesh->getEdge(*it);
edge->setUsed(false);
}
didMerge = true;
}
#ifdef DEBUG
else {
cout << " HUH: ecount was " << ecount << endl;
}
#endif
}
break;
default:
break;
}
}
}
return didMerge;
}
void BOP_Merge2::mergeVertex(BOP_Faces &faces, BOP_Index v1, BOP_Index v2)
{
for(BOP_IT_Faces face=faces.begin();face!=faces.end();face++) {
if( (*face)->size() == 3)
mergeVertex((BOP_Face3 *) *face, v1, v2);
else
mergeVertex((BOP_Face4 *) *face, v1, v2);
(*face)->setTAG(BROKEN);
#ifdef DEBUG
cout << " breaking " << (*face) << endl;
#endif
}
}
/*
* Remove a face from the mesh and from each edges's face list
*/
static void deleteFace(BOP_Mesh *m, BOP_Face *face)
{
BOP_Index l2 = face->getVertex(0);
BOP_Faces faces = m->getFaces();
for(int i = face->size(); i-- ; ) {
BOP_Indexs edges = m->getVertex(l2)->getEdges();
BOP_Index l1 = face->getVertex(i);
for(BOP_IT_Indexs it1 = edges.begin(); it1 != edges.end(); ++it1 ) {
BOP_Edge *edge = m->getEdge(*it1);
if( ( edge->getVertex1() == l1 && edge->getVertex2() == l2 ) ||
( edge->getVertex1() == l2 && edge->getVertex2() == l1 ) ) {
BOP_Indexs ef = edge->getFaces();
for(BOP_IT_Indexs it = ef.begin(); it != ef.end(); ++it ) {
if( m->getFace(*it) == face) {
edge->removeFace(*it);
break;
}
}
break;
}
}
l2 = l1;
}
face->setTAG(BROKEN);
}
void BOP_Merge2::mergeVertex(BOP_Face3 *face, BOP_Index v1, BOP_Index v2)
{
BOP_Index next, prev;
face->getNeighbours(v1,prev,next);
// if new vertex is not already in the tri, make a new tri
if( prev != v2 && next != v2 ) {
m_mesh->addFace( new BOP_Face3(prev,v2,next,
face->getPlane(),face->getOriginalFace()) );
#ifdef DEBUG
cout << "mv3: add " << prev << "," << v2 << "," << next << endl;
} else {
cout << "mv3: vertex already in tri: doing nothing" << endl;
#endif
}
deleteFace(m_mesh, face);
}
void BOP_Merge2::mergeVertex(BOP_Face4 *face, BOP_Index v1, BOP_Index v2)
{
BOP_Index next, prev, opp;
face->getNeighbours(v1,prev,next,opp);
// if new vertex is already in the quad, replace quad with new tri
if( prev == v2 || next == v2 ) {
m_mesh->addFace( new BOP_Face3(prev,next,opp,
face->getPlane(),face->getOriginalFace()) );
#ifdef DEBUG
cout << "mv4a: add " << prev << "," << next << "," << opp << endl;
#endif
}
// otherwise make a new quad
else {
m_mesh->addFace( new BOP_Face4(prev,v2,next,opp,
face->getPlane(),face->getOriginalFace()) );
#ifdef DEBUG
cout << "mv4b: add "<<prev<<","<<v2<<","<<next<<","<<opp<<endl;
#endif
}
deleteFace(m_mesh, face);
}
// #define OLD_QUAD
/**
* Simplifies the mesh, merging the pairs of triangles that come frome the
* same original face and define a quad.
* @return true if a quad was added, false otherwise
*/
bool BOP_Merge2::createQuads()
{
BOP_Faces quads;
// Get mesh faces
BOP_Faces faces = m_mesh->getFaces();
// Merge mesh triangles
const BOP_IT_Faces facesIEnd = (faces.end()-1);
const BOP_IT_Faces facesJEnd = faces.end();
for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) {
#ifdef OLD_QUAD
if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue;
for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 ||
(*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;
BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
if (faceK != NULL) {
// Set triangles to BROKEN
deleteFace(m_mesh, *faceI);
deleteFace(m_mesh, *faceJ);
#ifdef DEBUG
cout << "createQuad: del " << *faceI << endl;
cout << "createQuad: del " << *faceJ << endl;
cout << "createQuad: add " << faceK << endl;
#endif
quads.push_back(faceK);
break;
}
}
#else
if ((*faceI)->getTAG() == BROKEN ) continue;
for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
if ((*faceJ)->getTAG() == BROKEN ||
(*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;
BOP_Face *faceK = NULL;
if((*faceI)->size() == 3) {
if((*faceJ)->size() == 3)
faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
else
faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face4*)*faceJ);
} else {
if((*faceJ)->size() == 3)
faceK = createQuad((BOP_Face3*)*faceJ,(BOP_Face4*)*faceI);
else
faceK = createQuad((BOP_Face4*)*faceI,(BOP_Face4*)*faceJ);
}
if (faceK != NULL) {
// Set triangles to BROKEN
deleteFace(m_mesh, *faceI);
deleteFace(m_mesh, *faceJ);
#ifdef DEBUG
cout << "createQuad: del " << *faceI << endl;
cout << "createQuad: del " << *faceJ << endl;
cout << "createQuad: add " << faceK << endl;
#endif
quads.push_back(faceK);
break;
}
}
#endif
}
// Add quads to mesh
const BOP_IT_Faces quadsEnd = quads.end();
for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad);
return (quads.size() > 0);
}
/**
* Returns a new quad (convex) from the merge of two triangles that share the
* vertex index v.
* @param faceI mesh triangle
* @param faceJ mesh triangle
* @param v vertex index shared by both triangles
* @return a new convex quad if the merge is possible
*/
BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ)
{
// Test if both triangles share a vertex index
BOP_Index v;
unsigned int i;
for(i=0;i<3 ;i++) {
v = faceI->getVertex(i);
if( faceJ->containsVertex(v) ) break;
}
if (i == 3) return NULL;
BOP_Face *faceK = NULL;
// Get faces data
BOP_Index prevI, nextI, prevJ, nextJ;
faceI->getNeighbours(v,prevI,nextI);
faceJ->getNeighbours(v,prevJ,nextJ);
MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
// Quad test
if (prevI == nextJ) {
if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) &&
BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) {
faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace());
faceK->setTAG(faceI->getTAG());
BOP_Index edge;
m_mesh->getIndexEdge(v,prevI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(prevI)->removeEdge(edge);
}
}
else if (nextI == prevJ) {
if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) &&
BOP_convex(vertex,vNextJ,vNextI,vPrevI)) {
faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace());
faceK->setTAG(faceI->getTAG());
BOP_Index edge;
m_mesh->getIndexEdge(v,nextI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(nextI)->removeEdge(edge);
}
}
return faceK;
}
/**
* Returns a new quad (convex) from the merge of two triangles that share the
* vertex index v.
* @param faceI mesh triangle
* @param faceJ mesh triangle
* @param v vertex index shared by both triangles
* @return a new convex quad if the merge is possible
*/
BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ)
{
// Test if triangle and quad share a vertex index
BOP_Index v;
unsigned int i;
for(i=0;i<3 ;i++) {
v = faceI->getVertex(i);
if( faceJ->containsVertex(v) ) break;
}
if (i == 3) return NULL;
BOP_Face *faceK = NULL;
// Get faces data
BOP_Index prevI, nextI, prevJ, nextJ, oppJ;
faceI->getNeighbours(v,prevI,nextI);
faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
// Quad test
BOP_Index edge;
if (nextI == prevJ) {
if (prevI == nextJ) { // v is in center
faceK = new BOP_Face3(nextJ,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace());
faceK->setTAG(faceI->getTAG());
m_mesh->getIndexEdge(v,prevI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(prevI)->removeEdge(edge);
m_mesh->getIndexEdge(v,nextI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(nextI)->removeEdge(edge);
freeVerts(v, m_mesh->getVertex(v));
} else if (prevI == oppJ) { // nextI is in center
faceK = new BOP_Face3(v,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
faceK->setTAG(faceI->getTAG());
m_mesh->getIndexEdge(v,nextI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(nextI)->removeEdge(edge);
m_mesh->getIndexEdge(prevI,nextI,edge);
m_mesh->getVertex(prevI)->removeEdge(edge);
m_mesh->getVertex(nextI)->removeEdge(edge);
freeVerts(nextI, m_mesh->getVertex(nextI));
}
} else if (nextI == oppJ && prevI == nextJ ) { // prevI is in center
faceK = new BOP_Face3(prevJ,v,oppJ,faceI->getPlane(),faceI->getOriginalFace());
faceK->setTAG(faceI->getTAG());
m_mesh->getIndexEdge(v,prevI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(prevI)->removeEdge(edge);
m_mesh->getIndexEdge(nextI,prevI,edge);
m_mesh->getVertex(nextI)->removeEdge(edge);
m_mesh->getVertex(prevI)->removeEdge(edge);
freeVerts(prevI, m_mesh->getVertex(prevI));
}
return faceK;
}
/**
* Returns a new quad (convex) from the merge of two triangles that share the
* vertex index v.
* @param faceI mesh triangle
* @param faceJ mesh triangle
* @param v vertex index shared by both triangles
* @return a new convex quad if the merge is possible
*/
BOP_Face* BOP_Merge2::createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ)
{
BOP_Face *faceK = NULL;
//
// Test if both quads share a vertex index
//
BOP_Index v;
unsigned int i;
for(i=0;i<4 ;i++) {
v = faceI->getVertex(i);
if( faceJ->containsVertex(v) ) break;
}
if (i == 3) return NULL;
// Get faces data
BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ;
faceI->getNeighbours(v,prevI,nextI,oppI);
faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
// Quad test
BOP_Index edge;
if (nextI == prevJ) {
if (prevI == nextJ) { // v is in center
faceK = new BOP_Face4(nextI,oppI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
faceK->setTAG(faceI->getTAG());
m_mesh->getIndexEdge(v,prevI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(prevI)->removeEdge(edge);
m_mesh->getIndexEdge(v,nextI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(nextI)->removeEdge(edge);
freeVerts(v, m_mesh->getVertex(v));
} else if (oppI == oppJ) { // nextI is in center
faceK = new BOP_Face4(v,nextJ,oppJ,prevI,faceI->getPlane(),faceI->getOriginalFace());
faceK->setTAG(faceI->getTAG());
m_mesh->getIndexEdge(v,nextI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(nextI)->removeEdge(edge);
m_mesh->getIndexEdge(prevI,nextI,edge);
m_mesh->getVertex(prevI)->removeEdge(edge);
m_mesh->getVertex(nextI)->removeEdge(edge);
freeVerts(nextI, m_mesh->getVertex(nextI));
}
} else if (prevI == nextJ && oppI == oppJ) { // prevI is in center
faceK = new BOP_Face4(v,nextI,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace());
faceK->setTAG(faceI->getTAG());
m_mesh->getIndexEdge(v,prevI,edge);
m_mesh->getVertex(v)->removeEdge(edge);
m_mesh->getVertex(prevI)->removeEdge(edge);
m_mesh->getIndexEdge(nextI,prevI,edge);
m_mesh->getVertex(nextI)->removeEdge(edge);
m_mesh->getVertex(prevI)->removeEdge(edge);
freeVerts(prevI, m_mesh->getVertex(prevI));
}
return faceK;
}
/**
* Returns if a index is inside a set of indexs.
* @param indexs set of indexs
* @param i index
* @return true if the index is inside the set, false otherwise
*/
bool BOP_Merge2::containsIndex(BOP_Indexs indexs, BOP_Index i)
{
const BOP_IT_Indexs indexsEnd = indexs.end();
for(BOP_IT_Indexs it=indexs.begin();it!=indexsEnd;it++) {
if (*it == i) return true;
}
return false;
}
/**
* Creates a list of lists L1, L2, ... LN where
* LX = mesh faces with vertex v that come from the same original face
* @param facesByOriginalFace list of faces lists
* @param v vertex index
*/
void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v)
{
// Get edges with vertex v
BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {
// For each edge, add its no broken faces to the output list
BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
BOP_Indexs faceIndexs = edge->getFaces();
const BOP_IT_Indexs faceEnd = faceIndexs.end();
for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
BOP_Face* face = m_mesh->getFace(*faceIndex);
if (face->getTAG() != BROKEN) {
bool found = false;
// Search if we already have created a list for the
// faces that come from the same original face
const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
// Search that the face has not been added to the list before
for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
if ((*facesByOriginalFaceX)[i] == face) {
found = true;
break;
}
}
if (!found) {
// Add the face to the list
if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
else facesByOriginalFaceX->push_back(face);
found = true;
}
break;
}
}
if (!found) {
// Create a new list and add the current face
BOP_Faces facesByOriginalFaceX;
facesByOriginalFaceX.push_back(face);
facesByOriginalFace.push_back(facesByOriginalFaceX);
}
}
}
}
}
/**
* Creates a list of lists L1, L2, ... LN where
* LX = mesh faces with vertex v that come from the same original face
* and without any of the vertices that appear before v in vertices
* @param facesByOriginalFace list of faces lists
* @param vertices vector with vertices indexs that contains v
* @param v vertex index
*/
void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v)
{
// Get edges with vertex v
BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {
// Foreach edge, add its no broken faces to the output list
BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
BOP_Indexs faceIndexs = edge->getFaces();
const BOP_IT_Indexs faceEnd = faceIndexs.end();
for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
BOP_Face* face = m_mesh->getFace(*faceIndex);
if (face->getTAG() != BROKEN) {
// Search if the face contains any of the forbidden vertices
bool found = false;
for(BOP_IT_Indexs vertex = vertices.begin();*vertex!= v;vertex++) {
if (face->containsVertex(*vertex)) {
// face contains a forbidden vertex!
found = true;
break;
}
}
if (!found) {
// Search if we already have created a list with the
// faces that come from the same original face
const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
// Search that the face has not been added to the list before
for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
if ((*facesByOriginalFaceX)[i] == face) {
found = true;
break;
}
}
if (!found) {
// Add face to the list
if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
else facesByOriginalFaceX->push_back(face);
found = true;
}
break;
}
}
if (!found) {
// Create a new list and add the current face
BOP_Faces facesByOriginalFaceX;
facesByOriginalFaceX.push_back(face);
facesByOriginalFace.push_back(facesByOriginalFaceX);
}
}
}
}
}
}
#endif /* BOP_NEW_MERGE */
+99
View File
@@ -0,0 +1,99 @@
/**
* ***** 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.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BOP_MERGE2_H
#define BOP_MERGE2_H
#include "BOP_Misc.h"
#ifdef BOP_NEW_MERGE
#include "BOP_Mesh.h"
#include "BOP_Tag.h"
#include "BOP_MathUtils.h"
#include "MEM_SmartPtr.h"
typedef vector< BOP_Faces > BOP_LFaces;
typedef vector< BOP_Faces >::iterator BOP_IT_LFaces;
class BOP_Merge2 {
private:
BOP_Mesh* m_mesh;
BOP_Index m_firstVertex;
static BOP_Merge2 SINGLETON;
BOP_Merge2() {};
bool mergeFaces();
bool mergeFaces(BOP_Indexs &mergeVertices);
bool mergeFaces(BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v);
bool mergeFaces(BOP_Faces &faces, BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v);
BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v);
BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Indexs &pending, BOP_Index v);
BOP_Face *mergeFaces(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v);
BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Index v);
BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Indexs &pending, BOP_Index v);
BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face4 *faceJ, BOP_Indexs &pending, BOP_Index v);
bool createQuads();
bool containsIndex(BOP_Indexs indexs, BOP_Index index);
void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v);
void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v);
BOP_Face *createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ);
BOP_Face *createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ);
BOP_Face *createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ);
bool mergeVertex(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v,
BOP_Indexs &mergeVertices);
bool mergeVertex(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v,
BOP_Indexs &pending, BOP_Faces &oldFaces, BOP_Faces &newFaces );
BOP_Face *find3Neighbor(BOP_Face *faceI, BOP_Face *faceJ,
BOP_Index X, BOP_Index I, BOP_Index P, BOP_Index N );
BOP_Face *find4Neighbor(BOP_Face *faceI, BOP_Face *faceJ,
BOP_Index X, BOP_Index I, BOP_Index P, BOP_Index N,
BOP_Face **faceL, BOP_Index &O);
BOP_Face3 *collapse(BOP_Face4 *faceC, BOP_Index X);
void mergeFaces(BOP_Face *A, BOP_Face *B, BOP_Index X,
BOP_Index I, BOP_Index N, BOP_Index P, BOP_Faces &newFaces );
void freeVerts(BOP_Index v, BOP_Vertex *vert);
void mergeVertex(BOP_Faces&, BOP_Index, BOP_Index);
void mergeVertex(BOP_Face3 *, BOP_Index, BOP_Index);
void mergeVertex(BOP_Face4 *, BOP_Index, BOP_Index);
void cleanup( void );
public:
static BOP_Merge2 &getInstance() {
return SINGLETON;
}
void mergeFaces(BOP_Mesh *m, BOP_Index v);
};
void dumpmesh(BOP_Mesh *, bool);
#endif /* BOP_NEW_MERGE2 */
#endif
+10 -1
View File
@@ -449,6 +449,13 @@ bool BOP_Mesh::getIndexEdge(BOP_Index v1, BOP_Index v2, BOP_Index &e)
printf ("found edge (%d %d)\n",v1,v2);
#endif
e = edge->index;
#ifdef BOP_NEW_MERGE
if( m_edges[e]->getUsed() == false ) {
m_edges[e]->setUsed(true);
m_vertexs[v1]->addEdge(e);
m_vertexs[v2]->addEdge(e);
}
#endif
return true;
}
#ifdef HASH_PRINTF_DEBUG
@@ -794,7 +801,8 @@ bool BOP_Mesh::isClosedMesh()
}
/** ***************************************************************************
#ifdef BOP_DEBUG
/******************************************************************************
* DEBUG METHODS *
* This functions are used to test the mesh state and debug program errors. *
******************************************************************************/
@@ -1075,3 +1083,4 @@ void BOP_Mesh::updatePlanes()
}
}
#endif
-7
View File
@@ -1,10 +1,3 @@
/*
* TEMPORARY defines to enable hashing support
*/
#define HASH(x) ((x) >> 5) /* each "hash" covers 32 indices */
// #define HASH_PRINTF_DEBUG /* uncomment to enable debug output */
/**
*
* $Id$
+54
View File
@@ -0,0 +1,54 @@
/**
*
* $Id: BOP_Misc.h 14444 2008-04-16 22:40:48Z khughes $
*
* ***** 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.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Ken Hughes
*
* ***** END GPL LICENSE BLOCK *****
*/
/*
* This file contains various definitions used across the modules
*/
/*
* define operator>> for faces, edges and vertices, and also add some
* debugging functions for displaying various internal data structures
*/
// #define BOP_DEBUG
#define HASH(x) ((x) >> 5) /* each "hash" covers 32 indices */
// #define HASH_PRINTF_DEBUG /* uncomment to enable debug output */
/*
* temporary: control which method is used to merge final triangles and
* quads back together after an operation. If both methods are included,
* the "rt" debugging button on the Scene panel (F10) is used to control
* which is active. Setting it to 100 enables the original method, any
* other value enables the new method.
*/
#define BOP_ORIG_MERGE /* include original merge code */
#define BOP_NEW_MERGE /* include new merge code */
+1 -1
View File
@@ -39,7 +39,7 @@
#define OUTON_TAG 0x11 // Above and on the plane
#define UNCLASSIFIED_TAG 0x0F // Expecting to be classified
#define PHANTOM_TAG 0x0C // Phantom face
#define PHANTOM_TAG 0x0C // Phantom face: verts form collinear triangle
#define OVERLAPPED_TAG 0x0D // Overlapped face
#define BROKEN_TAG 0x0B // Splitted and unused ...
+19
View File
@@ -89,3 +89,22 @@ bool BOP_Vertex::containsEdge(BOP_Index i)
return false;
}
#ifdef BOP_DEBUG
/**
* Implements operator <<.
*/
#include <iomanip>
ostream &operator<<(ostream &stream, BOP_Vertex *v)
{
char aux[20];
BOP_stringTAG(v->m_tag,aux);
MT_Point3 point = v->getPoint();
stream << setprecision(6) << showpoint << fixed;
stream << "Vertex[" << point[0] << "," << point[1] << ",";
stream << point[2] << "] (" << aux << ")";
return stream;
}
#endif
+5
View File
@@ -31,6 +31,7 @@
#include "BOP_Tag.h"
#include "BOP_Indexs.h"
#include "MT_Point3.h"
#include "BOP_Misc.h"
class BOP_Vertex
{
@@ -52,6 +53,10 @@ public:
inline MT_Point3 getPoint() const { return m_point;};
inline BOP_TAG getTAG() { return m_tag;};
inline void setTAG(BOP_TAG t) { m_tag = t;};
#ifdef BOP_DEBUG
friend ostream &operator<<(ostream &stream, BOP_Vertex *v);
#endif
};
#endif
@@ -142,9 +142,6 @@
<File
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderMouseDevice.cpp">
</File>
<File
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderPolyMaterial.cpp">
</File>
<File
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderRenderTools.cpp">
</File>
@@ -170,9 +167,6 @@
<File
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderMouseDevice.h">
</File>
<File
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderPolyMaterial.h">
</File>
<File
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderRenderTools.h">
</File>
+32 -32
View File
@@ -14,7 +14,7 @@ __url__ = ("blender", "blenderartists.org",
__version__ = "2007/04/27"
__bpydoc__ = """\
"DEFORM to RVK2" copies deform data (except EDGESPLIT,DECIMATE,SUBSURF,BOOLEAN,
"DEFORM to RVK2" copies deform data (except EDGESPLIT,DECIMATE,SUBSURF,BOOLEAN,
BUILD,MIRROR,ARRAY) of the active object to the RVK (relative vertex key) of
the other selected object.
@@ -25,7 +25,7 @@ key.
The new version of this scrit (Blender 2.43) manages the modifier changes.
There are a lot of modifiers but only the ones which just deforms the shape
can be used : LATTICE, CURVE, WAVE, ARMATURE. You can unset these modifiers
from the script.
from the script.
Usage:
@@ -35,7 +35,7 @@ the 3d View. If the active object has subsurf turned on and nonzero subdiv
level, the script will ask if it should change that. Before copying data to
the rvk it will also ask whether it should replace or add a new vertex group.
"""
#----------------------------------------------
@@ -70,7 +70,7 @@ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
# Copy the rvk (1, or armature, lattice, or
# any mesh deformation except surface
@@ -83,7 +83,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# download the script :
# http://jmsoler.free.fr/util/blenderfile/py/rvk1_torvk2.py
# Communicate upon problems or errors:
# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
#----------------------------------------------
# Page officielle :
# http://jmsoler.free.fr/util/blenderfile/py/rvk1_torvk2.py
@@ -101,22 +101,22 @@ def Value(t):
exec "t=Modifier.Types.%s"%t
return t
def deform2rvk():
def deform2rvk():
POSSMOD_list=['EDGESPLIT',
'DECIMATE',
'SUBSURF',
'BOOLEAN',
'SUBSURF',
'BOOLEAN',
'BUILD',
'MIRROR',
'MIRROR',
'ARRAY']
AUTHMOD_list=['LATTICE',
'CURVE',
'CURVE',
'WAVE',
'ARMATURE']
MODIFIERS=0
BMOD=[['Possible Modifiers'],
['Allowed Modifiers']]
@@ -129,8 +129,8 @@ def deform2rvk():
# =============================================================
# must be 2 meshes ============================================
# =============================================================
if RVK1.getType()=='Mesh' and RVK2.getType()=='Mesh':
FRAME=Blender.Get('curframe')
if RVK1.getType()=='Mesh' and RVK2.getType()=='Mesh':
FRAME=Blender.Get('curframe')
DATA2=RVK2.getData()
if DEBUG: print DATA2.getKey()
# ============================================================
@@ -151,7 +151,7 @@ def deform2rvk():
# === Bloc Menu Modifiers ===1 doc =================
# ===================================================
m=0
for mod in MODRVK1:
for mod in MODRVK1:
if DEBUG: print mod.type
if mod.type in POSSMOD:
BMOD[0].append([Draw.Create(0),mod.type,
@@ -183,7 +183,7 @@ def deform2rvk():
retval = Blender.Draw.PupBlock("MESH 2 RVK", block)
# ===================================================
# === unset Modifiers =============================
# ===================================================
# ===================================================
for B in BMOD[0][1:]:
if DEBUG: print B[2]
MODRVK1[B[2]][Modifier.Settings.RENDER]=0
@@ -193,12 +193,12 @@ def deform2rvk():
# ===================================================
# === update Modifiers =============================
# ===================================================
RVK1.makeDisplayList()
#RVK1.makeDisplayList()
# =======================================================
# === get deformed mesh ================================
# =======================================================
RVK1NAME=Object.GetSelected()[0].getName()
meshrvk1=NMesh.GetRawFromObject(RVK1NAME)
meshrvk1=NMesh.GetRawFromObject(RVK1NAME)
if DEBUG: print len(meshrvk1.verts)
# =======================================================
# === get normal mesh for vertex group =================
@@ -209,18 +209,18 @@ def deform2rvk():
# =======================================================
DATA2=RVK2.getData()
if DEBUG: print len(meshrvk1.verts)
if DEBUG: print len(DATA2.verts)
if DEBUG: print len(DATA2.verts)
# ========================================================
# ===== is there the same number of vertices =============
# ========================================================
if len(meshrvk1.verts)==len(DATA2.verts):
name = "Do you want to replace or add vertex groups ? %t| YES %x1| NO ? %x2 "
if len(meshrvk1.verts)==len(DATA2.verts):
name = "Do you want to replace or add vertex groups ? %t| YES %x1| NO ? %x2 "
result = Draw.PupMenu(name)
if result==1:
if result==1:
# =====================================================
# ===== Do we save vertex groups ? ===================
# =====================================================
GROUPNAME2=DATA2.getVertGroupNames()
GROUPNAME2=DATA2.getVertGroupNames()
if len(GROUPNAME2)!=0:
for GROUP2 in GROUPNAME2:
DATA2.removeVertGroup(GROUP2)
@@ -233,11 +233,11 @@ def deform2rvk():
# ===== now copy the vertices coords =====================
# ========================================================
for v in meshrvk1.verts:
i= meshrvk1.verts.index(v)
i= meshrvk1.verts.index(v)
v1=DATA2.verts[i]
for n in [0,1,2]:
v1.co[n]=v.co[n]
DATA2.update()
DATA2.update()
DATA2.insertKey(FRAME,'relative')
DATA2.update()
RVK2.makeDisplayList()
@@ -251,23 +251,23 @@ def deform2rvk():
if not B[1]:
MODRVK1[B[2]][Modifier.Settings.RENDER]|=B[-2]
else:
name = "Meshes Objects must the same number of vertices %t| Ok. %x1"
name = "Meshes Objects must the same number of vertices %t| Ok. %x1"
result = Draw.PupMenu(name)
return
else:
name = "Second Object must have at least a shape key %t| Ok. %x1"
name = "Second Object must have at least a shape key %t| Ok. %x1"
result = Draw.PupMenu(name)
return
else:
name = "Object must be Meshes %t| Ok. %x1"
else:
name = "Object must be Meshes %t| Ok. %x1"
result = Draw.PupMenu(name)
return
return
else :
name = "At least 2 Meshes as to be selected %t| Ok. %x1"
name = "At least 2 Meshes as to be selected %t| Ok. %x1"
result = Draw.PupMenu(name)
return
Blender.Redraw()
Blender.Redraw()
EDITMODE=Blender.Window.EditMode()
Blender.Window.EditMode(0)
deform2rvk()
Blender.Window.EditMode(EDITMODE)
Blender.Window.EditMode(EDITMODE)
@@ -437,5 +437,7 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb);
/* determines required DerivedMesh data according to view and edit modes */
CustomDataMask get_viewedit_datamask();
void DM_add_tangent_layer(DerivedMesh *dm);
#endif
+1 -1
View File
@@ -41,7 +41,7 @@ struct ListBase;
struct MemFile;
#define BLENDER_VERSION 246
#define BLENDER_SUBVERSION 0
#define BLENDER_SUBVERSION 1
#define BLENDER_MINVERSION 245
#define BLENDER_MINSUBVERSION 15
+1
View File
@@ -62,6 +62,7 @@ struct Tex *copy_texture(struct Tex *tex);
void make_local_texture(struct Tex *tex);
void autotexname(struct Tex *tex);
struct Tex *give_current_texture(struct Object *ob, int act);
struct Tex *give_current_world_texture(void);
struct TexMapping *add_mapping(void);
void init_mapping(struct TexMapping *texmap);
@@ -354,7 +354,6 @@ TimeMarker *get_frame_marker(int frame){return 0;};
/* editseq.c */
Sequence *get_forground_frame_seq(int frame){return 0;};
void set_last_seq(Sequence *seq){};
void clear_last_seq(Sequence *seq){};
@@ -59,6 +59,7 @@
#include "BLI_edgehash.h"
#include "BLI_editVert.h"
#include "BLI_linklist.h"
#include "BLI_memarena.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
@@ -2844,6 +2845,127 @@ int editmesh_get_first_deform_matrices(float (**deformmats)[3][3], float (**defo
return numleft;
}
void DM_add_tangent_layer(DerivedMesh *dm)
{
/* mesh vars */
MTFace *mtface, *tf;
MFace *mface, *mf;
MVert *mvert, *v1, *v2, *v3, *v4;
MemArena *arena= NULL;
VertexTangent **vtangents= NULL;
float (*orco)[3]= NULL, (*tangent)[3];
float *uv1, *uv2, *uv3, *uv4, *vtang;
float fno[3], tang[3], uv[4][2];
int i, j, len, mf_vi[4], totvert, totface;
if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1)
return;
/* check we have all the needed layers */
totvert= dm->getNumVerts(dm);
totface= dm->getNumFaces(dm);
mvert= dm->getVertArray(dm);
mface= dm->getFaceArray(dm);
mtface= dm->getFaceDataArray(dm, CD_MTFACE);
if(!mtface) {
orco= dm->getVertDataArray(dm, CD_ORCO);
if(!orco)
return;
}
/* create tangent layer */
DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
tangent= DM_get_face_data_layer(dm, CD_TANGENT);
/* allocate some space */
arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
BLI_memarena_use_calloc(arena);
vtangents= MEM_callocN(sizeof(VertexTangent*)*totvert, "VertexTangent");
/* sum tangents at connected vertices */
for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) {
v1= &mvert[mf->v1];
v2= &mvert[mf->v2];
v3= &mvert[mf->v3];
if (mf->v4) {
v4= &mvert[mf->v4];
CalcNormFloat4(v4->co, v3->co, v2->co, v1->co, fno);
}
else {
v4= NULL;
CalcNormFloat(v3->co, v2->co, v1->co, fno);
}
if(mtface) {
uv1= tf->uv[0];
uv2= tf->uv[1];
uv3= tf->uv[2];
uv4= tf->uv[3];
}
else {
uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]);
spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]);
spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]);
if(v4)
spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]);
}
tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang);
sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2);
sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
if(mf->v4) {
v4= &mvert[mf->v4];
tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang);
sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4);
}
}
/* write tangent to layer */
for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++, tangent+=4) {
len= (mf->v4)? 4 : 3;
if(mtface) {
uv1= tf->uv[0];
uv2= tf->uv[1];
uv3= tf->uv[2];
uv4= tf->uv[3];
}
else {
uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]);
spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]);
spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]);
if(len==4)
spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]);
}
mf_vi[0]= mf->v1;
mf_vi[1]= mf->v2;
mf_vi[2]= mf->v3;
mf_vi[3]= mf->v4;
for(j=0; j<len; j++) {
vtang= find_vertex_tangent(vtangents[mf_vi[j]], mtface ? tf->uv[j] : uv[j]);
VECCOPY(tangent[j], vtang);
Normalize(tangent[j]);
}
}
BLI_memarena_free(arena);
MEM_freeN(vtangents);
}
/* ************************* fluidsim bobj file handling **************************** */
#ifndef DISABLE_ELBEEM
+1 -1
View File
@@ -1547,7 +1547,7 @@ int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, f
{
Cloth *cloth=NULL;
BVHTree *cloth_bvh=NULL;
long i=0, numfaces = 0, numverts = 0;
int i=0, numfaces = 0, numverts = 0;
int rounds = 0; // result counts applied collisions; ic is for debug output;
ClothVertex *verts = NULL;
int ret = 0, ret2 = 0;
@@ -558,8 +558,8 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
if (dgroup < 0) return;
/* get DerivedMesh */
if (G.obedit && G.editMesh) {
/* we are in editmode, so get a special derived mesh */
if ((G.obedit == ob) && (G.editMesh)) {
/* target is in editmode, so get a special derived mesh */
dm = CDDM_from_editmesh(G.editMesh, ob->data);
}
else {
@@ -532,13 +532,14 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
{sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol}
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
{sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol"};
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent"};
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
@@ -552,7 +553,7 @@ const CustomDataMask CD_MASK_EDITMESH =
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO;
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT;
const CustomDataMask CD_MASK_BMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
const CustomDataMask CD_MASK_FACECORNERS =
+14 -1
View File
@@ -53,6 +53,7 @@
#include "DNA_world_types.h"
#include "DNA_brush_types.h"
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -731,7 +732,7 @@ Tex *give_current_texture(Object *ob, int act)
bNode *node;
if(ob==0) return 0;
if(ob->totcol==0) return 0;
if(ob->totcol==0 && !(ob->type==OB_LAMP)) return 0;
if(ob->type==OB_LAMP) {
la=(Lamp *)ob->data;
@@ -775,6 +776,18 @@ Tex *give_current_texture(Object *ob, int act)
return tex;
}
Tex *give_current_world_texture(void)
{
MTex *mtex = 0;
Tex *tex = 0;
if(!(G.scene->world)) return 0;
mtex= G.scene->world->mtex[(int)(G.scene->world->texact)];
if(mtex) tex= mtex->tex;
return tex;
}
/* ------------------------------------------------------------------------- */
+1 -1
View File
@@ -405,7 +405,7 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile * pf)
lcode = charcode;
}
err = FT_Set_Charmap( face, (FT_CharMap) FT_ENCODING_UNICODE );
err = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
return vfd;
}
+52 -1
View File
@@ -4870,6 +4870,49 @@ void idproperties_fix_group_lengths(ListBase idlist)
}
}
void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
{
Material *ma;
MFace *mf;
MTFace *tf;
int a, b, texalpha;
/* verify we have a tface layer */
for(b=0; b<me->fdata.totlayer; b++)
if(me->fdata.layers[b].type == CD_MTFACE)
break;
if(b == me->fdata.totlayer)
return;
/* if we do, set alpha sort if the game engine did it before */
for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
if(mf->mat_nr < me->totcol) {
ma= newlibadr(fd, lib, me->mat[mf->mat_nr]);
texalpha = 0;
for(b=0; ma && b<MAX_MTEX; b++)
if(ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
texalpha = 1;
}
else {
ma= NULL;
texalpha = 0;
}
for(b=0; b<me->fdata.totlayer; b++) {
if(me->fdata.layers[b].type == CD_MTFACE) {
tf = ((MTFace*)me->fdata.layers[b].data) + a;
tf->mode &= ~TF_ALPHASORT;
if(ma && (ma->mode & MA_ZTRA))
if(ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP)))
tf->mode |= TF_ALPHASORT;
}
}
}
}
static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@@ -7714,8 +7757,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
/* sun/sky */
if ((main->versionfile < 246) ){
if(main->versionfile < 246) {
Lamp *la;
for(la=main->lamp.first; la; la= la->id.next) {
la->sun_effect_type = 0;
la->horizon_brightness = 1.0;
@@ -7731,6 +7775,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
if(main->versionfile <= 246 && main->subversionfile < 1){
Mesh *me;
for(me=main->mesh.first; me; me= me->id.next)
alphasort_version_246(fd, lib, me);
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
+1 -1
View File
@@ -2275,7 +2275,7 @@ static int handle_append_runtime(int handle, char *exename, char **cause_r) {
unsigned char buf[1024];
int count, progfd= -1;
if (!runtime) {
if (!BLI_exists(runtime)) {
cause= "Unable to find runtime";
goto cleanup;
}
+9
View File
@@ -38,6 +38,15 @@ struct bGPdata;
struct bGPDlayer;
struct bGPDframe;
/* ------------- Grease-Pencil Helpers -------------- */
/* Temporary 'Stroke Point' data */
typedef struct tGPspoint {
short x, y; /* x and y coordinates of cursor (in relative to area) */
float xf, yf; /* same as x and y, but as floats */
float pressure; /* pressure of tablet at this point */
} tGPspoint;
/* ------------ Grease-Pencil API ------------------ */
void free_gpencil_strokes(struct bGPDframe *gpf);
@@ -134,6 +134,7 @@ void transform_armature_mirror_update(void);
void hide_selected_armature_bones(void);
void hide_unselected_armature_bones(void);
void show_all_armature_bones(void);
void set_locks_armature_bones(short lock);
#define BONESEL_ROOT 0x10000000
#define BONESEL_TIP 0x20000000
+3
View File
@@ -34,9 +34,12 @@ struct Base;
struct Object;
struct Camera;
struct View3D;
struct rcti;
void arrows_move_cursor(unsigned short event);
void lasso_select_boundbox(struct rcti *rect, short mcords[][2], short moves);
int lasso_inside(short mcords[][2], short moves, short sx, short sy);
int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1);
void borderselect(void);
void circle_select(void);
void deselectall(void);
+2 -1
View File
@@ -154,7 +154,8 @@ typedef enum eBone_Flag {
BONE_NO_SCALE = (1<<15), /* No parent scale */
BONE_HIDDEN_PG = (1<<16), /* hidden bone when drawing PoseChannels (for ghost drawing) */
BONE_DRAWWIRE = (1<<17), /* bone should be drawn as OB_WIRE, regardless of draw-types of view+armature */
BONE_NO_CYCLICOFFSET = (1<<18) /* when no parent, bone will not get cyclic offset */
BONE_NO_CYCLICOFFSET = (1<<18), /* when no parent, bone will not get cyclic offset */
BONE_EDITMODE_LOCKED = (1<<19), /* bone transforms are locked in EditMode */
} eBone_Flag;
#endif
@@ -375,11 +375,13 @@ typedef enum B_CONSTRAINT_SPACETYPES {
/* for objects (relative to parent/without parent influence),
* for bones (along normals of bone, without parent/restpositions)
*/
CONSTRAINT_SPACE_LOCAL,
CONSTRAINT_SPACE_LOCAL, /* = 1 */
/* for posechannels - pose space */
CONSTRAINT_SPACE_POSE,
/* for posechannels - local with parent */
CONSTRAINT_SPACE_PARLOCAL,
CONSTRAINT_SPACE_POSE, /* = 2 */
/* for posechannels - local with parent */
CONSTRAINT_SPACE_PARLOCAL, /* = 3 */
/* for files from between 2.43-2.46 (should have been parlocal) */
CONSTRAINT_SPACE_INVALID, /* = 4. do not exchange for anything! */
} B_CONSTRAINT_SPACETYPES;
/* bConstraintChannel.flag */
@@ -71,7 +71,8 @@ typedef struct CustomData {
#define CD_MTEXPOLY 15
#define CD_MLOOPUV 16
#define CD_MLOOPCOL 17
#define CD_NUMTYPES 18
#define CD_TANGENT 18
#define CD_NUMTYPES 19
/* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT)
@@ -92,6 +93,7 @@ typedef struct CustomData {
#define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY)
#define CD_MASK_MLOOPUV (1 << CD_MLOOPUV)
#define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL)
#define CD_MASK_TANGENT (1 << CD_TANGENT)
/* CustomData.flag */
+1 -1
View File
@@ -125,7 +125,7 @@ typedef struct bGPdata {
*/
short sbuffer_size; /* number of elements currently in cache */
short sbuffer_sflag; /* flags for stroke that cache represents */
bGPDspoint *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
void *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
} bGPdata;
/* bGPdata->flag */
+1 -1
View File
@@ -228,7 +228,7 @@ typedef struct PartialVisibility {
/* mtface->mode */
#define TF_DYNAMIC 1
#define TF_DEPRECATED 2
#define TF_ALPHASORT 2
#define TF_TEX 4
#define TF_SHAREDVERT 8
#define TF_LIGHT 16
@@ -466,9 +466,11 @@ extern Object workob;
#define OB_LOCK_ROTX 8
#define OB_LOCK_ROTY 16
#define OB_LOCK_ROTZ 32
#define OB_LOCK_ROT 56
#define OB_LOCK_SCALEX 64
#define OB_LOCK_SCALEY 128
#define OB_LOCK_SCALEZ 256
#define OB_LOCK_SCALE 448
/* ob->softflag in DNA_object_force.h */
+2
View File
@@ -1469,6 +1469,8 @@ PyObject *Armature_Init(void)
PyConstant_NewInt("BONE_SELECTED", BONE_SELECTED));
PyModule_AddObject(module, "TIP_SELECTED",
PyConstant_NewInt("TIP_SELECTED", BONE_TIPSEL));
PyModule_AddObject(module, "LOCKED_EDIT",
PyConstant_NewInt("LOCKED_EDIT", BONE_EDITMODE_LOCKED));
PyModule_AddObject(module, "OCTAHEDRON",
PyConstant_NewInt("OCTAHEDRON", ARM_OCTA));
+9 -1
View File
@@ -368,6 +368,10 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
goto RuntimeError;
if(self->editbone->flag & BONE_EDITMODE_LOCKED)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "LOCKED_EDIT")) == -1)
goto RuntimeError;
}else{
if(self->flag & BONE_CONNECTED)
if (PyList_Append(list,
@@ -401,6 +405,10 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
goto RuntimeError;
if(self->flag & BONE_EDITMODE_LOCKED)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "LOCKED_EDIT")) == -1)
goto RuntimeError;
}
return list;
@@ -422,7 +430,7 @@ static int EditBone_CheckValidConstant(PyObject *constant)
return 0;
if (!STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM") &&
!STREQ3(PyString_AsString(name), "ROOT_SELECTED", "BONE_SELECTED", "TIP_SELECTED") &&
!STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))
!STREQ3(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT", "LOCKED_EDIT"))
return 0;
else
return 1;
@@ -89,6 +89,8 @@ Example::
@type BONE_SELECTED: Constant
@var TIP_SELECTED: Tip of the Bone is selected
@type TIP_SELECTED: Constant
@var LOCKED_EDIT: Prevents the bone from being transformed in editmode
@type LOCKED_EDIT: Constant
@var OCTAHEDRON: Bones drawn as octahedrons
@type OCTAHEDRON: Constant
@var STICK: Bones drawn as a line
@@ -286,6 +288,7 @@ class Bone:
- Armature.ROOT_SELECTED: Selection of root ball of bone
- Armature.BONE_SELECTED: Selection of bone
- Armature.TIP_SELECTED: Selection of tip ball of bone
- Armature.LOCKED_EDIT: Prevents the bone from being transformed in editmode
@type options: List of Constants
@ivar subdivision: The number of bone subdivisions.
@type subdivision: Int
+32 -6
View File
@@ -56,6 +56,7 @@ struct View3D; /* keep me up here */
#include "gen_utils.h"
#include "gen_library.h"
#include "../BPY_extern.h" /* for BPY_do_all_scripts() */
#include "Scene.h"
#include "Group.h"
@@ -469,19 +470,20 @@ PyObject *M_Render_EnableDispWin( PyObject * self )
PyObject *RenderData_Render( BPy_RenderData * self )
{
Scene *oldsce;
/* unlock to prevent a deadlock when there are pynodes: */
PyThreadState *tstate = NULL;
if (!G.background) {
oldsce = G.scene;
set_scene( self->scene );
tstate = PyEval_SaveThread();
BIF_do_render( 0 );
set_scene( oldsce );
}
else { /* background mode (blender -b file.blend -P script) */
int slink_flag = 0;
Render *re= RE_NewRender(G.scene->id.name);
int end_frame = G.scene->r.efra;
if (G.scene != self->scene)
@@ -490,11 +492,25 @@ PyObject *RenderData_Render( BPy_RenderData * self )
G.scene->r.efra = G.scene->r.sfra;
if (G.f & G_DOSCRIPTLINKS) {
BPY_do_all_scripts(SCRIPT_RENDER);
G.f &= ~G_DOSCRIPTLINKS; /* avoid FRAMECHANGED events*/
slink_flag = 1;
}
tstate = PyEval_SaveThread();
RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
if (slink_flag) {
G.f |= G_DOSCRIPTLINKS;
BPY_do_all_scripts(SCRIPT_POSTRENDER);
}
G.scene->r.efra = end_frame;
}
PyEval_RestoreThread(tstate);
Py_RETURN_NONE;
}
@@ -565,12 +581,13 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
PyObject *RenderData_RenderAnim( BPy_RenderData * self )
{
Scene *oldsce;
/* this prevents a deadlock when there are pynodes: */
PyThreadState *tstate = PyEval_SaveThread();
/* unlock to prevent a deadlock when there are pynodes: */
PyThreadState *tstate = NULL;
if (!G.background) {
oldsce = G.scene;
set_scene( self->scene );
tstate = PyEval_SaveThread();
BIF_do_render( 1 );
set_scene( oldsce );
}
@@ -584,8 +601,17 @@ PyObject *RenderData_RenderAnim( BPy_RenderData * self )
if (G.scene->r.sfra > G.scene->r.efra)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"start frame must be less or equal to end frame");
if (G.f & G_DOSCRIPTLINKS)
BPY_do_all_scripts(SCRIPT_RENDER);
tstate = PyEval_SaveThread();
RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
if (G.f & G_DOSCRIPTLINKS)
BPY_do_all_scripts(SCRIPT_POSTRENDER);
}
PyEval_RestoreThread(tstate);
Py_RETURN_NONE;
}
+7 -5
View File
@@ -4371,11 +4371,12 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm)
uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", 225, by-19,105, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight");
/* bone types */
uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S", 70,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit scale from parent Bone");
uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 90, by-38, 80, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry");
uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 170,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup");
uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", 250,by-38,80,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode");
uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,60,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S", 50,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit scale from parent Bone");
uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 70, by-38, 80, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry");
uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 150,by-38,60,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup");
uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", 210,by-38,60,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode");
uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, REDRAWVIEW3D, "Lock", 270,by-38,60,18, &curBone->flag, 0, 0, 0, 0, "Prevents this bone from being transformed in Edit Mode");
/* layers */
uiBlockBeginAlign(block);
@@ -6188,6 +6189,7 @@ static void editing_panel_mesh_texface(void)
uiDefButBitS(block, TOG, TF_BILLBOARD2, B_TFACE_BILLB, "Billboard",660,110,60,19, &tf->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint");
uiDefButBitS(block, TOG, TF_SHADOW, REDRAWVIEW3D, "Shadow", 720,110,60,19, &tf->mode, 0, 0, 0, 0, "Face is used for shadow");
uiDefButBitS(block, TOG, TF_BMFONT, REDRAWVIEW3D, "Text", 780,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable bitmap text on face");
uiDefButBitS(block, TOG, TF_ALPHASORT, REDRAWVIEW3D, "Sort", 840,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable sorting of faces for correct alpha drawing (slow, use Clip Alpha instead when possible)");
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
+53 -40
View File
@@ -1654,53 +1654,66 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
wval = (width-100)/3;
if (oa->type == ACT_OBJECT_NORMAL)
{
ysize= 175;
if ( ob->gameflag & OB_DYNAMIC )
{
ysize= 175;
}
else
{
ysize= 72;
}
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
uiDefBut(block, LABEL, 0, "Force", xco, yco-45, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "Loc", xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the location");
uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "Torque", xco, yco-64, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "dLoc", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc");
uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "dRot", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot");
uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "linV", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "angV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
uiDefBut(block, LABEL, 0, "Rot", xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the rotation");
uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
if ( ob->gameflag & OB_DYNAMIC )
{
uiDefBut(block, LABEL, 0, "Force", xco, yco-87, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
uiDefBut(block, LABEL, 0, "Torque", xco, yco-106, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-6106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
}
if ( ob->gameflag & OB_DYNAMIC )
{
uiDefBut(block, LABEL, 0, "LinV", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "AngV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "Damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
}
} else if (oa->type == ACT_OBJECT_SERVO)
{
ysize= 172;
+2 -2
View File
@@ -480,7 +480,7 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short
/* Target-Space */
if (target == 1) {
uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1",
uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1",
tarx, yco, bwidth, 18, &con->tarspace, 0, 0, 0, 0, "Choose space that target is evaluated in");
}
else if (target == 0) {
@@ -490,7 +490,7 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short
/* Owner-Space */
if (owner == 1) {
uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1",
uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1",
ownx, yco, bwidth, 18, &con->ownspace, 0, 0, 0, 0, "Choose space that owner is evaluated in");
}
else if (owner == 0) {
+89 -44
View File
@@ -187,10 +187,15 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
sprintf(name, "%s (Locked)", gpl->info);
uiDefBut(block, LABEL, 1, name, *xco+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "Short description of what this layer is for (optional)");
/* delete button (only if hidden but not locked!) */
if ((gpl->flag & GP_LAYER_HIDE) & !(gpl->flag & GP_LAYER_LOCKED)) {
but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer");
uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL);
}
uiBlockSetEmboss(block, UI_EMBOSS);
}
else {
height= 100;
height= 97;
/* draw rest of header */
{
@@ -228,6 +233,10 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
/* stroke thickness */
uiDefButS(block, NUMSLI, B_REDR, "Thickness:", *xco, *yco-75, 150, 20, &gpl->thickness, 1, 10, 0, 0, "Thickness of strokes (in pixels)");
/* debugging options */
if (G.f & G_DEBUG) {
uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco, *yco-95, 150, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes");
}
/* onion-skinning */
uiBlockBeginAlign(block);
@@ -243,8 +252,6 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame (Hotkey = Alt-XKEY/DEL)");
uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl);
uiBlockEndAlign(block);
//uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco+160, *yco-75, 130, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes");
}
}
@@ -273,11 +280,15 @@ short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa)
/* show override lmb-clicks button + painting lock */
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret LMB-click as new strokes (same as holding Shift-Key per stroke)");
uiBlockSetCol(block, TH_BUT_SETTING);
uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED, 300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)");
uiBlockSetCol(block, TH_AUTO);
if ((gpd->flag & GP_DATA_EDITPAINT)==0) {
uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
uiBlockSetCol(block, TH_BUT_SETTING);
uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED, 300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)");
uiBlockSetCol(block, TH_AUTO);
}
else
uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
uiBlockEndAlign(block);
/* 'view align' button (naming depends on context) */
@@ -306,6 +317,66 @@ enum {
GP_DRAWDATA_ONLYV2D = (1<<2), /* only draw 'canvas' strokes */
};
/* draw stroke in buffer */
static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thickness, short dflag, short sflag)
{
tGPspoint *pt;
int i;
/* error checking */
if ((points == NULL) || (totpoints <= 0))
return;
/* check if buffer can be drawn */
if (dflag & (GP_DRAWDATA_ONLY3D|GP_DRAWDATA_ONLYV2D))
return;
/* if drawing a single point, draw it larger */
if (totpoints == 1) {
/* draw point */
glBegin(GL_POINTS);
glVertex2f(points->x, points->y);
glEnd();
}
else if (sflag & GP_STROKE_ERASER) {
/* draw stroke curve - just standard thickness */
setlinestyle(4);
glLineWidth(1.0f);
glBegin(GL_LINE_STRIP);
for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
glVertex2f(pt->x, pt->y);
}
glEnd();
setlinestyle(0);
}
else {
float oldpressure = 0.0f;
/* draw stroke curve */
setlinestyle(2);
glBegin(GL_LINE_STRIP);
for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
if (fabs(pt->pressure - oldpressure) > 0.2f) {
glEnd();
glLineWidth(pt->pressure * thickness);
glBegin(GL_LINE_STRIP);
glVertex2f(pt->x, pt->y);
oldpressure = pt->pressure;
}
else
glVertex2f(pt->x, pt->y);
}
glEnd();
setlinestyle(0);
}
}
/* draw a given stroke */
static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy)
{
@@ -425,32 +496,8 @@ static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, shor
glColor4f(color[0], color[1], color[2], color[3]);
for (gps= gpf->strokes.first; gps; gps= gps->next) {
/* handle 'eraser' strokes differently */
if (gps->flag & GP_STROKE_ERASER) {
// FIXME: this method is a failed experiment
#if 0
/* draw stroke twice, first time with 'white' to set a mask to invert
* contents of framebuffer, then second-time the same again but to restore
* the contents
*/
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_XOR);
glColor4f(1, 1, 1, 1); /* white */
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, 0, winx, winy);
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, 0, winx, winy);
glDisable(GL_COLOR_LOGIC_OP);
/* reset color for drawing next stroke */
glColor4f(color[0], color[1], color[2], color[3]);
#endif
}
else {
/* just draw the stroke once */
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
}
/* just draw the stroke once */
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
}
}
@@ -506,8 +553,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* check if frame is drawable */
if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
/* alpha decreases with distance from curframe index */
tcolor[3] = color[3] - (i * 0.7);
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
tcolor[3] = color[3] - (i/gpl->gstep);
gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
}
else
break;
@@ -518,8 +565,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* check if frame is drawable */
if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
/* alpha decreases with distance from curframe index */
tcolor[3] = color[3] - (i * 0.7);
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
tcolor[3] = color[3] - (i/gpl->gstep);
gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
}
else
break;
@@ -532,12 +579,12 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* draw the strokes for the ghost frames (at half of the alpha set by user) */
if (gpf->prev) {
tcolor[3] = (color[3] / 7);
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
gp_draw_strokes(gpf->prev, winx, winy, dflag, debug, lthick, tcolor);
}
if (gpf->next) {
tcolor[3] = (color[3] / 4);
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
gp_draw_strokes(gpf->next, winx, winy, dflag, debug, lthick, tcolor);
}
/* restore alpha */
@@ -550,15 +597,13 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
* that is being edited. (Stroke cache is currently stored in gp-data)
* that is being edited. (Stroke buffer is currently stored in gp-data)
*/
if ((G.f & G_GREASEPENCIL) && (gpl->flag & GP_LAYER_ACTIVE) &&
(gpf->flag & GP_FRAME_PAINT))
{
/* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */
setlinestyle(2);
gp_draw_stroke(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, debug, winx, winy);
setlinestyle(0);
gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
}
}
+2
View File
@@ -1995,6 +1995,8 @@ static void v3d_editarmature_buts(uiBlock *block, Object *ob, float lim)
tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:", 10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, REDRAWVIEW3D, "Lock", 160, 100, 140, 19, &(ebone->flag), 0, 0, 0, 0, "Prevents bone from being transformed in edit mode");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:", 10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
if (ebone->parent && ebone->flag & BONE_CONNECTED )
+26
View File
@@ -2709,6 +2709,32 @@ void show_all_armature_bones(void)
BIF_undo_push("Reveal Bones");
}
/* Sets editmode transform locks for bones (adds if lock==1, clears otherwise) */
void set_locks_armature_bones(short lock)
{
bArmature *arm= G.obedit->data;
EditBone *ebone;
for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
if (arm->layer & ebone->layer) {
if (ebone->flag & BONE_SELECTED) {
if (lock)
ebone->flag |= BONE_EDITMODE_LOCKED;
else
ebone->flag &= ~BONE_EDITMODE_LOCKED;
}
}
}
countall();
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
if (lock)
BIF_undo_push("Lock Bones");
else
BIF_undo_push("Unlock Bones");
}
/* check for null, before calling! */
static void bone_connect_to_existing_parent(EditBone *bone)
{
+10 -1
View File
@@ -82,6 +82,7 @@
#include "BKE_group.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_particle.h"
#include "BKE_texture.h"
@@ -933,6 +934,9 @@ static void make_editipo(void)
ob->ipowin= ID_TE;
make_texture_editipo(G.sipo);
}
else if(G.scene->world && give_current_world_texture()) {
make_texture_editipo(G.sipo);
}
}
else if(G.sipo->blocktype==ID_CA) {
if (ob) {
@@ -1120,6 +1124,11 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
*from= (ID *)tex;
if(tex) *ipo= tex->ipo;
}
else if(G.scene->world) {
Tex *tex= give_current_world_texture();
*from= (ID *)tex;
if(tex) *ipo= tex->ipo;
}
}
else if(blocktype==ID_MA) {
if(ob) {
@@ -6002,4 +6011,4 @@ void move_to_frame(void)
}
}
BIF_undo_push("Set frame to selected Ipo vertex");
}
}
+17 -2
View File
@@ -2760,7 +2760,7 @@ void special_editmenu(void)
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
}
else if(G.obedit->type==OB_ARMATURE) {
nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6");
nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6|%l|Lock%x7|Unlock%x8");
if(nr==1)
subdivide_armature(1);
if(nr==2) {
@@ -2773,6 +2773,10 @@ void special_editmenu(void)
else if(ELEM3(nr, 4, 5, 6)) {
armature_autoside_names(nr-4);
}
else if(nr==7)
set_locks_armature_bones(1);
else if(nr==8)
set_locks_armature_bones(0);
}
else if(G.obedit->type==OB_LATTICE) {
static float weight= 1.0f;
@@ -3502,6 +3506,17 @@ void copy_attr(short event)
base->object->damping= ob->damping;
base->object->rdamping= ob->rdamping;
}
else if(event==11) { /* all physical attributes */
base->object->gameflag = ob->gameflag;
base->object->inertia = ob->inertia;
base->object->formfactor = ob->formfactor;
base->object->damping= ob->damping;
base->object->rdamping= ob->rdamping;
base->object->mass= ob->mass;
if (ob->gameflag & OB_BOUNDS) {
base->object->boundtype = ob->boundtype;
}
}
else if(event==17) { /* tex space */
copy_texture_space(base->object, ob);
}
@@ -3688,7 +3703,7 @@ void copy_attr_menu()
* view3d_edit_object_copyattrmenu() and in toolbox.c
*/
strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|%l|Mass%x7|Damping%x8|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l");
strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|%l|Mass%x7|Damping%x8|All Physical Attributes%x11|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l");
strcat (str, "|Object Constraints%x22");
strcat (str, "|NLA Strips%x26");
+2 -2
View File
@@ -298,7 +298,7 @@ int lasso_inside(short mcords[][2], short moves, short sx, short sy)
}
/* edge version for lasso select. we assume boundbox check was done */
static int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1)
int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1)
{
short v1[2], v2[2];
int a;
@@ -371,7 +371,7 @@ static void do_lasso_select_objects(short mcords[][2], short moves, short select
}
}
static void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves)
void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves)
{
short a;
+317 -62
View File
@@ -48,6 +48,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
#include "DNA_vec_types.h"
#include "DNA_view3d_types.h"
#include "BKE_global.h"
@@ -57,6 +58,7 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_butspace.h"
#include "BIF_editview.h"
#include "BIF_graphics.h"
#include "BIF_interface.h"
#include "BIF_mywindow.h"
@@ -662,7 +664,14 @@ void gpencil_delete_menu (void)
/* ---------- 'Globals' and Defines ----------------- */
/* maximum sizes of gp-session buffer */
#define GP_STROKE_BUFFER_MAX 500
#define GP_STROKE_BUFFER_MAX 5000
/* Hardcoded sensitivity thresholds... */
// TODO: one day, these might be added to the UI if it is necessary
/* minimum number of pixels mouse should move before new point created */
#define MIN_MANHATTEN_PX 3
/* minimum length of new segment before new point can be added */
#define MIN_EUCLIDEAN_PX 20
/* ------ */
@@ -676,7 +685,7 @@ typedef struct tGPsdata {
bGPDframe *gpf; /* frame we're working on */
short status; /* current status of painting */
short paintmode; /* mode for painting (L_MOUSE or R_MOUSE for now) */
short paintmode; /* mode for painting */
} tGPsdata;
/* values for tGPsdata->status */
@@ -686,6 +695,12 @@ enum {
GP_STATUS_DONE /* painting done */
};
/* values for tGPsdata->paintmode */
enum {
GP_PAINTMODE_DRAW = 0,
GP_PAINTMODE_ERASER
};
/* Return flags for adding points to stroke buffer */
enum {
GP_STROKEADD_INVALID = -2, /* error occurred - insufficient info to do so */
@@ -703,9 +718,9 @@ static void gp_session_validatebuffer (tGPsdata *p)
/* clear memory of buffer (or allocate it if starting a new session) */
if (gpd->sbuffer)
memset(gpd->sbuffer, 0, sizeof(bGPDspoint)*GP_STROKE_BUFFER_MAX);
memset(gpd->sbuffer, 0, sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX);
else
gpd->sbuffer= MEM_callocN(sizeof(bGPDspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
gpd->sbuffer= MEM_callocN(sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
/* reset indices */
gpd->sbuffer_size = 0;
@@ -843,6 +858,25 @@ static void gp_session_cleanup (tGPsdata *p)
gpd->sbuffer_sflag= 0;
}
/* check if the current mouse position is suitable for adding a new point */
static short gp_stroke_filtermval (tGPsdata *p, short mval[2], short pmval[2])
{
short dx= abs(mval[0] - pmval[0]);
short dy= abs(mval[1] - pmval[1]);
/* check if mouse moved at least certain distance on both axes (best case) */
if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX))
return 1;
/* check if the distance since the last point is significant enough */
else if (sqrt(dx*dx + dy*dy) > MIN_EUCLIDEAN_PX)
return 1;
/* mouse 'didn't move' */
else
return 0;
}
/* convert screen-coordinates to buffer-coordinates */
static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
{
@@ -878,23 +912,23 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
}
/* add current stroke-point to buffer (returns whether point was successfully added) */
static short gp_stroke_addpoint (tGPsdata *p, short mval[], float pressure)
static short gp_stroke_addpoint (tGPsdata *p, short mval[2], float pressure)
{
bGPdata *gpd= p->gpd;
bGPDspoint *pt;
tGPspoint *pt;
/* check if still room in buffer */
if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX)
return GP_STROKEADD_OVERFLOW;
/* get pointer to destination point */
pt= gpd->sbuffer + gpd->sbuffer_size;
pt= ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size);
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, mval, &pt->x);
/* store other settings */
/* store settings */
pt->x= mval[0];
pt->y= mval[1];
pt->xf= (float)mval[0];
pt->yf= (float)mval[0];
pt->pressure= pressure;
/* increment counters */
@@ -907,35 +941,13 @@ static short gp_stroke_addpoint (tGPsdata *p, short mval[], float pressure)
return GP_STROKEADD_NORMAL;
}
/* smooth a stroke (in buffer) before storing it */
static void gp_stroke_smooth (tGPsdata *p)
{
bGPdata *gpd= p->gpd;
int i=0, cmx=gpd->sbuffer_size;
/* don't try if less than 2 points in buffer */
if ((cmx <= 2) || (gpd->sbuffer == NULL))
return;
/* apply weighting-average (note doing this along path sequentially does introduce slight error) */
for (i=0; i < gpd->sbuffer_size; i++) {
bGPDspoint *pc= (gpd->sbuffer + i);
bGPDspoint *pb= (i-1 > 0)?(pc-1):(pc);
bGPDspoint *pa= (i-2 > 0)?(pc-2):(pb);
bGPDspoint *pd= (i+1 < cmx)?(pc+1):(pc);
bGPDspoint *pe= (i+2 < cmx)?(pc+2):(pd);
pc->x= (0.1*pa->x + 0.2*pb->x + 0.4*pc->x + 0.2*pd->x + 0.1*pe->x);
pc->y= (0.1*pa->y + 0.2*pb->y + 0.4*pc->y + 0.2*pd->y + 0.1*pe->y);
}
}
/* make a new stroke from the buffer data */
static void gp_stroke_newfrombuffer (tGPsdata *p)
{
bGPdata *gpd= p->gpd;
bGPDstroke *gps;
bGPDspoint *pt, *ptc;
bGPDspoint *pt;
tGPspoint *ptc;
int i, totelem;
/* get total number of points to allocate space for */
@@ -961,7 +973,12 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
/* copy points from the buffer to the stroke */
for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) {
memcpy(pt, ptc, sizeof(bGPDspoint));
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x);
/* copy pressure */
pt->pressure= ptc->pressure;
pt++;
}
@@ -969,10 +986,220 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
BLI_addtail(&p->gpf->strokes, gps);
}
/* --- 'Eraser' for 'Paint' Tool ------ */
/* User should draw 'circles' around the parts of the sketches they wish to
* delete instead of drawing squiggles over existing lines. This should be
* easier to manage than if it was done otherwise.
*/
/* convert gp-buffer stroke into mouse-coordinates array */
static short (*gp_stroke_eraser_2mco (bGPdata *gpd))[2]
{
tGPspoint *pt;
short (*mcoords)[2];
int i;
/* allocate memory for coordinates array */
mcoords= MEM_mallocN(sizeof(*mcoords)*gpd->sbuffer_size,"gp_buf_mcords");
/* copy coordinates */
for (pt=gpd->sbuffer, i=0; i < gpd->sbuffer_size; i++, pt++) {
mcoords[i][0]= pt->x;
mcoords[i][1]= pt->y;
}
/* return */
return mcoords;
}
/* eraser tool - remove segment from stroke/split stroke (after lasso inside) */
static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i)
{
bGPDspoint *pt_tmp= gps->points;
bGPDstroke *gsn = NULL;
/* if stroke only had two points, get rid of stroke */
if (gps->totpoints == 2) {
/* free stroke points, then stroke */
MEM_freeN(pt_tmp);
BLI_freelinkN(&gpf->strokes, gps);
/* nothing left in stroke, so stop */
return 1;
}
/* if last segment, just remove segment from the stroke */
else if (i == gps->totpoints - 2) {
/* allocate new points array, and assign most of the old stroke there */
gps->totpoints--;
gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*gps->totpoints);
/* free temp buffer */
MEM_freeN(pt_tmp);
/* nothing left in stroke, so stop */
return 1;
}
/* if first segment, just remove segment from the stroke */
else if (i == 0) {
/* allocate new points array, and assign most of the old stroke there */
gps->totpoints--;
gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint)*gps->totpoints);
/* free temp buffer */
MEM_freeN(pt_tmp);
/* no break here, as there might still be stuff to remove in this stroke */
return 0;
}
/* segment occurs in 'middle' of stroke, so split */
else {
/* duplicate stroke, and assign 'later' data to that stroke */
gsn= MEM_dupallocN(gps);
gsn->prev= gsn->next= NULL;
BLI_insertlinkafter(&gpf->strokes, gps, gsn);
gsn->totpoints= gps->totpoints - i;
gsn->points= MEM_callocN(sizeof(bGPDspoint)*gsn->totpoints, "gp_stroke_points");
memcpy(gsn->points, pt_tmp + i, sizeof(bGPDspoint)*gsn->totpoints);
/* adjust existing stroke */
gps->totpoints= i;
gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*i);
/* free temp buffer */
MEM_freeN(pt_tmp);
/* nothing left in stroke, so stop */
return 1;
}
}
/* eraser tool - evaluation per stroke */
static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short moves, rcti *rect, bGPDframe *gpf, bGPDstroke *gps)
{
bGPDspoint *pt1, *pt2;
short x0=0, y0=0, x1=0, y1=0;
short xyval[2];
int i;
if (gps->totpoints == 0) {
/* just free stroke */
if (gps->points)
MEM_freeN(gps->points);
BLI_freelinkN(&gpf->strokes, gps);
}
else if (gps->totpoints == 1) {
/* get coordinates */
if (gps->flag & GP_STROKE_3DSPACE) {
// FIXME: this may not be the correct correction
project_short(&gps->points->x, xyval);
x0= xyval[0];
x1= xyval[1];
}
else if (gps->flag & GP_STROKE_2DSPACE) {
ipoco_to_areaco_noclip(p->v2d, &gps->points->x, xyval);
x0= xyval[0];
y0= xyval[1];
}
else {
x0= (gps->points->x / 1000 * p->sa->winx);
y0= (gps->points->y / 1000 * p->sa->winy);
}
/* do boundbox check first */
if (BLI_in_rcti(rect, x0, y0)) {
/* only check if point is inside */
if (lasso_inside(mcoords, moves, x0, y0)) {
/* free stroke */
MEM_freeN(gps->points);
BLI_freelinkN(&gpf->strokes, gps);
}
}
}
else {
/* loop over the points in the stroke, checking for intersections
* - an intersection will require the stroke to be split
*/
for (i=0; (i+1) < gps->totpoints; i++) {
/* get points to work with */
pt1= gps->points + i;
pt2= gps->points + i + 1;
/* get coordinates */
if (gps->flag & GP_STROKE_3DSPACE) {
// FIXME: may not be correct correction
project_short(&gps->points->x, xyval);
x0= xyval[0];
x1= xyval[1];
}
else if (gps->flag & GP_STROKE_2DSPACE) {
ipoco_to_areaco_noclip(p->v2d, &pt1->x, xyval);
x0= xyval[0];
y0= xyval[1];
ipoco_to_areaco_noclip(p->v2d, &pt2->x, xyval);
x1= xyval[0];
y1= xyval[1];
}
else {
x0= (pt1->x / 1000 * p->sa->winx);
y0= (pt1->y / 1000 * p->sa->winy);
x1= (pt2->x / 1000 * p->sa->winx);
y1= (pt2->y / 1000 * p->sa->winy);
}
/* check that point segment of the boundbox of the eraser stroke */
if (BLI_in_rcti(rect, x0, y0) || BLI_in_rcti(rect, x1, y1)) {
/* check if point segment of stroke had anything to do with
* eraser region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
* - handled using the lasso-select checking code
*/
if (lasso_inside_edge(mcoords, moves, x0, y0, x1, x1)) {
/* if function returns true, break this loop (as no more point to check) */
if (gp_stroke_eraser_splitdel(gpf, gps, i))
break;
}
}
}
}
}
/* -------- */
/* erase strokes which fall under the eraser strokes */
static void gp_stroke_doeraser (tGPsdata *p)
{
bGPdata *gpd= p->gpd;
bGPDframe *gpf= p->gpf;
bGPDstroke *gps, *gpn;
short (*mcoords)[2];
rcti rect;
/* get buffer-stroke coordinates as shorts array, and then get bounding box */
mcoords= gp_stroke_eraser_2mco(gpd);
lasso_select_boundbox(&rect, mcoords, gpd->sbuffer_size);
/* loop over strokes, checking segments for intersections */
for (gps= gpf->strokes.first; gps; gps= gpn) {
gpn= gps->next;
gp_stroke_eraser_dostroke(p, mcoords, gpd->sbuffer_size, &rect, gpf, gps);
}
/* free mcoords array */
MEM_freeN(mcoords);
}
/* ---------- 'Paint' Tool ------------ */
/* init new stroke */
static void gp_paint_initstroke (tGPsdata *p, short mousebutton)
static void gp_paint_initstroke (tGPsdata *p, short paintmode)
{
/* get active layer (or add a new one if non-existent) */
p->gpl= gpencil_layer_getactive(p->gpd);
@@ -996,14 +1223,10 @@ static void gp_paint_initstroke (tGPsdata *p, short mousebutton)
else
p->gpf->flag |= GP_FRAME_PAINT;
/* set 'eraser' for this stroke if using eraser or right-mouse in action */
if ( get_activedevice() == 2 || (mousebutton & R_MOUSE) ) {
/* set 'eraser' for this stroke if using eraser */
p->paintmode= paintmode;
if (p->paintmode == GP_PAINTMODE_ERASER)
p->gpd->sbuffer_sflag |= GP_STROKE_ERASER;
// for now: eraser isn't ready for prime-time yet, so no painting available here yet
p->status= GP_STATUS_ERROR;
return;
}
/* check if points will need to be made in view-aligned space */
if (p->gpd->flag & GP_DATA_VIEWALIGN) {
@@ -1033,11 +1256,15 @@ static void gp_paint_initstroke (tGPsdata *p, short mousebutton)
/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */
static void gp_paint_strokeend (tGPsdata *p)
{
/* sanitize stroke-points in buffer */
gp_stroke_smooth(p);
/* transfer stroke to frame */
gp_stroke_newfrombuffer(p);
/* check if doing eraser or not */
if (p->gpd->sbuffer_sflag & GP_STROKE_ERASER) {
/* get rid of relevant sections of strokes */
gp_stroke_doeraser(p);
}
else {
/* transfer stroke to frame */
gp_stroke_newfrombuffer(p);
}
/* clean up buffer now */
gp_session_validatebuffer(p);
@@ -1065,7 +1292,7 @@ static void gp_paint_cleanup (tGPsdata *p)
/* -------- */
/* main call to paint a new stroke */
short gpencil_paint (short mousebutton)
short gpencil_paint (short mousebutton, short paintmode)
{
tGPsdata p;
short prevmval[2], mval[2];
@@ -1078,7 +1305,7 @@ short gpencil_paint (short mousebutton)
gp_session_cleanup(&p);
return 0;
}
gp_paint_initstroke(&p, mousebutton);
gp_paint_initstroke(&p, paintmode);
if (p.status == GP_STATUS_ERROR) {
gp_session_cleanup(&p);
return 0;
@@ -1110,7 +1337,7 @@ short gpencil_paint (short mousebutton)
pressure = get_pressure();
/* only add current point to buffer if mouse moved (otherwise wait until it does) */
if ((mval[0] != prevmval[0]) || (mval[1] != prevmval[1])) {
if (gp_stroke_filtermval(&p, mval, prevmval)) {
/* try to add point */
ok= gp_stroke_addpoint(&p, mval, pressure);
@@ -1153,7 +1380,10 @@ short gpencil_paint (short mousebutton)
setcursor_space(p.sa->spacetype, CURSOR_STD);
/* check size of buffer before cleanup, to determine if anything happened here */
ok= p.gpd->sbuffer_size;
if (paintmode == GP_PAINTMODE_ERASER)
ok= (p.gpd->sbuffer_size > 1);
else
ok= p.gpd->sbuffer_size;
/* cleanup */
gp_paint_cleanup(&p);
@@ -1167,7 +1397,7 @@ short gpencil_paint (short mousebutton)
/* All event (loops) handling checking if stroke drawing should be initiated
* should call this function.
*/
short gpencil_do_paint (ScrArea *sa, short mousebutton)
short gpencil_do_paint (ScrArea *sa, short mbut)
{
bGPdata *gpd = gpencil_data_getactive(sa);
short retval= 0;
@@ -1176,18 +1406,43 @@ short gpencil_do_paint (ScrArea *sa, short mousebutton)
if (gpd == NULL)
return 0;
/* currently, we will only paint if:
/* currently, we will only 'paint' if:
* 1. draw-mode on gpd is set (for accessibility reasons)
* (single 'dots' are only available via this method)
* 2. if shift-modifier is held + lmb -> 'quick paint'
*
* OR
*
* draw eraser stroke if:
* 1. using the eraser on a tablet
* 2. draw-mode on gpd is set (for accessiblity reasons)
* (eraser is mapped to right-mouse)
* 3. Alt + 'select' mouse-button
* i.e. if LMB = select: Alt-LMB
* if RMB = select: Alt-RMB
*/
if (gpd->flag & GP_DATA_EDITPAINT) {
/* try to paint */
retval = gpencil_paint(mousebutton);
if (get_activedevice() == 2) {
/* eraser on a tablet - always try to erase strokes */
retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER);
}
else if (!(gpd->flag & GP_DATA_LMBPLOCK) && (G.qual == LR_SHIFTKEY)) {
/* try to paint */
retval = gpencil_paint(mousebutton);
else if (gpd->flag & GP_DATA_EDITPAINT) {
/* try to paint/erase */
if (mbut == L_MOUSE)
retval = gpencil_paint(mbut, GP_PAINTMODE_DRAW);
else if (mbut == R_MOUSE)
retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER);
}
else if (!(gpd->flag & GP_DATA_LMBPLOCK)) {
/* try to paint/erase as not locked */
if ((G.qual == LR_SHIFTKEY) && (mbut == L_MOUSE)) {
retval = gpencil_paint(mbut, GP_PAINTMODE_DRAW);
}
else if (G.qual == LR_ALTKEY) {
if ((U.flag & USER_LMOUSESELECT) && (mbut == L_MOUSE))
retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER);
else if (!(U.flag & USER_LMOUSESELECT) && (mbut == R_MOUSE))
retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER);
}
}
/* return result of trying to paint */
+2 -2
View File
@@ -1078,9 +1078,9 @@ static uiBlock *info_filemenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot Subwindow|Ctrl F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot All|Ctrl Shift F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, "");
#if GAMEBLENDER == 1
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Game As Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
#ifdef _WIN32
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Dynamic Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 23, "");
// uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Dynamic Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 23, "");
#endif
#endif
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+1 -1
View File
@@ -970,7 +970,7 @@ static char *ipo_modeselect_pup(void)
if(ob && ob->type==OB_LAMP)
str += sprintf(str,formatstring, "Lamp",ID_LA, ICON_LAMP);
if(ob && give_current_texture(ob, ob->actcol))
if((ob && give_current_texture(ob, ob->actcol))||(give_current_world_texture()))
str += sprintf(str,formatstring, "Texture",ID_TE, ICON_TEXTURE);
if(ob){
+1
View File
@@ -2196,6 +2196,7 @@ static uiBlock *view3d_edit_object_copyattrmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mass|Ctrl C, 7", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Damping|Ctrl C, 8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "All Physical Attributes|Ctrl C, 11", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Properties|Ctrl C, 9", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Logic Bricks|Ctrl C, 10", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Protected Transform |Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 29, "");
+1 -1
View File
@@ -532,7 +532,7 @@ static int ui_but_copy_paste(uiBut *but, char mode)
/* give butfunc the original text too */
/* feature used for bone renaming, channels, etc */
if(but->func_arg2==NULL) {
strncpy(backstr, but->drawstr, UI_MAX_DRAW_STR);
strncpy(backstr, but->poin, UI_MAX_DRAW_STR);
but->func_arg2= backstr;
}
strncpy(but->poin, but_copypaste_str, but->max);
+1 -1
View File
@@ -1281,9 +1281,9 @@ static int meshdeform_inside_cage(MeshDeformBind *mdb, float *co)
outside[1] = co[1] + (mdb->max[1] - mdb->min[1] + 1.0f)*MESHDEFORM_OFFSET[i][1];
outside[2] = co[2] + (mdb->max[2] - mdb->min[2] + 1.0f)*MESHDEFORM_OFFSET[i][2];
VECCOPY(start, co);
VECSUB(dir, outside, start);
Normalize(dir);
VECCOPY(start, co);
isect = meshdeform_ray_tree_intersect(mdb, start, outside);
if(isect && !isect->facing)
+6 -13
View File
@@ -3654,7 +3654,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, SpaceOops *soops, ListBas
uiBut *bt;
TreeElement *te;
TreeStoreElem *tselem;
Object *ob;
Object *ob = NULL;
for(te= lb->first; te; te= te->next) {
tselem= TREESTORE(te);
@@ -3662,7 +3662,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, SpaceOops *soops, ListBas
/* objects have toggle-able restriction flags */
if(tselem->type==0 && te->idcode==ID_OB) {
ob = (Object *)tselem->id;
uiBlockSetEmboss(block, UI_EMBOSSN);
bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_VIEW, REDRAWALL, ICON_RESTRICT_VIEW_OFF,
(int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
@@ -3718,13 +3718,6 @@ static void outliner_draw_restrictbuts(uiBlock *block, SpaceOops *soops, ListBas
uiButSetFunc(bt, restrictbutton_modifier_cb, ob, NULL);
uiButSetFlag(bt, UI_NO_HILITE);
/*
bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Editmode, REDRAWALL, VICON_EDIT,
(int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_modifier_cb, ob, NULL);
uiButSetFlag(bt, UI_NO_HILITE);
*/
bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, REDRAWALL, ICON_RESTRICT_RENDER_OFF,
(int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
uiButSetFunc(bt, restrictbutton_modifier_cb, ob, NULL);
@@ -3733,20 +3726,20 @@ static void outliner_draw_restrictbuts(uiBlock *block, SpaceOops *soops, ListBas
else if(tselem->type==TSE_POSE_CHANNEL) {
bPoseChannel *pchan= (bPoseChannel *)te->directdata;
Bone *bone = pchan->bone;
uiBlockSetEmboss(block, UI_EMBOSSN);
bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, REDRAWALL, ICON_RESTRICT_VIEW_OFF,
(int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_bone_cb, ob, NULL);
uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
uiButSetFlag(bt, UI_NO_HILITE);
}
else if(tselem->type==TSE_EBONE) {
EditBone *ebone= (EditBone *)te->directdata;
uiBlockSetEmboss(block, UI_EMBOSSN);
bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, REDRAWALL, ICON_RESTRICT_VIEW_OFF,
(int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_bone_cb, ob, NULL);
uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
uiButSetFlag(bt, UI_NO_HILITE);
}
}
+97 -59
View File
@@ -180,27 +180,26 @@ bPoseChannel *get_active_posechannel (Object *ob)
return NULL;
}
/* if a selected or active bone is protected, throw error and return 1 */
/* if a selected or active bone is protected, throw error (oonly if warn==1) and return 1 */
/* only_selected==1 : the active bone is allowed to be protected */
static int pose_has_protected_selected(Object *ob, int only_selected)
static short pose_has_protected_selected(Object *ob, short only_selected, short warn)
{
/* check protection */
if(ob->proxy) {
if (ob->proxy) {
bPoseChannel *pchan;
bArmature *arm= ob->data;
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone && (pchan->bone->layer & arm->layer)) {
if(pchan->bone->layer & arm->layer_protected) {
if(only_selected && (pchan->bone->flag & BONE_ACTIVE));
else if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED))
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if (pchan->bone && (pchan->bone->layer & arm->layer)) {
if (pchan->bone->layer & arm->layer_protected) {
if (only_selected && (pchan->bone->flag & BONE_ACTIVE));
else if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED))
break;
}
}
}
if(pchan) {
error("Cannot change Proxy protected bones");
if (pchan) {
if (warn) error("Cannot change Proxy protected bones");
return 1;
}
}
@@ -540,7 +539,7 @@ void pose_clear_IK(void)
if(!ob && !ob->pose) return;
if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
if(pose_has_protected_selected(ob, 0))
if(pose_has_protected_selected(ob, 0, 1))
return;
if(okee("Remove IK constraint(s)")==0) return;
@@ -581,7 +580,7 @@ void pose_clear_constraints(void)
if(!ob && !ob->pose) return;
if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
if(pose_has_protected_selected(ob, 0))
if(pose_has_protected_selected(ob, 0, 1))
return;
if(okee("Remove Constraints")==0) return;
@@ -612,38 +611,49 @@ void pose_copy_menu(void)
Object *ob= OBACT;
bArmature *arm= ob->data;
bPoseChannel *pchan, *pchanact;
short nr;
short nr=0;
int i=0;
/* paranoia checks */
if(!ob && !ob->pose) return;
if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
if (ELEM(NULL, ob, ob->pose)) return;
if ((ob==G.obedit) || (ob->flag & OB_POSEMODE)==0) return;
/* find active */
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone->flag & BONE_ACTIVE) break;
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if (pchan->bone->flag & BONE_ACTIVE)
break;
}
if(pchan==NULL) return;
if(pose_has_protected_selected(ob, 1))
return;
if (pchan==NULL) return;
pchanact= pchan;
i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
if (i<25)
nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8");
else
nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8");
/* if proxy-protected bones selected, some things (such as locks + displays) shouldn't be changable,
* but for constraints (just add local constraints)
*/
if (pose_has_protected_selected(ob, 1, 0)) {
i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
if (i < 25)
nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5");
else
nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4");
}
else {
i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
if (i < 25)
nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8");
else
nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8");
}
if(nr==-1) return;
if(nr!=5) {
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if( (arm->layer & pchan->bone->layer) &&
(pchan->bone->flag & BONE_SELECTED) &&
(pchan!=pchanact)
) {
if (nr <= 0)
return;
if (nr != 5) {
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if ( (arm->layer & pchan->bone->layer) &&
(pchan->bone->flag & BONE_SELECTED) &&
(pchan != pchanact) )
{
switch (nr) {
case 1: /* Local Location */
VECCOPY(pchan->loc, pchanact->loc);
@@ -656,13 +666,26 @@ void pose_copy_menu(void)
break;
case 4: /* All Constraints */
{
free_constraints(&pchan->constraints);
copy_constraints(&pchan->constraints, &pchanact->constraints);
pchan->constflag = pchanact->constflag;
ListBase tmp_constraints = {NULL, NULL};
if (ob->pose) {
ob->pose->flag |= POSE_RECALC;
/* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
copy_constraints(&tmp_constraints, &pchanact->constraints);
if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
bConstraint *con;
/* add proxy-local tags */
for (con= tmp_constraints.first; con; con= con->next)
con->flag |= CONSTRAINT_PROXY_LOCAL;
}
addlisttolist(&pchan->constraints, &tmp_constraints);
/* update flags (need to add here, not just copy) */
pchan->constflag |= pchanact->constflag;
if (ob->pose)
ob->pose->flag |= POSE_RECALC;
}
break;
case 6: /* Transform Locks */
@@ -703,12 +726,13 @@ void pose_copy_menu(void)
}
}
}
} else { /* constraints, optional */
}
else { /* constraints, optional (note: max we can have is 24 constraints) */
bConstraint *con, *con_back;
int const_toggle[24];
ListBase const_copy={0, 0};
ListBase const_copy = {NULL, NULL};
duplicatelist (&const_copy, &(pchanact->constraints));
duplicatelist(&const_copy, &(pchanact->constraints));
/* build the puplist of constraints */
for (con = pchanact->constraints.first, i=0; con; con=con->next, i++){
@@ -723,32 +747,46 @@ void pose_copy_menu(void)
/* now build a new listbase from the options selected */
for (i=0, con=const_copy.first; con; i++) {
/* if not selected, free/remove it from the list */
if (!const_toggle[i]) {
con_back= con->next;
BLI_freelinkN(&const_copy, con);
con= con_back;
} else {
}
else
con= con->next;
}
}
/* Copy the temo listbase to the selected posebones */
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if( (arm->layer & pchan->bone->layer) &&
(pchan->bone->flag & BONE_SELECTED) &&
(pchan!=pchanact)
) {
free_constraints(&pchan->constraints);
copy_constraints(&pchan->constraints, &const_copy);
pchan->constflag = pchanact->constflag;
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if ( (arm->layer & pchan->bone->layer) &&
(pchan->bone->flag & BONE_SELECTED) &&
(pchan!=pchanact) )
{
ListBase tmp_constraints = {NULL, NULL};
/* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
copy_constraints(&tmp_constraints, &const_copy);
if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
bConstraint *con;
/* add proxy-local tags */
for (con= tmp_constraints.first; con; con= con->next)
con->flag |= CONSTRAINT_PROXY_LOCAL;
}
addlisttolist(&pchan->constraints, &tmp_constraints);
/* update flags (need to add here, not just copy) */
pchan->constflag |= pchanact->constflag;
}
}
BLI_freelistN(&const_copy);
update_pose_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */
if (ob->pose) {
if (ob->pose)
ob->pose->flag |= POSE_RECALC;
}
}
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); // and all its relations
@@ -808,7 +846,7 @@ void paste_posebuf (int flip)
/*
// disabled until protected bones in proxies follow the rules everywhere else!
if(pose_has_protected_selected(ob, 1))
if(pose_has_protected_selected(ob, 1, 1))
return;
*/
@@ -1249,7 +1287,7 @@ void pose_flip_names(void)
if(!ob && !ob->pose) return;
if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
if(pose_has_protected_selected(ob, 0))
if(pose_has_protected_selected(ob, 0, 1))
return;
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
@@ -1282,7 +1320,7 @@ void pose_autoside_names(short axis)
if (ELEM(NULL, ob, ob->pose)) return;
if (ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
if (pose_has_protected_selected(ob, 0))
if (pose_has_protected_selected(ob, 0, 1))
return;
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
@@ -1415,7 +1453,7 @@ void pose_movetolayer(void)
/* pose-channel layers */
bPoseChannel *pchan;
if (pose_has_protected_selected(ob, 0))
if (pose_has_protected_selected(ob, 0, 1))
return;
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+2 -2
View File
@@ -1473,8 +1473,8 @@ static void input_preprocess(Sequence * seq, TStripElem* se, int cfra)
dy = sy;
if (seq->flag & SEQ_USE_TRANSFORM) {
dx = seqrectx;
dy = seqrecty;
dx = G.scene->r.xsch;
dy = G.scene->r.ysch;
}
if (c.top + c.bottom >= se->ibuf->y ||
+4 -1
View File
@@ -5119,7 +5119,10 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
}
if(doredraw) scrarea_queue_winredraw(curarea);
if(doredraw) {
scrarea_queue_winredraw(curarea);
scrarea_queue_headredraw(curarea);
}
}
@@ -1089,6 +1089,8 @@ static void createTransArmatureVerts(TransInfo *t)
VECCOPY (td->center, td->iloc);
td->loc= ebo->tail;
td->flag= TD_SELECTED;
if (ebo->flag & BONE_EDITMODE_LOCKED)
td->protectflag = OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE;
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
@@ -1104,6 +1106,8 @@ static void createTransArmatureVerts(TransInfo *t)
VECCOPY (td->center, td->iloc);
td->loc= ebo->head;
td->flag= TD_SELECTED;
if (ebo->flag & BONE_EDITMODE_LOCKED)
td->protectflag = OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE;
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
@@ -170,6 +170,13 @@ static void stats_pose(View3D *v3d, bPoseChannel *pchan)
}
}
/* for editmode*/
static void stats_editbone(View3D *v3d, EditBone *ebo)
{
if (ebo->flag & BONE_EDITMODE_LOCKED)
protectflag_to_drawflags(OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE, &v3d->twdrawflag);
}
/* only counts the parent selection, and tags transform flag */
/* bad call... should re-use method from transform_conversion once */
static void count_bone_select(TransInfo *t, bArmature *arm, ListBase *lb, int do_it)
@@ -258,6 +265,9 @@ int calc_manipulator_stats(ScrArea *sa)
calc_tw_center(ebo->head);
totsel++;
}
if (ebo->flag & BONE_SELECTED) {
stats_editbone(v3d, ebo);
}
}
}
}
+22
View File
@@ -618,8 +618,23 @@ int main(int argc, char **argv)
if (G.scene) {
if (a < argc) {
int frame= MIN2(MAXFRAME, MAX2(1, atoi(argv[a])));
int slink_flag= 0;
Render *re= RE_NewRender(G.scene->id.name);
if (G.f & G_DOSCRIPTLINKS) {
BPY_do_all_scripts(SCRIPT_RENDER);
/* avoid FRAMECHANGED slink event
* (should only be triggered in anims): */
G.f &= ~G_DOSCRIPTLINKS;
slink_flag= 1;
}
RE_BlenderAnim(re, G.scene, frame, frame);
if (slink_flag) {
G.f |= G_DOSCRIPTLINKS;
BPY_do_all_scripts(SCRIPT_POSTRENDER);
}
}
} else {
printf("\nError: no blend loaded. cannot use '-f'.\n");
@@ -628,7 +643,14 @@ int main(int argc, char **argv)
case 'a':
if (G.scene) {
Render *re= RE_NewRender(G.scene->id.name);
if (G.f & G_DOSCRIPTLINKS)
BPY_do_all_scripts(SCRIPT_RENDER);
RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
if (G.f & G_DOSCRIPTLINKS)
BPY_do_all_scripts(SCRIPT_POSTRENDER);
} else {
printf("\nError: no blend loaded. cannot use '-a'.\n");
}
@@ -170,6 +170,7 @@ void BL_RenderText(int mode,const char* textstr,int textlen,struct MTFace* tface
void DisableForText()
{
if(glIsEnabled(GL_BLEND)) glDisable(GL_BLEND);
if(glIsEnabled(GL_ALPHA_TEST)) glDisable(GL_ALPHA_TEST);
if(glIsEnabled(GL_LIGHTING)) {
glDisable(GL_LIGHTING);
@@ -1,114 +0,0 @@
/**
* $Id$
* ***** 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.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "KX_BlenderPolyMaterial.h"
#include "BKE_mesh.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if 0
KX_BlenderPolyMaterial::KX_BlenderPolyMaterial(const STR_String &texname,
bool ba,
const STR_String& matname,
int tile,
int tilexrep,
int tileyrep,
int mode,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject,
struct MTFace* tface)
: RAS_IPolyMaterial(texname,
false,
matname,
tile,
tilexrep,
tileyrep,
mode,
transparant,
zsort,
lightlayer,
bIsTriangle,
clientobject),
m_tface(tface)
{
}
void KX_BlenderPolyMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const
{
if (GetCachingInfo() != cachingInfo)
{
if (!cachingInfo)
{
set_tpage(NULL);
}
cachingInfo = GetCachingInfo();
if ((m_drawingmode & 4)&& (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED))
{
update_realtime_texture((struct MTFace*) m_tface, rasty->GetTime());
set_tpage(m_tface);
rasty->EnableTextures(true);
}
else
{
set_tpage(NULL);
rasty->EnableTextures(false);
}
if(m_drawingmode & RAS_IRasterizer::KX_TWOSIDE)
{
rasty->SetCullFace(false);
}
else
{
rasty->SetCullFace(true);
}
if (m_drawingmode & RAS_IRasterizer::KX_LINES) {
rasty->SetLines(true);
}
else {
rasty->SetLines(false);
}
}
rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
rasty->SetShinyness(m_shininess);
rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
}
#endif
@@ -1,99 +0,0 @@
/**
* $Id$
*
* ***** 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.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __KX_BLENDERPOLYMATERIAL
#define __KX_BLENDERPOLYMATERIAL
#include "RAS_MaterialBucket.h"
#include "RAS_IRasterizer.h"
struct MTFace;
extern "C" int set_tpage(MTFace* tface); /* Worst hack ever */
#if 0
class KX_BlenderPolyMaterial : public RAS_IPolyMaterial
{
/** Blender texture face structure. */
MTFace* m_tface;
public:
KX_BlenderPolyMaterial(const STR_String &texname,
bool ba,
const STR_String& matname,
int tile,
int tilexrep,
int tileyrep,
int mode,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject,
struct MTFace* tface);
/**
* Returns the caching information for this material,
* This can be used to speed up the rasterizing process.
* @return The caching information.
*/
virtual TCachingInfo GetCachingInfo(void) const;
/**
* Activates the material in the (OpenGL) rasterizer.
* On entry, the cachingInfo contains info about the last activated material.
* On exit, the cachingInfo should contain updated info about this material.
* @param rasty The rasterizer in which the material should be active.
* @param cachingInfo The information about the material used to speed up rasterizing.
*/
virtual void Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const;
/**
* Returns the Blender texture face structure that is used for this material.
* @return The material's texture face.
*/
MTFace* GetMTFace(void) const;
protected:
private:
};
inline MTFace* KX_BlenderPolyMaterial::GetMTFace(void) const
{
return m_tface;
}
inline RAS_IPolyMaterial::TCachingInfo KX_BlenderPolyMaterial::GetCachingInfo(void) const
{
return GetMTFace();
}
#endif
#endif // __KX_BLENDERPOLYMATERIAL
@@ -40,7 +40,6 @@
// it needs the gameobject and the sumo physics scene for a raycast
#include "KX_GameObject.h"
#include "KX_BlenderPolyMaterial.h"
#include "KX_PolygonMaterial.h"
#include "KX_BlenderMaterial.h"
@@ -57,24 +57,12 @@
BL_ActionActuator::~BL_ActionActuator()
{
if (m_pose) {
free_pose_channels(m_pose);
MEM_freeN(m_pose);
m_pose = NULL;
};
if (m_userpose){
free_pose_channels(m_userpose);
MEM_freeN(m_userpose);
m_userpose=NULL;
}
if (m_blendpose) {
free_pose_channels(m_blendpose);
MEM_freeN(m_blendpose);
m_blendpose = NULL;
};
if (m_pose)
free_pose(m_pose);
if (m_userpose)
free_pose(m_userpose);
if (m_blendpose)
free_pose(m_blendpose);
}
void BL_ActionActuator::ProcessReplica(){
@@ -82,10 +82,8 @@ void BL_ArmatureObject::ProcessReplica(BL_ArmatureObject *replica)
BL_ArmatureObject::~BL_ArmatureObject()
{
if (m_mrdPose){
free_pose_channels(m_mrdPose);
MEM_freeN(m_mrdPose);
}
if (m_mrdPose)
free_pose(m_mrdPose);
}
/* note, you can only call this for exisiting Armature objects, and not mix it with other Armatures */
@@ -172,12 +170,13 @@ void BL_ArmatureObject::GetMRDPose(bPose **pose)
// copy_pose (&m_mrdPose, m_pose, 0);
//}
if (!*pose)
if (!*pose) {
// must duplicate the constraints too otherwise we have corruption in free_pose_channels()
// because it will free the blender constraints.
// Ideally, blender should rememeber that the constraints were not copied so that
// free_pose_channels() would not free them.
copy_pose(pose, m_objArma->pose, 1);
}
else
extract_pose_from_pose(*pose, m_objArma->pose);
@@ -136,8 +136,12 @@
#include "BKE_mesh.h"
#include "MT_Point3.h"
#include "BLI_arithb.h"
extern "C" {
#include "BKE_customdata.h"
#include "BKE_customdata.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_DerivedMesh.h"
}
#include "BKE_material.h" /* give_current_material */
@@ -309,7 +313,6 @@ typedef struct MTF_localLayer
// ------------------------------------
BL_Material* ConvertMaterial(
Mesh* mesh,
Material *mat,
MTFace* tface,
const char *tfaceName,
@@ -323,15 +326,16 @@ BL_Material* ConvertMaterial(
//this needs some type of manager
BL_Material *material = new BL_Material();
int numchan = -1;
int numchan = -1, texalpha = 0;
bool validmat = (mat!=0);
bool validface = (mesh->mtface && tface);
bool validface = (tface!=0);
short type = 0;
if( validmat )
type = 1; // material color
material->IdMode = DEFAULT_BLENDER;
material->glslmat = (validmat)? glslmat: false;
// --------------------------------
if(validmat) {
@@ -367,12 +371,13 @@ BL_Material* ConvertMaterial(
if(i==0 && facetex ) {
Image*tmp = (Image*)(tface->tpage);
if(tmp) {
material->img[i] = tmp;
material->texname[i] = material->img[i]->id.name;
material->flag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
material->ras_mode|= ( tface->transp &(TF_ADD | TF_ALPHA))?TRANSP:0;
if(material->img[i]->flag & IMA_REFLECT)
material->mapping[i].mapping |= USEREFL;
else
@@ -430,6 +435,8 @@ BL_Material* ConvertMaterial(
material->flag[i] |= ( mttmp->mapto & MAP_ALPHA )?TEXALPHA:0;
material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE )?TEXNEG:0;
if(!glslmat && (material->flag[i] & TEXALPHA))
texalpha = 1;
}
}
else if(mttmp->tex->type == TEX_ENVMAP) {
@@ -546,17 +553,7 @@ BL_Material* ConvertMaterial(
material->ref = mat->ref;
material->amb = mat->amb;
// set alpha testing without z-sorting
if( ( validface && (!(tface->transp &~ TF_CLIP))) && mat->mode & MA_ZTRA) {
// sets the RAS_IPolyMaterial::m_flag |RAS_FORCEALPHA
// this is so we don't have the overhead of the z-sorting code
material->ras_mode|=ALPHA_TEST;
}
else{
// use regular z-sorting
material->ras_mode |= ((mat->mode & MA_ZTRA) != 0)?ZSORT:0;
}
material->ras_mode |= ((mat->mode & MA_WIRE) != 0)?WIRE:0;
material->ras_mode |= (mat->mode & MA_WIRE)? WIRE: 0;
}
else {
int valid = 0;
@@ -574,7 +571,6 @@ BL_Material* ConvertMaterial(
material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
material->ras_mode|= ( tface->transp & (TF_ADD|TF_ALPHA))?TRANSP:0;
valid++;
}
}
@@ -607,10 +603,6 @@ BL_Material* ConvertMaterial(
material->ras_mode |= ( (tface->mode & TF_DYNAMIC)!= 0 )?COLLIDER:0;
material->transp = tface->transp;
if(tface->transp&~TF_CLIP)
material->ras_mode |= TRANSP;
material->tile = tface->tile;
material->mode = tface->mode;
@@ -631,7 +623,16 @@ BL_Material* ConvertMaterial(
material->tile = 0;
}
// with ztransp enabled, enforce alpha blending mode
if(validmat && (mat->mode & MA_ZTRA) && (material->transp == TF_SOLID))
material->transp = TF_ALPHA;
// always zsort alpha + add
if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha)
&& (material->transp != TF_CLIP)) {
material->ras_mode |= ALPHA;
material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0;
}
// get uv sets
if(validmat)
@@ -711,132 +712,54 @@ BL_Material* ConvertMaterial(
}
static void BL_ComputeTriTangentSpace(const MT_Vector3 &v1, const MT_Vector3 &v2, const MT_Vector3 &v3,
const MT_Vector2 &uv1, const MT_Vector2 &uv2, const MT_Vector2 &uv3,
MFace* mface, MT_Vector3 *tan1, MT_Vector3 *tan2)
{
MT_Vector3 dx1(v2 - v1), dx2(v3 - v1);
MT_Vector2 duv1(uv2 - uv1), duv2(uv3 - uv1);
MT_Scalar r = 1.0 / (duv1.x() * duv2.y() - duv2.x() * duv1.y());
duv1 *= r;
duv2 *= r;
MT_Vector3 sdir(duv2.y() * dx1 - duv1.y() * dx2);
MT_Vector3 tdir(duv1.x() * dx2 - duv2.x() * dx1);
tan1[mface->v1] += sdir;
tan1[mface->v2] += sdir;
tan1[mface->v3] += sdir;
tan2[mface->v1] += tdir;
tan2[mface->v2] += tdir;
tan2[mface->v3] += tdir;
}
static MT_Vector4* BL_ComputeMeshTangentSpace(Mesh* mesh)
{
MFace* mface = static_cast<MFace*>(mesh->mface);
MTFace* tface = static_cast<MTFace*>(mesh->mtface);
MT_Vector3 *tan1 = new MT_Vector3[mesh->totvert];
MT_Vector3 *tan2 = new MT_Vector3[mesh->totvert];
int v;
for (v = 0; v < mesh->totvert; v++)
{
tan1[v] = MT_Vector3(0.0, 0.0, 0.0);
tan2[v] = MT_Vector3(0.0, 0.0, 0.0);
}
for (int p = 0; p < mesh->totface; p++, mface++, tface++)
{
MT_Vector3 v1(mesh->mvert[mface->v1].co),
v2(mesh->mvert[mface->v2].co),
v3(mesh->mvert[mface->v3].co);
MT_Vector2 uv1(tface->uv[0]),
uv2(tface->uv[1]),
uv3(tface->uv[2]);
BL_ComputeTriTangentSpace(v1, v2, v3, uv1, uv2, uv3, mface, tan1, tan2);
if (mface->v4)
{
MT_Vector3 v4(mesh->mvert[mface->v4].co);
MT_Vector2 uv4(tface->uv[3]);
BL_ComputeTriTangentSpace(v1, v3, v4, uv1, uv3, uv4, mface, tan1, tan2);
}
}
MT_Vector4 *tangent = new MT_Vector4[mesh->totvert];
for (v = 0; v < mesh->totvert; v++)
{
const MT_Vector3 no(mesh->mvert[v].no[0]/32767.0,
mesh->mvert[v].no[1]/32767.0,
mesh->mvert[v].no[2]/32767.0);
// Gram-Schmidt orthogonalize
MT_Vector3 t(tan1[v] - no.cross(no.cross(tan1[v])));
if (!MT_fuzzyZero(t))
t /= t.length();
tangent[v].x() = t.x();
tangent[v].y() = t.y();
tangent[v].z() = t.z();
// Calculate handedness
tangent[v].w() = no.dot(tan1[v].cross(tan2[v])) < 0.0 ? -1.0 : 1.0;
}
delete [] tan1;
delete [] tan2;
return tangent;
}
RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter)
{
RAS_MeshObject *meshobj;
bool skinMesh = false;
bool skinMesh = false;
int lightlayer = blenderobj->lay;
MFace* mface = static_cast<MFace*>(mesh->mface);
MTFace* tface = static_cast<MTFace*>(mesh->mtface);
const char *tfaceName = "";
MCol* mmcol = mesh->mcol;
MT_assert(mface || mesh->totface == 0);
// Get DerivedMesh data
DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj);
MVert *mvert = dm->getVertArray(dm);
int totvert = dm->getNumVerts(dm);
MFace *mface = dm->getFaceArray(dm);
MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE));
MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL));
float (*tangent)[3] = NULL;
int totface = dm->getNumFaces(dm);
const char *tfaceName = "";
if(tface) {
DM_add_tangent_layer(dm);
tangent = (float(*)[3])dm->getFaceDataArray(dm, CD_TANGENT);
}
// Determine if we need to make a skinned mesh
if (mesh->dvert || mesh->key){
if (mesh->dvert || mesh->key) {
meshobj = new BL_SkinMeshObject(mesh, lightlayer);
skinMesh = true;
}
else {
else
meshobj = new RAS_MeshObject(mesh, lightlayer);
}
MT_Vector4 *tangent = 0;
if (tface)
tangent = BL_ComputeMeshTangentSpace(mesh);
// Extract avaiable layers
MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE];
for (int lay=0; lay<MAX_MTFACE; lay++)
{
for (int lay=0; lay<MAX_MTFACE; lay++) {
layers[lay].face = 0;
layers[lay].name = "";
}
int validLayers = 0;
for (int i=0; i<mesh->fdata.totlayer; i++)
for (int i=0; i<dm->faceData.totlayer; i++)
{
if (mesh->fdata.layers[i].type == CD_MTFACE)
if (dm->faceData.layers[i].type == CD_MTFACE)
{
assert(validLayers <= 8);
layers[validLayers].face = (MTFace*)mesh->fdata.layers[i].data;;
layers[validLayers].name = mesh->fdata.layers[i].name;
layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data);
layers[validLayers].name = dm->faceData.layers[i].name;
if(tface == layers[validLayers].face)
tfaceName = layers[validLayers].name;
validLayers++;
@@ -844,271 +767,269 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
}
meshobj->SetName(mesh->id.name);
meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert);
for (int f=0;f<mesh->totface;f++,mface++)
meshobj->m_xyz_index_to_vertex_index_mapping.resize(totvert);
for (int f=0;f<totface;f++,mface++)
{
Material* ma = 0;
bool collider = true;
// only add valid polygons
if (mface->v3)
{
MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
// rgb3 is set from the adjoint face in a square
unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
MT_Vector3 no0(mesh->mvert[mface->v1].no[0], mesh->mvert[mface->v1].no[1], mesh->mvert[mface->v1].no[2]),
no1(mesh->mvert[mface->v2].no[0], mesh->mvert[mface->v2].no[1], mesh->mvert[mface->v2].no[2]),
no2(mesh->mvert[mface->v3].no[0], mesh->mvert[mface->v3].no[1], mesh->mvert[mface->v3].no[2]),
no3(0.0, 0.0, 0.0);
MT_Point3 pt0(mesh->mvert[mface->v1].co),
pt1(mesh->mvert[mface->v2].co),
pt2(mesh->mvert[mface->v3].co),
pt3(0.0, 0.0, 0.0);
MT_Vector4 tan0(0.0, 0.0, 0.0, 0.0),
tan1(0.0, 0.0, 0.0, 0.0),
tan2(0.0, 0.0, 0.0, 0.0),
tan3(0.0, 0.0, 0.0, 0.0);
MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
MT_Vector3 no0, no1, no2, no3;
MT_Point3 pt0, pt1, pt2, pt3;
MT_Vector4 tan0, tan1, tan2, tan3;
/* get coordinates, normals and tangents */
pt0 = MT_Point3(mvert[mface->v1].co);
pt1 = MT_Point3(mvert[mface->v2].co);
pt2 = MT_Point3(mvert[mface->v3].co);
pt3 = (mface->v4)? MT_Point3(mvert[mface->v4].co): MT_Point3(0.0, 0.0, 0.0);
if(mface->flag & ME_SMOOTH) {
float n0[3], n1[3], n2[3], n3[3];
NormalShortToFloat(n0, mvert[mface->v1].no);
NormalShortToFloat(n1, mvert[mface->v2].no);
NormalShortToFloat(n2, mvert[mface->v3].no);
no0 = n0;
no1 = n1;
no2 = n2;
if(mface->v4) {
NormalShortToFloat(n3, mvert[mface->v4].no);
no3 = n3;
}
else
no3 = MT_Vector3(0.0, 0.0, 0.0);
}
else {
float fno[3];
if(mface->v4)
CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
mvert[mface->v3].co, mvert[mface->v4].co, fno);
else
CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
mvert[mface->v3].co, fno);
no0 = no1 = no2 = no3 = MT_Vector3(fno);
}
if(tangent) {
tan0 = tangent[f*4 + 0];
tan1 = tangent[f*4 + 1];
tan2 = tangent[f*4 + 2];
no0 /= 32767.0;
no1 /= 32767.0;
no2 /= 32767.0;
if (mface->v4)
{
pt3 = MT_Point3(mesh->mvert[mface->v4].co);
no3 = MT_Vector3(mesh->mvert[mface->v4].no[0], mesh->mvert[mface->v4].no[1], mesh->mvert[mface->v4].no[2]);
no3 /= 32767.0;
}
tan3 = tangent[f*4 + 3];
}
/* get material */
ma = give_current_material(blenderobj, mface->mat_nr+1);
if(!(mface->flag & ME_SMOOTH))
{
MT_Vector3 norm = ((pt1-pt0).cross(pt2-pt0)).safe_normalized();
norm[0] = ((int) (10*norm[0]))/10.0;
norm[1] = ((int) (10*norm[1]))/10.0;
norm[2] = ((int) (10*norm[2]))/10.0;
no0=no1=no2=no3= norm;
}
{
Material* ma = 0;
bool polyvisible = true;
RAS_IPolyMaterial* polymat = NULL;
BL_Material *bl_mat = NULL;
{
bool polyvisible = true;
RAS_IPolyMaterial* polymat = NULL;
BL_Material *bl_mat = NULL;
if(converter->GetMaterials())
{
if(mesh->totcol > 1)
ma = mesh->mat[mface->mat_nr];
else
ma = give_current_material(blenderobj, 1);
if(converter->GetMaterials()) {
/* do Blender Multitexture and Blender GLSL materials */
unsigned int rgb[4];
MT_Point2 uv[4];
bl_mat = ConvertMaterial(mesh, ma, tface, tfaceName, mface, mmcol, lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
// set the index were dealing with
bl_mat->material_index = (int)mface->mat_nr;
/* first is the BL_Material */
bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol,
lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
collider = ((bl_mat->ras_mode & COLLIDER)!=0);
polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj );
unsigned int rgb[4];
bl_mat->GetConversionRGB(rgb);
rgb0 = rgb[0]; rgb1 = rgb[1];
rgb2 = rgb[2]; rgb3 = rgb[3];
MT_Point2 uv[4];
bl_mat->GetConversionUV(uv);
uv0 = uv[0]; uv1 = uv[1];
uv2 = uv[2]; uv3 = uv[3];
bl_mat->material_index = (int)mface->mat_nr;
bl_mat->GetConversionUV2(uv);
uv20 = uv[0]; uv21 = uv[1];
uv22 = uv[2]; uv23 = uv[3];
polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
collider = ((bl_mat->ras_mode & COLLIDER)!=0);
if(tangent){
tan0 = tangent[mface->v1];
tan1 = tangent[mface->v2];
tan2 = tangent[mface->v3];
if (mface->v4)
tan3 = tangent[mface->v4];
}
}
else
{
ma = give_current_material(blenderobj, 1);
/* vertex colors and uv's were stored in bl_mat temporarily */
bl_mat->GetConversionRGB(rgb);
rgb0 = rgb[0]; rgb1 = rgb[1];
rgb2 = rgb[2]; rgb3 = rgb[3];
Image* bima = ((mesh->mtface && tface) ? (Image*) tface->tpage : NULL);
STR_String imastr =
((mesh->mtface && tface) ?
(bima? (bima)->id.name : "" ) : "" );
char transp=0;
short mode=0, tile=0;
int tilexrep=4,tileyrep = 4;
if (bima)
{
tilexrep = bima->xrep;
tileyrep = bima->yrep;
bl_mat->GetConversionUV(uv);
uv0 = uv[0]; uv1 = uv[1];
uv2 = uv[2]; uv3 = uv[3];
bl_mat->GetConversionUV2(uv);
uv20 = uv[0]; uv21 = uv[1];
uv22 = uv[2]; uv23 = uv[3];
}
if (mesh->mtface && tface)
{
// Use texface colors if available
//TF_DYNAMIC means the polygon is a collision face
collider = ((tface->mode & TF_DYNAMIC) != 0);
transp = tface->transp &~ TF_CLIP;
tile = tface->tile;
mode = tface->mode;
polyvisible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
uv0 = MT_Point2(tface->uv[0]);
uv1 = MT_Point2(tface->uv[1]);
uv2 = MT_Point2(tface->uv[2]);
/* then the KX_BlenderMaterial */
polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj );
}
else {
/* do Texture Face materials */
Image* bima = (tface)? (Image*)tface->tpage: NULL;
STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
if (mface->v4)
uv3 = MT_Point2(tface->uv[3]);
}
else
{
// no texfaces, set COLLSION true and everything else FALSE
mode = default_face_mode;
transp = TF_SOLID;
tile = 0;
}
char transp=0;
short mode=0, tile=0;
int tilexrep=4,tileyrep = 4;
if (bima) {
tilexrep = bima->xrep;
tileyrep = bima->yrep;
}
if (mmcol)
{
// Use vertex colors
rgb0 = KX_Mcol2uint_new(mmcol[0]);
rgb1 = KX_Mcol2uint_new(mmcol[1]);
rgb2 = KX_Mcol2uint_new(mmcol[2]);
if (mface->v4)
rgb3 = KX_Mcol2uint_new(mmcol[3]);
}
else {
// no vertex colors: take from material if we have one,
// otherwise set to white
unsigned int color = 0xFFFFFFFFL;
if (ma)
{
union
{
unsigned char cp[4];
unsigned int integer;
} col_converter;
col_converter.cp[3] = (unsigned char) (ma->r*255.0);
col_converter.cp[2] = (unsigned char) (ma->g*255.0);
col_converter.cp[1] = (unsigned char) (ma->b*255.0);
col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
color = col_converter.integer;
}
/* get tface properties if available */
if(tface) {
/* TF_DYNAMIC means the polygon is a collision face */
collider = ((tface->mode & TF_DYNAMIC) != 0);
transp = tface->transp;
tile = tface->tile;
mode = tface->mode;
polyvisible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
uv0 = MT_Point2(tface->uv[0]);
uv1 = MT_Point2(tface->uv[1]);
uv2 = MT_Point2(tface->uv[2]);
rgb0 = KX_rgbaint2uint_new(color);
rgb1 = KX_rgbaint2uint_new(color);
rgb2 = KX_rgbaint2uint_new(color);
if (mface->v4)
rgb3 = KX_rgbaint2uint_new(color);
}
if (mface->v4)
uv3 = MT_Point2(tface->uv[3]);
}
else {
/* no texfaces, set COLLSION true and everything else FALSE */
mode = default_face_mode;
transp = TF_SOLID;
tile = 0;
}
/* get vertex colors */
if (mcol) {
/* we have vertex colors */
rgb0 = KX_Mcol2uint_new(mcol[0]);
rgb1 = KX_Mcol2uint_new(mcol[1]);
rgb2 = KX_Mcol2uint_new(mcol[2]);
bool istriangle = (mface->v4==0);
bool zsort = ma?(ma->mode & MA_ZTRA) != 0:false;
polymat = new KX_PolygonMaterial(imastr, ma,
tile, tilexrep, tileyrep,
mode, transp, zsort, lightlayer, istriangle, blenderobj, tface, (unsigned int*)mmcol);
if (mface->v4)
rgb3 = KX_Mcol2uint_new(mcol[3]);
}
else {
/* no vertex colors, take from material, otherwise white */
unsigned int color = 0xFFFFFFFFL;
if (ma)
{
polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
} else
{
polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
polymat->m_shininess = 35.0;
union
{
unsigned char cp[4];
unsigned int integer;
} col_converter;
col_converter.cp[3] = (unsigned char) (ma->r*255.0);
col_converter.cp[2] = (unsigned char) (ma->g*255.0);
col_converter.cp[1] = (unsigned char) (ma->b*255.0);
col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
color = col_converter.integer;
}
}
// see if a bucket was reused or a new one was created
// this way only one KX_BlenderMaterial object has to exist per bucket
bool bucketCreated;
RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
if (bucketCreated) {
// this is needed to free up memory afterwards
converter->RegisterPolyMaterial(polymat);
if(converter->GetMaterials()) {
converter->RegisterBlenderMaterial(bl_mat);
}
} else {
// delete the material objects since they are no longer needed
// from now on, use the polygon material from the material bucket
delete polymat;
if(converter->GetMaterials()) {
delete bl_mat;
}
polymat = bucket->GetPolyMaterial();
}
int nverts = mface->v4?4:3;
int vtxarray = meshobj->FindVertexArray(nverts,polymat);
RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
bool flat;
if (skinMesh) {
/* If the face is set to solid, all fnors are the same */
if (mface->flag & ME_SMOOTH)
flat = false;
else
flat = true;
}
else
flat = false;
poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1));
poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2));
poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3));
if (nverts==4)
poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4));
meshobj->AddPolygon(poly);
if (poly->IsCollider())
{
RAS_TriangleIndex idx;
idx.m_index[0] = mface->v1;
idx.m_index[1] = mface->v2;
idx.m_index[2] = mface->v3;
idx.m_collider = collider;
meshobj->m_triangle_indices.push_back(idx);
if (nverts==4)
{
idx.m_index[0] = mface->v1;
idx.m_index[1] = mface->v3;
idx.m_index[2] = mface->v4;
idx.m_collider = collider;
meshobj->m_triangle_indices.push_back(idx);
}
rgb0 = KX_rgbaint2uint_new(color);
rgb1 = KX_rgbaint2uint_new(color);
rgb2 = KX_rgbaint2uint_new(color);
if (mface->v4)
rgb3 = KX_rgbaint2uint_new(color);
}
// poly->SetVisibleWireframeEdges(mface->edcode);
poly->SetCollider(collider);
bool istriangle = (mface->v4==0);
// only zsort alpha + add
bool alpha = (transp == TF_ALPHA || transp == TF_ADD);
bool zsort = (mode & TF_ALPHASORT)? alpha: 0;
polymat = new KX_PolygonMaterial(imastr, ma,
tile, tilexrep, tileyrep,
mode, transp, alpha, zsort, lightlayer, istriangle, blenderobj, tface, (unsigned int*)mcol);
if (ma) {
polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
}
else {
polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
polymat->m_shininess = 35.0;
}
}
// see if a bucket was reused or a new one was created
// this way only one KX_BlenderMaterial object has to exist per bucket
bool bucketCreated;
RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
if (bucketCreated) {
// this is needed to free up memory afterwards
converter->RegisterPolyMaterial(polymat);
if(converter->GetMaterials()) {
converter->RegisterBlenderMaterial(bl_mat);
}
} else {
// delete the material objects since they are no longer needed
// from now on, use the polygon material from the material bucket
delete polymat;
if(converter->GetMaterials()) {
delete bl_mat;
}
polymat = bucket->GetPolyMaterial();
}
int nverts = mface->v4?4:3;
int vtxarray = meshobj->FindVertexArray(nverts,polymat);
RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
bool flat;
if (skinMesh) {
/* If the face is set to solid, all fnors are the same */
if (mface->flag & ME_SMOOTH)
flat = false;
else
flat = true;
}
else
flat = false;
poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1));
poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2));
poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3));
if (nverts==4)
poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4));
meshobj->AddPolygon(poly);
if (poly->IsCollider())
{
RAS_TriangleIndex idx;
idx.m_index[0] = mface->v1;
idx.m_index[1] = mface->v2;
idx.m_index[2] = mface->v3;
idx.m_collider = collider;
meshobj->m_triangle_indices.push_back(idx);
if (nverts==4)
{
idx.m_index[0] = mface->v1;
idx.m_index[1] = mface->v3;
idx.m_index[2] = mface->v4;
idx.m_collider = collider;
meshobj->m_triangle_indices.push_back(idx);
}
}
// poly->SetVisibleWireframeEdges(mface->edcode);
poly->SetCollider(collider);
}
if (tface)
tface++;
if (mmcol)
mmcol+=4;
if (mcol)
mcol+=4;
for (int lay=0; lay<MAX_MTFACE; lay++)
{
@@ -1127,11 +1048,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
(*mit)->GetPolyMaterial()->OnConstruction();
}
if(tangent)
delete [] tangent;
if (layers)
delete []layers;
dm->release(dm);
return meshobj;
}
@@ -1819,7 +1739,7 @@ KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){
return 0;
}
#include "BLI_arithb.h"
// convert blender objects into ketsji gameobjects
void BL_ConvertBlenderObjects(struct Main* maggie,
const STR_String& scenename,
@@ -1937,7 +1857,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (converter->addInitFromFrame)
if (!isInActiveLayer)
addobj=false;
if (gameobj&&addobj)
{
MT_Point3 posPrev;
@@ -2027,8 +1947,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
// needed for python scripting
logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
// needed for dynamic object morphing
logicmgr->RegisterGameObj(gameobj, blenderobject);
// needed for group duplication
logicmgr->RegisterGameObj(blenderobject, gameobj);
for (int i = 0; i < gameobj->GetMeshCount(); i++)
logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
@@ -2050,8 +1970,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->NodeUpdateGS(0,true);
gameobj->Bucketize();
if (gameobj->IsDupliGroup())
grouplist.insert(blenderobject->dup_group);
}
else
{
@@ -2059,6 +1977,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
//at the end of this function if it is not a root object
inactivelist->Add(gameobj->AddRef());
}
if (gameobj->IsDupliGroup())
grouplist.insert(blenderobject->dup_group);
if (converter->addInitFromFrame){
gameobj->NodeSetLocalPosition(posPrev);
gameobj->NodeSetLocalOrientation(angor);
@@ -2109,7 +2029,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
blenderscene);
// this code is copied from above except that
// object from groups are never is active layer
// object from groups are never in active layer
bool isInActiveLayer = false;
bool addobj=true;
@@ -2207,8 +2127,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
// needed for python scripting
logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
// needed for dynamic object morphing
logicmgr->RegisterGameObj(gameobj, blenderobject);
// needed for group duplication
logicmgr->RegisterGameObj(blenderobject, gameobj);
for (int i = 0; i < gameobj->GetMeshCount(); i++)
logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
@@ -2258,7 +2178,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
}
if (blenderscene->camera) {
// non-camera objects not supported as camera currently
if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) {
KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
if(gamecamera)
@@ -2520,13 +2441,13 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,layerMask,isInActiveLayer,canvas,converter);
}
// apply the initial state to controllers
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
// set the init state to all objects
gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
}
// apply the initial state to controllers, only on the active objects as this registers the sensors
for ( i=0;i<objectlist->GetCount();i++)
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i));
gameobj->ResetState();
}
@@ -733,9 +733,9 @@ void BL_ConvertSensors(struct Object* blenderobject,
gameobj->AddSensor(gamesensor);
// only register to manager if it's in an active layer
if (isInActiveLayer)
gamesensor->RegisterToManager();
// Make registration dynamic: only when sensor is activated
//if (isInActiveLayer)
// gamesensor->RegisterToManager();
for (int i=0;i<sens->totlinks;i++)
@@ -48,19 +48,10 @@ SCA_ActuatorEventManager::~SCA_ActuatorEventManager()
}
void SCA_ActuatorEventManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
}
void SCA_ActuatorEventManager::NextFrame()
{
// check for changed actuator
for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
(*it)->Activate(m_logicmgr,NULL);
}
@@ -69,7 +60,7 @@ void SCA_ActuatorEventManager::NextFrame()
void SCA_ActuatorEventManager::UpdateFrame()
{
// update the state of actuator before executing them
for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
((SCA_ActuatorSensor*)(*it))->Update();
}
@@ -44,7 +44,6 @@ public:
virtual ~SCA_ActuatorEventManager();
virtual void NextFrame();
virtual void UpdateFrame();
virtual void RegisterSensor(SCA_ISensor* sensor);
//SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
};
@@ -51,16 +51,9 @@ SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr)
void SCA_AlwaysEventManager::NextFrame()
{
for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
SCA_ISensor* sensor = *i;
sensor->Activate(m_logicmgr, NULL);
(*i)->Activate(m_logicmgr, NULL);
}
}
void SCA_AlwaysEventManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
}
@@ -39,7 +39,6 @@ class SCA_AlwaysEventManager : public SCA_EventManager
public:
SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr);
virtual void NextFrame();
virtual void RegisterSensor(SCA_ISensor* sensor);
};
@@ -45,17 +45,14 @@ SCA_EventManager::~SCA_EventManager()
{
}
void SCA_EventManager::RegisterSensor(class SCA_ISensor* sensor)
{
m_sensors.insert(sensor);
}
void SCA_EventManager::RemoveSensor(class SCA_ISensor* sensor)
{
std::vector<SCA_ISensor*>::iterator i =
std::find(m_sensors.begin(), m_sensors.end(), sensor);
if (!(i == m_sensors.end()))
{
std::swap(*i, m_sensors.back());
m_sensors.pop_back();
}
m_sensors.erase(sensor);
}
void SCA_EventManager::NextFrame(double curtime, double fixedtime)
@@ -30,12 +30,14 @@
#define __KX_EVENTMANAGER
#include <vector>
#include <set>
#include <algorithm>
class SCA_EventManager
{
protected:
std::vector <class SCA_ISensor*> m_sensors;
// use a set to speed-up insertion/removal
std::set <class SCA_ISensor*> m_sensors;
public:
enum EVENT_MANAGER_TYPE {
@@ -61,7 +63,7 @@ public:
virtual void NextFrame();
virtual void UpdateFrame();
virtual void EndFrame();
virtual void RegisterSensor(class SCA_ISensor* sensor)=0;
virtual void RegisterSensor(class SCA_ISensor* sensor);
int GetType();
protected:
+23 -4
View File
@@ -337,12 +337,31 @@ void SCA_IObject::Resume(void)
void SCA_IObject::SetState(unsigned int state)
{
m_state = state;
// update the status of the controllers
unsigned int tmpstate;
SCA_ControllerList::iterator contit;
for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
// we will update the state in two steps:
// 1) set the new state bits that are 1
// 2) clr the new state bits that are 0
// This to ensure continuity if a sensor is attached to two states
// that are switching state: no need to deactive and reactive the sensor
tmpstate = m_state | state;
if (tmpstate != m_state)
{
(*contit)->ApplyState(m_state);
// update the status of the controllers
for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
{
(*contit)->ApplyState(tmpstate);
}
}
m_state = state;
if (m_state != tmpstate)
{
for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
{
(*contit)->ApplyState(m_state);
}
}
}
+8 -1
View File
@@ -41,7 +41,8 @@
void SCA_ISensor::ReParent(SCA_IObject* parent)
{
SCA_ILogicBrick::ReParent(parent);
m_eventmgr->RegisterSensor(this);
// will be done when the sensor is activated
//m_eventmgr->RegisterSensor(this);
this->SetActive(false);
}
@@ -133,6 +134,7 @@ void SCA_ISensor::DecLink() {
{
// sensor is detached from all controllers, initialize it so that it
// is fresh as at startup when it is reattached again.
UnregisterToManager();
Init();
}
}
@@ -203,6 +205,11 @@ void SCA_ISensor::RegisterToManager()
m_eventmgr->RegisterSensor(this);
}
void SCA_ISensor::UnregisterToManager()
{
m_eventmgr->RemoveSensor(this);
}
void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
{
+3 -1
View File
@@ -115,6 +115,8 @@ public:
void SetLevel(bool lvl);
void RegisterToManager();
void UnregisterToManager();
virtual float GetNumber();
/** Stop sensing for a while. */
@@ -129,7 +131,7 @@ public:
void ClrLink()
{ m_links = 0; }
void IncLink()
{ m_links++; }
{ if (!m_links++) RegisterToManager(); }
void DecLink();
bool IsNoLink() const
{ return !m_links; }
@@ -52,9 +52,10 @@ SCA_JoystickManager::~SCA_JoystickManager()
void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
{
for (unsigned int i = 0; i < m_sensors.size(); i++)
set<SCA_ISensor*>::iterator it;
for (it = m_sensors.begin(); it != m_sensors.end(); it++)
{
SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*) m_sensors[i];
SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*)(*it);
if(!joysensor->IsSuspended())
{
m_joystick->HandleEvents();
@@ -64,12 +65,6 @@ void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
}
void SCA_JoystickManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
}
SCA_Joystick *SCA_JoystickManager::GetJoystickDevice()
{
/*
@@ -45,7 +45,6 @@ public:
SCA_JoystickManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_JoystickManager();
virtual void NextFrame(double curtime,double deltatime);
virtual void RegisterSensor(SCA_ISensor* sensor);
SCA_Joystick* GetJoystickDevice(void);
};
@@ -62,23 +62,14 @@ void SCA_KeyboardManager::NextFrame()
{
//const SCA_InputEvent& event = GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
// cerr << "SCA_KeyboardManager::NextFrame"<< endl;
for (unsigned int i=0;i<m_sensors.size();i++)
set<SCA_ISensor*>::iterator it;
for (it=m_sensors.begin(); it != m_sensors.end(); it++)
{
SCA_KeyboardSensor* keysensor = (SCA_KeyboardSensor*)m_sensors[i];
keysensor->Activate(m_logicmanager,NULL);
(*it)->Activate(m_logicmanager,NULL);
}
}
void SCA_KeyboardManager::RegisterSensor(SCA_ISensor* keysensor)
{
m_sensors.push_back(keysensor);
}
bool SCA_KeyboardManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
return false;
@@ -55,7 +55,6 @@ public:
bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
virtual void NextFrame();
virtual void RegisterSensor(class SCA_ISensor* sensor);
SCA_IInputDevice* GetInputDevice();
};
@@ -127,12 +127,17 @@ void SCA_LogicManager::RegisterGameMeshName(const STR_String& gamemeshname, void
void SCA_LogicManager::RegisterGameObj(CValue* gameobj, void* blendobj)
void SCA_LogicManager::RegisterGameObj(void* blendobj, CValue* gameobj)
{
m_map_gameobj_to_blendobj.insert(CHashedPtr(gameobj), blendobj);
m_map_blendobj_to_gameobj.insert(CHashedPtr(blendobj), gameobj);
}
void SCA_LogicManager::UnregisterGameObj(void* blendobj, CValue* gameobj)
{
void **obp = m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
if (obp && (CValue*)(*obp) == gameobj)
m_map_blendobj_to_gameobj.remove(CHashedPtr(blendobj));
}
CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
{
@@ -146,10 +151,10 @@ CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
}
void* SCA_LogicManager::FindBlendObjByGameObj(CValue* gameobject)
CValue* SCA_LogicManager::FindGameObjByBlendObj(void* blendobj)
{
void **obp= m_map_gameobj_to_blendobj[CHashedPtr(gameobject)];
return obp?*obp:NULL;
void **obp= m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
return obp?(CValue*)(*obp):NULL;
}
@@ -171,12 +176,7 @@ void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
(*c)->UnlinkSensor(sensor);
}
m_sensorcontrollermapje.erase(sensor);
for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
!(ie==m_eventmanagers.end());ie++)
{
(*ie)->RemoveSensor(sensor);
}
sensor->UnregisterToManager();
}
void SCA_LogicManager::RemoveController(SCA_IController* controller)
@@ -109,7 +109,7 @@ class SCA_LogicManager
GEN_Map<STR_HashedString,void*> m_mapStringToActions;
GEN_Map<STR_HashedString,void*> m_map_gamemeshname_to_blendobj;
GEN_Map<CHashedPtr,void*> m_map_gameobj_to_blendobj;
GEN_Map<CHashedPtr,void*> m_map_blendobj_to_gameobj;
vector<SmartActuatorPtr> m_removedActuators;
public:
@@ -152,8 +152,9 @@ public:
void RegisterGameMeshName(const STR_String& gamemeshname, void* blendobj);
void* FindBlendObjByGameMeshName(const STR_String& gamemeshname);
void RegisterGameObj(CValue* gameobj, void* blendobj);
void* FindBlendObjByGameObj(CValue* gameobj);
void RegisterGameObj(void* blendobj, CValue* gameobj);
void UnregisterGameObj(void* blendobj, CValue* gameobj);
CValue* FindGameObjByBlendObj(void* blendobj);
};
#endif //__KX_LOGICMANAGER
@@ -75,9 +75,10 @@ void SCA_MouseManager::NextFrame()
{
if (m_mousedevice)
{
for (unsigned int i = 0; i < m_sensors.size(); i++)
set<SCA_ISensor*>::iterator it;
for (it=m_sensors.begin(); it!=m_sensors.end(); it++)
{
SCA_MouseSensor* mousesensor = (SCA_MouseSensor*) m_sensors[i];
SCA_MouseSensor* mousesensor = (SCA_MouseSensor*)(*it);
// (0,0) is the Upper Left corner in our local window
// coordinates
if (!mousesensor->IsSuspended())
@@ -98,15 +99,6 @@ void SCA_MouseManager::NextFrame()
}
}
void SCA_MouseManager::RegisterSensor(SCA_ISensor* keysensor)
{
m_sensors.push_back(keysensor);
}
bool SCA_MouseManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
/* We should guard for non-mouse events maybe? A rather silly side */
@@ -62,7 +62,6 @@ public:
*/
bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
virtual void NextFrame();
virtual void RegisterSensor(class SCA_ISensor* sensor);
SCA_IInputDevice* GetInputDevice();
};
@@ -47,19 +47,10 @@ SCA_PropertyEventManager::~SCA_PropertyEventManager()
}
void SCA_PropertyEventManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
}
void SCA_PropertyEventManager::NextFrame()
{
// check for changed properties
for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
(*it)->Activate(m_logicmgr,NULL);
}
@@ -43,7 +43,6 @@ public:
SCA_PropertyEventManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_PropertyEventManager();
virtual void NextFrame();
virtual void RegisterSensor(SCA_ISensor* sensor);
//SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
};
@@ -50,16 +50,9 @@ SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr)
void SCA_RandomEventManager::NextFrame()
{
for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
SCA_ISensor *sensor = *i;
sensor->Activate(m_logicmgr, NULL);
(*i)->Activate(m_logicmgr, NULL);
}
}
void SCA_RandomEventManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
};
@@ -45,7 +45,6 @@ public:
SCA_RandomEventManager(class SCA_LogicManager* logicmgr);
virtual void NextFrame();
virtual void RegisterSensor(SCA_ISensor* sensor);
};
#endif //__KX_RANDOMEVENTMGR
@@ -65,6 +65,11 @@ void SCA_TimeEventManager::RegisterSensor(SCA_ISensor* sensor)
// not yet
}
void SCA_TimeEventManager::RemoveSensor(SCA_ISensor* sensor)
{
// empty
}
void SCA_TimeEventManager::NextFrame(double curtime, double fixedtime)
@@ -45,6 +45,7 @@ public:
virtual void NextFrame(double curtime, double fixedtime);
virtual void RegisterSensor(class SCA_ISensor* sensor);
virtual void RemoveSensor(class SCA_ISensor* sensor);
void AddTimeProperty(CValue* timeval);
void RemoveTimeProperty(CValue* timeval);
};
+68 -17
View File
@@ -1,6 +1,10 @@
#include "DNA_customdata_types.h"
#include "DNA_material_types.h"
#include "DNA_scene_types.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BL_BlenderShader.h"
#include "BL_Material.h"
@@ -10,30 +14,51 @@
#include "GPU_material.h"
#endif
#include "RAS_BucketManager.h"
#include "RAS_MeshObject.h"
#include "RAS_IRasterizer.h"
/* this is evil, but we need the scene to create materials with
* lights from the correct scene .. */
static struct Scene *GetSceneForName(const STR_String& scenename)
{
Scene *sce;
const bool BL_BlenderShader::Ok()const
for (sce= (Scene*)G.main->scene.first; sce; sce= (Scene*)sce->id.next)
if (scenename == (sce->id.name+2))
return sce;
return (Scene*)G.main->scene.first;
}
bool BL_BlenderShader::Ok()
{
#ifdef BLENDER_GLSL
return (mGPUMat != 0);
VerifyShader();
return (mMat && mMat->gpumaterial);
#else
return 0;
#endif
}
BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer)
BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer)
:
#ifdef BLENDER_GLSL
mGPUMat(0),
mScene(scene),
mMat(ma),
mGPUMat(NULL),
#endif
mBound(false),
mLightLayer(lightlayer)
{
#ifdef BLENDER_GLSL
if(ma) {
GPU_material_from_blender(ma);
mGPUMat = ma->gpumaterial;
mBlenderScene = GetSceneForName(scene->GetName());
mBlendMode = GPU_BLEND_SOLID;
if(mMat) {
GPU_material_from_blender(mBlenderScene, mMat);
mGPUMat = mMat->gpumaterial;
}
#endif
}
@@ -41,17 +66,29 @@ BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer)
BL_BlenderShader::~BL_BlenderShader()
{
#ifdef BLENDER_GLSL
if(mGPUMat) {
GPU_material_unbind(mGPUMat);
mGPUMat = 0;
}
if(mMat && mMat->gpumaterial)
GPU_material_unbind(mMat->gpumaterial);
#endif
}
bool BL_BlenderShader::VerifyShader()
{
#ifdef BLENDER_GLSL
if(mMat && !mMat->gpumaterial)
GPU_material_from_blender(mBlenderScene, mMat);
mGPUMat = mMat->gpumaterial;
return (mMat && mGPUMat);
#else
return false;
#endif
}
void BL_BlenderShader::SetProg(bool enable)
{
#ifdef BLENDER_GLSL
if(mGPUMat) {
if(VerifyShader()) {
if(enable) {
GPU_material_bind(mGPUMat, mLightLayer);
mBound = true;
@@ -70,7 +107,7 @@ int BL_BlenderShader::GetAttribNum()
GPUVertexAttribs attribs;
int i, enabled = 0;
if(!mGPUMat)
if(!VerifyShader())
return enabled;
GPU_material_vertex_attributes(mGPUMat, &attribs);
@@ -96,7 +133,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
ras->SetAttribNum(0);
if(!mGPUMat)
if(!VerifyShader())
return;
if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
@@ -142,9 +179,11 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
{
#ifdef BLENDER_GLSL
float obmat[4][4], viewmat[4][4], viewinvmat[4][4];
float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4];
if(!mGPUMat || !mBound)
VerifyShader();
if(!mGPUMat) // || !mBound)
return;
MT_Matrix4x4 model;
@@ -158,10 +197,22 @@ void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
view.invert();
view.getValue((float*)viewinvmat);
GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat);
if(ms.m_bObjectColor)
ms.m_RGBAcolor.getValue((float*)obcol);
else
obcol[0]= obcol[1]= obcol[2]= obcol[3]= 1.0f;
GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat, obcol);
mBlendMode = GPU_material_blend_mode(mGPUMat, obcol);
#endif
}
int BL_BlenderShader::GetBlendMode()
{
return mBlendMode;
}
bool BL_BlenderShader::Equals(BL_BlenderShader *blshader)
{
#ifdef BLENDER_GLSL
+12 -2
View File
@@ -14,7 +14,10 @@
#include "RAS_IPolygonMaterial.h"
#include "KX_Scene.h"
struct Material;
struct Scene;
class BL_Material;
#define BL_MAX_ATTRIB 16
@@ -27,21 +30,28 @@ class BL_BlenderShader
{
private:
#ifdef BLENDER_GLSL
KX_Scene *mScene;
struct Scene *mBlenderScene;
struct Material *mMat;
GPUMaterial *mGPUMat;
#endif
bool mBound;
int mLightLayer;
int mBlendMode;
bool VerifyShader();
public:
BL_BlenderShader(struct Material *ma, int lightlayer);
BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer);
virtual ~BL_BlenderShader();
const bool Ok()const;
bool Ok();
void SetProg(bool enable);
int GetAttribNum();
void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);
void Update(const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty);
int GetBlendMode();
bool Equals(BL_BlenderShader *blshader);
};
+2 -3
View File
@@ -129,8 +129,7 @@ enum BL_flag
TEXALPHA=8, // use alpha combiner functions
TEXNEG=16, // negate blending
HASIPO=32,
USENEGALPHA=64,
ALPHA_TEST=128
USENEGALPHA=64
};
// BL_Material::ras_mode
@@ -139,7 +138,7 @@ enum BL_ras_mode
POLY_VIS=1,
COLLIDER=2,
ZSORT=4,
TRANSP=8,
ALPHA=8,
TRIANGLE=16,
USE_LIGHT=32,
WIRE=64
-2
View File
@@ -384,8 +384,6 @@ void BL_Texture::DisableUnit()
void BL_Texture::DisableAllTextures()
{
glDisable(GL_BLEND);
for(int i=0; i<MAXTEX; i++) {
if(GLEW_ARB_multitexture)
glActiveTextureARB(GL_TEXTURE0_ARB+i);

Some files were not shown because too many files have changed in this diff Show More