Skip to content

Commit 95433df

Browse files
authored
Merge pull request #563 from pro3d-space/features/area-of-polygons
Features/area of polygons Already merged as base for next steps
2 parents f281243 + 995c138 commit 95433df

16 files changed

Lines changed: 145 additions & 21 deletions

PRODUCT_RELEASE_NOTES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 5.3.0-prerelease1
2+
- axis-ellipses added
3+
- area calculation for closed polygons and ellipses included
4+
- surface intersection preview added
5+
16
## 5.1.2
27
- fixed legacy traverse scene file / m20 waypoint loading
38

aardium/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "PRo3D",
33
"productName": "PRo3D.Viewer",
4-
"version": "5.1.2",
4+
"version": "5.3.0-prerelease1",
55
"description": "PRo3D, short for Planetary Robotics 3D Viewer, is an interactive 3D visualization tool to allow planetary scientists to work with high-resolution 3D reconstructions of the Martian surface.",
66
"license": "AGPL",
77
"copyright": "VRVis Zentrum für Virtual Reality und Visualisierung Forschungs-GmbH",

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,10 @@ type AnnotationResults = {
257257
slope : float
258258
trueThickness : float
259259
verticalThickness : float
260+
area : float
260261
}
261262
with
262-
static member current = 2
263+
static member current = 3
263264
static member private readV0 =
264265
json {
265266
let! height = Json.readFloat "height"
@@ -281,6 +282,7 @@ with
281282
slope = slope
282283
trueThickness = Double.NaN
283284
verticalThickness = Double.NaN
285+
area = Double.NaN
284286
}
285287
}
286288

@@ -306,6 +308,7 @@ with
306308
slope = slope
307309
trueThickness = trueThickness
308310
verticalThickness = Double.NaN
311+
area = Double.NaN
309312
}
310313
}
311314

@@ -332,6 +335,35 @@ with
332335
slope = slope
333336
trueThickness = trueThickness
334337
verticalThickness = verticalThickness
338+
area = Double.NaN
339+
}
340+
}
341+
342+
static member private readV3 =
343+
json {
344+
let! height = Json.readFloat "height"
345+
let! heightDelta = Json.readFloat "heightDelta"
346+
let! avgAltitude = Json.readFloat "avgAltitude"
347+
let! length = Json.readFloat "length"
348+
let! wayLength = Json.readFloat "wayLength"
349+
let! bearing = Json.readFloat "bearing"
350+
let! slope = Json.readFloat "slope"
351+
let! trueThickness = Json.readFloat "trueThickness"
352+
let! verticalThickness = Json.readFloat "verticalThickness"
353+
let! area = Json.readFloat "area"
354+
355+
return {
356+
version = AnnotationResults.current
357+
height = height
358+
heightDelta = heightDelta
359+
avgAltitude = avgAltitude
360+
length = length
361+
wayLength = wayLength
362+
bearing = bearing
363+
slope = slope
364+
trueThickness = trueThickness
365+
verticalThickness = verticalThickness
366+
area = area
335367
}
336368
}
337369

@@ -342,6 +374,7 @@ with
342374
| 0 -> return! AnnotationResults.readV0
343375
| 1 -> return! AnnotationResults.readV1
344376
| 2 -> return! AnnotationResults.readV2
377+
| 3 -> return! AnnotationResults.readV3
345378
| _ -> return! v |> sprintf "don't know version %A of AnnotationResults" |> Json.error
346379
}
347380

@@ -357,6 +390,7 @@ with
357390
do! Json.writeFloat "slope" x.slope
358391
do! Json.writeFloat "trueThickness" x.trueThickness
359392
do! Json.writeFloat "verticalThickness" x.verticalThickness
393+
do! Json.writeFloat "area" x.area
360394
}
361395

362396

@@ -409,6 +443,7 @@ module AnnotationResults =
409443
slope = Double.NaN
410444
trueThickness = Double.NaN
411445
verticalThickness = Double.NaN
446+
area = Double.NaN
412447
}
413448

414449
type SemanticId = SemanticId of string

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-
//bfe6acfa-0299-89a4-8870-5436b29c454b
2-
//124b09b1-6601-961c-adac-7438070f4a0a
1+
//d57beed9-6fc2-ac59-849a-0162bb994dd5
2+
//f8c5a4a6-357e-5ffe-e148-5d422bdaddc4
33
#nowarn "49" // upper case patterns
44
#nowarn "66" // upcast is unncecessary
55
#nowarn "1337" // internal types
@@ -140,6 +140,7 @@ type AdaptiveAnnotationResults(value : AnnotationResults) =
140140
let _slope_ = FSharp.Data.Adaptive.cval(value.slope)
141141
let _trueThickness_ = FSharp.Data.Adaptive.cval(value.trueThickness)
142142
let _verticalThickness_ = FSharp.Data.Adaptive.cval(value.verticalThickness)
143+
let _area_ = FSharp.Data.Adaptive.cval(value.area)
143144
let mutable __value = value
144145
let __adaptive = FSharp.Data.Adaptive.AVal.custom((fun (token : FSharp.Data.Adaptive.AdaptiveToken) -> __value))
145146
static member Create(value : AnnotationResults) = AdaptiveAnnotationResults(value)
@@ -158,6 +159,7 @@ type AdaptiveAnnotationResults(value : AnnotationResults) =
158159
_slope_.Value <- value.slope
159160
_trueThickness_.Value <- value.trueThickness
160161
_verticalThickness_.Value <- value.verticalThickness
162+
_area_.Value <- value.area
161163
member __.Current = __adaptive
162164
member __.version = _version_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.int>
163165
member __.height = _height_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.float>
@@ -169,6 +171,7 @@ type AdaptiveAnnotationResults(value : AnnotationResults) =
169171
member __.slope = _slope_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.float>
170172
member __.trueThickness = _trueThickness_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.float>
171173
member __.verticalThickness = _verticalThickness_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.float>
174+
member __.area = _area_ :> FSharp.Data.Adaptive.aval<Microsoft.FSharp.Core.float>
172175
[<AutoOpen; System.Diagnostics.CodeAnalysis.SuppressMessage("NameConventions", "*")>]
173176
module AnnotationResultsLenses =
174177
type AnnotationResults with
@@ -182,6 +185,7 @@ module AnnotationResultsLenses =
182185
static member slope_ = ((fun (self : AnnotationResults) -> self.slope), (fun (value : Microsoft.FSharp.Core.float) (self : AnnotationResults) -> { self with slope = value }))
183186
static member trueThickness_ = ((fun (self : AnnotationResults) -> self.trueThickness), (fun (value : Microsoft.FSharp.Core.float) (self : AnnotationResults) -> { self with trueThickness = value }))
184187
static member verticalThickness_ = ((fun (self : AnnotationResults) -> self.verticalThickness), (fun (value : Microsoft.FSharp.Core.float) (self : AnnotationResults) -> { self with verticalThickness = value }))
188+
static member area_ = ((fun (self : AnnotationResults) -> self.area), (fun (value : Microsoft.FSharp.Core.float) (self : AnnotationResults) -> { self with area = value }))
185189
[<System.Diagnostics.CodeAnalysis.SuppressMessage("NameConventions", "*")>]
186190
type AdaptiveAnnotation(value : Annotation) =
187191
let _version_ = FSharp.Data.Adaptive.cval(value.version)

src/PRo3D.Base/Annotation/AnnotationHelpers.fs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,35 @@ module Calculations =
9595
yield getSegmentDistance s
9696
]
9797
|> List.sum
98+
99+
100+
let calculateVertexPlane (points: V3d[]) =
101+
if points.Length < 3 then Plane3d.Invalid
102+
else
103+
(PlaneFitting.planeFit(points))
104+
105+
let calculatePolygonArea (points:IndexList<V3d>) =
106+
if points.Count < 3 then
107+
0.0
108+
else
109+
let points = points |> IndexList.filter(fun x -> not x.IsNaN)
110+
let v3dArray = points.AsArray
111+
112+
let vertexPlane = calculateVertexPlane v3dArray
113+
114+
if vertexPlane.IsValid then
115+
116+
let w2Plane = vertexPlane.GetWorldToPlane()
117+
118+
let v2dArray =
119+
v3dArray
120+
|> Array.map(fun p -> (w2Plane.TransformPos p).XY)
121+
122+
let p2D = Polygon2d(v2dArray)
123+
p2D.ComputeArea()
124+
else
125+
0.0
126+
98127

99128
let calcResultsLine (annotation : Annotation) (upVec:V3d) (northVec:V3d) (planet:Planet) : AnnotationResults =
100129
let count = annotation.points.Count
@@ -136,6 +165,14 @@ module Calculations =
136165
planeHeight, verticalDistance
137166
| _ -> Double.NaN, Double.NaN
138167

168+
let area =
169+
match (annotation.geometry) with
170+
| Geometry.Polygon
171+
| Geometry.Ellipse
172+
| Geometry.AxisEllipse ->
173+
calculatePolygonArea annotation.points
174+
| _ -> Double.NaN
175+
139176
{
140177
version = AnnotationResults.current
141178
height = height
@@ -147,6 +184,7 @@ module Calculations =
147184
slope = slope
148185
trueThickness = trueThickness
149186
verticalThickness = verticalThickness
187+
area = area
150188
}
151189

152190
let calculateAnnotationResults (model:Annotation) (upVec:V3d) (northVec:V3d) (planet:Planet) : AnnotationResults =

src/PRo3D.Base/Annotation/Exporters/CSV.Export.fs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ module CSVExport =
4545
dipAzimuth : float
4646
strikeAzimuth : float
4747
rake : float
48+
area : float
4849

4950
manualDip : float
5051
trueThickness : float
@@ -173,12 +174,13 @@ module CSVExport =
173174

174175
horizontalDelta = horizontalDelta //
175176
verticalDelta = verticalDelta //
177+
area = results.area //
176178

177179
//dns
178180
dipAngle = dnsResults.dipAngle //
179181
dipAzimuth = dnsResults.dipAzimuth //
180182
strikeAzimuth = dnsResults.strikeAzimuth //
181-
rake = dnsResults.rake
183+
rake = dnsResults.rake
182184

183185
//error measures
184186
errorAvg = dnsResults.errorAvg

src/PRo3D.Core/Drawing/Drawing-App.fs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,40 @@ module DrawingApp =
488488
| GroupsMessage msg,_, _ ->
489489
let m = { model with annotations = GroupsApp.update model.annotations msg}
490490
m
491+
| RecalculateMeasurements, _,_ ->
492+
let up = smallConfig.up.Get(bigConfig)
493+
let north = smallConfig.north.Get(bigConfig)
494+
let planet = smallConfig.planet.Get(bigConfig)
495+
496+
let selected =
497+
model.annotations.selectedLeaves
498+
|> HashSet.map(fun selection -> selection.id)
499+
500+
let selected =
501+
if selected.IsEmpty then
502+
model.annotations.singleSelectLeaf
503+
|> Option.map(fun leafGuid ->
504+
HashSet.empty |> HashSet.add leafGuid)
505+
|> Option.defaultValue selected
506+
else
507+
selected
508+
509+
let annotationsFlat =
510+
selected
511+
|> HashSet.fold(fun annotations guid ->
512+
let a =
513+
model.annotations.flat.TryFind guid
514+
|> Option.map (fun anno -> anno |> Leaf.toAnnotation)
515+
516+
match a with
517+
| Some annotation ->
518+
let results = Calculations.calculateAnnotationResults annotation up north planet
519+
let annotation = { annotation with results = Some(results) }
520+
annotations |> HashMap.add guid (Leaf.Annotations annotation)
521+
| None -> annotations
522+
) model.annotations.flat
523+
524+
{ model with annotations = { model.annotations with flat = annotationsFlat }}
491525
| DnsColorLegendMessage msg,_, _ ->
492526
{ model with dnsColorLegend = FalseColorLegendApp.update model.dnsColorLegend msg }
493527
| FlyToAnnotation msg, _, _ ->

src/PRo3D.Core/Drawing/Drawing-Model.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type DrawingAction =
5656
| UpVectorChanged of V3d
5757
| NorthVectorChanged of V3d
5858
| GroupsMessage of GroupsAppAction
59+
| RecalculateMeasurements
5960
| DnsColorLegendMessage of FalseColorLegendApp.Action
6061
| ExportAsAnnotations of string
6162
| AddAnnotations of list<string>

src/PRo3D.Core/Drawing/Drawing-Model.g.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//5f52137c-4504-3d0c-e38d-92b4e1fe881d
1+
//551da2aa-09ea-8000-db8d-bb1b622e2009
22
//011fab16-2e0f-378e-5edf-99b0128f7a93
33
#nowarn "49" // upper case patterns
44
#nowarn "66" // upcast is unncecessary

src/PRo3D.Core/Drawing/Drawing-Properties.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ module AnnotationProperties =
113113
let slope = AVal.bindOption results Double.NaN (fun a -> a.slope)
114114
let trueThickness = AVal.bindOption results Double.NaN (fun a -> a.trueThickness)
115115
let verticalThickness = AVal.bindOption results Double.NaN (fun a -> a.verticalThickness)
116+
let area = AVal.bindOption results Double.NaN (fun a -> a.area)
116117

117118
// TODO refactor: why so complicated to list stuff?, not incremental
118119
let vertDist = AVal.map( fun u -> Calculations.verticalDelta (model.points |> AList.force |> IndexList.toList) u ) up
@@ -142,6 +143,7 @@ module AnnotationProperties =
142143
yield Html.row "Horizontal Distance:" [Incremental.text (horDist |> AVal.map (fun d -> sprintf "%.4f m" (d)))]
143144
yield Html.row "True Thickness:" [Incremental.text (trueThickness |> AVal.map (fun d -> sprintf "%.4f m" (d)))]
144145
yield Html.row "Vertical Thickness:" [Incremental.text (verticalThickness |> AVal.map (fun d -> sprintf "%.4f m" (d)))]
146+
yield Html.row "Area:" [Incremental.text (area |> AVal.map (fun d -> sprintf "%.4f m\xB2" (d)))]
145147
]
146148
)
147149

0 commit comments

Comments
 (0)