Skip to content

Commit d7d25fd

Browse files
committed
New AutoUV Scale->Normalize RMB option
It's intended to normalize a set of charts relative to a reference one. This is option is useful in cases where we need to remap a portion of an already unwrapped object, or when someone unwraps a composite object in parts. In these situations, we want the new charts to remain consistent in scale with the previously unwrapped ones. To achieve this, we simply select one of them as a reference. NOTE: New AutoUV option to Normalize a set of charts using another as reference. It's accessed via RMB option. Thanks to envelupo and Vaughan for the suggestion
1 parent 974118f commit d7d25fd

1 file changed

Lines changed: 91 additions & 4 deletions

File tree

plugins_src/autouv/wpc_autouv.erl

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -607,10 +607,7 @@ command_menu(body, X, Y) ->
607607
?__(3,"Move selected charts")},
608608
{?__(4,"Scale"), {scale, scale_directions(false) ++
609609
[separator] ++ stretch_directions() ++
610-
[separator,
611-
{?__(411,"Normalize Sizes"), normalize,
612-
?__(412,"Normalize Chart Sizes so that each"
613-
"chart get it's corresponding 2d area")}]},
610+
[separator] ++ normalize()},
614611
?__(5,"Scale selected charts")},
615612
{?__(6,"Rotate"), {rotate,rotate_free(false)},
616613
{?__(7,"Rotate selected charts"),[],?__(59,"Pick rotation center")},[]},
@@ -744,6 +741,12 @@ stretch_directions() ->
744741
{?__(3,"Max Horizontal"), max_x, ?__(4,"Maximize horizontally (X dir)")},
745742
{?__(5,"Max Vertical"), max_y, ?__(6,"Maximize vertically (Y dir)")}].
746743

744+
normalize() ->
745+
[{?__(411,"Normalize Sizes"), normalize_fun(),
746+
{?__(412,"Normalize Chart Sizes so that each "
747+
"chart get it's corresponding 2d area"),[],
748+
?__(413,"Normalize chart sizes by taking a reference into account")}}].
749+
747750
move_directions(true) ->
748751
[{?__(1,"Free"), free_2d, ?__(2,"Move in both directions"), [magnet]},
749752
{?__(3,"Horizontal"), x, ?__(4,"Move horizontally (X dir)"), [magnet]},
@@ -823,6 +826,12 @@ max_uniform() ->
823826
(3, _Ns) -> {auv,{scale,{max_uniform,y}}}
824827
end.
825828

829+
normalize_fun() ->
830+
fun
831+
(1, _Ns) -> {auv,{scale,normalize}};
832+
(3, _Ns) -> {auv,{scale,normalize_ref}}
833+
end.
834+
826835
option_menu() ->
827836
[separator,
828837
{?__(1,"Create Texture"),create_texture,?__(2,"Make and Attach a texture to the model")}].
@@ -1214,6 +1223,9 @@ handle_command_1({scale,normalize}, St0) -> %% Normalize chart sizes
12141223
Sh = lists:foldl(Scale, Sh0, List),
12151224
St = update_selected_uvcoords(St0#st{shapes=Sh}),
12161225
get_event(St);
1226+
handle_command_1({scale,normalize_ref}, St) -> %% Normalize chart sizes using a reference
1227+
Sel = wings_sel:selected_ids(St),
1228+
wings:ask(normalize_ask(Sel), St, fun normalize_by_ref/2);
12171229
handle_command_1({scale, {'ASK', Ask}}, St) ->
12181230
wings:ask(Ask, St, fun({Dir,M},St0) when is_tuple(M), element(1,M) == magnet ->
12191231
do_drag(wings_scale:setup({Dir,center,M}, St0));
@@ -1502,6 +1514,81 @@ do_drag({drag,Drag}) ->
15021514
do_drag(Other) ->
15031515
Other.
15041516

1517+
normalize_ask(OrigSel) ->
1518+
Fun = fun(check, St) ->
1519+
case check_selection(OrigSel, St) of
1520+
{Result,Msg} ->
1521+
{Result,Msg};
1522+
Msg ->
1523+
{none,Msg}
1524+
end;
1525+
(exit, {_,_,St}) ->
1526+
case check_selection(OrigSel, St) of
1527+
{{_,_,Id},_} ->
1528+
{result,Id};
1529+
_ ->
1530+
error
1531+
end
1532+
end,
1533+
{[{Fun,?__(1,"Pick the chart to be used as reference")}],[],[],[body]}.
1534+
1535+
check_selection(Ids, #st{selmode=Mode}=St) ->
1536+
Sel = case Mode of
1537+
body -> Ids;
1538+
_ -> []
1539+
end,
1540+
MF = fun(_Items, #we{id=Id}) ->
1541+
case lists:member(Id, Sel) of
1542+
true ->
1543+
[wrong];
1544+
false ->
1545+
[{0,0,Id}]
1546+
end;
1547+
(_, _) ->
1548+
[wrong]
1549+
end,
1550+
RF = fun erlang:'++'/2,
1551+
case wings_sel:dfold(MF, RF, [], St) of
1552+
[] ->
1553+
?__(1,"Nothing selected");
1554+
[wrong] ->
1555+
?__(2,"Only unselected charts are allowed");
1556+
[Result] when is_tuple(Result) ->
1557+
{Result, ?__(3,"Reference chart picked")};
1558+
[_|_] ->
1559+
?__(4,"Select only one chart")
1560+
end.
1561+
1562+
normalize_by_ref(RefId, St0) ->
1563+
#st{shapes=Sh0, bb=#uvstate{id=Id,st=#st{shapes=Orig}}} = St0,
1564+
OWe = gb_trees:get(Id, Orig),
1565+
RWe = gb_trees:get(RefId, Sh0),
1566+
{RA2D,RA3D,_} = calc_areas(RWe,OWe,{0.0,0.0,[]}),
1567+
RScale = RA2D/RA3D,
1568+
1569+
io:format("RScale: ~p\n",[RScale]),
1570+
{TA2D,TA3D,List} = wings_sel:fold(fun(_,We,Areas) ->
1571+
calc_areas(We,OWe,Areas)
1572+
end, {0.0,0.0,[]}, St0),
1573+
TScale = TA2D/TA3D,
1574+
K = RScale/TScale,
1575+
io:format("TScale: ~p\nK: ~p\n",[TScale,K]),
1576+
Scale = fun({A2D,A3D,We0 = #we{id=WId}},Sh) ->
1577+
Ri = A2D / wings_util:nonzero(A3D),
1578+
Scale = math:sqrt(RScale / Ri),
1579+
io:format("-> Scale: ~p\n",[Scale]),
1580+
Center = wings_vertex:center(We0),
1581+
T0 = e3d_mat:translate(e3d_vec:neg(Center)),
1582+
SM = e3d_mat:scale(Scale, Scale, 1.0),
1583+
T1 = e3d_mat:mul(SM, T0),
1584+
T = e3d_mat:mul(e3d_mat:translate(Center), T1),
1585+
We = wings_we:transform_vs(T, We0),
1586+
gb_trees:update(WId,We,Sh)
1587+
end,
1588+
Sh = lists:foldl(Scale, Sh0, List),
1589+
St = update_selected_uvcoords(St0#st{shapes=Sh}),
1590+
get_event(St).
1591+
15051592
tighten(#st{selmode=vertex}=St) ->
15061593
tighten_1(fun vertex_tighten/2, St);
15071594
tighten(#st{selmode=body}=St) ->

0 commit comments

Comments
 (0)