32 const float plane_co[3],
59 if (!do_bisect_flip_axis) {
70 float plane_offset[4];
72 plane_offset[3] = plane[3] - bisect_distance;
103 "symmetrize input=%avef direction=%i dist=%f use_shapekey=%b",
119 const bool use_correct_order_on_merge,
120 int **r_vert_merge_map,
121 int *r_vert_merge_map_len)
133 float plane_co[3], plane_no[3];
135 int *vtmap_a =
nullptr, *vtmap_b =
nullptr;
139 mtx[axis][axis] = -1.0f;
142 if (mirror_ob !=
nullptr) {
149 mul_m4_m4m4(tmp, tmp, ob->object_to_world().ptr());
164 float ob_scale[3] = {
171 if (
LIKELY(ob_scale_max != 0.0f)) {
172 mul_v3_fl(ob_scale, 1.0f / ob_scale_max);
177 else if (do_bisect) {
183 Mesh *mesh_bisect =
nullptr;
186 mmd,
mesh, axis, plane_co, plane_no);
190 const int src_verts_num =
mesh->verts_num;
191 const int src_edges_num =
mesh->edges_num;
193 const int src_loops_num =
mesh->corners_num;
196 mesh, src_verts_num * 2, src_edges_num * 2, src_faces.
size() * 2, src_loops_num * 2);
214 vtmap_a = *r_vert_merge_map;
215 vtmap_b = *r_vert_merge_map + src_verts_num;
217 *r_vert_merge_map_len = 0;
222 for (
int i = 0;
i < src_verts_num;
i++) {
223 const int vert_index_prev =
i;
224 const int vert_index = src_verts_num +
i;
241 if (use_correct_order_on_merge) {
246 (*r_vert_merge_map_len)++;
249 mid_v3_v3v3(positions[vert_index], positions[vert_index_prev], positions[vert_index]);
250 copy_v3_v3(positions[vert_index_prev], positions[vert_index]);
263 *vtmap_a = src_verts_num +
i;
264 (*r_vert_merge_map_len)++;
267 mid_v3_v3v3(positions[vert_index], positions[vert_index_prev], positions[vert_index]);
268 copy_v3_v3(positions[vert_index_prev], positions[vert_index]);
285 for (a = 0; a < totshape; a++) {
286 float (*
cos)[3] =
static_cast<float (*)[3]
>(
288 for (
int i = src_verts_num;
i <
result->verts_num;
i++) {
300 result_edges[
i] += src_verts_num;
305 result_face_offsets[src_faces.
size() +
i] = src_faces[
i].start() + src_loops_num;
312 const int mirror_i = src_faces.
size() +
i;
320 for (
int j = 1; j < mirror_face.
size(); j++) {
322 &
mesh->corner_data, &
result->corner_data, src_face[j], mirror_face.
last(j - 1), 1);
326 const int e = mirror_face_edges.
first();
327 for (
int j = 0; j < mirror_face.
size() - 1; j++) {
328 mirror_face_edges[j] = mirror_face_edges[j + 1];
330 mirror_face_edges.
last() =
e;
335 result_corner_verts[
i] += src_verts_num;
338 result_corner_edges[
i] += src_edges_num;
341 if (!
mesh->runtime->subsurf_optimal_display_edges.is_empty()) {
343 result->runtime->subsurf_optimal_display_edges.resize(
result->edges_num);
361 for (a = 0; a < totuv; a++) {
364 int j = src_loops_num;
366 for (; j-- > 0; uv_map++) {
368 float u = (*uv_map)[0];
373 (*uv_map)[0] = 1.0f - u + mmd->
uv_offset[0];
377 float v = (*uv_map)[1];
414 result->vert_to_face_map(),
415 result->face_normals_true(),
425 const int mirror_i = src_faces.
size() +
i;
427 for (
const int j : src_face) {
428 int mirrorj = result_faces[mirror_i].start();
429 if (j > src_face.
start()) {
430 mirrorj += result_faces[mirror_i].
size() - (j - src_face.
start());
433 copy_v3_v3(corner_normals[mirrorj], corner_normals[j]);
434 mul_m4_v3(mtx_nor, corner_normals[mirrorj]);
438 lnors_spacearr.
spaces[space_index], corner_normals[mirrorj]);
450 int flip_map_len = 0;
453 for (
int i = 0;
i < src_verts_num; dvert++,
i++) {
455 if (use_correct_order_on_merge && do_vtargetmap &&
456 ((*r_vert_merge_map)[
i + src_verts_num] != -1))
460 else if (!use_correct_order_on_merge && do_vtargetmap && ((*r_vert_merge_map)[
i] != -1))
474 if (mesh_bisect !=
nullptr) {
void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
void * CustomData_get_layer_n_for_write(CustomData *data, eCustomDataType type, int n, int totelem)
void BKE_id_free(Main *bmain, void *idv)
Mesh * BKE_mesh_new_nomain_from_template(const Mesh *me_src, int verts_num, int edges_num, int faces_num, int corners_num)
Mesh * BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
BMesh * BKE_mesh_to_bmesh_ex(const Mesh *mesh, const BMeshCreateParams *create_params, const BMeshFromMeshParams *convert_params)
MINLINE float max_fff(float a, float b, float c)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
#define mul_m4_series(...)
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void transpose_m4(float R[4][4])
void unit_m4(float m[4][4])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v3_v3(float r[3], const float a[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE bool is_zero_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3(float r[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
#define CD_MASK_ORIGINDEX
@ MOD_MIR_BISECT_FLIP_AXIS_X
@ MOD_MIR_BISECT_FLIP_AXIS_Z
@ MOD_MIR_BISECT_FLIP_AXIS_Y
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
Mesh * BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, Object *ob, const Mesh *mesh, const int axis, const bool use_correct_order_on_merge, int **r_vert_merge_map, int *r_vert_merge_map_len)
void BKE_mesh_mirror_apply_mirror_on_axis(Main *bmain, Mesh *mesh, const int axis, const float dist)
Mesh * BKE_mesh_mirror_bisect_on_mirror_plane_for_modifier(MirrorModifierData *mmd, const Mesh *mesh, int axis, const float plane_co[3], float plane_no[3])
void BM_mesh_bisect_plane(BMesh *bm, const float plane[4], const bool use_snap_center, const bool use_tag, const short oflag_center, const short oflag_new, const float eps)
void BM_vert_kill(BMesh *bm, BMVert *v)
#define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype)
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParams *params)
bool BMO_op_callf(BMesh *bm, int flag, const char *fmt,...)
#define BMO_FLAG_DEFAULTS
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
const CPPType & type() const
VMutableArray< T > typed() const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr int64_t start() const
constexpr IndexRange drop_front(int64_t n) const
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr T & first() const
constexpr IndexRange index_range() const
constexpr void copy_from(Span< T > values) const
constexpr MutableSpan take_front(const int64_t n) const
constexpr T & last(const int64_t n=0) const
void copy_from(const BitSpan other)
MutableBitSpan take_back(const int64_t n) const
MutableBoundedBitSpan take_front(const int64_t n) const
void copy_from(const BitSpan other)
GAttributeReader lookup(const StringRef attribute_id) const
GAttributeWriter lookup_for_write(StringRef attribute_id)
IndexRange index_range() const
VecBase< short, 2 > short2
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void normals_calc_corners(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, GroupedSpan< int > vert_to_face_map, Span< float3 > face_normals, Span< bool > sharp_edges, Span< bool > sharp_faces, Span< short2 > custom_normals, CornerNormalSpaceArray *r_fan_spaces, MutableSpan< float3 > r_corner_normals)
short2 corner_space_custom_normal_to_data(const CornerNormalSpace &lnor_space, const float3 &custom_lnor)
struct CustomData_MeshMasks cd_mask_extra
struct Object * mirror_ob
Array< int > corner_space_indices
Vector< CornerNormalSpace > spaces