void MoleculeCleaner2d::_initComponents()

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();
}