diff options
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_image.h | 21 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_modifier.py | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 2 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector.c | 25 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_270.c | 11 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_edit.c | 2 | ||||
-rw-r--r-- | source/blender/editors/mask/mask_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 27 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 46 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 50 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_view3d_types.h | 3 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_modifier.c | 13 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_screw.c | 61 |
16 files changed, 213 insertions, 64 deletions
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index e481468ea18..59db6cbd430 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -891,7 +891,7 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals *kg, int prim, i /* flip normal if necessary */ const int object_flag = kernel_tex_fetch(__object_flag, object); - if(!(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED)) { + if(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { ls->Ng = -ls->Ng; } ls->eval_fac = 1.0f; diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index 7be03dcd65a..6d6e92e73f6 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -211,6 +211,8 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float object_inverse_normal_transform(kg, sd, &N); /* project from direction vector to barycentric coordinates in triangles */ + float3 signed_N = N; + N.x = fabsf(N.x); N.y = fabsf(N.y); N.z = fabsf(N.z); @@ -280,12 +282,19 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float float4 f = make_float4(0.0f, 0.0f, 0.0f, 0.0f); uint use_alpha = stack_valid(alpha_offset); - if(weight.x > 0.0f) - f += weight.x*svm_image_texture(kg, id, co.y, co.z, srgb, use_alpha); - if(weight.y > 0.0f) - f += weight.y*svm_image_texture(kg, id, co.x, co.z, srgb, use_alpha); - if(weight.z > 0.0f) - f += weight.z*svm_image_texture(kg, id, co.y, co.x, srgb, use_alpha); + /* Map so that no textures are flipped, rotation is somewhat arbitrary. */ + if(weight.x > 0.0f) { + float2 uv = make_float2((signed_N.x < 0.0f)? 1.0f - co.y: co.y, co.z); + f += weight.x*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + } + if(weight.y > 0.0f) { + float2 uv = make_float2((signed_N.y > 0.0f)? 1.0f - co.x: co.x, co.z); + f += weight.y*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + } + if(weight.z > 0.0f) { + float2 uv = make_float2((signed_N.z > 0.0f)? 1.0f - co.y: co.y, co.x); + f += weight.z*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + } if(stack_valid(out_offset)) stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 8f6f4e7010f..e9dc5b214c6 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -747,6 +747,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "steps") col.prop(md, "render_steps") col.prop(md, "use_smooth_shade") + col.prop(md, "use_merge_vertices") + sub = col.column() + sub.active = md.use_merge_vertices + sub.prop(md, "merge_threshold") col = split.column() row = col.row() diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index b0f5f21288c..1c6bc7f98a2 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1019,7 +1019,7 @@ static void vectomat(const float vec[3], const float target_up[3], short axis, s } /* project the up vector onto the plane specified by n */ - project_v3_v3v3(proj, u, n); /* first u onto n... */ + project_v3_v3v3_normalized(proj, u, n); /* first u onto n... */ sub_v3_v3v3(proj, u, proj); /* then onto the plane */ /* proj specifies the transformation of the up axis */ diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 120f3bb5ac3..e4e0bf22de0 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -300,6 +300,8 @@ void angle_poly_v3(float *angles, const float *verts[3], int len); void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2]); void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3]); +void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_proj[2]); +void project_v3_v3v3_normalized(float out[3], const float p[3], const float v_proj[3]); void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3]); void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2]); void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3]); diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 40a78adcefe..05562502278 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -652,6 +652,31 @@ void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3]) } /** + * Project \a p onto a unit length \a v_proj + */ +void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_proj[2]) +{ + BLI_ASSERT_UNIT_V2(v_proj); + const float mul = dot_v2v2(p, v_proj); + + out[0] = mul * v_proj[0]; + out[1] = mul * v_proj[1]; +} + +/** + * Project \a p onto a unit length \a v_proj + */ +void project_v3_v3v3_normalized(float out[3], const float p[3], const float v_proj[3]) +{ + BLI_ASSERT_UNIT_V3(v_proj); + const float mul = dot_v3v3(p, v_proj); + + out[0] = mul * v_proj[0]; + out[1] = mul * v_proj[1]; + out[2] = mul * v_proj[2]; +} + +/** * In this case plane is a 3D vector only (no 4th component). * * Projecting will make \a c a copy of \a v orthogonal to \a v_plane. diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index cabb1409603..9f17b8d3c5c 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1692,6 +1692,17 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } } + + { + /* Fix for invalid state of screen due to bug in older versions. */ + for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) { + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { + if(sa->full && sc->state == SCREENNORMAL) { + sa->full = NULL; + } + } + } + } } void do_versions_after_linking_270(Main *main) diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 67d5a038c78..51b76563c72 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -222,7 +222,7 @@ float ED_rollBoneToVector(EditBone *bone, const float align_axis[3], const bool vec_roll_to_mat3_normalized(nor, 0.0f, mat); /* project the new_up_axis along the normal */ - project_v3_v3v3(vec, align_axis, nor); + project_v3_v3v3_normalized(vec, align_axis, nor); sub_v3_v3v3(align_axis_proj, align_axis, vec); if (axis_only) { diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 7bd8d9de278..d299bba93c3 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1000,7 +1000,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event) if (weight) { sub_v2_v2v2(c, offco, p); - project_v2_v2v2(vec, c, no); + project_v2_v2v2_normalized(vec, c, no); w = len_v2(vec); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 56fe11a5006..fca2def644c 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1472,17 +1472,28 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s if (sa && sa->full) { WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); /* restoring back to SCREENNORMAL */ - ScrArea *old; - sc = sa->full; /* the old screen to restore */ oldscreen = WM_window_get_active_screen(win); /* the one disappearing */ sc->state = SCREENNORMAL; - /* find old area */ - for (old = sc->areabase.first; old; old = old->next) - if (old->full) break; - if (old == NULL) { + /* find old area to restore from */ + ScrArea *fullsa = NULL; + for (ScrArea *old = sc->areabase.first; old; old = old->next) { + /* area to restore from is always first */ + if (old->full && !fullsa) { + fullsa = old; + } + + /* clear full screen state */ + old->full = NULL; + old->flag &= ~AREA_TEMP_INFO; + } + + sa->flag &= ~AREA_TEMP_INFO; + sa->full = NULL; + + if (fullsa == NULL) { if (G.debug & G_DEBUG) printf("%s: something wrong in areafullscreen\n", __func__); return NULL; @@ -1495,9 +1506,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s } } - ED_area_data_swap(old, sa); - if (sa->flag & AREA_TEMP_INFO) sa->flag &= ~AREA_TEMP_INFO; - old->full = NULL; + ED_area_data_swap(fullsa, sa); /* animtimer back */ sc->animtimer = oldscreen->animtimer; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index a6636f9ffb3..9654ff74f54 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1404,33 +1404,31 @@ static void view3d_id_remap(ScrArea *sa, SpaceLink *slink, ID *old_id, ID *new_i } } } - if ((ID *)v3d->ob_centre == old_id) { - v3d->ob_centre = (Object *)new_id; - if (new_id == NULL) { /* Otherwise, bonename may remain valid... We could be smart and check this, too? */ - v3d->ob_centre_bone[0] = '\0'; - } - } - if ((ID *)v3d->defmaterial == old_id) { - v3d->defmaterial = (Material *)new_id; - } -#if 0 /* XXX Deprecated? */ - if ((ID *)v3d->gpd == old_id) { - v3d->gpd = (bGPData *)new_id; - } -#endif + /* Values in local-view aren't used, see: T52663 */ + if (is_local == false) { + /* Skip 'v3d->defmaterial', it's not library data. */ - if (ELEM(GS(old_id->name), ID_IM, ID_MC)) { - for (BGpic *bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { - if ((ID *)bgpic->ima == old_id) { - bgpic->ima = (Image *)new_id; - id_us_min(old_id); - id_us_plus(new_id); + if ((ID *)v3d->ob_centre == old_id) { + v3d->ob_centre = (Object *)new_id; + /* Otherwise, bonename may remain valid... We could be smart and check this, too? */ + if (new_id == NULL) { + v3d->ob_centre_bone[0] = '\0'; } - if ((ID *)bgpic->clip == old_id) { - bgpic->clip = (MovieClip *)new_id; - id_us_min(old_id); - id_us_plus(new_id); + } + + if (ELEM(GS(old_id->name), ID_IM, ID_MC)) { + for (BGpic *bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { + if ((ID *)bgpic->ima == old_id) { + bgpic->ima = (Image *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } + if ((ID *)bgpic->clip == old_id) { + bgpic->clip = (MovieClip *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } } } } diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index b060031c27f..3a47aea405e 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -3383,15 +3383,17 @@ void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha) } void node_tex_image_box(vec3 texco, - vec3 nob, + vec3 N, sampler2D ima, float blend, out vec4 color, out float alpha) { + vec3 signed_N = N; + /* project from direction vector to barycentric coordinates in triangles */ - nob = vec3(abs(nob.x), abs(nob.y), abs(nob.z)); - nob /= (nob.x + nob.y + nob.z); + N = vec3(abs(N.x), abs(N.y), abs(N.z)); + N /= (N.x + N.y + N.z); /* basic idea is to think of this as a triangle, each corner representing * one of the 3 faces of the cube. in the corners we have single textures, @@ -3407,37 +3409,37 @@ void node_tex_image_box(vec3 texco, float limit = 0.5 * (1.0 + blend); /* first test for corners with single texture */ - if (nob.x > limit * (nob.x + nob.y) && nob.x > limit * (nob.x + nob.z)) { + if (N.x > limit * (N.x + N.y) && N.x > limit * (N.x + N.z)) { weight.x = 1.0; } - else if (nob.y > limit * (nob.x + nob.y) && nob.y > limit * (nob.y + nob.z)) { + else if (N.y > limit * (N.x + N.y) && N.y > limit * (N.y + N.z)) { weight.y = 1.0; } - else if (nob.z > limit * (nob.x + nob.z) && nob.z > limit * (nob.y + nob.z)) { + else if (N.z > limit * (N.x + N.z) && N.z > limit * (N.y + N.z)) { weight.z = 1.0; } else if (blend > 0.0) { /* in case of blending, test for mixes between two textures */ - if (nob.z < (1.0 - limit) * (nob.y + nob.x)) { - weight.x = nob.x / (nob.x + nob.y); + if (N.z < (1.0 - limit) * (N.y + N.x)) { + weight.x = N.x / (N.x + N.y); weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); weight.y = 1.0 - weight.x; } - else if (nob.x < (1.0 - limit) * (nob.y + nob.z)) { - weight.y = nob.y / (nob.y + nob.z); + else if (N.x < (1.0 - limit) * (N.y + N.z)) { + weight.y = N.y / (N.y + N.z); weight.y = clamp((weight.y - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); weight.z = 1.0 - weight.y; } - else if (nob.y < (1.0 - limit) * (nob.x + nob.z)) { - weight.x = nob.x / (nob.x + nob.z); + else if (N.y < (1.0 - limit) * (N.x + N.z)) { + weight.x = N.x / (N.x + N.z); weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); weight.z = 1.0 - weight.x; } else { /* last case, we have a mix between three */ - weight.x = ((2.0 - limit) * nob.x + (limit - 1.0)) / (2.0 * limit - 1.0); - weight.y = ((2.0 - limit) * nob.y + (limit - 1.0)) / (2.0 * limit - 1.0); - weight.z = ((2.0 - limit) * nob.z + (limit - 1.0)) / (2.0 * limit - 1.0); + weight.x = ((2.0 - limit) * N.x + (limit - 1.0)) / (2.0 * limit - 1.0); + weight.y = ((2.0 - limit) * N.y + (limit - 1.0)) / (2.0 * limit - 1.0); + weight.z = ((2.0 - limit) * N.z + (limit - 1.0)) / (2.0 * limit - 1.0); } } else { @@ -3446,13 +3448,25 @@ void node_tex_image_box(vec3 texco, } color = vec4(0); if (weight.x > 0.0) { - color += weight.x * texture(ima, texco.yz); + vec2 uv = texco.yz; + if(signed_N.x < 0.0) { + uv.x = 1.0 - uv.x; + } + color += weight.x * texture(ima, uv); } if (weight.y > 0.0) { - color += weight.y * texture(ima, texco.xz); + vec2 uv = texco.xz; + if(signed_N.y > 0.0) { + uv.x = 1.0 - uv.x; + } + color += weight.y * texture(ima, uv); } if (weight.z > 0.0) { - color += weight.z * texture(ima, texco.yx); + vec2 uv = texco.yx; + if(signed_N.z > 0.0) { + uv.x = 1.0 - uv.x; + } + color += weight.z * texture(ima, uv); } alpha = color.a; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index c185f84997e..e0d1831a7e0 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -924,9 +924,10 @@ typedef struct ScrewModifierData { unsigned int iter; float screw_ofs; float angle; - char axis; - char pad; + float merge_dist; short flag; + char axis; + char pad[5]; } ScrewModifierData; enum { @@ -937,6 +938,7 @@ enum { MOD_SCREW_SMOOTH_SHADING = (1 << 5), MOD_SCREW_UV_STRETCH_U = (1 << 6), MOD_SCREW_UV_STRETCH_V = (1 << 7), + MOD_SCREW_MERGE = (1 << 8), }; typedef struct OceanModifierData { diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 6a9b979596b..2af89a8eff0 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -234,7 +234,8 @@ typedef struct View3D { struct GPUFXSettings fx_settings; void *properties_storage; /* Nkey panel stores stuff here (runtime only!) */ - struct Material *defmaterial; /* used by matcap now */ + /* Allocated per view, not library data (used by matcap). */ + struct Material *defmaterial; /* XXX deprecated? */ struct bGPdata *gpd DNA_DEPRECATED; /* Grease-Pencil Data (annotation layers) */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 03340c6c356..9f083c851a0 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3410,6 +3410,13 @@ static void rna_def_modifier_screw(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Screw", "Offset the revolution along its axis"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "merge_threshold", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_sdna(prop, NULL, "merge_dist"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_range(prop, 0, 1, 1, 4); + RNA_def_property_ui_text(prop, "Merge Distance", "Limit below which to merge vertices"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_normal_flip", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SCREW_NORMAL_FLIP); RNA_def_property_ui_text(prop, "Flip", "Flip normals of lathed faces"); @@ -3425,6 +3432,12 @@ static void rna_def_modifier_screw(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object Screw", "Use the distance between the objects to make a screw"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + /* Vertex merging parameters */ + prop = RNA_def_property(srna, "use_merge_vertices", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SCREW_MERGE); + RNA_def_property_ui_text(prop, "Merge Vertices", "Merge adjacent vertices (screw offset must be zero)"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_smooth_shade", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SCREW_SMOOTH_SHADING); RNA_def_property_ui_text(prop, "Smooth Shading", "Output faces with smooth shading rather than flat shaded"); diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index b951c4afc00..010bf8bf092 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -111,6 +111,56 @@ static void screwvert_iter_step(ScrewVertIter *iter) } } +static DerivedMesh *dm_remove_doubles_on_axis( + DerivedMesh *result, MVert *mvert_new, const uint totvert, const uint step_tot, + const float axis_vec[3], const float axis_offset[3], const float merge_threshold) +{ + const float merge_threshold_sq = SQUARE(merge_threshold); + const bool use_offset = axis_offset != NULL; + uint tot_doubles = 0; + for (uint i = 0; i < totvert; i += 1) { + float axis_co[3]; + if (use_offset) { + float offset_co[3]; + sub_v3_v3v3(offset_co, mvert_new[i].co, axis_offset); + project_v3_v3v3_normalized(axis_co, offset_co, axis_vec); + add_v3_v3(axis_co, axis_offset); + } + else { + project_v3_v3v3_normalized(axis_co, mvert_new[i].co, axis_vec); + } + const float dist_sq = len_squared_v3v3(axis_co, mvert_new[i].co); + if (dist_sq <= merge_threshold_sq) { + mvert_new[i].flag |= ME_VERT_TMP_TAG; + tot_doubles += 1; + copy_v3_v3(mvert_new[i].co, axis_co); + } + } + + if (tot_doubles != 0) { + uint tot = totvert * step_tot; + int *full_doubles_map = MEM_mallocN(sizeof(int) * tot, __func__); + copy_vn_i(full_doubles_map, (int)tot, -1); + + uint tot_doubles_left = tot_doubles; + for (uint i = 0; i < totvert; i += 1) { + if (mvert_new[i].flag & ME_VERT_TMP_TAG) { + int *doubles_map = &full_doubles_map[totvert + i] ; + for (uint step = 1; step < step_tot; step += 1) { + *doubles_map = (int)i; + doubles_map += totvert; + } + tot_doubles_left -= 1; + if (tot_doubles_left == 0) { + break; + } + } + } + result = CDDM_merge_verts(result, full_doubles_map, (int)(tot_doubles * (step_tot - 1)), CDDM_MERGE_VERTS_DUMP_IF_MAPPED); + MEM_freeN(full_doubles_map); + } + return result; +} static void initData(ModifierData *md) { @@ -122,6 +172,7 @@ static void initData(ModifierData *md) ltmd->steps = 16; ltmd->render_steps = 16; ltmd->iter = 1; + ltmd->merge_dist = 0.01f; } static void copyData(ModifierData *md, ModifierData *target) @@ -1049,6 +1100,16 @@ static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationConte MEM_freeN(vert_loop_map); } + if ((ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f)) { + DerivedMesh *result_prev = result; + result = dm_remove_doubles_on_axis( + result, mvert_new, totvert, step_tot, + axis_vec, ltmd->ob_axis ? mtx_tx[3] : NULL, ltmd->merge_dist); + if (result != result_prev) { + result->dirty |= DM_DIRTY_NORMALS; + } + } + if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) { result->dirty |= DM_DIRTY_NORMALS; } |