Skip to content

Commit

Permalink
#808: render2d: equilibrium arrows rendering supported (#801)
Browse files Browse the repository at this point in the history
Co-authored-by: Roman Porozhnetov <Roman_Porozhnetov@epam.com>
  • Loading branch information
even1024 and even1024 authored Aug 7, 2022
1 parent 14d7805 commit 2cceed3
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 33 deletions.
4 changes: 3 additions & 1 deletion core/indigo-core/molecule/ket_commons.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ namespace indigo
EEquilibriumOpenAngle,
EUnbalancedEquilibriumFilledHalfBow,
EUnbalancedEquilibriumLargeFilledHalfBow,
EUnbalancedEquilibriumFilleHalfTriangle,
EUnbalancedEquilibriumOpenHalfAngle,
EUnbalancedEquilibriumFilledHalfTriangle,
EEllipticalArcFilledBow,
EEllipticalArcFilledTriangle,
EEllipticalArcOpenAngle,
Expand Down Expand Up @@ -263,6 +264,7 @@ namespace indigo
ARROW_EQUILIBRIUM_OPEN_ANGLE,
ARROW_UNBALANCED_EQUILIBRIUM_FILLED_HALF_BOW,
ARROW_UNBALANCED_EQUILIBRIUM_LARGE_FILLED_HALF_BOW,
ARROW_UNBALANCED_EQUILIBRIUM_OPEN_HALF_ANGLE,
ARROW_UNBALANCED_EQUILIBRIUM_FILLED_HALF_TRIANGLE,
ARROW_ELLIPTICAL_ARC_FILLED_BOW,
ARROW_ELLIPTICAL_ARC_FILLED_TRIANGLE,
Expand Down
6 changes: 2 additions & 4 deletions core/indigo-core/molecule/src/molecule_json_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -985,8 +985,6 @@ void MoleculeJsonLoader::loadMolecule(BaseMolecule& mol, bool load_arrows)
mol.buildFromBondsStereocenters(stereochemistry_options, sensible_bond_directions.data());
mol.buildFromBondsAlleneStereo(stereochemistry_options.ignore_errors, sensible_bond_directions.data());

// int num_atoms = mol.vertices();
// printf("%d", num_atoms);
if (!mol.getChiralFlag())
for (int i : mol.vertices())
{
Expand All @@ -1003,7 +1001,6 @@ void MoleculeJsonLoader::loadMolecule(BaseMolecule& mol, bool load_arrows)

for (const auto& sc : _stereo_centers)
{
// const int undefined_pyramid[] = {-1, -1, -1, -1};
if (mol.stereocenters.getType(sc._atom_idx) == 0)
{
if (!stereochemistry_options.ignore_errors)
Expand Down Expand Up @@ -1039,7 +1036,8 @@ void MoleculeJsonLoader::loadMetaObjects(rapidjson::Value& meta_objects, MetaDat
{"equilibrium-open-angle", ReactionComponent::ARROW_EQUILIBRIUM_OPEN_ANGLE},
{"unbalanced-equilibrium-filled-half-bow", ReactionComponent::ARROW_UNBALANCED_EQUILIBRIUM_FILLED_HALF_BOW},
{"unbalanced-equilibrium-large-filled-half-bow", ReactionComponent::ARROW_UNBALANCED_EQUILIBRIUM_LARGE_FILLED_HALF_BOW},
{"unbalanced-equilibrium-filled-half-triangle", ReactionComponent::ARROW_BOTH_ENDS_FILLED_TRIANGLE},
{"unbalanced-equilibrium-open-half-angle", ReactionComponent::ARROW_UNBALANCED_EQUILIBRIUM_OPEN_HALF_ANGLE},
{"unbalanced-equilibrium-filled-half-triangle", ReactionComponent::ARROW_UNBALANCED_EQUILIBRIUM_FILLED_HALF_TRIANGLE},
{"elliptical-arc-arrow-filled-bow", ReactionComponent::ARROW_ELLIPTICAL_ARC_FILLED_BOW},
{"elliptical-arc-arrow-filled-triangle", ReactionComponent::ARROW_ELLIPTICAL_ARC_FILLED_TRIANGLE},
{"elliptical-arc-arrow-open-angle", ReactionComponent::ARROW_ELLIPTICAL_ARC_OPEN_ANGLE},
Expand Down
20 changes: 17 additions & 3 deletions core/render2d/render_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ namespace indigo
class RenderContext
{
public:
enum class ArrowType
{
EOpenArrow,
EBowArray,
ETriangleArrow
};
DECL_ERROR;

void checkPathNonEmpty() const;
Expand Down Expand Up @@ -100,14 +106,22 @@ namespace indigo
void drawPlus(const Vec2f& pos, const float linewidth, const float size);
void drawEquality(const Vec2f& pos, const float linewidth, const float size, const float interval);
void drawArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize);
void drawCustomArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize, const bool is_bow = false,
const bool is_failed = false);
void drawCustomArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize, const bool is_bow,
const bool is_failed);

void drawCustomArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize, const bool is_bow);
void drawEquillibriumFilledTriangle(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize);
void drawEquillibriumHalf(const Vec2f& p1, const Vec2f& p2, const float width, float headwidth, const float headsize,
const ArrowType arrow_type = ArrowType::EOpenArrow, const bool is_large = false, const bool is_unbalanced = false);
void drawBar(const Vec2f& p1, const Vec2f& p2, const float width, const float margin = 0);

void drawDashedArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize);
void drawBothEndsArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize);
void drawEllipticalArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize, const float height,
int arrow_type);
void drawArrowHeader(const Vec2f& v, const Vec2f& dir, const float width, const float headwidth, const float headsize, bool is_bow = false);
void drawHalfArrowHeader(const Vec2f& v, const Vec2f& dir, const float width, const float headwidth, const float headsize);
void drawHalfArrowHeader(const Vec2f& v, const Vec2f& dir, const float width, const float headwidth, const float headsize,
const ArrowType arrow_type = ArrowType::EOpenArrow);

void drawTriangleArrowHeader(const Vec2f& v, const Vec2f& dir, const float width, const float headwidth, const float headsize);

Expand Down
112 changes: 104 additions & 8 deletions core/render2d/src/render_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,8 @@ void RenderContext::drawTriangleArrowHeader(const Vec2f& v, const Vec2f& dir, co
lineTo(v);
}

void RenderContext::drawHalfArrowHeader(const Vec2f& v, const Vec2f& dir, const float width, const float headwidth, const float headsize)
void RenderContext::drawHalfArrowHeader(const Vec2f& v, const Vec2f& dir, const float width, const float headwidth, const float headsize,
const ArrowType arrow_type)
{
Vec2f n(dir), p(v), d(dir);
n.rotate(1, 0);
Expand All @@ -1000,14 +1001,21 @@ void RenderContext::drawHalfArrowHeader(const Vec2f& v, const Vec2f& dir, const
auto inner_w = arr_wc * (arr_h - width) / arr_h;
auto inner_h = inner_w * headsize / arr_wc;
auto inner_hyp = std::hypot(inner_w, inner_h);

d.rotate(si, cs);
p.addScaled(d, arr_hyp);
lineTo(p);
p.addScaled(n, width / cs);
lineTo(p);
d.negate();
p.addScaled(d, inner_hyp);
if (arrow_type == ArrowType::ETriangleArrow)
{
p.addScaled(n, arr_wc);
}
else
{
p.addScaled(n, width / cs);
if (arrow_type == ArrowType::EOpenArrow)
lineTo(p);
d.negate();
p.addScaled(d, inner_hyp);
}
lineTo(p);
lineTo(header);
}
Expand Down Expand Up @@ -1195,8 +1203,86 @@ void RenderContext::drawDashedArrow(const Vec2f& p1, const Vec2f& p2, const floa
cairoCheckStatus();
}

void RenderContext::drawCustomArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize, const bool is_bow,
const bool is_failed)
void RenderContext::drawBar(const Vec2f& p1, const Vec2f& p2, const float width, const float margin)
{
Vec2f d, n, p(p1);
d.diff(p2, p1);
float len = d.length() - margin;
d.normalize();
n.copy(d);
n.rotate(1, 0);
moveTo(p);
p.addScaled(n, width / 2);
lineTo(p);
p.addScaled(d, len);
lineTo(p);
n.negate();
p.addScaled(n, width);
lineTo(p);
d.negate();
p.addScaled(d, len);
lineTo(p);
n.negate();
d.negate();
p.addScaled(n, width / 2);
lineTo(p);
}

void RenderContext::drawEquillibriumHalf(const Vec2f& p1, const Vec2f& p2, const float width, float headwidth, const float headsize, const ArrowType arrow_type,
const bool is_large, const bool is_unbalanced)
{
float margin = arrow_type == ArrowType::ETriangleArrow ? headsize : width * 1.5;
float width_scale = is_large ? 1.5 : 1;
Vec2f d, n, pa(p1);
d.diff(p2, p1);
float len = d.length();
d.normalize();
n.copy(d);
n.rotate(-1, 0);
pa.addScaled(n, headwidth / 2);
Vec2f pb(pa);
pb.addScaled(d, len);
drawHalfArrowHeader(pb, d, width, headwidth * width_scale, headsize, arrow_type);
drawBar(pa, pb, width, margin);
n.negate();
pa.addScaled(n, headwidth);
pb.addScaled(n, headwidth);
if (is_unbalanced)
pa.addScaled(d, headsize * 2);
d.negate();
if (is_unbalanced)
pb.addScaled(d, headsize * 2);
drawHalfArrowHeader(pa, d, width, headwidth * width_scale, headsize, arrow_type);
drawBar(pb, pa, width, margin);
checkPathNonEmpty();
bbIncludePath(false);
cairo_fill(_cr);
cairoCheckStatus();
}

void RenderContext::drawEquillibriumFilledTriangle(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize)
{
Vec2f d, n, pa(p1);
d.diff(p2, p1);
float len = d.length();
d.normalize();
n.copy(d);
n.rotate(-1, 0);
pa.addScaled(n, headwidth / 2);
Vec2f pb(pa);
pb.addScaled(d, len);
drawCustomArrow(pa, pb, width, headwidth, headsize, false);
n.negate();
pa.addScaled(n, headwidth);
pb.addScaled(n, headwidth);
drawCustomArrow(pb, pa, width, headwidth, headsize, false);
checkPathNonEmpty();
bbIncludePath(false);
cairo_fill(_cr);
cairoCheckStatus();
}

void RenderContext::drawCustomArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize, const bool is_bow)
{
Vec2f d, n, p(p1);
d.diff(p2, p1);
Expand Down Expand Up @@ -1240,6 +1326,16 @@ void RenderContext::drawCustomArrow(const Vec2f& p1, const Vec2f& p2, const floa
lineTo(p);
p.addScaled(n, width);
lineTo(p);
}

void RenderContext::drawCustomArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize, const bool is_bow,
const bool is_failed)
{
Vec2f d, n, p(p1);
d.diff(p2, p1);
float len = d.length();
d.normalize();
drawCustomArrow(p1, p2, width, headwidth, headsize, is_bow);
if (is_failed)
{
cairo_fill(_cr);
Expand Down
10 changes: 8 additions & 2 deletions core/render2d/src/render_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,13 @@ void MoleculeRenderInternal::_initSGroups(Tree& sgroups, Rect2f parent)
parent = bound;
}

if (sgroup.sgroup_type == SGroup::SG_TYPE_GEN)
{
Sgroup& sg = _data.sgroups.push();
_loadBracketsAuto(sgroup, sg);
parent = ILLEGAL_RECT();
}

if (sgroup.sgroup_type == SGroup::SG_TYPE_MUL)
{
const MultipleGroup& group = (MultipleGroup&)sgroup;
Expand All @@ -706,7 +713,6 @@ void MoleculeRenderInternal::_initSGroups(Tree& sgroups, Rect2f parent)
index.fontsize = FONT_SIZE_ATTR;
bprintf(index.text, "%d", group.multiplier);
_positionIndex(sg, tiIndex, true);

parent = ILLEGAL_RECT();
}

Expand Down Expand Up @@ -790,7 +796,7 @@ void MoleculeRenderInternal::_loadBracketsAuto(const SGroup& group, Sgroup& sg)
Array<Vec2f[2]> brackets;
_placeBrackets(sg, group.atoms, brackets);

const bool isBracketsCoordinates = group.brackets.size() != 0 || Vec2f::distSqr(group.brackets.at(0)[0], group.brackets.at(0)[1]) > EPSILON;
const bool isBracketsCoordinates = group.brackets.size() != 0 && Vec2f::distSqr(group.brackets.at(0)[0], group.brackets.at(0)[1]) > EPSILON;
if (isBracketsCoordinates)
{
Array<Vec2f[2]> temp;
Expand Down
43 changes: 28 additions & 15 deletions core/render2d/src/render_item_aux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,11 @@ void RenderItemAuxiliary::_drawArrow(const KETReactionArrow& ar)
switch (ar._arrow_type)
{
case KETReactionArrow::EOpenAngle:
_rc.drawCustomArrow(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize);
_rc.drawCustomArrow(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize, false, false);
break;

case KETReactionArrow::EFilledBow:
_rc.drawCustomArrow(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize, true);
_rc.drawCustomArrow(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize, true, false);
break;

case KETReactionArrow::EFailed:
Expand All @@ -195,24 +195,37 @@ void RenderItemAuxiliary::_drawArrow(const KETReactionArrow& ar)
_rc.drawBothEndsArrow(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize);
break;

/*
case KETReactionArrow::EEquilibriumFilledHalfBow:
break;
case KETReactionArrow::EEquilibriumFilledHalfBow:
_rc.drawEquillibriumHalf(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize, RenderContext::ArrowType::EBowArray);
break;

case KETReactionArrow::EEquilibriumFilledTriangle:
break;
case KETReactionArrow::EEquilibriumFilledTriangle:
_rc.drawEquillibriumFilledTriangle(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize);
break;

case KETReactionArrow::EEquilibriumOpenAngle:
break;
case KETReactionArrow::EEquilibriumOpenAngle:
_rc.drawEquillibriumHalf(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize);
break;

case KETReactionArrow::EUnbalancedEquilibriumFilledHalfBow:
break;
case KETReactionArrow::EUnbalancedEquilibriumLargeFilledHalfBow:
_rc.drawEquillibriumHalf(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize, RenderContext::ArrowType::EBowArray,
true, true);
break;

case KETReactionArrow::EUnbalancedEquilibriumLargeFilledHalfBow:
break;
case KETReactionArrow::EUnbalancedEquilibriumFilledHalfBow:
_rc.drawEquillibriumHalf(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize, RenderContext::ArrowType::EBowArray,
false, true);
break;

case KETReactionArrow::EUnbalancedEquilibriumFilleHalfTriangle:
break; */
case KETReactionArrow::EUnbalancedEquilibriumOpenHalfAngle:
_rc.drawEquillibriumHalf(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize, RenderContext::ArrowType::EOpenArrow,
false, true);
break;

case KETReactionArrow::EUnbalancedEquilibriumFilledHalfTriangle:
_rc.drawEquillibriumHalf(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize, RenderContext::ArrowType::ETriangleArrow,
false, true);
break;

case KETReactionArrow::EEllipticalArcFilledBow:
_rc.drawEllipticalArrow(beg, end, _settings.metaLineWidth, _settings.arrowHeadWidth, _settings.arrowHeadSize, ar._height, ar._arrow_type);
Expand Down

0 comments on commit 2cceed3

Please sign in to comment.