Skip to content

Commit

Permalink
* #5400 – Expand macromolecules in micro mode
Browse files Browse the repository at this point in the history
* #5400 – Fix build and ui tests

* #5400 – Fix two more ui tests
  • Loading branch information
svvald authored and Guch1g0v committed Oct 17, 2024
1 parent 4e5df65 commit 37cf12d
Show file tree
Hide file tree
Showing 24 changed files with 361 additions and 93 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -315,75 +315,63 @@ test.describe('Macro-Micro-Switcher', () => {
await takeEditorScreenshot(page);
});

test(
'Create a sequence of monomers in macro mode then switch to micro mode select the entire structure and move it to a new position',
{ tag: ['@IncorrectResultBecauseOfBug'] },
async () => {
/*
test('Create a sequence of monomers in macro mode then switch to micro mode select the entire structure and move it to a new position', async () => {
/*
Test case: Macro-Micro-Switcher
Description: Sequence of monomers moved to a new position in Micro mode
Now test working not properly because we have bug https://github.com/epam/ketcher/issues/3654
*/
const x = 400;
const y = 400;
await turnOnMacromoleculesEditor(page);
await openFileAndAddToCanvasMacro(
'KET/three-monomers-connected-with-bonds.ket',
page,
);
await turnOnMicromoleculesEditor(page);
await page.keyboard.press('Control+a');
await page.getByText('Edc').hover();
await dragMouseTo(x, y, page);
await takeEditorScreenshot(page);
},
);
const x = 400;
const y = 400;
await turnOnMacromoleculesEditor(page);
await openFileAndAddToCanvasMacro(
'KET/three-monomers-connected-with-bonds.ket',
page,
);
await turnOnMicromoleculesEditor(page);
await page.keyboard.press('Control+a');
await page.getByText('Edc').hover();
await dragMouseTo(x, y, page);
await takeEditorScreenshot(page);
});

test(
'Add monomers in macro mode then switch to micro mode and check that it can not be expanded and abreviation can not be removed',
{ tag: ['@IncorrectResultBecauseOfBug'] },
async () => {
/*
test('Add monomers in macro mode then switch to micro mode and check that it can not be expanded and abreviation can not be removed', async () => {
/*
Test case: Macro-Micro-Switcher
Description: Abbreviation of monomer expanded without errors.
Now test working not properly because we have bug https://github.com/epam/ketcher/issues/3659
*/
await openFileAndAddToCanvasMacro(
'KET/three-monomers-connected-with-bonds.ket',
page,
);
await turnOnMicromoleculesEditor(page);
await page.getByText('A6OH').click({ button: 'right' });
await takeEditorScreenshot(page);
},
);
await openFileAndAddToCanvasMacro(
'KET/three-monomers-connected-with-bonds.ket',
page,
);
await turnOnMicromoleculesEditor(page);
await page.getByText('A6OH').click({ button: 'right' });
await takeEditorScreenshot(page);
});

test(
'Add monomers in macro mode then switch to micro mode and check that it can not be moved',
{ tag: ['@IncorrectResultBecauseOfBug'] },
async () => {
/*
test('Add monomers in macro mode then switch to micro mode and check that it can not be moved', async () => {
/*
Test case: Macro-Micro-Switcher
Description: Sequence of monomers moved to a new position in Micro mode
Now test working not properly because we have bug https://github.com/epam/ketcher/issues/3658
*/
const x1 = 400;
const y1 = 400;
const x2 = 500;
const y2 = 500;
await turnOnMacromoleculesEditor(page);
await openFileAndAddToCanvasMacro(
'KET/three-monomers-not-connected-with-bonds.ket',
page,
);
await turnOnMicromoleculesEditor(page);
await page.getByText('Edc').hover();
await dragMouseTo(x1, y1, page);
await page.getByText('Edc').hover();
await dragMouseTo(x2, y2, page);
await takeEditorScreenshot(page);
},
);
const x1 = 400;
const y1 = 400;
const x2 = 500;
const y2 = 500;
await turnOnMacromoleculesEditor(page);
await openFileAndAddToCanvasMacro(
'KET/three-monomers-not-connected-with-bonds.ket',
page,
);
await turnOnMicromoleculesEditor(page);
await page.getByText('Edc').hover();
await dragMouseTo(x1, y1, page);
await page.getByText('Edc').hover();
await dragMouseTo(x2, y2, page);
await takeEditorScreenshot(page);
});

test('Check that Zoom In/Zoom Out/ Reset Zoom Tools work (UI Buttons) after switching to Macro mode', async () => {
/*
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ import { fromAtomsFragmentAttr } from './atom';
import { getRelSGroupsBySelection } from './utils';
import { IMAGE_KEY, MULTITAIL_ARROW_KEY } from 'domain/constants';

export function fromMultipleMove(restruct, lists, d: Vec2) {
export function fromMultipleMove(
restruct,
lists,
d: Vec2,
shouldPerform = true,
) {
d = new Vec2(d);

const action = new Action();
Expand Down Expand Up @@ -142,7 +147,7 @@ export function fromMultipleMove(restruct, lists, d: Vec2) {
});
}

return action.perform(restruct);
return shouldPerform ? action.perform(restruct) : action;
}

export function fromStereoFlagUpdate(restruct, frid, flag = null) {
Expand Down
136 changes: 135 additions & 1 deletion packages/ketcher-core/src/application/editor/actions/sgroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@

import {
AtomAttr,
AtomMove,
SGroupAddToHierarchy,
SGroupAtomAdd,
SGroupAtomRemove,
SGroupAttr,
SGroupCreate,
SGroupDataMove,
SGroupDelete,
SGroupRemoveFromHierarchy,
} from '../operations';
import { Pile, SGroup, SGroupAttachmentPoint } from 'domain/entities';
import { Pile, SGroup, SGroupAttachmentPoint, Vec2 } from 'domain/entities';
import { atomGetAttr, atomGetDegree, atomGetSGroups } from './utils';

import { Action } from './action';
Expand Down Expand Up @@ -111,6 +113,138 @@ export function setExpandSGroup(
return action.perform(restruct);
}

export function setExpandMonomerSGroup(
restruct: Restruct,
sgid: number,
attrs: { expanded: boolean },
) {
const action = new Action();

Object.keys(attrs).forEach((key) => {
action.addOp(new SGroupAttr(sgid, key, attrs[key]));
});

const sgroup = restruct.molecule.sgroups.get(sgid);
assert(sgroup != null);

const sGroupAtoms = SGroup.getAtoms(restruct, sgroup);
const attachmentPoints = sgroup.getAttachmentPoints();
const bondsToOutside = restruct.molecule.bonds.filter((_, bond) => {
return (
(sGroupAtoms.includes(bond.begin) && !sGroupAtoms.includes(bond.end)) ||
(sGroupAtoms.includes(bond.end) && !sGroupAtoms.includes(bond.begin))
);
});

const attachmentAtomsFromOutside: number[] = [];

for (const bond of bondsToOutside.values()) {
if (
attachmentPoints.some(
(attachmentPoint) => attachmentPoint.atomId === bond.begin,
)
) {
attachmentAtomsFromOutside.push(bond.end);
} else {
attachmentAtomsFromOutside.push(bond.begin);
}
}

const sGroupBBox = SGroup.getObjBBox(sGroupAtoms, restruct.molecule);
const sGroupWidth = sGroupBBox.p1.x - sGroupBBox.p0.x;
const sGroupHeight = sGroupBBox.p1.y - sGroupBBox.p0.y;

const visitedAtoms = new Set<number>();
const visitedSGroups = new Set<number>();

const atomsToMove = new Map<number, number[]>();
const sGroupsToMove = new Map<number, number[]>();

const prepareSubStructure = (atomId: number, subStructureKey: number) => {
if (visitedAtoms.has(atomId)) {
return;
}
visitedAtoms.add(atomId);

const atomSGroups = restruct.atoms.get(atomId)?.a.sgs;
const atomInSGroup = atomSGroups?.size && atomSGroups.size > 0;
if (atomInSGroup) {
for (const anotherSGroupId of atomSGroups.values()) {
if (visitedSGroups.has(anotherSGroupId) || anotherSGroupId === sgid) {
continue;
}
visitedSGroups.add(anotherSGroupId);

const anotherSGroup = restruct.molecule.sgroups.get(anotherSGroupId);
if (!anotherSGroup) {
continue;
}

const previousArray = sGroupsToMove.get(subStructureKey) ?? [];
sGroupsToMove.set(
subStructureKey,
previousArray.concat(anotherSGroupId),
);
}
}

const atom = restruct.atoms.get(atomId);
if (atom) {
const previousArray = atomsToMove.get(subStructureKey) ?? [];
atomsToMove.set(subStructureKey, previousArray.concat(atomId));

atom.a.neighbors.forEach((halfBondId) => {
const neighborAtomId =
restruct.molecule?.halfBonds?.get(halfBondId)?.end;
if (!neighborAtomId || sGroupAtoms.includes(neighborAtomId)) {
return;
}

prepareSubStructure(neighborAtomId, subStructureKey);
});
}
};

attachmentAtomsFromOutside.forEach((atomId, index) => {
prepareSubStructure(atomId, index);
});

atomsToMove.forEach((atomIds, key) => {
const sGroups = sGroupsToMove.get(key) ?? [];
const subStructBBox = SGroup.getObjBBox(atomIds, restruct.molecule);
const subStructCenter = new Vec2(
subStructBBox.p0.x + subStructBBox.p1.x / 2,
subStructBBox.p0.y + subStructBBox.p1.y / 2,
);
const sGroupCenter = new Vec2(
sGroupBBox.p0.x + sGroupBBox.p1.x / 2,
sGroupBBox.p0.y + sGroupBBox.p1.y / 2,
);
const direction = subStructCenter.sub(sGroupCenter).normalized();
const moveVector = new Vec2(
(direction.x * sGroupHeight) / 4,
(direction.y * sGroupWidth) / 4,
);

const finalMoveVector = attrs.expanded ? moveVector : moveVector.negated();

atomIds.forEach((atomId) => {
action.addOp(new AtomMove(atomId, finalMoveVector));
});
sGroups.forEach((sGroupId) => {
action.addOp(new SGroupDataMove(sGroupId, finalMoveVector));
});
});

sGroupAtoms.forEach((aid) => {
action.mergeWith(
fromAtomsAttrs(restruct, aid, restruct.atoms.get(aid)?.a, false),
);
});

return action.perform(restruct);
}

// todo delete after supporting expand - collapse for 2 attachment points
export function expandSGroupWithMultipleAttachmentPoint(restruct) {
const action = new Action();
Expand Down
31 changes: 17 additions & 14 deletions packages/ketcher-core/src/application/render/restruct/rebond.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
***************************************************************************/

import {
AmbiguousMonomer,
Atom,
Bond,
FunctionalGroup,
Expand Down Expand Up @@ -65,10 +64,7 @@ class ReBond extends ReObject {
atomId: number,
sgroup?: SGroup,
) {
return sgroup instanceof MonomerMicromolecule &&
!(sgroup.monomer instanceof AmbiguousMonomer)
? (sgroup.getAttachmentAtomId() as number)
: sgroup?.isContracted()
return sgroup?.isContracted()
? sgroup?.getContractedPosition(struct).atomId
: atomId;
}
Expand All @@ -92,15 +88,22 @@ class ReBond extends ReObject {
) {
return;
}
const p1 =
sgroup1 instanceof MonomerMicromolecule
? (sgroup1.pp as Vec2)
: beginAtom.a.pp;

const p2 =
sgroup2 instanceof MonomerMicromolecule
? (sgroup2.pp as Vec2)
: endAtom.a.pp;

let p1: Vec2;
let p2: Vec2;

if (sgroup1 instanceof MonomerMicromolecule && sgroup1 !== sgroup2) {
p1 = sgroup1.isContracted() ? (sgroup1.pp as Vec2) : beginAtom.a.pp;
} else {
p1 = beginAtom.a.pp;
}

if (sgroup2 instanceof MonomerMicromolecule && sgroup1 !== sgroup2) {
p2 = sgroup2.isContracted() ? (sgroup2.pp as Vec2) : endAtom.a.pp;
} else {
p2 = endAtom.a.pp;
}

const hb1 = restruct.molecule.halfBonds.get(bond.b.hb1);
const hb2 = restruct.molecule.halfBonds.get(bond.b.hb2);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
SGroup,
Vec2,
Struct,
MonomerMicromolecule,
} from 'domain/entities';
import { SgContexts } from 'application/editor/shared/constants';
import ReDataSGroupData from './redatasgroupdata';
Expand Down Expand Up @@ -129,7 +130,8 @@ class ReSGroup extends ReObject {
];
if (
sgroupTypesWithBrackets.includes(sgroup.type) &&
!sgroup.isSuperatomWithoutLabel
!sgroup.isSuperatomWithoutLabel &&
!(sgroup instanceof MonomerMicromolecule)
) {
SGroupdrawBrackets(SGroupdrawBracketsOptions);
}
Expand Down
Loading

0 comments on commit 37cf12d

Please sign in to comment.