forked from bartvdbraak/blender
Transform: New Snap Option: Edge Perpendicular
Part of T66420 Option for snapping to the nearest point of a reference coordinate. The patch also adds Edge Center and Perpendicular snaps to the ruler. {F7675906} Reviewers: campbellbarton, brecht Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D5543
This commit is contained in:
parent
2db09212fc
commit
dd08d68df8
@ -5295,6 +5295,14 @@
|
|||||||
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.6;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new" d="m 178.5,158 c -0.1326,3e-5 -0.25976,0.0527 -0.35352,0.14649 l -1.99219,1.99218 c -0.11574,0.11126 -0.14648,0.23321 -0.14648,0.35352 v 1.90729 h 1 l 0.008,-1.70825 L 178.70703,159 H 187 v 8.29297 l -2.70703,2.70508 -7.28522,-0.003 v -1.55553 l -1,-10e-4 v 2.06253 c 0.008,0.28778 0.21557,0.51105 0.50025,0.5 h 7.992 c 0.1326,-3e-5 0.25975,-0.0527 0.35351,-0.14648 l 3,-3 c 0.0938,-0.0938 0.14646,-0.22092 0.14649,-0.35352 v -9 c -3e-5,-0.27613 -0.22387,-0.49997 -0.5,-0.5 z" id="path22118-4" inkscape:connector-curvature="0" sodipodi:nodetypes="cccsccccccccccccccccccc" />
|
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.6;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new" d="m 178.5,158 c -0.1326,3e-5 -0.25976,0.0527 -0.35352,0.14649 l -1.99219,1.99218 c -0.11574,0.11126 -0.14648,0.23321 -0.14648,0.35352 v 1.90729 h 1 l 0.008,-1.70825 L 178.70703,159 H 187 v 8.29297 l -2.70703,2.70508 -7.28522,-0.003 v -1.55553 l -1,-10e-4 v 2.06253 c 0.008,0.28778 0.21557,0.51105 0.50025,0.5 h 7.992 c 0.1326,-3e-5 0.25975,-0.0527 0.35351,-0.14648 l 3,-3 c 0.0938,-0.0938 0.14646,-0.22092 0.14649,-0.35352 v -9 c -3e-5,-0.27613 -0.22387,-0.49997 -0.5,-0.5 z" id="path22118-4" inkscape:connector-curvature="0" sodipodi:nodetypes="cccsccccccccccccccccccc" />
|
||||||
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 174.5,163.36793 c -0.27613,3e-5 -0.49997,0.22387 -0.5,0.5 v 3 c 3e-5,0.27613 0.22387,0.49997 0.5,0.5 h 3 c 0.27613,-3e-5 0.49997,-0.22387 0.5,-0.5 v -3 c -3e-5,-0.27613 -0.22387,-0.49997 -0.5,-0.5 z" id="path22124-6" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccc" />
|
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 174.5,163.36793 c -0.27613,3e-5 -0.49997,0.22387 -0.5,0.5 v 3 c 3e-5,0.27613 0.22387,0.49997 0.5,0.5 h 3 c 0.27613,-3e-5 0.49997,-0.22387 0.5,-0.5 v -3 c -3e-5,-0.27613 -0.22387,-0.49997 -0.5,-0.5 z" id="path22124-6" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccc" />
|
||||||
</g>
|
</g>
|
||||||
|
<g id="g12955">
|
||||||
|
<g inkscape:export-ydpi="96" inkscape:export-xdpi="96" inkscape:export-filename="C:\Users\Andrzej Ambroż\Desktop\mtrx.png" transform="translate(-212.98058,-205.92773)" id="g12701-3-4-7" style="display:inline;fill:#ffffff;enable-background:new" />
|
||||||
|
<g id="g12966" transform="translate(-0.69998671,-0.49999787)">
|
||||||
|
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.6;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 49.49458,158.98554 c -0.27614,0.004 -0.49651,0.23167 -0.49219,0.50781 v 11.91992 c -0.0234,0.14486 0.018,0.29268 0.11328,0.4043 0.005,0.007 0.0102,0.0131 0.0156,0.0195 0.006,0.006 0.0116,0.0119 0.0176,0.0176 10e-4,6.7e-4 0.003,0.001 0.004,0.002 0.0106,0.0109 0.0217,0.0213 0.0332,0.0312 10e-4,6.7e-4 0.003,0.001 0.004,0.002 0.11078,0.0889 0.25417,0.12657 0.39435,0.10348 h 11.91797 c 0.67616,0.01 0.67616,-1.00956 0,-1 h -11.5 v -11.5 c 0.004,-0.28226 -0.22555,-0.51223 -0.50781,-0.50781 z" id="path15133-4-3" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccccccc" />
|
||||||
|
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.6;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" d="m 56.91059,169.94795 v -5.31582 c 0.0234,-0.14486 -0.018,-0.29268 -0.11328,-0.4043 -0.005,-0.007 -0.0102,-0.0131 -0.0156,-0.0195 -0.006,-0.006 -0.0116,-0.0119 -0.0176,-0.0176 -0.001,-6.7e-4 -0.003,-0.001 -0.004,-0.002 -0.0106,-0.0109 -0.0217,-0.0213 -0.0332,-0.0312 -10e-4,-6.7e-4 -0.003,-0.001 -0.004,-0.002 -0.11078,-0.0889 -0.25417,-0.12658 -0.39435,-0.10348 h -5.24715 v 1 h 4.82918 v 4.89589 z" id="path15133-4-3-2" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccccccccc" />
|
||||||
|
<path inkscape:connector-curvature="0" d="m 51.401825,168.1 c 10e-7,0.82742 0.670754,1.49817 1.49817,1.49817 0.82742,0 1.498179,-0.67075 1.49818,-1.49817 -1e-6,-0.82742 -0.67076,-1.49817 -1.49818,-1.49817 -0.827416,0 -1.498169,0.67075 -1.49817,1.49817 z" style="display:inline;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;enable-background:new" id="ellipse24887-7" sodipodi:nodetypes="ccccc" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g inkscape:groupmode="layer" id="layer2" inkscape:label="EMPTY ICON TRACKING" style="display:none">
|
<g inkscape:groupmode="layer" id="layer2" inkscape:label="EMPTY ICON TRACKING" style="display:none">
|
||||||
<g id="g16331" style="fill:#ffcc00">
|
<g id="g16331" style="fill:#ffcc00">
|
||||||
|
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 2.4 MiB |
BIN
release/datafiles/blender_icons16/icon16_snap_perpendicular.dat
Normal file
BIN
release/datafiles/blender_icons16/icon16_snap_perpendicular.dat
Normal file
Binary file not shown.
BIN
release/datafiles/blender_icons32/icon32_snap_perpendicular.dat
Normal file
BIN
release/datafiles/blender_icons32/icon32_snap_perpendicular.dat
Normal file
Binary file not shown.
@ -5680,6 +5680,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|||||||
},
|
},
|
||||||
mval,
|
mval,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
location,
|
location,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
@ -283,6 +283,7 @@ static int gizmo_move_modal(bContext *C,
|
|||||||
.use_occlusion_test = true,
|
.use_occlusion_test = true,
|
||||||
},
|
},
|
||||||
mval_fl,
|
mval_fl,
|
||||||
|
NULL,
|
||||||
&dist_px,
|
&dist_px,
|
||||||
co,
|
co,
|
||||||
NULL)) {
|
NULL)) {
|
||||||
|
@ -125,6 +125,7 @@ short ED_transform_snap_object_project_view3d_ex(struct SnapObjectContext *sctx,
|
|||||||
const unsigned short snap_to,
|
const unsigned short snap_to,
|
||||||
const struct SnapObjectParams *params,
|
const struct SnapObjectParams *params,
|
||||||
const float mval[2],
|
const float mval[2],
|
||||||
|
const float prev_co[3],
|
||||||
float *dist_px,
|
float *dist_px,
|
||||||
float r_loc[3],
|
float r_loc[3],
|
||||||
float r_no[3],
|
float r_no[3],
|
||||||
@ -135,6 +136,7 @@ bool ED_transform_snap_object_project_view3d(struct SnapObjectContext *sctx,
|
|||||||
const unsigned short snap_to,
|
const unsigned short snap_to,
|
||||||
const struct SnapObjectParams *params,
|
const struct SnapObjectParams *params,
|
||||||
const float mval[2],
|
const float mval[2],
|
||||||
|
const float prev_co[3],
|
||||||
float *dist_px,
|
float *dist_px,
|
||||||
/* return args */
|
/* return args */
|
||||||
float r_loc[3],
|
float r_loc[3],
|
||||||
|
@ -667,7 +667,7 @@ DEF_ICON(PARTICLE_PATH)
|
|||||||
/* EDITING */
|
/* EDITING */
|
||||||
DEF_ICON_BLANK(669)
|
DEF_ICON_BLANK(669)
|
||||||
DEF_ICON_BLANK(670)
|
DEF_ICON_BLANK(670)
|
||||||
DEF_ICON_BLANK(671)
|
DEF_ICON(SNAP_PERPENDICULAR)
|
||||||
DEF_ICON(SNAP_MIDPOINT)
|
DEF_ICON(SNAP_MIDPOINT)
|
||||||
DEF_ICON(SNAP_OFF)
|
DEF_ICON(SNAP_OFF)
|
||||||
DEF_ICON(SNAP_ON)
|
DEF_ICON(SNAP_ON)
|
||||||
|
@ -437,6 +437,7 @@ void EDBM_project_snap_verts(bContext *C, Depsgraph *depsgraph, ARegion *ar, BME
|
|||||||
},
|
},
|
||||||
mval,
|
mval,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
co_proj,
|
co_proj,
|
||||||
NULL)) {
|
NULL)) {
|
||||||
mul_v3_m4v3(eve->co, obedit->imat, co_proj);
|
mul_v3_m4v3(eve->co, obedit->imat, co_proj);
|
||||||
|
@ -4944,6 +4944,7 @@ void ED_view3d_cursor3d_position_rotation(bContext *C,
|
|||||||
.use_object_edit_cage = false,
|
.use_object_edit_cage = false,
|
||||||
},
|
},
|
||||||
mval_fl,
|
mval_fl,
|
||||||
|
NULL,
|
||||||
&dist_px,
|
&dist_px,
|
||||||
ray_co,
|
ray_co,
|
||||||
ray_no,
|
ray_no,
|
||||||
|
@ -343,6 +343,7 @@ static bool view3d_ruler_item_mousemove(RulerInfo *ruler_info,
|
|||||||
.use_object_edit_cage = true,
|
.use_object_edit_cage = true,
|
||||||
},
|
},
|
||||||
mval_fl,
|
mval_fl,
|
||||||
|
NULL,
|
||||||
&dist_px,
|
&dist_px,
|
||||||
co,
|
co,
|
||||||
ray_normal)) {
|
ray_normal)) {
|
||||||
@ -363,16 +364,31 @@ static bool view3d_ruler_item_mousemove(RulerInfo *ruler_info,
|
|||||||
}
|
}
|
||||||
else if (do_snap) {
|
else if (do_snap) {
|
||||||
const float mval_fl[2] = {UNPACK2(mval)};
|
const float mval_fl[2] = {UNPACK2(mval)};
|
||||||
|
float *prev_point = NULL;
|
||||||
|
|
||||||
|
if (inter->co_index != 1) {
|
||||||
|
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
|
||||||
|
prev_point = ruler_item->co[1];
|
||||||
|
}
|
||||||
|
else if (inter->co_index == 0) {
|
||||||
|
prev_point = ruler_item->co[2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prev_point = ruler_item->co[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ED_transform_snap_object_project_view3d(
|
if (ED_transform_snap_object_project_view3d(
|
||||||
ruler_info->snap_context,
|
ruler_info->snap_context,
|
||||||
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE),
|
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
||||||
|
SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR),
|
||||||
&(const struct SnapObjectParams){
|
&(const struct SnapObjectParams){
|
||||||
.snap_select = SNAP_ALL,
|
.snap_select = SNAP_ALL,
|
||||||
.use_object_edit_cage = true,
|
.use_object_edit_cage = true,
|
||||||
.use_occlusion_test = true,
|
.use_occlusion_test = true,
|
||||||
},
|
},
|
||||||
mval_fl,
|
mval_fl,
|
||||||
|
prev_point,
|
||||||
&dist_px,
|
&dist_px,
|
||||||
co,
|
co,
|
||||||
NULL)) {
|
NULL)) {
|
||||||
|
@ -328,6 +328,7 @@ void applyProject(TransInfo *t)
|
|||||||
.use_occlusion_test = false,
|
.use_occlusion_test = false,
|
||||||
},
|
},
|
||||||
mval_fl,
|
mval_fl,
|
||||||
|
NULL,
|
||||||
0,
|
0,
|
||||||
loc,
|
loc,
|
||||||
no)) {
|
no)) {
|
||||||
@ -999,7 +1000,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
|
|||||||
mval[1] = t->mval[1];
|
mval[1] = t->mval[1];
|
||||||
|
|
||||||
if (t->tsnap.mode & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
if (t->tsnap.mode & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
||||||
SCE_SNAP_MODE_EDGE_MIDPOINT)) {
|
SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||||
zero_v3(no); /* objects won't set this */
|
zero_v3(no); /* objects won't set this */
|
||||||
found = snapObjectsTransform(t, mval, &dist_px, loc, no);
|
found = snapObjectsTransform(t, mval, &dist_px, loc, no);
|
||||||
}
|
}
|
||||||
@ -1272,6 +1273,7 @@ bool snapObjectsTransform(
|
|||||||
.use_occlusion_test = t->scene->toolsettings->snap_mode != SCE_SNAP_MODE_FACE,
|
.use_occlusion_test = t->scene->toolsettings->snap_mode != SCE_SNAP_MODE_FACE,
|
||||||
},
|
},
|
||||||
mval,
|
mval,
|
||||||
|
t->center_global,
|
||||||
dist_px,
|
dist_px,
|
||||||
r_loc,
|
r_loc,
|
||||||
r_no);
|
r_no);
|
||||||
|
@ -1260,7 +1260,8 @@ static short snap_mesh_polygon(SnapObjectContext *sctx,
|
|||||||
|
|
||||||
const MPoly *mp = &((SnapObjectData_Mesh *)sod)->poly[*r_index];
|
const MPoly *mp = &((SnapObjectData_Mesh *)sod)->poly[*r_index];
|
||||||
const MLoop *ml = &treedata->loop[mp->loopstart];
|
const MLoop *ml = &treedata->loop[mp->loopstart];
|
||||||
if (snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) {
|
if (snapdata->snap_to_flag &
|
||||||
|
(SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||||
elem = SCE_SNAP_MODE_EDGE;
|
elem = SCE_SNAP_MODE_EDGE;
|
||||||
BLI_assert(treedata->edge != NULL);
|
BLI_assert(treedata->edge != NULL);
|
||||||
for (int i = mp->totloop; i--; ml++) {
|
for (int i = mp->totloop; i--; ml++) {
|
||||||
@ -1297,7 +1298,8 @@ static short snap_mesh_polygon(SnapObjectContext *sctx,
|
|||||||
BMFace *f = BM_face_at_index(em->bm, *r_index);
|
BMFace *f = BM_face_at_index(em->bm, *r_index);
|
||||||
BMLoop *l_iter, *l_first;
|
BMLoop *l_iter, *l_first;
|
||||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||||
if (snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) {
|
if (snapdata->snap_to_flag &
|
||||||
|
(SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||||
elem = SCE_SNAP_MODE_EDGE;
|
elem = SCE_SNAP_MODE_EDGE;
|
||||||
BM_mesh_elem_index_ensure(em->bm, BM_EDGE);
|
BM_mesh_elem_index_ensure(em->bm, BM_EDGE);
|
||||||
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE);
|
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE);
|
||||||
@ -1352,6 +1354,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
|
|||||||
Object *ob,
|
Object *ob,
|
||||||
float obmat[4][4],
|
float obmat[4][4],
|
||||||
float original_dist_px,
|
float original_dist_px,
|
||||||
|
const float prev_co[3],
|
||||||
/* read/write args */
|
/* read/write args */
|
||||||
float *dist_px,
|
float *dist_px,
|
||||||
/* return args */
|
/* return args */
|
||||||
@ -1460,13 +1463,43 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prev_co && (snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||||
|
float v_near[3], va_g[3], vb_g[3];
|
||||||
|
|
||||||
|
mul_v3_m4v3(va_g, obmat, v_pair[0]);
|
||||||
|
mul_v3_m4v3(vb_g, obmat, v_pair[1]);
|
||||||
|
lambda = line_point_factor_v3(prev_co, va_g, vb_g);
|
||||||
|
|
||||||
|
if (IN_RANGE(lambda, 0.0f, 1.0f)) {
|
||||||
|
interp_v3_v3v3(v_near, va_g, vb_g, lambda);
|
||||||
|
|
||||||
|
if (test_projected_vert_dist(&neasrest_precalc,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
nearest2d.is_persp,
|
||||||
|
v_near,
|
||||||
|
&nearest.dist_sq,
|
||||||
|
nearest.co)) {
|
||||||
|
float v_nor[2][3];
|
||||||
|
nearest2d.copy_vert_no(vindex[0], v_nor[0], nearest2d.userdata);
|
||||||
|
nearest2d.copy_vert_no(vindex[1], v_nor[1], nearest2d.userdata);
|
||||||
|
mid_v3_v3v3(nearest.no, v_nor[0], v_nor[1]);
|
||||||
|
|
||||||
|
nearest.index = *r_index;
|
||||||
|
elem = SCE_SNAP_MODE_EDGE_PERPENDICULAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nearest.index != -1) {
|
if (nearest.index != -1) {
|
||||||
*dist_px = sqrtf(nearest.dist_sq);
|
*dist_px = sqrtf(nearest.dist_sq);
|
||||||
|
|
||||||
copy_v3_v3(r_loc, nearest.co);
|
copy_v3_v3(r_loc, nearest.co);
|
||||||
|
if (elem != SCE_SNAP_MODE_EDGE_PERPENDICULAR) {
|
||||||
mul_m4_v3(obmat, r_loc);
|
mul_m4_v3(obmat, r_loc);
|
||||||
|
}
|
||||||
|
|
||||||
if (r_no) {
|
if (r_no) {
|
||||||
float imat[4][4];
|
float imat[4][4];
|
||||||
@ -2092,7 +2125,8 @@ static short snapMesh(SnapObjectContext *sctx,
|
|||||||
last_index = nearest.index;
|
last_index = nearest.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) {
|
if (snapdata->snap_to_flag &
|
||||||
|
(SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||||
if (bvhtree[0]) {
|
if (bvhtree[0]) {
|
||||||
/* snap to loose edges */
|
/* snap to loose edges */
|
||||||
BLI_bvhtree_find_nearest_projected(bvhtree[0],
|
BLI_bvhtree_find_nearest_projected(bvhtree[0],
|
||||||
@ -2258,7 +2292,8 @@ static short snapEditMesh(SnapObjectContext *sctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) {
|
if (snapdata->snap_to_flag &
|
||||||
|
(SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||||
if (sod->bvh_trees[1] == NULL) {
|
if (sod->bvh_trees[1] == NULL) {
|
||||||
sod->bvh_trees[1] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees));
|
sod->bvh_trees[1] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees));
|
||||||
}
|
}
|
||||||
@ -2330,8 +2365,8 @@ static short snapEditMesh(SnapObjectContext *sctx,
|
|||||||
last_index = nearest.index;
|
last_index = nearest.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (treedata_edge &&
|
if (treedata_edge && snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||||
snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) {
|
SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||||
BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT);
|
BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT);
|
||||||
BLI_bvhtree_find_nearest_projected(treedata_edge->tree,
|
BLI_bvhtree_find_nearest_projected(treedata_edge->tree,
|
||||||
lpmat,
|
lpmat,
|
||||||
@ -2727,6 +2762,7 @@ static short transform_snap_context_project_view3d_mixed_impl(
|
|||||||
const unsigned short snap_to_flag,
|
const unsigned short snap_to_flag,
|
||||||
const struct SnapObjectParams *params,
|
const struct SnapObjectParams *params,
|
||||||
const float mval[2],
|
const float mval[2],
|
||||||
|
const float prev_co[3],
|
||||||
float *dist_px,
|
float *dist_px,
|
||||||
float r_loc[3],
|
float r_loc[3],
|
||||||
float r_no[3],
|
float r_no[3],
|
||||||
@ -2735,7 +2771,8 @@ static short transform_snap_context_project_view3d_mixed_impl(
|
|||||||
float r_obmat[4][4])
|
float r_obmat[4][4])
|
||||||
{
|
{
|
||||||
BLI_assert((snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
BLI_assert((snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
||||||
SCE_SNAP_MODE_EDGE_MIDPOINT)) != 0);
|
SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) !=
|
||||||
|
0);
|
||||||
|
|
||||||
short retval = 0;
|
short retval = 0;
|
||||||
bool has_hit = false;
|
bool has_hit = false;
|
||||||
@ -2773,7 +2810,8 @@ static short transform_snap_context_project_view3d_mixed_impl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) {
|
if (snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||||
|
SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||||
short elem;
|
short elem;
|
||||||
float dist_px_tmp = *dist_px;
|
float dist_px_tmp = *dist_px;
|
||||||
|
|
||||||
@ -2827,9 +2865,10 @@ static short transform_snap_context_project_view3d_mixed_impl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((retval == SCE_SNAP_MODE_EDGE) &&
|
if ((retval == SCE_SNAP_MODE_EDGE) &&
|
||||||
(snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE_MIDPOINT))) {
|
(snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||||
|
SCE_SNAP_MODE_EDGE_PERPENDICULAR))) {
|
||||||
elem = snap_mesh_edge_verts_mixed(
|
elem = snap_mesh_edge_verts_mixed(
|
||||||
sctx, &snapdata, ob, obmat, *dist_px, &dist_px_tmp, loc, no, &index);
|
sctx, &snapdata, ob, obmat, *dist_px, prev_co, &dist_px_tmp, loc, no, &index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elem) {
|
if (elem) {
|
||||||
@ -2864,6 +2903,7 @@ short ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
|
|||||||
const unsigned short snap_to,
|
const unsigned short snap_to,
|
||||||
const struct SnapObjectParams *params,
|
const struct SnapObjectParams *params,
|
||||||
const float mval[2],
|
const float mval[2],
|
||||||
|
const float prev_co[3],
|
||||||
float *dist_px,
|
float *dist_px,
|
||||||
float r_loc[3],
|
float r_loc[3],
|
||||||
float r_no[3],
|
float r_no[3],
|
||||||
@ -2872,7 +2912,8 @@ short ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
|
|||||||
float r_obmat[4][4])
|
float r_obmat[4][4])
|
||||||
{
|
{
|
||||||
return transform_snap_context_project_view3d_mixed_impl(
|
return transform_snap_context_project_view3d_mixed_impl(
|
||||||
sctx, snap_to, params, mval, dist_px, r_loc, r_no, r_index, r_ob, r_obmat) != 0;
|
sctx, snap_to, params, mval, prev_co, dist_px, r_loc, r_no, r_index, r_ob, r_obmat) !=
|
||||||
|
0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2882,6 +2923,7 @@ short ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
|
|||||||
*
|
*
|
||||||
* \param sctx: Snap context.
|
* \param sctx: Snap context.
|
||||||
* \param mval: Screenspace coordinate.
|
* \param mval: Screenspace coordinate.
|
||||||
|
* \param prev_co: Coordinate for perpendicular point calculation (optional).
|
||||||
* \param dist_px: Maximum distance to snap (in pixels).
|
* \param dist_px: Maximum distance to snap (in pixels).
|
||||||
* \param r_co: hit location.
|
* \param r_co: hit location.
|
||||||
* \param r_no: hit normal (optional).
|
* \param r_no: hit normal (optional).
|
||||||
@ -2891,12 +2933,13 @@ bool ED_transform_snap_object_project_view3d(SnapObjectContext *sctx,
|
|||||||
const unsigned short snap_to,
|
const unsigned short snap_to,
|
||||||
const struct SnapObjectParams *params,
|
const struct SnapObjectParams *params,
|
||||||
const float mval[2],
|
const float mval[2],
|
||||||
|
const float prev_co[3],
|
||||||
float *dist_px,
|
float *dist_px,
|
||||||
float r_loc[3],
|
float r_loc[3],
|
||||||
float r_no[3])
|
float r_no[3])
|
||||||
{
|
{
|
||||||
return ED_transform_snap_object_project_view3d_ex(
|
return ED_transform_snap_object_project_view3d_ex(
|
||||||
sctx, snap_to, params, mval, dist_px, r_loc, r_no, NULL, NULL, NULL) != 0;
|
sctx, snap_to, params, mval, prev_co, dist_px, r_loc, r_no, NULL, NULL, NULL) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2048,6 +2048,7 @@ enum {
|
|||||||
#define SCE_SNAP_MODE_VOLUME (1 << 3)
|
#define SCE_SNAP_MODE_VOLUME (1 << 3)
|
||||||
#define SCE_SNAP_MODE_INCREMENT (1 << 4)
|
#define SCE_SNAP_MODE_INCREMENT (1 << 4)
|
||||||
#define SCE_SNAP_MODE_EDGE_MIDPOINT (1 << 5)
|
#define SCE_SNAP_MODE_EDGE_MIDPOINT (1 << 5)
|
||||||
|
#define SCE_SNAP_MODE_EDGE_PERPENDICULAR (1 << 6)
|
||||||
|
|
||||||
/* ToolSettings.snap_node_mode */
|
/* ToolSettings.snap_node_mode */
|
||||||
#define SCE_SNAP_MODE_GRID (1 << 5)
|
#define SCE_SNAP_MODE_GRID (1 << 5)
|
||||||
|
@ -172,6 +172,11 @@ const EnumPropertyItem rna_enum_snap_element_items[] = {
|
|||||||
ICON_SNAP_MIDPOINT,
|
ICON_SNAP_MIDPOINT,
|
||||||
"Edge Center",
|
"Edge Center",
|
||||||
"Snap to the middle of edges"},
|
"Snap to the middle of edges"},
|
||||||
|
{SCE_SNAP_MODE_EDGE_PERPENDICULAR,
|
||||||
|
"EDGE_PERPENDICULAR",
|
||||||
|
ICON_SNAP_PERPENDICULAR,
|
||||||
|
"Edge Perpendicular",
|
||||||
|
"Snap to the nearest point on an edge"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, NULL, 0, NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user