File: MolDraw2DDetails.h

package info (click to toggle)
rdkit 202503.1-4
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 220,160 kB
  • sloc: cpp: 399,240; python: 77,453; ansic: 25,517; java: 8,173; javascript: 4,005; sql: 2,389; yacc: 1,565; lex: 1,263; cs: 1,081; makefile: 578; xml: 229; fortran: 183; sh: 105
file content (168 lines) | stat: -rw-r--r-- 7,782 bytes parent folder | download | duplicates (2)
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
157
158
159
160
161
162
163
164
165
166
167
168
//
//  Copyright (C) 2015-2022 Greg Landrum and other RDKit contributors
//
//   @@ 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 <tuple>
#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 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);

// calculate the points making up the arrowhead of a DrawShapeArrow, allowing
// for the fact that in polygon mode the point can extend over the end
// of the point, because of the mitring.
RDKIT_MOLDRAW2D_EXPORT void calcArrowHead(Point2D &arrowEnd, Point2D &arrow1,
                                          Point2D &arrow2,
                                          const Point2D &arrowBegin,
                                          bool asPolygon, double frac,
                                          double angle);

// adjust p2 so that the line from p1 to p2 stops where it intersects
// the ellipse.
RDKIT_MOLDRAW2D_EXPORT void adjustLineEndForEllipse(const Point2D &centre,
                                                    double xradius,
                                                    double yradius, Point2D p1,
                                                    Point2D &p2);

}  // namespace MolDraw2D_detail
}  // namespace RDKit

#endif