Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
Molstar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michal Malý
Molstar
Commits
f68d16b9
Commit
f68d16b9
authored
6 years ago
by
Alexander Rose
Browse files
Options
Downloads
Patches
Plain Diff
simplified units-visual builder
parent
02892d7d
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/mol-geo/representation/structure/units-visual.ts
+82
-422
82 additions, 422 deletions
src/mol-geo/representation/structure/units-visual.ts
with
82 additions
and
422 deletions
src/mol-geo/representation/structure/units-visual.ts
+
82
−
422
View file @
f68d16b9
...
@@ -4,11 +4,9 @@
...
@@ -4,11 +4,9 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
*/
// TODO refactor to make DRY
import
{
Unit
,
Structure
}
from
'
mol-model/structure
'
;
import
{
Unit
,
Structure
}
from
'
mol-model/structure
'
;
import
{
RepresentationProps
,
Visual
}
from
'
../
'
;
import
{
RepresentationProps
,
Visual
}
from
'
../
'
;
import
{
VisualUpdateState
,
StructureMeshParams
,
StructurePointsParams
,
StructureLinesParams
,
StructureDirectVolumeParams
,
StructureProps
}
from
'
.
'
;
import
{
VisualUpdateState
,
StructureMeshParams
,
StructurePointsParams
,
StructureLinesParams
,
StructureDirectVolumeParams
,
StructureProps
,
StructureParams
}
from
'
.
'
;
import
{
RuntimeContext
}
from
'
mol-task
'
;
import
{
RuntimeContext
}
from
'
mol-task
'
;
import
{
PickingId
}
from
'
../../geometry/picking
'
;
import
{
PickingId
}
from
'
../../geometry/picking
'
;
import
{
LocationIterator
}
from
'
../../util/location-iterator
'
;
import
{
LocationIterator
}
from
'
../../util/location-iterator
'
;
...
@@ -26,6 +24,7 @@ import { createSizes, SizeProps } from '../../geometry/size-data';
...
@@ -26,6 +24,7 @@ import { createSizes, SizeProps } from '../../geometry/size-data';
import
{
Lines
}
from
'
../../geometry/lines/lines
'
;
import
{
Lines
}
from
'
../../geometry/lines/lines
'
;
import
{
MultiSelectParam
,
paramDefaultValues
}
from
'
mol-view/parameter
'
;
import
{
MultiSelectParam
,
paramDefaultValues
}
from
'
mol-view/parameter
'
;
import
{
DirectVolume
}
from
'
../../geometry/direct-volume/direct-volume
'
;
import
{
DirectVolume
}
from
'
../../geometry/direct-volume/direct-volume
'
;
import
{
RenderableValues
}
from
'
mol-gl/renderable/schema
'
;
export
const
UnitKindInfo
=
{
export
const
UnitKindInfo
=
{
'
atomic
'
:
{},
'
atomic
'
:
{},
...
@@ -72,8 +71,13 @@ function colorChanged(oldProps: ColorProps, newProps: ColorProps) {
...
@@ -72,8 +71,13 @@ function colorChanged(oldProps: ColorProps, newProps: ColorProps) {
}
}
const
UnitsParams
=
{
const
UnitsParams
=
{
...
StructureParams
,
unitKinds
:
MultiSelectParam
<
UnitKind
>
(
'
Unit Kind
'
,
''
,
[
'
atomic
'
,
'
spheres
'
],
UnitKindOptions
),
unitKinds
:
MultiSelectParam
<
UnitKind
>
(
'
Unit Kind
'
,
''
,
[
'
atomic
'
,
'
spheres
'
],
UnitKindOptions
),
}
}
const
DefaultUnitsProps
=
paramDefaultValues
(
UnitsParams
)
type
UnitsProps
=
typeof
DefaultUnitsProps
type
UnitsRenderObject
=
MeshRenderObject
|
LinesRenderObject
|
PointsRenderObject
|
DirectVolumeRenderObject
interface
UnitsVisualBuilder
<
P
extends
StructureProps
,
G
extends
Geometry
>
{
interface
UnitsVisualBuilder
<
P
extends
StructureProps
,
G
extends
Geometry
>
{
defaultProps
:
P
defaultProps
:
P
...
@@ -84,23 +88,20 @@ interface UnitsVisualBuilder<P extends StructureProps, G extends Geometry> {
...
@@ -84,23 +88,20 @@ interface UnitsVisualBuilder<P extends StructureProps, G extends Geometry> {
setUpdateState
(
state
:
VisualUpdateState
,
newProps
:
P
,
currentProps
:
P
):
void
setUpdateState
(
state
:
VisualUpdateState
,
newProps
:
P
,
currentProps
:
P
):
void
}
}
// mesh
interface
UnitsVisualGeometryBuilder
<
P
extends
StructureProps
,
G
extends
Geometry
>
extends
UnitsVisualBuilder
<
P
,
G
>
{
createEmptyGeometry
(
geometry
?:
G
):
G
export
const
UnitsMeshParams
=
{
createRenderObject
(
ctx
:
RuntimeContext
,
group
:
Unit
.
SymmetryGroup
,
geometry
:
Geometry
,
locationIt
:
LocationIterator
,
currentProps
:
P
):
Promise
<
UnitsRenderObject
>
...
StructureMeshParams
,
updateValues
(
values
:
RenderableValues
,
newProps
:
P
):
void
...
UnitsParams
,
}
}
export
const
DefaultUnitsMeshProps
=
paramDefaultValues
(
UnitsMeshParams
)
export
type
UnitsMeshProps
=
typeof
DefaultUnitsMeshProps
export
interface
UnitsMeshVisualBuilder
<
P
extends
UnitsMeshProps
>
extends
UnitsVisualBuilder
<
P
,
Mesh
>
{
}
export
function
Units
Mesh
Visual
<
P
extends
Units
Mesh
Props
>
(
builder
:
Units
Mesh
VisualBuilder
<
P
>
):
UnitsVisual
<
P
>
{
export
function
UnitsVisual
<
P
extends
UnitsProps
>
(
builder
:
UnitsVisual
Geometry
Builder
<
P
,
Geometry
>
):
UnitsVisual
<
P
>
{
const
{
defaultProps
,
createGeometry
,
createLocationIterator
,
getLoci
,
mark
,
setUpdateState
}
=
builder
const
{
defaultProps
,
createGeometry
,
createLocationIterator
,
getLoci
,
mark
,
setUpdateState
}
=
builder
const
{
createEmptyGeometry
,
createRenderObject
,
updateValues
}
=
builder
const
updateState
=
VisualUpdateState
.
create
()
const
updateState
=
VisualUpdateState
.
create
()
let
renderObject
:
Mesh
RenderObject
|
undefined
let
renderObject
:
Units
RenderObject
|
undefined
let
currentProps
:
P
let
currentProps
:
P
let
mesh
:
Mesh
let
geometry
:
Geometry
let
currentGroup
:
Unit
.
SymmetryGroup
let
currentGroup
:
Unit
.
SymmetryGroup
let
currentStructure
:
Structure
let
currentStructure
:
Structure
let
locationIt
:
LocationIterator
let
locationIt
:
LocationIterator
...
@@ -112,13 +113,13 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
...
@@ -112,13 +113,13 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
const
unit
=
group
.
units
[
0
]
const
unit
=
group
.
units
[
0
]
currentConformationId
=
Unit
.
conformationId
(
unit
)
currentConformationId
=
Unit
.
conformationId
(
unit
)
mesh
=
includesUnitKind
(
currentProps
.
unitKinds
,
unit
)
geometry
=
includesUnitKind
(
currentProps
.
unitKinds
,
unit
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
currentProps
,
mesh
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
currentProps
,
geometry
)
:
Mesh
.
createEmpty
(
mesh
)
:
createEmpty
Geometry
(
geometry
)
// TODO create empty location iterator when not in unitKinds
// TODO create empty location iterator when not in unitKinds
locationIt
=
createLocationIterator
(
group
)
locationIt
=
createLocationIterator
(
group
)
renderObject
=
await
create
UnitsMesh
RenderObject
(
ctx
,
group
,
mesh
,
locationIt
,
currentProps
)
renderObject
=
await
createRenderObject
(
ctx
,
group
,
geometry
,
locationIt
,
currentProps
)
}
}
async
function
update
(
ctx
:
RuntimeContext
,
props
:
Partial
<
P
>
=
{})
{
async
function
update
(
ctx
:
RuntimeContext
,
props
:
Partial
<
P
>
=
{})
{
...
@@ -139,7 +140,6 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
...
@@ -139,7 +140,6 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
if
(
currentGroup
.
units
.
length
!==
locationIt
.
instanceCount
)
updateState
.
updateTransform
=
true
if
(
currentGroup
.
units
.
length
!==
locationIt
.
instanceCount
)
updateState
.
updateTransform
=
true
if
(
sizeChanged
(
currentProps
,
newProps
))
updateState
.
createGeometry
=
true
if
(
colorChanged
(
currentProps
,
newProps
))
updateState
.
updateColor
=
true
if
(
colorChanged
(
currentProps
,
newProps
))
updateState
.
updateColor
=
true
if
(
!
deepEqual
(
newProps
.
unitKinds
,
currentProps
.
unitKinds
))
updateState
.
createGeometry
=
true
if
(
!
deepEqual
(
newProps
.
unitKinds
,
currentProps
.
unitKinds
))
updateState
.
createGeometry
=
true
...
@@ -154,20 +154,26 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
...
@@ -154,20 +154,26 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
}
}
if
(
updateState
.
createGeometry
)
{
if
(
updateState
.
createGeometry
)
{
mesh
=
includesUnitKind
(
newProps
.
unitKinds
,
unit
)
geometry
=
includesUnitKind
(
newProps
.
unitKinds
,
unit
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
newProps
,
mesh
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
newProps
,
geometry
)
:
Mesh
.
createEmpty
(
mesh
)
:
createEmpty
Geometry
(
geometry
)
ValueCell
.
update
(
renderObject
.
values
.
drawCount
,
mesh
.
triangleCount
*
3
)
ValueCell
.
update
(
renderObject
.
values
.
drawCount
,
Geometry
.
getDrawCount
(
geometry
)
)
updateState
.
updateColor
=
true
updateState
.
updateColor
=
true
}
}
if
(
updateState
.
updateSize
)
{
// not all geometries have size data, so check here
if
(
'
uSize
'
in
renderObject
.
values
)
{
await
createSizes
(
ctx
,
locationIt
,
newProps
,
renderObject
.
values
)
}
}
if
(
updateState
.
updateColor
)
{
if
(
updateState
.
updateColor
)
{
await
createColors
(
ctx
,
locationIt
,
newProps
,
renderObject
.
values
)
await
createColors
(
ctx
,
locationIt
,
newProps
,
renderObject
.
values
)
}
}
// TODO why do I need to cast here?
updateValues
(
renderObject
.
values
,
newProps
)
Mesh
.
updateValues
(
renderObject
.
values
,
newProps
as
UnitsMeshProps
)
updateRenderableState
(
renderObject
.
state
,
newProps
)
updateRenderableState
(
renderObject
.
state
,
newProps
as
UnitsMeshProps
)
currentProps
=
newProps
currentProps
=
newProps
}
}
...
@@ -226,6 +232,29 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
...
@@ -226,6 +232,29 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
}
}
}
}
// mesh
export
const
UnitsMeshParams
=
{
...
StructureMeshParams
,
...
UnitsParams
,
}
export
const
DefaultUnitsMeshProps
=
paramDefaultValues
(
UnitsMeshParams
)
export
type
UnitsMeshProps
=
typeof
DefaultUnitsMeshProps
export
interface
UnitsMeshVisualBuilder
<
P
extends
UnitsMeshProps
>
extends
UnitsVisualBuilder
<
P
,
Mesh
>
{
}
export
function
UnitsMeshVisual
<
P
extends
UnitsMeshProps
>
(
builder
:
UnitsMeshVisualBuilder
<
P
>
):
UnitsVisual
<
P
>
{
return
UnitsVisual
({
...
builder
,
setUpdateState
:
(
state
:
VisualUpdateState
,
newProps
:
P
,
currentProps
:
P
)
=>
{
builder
.
setUpdateState
(
state
,
newProps
,
currentProps
)
if
(
sizeChanged
(
currentProps
,
newProps
))
state
.
createGeometry
=
true
},
createEmptyGeometry
:
Mesh
.
createEmpty
,
createRenderObject
:
createUnitsMeshRenderObject
,
updateValues
:
Mesh
.
updateValues
})
}
// points
// points
export
const
UnitsPointsParams
=
{
export
const
UnitsPointsParams
=
{
...
@@ -237,139 +266,16 @@ export type UnitsPointsProps = typeof DefaultUnitsPointsProps
...
@@ -237,139 +266,16 @@ export type UnitsPointsProps = typeof DefaultUnitsPointsProps
export
interface
UnitsPointVisualBuilder
<
P
extends
UnitsPointsProps
>
extends
UnitsVisualBuilder
<
P
,
Points
>
{
}
export
interface
UnitsPointVisualBuilder
<
P
extends
UnitsPointsProps
>
extends
UnitsVisualBuilder
<
P
,
Points
>
{
}
export
function
UnitsPointsVisual
<
P
extends
UnitsPointsProps
>
(
builder
:
UnitsPointVisualBuilder
<
P
>
):
UnitsVisual
<
P
>
{
export
function
UnitsPointsVisual
<
P
extends
UnitsPointsProps
>
(
builder
:
UnitsPointVisualBuilder
<
P
>
):
UnitsVisual
<
P
>
{
const
{
defaultProps
,
createGeometry
,
createLocationIterator
,
getLoci
,
mark
,
setUpdateState
}
=
builder
return
UnitsVisual
({
const
updateState
=
VisualUpdateState
.
create
()
...
builder
,
createEmptyGeometry
:
Points
.
createEmpty
,
let
renderObject
:
PointsRenderObject
|
undefined
createRenderObject
:
createUnitsPointsRenderObject
,
let
currentProps
:
P
setUpdateState
:
(
state
:
VisualUpdateState
,
newProps
:
P
,
currentProps
:
P
)
=>
{
let
points
:
Points
builder
.
setUpdateState
(
state
,
newProps
,
currentProps
)
let
currentGroup
:
Unit
.
SymmetryGroup
if
(
sizeChanged
(
currentProps
,
newProps
))
state
.
updateSize
=
true
let
currentStructure
:
Structure
let
locationIt
:
LocationIterator
let
currentConformationId
:
UUID
async
function
create
(
ctx
:
RuntimeContext
,
group
:
Unit
.
SymmetryGroup
,
props
:
Partial
<
P
>
=
{})
{
currentProps
=
Object
.
assign
({},
defaultProps
,
props
,
{
structure
:
currentStructure
})
currentGroup
=
group
const
unit
=
group
.
units
[
0
]
currentConformationId
=
Unit
.
conformationId
(
unit
)
points
=
includesUnitKind
(
currentProps
.
unitKinds
,
unit
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
currentProps
,
points
)
:
Points
.
createEmpty
(
points
)
// TODO create empty location iterator when not in unitKinds
locationIt
=
createLocationIterator
(
group
)
renderObject
=
await
createUnitsPointsRenderObject
(
ctx
,
group
,
points
,
locationIt
,
currentProps
)
}
async
function
update
(
ctx
:
RuntimeContext
,
props
:
Partial
<
P
>
=
{})
{
if
(
!
renderObject
)
return
const
newProps
=
Object
.
assign
({},
currentProps
,
props
,
{
structure
:
currentStructure
})
const
unit
=
currentGroup
.
units
[
0
]
locationIt
.
reset
()
VisualUpdateState
.
reset
(
updateState
)
setUpdateState
(
updateState
,
newProps
,
currentProps
)
const
newConformationId
=
Unit
.
conformationId
(
unit
)
if
(
newConformationId
!==
currentConformationId
)
{
currentConformationId
=
newConformationId
updateState
.
createGeometry
=
true
}
if
(
currentGroup
.
units
.
length
!==
locationIt
.
instanceCount
)
updateState
.
updateTransform
=
true
if
(
sizeChanged
(
currentProps
,
newProps
))
updateState
.
updateSize
=
true
if
(
colorChanged
(
currentProps
,
newProps
))
updateState
.
updateColor
=
true
if
(
!
deepEqual
(
newProps
.
unitKinds
,
currentProps
.
unitKinds
))
updateState
.
createGeometry
=
true
//
if
(
updateState
.
updateTransform
)
{
locationIt
=
createLocationIterator
(
currentGroup
)
const
{
instanceCount
,
groupCount
}
=
locationIt
createUnitsTransform
(
currentGroup
,
renderObject
.
values
)
createMarkers
(
instanceCount
*
groupCount
,
renderObject
.
values
)
updateState
.
updateColor
=
true
}
if
(
updateState
.
createGeometry
)
{
points
=
includesUnitKind
(
newProps
.
unitKinds
,
unit
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
newProps
,
points
)
:
Points
.
createEmpty
(
points
)
ValueCell
.
update
(
renderObject
.
values
.
drawCount
,
points
.
pointCount
)
updateState
.
updateColor
=
true
}
if
(
updateState
.
updateSize
)
{
await
createSizes
(
ctx
,
locationIt
,
newProps
,
renderObject
.
values
)
}
if
(
updateState
.
updateColor
)
{
await
createColors
(
ctx
,
locationIt
,
newProps
,
renderObject
.
values
)
}
// TODO why do I need to cast here?
Points
.
updateValues
(
renderObject
.
values
,
newProps
as
UnitsPointsProps
)
updateRenderableState
(
renderObject
.
state
,
newProps
as
UnitsPointsProps
)
currentProps
=
newProps
}
return
{
get
renderObject
()
{
return
renderObject
},
async
createOrUpdate
(
ctx
:
RuntimeContext
,
props
:
Partial
<
P
>
=
{},
structureGroup
?:
StructureGroup
)
{
if
(
structureGroup
)
currentStructure
=
structureGroup
.
structure
const
group
=
structureGroup
?
structureGroup
.
group
:
undefined
if
(
!
group
&&
!
currentGroup
)
{
throw
new
Error
(
'
missing group
'
)
}
else
if
(
group
&&
(
!
currentGroup
||
!
renderObject
))
{
// console.log('unit-visual first create')
await
create
(
ctx
,
group
,
props
)
}
else
if
(
group
&&
group
.
hashCode
!==
currentGroup
.
hashCode
)
{
// console.log('unit-visual group.hashCode !== currentGroup.hashCode')
await
create
(
ctx
,
group
,
props
)
}
else
{
// console.log('unit-visual update')
if
(
group
&&
!
sameGroupConformation
(
group
,
currentGroup
))
{
// console.log('unit-visual new conformation')
currentGroup
=
group
}
await
update
(
ctx
,
props
)
}
},
getLoci
(
pickingId
:
PickingId
)
{
return
renderObject
?
getLoci
(
pickingId
,
currentGroup
,
renderObject
.
id
)
:
EmptyLoci
},
},
mark
(
loci
:
Loci
,
action
:
MarkerAction
)
{
updateValues
:
Points
.
updateValues
if
(
!
renderObject
)
return
false
})
const
{
tMarker
}
=
renderObject
.
values
const
{
groupCount
,
instanceCount
}
=
locationIt
function
apply
(
interval
:
Interval
)
{
const
start
=
Interval
.
start
(
interval
)
const
end
=
Interval
.
end
(
interval
)
return
applyMarkerAction
(
tMarker
.
ref
.
value
.
array
,
start
,
end
,
action
)
}
let
changed
=
false
if
(
isEveryLoci
(
loci
))
{
changed
=
apply
(
Interval
.
ofBounds
(
0
,
groupCount
*
instanceCount
))
}
else
{
changed
=
mark
(
loci
,
currentGroup
,
apply
)
}
if
(
changed
)
{
ValueCell
.
update
(
tMarker
,
tMarker
.
ref
.
value
)
}
return
changed
},
destroy
()
{
// TODO
renderObject
=
undefined
}
}
}
}
// lines
// lines
...
@@ -383,139 +289,16 @@ export type UnitsLinesProps = typeof DefaultUnitsLinesProps
...
@@ -383,139 +289,16 @@ export type UnitsLinesProps = typeof DefaultUnitsLinesProps
export
interface
UnitsLinesVisualBuilder
<
P
extends
UnitsLinesProps
>
extends
UnitsVisualBuilder
<
P
,
Lines
>
{
}
export
interface
UnitsLinesVisualBuilder
<
P
extends
UnitsLinesProps
>
extends
UnitsVisualBuilder
<
P
,
Lines
>
{
}
export
function
UnitsLinesVisual
<
P
extends
UnitsLinesProps
>
(
builder
:
UnitsLinesVisualBuilder
<
P
>
):
UnitsVisual
<
P
>
{
export
function
UnitsLinesVisual
<
P
extends
UnitsLinesProps
>
(
builder
:
UnitsLinesVisualBuilder
<
P
>
):
UnitsVisual
<
P
>
{
const
{
defaultProps
,
createGeometry
,
createLocationIterator
,
getLoci
,
mark
,
setUpdateState
}
=
builder
return
UnitsVisual
({
const
updateState
=
VisualUpdateState
.
create
()
...
builder
,
createEmptyGeometry
:
Lines
.
createEmpty
,
let
renderObject
:
LinesRenderObject
|
undefined
createRenderObject
:
createUnitsLinesRenderObject
,
let
currentProps
:
P
setUpdateState
:
(
state
:
VisualUpdateState
,
newProps
:
P
,
currentProps
:
P
)
=>
{
let
lines
:
Lines
builder
.
setUpdateState
(
state
,
newProps
,
currentProps
)
let
currentGroup
:
Unit
.
SymmetryGroup
if
(
sizeChanged
(
currentProps
,
newProps
))
state
.
updateSize
=
true
let
currentStructure
:
Structure
let
locationIt
:
LocationIterator
let
currentConformationId
:
UUID
async
function
create
(
ctx
:
RuntimeContext
,
group
:
Unit
.
SymmetryGroup
,
props
:
Partial
<
P
>
=
{})
{
currentProps
=
Object
.
assign
({},
defaultProps
,
props
,
{
structure
:
currentStructure
})
currentGroup
=
group
const
unit
=
group
.
units
[
0
]
currentConformationId
=
Unit
.
conformationId
(
unit
)
lines
=
includesUnitKind
(
currentProps
.
unitKinds
,
unit
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
currentProps
,
lines
)
:
Lines
.
createEmpty
(
lines
)
// TODO create empty location iterator when not in unitKinds
locationIt
=
createLocationIterator
(
group
)
renderObject
=
await
createUnitsLinesRenderObject
(
ctx
,
group
,
lines
,
locationIt
,
currentProps
)
}
async
function
update
(
ctx
:
RuntimeContext
,
props
:
Partial
<
P
>
=
{})
{
if
(
!
renderObject
)
return
const
newProps
=
Object
.
assign
({},
currentProps
,
props
,
{
structure
:
currentStructure
})
const
unit
=
currentGroup
.
units
[
0
]
locationIt
.
reset
()
VisualUpdateState
.
reset
(
updateState
)
setUpdateState
(
updateState
,
newProps
,
currentProps
)
const
newConformationId
=
Unit
.
conformationId
(
unit
)
if
(
newConformationId
!==
currentConformationId
)
{
currentConformationId
=
newConformationId
updateState
.
createGeometry
=
true
}
if
(
currentGroup
.
units
.
length
!==
locationIt
.
instanceCount
)
updateState
.
updateTransform
=
true
if
(
sizeChanged
(
currentProps
,
newProps
))
updateState
.
updateSize
=
true
if
(
colorChanged
(
currentProps
,
newProps
))
updateState
.
updateColor
=
true
if
(
!
deepEqual
(
newProps
.
unitKinds
,
currentProps
.
unitKinds
))
updateState
.
createGeometry
=
true
//
if
(
updateState
.
updateTransform
)
{
locationIt
=
createLocationIterator
(
currentGroup
)
const
{
instanceCount
,
groupCount
}
=
locationIt
createUnitsTransform
(
currentGroup
,
renderObject
.
values
)
createMarkers
(
instanceCount
*
groupCount
,
renderObject
.
values
)
updateState
.
updateColor
=
true
}
if
(
updateState
.
createGeometry
)
{
lines
=
includesUnitKind
(
newProps
.
unitKinds
,
unit
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
newProps
,
lines
)
:
Lines
.
createEmpty
(
lines
)
ValueCell
.
update
(
renderObject
.
values
.
drawCount
,
lines
.
lineCount
*
2
*
3
)
updateState
.
updateColor
=
true
}
if
(
updateState
.
updateSize
)
{
await
createSizes
(
ctx
,
locationIt
,
newProps
,
renderObject
.
values
)
}
if
(
updateState
.
updateColor
)
{
await
createColors
(
ctx
,
locationIt
,
newProps
,
renderObject
.
values
)
}
// TODO why do I need to cast here?
Lines
.
updateValues
(
renderObject
.
values
,
newProps
as
UnitsLinesProps
)
updateRenderableState
(
renderObject
.
state
,
newProps
as
UnitsLinesProps
)
currentProps
=
newProps
}
return
{
get
renderObject
()
{
return
renderObject
},
async
createOrUpdate
(
ctx
:
RuntimeContext
,
props
:
Partial
<
P
>
=
{},
structureGroup
?:
StructureGroup
)
{
if
(
structureGroup
)
currentStructure
=
structureGroup
.
structure
const
group
=
structureGroup
?
structureGroup
.
group
:
undefined
if
(
!
group
&&
!
currentGroup
)
{
throw
new
Error
(
'
missing group
'
)
}
else
if
(
group
&&
(
!
currentGroup
||
!
renderObject
))
{
// console.log('unit-visual first create')
await
create
(
ctx
,
group
,
props
)
}
else
if
(
group
&&
group
.
hashCode
!==
currentGroup
.
hashCode
)
{
// console.log('unit-visual group.hashCode !== currentGroup.hashCode')
await
create
(
ctx
,
group
,
props
)
}
else
{
// console.log('unit-visual update')
if
(
group
&&
!
sameGroupConformation
(
group
,
currentGroup
))
{
// console.log('unit-visual new conformation')
currentGroup
=
group
}
await
update
(
ctx
,
props
)
}
},
getLoci
(
pickingId
:
PickingId
)
{
return
renderObject
?
getLoci
(
pickingId
,
currentGroup
,
renderObject
.
id
)
:
EmptyLoci
},
},
mark
(
loci
:
Loci
,
action
:
MarkerAction
)
{
updateValues
:
Lines
.
updateValues
if
(
!
renderObject
)
return
false
})
const
{
tMarker
}
=
renderObject
.
values
const
{
groupCount
,
instanceCount
}
=
locationIt
function
apply
(
interval
:
Interval
)
{
const
start
=
Interval
.
start
(
interval
)
const
end
=
Interval
.
end
(
interval
)
return
applyMarkerAction
(
tMarker
.
ref
.
value
.
array
,
start
,
end
,
action
)
}
let
changed
=
false
if
(
isEveryLoci
(
loci
))
{
changed
=
apply
(
Interval
.
ofBounds
(
0
,
groupCount
*
instanceCount
))
}
else
{
changed
=
mark
(
loci
,
currentGroup
,
apply
)
}
if
(
changed
)
{
ValueCell
.
update
(
tMarker
,
tMarker
.
ref
.
value
)
}
return
changed
},
destroy
()
{
// TODO
renderObject
=
undefined
}
}
}
}
// direct-volume
// direct-volume
...
@@ -529,137 +312,14 @@ export type UnitsDirectVolumeProps = typeof DefaultUnitsDirectVolumeProps
...
@@ -529,137 +312,14 @@ export type UnitsDirectVolumeProps = typeof DefaultUnitsDirectVolumeProps
export
interface
UnitsDirectVolumeVisualBuilder
<
P
extends
UnitsDirectVolumeProps
>
extends
UnitsVisualBuilder
<
P
,
DirectVolume
>
{
}
export
interface
UnitsDirectVolumeVisualBuilder
<
P
extends
UnitsDirectVolumeProps
>
extends
UnitsVisualBuilder
<
P
,
DirectVolume
>
{
}
export
function
UnitsDirectVolumeVisual
<
P
extends
UnitsDirectVolumeProps
>
(
builder
:
UnitsDirectVolumeVisualBuilder
<
P
>
):
UnitsVisual
<
P
>
{
export
function
UnitsDirectVolumeVisual
<
P
extends
UnitsDirectVolumeProps
>
(
builder
:
UnitsDirectVolumeVisualBuilder
<
P
>
):
UnitsVisual
<
P
>
{
const
{
defaultProps
,
createGeometry
,
createLocationIterator
,
getLoci
,
mark
,
setUpdateState
}
=
builder
return
UnitsVisual
({
const
updateState
=
VisualUpdateState
.
create
()
...
builder
,
createEmptyGeometry
:
DirectVolume
.
createEmpty
,
let
renderObject
:
DirectVolumeRenderObject
|
undefined
createRenderObject
:
createUnitsDirectVolumeRenderObject
,
let
currentProps
:
P
setUpdateState
:
(
state
:
VisualUpdateState
,
newProps
:
P
,
currentProps
:
P
)
=>
{
let
directVolume
:
DirectVolume
builder
.
setUpdateState
(
state
,
newProps
,
currentProps
)
let
currentGroup
:
Unit
.
SymmetryGroup
if
(
sizeChanged
(
currentProps
,
newProps
))
state
.
createGeometry
=
true
let
currentStructure
:
Structure
let
locationIt
:
LocationIterator
let
currentConformationId
:
UUID
async
function
create
(
ctx
:
RuntimeContext
,
group
:
Unit
.
SymmetryGroup
,
props
:
Partial
<
P
>
=
{})
{
const
{
webgl
}
=
props
if
(
webgl
===
undefined
)
throw
new
Error
(
'
UnitsDirectVolumeVisual requires `webgl` in props
'
)
currentProps
=
Object
.
assign
({},
defaultProps
,
props
,
{
structure
:
currentStructure
})
currentGroup
=
group
const
unit
=
group
.
units
[
0
]
currentConformationId
=
Unit
.
conformationId
(
unit
)
directVolume
=
includesUnitKind
(
currentProps
.
unitKinds
,
unit
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
currentProps
,
directVolume
)
:
DirectVolume
.
createEmpty
(
directVolume
)
// TODO create empty location iterator when not in unitKinds
locationIt
=
createLocationIterator
(
group
)
renderObject
=
await
createUnitsDirectVolumeRenderObject
(
ctx
,
group
,
directVolume
,
locationIt
,
currentProps
)
}
async
function
update
(
ctx
:
RuntimeContext
,
props
:
Partial
<
P
>
=
{})
{
const
{
webgl
}
=
props
if
(
webgl
===
undefined
)
throw
new
Error
(
'
UnitsDirectVolumeVisual requires `webgl` in props
'
)
if
(
!
renderObject
)
return
const
newProps
=
Object
.
assign
({},
currentProps
,
props
,
{
structure
:
currentStructure
})
const
unit
=
currentGroup
.
units
[
0
]
locationIt
.
reset
()
VisualUpdateState
.
reset
(
updateState
)
setUpdateState
(
updateState
,
newProps
,
currentProps
)
const
newConformationId
=
Unit
.
conformationId
(
unit
)
if
(
newConformationId
!==
currentConformationId
)
{
currentConformationId
=
newConformationId
updateState
.
createGeometry
=
true
}
if
(
currentGroup
.
units
.
length
!==
locationIt
.
instanceCount
)
updateState
.
updateTransform
=
true
if
(
sizeChanged
(
currentProps
,
newProps
))
updateState
.
createGeometry
=
true
if
(
colorChanged
(
currentProps
,
newProps
))
updateState
.
updateColor
=
true
if
(
!
deepEqual
(
newProps
.
unitKinds
,
currentProps
.
unitKinds
))
updateState
.
createGeometry
=
true
//
if
(
updateState
.
updateTransform
)
{
locationIt
=
createLocationIterator
(
currentGroup
)
const
{
instanceCount
,
groupCount
}
=
locationIt
createUnitsTransform
(
currentGroup
,
renderObject
.
values
)
createMarkers
(
instanceCount
*
groupCount
,
renderObject
.
values
)
updateState
.
updateColor
=
true
}
if
(
updateState
.
createGeometry
)
{
directVolume
=
includesUnitKind
(
newProps
.
unitKinds
,
unit
)
?
await
createGeometry
(
ctx
,
unit
,
currentStructure
,
newProps
,
directVolume
)
:
DirectVolume
.
createEmpty
(
directVolume
)
updateState
.
updateColor
=
true
}
if
(
updateState
.
updateColor
)
{
await
createColors
(
ctx
,
locationIt
,
newProps
,
renderObject
.
values
)
}
DirectVolume
.
updateValues
(
renderObject
.
values
,
newProps
)
updateRenderableState
(
renderObject
.
state
,
newProps
)
currentProps
=
newProps
}
return
{
get
renderObject
()
{
return
renderObject
},
async
createOrUpdate
(
ctx
:
RuntimeContext
,
props
:
Partial
<
P
>
=
{},
structureGroup
?:
StructureGroup
)
{
if
(
structureGroup
)
currentStructure
=
structureGroup
.
structure
const
group
=
structureGroup
?
structureGroup
.
group
:
undefined
if
(
!
group
&&
!
currentGroup
)
{
throw
new
Error
(
'
missing group
'
)
}
else
if
(
group
&&
(
!
currentGroup
||
!
renderObject
))
{
// console.log('unit-visual first create')
await
create
(
ctx
,
group
,
props
)
}
else
if
(
group
&&
group
.
hashCode
!==
currentGroup
.
hashCode
)
{
// console.log('unit-visual group.hashCode !== currentGroup.hashCode')
await
create
(
ctx
,
group
,
props
)
}
else
{
// console.log('unit-visual update')
if
(
group
&&
!
sameGroupConformation
(
group
,
currentGroup
))
{
// console.log('unit-visual new conformation')
currentGroup
=
group
}
await
update
(
ctx
,
props
)
}
},
getLoci
(
pickingId
:
PickingId
)
{
return
renderObject
?
getLoci
(
pickingId
,
currentGroup
,
renderObject
.
id
)
:
EmptyLoci
},
},
mark
(
loci
:
Loci
,
action
:
MarkerAction
)
{
updateValues
:
DirectVolume
.
updateValues
if
(
!
renderObject
)
return
false
})
const
{
tMarker
}
=
renderObject
.
values
const
{
groupCount
,
instanceCount
}
=
locationIt
function
apply
(
interval
:
Interval
)
{
const
start
=
Interval
.
start
(
interval
)
const
end
=
Interval
.
end
(
interval
)
return
applyMarkerAction
(
tMarker
.
ref
.
value
.
array
,
start
,
end
,
action
)
}
let
changed
=
false
if
(
isEveryLoci
(
loci
))
{
changed
=
apply
(
Interval
.
ofBounds
(
0
,
groupCount
*
instanceCount
))
}
else
{
changed
=
mark
(
loci
,
currentGroup
,
apply
)
}
if
(
changed
)
{
ValueCell
.
update
(
tMarker
,
tMarker
.
ref
.
value
)
}
return
changed
},
destroy
()
{
// TODO
renderObject
=
undefined
}
}
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment