RDKit
Open-source cheminformatics and machine learning.
MolDraw2DDetails.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2015-2022 Greg Landrum and other RDKit contributors
3 //
4 // @@ All Rights Reserved @@
5 // This file is part of the RDKit.
6 // The contents are covered by the terms of the BSD license
7 // which is included in the file license.txt, found at the root
8 // of the RDKit source tree.
9 //
10 
11 #include <RDGeneral/export.h>
12 #ifndef RDKITMOLDRAW2DDETAILS_H
13 #define RDKITMOLDRAW2DDETAILS_H
14 
15 #include <vector>
16 
17 #include <Geometry/point.h>
18 #include <GraphMol/RDKitBase.h>
20 
21 #include <tuple>
22 #include <boost/format.hpp>
23 
24 // ****************************************************************************
25 using RDGeom::Point2D;
26 
27 namespace RDKit {
28 namespace MolDraw2D_detail {
29 struct StringRect;
30 
31 // data taken from the helvetica font info in
32 // $RDBASE/rdkit/sping/PDF/pdfmetrics.py
33 const int char_widths[] = {
34  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36  0, 0, 0, 0, 278, 278, 355, 556, 556, 889, 667, 222, 333, 333,
37  389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556,
38  556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667,
39  611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667,
40  611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 222, 556,
41  556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556,
42  556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334,
43  584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45  0, 0, 0, 0, 0, 0, 0, 333, 556, 556, 167, 556, 556, 556,
46  556, 191, 333, 556, 333, 333, 500, 500, 0, 556, 556, 556, 278, 0,
47  537, 350, 222, 333, 333, 556, 1000, 1000, 0, 611, 0, 333, 333, 333,
48  333, 333, 333, 333, 333, 0, 333, 333, 0, 333, 333, 333, 1000, 0,
49  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50  0, 1000, 0, 370, 0, 0, 0, 0, 556, 778, 1000, 365, 0, 0,
51  0, 0, 0, 889, 0, 0, 0, 278, 0, 0, 222, 611, 944, 611,
52  0, 0, 834};
53 
54 // angles in degrees.
55 RDKIT_MOLDRAW2D_EXPORT void arcPoints(const Point2D &cds1, const Point2D &cds2,
56  std::vector<Point2D> &res,
57  float startAng = 0, float extent = 360);
58 
59 //! add R/S, relative stereo, and E/Z annotations to atoms and bonds
61  const ROMol &mol, bool includeRelativeCIP = false);
62 
63 //! add annotations with atom indices.
64 RDKIT_MOLDRAW2D_EXPORT inline void addAtomIndices(const ROMol &mol) {
65  // we don't need this in the global set of tags since it will only be used
66  // here
67  if (mol.hasProp("_atomIndicesAdded")) {
68  return;
69  }
70  bool computed = true;
71  mol.setProp("_atomIndicesAdded", 1, computed);
72  for (auto atom : mol.atoms()) {
73  auto lab = std::to_string(atom->getIdx());
74  if (atom->hasProp(common_properties::atomNote)) {
75  lab += "," + atom->getProp<std::string>(common_properties::atomNote);
76  }
77  atom->setProp(common_properties::atomNote, lab);
78  }
79 };
80 
81 //! add annotations with bond indices.
82 RDKIT_MOLDRAW2D_EXPORT inline void addBondIndices(const ROMol &mol) {
83  // we don't need this in the global set of tags since it will only be used
84  // here
85  if (mol.hasProp("_bondIndicesAdded")) {
86  return;
87  }
88  bool computed = true;
89  mol.setProp("_bondIndicesAdded", 1, computed);
90  for (auto bond : mol.bonds()) {
91  auto lab = std::to_string(bond->getIdx());
92  if (bond->hasProp(common_properties::bondNote)) {
93  lab += "," + bond->getProp<std::string>(common_properties::bondNote);
94  }
95  bond->setProp(common_properties::bondNote, lab);
96  }
97 };
98 
100  const Point2D &p1, const Point2D &p2, const Point2D &refPt,
101  const std::vector<std::pair<Point2D, Point2D>> &bondSegments,
102  double bracketFrac = 0.1);
103 // there are a several empirically determined constants here.
105  Point2D cds1, Point2D cds2, double scale, bool shiftBegin = false,
106  bool shiftEnd = false, unsigned nSteps = 4, double deviation = 0.03,
107  double endShift = 0.5);
108 
109 inline std::string formatDouble(double val) {
110  return boost::str(boost::format("%.1f") % val);
111 }
112 
114  const Point2D &end1,
115  const Point2D &end2,
116  double padding);
117 // returns true if any corner of triangle is inside the rectangle.
119  const Point2D &pt1,
120  const Point2D &pt2,
121  const Point2D &pt3,
122  double padding);
124  const Point2D &centre, double xradius, double yradius, double padding,
125  const Point2D &end1, const Point2D &end2);
126 // angles expected in degrees, between 0 and 360.
128  const Point2D &centre, double xradius, double yradius, double start_ang,
129  double stop_ang, double padding, const Point2D &end1, const Point2D &end2);
131  const Point2D &l1f,
132  const Point2D &l2s,
133  const Point2D &l2f, Point2D *ip);
134 // This uses the barycentric coordinate system method from
135 // http://totologic.blogspot.com/2014/01/accurate-point-in-triangle-test.html
136 // where it notes and provides a solution for instabilities when the point
137 // in exactly on one of the edges of the triangle. That refinement is not
138 // implemented because it seems a bit of overkill for most uses. It is an
139 // issue when, for example, two triangles share an edge and the point is on that
140 // edge, when it might give the disappointing result that the point is in
141 // neither triangle.
143  const Point2D &t1,
144  const Point2D &t2,
145  const Point2D &t3);
146 
147 // returns a vector of p1,c1,c2,p2 tuples for bezier curves
149 std::vector<std::tuple<Point2D, Point2D, Point2D, Point2D>> getWavyLineSegments(
150  const Point2D &p1, const Point2D &p2, unsigned int nSegments,
151  double vertOffset);
152 
153 // calculate the points making up the arrowhead of a DrawShapeArrow, allowing
154 // for the fact that in polygon mode the point can extend over the end
155 // of the point, because of the mitring.
157  Point2D &arrow2,
158  const Point2D &arrowBegin,
159  bool asPolygon, double frac,
160  double angle);
161 } // namespace MolDraw2D_detail
162 } // namespace RDKit
163 
164 #endif
pulls in the core RDKit functionality
bool hasProp(const std::string &key) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: RDProps.h:126
void setProp(const std::string &key, T val, bool computed=false) const
sets a property value
Definition: RDProps.h:77
CXXBondIterator< MolGraph, Bond * > bonds()
Definition: ROMol.h:316
CXXAtomIterator< MolGraph, Atom * > atoms()
C++11 Range iterator.
Definition: ROMol.h:277
#define RDKIT_MOLDRAW2D_EXPORT
Definition: export.h:281
static std::string to_string(const Descriptor &desc)
Definition: Descriptor.h:54
RDKIT_MOLDRAW2D_EXPORT void arcPoints(const Point2D &cds1, const Point2D &cds2, std::vector< Point2D > &res, float startAng=0, float extent=360)
RDKIT_MOLDRAW2D_EXPORT bool doesLineIntersect(const StringRect &rect, const Point2D &end1, const Point2D &end2, double padding)
RDKIT_MOLDRAW2D_EXPORT bool doLinesIntersect(const Point2D &l1s, const Point2D &l1f, const Point2D &l2s, const Point2D &l2f, Point2D *ip)
RDKIT_MOLDRAW2D_EXPORT void addBondIndices(const ROMol &mol)
add annotations with bond indices.
RDKIT_MOLDRAW2D_EXPORT std::vector< std::tuple< Point2D, Point2D, Point2D, Point2D > > getWavyLineSegments(const Point2D &p1, const Point2D &p2, unsigned int nSegments, double vertOffset)
RDKIT_MOLDRAW2D_EXPORT bool isPointInTriangle(const Point2D &pt, const Point2D &t1, const Point2D &t2, const Point2D &t3)
RDKIT_MOLDRAW2D_EXPORT void addAtomIndices(const ROMol &mol)
add annotations with atom indices.
RDKIT_MOLDRAW2D_EXPORT void addStereoAnnotation(const ROMol &mol, bool includeRelativeCIP=false)
add R/S, relative stereo, and E/Z annotations to atoms and bonds
RDKIT_MOLDRAW2D_EXPORT bool doesTriangleIntersect(const StringRect &rect, const Point2D &pt1, const Point2D &pt2, const Point2D &pt3, double padding)
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 doesLineIntersectEllipse(const Point2D &centre, double xradius, double yradius, double padding, const Point2D &end1, const Point2D &end2)
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)
std::string formatDouble(double val)
RDKIT_MOLDRAW2D_EXPORT void calcArrowHead(Point2D &arrowEnd, Point2D &arrow1, Point2D &arrow2, const Point2D &arrowBegin, bool asPolygon, double frac, double angle)
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)
RDKIT_RDGENERAL_EXPORT const std::string bondNote
RDKIT_RDGENERAL_EXPORT const std::string atomNote
Std stuff.
Definition: Abbreviations.h:19