Blender  V3.3
WingedEdgeBuilder.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #include <set>
10 
11 #include "WingedEdgeBuilder.h"
12 
13 #include "../geometry/GeomUtils.h"
14 
15 #include "../scene_graph/NodeShape.h"
16 
17 using namespace std;
18 
19 namespace Freestyle {
20 
21 void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet &ifs)
22 {
23  if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
24  return;
25  }
26  WShape *shape = new WShape;
27  if (!buildWShape(*shape, ifs)) {
28  delete shape;
29  return;
30  }
31  shape->setId(ifs.getId().getFirst());
32  // ifs.setId(shape->GetId());
33 }
34 
35 void WingedEdgeBuilder::visitNodeShape(NodeShape &ns)
36 {
37  // Sets the current material to iShapeode->material:
38  _current_frs_material = &(ns.frs_material());
39 }
40 
41 void WingedEdgeBuilder::visitNodeTransform(NodeTransform &tn)
42 {
43  if (!_current_matrix) {
44  _current_matrix = new Matrix44r(tn.matrix());
45  return;
46  }
47 
48  _matrices_stack.push_back(_current_matrix);
49  Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix());
50  _current_matrix = new_matrix;
51 }
52 
53 void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform &UNUSED(transform))
54 {
55  delete _current_matrix;
56 
57  if (_matrices_stack.empty()) {
58  _current_matrix = nullptr;
59  return;
60  }
61 
62  _current_matrix = _matrices_stack.back();
63  _matrices_stack.pop_back();
64 }
65 
66 bool WingedEdgeBuilder::buildWShape(WShape &shape, IndexedFaceSet &ifs)
67 {
68  unsigned int vsize = ifs.vsize();
69  unsigned int nsize = ifs.nsize();
70  // soc unused - unsigned tsize = ifs.tsize();
71 
72  const float *vertices = ifs.vertices();
73  const float *normals = ifs.normals();
74  const float *texCoords = ifs.texCoords();
75 
76  float *new_vertices;
77  float *new_normals;
78 
79  new_vertices = new float[vsize];
80  new_normals = new float[nsize];
81 
82  // transform coordinates from local to world system
83  if (_current_matrix) {
84  transformVertices(vertices, vsize, *_current_matrix, new_vertices);
85  transformNormals(normals, nsize, *_current_matrix, new_normals);
86  }
87  else {
88  memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices));
89  memcpy(new_normals, normals, nsize * sizeof(*new_normals));
90  }
91 
92  const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle();
93 
94  vector<FrsMaterial> frs_materials;
95  if (ifs.msize()) {
96  const FrsMaterial *const *mats = ifs.frs_materials();
97  for (unsigned i = 0; i < ifs.msize(); ++i) {
98  frs_materials.push_back(*(mats[i]));
99  }
100  shape.setFrsMaterials(frs_materials);
101  }
102 
103 #if 0
104  const FrsMaterial *mat = (ifs.frs_material());
105  if (mat) {
106  shape.setFrsMaterial(*mat);
107  }
108  else if (_current_frs_material) {
109  shape.setFrsMaterial(*_current_frs_material);
110  }
111 #endif
112  const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();
113 
114  // sets the current WShape to shape
115  _current_wshape = &shape;
116 
117  // create a WVertex for each vertex
118  buildWVertices(shape, new_vertices, vsize);
119 
120  const unsigned int *vindices = ifs.vindices();
121  const unsigned int *nindices = ifs.nindices();
122  const unsigned int *tindices = nullptr;
123  if (ifs.tsize()) {
124  tindices = ifs.tindices();
125  }
126 
127  const unsigned int *mindices = nullptr;
128  if (ifs.msize()) {
129  mindices = ifs.mindices();
130  }
131  const unsigned int *numVertexPerFace = ifs.numVertexPerFaces();
132  const unsigned int numfaces = ifs.numFaces();
133 
134  for (unsigned int index = 0; index < numfaces; index++) {
135  switch (faceStyle[index]) {
136  case IndexedFaceSet::TRIANGLE_STRIP:
137  buildTriangleStrip(new_vertices,
138  new_normals,
139  frs_materials,
140  texCoords,
141  faceEdgeMarks,
142  vindices,
143  nindices,
144  mindices,
145  tindices,
146  numVertexPerFace[index]);
147  break;
148  case IndexedFaceSet::TRIANGLE_FAN:
149  buildTriangleFan(new_vertices,
150  new_normals,
151  frs_materials,
152  texCoords,
153  faceEdgeMarks,
154  vindices,
155  nindices,
156  mindices,
157  tindices,
158  numVertexPerFace[index]);
159  break;
160  case IndexedFaceSet::TRIANGLES:
161  buildTriangles(new_vertices,
162  new_normals,
163  frs_materials,
164  texCoords,
165  faceEdgeMarks,
166  vindices,
167  nindices,
168  mindices,
169  tindices,
170  numVertexPerFace[index]);
171  break;
172  }
173  vindices += numVertexPerFace[index];
174  nindices += numVertexPerFace[index];
175  if (mindices) {
176  mindices += numVertexPerFace[index];
177  }
178  if (tindices) {
179  tindices += numVertexPerFace[index];
180  }
181  faceEdgeMarks++;
182  }
183 
184  delete[] new_vertices;
185  delete[] new_normals;
186 
187  if (shape.GetFaceList().empty()) { // this may happen due to degenerate triangles
188  return false;
189  }
190 
191 #if 0
192  // compute bbox
193  shape.ComputeBBox();
194  // compute mean edge size:
195  shape.ComputeMeanEdgeSize();
196 #endif
197 
198  // Parse the built winged-edge shape to update post-flags
199  set<Vec3f> normalsSet;
200  vector<WVertex *> &wvertices = shape.getVertexList();
201  for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend;
202  ++wv) {
203  if ((*wv)->isBoundary()) {
204  continue;
205  }
206  if ((*wv)->GetEdges().empty()) {
207  // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
208  continue;
209  }
210  normalsSet.clear();
211  WVertex::face_iterator fit = (*wv)->faces_begin();
212  WVertex::face_iterator fitend = (*wv)->faces_end();
213  for (; fit != fitend; ++fit) {
214  WFace *face = *fit;
215  normalsSet.insert(face->GetVertexNormal(*wv));
216  if (normalsSet.size() != 1) {
217  break;
218  }
219  }
220  if (normalsSet.size() != 1) {
221  (*wv)->setSmooth(false);
222  }
223  }
224 
225  // Adds the new WShape to the WingedEdge structure
226  _winged_edge->addWShape(&shape);
227 
228  return true;
229 }
230 
231 void WingedEdgeBuilder::buildWVertices(WShape &shape, const float *vertices, unsigned vsize)
232 {
233  WVertex *vertex;
234  for (unsigned int i = 0; i < vsize; i += 3) {
235  vertex = new WVertex(Vec3f(vertices[i], vertices[i + 1], vertices[i + 2]));
236  vertex->setId(i / 3);
237  shape.AddVertex(vertex);
238  }
239 }
240 
241 void WingedEdgeBuilder::buildTriangleStrip(const float * /*vertices*/,
242  const float *normals,
243  vector<FrsMaterial> & /*iMaterials*/,
244  const float *texCoords,
245  const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
246  const unsigned *vindices,
247  const unsigned *nindices,
248  const unsigned *mindices,
249  const unsigned *tindices,
250  const unsigned nvertices)
251 {
252  unsigned nDoneVertices = 2; // number of vertices already treated
253  unsigned nTriangle = 0; // number of the triangle currently being treated
254  // int nVertex = 0; // vertex number
255 
256  WShape *currentShape = _current_wshape; // the current shape being built
257  vector<WVertex *> triangleVertices;
258  vector<Vec3f> triangleNormals;
259  vector<Vec2f> triangleTexCoords;
260  vector<bool> triangleFaceEdgeMarks;
261 
262  while (nDoneVertices < nvertices) {
263  // clear the vertices list:
264  triangleVertices.clear();
265  // Then rebuild it:
266  if (0 == nTriangle % 2) { // if nTriangle is even
267  triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
268  triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
269  triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
270 
271  triangleNormals.emplace_back(normals[nindices[nTriangle]],
272  normals[nindices[nTriangle] + 1],
273  normals[nindices[nTriangle] + 2]);
274  triangleNormals.emplace_back(normals[nindices[nTriangle + 1]],
275  normals[nindices[nTriangle + 1] + 1],
276  normals[nindices[nTriangle + 1] + 2]);
277  triangleNormals.emplace_back(normals[nindices[nTriangle + 2]],
278  normals[nindices[nTriangle + 2] + 1],
279  normals[nindices[nTriangle + 2] + 2]);
280 
281  if (texCoords) {
282  triangleTexCoords.emplace_back(texCoords[tindices[nTriangle]],
283  texCoords[tindices[nTriangle] + 1]);
284  triangleTexCoords.emplace_back(texCoords[tindices[nTriangle + 1]],
285  texCoords[tindices[nTriangle + 1] + 1]);
286  triangleTexCoords.emplace_back(texCoords[tindices[nTriangle + 2]],
287  texCoords[tindices[nTriangle + 2] + 1]);
288  }
289  }
290  else { // if nTriangle is odd
291  triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
292  triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
293  triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
294 
295  triangleNormals.emplace_back(normals[nindices[nTriangle]],
296  normals[nindices[nTriangle] + 1],
297  normals[nindices[nTriangle] + 2]);
298  triangleNormals.emplace_back(normals[nindices[nTriangle + 2]],
299  normals[nindices[nTriangle + 2] + 1],
300  normals[nindices[nTriangle + 2] + 2]);
301  triangleNormals.emplace_back(normals[nindices[nTriangle + 1]],
302  normals[nindices[nTriangle + 1] + 1],
303  normals[nindices[nTriangle + 1] + 2]);
304 
305  if (texCoords) {
306  triangleTexCoords.emplace_back(texCoords[tindices[nTriangle]],
307  texCoords[tindices[nTriangle] + 1]);
308  triangleTexCoords.emplace_back(texCoords[tindices[nTriangle + 2]],
309  texCoords[tindices[nTriangle + 2] + 1]);
310  triangleTexCoords.emplace_back(texCoords[tindices[nTriangle + 1]],
311  texCoords[tindices[nTriangle + 1] + 1]);
312  }
313  }
314  triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) !=
315  0);
316  triangleFaceEdgeMarks.push_back(
317  (iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
318  triangleFaceEdgeMarks.push_back(
319  (iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
320  triangleFaceEdgeMarks.push_back(
321  (iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
322  if (mindices) {
323  currentShape->MakeFace(triangleVertices,
324  triangleNormals,
325  triangleTexCoords,
326  triangleFaceEdgeMarks,
327  mindices[nTriangle / 3]);
328  }
329  else {
330  currentShape->MakeFace(
331  triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
332  }
333  nDoneVertices++; // with a strip, each triangle is one vertex more
334  nTriangle++;
335  }
336 }
337 
338 void WingedEdgeBuilder::buildTriangleFan(const float * /*vertices*/,
339  const float * /*normals*/,
340  vector<FrsMaterial> & /*iMaterials*/,
341  const float * /*texCoords*/,
342  const IndexedFaceSet::FaceEdgeMark * /*iFaceEdgeMarks*/,
343  const unsigned * /*vindices*/,
344  const unsigned * /*nindices*/,
345  const unsigned * /*mindices*/,
346  const unsigned * /*tindices*/,
347  const unsigned /*nvertices*/)
348 {
349  // Nothing to be done
350 }
351 
352 void WingedEdgeBuilder::buildTriangles(const float * /*vertices*/,
353  const float *normals,
354  vector<FrsMaterial> & /*iMaterials*/,
355  const float *texCoords,
356  const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
357  const unsigned *vindices,
358  const unsigned *nindices,
359  const unsigned *mindices,
360  const unsigned *tindices,
361  const unsigned nvertices)
362 {
363  WShape *currentShape = _current_wshape; // the current shape begin built
364  vector<WVertex *> triangleVertices;
365  vector<Vec3f> triangleNormals;
366  vector<Vec2f> triangleTexCoords;
367  vector<bool> triangleFaceEdgeMarks;
368 
369  // Each triplet of vertices is considered as an independent triangle
370  for (unsigned int i = 0; i < nvertices / 3; i++) {
371  triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]);
372  triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]);
373  triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]);
374 
375  triangleNormals.emplace_back(
376  normals[nindices[3 * i]], normals[nindices[3 * i] + 1], normals[nindices[3 * i] + 2]);
377  triangleNormals.emplace_back(normals[nindices[3 * i + 1]],
378  normals[nindices[3 * i + 1] + 1],
379  normals[nindices[3 * i + 1] + 2]);
380  triangleNormals.emplace_back(normals[nindices[3 * i + 2]],
381  normals[nindices[3 * i + 2] + 1],
382  normals[nindices[3 * i + 2] + 2]);
383 
384  if (texCoords) {
385  triangleTexCoords.emplace_back(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1]);
386  triangleTexCoords.emplace_back(texCoords[tindices[3 * i + 1]],
387  texCoords[tindices[3 * i + 1] + 1]);
388  triangleTexCoords.emplace_back(texCoords[tindices[3 * i + 2]],
389  texCoords[tindices[3 * i + 2] + 1]);
390  }
391 
392  triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
393  triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
394  triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
395  triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
396  }
397  if (mindices) {
398  currentShape->MakeFace(
399  triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]);
400  }
401  else {
402  currentShape->MakeFace(
403  triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
404  }
405 }
406 
407 void WingedEdgeBuilder::transformVertices(const float *vertices,
408  unsigned vsize,
409  const Matrix44r &transform,
410  float *res)
411 {
412  const float *v = vertices;
413  float *pv = res;
414 
415  for (unsigned int i = 0; i < vsize / 3; i++) {
416  HVec3r hv_tmp(v[0], v[1], v[2]);
417  HVec3r hv(transform * hv_tmp);
418  for (unsigned int j = 0; j < 3; j++) {
419  pv[j] = hv[j] / hv[3];
420  }
421  v += 3;
422  pv += 3;
423  }
424 }
425 
426 void WingedEdgeBuilder::transformNormals(const float *normals,
427  unsigned nsize,
428  const Matrix44r &transform,
429  float *res)
430 {
431  const float *n = normals;
432  float *pn = res;
433 
434  for (unsigned int i = 0; i < nsize / 3; i++) {
435  Vec3r hn(n[0], n[1], n[2]);
437  for (unsigned int j = 0; j < 3; j++) {
438  pn[j] = hn[j];
439  }
440  n += 3;
441  pn += 3;
442  }
443 }
444 
445 } /* namespace Freestyle */
#define UNUSED(x)
Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes of a ...
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define FACE_MARK
Definition: bmo_beautify.c:19
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
virtual const unsigned * nindices() const
virtual const FrsMaterial *const * frs_materials() const
virtual const float * normals() const
virtual const unsigned vsize() const
virtual const float * texCoords() const
virtual const unsigned char * faceEdgeMarks() const
virtual const unsigned numFaces() const
virtual const unsigned * vindices() const
virtual const unsigned * mindices() const
virtual const unsigned tsize() const
virtual const unsigned * numVertexPerFaces() const
virtual const unsigned nsize() const
virtual const unsigned * tindices() const
virtual const float * vertices() const
virtual const TRIANGLES_STYLE * trianglesStyle() const
virtual const unsigned msize() const
const FrsMaterial * frs_material() const
Definition: Rep.h:129
Vec3f & GetVertexNormal(int index)
Definition: WEdge.h:825
void setFrsMaterials(const vector< FrsMaterial > &iMaterials)
Definition: WEdge.h:1139
real ComputeMeanEdgeSize() const
Definition: WEdge.cpp:709
virtual WFace * MakeFace(vector< WVertex * > &iVertexList, vector< bool > &iFaceEdgeMarksList, unsigned iMaterialIndex)
Definition: WEdge.cpp:586
void AddVertex(WVertex *iVertex)
Definition: WEdge.h:1200
vector< WVertex * > & getVertexList()
Definition: WEdge.h:1050
void setFrsMaterial(const FrsMaterial &frs_material, unsigned i)
Definition: WEdge.h:1134
vector< WFace * > & GetFaceList()
Definition: WEdge.h:1055
void setId(int id)
Definition: WEdge.h:111
struct Vec3f Vec3f
void transformVertices(const vector< Vec3r > &vertices, const Matrix44r &trans, vector< Vec3r > &res)
Definition: GeomUtils.cpp:622
Vec3r rotateVector(const Matrix44r &mat, const Vec3r &v)
Definition: GeomUtils.cpp:631
VecMat::SquareMatrix< real, 4 > Matrix44r
Definition: Geom.h:52
VecMat::HVec3< real > HVec3r
Definition: Geom.h:34
VecMat::Vec3< real > Vec3r
Definition: Geom.h:28
inherits from class Rep
Definition: AppCanvas.cpp:18
MutableSpan< float3 > normals