Blender V5.0
dualcon_c_api.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "ModelReader.h"
6#include "dualcon.h"
7#include "octree.h"
8#include <algorithm>
9#include <cassert>
10
11#include <cfloat>
12#include <cmath>
13
14static void veccopy(float dst[3], const float src[3])
15{
16 dst[0] = src[0];
17 dst[1] = src[1];
18 dst[2] = src[2];
19}
20
21#define GET_TRI(_mesh, _n) \
22 (*(DualConTri)(((char *)(_mesh)->corner_tris) + ((_n) * (_mesh)->tri_stride)))
23
24#define GET_CO(_mesh, _n) (*(DualConCo)(((char *)(_mesh)->co) + ((_n) * (_mesh)->co_stride)))
25
26#define GET_CORNER_VERT(_mesh, _n) \
27 (*(DualConCornerVerts)(((char *)(_mesh)->corner_verts) + ((_n) * (_mesh)->corner_verts_stride)))
28
30 private:
31 const DualConInput *input_mesh;
32 int tottri, curtri;
33 float min[3], max[3], maxsize;
34 float scale;
35
36 public:
37 DualConInputReader(const DualConInput *mesh, float _scale) : input_mesh(mesh), scale(_scale)
38 {
39 reset();
40 }
41
42 void reset() override
43 {
44 curtri = 0;
45 maxsize = 0;
46 tottri = input_mesh->tottri;
47
48 veccopy(min, input_mesh->min);
49 veccopy(max, input_mesh->max);
50
51 /* initialize maxsize */
52 for (int i = 0; i < 3; i++) {
53 float d = max[i] - min[i];
54 maxsize = std::max(d, maxsize);
55 }
56
57 /* redo the bounds */
58 for (int i = 0; i < 3; i++) {
59 min[i] = (max[i] + min[i]) / 2 - maxsize / 2;
60 max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
61 }
62
63 for (int i = 0; i < 3; i++) {
64 min[i] -= maxsize * (1 / scale - 1) / 2;
65 }
66 maxsize *= 1 / scale;
67 }
68
70 {
71 if (curtri == input_mesh->tottri) {
72 return nullptr;
73 }
74
75 Triangle *t = new Triangle();
76
77 const unsigned int *tr = GET_TRI(input_mesh, curtri);
78 veccopy(t->vt[0], GET_CO(input_mesh, GET_CORNER_VERT(input_mesh, tr[0])));
79 veccopy(t->vt[1], GET_CO(input_mesh, GET_CORNER_VERT(input_mesh, tr[1])));
80 veccopy(t->vt[2], GET_CO(input_mesh, GET_CORNER_VERT(input_mesh, tr[2])));
81
82 curtri++;
83
84 /* remove triangle if it contains invalid coords */
85 for (int i = 0; i < 3; i++) {
86 const float *co = t->vt[i];
87 if (std::isnan(co[0]) || std::isnan(co[1]) || std::isnan(co[2])) {
88 delete t;
89 return getNextTriangle();
90 }
91 }
92
93 return t;
94 }
95
96 int getNextTriangle(int t[3]) override
97 {
98 if (curtri == input_mesh->tottri) {
99 return 0;
100 }
101
102 const unsigned int *tr = GET_TRI(input_mesh, curtri);
103 t[0] = tr[0];
104 t[1] = tr[1];
105 t[2] = tr[2];
106
107 curtri++;
108
109 return 1;
110 }
111
112 int getNumTriangles() override
113 {
114 return tottri;
115 }
116
117 int getNumVertices() override
118 {
119 return input_mesh->totco;
120 }
121
122 float getBoundingBox(float origin[3]) override
123 {
124 veccopy(origin, min);
125 return maxsize;
126 }
127
128 /* output */
129 void getNextVertex(float /*v*/[3]) override
130 {
131 /* not used */
132 }
133
134 /* stubs */
135 void printInfo() override {}
136 int getMemory() override
137 {
138 return sizeof(DualConInputReader);
139 }
140
141 MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:DualConInputReader")
142};
143
144void *dualcon(const DualConInput *input_mesh,
145 /* callbacks for output */
146 DualConAllocOutput alloc_output,
147 DualConAddVert add_vert,
148 DualConAddQuad add_quad,
149
150 DualConFlags flags,
151 DualConMode mode,
152 float threshold,
153 float hermite_num,
154 float scale,
155 int depth)
156{
157 DualConInputReader r(input_mesh, scale);
158 Octree o(&r, alloc_output, add_vert, add_quad, flags, mode, depth, threshold, hermite_num);
159 o.scanConvert();
160 return o.getOutputMesh();
161}
int getNumVertices() override
For explicit vertex models.
void getNextVertex(float[3]) override
float getBoundingBox(float origin[3]) override
Get bounding box.
DualConInputReader(const DualConInput *mesh, float _scale)
void printInfo() override
int getNextTriangle(int t[3]) override
void reset() override
Reset file reading location.
int getNumTriangles() override
Get number of triangles.
int getMemory() override
Get storage size.
Triangle * getNextTriangle() override
Get next triangle.
ModelReader()=default
Constructor.
void * getOutputMesh()
DualConMode
Definition dualcon.h:45
void(* DualConAddQuad)(void *output, const int vert_indices[4])
Definition dualcon.h:39
void(* DualConAddVert)(void *output, const float co[3])
Definition dualcon.h:37
void *(* DualConAllocOutput)(int totvert, int totquad)
Definition dualcon.h:35
DualConFlags
Definition dualcon.h:41
void * dualcon(const DualConInput *input_mesh, DualConAllocOutput alloc_output, DualConAddVert add_vert, DualConAddQuad add_quad, DualConFlags flags, DualConMode mode, float threshold, float hermite_num, float scale, int depth)
static void veccopy(float dst[3], const float src[3])
#define GET_CO(_mesh, _n)
#define GET_CORNER_VERT(_mesh, _n)
#define GET_TRI(_mesh, _n)
float vt[3][3]
Definition GeoCommon.h:31
i
Definition text_draw.cc:230