Skip to content

Commit f281243

Browse files
authored
Merge pull request #542 from pro3d-space/features/annotationImprovements
Surface intersection preview & ellipse annotations
2 parents 408972d + 47d6f09 commit f281243

51 files changed

Lines changed: 1354 additions & 220 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/AdvancedAnnotations.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
## Advanced Annotation & Preview picking
2+
3+
4+
Previously PRo3D provided no feedback where the intersection will happen. This one adds a 3D cursor which is continously computes intersections given cursor movements.
5+
It runs in a background thread.
6+
7+
The feature can be explicityly disabled via `--disablePreviewIntersections`
8+
9+
Here is the additional annotation type: https://github.com/pro3d-space/PRo3D/pull/542/commits/54ff51f2545b7727b8bd2121a94a3a90a5d35c83#diff-e3ae8667e8128f79e46ea606a6958260ad62ddc73b7e187fccace130e9f14a01R33
10+
11+
Preview intersections can be controlled via: https://github.com/pro3d-space/PRo3D/pull/542/commits/54ff51f2545b7727b8bd2121a94a3a90a5d35c83#diff-5b8179e37acaceeb2a6bf8b9ce4ceedf9785501303594064bbee53391179b622R88
12+
13+
14+
Async preview pickign is controlled via `PreviewPickSurface` message, see https://github.com/pro3d-space/PRo3D/pull/542/commits/c7435faa1963e592cdd5829157b4c804744d40d9#diff-0e871cb4421e88e1ad3efc5e947173c95acb60eedb089a13a0477143e2199f11R516.
15+
16+
## Caveats
17+
18+
Additional memory footprint due to stressed kdtre cache. The kdtree cache however should be reworked to use a LRU queue or similarly.
19+

paket.dependencies

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,20 @@ nuget Adaptify.Core ~> 1.3.0
4848
nuget Aardvark.Data.Opc ~> 0.11.0
4949
nuget Aardvark.Data.Wavefront ~> 5.3.10
5050
nuget Aardvark.GeoSpatial.Opc ~> 5.11.2
51+
nuget Aardvark.Data.GLTF ~> 1.0.1
5152

5253
nuget Aardvark.PixImage.FreeImage == 5.3.5
5354

54-
nuget Aardium ~> 2.1.1
55-
5655
nuget OPCViewer.Base ~> 1.9.2
5756

57+
nuget MathNet.Numerics.FSharp ~> 5.0.0
5858
nuget Uncodium.Eigensystems ~> 1.1.2
5959
nuget Chiron ~> 6.3.1
6060

6161
nuget Microsoft.Diagnostics.Runtime ~> 2.0.1
6262
nuget Microsoft.AspNetCore.Authentication.JwtBearer ~> 6.0.10
6363

64+
nuget Aardium ~> 2.1.1
6465
nuget Giraffe
6566
nuget Saturn
6667
nuget Thoth.Json.Giraffe
@@ -73,7 +74,6 @@ nuget CommandLineParser.FSharp ~> 2.9.1
7374

7475
nuget PRo3D.SPICE ~> 1.0.6
7576

76-
nuget Aardvark.Data.GLTF ~> 1.0.1
7777

7878

7979
group Test

paket.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,10 @@ NUGET
314314
glTF2Loader (1.1.4-alpha)
315315
NETStandard.Library (>= 1.6.1)
316316
Newtonsoft.Json (>= 10.0.3)
317+
MathNet.Numerics (5.0)
318+
MathNet.Numerics.FSharp (5.0)
319+
FSharp.Core (>= 6.0.2)
320+
MathNet.Numerics (>= 5.0)
317321
Microsoft.AspNetCore.Authentication.JwtBearer (6.0.35)
318322
Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 6.35) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0))
319323
Microsoft.Bcl.AsyncInterfaces (8.0)

src/PRo3D.Base/Annotation/Annotation-Model.fs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ type Geometry =
2929
| Polygon = 3
3030
| DnS = 4
3131
| TT = 5
32+
| Ellipse = 6
33+
| AxisEllipse = 7
3234

3335
type Semantic =
3436
| Horizon0 = 0
@@ -357,6 +359,42 @@ with
357359
do! Json.writeFloat "verticalThickness" x.verticalThickness
358360
}
359361

362+
363+
type EllipticAnnotationResult =
364+
{
365+
geographicalEllipse : Ellipse2d
366+
}
367+
with
368+
static let version = 0
369+
370+
static member private readV0 =
371+
json {
372+
let! center = Json.read "center"
373+
let! major = Json.read "major"
374+
let! minor = Json.read "minor"
375+
376+
return {
377+
geographicalEllipse = Ellipse2d(V2d.Parse(center), V2d.Parse(major), V2d.Parse(minor))
378+
}
379+
}
380+
381+
static member FromJson(_: EllipticAnnotationResult) =
382+
json {
383+
let! v = Json.read "version"
384+
match v with
385+
| 0 -> return! EllipticAnnotationResult.readV0
386+
| _ -> return! v |> sprintf "don't know version %A of AnnotationResults" |> Json.error
387+
}
388+
389+
static member ToJson (x : EllipticAnnotationResult) =
390+
json {
391+
do! Json.write "version" version
392+
do! Json.write "center" (string x.geographicalEllipse.Center)
393+
do! Json.write "major" (string x.geographicalEllipse.Axis0)
394+
do! Json.write "minor" (string x.geographicalEllipse.Axis1)
395+
}
396+
397+
360398
module AnnotationResults =
361399

362400
let initial =
@@ -400,6 +438,7 @@ type Annotation = {
400438

401439
results : Option<AnnotationResults>
402440
dnsResults : Option<DipAndStrikeResults>
441+
ellipticResults : Option<EllipticAnnotationResult>
403442

404443
visible : bool
405444
showDns : bool
@@ -490,6 +529,7 @@ with
490529
manualDipAzimuth = Annotation.initialmanualDipAzimuth
491530
bookmarkId = None
492531
referenceSystem = None
532+
ellipticResults = None
493533
}
494534
}
495535

@@ -551,6 +591,7 @@ with
551591
manualDipAzimuth = Annotation.initialmanualDipAzimuth
552592
bookmarkId = None
553593
referenceSystem = None
594+
ellipticResults = None
554595
}
555596
}
556597

@@ -612,6 +653,7 @@ with
612653
manualDipAzimuth = Annotation.initialmanualDipAzimuth
613654
bookmarkId = None
614655
referenceSystem = None
656+
ellipticResults = None
615657
}
616658
}
617659

@@ -676,6 +718,7 @@ with
676718
manualDipAzimuth = Annotation.initialmanualDipAzimuth
677719
bookmarkId = bookmarkId
678720
referenceSystem = None
721+
ellipticResults = None
679722
}
680723
}
681724

@@ -741,6 +784,7 @@ with
741784
manualDipAzimuth = manualDipAzimuth
742785
bookmarkId = bookmarkId
743786
referenceSystem = None
787+
ellipticResults = None
744788
}
745789
}
746790

@@ -780,6 +824,8 @@ with
780824

781825
let! manualDipAngle = Json.readWith Ext.fromJson<NumericInput,Ext> "manualDipAngle"
782826
let! manualDipAzimuth = Json.readWith Ext.fromJson<NumericInput,Ext> "manualDipAzimuth"
827+
828+
let! ellipseProperties = Json.tryRead "ellipseResults"
783829

784830
return {
785831
version = Annotation.current
@@ -807,6 +853,7 @@ with
807853
manualDipAzimuth = manualDipAzimuth
808854
bookmarkId = bookmarkId
809855
referenceSystem = None
856+
ellipticResults = ellipseProperties
810857
}
811858
}
812859

@@ -856,7 +903,12 @@ with
856903
do! Json.write "semanticType" (x.semanticType |> int)
857904

858905
do! Json.writeWith (Ext.toJson<NumericInput,Ext>) "manualDipAngle" (x.manualDipAngle)
859-
do! Json.writeWith (Ext.toJson<NumericInput,Ext>) "manualDipAzimuth" (x.manualDipAzimuth)
906+
do! Json.writeWith (Ext.toJson<NumericInput,Ext>) "manualDipAzimuth" (x.manualDipAzimuth)
907+
908+
match x.ellipticResults with
909+
| None -> ()
910+
| Some e ->
911+
do! Json.write "ellipseResults" x.ellipticResults
860912
}
861913

862914
module Annotation =
@@ -937,6 +989,7 @@ module Annotation =
937989
manualDipAzimuth = Annotation.initialmanualDipAzimuth
938990
bookmarkId = bookmarkId
939991
referenceSystem = referenceSystem
992+
ellipticResults = None
940993
}
941994

942995
let initial =

src/PRo3D.Base/Annotation/Annotation-Model.g.fs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//7ee60322-ffc9-9bed-080f-d357fa699a22
2-
//98622bb4-7bf2-1f2e-b011-a4b0e555e5e7
1+
//bfe6acfa-0299-89a4-8870-5436b29c454b
2+
//124b09b1-6601-961c-adac-7438070f4a0a
33
#nowarn "49" // upper case patterns
44
#nowarn "66" // upcast is unncecessary
55
#nowarn "1337" // internal types
@@ -215,6 +215,7 @@ type AdaptiveAnnotation(value : Annotation) =
215215
(unbox<AdaptiveDipAndStrikeResults> o).Update(v)
216216
o
217217
Adaptify.FSharp.Core.AdaptiveOption<PRo3D.Base.Annotation.DipAndStrikeResults, PRo3D.Base.Annotation.AdaptiveDipAndStrikeResults, PRo3D.Base.Annotation.AdaptiveDipAndStrikeResults>(value.dnsResults, (fun (v : DipAndStrikeResults) -> AdaptiveDipAndStrikeResults(v) :> System.Object), __arg2, (fun (o : System.Object) -> unbox<AdaptiveDipAndStrikeResults> o), (fun (v : DipAndStrikeResults) -> AdaptiveDipAndStrikeResults(v) :> System.Object), __arg5, (fun (o : System.Object) -> unbox<AdaptiveDipAndStrikeResults> o))
218+
let _ellipticResults_ = FSharp.Data.Adaptive.cval(value.ellipticResults)
218219
let _visible_ = FSharp.Data.Adaptive.cval(value.visible)
219220
let _showDns_ = FSharp.Data.Adaptive.cval(value.showDns)
220221
let _text_ = FSharp.Data.Adaptive.cval(value.text)
@@ -247,6 +248,7 @@ type AdaptiveAnnotation(value : Annotation) =
247248
_thickness_.Update(value.thickness)
248249
_results_.Update(value.results)
249250
_dnsResults_.Update(value.dnsResults)
251+
_ellipticResults_.Value <- value.ellipticResults
250252
_visible_.Value <- value.visible
251253
_showDns_.Value <- value.showDns
252254
_text_.Value <- value.text
@@ -273,6 +275,7 @@ type AdaptiveAnnotation(value : Annotation) =
273275
member __.thickness = _thickness_
274276
member __.results = _results_ :> FSharp.Data.Adaptive.aval<Adaptify.FSharp.Core.AdaptiveOptionCase<AnnotationResults, AdaptiveAnnotationResults, AdaptiveAnnotationResults>>
275277
member __.dnsResults = _dnsResults_ :> FSharp.Data.Adaptive.aval<Adaptify.FSharp.Core.AdaptiveOptionCase<DipAndStrikeResults, AdaptiveDipAndStrikeResults, AdaptiveDipAndStrikeResults>>
278+
member __.ellipticResults = _ellipticResults_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.Option<EllipticAnnotationResult>>
276279
member __.visible = _visible_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.bool>
277280
member __.showDns = _showDns_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.bool>
278281
member __.text = _text_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.string>
@@ -301,6 +304,7 @@ module AnnotationLenses =
301304
static member thickness_ = ((fun (self : Annotation) -> self.thickness), (fun (value : Aardvark.UI.Primitives.NumericInput) (self : Annotation) -> { self with thickness = value }))
302305
static member results_ = ((fun (self : Annotation) -> self.results), (fun (value : Microsoft.FSharp.Core.Option<AnnotationResults>) (self : Annotation) -> { self with results = value }))
303306
static member dnsResults_ = ((fun (self : Annotation) -> self.dnsResults), (fun (value : Microsoft.FSharp.Core.Option<DipAndStrikeResults>) (self : Annotation) -> { self with dnsResults = value }))
307+
static member ellipticResults_ = ((fun (self : Annotation) -> self.ellipticResults), (fun (value : Microsoft.FSharp.Core.Option<EllipticAnnotationResult>) (self : Annotation) -> { self with ellipticResults = value }))
304308
static member visible_ = ((fun (self : Annotation) -> self.visible), (fun (value : Microsoft.FSharp.Core.bool) (self : Annotation) -> { self with visible = value }))
305309
static member showDns_ = ((fun (self : Annotation) -> self.showDns), (fun (value : Microsoft.FSharp.Core.bool) (self : Annotation) -> { self with showDns = value }))
306310
static member text_ = ((fun (self : Annotation) -> self.text), (fun (value : Microsoft.FSharp.Core.string) (self : Annotation) -> { self with text = value }))

src/PRo3D.Base/Annotation/AnnotationHelpers.fs

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,14 @@ module DipAndStrike =
170170

171171
let projectOntoPlane (x:V3d) (n:V3d) = (x - (x * n)).Normalized
172172

173-
let computeStandardDeviation avg (input : List<float>) =
173+
let computeStandardDeviation avg (input : array<float>) =
174174

175175
let sosq =
176176
input
177-
|> List.map(fun (x:double) ->
177+
|> Array.sumBy(fun (x:double) ->
178178
let k = (x.Abs() - avg)
179-
Math.Pow(k,2.0))
180-
|> List.sum
179+
Math.Pow(k,2.0)
180+
)
181181

182182
Math.Sqrt (sosq / float (input.Length - 1))
183183

@@ -258,18 +258,13 @@ module DipAndStrike =
258258
Some dns
259259

260260
let calculateDipAndStrikeResults (up:V3d) (north : V3d) (points:IndexList<V3d>) =
261+
262+
let points = points |> IndexList.toArray |> Array.filter (_.IsNaN >> not)
261263

262-
let points = points |> IndexList.filter(fun x -> not x.IsNaN)
263-
264-
match points.Count with
264+
match points.Length with
265265
| x when x > 2 ->
266-
267-
let v3dArray = points.AsList |> List.toArray // points.toArray not possible because of: int -> V3d[]
268-
269-
//let p = v3dArray.[0]
270-
// let up = p.Normalized
271-
272-
let linRegression = (new LinearRegression3d(v3dArray)).TryGetRegressionInfo()
266+
267+
let linRegression = LinearRegression3d(points).TryGetRegressionInfo()
273268

274269
Log.line "[AnnotationHelpers.fs] %A" linRegression
275270

@@ -278,18 +273,17 @@ module DipAndStrike =
278273
| Some lr -> lr.Plane
279274
| None ->
280275
Log.line "[dns computation] linear regression failed, fallback to evd"
281-
PlaneFitting.planeFit(v3dArray)
276+
PlaneFitting.planeFit(points)
282277

283278
let distances =
284279
points
285-
|> IndexList.toList
286-
|> List.map(fun x -> (plane.Height x).Abs())
280+
|> Array.map(fun x -> (plane.Height x).Abs())
287281

288-
let sos = distances |> List.map(fun x -> x * x) |> List.sum /// (float distances.Length)
282+
let sos = distances |> Array.map (fun x -> x * x) |> Array.sum /// (float distances.Length)
289283
290-
let avg = distances |> List.average
291-
let max = distances |> List.max
292-
let min = distances |> List.min
284+
let avg = distances |> Array.average
285+
let max = distances |> Array.max
286+
let min = distances |> Array.min
293287

294288
let std = distances |> computeStandardDeviation avg
295289

@@ -311,8 +305,8 @@ module DipAndStrike =
311305
let v = strike.Cross(up).Normalized
312306

313307
let centerOfMass =
314-
let sum = IndexList.sum points
315-
sum / (float)points.Count
308+
let sum = Array.sum points
309+
sum / float points.Length
316310

317311
let dns = {
318312
version = DipAndStrikeResults.current

0 commit comments

Comments
 (0)