| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- // Author: Axel Antoine
- // mail: ax.antoine@gmail.com
- // website: https://axantoine.com
- // 09/12/2021
-
- // Loki, Inria project-team with Université de Lille
- // within the Joint Research Unit UMR 9189 CNRS-Centrale
- // Lille-Université de Lille, CRIStAL.
- // https://loki.lille.inria.fr
-
- // LICENCE: Licence.md
-
- import {Color, Material, Mesh, Vector3} from 'three';
- import {HalfedgeDS} from '../../three-mesh-halfedge';
- import {acceleratedRaycast, CENTER, MeshBVH, MeshBVHOptions} from 'three-mesh-bvh';
- import {computeMorphedGeometry, disposeMesh} from '../utils/buffergeometry';
-
- type ColorMaterial = Material & {color: Color};
-
- export interface SVGMeshOptions {
- bvhOptions?: MeshBVHOptions;
- }
-
- /**
- * SVGTexture allows to add a texture to a SVGMesh.
- * Raster image (.jpeg, .png) or vector graphics (.svg) are supported.
- */
- export interface SVGTexture {
- /**
- * Name of the texture
- */
- name: string;
- /**
- * DataUrl to the image and vector graphics texture
- */
- url: string;
- }
-
- /**
- * Mesh object that can be rendered as SVG.
- * Wrapper class around three mesh object that duplicates geometry if needed (i.e.
- * for SkinnedMesh) and computes BVH and HalfEdgeStructure on demand)
- */
- export class SVGMesh {
-
- readonly sourceMesh: Mesh;
- readonly threeMesh = new Mesh();
- readonly hes: HalfedgeDS;
- readonly bvhOptions: MeshBVHOptions;
- bvh: MeshBVH;
- drawFills = true;
- drawVisibleContours = true;
- drawHiddenContours = true;
- isUsingBVHForRaycasting = false;
- texture?: SVGTexture;
-
- constructor(mesh: Mesh, options: SVGMeshOptions = {}) {
- this.sourceMesh = mesh;
- this.threeMesh.copy(mesh);
- // if(this.sourceMesh.geometry.index){
- // this.threeMesh.geometry = this.sourceMesh.geometry.toNonIndexed();
- // }else {
- this.threeMesh.geometry = this.sourceMesh.geometry.clone();
- // }
- // this.threeMesh.geometry = toIndexedGeometry(this.sourceMesh.geometry, 1);
-
- // Setup HES
- this.hes = new HalfedgeDS();
- // const t = this.hes.addEdge
- // this.hes.addEdge = (...args)=>{
- // try{
- // return t.call(this.hes, ...args)
- // }catch(e){
- // console.error(e)
- // console.log('args', args)
- // }
- // }
-
- // Setup BVH
- const bvhOptions = {
- maxLeafTris: 1,
- strategy: CENTER,
- ...options?.bvhOptions
- }
-
- this.bvhOptions = bvhOptions
- this.bvh = new MeshBVH(this.threeMesh.geometry, bvhOptions);
- this.threeMesh.geometry.boundsTree = this.bvh;
- this.threeMesh.raycast = acceleratedRaycast;
- }
-
- /**
- * Adds a SVGtexture to the mesh.
- *
- * @param texture The image or vector graphics texture to use.
- */
- addTexture(texture: SVGTexture) {
- this.texture = texture;
- }
-
- updateMorphGeometry() {
- computeMorphedGeometry(this.sourceMesh, this.threeMesh.geometry);
- }
-
- // private _i= 0
- updateBVH(updateMorphGeometry = true) {
- // if(this._i) return
- // this._i++
- updateMorphGeometry && this.updateMorphGeometry();
- this.bvh.refit();
- }
-
- updateHES(updateMorphGeometry = true) {
- // if(!force && this.hes.faces.length) return
- updateMorphGeometry && this.updateMorphGeometry();
- this.hes.setFromGeometry(this.threeMesh.geometry, 1e-10);
- }
-
- localToWorld(target: Vector3): Vector3 {
- return this.threeMesh.localToWorld(target);
- }
-
- colorForFaceIndex(faceIndex: number): null | Color {
-
- if (Array.isArray(this.material)) {
- for (const group of this.threeMesh.geometry.groups) {
- if (group.start <= faceIndex &&
- faceIndex < (group.start + group.count) &&
- group.materialIndex != undefined &&
- group.materialIndex < this.material.length) {
- return colorForMaterial(this.material[group.materialIndex]);
- }
- }
- return null;
- }
- return colorForMaterial(this.material);
- }
-
- dispose() {
- disposeMesh(this.threeMesh);
- }
-
- get material() { return this.threeMesh.material; }
- get matrixWorld() { return this.threeMesh.matrixWorld; }
- get name() { return this.threeMesh.name; }
- set name(name: string) { this.threeMesh.name = name; }
-
- updateObject(){
- // const g = this.sourceMesh.geometry;
- // const ud = this.sourceMesh.userData;
- // this.sourceMesh.userData = {};
- // this.threeMesh.copy(this.sourceMesh, false);
- // this.sourceMesh.userData = ud;
- // this.threeMesh.geometry = g;
- this.threeMesh.position.copy(this.sourceMesh.position);
- this.threeMesh.quaternion.copy(this.sourceMesh.quaternion);
- this.threeMesh.scale.copy(this.sourceMesh.scale);
- this.threeMesh.updateMatrix();
- this.threeMesh.updateMatrixWorld();
- }
-
- remakeBVH(){
- this.bvh = new MeshBVH(this.threeMesh.geometry, this.bvhOptions);
- this.threeMesh.geometry.boundsTree = this.bvh;
- }
- }
-
- function colorForMaterial(material: Material) {
- const colorMaterial = material as ColorMaterial;
- return colorMaterial.color;
- }
|