Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Named views #5532

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
f752215
feature: building skeleton for adding a viewpoint in frontend as well…
nadr0 Jan 15, 2025
623de50
fix: merged main
nadr0 Jan 16, 2025
227e31a
chore: named views loaded into memory
nadr0 Jan 16, 2025
c574274
fix: testing code
nadr0 Jan 16, 2025
ec883c4
chore: saving off progress, skeleton for listing and deleting named v…
nadr0 Jan 16, 2025
28d740b
fix: fixed state stale dereferencing issue
nadr0 Jan 17, 2025
35affa9
feat: initial skeleton for loading view points
nadr0 Jan 17, 2025
0094bc9
fix: pushing bug
nadr0 Jan 17, 2025
ab95c72
fix: saving off progress
nadr0 Jan 29, 2025
421189e
fix: merge main
nadr0 Feb 25, 2025
154d145
fix: trying to update to main?
nadr0 Feb 25, 2025
470a272
fix: main fixes, API fixes
nadr0 Feb 25, 2025
129d505
fix: what is happening
nadr0 Feb 26, 2025
a7e2660
fix: ope
nadr0 Feb 26, 2025
18e3374
fix: implemented default values on serde
nadr0 Feb 26, 2025
81bbf4a
fix: pushing working dev code... need to clean it up
nadr0 Feb 26, 2025
36fdbee
feature: adding no results found on filteroptions within an options i…
nadr0 Feb 26, 2025
1b288b7
fix: initial PR cleanup pass of junky code
nadr0 Feb 26, 2025
b352700
fix: addressing comments in initial pass
nadr0 Feb 27, 2025
27bbc4f
fix: addressing PR comments
nadr0 Feb 27, 2025
324db3c
fix: moved modeling.namedViews to app.namedViews as per request
nadr0 Feb 27, 2025
b10f559
fix: _id and _version are now id and version.
nadr0 Feb 27, 2025
95d65e4
fix: python codespell, perspective
nadr0 Feb 27, 2025
bfd2bb6
fix: cargo fmt
nadr0 Feb 27, 2025
091b3e7
fix: updating description of the named view commands
nadr0 Feb 27, 2025
2655d14
fix: removing testing code
nadr0 Feb 27, 2025
c06446b
fix: feature flag this to DEV only
nadr0 Feb 27, 2025
8138ff2
fix: ts ignore for production engine api
nadr0 Feb 27, 2025
998e651
fix: deep parital fights arrays and objects within settings, doing a …
nadr0 Feb 27, 2025
6f56d17
fix: auto fixes
nadr0 Feb 27, 2025
e1558b8
Merge branch 'main' into nadro/gh-4217/named-views
lf94 Feb 28, 2025
b70d751
Remove unnecessary alias
lf94 Feb 28, 2025
ab24f92
Reword toast messages (more consistency)
lf94 Feb 28, 2025
889a7a5
fmt
lf94 Feb 28, 2025
99f983a
cargo clippy
lf94 Feb 28, 2025
c119de8
Fix Set appearance flakes
lf94 Feb 28, 2025
32243dd
cargo test
lf94 Feb 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/clientSideScene/CameraControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,14 @@ export class CameraControls {
camSettings.up.y,
camSettings.up.z
)

this.camera.quaternion.set(
orientation.x,
orientation.y,
orientation.z,
orientation.w
)

this.camera.up.copy(newUp)
this.camera.updateProjectionMatrix()
if (this.camera instanceof PerspectiveCamera && camSettings.ortho) {
Expand Down
66 changes: 36 additions & 30 deletions src/components/CommandBar/CommandArgOptionInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,37 +168,43 @@ function CommandArgOptionInput({
autoFocus
/>
</div>
<Combobox.Options
static
className="overflow-y-auto max-h-96 cursor-pointer"
onMouseDown={() => {
setShouldSubmitOnChange(true)
}}
>
{filteredOptions?.map((option) => (
<Combobox.Option
key={option.name}
value={option}
disabled={option.disabled}
className="flex items-center gap-2 px-4 py-1 first:mt-2 last:mb-2 ui-active:bg-primary/10 dark:ui-active:bg-chalkboard-90"
>
<p
className={`flex-grow ${
(option.disabled &&
'text-chalkboard-70 dark:text-chalkboard-50 cursor-not-allowed') ||
''
}`}
{filteredOptions?.length ? (
<Combobox.Options
static
className="overflow-y-auto max-h-96 cursor-pointer"
onMouseDown={() => {
setShouldSubmitOnChange(true)
}}
>
{filteredOptions?.map((option) => (
<Combobox.Option
key={option.name}
value={option}
disabled={option.disabled}
className="flex items-center gap-2 px-4 py-1 first:mt-2 last:mb-2 ui-active:bg-primary/10 dark:ui-active:bg-chalkboard-90"
>
{option.name}
</p>
{option.value === currentOption?.value && (
<small className="text-chalkboard-70 dark:text-chalkboard-50">
current
</small>
)}
</Combobox.Option>
))}
</Combobox.Options>
<p
className={`flex-grow ${
(option.disabled &&
'text-chalkboard-70 dark:text-chalkboard-50 cursor-not-allowed') ||
''
}`}
>
{option.name}
</p>
{option.value === currentOption?.value && (
<small className="text-chalkboard-70 dark:text-chalkboard-50">
current
</small>
)}
</Combobox.Option>
))}
</Combobox.Options>
) : (
<p className="px-4 pt-2 text-chalkboard-60 dark:text-chalkboard-50">
No results found
</p>
)}
</Combobox>
</form>
)
Expand Down
19 changes: 19 additions & 0 deletions src/components/FileMachineProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { commandBarActor } from 'machines/commandBarMachine'
import { settingsActor, useSettings } from 'machines/appMachine'
import { createRouteCommands } from 'lib/commandBarConfigs/routeCommandConfig'
import { useToken } from 'machines/appMachine'
import { createNamedViewsCommand } from 'lib/commandBarConfigs/namedViewsConfig'

type MachineContext<T extends AnyStateMachine> = {
state: StateFrom<T>
Expand All @@ -58,6 +59,24 @@ export const FileMachineProvider = ({
[]
)

useEffect(() => {
const {
createNamedViewCommand,
deleteNamedViewCommand,
loadNamedViewCommand,
} = createNamedViewsCommand()
commandBarActor.send({
type: 'Add commands',
data: {
commands: [
createNamedViewCommand,
deleteNamedViewCommand,
loadNamedViewCommand,
],
},
})
}, [])

// Due to the route provider, i've moved this to the FileMachineProvider instead of CommandBarProvider
// This will register the commands to route to Telemetry, Home, and Settings.
useEffect(() => {
Expand Down
163 changes: 163 additions & 0 deletions src/lib/commandBarConfigs/namedViewsConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import { NamedView } from 'wasm-lib/kcl/bindings/NamedView'
import { Command } from '../commandTypes'
import toast from 'react-hot-toast'
import { engineCommandManager } from 'lib/singletons'
import { uuidv4 } from 'lib/utils'
import { settingsActor } from 'machines/appMachine'

export function createNamedViewsCommand() {
const createNamedViewCommand: Command = {
name: 'Create named view',
displayName: `Create named view`,
description: 'Create a named view to reload this view',
groupId: 'namedViews',
icon: 'settings',
needsReview: false,
onSubmit: async (data) => {

Check failure on line 16 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-lint

Promise-returning function provided to property where a void return was expected
const namedViews = [
...settingsActor.getSnapshot().context.modeling.namedViews.current,
]
var a = await engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: { type: 'default_camera_get_view' },

Check failure on line 23 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

Type '"default_camera_get_view"' is not assignable to type '"engine_util_evaluate_path" | "start_path" | "move_path_pen" | "extend_path" | "extrude" | "sweep" | "revolve" | "solid3d_shell_face" | "revolve_about_edge" | "loft" | "close_path" | "camera_drag_start" | "camera_drag_move" | "camera_drag_end" | "default_camera_get_settings" | "default_camera_look_at" | "default_camera_perspective_settings" | "default_camera_zoom" | "entity_get_parent_id" | "entity_get_num_children" | "entity_get_child_uuid" | "entity_get_all_child_uuids" | "entity_get_sketch_paths" | "entity_get_distance" | "entity_linear_pattern_transform" | "entity_linear_pattern" | "entity_circular_pattern" | "entity_make_helix" | "entity_make_helix_from_params" | "entity_make_helix_from_edge" | "entity_mirror" | "entity_mirror_across_edge" | "select_with_point" | "select_add" | "select_remove" | "scene_clear_all" | "select_replace" | "highlight_set_entity" | "highlight_set_entities" | "new_annotation" | "update_annotation" | "edge_lines_visible" | "object_visible" | "object_bring_to_front" | "object_set_material_params_pbr" | "get_entity_type" | "solid3d_get_all_edge_faces" | "solid2d_add_hole" | "solid3d_get_all_opposite_edges" | "solid3d_get_opposite_edge" | "solid3d_get_next_adjacent_edge" | "solid3d_get_prev_adjacent_edge" | "solid3d_get_common_edge" | "solid3d_fillet_edge" | "face_is_planar" | "face_get_position" | "face_get_center" | "face_get_gradient" | "send_object" | "entity_set_opacity" | "entity_fade" | "make_plane" | "plane_set_color" | "set_tool" | "mouse_move" | "mouse_click" | "sketch_mode_disable" | "get_sketch_mode_plane" | "curve_set_constraint" | "enable_sketch_mode" | "enable_dry_run" | "disable_dry_run" | "set_background_color" | "set_current_tool_properties" | "set_default_system_properties" | "curve_get_type" | "curve_get_control_points" | "project_entity_to_plane" | "project_points_to_plane" | "take_snapshot" | "make_axes_gizmo" | "path_get_info" | "path_get_curve_uuids_for_vertices" | "path_get_curve_uuid" | "path_get_vertex_uuids" | "path_get_sketch_target_uuid" | "handle_mouse_drag_start" | "handle_mouse_drag_move" | "handle_mouse_drag_end" | "remove_scene_objects" | "plane_intersect_and_project" | "curve_get_end_points" | "reconfigure_stream" | "import_files" | "set_scene_units" | "mass" | "density" | "volume" | "center_of_mass" | "surface_area" | "default_camera_focus_on" | "set_selection_type" | "set_selection_filter" | "default_camera_set_orthographic" | "default_camera_set_perspective" | "default_camera_center_to_selection" | "default_camera_center_to_scene" | "zoom_to_fit" | "view_isometric" | "solid3d_get_extrusion_face_info" | "select_clear" | "select_get" | "get_num_objects" | "set_object_transform" | "make_offset_path" | "add_hole_from_offset" | "export"'.
})
var view = a.resp.data.modeling_response.data

Check failure on line 25 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

Property 'resp' does not exist on type 'WebSocketResponse_type'.

Check failure on line 25 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

'a' is possibly 'null'.
const requestedView: NamedView = {
name: data.name,

Check failure on line 27 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

'data' is possibly 'undefined'.
...view.view,
}

const requestedNamedViews = [...namedViews, requestedView]
settingsActor.send({
type: `set.modeling.namedViews`,
data: {
level: 'project',
value: requestedNamedViews,
},
})

// TODO: duplicate
// TODO: overwrite
// TODO: ask them to rename?
toast.success(
`Your named view ${requestedView.name} successfully created.`
)
},
args: {
name: {
required: true,
inputType: 'string',
},
},
}

const deleteNamedViewCommand: Command = {
name: 'Delete named view',
displayName: `Delete named view`,
description: 'Delete a named view',
groupId: 'namedViews',
icon: 'settings',
needsReview: false,
onSubmit: (data) => {
const nameToDelete = data.name

Check failure on line 63 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

'data' is possibly 'undefined'.
const namedViews = [
...settingsActor.getSnapshot().context.modeling.namedViews.current,
]
const indexToDelete = namedViews.findIndex(
(view) => view.name === nameToDelete
)
if (indexToDelete >= 0) {
namedViews.splice(indexToDelete, 1)
settingsActor.send({
type: `set.modeling.namedViews`,
data: {
level: 'project',
value: namedViews,
},
})
toast.success(`Deleted ${data.name} named view.`)

Check failure on line 79 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

'data' is possibly 'undefined'.
} else {
toast.error(`Unable to delete ${data.name}, something went wrong.`)

Check failure on line 81 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

'data' is possibly 'undefined'.
}
},
args: {
name: {
required: true,
inputType: 'options',
options: () => {
const namedViews = [
...settingsActor.getSnapshot().context.modeling.namedViews.current,
]
return namedViews.map((view, index) => {
return {
name: view.name,
isCurrent: index === 0,
value: view.name,
}
})
},
},
},
}

const loadNamedViewCommand: Command = {
name: 'Load named view',
displayName: `Load named view`,
description: 'Load a named view',
groupId: 'namedViews',
icon: 'settings',
needsReview: false,
onSubmit: async (data) => {

Check failure on line 111 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-lint

Promise-returning function provided to property where a void return was expected
// Key is name but value is _id
const _idToLoad = data.name

Check failure on line 113 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

'data' is possibly 'undefined'.
const namedViews = [
...settingsActor.getSnapshot().context.modeling.namedViews.current,
]
console.log('NAMED VIEWS?', namedViews)
const viewToLoad = namedViews.find((view) => view._id === _idToLoad)
if (viewToLoad) {
const cameraViewData = { ...viewToLoad }
delete cameraViewData.name

Check failure on line 121 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

The operand of a 'delete' operator must be optional.
console.log(cameraViewData, 'gonna load')
await engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_set_view',

Check failure on line 127 in src/lib/commandBarConfigs/namedViewsConfig.ts

View workflow job for this annotation

GitHub Actions / yarn-tsc

Type '"default_camera_set_view"' is not assignable to type '"engine_util_evaluate_path" | "start_path" | "move_path_pen" | "extend_path" | "extrude" | "sweep" | "revolve" | "solid3d_shell_face" | "revolve_about_edge" | "loft" | "close_path" | "camera_drag_start" | "camera_drag_move" | "camera_drag_end" | "default_camera_get_settings" | "default_camera_look_at" | "default_camera_perspective_settings" | "default_camera_zoom" | "entity_get_parent_id" | "entity_get_num_children" | "entity_get_child_uuid" | "entity_get_all_child_uuids" | "entity_get_sketch_paths" | "entity_get_distance" | "entity_linear_pattern_transform" | "entity_linear_pattern" | "entity_circular_pattern" | "entity_make_helix" | "entity_make_helix_from_params" | "entity_make_helix_from_edge" | "entity_mirror" | "entity_mirror_across_edge" | "select_with_point" | "select_add" | "select_remove" | "scene_clear_all" | "select_replace" | "highlight_set_entity" | "highlight_set_entities" | "new_annotation" | "update_annotation" | "edge_lines_visible" | "object_visible" | "object_bring_to_front" | "object_set_material_params_pbr" | "get_entity_type" | "solid3d_get_all_edge_faces" | "solid2d_add_hole" | "solid3d_get_all_opposite_edges" | "solid3d_get_opposite_edge" | "solid3d_get_next_adjacent_edge" | "solid3d_get_prev_adjacent_edge" | "solid3d_get_common_edge" | "solid3d_fillet_edge" | "face_is_planar" | "face_get_position" | "face_get_center" | "face_get_gradient" | "send_object" | "entity_set_opacity" | "entity_fade" | "make_plane" | "plane_set_color" | "set_tool" | "mouse_move" | "mouse_click" | "sketch_mode_disable" | "get_sketch_mode_plane" | "curve_set_constraint" | "enable_sketch_mode" | "enable_dry_run" | "disable_dry_run" | "set_background_color" | "set_current_tool_properties" | "set_default_system_properties" | "curve_get_type" | "curve_get_control_points" | "project_entity_to_plane" | "project_points_to_plane" | "take_snapshot" | "make_axes_gizmo" | "path_get_info" | "path_get_curve_uuids_for_vertices" | "path_get_curve_uuid" | "path_get_vertex_uuids" | "path_get_sketch_target_uuid" | "handle_mouse_drag_start" | "handle_mouse_drag_move" | "handle_mouse_drag_end" | "remove_scene_objects" | "plane_intersect_and_project" | "curve_get_end_points" | "reconfigure_stream" | "import_files" | "set_scene_units" | "mass" | "density" | "volume" | "center_of_mass" | "surface_area" | "default_camera_focus_on" | "set_selection_type" | "set_selection_filter" | "default_camera_set_orthographic" | "default_camera_set_perspective" | "default_camera_center_to_selection" | "default_camera_center_to_scene" | "zoom_to_fit" | "view_isometric" | "solid3d_get_extrusion_face_info" | "select_clear" | "select_get" | "get_num_objects" | "set_object_transform" | "make_offset_path" | "add_hole_from_offset" | "export"'.
view: {
...cameraViewData,
},
},
})
toast.success(`Loaded ${data.name} named view.`)
} else {
toast.error(`Unable to load ${data.name}, something went wrong.`)
}
},
args: {
name: {
required: true,
inputType: 'options',
options: () => {
const namedViews = [
...settingsActor.getSnapshot().context.modeling.namedViews.current,
]
return namedViews.map((view, index) => {
return {
name: view.name,
isCurrent: index === 0,
value: view._id,
}
})
},
},
},
}

return {
createNamedViewCommand,
deleteNamedViewCommand,
loadNamedViewCommand,
}
}
5 changes: 5 additions & 0 deletions src/lib/settings/initialSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { isArray, toSync } from 'lib/utils'
import { reportRejection } from 'lib/trap'
import { CameraProjectionType } from 'wasm-lib/kcl/bindings/CameraProjectionType'
import { OnboardingStatus } from 'wasm-lib/kcl/bindings/OnboardingStatus'
import { NamedView } from 'wasm-lib/kcl/bindings/NamedView'
import { CameraOrbitType } from 'wasm-lib/kcl/bindings/CameraOrbitType'

/**
Expand Down Expand Up @@ -467,6 +468,10 @@ export function createSettings() {
// inputType: 'boolean',
// },
// }),
namedViews: new Setting<NamedView[]>({
defaultValue: [],
validate: (v) => true,
}),
},
/**
* Settings that affect the behavior of the KCL text editor.
Expand Down
1 change: 1 addition & 0 deletions src/lib/settings/settingsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export function projectConfigurationToSettingsPayload(
),
highlightEdges: configuration?.settings?.modeling?.highlight_edges,
showDebugPanel: configuration?.settings?.modeling?.show_debug_panel,
namedViews: configuration?.settings?.modeling?.named_views,
},
textEditor: {
textWrapping: configuration?.settings?.text_editor?.text_wrapping,
Expand Down
11 changes: 10 additions & 1 deletion src/machines/settingsMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
saveSettings,
setSettingsAtLevel,
} from 'lib/settings/settingsUtils'
import { NamedView } from 'wasm-lib/kcl/bindings/NamedView'
import {
codeManager,
engineCommandManager,
Expand Down Expand Up @@ -77,6 +78,7 @@ export const settingsMachine = setup({
level: SettingsLevel
}
| { type: 'Set all settings'; settings: typeof settings }
| { type: 'set.modeling.namedViews'; value: NamedView }
| { type: 'load.project'; project?: Project }
| { type: 'clear.project' }
) & { doNotPersist?: boolean },
Expand Down Expand Up @@ -151,6 +153,7 @@ export const settingsMachine = setup({
type: 'Add commands',
data: { commands: commands },
})

const removeCommands = () =>
commandBarActor.send({
type: 'Remove commands',
Expand Down Expand Up @@ -204,7 +207,7 @@ export const settingsMachine = setup({
if (!('data' in event)) return
const eventParts = event.type.replace(/^set./, '').split('.') as [
keyof typeof settings,
string
string,
]
const truncatedNewValue = event.data.value?.toString().slice(0, 28)
const message =
Expand Down Expand Up @@ -391,6 +394,12 @@ export const settingsMachine = setup({
],
},

'set.modeling.namedViews': {
target: 'persisting settings',

actions: ['setSettingAtLevel'],
},

'set.app.onboardingStatus': {
target: 'persisting settings',

Expand Down
2 changes: 1 addition & 1 deletion src/wasm-lib/kcl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ mod log;
mod lsp;
mod modules;
mod parsing;
mod settings;
pub mod settings;
#[cfg(test)]
mod simulation_tests;
mod source_range;
Expand Down
Loading
Loading