@@ -9,7 +9,13 @@ use kittycad::types as kt;
99use kittycad_modeling_cmds:: { self as kcmc, units:: UnitLength } ;
1010use url:: Url ;
1111
12- use crate :: { iostreams:: IoStreams , kcl_error_fmt, types:: CameraView } ;
12+ use crate :: {
13+ iostreams:: IoStreams ,
14+ kcl_error_fmt,
15+ types:: { CameraStyle , CameraView } ,
16+ } ;
17+
18+ mod camera_angles;
1319
1420/// Perform actions on `kcl` files.
1521#[ derive( Parser , Debug , Clone ) ]
@@ -284,6 +290,17 @@ pub struct CmdKclSnapshot {
284290 /// Defaults to "front".
285291 #[ clap( long, value_enum) ]
286292 pub angle : Option < CameraView > ,
293+
294+ /// Which style of camera to use for snapshots.
295+ #[ clap( long, value_enum) ]
296+ pub camera_style : Option < CameraStyle > ,
297+
298+ /// How much padding to use when zooming before the screenshot.
299+ /// Positive padding will zoom out, negative padding will zoom in (and therefore crop).
300+ /// e.g. padding = 0.2 means the view will span 120% of the object(s) bounding box,
301+ /// and padding = -0.2 means the view will span 80% of the object(s) bounding box.
302+ #[ clap( long, default_value = "0.1" , allow_negative_numbers = true ) ]
303+ pub camera_padding : f32 ,
287304}
288305
289306#[ async_trait:: async_trait( ?Send ) ]
@@ -370,7 +387,7 @@ impl crate::cmd::Command for CmdKclSnapshot {
370387 "" ,
371388 & filepath. display ( ) . to_string ( ) ,
372389 & code,
373- four_sides_view ( ) ,
390+ four_sides_view ( self . camera_style . unwrap_or_default ( ) , self . camera_padding ) ,
374391 executor_settings,
375392 )
376393 . await ?;
@@ -456,6 +473,17 @@ pub struct CmdKclView {
456473 /// Defaults to "front".
457474 #[ clap( long, value_enum) ]
458475 pub angle : Option < CameraView > ,
476+
477+ /// Which style of camera to use for snapshots.
478+ #[ clap( long, value_enum) ]
479+ pub camera_style : Option < CameraStyle > ,
480+
481+ /// How much padding to use when zooming before the screenshot.
482+ /// Positive padding will zoom out, negative padding will zoom in (and therefore crop).
483+ /// e.g. padding = 0.2 means the view will span 120% of the object(s) bounding box,
484+ /// and padding = -0.2 means the view will span 80% of the object(s) bounding box.
485+ #[ clap( long, default_value = "0.1" , allow_negative_numbers = true ) ]
486+ pub camera_padding : f32 ,
459487}
460488
461489#[ async_trait:: async_trait( ?Send ) ]
@@ -505,7 +533,7 @@ impl crate::cmd::Command for CmdKclView {
505533 "" ,
506534 & filepath. display ( ) . to_string ( ) ,
507535 & code,
508- four_sides_view ( ) ,
536+ four_sides_view ( self . camera_style . unwrap_or_default ( ) , self . camera_padding ) ,
509537 executor_settings,
510538 )
511539 . await ?;
@@ -1209,57 +1237,36 @@ pub fn write_deterministic_export(file_path: &std::path::Path, file_contents: &[
12091237}
12101238
12111239/// Generate snapshots from 4 perspectives: front/side/top/isometric.
1212- fn four_sides_view ( ) -> Vec < kcmc:: ModelingCmd > {
1213- use kcmc:: shared:: Point3d ;
1214- let center = Point3d :: default ( ) ;
1215-
1240+ fn four_sides_view ( camera_style : CameraStyle , padding : f32 ) -> Vec < kcmc:: ModelingCmd > {
12161241 let snap = kcmc:: ModelingCmd :: TakeSnapshot ( kcmc:: TakeSnapshot {
12171242 format : kittycad_modeling_cmds:: ImageFormat :: Png ,
12181243 } ) ;
12191244
1220- let front = kcmc:: ModelingCmd :: DefaultCameraLookAt ( kcmc:: DefaultCameraLookAt {
1221- up : Point3d { x : 0.0 , y : 0.0 , z : 1.0 } ,
1222- vantage : Point3d {
1223- x : 0.0 ,
1224- y : -1.0 ,
1225- z : 0.0 ,
1226- } ,
1227- center,
1228- sequence : None ,
1229- } ) ;
1230-
1231- let side = kcmc:: ModelingCmd :: DefaultCameraLookAt ( kcmc:: DefaultCameraLookAt {
1232- up : Point3d { x : 0.0 , y : 0.0 , z : 1.0 } ,
1233- vantage : Point3d { x : 1.0 , y : 0.0 , z : 0.0 } ,
1234- center,
1235- sequence : None ,
1236- } ) ;
1237-
1238- let top = kcmc:: ModelingCmd :: DefaultCameraLookAt ( kcmc:: DefaultCameraLookAt {
1239- up : Point3d { x : 0.0 , y : 1.0 , z : 0.0 } ,
1240- vantage : Point3d { x : 0.0 , y : 0.0 , z : 1.0 } ,
1241- center,
1242- sequence : None ,
1243- } ) ;
1244-
1245- let iso = kcmc:: ModelingCmd :: ViewIsometric ( kcmc:: ViewIsometric { padding : 0.0 } ) ;
1246-
12471245 let zoom = kcmc:: ModelingCmd :: ZoomToFit ( kcmc:: ZoomToFit {
12481246 animated : false ,
12491247 object_ids : Default :: default ( ) ,
1250- padding : 0.1 ,
1248+ padding,
12511249 } ) ;
1250+
1251+ let camera_style = match camera_style {
1252+ CameraStyle :: Perspective => {
1253+ kcmc:: ModelingCmd :: DefaultCameraSetPerspective ( kcmc:: DefaultCameraSetPerspective { parameters : None } )
1254+ }
1255+ CameraStyle :: Ortho => kcmc:: ModelingCmd :: DefaultCameraSetOrthographic ( kcmc:: DefaultCameraSetOrthographic { } ) ,
1256+ } ;
1257+
12521258 vec ! [
1253- front,
1259+ camera_style,
1260+ camera_angles:: FRONT ,
12541261 zoom. clone( ) ,
12551262 snap. clone( ) ,
1256- side ,
1263+ camera_angles :: SIDE ,
12571264 zoom. clone( ) ,
12581265 snap. clone( ) ,
1259- top ,
1266+ camera_angles :: TOP ,
12601267 zoom. clone( ) ,
12611268 snap. clone( ) ,
1262- iso ,
1269+ camera_angles :: ISO ,
12631270 zoom. clone( ) ,
12641271 snap,
12651272 ]
0 commit comments