LowStretchTorusParametrization.cpp
Go to the documentation of this file.
2
3#include "Bitmap.h"
4
6{
7 m_hcs.FromNormal(m_torus->AxisDirection());
8 m_minorFrame.Canonical();
9}
10
11void
13{
14 m_torus = &torus;
15 m_hcs.FromNormal(m_torus->AxisDirection());
16 m_minorFrame.Canonical();
17}
18
19void
22 float epsilon,
23 size_t uextent,
24 size_t vextent,
25 MiscLib::Vector<int>* componentImg,
26 MiscLib::Vector<std::pair<int, size_t>>* labels) const
27{
28 // there are wraps along both u and v direction
29 // the first pixel of each column/row is copied to the last element
30 // and components are merged accordingly
31
32 // relabel the components
33 MiscLib::Vector<std::pair<int, size_t>> tempLabels(*labels);
34
35 // first wrap along v (minor radius)
36 // but only if necessary
37 if (bbox.Max()[1] - bbox.Min()[1] >= 2 * M_PI * m_torus->MinorRadius() - 2 * epsilon)
38 {
39 for (size_t u = 0; u < uextent; ++u)
40 {
41 if (!(*componentImg)[u])
42 {
43 continue;
44 }
45 // check the three neighbors on the other side
46 if ((*componentImg)[(vextent - 1) * uextent + u])
48 (*componentImg)[u], (*componentImg)[(vextent - 1) * uextent + u], &tempLabels);
49 if (u > 0 && u < uextent - 1 && (*componentImg)[(vextent - 1) * uextent + u + 1])
50 AssociateLabel((*componentImg)[u],
51 (*componentImg)[(vextent - 1) * uextent + u + 1],
52 &tempLabels);
53 if (u > 0 && (*componentImg)[(vextent - 1) * uextent + u - 1])
54 AssociateLabel((*componentImg)[u],
55 (*componentImg)[(vextent - 1) * uextent + u - 1],
56 &tempLabels);
57 }
58 }
59
60 // wrap along u (major radius)
61 float minorRot = MinorFrameRotation(); // get the rotation of the minor frame
62 float ustartPrev, uendPrev, ustart = 0, uend = 0, ustartNext = 0, uendNext = 0;
63 size_t usPrev, uePrev, us = 0, ue = 0, usNext = 0, ueNext = 0;
64 float vangle = (bbox.Min()[1] + .5f * epsilon) / m_torus->MinorRadius();
65 float majorRadius =
66 m_torus->MajorRadius() + std::cos(vangle + minorRot) * m_torus->MinorRadius();
67 ustartNext = float(-M_PI) * majorRadius;
68 uendNext = float(M_PI) * majorRadius;
69 usNext =
70 std::min(uextent - 1,
71 (size_t)std::max((intptr_t)0, (intptr_t)((ustartNext - bbox.Min()[0]) / epsilon)));
72 ueNext = (size_t)std::max(
73 (intptr_t)0,
74 std::min((intptr_t)uextent - 1, (intptr_t)((uendNext - bbox.Min()[0]) / epsilon)));
75 for (size_t v = 0; v < vextent; ++v)
76 {
77 ustartPrev = ustart;
78 ustart = ustartNext;
79 uendPrev = uend;
80 uend = uendNext;
81 usPrev = us;
82 us = usNext;
83 uePrev = ue;
84 ue = ueNext;
85 // determine starting position in the next column
86 if (v < vextent - 1)
87 {
88 float vangle = ((v + 1.5f) * epsilon + bbox.Min()[1]) / m_torus->MinorRadius();
89 float majorRadius =
90 m_torus->MajorRadius() + std::cos(vangle + minorRot) * m_torus->MinorRadius();
91 ustartNext = float(-M_PI) * majorRadius;
92 uendNext = float(M_PI) * majorRadius;
93 usNext = std::min(
94 uextent - 1,
95 (size_t)std::max((intptr_t)0, (intptr_t)((ustartNext - bbox.Min()[0]) / epsilon)));
96 ueNext = (size_t)std::max(
97 (intptr_t)0,
98 std::min((intptr_t)uextent - 1, (intptr_t)((uendNext - bbox.Min()[0]) / epsilon)));
99 }
100 if (ustart <= bbox.Min()[0] - epsilon || uend >= bbox.Max()[0] + epsilon ||
101 !(*componentImg)[v * uextent + us])
102 {
103 continue;
104 }
105 // check the three neighbors on the other side
106 if ((*componentImg)[v * uextent + ue])
108 (*componentImg)[v * uextent + us], (*componentImg)[v * uextent + ue], &tempLabels);
109 if (v > 0 && ustartPrev > bbox.Min()[0] - epsilon && uendPrev < bbox.Min()[0] + epsilon &&
110 (*componentImg)[(v - 1) * uextent + uePrev])
111 AssociateLabel((*componentImg)[v * uextent + us],
112 (*componentImg)[(v - 1) * uextent + uePrev],
113 &tempLabels);
114 if (v < vextent - 1 && ustartNext > bbox.Min()[0] - epsilon &&
115 uendNext < bbox.Min()[0] + epsilon && (*componentImg)[(v + 1) * uextent + ueNext])
116 AssociateLabel((*componentImg)[v * uextent + us],
117 (*componentImg)[(v + 1) * uextent + ueNext],
118 &tempLabels);
119 }
120
121 // condense labels
122 for (size_t i = tempLabels.size() - 1; i > 0; --i)
123 {
124 tempLabels[i].first = ReduceLabel(i, tempLabels);
125 }
126 MiscLib::Vector<int> condensed(tempLabels.size());
127 labels->clear();
128 labels->reserve(condensed.size());
129 int count = 0;
130 for (size_t i = 0; i < tempLabels.size(); ++i)
131 if (i == tempLabels[i].first)
132 {
133 labels->push_back(std::make_pair(count, tempLabels[i].second));
134 condensed[i] = count;
135 ++count;
136 }
137 else
138 (*labels)[condensed[tempLabels[i].first]].second += tempLabels[i].second;
139 // set new component ids
140 for (size_t i = 0; i < componentImg->size(); ++i)
141 (*componentImg)[i] = condensed[tempLabels[(*componentImg)[i]].first];
142}
143
144size_t
146{
147 return 2 * sizeof(float);
148}
149
150void
151LowStretchTorusParametrization::Serialize(std::ostream* o, bool binary) const
152{
153 float rot = 0;
154 if (binary)
155 {
156 rot = MajorFrameRotation();
157 o->write((char*)&rot, sizeof(rot));
158 rot = MinorFrameRotation();
159 o->write((char*)&rot, sizeof(rot));
160 }
161 else
162 {
163 *o << MajorFrameRotation() << " " << MinorFrameRotation() << " ";
164 }
165}
166
167void
169{
170 float majorRot, minorRot;
171 if (binary)
172 {
173 i->read((char*)&majorRot, sizeof(majorRot));
174 i->read((char*)&minorRot, sizeof(minorRot));
175 }
176 else
177 {
178 *i >> majorRot >> minorRot;
179 }
181 nframe.FromNormal(m_torus->AxisDirection());
182 nframe.RotateOnNormal(majorRot);
183 m_hcs[0] = nframe[0];
184 m_hcs[1] = nframe[1];
185 m_minorFrame.Canonical();
186 m_minorFrame.RotateFrame(minorRot);
187}
188
189float
190LowStretchTorusParametrization::MinorFrameRotation() const
191{
192 return std::atan2(GfxTL::Math<float>::Clamp(m_minorFrame[0][1], -1, 1),
193 GfxTL::Math<float>::Clamp(m_minorFrame[0][0], -1, 1));
194}
195
196float
197LowStretchTorusParametrization::MajorFrameRotation() const
198{
199 // defer rotation from frame
200 GfxTL::Frame<3, float> nframe;
201 nframe.FromNormal(m_torus->AxisDirection());
202 GfxTL::VectorXD<2, float> t;
203 nframe.ToTangent(m_hcs[0], &t);
204 for (unsigned int i = 0; i < 2; ++i)
205 {
206 t[i] = GfxTL::Math<float>::Clamp(t[i], -1, 1);
207 }
208 return std::atan2(t[1], t[0]);
209}
#define float
Definition 16_Level.h:22
int ReduceLabel(int a, const MiscLib::Vector< std::pair< int, size_t > > &labels)
Definition Bitmap.cpp:866
void AssociateLabel(int a, int b, MiscLib::Vector< std::pair< int, size_t > > *labels)
Definition Bitmap.cpp:840
#define M_PI
Definition MathTools.h:17
Point & Min()
Definition AABox.hpp:68
Point & Max()
Definition AABox.hpp:82
static ScalarT Clamp(ScalarT s, ScalarT bottom, ScalarT top)
Definition MathHelper.h:39
void WrapComponents(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, size_t uextent, size_t vextent, MiscLib::Vector< int > *componentImg, MiscLib::Vector< std::pair< int, size_t > > *labels) const
void Deserialize(std::istream *i, bool binary)
void Serialize(std::ostream *o, bool binary) const
size_type size() const
Definition Vector.h:215
Definition Torus.h:21