!B (Sandbox) (CE-21795) Importing models with multisubmaterials via fbx switches...
[CRYENGINE.git] / Code / Sandbox / Plugins / LodGeneratorPlugin / Util / UVGenerator.cpp
blob34e2d86e7517b53ae7bfcaca12ca69b34e72fa68
1 #include "StdAfx.h"
2 #include "UVGenerator.h"
3 #include "Splitter.h"
4 #include "ABF.h"
5 #include "Component.h"
6 #include "Packer.h"
7 #include "Validator.h"
9 namespace LODGenerator
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) {
18 return false;
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;
28 max_scaling_ = 20.0;
29 min_fill_ratio_ = 0.25;
30 auto_cut_ = true;
31 auto_cut_cylinders_ = true;
33 parameterizer_ = new CABF();
34 splitter_ = new CSplitter();
37 CUVGenerator::~CUVGenerator()
39 delete parameterizer_;
40 parameterizer_ = NULL;
41 delete splitter_;
42 splitter_ = NULL;
45 void CUVGenerator::activate_component(CComponent* comp, int iter)
47 if(comp->size_of_facets() == 0)
48 return;
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);
65 else
67 CryLog("UVGenerator Split Component failed");
70 delete component;
74 void CUVGenerator::apply()
76 parameterized_faces_ = 0;
77 total_faces_ = map_->size_of_facets();
79 get_components();
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_)
97 CValidator validator;
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);
104 if(is_valid)
106 parameterized_faces_ += cur->size_of_facets();
107 delete cur;
108 cur = NULL;
110 else
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_)));
119 CPacker packer;
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);
141 else
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);
155 else
157 CryLog("UVGenerator topological monster, try to parameterize");
158 activate_component(cur);