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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Curioni <maxime.curioni@gmail.com>2008-05-08 23:16:40 +0400
committerMaxime Curioni <maxime.curioni@gmail.com>2008-05-08 23:16:40 +0400
commit64e4a3ec9aed6c8abe095e2cd1fe1552f7cde51c (patch)
tree6c77358bd447b6c2d215324ef48fc12d1f5ae5ca /source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
parentcf2e1e2857cfc5b3c2848c7fc6c9d919ac72fabb (diff)
parent106974a9d2d5caa5188322507980e3d57d2e3517 (diff)
soc-2008-mxcurioni: merged changes to revision 14747, cosmetic changes for source/blender/freestyle
Diffstat (limited to 'source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp')
-rwxr-xr-xsource/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp362
1 files changed, 362 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
new file mode 100755
index 00000000000..98e7c269248
--- /dev/null
+++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
@@ -0,0 +1,362 @@
+
+//
+// Copyright (C) : Please refer to the COPYRIGHT file distributed
+// with this source distribution.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "../geometry/GeomUtils.h"
+#include "../scene_graph/NodeShape.h"
+#include "WingedEdgeBuilder.h"
+#include <set>
+using namespace std;
+
+void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) {
+ WShape *shape = new WShape;
+ buildWShape(*shape, ifs);
+ shape->SetId(ifs.getId().getFirst());
+ //ifs.SetId(shape->GetId());
+}
+
+void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) {
+ //Sets the current material to iShapeode->material:
+ _current_material = &(ns.material());
+}
+
+void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) {
+ if(!_current_matrix) {
+ _current_matrix = new Matrix44r(tn.matrix());
+ return;
+ }
+
+ _matrices_stack.push_back(_current_matrix);
+ Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix());
+ _current_matrix = new_matrix;
+}
+
+void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) {
+ if(_current_matrix)
+ delete _current_matrix;
+
+ if(_matrices_stack.empty()) {
+ _current_matrix = NULL;
+ return;
+ }
+
+ _current_matrix = _matrices_stack.back();
+ _matrices_stack.pop_back();
+}
+
+void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) {
+ unsigned vsize = ifs.vsize();
+ unsigned nsize = ifs.nsize();
+ unsigned tsize = ifs.tsize();
+
+ const real* vertices = ifs.vertices();
+ const real* normals = ifs.normals();
+ const real* texCoords = ifs.texCoords();
+
+ real* new_vertices;
+ real* new_normals;
+
+ new_vertices = new real[vsize];
+ new_normals = new real[nsize];
+
+ // transform coordinates from local to world system
+ if(_current_matrix) {
+ transformVertices(vertices, vsize, *_current_matrix, new_vertices);
+ transformNormals(normals, nsize, *_current_matrix, new_normals);
+ }
+ else {
+ memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices));
+ memcpy(new_normals, normals, nsize * sizeof(*new_normals));
+ }
+
+ const IndexedFaceSet::TRIANGLES_STYLE* faceStyle = ifs.trianglesStyle();
+
+ vector<Material> materials;
+ if(ifs.msize()){
+ const Material*const* mats = ifs.materials();
+ for(unsigned i=0; i<ifs.msize(); ++i)
+ materials.push_back(*(mats[i]));
+ shape.SetMaterials(materials);
+ }
+
+ // const Material * mat = (ifs.material());
+ // if (mat)
+ // shape.SetMaterial(*mat);
+ // else if(_current_material)
+ // shape.SetMaterial(*_current_material);
+
+ // sets the current WShape to shape
+ _current_wshape = &shape;
+
+ // create a WVertex for each vertex
+ buildWVertices(shape, new_vertices, vsize);
+
+ const unsigned* vindices = ifs.vindices();
+ const unsigned* nindices = ifs.nindices();
+ const unsigned* tindices = 0;
+ if(ifs.tsize()){
+ tindices = ifs.tindices();
+ }
+
+ const unsigned *mindices = 0;
+ if(ifs.msize())
+ mindices = ifs.mindices();
+ const unsigned* numVertexPerFace = ifs.numVertexPerFaces();
+ const unsigned numfaces = ifs.numFaces();
+
+ for (unsigned index = 0; index < numfaces; index++) {
+ switch(faceStyle[index]) {
+ case IndexedFaceSet::TRIANGLE_STRIP:
+ buildTriangleStrip(new_vertices,
+ new_normals,
+ materials,
+ texCoords,
+ vindices,
+ nindices,
+ mindices,
+ tindices,
+ numVertexPerFace[index]);
+ break;
+ case IndexedFaceSet::TRIANGLE_FAN:
+ buildTriangleFan(new_vertices,
+ new_normals,
+ materials,
+ texCoords,
+ vindices,
+ nindices,
+ mindices,
+ tindices,
+ numVertexPerFace[index]);
+ break;
+ case IndexedFaceSet::TRIANGLES:
+ buildTriangles(new_vertices,
+ new_normals,
+ materials,
+ texCoords,
+ vindices,
+ nindices,
+ mindices,
+ tindices,
+ numVertexPerFace[index]);
+ break;
+ }
+ vindices += numVertexPerFace[index];
+ nindices += numVertexPerFace[index];
+ if(mindices)
+ mindices += numVertexPerFace[index];
+ if(tindices)
+ tindices += numVertexPerFace[index];
+ }
+
+ delete[] new_vertices;
+ delete[] new_normals;
+
+ // compute bbox
+ shape.ComputeBBox();
+ // compute mean edge size:
+ shape.ComputeMeanEdgeSize();
+
+ // Parse the built winged-edge shape to update post-flags
+ set<Vec3r> normalsSet;
+ vector<WVertex*>& wvertices = shape.GetVertexList();
+ for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end();
+ wv!=wvend;
+ ++wv){
+ if((*wv)->isBoundary())
+ continue;
+ normalsSet.clear();
+ WVertex::face_iterator fit = (*wv)->faces_begin();
+ WVertex::face_iterator fitend = (*wv)->faces_end();
+ while(fit!=fitend){
+ WFace *face = *fit;
+ normalsSet.insert(face->GetVertexNormal(*wv));
+ if(normalsSet.size()!=1){
+ break;
+ }
+ ++fit;
+ }
+ if(normalsSet.size()!=1){
+ (*wv)->SetSmooth(false);
+ }
+ }
+ // Adds the new WShape to the WingedEdge structure
+ _winged_edge->addWShape(&shape);
+}
+
+void WingedEdgeBuilder::buildWVertices(WShape& shape,
+ const real *vertices,
+ unsigned vsize) {
+ WVertex *vertex;
+ for (unsigned i = 0; i < vsize; i += 3) {
+ vertex = new WVertex(Vec3r(vertices[i],
+ vertices[i + 1],
+ vertices[i + 2]));
+ vertex->SetId(i / 3);
+ shape.AddVertex(vertex);
+ }
+}
+
+void WingedEdgeBuilder::buildTriangleStrip( const real *vertices,
+ const real *normals,
+ vector<Material>& iMaterials,
+ const real *texCoords,
+ const unsigned *vindices,
+ const unsigned *nindices,
+ const unsigned *mindices,
+ const unsigned *tindices,
+ const unsigned nvertices) {
+ unsigned nDoneVertices = 2; // number of vertices already treated
+ unsigned nTriangle = 0; // number of the triangle currently being treated
+ //int nVertex = 0; // vertex number
+
+ WShape* currentShape = _current_wshape; // the current shape being built
+ vector<WVertex *> triangleVertices;
+ vector<Vec3r> triangleNormals;
+ vector<Vec2r> triangleTexCoords;
+
+ while(nDoneVertices < nvertices)
+ {
+ //clear the vertices list:
+ triangleVertices.clear();
+ //Then rebuild it:
+ if(0 == nTriangle%2) // if nTriangle is even
+ {
+ triangleVertices.push_back(currentShape->GetVertexList()[vindices[nTriangle]/3]);
+ triangleVertices.push_back(currentShape->GetVertexList()[vindices[nTriangle+1]/3]);
+ triangleVertices.push_back(currentShape->GetVertexList()[vindices[nTriangle+2]/3]);
+
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]],normals[nindices[nTriangle+1]+1],normals[nindices[nTriangle+1]+2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]], normals[nindices[nTriangle+2]+1], normals[nindices[nTriangle+2]+2]));
+
+ if(texCoords){
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]],texCoords[tindices[nTriangle+1]+1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]], texCoords[tindices[nTriangle+2]+1]));
+ }
+ }
+ else // if nTriangle is odd
+ {
+ triangleVertices.push_back(currentShape->GetVertexList()[vindices[nTriangle]/3]);
+ triangleVertices.push_back(currentShape->GetVertexList()[vindices[nTriangle+2]/3]);
+ triangleVertices.push_back(currentShape->GetVertexList()[vindices[nTriangle+1]/3]);
+
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]],normals[nindices[nTriangle+2]+1],normals[nindices[nTriangle+2]+2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]], normals[nindices[nTriangle+1]+1], normals[nindices[nTriangle+1]+2]));
+
+ if(texCoords){
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]],texCoords[tindices[nTriangle+2]+1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]], texCoords[tindices[nTriangle+1]+1]));
+ }
+ }
+ if(mindices)
+ currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, mindices[nTriangle/3]);
+ else
+ currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, 0);
+ nDoneVertices++; // with a strip, each triangle is one vertex more
+ nTriangle++;
+ }
+}
+
+void WingedEdgeBuilder::buildTriangleFan( const real *vertices,
+ const real *normals,
+ vector<Material>& iMaterials,
+ const real *texCoords,
+ const unsigned *vindices,
+ const unsigned *nindices,
+ const unsigned *mindices,
+ const unsigned *tindices,
+ const unsigned nvertices) {
+ // Nothing to be done
+}
+
+void WingedEdgeBuilder::buildTriangles(const real *vertices,
+ const real *normals,
+ vector<Material>& iMaterials,
+ const real *texCoords,
+ const unsigned *vindices,
+ const unsigned *nindices,
+ const unsigned *mindices,
+ const unsigned *tindices,
+ const unsigned nvertices) {
+ WShape * currentShape = _current_wshape; // the current shape begin built
+ vector<WVertex *> triangleVertices;
+ vector<Vec3r> triangleNormals;
+ vector<Vec2r> triangleTexCoords;
+
+ // Each triplet of vertices is considered as an independent triangle
+ for(unsigned i = 0; i < nvertices / 3; i++)
+ {
+ triangleVertices.push_back(currentShape->GetVertexList()[vindices[3*i]/3]);
+ triangleVertices.push_back(currentShape->GetVertexList()[vindices[3*i+1]/3]);
+ triangleVertices.push_back(currentShape->GetVertexList()[vindices[3*i+2]/3]);
+
+ triangleNormals.push_back(Vec3r(normals[nindices[3*i]],normals[nindices[3*i]+1], normals[nindices[3*i]+2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[3*i+1]],normals[nindices[3*i+1]+1],normals[nindices[3*i+1]+2]));
+ triangleNormals.push_back(Vec3r(normals[nindices[3*i+2]], normals[nindices[3*i+2]+1], normals[nindices[3*i+2]+2]));
+
+ if(texCoords){
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i]],texCoords[tindices[3*i]+1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+1]],texCoords[tindices[3*i+1]+1]));
+ triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+2]], texCoords[tindices[3*i+2]+1]));
+ }
+ }
+ if(mindices)
+ currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, mindices[0]);
+ else
+ currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords,0);
+
+}
+
+void WingedEdgeBuilder::transformVertices(const real *vertices,
+ unsigned vsize,
+ const Matrix44r& transform,
+ real *res) {
+ const real *v = vertices;
+ real *pv = res;
+
+ for (unsigned i = 0; i < vsize / 3; i++) {
+ HVec3r hv_tmp(v[0], v[1], v[2]);
+ HVec3r hv(transform * hv_tmp);
+ for (unsigned j = 0; j < 3; j++)
+ pv[j] = hv[j] / hv[3];
+ v += 3;
+ pv += 3;
+ }
+}
+
+void WingedEdgeBuilder::transformNormals(const real *normals,
+ unsigned nsize,
+ const Matrix44r& transform,
+ real* res) {
+ const real *n = normals;
+ real *pn = res;
+
+ for (unsigned i = 0; i < nsize / 3; i++) {
+ Vec3r hn(n[0], n[1], n[2]);
+ hn = GeomUtils::rotateVector(transform, hn);
+ for (unsigned j = 0; j < 3; j++)
+ pn[j] = hn[j];
+ n += 3;
+ pn += 3;
+ }
+}