Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/origin/develop' into features/c…
Browse files Browse the repository at this point in the history
…ontourLines
  • Loading branch information
haraldsteinlechner committed Jan 25, 2024
2 parents f0e40c5 + 154bad0 commit 202966d
Show file tree
Hide file tree
Showing 17 changed files with 324 additions and 72 deletions.
7 changes: 7 additions & 0 deletions src/PRo3D.Base/Utilities.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,13 @@ module Electron =
sprintf "top.aardvark.electron.shell.showItemInFolder('%s');" (JsInterop.escapePath s)

module FrustumUtils =
let withAspect (aspect : float) (frustum : Frustum) =
Frustum.perspective
(Frustum.horizontalFieldOfViewInDegrees frustum)
frustum.near
frustum.far
aspect

let calculateFrustum (focal : float) (near : float) (far: float) =
// http://paulbourke.net/miscellaneous/lens/
// https://photo.stackexchange.com/questions/41273/how-to-calculate-the-fov-in-degrees-from-focal-length-or-distance
Expand Down
3 changes: 2 additions & 1 deletion src/PRo3D.Core/Drawing/Drawing-App.fs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,8 @@ module DrawingApp =

match model.working with
| Some w when w.points.Count > 0->
{ model with working = Some { w with points = w.points |> IndexList.removeAt (w.points.Count - 1) }}
{ model with working = Some { w with points = w.points |> IndexList.removeAt (w.points.Count - 1);
segments = w.segments |> IndexList.removeAt (w.segments.Count - 1)}}
| Some _ -> { model with working = None }
| None -> model
| SetSegment(segmentIndex,segment), _, _ ->
Expand Down
2 changes: 1 addition & 1 deletion src/PRo3D.Core/GroupsApp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ module GroupsApp =
(fun (x:Node) ->
{ x with subNodes = IndexList.add group x.subNodes })

{ model with rootGroup = updateNodeAt path func model.rootGroup }
{ model with rootGroup = updateNodeAt path func model.rootGroup; lastSelectedItem = SelectedItem.Group }

let union (left : GroupsModel) (right : GroupsModel) : GroupsModel =
if left.rootGroup.key = right.rootGroup.key then
Expand Down
34 changes: 34 additions & 0 deletions src/PRo3D.Core/SceneObjectsApp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type SceneObjectAction =
| PlaceSO of V3d
| TranslationMessage of TransformationApp.Action
| PlaceSceneObject of V3d
| ChangeSOImportDirectories of list<string>


module SceneObjectTransformations =
Expand Down Expand Up @@ -124,6 +125,12 @@ module SceneObjectsUtils =
let sghs =
sceneObject
|> IndexList.toList
|> List.filter(fun (so : SceneObject) ->
let dirExists = File.Exists so.importPath
if dirExists |> not then
Log.error "[SceneObject.Sg] could not find %s" so.importPath
dirExists
)
|> List.map loadSceneObject

let sgSceneObjects =
Expand All @@ -145,6 +152,26 @@ module SceneObjectsApp =
else
None

let changeSOImportDirectories (model:SceneObjectsModel) (selectedPaths:list<string>) =
let sceneObjs =
model.sceneObjects
|> HashMap.map(fun id so ->
let newPath =
selectedPaths
|> List.map(fun p ->
let name = p |> IO.Path.GetFileName
match name = so.name with
| true -> Some p
| false -> None
)
|> List.choose( fun np -> np)
match newPath.IsEmpty with
| true -> so
| false -> { so with importPath = newPath.Head }
)

{ model with sceneObjects = sceneObjs }

let update
(model : SceneObjectsModel)
(act : SceneObjectAction)
Expand Down Expand Up @@ -203,7 +230,14 @@ module SceneObjectsApp =
{ model with sceneObjects = sceneObjs}
| None -> model
| None -> model
| ChangeSOImportDirectories sl ->
match sl with
| [] -> model
| paths ->
let selectedPaths = paths |> List.choose( fun p -> if File.Exists p then Some p else None)
changeSOImportDirectories model selectedPaths
|_-> model



module UI =
Expand Down
12 changes: 6 additions & 6 deletions src/PRo3D.Core/SequencedBookmarks/BookmarkAnimations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ module BookmarkAnimations =
//let appearance = getName "appearance"

module Primitives =
let frustum_ = ViewConfigModel.frustumModel_ >-> FrustumModel.frustum_
let focal_ = ViewConfigModel.frustumModel_ >-> FrustumModel.focal_ >-> NumericInput.value_
let frustum_ = SceneStateViewConfig.frustumModel_ >-> FrustumModel.frustum_
let focal_ = SceneStateViewConfig.frustumModel_ >-> FrustumModel.focal_ >-> NumericInput.value_

let interpVcm (src : ViewConfigModel) (dst : ViewConfigModel)
: IAnimation<'Model, ViewConfigModel> =
let interpVcm (src : SceneStateViewConfig) (dst : SceneStateViewConfig)
: IAnimation<'Model, SceneStateViewConfig> =
//let animFocal = Primitives.lerp src.frustumModel.focal.value src.frustumModel.focal.value
let animFocal = Animation.create (lerp src.frustumModel.focal.value dst.frustumModel.focal.value)
|> Animation.seconds 1
Expand All @@ -44,8 +44,8 @@ module BookmarkAnimations =
let newFrustum =
FrustumUtils.calculateFrustum
focal
dst.nearPlane.value
dst.farPlane.value
dst.nearPlane
dst.farPlane

dst
|> Optic.set frustum_ newFrustum
Expand Down
168 changes: 162 additions & 6 deletions src/PRo3D.Core/SequencedBookmarks/SequencedBookmarks-Model.fs
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,119 @@ type SequencedBookmarksAction =
| ToggleUpdateJsonBeforeRendering
| SaveAnimation


/// a reduced version of SceneConfigModel that is saved and restore with sequenced bookmarks
type SceneStateViewConfig =
{
nearPlane : float
farPlane : float
frustumModel : FrustumModel
arrowLength : float
arrowThickness : float
dnsPlaneSize : float
lodColoring : bool
drawOrientationCube : bool
} with
static member frustumModel_ =
(fun c -> c.frustumModel),
(fun (value : FrustumModel) (c : SceneStateViewConfig) ->
{ c with frustumModel = value })
static member fromViewConfigModel (config : ViewConfigModel) =
{
nearPlane = config.nearPlane.value
farPlane = config.farPlane.value
frustumModel = config.frustumModel
arrowLength = config.arrowLength.value
arrowThickness = config.arrowThickness.value
dnsPlaneSize = config.dnsPlaneSize.value
lodColoring = config.lodColoring
drawOrientationCube = config.drawOrientationCube
}

static member FromJson(_ : SceneStateViewConfig) =
json {
let! nearPlane = Json.read "nearPlane"
let! farPlane = Json.read "farPlane"
let! frustumModel = Json.read "frustumModel"
let! arrowLength = Json.read "arrowLength"
let! arrowThickness = Json.read "arrowThickness"
let! dnsPlaneSize = Json.read "dnsPlaneSize"
let! lodColoring = Json.read "lodColoring"
let! drawOrientationCube = Json.read "drawOrientationCube"

return {
nearPlane = nearPlane
farPlane = farPlane
frustumModel = frustumModel
arrowLength = arrowLength
arrowThickness = arrowThickness
dnsPlaneSize = dnsPlaneSize
lodColoring = lodColoring
drawOrientationCube = drawOrientationCube
}
}
static member ToJson (x : SceneStateViewConfig) =
json {
do! Json.write "nearPlane" x.nearPlane
do! Json.write "farPlane" x.farPlane
do! Json.write "frustumModel" x.frustumModel
do! Json.write "arrowLength" x.arrowLength
do! Json.write "arrowThickness" x.arrowThickness
do! Json.write "dnsPlaneSize" x.dnsPlaneSize
do! Json.write "lodColoring" x.lodColoring
do! Json.write "drawOrientationCube" x.drawOrientationCube
}

type SceneStateReferenceSystem =
{
origin : V3d
isVisible : bool
size : float
selectedScale : string
} with
static member fromReferenceSystem (refSystem : ReferenceSystem)
: SceneStateReferenceSystem =
{
origin = refSystem.origin
isVisible = refSystem.isVisible
size = refSystem.size.value
selectedScale = refSystem.selectedScale
}
static member FromJson(_ : SceneStateReferenceSystem) =
json {
let! origin = Json.read "origin"
let! isVisible = Json.read "isVisible"
let! size = Json.read "size"
let! selectedScale = Json.read "selectedScale"

return {
origin = origin |> V3d.Parse
isVisible = isVisible
size = size
selectedScale = selectedScale
}
}
static member ToJson(x : SceneStateReferenceSystem) =
json {
do! Json.write "origin" (string x.origin)
do! Json.write "isVisible" x.isVisible
do! Json.write "size" x.size
do! Json.write "selectedScale" x.selectedScale
}

/// state of various scene elements for use with animations
type SceneState =
{
version : int
isValid : bool
timestamp : DateTime
stateAnnoatations : GroupsModel
stateSurfaces : GroupsModel
stateSceneObjects : SceneObjectsModel
stateScaleBars : ScaleBarsModel
stateGeologicSurfaces : GeologicSurfacesModel
stateConfig : ViewConfigModel
stateReferenceSystem : ReferenceSystem
stateConfig : SceneStateViewConfig
stateReferenceSystem : SceneStateReferenceSystem
stateTraverses : option<TraverseModel>
} with
static member stateConfig_ =
Expand All @@ -95,14 +196,52 @@ type SceneState =
)
static member frustum_ =
SceneState.stateConfig_
>-> ViewConfigModel.frustumModel_
>-> SceneStateViewConfig.frustumModel_
>-> FrustumModel.frustum_
static member focalLength_ =
SceneState.stateConfig_
>-> ViewConfigModel.frustumModel_
>-> SceneStateViewConfig.frustumModel_
>-> FrustumModel.focal_
>-> NumericInput.value_
static member FromJson( _ : SceneState) =

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module SceneState =
let currentVersion = 1
let read0 =
json {
let isValid = true
let! timestamp = Json.tryRead "timestamp"
let timestamp =
match timestamp with
| Some timestamp -> timestamp
| None -> DateTime.Now
let! stateAnnoatations = Json.read "stateAnnoatations"
let! stateSurfaces = Json.read "stateSurfaces"
let! stateSceneObjects = Json.read "stateSceneObjects"
let! stateScaleBars = Json.read "stateScaleBars"
let! stateGeologicSurfaces = Json.read "stateGeologicSurfaces"
let! stateConfig = Json.read "stateConfig"
let! stateReferenceSystem = Json.read "stateReferenceSystem"
let! stateTraverse = Json.tryRead "stateTraverse"

return {
version = currentVersion
isValid = isValid
timestamp = timestamp
stateAnnoatations = stateAnnoatations
stateSurfaces = stateSurfaces
stateSceneObjects = stateSceneObjects
stateScaleBars = stateScaleBars
stateGeologicSurfaces = stateGeologicSurfaces
stateConfig =
SceneStateViewConfig.fromViewConfigModel stateConfig
stateReferenceSystem =
SceneStateReferenceSystem.fromReferenceSystem stateReferenceSystem
stateTraverses = stateTraverse
}
}

let read1 =
json {
let isValid = true
let! timestamp = Json.tryRead "timestamp"
Expand All @@ -120,6 +259,7 @@ type SceneState =
let! stateTraverse = Json.tryRead "stateTraverse"

return {
version = currentVersion
isValid = isValid
timestamp = timestamp
stateAnnoatations = stateAnnoatations
Expand All @@ -133,8 +273,24 @@ type SceneState =
}
}

type SceneState with
static member FromJson( _ : SceneState) =
json {
let! version = Json.tryRead "version"
match version with
| None ->
return! SceneState.read0
| Some v when v = 1 ->
return! SceneState.read1
| _ ->
return! version
|> sprintf "don't know version %A of SceneState"
|> Json.error
}

static member ToJson(x : SceneState) =
json {
do! Json.write "version" SceneState.currentVersion
do! Json.write "timestamp" x.timestamp
do! Json.write "stateAnnoatations" x.stateAnnoatations
do! Json.write "stateSurfaces" x.stateSurfaces
Expand Down Expand Up @@ -247,7 +403,7 @@ type SequencedBookmarkModel = {
this.filename
]
| None ->
Log.warn "[SequencedBookmarks] Bookmark has no basePath."
//Log.warn "[SequencedBookmarks] Bookmark has no basePath." //debugging
this.filename

member this.filename =
Expand Down
Loading

0 comments on commit 202966d

Please sign in to comment.