@@ -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+
747750move_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+
826835option_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 );
12171229handle_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}) ->
15021514do_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 \n K: ~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+
15051592tighten (# st {selmode = vertex }= St ) ->
15061593 tighten_1 (fun vertex_tighten /2 , St );
15071594tighten (# st {selmode = body }= St ) ->
0 commit comments