Blender  V2.93
multires_reshape_vertcos.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "multires_reshape.h"
25 
26 #include "DNA_mesh_types.h"
27 #include "DNA_meshdata_types.h"
28 
29 #include "BLI_math_vector.h"
30 
31 #include "BKE_subdiv_foreach.h"
32 #include "BKE_subdiv_mesh.h"
33 
36 
37  const float (*vert_coords)[3];
38  const int num_vert_coords;
40 
46  const SubdivForeachContext *foreach_context,
47  const GridCoord *grid_coord,
48  const int subdiv_vertex_index)
49 {
50  MultiresReshapeAssignVertcosContext *reshape_vertcos_context = foreach_context->user_data;
51  const float *coordinate = reshape_vertcos_context->vert_coords[subdiv_vertex_index];
52 
54  reshape_vertcos_context->reshape_context, grid_coord);
55  BLI_assert(grid_element.displacement != NULL);
56  copy_v3_v3(grid_element.displacement, coordinate);
57 }
58 
59 /* TODO(sergey): De-duplicate with similar function in multires_reshape_smooth.c */
61  const PTexCoord *ptex_coord,
62  const int subdiv_vertex_index)
63 {
64  const MultiresReshapeAssignVertcosContext *reshape_vertcos_context = foreach_context->user_data;
65  const MultiresReshapeContext *reshape_context = reshape_vertcos_context->reshape_context;
66 
67  const GridCoord grid_coord = multires_reshape_ptex_coord_to_grid(reshape_context, ptex_coord);
68  const int face_index = multires_reshape_grid_to_face_index(reshape_context,
69  grid_coord.grid_index);
70 
71  const Mesh *base_mesh = reshape_context->base_mesh;
72  const MPoly *base_poly = &base_mesh->mpoly[face_index];
73  const int num_corners = base_poly->totloop;
74  const int start_grid_index = reshape_context->face_start_grid_index[face_index];
75  const int corner = grid_coord.grid_index - start_grid_index;
76 
77  if (grid_coord.u == 0.0f && grid_coord.v == 0.0f) {
78  for (int current_corner = 0; current_corner < num_corners; ++current_corner) {
79  GridCoord corner_grid_coord = grid_coord;
80  corner_grid_coord.grid_index = start_grid_index + current_corner;
82  foreach_context, &corner_grid_coord, subdiv_vertex_index);
83  }
84  return;
85  }
86 
88  foreach_context, &grid_coord, subdiv_vertex_index);
89 
90  if (grid_coord.u == 0.0f) {
91  GridCoord prev_grid_coord;
92  prev_grid_coord.grid_index = start_grid_index + ((corner + num_corners - 1) % num_corners);
93  prev_grid_coord.u = grid_coord.v;
94  prev_grid_coord.v = 0.0f;
95 
97  foreach_context, &prev_grid_coord, subdiv_vertex_index);
98  }
99 
100  if (grid_coord.v == 0.0f) {
101  GridCoord next_grid_coord;
102  next_grid_coord.grid_index = start_grid_index + ((corner + 1) % num_corners);
103  next_grid_coord.u = 0.0f;
104  next_grid_coord.v = grid_coord.u;
105 
107  foreach_context, &next_grid_coord, subdiv_vertex_index);
108  }
109 }
110 
111 /* SubdivForeachContext::topology_info() */
113  const SubdivForeachContext *foreach_context,
114  const int num_vertices,
115  const int UNUSED(num_edges),
116  const int UNUSED(num_loops),
117  const int UNUSED(num_polygons))
118 {
119  MultiresReshapeAssignVertcosContext *reshape_vertcos_context = foreach_context->user_data;
120  if (num_vertices != reshape_vertcos_context->num_vert_coords) {
121  return false;
122  }
123  return true;
124 }
125 
126 /* SubdivForeachContext::vertex_inner() */
128  const SubdivForeachContext *foreach_context,
129  void *UNUSED(tls_v),
130  const int ptex_face_index,
131  const float ptex_face_u,
132  const float ptex_face_v,
133  const int UNUSED(coarse_face_index),
134  const int UNUSED(coarse_face_corner),
135  const int subdiv_vertex_index)
136 {
137  const PTexCoord ptex_coord = {
138  .ptex_face_index = ptex_face_index,
139  .u = ptex_face_u,
140  .v = ptex_face_v,
141  };
142  multires_reshape_vertcos_foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index);
143 }
144 
145 /* SubdivForeachContext::vertex_every_corner() */
147  const struct SubdivForeachContext *foreach_context,
148  void *UNUSED(tls_v),
149  const int ptex_face_index,
150  const float ptex_face_u,
151  const float ptex_face_v,
152  const int UNUSED(coarse_vertex_index),
153  const int UNUSED(coarse_face_index),
154  const int UNUSED(coarse_face_corner),
155  const int subdiv_vertex_index)
156 {
157  const PTexCoord ptex_coord = {
158  .ptex_face_index = ptex_face_index,
159  .u = ptex_face_u,
160  .v = ptex_face_v,
161  };
162  multires_reshape_vertcos_foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index);
163 }
164 
165 /* SubdivForeachContext::vertex_every_edge() */
167  const struct SubdivForeachContext *foreach_context,
168  void *UNUSED(tls_v),
169  const int ptex_face_index,
170  const float ptex_face_u,
171  const float ptex_face_v,
172  const int UNUSED(coarse_edge_index),
173  const int UNUSED(coarse_face_index),
174  const int UNUSED(coarse_face_corner),
175  const int subdiv_vertex_index)
176 {
177  const PTexCoord ptex_coord = {
178  .ptex_face_index = ptex_face_index,
179  .u = ptex_face_u,
180  .v = ptex_face_v,
181  };
182  multires_reshape_vertcos_foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index);
183 }
184 
185 /* Set displacement grids values at a reshape level to a object coordinates of the given source. */
187  const MultiresReshapeContext *reshape_context,
188  const float (*vert_coords)[3],
189  const int num_vert_coords)
190 {
191  MultiresReshapeAssignVertcosContext reshape_vertcos_context = {
192  .reshape_context = reshape_context,
193  .vert_coords = vert_coords,
194  .num_vert_coords = num_vert_coords,
195  };
196 
197  SubdivForeachContext foreach_context = {
202  .user_data = &reshape_vertcos_context,
203  };
204 
205  SubdivToMeshSettings mesh_settings;
206  mesh_settings.resolution = (1 << reshape_context->reshape.level) + 1;
207  mesh_settings.use_optimal_display = false;
208 
210  reshape_context->subdiv, &foreach_context, &mesh_settings, reshape_context->base_mesh);
211 }
typedef float(TangentPoint)[2]
bool BKE_subdiv_foreach_subdiv_geometry(struct Subdiv *subdiv, const struct SubdivForeachContext *context, const struct SubdivToMeshSettings *mesh_settings, const struct Mesh *coarse_mesh)
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define UNUSED(x)
int multires_reshape_grid_to_face_index(const MultiresReshapeContext *reshape_context, int grid_index)
ReshapeGridElement multires_reshape_grid_element_for_grid_coord(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord)
GridCoord multires_reshape_ptex_coord_to_grid(const MultiresReshapeContext *reshape_context, const PTexCoord *ptex_coord)
static void multires_reshape_vertcos_foreach_single_vertex(const SubdivForeachContext *foreach_context, const GridCoord *grid_coord, const int subdiv_vertex_index)
static void multires_reshape_vertcos_foreach_vertex(const SubdivForeachContext *foreach_context, const PTexCoord *ptex_coord, const int subdiv_vertex_index)
static void multires_reshape_vertcos_foreach_vertex_every_edge(const struct SubdivForeachContext *foreach_context, void *UNUSED(tls_v), const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, const int UNUSED(coarse_edge_index), const int UNUSED(coarse_face_index), const int UNUSED(coarse_face_corner), const int subdiv_vertex_index)
static void multires_reshape_vertcos_foreach_vertex_every_corner(const struct SubdivForeachContext *foreach_context, void *UNUSED(tls_v), const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, const int UNUSED(coarse_vertex_index), const int UNUSED(coarse_face_index), const int UNUSED(coarse_face_corner), const int subdiv_vertex_index)
static bool multires_reshape_vertcos_foreach_topology_info(const SubdivForeachContext *foreach_context, const int num_vertices, const int UNUSED(num_edges), const int UNUSED(num_loops), const int UNUSED(num_polygons))
bool multires_reshape_assign_final_coords_from_vertcos(const MultiresReshapeContext *reshape_context, const float(*vert_coords)[3], const int num_vert_coords)
static void multires_reshape_vertcos_foreach_vertex_inner(const SubdivForeachContext *foreach_context, void *UNUSED(tls_v), const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, const int UNUSED(coarse_face_index), const int UNUSED(coarse_face_corner), const int subdiv_vertex_index)
struct MultiresReshapeAssignVertcosContext MultiresReshapeAssignVertcosContext
struct MPoly * mpoly
const MultiresReshapeContext * reshape_context
struct MultiresReshapeContext::@99 reshape
struct Subdiv * subdiv
SubdivForeachTopologyInformationCb topology_info