Skip to content

Commit

Permalink
Backmerge: #5699 – Fix collapsed monomers and their bonds bulk select…
Browse files Browse the repository at this point in the history
…ion, removal and undoing in micro mode (#5867) (#5872)
  • Loading branch information
svvald authored Oct 28, 2024
1 parent c55cc66 commit d0956ee
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,9 @@ class ReStruct {
const sGroupAtoms = atoms.filter(
(atom) => atom.sgroup === item?.item?.id,
);
item.selected = sGroupAtoms.length > 0 && sGroupAtoms[0].selected;
item.selected =
sGroupAtoms.length > 0 &&
sGroupAtoms.some((atom) => atom.selected);
}

let selected = selection?.[map]
Expand Down
17 changes: 3 additions & 14 deletions packages/ketcher-core/src/domain/entities/atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,17 +788,11 @@ export class Atom extends BaseMicromoleculeEntity {
attachmentPointAtomBonds.filter((_, bond) => {
const beginAtom = struct.atoms.get(bond.begin);
const endAtom = struct.atoms.get(bond.end);

if (
Atom.isAtomInMonomer(struct, bond.begin) ||
Atom.isAtomInMonomer(struct, bond.end)
) {
const sGroup1 = struct.getGroupFromAtomId(bond.begin);
const sGroup2 = struct.getGroupFromAtomId(bond.end);
return sGroup1 !== sGroup2;
}
const isExternalBondBetweenMonomers =
bond.isExternalBondBetweenMonomers(struct);

return (
isExternalBondBetweenMonomers ||
beginAtom?.fragment !== atom?.fragment ||
endAtom?.fragment !== atom?.fragment
);
Expand All @@ -807,11 +801,6 @@ export class Atom extends BaseMicromoleculeEntity {
return attachmentAtomExternalConnection;
}

public static isAtomInMonomer(struct: Struct, atomId: number) {
const sGroup = struct.getGroupFromAtomId(atomId);
return sGroup instanceof MonomerMicromolecule;
}

public static isHiddenLeavingGroupAtom(struct: Struct, atomId: number) {
const attachmentAtomExternalConnections =
Atom.getAttachmentAtomExternalConnections(struct, undefined, atomId);
Expand Down
15 changes: 15 additions & 0 deletions packages/ketcher-core/src/domain/entities/bond.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,21 @@ export class Bond extends BaseMicromoleculeEntity {
return sGroupsWithBeginAtom?.intersection(sGroupsWithEndAtom);
}

isExternalBondBetweenMonomers(struct: Struct) {
if (!struct.isBondFromMacromolecule(this)) {
return false;
}

const sGroup1 = struct.getGroupFromAtomId(this.begin);
const sGroup2 = struct.getGroupFromAtomId(this.end);

if (!sGroup1 || !sGroup2) {
return false;
}

return sGroup1 !== sGroup2;
}

public static isBondToHiddenLeavingGroup(struct: Struct, bond: Bond) {
const beginSuperatomAttachmentPoint =
Atom.getSuperAtomAttachmentPointByLeavingGroup(struct, bond.begin);
Expand Down
7 changes: 5 additions & 2 deletions packages/ketcher-core/src/domain/entities/struct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1319,8 +1319,11 @@ export class Struct {
return sgroup instanceof MonomerMicromolecule;
}

isBondFromMacromolecule(bondId: number) {
const bond = this.bonds.get(bondId);
isBondFromMacromolecule(bondOrBondId: Bond | number) {
const bond =
bondOrBondId instanceof Bond
? bondOrBondId
: this.bonds.get(bondOrBondId);

assert(bond);

Expand Down
24 changes: 9 additions & 15 deletions packages/ketcher-react/src/script/editor/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@

import {
Action,
FloatingToolsParams,
Editor as KetcherEditor,
Pile,
Render,
Scale,
Struct,
Vec2,
FloatingToolsParams,
fromDescriptorsAlign,
fromMultipleMove,
fromNewCanvas,
provideEditorSettings,
ReStruct,
IMAGE_KEY,
MULTITAIL_ARROW_KEY,
Pile,
provideEditorSettings,
Render,
ReStruct,
Scale,
Struct,
Vec2,
} from 'ketcher-core';
import {
DOMSubscription,
Expand Down Expand Up @@ -446,20 +446,14 @@ class Editor implements KetcherEditor {
return this._selection; // eslint-disable-line
}

const struct = this.struct();
let ReStruct = this.render.ctab;
let selectAll = false;
this._selection = null; // eslint-disable-line
if (ci === 'all') {
selectAll = true;
// TODO: better way will be this.struct()
ci = structObjects.reduce((res, key) => {
let restructItemsIds: number[] = Array.from(ReStruct[key].keys());
restructItemsIds = restructItemsIds.filter(
(restructItemId) =>
!struct.isTargetFromMacromolecule({ map: key, id: restructItemId }),
);
res[key] = restructItemsIds;
res[key] = Array.from(ReStruct[key].keys());
return res;
}, {});
}
Expand Down
154 changes: 91 additions & 63 deletions packages/ketcher-react/src/script/editor/tool/helper/locate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
ReStruct,
MULTITAIL_ARROW_KEY,
} from 'ketcher-core';
import assert from 'assert';

function getElementsInRectangle(restruct: ReStruct, p0, p1) {
const bondList: Array<number> = [];
Expand All @@ -48,29 +49,33 @@ function getElementsInRectangle(restruct: ReStruct, p0, p1) {
];

restruct.bonds.forEach((bond, bid) => {
if (struct.isBondFromMacromolecule(bid)) {
return;
}

const centre = Vec2.lc2(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
restruct.atoms.get(bond.b.begin)!.a.pp,
0.5,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
restruct.atoms.get(bond.b.end)!.a.pp,
0.5,
);
if (
centre.x > x0 &&
centre.x < x1 &&
centre.y > y0 &&
centre.y < y1 &&
!FunctionalGroup.isBondInContractedFunctionalGroup(
FunctionalGroup.isBondInContractedFunctionalGroup(
bond.b,
sGroups,
functionalGroups,
)
) {
return;
}

let center: Vec2;
if (bond.b.isExternalBondBetweenMonomers(struct)) {
const firstMonomer = struct.getGroupFromAtomId(bond.b.begin);
const secondMonomer = struct.getGroupFromAtomId(bond.b.end);

assert(firstMonomer);
assert(secondMonomer);

center =
firstMonomer.pp && secondMonomer.pp
? Vec2.centre(firstMonomer.pp, secondMonomer.pp)
: bond.b.center;
} else {
center = bond.b.center;
}

if (center.x > x0 && center.x < x1 && center.y > y0 && center.y < y1) {
bondList.push(bid);
}
});
Expand All @@ -80,22 +85,35 @@ function getElementsInRectangle(restruct: ReStruct, p0, p1) {
functionalGroups,
aid,
);
const reSGroup = restruct.sgroups.get(relatedFGId as number);
if (
atom.a.pp.x > x0 &&
atom.a.pp.x < x1 &&
atom.a.pp.y > y0 &&
atom.a.pp.y < y1 &&
(!FunctionalGroup.isAtomInContractedFunctionalGroup(
atom.a,
sGroups,
functionalGroups,
true,
) ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
aid === reSGroup!.item!.atoms[0])
) {
atomList.push(aid);
const sGroup = struct.sgroups.get(relatedFGId as number);

if (struct.isAtomFromMacromolecule(aid)) {
if (
sGroup &&
sGroup.pp &&
sGroup.pp.x > x0 &&
sGroup.pp.x < x1 &&
sGroup.pp.y > y0 &&
sGroup.pp.y < y1
) {
atomList.push(aid);
}
} else {
if (
atom.a.pp.x > x0 &&
atom.a.pp.x < x1 &&
atom.a.pp.y > y0 &&
atom.a.pp.y < y1 &&
(!FunctionalGroup.isAtomInContractedFunctionalGroup(
atom.a,
sGroups,
functionalGroups,
true,
) ||
aid === sGroup?.atoms[0])
) {
atomList.push(aid);
}
}
});

Expand Down Expand Up @@ -230,28 +248,32 @@ function getElementsInPolygon(restruct: ReStruct, rr) {

restruct.bonds.forEach((bond, bid) => {
if (
struct.isAtomFromMacromolecule(bond.b.begin) ||
struct.isAtomFromMacromolecule(bond.b.end)
) {
return;
}

const centre = Vec2.lc2(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
restruct.atoms.get(bond.b.begin)!.a.pp,
0.5,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
restruct.atoms.get(bond.b.end)!.a.pp,
0.5,
);
if (
isPointInPolygon(r, centre) &&
!FunctionalGroup.isBondInContractedFunctionalGroup(
FunctionalGroup.isBondInContractedFunctionalGroup(
bond.b,
sGroups,
functionalGroups,
)
) {
return;
}

let center: Vec2;
if (bond.b.isExternalBondBetweenMonomers(struct)) {
const firstMonomer = struct.getGroupFromAtomId(bond.b.begin);
const secondMonomer = struct.getGroupFromAtomId(bond.b.end);

assert(firstMonomer);
assert(secondMonomer);

center =
firstMonomer?.pp && secondMonomer?.pp
? Vec2.centre(firstMonomer.pp, secondMonomer.pp)
: bond.b.center;
} else {
center = bond.b.center;
}

if (isPointInPolygon(r, center)) {
bondList.push(bid);
}
});
Expand All @@ -261,19 +283,25 @@ function getElementsInPolygon(restruct: ReStruct, rr) {
functionalGroups,
aid,
);
const reSGroup = restruct.sgroups.get(relatedFGId as number);
if (
isPointInPolygon(r, atom.a.pp) &&
(!FunctionalGroup.isAtomInContractedFunctionalGroup(
atom.a,
sGroups,
functionalGroups,
true,
) ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
aid === reSGroup!.item!.atoms[0])
) {
atomList.push(aid);
const sGroup = struct.sgroups.get(relatedFGId as number);

if (struct.isAtomFromMacromolecule(aid)) {
if (sGroup && sGroup.pp && isPointInPolygon(r, sGroup.pp)) {
atomList.push(aid);
}
} else {
if (
isPointInPolygon(r, atom.a.pp) &&
(!FunctionalGroup.isAtomInContractedFunctionalGroup(
atom.a,
sGroups,
functionalGroups,
true,
) ||
aid === sGroup?.atoms[0])
) {
atomList.push(aid);
}
}
});

Expand Down

0 comments on commit d0956ee

Please sign in to comment.