From 4d264473ec5ad1107717947513618860032fc76c Mon Sep 17 00:00:00 2001 From: David Koes Date: Wed, 20 Sep 2023 12:15:42 -0400 Subject: [PATCH] Fix #721 Object intersection testing was completly broken for viewer grids. It is less so now. --- package-lock.json | 4 +- py3Dmol/py3Dmol/__init__.py | 2 +- py3Dmol/setup.py | 2 +- src/GLViewer.ts | 101 +++++++++++------- tests/auto/tests/testgridlabel.js | 95 ++++++++++++++++ ...lcheck-render-tests-testgridlabel.html.png | Bin 0 -> 43697 bytes 6 files changed, 164 insertions(+), 40 deletions(-) create mode 100644 tests/auto/tests/testgridlabel.js create mode 100644 tests/glcheck/reference-images/tests-glcheck-render-tests-testgridlabel.html.png diff --git a/package-lock.json b/package-lock.json index 07cfe6222..26d94e52b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "3dmol", - "version": "2.0.3", + "version": "2.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "3dmol", - "version": "2.0.3", + "version": "2.0.4", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { diff --git a/py3Dmol/py3Dmol/__init__.py b/py3Dmol/py3Dmol/__init__.py index 02260e935..2b8d23586 100644 --- a/py3Dmol/py3Dmol/__init__.py +++ b/py3Dmol/py3Dmol/__init__.py @@ -54,7 +54,7 @@ class view(object): the exception that the functions all return None. http://3dmol.org/doc/GLViewer.html ''' - def __init__(self,query='',width=640,height=480,viewergrid=None,data=None,style=None,linked=True,options=dict(),js='https://cdnjs.cloudflare.com/ajax/libs/3Dmol/2.0.3/3Dmol-min.js'): + def __init__(self,query='',width=640,height=480,viewergrid=None,data=None,style=None,linked=True,options=dict(),js='https://cdnjs.cloudflare.com/ajax/libs/3Dmol/2.0.4/3Dmol-min.js'): '''Create a 3Dmol.js view. width -- width in pixels of container height -- height in pixels of container diff --git a/py3Dmol/setup.py b/py3Dmol/setup.py index 223755180..252e0e51b 100644 --- a/py3Dmol/setup.py +++ b/py3Dmol/setup.py @@ -24,7 +24,7 @@ # the version across setup.py and the project code, see # https://packaging.python.org/en/latest/single_source_version.html # Keep version in synce with 3Dmol.js version. Use "postX" suffix if needed - version='2.0.3', + version='2.0.4', description='An IPython interface for embedding 3Dmol.js views in Jupyter notebooks', long_description=long_description, diff --git a/src/GLViewer.ts b/src/GLViewer.ts index a2356412e..809f7fc70 100644 --- a/src/GLViewer.ts +++ b/src/GLViewer.ts @@ -466,7 +466,7 @@ export class GLViewer { //for grid viewers, return true if point is in this viewer private isInViewer(x: number, y: number) { - if (this.viewers != undefined && !this.control_all) { + if (this.viewers != undefined) { var width = this.WIDTH / this.cols; var height = this.HEIGHT / this.rows; var offset = this.canvasOffset(); @@ -590,8 +590,8 @@ export class GLViewer { this.setupRenderer(); - this.row = this.config.row; - this.col = this.config.col; + this.row = this.config.row == undefined ? 0 : this.config.row; + this.col = this.config.col == undefined ? 0 : this.config.col; this.cols = this.config.cols; this.rows = this.config.rows; this.viewers = this.config.viewers; @@ -670,14 +670,23 @@ export class GLViewer { returnsingle = true; } + let ratioX = this.renderer.getXRatio(); + let ratioY = this.renderer.getYRatio(); + + let col = this.col; + let row = this.row; + let viewxoff = col*(this.WIDTH/ratioX); + //row is from bottom + let viewyoff = (ratioY-row-1)*(this.HEIGHT/ratioY); + let results = []; let offset = this.canvasOffset(); coords.forEach(coord => { let t = new Vector3(coord.x, coord.y, coord.z); t.applyMatrix4(this.modelGroup.matrixWorld); this.projector.projectVector(t, this.camera); - let screenX = this.WIDTH * (t.x + 1) / 2.0 + offset.left; - let screenY = -this.HEIGHT * (t.y - 1) / 2.0 + offset.top; + let screenX = (this.WIDTH/ratioX) * (t.x + 1) / 2.0 + offset.left + viewxoff; + let screenY = -(this.HEIGHT/ratioY) * (t.y - 1) / 2.0 + offset.top + viewyoff; results.push({ x: screenX, y: screenY }); }); if (returnsingle) results = results[0]; @@ -902,11 +911,9 @@ export class GLViewer { if (this.isDragging && this.scene) { //saw mousedown, haven't moved var x = this.getX(ev); var y = this.getY(ev); - if (this.closeEnoughForClick(ev)) { - var offset = this.canvasOffset(); - var mouseX = ((x - offset.left) / this.WIDTH) * 2 - 1; - var mouseY = -((y - offset.top) / this.HEIGHT) * 2 + 1; - this.handleClickSelection(mouseX, mouseY, ev); + if (this.closeEnoughForClick(ev) && this.isInViewer(x,y)) { + let mouse = this.mouseXY(x,y); + this.handleClickSelection(mouse.x, mouse.y, ev); } } @@ -922,7 +929,7 @@ export class GLViewer { var y = this.getY(ev); if (x === undefined) return; - if (!this.isInViewer(x, y)) { + if (!this.control_all && !this.isInViewer(x, y)) { return; } @@ -1026,43 +1033,64 @@ export class GLViewer { this.hoverDuration = duration; }; + private mouseXY(x,y) { + //convert to -1..1 coordinates + let offset = this.canvasOffset(); + let ratioX = this.renderer.getXRatio(); + let ratioY = this.renderer.getYRatio(); + + let col = this.col; + let row = this.row; + let viewxoff = col*(this.WIDTH/ratioX); + //row is from bottom + let viewyoff = (ratioY-row-1)*(this.HEIGHT/ratioY); + + let mouseX = ((x - offset.left-viewxoff) / (this.WIDTH/ratioX)) * 2 - 1; + let mouseY = -((y - offset.top - viewyoff) / (this.HEIGHT/ratioY)) * 2 + 1; + + return {x: mouseX, y: mouseY}; + } + public _handleMouseMove(ev) { // touchmove clearTimeout(this.hoverTimeout); - var offset = this.canvasOffset(); - var mouseX = ((this.getX(ev) - offset.left) / this.WIDTH) * 2 - 1; - var mouseY = -((this.getY(ev) - offset.top) / this.HEIGHT) * 2 + 1; + ev.preventDefault(); + + + let x = this.getX(ev); + let y = this.getY(ev); + if (x === undefined) + return; + + let ratioX = this.renderer.getXRatio(); + let ratioY = this.renderer.getYRatio(); + + let mouse = this.mouseXY(x,y); + let self = this; // hover timeout if (this.current_hover !== null) { - this.handleHoverContinue(mouseX, mouseY); + this.handleHoverContinue(mouse.x, mouse.y); + } + + var mode = 0; + if (!this.control_all && !this.isInViewer(x, y)) { + return; } + if (!this.scene) + return; + if (this.hoverables.length > 0) { this.hoverTimeout = setTimeout( function () { - self.handleHoverSelection(mouseX, mouseY, ev); + self.handleHoverSelection(mouse.x, mouse.y, ev); }, this.hoverDuration); } - ev.preventDefault(); - if (!this.scene) - return; if (!this.isDragging) return; - var mode = 0; - - var x = this.getX(ev); - var y = this.getY(ev); - if (x === undefined) - return; - - if (!this.isInViewer(x, y)) { - return; - } - - var dx = (x - this.mouseStartX) / this.WIDTH; var dy = (y - this.mouseStartY) / this.HEIGHT; // check for pinch @@ -1078,8 +1106,7 @@ export class GLViewer { // translate mode = 1; } - var ratioX = this.renderer.getXRatio(); - var ratioY = this.renderer.getYRatio(); + dx *= ratioX; dy *= ratioY; var r = Math.hypot(dx, dy); @@ -1127,8 +1154,10 @@ export class GLViewer { var x = this.mouseStartX; var y = this.mouseStartY; var offset = this.canvasOffset(); - var mouseX = ((x - offset.left) / this.WIDTH) * 2 - 1; - var mouseY = -((y - offset.top) / this.HEIGHT) * 2 + 1; + let mouse = this.mouseXY(x,y); + let mouseX = mouse.x; + let mouseY = mouse.y; + let intersects = this.targetedObjects(mouseX, mouseY, this.contextMenuEnabledAtoms); var selected = null; if (intersects.length) { @@ -4715,7 +4744,7 @@ export function createViewerGrid(element, config:ViewerGridSpec={}, viewer_confi viewer_config.canvas = canvas; viewer_config.viewers = viewers; viewer_config.control_all = config.control_all; - var viewer = createViewer(element, viewer_config); + var viewer = createViewer(element, extend({},viewer_config)); row.push(viewer); } viewers.unshift(row); //compensate for weird ordering in renderer diff --git a/tests/auto/tests/testgridlabel.js b/tests/auto/tests/testgridlabel.js new file mode 100644 index 000000000..e1b6f694b --- /dev/null +++ b/tests/auto/tests/testgridlabel.js @@ -0,0 +1,95 @@ +var benz=` + RDKit 3D + + 6 6 0 0 0 0 0 0 0 0999 V2000 + -0.9517 0.7811 -0.6622 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.2847 1.3329 -0.3121 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.2365 0.5518 0.3512 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.9517 -0.7811 0.6644 C 0 0 0 0 0 0 0 0 0 0 0 0 + -0.2847 -1.3329 0.3144 C 0 0 0 0 0 0 0 0 0 0 0 0 + -1.2365 -0.5518 -0.3489 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 + 2 3 1 0 + 3 4 2 0 + 4 5 1 0 + 5 6 2 0 + 6 1 1 0 +M END +$$$$ +` + +var viewers = $3Dmol.createViewerGrid( + 'gldiv', //id of div to create canvas in + { + rows: 2, + cols: 2, + linked: true, + control_all: true //mouse controls all viewers + } +); + +var view0 = viewers[0][0]; +var view1 = viewers[1][1]; + +view0.addModel(benz,'sdf') +view0.setStyle({'stick':{}}) +view1.addModel(benz,'sdf') +view1.setStyle({'stick':{"colorscheme": "cyanCarbon"}}) +view0.setHoverable( + {}, + true, + function(atom,viewer,event,container) { + console.log(); + if(!atom.label) { + atom.label = viewer.addLabel(atom.atom,{position: atom, backgroundColor: 'mintcream', fontColor:'black'}); + viewer.render(); + }}, + function(atom,viewer) { + if(atom.label) { + viewer.removeLabel(atom.label); + delete atom.label; + } + } +) + +view1.setHoverable( + {}, + true, + function(atom,viewer,event,container) { + console.log(); + if(!atom.label) { + atom.label = viewer.addLabel(atom.atom,{position: atom, backgroundColor: 'cyan', fontColor:'black'}); + viewer.render(); + }}, + function(atom,viewer) { + if(atom.label) { + viewer.removeLabel(atom.label); + delete atom.label; + } + } +) + +view0.setClickable({},true,function(atom,viewer) { + viewer.removeAllShapes(); + viewer.addSphere({center:atom,radius:1.0,color:'red',alpha:0.4}); + viewer.render(); +}); + +view1.setClickable({},true,function(atom,viewer) { + viewer.removeAllShapes(); + viewer.addSphere({center:atom,radius:1.0,color:'purple',alpha:0.4}); + viewer.render( ); +}); + +view0.zoomTo(); +view1.zoomTo(); +view0.render( ); +view1.render( ); + +let xy = view0.modelToScreen(view0.models[0].atoms[1]) +view0._handleMouseDown({pageX: xy.x, pageY: xy.y, preventDefault: function(){}}); +view0._handleMouseUp({pageX: xy.x, pageY: xy.y, preventDefault: function(){}}); + +xy = view1.modelToScreen(view1.models[0].atoms[0]) +view1._handleMouseDown({pageX: xy.x, pageY: xy.y, preventDefault: function(){}}); +view1._handleMouseUp({pageX: xy.x, pageY: xy.y, preventDefault: function(){}}); diff --git a/tests/glcheck/reference-images/tests-glcheck-render-tests-testgridlabel.html.png b/tests/glcheck/reference-images/tests-glcheck-render-tests-testgridlabel.html.png new file mode 100644 index 0000000000000000000000000000000000000000..deee2c17ac84bccdc4955c90306239802f66d852 GIT binary patch literal 43697 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
Bg1m=*RUzVPw-0?MS+W$#Ow? zzqpCTt`x`&Xjb^C>%ZJ$ajGwQXXIm>MHm+&_kbLfvh3||FY=D`${;$x)?>>W7T<$( zv{<6HFkij}u8&b+V|CVhTArl(V8a0DZFQdL#hlRnTVC!y$* zk@|A|mnr0F=EFvk(!?u}Yu#8%+PL)R(@y_+AO>g@Ms?M@Xm{bUOS31W^YqML`7|by zIT&oY;oG$UOR)QXH**gOoU#6q_g$hSyPsC77W43z@1!PKEoM}pRILpFp)TU=+q^M_Y(t|C@i6nADQ*`yj-jP)!&fLls9I49qI4ApDcYm+GuCInH z4maGW3$i4`Z!6UgqgJPWXRuqrT;pPAKqEn^-Bc3yjw_1;-ClP0kL2oKMF~)ixKr3o zml0EHi*tSE0?qVKX2^p)$#2X#Sb0jGCD=n`I)+nWNOxwhzV83C#I`R=AdYpktX<(T#y{+d~db^U9*O|+oXb?N!>(0cQ3 zb-8Zq!3igYcyxC(7VQjjW*TX|LcG4njFGaDw@wuXz0I&^FdAv?vE)uFXrOQ$Wm^8P7^cB&%DU)nd-+R zo-OqD%_?xpgQHNuERC~UPSlVaCmiC9(i;2Bh>AGd_-OwzrO%(#`qToeD(D*|y4HDZ zlE6Qqg)gX`Z8pxm%wB&dQfXew7kMG$OQpiCrR4Lzg2vjWY&<^m9X15VRD2jjNq>cuA|J#3bd{Mbz$e;&=CajmEC;-K@e-v6uuf1LA?U6d~; z9@G97I07LrOaTsvD;L9?SU~NxS1|mQ-mY+~x-+A2&=&9vZ5_$yr=rr9_hBcN0k|?} z7gi=-Lke%Yn93RTx6#ICwCP6u23ch8)HLut{8VchkI7#M<;5L+#+ZUF{AQe6S8tBo zWACeARTReJdEiJ5Cu}zm_i{H-;2khFdy*=@`mIcGQ~zWo z3Olxp1vAky3x~+muI*udow_g_xwjXf9r$0V!jf(gQiTY2Y942 zWXq@)pwt2DRi@U)$bAhVZ)?XC{;(Y+j3aBw&GcgSjYDBiw6LxNM6~mChK#h-q;;Cz zWLy{Ej&^Rn2~-4;#EcK!Y`hF9W&4Qo`N970LTXU8&TM5s6LngJ@u3ri`=J+*$6zOb z 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