in core/indigo-core/layout/src/molecule_cleaner_2d.cpp [91:354]
void MoleculeCleaner2d::_initComponents(bool use_beconnected_decomposition)
{
pos.clear_resize(vertex_size);
base_point.clear();
in.clear();
for (int i = 0; i < vertex_size; i++)
{
coef.push();
coef.top().clear();
}
if (use_beconnected_decomposition)
{
BiconnectedDecomposer bi_decomposer(_mol);
component_count = bi_decomposer.decompose();
for (int i = 0; i < component_count; i++)
{
in.push();
in.top().clear_resize(vertex_size);
in.top().zerofill();
}
Filter filter;
_is_trivial.clear_resize(component_count);
_is_trivial.zerofill();
for (int i = 0; i < component_count; i++)
{
bi_decomposer.getComponent(i, filter);
int cnt = 0;
for (int j = _mol.vertexBegin(); j != _mol.vertexEnd(); j = _mol.vertexNext(j))
{
in[i][j] = filter.valid(j);
cnt += in[i][j];
}
if (cnt == 2)
_is_trivial[i] = true;
}
}
else
{
component_count = _mol.edgeCount();
for (int i = 0; i < component_count; i++)
{
in.push();
in.top().clear_resize(vertex_size);
in.top().zerofill();
}
_is_trivial.clear_resize(component_count);
for (int i = 0, e = _mol.edgeBegin(); e != _mol.edgeEnd(); i++, e = _mol.edgeNext(e))
{
const Edge& edge = _mol.getEdge(e);
in[i][edge.beg] = true;
in[i][edge.end] = true;
_is_trivial[i] = true;
}
}
_uniteBondsOnLine();
_initArtPoints();
_initBasePointValid();
if (component_count == 1)
{
is_trivial = true;
return;
}
definiting_points.clear();
for (int i = 0; i < component_count; i++)
{
definiting_points.push();
definiting_points.top().clear();
}
if (use_beconnected_decomposition)
{
QS_DEF(Array<bool>, has_component);
QS_DEF(Array<int>, component_list);
QS_DEF(Array<bool>, has_vertex);
QS_DEF(Array<bool>, block_vertex);
has_component.clear_resize(component_count);
has_component.zerofill();
component_list.clear();
has_vertex.clear_resize(vertex_size);
has_vertex.zerofill();
block_vertex.clear_resize(vertex_size);
block_vertex.zerofill();
QS_DEF(Array<int>, local_component_list);
int index = 0;
for (int c = 0; c < component_count; c++)
if (!has_component[c])
{
int ver = -1;
for (int i = _mol.vertexBegin(); i != _mol.vertexEnd(); i = _mol.vertexNext(i))
if (in[c][i])
if (is_valid_base[i])
{
ver = i;
break;
}
if (ver == -1)
{
for (int i = _mol.vertexBegin(); i != _mol.vertexEnd(); i = _mol.vertexNext(i))
if (in[c][i])
{
ver = i;
break;
}
}
base_point.push(ver);
_addCoef(ver, base_point.size() - 1, ONE);
has_vertex[ver] = true;
block_vertex[ver] = true;
has_component[c] = true;
component_list.push(c);
for (; index < component_list.size(); index++)
{
// 1. Search for new vertex
int comp = component_list[index];
ver = -1;
for (int j = _mol.vertexBegin(); j != _mol.vertexEnd(); j = _mol.vertexNext(j))
if (in[comp][j] && !block_vertex[j] && is_art_point[j])
{
ver = j;
break;
}
if (ver == -1)
{
for (int j = _mol.vertexBegin(); j != _mol.vertexEnd(); j = _mol.vertexNext(j))
if (in[comp][j] && !block_vertex[j] && is_valid_base[j])
{
ver = j;
break;
}
}
if (ver == -1)
{
for (int j = _mol.vertexBegin(); j != _mol.vertexEnd(); j = _mol.vertexNext(j))
if (in[comp][j] && !block_vertex[j])
{
ver = j;
break;
}
}
if (ver == -1)
{
for (int j = _mol.vertexBegin(); j != _mol.vertexEnd(); j = _mol.vertexNext(j))
if (in[comp][j] && is_valid_base[j])
{
ver = j;
break;
}
}
base_point.push(ver);
_addCoef(ver, base_point.size() - 1, ONE);
has_vertex[ver] = true;
// 2. Add yet another defining point if it is need
for (int j = 0; j < base_point.size(); j++)
if (in[comp][base_point[j]])
definiting_points[comp].push(base_point[j]);
if (definiting_points[comp].size() < 2)
{
int newver = -1;
for (int j = _mol.vertexBegin(); j != _mol.vertexEnd(); j = _mol.vertexNext(j))
if (block_vertex[j] && in[comp][j])
{
newver = j;
break;
}
definiting_points[comp].push(newver);
}
// 3. Calculation coefficients
for (int j = _mol.vertexBegin(); j != _mol.vertexEnd(); j = _mol.vertexNext(j))
if (in[comp][j] && j != definiting_points[comp][0] && j != definiting_points[comp][1] && !block_vertex[j])
_calcCoef(j, definiting_points[comp][0], definiting_points[comp][1]);
// 4. Add new components to list
for (int v = _mol.vertexBegin(); v != _mol.vertexEnd(); v = _mol.vertexNext(v))
if (in[comp][v] && is_art_point[v])
{
for (int j = 0; j < component_count; j++)
if (in[j][v] && !has_component[j])
{
component_list.push(j);
has_component[j] = true;
}
}
for (int v = _mol.vertexBegin(); v != _mol.vertexEnd(); v = _mol.vertexNext(v))
if (in[comp][v])
block_vertex[v] = true;
}
}
}
else
{
for (int v = _mol.vertexBegin(); v != _mol.vertexEnd(); v = _mol.vertexNext(v))
if (is_valid_base[v])
{
base_point.push(v);
_addCoef(v, base_point.size() - 1, ONE);
}
QS_DEF(Array<int>, vertex_list);
QS_DEF(Array<char>, debug_atoms);
vertex_list.clear();
for (int c = 0; c < component_count; c++)
{
vertex_list.clear();
for (int v = _mol.vertexBegin(); v != _mol.vertexEnd(); v = _mol.vertexNext(v))
if (in[c][v] && is_valid_base[v])
{
vertex_list.push(v);
break;
}
std::set<int> vertices;
vertices.insert(vertex_list.top());
std::set<int>::iterator it;
while (true)
{
const Vertex& vert = _mol.getVertex(vertex_list.top());
bool found = false;
for (int n = vert.neiBegin(); n != vert.neiEnd() && !found; n = vert.neiNext(n))
{
_mol.getAtomSymbol(vert.neiVertex(n), debug_atoms);
if (in[c][vert.neiVertex(n)] && vertices.count(vert.neiVertex(n)) < 1)
{
found = true;
vertex_list.push(vert.neiVertex(n));
vertices.insert(vert.neiVertex(n));
}
}
if (!found)
break;
}
for (int i = 1; i < vertex_list.size() - 1; i++)
{
_calcCoef(vertex_list[i], vertex_list[0], vertex_list.top(), _2FLOAT(1. - 1. * i / (vertex_list.size() - 1)));
}
}
}
is_trivial = component_count <= 1;
_initBasePointIndex();
_initGeometry();
}