Merged 15771:15912 from trunk
This commit is contained in:
@@ -20,3 +20,4 @@ Romanian:ro
|
||||
Arabic:ar
|
||||
Bulgarian:bg
|
||||
Greek:el
|
||||
Korean:kr
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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$
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 ...
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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! */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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, "");
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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, "");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user