File: MolDraw2DDetails.h

package info (click to toggle)
rdkit 202209.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 203,880 kB
  • sloc: cpp: 334,239; python: 80,247; ansic: 24,579; java: 7,667; sql: 2,123; yacc: 1,884; javascript: 1,358; lex: 1,260; makefile: 576; xml: 229; fortran: 183; cs: 181; sh: 101
file content (156 lines) | stat: -rw-r--r-- 7,043 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//
//  Copyright (C) 2015-2020 Greg Landrum
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//

#include <RDGeneral/export.h>
#ifndef RDKITMOLDRAW2DDETAILS_H
#define RDKITMOLDRAW2DDETAILS_H

#include <vector>

#include <Geometry/point.h>
#include <GraphMol/RDKitBase.h>
#include <GraphMol/MolDraw2D/MolDraw2D.h>

#include <boost/tuple/tuple.hpp>
#include <boost/format.hpp>

// ****************************************************************************
using RDGeom::Point2D;

namespace RDKit {
namespace MolDraw2D_detail {
struct StringRect;

// data taken from the helvetica font info in
// $RDBASE/rdkit/sping/PDF/pdfmetrics.py
const int char_widths[] = {
    0,   0,    0,   0,   0,   0,   0,    0,    0,    0,   0,    0,   0,    0,
    0,   0,    0,   0,   0,   0,   0,    0,    0,    0,   0,    0,   0,    0,
    0,   0,    0,   0,   278, 278, 355,  556,  556,  889, 667,  222, 333,  333,
    389, 584,  278, 333, 278, 278, 556,  556,  556,  556, 556,  556, 556,  556,
    556, 556,  278, 278, 584, 584, 584,  556,  1015, 667, 667,  722, 722,  667,
    611, 778,  722, 278, 500, 667, 556,  833,  722,  778, 667,  778, 722,  667,
    611, 722,  667, 944, 667, 667, 611,  278,  278,  278, 469,  556, 222,  556,
    556, 500,  556, 556, 278, 556, 556,  222,  222,  500, 222,  833, 556,  556,
    556, 556,  333, 500, 278, 556, 500,  722,  500,  500, 500,  334, 260,  334,
    584, 0,    0,   0,   0,   0,   0,    0,    0,    0,   0,    0,   0,    0,
    0,   0,    0,   0,   0,   0,   0,    0,    0,    0,   0,    0,   0,    0,
    0,   0,    0,   0,   0,   0,   0,    333,  556,  556, 167,  556, 556,  556,
    556, 191,  333, 556, 333, 333, 500,  500,  0,    556, 556,  556, 278,  0,
    537, 350,  222, 333, 333, 556, 1000, 1000, 0,    611, 0,    333, 333,  333,
    333, 333,  333, 333, 333, 0,   333,  333,  0,    333, 333,  333, 1000, 0,
    0,   0,    0,   0,   0,   0,   0,    0,    0,    0,   0,    0,   0,    0,
    0,   1000, 0,   370, 0,   0,   0,    0,    556,  778, 1000, 365, 0,    0,
    0,   0,    0,   889, 0,   0,   0,    278,  0,    0,   222,  611, 944,  611,
    0,   0,    834};

// angles in degrees.
RDKIT_MOLDRAW2D_EXPORT void arcPoints(const Point2D &cds1, const Point2D &cds2,
                                      std::vector<Point2D> &res,
                                      float startAng = 0, float extent = 360);

//! add R/S, relative stereo, and E/Z annotations to atoms and bonds
RDKIT_MOLDRAW2D_EXPORT void addStereoAnnotation(
    const ROMol &mol, bool includeRelativeCIP = false);

//! add annotations with atom indices.
RDKIT_MOLDRAW2D_EXPORT inline void addAtomIndices(const ROMol &mol) {
  // we don't need this in the global set of tags since it will only be used
  // here
  if (mol.hasProp("_atomIndicesAdded")) {
    return;
  }
  bool computed = true;
  mol.setProp("_atomIndicesAdded", 1, computed);
  for (auto atom : mol.atoms()) {
    auto lab = std::to_string(atom->getIdx());
    if (atom->hasProp(common_properties::atomNote)) {
      lab += "," + atom->getProp<std::string>(common_properties::atomNote);
    }
    atom->setProp(common_properties::atomNote, lab);
  }
};

//! add annotations with bond indices.
RDKIT_MOLDRAW2D_EXPORT inline void addBondIndices(const ROMol &mol) {
  // we don't need this in the global set of tags since it will only be used
  // here
  if (mol.hasProp("_bondIndicesAdded")) {
    return;
  }
  bool computed = true;
  mol.setProp("_bondIndicesAdded", 1, computed);
  for (auto bond : mol.bonds()) {
    auto lab = std::to_string(bond->getIdx());
    if (bond->hasProp(common_properties::bondNote)) {
      lab += "," + bond->getProp<std::string>(common_properties::bondNote);
    }
    bond->setProp(common_properties::bondNote, lab);
  }
};

RDKIT_MOLDRAW2D_EXPORT std::vector<Point2D> getBracketPoints(
    const Point2D &p1, const Point2D &p2, const Point2D &refPt,
    const std::vector<std::pair<Point2D, Point2D>> &bondSegments,
    double bracketFrac = 0.1);
// there are a several empirically determined constants here.
RDKIT_MOLDRAW2D_EXPORT std::vector<Point2D> handdrawnLine(
    Point2D cds1, Point2D cds2, double scale, bool shiftBegin = false,
    bool shiftEnd = false, unsigned nSteps = 4, double deviation = 0.03,
    double endShift = 0.5);

inline std::string formatDouble(double val) {
  return boost::str(boost::format("%.1f") % val);
}

RDKIT_MOLDRAW2D_EXPORT bool doesLineIntersect(const StringRect &rect,
                                              const Point2D &end1,
                                              const Point2D &end2,
                                              double padding);
// returns true if any corner of triangle is inside the rectangle.
RDKIT_MOLDRAW2D_EXPORT bool doesTriangleIntersect(const StringRect &rect,
                                                  const Point2D &pt1,
                                                  const Point2D &pt2,
                                                  const Point2D &pt3,
                                                  double padding);
RDKIT_MOLDRAW2D_EXPORT bool doesLineIntersectEllipse(
    const Point2D &centre, double xradius, double yradius, double padding,
    const Point2D &end1, const Point2D &end2);
// angles expected in degrees, between 0 and 360.
RDKIT_MOLDRAW2D_EXPORT bool doesLineIntersectArc(
    const Point2D &centre, double xradius, double yradius, double start_ang,
    double stop_ang, double padding, const Point2D &end1, const Point2D &end2);
RDKIT_MOLDRAW2D_EXPORT bool doLinesIntersect(const Point2D &l1s,
                                             const Point2D &l1f,
                                             const Point2D &l2s,
                                             const Point2D &l2f, Point2D *ip);
// This uses the barycentric coordinate system method from
// http://totologic.blogspot.com/2014/01/accurate-point-in-triangle-test.html
// where it notes and provides a solution for instabilities when the point
// in exactly on one of the edges of the triangle.  That refinement is not
// implemented because it seems a bit of overkill for most uses.  It is an
// issue when, for example, two triangles share an edge and the point is on that
// edge, when it might give the disappointing result that the point is in
// neither triangle.
RDKIT_MOLDRAW2D_EXPORT bool isPointInTriangle(const Point2D &pt,
                                              const Point2D &t1,
                                              const Point2D &t2,
                                              const Point2D &t3);

// returns a vector of p1,c1,c2,p2 tuples for bezier curves
RDKIT_MOLDRAW2D_EXPORT
std::vector<std::tuple<Point2D, Point2D, Point2D, Point2D>> getWavyLineSegments(
    const Point2D &p1, const Point2D &p2, unsigned int nSegments,
    double vertOffset);

}  // namespace MolDraw2D_detail
}  // namespace RDKit

#endif