Skip to content
Snippets Groups Projects
Commit a80088ec authored by MarcoSchaeferT's avatar MarcoSchaeferT
Browse files

parser is working + try to get mesh/shape

parent 299f3baf
No related branches found
No related tags found
No related merge requests found
...@@ -24,11 +24,14 @@ export interface ply_form { ...@@ -24,11 +24,14 @@ export interface ply_form {
readonly initialHead: ReadonlyArray<string>, readonly initialHead: ReadonlyArray<string>,
readonly propertyNames: ReadonlyArray<string>, readonly propertyNames: ReadonlyArray<string>,
readonly properties: number[], readonly properties: number[],
readonly vertices: number[],
readonly colors: number[],
readonly normals: number[],
readonly faces: number[], readonly faces: number[],
} }
export function PlyStructure(vertexCount: number, faceCount: number, propertyCount: number, initialHead: string[], propertyNames: string[], properties: number[], faces: number[]): ply_form { export function PlyStructure(vertexCount: number, faceCount: number, propertyCount: number, initialHead: string[], propertyNames: string[], properties: number[], vertices: number[], colors: number[], normals: number[], faces: number[]): ply_form {
return {vertexCount, faceCount, propertyCount, initialHead: [...initialHead], propertyNames: [...propertyNames], properties: [...properties], faces: [...faces]}; return {vertexCount, faceCount, propertyCount, initialHead: [...initialHead], propertyNames: [...propertyNames], properties: [...properties], vertices: [...vertices], colors: [...colors], normals: [...normals], faces: [...faces]};
} }
export type PlyColumns = { [name: string]: PlyColumn } export type PlyColumns = { [name: string]: PlyColumn }
......
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import Field from '../../cif/text/field'
export default Field
\ No newline at end of file
...@@ -9,8 +9,15 @@ import { Tokens, TokenBuilder, Tokenizer } from '../../common/text/tokenizer' ...@@ -9,8 +9,15 @@ import { Tokens, TokenBuilder, Tokenizer } from '../../common/text/tokenizer'
import * as Data from './data-model' import * as Data from './data-model'
import Result from '../../result' import Result from '../../result'
import { Task, RuntimeContext, chunkedSubtask, } from 'mol-task' import {Task, RuntimeContext, chunkedSubtask, Progress,} from 'mol-task'
import * as plyToShape from 'mol-model/shape/formarts/ply/plyData_to_shape'
import {MyData} from 'mol-model/shape/formarts/ply/plyData_to_shape';
import {Mesh} from '../../../../mol-geo/geometry/mesh/mesh';
import {ParamDefinition} from '../../../../mol-util/param-definition';
import Color = ParamDefinition.Color;
import {ColorNames} from '../../../../mol-util/color/tables';
import {ShapeRepresentation} from '../../../../mol-repr/shape/representation';
//import {init2} from '../../../../tests/browser/render-shape';
...@@ -46,6 +53,9 @@ interface State { ...@@ -46,6 +53,9 @@ interface State {
initialHead: string[], initialHead: string[],
properties: number[], properties: number[],
vertices: number[],
colors: number[],
normals: number[],
faces: number[], faces: number[],
propertyNames: string[], propertyNames: string[],
check: string[], check: string[],
...@@ -80,6 +90,9 @@ function State(data: string, runtimeCtx: RuntimeContext, opts: PlyOptions): Stat ...@@ -80,6 +90,9 @@ function State(data: string, runtimeCtx: RuntimeContext, opts: PlyOptions): Stat
initialHead: [], initialHead: [],
properties: [], properties: [],
vertices: [],
colors: [],
normals:[],
faces: [], faces: [],
propertyNames: [], propertyNames: [],
check: [], check: [],
...@@ -192,6 +205,15 @@ function moveNextInternal(state: State) { ...@@ -192,6 +205,15 @@ function moveNextInternal(state: State) {
{ {
if(state.currentVertex < state.vertexCount){ if(state.currentVertex < state.vertexCount){
state.properties[state.currentVertex * state.propertyCount + state.currentProperty] = Number(Tokenizer.getTokenString(state.tokenizer)); state.properties[state.currentVertex * state.propertyCount + state.currentProperty] = Number(Tokenizer.getTokenString(state.tokenizer));
if(state.currentProperty < 3){
state.vertices[state.currentVertex * 3 + state.currentProperty] = Number(Tokenizer.getTokenString(state.tokenizer));
}
if(state.currentProperty >= 3 && state.currentProperty <6){
state.colors[state.currentVertex * 3 + state.currentProperty-3] = Number(Tokenizer.getTokenString(state.tokenizer));
}
if(state.currentProperty >= 6 && state.currentProperty <9){
state.normals[state.currentVertex * 3 + state.currentProperty-6] = Number(Tokenizer.getTokenString(state.tokenizer));
}
state.currentProperty++; state.currentProperty++;
if(state.currentProperty === state.propertyCount){ if(state.currentProperty === state.propertyCount){
state.currentProperty = 0; state.currentProperty = 0;
...@@ -287,16 +309,25 @@ async function handleRecords(state: State): Promise<Data.ply_form> { ...@@ -287,16 +309,25 @@ async function handleRecords(state: State): Promise<Data.ply_form> {
} }
await readRecordsChunks(state) await readRecordsChunks(state)
return Data.PlyStructure(state.vertexCount, state.faceCount, state.propertyCount, state.initialHead, state.propertyNames, state.properties, state.faces) return Data.PlyStructure(state.vertexCount, state.faceCount, state.propertyCount, state.initialHead, state.propertyNames, state.properties, state.vertices, state.colors, state.normals, state.faces)
} }
async function parseInternal(data: string, ctx: RuntimeContext, opts: PlyOptions): Promise<Result<Data.PlyFile>> { async function parseInternal(data: string, ctx: RuntimeContext, opts: PlyOptions): Promise<Result<Data.PlyFile>> {
const state = State(data, ctx, opts); const state = State(data, ctx, opts);
ctx.update({ message: 'Parsing...', current: 0, max: data.length }); ctx.update({ message: 'Parsing...', current: 0, max: data.length });
const table = await handleRecords(state) const PLYdata = await handleRecords(state)
const result = Data.PlyFile(table) const result = Data.PlyFile(PLYdata)
console.log(result); console.log(result);
// let Data_for_Shape = plyToShape.collectData_for_Shape(table, datas);
//console.log(plyToShape.getShape(state.runtimeCtx, table));
let shape = plyToShape.init_ren(PLYdata);
console.log("shape"+shape);
const script = document.createElement('script');
script.src = "../../build/src/mol-model/shape/formarts/ply/plyData_to_shape.js";
document.body.appendChild(script);
return Result.success(result); return Result.success(result);
} }
......
import {ply_form} from '../../../../mol-io/reader/ply/parse_data/data-model';
import {MyData} from '../../../../../build/src/mol-model/shape/formarts/ply/plyData_to_shape';
import {Progress, RuntimeContext} from 'mol-task';
import {Mesh} from '../../../../mol-geo/geometry/mesh/mesh';
import {MeshBuilder} from '../../../../mol-geo/geometry/mesh/mesh-builder';
import {Mat4, Vec3} from '../../../../mol-math/linear-algebra/3d';
import {Sphere} from '../../../../mol-geo/primitive/sphere';
import {Shape} from '../../shape';
import {Color} from '../../../../mol-util/color';
import {Canvas3D} from '../../../../mol-canvas3d/canvas3d';
import {labelFirst} from '../../../../mol-theme/label';
import {ColorNames} from '../../../../mol-util/color/tables';
import {ShapeRepresentation} from '../../../../mol-repr/shape/representation';
const parent = document.getElementById('app')!
parent.style.width = '100%'
parent.style.height = '100%'
const canvas = document.createElement('canvas')
canvas.style.width = '100%'
canvas.style.height = '100%'
parent.appendChild(canvas)
const info = document.createElement('div')
info.style.position = 'absolute'
info.style.fontFamily = 'sans-serif'
info.style.fontSize = '24pt'
info.style.bottom = '20px'
info.style.right = '20px'
info.style.color = 'white'
parent.appendChild(info)
const canvas3d = Canvas3D.create(canvas, parent)
canvas3d.animate()
canvas3d.input.move.subscribe(async ({x, y}) => {
const pickingId = await canvas3d.identify(x, y)
let label = ''
if (pickingId) {
const { loci } = canvas3d.getLoci(pickingId)
label = labelFirst(loci)
}
info.innerText = label
})
export interface MyData {
centers: number[],
colors: string[],
labels: string[],
transforms: number[]
}
let data:MyData = {
centers: [],
colors: [],
labels: [],
transforms:[]
}
function componentToHex(c) {
let hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
function collectData_for_Shape(parsedData: ply_form):{centers: number[], colors: string[], labels: string[], transforms: number[]}{
// parsedData.data.PLY_File. to access So.format.Ply
data.centers = parsedData.vertices;
let hexColor;
for(let i=0; i<parsedData.vertexCount; i++){
hexColor = rgbToHex(parsedData.colors[i*3+0],parsedData.colors[i*3+1],parsedData.colors[i*3+2]);
data.colors[i] = hexColor;
data.labels[i] = '';
data.transforms[i] = 0;
}
console.log(data);
return data;
}
async function getSphereMesh(ctx: RuntimeContext, centers: number[], mesh?: Mesh) {
const builderState = MeshBuilder.createState(centers.length * 128, centers.length * 128 / 2, mesh)
const t = Mat4.identity()
const v = Vec3.zero()
const sphere = Sphere(4)
builderState.currentGroup = 0
for (let i = 0, il = centers.length / 3; i < il; ++i) {
// for production, calls to update should be guarded by `if (ctx.shouldUpdate)`
await ctx.update({ current: i, max: il, message: `adding sphere ${i}` })
builderState.currentGroup = i
Mat4.setTranslation(t, Vec3.fromArray(v, centers, i * 3))
MeshBuilder.addPrimitive(builderState, t, sphere)
}
let a = MeshBuilder.getMesh(builderState);
//console.log(a);
return a
}
export async function getShape(ctx: RuntimeContext, parsedData: ply_form, props: {}, shape?: Shape<Mesh>) {
let data:MyData;
data = collectData_for_Shape(parsedData)
await ctx.update('async creation of shape from myData')
const { centers , colors, labels} = data
const mesh = await getSphereMesh(ctx, centers, shape && shape.geometry)
const groupCount = centers.length / 3
return shape || Shape.create(
'test', mesh,
(groupId: number) => Color(Number(colors[groupId])), // color: per group, same for instances
() => 1, // size: constant
(groupId: number, instanceId: number) => labels[instanceId * groupCount + groupId] // label: per group and instance
)
}
const repr = ShapeRepresentation(getShape, Mesh.Utils)
export async function init_ren(myData : ply_form) {
// Create shape from myData and add to canvas3d
await repr.createOrUpdate({}, myData).run((p: Progress) => console.log(Progress.format(p)))
canvas3d.add(repr)
canvas3d.resetCamera()
// Change color after 1s
setTimeout(async () => {
myData.colors[0] = ColorNames.darkmagenta
// Calling `createOrUpdate` with `data` will trigger color and transform update
await repr.createOrUpdate({}, myData).run()
}, 1000)
}
...@@ -14,7 +14,9 @@ import { PluginStateObject } from '../objects'; ...@@ -14,7 +14,9 @@ import { PluginStateObject } from '../objects';
import { StateTransforms } from '../transforms'; import { StateTransforms } from '../transforms';
import { Download } from '../transforms/data'; import { Download } from '../transforms/data';
import { StructureRepresentation3DHelpers } from '../transforms/representation'; import { StructureRepresentation3DHelpers } from '../transforms/representation';
import * as data_functions from "mol-io/reader/ply//read_data/data" import * as data_functions from 'mol-io/reader/ply/read_data/data'
// TODO: "structure parser provider" // TODO: "structure parser provider"
...@@ -86,6 +88,7 @@ export const OpenStructure = StateAction.build({ ...@@ -86,6 +88,7 @@ export const OpenStructure = StateAction.build({
return state.update(createStructureTree(ctx, data, false)); return state.update(createStructureTree(ctx, data, false));
}); });
export const PLYtest = StateAction.build({ export const PLYtest = StateAction.build({
display: { name: 'PLY Test', description: 'nothing ply' }, display: { name: 'PLY Test', description: 'nothing ply' },
from: PluginStateObject.Root, from: PluginStateObject.Root,
...@@ -93,13 +96,12 @@ export const PLYtest = StateAction.build({ ...@@ -93,13 +96,12 @@ export const PLYtest = StateAction.build({
})(({ params, state }, ctx: PluginContext) => { })(({ params, state }, ctx: PluginContext) => {
const b = state.build(); const b = state.build();
const data = b.toRoot().apply(data_functions.ReadFile_ascii, { file: params.file, isBinary: false }); const data = b.toRoot().apply(data_functions.ReadFile_ascii, { file: params.file, isBinary: false });
return state.update(getPLYdata(ctx, data)); let tmp = state.update(getPLYdata(ctx, data));
return tmp ;
}); });
function getPLYdata(ctx: PluginContext, b: StateTreeBuilder.To<PluginStateObject.Data.String>, ): StateTree { function getPLYdata(ctx: PluginContext, b: StateTreeBuilder.To<PluginStateObject.Data.String>, ): StateTree {
let root = b let root = b.apply(data_functions.ParsePLY);
.apply(data_functions.ParsePLY);
console.log(data_functions.ParsePLY);
return root.getTree(); return root.getTree();
} }
......
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>Mol* Browser Test</title> <title>Mol* Browser Test</title>
<style> <style>
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
box-sizing: border-box; box-sizing: border-box;
} }
html, body { html, body {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
} }
</style> </style>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<script type="text/javascript"> <script type="text/javascript">
function urlQueryParameter (id) { function urlQueryParameter (id) {
if (typeof window === 'undefined') return undefined if (typeof window === 'undefined') return undefined
const a = new RegExp(`${id}=([^&#=]*)`) const a = new RegExp(`${id}=([^&#=]*)`)
const m = a.exec(window.location.search) const m = a.exec(window.location.search)
return m ? decodeURIComponent(m[1]) : undefined return m ? decodeURIComponent(m[1]) : undefined
} }
const name = urlQueryParameter('name')
const name = urlQueryParameter('name') if (name) {
if (name) {
const script = document.createElement('script') const script = document.createElement('script')
script.src = name + '.js' script.src = name + '.js'
document.body.appendChild(script) document.body.appendChild(script)
} }
</script> </script>
<script type="text/javascript" src="./render-shape.js"></script> <script type="text/javascript" >
</body> const script = document.createElement('script');
script.src = "render-shape.js";
document.body.appendChild(script);
</script>
</body>
</html> </html>
\ No newline at end of file
...@@ -18,6 +18,7 @@ import { RuntimeContext, Progress } from 'mol-task'; ...@@ -18,6 +18,7 @@ import { RuntimeContext, Progress } from 'mol-task';
const parent = document.getElementById('app')! const parent = document.getElementById('app')!
parent.style.width = '100%' parent.style.width = '100%'
parent.style.height = '100%' parent.style.height = '100%'
...@@ -101,7 +102,6 @@ const repr = ShapeRepresentation(getShape, Mesh.Utils) ...@@ -101,7 +102,6 @@ const repr = ShapeRepresentation(getShape, Mesh.Utils)
export async function init() { export async function init() {
// Create shape from myData and add to canvas3d // Create shape from myData and add to canvas3d
await repr.createOrUpdate({}, myData).run((p: Progress) => console.log(Progress.format(p))) await repr.createOrUpdate({}, myData).run((p: Progress) => console.log(Progress.format(p)))
console.log(repr)
canvas3d.add(repr) canvas3d.add(repr)
canvas3d.resetCamera() canvas3d.resetCamera()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment