2 #include "UVGenerator.h"
11 static double default_sock_treshold
= 5.0 / (4.0 * 4.0);
13 static bool component_is_sock(CComponent
* comp
, double treshold
= default_sock_treshold
)
15 double area
= comp
->component_area();
16 double perimeter
= comp
->component_border_length();
17 if(::fabs(perimeter
) < 1e-30) {
20 // Note: perimeter is squared to be scale invariant
21 double ratio
= area
/ (perimeter
* perimeter
);
22 return (ratio
> treshold
);
25 CUVGenerator::CUVGenerator(CTopologyGraph
* map
) : map_(map
)
27 max_overlap_ratio_
= 0.005;
29 min_fill_ratio_
= 0.25;
31 auto_cut_cylinders_
= true;
33 parameterizer_
= new CABF();
34 splitter_
= new CSplitter();
37 CUVGenerator::~CUVGenerator()
39 delete parameterizer_
;
40 parameterizer_
= NULL
;
45 void CUVGenerator::activate_component(CComponent
* comp
, int iter
)
47 if(comp
->size_of_facets() == 0)
50 SActiveComponent
i(iter
+1);
51 active_components_
.push_back(i
);
52 active_components_
.back().component
= comp
;
55 void CUVGenerator::split_component(CComponent
* component
, int iter
)
57 std::vector
<CComponent
*> charts
;
58 if(splitter_
->split_component(component
, charts
))
60 for(unsigned int i
=0; i
<charts
.size(); i
++)
62 activate_component(charts
[i
],iter
);
67 CryLog("UVGenerator Split Component failed");
74 void CUVGenerator::apply()
76 parameterized_faces_
= 0;
77 total_faces_
= map_
->size_of_facets();
81 FOR_EACH_HALFEDGE(CTopologyGraph
, map_
, it
)
83 (*it
)->tex_vertex()->set_tex_coord(Vec2d(0,0));
86 while(!active_components_
.empty())
88 int iter
= active_components_
.front().iter
;
89 CComponent
* cur
= active_components_
.front().component
;
90 active_components_
.pop_front();
91 CryLog("UVGenerator Processing component, iter= %d size= %d",iter
,cur
->size_of_facets());
93 bool is_valid
= parameterizer_
->parameterize_disc(cur
);
95 if(is_valid
&& auto_cut_
)
98 validator
.set_max_overlap_ratio(max_overlap_ratio_
);
99 validator
.set_max_scaling(max_scaling_
);
100 validator
.set_min_fill_ratio(min_fill_ratio_
);
101 is_valid
= validator
.component_is_valid(cur
);
106 parameterized_faces_
+= cur
->size_of_facets();
112 split_component(cur
, iter
);
115 CryLog("UVGenerator ====> %d/%d parameterized (%d%%)",parameterized_faces_
,total_faces_
,int(double(parameterized_faces_
) * 100.0 / double(total_faces_
)));
120 packer
.pack_map(map_
);
123 CryLog("UVGenerator total elapsed time: ??");
127 void CUVGenerator::get_components()
129 CComponentExtractor extractor
;
130 ComponentList components
= extractor
.extract_components(map_
);
132 for(ComponentList::iterator it
= components
.begin(); it
!= components
.end(); it
++)
134 CComponent
* cur
= (*it
);
135 CComponentTopology
topology(cur
);
136 if( topology
.is_disc() && !topology
.is_almost_closed())
138 CryLog("UVGenerator component is disc");
139 activate_component(cur
);
143 CryLog("UVGenerator Processing non-disc component");
144 CryLog("UVGenerator xi=%d #borders=%d #vertices=%d #facets=%d largest border size=%d largest border size=%d",topology
.xi(),topology
.number_of_borders(),cur
->size_of_vertices(),cur
->size_of_facets(),topology
.largest_border_size());
145 if( (topology
.is_almost_closed() || (topology
.is_disc() && component_is_sock(cur
)) ) )
147 CryLog("UVGenerator Almost closed component, cutting ...");
148 split_component(cur
);
150 else if (auto_cut_cylinders_
&& topology
.is_cylinder())
152 CryLog("UVGenerator Cutting cylinder ...");
153 split_component(cur
);
157 CryLog("UVGenerator topological monster, try to parameterize");
158 activate_component(cur
);