Fix T64842: crash rendering files with bevel curves
[blender.git] / source / blender / blenkernel / BKE_shrinkwrap.h
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) Blender Foundation.
17  * All rights reserved.
18  */
19 #ifndef __BKE_SHRINKWRAP_H__
20 #define __BKE_SHRINKWRAP_H__
21
22 /** \file
23  * \ingroup bke
24  */
25
26 /* Shrinkwrap stuff */
27 #include "BKE_bvhutils.h"
28 #include "BLI_bitmap.h"
29
30 /*
31  * Shrinkwrap is composed by a set of functions and options that define the type of shrink.
32  *
33  * 3 modes are available:
34  * - Nearest vertex
35  * - Nearest surface
36  * - Normal projection
37  *
38  * ShrinkwrapCalcData encapsulates all needed data for shrinkwrap functions.
39  * (So that you don't have to pass an enormous amount of arguments to functions)
40  */
41
42 struct BVHTree;
43 struct MDeformVert;
44 struct MVert;
45 struct Mesh;
46 struct ModifierEvalContext;
47 struct Object;
48 struct ShrinkwrapModifierData;
49 struct SpaceTransform;
50
51 /* Information about boundary edges in the mesh. */
52 typedef struct ShrinkwrapBoundaryVertData {
53   /* Average direction of edges that meet here. */
54   float direction[3];
55
56   /* Closest vector to direction that is orthogonal to vertex normal. */
57   float normal_plane[3];
58 } ShrinkwrapBoundaryVertData;
59
60 typedef struct ShrinkwrapBoundaryData {
61   /* True if the edge belongs to exactly one face. */
62   const BLI_bitmap *edge_is_boundary;
63   /* True if the looptri has any boundary edges. */
64   const BLI_bitmap *looptri_has_boundary;
65
66   /* Mapping from vertex index to boundary vertex index, or -1.
67    * Used for compact storage of data about boundary vertices. */
68   const int *vert_boundary_id;
69   unsigned int num_boundary_verts;
70
71   /* Direction data about boundary vertices. */
72   const ShrinkwrapBoundaryVertData *boundary_verts;
73 } ShrinkwrapBoundaryData;
74
75 void BKE_shrinkwrap_discard_boundary_data(struct Mesh *mesh);
76 void BKE_shrinkwrap_compute_boundary_data(struct Mesh *mesh);
77
78 /* Information about a mesh and BVH tree. */
79 typedef struct ShrinkwrapTreeData {
80   Mesh *mesh;
81
82   BVHTree *bvh;
83   BVHTreeFromMesh treeData;
84
85   float (*pnors)[3];
86   float (*clnors)[3];
87   ShrinkwrapBoundaryData *boundary;
88 } ShrinkwrapTreeData;
89
90 /* Checks if the modifier needs target normals with these settings. */
91 bool BKE_shrinkwrap_needs_normals(int shrinkType, int shrinkMode);
92
93 /* Initializes the mesh data structure from the given mesh and settings. */
94 bool BKE_shrinkwrap_init_tree(struct ShrinkwrapTreeData *data,
95                               Mesh *mesh,
96                               int shrinkType,
97                               int shrinkMode,
98                               bool force_normals);
99
100 /* Frees the tree data if necessary. */
101 void BKE_shrinkwrap_free_tree(struct ShrinkwrapTreeData *data);
102
103 /* Implementation of the Shrinkwrap modifier */
104 void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd,
105                                const struct ModifierEvalContext *ctx,
106                                struct Scene *scene,
107                                struct Object *ob,
108                                struct Mesh *mesh,
109                                struct MDeformVert *dvert,
110                                const int defgrp_index,
111                                float (*vertexCos)[3],
112                                int numVerts);
113
114 /*
115  * This function casts a ray in the given BVHTree.
116  * but it takes into consideration the space_transform, that is:
117  *
118  * if transf was configured with "SPACE_TRANSFORM_SETUP( &transf,  ob1, ob2 )"
119  * then the input (vert, dir, BVHTreeRayHit) must be defined in ob1 coordinates space
120  * and the BVHTree must be built in ob2 coordinate space.
121  *
122  * Thus it provides an easy way to cast the same ray across several trees
123  * (where each tree was built on its own coords space)
124  */
125 bool BKE_shrinkwrap_project_normal(char options,
126                                    const float vert[3],
127                                    const float dir[3],
128                                    const float ray_radius,
129                                    const struct SpaceTransform *transf,
130                                    struct ShrinkwrapTreeData *tree,
131                                    BVHTreeRayHit *hit);
132
133 /* Maps the point to the nearest surface, either by simple nearest,
134  * or by target normal projection. */
135 void BKE_shrinkwrap_find_nearest_surface(struct ShrinkwrapTreeData *tree,
136                                          struct BVHTreeNearest *nearest,
137                                          float co[3],
138                                          int type);
139
140 /* Computes a smooth normal of the target (if applicable) at the hit location. */
141 void BKE_shrinkwrap_compute_smooth_normal(const struct ShrinkwrapTreeData *tree,
142                                           const struct SpaceTransform *transform,
143                                           int looptri_idx,
144                                           const float hit_co[3],
145                                           const float hit_no[3],
146                                           float r_no[3]);
147
148 /* Apply the shrink to surface modes to the given original coordinates and nearest point. */
149 void BKE_shrinkwrap_snap_point_to_surface(const struct ShrinkwrapTreeData *tree,
150                                           const struct SpaceTransform *transform,
151                                           int mode,
152                                           int hit_idx,
153                                           const float hit_co[3],
154                                           const float hit_no[3],
155                                           float goal_dist,
156                                           const float point_co[3],
157                                           float r_point_co[3]);
158
159 /*
160  * NULL initializers to local data
161  */
162 #define NULL_ShrinkwrapCalcData \
163   { \
164     NULL, \
165   }
166 #define NULL_BVHTreeFromMesh \
167   { \
168     NULL, \
169   }
170 #define NULL_BVHTreeRayHit \
171   { \
172     NULL, \
173   }
174 #define NULL_BVHTreeNearest \
175   { \
176     0, \
177   }
178
179 #endif /* __BKE_SHRINKWRAP_H__ */