Skip to content

Commit

Permalink
#1990 - Functional group does not connect with another functional gro…
Browse files Browse the repository at this point in the history
…up on click&drag
  • Loading branch information
Stanislav Permiakov committed Feb 16, 2023
1 parent 2984aed commit 7b74abd
Show file tree
Hide file tree
Showing 9 changed files with 281 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ export function getHoverToFuse(items) {

const hoverItems = {
atoms: Array.from(items.atoms.values()),
bonds: Array.from(items.bonds.values())
bonds: Array.from(items.bonds.values()),
...(items.functionalGroups && {
functionalGroups: Array.from(items.functionalGroups.values())
})
}

return { map: 'merge', id: +Date.now(), items: hoverItems }
Expand Down
46 changes: 6 additions & 40 deletions packages/ketcher-core/src/application/editor/actions/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

import { Atom, Vec2 } from 'domain/entities'
import { AtomAdd, BondAdd, CalcImplicitH } from '../operations'
import { atomForNewBond, atomGetAttr } from './utils'
import { atomForNewBond, atomGetAttr, extraBondAction } from './utils'
import { fromAtomsAttrs, mergeSgroups } from './atom'
import { fromBondAddition, fromBondStereoUpdate, fromBondsAttrs } from './bond'
import { fromBondStereoUpdate, fromBondsAttrs } from './bond'

import { Action } from './action'
import closest from '../shared/closest'
Expand All @@ -40,49 +40,14 @@ export function fromTemplateOnCanvas(restruct, template, pos, angle) {
return [action, pasteItems]
}

function extraBondAction(restruct, aid, angle) {
let action = new Action()
const frid = atomGetAttr(restruct, aid, 'fragment')
let additionalAtom: any = null

if (angle === null) {
const middleAtom = atomForNewBond(restruct, aid)
const actionRes = fromBondAddition(
restruct,
{ type: 1 },
aid,
middleAtom.atom,
middleAtom.pos.get_xy0()
)
action = actionRes[0]
action.operations.reverse()
additionalAtom = actionRes[2]
} else {
const operation = new AtomAdd(
{ label: 'C', fragment: frid },
new Vec2(1, 0)
.rotate(angle)
.add(restruct.molecule.atoms.get(aid).pp)
.get_xy0()
).perform(restruct) as AtomAdd

action.addOp(operation)
action.addOp(
new BondAdd(aid, operation.data.aid, { type: 1 }).perform(restruct)
)

additionalAtom = operation.data.aid
}

return { action, aid1: additionalAtom }
}

export function fromTemplateOnAtom(restruct, template, aid, angle, extraBond) {
let action = new Action()

const tmpl = template.molecule
const struct = restruct.molecule

const isTmplSingleGroup = template.molecule.isSingleGroup()

let atom = struct.atoms.get(aid) // aid - the atom that was clicked on
let aid1 = aid // aid1 - the atom on the other end of the extra bond || aid

Expand Down Expand Up @@ -134,7 +99,8 @@ export function fromTemplateOnAtom(restruct, template, aid, angle, extraBond) {
pasteItems.atoms.push(operation.data.aid)
}
})
mergeSgroups(action, restruct, pasteItems.atoms, aid)

if (!isTmplSingleGroup) mergeSgroups(action, restruct, pasteItems.atoms, aid)

tmpl.bonds.forEach((bond) => {
const operation = new BondAdd(
Expand Down
38 changes: 38 additions & 0 deletions packages/ketcher-core/src/application/editor/actions/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Bond, Vec2 } from 'domain/entities'

import closest from '../shared/closest'
import { difference } from 'lodash'
import { Action, AtomAdd, BondAdd, fromBondAddition } from 'application/editor'

export function atomGetAttr(restruct, aid, name) {
return restruct.molecule.atoms.get(aid)[name]
Expand Down Expand Up @@ -198,3 +199,40 @@ export function isAttachmentBond({ begin, end }: Bond, selection): boolean {
isBondEndsInSelectionAndStartsOutside
)
}

export function extraBondAction(restruct, aid, angle) {
let action = new Action()
const frid = atomGetAttr(restruct, aid, 'fragment')
let additionalAtom: any = null

if (angle === null) {
const middleAtom = atomForNewBond(restruct, aid)
const actionRes = fromBondAddition(
restruct,
{ type: 1 },
aid,
middleAtom.atom,
middleAtom.pos.get_xy0()
)
action = actionRes[0]
action.operations.reverse()
additionalAtom = actionRes[2]
} else {
const operation = new AtomAdd(
{ label: 'C', fragment: frid },
new Vec2(1, 0)
.rotate(angle)
.add(restruct.molecule.atoms.get(aid).pp)
.get_xy0()
).perform(restruct) as AtomAdd

action.addOp(operation)
action.addOp(
new BondAdd(aid, operation.data.aid, { type: 1 }).perform(restruct)
)

additionalAtom = operation.data.aid
}

return { action, aid1: additionalAtom }
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,15 @@ class ReBond extends ReObject {
const bond = restruct.molecule.bonds.get(bid)
const sgroups = restruct.molecule.sgroups
const functionalGroups = restruct.molecule.functionalGroups
const sgroupsIds = struct.getGroupsIdsFromBondId(bid)
if (
FunctionalGroup.isBondInContractedFunctionalGroup(
bond,
sgroups,
functionalGroups,
false
)
) &&
sgroupsIds.length < 2
) {
return
}
Expand Down
18 changes: 18 additions & 0 deletions packages/ketcher-core/src/domain/entities/struct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,7 @@ export class Struct {
}

// TODO: simplify if bonds ids ever appear in sgroup
// ! deprecate
getGroupIdFromBondId(bondId: number): number | null {
const bond = this.bonds.get(bondId)
if (!bond) return null
Expand All @@ -1092,4 +1093,21 @@ export class Struct {
}
return null
}

getGroupsIdsFromBondId(bondId: number): number[] {
const bond = this.bonds.get(bondId)
if (!bond) return []

const groupsIds: number[] = []

for (const [groupId, sgroup] of Array.from(this.sgroups)) {
if (
sgroup.atoms.includes(bond.begin) ||
sgroup.atoms.includes(bond.end)
) {
groupsIds.push(groupId)
}
}
return groupsIds
}
}
7 changes: 5 additions & 2 deletions packages/ketcher-react/src/script/editor/shared/closest.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,12 @@ function findClosestSGroup(restruct, pos) {
return null
}

function findClosestFG(restruct, pos) {
function findClosestFG(restruct, pos, skip) {
const sGroups = restruct.sgroups
for (const reSGroup of sGroups.values()) {
const skipId = skip && skip.map === 'functionalGroups' ? skip.id : null
for (const [reSGroupId, reSGroup] of sGroups.entries()) {
if (reSGroupId === skipId) continue

const { startX, startY, width, height } =
reSGroup.getTextHighlightDimensions()
const { x, y } = Scale.obj2scaled(pos, restruct.render.options)
Expand Down
Empty file.
Loading

0 comments on commit 7b74abd

Please sign in to comment.