51
51
import org .openmolecules .mesh .Cone ;
52
52
import org .openmolecules .mesh .MoleculeSurfaceAlgorithm ;
53
53
import org .openmolecules .render .MoleculeArchitect ;
54
- import org .openmolecules .render .MoleculeBuilder ;
54
+ import org .openmolecules .render .RoleHelper ;
55
55
import org .openmolecules .render .TorsionStrainVisualization ;
56
56
57
57
import java .util .*;
@@ -66,7 +66,7 @@ public class V3DMolecule extends V3DRotatableGroup {
66
66
private static final int DEFAULT_SURFACE_COLOR_MODE = SURFACE_COLOR_PLAIN ;
67
67
68
68
public enum SurfaceMode {NONE (0 ), WIRES (1 ),FILLED (2 );
69
- public int mode ;
69
+ public final int mode ;
70
70
SurfaceMode (int mode ) {
71
71
this .mode = mode ;
72
72
}
@@ -105,6 +105,7 @@ public enum SurfaceMode {NONE(0), WIRES(1),FILLED(2);
105
105
private TorsionStrainVisualization torsionStrainVis ;
106
106
private ArrayList <AtomIndexLabel > mLabelList ;
107
107
private int mnUnconnectedFragments ;
108
+ private boolean mSplitAllBonds ;
108
109
109
110
public enum MoleculeRole {
110
111
LIGAND { public String toString (){
@@ -140,6 +141,21 @@ public V3DMolecule(StereoMolecule mol) {
140
141
this (mol , MoleculeArchitect .CONSTRUCTION_MODE_STICKS , MoleculeArchitect .HYDROGEN_MODE_DEFAULT , 0 , MoleculeRole .LIGAND );
141
142
}
142
143
144
+ /**
145
+ * Creates a V3DMolecule from the given molecule with the following default specification:<br>
146
+ * - construction mode: sticks<br>
147
+ * - default hydrogen mode, i.e. shows all explicit hydrogens<br>
148
+ * - shows no surface<br>
149
+ * - id = 0<br>
150
+ * - group = 0<br>
151
+ * - role = LIGAND
152
+ * @param mol
153
+ * @param splitAllBonds
154
+ */
155
+ public V3DMolecule (StereoMolecule mol , boolean overrideHydrogen , boolean splitAllBonds ) {
156
+ this (mol , MoleculeArchitect .CONSTRUCTION_MODE_STICKS , MoleculeArchitect .HYDROGEN_MODE_DEFAULT , 0 , MoleculeRole .LIGAND , overrideHydrogen , splitAllBonds );
157
+ }
158
+
143
159
/**
144
160
* Creates a V3DMolecule from the given molecule with the following default specification:<br>
145
161
* - construction mode: sticks<br>
@@ -151,8 +167,8 @@ public V3DMolecule(StereoMolecule mol, int id, MoleculeRole role) {
151
167
this (mol , MoleculeArchitect .CONSTRUCTION_MODE_STICKS , MoleculeArchitect .HYDROGEN_MODE_DEFAULT , id , role );
152
168
}
153
169
154
- public V3DMolecule (StereoMolecule mol , int id , MoleculeRole role , boolean overrideHydrogen ) {
155
- this (mol , MoleculeArchitect .CONSTRUCTION_MODE_STICKS , MoleculeArchitect .HYDROGEN_MODE_DEFAULT , id , role , overrideHydrogen );
170
+ public V3DMolecule (StereoMolecule mol , int id , MoleculeRole role , boolean overrideHydrogen , boolean splitAllBonds ) {
171
+ this (mol , MoleculeArchitect .CONSTRUCTION_MODE_STICKS , MoleculeArchitect .HYDROGEN_MODE_DEFAULT , id , role , overrideHydrogen , splitAllBonds );
156
172
}
157
173
158
174
/**
@@ -174,12 +190,12 @@ public V3DMolecule(StereoMolecule mol, int constructionMode, int id, MoleculeRol
174
190
*/
175
191
public V3DMolecule (StereoMolecule mol , int constructionMode , MoleculeArchitect .HydrogenMode hydrogenMode , int id , MoleculeRole role ) {
176
192
this (mol , constructionMode , hydrogenMode , SurfaceMode .NONE ,
177
- DEFAULT_SURFACE_COLOR_MODE , null , DEFAULT_SURFACE_TRANSPARENCY , id , role , true );
193
+ DEFAULT_SURFACE_COLOR_MODE , null , DEFAULT_SURFACE_TRANSPARENCY , id , role , true , false );
178
194
}
179
195
180
- public V3DMolecule (StereoMolecule mol , int constructionMode , MoleculeArchitect .HydrogenMode hydrogenMode , int id , MoleculeRole role , boolean overrideHydrogen ) {
196
+ public V3DMolecule (StereoMolecule mol , int constructionMode , MoleculeArchitect .HydrogenMode hydrogenMode , int id , MoleculeRole role , boolean overrideHydrogen , boolean splitAllBonds ) {
181
197
this (mol , constructionMode , hydrogenMode , SurfaceMode .NONE ,
182
- DEFAULT_SURFACE_COLOR_MODE , null , DEFAULT_SURFACE_TRANSPARENCY , id , role , overrideHydrogen );
198
+ DEFAULT_SURFACE_COLOR_MODE , null , DEFAULT_SURFACE_TRANSPARENCY , id , role , overrideHydrogen , splitAllBonds );
183
199
}
184
200
185
201
/**
@@ -191,10 +207,14 @@ public V3DMolecule(StereoMolecule mol, int constructionMode, MoleculeArchitect.H
191
207
* @param surfaceColorMode DEFAULT_SURFACE_COLOR_MODE or one of the SurfaceMesh.SURFACE_COLOR_xxx modes
192
208
* @param surfaceColor null or explicit surface color used for some color modes
193
209
* @param transparency
210
+ * @param id
211
+ * @param role
212
+ * @param overrideHydrogens whether hydrogen atoms are drawn in the molecule override color
213
+ * @param splitAllBonds whether all bonds shall be constructed from two cylinders (allowing better selection coloring)
194
214
*/
195
215
public V3DMolecule (StereoMolecule mol , int constructionMode , MoleculeArchitect .HydrogenMode hydrogenMode ,
196
216
SurfaceMode surfaceMode , int surfaceColorMode , Color surfaceColor , double transparency ,
197
- int id , MoleculeRole role , boolean overrideHydrogens ) {
217
+ int id , MoleculeRole role , boolean overrideHydrogens , boolean splitAllBonds ) {
198
218
super (mol .getName ());
199
219
mMol = mol ;
200
220
mnUnconnectedFragments = mMol .getFragmentNumbers (new int [mMol .getAllAtoms ()], false , true );
@@ -207,6 +227,7 @@ public V3DMolecule(StereoMolecule mol, int constructionMode, MoleculeArchitect.H
207
227
mSelectedProperty = new SimpleBooleanProperty (false );
208
228
mSelectedProperty .addListener ((v ,ov ,nv ) -> updateSelectionAppearance ());
209
229
mOverrideHydrogens = overrideHydrogens ;
230
+ mSplitAllBonds = splitAllBonds ;
210
231
int surfaceCount = MoleculeSurfaceAlgorithm .SURFACE_TYPE .length ;
211
232
mSurface = new MeshView [surfaceCount ];
212
233
mSurfaceMesh = new SurfaceMesh [surfaceCount ];
@@ -235,9 +256,7 @@ public V3DMolecule(StereoMolecule mol, int constructionMode, MoleculeArchitect.H
235
256
}
236
257
237
258
constructMaterials ();
238
- V3DMoleculeBuilder builder = new V3DMoleculeBuilder (this );
239
- // we cannot center pre-aligned conformers builder.centerMolecule(conformer);
240
- builder .buildMolecule ();
259
+ new V3DMoleculeBuilder (this ).buildMolecule ();
241
260
242
261
if (surfaceMode != SurfaceMode .NONE ) {
243
262
mSurfaceMesh [0 ] = new SurfaceMesh (mMol , 0 , surfaceColorMode , getNeutralColor (0 ), 1.0 - transparency , createSurfaceCutter ());
@@ -639,7 +658,11 @@ public IntegerProperty IDProperty() {
639
658
public boolean isSelected () {
640
659
return mSelectedProperty .get ();
641
660
}
642
-
661
+
662
+ public boolean isSplitAllBonds () {
663
+ return mSplitAllBonds ;
664
+ }
665
+
643
666
public boolean overrideHydrogens () {
644
667
return mOverrideHydrogens ;
645
668
}
@@ -881,29 +904,68 @@ private boolean pickedAtomsAreStrand() {
881
904
public void toggleSelection () {
882
905
mSelectedProperty .set (!mSelectedProperty .get ());
883
906
}
884
-
907
+
908
+ /**
909
+ * Updates the selection of the entire molecule
910
+ */
885
911
private void updateSelectionAppearance () {
912
+ // Complete molecule selection
886
913
for (Node node :getChildren ()) {
887
914
NodeDetail detail = (NodeDetail )node .getUserData ();
888
915
if (detail != null && !detail .isTransparent ()) {
889
916
detail .setSelected (mSelectedProperty .get ());
890
917
updateAppearance (node );
891
918
}
892
919
}
920
+
893
921
for (int atom =0 ; atom <mMol .getAllAtoms (); atom ++)
894
922
mMol .setAtomSelection (atom , mSelectedProperty .get ());
895
- }
896
-
897
-
898
-
923
+ }
899
924
900
925
/**
901
926
* @param polygon screen coordinate polygon defining the selection
902
927
* @param mode 0: normal, 1:add, 2:subtract
903
928
* @param paneOnScreen top let point of parent pane on screen
904
929
*/
905
930
public void select (Polygon polygon , int mode , Point2D paneOnScreen ) {
906
- mSelectedProperty .set (!mSelectedProperty .get ());
931
+ boolean selectionChanged = false ;
932
+ for (Node node :getChildren ()) {
933
+ NodeDetail detail = (NodeDetail )node .getUserData ();
934
+ if (detail != null && !detail .isTransparent () && detail .isAtom ()) {
935
+ boolean isSelected = (polygon != null )
936
+ && polygon .contains (node .localToScreen (0 , 0 , 0 ).subtract (paneOnScreen ));
937
+ if (mode == 1 )
938
+ isSelected |= detail .isSelected ();
939
+ else if (mode == 2 )
940
+ isSelected = detail .isSelected () && !isSelected ;
941
+ if (isSelected != detail .isSelected ()) {
942
+ detail .setSelected (isSelected );
943
+ updateAppearance (node );
944
+ mMol .setAtomSelection (detail .getAtom (), isSelected );
945
+ selectionChanged = true ;
946
+ }
947
+ }
948
+ }
949
+ if (selectionChanged ) {
950
+ for (Node node :getChildren ()) {
951
+ NodeDetail detail = (NodeDetail )node .getUserData ();
952
+ if (detail != null && !detail .isTransparent ()) {
953
+ if (detail .isBond ()) {
954
+ int bond = detail .getBond ();
955
+ int bondAtom = detail .getBondAtom (mMol );
956
+ boolean isSelected = (bondAtom != -1 ) ? mMol .isSelectedAtom (bondAtom )
957
+ : mMol .isSelectedAtom (mMol .getBondAtom (0 , bond ))
958
+ && mMol .isSelectedAtom (mMol .getBondAtom (1 , bond ));
959
+ if (isSelected != detail .isSelected ()) {
960
+ detail .setSelected (isSelected );
961
+ updateAppearance (node );
962
+ }
963
+ }
964
+ }
965
+ }
966
+ }
967
+
968
+ /* mSelectedProperty.set(!mSelectedProperty.get());
907
969
for (Node node:getChildren()) {
908
970
NodeDetail detail = (NodeDetail)node.getUserData();
909
971
if (detail != null && !detail.isTransparent()) {
@@ -921,7 +983,7 @@ else if (mode == 2)
921
983
mMol.setAtomSelection(atom, isSelected);
922
984
}
923
985
}
924
- }
986
+ }*/
925
987
}
926
988
927
989
// Delete all flagged atoms except those that have a direct connection
@@ -1116,7 +1178,7 @@ public void updateAppearance(Node node) {
1116
1178
&& ((NodeDetail )shape .getUserData ()).getMaterial ().getDiffuseColor ().getOpacity () == 0.0 );
1117
1179
1118
1180
if (!isInvisibleShape ) {
1119
- float scale = (shape == mHighlightedShape || mPickedAtomList .contains (shape )) ? HIGHLIGHT_SCALE : 1.0f ;
1181
+ float scale = (shape == mHighlightedShape || mPickedAtomList .contains (shape ) /*|| isSelectedAtom*/ ) ? HIGHLIGHT_SCALE : 1.0f ;
1120
1182
if (shape .getScaleX () != scale ) {
1121
1183
shape .setScaleX (scale );
1122
1184
shape .setScaleY (scale );
@@ -1236,7 +1298,7 @@ private void updateTemporaryAtomSpheres() {
1236
1298
sphere .setTranslateX (mMol .getAtomX (atom ));
1237
1299
sphere .setTranslateY (mMol .getAtomY (atom ));
1238
1300
sphere .setTranslateZ (mMol .getAtomZ (atom ));
1239
- sphere .setUserData (new NodeDetail (material , MoleculeBuilder . ROLE_IS_ATOM | atom , isOverridable ));
1301
+ sphere .setUserData (new NodeDetail (material , RoleHelper . createAtomRole ( atom ) , isOverridable ));
1240
1302
getChildren ().add (sphere );
1241
1303
mTemporaryAtomSpheres .add (sphere );
1242
1304
}
0 commit comments