Example #1
0
// Paste anchored model to target model
void Fragment::pasteAnchoredModel(Atom* anchorpoint, bool replace, int& replacebond, Model* target, bool adjustbond)
{
	Messenger::enter("Fragment::pasteAnchoredModel");

	// Set up anchored model in correct geometry - have we a valid attachment point?
	if (!anchoredModel(anchorpoint, replace, replacebond))
	{
		Messenger::exit("Fragment::pasteAnchoredModel");
		return;
	}

	// Get pointers to link and partner atoms, determine if there was a bond there, and then delete link atom
	Bond::BondType bt = Bond::nBondTypes;
	Atom* linkPartner = NULL, *linkAtom;
	if (masterLinkPartner_ != NULL)
	{
		linkPartner = anchoredModel_.atom(masterLinkPartner_->id());
		bt = (masterLinkAtom_->findBond(masterLinkPartner_) == NULL ? Bond::nBondTypes : masterLinkAtom_->findBond(masterLinkPartner_)->type());
	}
	linkAtom = anchoredModel_.atom(masterLinkAtom_->id());
	anchoredModel_.deleteAtom(linkAtom);

	// Remove any other anchorpoints, and translate model to correct position relative to anchor
	anchoredModel_.selectElement(0);
	anchoredModel_.selectionDelete();
	anchoredModel_.selectAll();
	anchoredModel_.translateSelectionLocal(anchorpoint->r());

	// If we are to replace a hydrogen in the target model, delete it first
	if (replace && (anchorpoint->nBonds() != 0))
	{
		// For safety, clamp range of replaced atom id (shouldn't be necessary)
		if (replacebond >= anchorpoint->nBonds()) replacebond = 0;

		// Grab atom along n'th bond
		RefListItem<Bond,int>* ri = anchorpoint->bond(replacebond);
		target->deleteAtom(ri->item->partner(anchorpoint));
	}

	// Paste to the target model, bonding the anchor and linkPartners if a bond was there before
	Clipboard clip;
	clip.copyAll(&anchoredModel_);
	// Translate to adjust bond length if requested
	if (adjustbond)
	{
		Vec3<double> delta = linkPartner->r() - anchorpoint->r();
		double original = delta.magAndNormalise();
		delta *= (ElementMap::atomicRadius(linkPartner) + ElementMap::atomicRadius(anchorpoint)) - original;
		clip.translate(delta);
	}
	clip.pasteToModel(target, false);
	if (bt != Bond::nBondTypes) target->bondAtoms(anchorpoint->id(), target->nAtoms() - anchoredModel_.nAtoms() + linkPartner->id(), bt);
	
	// Since we've physically altered anchoredModel_, re-copy it
	anchoredModel_.copy(masterModel_);
	linkAtom = anchoredModel_.atom(masterLinkAtom_->id());
	anchoredModel_.markAll();
	anchoredModel_.translateSelectionLocal(-linkAtom->r(), true);

	Messenger::exit("Fragment::pasteAnchoredModel");
}