<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -3,7 +3,7 @@
 %%
 %%     Functions for reading and writing Wavefront ASCII files (.obj).
 %%
-%%  Copyright (c) 2001-2008 Bjorn Gustavsson
+%%  Copyright (c) 2001-2009 Bjorn Gustavsson
 %%
 %%  See the file &quot;license.terms&quot; for information on usage and redistribution
 %%  of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -637,17 +637,57 @@ export_smooth_groups(#e3d_mesh{fs=Fs0,he=He0}) -&gt;
     Cs = digraph_utils:components(G),
     digraph:delete(G),
 
+    %% Generate a mapping from Face to a list of all neighboring faces.
+    Neib0 = sofs:range(Fam0),
+    Neib1 = sofs:canonical_relation(Neib0),
+    Neib2 = sofs:relation_to_family(Neib1),
+    Neib3 = sofs:family_union(Neib2),
+    Neib4 = sofs:to_external(Neib3),
+    Neib = array:from_orddict(Neib4),
+
     %% Number the smoothing groups starting from 1.
+    %%
+    %% Try to generate as few smoothing groups as possible,
+    %% since some applications may have trouble handling
+    %% hundreds or thousands of smoothing groups.
+    %%
     %% Return [{SG,#e3d_face{}}].
     Fs = sofs:relation(Fs1, [{face,data}]),
-    Sg0 = number(Cs, 1, []),
-    Sg1 = sofs:relation(Sg0, [{group,[face]}]),
-    Sg2 = sofs:family_to_relation(Sg1),
-    Sg3 = sofs:converse(Sg2),
-    Sg4 = sofs:relative_product({Sg3,Fs}),
-    Sg = sofs:range(Sg4),
+    Sg0 = exp_sgs_1(Cs, Neib, array:new()),
+    Sg1 = sofs:relation(Sg0, [{face,group}]),
+    Sg2 = sofs:relative_product({Sg1,Fs}),
+    Sg = sofs:range(Sg2),
     sofs:to_external(Sg).
 
+%% Return [{Face,SG}].
+exp_sgs_1([Fs|Cs], Neib, SgMap0) -&gt;
+    SG = find_sg(Fs, Neib, SgMap0),
+    SgMap = foldl(fun(F, M) -&gt;
+			  array:set(F, SG, M)
+		  end, SgMap0, Fs),
+    exp_sgs_1(Cs, Neib, SgMap);
+exp_sgs_1([], _, SgMap) -&gt; array:to_orddict(SgMap).
+
+%% find_sg(Faces, NeighborMap, SgMap) -&gt; SG
+%%  Find the lowest smoothing group number (&gt;= 1) that is not
+%%  used by any face that is a neighbor to any face in Faces.
+%%
+find_sg(Fs, Neib, SgMap) -&gt;
+    find_sg_2(find_sg_1(Fs, Neib, SgMap, gb_sets:new()), 1).
+
+find_sg_1([F|Fs], Neib, SgMap, Acc0) -&gt;
+    Acc = foldl(fun(N, A) -&gt;
+			case array:get(N, SgMap) of
+			    undefined -&gt; A;
+			    SG when is_integer(SG) -&gt; gb_sets:add(SG, A)
+			end
+		end, Acc0, array:get(F, Neib)),
+    find_sg_1(Fs, Neib, SgMap, Acc);
+find_sg_1([], _, _, Acc) -&gt; gb_sets:to_list(Acc).
+
+find_sg_2([SG|T], SG) -&gt; find_sg_2(T, SG+1);
+find_sg_2(_, SG) -&gt; SG.
+
 build_edges(Fs) -&gt;
     build_edges(Fs, []).
 </diff>
      <filename>e3d/e3d_obj.erl</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>1eccc5f27a05e538b92650f1975b82298c7aa34f</id>
    </parent>
  </parents>
  <author>
    <name>Bjorn Gustavsson</name>
    <email>bjorng@users.sourceforge.net</email>
  </author>
  <url>http://github.com/bjorng/wings/commit/091721dee22478956e3add58cf6637e9f3f06f17</url>
  <id>091721dee22478956e3add58cf6637e9f3f06f17</id>
  <committed-date>2009-06-24T03:32:28-07:00</committed-date>
  <authored-date>2009-06-24T03:32:28-07:00</authored-date>
  <message>OBJ export: Minimize the number of smoothing groups

Some programs seems to have trouble coping with hundreds
or thousands of smoothing groups, so we must limit
the number of smoothing groups.

NOTE: The Wavefront (OBJ) exporter now tries to minimize
the number of smoothing groups. (Thanks to Ran13.) [bjorng]</message>
  <tree>094e4dafebc95b82ba3ffb14ce795af7caf9396b</tree>
  <committer>
    <name>Bjorn Gustavsson</name>
    <email>bjorng@users.sourceforge.net</email>
  </committer>
</commit>
