Blender  V2.93
BlenderFileLoader.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include "BlenderFileLoader.h"
22 
23 #include "BLI_utildefines.h"
24 
25 #include "BKE_global.h"
26 #include "BKE_object.h"
27 
28 #include <sstream>
29 
30 namespace Freestyle {
31 
33 {
34  _re = re;
36  _Scene = nullptr;
37  _numFacesRead = 0;
38 #if 0
39  _minEdgeSize = DBL_MAX;
40 #endif
42  _pRenderMonitor = nullptr;
43 }
44 
46 {
47  _Scene = nullptr;
48 }
49 
51 {
52  if (G.debug & G_DEBUG_FREESTYLE) {
53  cout << "\n=== Importing triangular meshes into Blender ===" << endl;
54  }
55 
56  // creation of the scene root node
57  _Scene = new NodeGroup;
58 
59  if (_re->clip_start < 0.0f) {
60  // Adjust clipping start/end and set up a Z offset when the viewport preview
61  // is used with the orthographic view. In this case, _re->clip_start is negative,
62  // while Freestyle assumes that imported mesh data are in the camera coordinate
63  // system with the view point located at origin [bug T36009].
64  _z_near = -0.001f;
67  }
68  else {
70  _z_far = -_re->clip_end;
71  _z_offset = 0.0f;
72  }
73 
74  int id = 0;
75  const eEvaluationMode eval_mode = DEG_get_mode(_depsgraph);
76 
78  ob,
83  break;
84  }
85 
86  if (ob->base_flag & (BASE_HOLDOUT | BASE_INDIRECT_ONLY)) {
87  continue;
88  }
89 
90  if (!(BKE_object_visibility(ob, eval_mode) & OB_VISIBLE_SELF)) {
91  continue;
92  }
93 
94  Mesh *mesh = BKE_object_to_mesh(nullptr, ob, false);
95 
96  if (mesh) {
97  insertShapeNode(ob, mesh, ++id);
99  }
100  }
102 
103  // Return the built scene.
104  return _Scene;
105 }
106 
107 #define CLIPPED_BY_NEAR -1
108 #define NOT_CLIPPED 0
109 #define CLIPPED_BY_FAR 1
110 
111 // check if each vertex of a triangle (V1, V2, V3) is clipped by the near/far plane
112 // and calculate the number of triangles to be generated by clipping
113 int BlenderFileLoader::countClippedFaces(float v1[3], float v2[3], float v3[3], int clip[3])
114 {
115  float *v[3];
116  int numClipped, sum, numTris = 0;
117 
118  v[0] = v1;
119  v[1] = v2;
120  v[2] = v3;
121  numClipped = sum = 0;
122  for (int i = 0; i < 3; i++) {
123  if (v[i][2] > _z_near) {
124  clip[i] = CLIPPED_BY_NEAR;
125  numClipped++;
126  }
127  else if (v[i][2] < _z_far) {
128  clip[i] = CLIPPED_BY_FAR;
129  numClipped++;
130  }
131  else {
132  clip[i] = NOT_CLIPPED;
133  }
134 #if 0
135  if (G.debug & G_DEBUG_FREESTYLE) {
136  printf("%d %s\n",
137  i,
138  (clip[i] == NOT_CLIPPED) ? "not" : (clip[i] == CLIPPED_BY_NEAR) ? "near" : "far");
139  }
140 #endif
141  sum += clip[i];
142  }
143  switch (numClipped) {
144  case 0:
145  numTris = 1; // triangle
146  break;
147  case 1:
148  numTris = 2; // tetragon
149  break;
150  case 2:
151  if (sum == 0) {
152  numTris = 3; // pentagon
153  }
154  else {
155  numTris = 1; // triangle
156  }
157  break;
158  case 3:
159  if (ELEM(sum, 3, -3)) {
160  numTris = 0;
161  }
162  else {
163  numTris = 2; // tetragon
164  }
165  break;
166  }
167  return numTris;
168 }
169 
170 // find the intersection point C between the line segment from V1 to V2 and
171 // a clipping plane at depth Z (i.e., the Z component of C is known, while
172 // the X and Y components are unknown).
173 void BlenderFileLoader::clipLine(float v1[3], float v2[3], float c[3], float z)
174 {
175  // Order v1 and v2 by Z values to make sure that clipLine(P, Q, c, z)
176  // and clipLine(Q, P, c, z) gives exactly the same numerical result.
177  float *p, *q;
178  if (v1[2] < v2[2]) {
179  p = v1;
180  q = v2;
181  }
182  else {
183  p = v2;
184  q = v1;
185  }
186  double d[3];
187  for (int i = 0; i < 3; i++) {
188  d[i] = q[i] - p[i];
189  }
190  double t = (z - p[2]) / d[2];
191  c[0] = p[0] + t * d[0];
192  c[1] = p[1] + t * d[1];
193  c[2] = z;
194 }
195 
196 // clip the triangle (V1, V2, V3) by the near and far clipping plane and
197 // obtain a set of vertices after the clipping. The number of vertices
198 // is at most 5.
200  float triCoords[][3],
201  float v1[3],
202  float v2[3],
203  float v3[3],
204  float triNormals[][3],
205  float n1[3],
206  float n2[3],
207  float n3[3],
208  bool edgeMarks[],
209  bool em1,
210  bool em2,
211  bool em3,
212  const int clip[3])
213 {
214  float *v[3], *n[3];
215  bool em[3];
216  int i, j, k;
217 
218  v[0] = v1;
219  n[0] = n1;
220  v[1] = v2;
221  n[1] = n2;
222  v[2] = v3;
223  n[2] = n3;
224  em[0] = em1; /* edge mark of the edge between v1 and v2 */
225  em[1] = em2; /* edge mark of the edge between v2 and v3 */
226  em[2] = em3; /* edge mark of the edge between v3 and v1 */
227  k = 0;
228  for (i = 0; i < 3; i++) {
229  j = (i + 1) % 3;
230  if (clip[i] == NOT_CLIPPED) {
231  copy_v3_v3(triCoords[k], v[i]);
232  copy_v3_v3(triNormals[k], n[i]);
233  edgeMarks[k] = em[i];
234  k++;
235  if (clip[j] != NOT_CLIPPED) {
236  clipLine(v[i], v[j], triCoords[k], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far);
237  copy_v3_v3(triNormals[k], n[j]);
238  edgeMarks[k] = false;
239  k++;
240  }
241  }
242  else if (clip[i] != clip[j]) {
243  if (clip[j] == NOT_CLIPPED) {
244  clipLine(v[i], v[j], triCoords[k], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far);
245  copy_v3_v3(triNormals[k], n[i]);
246  edgeMarks[k] = em[i];
247  k++;
248  }
249  else {
250  clipLine(v[i], v[j], triCoords[k], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far);
251  copy_v3_v3(triNormals[k], n[i]);
252  edgeMarks[k] = em[i];
253  k++;
254  clipLine(v[i], v[j], triCoords[k], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far);
255  copy_v3_v3(triNormals[k], n[j]);
256  edgeMarks[k] = false;
257  k++;
258  }
259  }
260  }
261  BLI_assert(k == 2 + numTris);
262  (void)numTris; /* Ignored in release builds. */
263 }
264 
266  float v1[3],
267  float v2[3],
268  float v3[3],
269  float n1[3],
270  float n2[3],
271  float n3[3],
272  bool fm,
273  bool em1,
274  bool em2,
275  bool em3)
276 {
277  float *fv[3], *fn[3];
278 #if 0
279  float len;
280 #endif
281  unsigned int i, j;
283 
284  // initialize the bounding box by the first vertex
285  if (ls->currentIndex == 0) {
286  copy_v3_v3(ls->minBBox, v1);
287  copy_v3_v3(ls->maxBBox, v1);
288  }
289 
290  fv[0] = v1;
291  fn[0] = n1;
292  fv[1] = v2;
293  fn[1] = n2;
294  fv[2] = v3;
295  fn[2] = n3;
296  for (i = 0; i < 3; i++) {
297 
298  copy_v3_v3(ls->pv, fv[i]);
299  copy_v3_v3(ls->pn, fn[i]);
300 
301  // update the bounding box
302  for (j = 0; j < 3; j++) {
303  if (ls->minBBox[j] > ls->pv[j]) {
304  ls->minBBox[j] = ls->pv[j];
305  }
306 
307  if (ls->maxBBox[j] < ls->pv[j]) {
308  ls->maxBBox[j] = ls->pv[j];
309  }
310  }
311 
312 #if 0
313  len = len_v3v3(fv[i], fv[(i + 1) % 3]);
314  if (_minEdgeSize > len) {
315  _minEdgeSize = len;
316  }
317 #endif
318 
319  *ls->pvi = ls->currentIndex;
320  *ls->pni = ls->currentIndex;
321  *ls->pmi = ls->currentMIndex;
322 
323  ls->currentIndex += 3;
324  ls->pv += 3;
325  ls->pn += 3;
326 
327  ls->pvi++;
328  ls->pni++;
329  ls->pmi++;
330  }
331 
332  if (fm) {
333  marks |= IndexedFaceSet::FACE_MARK;
334  }
335  if (em1) {
337  }
338  if (em2) {
340  }
341  if (em3) {
343  }
344  *(ls->pm++) = marks;
345 }
346 
347 // With A, B and P indicating the three vertices of a given triangle, returns:
348 // 1 if points A and B are in the same position in the 3D space;
349 // 2 if the distance between point P and line segment AB is zero; and
350 // zero otherwise.
351 int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3[3])
352 {
353  const float eps = 1.0e-6;
354  const float eps_sq = eps * eps;
355 
356 #if 0
357  float area = area_tri_v3(v1, v2, v3);
358  bool verbose = (area < 1.0e-6);
359 #endif
360 
361  if (equals_v3v3(v1, v2) || equals_v3v3(v2, v3) || equals_v3v3(v1, v3)) {
362 #if 0
363  if (verbose && G.debug & G_DEBUG_FREESTYLE) {
364  printf("BlenderFileLoader::testDegenerateTriangle = 1\n");
365  }
366 #endif
367  return 1;
368  }
369  if (dist_squared_to_line_segment_v3(v1, v2, v3) < eps_sq ||
370  dist_squared_to_line_segment_v3(v2, v1, v3) < eps_sq ||
371  dist_squared_to_line_segment_v3(v3, v1, v2) < eps_sq) {
372 #if 0
373  if (verbose && G.debug & G_DEBUG_FREESTYLE) {
374  printf("BlenderFileLoader::testDegenerateTriangle = 2\n");
375  }
376 #endif
377  return 2;
378  }
379 #if 0
380  if (verbose && G.debug & G_DEBUG_FREESTYLE) {
381  printf("BlenderFileLoader::testDegenerateTriangle = 0\n");
382  }
383 #endif
384  return 0;
385 }
386 
387 static bool testEdgeMark(Mesh *me, FreestyleEdge *fed, const MLoopTri *lt, int i)
388 {
389  MLoop *mloop = &me->mloop[lt->tri[i]];
390  MLoop *mloop_next = &me->mloop[lt->tri[(i + 1) % 3]];
391  MEdge *medge = &me->medge[mloop->e];
392 
393  if (!ELEM(mloop_next->v, medge->v1, medge->v2)) {
394  /* Not an edge in the original mesh before triangulation. */
395  return false;
396  }
397 
398  return (fed[mloop->e].flag & FREESTYLE_EDGE_MARK) != 0;
399 }
400 
402 {
403  char *name = ob->id.name + 2;
404 
405  // Compute loop triangles
406  int tottri = poly_to_tri_count(me->totpoly, me->totloop);
407  MLoopTri *mlooptri = (MLoopTri *)MEM_malloc_arrayN(tottri, sizeof(*mlooptri), __func__);
408  BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri);
409 
410  // Compute loop normals
412  float(*lnors)[3] = nullptr;
413 
414  if (CustomData_has_layer(&me->ldata, CD_NORMAL)) {
415  lnors = (float(*)[3])CustomData_get_layer(&me->ldata, CD_NORMAL);
416  }
417 
418  // Get other mesh data
419  MVert *mvert = me->mvert;
420  MLoop *mloop = me->mloop;
421  MPoly *mpoly = me->mpoly;
424 
425  // Compute view matrix
427  float viewinv[4][4], viewmat[4][4];
428  RE_GetCameraModelMatrix(_re, ob_camera_eval, viewinv);
429  invert_m4_m4(viewmat, viewinv);
430 
431  // Compute matrix including camera transform
432  float obmat[4][4], nmat[4][4];
433  mul_m4_m4m4(obmat, viewmat, ob->obmat);
434  invert_m4_m4(nmat, obmat);
435  transpose_m4(nmat);
436 
437  // We count the number of triangles after the clipping by the near and far view
438  // planes is applied (Note: mesh vertices are in the camera coordinate system).
439  unsigned numFaces = 0;
440  float v1[3], v2[3], v3[3];
441  float n1[3], n2[3], n3[3], facenormal[3];
442  int clip[3];
443  for (int a = 0; a < tottri; a++) {
444  const MLoopTri *lt = &mlooptri[a];
445 
446  copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co);
447  copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co);
448  copy_v3_v3(v3, mvert[mloop[lt->tri[2]].v].co);
449 
450  mul_m4_v3(obmat, v1);
451  mul_m4_v3(obmat, v2);
452  mul_m4_v3(obmat, v3);
453 
454  v1[2] += _z_offset;
455  v2[2] += _z_offset;
456  v3[2] += _z_offset;
457 
458  numFaces += countClippedFaces(v1, v2, v3, clip);
459  }
460 #if 0
461  if (G.debug & G_DEBUG_FREESTYLE) {
462  cout << "numFaces " << numFaces << endl;
463  }
464 #endif
465  if (numFaces == 0) {
466  MEM_freeN(mlooptri);
467  return;
468  }
469 
470  // We allocate memory for the meshes to be imported
471  NodeGroup *currentMesh = new NodeGroup;
472  NodeShape *shape = new NodeShape;
473 
474  unsigned vSize = 3 * 3 * numFaces;
475  float *vertices = new float[vSize];
476  unsigned nSize = vSize;
477  float *normals = new float[nSize];
478  unsigned *numVertexPerFaces = new unsigned[numFaces];
479  vector<Material *> meshMaterials;
480  vector<FrsMaterial> meshFrsMaterials;
481 
483  unsigned i;
484  for (i = 0; i < numFaces; i++) {
485  faceStyle[i] = IndexedFaceSet::TRIANGLES;
486  numVertexPerFaces[i] = 3;
487  }
488 
489  IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = new IndexedFaceSet::FaceEdgeMark[numFaces];
490 
491  unsigned viSize = 3 * numFaces;
492  unsigned *VIndices = new unsigned[viSize];
493  unsigned niSize = viSize;
494  unsigned *NIndices = new unsigned[niSize];
495  unsigned *MIndices = new unsigned[viSize]; // Material Indices
496 
497  struct LoaderState ls;
498  ls.pv = vertices;
499  ls.pn = normals;
500  ls.pm = faceEdgeMarks;
501  ls.pvi = VIndices;
502  ls.pni = NIndices;
503  ls.pmi = MIndices;
504  ls.currentIndex = 0;
505  ls.currentMIndex = 0;
506 
507  FrsMaterial tmpMat;
508 
509  // We parse the vlak nodes again and import meshes while applying the clipping
510  // by the near and far view planes.
511  for (int a = 0; a < tottri; a++) {
512  const MLoopTri *lt = &mlooptri[a];
513  const MPoly *mp = &mpoly[lt->poly];
514  Material *mat = BKE_object_material_get(ob, mp->mat_nr + 1);
515 
516  copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co);
517  copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co);
518  copy_v3_v3(v3, mvert[mloop[lt->tri[2]].v].co);
519 
520  mul_m4_v3(obmat, v1);
521  mul_m4_v3(obmat, v2);
522  mul_m4_v3(obmat, v3);
523 
524  v1[2] += _z_offset;
525  v2[2] += _z_offset;
526  v3[2] += _z_offset;
527 
528  if (_smooth && (mp->flag & ME_SMOOTH) && lnors) {
529  copy_v3_v3(n1, lnors[lt->tri[0]]);
530  copy_v3_v3(n2, lnors[lt->tri[1]]);
531  copy_v3_v3(n3, lnors[lt->tri[2]]);
532 
533  mul_mat3_m4_v3(nmat, n1);
534  mul_mat3_m4_v3(nmat, n2);
535  mul_mat3_m4_v3(nmat, n3);
536 
537  normalize_v3(n1);
538  normalize_v3(n2);
539  normalize_v3(n3);
540  }
541  else {
542  normal_tri_v3(facenormal, v3, v2, v1);
543 
544  copy_v3_v3(n1, facenormal);
545  copy_v3_v3(n2, facenormal);
546  copy_v3_v3(n3, facenormal);
547  }
548 
549  unsigned int numTris = countClippedFaces(v1, v2, v3, clip);
550  if (numTris == 0) {
551  continue;
552  }
553 
554  bool fm = (ffa) ? (ffa[lt->poly].flag & FREESTYLE_FACE_MARK) != 0 : false;
555  bool em1 = false, em2 = false, em3 = false;
556 
557  if (fed) {
558  em1 = testEdgeMark(me, fed, lt, 0);
559  em2 = testEdgeMark(me, fed, lt, 1);
560  em3 = testEdgeMark(me, fed, lt, 2);
561  }
562 
563  if (mat) {
564  tmpMat.setLine(mat->line_col[0], mat->line_col[1], mat->line_col[2], mat->line_col[3]);
565  tmpMat.setDiffuse(mat->r, mat->g, mat->b, 1.0f);
566  tmpMat.setSpecular(mat->specr, mat->specg, mat->specb, 1.0f);
567  tmpMat.setShininess(128.0f);
568  tmpMat.setPriority(mat->line_priority);
569  }
570 
571  if (meshMaterials.empty()) {
572  meshMaterials.push_back(mat);
573  meshFrsMaterials.push_back(tmpMat);
574  shape->setFrsMaterial(tmpMat);
575  }
576  else {
577  // find if the Blender material is already in the list
578  unsigned int i = 0;
579  bool found = false;
580 
581  for (vector<Material *>::iterator it = meshMaterials.begin(), itend = meshMaterials.end();
582  it != itend;
583  it++, i++) {
584  if (*it == mat) {
585  ls.currentMIndex = i;
586  found = true;
587  break;
588  }
589  }
590 
591  if (!found) {
592  meshMaterials.push_back(mat);
593  meshFrsMaterials.push_back(tmpMat);
594  ls.currentMIndex = meshFrsMaterials.size() - 1;
595  }
596  }
597 
598  float triCoords[5][3], triNormals[5][3];
599  bool edgeMarks[5]; // edgeMarks[i] is for the edge between i-th and (i+1)-th vertices
600 
601  clipTriangle(
602  numTris, triCoords, v1, v2, v3, triNormals, n1, n2, n3, edgeMarks, em1, em2, em3, clip);
603  for (i = 0; i < numTris; i++) {
604  addTriangle(&ls,
605  triCoords[0],
606  triCoords[i + 1],
607  triCoords[i + 2],
608  triNormals[0],
609  triNormals[i + 1],
610  triNormals[i + 2],
611  fm,
612  (i == 0) ? edgeMarks[0] : false,
613  edgeMarks[i + 1],
614  (i == numTris - 1) ? edgeMarks[i + 2] : false);
615  _numFacesRead++;
616  }
617  }
618 
619  MEM_freeN(mlooptri);
620 
621  // We might have several times the same vertex. We want a clean
622  // shape with no real-vertex. Here, we are making a cleaning pass.
623  float *cleanVertices = nullptr;
624  unsigned int cvSize;
625  unsigned int *cleanVIndices = nullptr;
626 
628  vertices, vSize, VIndices, viSize, &cleanVertices, &cvSize, &cleanVIndices);
629 
630  float *cleanNormals = nullptr;
631  unsigned int cnSize;
632  unsigned int *cleanNIndices = nullptr;
633 
635  normals, nSize, NIndices, niSize, &cleanNormals, &cnSize, &cleanNIndices);
636 
637  // format materials array
638  FrsMaterial **marray = new FrsMaterial *[meshFrsMaterials.size()];
639  unsigned int mindex = 0;
640  for (vector<FrsMaterial>::iterator m = meshFrsMaterials.begin(), mend = meshFrsMaterials.end();
641  m != mend;
642  ++m) {
643  marray[mindex] = new FrsMaterial(*m);
644  ++mindex;
645  }
646 
647  // deallocates memory:
648  delete[] vertices;
649  delete[] normals;
650  delete[] VIndices;
651  delete[] NIndices;
652 
653  // Fix for degenerated triangles
654  // A degenerate triangle is a triangle such that
655  // 1) A and B are in the same position in the 3D space; or
656  // 2) the distance between point P and line segment AB is zero.
657  // Only those degenerate triangles in the second form are resolved here
658  // by adding a small offset to P, whereas those in the first form are
659  // addressed later in WShape::MakeFace().
660  vector<detri_t> detriList;
661  Vec3r zero(0.0, 0.0, 0.0);
662  unsigned vi0, vi1, vi2;
663  for (i = 0; i < viSize; i += 3) {
664  detri_t detri;
665  vi0 = cleanVIndices[i];
666  vi1 = cleanVIndices[i + 1];
667  vi2 = cleanVIndices[i + 2];
668  Vec3r v0(cleanVertices[vi0], cleanVertices[vi0 + 1], cleanVertices[vi0 + 2]);
669  Vec3r v1(cleanVertices[vi1], cleanVertices[vi1 + 1], cleanVertices[vi1 + 2]);
670  Vec3r v2(cleanVertices[vi2], cleanVertices[vi2 + 1], cleanVertices[vi2 + 2]);
671  if (v0 == v1 || v0 == v2 || v1 == v2) {
672  continue; // do nothing for now
673  }
674  if (GeomUtils::distPointSegment<Vec3r>(v0, v1, v2) < 1.0e-6) {
675  detri.viP = vi0;
676  detri.viA = vi1;
677  detri.viB = vi2;
678  }
679  else if (GeomUtils::distPointSegment<Vec3r>(v1, v0, v2) < 1.0e-6) {
680  detri.viP = vi1;
681  detri.viA = vi0;
682  detri.viB = vi2;
683  }
684  else if (GeomUtils::distPointSegment<Vec3r>(v2, v0, v1) < 1.0e-6) {
685  detri.viP = vi2;
686  detri.viA = vi0;
687  detri.viB = vi1;
688  }
689  else {
690  continue;
691  }
692 
693  detri.v = zero;
694  detri.n = 0;
695  for (unsigned int j = 0; j < viSize; j += 3) {
696  if (i == j) {
697  continue;
698  }
699  vi0 = cleanVIndices[j];
700  vi1 = cleanVIndices[j + 1];
701  vi2 = cleanVIndices[j + 2];
702  Vec3r v0(cleanVertices[vi0], cleanVertices[vi0 + 1], cleanVertices[vi0 + 2]);
703  Vec3r v1(cleanVertices[vi1], cleanVertices[vi1 + 1], cleanVertices[vi1 + 2]);
704  Vec3r v2(cleanVertices[vi2], cleanVertices[vi2 + 1], cleanVertices[vi2 + 2]);
705  if (detri.viP == vi0 && (detri.viA == vi1 || detri.viB == vi1)) {
706  detri.v += (v2 - v0);
707  detri.n++;
708  }
709  else if (detri.viP == vi0 && (detri.viA == vi2 || detri.viB == vi2)) {
710  detri.v += (v1 - v0);
711  detri.n++;
712  }
713  else if (detri.viP == vi1 && (detri.viA == vi0 || detri.viB == vi0)) {
714  detri.v += (v2 - v1);
715  detri.n++;
716  }
717  else if (detri.viP == vi1 && (detri.viA == vi2 || detri.viB == vi2)) {
718  detri.v += (v0 - v1);
719  detri.n++;
720  }
721  else if (detri.viP == vi2 && (detri.viA == vi0 || detri.viB == vi0)) {
722  detri.v += (v1 - v2);
723  detri.n++;
724  }
725  else if (detri.viP == vi2 && (detri.viA == vi1 || detri.viB == vi1)) {
726  detri.v += (v0 - v2);
727  detri.n++;
728  }
729  }
730  if (detri.n > 0) {
731  detri.v.normalizeSafe();
732  }
733  detriList.push_back(detri);
734  }
735 
736  if (!detriList.empty()) {
737  vector<detri_t>::iterator v;
738  for (v = detriList.begin(); v != detriList.end(); v++) {
739  detri_t detri = (*v);
740  if (detri.n == 0) {
741  cleanVertices[detri.viP] = cleanVertices[detri.viA];
742  cleanVertices[detri.viP + 1] = cleanVertices[detri.viA + 1];
743  cleanVertices[detri.viP + 2] = cleanVertices[detri.viA + 2];
744  }
745  else if (detri.v.norm() > 0.0) {
746  cleanVertices[detri.viP] += 1.0e-5 * detri.v.x();
747  cleanVertices[detri.viP + 1] += 1.0e-5 * detri.v.y();
748  cleanVertices[detri.viP + 2] += 1.0e-5 * detri.v.z();
749  }
750  }
751  if (G.debug & G_DEBUG_FREESTYLE) {
752  printf("Warning: Object %s contains %lu degenerated triangle%s (strokes may be incorrect)\n",
753  name,
754  (long unsigned int)detriList.size(),
755  (detriList.size() > 1) ? "s" : "");
756  }
757  }
758 
759  // Create the IndexedFaceSet with the retrieved attributes
760  IndexedFaceSet *rep;
761  rep = new IndexedFaceSet(cleanVertices,
762  cvSize,
763  cleanNormals,
764  cnSize,
765  marray,
766  meshFrsMaterials.size(),
767  nullptr,
768  0,
769  numFaces,
770  numVertexPerFaces,
771  faceStyle,
772  faceEdgeMarks,
773  cleanVIndices,
774  viSize,
775  cleanNIndices,
776  niSize,
777  MIndices,
778  viSize,
779  nullptr,
780  0,
781  0);
782  // sets the id of the rep
783  rep->setId(Id(id, 0));
784  rep->setName(ob->id.name + 2);
785  rep->setLibraryPath(ob->id.lib ? ob->id.lib->filepath : "");
786 
787  const BBox<Vec3r> bbox = BBox<Vec3r>(Vec3r(ls.minBBox[0], ls.minBBox[1], ls.minBBox[2]),
788  Vec3r(ls.maxBBox[0], ls.maxBBox[1], ls.maxBBox[2]));
789  rep->setBBox(bbox);
790  shape->AddRep(rep);
791 
792  currentMesh->AddChild(shape);
793  _Scene->AddChild(currentMesh);
794 }
795 
796 } /* namespace Freestyle */
typedef float(TangentPoint)[2]
bool CustomData_has_layer(const struct CustomData *data, int type)
void * CustomData_get_layer(const struct CustomData *data, int type)
@ G_DEBUG_FREESTYLE
Definition: BKE_global.h:140
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:697
void BKE_mesh_recalc_looptri(const struct MLoop *mloop, const struct MPoly *mpoly, const struct MVert *mvert, int totloop, int totpoly, struct MLoopTri *mlooptri)
void BKE_mesh_calc_normals_split(struct Mesh *mesh)
Definition: mesh.c:1865
General operations, lookup, etc. for blender objects.
void BKE_object_to_mesh_clear(struct Object *object)
Definition: object.c:5673
@ OB_VISIBLE_SELF
Definition: BKE_object.h:125
struct Mesh * BKE_object_to_mesh(struct Depsgraph *depsgraph, struct Object *object, bool preserve_all_data_layers)
Definition: object.c:5664
int BKE_object_visibility(const struct Object *ob, const int dag_eval_mode)
#define BLI_assert(a)
Definition: BLI_assert.h:58
float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
Definition: math_geom.c:493
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:116
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:51
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:794
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void transpose_m4(float R[4][4])
Definition: math_matrix.c:1358
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool equals_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
#define ELEM(...)
#define NOT_CLIPPED
#define CLIPPED_BY_FAR
#define CLIPPED_BY_NEAR
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
eEvaluationMode
Definition: DEG_depsgraph.h:60
#define DEG_OBJECT_ITER_END
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
#define DEG_OBJECT_ITER_BEGIN(graph_, instance_, flag_)
@ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY
@ DEG_ITER_OBJECT_FLAG_VISIBLE
@ DEG_ITER_OBJECT_FLAG_DUPLI
@ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ CD_FREESTYLE_EDGE
@ CD_FREESTYLE_FACE
@ FREESTYLE_FACE_SMOOTHNESS_FLAG
@ BASE_INDIRECT_ONLY
@ BASE_HOLDOUT
@ FREESTYLE_EDGE_MARK
@ FREESTYLE_FACE_MARK
@ ME_SMOOTH
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static T sum(const btAlignedObjectArray< T > &items)
static int verbose
Definition: cineonlib.c:44
BlenderFileLoader(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph)
void clipLine(float v1[3], float v2[3], float c[3], float z)
void addTriangle(struct LoaderState *ls, float v1[3], float v2[3], float v3[3], float n1[3], float n2[3], float n3[3], bool fm, bool em1, bool em2, bool em3)
int testDegenerateTriangle(float v1[3], float v2[3], float v3[3])
void insertShapeNode(Object *ob, Mesh *mesh, int id)
void clipTriangle(int numTris, float triCoords[][3], float v1[3], float v2[3], float v3[3], float triNormals[][3], float n1[3], float n2[3], float n3[3], bool edgeMarks[5], bool em1, bool em2, bool em3, const int clip[3])
int countClippedFaces(float v1[3], float v2[3], float v3[3], int clip[3])
void setSpecular(const float r, const float g, const float b, const float a)
Definition: FrsMaterial.h:396
void setDiffuse(const float r, const float g, const float b, const float a)
Definition: FrsMaterial.h:388
void setShininess(const float s)
Definition: FrsMaterial.h:420
void setLine(const float r, const float g, const float b, const float a)
Definition: FrsMaterial.h:380
void setPriority(const int priority)
Definition: FrsMaterial.h:425
static void CleanIndexedVertexArray(const float *iVertices, unsigned iVSize, const unsigned *iIndices, unsigned iISize, float **oVertices, unsigned *oVSize, unsigned **oIndices)
static const FaceEdgeMark EDGE_MARK_V2V3
static const FaceEdgeMark EDGE_MARK_V1V2
static const FaceEdgeMark FACE_MARK
static const FaceEdgeMark EDGE_MARK_V3V1
virtual void AddChild(Node *iChild)
Definition: NodeGroup.cpp:28
virtual void AddRep(Rep *iRep)
Definition: NodeShape.h:53
void setFrsMaterial(const FrsMaterial &iMaterial)
Definition: NodeShape.h:69
void setLibraryPath(const string &path)
Definition: Rep.h:164
void setId(const Id &id)
Definition: Rep.h:154
virtual void setBBox(const BBox< Vec3f > &iBox)
Definition: Rep.h:149
void setName(const string &name)
Definition: Rep.h:159
value_type x() const
Definition: VecMat.h:532
value_type z() const
Definition: VecMat.h:552
value_type y() const
Definition: VecMat.h:542
Vec< T, N > & normalizeSafe()
Definition: VecMat.h:128
value_type norm() const
Definition: VecMat.h:109
const Depsgraph * depsgraph
static float normals[][3]
void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_modelmat[4][4])
Definition: initrender.c:230
struct Object * RE_GetCamera(Render *re)
Definition: initrender.c:169
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
VecMat::Vec3< real > Vec3r
Definition: Geom.h:42
inherits from class Rep
Definition: AppCanvas.cpp:32
static unsigned c
Definition: RandGen.cpp:97
static bool testEdgeMark(Mesh *me, FreestyleEdge *fed, const MLoopTri *lt, int i)
static unsigned a[3]
Definition: RandGen.cpp:92
static void area(int d1, int d2, int e1, int e2, float weights[2])
const btScalar eps
Definition: poly34.cpp:11
IndexedFaceSet::FaceEdgeMark * pm
struct Library * lib
Definition: DNA_ID.h:277
char name[66]
Definition: DNA_ID.h:283
char filepath[1024]
Definition: DNA_ID.h:352
unsigned int v1
unsigned int v2
unsigned int poly
unsigned int tri[3]
unsigned int e
unsigned int v
short mat_nr
float co[3]
float line_col[4]
struct MEdge * medge
struct CustomData pdata ldata
struct MVert * mvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
float obmat[4][4]
float clip_start
Definition: render_types.h:107
float clip_end
Definition: render_types.h:108
struct FreestyleConfig freestyle_config
#define G(x, y, z)
uint len