Blender V4.3
WXEdge.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include "WXEdge.h"
11
12#include "BLI_sys_types.h"
13
14#include "BKE_global.hh"
15
16namespace Freestyle {
17
18/**********************************
19 * *
20 * *
21 * WXFace *
22 * *
23 * *
24 **********************************/
25
27{
28 int i = 0;
29 int nEdges = _pWXFace->numberOfEdges();
30 for (i = 0; i < nEdges; ++i) {
31 if (_DotP[i] == 0.0f) { /* TODO: this comparison is weak, check if it actually works */
32 return i;
33 }
34 }
35 return -1;
36}
38{
39 int i = 0;
40 int nEdges = _pWXFace->numberOfEdges();
41 for (i = 0; i < nEdges; ++i) {
42 if ((_DotP[i] == 0.0f) && (_DotP[(i + 1) % nEdges] == 0.0f)) { /* TODO: ditto */
43 return i;
44 }
45 }
46 return -1;
47}
48
49void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int> &oCuspEdges)
50{
51 int i = 0;
52 int nEdges = _pWXFace->numberOfEdges();
53 for (i = 0; i < nEdges; ++i) {
54 if (_DotP[i] * _DotP[(i + 1) % nEdges] < 0.0f) {
55 // we got one
56 oCuspEdges.push_back(i);
57 }
58 }
59}
60
62{
63 // if the smooth edge has already been built: exit
64 if (_pSmoothEdge) {
65 return _pSmoothEdge;
66 }
67 float ta, tb;
68 WOEdge *woea(nullptr), *woeb(nullptr);
69 bool ok = false;
70 vector<int> cuspEdgesIndices;
71 int indexStart, indexEnd;
72 uint nedges = _pWXFace->numberOfEdges();
73 if (_nNullDotP == nedges) {
74 _pSmoothEdge = nullptr;
75 return _pSmoothEdge;
76 }
77 if ((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)) {
78 // that means that we have a smooth edge that starts from an edge and ends at an edge
79 //-----------------------------
80 // We retrieve the 2 edges for which we have opposite signs for each extremity
81 RetrieveCuspEdgesIndices(cuspEdgesIndices);
82 if (cuspEdgesIndices.size() != 2) { // we necessarily have 2 cusp edges
83 return nullptr;
84 }
85
86 // let us determine which cusp edge corresponds to the starting:
87 // We can do that because we defined that a silhouette edge had the back facing part on its
88 // right. So if the WOEdge woea is such that woea[0].dotp > 0 and woea[1].dotp < 0, it is the
89 // starting edge.
90 //-------------------------------------------
91
92 if (_DotP[cuspEdgesIndices[0]] > 0.0f) {
93 woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
94 woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
95 indexStart = cuspEdgesIndices[0];
96 indexEnd = cuspEdgesIndices[1];
97 }
98 else {
99 woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]);
100 woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
101 indexStart = cuspEdgesIndices[1];
102 indexEnd = cuspEdgesIndices[0];
103 }
104
105 // Compute the interpolation:
106 ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
107 tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
108 ok = true;
109 }
110 else if (_nNullDotP == 1) {
111 // that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex
112 // of the mesh
113 if (ELEM(_nPosDotP, 2, 0)) {
114 _pSmoothEdge = nullptr;
115 return _pSmoothEdge;
116 }
117 RetrieveCuspEdgesIndices(cuspEdgesIndices);
118 // We should have only one EdgeCusp:
119 if (cuspEdgesIndices.size() != 1) {
120 if (G.debug & G_DEBUG_FREESTYLE) {
121 cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl;
122 }
123 _pSmoothEdge = nullptr;
124 return nullptr;
125 }
126 uint index0 = Get0VertexIndex(); // retrieve the 0 vertex index
127 uint nedges = _pWXFace->numberOfEdges();
128 if (_DotP[cuspEdgesIndices[0]] > 0.0f) {
129 woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
130 woeb = _pWXFace->GetOEdge(index0);
131 indexStart = cuspEdgesIndices[0];
132 ta = _DotP[indexStart] / (_DotP[indexStart] - _DotP[(indexStart + 1) % nedges]);
133 tb = 0.0f;
134 }
135 else {
136 woea = _pWXFace->GetOEdge(index0);
137 woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]);
138 indexEnd = cuspEdgesIndices[0];
139 ta = 0.0f;
140 tb = _DotP[indexEnd] / (_DotP[indexEnd] - _DotP[(indexEnd + 1) % nedges]);
141 }
142 ok = true;
143 }
144 else if (_nNullDotP == 2) {
145 // that means that the silhouette edge is an edge of the mesh
146 int index = GetSmoothEdgeIndex();
147 if (!_pWXFace->front()) { // is it in the right order ?
148 // the order of the WOEdge index is wrong
149 woea = _pWXFace->GetOEdge((index + 1) % nedges);
150 woeb = _pWXFace->GetOEdge((index - 1) % nedges);
151 ta = 0.0f;
152 tb = 1.0f;
153 ok = true;
154 }
155 else {
156 // here it's not good, our edge is a single point -> skip that face
157 ok = false;
158#if 0
159 // the order of the WOEdge index is good
160 woea = _pWXFace->GetOEdge((index - 1) % nedges);
161 woeb = _pWXFace->GetOEdge((index + 1) % nedges);
162 ta = 1.0f;
163 tb = 0.0f;
164#endif
165 }
166 }
167 if (ok) {
169 _pSmoothEdge->setWOeA(woea);
170 _pSmoothEdge->setWOeB(woeb);
171 _pSmoothEdge->setTa(ta);
172 _pSmoothEdge->setTb(tb);
174 if (_nNullDotP != 2) {
175 if (_DotP[_ClosestPointIndex] + 0.01f > 0.0f) {
176 _pSmoothEdge->setFront(true);
177 }
178 else {
179 _pSmoothEdge->setFront(false);
180 }
181 }
182 }
183 }
184
185#if 0
186 // check bording edges to see if they have different dotp values in bording faces.
187 for (int i = 0; i < numberOfEdges(); i++) {
188 WSFace *bface = (WSFace *)GetBordingFace(i);
189 if (bface) {
190 if ((front()) ^ (bface->front()))
191 { // fA->front XOR fB->front (true if one is 0 and the other is 1)
192 // that means that the edge i of the face is a silhouette edge
193 // CHECK FIRST WHETHER THE EXACTSILHOUETTEEDGE HAS
194 // NOT YET BEEN BUILT ON THE OTHER FACE (1 is enough).
195 if (((WSExactFace *)bface)->exactSilhouetteEdge()) {
196 // that means that this silhouette edge has already been built
197 return ((WSExactFace *)bface)->exactSilhouetteEdge();
198 }
199 // Else we must build it
200 WOEdge *woea, *woeb;
201 float ta, tb;
202 if (!front()) { // is it in the right order ?
203 // the order of the WOEdge index is wrong
204 woea = _OEdgeList[(i + 1) % numberOfEdges()];
205 if (0 == i) {
206 woeb = _OEdgeList[numberOfEdges() - 1];
207 }
208 else {
209 woeb = _OEdgeList[(i - 1)];
210 }
211 ta = 0.0f;
212 tb = 1.0f;
213 }
214 else {
215 // the order of the WOEdge index is good
216 if (0 == i) {
217 woea = _OEdgeList[numberOfEdges() - 1];
218 }
219 else {
220 woea = _OEdgeList[(i - 1)];
221 }
222 woeb = _OEdgeList[(i + 1) % numberOfEdges()];
223 ta = 1.0f;
224 tb = 0.0f;
225 }
226
227 _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX);
228 _pSmoothEdge->setWOeA(woea);
229 _pSmoothEdge->setWOeA(woeb);
230 _pSmoothEdge->setTa(ta);
231 _pSmoothEdge->setTb(tb);
232
233 return _pSmoothEdge;
234 }
235 }
236 }
237#endif
238 return _pSmoothEdge;
239}
240
242{
243 vector<WVertex *> iVertexList;
244 RetrieveVertexList(iVertexList);
246 for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end();
247 wv != wvend;
248 ++wv)
249 {
250 center += (*wv)->GetVertex();
251 }
252 center /= float(iVertexList.size());
254}
255
256/**********************************
257 * *
258 * *
259 * WXShape *
260 * *
261 * *
262 **********************************/
263
264WFace *WXShape::MakeFace(vector<WVertex *> &iVertexList,
265 vector<bool> &iFaceEdgeMarksList,
266 uint iMaterialIndex)
267{
268 WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex);
269 if (!face) {
270 return nullptr;
271 }
272
273 Vec3f center;
274 for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end();
275 wv != wvend;
276 ++wv)
277 {
278 center += (*wv)->GetVertex();
279 }
280 center /= float(iVertexList.size());
281 ((WXFace *)face)->setCenter(center);
282
283 return face;
284}
285
286WFace *WXShape::MakeFace(vector<WVertex *> &iVertexList,
287 vector<Vec3f> &iNormalsList,
288 vector<Vec2f> &iTexCoordsList,
289 vector<bool> &iFaceEdgeMarksList,
290 uint iMaterialIndex)
291{
292 WFace *face = WShape::MakeFace(
293 iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex);
294
295#if 0
296 Vec3f center;
297 for (vector<WVertex *>::iterator wv = iVertexList.begin(), wvend = iVertexList.end();
298 wv != wvend;
299 ++wv)
300 {
301 center += (*wv)->GetVertex();
302 }
303 center /= float(iVertexList.size());
304 ((WXFace *)face)->setCenter(center);
305#endif
306
307 return face;
308}
309
310} /* namespace Freestyle */
@ G_DEBUG_FREESTYLE
unsigned int uint
#define ELEM(...)
Classes to define an Extended Winged Edge data structure.
int numberOfEdges() const
Definition WEdge.h:881
WOEdge * GetOEdge(int i)
Definition WEdge.h:721
void RetrieveVertexList(vector< WVertex * > &oVertices)
Definition WEdge.h:777
virtual WFace * MakeFace(vector< WVertex * > &iVertexList, vector< bool > &iFaceEdgeMarksList, uint iMaterialIndex)
Definition WEdge.cpp:590
void RetrieveCuspEdgesIndices(vector< int > &oCuspEdges)
Definition WXEdge.cpp:49
uint Get0VertexIndex() const
Definition WXEdge.cpp:26
uint GetSmoothEdgeIndex() const
Definition WXEdge.cpp:37
vector< float > _DotP
Definition WXEdge.h:312
WXSmoothEdge * BuildSmoothEdge()
Definition WXEdge.cpp:61
WXSmoothEdge * _pSmoothEdge
Definition WXEdge.h:313
void setCenter(const Vec3f &iCenter)
Definition WXEdge.h:618
void ComputeCenter()
Definition WXEdge.cpp:241
Vec3f & center()
Definition WXEdge.h:541
virtual WFace * MakeFace(vector< WVertex * > &iVertexList, vector< bool > &iFaceEdgeMarksList, uint iMaterialIndex)
Definition WXEdge.cpp:264
void setWOeA(WOEdge *iwoea)
Definition WXEdge.h:266
void setWOeB(WOEdge *iwoeb)
Definition WXEdge.h:271
void setTb(float tb)
Definition WXEdge.h:281
void setFront(bool iFront)
Definition WXEdge.h:286
void setTa(float ta)
Definition WXEdge.h:276
draw_view in_light_buf[] float
#define G(x, y, z)
static const EdgeNature SILHOUETTE
Definition Nature.h:40
inherits from class Rep
Definition AppCanvas.cpp:20