Blender V4.3
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 "scene/mesh.h"
8
9#include "subd/patch.h"
10
11#include "util/math.h"
12#include "util/types.h"
13
15
16/* De Casteljau Evaluation */
17
18static void decasteljau_cubic(float3 *P, float3 *dt, float t, const float3 cp[4])
19{
20 float3 d0 = cp[0] + t * (cp[1] - cp[0]);
21 float3 d1 = cp[1] + t * (cp[2] - cp[1]);
22 float3 d2 = cp[2] + t * (cp[3] - cp[2]);
23
24 d0 += t * (d1 - d0);
25 d1 += t * (d2 - d1);
26
27 *P = d0 + t * (d1 - d0);
28 if (dt) {
29 *dt = d1 - d0;
30 }
31}
32
34 float3 *P, float3 *du, float3 *dv, const float3 cp[16], float u, float v)
35{
36 float3 ucp[4], utn[4];
37
38 /* interpolate over u */
39 decasteljau_cubic(ucp + 0, utn + 0, u, cp);
40 decasteljau_cubic(ucp + 1, utn + 1, u, cp + 4);
41 decasteljau_cubic(ucp + 2, utn + 2, u, cp + 8);
42 decasteljau_cubic(ucp + 3, utn + 3, u, cp + 12);
43
44 /* interpolate over v */
45 decasteljau_cubic(P, dv, v, ucp);
46 if (du) {
47 decasteljau_cubic(du, NULL, v, utn);
48 }
49}
50
51/* Linear Quad Patch */
52
53void LinearQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
54{
55 float3 d0 = interp(hull[0], hull[1], u);
56 float3 d1 = interp(hull[2], hull[3], u);
57
58 *P = interp(d0, d1, v);
59
60 if (dPdu && dPdv) {
61 *dPdu = interp(hull[1] - hull[0], hull[3] - hull[2], v);
62 *dPdv = interp(hull[2] - hull[0], hull[3] - hull[1], u);
63 }
64
65 if (N) {
66 *N = normalize(
67 interp(interp(normals[0], normals[1], u), interp(normals[2], normals[3], u), v));
68 }
69}
70
72{
74
75 for (int i = 0; i < 4; i++) {
76 bbox.grow(hull[i]);
77 }
78
79 return bbox;
80}
81
82/* Bicubic Patch */
83
84void BicubicPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
85{
86 if (N) {
87 float3 dPdu_, dPdv_;
88 decasteljau_bicubic(P, &dPdu_, &dPdv_, hull, u, v);
89
90 if (dPdu && dPdv) {
91 *dPdu = dPdu_;
92 *dPdv = dPdv_;
93 }
94
95 *N = normalize(cross(dPdu_, dPdv_));
96 }
97 else {
98 decasteljau_bicubic(P, dPdu, dPdv, hull, u, v);
99 }
100}
101
103{
105
106 for (int i = 0; i < 16; i++) {
107 bbox.grow(hull[i]);
108 }
109
110 return bbox;
111}
112
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
BoundBox bound()
Definition patch.cpp:102
float3 hull[16]
Definition subd/patch.h:41
void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
Definition patch.cpp:84
float3 hull[4]
Definition subd/patch.h:30
BoundBox bound()
Definition patch.cpp:71
void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
Definition patch.cpp:53
#define CCL_NAMESPACE_END
#define NULL
ccl_device_inline float cross(const float2 a, const float2 b)
ccl_device_inline float2 interp(const float2 a, const float2 b, float t)
#define N
static void decasteljau_bicubic(float3 *P, float3 *du, float3 *dv, const float3 cp[16], float u, float v)
Definition patch.cpp:33
static CCL_NAMESPACE_BEGIN void decasteljau_cubic(float3 *P, float3 *dt, float t, const float3 cp[4])
Definition patch.cpp:18
__forceinline void grow(const float3 &pt)
Definition boundbox.h:36