Wings 3D Development Forum
Want to finalize a new wings_we:build for colors. - Printable Version

+- Wings 3D Development Forum (https://www.wings3d.com/forum)
+-- Forum: Wings 3D (https://www.wings3d.com/forum/forumdisplay.php?fid=1)
+--- Forum: Design & Development (https://www.wings3d.com/forum/forumdisplay.php?fid=6)
+--- Thread: Want to finalize a new wings_we:build for colors. (/showthread.php?tid=911)



Want to finalize a new wings_we:build for colors. - ggaliens - 10-22-2014

Want to finalize a new wings_we:build for colors.
I have one that works below in the MIDDLE with rgb vertex colors.
Problem with it as I see it is ... it probably used the wrong sort of accumulator to inject the vertex colors (maybe slow).
Looking for a better way.

Code:
%% build() -> We'
%% Create a we from faces and vertices or a mesh.
build(Mode, #e3d_mesh{fs=Fs0,vs=Vs,tx=Tx,he=He,vc=[]}) when is_atom(Mode) ->
    Fs = translate_faces(Fs0, list_to_tuple(Tx), []),
    #we{} = We = wings_we_build:we(Fs, Vs, He),
    wings_we:renumber(We,0);
build(Mode, #e3d_mesh{fs=Fs0,vs=Vs,tx=Tx,he=He,vc=[{_R,_G,_B}|_]=Vc}) when is_atom(Mode) ->
    Fs = translate_faces(Fs0, list_to_tuple(Tx), []),
    #we{vp=VPos} = We = wings_we_build:we(Fs, Vs, He),
    MyAcc = fun({Vi,_}, Acc) ->
         wings_va:set_vertex_color( gb_sets:singleton(Vi), lists:nth(Vi+1,Vc)  , Acc)
    end,
    We1 = lists:foldl(MyAcc, We, array:sparse_to_orddict(VPos)),
    wings_we:renumber(We1,0);
build(Fs, Vs) ->
    wings_we:renumber(wings_we_build:we(Fs, Vs, []),0).

Cool thing about this is that with a few lines of code changes to the .ply importer ... I can get some neat vertex colors to import from MeshLab.

OH ... some background. I have been doing some mesh analysis that seems to benefit from Ambient Occulsion type vertex colors. But the wings3d built in ambient occ ... is too slow on my models. MeshLabs is a great deal vaster and a bit different w.r.t. quality. So I figured ... try to get those MeshLab colors in via vertex color. I had thought about a WRL importer ... but when looking at ASCII PLY format ... it looked far simpler to just augment the current ply importer to bring in the vertex colors. This seems to be true after it was all said and done. Fairly few lines of code needed to import the vertex colors.


RE: Want to finalize a new wings_we:build for colors. - micheus - 10-22-2014

considering you only need extract the vertex index from VPos, why not use array:fold instead of to convert the array to a lists which from the tuple element you want get the index?
Code:
...
MyAcc = fun(Vi, _Value, We) ->
    wings_va:set_vertex_color(gb_sets:singleton(Vi), lists:nth(Vi+1,Vc) , Acc)
end,

We1 = array:foldl(MyAcc, We, VPos)
...
Considering the use of the API by the wings3d itself I think that use wings_va is the right way to avoid problems with any change made to vertex color attribute.

If the implementation is made in a importer I think it's possible to improve it a little by removing a intermediate function call - the parameters are copied once less: (that makes sense?! Undecided)
Code:
...
    #we{vp=VPos} = We = wings_we_build:we(Fs, Vs, He),
    MyAcc = fun(Vi, _Value, #we{lv=Lva0,rv=Rva0} = We0) ->
        {Lva,Rva} = wings_vertex:fold(
                fun(Edge, _Face, Rec0, {Lv,Rv}) ->
                  case Rec0 of
                      #edge{vs=Vi} ->
                      {set_color(Edge, Color, Lv),Rv};
                      #edge{ve=Vi} ->
                      {Lv,set_color(Edge, Color, Rv)}
                  end,
                end, {Lva0,Rva0}, Vi, We),
        We0#we{lv=Lva,rv=Rva}
    end,
    We1 = array:foldl(MyAcc, We, VPos),
...
it came from wings_vaConfusedet_vertex_color_1. maybe you could test it.


RE: Want to finalize a new wings_we:build for colors. - ggaliens - 10-22-2014

Micheus. You have some good ideas and observations. I will use array:fold

Anyways ... your code is not finding Color . That is one the the problems. I'm using a GbTree now
to do it faster instead of lists:nth. lists nth is just tad slow.

Little bit better ... maybe. I should maybe check that Vs and Vc are of equal length !
I was able to get the PLY vertex colors to work very easily because standard import codes
are doing a bunch of work ... so I want to fix it in a general way ... you know ... and do a pull request if I can get it done just right. Then I can also update WRL importer (old I know).

Code:
build(Mode, #e3d_mesh{fs=Fs0,vs=Vs,tx=Tx,he=He,vc=[{_R,_G,_B}|_]=Vc}) when is_atom(Mode) ->
    Fs = translate_faces(Fs0, list_to_tuple(Tx), []),
    #we{vp=VPos} = We = wings_we_build:we(Fs, Vs, He),
    Dict = lists:zip(lists:seq(0,length(Vc)-1), Vc),
    Tree = gb_trees:from_orddict(Dict),
    MyAcc = fun(Vi,_VAL, Acc) ->
         wings_va:set_vertex_color(gb_sets:singleton(Vi),gb_trees:get(Vi,Tree), Acc)
    end,
    We1 = array:fold(MyAcc, We, VPos),
    wings_we:renumber(We1,0);



RE: Want to finalize a new wings_we:build for colors. - micheus - 10-22-2014

(10-22-2014, 11:25 PM)ggaliens Wrote: Anyways ... your code is not finding Color . That is one the the problems. I'm using a GbTree now
to do it faster instead of lists:nth. lists nth is just tad slow.
Sorry about that.
Yeah, for sure lists:nth was an option by the slowest approach. Smile


RE: Want to finalize a new wings_we:build for colors. - micheus - 10-25-2014

As I had to look into the code to know better about this subject I think the best option (thinking about optimization too) is to use the vc field of #e3d_face{} data structure in the importer.

wings_we:build process that data using the translate_faces before call wings_we_build:we.
Currently, translate_faces is processing only material (mat) and texture (tx) for each vertex of a face. So, there is room to process vertex color (vc) too.

By doing that, it's necessary to create a new wings_we_build:build_half_edges "binding" (?!) and update the other functions called by it.

I believe this is the best and the right way to get the vertex color imported and managed in a native way. That's my thought.


RE: Want to finalize a new wings_we:build for colors. - ggaliens - 10-26-2014

I checked the PLY file format spec and then did example export from MeshLab ...
which leads me to believe that PLY will support both pure vertex colors (which I handle now) and also
per-face vertex colors ... which you are suggesting also need consideration.


RE: Want to finalize a new wings_we:build for colors. - ggaliens - 10-27-2014

I think for this all to be taken a step further along the lines you suggest ... we need

Fs, Fc, Vs, Vc lists coming back from a plugin.

Currently ... we would only even have structure for Fs, Vs, Vc ... we are missing Fc


RE: Want to finalize a new wings_we:build for colors. - micheus - 10-27-2014

If the plugin fill the Fs (#e3d_face{}) no much changes need to be made to the wings3d core. I'm sure you are able to update Fs data in order to have the vertex color information and it still should be faster than using your current implementation vertex by vertex.


RE: Want to finalize a new wings_we:build for colors. - ggaliens - 10-27-2014

There is no Fs in e3d_face (at least on my machine with the headers I have).

So, if I was to add it in there ... I would call it Fc and not Fs. This would be more consistent with
everything else in the code base.


RE: Want to finalize a new wings_we:build for colors. - micheus - 10-27-2014

Fs is related to fs field you found in the #e3d_mesh {} whish is the parameter you find in build function - the same you are "rewriting". That fs is a #e3d_face{}. And any plugin can provide that information to the wings3d core.

Fell free to do what do you think is needed. You need dgud approval - not mine. Wink