Blender V5.0
patch.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5/* Parts adapted from code in the public domain in NVidia Mesh Tools. */
6
7#include "subd/patch.h"
8
9#include "util/math.h"
10#include "util/types.h"
11
13
14/* De Casteljau Evaluation */
15
16static void decasteljau_cubic(float3 *P, float3 *dt, const float t, const float3 cp[4])
17{
18 float3 d0 = cp[0] + t * (cp[1] - cp[0]);
19 float3 d1 = cp[1] + t * (cp[2] - cp[1]);
20 const float3 d2 = cp[2] + t * (cp[3] - cp[2]);
21
22 d0 += t * (d1 - d0);
23 d1 += t * (d2 - d1);
24
25 *P = d0 + t * (d1 - d0);
26 if (dt) {
27 *dt = d1 - d0;
28 }
29}
30
32 float3 *P, float3 *du, float3 *dv, const float3 cp[16], float u, const float v)
33{
34 float3 ucp[4];
35 float3 utn[4];
36
37 /* interpolate over u */
38 decasteljau_cubic(ucp + 0, utn + 0, u, cp);
39 decasteljau_cubic(ucp + 1, utn + 1, u, cp + 4);
40 decasteljau_cubic(ucp + 2, utn + 2, u, cp + 8);
41 decasteljau_cubic(ucp + 3, utn + 3, u, cp + 12);
42
43 /* interpolate over v */
44 decasteljau_cubic(P, dv, v, ucp);
45 if (du) {
46 decasteljau_cubic(du, nullptr, v, utn);
47 }
48}
49
50/* Linear Quad Patch */
51
53 float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, const float u, float v) const
54{
55 const float3 d0 = interp(hull[0], hull[1], u);
56 const float3 d1 = interp(hull[2], hull[3], u);
57
58 *P = interp(d0, d1, v);
59
60 if (N || (dPdu && dPdv)) {
61 const float3 dPdu_ = interp(hull[1] - hull[0], hull[3] - hull[2], v);
62 const float3 dPdv_ = interp(hull[2] - hull[0], hull[3] - hull[1], u);
63
64 if (dPdu && dPdv) {
65 *dPdu = dPdu_;
66 *dPdv = dPdv_;
67 }
68
69 if (N) {
70 *N = normalize(cross(dPdu_, dPdv_));
71 }
72 }
73}
74
76{
78
79 for (int i = 0; i < 4; i++) {
80 bbox.grow(hull[i]);
81 }
82
83 return bbox;
84}
85
86/* Bicubic Patch */
87
89 float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, const float u, const float v) const
90{
91 if (N) {
92 float3 dPdu_;
93 float3 dPdv_;
94 decasteljau_bicubic(P, &dPdu_, &dPdv_, hull, u, v);
95
96 if (dPdu && dPdv) {
97 *dPdu = dPdu_;
98 *dPdv = dPdv_;
99 }
100
101 *N = normalize(cross(dPdu_, dPdv_));
102 }
103 else {
104 decasteljau_bicubic(P, dPdu, dPdv, hull, u, v);
105 }
106}
107
109{
111
112 for (int i = 0; i < 16; i++) {
113 bbox.grow(hull[i]);
114 }
115
116 return bbox;
117}
118
ATTR_WARN_UNUSED_RESULT const BMVert * v
BoundBox bound()
Definition patch.cpp:108
float3 hull[16]
Definition patch.h:41
void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, const float u, float v) const override
Definition patch.cpp:88
float3 hull[4]
Definition patch.h:30
void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, const float u, float v) const override
Definition patch.cpp:52
BoundBox bound()
Definition patch.cpp:75
#define CCL_NAMESPACE_END
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
ccl_device_inline float interp(const float a, const float b, const float t)
Definition math_base.h:502
#define N
static void decasteljau_bicubic(float3 *P, float3 *du, float3 *dv, const float3 cp[16], float u, const float v)
Definition patch.cpp:31
static CCL_NAMESPACE_BEGIN void decasteljau_cubic(float3 *P, float3 *dt, const float t, const float3 cp[4])
Definition patch.cpp:16
__forceinline void grow(const float3 &pt)
Definition boundbox.h:35
i
Definition text_draw.cc:230