1%% 2%% e3d_util.erl -- 3%% 4%% Utility functions. 5%% 6%% Copyright (c) 2002-2011 Bjorn Gustavsson 7%% 8%% See the file "license.terms" for information on usage and redistribution 9%% of this file, and for a DISCLAIMER OF ALL WARRANTIES. 10%% 11%% $Id: e3d_util.erl,v 1.2 2006/08/02 20:25:02 antoneos Exp $ 12%% 13 14-module(e3d_util). 15-export([make_uniq/2, indexed_to_raw/2, raw_to_indexed/1]). 16 17-import(lists, [reverse/1,sort/1,sublist/2,sublist/3,all/2]). 18 19make_uniq([Name|_]=Ns0, Max) when is_atom(Name) -> 20 Ns1 = [atom_to_list(N) || N <- Ns0], 21 Ns = make_uniq(Ns1, Max), 22 [{list_to_atom(Orig),list_to_atom(New)} || {Orig,New} <- Ns]; 23make_uniq(Ns, Max) -> make_uniq_0(Ns, Max). 24 25make_uniq_0(L0, Max) -> 26 L1 = [{sublist(Name, Max),Name} || Name <- L0], 27 L = make_uniq_1(L1, Max), 28 [{From,To} || {To,From} <- L]. 29 30make_uniq_1(L, Max) -> 31 R = sofs:relation(L), 32 F0 = sofs:relation_to_family(R), 33 F = sofs:to_external(F0), 34 make_uniq_2(F, Max, [], done). 35 36make_uniq_2([{Short,[Orig]}|T], Max, Acc, Status) -> 37 make_uniq_2(T, Max, [{Short,Orig}|Acc], Status); 38make_uniq_2([{Short,Os0}|T], Max, Acc0, _) -> 39 Os = [{Short,Orig} || Orig <- Os0], 40 Acc = remove_chars(Os, Max, []) ++ Acc0, 41 make_uniq_2(T, Max, Acc, not_done); 42make_uniq_2([], _, Acc, done) -> Acc; 43make_uniq_2([], Max, Acc, not_done) -> 44 L0 = [{sublist(Key, Max),Key} || {Key,_} <- Acc], 45 L1 = make_uniq_1(L0, Max), 46 L2 = sofs:relation(L1), 47 L = sofs:relative_product(L2, sofs:relation(Acc)), 48 sofs:to_external(L). 49 50remove_chars([{Orig,Orig}=Pair|T], Max, Acc) when length(Orig) < Max -> 51 remove_chars(T, Max, [Pair|Acc]); 52remove_chars([{Key,Orig}|T], Max, Acc) when length(Key) >= Max -> 53 New = {sublist(Key, Max-1)++sublist(Orig, Max+1, 999999),Orig}, 54 remove_chars(T, Max, [New|Acc]); 55remove_chars([{Key,Orig}|T], Max, Acc) -> 56 C = trunc($a+rand:uniform(26)), 57 remove_chars(T, Max, [{[C|Key],Orig}|Acc]); 58remove_chars([], Max, Acc) -> 59 L0 = [{sublist(Key, Max),Key} || {Key,_} <- Acc], 60 L1 = make_uniq_1(L0, Max), 61 L2 = sofs:relation(L1), 62 L = sofs:relative_product(L2, sofs:relation(Acc)), 63 sofs:to_external(L). 64 65% 66% Functions for meshes stored in indexed format (verts/faces lists) 67% 68indexed_to_raw(Verts, Faces) -> % replace indices with values 69 VertexArray = array:from_list(Verts), 70 Make_Raw_Face = fun(Face) -> 71 [array:get(Index, VertexArray) || Index <- Face] 72 end, 73 lists:map(Make_Raw_Face, Faces). 74 75raw_to_indexed(RawTriangles) -> % replace values with indices 76 VertsWithDups = lists:append(RawTriangles), 77 Verts = remove_dups(VertsWithDups), 78 IndexedVerts = dict:from_list(add_indices(Verts)), 79 Get_Index = fun(Vertex) -> dict:fetch(Vertex, IndexedVerts) end, 80 Process_Face = fun(Face) -> lists:map(Get_Index, Face) end, 81 Faces = lists:map(Process_Face, RawTriangles), % re-indexes the Faces list 82 {Verts, Faces}. 83 84remove_dups(List) -> % remove duplicates (uses Zero tolerance) 85 lists:usort(List). 86 87add_indices(List) -> 88 ListLen = length(List), 89 Indices = lists:seq(0, ListLen-1), 90 IndexedList = lists:zip(List, Indices), 91 IndexedList. 92 93