Pixel-based threshold for line detection.
This commit is contained in:
parent
db3f33d52f
commit
71e51ecf58
@ -66,7 +66,7 @@ import { Unit } from './model/unit.js';
|
||||
import { ParameterListBuilder, ParameterListParser, CreateUrlBuilder, CreateUrlParser, CreateModelUrlParameters, ParameterConverter } from './parameters/parameterlist.js';
|
||||
import { ModelToThreeConversionParams, ModelToThreeConversionOutput, ThreeConversionStateHandler, ThreeNodeTree, ThreeMaterialHandler, ThreeMeshMaterialHandler, ConvertModelToThreeObject, MaterialGeometryType } from './threejs/threeconverter.js';
|
||||
import { ThreeModelLoader } from './threejs/threemodelloader.js';
|
||||
import { ThreeColorConverter, ThreeLinearToSRGBColorConverter, ThreeSRGBToLinearColorConverter, HasHighpDriverIssue, GetShadingType, ConvertThreeColorToColor, ConvertColorToThreeColor, ConvertThreeGeometryToMesh, CreateHighlightMaterial, CreateHighlightMaterials, DisposeThreeObjects, ShadingType } from './threejs/threeutils.js';
|
||||
import { ThreeColorConverter, ThreeLinearToSRGBColorConverter, ThreeSRGBToLinearColorConverter, HasHighpDriverIssue, GetShadingType, ConvertThreeColorToColor, ConvertColorToThreeColor, ConvertThreeGeometryToMesh, CreateHighlightMaterial, CreateHighlightMaterials, DisposeThreeObjects, GetLineSegmentsProjectedDistance, ShadingType } from './threejs/threeutils.js';
|
||||
import { Camera, CameraIsEqual3D, NavigationMode, ProjectionMode } from './viewer/camera.js';
|
||||
import { GetIntegerFromStyle, GetDomElementExternalWidth, GetDomElementExternalHeight, GetDomElementInnerDimensions, GetDomElementClientCoordinates, CreateDomElement, AddDomElement, AddDiv, ClearDomElement, InsertDomElementBefore, InsertDomElementAfter, ShowDomElement, IsDomElementVisible, SetDomElementWidth, SetDomElementHeight, GetDomElementOuterWidth, GetDomElementOuterHeight, SetDomElementOuterWidth, SetDomElementOuterHeight, CreateDiv } from './viewer/domutils.js';
|
||||
import { EmbeddedViewer, Init3DViewerFromUrlList, Init3DViewerFromFileList, Init3DViewerElements } from './viewer/embeddedviewer.js';
|
||||
@ -305,6 +305,7 @@ export {
|
||||
CreateHighlightMaterial,
|
||||
CreateHighlightMaterials,
|
||||
DisposeThreeObjects,
|
||||
GetLineSegmentsProjectedDistance,
|
||||
ShadingType,
|
||||
Camera,
|
||||
CameraIsEqual3D,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Coord2D } from '../geometry/coord2d.js';
|
||||
import { Coord3D } from '../geometry/coord3d.js';
|
||||
import { Segment2D, SegmentPointDistance2D } from '../geometry/line2d.js';
|
||||
import { RGBColorFromFloatComponents } from '../model/color.js';
|
||||
import { MaterialType } from '../model/material.js';
|
||||
import { Mesh } from '../model/mesh.js';
|
||||
@ -272,3 +273,33 @@ export function DisposeThreeObjects (mainObject)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function GetLineSegmentsProjectedDistance (camera, canvasWidth, canvasHeight, lineSegments, screenPoint)
|
||||
{
|
||||
function GetProjectedVertex (camera, canvasWidth, canvasHeight, lineSegments, vertices, index)
|
||||
{
|
||||
let vertex = new THREE.Vector3 (
|
||||
vertices[3 * index],
|
||||
vertices[3 * index + 1],
|
||||
vertices[3 * index + 2]
|
||||
);
|
||||
vertex.applyMatrix4 (lineSegments.matrixWorld);
|
||||
let projected = vertex.project (camera);
|
||||
return new Coord2D (
|
||||
(projected.x + 1.0) * canvasWidth / 2.0,
|
||||
-(projected.y - 1.0) * canvasHeight / 2.0
|
||||
);
|
||||
}
|
||||
|
||||
let vertices = lineSegments.geometry.attributes.position.array;
|
||||
let segmentCount = vertices.length / 6;
|
||||
let distance = Infinity;
|
||||
for (let segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++) {
|
||||
let segment = new Segment2D (
|
||||
GetProjectedVertex (camera, canvasWidth, canvasHeight, lineSegments, vertices, 2 * segmentIndex),
|
||||
GetProjectedVertex (camera, canvasWidth, canvasHeight, lineSegments, vertices, 2 * segmentIndex + 1)
|
||||
);
|
||||
distance = Math.min (distance, SegmentPointDistance2D (segment, screenPoint));
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import { RGBColor } from '../model/color.js';
|
||||
import { ConvertColorToThreeColor, DisposeThreeObjects } from '../threejs/threeutils.js';
|
||||
import { ConvertColorToThreeColor, DisposeThreeObjects, GetLineSegmentsProjectedDistance } from '../threejs/threeutils.js';
|
||||
|
||||
import * as THREE from 'three';
|
||||
|
||||
const LineThresholdInPixels = 10.0;
|
||||
|
||||
export const IntersectionMode =
|
||||
{
|
||||
MeshOnly : 1,
|
||||
@ -127,7 +129,6 @@ export class ViewerMainModel
|
||||
this.edgeSettings = new EdgeSettings (false, new RGBColor (0, 0, 0), 1);
|
||||
this.hasLines = false;
|
||||
this.hasPolygonOffset = false;
|
||||
this.fullBoundingBox = null;
|
||||
}
|
||||
|
||||
SetMainObject (mainObject)
|
||||
@ -135,7 +136,6 @@ export class ViewerMainModel
|
||||
this.mainModel.SetRootObject (mainObject);
|
||||
this.hasLines = false;
|
||||
this.hasPolygonOffset = false;
|
||||
this.fullBoundingBox = null;
|
||||
|
||||
this.EnumerateLines ((line) => {
|
||||
this.hasLines = true;
|
||||
@ -200,17 +200,6 @@ export class ViewerMainModel
|
||||
this.UpdatePolygonOffset ();
|
||||
}
|
||||
|
||||
GetFullBoundingBox ()
|
||||
{
|
||||
if (this.fullBoundingBox !== null) {
|
||||
return this.fullBoundingBox;
|
||||
}
|
||||
this.fullBoundingBox = this.GetBoundingBox (() => {
|
||||
return true;
|
||||
});
|
||||
return this.fullBoundingBox;
|
||||
}
|
||||
|
||||
GetBoundingBox (needToProcess)
|
||||
{
|
||||
let hasMesh = false;
|
||||
@ -311,18 +300,6 @@ export class ViewerMainModel
|
||||
|
||||
GetMeshIntersectionUnderMouse (intersectionMode, mouseCoords, camera, width, height)
|
||||
{
|
||||
function CalculateLineThreshold (mousePos, camera, boundingBoxCenter)
|
||||
{
|
||||
let thresholdInScreenCoordinates = 15.0;
|
||||
let frustumRange = camera.far - camera.near;
|
||||
let cameraDistanceFromCenter = boundingBoxCenter.distanceTo (camera.position);
|
||||
let distanceInFrustumRatio = cameraDistanceFromCenter / frustumRange;
|
||||
let zValue = -1.0 + 2.0 * distanceInFrustumRatio;
|
||||
let referencePoint1 = new THREE.Vector3 (mousePos.x, mousePos.y, zValue).unproject (camera);
|
||||
let referencePoint2 = new THREE.Vector3 (mousePos.x + thresholdInScreenCoordinates, mousePos.y, zValue).unproject (camera);
|
||||
return referencePoint1.distanceTo (referencePoint2);
|
||||
}
|
||||
|
||||
if (this.mainModel.IsEmpty ()) {
|
||||
return null;
|
||||
}
|
||||
@ -336,16 +313,9 @@ export class ViewerMainModel
|
||||
mousePos.y = -(mouseCoords.y / height) * 2 + 1;
|
||||
|
||||
let raycaster = new THREE.Raycaster ();
|
||||
if (this.hasLines) {
|
||||
let boundingBox = this.GetFullBoundingBox ();
|
||||
if (boundingBox !== null) {
|
||||
let boundingBoxCenter = new THREE.Vector3 (0.0, 0.0, 0.0);
|
||||
boundingBox.getCenter (boundingBoxCenter);
|
||||
raycaster.params.Line.threshold = CalculateLineThreshold (mousePos, camera, boundingBoxCenter);
|
||||
}
|
||||
}
|
||||
|
||||
raycaster.setFromCamera (mousePos, camera);
|
||||
raycaster.params.Line.threshold = 10.0;
|
||||
|
||||
let iSectObjects = raycaster.intersectObject (this.mainModel.GetRootObject (), true);
|
||||
for (let i = 0; i < iSectObjects.length; i++) {
|
||||
let iSectObject = iSectObjects[i];
|
||||
@ -355,7 +325,13 @@ export class ViewerMainModel
|
||||
if (intersectionMode === IntersectionMode.MeshOnly && iSectObject.object.isLineSegments) {
|
||||
continue;
|
||||
}
|
||||
if (iSectObject.object.isMesh || iSectObject.object.isLineSegments) {
|
||||
if (iSectObject.object.isMesh) {
|
||||
return iSectObject;
|
||||
} else if (iSectObject.object.isLineSegments) {
|
||||
let distance = GetLineSegmentsProjectedDistance (camera, width, height, iSectObject.object, mouseCoords);
|
||||
if (distance > LineThresholdInPixels) {
|
||||
continue;
|
||||
}
|
||||
return iSectObject;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user