Blender  V2.93
subd_subpatch.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2018 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __SUBD_SUBPATCH_H__
18 #define __SUBD_SUBPATCH_H__
19 
20 #include "util/util_map.h"
21 #include "util/util_types.h"
22 
24 
25 /* Subpatch */
26 
27 class Subpatch {
28  public:
29  class Patch *patch; /* Patch this is a subpatch of. */
31 
32  struct edge_t {
33  int T;
34  int offset; /* Offset along main edge, interpretation depends on the two flags below. */
35 
38 
39  struct Edge *edge;
40 
41  int get_vert_along_edge(int n) const;
42  };
43 
44  /*
45  * eu1
46  * c01 --------- c11
47  * | |
48  * ev0 | | ev1
49  * | |
50  * c00 --------- c10
51  * eu0
52  */
53 
54  union {
55  float2 corners[4]; /* UV within patch, clockwise starting from uv (0, 0) towards (0, 1) etc. */
56  struct {
58  };
59  };
60 
61  union {
62  edge_t
63  edges[4]; /* Edges of this subpatch, each edge starts at the corner of the same index. */
64  struct {
66  };
67  };
68 
69  explicit Subpatch(Patch *patch = nullptr)
70  : patch(patch),
71  c00(zero_float2()),
72  c01(make_float2(0.0f, 1.0f)),
73  c11(one_float2()),
74  c10(make_float2(1.0f, 0.0f))
75  {
76  }
77 
79  : patch(patch), c00(c00), c01(c01), c11(c11), c10(c10)
80  {
81  }
82 
84  {
85  int Mu = max(edge_u0.T, edge_u1.T);
86  int Mv = max(edge_v0.T, edge_v1.T);
87  Mu = max(Mu, 2);
88  Mv = max(Mv, 2);
89  return (Mu - 1) * (Mv - 1);
90  }
91 
92  int calc_num_triangles() const
93  {
94  int Mu = max(edge_u0.T, edge_u1.T);
95  int Mv = max(edge_v0.T, edge_v1.T);
96  Mu = max(Mu, 2);
97  Mv = max(Mv, 2);
98 
99  int inner_triangles = (Mu - 2) * (Mv - 2) * 2;
100  int edge_triangles = edge_u0.T + edge_u1.T + edge_v0.T + edge_v1.T + (Mu - 2) * 2 +
101  (Mv - 2) * 2;
102 
103  return inner_triangles + edge_triangles;
104  }
105 
106  int get_vert_along_edge(int e, int n) const;
107 
108  int get_vert_along_grid_edge(int edge, int n) const
109  {
110  int Mu = max(edge_u0.T, edge_u1.T);
111  int Mv = max(edge_v0.T, edge_v1.T);
112  Mu = max(Mu, 2);
113  Mv = max(Mv, 2);
114 
115  switch (edge) {
116  case 0:
117  return inner_grid_vert_offset + n * (Mu - 1);
118  case 1:
119  return inner_grid_vert_offset + (Mu - 1) * (Mv - 2) + n;
120  case 2:
121  return inner_grid_vert_offset + ((Mu - 1) * (Mv - 1) - 1) - n * (Mu - 1);
122  case 3:
123  return inner_grid_vert_offset + (Mu - 2) - n;
124  }
125 
126  return -1;
127  }
128 };
129 
130 struct Edge {
131  /* Number of segments the edge will be diced into, see DiagSplit paper. */
132  int T;
133 
134  /* top is edge adjacent to start, bottom is adjacent to end. */
136 
139 
142 
143  /* Index of the second vert from this edges corner along the edge towards the next corner. */
145 
146  /* Vertices on edge are to be stitched. */
148 
149  /* Key to match this edge with others to be stitched with.
150  * The ints in the pair are ordered stitching indices */
151  pair<int, int> stitch_edge_key;
152 
153  /* Full T along edge (may be larger than T for edges split from ngon edges) */
159 
161  : T(0),
162  top(nullptr),
163  bottom(nullptr),
164  top_offset(-1),
165  bottom_offset(-1),
166  top_indices_decrease(false),
168  start_vert_index(-1),
169  end_vert_index(-1),
170  second_vert_index(-1),
171  is_stitch_edge(false),
172  stitch_edge_T(0),
173  stitch_offset(0)
174  {
175  }
176 
177  int get_vert_along_edge(int n) const
178  {
179  assert(n >= 0 && n <= T);
180 
181  if (n == 0) {
182  return start_vert_index;
183  }
184  else if (n == T) {
185  return end_vert_index;
186  }
187 
188  return second_vert_index + n - 1;
189  }
190 };
191 
193 {
194  assert(n >= 0 && n <= T);
195 
197  n = offset + n;
198  }
200  n = edge->T - offset - T + n;
201  }
203  n = offset + T - n;
204  }
206  n = edge->T - offset - n;
207  }
208 
209  return edge->get_vert_along_edge(n);
210 }
211 
212 inline int Subpatch::get_vert_along_edge(int edge, int n) const
213 {
214  return edges[edge].get_vert_along_edge(n);
215 }
216 
218 
219 #endif /* __SUBD_SUBPATCH_H__ */
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
int get_vert_along_grid_edge(int edge, int n) const
edge_t edges[4]
Definition: subd_subpatch.h:63
float2 c11
Definition: subd_subpatch.h:57
Subpatch(Patch *patch=nullptr)
Definition: subd_subpatch.h:69
int inner_grid_vert_offset
Definition: subd_subpatch.h:30
edge_t edge_v1
Definition: subd_subpatch.h:65
edge_t edge_u0
Definition: subd_subpatch.h:65
float2 c01
Definition: subd_subpatch.h:57
class Patch * patch
Definition: subd_subpatch.h:29
int calc_num_triangles() const
Definition: subd_subpatch.h:92
edge_t edge_u1
Definition: subd_subpatch.h:65
Subpatch(Patch *patch, float2 c00, float2 c01, float2 c11, float2 c10)
Definition: subd_subpatch.h:78
int calc_num_inner_verts() const
Definition: subd_subpatch.h:83
float2 corners[4]
Definition: subd_subpatch.h:55
edge_t edge_v0
Definition: subd_subpatch.h:65
float2 c10
Definition: subd_subpatch.h:57
float2 c00
Definition: subd_subpatch.h:57
int get_vert_along_edge(int e, int n) const
#define CCL_NAMESPACE_END
#define make_float2(x, y)
int stitch_offset
bool bottom_indices_decrease
int second_vert_index
Edge * bottom
int stitch_end_vert_index
int start_vert_index
int bottom_offset
Edge * top
int stitch_top_offset
pair< int, int > stitch_edge_key
bool is_stitch_edge
bool top_indices_decrease
int get_vert_along_edge(int n) const
int stitch_edge_T
int top_offset
int stitch_start_vert_index
int end_vert_index
bool sub_edges_created_in_reverse_order
Definition: subd_subpatch.h:37
int get_vert_along_edge(int n) const
struct Edge * edge
Definition: subd_subpatch.h:39
bool indices_decrease_along_edge
Definition: subd_subpatch.h:36
float max
ccl_device_inline float2 one_float2()
ccl_device_inline float2 zero_float2()