void convertMolfile (char *path, char *filename, FileOutput &cpp_file) { FileScanner molfile("%s\\%s", path, filename); MolfileLoader mf_loader(molfile); Molecule mol; QS_DEF(Array<int>, edges); printf("%s\n", filename); mf_loader.loadMolecule(mol, true); BiconnectedDecomposer bd(mol); if (bd.decompose() != 1) { printf("Error: %s is not biconnected\n", filename); return; } int i, j; edges.clear_reserve(mol.edgeCount()); for (i = mol.edgeBegin() ; i < mol.edgeEnd(); i = mol.edgeNext(i)) edges.push(i); edges.qsort(edge_cmp, &mol); const Edge &edge = mol.getEdge(edges[edges.size() / 2]); Vec3f v1 = mol.getAtomPos(edge.beg); Vec3f v2 = mol.getAtomPos(edge.end); v1.z = 0.f; v2.z = 0.f; float scale = Vec3f::dist(v1, v2); if (scale < 0.0001f) { printf("Error: %s has zero bond\n", filename); return; } scale = 1.f / scale; int first_idx = mol.vertexBegin(); Vec3f pos = mol.getAtomPos(first_idx); for (i = mol.vertexNext(first_idx); i < mol.vertexEnd(); i = mol.vertexNext(i)) { if (mol.getAtomPos(i).y < pos.y) { pos = mol.getAtomPos(i); first_idx = i; } } for (i = mol.vertexBegin() ; i < mol.vertexEnd(); i = mol.vertexNext(i)) { mol.getAtom2(i).pos.sub(pos); mol.getAtom2(i).pos.scale(scale); } char buf[1024]; sprintf_s(buf, "BEGIN_PATTERN(\"%s\")", filename); cpp_file.writeStringCR(buf); for (i = mol.vertexBegin(); i < mol.vertexEnd(); i = mol.vertexNext(i)) { sprintf_s(buf, " ADD_ATOM(%d, %ff, %ff)", i, mol.getAtomPos(i).x, mol.getAtomPos(i).y); cpp_file.writeStringCR(buf); } for (i = mol.edgeBegin(); i < mol.edgeEnd(); i = mol.edgeNext(i)) { const Edge &edge = mol.getEdge(i); int type = mol.getBond(i).type; int qtype = mol.getQueryBond(i).type; sprintf_s(buf, " ADD_BOND(%d, %d, %d)", edge.beg, edge.end, qtype != 0 ? qtype : type); cpp_file.writeStringCR(buf); } Vec2f v, inter; Vec2f pos_i; int idx = mol.vertexCount(); i = first_idx; float max_angle, cur_angle; float i_angle = 0; int next_nei = 0; int point_idx = 0; pos_i.set(mol.getAtomPos(i).x, mol.getAtomPos(i).y); while (true) { const Vertex &vert = mol.getVertex(i); if (i != first_idx) { v.set(pos_i.x, pos_i.y); pos_i.set(mol.getAtomPos(i).x, mol.getAtomPos(i).y); v.sub(pos_i); i_angle = v.tiltAngle2(); } else if (point_idx > 0) break; sprintf_s(buf, " OUTLINE_POINT(%d, %ff, %ff)", point_idx++, pos_i.x, pos_i.y); cpp_file.writeStringCR(buf); max_angle = 0.f; for (j = vert.neiBegin(); j < vert.neiEnd(); j = vert.neiNext(j)) { const Vec3f &pos_nei = mol.getAtomPos(vert.neiVertex(j)); v.set(pos_nei.x - pos_i.x, pos_nei.y - pos_i.y); cur_angle = v.tiltAngle2() - i_angle; if (cur_angle < 0.f) cur_angle += 2 * PI; if (max_angle < cur_angle) { max_angle = cur_angle; next_nei = j; } } i = vert.neiVertex(next_nei); float dist, min_dist = 0.f; int int_edge; Vec2f cur_v1 = pos_i; Vec2f cur_v2(mol.getAtomPos(i).x, mol.getAtomPos(i).y); while (min_dist < 10000.f) { min_dist = 10001.f; for (j = mol.edgeBegin(); j < mol.edgeEnd(); j = mol.edgeNext(j)) { const Edge &edge = mol.getEdge(j); Vec2f cur_v3(mol.getAtomPos(edge.beg).x, mol.getAtomPos(edge.beg).y); Vec2f cur_v4(mol.getAtomPos(edge.end).x, mol.getAtomPos(edge.end).y); if (Vec2f::intersection(cur_v1, cur_v2, cur_v3, cur_v4, v)) if ((dist = Vec2f::dist(cur_v1, v)) < min_dist) { inter = v; min_dist = dist; int_edge = j; } } if (min_dist < 10000.f) { sprintf_s(buf, " OUTLINE_POINT(%d, %ff, %ff)", point_idx++, v.x, v.y); cpp_file.writeStringCR(buf); const Edge &edge = mol.getEdge(int_edge); Vec2f cur_v3(mol.getAtomPos(edge.beg).x, mol.getAtomPos(edge.beg).y); Vec2f cur_v4(mol.getAtomPos(edge.end).x, mol.getAtomPos(edge.end).y); Vec2f cur_v1v; Vec2f cur_v3v; Vec2f cur_v4v; cur_v1v.diff(cur_v1, inter); cur_v3v.diff(cur_v3, inter); cur_v4v.diff(cur_v4, inter); float angle1 = cur_v1v.tiltAngle2(); float angle3 = cur_v3v.tiltAngle2() - angle1; float angle4 = cur_v4v.tiltAngle2() - angle1; if (angle3 < 0) angle3 += 2 * PI; if (angle4 < 0) angle4 += 2 * PI; cur_v1 = inter; if (angle3 > angle4) { cur_v2 = cur_v3; i = edge.beg; } else { cur_v2 = cur_v4; i = edge.end; } } } } cpp_file.writeStringCR("END_PATTERN()"); }
void CrfLoader::_loadMolecule (Molecule &molecule) { Obj<CmfLoader> loader; int i; if (_decoder.get() != 0) loader.create(_decoder.ref()); else loader.create(_scanner); QS_DEF(Array<int>, atom_flags); QS_DEF(Array<int>, bond_flags); loader->atom_flags = &atom_flags; loader->bond_flags = &bond_flags; loader->version = version; loader->loadMolecule(molecule); bool has_mapping = loader->has_mapping; if (_atom_stereo_flags != 0) { _atom_stereo_flags->clear_resize(molecule.vertexCount()); _atom_stereo_flags->zerofill(); for (i = 0; i < molecule.vertexCount(); i++) { int idx = i; if (has_mapping) idx = loader->inv_atom_mapping_to_restore[i]; if (atom_flags[i] & 1) _atom_stereo_flags->at(idx) |= STEREO_RETAINS; if (atom_flags[i] & 2) _atom_stereo_flags->at(idx) |= STEREO_INVERTS; } } if (_bond_rc_flags != 0) { _bond_rc_flags->clear_resize(molecule.edgeCount()); _bond_rc_flags->zerofill(); for (i = 0; i < molecule.edgeCount(); i++) { int idx = i; if (has_mapping) idx = loader->inv_bond_mapping_to_restore[i]; if (bond_flags[i] & 1) _bond_rc_flags->at(idx) |= RC_UNCHANGED; if (bond_flags[i] & 2) _bond_rc_flags->at(idx) |= RC_MADE_OR_BROKEN; if (bond_flags[i] & 4) _bond_rc_flags->at(idx) |= RC_ORDER_CHANGED; } } if (_aam != 0) { _aam->clear_resize(molecule.vertexCount()); _aam->zerofill(); for (i = 0; i < molecule.vertexCount(); i++) { int value; if (_decoder.get() != 0) value = _decoder->get(); else value = _scanner.readByte(); int idx = i; if (has_mapping) idx = loader->inv_atom_mapping_to_restore[i]; _aam->at(idx) = value - 1; } } if (xyz_scanner != 0) loader->loadXyz(*xyz_scanner); }