From 5dec5d2abe1ed4b699769c5eb44547a950ff8b1f Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov@gmail.com>
Date: Thu, 10 May 2012 23:52:56 +0400
Subject: [PATCH 1/6] No Erlang OpenCL support for now
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
---
src/wings_cc.erl | 866 ---------------------------------------------------
src/wings_cc_ref.erl | 449 --------------------------
src/wings_cl.erl | 108 +------
src/wings_proxy.erl | 78 +----
4 files changed, 5 insertions(+), 1496 deletions(-)
diff --git a/src/wings_cc.erl b/src/wings_cc.erl
index 09ac158..54592ee 100644
--- a/src/wings_cc.erl
+++ b/src/wings_cc.erl
@@ -24,869 +24,3 @@
%%%
-module(wings_cc).
--export([init/3, update/2, gen_vab/1, gen_vab/2]).
-
-%% debug
--import(lists, [reverse/1, foldl/3]).
-
--define(NEED_OPENGL, 1).
--include("wings.hrl").
--include_lib("cl/include/cl.hrl").
-
--compile(export_all).
-
--define(PL_UNITS, 4).
-
--record(v, {pos, % position
- vc}). % Valence
-
-%% The different working sets
-
--record(base, {v, %% array of #v{} nv
- f, %% array of [v0,v1..,vn] nf
- fi, %% array of {Start,Size} nf
- e, %% array of v0,v1,f1,f2 ne
- as, %% Vertex attrs
- level,%% Subdiv levels
- n, %% Number of faces
- mmap, %% Material map, {mat, start, vertex_count}
- vmap, %% array Wings Vertex Id -> CL vertex id
- fmap, %% gb_tree Wings face id -> CL face id
- type %% Type of data plain,uv,color,color_uv
- }).
-
-%% OpenCL defines
--record(cls,
- {cl,
- %% CL temp buffers and respective sizes
- vab, vab_sz=0, fl, fl_sz=0, fi, fi_sz=0,
- sn, sn_sz %% Smooth normals ? can reuse fl?
- }).
-
--record(cl_mem, {v, v_no, f, fs_no, e, e_no, fi, fi0, as, max_vs}).
--record(cc_cache, {mem, old, wait}).
-
--define(EDGE_SZ, (4*4)).
--define(FACE_SZ, (4*4)).
--define(VERTEX_SZ, ((3*4)+4)).
--define(LOCK_SZ, 32).
-%%-define(DEFAULT, erlang).
--define(DEFAULT, opencl).
-
-%%%% API %%%%%%%%%
-
-%% Returns opaque data
-init(Plan, Level, We) when is_integer(Level) ->
- build_data(Plan,Level,We,?DEFAULT);
-
-init(Plan, #base{level=Level}, We) ->
- build_data(Plan,Level,We,?DEFAULT).
-
-%% Update state with new vertex positions
-update(ChangedVs, Data) ->
- case ?DEFAULT of
- erlang -> wings_cc_ref:update(ChangedVs, Data);
- _ -> update_1(ChangedVs, Data)
- end.
-
-%% Generates a subdivided #vab{}
-gen_vab(Base) ->
- try
- case subdiv(Base, ?DEFAULT) of
- skip -> create_vab(<<>>, []);
- Data ->
- gen_vab_1(Data, Base)
- end
- catch
- exit:{out_of_resources, Wanted, CardMax} ->
- io:format(?__(1,"OpenCL subd failed: wanted ~pMB only ~pMB available~n"),
- [Wanted, CardMax]),
- DecBase = decrease_level(Base),
- gen_vab(DecBase)
- end.
-%% Generates a subdivided #vab{} from Material Plan
-gen_vab(Plan, Base) ->
- try
- case subdiv(Base, ?DEFAULT) of
- skip -> create_vab(<<>>, []);
- Data ->
- gen_vab_1(Plan, Data, Base)
- end
- catch
- exit:{out_of_resources, Wanted, CardMax} ->
- io:format(?__(1,"OpenCL subd failed: wanted ~pMB only ~pMB available~n"),
- [Wanted, CardMax]),
- DecBase = decrease_level(Base),
- gen_vab(Plan, DecBase)
- end.
-
-%% Subdivide mesh
-subdiv(Base = #base{level=N, n=Total, type=Type}, Impl) when Total > 0 ->
- case Impl of
- opencl ->
- {In,Out,CL} = cl_allocate(Base, cl_setup()),
- Wait = cl_write_input(Base, In, Out, CL),
- subdiv_1(N, In, Out, Type, CL, Wait);
- erlang ->
- wings_cc_ref:subdiv(Base)
- end;
-subdiv(_, _) ->
- skip.
-
-%% Generates a vab (and updates Data)
-%% Returns Vab
-gen_vab_1(Data0, Base) ->
- case ?DEFAULT of
- erlang -> create_vab(wings_cc_ref:gen_vab(Data0, Base), Base);
- opencl -> create_vab(gen_vab_2(Data0, Base), Base)
- end.
-
-gen_vab_1(Plan, Data, Base) ->
- case ?DEFAULT of
- erlang -> create_vab(wings_cc_ref:gen_vab(Plan, Data, Base), Base);
- opencl -> create_vab(gen_vab_2(Plan, Data, Base), Base)
- end.
-
-create_vab({Vs, SNs0, Attrs0, Edges, MatInfo}, #base{type=Type}) ->
- Ns = case Vs of
- <<>> -> Vs;
- <<_:3/unit:32,NsP/bytes>> ->
- NsP
- end,
- S = 3*4+3*4,
- SNs = case SNs0 of
- <<>> -> {S, Ns};
- _ -> {4*4, SNs0} %% Special case easier cl code
- end,
- Colors = case Attrs0 of
- <<>> -> none;
- _ when Type =:= color ->
- {3*4, Attrs0};
- _ when Type =:= color_uv ->
- {5*4, Attrs0};
- _ -> none
- end,
- UVs = case Attrs0 of
- <<>> -> none;
- _ when Type =:= uv ->
- {2*4, Attrs0};
- <<_:3/unit:32,UVBin/bytes>>
- when Type =:= color_uv ->
- {5*4, UVBin};
- _ -> none
- end,
- #vab{face_vs={S,Vs},face_fn={S,Ns}, face_es=Edges,
- face_sn=SNs, face_vc=Colors, face_uv=UVs,
- mat_map=MatInfo}.
-
-update_1(ChangedVs0, #base{vmap=VMap, v=VsBin0}=Base)
- when is_list(ChangedVs0) ->
- ChangedVs = [{array:get(Id,VMap),Pos} || {Id,Pos} <- ChangedVs0],
- VsList = update_vs(lists:sort(ChangedVs), 0, VsBin0),
- VsBin = iolist_to_binary(VsList),
- Base#base{v=VsBin};
-
-update_1(#we{vp=Vpos}, #base{vmap=VMap, v=VsBin0}=Base) ->
- Change = fun(Vid, CLid, Acc) ->
- Pos = array:get(Vid, Vpos),
- Skip = CLid*16+12,
- <<_:Skip/binary, VI:4/binary, _/binary>> = VsBin0,
- [{CLid, Pos, VI}|Acc]
- end,
- VsInfo = array:sparse_foldl(Change, [], VMap),
- VsBin = << <<X:?F32,Y:?F32,Z:?F32,VI/binary>>
- || {_,{X,Y,Z}, VI} <- lists:sort(VsInfo) >>,
- true = size(VsBin) == size(VsBin0), %% Assert
- Base#base{v=VsBin}.
-
-update_vs([{Id, {X,Y,Z}}|Vs], Where, Bin) ->
- Skip = Id*4*4-Where,
- <<Head:Skip/binary, _:(4*3)/binary, Rest/binary>> = Bin,
- New = <<X:?F32,Y:?F32,Z:?F32>>,
- [Head, New | update_vs(Vs, Where+Skip+12, Rest)];
-update_vs([], _, Bin) -> [Bin].
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-build_data({Type, MatFs}, N, We0, Impl) ->
- {FMap0, We} = gen_fmap(MatFs, We0),
- FMap = gb_trees:from_orddict(lists:sort(FMap0)),
- Empty = array:new(),
- StartAcc = {Empty, Empty, {0, Empty}},
- Get = fun(V,Eid,E,Acc) ->
- get_face_info(V,Eid,E,Acc,FMap,We)
- end,
- B0 = case Type of
- plain -> build_data_plain(FMap0, [], StartAcc, Get, We);
- _ ->
- {Attrs, _Sz} = attrs(Type),
- build_data_attrs(FMap0, [], [], StartAcc, Get, Attrs, We)
- end,
- B1 = calc_matmap(MatFs, B0#base{type=Type, level=N}),
- pack_data(B1, Impl).
-
-build_data_plain([{F,_}|Fs], Ftab0, Acc0, Get, We) ->
- {Vs, Acc} = wings_face:fold(Get, {[], Acc0}, F, We), %% CCW
- build_data_plain(Fs, [Vs|Ftab0], Acc, Get, We);
-build_data_plain([], Ftab0, {Vtab, Etab, {_,VMap}}, _, _) ->
- Ftab = reverse(Ftab0),
- #base{v=Vtab, e=Etab, f=Ftab, vmap=VMap}.
-
-build_data_attrs([{F,_}|Fs], Ftab0, Attrs, Acc0, Get, Type, We) ->
- Attr = wings_va:face_attr(Type, F, We),
- {Vs, Acc} = wings_face:fold(Get, {[], Acc0}, F, We), %% CCW
- build_data_attrs(Fs, [Vs|Ftab0], [Attr|Attrs], Acc, Get, Type, We);
-build_data_attrs([], Ftab, Attrs, {Vtab, Etab, {_,VMap}}, _, _, _) ->
- #base{v=Vtab, e=Etab, f=reverse(Ftab),
- vmap=VMap, as=reverse(Attrs)}.
-
-gen_fmap(Plan, We = #we{}) ->
- Fmap0=[{_,Last}|_] = gen_fmap(Plan, 0, []),
- %% Add hidden faces but not holes
- {Hidden, Htab} = hidden_fs(We),
- Fmap = reverse(gen_fmap2(Hidden, Last+1, Fmap0)),
- {Fmap, We#we{he=Htab}}.
-
-gen_fmap([{_Mat, Fs}|MatFs], Curr, Fmap0) ->
- Fmap = [{_,Last}|_] = gen_fmap2(Fs, Curr, Fmap0),
- gen_fmap(MatFs, Last+1, Fmap);
-gen_fmap([], _, Fmap) ->
- Fmap.
-
-gen_fmap2([Face|Fs], Id, Fmap) ->
- gen_fmap2(Fs, Id+1, [{Face, Id}|Fmap]);
-gen_fmap2([],_,Fmap) -> Fmap.
-
-hidden_fs(#we{mirror=none, holes=[], fs=Ftab, he=Htab}) ->
- {hidden_fs2(gb_trees:iterator(Ftab),none,[]), Htab};
-hidden_fs(We = #we{mirror=Mirror, holes=Holes, fs=Ftab, he=Htab}) ->
- Exclude = case Mirror of
- none -> Holes;
- _ -> ordsets:add_element(Mirror, Holes)
- end,
- He0 = wings_face:to_edges(Exclude, We),
- He = gb_sets:union(gb_sets:from_list(He0), Htab),
- {hidden_fs2(gb_trees:iterator(Ftab),Exclude,[]), He}.
-
-hidden_fs2(Iter0, none, Hidden) ->
- case gb_trees:next(Iter0) of
- {Face, _, Iter} when Face < 0 ->
- hidden_fs2(Iter, none, [Face|Hidden]);
- _ ->
- Hidden
- end;
-hidden_fs2(Iter0, Exclude, Hidden) ->
- case gb_trees:next(Iter0) of
- {Face, _, Iter} when Face < 0 ->
- case ordsets:is_element(Face, Exclude) of
- true ->
- hidden_fs2(Iter, Exclude, Hidden);
- false ->
- hidden_fs2(Iter, Exclude, [Face|Hidden])
- end;
- _ ->
- Hidden
- end.
-
-calc_matmap(MatMap0, B=#base{f=Ftab0, level=N}) ->
- Mul = trunc(math:pow(4,N-1)), %% Subd level
- {Total, MatMap, FMap} = calc_matmap(MatMap0, 0, Ftab0, Mul, [], []),
- B#base{n=Total, mmap=MatMap, fmap=FMap}.
-
-calc_matmap([{Mat,Fs}|Mfs], Start, Ftab0, Mul, FMap0, Acc) ->
- {Next, Ftab, FMap} = calc_matmap_1(Fs, Ftab0, Mul, Start, FMap0),
- calc_matmap(Mfs, Next, Ftab, Mul, FMap,
- [{Mat, ?GL_QUADS, Start*4, (Next-Start)*4}|Acc]);
-calc_matmap([], Total, _, _, FMap, Acc) ->
- {Total, reverse(Acc), gb_trees:from_orddict(lists:sort(FMap))}.
-
-calc_matmap_1([Id|Fs], [Vs|Ftab], Mul, Count, FMap) ->
- VSize = length(Vs),
- Size = VSize*Mul,
- FInfo = {Id, {Count, Size}},
- calc_matmap_1(Fs, Ftab, Mul, Count + Size, [FInfo|FMap]);
-calc_matmap_1([], Ftab, _, Count, FMap) ->
- {Count, Ftab, FMap}.
-
-decrease_level(#base{level=Level}) when Level =< 1 ->
- throw(to_large);
-decrease_level(Base = #base{n=Total, level=Level, mmap=MatMap0, fmap=Fmap0}) ->
- io:format(?__(1,"Could not acquire needed memory, "
- "decreasing to subd level ~p~n"), [Level-1]),
- MatMap = [{Mat, ?GL_QUADS, Start div 4, Stop div 4} ||
- {Mat, ?GL_QUADS, Start, Stop} <- MatMap0],
- Fmap = gb_trees:map(fun(_, {Count, Size}) ->
- {Count div 4, Size div 4}
- end,
- Fmap0),
- Base#base{n=Total div 4, level=Level-1, mmap=MatMap, fmap=Fmap}.
-
-get_face_info(Orig, Eid, E, {Vs, {Vtab0, Etab0, VMap0}}, FMap, We) ->
- {V, Vtab, VMap1} = setup_vertex(Orig, Vtab0, VMap0, We),
- {Etab, VMap} = setup_edge(Eid, E, VMap1, FMap, Etab0, We#we.he),
- {[V|Vs], {Vtab, Etab, VMap}}.
-
-setup_vertex(Orig, Vtab, VMap0, We = #we{vp=Vpos,he=He}) ->
- {V,VMap} = update_vmap(Orig, VMap0),
- case array:get(V, Vtab) of
- undefined ->
- Count = fun(E,_,_,{C,H}) -> {C+1,add_hard(E,He,H)} end,
- N = wings_vertex:fold(Count, {0, 0}, Orig, We),
- VP = #v{pos=array:get(Orig,Vpos), vc=N},
- {V,array:set(V,VP,Vtab),VMap};
- _ ->
- {V,Vtab,VMap}
- end.
-
-add_hard(_Edge, _Htab, H) when H > 3 -> 3;
-add_hard(Edge, Htab, H) ->
- case gb_sets:is_member(Edge,Htab) of
- true -> H+1;
- false -> H
- end.
-
-setup_edge(Eid, #edge{vs=OV1,ve=OV2,lf=F1,rf=F2},
- VMap0, FMap, Etab, Htab) ->
- case array:get(Eid, Etab) of
- undefined ->
- {V1,VMap1} = update_vmap(OV1, VMap0),
- {V2,VMap} = update_vmap(OV2, VMap1),
- {array:set(Eid, {V1,V2,
- get_face(F1, FMap),
- get_face(F2, FMap),
- gb_sets:is_member(Eid,Htab)
- },
- Etab), VMap};
- _ ->
- {Etab, VMap0}
- end.
-
-get_face(F, FMap) -> %% when F >= 0 ->
- case gb_trees:lookup(F, FMap) of
- none -> -1;
- {value,Mapped} -> Mapped
- end.
-
-update_vmap(Orig, VM={N,VMap}) ->
- case array:get(Orig, VMap) of
- undefined ->
- {N, {N+1,array:set(Orig, N, VMap)}};
- V ->
- {V, VM}
- end.
-
-pack_data(B=#base{e=Etab0, f=Ftab0}, erlang) ->
- Etab = array:from_list(array:sparse_to_list(Etab0)),
- Ftab = array:from_list(Ftab0),
- B#base{e=Etab, f=Ftab};
-pack_data(B0=#base{v=Vtab0, e=Etab0, f=Ftab0}, opencl) ->
- GetFs = fun(Vs, {No, FI, Fs}) ->
- Len = length(Vs),
- {No+Len, <<FI/binary, No:?I32, Len:?I32>>,
- << Fs/binary,
- (<< <<V:?I32>> || V <- Vs >>)/binary >>}
- end,
- {_, FI, Ftab} = foldl(GetFs, {0, <<>>, <<>>}, Ftab0),
-
- GetEs = fun(_, {V0,V1,F1,F2,H}, Bin) ->
- %% Code neg vertex as hardedge
- V0H = if H -> -1-V0; true -> V0 end,
- <<Bin/binary, V0H:?I32, V1:?I32, F1:?I32, F2:?I32>>
- end,
- Etab = array:sparse_foldl(GetEs, <<>>, Etab0),
-
- GetVs = fun(_, #v{pos={X1,Y1,Z1}, vc={Vc,Hc}}, Bin) ->
- VI = (Vc bsl 2) bor min(Hc,3),
- << Bin/binary,
- X1:?F32,Y1:?F32,Z1:?F32,VI:?F32 >>
- end,
- Vtab = array:foldl(GetVs, <<>>, Vtab0),
- B = pack_attrs(B0),
- B#base{v=Vtab, e=Etab, f=Ftab, fi=FI}.
-
-pack_attrs(B=#base{type=plain}) -> B;
-pack_attrs(B=#base{type=uv, as=AS0}) ->
- Pack = fun(FaceUVs, Acc) ->
- << Acc/binary,
- (<< <<(uv_bin(UV))/binary>>
- || UV <- FaceUVs >>)/binary >>
- end,
- AS = foldl(Pack, <<>>, AS0),
- B#base{as=AS};
-pack_attrs(B=#base{type=color, as=AS0}) ->
- Pack = fun(FaceUVs, Acc) ->
- << Acc/binary,
- (<< <<(col_bin(UV))/binary>>
- || UV <- FaceUVs >>)/binary >>
- end,
- AS = foldl(Pack, <<>>, AS0),
- B#base{as=AS};
-pack_attrs(B=#base{type=color_uv, as=AS0}) ->
- Pack = fun(FaceUVs, Acc) ->
- << Acc/binary,
- (<< <<(col_uv_bin(ColUV))/binary>>
- || ColUV <- FaceUVs >>)/binary >>
- end,
- AS = foldl(Pack, <<>>, AS0),
- B#base{as=AS}.
-
-
-uv_bin({U,V}) -> <<U:?F32,V:?F32>>;
-uv_bin(_) -> <<0.0:?F32,0.0:?F32>>.
-
-col_bin({R,G,B}) -> <<R:?F32,G:?F32,B:?F32>>;
-col_bin(_) -> <<1.0:?F32,1.0:?F32,1.0:?F32>>.
-
-col_uv_bin([{R,G,B}|{U,V}]) ->
- <<R:?F32,G:?F32,B:?F32, U:?F32,V:?F32>>;
-col_uv_bin([none|{U,V}]) ->
- <<1.0:?F32,1.0:?F32,1.0:?F32, U:?F32,V:?F32>>;
-col_uv_bin([{R,G,B}|none]) ->
- <<R:?F32,G:?F32,B:?F32, 0.0:?F32,0.0:?F32>>;
-col_uv_bin([none|none]) ->
- <<1.0:?F32,1.0:?F32,1.0:?F32, 0.0:?F32,0.0:?F32>>.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%% Opencl Implementation
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-subdiv_1(N,
- In = #cl_mem{v=VsIn, f=FsIn, fi=FiIn, e=EsIn, as=AsIn,
- v_no=NoVs, fs_no=NoFs, e_no=NoEs},
- Out= #cl_mem{v=VsOut, f=FsOut, e=EsOut, fi=FiOut, as=AsOut,
- v_no=NoVsOut,fs_no=NoFs1, e_no=NoEs1},
- Type, CLS=#cls{cl=CL}, Wait0)
- when N > 0 ->
- Args1 = [VsIn, FsIn, FiIn, VsOut, FsOut, NoFs, NoVs],
- W0 = wings_cl:cast(gen_faces, Args1, NoFs, Wait0, CL),
- [cl:release_event(Ev) || Ev <- Wait0],
- Args2 = [FsIn, FiIn, VsOut, NoFs, NoVs, NoVsOut],
- W1 = wings_cl:cast(add_center, Args2, ?PL_UNITS, [W0], CL),
-
- Args3 = [VsIn, FsIn, EsIn, FiIn,VsOut, FsOut, EsOut, NoFs, NoVs, NoEs],
- W2 = wings_cl:cast(gen_edges, Args3, NoEs, [W1], CL),
- Args4 = [VsIn, VsOut, EsIn, NoEs, NoVsOut],
- W3 = wings_cl:cast(add_edge_verts, Args4, ?PL_UNITS, [W2], CL),
-
- Args5 = [VsIn,VsOut,NoVs,NoVsOut],
- W4 = wings_cl:cast(move_verts, Args5, NoVsOut, [W3], CL),
- Wait = case Type of
- plain -> W4;
- color ->
- Args6 = [AsIn, FiIn, AsOut, NoFs],
- wings_cl:cast(subd_vcolor, Args6, NoFs, [W4], CL);
- uv ->
- Args6 = [AsIn, FiIn, AsOut, NoFs],
- wings_cl:cast(subd_uv, Args6, NoFs, [W4], CL);
- color_uv ->
- Args6 = [AsIn, FiIn, AsOut, NoFs],
- wings_cl:cast(subd_col_uv, Args6, NoFs, [W4], CL);
- _ -> %% unknown ignore
- W4
- end,
- [cl:release_event(Ev) || Ev <- [W0,W1,W2,W3]],
- subdiv_1(N-1, Out,
- In#cl_mem{fi=FiOut, v_no=NoVsOut+NoFs1+NoEs1,
- fs_no=NoFs1*4, e_no=NoEs1*4},
- Type, CLS, [Wait]);
-subdiv_1(_C, ResultBuffs, OutBuffs, _, _, Wait) ->
- #cc_cache{mem=ResultBuffs, old=OutBuffs, wait=Wait}.
-
-gen_vab_2(#cc_cache{mem=Mem,old=Old,wait=Wait}, B=#base{n=NoFs,level=N,type=Type}) ->
- #cls{cl=CL, vab=Vab} = cl_setup(),
- %% Create #vab{}
- #cl_mem{v=Vs, f=Fs, e=Es, e_no=NoEs, as=As} = Mem,
- WVab = wings_cl:cast(create_vab_all,[Vs,Fs,Vab,NoFs], NoFs, Wait,CL),
- Attrs = gen_attrs(attrs(Type), As, NoFs, Wait, CL),
- Edges = gen_edges([Es, Vs, As, N, NoEs], Wait, CL),
- WData = wings_cl:read(Vab,NoFs*4*6*4,[WVab],CL),
- {ok, VabBin} = cl:wait(WData),
- Smooth = gen_smooth_normals(Vab, NoFs, Mem, Old, [WVab], CL),
-
- [cl:release_event(Ev) || Ev <- [WVab,WData|Wait]],
- cl_release(Mem, true),
- cl_release(Old, false),
- {VabBin, Smooth, Attrs, Edges, B#base.mmap}.
-
-gen_vab_2({_Type, MatFs},
- #cc_cache{mem=Mem, wait=Wait0, old=Old},
- #base{fmap=FMap, type=Type}) ->
- #cls{cl=CL, vab=Vab, fl=FL} = cl_setup(),
- %% Create #vab{}
- #cl_mem{v=Vs, f=Fs, as=AsIn} = Mem,
- CountF = fun(WFace, [Start|Bin0]) ->
- {Fstart,FSz} = gb_trees:get(WFace,FMap),
- Bin = <<
- Bin0/binary,
- Fstart:?I32, %% Start in Fs
- FSz:?I32, %% No of faces
- Start:?I32 %% Start in vab
- >>,
- [Start+FSz|Bin]
- end,
- {NoOutFs,FsBin,MatI} = mat_index(MatFs, CountF, [0|<<>>], []),
- NoInFs = byte_size(FsBin) div 12,
- case NoInFs > 0 of
- true ->
- W1 = wings_cl:write(FL, FsBin, CL),
- Wait = [W1|Wait0],
- Args0 = [Vs,Fs,FL,Vab,NoInFs],
- WVab = wings_cl:cast(create_vab_sel,Args0,NoInFs,Wait,CL),
- #cl_mem{as=AsOut} = Old,
- VabSz = NoOutFs*4*6*4,
- WData = wings_cl:read(Vab,VabSz,[WVab],CL),
- {ok, VabBin} = cl:wait(WData),
- Args1 = [FL,AsIn,AsOut,NoInFs],
- Attrs = gen_sel_attr(Type, Args1, NoOutFs,Wait,CL),
- [cl:release_event(Ev) || Ev <- [WVab,W1|Wait]],
- cl_release(Mem, true),
- cl_release(Old, false),
- {VabBin, <<>>, Attrs, none, MatI};
- false ->
- {<<>>, <<>>, <<>>, none, []}
- end.
-
-mat_index([{Mat,Fs}|MFs], Fun, Acc0 = [Start|_], MI) ->
- Acc = [Next|_] = foldl(Fun, Acc0, Fs),
- NoVs = (Next-Start)*4,
- MatInfo = {Mat,?GL_QUADS,Start*4,NoVs},
- mat_index(MFs, Fun, Acc, [MatInfo|MI]);
-mat_index([], _, [Total|Bin], MatInfo) ->
- {Total, Bin, MatInfo}.
-
-gen_attrs({plain,_}, _As, _Sz, _Wait, _CL) -> <<>>;
-gen_attrs({_,Sz}, As, NoFs, Wait, CL) ->
- AData = wings_cl:read(As,NoFs*4*Sz,Wait,CL),
- {ok, A0} = cl:wait(AData),
- A0.
-
-gen_edges(Args, Wait, CL) ->
- Type = wings_pref:get_value(proxy_shaded_edge_style),
- gen_edges(Type, Args, Wait, CL).
-gen_edges(all, _Args, _Wait, _CL) -> none;
-gen_edges(cage, _Args, _Wait, _CL) -> none;
-gen_edges(some, [Es,Vs,As,N,TotNoEs], Wait, CL) ->
- Ediv = trunc(math:pow(4,N)),
- EMul = trunc(math:pow(2,N)),
- NoEs = EMul * (TotNoEs div Ediv),
- Args = [Es,Vs,As,N,NoEs],
- EWait0 = wings_cl:cast(gen_some_edges, Args, NoEs, Wait, CL),
- EWait1 = wings_cl:read(As, NoEs*2*3*4, [EWait0], CL),
- {ok, EsBin} = cl:wait(EWait1),
- {0, EsBin}.
-
-gen_smooth_normals(Vab, NoFs,
- #cl_mem{f=Fs,e=Es,e_no=NoEs,v=VsNs,v_no=NoVs,as=Out1},
- #cl_mem{v=Vs,as=Out2}, Wait, CL) ->
- VsOut = NoFs*4,
- C1 = wings_cl:cast(clearf, [VsNs,4,NoVs], NoVs, Wait, CL),
- C2 = wings_cl:cast(clearf, [Out1,4,VsOut], VsOut, Wait, CL),
- C3 = wings_cl:cast(clearf, [Out2,4,VsOut], VsOut, Wait, CL),
- Args0 = [Fs,Vab,VsNs,NoFs,NoVs],
- Pass0 = wings_cl:cast(smooth_ns_pass0, Args0, ?PL_UNITS, [C1], CL),
- Args1 = [Es,Fs,Vab,Out1,Out2,NoEs],
- Pass1 = wings_cl:cast(smooth_ns_pass1, Args1, NoEs, [C3,C2,Pass0], CL),
- Args2 = [Fs,Vs,VsNs,Vab,Out1,Out2,NoFs,NoVs],
- Pass2 = wings_cl:cast(smooth_ns, Args2, NoFs, [Pass1], CL),
-
- WData = wings_cl:read(Out1,VsOut*4*4,[Pass2],CL),
- {ok, OutBin} = cl:wait(WData),
- OutBin.
-
-gen_sel_attr(plain, _, _, _, _) ->
- <<>>;
-gen_sel_attr(Type,[FL,AsIn,AsOut,NoInFs],NoOutFs,Wait,CL) ->
- {T,Sz} = attrs(Type),
- Func = case T of
- color -> get_sel_vcolor;
- uv -> get_sel_uv;
- [color|uv] -> get_sel_col_uv
- end,
- Args = [FL,AsIn,AsOut,NoInFs],
- AW = wings_cl:cast(Func,Args,NoInFs,Wait,CL),
- AData = wings_cl:read(AsOut,NoOutFs*4*Sz,[AW],CL),
- {ok, A0} = cl:wait(AData),
- A0.
-
-attrs(uv) -> % wings_va type and byte size
- {uv, 2*4};
-attrs(color) ->
- {color, 3*4};
-attrs(color_uv) ->
- {[color|uv], 3*4+2*4};
-attrs(plain) ->
- {plain, 0}.
-
-cl_setup() ->
- case get({?MODULE, cl}) of
- undefined ->
- try
- cl_setup_1()
- catch _:Reason ->
- io:format("CL setup error: ~p~n",[Reason]),
- wings_pref:set_value(proxy_opencl_level, 0),
- wings_u:error_msg(?__(1, "Could not setup OpenCL, disabling proxy smooth."))
- end;
- CL ->
- CL
- end.
-
-cl_setup_1() ->
- CL0 = wings_cl:compile("cc_subdiv.cl", wings_cl:setup()),
- CL = #cls{cl=CL0},
- put({?MODULE, cl}, CL),
- CL.
-
-
-%% For now only one level at the time
-cl_allocate(Base=#base{fi=Fi, type=Type}, CL0=#cls{cl=CLI}) ->
- Ctxt = wings_cl:get_context(CLI),
- {NoFs,NoEs,NoVs, NoFs1, MaxFs,MaxEs,MaxVs} = verify_size(Base, CL0),
-
- {_, ASz0} = attrs(Type),
- ASz = max(ASz0, 4*4), %% Also used for smooth normals
-
- Sizes = [Fi, MaxFs*?FACE_SZ, MaxEs*?EDGE_SZ, MaxVs*?VERTEX_SZ*?PL_UNITS,
- MaxFs*?FACE_SZ, MaxEs*?EDGE_SZ, MaxVs*?VERTEX_SZ*?PL_UNITS,
- MaxFs*ASz*4, MaxFs*ASz*4],
-
- Buffs = create_buffers(Ctxt, Sizes, []),
- [FiIn,FsIn,EsIn,VsIn, FsOut,EsOut,VsOut, AsIn,AsOut] = Buffs,
-
- CL = #cls{fi=FiOut} = check_temp_buffs(CL0, Ctxt, MaxFs, Buffs),
- put({?MODULE, cl}, CL),
-
-
- {#cl_mem{v=VsIn, f=FsIn, e=EsIn, fi=FiIn, fi0=FiIn, as=AsIn,
- v_no=NoVs, fs_no=NoFs, e_no=NoEs, max_vs=MaxVs},
- #cl_mem{v=VsOut, f=FsOut, e=EsOut, fi=FiOut, fi0=FiIn, as=AsOut,
- v_no=NoVs+NoFs+NoEs, fs_no=NoFs1, e_no=NoEs*4, max_vs=MaxVs},
- CL}.
-
-create_buffers(Ctxt, [Size|Szs], Acc) when is_integer(Size) ->
- case cl:create_buffer(Ctxt, [], Size) of
- {ok,Buffer} ->
- create_buffers(Ctxt, Szs, [Buffer|Acc]);
- {error, out_of_resources} ->
- release_buffers(Acc, true)
- end;
-create_buffers(Ctxt, [Binary|Szs], Acc) ->
- case cl:create_buffer(Ctxt, [], byte_size(Binary), Binary) of
- {ok,Buffer} ->
- create_buffers(Ctxt, Szs, [Buffer|Acc]);
- {error, out_of_resources} ->
- release_buffers(Acc, true)
- end;
-create_buffers(_, [], Buffers) ->
- lists:reverse(Buffers).
-
-release_buffers(Buffers, true) ->
- case get({?MODULE, cl}) of
- undefined ->
- ok;
- #cls{cl=CL, vab=Vab, fl=FL, fi=FI} ->
- Vab /= undefined andalso cl:release_mem_object(Vab),
- FL /= undefined andalso cl:release_mem_object(FL),
- FI /= undefined andalso cl:release_mem_object(FI),
- put({?MODULE, cl}, #cls{cl=CL})
- end,
- release_buffers(Buffers, false);
-release_buffers(Buffers, false) ->
- [cl:release_mem_object(Buff) || Buff <- Buffers],
- exit({out_of_resources, unknown, unknown}).
-
-
-cl_write_input(#base{f=Fs,e=Es,v=Vs, as=As},
- #cl_mem{v=VsIn,f=FsIn,e=EsIn,as=AsIn,max_vs=MaxVs},
- #cl_mem{v=VsOut},
- #cls{cl=CL}) ->
- NoVs = MaxVs * ?PL_UNITS,
- Wait0 = wings_cl:cast(clearf, [VsIn, 4, NoVs], NoVs, [], CL),
- Wait1 = wings_cl:cast(clearf, [VsOut, 4, NoVs], NoVs, [], CL),
- W3 = wings_cl:write(FsIn, Fs, CL),
- W4 = wings_cl:write(EsIn, Es, CL),
- {ok, _} = cl:wait(Wait0), {ok, _} = cl:wait(Wait1),
- W1 = wings_cl:write(VsIn, Vs, CL),
- W2 = wings_cl:write(VsOut, Vs, CL),
- Last = case As of
- undefined -> [];
- _ ->
- W5 = wings_cl:write(AsIn, As, CL),
- [W5]
- end,
- [W1,W2,W3,W4|Last].
-
-cl_release(#cl_mem{v=Vs,f=Fs,e=Es,fi0=Fi0,as=As}, All) ->
- Vs /= undefined andalso cl:release_mem_object(Vs),
- Fs /= undefined andalso cl:release_mem_object(Fs),
- Es /= undefined andalso cl:release_mem_object(Es),
- As /= undefined andalso cl:release_mem_object(As),
- All andalso cl:release_mem_object(Fi0).
-
-check_temp_buffs(CL=#cls{
- vab=Vab0, vab_sz=VabSz0,
- fl=FL0, fl_sz=FLSz0,
- fi=Fi0, fi_sz=FiSz0
- %%sn = SN0, sn_vz = SNSz0
- }, Ctxt, MaxFs0, Buffs) ->
- MaxFs = MaxFs0,
- GenFi = fun() ->
- << <<(C*4):?I32, 4:?I32>> ||
- C <- lists:seq(0, MaxFs-1) >>
- end,
- {Vab,VabSz} = try
- check_temp(Vab0,VabSz0,MaxFs*(3+3)*4*4,
- Ctxt,[write_only],none)
- catch error:{badmatch, _} ->
- cl:release_mem_object(FL0),
- cl:release_mem_object(Fi0),
- release_buffers(Buffs, false)
- end,
- {FL,FLSz} = try check_temp(FL0,FLSz0,MaxFs*3*4,
- Ctxt,[read_only],none)
- catch error:{badmatch, _} ->
- cl:release_mem_object(Vab),
- cl:release_mem_object(Fi0),
- release_buffers(Buffs, false)
- end,
-
- {Fi,FiSz} = try check_temp(Fi0,FiSz0,MaxFs*2*4,
- Ctxt,[read_only],GenFi)
- catch error:{badmatch, _} ->
- cl:release_mem_object(Vab),
- cl:release_mem_object(FL),
- release_buffers(Buffs, false)
- end,
-
- CL#cls{vab=Vab, vab_sz=VabSz,
- fl=FL, fl_sz=FLSz,
- fi=Fi, fi_sz=FiSz
- }.
-
-check_temp(Buff, Current, Req, _, _, _)
- when Current >= Req ->
- {Buff, Current};
-check_temp(undefined, _, Req, Ctxt, Opt, none) ->
- {ok, Buff} = cl:create_buffer(Ctxt, Opt, Req),
- {Buff, Req};
-check_temp(undefined, _, Req, Ctxt, Opt, Fun) ->
- {ok,Buff} = cl:create_buffer(Ctxt, Opt, Req, Fun()),
- {Buff, Req};
-check_temp(Buff0, _, Req, Ctxt, Opt, Data) ->
- cl:release_mem_object(Buff0),
- check_temp(undefined, 0, Req, Ctxt, Opt, Data).
-
-verify_size(#base{fi=Fi, e=Es, v=Vs, level=N}, #cls{cl=CL}) ->
- NoFs = size(Fi) div 8,
- NoEs = size(Es) div ?EDGE_SZ,
- NoVs = size(Vs) div ?VERTEX_SZ,
-
- Skip = size(Fi) - 8,
- <<_:Skip/binary, NoFs0:?I32, LastFc:?I32>> = Fi,
- NoFs1 = NoFs0+LastFc,
- Device = wings_cl:get_device(CL),
- {ok, DevTotal} = cl:get_device_info(Device, max_mem_alloc_size),
- {MaxFs, MaxEs, MaxVs} = verify_size_1(N-1, N, NoFs1, NoEs*4, NoVs+NoEs+NoFs, DevTotal),
- {NoFs, NoEs, NoVs, NoFs1, MaxFs, MaxEs, MaxVs}.
-
-%% Does this function do anything good?
-verify_size_1(N, No, Fs, Es, Vs, CardMax) ->
- VertexSz = (3+3)*4*4,
- Temp = Fs*VertexSz+Fs*3*4+Fs*2*4,
- Total = Temp+2*(Fs*?FACE_SZ+Es*?EDGE_SZ+Vs*?VERTEX_SZ*?PL_UNITS+Fs*4*4),
- case Total < CardMax of
- true when N == 0 ->
- {Fs,Es,Vs};
- true ->
- verify_size_1(N-1, No, Fs*4, Es*4, Vs+Fs+Es, CardMax);
- false ->
- exit({out_of_resources,Total div 1024, CardMax div 1024})
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% DEBUG
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
--ifdef(DO_DEBUG).
-%-ifdef(PL_UNITS).
-cl_vs(Str, N, Vs, Count, CL, Wait0) ->
- Wait = if is_list(Wait0) -> Wait0; true -> [Wait0] end,
- W1 = wings_cl:read(Vs,Count*?VERTEX_SZ,Wait,CL),
- {ok, VsBin} = cl:wait(W1),
-
- {ok, F} = file:open(Str ++ "_" ++ integer_to_list(N), [write]),
- try
- W = fun(<<X:?F32,Y:?F32,Z:?F32,VI0:?F32>>,V) ->
- VI = {trunc(VI0) div 4, trunc(VI0) rem 4},
- ok=io:format(F,"{~w, {~.4f,~.4f,~.4f}, ~w}~n", [V,X,Y,Z,VI]),
- V+1
- end,
- lists:foldl(W, 0, [D || <<D:?VERTEX_SZ/binary>> <= VsBin])
- catch E:R ->
- io:format("Failed ~p:~p ~p~n",[E,R,erlang:get_stacktrace()])
- after
- file:close(F)
- end.
-
-cl_es(Str, N, Es, Count, CL, Wait0) ->
- Wait = if is_list(Wait0) -> Wait0; true -> [Wait0] end,
- W1 = wings_cl:read(Es,Count*?EDGE_SZ,Wait,CL),
- {ok, EsBin} = cl:wait(W1),
-
- {ok, F} = file:open(Str ++ "_" ++ integer_to_list(N), [write]),
- try
- W = fun(<<X:?I32,Y:?I32,Z:?I32,W:?I32>>,E) ->
- ok=io:format(F,"{~w, {~.4w,~.4w,~.4w,~.4w}~n", [E,X,Y,Z,W]),
- E+1
- end,
- lists:foldl(W, 0, [D || <<D:?EDGE_SZ/binary>> <= EsBin])
- catch E:R ->
- io:format("Failed ~p:~p ~p~n",[E,R,erlang:get_stacktrace()])
- after
- file:close(F)
- end.
-
-cl_face(Str, N, Vs, Count, CL, Wait0) ->
- Wait = if is_list(Wait0) -> Wait0; true -> [Wait0] end,
- W1 = wings_cl:read(Vs,Count*?FACE_SZ,Wait,CL),
- {ok, FsBin} = cl:wait(W1),
-
- {ok, FD} = file:open(Str ++ "_" ++ integer_to_list(N), [write]),
- try
- W = fun(<<X:?I32,Y:?I32,Z:?I32,VI0:?I32>>,V) ->
- ok=io:format(FD,"{~w, {~w,~w,~w,~w}}.~n",
- [V,X,Y,Z,VI0]),
- V+1
- end,
- lists:foldl(W, 0, [D || <<D:?FACE_SZ/binary>> <= FsBin])
- catch E:R ->
- io:format("Failed ~p:~p ~p~n",[E,R,erlang:get_stacktrace()])
- after
- file:close(FD)
- end.
-
-
-cl_destroy(Mem) ->
- %% During DEBUGGING REMOVE LATER BUGBUG
- cl_release(Mem, true),
- #cls{fl=Fl, fi=Fi,vab=Vab} = get({?MODULE, cl}),
-
- cl:release_mem_object(Vab),
- cl:release_mem_object(Fi),
- cl:release_mem_object(Fl),
-
- erase({?MODULE, cl}),
- %% cl:release_queue(Q),
- %% [cl:release_kernel(K) || #kernel{id=K} <- Ks],
- %% cl:release_context(C),
- ok.
-
-print_base(#base{v=Vs,f=Fs,fi=Fi,e=Es,n=N}) ->
- io:format("Vs = ~w~n",[Vs]),
- io:format("Fs = ~w~n",[Fs]),
- io:format("Es = ~w~n",[Es]),
- ok.
-
--endif.
-
diff --git a/src/wings_cc_ref.erl b/src/wings_cc_ref.erl
index 0b24b3a..20c7c01 100644
--- a/src/wings_cc_ref.erl
+++ b/src/wings_cc_ref.erl
@@ -13,452 +13,3 @@
%%
-module(wings_cc_ref).
-
--import(lists, [reverse/1, foldl/3]).
-
--define(NEED_OPENGL, 1).
--include("wings.hrl").
--include_lib("cl/include/cl.hrl").
-
--compile(export_all).
-
--record(v, {pos, % position
- vc}). % Valence
-
-%% The different working sets
-
--record(base, {v, %% array of #v{} nv
- f, %% array of [v0,v1..,vn] nf
- fi, %% array of {Start,Size} nf
- e, %% array of v0,v1,f1,f2 ne
- as, %% Vertex attrs
- level,%% Subdiv levels
- n, %% Number of faces
- mmap, %% Material map, {mat, start, vertex_count}
- vmap, %% array Wings Vertex Id -> CL vertex id
- fmap, %% gb_tree Wings face id -> CL face id
- type %% Type of data plain,uv,color,color_uv
- }).
-
--define(EDGE_SZ, (4*4)).
--define(FACE_SZ, (4*4)).
--define(VERTEX_SZ, ((3*4)+4)).
--define(LOCK_SZ, 32).
-
-subdiv(#base{v=Vs,e=Es,f=Fs, as=As, level=N}) ->
- subdiv_erl_1(Fs, Es, Vs, As, N).
-
-subdiv_erl_1(InFs, Es0, InVs, As, N) when N > 0 ->
- SFs0 = array:sparse_foldl(fun(_F, Vs, R=[Prev|_]) ->
- [Prev+length(Vs)|R]
- end, [0], InFs),
- SFs = array:from_list(reverse(SFs0)),
- {OutVs1, OutFs1} = gen_face_points(InFs, InVs, InVs, SFs),
- {OutVs2, OutFs, Es} = gen_edge_points(Es0, InVs, OutVs1,
- SFs, InFs, OutFs1, undefined),
- OutVs = move_vertex_points(InVs,OutVs2),
- OutAs = subdiv_attrs(As),
- %% erl_vs("evs_out3", N, OutVs),
- subdiv_erl_1(OutFs, Es, OutVs, OutAs, N-1);
-subdiv_erl_1(Fs0, _Es0, Vtab, As, _N) ->
- %% assert(Vtab, _Es0, Fs0),
- {Vtab, As, Fs0}.
-
-update(Changed, B=#base{v=Vs0,vmap=Map}) ->
- Vs = case Changed of
- [_|_] ->
- Move = fun({Vid, Pos}, Vs) ->
- try
- CLid = array:get(Vid, Map),
- V = array:get(CLid, Vs),
- array:set(CLid, V#v{pos=Pos}, Vs)
- catch _:badarg ->
- io:format("VMap ~w~n",
- [array:to_orddict(Map)]),
- io:format("Vid ~p ~n", [Vid]),
- io:format("CLid ~p ~n", [catch array:get(Vid, Map)]),
- exit(foo)
- end
- end,
- %% io:format("Changed ~p~n",[Changed]),
- foldl(Move, Vs0, Changed);
- #we{vp=Vpos} ->
- Move = fun(Vid, CLid, Vs) ->
- Pos = array:get(Vid, Vpos),
- V = array:get(CLid, Vs),
- array:set(CLid, V#v{pos=Pos}, Vs)
- end,
- array:sparse_foldl(Move, Vs0, Map)
- end,
- B#base{v=Vs}.
-
-gen_vab({Vtab, As, Ftab}, #base{n=Total, type=Type, mmap=Mats}) ->
- Gen = fun(Id, Vs0, Bin) when Id < Total ->
- Vs = [(array:get(V,Vtab))#v.pos || V <- Vs0],
- {Nx,Ny,Nz} = e3d_vec:normal(Vs),
- Face = << <<X:?F32,Y:?F32,Z:?F32,
- Nx:?F32,Ny:?F32,Nz:?F32 >>
- || {X,Y,Z} <- Vs >>,
- <<Bin/binary, Face/binary >>;
- (_,_, Bin) ->
- throw(Bin)
- end,
- Bin = try
- array:foldl(Gen, <<>>, Ftab)
- catch throw:Bin1 ->
- Bin1
- end,
- AsBin = case As of
- undefined -> <<>>;
- _ ->
- try
- lists:foldl(gen_attrib_fun(Type), <<>>, As)
- catch throw:Bin2 ->
- Bin2
- end
- end,
- {Bin, <<>>, AsBin, Mats}.
-
-%% print( <<R:?F32, G:?F32, B:?F32, U:?F32, V:?F32, Rest/binary>>, Face) ->
-%% io:format("~w: {~.4f,~.4f,~.4f}, {~.4f,~.4f}~n", [Face,R,G,B,U,V]),
-%% print(Rest, Face+1);
-%% print(<<>>, _) -> ok.
-
-gen_attrib_fun(color) ->
- fun(Colors, Bin) ->
- Face = << <<(col_bin(Col))/binary>> || Col <- Colors >>,
- <<Bin/binary, Face/binary >>
- end;
-gen_attrib_fun(uv) ->
- fun(Uvs, Bin) ->
- Face = << <<(uv_bin(Uv))/binary>> || Uv <- Uvs >>,
- <<Bin/binary, Face/binary >>
- end;
-gen_attrib_fun(color_uv) ->
- Gen = fun([Col|Uv], Bin) ->
- <<Bin/binary, (col_bin(Col))/binary,(uv_bin(Uv))/binary>>;
- (none, Bin) ->
- <<Bin/binary, (col_bin(none))/binary,(uv_bin(none))/binary>>
- end,
- fun(Uvs, Bin) ->
- foldl(Gen,Bin, Uvs)
- end;
-gen_attrib_fun(_) -> fun(_, _) -> throw(<<>>) end.
-
-uv_bin({U,V}) -> <<U:?F32, V:?F32>>;
-uv_bin(_) -> <<0.0:?F32, 0.0:?F32>>.
-
-col_bin({R,G,B}) -> <<R:?F32, G:?F32, B:?F32>>;
-col_bin(_) -> <<1.0:?F32, 1.0:?F32, 1.0:?F32>>.
-
-gen_vab({_Type, MatFs}, Data, #base{fmap=FMap}) ->
- gen_vab(MatFs, Data, FMap, 0, <<>>, []).
-
-gen_vab([{Mat,Fs}|T], D={Vtab, _, Ftab},FMap, Start, Bin0, MI) ->
- %%io:format("Mat: ~p Fs: ~p ~p~n",[Mat, length(Fs), Fs]),
- Build = fun(WFace, {C,Acc}) ->
- {FStart,Fsz} = gb_trees:get(WFace,FMap),
- Bin = gen_faces(FStart, FStart+Fsz, Ftab, Vtab, Acc),
- {C+Fsz*4, Bin}
- end,
- {Stop, Bin} = lists:foldl(Build, {Start, Bin0}, Fs),
- MatInfo = {Mat,?GL_QUADS,Start,Stop-Start},
- gen_vab(T, D, FMap, Stop, Bin, [MatInfo|MI]);
-gen_vab([], _, _,_, Bin, Mi) ->
- {Bin, <<>>, <<>>, Mi}.
-
-gen_faces(N, End, Ftab, Vtab, Acc0) when N < End ->
- Vs0 = array:get(N, Ftab),
- Vs = [(array:get(V,Vtab))#v.pos || V <- Vs0],
- {Nx,Ny,Nz} = e3d_vec:normal(Vs),
- Face = (<< <<X:?F32,Y:?F32,Z:?F32, Nx:?F32,Ny:?F32,Nz:?F32 >>
- || {X,Y,Z} <- Vs >>),
- Acc = <<Acc0/binary, Face/binary >>,
- gen_faces(N+1, End, Ftab, Vtab, Acc);
-gen_faces(_,_,_,_,Acc) -> Acc.
-
-%%% Step 2 build vertices/edges and faces
-
-gen_face_points(Fs0, InVs, OutVs0, SFs) ->
- Face = fun(Face, Vs, {OutVs, Fs}) ->
- gen_face_point(Face, Vs, InVs, SFs, OutVs, Fs)
- end,
- array:foldl(Face, {OutVs0, Fs0}, Fs0).
-
-gen_face_point(Face, FVs, InVs, SFs, OutVs0, Fs0) ->
- VsPos = [(array:get(V, InVs))#v.pos || V <- FVs],
- Center = e3d_vec:average(VsPos),
- OutVs1 = add_center(FVs, Center, OutVs0, face), %% atomicly
- Vid = array:size(InVs) + Face,
- NewFid = face_id(Face, SFs),
- %% Face == 5 andalso
- %% io:format("F ~p c ~p~n",[{V0,V1,V2,V3}, Vid]),
- New = #v{pos=Center, vc={length(FVs),0}},
- OutVs = array:set(Vid, New, OutVs1),
- {_, Fs} = foldl(fun(V, {Fid, Fs}) ->
- {Fid+1, array:set(Fid, [V, -5, Vid, -5], Fs)}
- end, {NewFid, Fs0}, FVs),
- {OutVs, Fs}.
-
-gen_edge_points(Es, InVs, OutVs, FsNo, InFs, OutFs, EdsNo) ->
- Edge = fun(Edge, Vs, Acc) ->
- gen_edge_point(Edge, Vs, Acc, InVs, FsNo, InFs, EdsNo)
- end,
- array:foldl(Edge, {OutVs,OutFs,Es}, Es).
-
-gen_edge_point(Edge, {-1,-1,-1,-1,_Hard}, {OutVs0,Fs0,Es0},
- InVs,_FsNo,InFs,EdsNo) ->
- SEdId = edge_id(Edge,EdsNo),
- VStart = array:size(InVs),
- FId = array:size(InFs) + VStart,
- VId = FId + Edge,
- Es1 = array:set(SEdId+0, {-1,-1,-1,-1,false}, Es0),
- Es2 = array:set(SEdId+1, {-1,-1,-1,-1,false}, Es1),
- Es3 = array:set(SEdId+2, {-1,-1,-1,-1,false}, Es2),
- Es4 = array:set(SEdId+3, {-1,-1,-1,-1,false}, Es3),
- OutVs = array:set(VId, #v{pos={0.0,0.0,0.0}, vc={4, 0}}, OutVs0),
- {OutVs,Fs0,Es4};
-
-gen_edge_point(Edge, {V0,V1,F1,F2,Hard}, {OutVs0,Fs0,Es0},
- InVs,FsNo,InFs,EdsNo) ->
- #v{pos=V0Pos} = array:get(V0, InVs),
- #v{pos=V1Pos} = array:get(V1, InVs),
-
- OutVs1 = add_center([V0], V1Pos, OutVs0, Hard),
- OutVs2 = add_center([V1], V0Pos, OutVs1, Hard),
- VStart = array:size(InVs),
- %% Edge Split position
- {EP,HC} = case Hard of
- true -> %% if Edge is hard Epoint = Mid,
- {e3d_vec:average(V0Pos, V1Pos),2};
- false -> %% Otherwise center of all
- {e3d_vec:average([(array:get(VStart+F1, OutVs2))#v.pos,
- (array:get(VStart+F2, OutVs2))#v.pos,
- V0Pos, V1Pos]),0}
- end,
- FId = array:size(InFs) + VStart,
- VId = FId + Edge,
- OutVs = array:set(VId, #v{pos=EP, vc={4, HC}}, OutVs2),
- SEdId = edge_id(Edge,EdsNo),
-
- %% Complete faces
- case F1 >= 0 of
- true ->
- SF1 = array:get(F1, FsNo),
- {F11,F12,CCW1} =
- find_new_faces(V0,V1,array:get(F1, InFs),SF1),
- Fs1 = update_face(F11, CCW1, VId, Fs0),
- Fs2 = update_face(F12, not CCW1, VId, Fs1),
- Es1 = array:set(SEdId+0, {VId,VStart+F1,F11,F12,false}, Es0);
- false ->
- F11 = -1,
- F12 = -1,
- Es1 = array:set(SEdId+0, {-1,-1,-1,-1,false}, Es0),
- Fs2 = Fs0
- end,
- case F2 >= 0 of
- true ->
- SF2 = array:get(F2, FsNo),
- {F21,F22,CCW2} =
- find_new_faces(V0,V1,array:get(F2, InFs),SF2),
- Fs3 = update_face(F21, CCW2, VId, Fs2),
- Fs4 = update_face(F22, not CCW2, VId, Fs3),
- Es2 = array:set(SEdId+1, {VId,VStart+F2,F21,F22,false}, Es1);
- false ->
- F21 = -1,
- F22 = -1,
- Es2 = array:set(SEdId+1, {-1,-1,-1,-1,false}, Es1),
- Fs4 = Fs2
- end,
- %% Edge == 0 andalso
- %% io:format("Up ~p ~p~n ~p => ~p ~p~n ~p => ~p~p~n",
- %% [Edge, {V0,V1},
- %% F1, {F11,F12}, get_face(F1, InFs),
- %% F2, {F21,F22}, get_face(F2, InFs)]),
- %% New Edges
- Es3 = array:set(SEdId+2, {V0,VId,F11,F21,Hard}, Es2),
- Es4 = array:set(SEdId+3, {VId,V1,F12,F22,Hard}, Es3),
- {OutVs,Fs4,Es4}.
-
-move_vertex_points(In, Out) ->
- Move = fun(V, InV=#v{pos=InPos,vc=Cs={VC,HC}}, VP) ->
- if HC < 2 ->
- {A,B} = vc_div(VC),
- #v{pos=PosOut} = array:get(V,Out),
- %% We started with Inpos remove it
- Ps = e3d_vec:sub(PosOut, InPos),
- Pos = e3d_vec:add_prod(e3d_vec:mul(Ps, A), InPos, B),
- array:set(V, #v{pos=Pos, vc=Cs}, VP);
- HC =:= 2 ->
- #v{pos=Hard} = array:get(V,Out),
- Pos0 = e3d_vec:add_prod(Hard, InPos, 6.0),
- Pos = e3d_vec:mul(Pos0, 1/8),
- array:set(V, #v{pos=Pos, vc=Cs}, VP);
- true ->
- array:set(V, InV, VP)
- end
- end,
- array:sparse_foldl(Move, Out, In).
-
-vc_div(3) -> {1/9, 1/3};
-vc_div(4) -> {1/16, 2/4};
-vc_div(5) -> {1/25, 3/5};
-vc_div(N) -> {1/(N*N), (N-2.0)/N}.
-
-subdiv_attrs(undefined) -> undefined;
-subdiv_attrs(As0) ->
- {_,As} = lists:foldl(fun(Attrs = [First|_], {F,Out}) ->
- Last = lists:last(Attrs),
- Center = average(Attrs),
- {F+1,subdiv_attrs(Last, Attrs, Center, First, Out)}
- end, {0,[]}, As0),
- reverse(As).
-
-subdiv_attrs(Last, [Curr|Attrs=[Next|_]], Center, First, Out) ->
- FaceAttr = [Curr, average(Curr,Next),
- Center, average(Curr,Last)],
- subdiv_attrs(Curr, Attrs, Center, First, [FaceAttr|Out]);
-subdiv_attrs(Last, [Curr], Center, Next, Out) ->
- FaceAttr = [Curr, average(Curr,Next),
- Center, average(Curr,Last)],
- [FaceAttr|Out].
-
-average(Attrs = [[_|_]|_]) ->
- wings_va:average_attrs(Attrs);
-average(Attrs) ->
- wings_color:average(Attrs).
-average(Attr1 = [_|_], Attr2) ->
- wings_va:average_attrs(Attr1, Attr2);
-average(A1, A2) ->
- wings_color:average(A1,A2).
-
-%% The order is important to get ccw winding
-%% find_new_faces(V0,V1,[V0,V1,_,_],Sid) -> {Sid+0,Sid+1,true};
-%% find_new_faces(V0,V1,[V1,V0,_,_],Sid) -> {Sid+1,Sid+0,false};
-%% find_new_faces(V0,V1,[_,V0,V1,_],Sid) -> {Sid+1,Sid+2,true};
-%% find_new_faces(V0,V1,[_,V1,V0,_],Sid) -> {Sid+2,Sid+1,false};
-%% find_new_faces(V0,V1,[_,_,V0,V1],Sid) -> {Sid+2,Sid+3,true};
-%% find_new_faces(V0,V1,[_,_,V1,V0],Sid) -> {Sid+3,Sid+2,false};
-%% find_new_faces(V0,V1,[V1,_,_,V0],Sid) -> {Sid+3,Sid+0,true};
-%% find_new_faces(V0,V1,[V0,_,_,V1],Sid) -> {Sid+0,Sid+3,false}.
-
-find_new_faces(V0,V1,[V0,VN|R],Sid) ->
- case VN of
- V1 -> {Sid,Sid+1,true};
- _ -> {Sid,Sid+1+length(R),false}
- end;
-find_new_faces(V0,V1,[V1,VN|R],Sid) ->
- case VN of
- V0 -> {Sid+1,Sid,false};
- _ -> {Sid+1+length(R),Sid,true}
- end;
-find_new_faces(V0,V1,[_|R],Sid) ->
- find_new_faces(V0,V1,R,Sid+1);
-find_new_faces(_,_, -1, _) ->
- ok.
-
-
-update_face(Face,true,VId, Fs) ->
- try
- [A,-5,C,D] = array:get(Face,Fs),
- array:set(Face, [A,VId,C,D], Fs)
- catch Class:Reason ->
- io:format("Fs: ~p~n",[array:sparse_to_orddict(Fs)]),
- io:format("~p ~p ~p ~p~n",
- [Face,1,VId,array:get(Face, Fs)]),
- erlang:raise(Class, Reason, erlang:get_stacktrace())
- end;
-update_face(Face,false,VId, Fs) ->
- try
- [A,B,C,-5] = array:get(Face,Fs),
- array:set(Face, [A,B,C,VId], Fs)
- catch Class:Reason ->
- io:format("XXX ~p ~n",[Fs]),
- io:format("Fs: ~p~n",[array:sparse_to_orddict(Fs)]),
- io:format("~p ~p ~p ~p~n",
- [Face,3,VId,array:get(Face, Fs)]),
- erlang:raise(Class, Reason, erlang:get_stacktrace())
- end.
-
-add_center([V|Vs], Center, OutVs, Hard=true) ->
- Vx = #v{pos=Pos} = array:get(V,OutVs),
- Updated = array:set(V, Vx#v{pos = e3d_vec:add(Pos,Center)}, OutVs),
- add_center(Vs, Center, Updated, Hard);
-add_center([V|Vs], Center, OutVs, Hard) ->
- Vx = #v{pos=Pos, vc={_,He}} = array:get(V,OutVs),
- if
- He < 2 ->
- Updated = array:set(V, Vx#v{pos = e3d_vec:add(Pos,Center)}, OutVs),
- add_center(Vs, Center, Updated, Hard);
- He =:= 2, Hard =:= face -> %% Reset
- Updated = array:set(V, Vx#v{pos = {0.0,0.0,0.0}}, OutVs),
- add_center(Vs, Center, Updated, Hard);
- true ->
- add_center(Vs, Center, OutVs, Hard)
- end;
-add_center([],_,OutVs,_) ->
- OutVs.
-
-face_id(Face, Fs) ->
- array:get(Face, Fs).
-
-edge_id(Edge, undefined) -> Edge*4;
-edge_id(Edge, Es) -> array:get(Edge, Es).
-
-%%%%%%%%
-%%assert(_OutVs, _Es, _OutFs) -> ok;
-assert(OutVs, Es, OutFs) ->
- io:format("Asserting .. ",[]),
- Assert =
- fun(_, {-1,-1,-1,-1,_H}, _Fs0) -> ok;
- (Edge, E={V1,V2,F1,F2,_H}, _Fs0) ->
- try
- #v{} = array:get(V1, OutVs),
- #v{} = array:get(V2, OutVs),
- find_new_faces(V1,V2,get_face2(F1, OutFs),0),
- find_new_faces(V1,V2,get_face2(F2, OutFs),0)
- catch _:Reason ->
- io:format("assert failed ~p ~p~n",
- [Reason, erlang:get_stacktrace()]),
- io:format("Edge ~p ~p ~n", [Edge, E]),
- io:format(" F ~p: ~p ~n", [F1,get_face2(F1, OutFs)]),
- io:format(" F ~p: ~p ~n", [F2,get_face2(F2, OutFs)]),
- exit(Reason)
- end
- end,
- array:foldl(Assert, array:new([{default, []}]), Es),
- %% ok = array:foldl(fun(_Face, [_,_,_,_], Ok) -> Ok;
- %% (Face, Eds, _) -> {Face,Eds}
- %% end, ok, F2Es),
- io:format("Asserted~n",[]).
-
-get_face2(F, Fs) when F >= 0 ->
- array:get(F,Fs);
-get_face2(_,_) -> -1.
-
-erl_vs(Str, N, Vs) ->
- {ok, F} = file:open(Str ++ "_" ++ integer_to_list(N), [write]),
- try
- W = fun(V, #v{pos={X,Y,Z}, vc=VI},_) ->
- io:format(F,"{~w, {~.4f,~.4f,~.4f}, ~w}~n", [V,X,Y,Z,VI])
- end,
- ok = array:foldl(W, ok, Vs)
- catch E:R ->
- io:format("Failed ~p:~p ~p~n",[E,R,erlang:get_stacktrace()])
- after
- file:close(F)
- end.
-
-erl_face(Str, N, Fs) ->
- {ok, FD} = file:open(Str ++ "_" ++ integer_to_list(N), [write]),
- try
- W = fun(F, [V1,V2,V3,V4], _) ->
- io:format(FD,"{~w, {~w,~w,~w,~w}}.~n", [F,V1,V2,V3,V4])
- end,
- ok = array:foldl(W, ok, Fs)
- catch E:R ->
- io:format("Failed ~p:~p ~p~n",[E,R,erlang:get_stacktrace()])
- after
- file:close(FD)
- end.
-
diff --git a/src/wings_cl.erl b/src/wings_cl.erl
index 04babb1..cee4583 100644
--- a/src/wings_cl.erl
+++ b/src/wings_cl.erl
@@ -12,111 +12,9 @@
%%
-module(wings_cl).
--include_lib("cl/include/cl.hrl").
-
--export([is_available/0,
- setup/0, compile/2, get_context/1, get_device/1,
- cast/5, write/3, read/4,
- tcast/5
- ]).
-
--record(cli, {context, kernels, q, cl, device}).
--record(kernel, {name, id, wg}).
+-export([is_available/0]).
is_available() ->
- try
- true == erlang:system_info(smp_support) orelse throw({error, no_smp_support}),
- ok == cl:start() orelse throw({error, no_opencl_loaded}),
- {ok, Ps} = cl:get_platform_ids(),
- [] /= Ps
- catch _:Reason ->
- io:format("OpenCL not available ~p ~n",[Reason]),
- false
- end.
-
-
-%% setup() -> cli().
-setup() ->
- Prefered = wings_pref:get_value(cl_type, gpu),
- Other = [gpu,cpu] -- [Prefered],
- CL = case clu:setup(Prefered) of
- {error, _} ->
- case clu:setup(Other) of
- {error, R} ->
- exit({no_opencl_device, R});
- Cpu -> Cpu
- end;
- Gpu ->
- Gpu
- end,
- [Device|_] = CL#cl.devices,
- {ok,Queue} = cl:create_queue(CL#cl.context,Device,[]),
- #cli{context=CL#cl.context, q=Queue, device=Device, cl=CL}.
-
-%% compile(File,cli()) -> cli().
-compile(File, CLI = #cli{cl=CL, device=Device}) ->
- Dir = filename:join(code:lib_dir(wings),"shaders"),
- {ok, Bin} = file:read_file(filename:join([Dir, File])),
- case clu:build_source(CL, Bin) of
- {error, {Err={error,build_program_failure}, _}} ->
- %% io:format("~s", [Str]),
- exit(Err);
- {ok, Program} ->
- {ok, MaxWGS} = cl:get_device_info(Device, max_work_group_size),
- {ok, Kernels0} = cl:create_kernels_in_program(Program),
- Kernels = [kernel_info(K,Device, MaxWGS) || K <- Kernels0],
- cl:release_program(Program),
- CLI#cli{kernels=Kernels}
- end.
-
-kernel_info(K,Device, MaxWGS) ->
- {ok, WG} = cl:get_kernel_workgroup_info(K, Device, work_group_size),
- {ok, Name} = cl:get_kernel_info(K, function_name),
- #kernel{name=list_to_atom(Name), wg=min(WG,MaxWGS), id=K}.
-
-get_context(#cli{context=Context}) ->
- Context.
-get_device(#cli{device=Device}) ->
- Device.
-
-
-%% cast(Kernel, Args, NoInvocations, [Wait], cli()) -> Wait
-tcast(Name, Args, No, Wait, CL) ->
- cast(Name, Args, No, Wait, true, CL).
-
-cast(Name, Args, No, Wait, CL) ->
- cast(Name, Args, No, Wait, false, CL).
-cast(Name, Args, No, Wait, Time, #cli{q=Q, kernels=Ks}) ->
- #kernel{id=K, wg=WG0} = lists:keyfind(Name, 2, Ks),
- try clu:apply_kernel_args(K, Args) of
- ok -> ok
- catch error:Reason ->
- io:format("Bad args ~p: ~p~n",[Name, Args]),
- erlang:raise(error,Reason, erlang:get_stacktrace())
- end,
- {GWG,WG} = if No > WG0 ->
- {(1+(No div WG0))*WG0, WG0};
- true -> {No,No}
- end,
- %% io:format("X ~p GWG ~p WG ~p~n", [Name, GWG, WG]),
- {ok, Event} = cl:enqueue_nd_range_kernel(Q,K,[GWG],[WG],Wait),
- Time andalso time_wait(Name, Event),
- Event.
-
-time_wait(Name, Event) ->
- Before = os:timestamp(),
- {ok,completed} = cl:wait(Event),
- io:format("CL ~p Time: ~p\n", [Name, timer:now_diff(os:timestamp(),Before)]).
-
-
-%% write(CLMem, Bin, cli()) -> Wait
-write(CLMem, Bin, #cli{q=Q}) ->
- {ok, W1} = cl:enqueue_write_buffer(Q, CLMem, 0, byte_size(Bin), Bin, []),
- W1.
-
-%% read(CLMem, Sz, [Wait], cli()) -> Wait
-read(CLMem, Sz, Wait, #cli{q=Q}) ->
- {ok, W} = cl:enqueue_read_buffer(Q,CLMem,0,Sz, Wait),
- W.
-
+ io:format("OpenCL is not available in Fedora (yet).~n"),
+ false.
diff --git a/src/wings_proxy.erl b/src/wings_proxy.erl
index da3d682..9bf4322 100644
--- a/src/wings_proxy.erl
+++ b/src/wings_proxy.erl
@@ -164,14 +164,6 @@ update_edges_1(_, #sp{vab=#vab{face_vs=BinVs,face_fn=Ns,mat_map=MatMap}}, all) -
wings_draw_setup:disableVertexPointer(BinVs),
wings_draw_setup:disableNormalPointer(Ns),
Dl;
-update_edges_1(#dlo{}, #sp{type={wings_cc,_}, vab=#vab{face_es={0,Bin}}}, some) ->
- Dl = gl:genLists(1),
- gl:newList(Dl, ?GL_COMPILE),
- gl:enableClientState(?GL_VERTEX_ARRAY),
- wings_draw:drawVertices(?GL_LINES, Bin),
- gl:disableClientState(?GL_VERTEX_ARRAY),
- gl:endList(),
- Dl;
update_edges_1(#dlo{src_we=#we{vp=OldVtab}}, #sp{we=#we{vp=Vtab,es=Etab}=We}, some) ->
Dl = gl:genLists(1),
gl:newList(Dl, ?GL_COMPILE),
@@ -306,7 +298,7 @@ draw_edges_1(#dlo{proxy_data=#sp{proxy_edges=ProxyEdges}}, _) ->
proxy_smooth(We0, Pd0, St) ->
Level = wings_pref:get_value(proxy_opencl_level),
if is_integer(Level),Level > 0 ->
- Impl = wings_cc;
+ Impl = ?MODULE;
true ->
Impl = ?MODULE
end,
@@ -316,16 +308,7 @@ proxy_smooth(We0, Pd0, St) ->
{_, _} = Info when Impl =:= ?MODULE ->
create_proxy_subdiv(Info, We0, St);
{Op, _} ->
- case Pd0 of
- #sp{type={wings_cc,Data}} when Op =:= update ->
- update_proxy_cc(We0, Data);
- _ ->
- try
- create_proxy_cc(We0, Level, St)
- catch to_large -> %% Fallback if we can't allocate memory
- create_proxy_subdiv({smooth,We0}, We0, St)
- end
- end
+ create_proxy_subdiv({smooth,We0}, We0, St)
end.
proxy_needs_update(We, #sp{we=SWe,src_we=We,vab=#vab{face_vs=Bin}})
@@ -357,56 +340,6 @@ create_proxy_subdiv(Info, We0, St) ->
Plan = wings_draw_setup:prepare(gb_trees:to_list(We#we.fs), We, St),
flat_faces(Plan, #sp{src_we=We0,we=We}).
-update_proxy_cc(We0, Data0) ->
- Data = wings_cc:update(We0, Data0),
- Vab = wings_cc:gen_vab(Data),
- #sp{src_we=We0,we=We0,vab=Vab,type={wings_cc,Data}}.
-
-create_proxy_cc(We = #we{fs=Ftab}, Level, St) ->
- Plan = wings_draw_setup:prepare(gb_trees:keys(Ftab), We, St),
- Data = wings_cc:init(Plan, Level, We),
- Vab = wings_cc:gen_vab(Data),
- #sp{src_we=We,we=We,vab=Vab,type={wings_cc,Data}}.
-
-split_proxy(#dlo{proxy=true, src_we=We=#we{fs=Ftab},
- proxy_data=Pd=#sp{type={wings_cc,Data0}}},
- DynVs0, St) ->
- Fs0 = gb_trees:keys(Ftab),
- DynFs0 = wings_face:from_vs(DynVs0, We),
-
- %% Expand once (to get the split drawing faces)
- DynVs1 = wings_face:to_vertices(DynFs0, We),
- DynFs = wings_face:from_vs(DynVs1, We),
-
- Data = case proxy_needs_update(We, Pd) of
- {false, _} ->
- Data0;
- {update, _} ->
- wings_cc:update(DynVs0, Data0);
- {_, _} ->
- Plan = wings_draw_setup:prepare(Fs0, We, St),
- wings_cc:init(Plan, Data0, We)
- end,
- StaticFsSet = gb_sets:subtract(gb_sets:from_ordset(Fs0),
- gb_sets:from_ordset(DynFs)),
- StaticFs = gb_sets:to_list(StaticFsSet),
- StaticPlan = wings_draw_setup:prepare(StaticFs, We, St),
- StaticVab = wings_cc:gen_vab(StaticPlan, Data),
- StaticDL = wings_draw:draw_flat_faces(StaticVab, St),
-
- %% To get the subdiv correct we need outer layer of faces during calc
- SubdivVs = wings_face:to_vertices(DynFs, We),
- SubdivFs = wings_face:from_vs(SubdivVs, We),
- SubdivPlan = wings_draw_setup:prepare(SubdivFs, We, St),
- SubdivData = wings_cc:init(SubdivPlan, Data0, We),
-
- DynPlan = wings_draw_setup:prepare(DynFs, We, St),
- DynVab = wings_cc:gen_vab(DynPlan, SubdivData),
- DynDL = wings_draw:draw_flat_faces(DynVab, St),
- Split = #split{dyn=DynPlan, info=SubdivData},
- #sp{we=We,src_we=We,type={wings_cc,Data},
- faces=[StaticDL,DynDL],split=Split};
-
split_proxy(#dlo{proxy=true,proxy_data=Pd0,src_we=SrcWe}, DynVs0, St) ->
DynFs0 = wings_face:from_vs(DynVs0, SrcWe),
#we{mirror=Mirror,holes=Holes} = SrcWe,
@@ -452,13 +385,6 @@ update_dynamic(ChangedVs, St,
Pd1 = flat_faces(DynPlan, Pd0#sp{we=We, src_we=SrcWe}),
Temp = wings_draw:draw_flat_faces(Pd1#sp.vab, St),
D0#dlo{proxy_data=Pd1#sp{faces=[SDL,Temp]}};
-update_dynamic(ChangedVs, St,
- D0=#dlo{proxy=true,proxy_data=#sp{type={wings_cc,_}}=Pd0}) ->
- #sp{faces=[SDL|_],split=SP=#split{dyn=DynPlan, info=Data0}}=Pd0,
- Data = wings_cc:update(ChangedVs, Data0),
- Vab = wings_cc:gen_vab(DynPlan, Data),
- DL = wings_draw:draw_flat_faces(Vab, St),
- D0#dlo{proxy_data=Pd0#sp{faces=[SDL,DL], split=SP#split{info=Data}}};
update_dynamic(_, _, D) ->
D.
--
1.8.1.4