├── chapters ├── creating_shapes_from_wires.adoc ├── design_intent.adoc ├── hair_dryer │ ├── braun_like_hair_dryer.png │ ├── braun_like_hair_dryer_2.png │ ├── braun_like_hair_dryer_3.png │ ├── hair_dryer.js │ ├── hairdryer.json │ ├── hairdryer2.json │ ├── hollow_shape.adoc │ └── thinbox.json ├── introduction.adoc ├── micke_cover │ ├── micke_cover.3mf │ ├── micke_cover.json │ ├── micke_cover.stl │ ├── micke_cover_3d.png │ ├── micke_cover_fine.stl │ ├── prusa_add_modifier.png │ ├── prusa_cover_sliced.PNG │ ├── prusa_import_stl.png │ ├── prusa_modifier_set.pdn │ ├── prusa_modifier_set.png │ ├── readme.adoc │ └── thicksolid.json ├── parametric_modelling.adoc └── three_arm │ ├── shaped_arms.png │ ├── shaped_arms_2.png │ ├── single_arm.slvs │ ├── single_arm_cutout.png │ ├── three-arm-arm.json │ ├── three-arm-arm.slvs │ ├── three-arm-library.json │ ├── three-arm-var.png │ ├── three-arm-var.slvs │ ├── three-arm-var2,slvs.slvs │ ├── three-arm-var2.slvs │ ├── three-arm-views.png │ ├── three-arm.js │ ├── three-arm.pdn │ ├── three-arm2.pdn │ ├── three-arm2.png │ ├── three_arm.adoc │ ├── three_arm_cutter.png │ ├── three_arms_complete.png │ ├── three_arms_rough.png │ ├── three_arms_union.png │ └── three_arms_views_2.png ├── images ├── OBJ_STL_export.png ├── antimony-nut-2.png ├── antimony-nut.png ├── antimony-nut3.png ├── antimony.png ├── bezier.png ├── bezier.pptx ├── bezier_test.slvs ├── blue_hi.png ├── blurry_silver_hi.png ├── button.png ├── car_environment.png ├── ccs-arcto.png ├── ccs-car-v2.png ├── ccs-intro.png ├── ccs-pwa-installed.png ├── ccs_directory.png ├── ccs_error.png ├── change_design_intent.png ├── change_design_intent1.png ├── change_design_intent2.png ├── changed_floor_background.png ├── changed_interface_layout.png ├── checkbox.png ├── chrome2_hi.png ├── chrome_apps.png ├── chrome_hi.png.png ├── circle_hole.png ├── code_ground.png ├── command_palette.png ├── coordinates.png ├── coordinates.png.pdf ├── cqeditor_interface.png ├── css-car.png ├── diagram.png ├── dialog_all.png ├── duller_grey_hi.png.png ├── dxy.pdn ├── dxy.png ├── edge_index.png ├── error_F8_1.png ├── errors_F8.png ├── export_step_se.png ├── extrude5.png ├── face_reverse.png ├── fillets.png ├── fillets_and_arc.png ├── fillets_wa.png ├── filletsquare.js ├── first-example.png ├── first_sphere.png ├── fork_crank_v2A.igs ├── fork_crank_v2A.stl ├── fork_crank_v2B.stp ├── fork_failed_filletedges.pdn ├── fork_failed_filletedges.png ├── fork_half.png ├── forked_bracket_blender.png ├── forked_bracket_joko.png ├── forked_bracket_se.png ├── forked_bracket_se2.png ├── forked_lever_replicad.png ├── freecad_named_constraints.png ├── gears.png ├── generative_design_1.png ├── gherkin_equation.js ├── gherkin_loft.png ├── gherkin_profile_3.json ├── gherkin_profile_correct.json ├── gherkin_shape.png ├── gizmo-rotate-e.png ├── gizmo-scale-r.png ├── gizmo.png ├── gizmo.pptx ├── gizmo1.png ├── gizmo_translate.png ├── gizno_rotate.png ├── helix.png ├── hollow_boxes.PNG ├── honeycomb.png ├── honeycomb_experiments.png ├── house_drawing.png ├── ideation.blend ├── ideation.png ├── image_list.txt ├── import_igs_se.png ├── import_step.png ├── import_step_0.png ├── import_step_se.png ├── import_stl.png ├── imported_fork.json ├── imported_fork.png ├── install_app_dialog.png ├── install_button.png ├── interface.png ├── jscad_interface.png ├── lever.png ├── loft3.png ├── makeface.png ├── matcap_change.png ├── mesh-res.png ├── mirror.png ├── modelling_approaches1.png ├── named_constraints.png ├── names_variables_freecad_2.png ├── newsketch.json ├── nut.pptx.pptx ├── nut_flow.png ├── offset.png ├── offset.pptx ├── openscad-car.jpg ├── openscad_interface.png ├── pipe1.png ├── pipe3.json ├── pipe3.png ├── pipe4.pdn ├── pipe4.png ├── polar.pdn ├── polar.png ├── polygon.png ├── radiusarc.pdn ├── radiusarc.png ├── red_car.png ├── red_hi.png ├── revolve.json ├── revolve.png ├── revolve2.png ├── revolve3.png ├── revolve5.png ├── revolve6.png ├── revolve_shapes.png ├── rotate_origin.png ├── rotated_extrude.png ├── rotated_extrude2.png ├── rounded_boxes.png ├── sagarc.pdn ├── sagarc.png ├── se_export_iges.png ├── se_export_stl.png ├── several_boxes.png ├── shapes.png ├── shapes2.png ├── shiny-red-hi.png ├── sketch_commands.png ├── sketch_iteration.png ├── sketch_to_shape.png ├── sketch_to_shape.pptx ├── slider.png ├── sliders_vacuum.png ├── splie4.png ├── spline1.png ├── spline20.png ├── spline4.png ├── splinesketch.png ├── step_import_moi3d.png ├── structural_analysis.jpg ├── tailored_level.js ├── tailored_lever.png ├── textures │ ├── blue.png │ ├── blurry_silver_mirrorball.jpg │ ├── chrome.jpg │ ├── chrome_mirrorball.jpg │ ├── dullFrontLitMetal.png │ ├── grey_matcap.png │ ├── matcap.png │ ├── readme.txt │ ├── red_carpaint-matcap.jpg │ ├── reflective_red_mirrorball.jpg │ ├── white_dull_matcap.png │ └── white_toon_matcap.png ├── torso_plan.png ├── turning_torso_complete.png ├── turning_torso_sketch.png ├── uHook-01b-gamme-sergePayen.jpg ├── uHook-03-shape-sergePayen.jpg ├── uneven_chamfer.json ├── unevenchamfer.png ├── vacuum_heads.png ├── vscode_command.png ├── vscode_extensions.png ├── vscode_start_liveserver.png ├── web-cad-experiment.json └── white_hi.png ├── parts ├── airbudHolder.js ├── antimony-nut.sb ├── bezier-spline.js ├── bookshelf.json ├── booleans.json ├── car.js ├── drawboard.json ├── ellipsebezier.json ├── extrude.json ├── feltHolder.js ├── fiat_binnenlamp_1.json ├── flatbase_holder_cs.json ├── forked-lever-v4rc.js ├── forked_lever_cs.pdn ├── forked_lever_cs_30.png ├── forked_lever_cs_50.png ├── forked_lever_cs_var.png ├── furniture.json.txt ├── gear.js ├── gherkin_6.js ├── gherkin_equation.js ├── gherkin_profile_5.js ├── gherkin_profile_correct.json ├── gnsholder.js ├── hairdryer_v2.json ├── hexagon.json ├── holder.js ├── holder.json ├── holderv2.js ├── honeycomb.js ├── honeycomb.step ├── honeycomb.stl ├── honeycomb_v2.js ├── icosahedron.js ├── inscribed_polygon.json ├── laptop_stand.json.txt ├── lever-roundedsketch.json ├── lever.json ├── lever_drawing.dxf ├── lever_tailored.js ├── lighter_lever.js ├── loft_plunge.json ├── micke_cover.json ├── mollino-cs.json ├── mollino-experiments.3dm ├── mollino.FCStd ├── newsketch.js ├── newsketch_1.js ├── nut.js ├── nut.json ├── plunge-imported-cs.3dm ├── plunge.blend ├── plunge2-v3.step ├── plunge6.json ├── radiator-cleaner.json ├── revolve5.json ├── rotate_extrude_demo.json ├── rough_lever.js ├── round_all_clone.js ├── rounded_solid_boxes.js ├── shapes.json ├── spline.js ├── spline.json ├── test-union.json ├── thread.js ├── three-arm-arm.json ├── three_arm.js ├── torso_plan.json ├── transform.js ├── turning_torso.js ├── turning_torso_v2.js └── turning_torso_v3.js └── readme.adoc /chapters/creating_shapes_from_wires.adoc: -------------------------------------------------------------------------------- 1 | == Creating shapes from faces or wires 2 | Most of the following functions work both on faces and on wires. Lofting and the RotatedExtrude require wires. A wire can be retrieved from a face using the "GetWire" function (see below). 3 | 4 | === Extrude(face, direction, keepFace) 5 | An extrusion is created by pushing a deformable substance, such as molten metal or clay through a die or orifice with the desired cross-section. The result is a beam with this cross-section. In digital 3D modelling, extrusion is taking a face and extending it in a direction to form a solid shape. Normally the extrusion is performed in the normal direction, meaning perpendicular to the face. CascadeStudio uses a 3D vector [x,y,z] to determine the direction. 6 | 7 | 8 | [source,javascript] 9 | ---- 10 | // Extrude(face, direction, keepFace) 11 | Extrude(face, [20*(1-t), 0, 20]), 12 | ---- 13 | 14 | 15 | === RotatedExtrude(wire, height, rotation[deg], keepWire?) 16 | Extrudes a wire vertically with a specified height and twist. Note the difference from the standard extrude, in that this function requires a wire instead of a face. This can be accomplished by using the `.Wire()` method for a sketch instead of the `Face()`. Another thing to point out is that the rotation is performed relative to the [0,0] location of the vertical axis. Moreover, the extrusion is always vertical - so along the z-axis or [0,0,1] - and not along the normal of a wire. The boolean keepwire indicates whether the wire should be kept or may be removed. 17 | 18 | RotatedExtrude(wire, height, degrees, false) 19 | 20 | --- 21 | ._Difference of RotatedExtrude depending on position of wire relative to origin_ 22 | image::https://github.com/raydeleu/CascadeStudioManual/blob/main/images/rotated_extrude.png?raw=true[width=500] 23 | --- 24 | 25 | --- 26 | ._Difference of RotatedExtrude exagerated by using a larger twist_ 27 | image::https://github.com/raydeleu/CascadeStudioManual/blob/main/images/rotated_extrude2.png?raw=true[width=500] 28 | --- 29 | 30 | 31 | === Pipe(shape, wirePath, keepInputs) 32 | Sweeps a face along a Wire 33 | 34 | Pipe(face, BSpline([[0,0,0],[0,0,10],[13,-10,30]], false)), 35 | 36 | === Revolve 37 | Revolves Edges, Wires, and Faces about the specified Axis 38 | 39 | Rotate([1,0,0], 90, Revolve(Translate([10*t,8*t,0], GetWire(face)), -60, [0, 1, 0])), 40 | 41 | 42 | === Loft 43 | A loft is a modelling function that takes a number of planar wire-sections and interpolates between those. The wires act as the ribs of a construction and the lofting function is like stretching a shell around these ribs, just like the planking of a boat. The function Loft builds a solid through the sections defined by an array of 2 or more closed wires. 44 | 45 | [source,javascript] 46 | ---- 47 | // Loft(wires, keepWires) 48 | Loft([GetWire(face), Translate([0,0,20], Circle(8, true))]), 49 | ---- 50 | 51 | 52 | 53 | === GetWire(shape, faceIndex, keepOriginal) 54 | As some of the functions above require a wire, it may be useful to retrieve a wire from a face. This can be achieved with the function GetWire. The first parameter indicates the shape that contains a face, the second parameter contains the index of the required face and the boolean indicates whether the original shape should be kept (true) or deleted (false). The following code snippet shows an example for creating a rectangle by using the bottom face of a box (with face index 4) to retrieve the wire of a rectangle. Note that it is necessary to translate the wire to the correct location before using it as input to another function. 55 | 56 | [source, javascript] 57 | ---- 58 | let width = 25; 59 | let length = 50; 60 | let height = 10; 61 | 62 | let box1 = Box(width,length,height,true); 63 | let wire4 = Translate([0,0,height/2],GetWire(box1,4,false)) 64 | RotatedExtrude(wire4,50,90 ) 65 | ---- 66 | 67 | -------------------------------------------------------------------------------- /chapters/design_intent.adoc: -------------------------------------------------------------------------------- 1 | == Design principles 2 | 3 | 4 | 5 | At https://cadquery.readthedocs.io/en/latest/designprinciples.html there 6 | 7 | 8 | === Begin with the end in mind 9 | The sentence "Begin with the end in mind" is the second habit defined in "The seven habits of highly effective people". This habit should also apply to your 3D modelling. 10 | 11 | 12 | Design in CAD vs Blender - Daphne Laméris (see https://www.youtube.com/watch?v=aiq8vePQIeU). 13 | A vision of blender in automotive design - Odilon Loiez (see https://www.youtube.com/watch?v=tABQPqplco0) 14 | How to Photorealistic Visualize a Motorbike https://www.youtube.com/watch?v=rYGbZXPFmpA 15 | 16 | https://www.youtube.com/c/flowwiescorner/videos 17 | 18 | 19 | 20 | * definition of relations, clear measurements 21 | * lockability 22 | * 2D drawings and export 23 | * manufacturing features 24 | * derive bill of materials 25 | * interaction with analysis software such as structural analysis (Finite Element Methods, FEM). 26 | 27 | Free CAD tools 28 | * Fusion 360 29 | * OnShape 30 | * FreeCAD 31 | * SolidEdge Community Edition 32 | * BricsCAD Shape 33 | * OpenSCAD 34 | 35 | Not so expensive 36 | * Moi3D 37 | * Alibre Atom 38 | * Rhino3D 39 | 40 | Curves and organic shapes 41 | Manifold models 42 | 43 | 44 | 45 | 46 | 47 | 48 | === Design intent should drive definition 49 | 50 | 51 | Many scripting languages do not provide a way to capture design intent– because they require that you always work in global coordinates. CadQuery is different– you can locate features relative to others in a relative way– preserving the design intent just like a human would when creating a drawing or building an object. 52 | 53 | 54 | 55 | 56 | 57 | 58 | CAD models as source code makes sense 59 | 60 | - easy to capture design history 61 | - changes are always reversible (non-destructive workflow) 62 | - modelling hierarchy is obvious in the code 63 | - easy to communicate design decisions to others 64 | 65 | Import of existing parts should be possible 66 | - standard parts are often available in a library 67 | - interaction with existing CAD tools should be possible 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /chapters/hair_dryer/braun_like_hair_dryer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/hair_dryer/braun_like_hair_dryer.png -------------------------------------------------------------------------------- /chapters/hair_dryer/braun_like_hair_dryer_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/hair_dryer/braun_like_hair_dryer_2.png -------------------------------------------------------------------------------- /chapters/hair_dryer/braun_like_hair_dryer_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/hair_dryer/braun_like_hair_dryer_3.png -------------------------------------------------------------------------------- /chapters/hair_dryer/hair_dryer.js: -------------------------------------------------------------------------------- 1 | // Model of a hair dryer, loosely based on Braun model from 70' 2 | // ============================================================ 3 | 4 | // parameters 5 | let fanRadius = 30; 6 | let fanThickness = 30; 7 | let fanCutoutRadius = 20; 8 | let fanCutoutDepth = 5 ; 9 | let fanRounding = 10; 10 | let lidRadius = 19; 11 | let lidThickness = 3; 12 | let lidRounding = 2; 13 | 14 | // fanhousing 15 | let fanhousing = Cylinder(fanRadius,fanThickness) 16 | fanhousing = FilletEdges(fanhousing,fanRounding,[0,2],false); 17 | let cutout = Translate([0,0,fanThickness-fanCutoutDepth],Cylinder(fanCutoutRadius,fanCutoutDepth+10)); 18 | fanhousing = Difference(fanhousing,[cutout],false); 19 | let fanhousing_inner = Offset(fanhousing,-1.5,0.01,true); 20 | 21 | // lid on cutout /airintake 22 | // let lid = Translate([0,0,fanThickness-lidThickness],Cylinder(lidRadius,lidThickness)) 23 | // lid = FilletEdges(lid,lidRounding,[0]); 24 | 25 | // outlet 26 | let outlet = Translate([-2,0,6], Box(30,60,18) ) 27 | outlet = FilletEdges(outlet,5,[1,3,5,7]); 28 | let outlet_inner = Offset(outlet, -1.5, 0.01, true) 29 | outlet_in = Translate([0,3,0],outlet_inner) 30 | 31 | // handle 32 | let handle = Translate([0,-30,7],Box(-80,25,16)) 33 | handle = FilletEdges(handle,5,[11,10,9,8,]); 34 | button_cut = Translate([-50,-10,10],Box(10,20,10)) 35 | button_cut= FilletEdges(button_cut,2,[1,5,7,3]) 36 | 37 | // buttons 38 | let button = Translate([-49,-10,11],Box(3,6,8)) 39 | button = FilletEdges(button,1.4,[1,3,5,7]); 40 | button2 = Translate([5,0,0],button,true); 41 | handle = Difference(handle,[button_cut]); 42 | 43 | let handle_inner = Offset(handle,-1,0.01,true) 44 | 45 | // creating hollow shape 46 | let dryer_solid = Union([fanhousing,outlet,handle],false); 47 | // dryer_solid = RemoveInternalEdges(dryer_solid); 48 | dryer_solid = FilletEdges(dryer_solid,5,[49]); 49 | dryer_solid = FilletEdges(dryer_solid,2,[39]); 50 | dryer_solid = FilletEdges(dryer_solid,2,[70]); 51 | 52 | dryer_inner = Union([fanhousing_inner,outlet_in,handle_inner]) 53 | dryer_hollow = Difference(dryer_solid,[dryer_inner]) 54 | 55 | // vanes 56 | let vane = Translate([2,46,7.5],Box(1,15,15)) 57 | vane = ChamferEdges(vane,2,[10,11],false) 58 | let vanes = [] 59 | for (j=0;j<=3;j++) 60 | { 61 | vanes[j] = Translate([5*(j+1),0,0],vane,true) 62 | } 63 | 64 | // creating a cut-away 65 | cutter = Translate([-100,-75,15],Box(150,150,25)) 66 | cutaway = Difference(dryer_hollow,[cutter]); 67 | -------------------------------------------------------------------------------- /chapters/hair_dryer/hairdryer.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "stack", 44 | "width": 50, 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "activeItemIndex": 0, 49 | "content": [ 50 | { 51 | "type": "component", 52 | "componentName": "codeEditor", 53 | "title": "* hairdryer.json", 54 | "componentState": { 55 | "code": [ 56 | "let fanhousing = Cylinder(30,30)", 57 | "fanhousing = FilletEdges(fanhousing,10,[0,2],false);", 58 | "let cutout = Translate([0,0,25],Cylinder(20,30));", 59 | "fanhousing = Difference(fanhousing,[cutout],false);", 60 | "let fanhousing_inner = Offset(fanhousing,-1,0.01,true);", 61 | "", 62 | "let lid = Translate([0,0,27],Cylinder(19,3))", 63 | "lid = FilletEdges(lid,2,[0]);", 64 | "", 65 | "", 66 | "", 67 | "let outlet = Translate([0,0,5], Box(30,60,20) )", 68 | "outlet = FilletEdges(outlet,5,[1,3,5,7]);", 69 | "let outlet_inner = Offset(outlet, -1, 0.01, true)", 70 | "outlet_in = Translate([0,3,0],outlet_inner)", 71 | "", 72 | "let handle = Translate([0,-30,5],Box(-75,20,20))", 73 | "handle = FilletEdges(handle,5,[11,10,9,8,]);", 74 | "let handle_inner = Offset(handle,-1,0.01,true)", 75 | "", 76 | "let dryer_solid = Union([fanhousing,outlet,handle],false);", 77 | "dryer_solid = RemoveInternalEdges(dryer_solid);", 78 | "dryer_solid = FilletEdges(dryer_solid,5,[12]);", 79 | "dryer_solid = FilletEdges(dryer_solid,2,[4]);", 80 | "dryer_solid = FilletEdges(dryer_solid,2,[50]);", 81 | "", 82 | "dryer_inner = Union([fanhousing_inner,outlet_in,handle_inner])", 83 | "dryer_hollow = Difference(dryer_solid,[dryer_inner])", 84 | "dryer_hollow = FilletEdges(dryer_hollow,1,[35]);", 85 | "" 86 | ] 87 | }, 88 | "width": 50, 89 | "isClosable": false, 90 | "reorderEnabled": true 91 | } 92 | ] 93 | }, 94 | { 95 | "type": "column", 96 | "isClosable": true, 97 | "reorderEnabled": true, 98 | "title": "", 99 | "width": 50, 100 | "content": [ 101 | { 102 | "type": "stack", 103 | "height": 80, 104 | "isClosable": true, 105 | "reorderEnabled": true, 106 | "title": "", 107 | "activeItemIndex": 0, 108 | "content": [ 109 | { 110 | "type": "component", 111 | "componentName": "cascadeView", 112 | "title": "CAD View", 113 | "componentState": { 114 | "componentName": "cascadeView", 115 | "MeshRes": 0.1, 116 | "MeshResRange": [ 117 | 0.01, 118 | 2 119 | ], 120 | "Cache?": true, 121 | "Radius": 30, 122 | "RadiusRange": [ 123 | 20, 124 | 40 125 | ] 126 | }, 127 | "isClosable": false, 128 | "reorderEnabled": true 129 | } 130 | ] 131 | }, 132 | { 133 | "type": "stack", 134 | "height": 20, 135 | "isClosable": true, 136 | "reorderEnabled": true, 137 | "title": "", 138 | "activeItemIndex": 0, 139 | "content": [ 140 | { 141 | "type": "component", 142 | "componentName": "console", 143 | "title": "Console", 144 | "componentState": {}, 145 | "height": 20, 146 | "isClosable": false, 147 | "reorderEnabled": true 148 | } 149 | ] 150 | } 151 | ] 152 | } 153 | ] 154 | } 155 | ], 156 | "isClosable": true, 157 | "reorderEnabled": true, 158 | "title": "", 159 | "openPopouts": [], 160 | "maximisedItemId": null 161 | } -------------------------------------------------------------------------------- /chapters/hair_dryer/hollow_shape.adoc: -------------------------------------------------------------------------------- 1 | To do: decribe how to create a hollow shape 2 | -------------------------------------------------------------------------------- /chapters/hair_dryer/thinbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "stack", 44 | "width": 50, 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "activeItemIndex": 0, 49 | "content": [ 50 | { 51 | "type": "component", 52 | "componentName": "codeEditor", 53 | "title": "thinbox.json", 54 | "componentState": { 55 | "code": [ 56 | "// Welcome to Cascade Studio! Here are some useful functions:", 57 | "// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()", 58 | "// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()", 59 | "// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(), ", 60 | "// FilletEdges(), ChamferEdges(),", 61 | "// Slider(), Button(), Checkbox()", 62 | "", 63 | "let box = Box(30,40,30)", 64 | "let smallbox = Offset(box,-0.5,0.001,true)", 65 | "let smallbox2 = Translate([0,0,2.5],smallbox)", 66 | "let inner = Union([smallbox,smallbox2])", 67 | "let thin = Difference(box,[inner])", 68 | "", 69 | "let rounded = Offset(thin,1.2,0.001,false)", 70 | "let rounded1 = Offset(rounded,-0.95,0.01,false)", 71 | "" 72 | ] 73 | }, 74 | "width": 50, 75 | "isClosable": false, 76 | "reorderEnabled": true 77 | } 78 | ] 79 | }, 80 | { 81 | "type": "column", 82 | "isClosable": true, 83 | "reorderEnabled": true, 84 | "title": "", 85 | "width": 50, 86 | "content": [ 87 | { 88 | "type": "stack", 89 | "height": 80, 90 | "isClosable": true, 91 | "reorderEnabled": true, 92 | "title": "", 93 | "activeItemIndex": 0, 94 | "content": [ 95 | { 96 | "type": "component", 97 | "componentName": "cascadeView", 98 | "title": "CAD View", 99 | "componentState": { 100 | "componentName": "cascadeView", 101 | "MeshRes": 0.1, 102 | "MeshResRange": [ 103 | 0.01, 104 | 2 105 | ], 106 | "Cache?": true, 107 | "Radius": 30, 108 | "RadiusRange": [ 109 | 20, 110 | 40 111 | ] 112 | }, 113 | "isClosable": false, 114 | "reorderEnabled": true 115 | } 116 | ] 117 | }, 118 | { 119 | "type": "stack", 120 | "height": 20, 121 | "isClosable": true, 122 | "reorderEnabled": true, 123 | "title": "", 124 | "activeItemIndex": 0, 125 | "content": [ 126 | { 127 | "type": "component", 128 | "componentName": "console", 129 | "title": "Console", 130 | "componentState": {}, 131 | "height": 20, 132 | "isClosable": false, 133 | "reorderEnabled": true 134 | } 135 | ] 136 | } 137 | ] 138 | } 139 | ] 140 | } 141 | ], 142 | "isClosable": true, 143 | "reorderEnabled": true, 144 | "title": "", 145 | "openPopouts": [], 146 | "maximisedItemId": null 147 | } -------------------------------------------------------------------------------- /chapters/micke_cover/micke_cover.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/micke_cover/micke_cover.3mf -------------------------------------------------------------------------------- /chapters/micke_cover/micke_cover.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "column", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "width": 100, 42 | "content": [ 43 | { 44 | "type": "row", 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "height": 88.74629812438302, 49 | "content": [ 50 | { 51 | "type": "stack", 52 | "width": 66.4751958224543, 53 | "height": 60, 54 | "isClosable": true, 55 | "reorderEnabled": true, 56 | "title": "", 57 | "activeItemIndex": 0, 58 | "content": [ 59 | { 60 | "type": "component", 61 | "componentName": "cascadeView", 62 | "title": "CAD View", 63 | "componentState": { 64 | "componentName": "cascadeView", 65 | "MeshRes": 0.05, 66 | "MeshResRange": [ 67 | 0.01, 68 | 2 69 | ], 70 | "Cache?": false, 71 | "Radius": 30, 72 | "RadiusRange": [ 73 | 20, 74 | 40 75 | ] 76 | }, 77 | "isClosable": false, 78 | "reorderEnabled": true 79 | } 80 | ] 81 | }, 82 | { 83 | "type": "stack", 84 | "header": {}, 85 | "isClosable": true, 86 | "reorderEnabled": true, 87 | "title": "", 88 | "activeItemIndex": 0, 89 | "width": 33.5248041775457, 90 | "content": [ 91 | { 92 | "type": "component", 93 | "componentName": "codeEditor", 94 | "title": "micke_cover.json", 95 | "componentState": { 96 | "code": [ 97 | "// Base shape", 98 | "let outerRadius = 35;", 99 | "let baseHeight = 10;", 100 | "let baseShape = Cylinder(outerRadius, baseHeight,false);", 101 | "let baseRounded = FilletEdges(baseShape,1,[2]);", 102 | "", 103 | "// Lid shape", 104 | "let lidWidth = 10;", 105 | "let lidHeight = 3;", 106 | "let lidFillet = 1;", 107 | "let lid = Translate([0,0,baseHeight], Cylinder(outerRadius+lidWidth, lidHeight, false))", 108 | "let lidRounded = FilletEdges(lid, lidFillet,[0]);", 109 | "", 110 | "// hole through all", 111 | "let coverThickness = 1.5;", 112 | "let holeRadius = outerRadius - coverThickness;", 113 | "let hole = Cylinder(holeRadius, 40, true);", 114 | "", 115 | "// let construction = Union([baseRounded,lidRounded]);", 116 | "let construction = Difference(baseRounded, [hole], false);", 117 | "Union([construction,lidRounded]);", 118 | " ", 119 | "", 120 | "", 121 | "", 122 | "", 123 | "", 124 | "", 125 | "" 126 | ] 127 | }, 128 | "width": 50, 129 | "isClosable": false, 130 | "reorderEnabled": true 131 | } 132 | ] 133 | } 134 | ] 135 | }, 136 | { 137 | "type": "stack", 138 | "height": 11.253701875616983, 139 | "isClosable": true, 140 | "reorderEnabled": true, 141 | "title": "", 142 | "activeItemIndex": 0, 143 | "content": [ 144 | { 145 | "type": "component", 146 | "componentName": "console", 147 | "title": "Console", 148 | "componentState": {}, 149 | "height": 20, 150 | "isClosable": false, 151 | "reorderEnabled": true 152 | } 153 | ] 154 | } 155 | ] 156 | } 157 | ], 158 | "isClosable": true, 159 | "reorderEnabled": true, 160 | "title": "", 161 | "openPopouts": [], 162 | "maximisedItemId": null 163 | } -------------------------------------------------------------------------------- /chapters/micke_cover/micke_cover_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/micke_cover/micke_cover_3d.png -------------------------------------------------------------------------------- /chapters/micke_cover/prusa_add_modifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/micke_cover/prusa_add_modifier.png -------------------------------------------------------------------------------- /chapters/micke_cover/prusa_cover_sliced.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/micke_cover/prusa_cover_sliced.PNG -------------------------------------------------------------------------------- /chapters/micke_cover/prusa_import_stl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/micke_cover/prusa_import_stl.png -------------------------------------------------------------------------------- /chapters/micke_cover/prusa_modifier_set.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/micke_cover/prusa_modifier_set.pdn -------------------------------------------------------------------------------- /chapters/micke_cover/prusa_modifier_set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/micke_cover/prusa_modifier_set.png -------------------------------------------------------------------------------- /chapters/micke_cover/readme.adoc: -------------------------------------------------------------------------------- 1 | = Cover for the IKEA Micke desk. 2 | 3 | == Introduction 4 | This chapter describes an example to produce a cover for the IKEA Micke desk. 5 | 6 | == Create a model for a cover 7 | The 3D model for the cover of the cable opening can be produced easily with CascadeStudio. The cover consists of the base shape that fits into the opening and a cover or lid. 8 | 9 | [source,javascript] 10 | ---- 11 | // Base shape 12 | let outerRadius = 35; 13 | let baseHeight = 10; 14 | let baseShape = Cylinder(outerRadius, baseHeight,false); 15 | let baseRounded = FilletEdges(baseShape,1,[2]); 16 | 17 | // Lid shape 18 | let lidWidth = 10; 19 | let lidHeight = 3; 20 | let lidFillet = 1; 21 | let lid = Translate([0,0,baseHeight], Cylinder(outerRadius+lidWidth, lidHeight, false)) 22 | let lidRounded = FilletEdges(lid, lidFillet,[0]); 23 | 24 | // make the base hollow 25 | let baseThickness = 1.5; 26 | let holeRadius = outerRadius - baseThickness; 27 | let hole = Cylinder(holeRadius, 40, true); 28 | 29 | let hollowBase = Difference(baseRounded, [hole], false); 30 | Union([hollowBase,lidRounded]); 31 | ---- 32 | 33 | == Export the 3D model to STL-format 34 | When you are satisfied with the shape of the model, export it to STL-format. This can be achieved with the menu button on the top of the CascadeStudio window. Do not forget to save the project file (in json format) or the javascript file (exporting the contents of the editor window to a text editor) as well. If you want to modify the shape to account for inaccuracies of your printer, you will save time by re-using these files as a starting point. 35 | 36 | == Slice the model with PrusaSlicer 37 | Now import the STL file into you favourite slicer. I used PrusaSlicer as I wanted to modify the cover with a hexagonal grid instead of a fully closed surface. You can also model the hexagonal grid in CascadeStudio, but this involves a large number of boolean operations and therefore takes a lot of time. Using the PrusaSlicer modifiers the same effect can be achieved with almost no effort. 38 | 39 | After importing you will probably have to place the cover with the top flat surface on the print bed. 40 | 41 | To add a modifier to achieve the hexagonal grid pattern, add a modifier shape. Right click and select "Add Modifier". Choose a Cylinder shape. Then scale the cylinder so that it covers the middle part of the Micke cover. With the modifier selected, choose "Layers and Perimeters". Set the Bottom and Top layers to 0. In the "Print Settings" tab, choose infill and select "honeycomb". The infill density of 20% produces nice results. 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /chapters/three_arm/shaped_arms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/shaped_arms.png -------------------------------------------------------------------------------- /chapters/three_arm/shaped_arms_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/shaped_arms_2.png -------------------------------------------------------------------------------- /chapters/three_arm/single_arm_cutout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/single_arm_cutout.png -------------------------------------------------------------------------------- /chapters/three_arm/three-arm-var.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three-arm-var.png -------------------------------------------------------------------------------- /chapters/three_arm/three-arm-var.slvs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three-arm-var.slvs -------------------------------------------------------------------------------- /chapters/three_arm/three-arm-var2,slvs.slvs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three-arm-var2,slvs.slvs -------------------------------------------------------------------------------- /chapters/three_arm/three-arm-var2.slvs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three-arm-var2.slvs -------------------------------------------------------------------------------- /chapters/three_arm/three-arm-views.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three-arm-views.png -------------------------------------------------------------------------------- /chapters/three_arm/three-arm.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three-arm.pdn -------------------------------------------------------------------------------- /chapters/three_arm/three-arm2.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three-arm2.pdn -------------------------------------------------------------------------------- /chapters/three_arm/three-arm2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three-arm2.png -------------------------------------------------------------------------------- /chapters/three_arm/three_arm.adoc: -------------------------------------------------------------------------------- 1 | Creating a three armed lever 2 | -------------------------------------------------------------------------------- /chapters/three_arm/three_arm_cutter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three_arm_cutter.png -------------------------------------------------------------------------------- /chapters/three_arm/three_arms_complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three_arms_complete.png -------------------------------------------------------------------------------- /chapters/three_arm/three_arms_rough.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three_arms_rough.png -------------------------------------------------------------------------------- /chapters/three_arm/three_arms_union.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three_arms_union.png -------------------------------------------------------------------------------- /chapters/three_arm/three_arms_views_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/chapters/three_arm/three_arms_views_2.png -------------------------------------------------------------------------------- /images/OBJ_STL_export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/OBJ_STL_export.png -------------------------------------------------------------------------------- /images/antimony-nut-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/antimony-nut-2.png -------------------------------------------------------------------------------- /images/antimony-nut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/antimony-nut.png -------------------------------------------------------------------------------- /images/antimony-nut3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/antimony-nut3.png -------------------------------------------------------------------------------- /images/antimony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/antimony.png -------------------------------------------------------------------------------- /images/bezier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/bezier.png -------------------------------------------------------------------------------- /images/bezier.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/bezier.pptx -------------------------------------------------------------------------------- /images/bezier_test.slvs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/bezier_test.slvs -------------------------------------------------------------------------------- /images/blue_hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/blue_hi.png -------------------------------------------------------------------------------- /images/blurry_silver_hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/blurry_silver_hi.png -------------------------------------------------------------------------------- /images/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/button.png -------------------------------------------------------------------------------- /images/car_environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/car_environment.png -------------------------------------------------------------------------------- /images/ccs-arcto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/ccs-arcto.png -------------------------------------------------------------------------------- /images/ccs-car-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/ccs-car-v2.png -------------------------------------------------------------------------------- /images/ccs-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/ccs-intro.png -------------------------------------------------------------------------------- /images/ccs-pwa-installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/ccs-pwa-installed.png -------------------------------------------------------------------------------- /images/ccs_directory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/ccs_directory.png -------------------------------------------------------------------------------- /images/ccs_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/ccs_error.png -------------------------------------------------------------------------------- /images/change_design_intent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/change_design_intent.png -------------------------------------------------------------------------------- /images/change_design_intent1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/change_design_intent1.png -------------------------------------------------------------------------------- /images/change_design_intent2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/change_design_intent2.png -------------------------------------------------------------------------------- /images/changed_floor_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/changed_floor_background.png -------------------------------------------------------------------------------- /images/changed_interface_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/changed_interface_layout.png -------------------------------------------------------------------------------- /images/checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/checkbox.png -------------------------------------------------------------------------------- /images/chrome2_hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/chrome2_hi.png -------------------------------------------------------------------------------- /images/chrome_apps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/chrome_apps.png -------------------------------------------------------------------------------- /images/chrome_hi.png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/chrome_hi.png.png -------------------------------------------------------------------------------- /images/circle_hole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/circle_hole.png -------------------------------------------------------------------------------- /images/code_ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/code_ground.png -------------------------------------------------------------------------------- /images/command_palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/command_palette.png -------------------------------------------------------------------------------- /images/coordinates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/coordinates.png -------------------------------------------------------------------------------- /images/coordinates.png.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/coordinates.png.pdf -------------------------------------------------------------------------------- /images/cqeditor_interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/cqeditor_interface.png -------------------------------------------------------------------------------- /images/css-car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/css-car.png -------------------------------------------------------------------------------- /images/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/diagram.png -------------------------------------------------------------------------------- /images/dialog_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/dialog_all.png -------------------------------------------------------------------------------- /images/duller_grey_hi.png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/duller_grey_hi.png.png -------------------------------------------------------------------------------- /images/dxy.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/dxy.pdn -------------------------------------------------------------------------------- /images/dxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/dxy.png -------------------------------------------------------------------------------- /images/edge_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/edge_index.png -------------------------------------------------------------------------------- /images/error_F8_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/error_F8_1.png -------------------------------------------------------------------------------- /images/errors_F8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/errors_F8.png -------------------------------------------------------------------------------- /images/export_step_se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/export_step_se.png -------------------------------------------------------------------------------- /images/extrude5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/extrude5.png -------------------------------------------------------------------------------- /images/face_reverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/face_reverse.png -------------------------------------------------------------------------------- /images/fillets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/fillets.png -------------------------------------------------------------------------------- /images/fillets_and_arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/fillets_and_arc.png -------------------------------------------------------------------------------- /images/fillets_wa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/fillets_wa.png -------------------------------------------------------------------------------- /images/filletsquare.js: -------------------------------------------------------------------------------- 1 | function FilletRect(x,y,f,center) { 2 | if (center == false) 3 | { 4 | let p0 = [0,0]; 5 | let p1 = [x,0]; 6 | let p2 = [x,y]; 7 | let p3 = [0,y]; 8 | } 9 | else 10 | { 11 | let p0 = [-0.5*x,-0.5*y]; 12 | let p1 = [0.5*x, -0.5*y]; 13 | let p2 = [0.5*x, 0.5*y]; 14 | let p3 = [-0.5*x, 0.5*y]; 15 | } 16 | return new Sketch(p0) 17 | .LineTo(p1).Fillet(f) 18 | .LineTo(p2).Fillet(f) 19 | .LineTo(p3).Fillet(f) 20 | .End(true).Fillet(f) 21 | .Face(); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /images/first-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/first-example.png -------------------------------------------------------------------------------- /images/first_sphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/first_sphere.png -------------------------------------------------------------------------------- /images/fork_failed_filletedges.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/fork_failed_filletedges.pdn -------------------------------------------------------------------------------- /images/fork_failed_filletedges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/fork_failed_filletedges.png -------------------------------------------------------------------------------- /images/fork_half.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/fork_half.png -------------------------------------------------------------------------------- /images/forked_bracket_blender.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/forked_bracket_blender.png -------------------------------------------------------------------------------- /images/forked_bracket_joko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/forked_bracket_joko.png -------------------------------------------------------------------------------- /images/forked_bracket_se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/forked_bracket_se.png -------------------------------------------------------------------------------- /images/forked_bracket_se2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/forked_bracket_se2.png -------------------------------------------------------------------------------- /images/forked_lever_replicad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/forked_lever_replicad.png -------------------------------------------------------------------------------- /images/freecad_named_constraints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/freecad_named_constraints.png -------------------------------------------------------------------------------- /images/gears.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gears.png -------------------------------------------------------------------------------- /images/generative_design_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/generative_design_1.png -------------------------------------------------------------------------------- /images/gherkin_equation.js: -------------------------------------------------------------------------------- 1 | function equationGherkin(x) 2 | { 3 | let pt1 = x*x - 144*x + 5184; 4 | let pt2 = pt1 / 11664; 5 | let pt3 = 1-pt2; 6 | let pt4 = Math.sqrt(pt3); 7 | let y = 28.25 * pt4; 8 | return y 9 | } 10 | 11 | // evaluate the function starting a height h=0 12 | let h = 0; 13 | let c0 = [equationGherkin(h),h]; 14 | let calculatedGherkin = new Sketch(c0) 15 | 16 | for (let hi = 1; hi <= 180; hi+=4) 17 | { 18 | calculatedGherkin.LineTo( [ equationGherkin(hi) , hi]) 19 | 20 | } 21 | calculatedGherkin.LineTo([0,180]) 22 | calculatedGherkin.LineTo([0,0]) 23 | calculatedGherkin.LineTo(c0); 24 | calculatedGherkin.End(); 25 | // calculatedGherkin.Face(); 26 | 27 | // revolve the sketch 28 | Rotate( [1,0,0],90, 29 | Revolve(calculatedGherkin.Face() 30 | ,360,[0,1,0], true, true 31 | ) 32 | ) -------------------------------------------------------------------------------- /images/gherkin_loft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gherkin_loft.png -------------------------------------------------------------------------------- /images/gherkin_profile_correct.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "stack", 44 | "width": 50.163398692810446, 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "activeItemIndex": 0, 49 | "content": [ 50 | { 51 | "type": "component", 52 | "componentName": "codeEditor", 53 | "title": "gherkin_profile_correct.json", 54 | "componentState": { 55 | "code": [ 56 | "function equationGherkin(x) ", 57 | "{", 58 | " let pt1 = x*x - 144*x + 5184;", 59 | " let pt2 = pt1 / 11664;", 60 | " let pt3 = 1-pt2;", 61 | " let pt4 = Math.sqrt(pt3);", 62 | " let y = 28.25 * pt4;", 63 | " return y", 64 | "}", 65 | "", 66 | "// evaluate the function starting a height h=0", 67 | "let h = 0;", 68 | "let c0 = [equationGherkin(h),h];", 69 | "let calculatedGherkin = new Sketch(c0)", 70 | "", 71 | "for (let hi = 1; hi <= 180; hi+=4)", 72 | "{", 73 | " calculatedGherkin.LineTo( [ equationGherkin(hi) , hi])", 74 | "", 75 | "}", 76 | "calculatedGherkin.LineTo([0,180])", 77 | "calculatedGherkin.LineTo([0,0])", 78 | "calculatedGherkin.LineTo(c0);", 79 | "calculatedGherkin.End();", 80 | "// calculatedGherkin.Face();", 81 | "", 82 | "// revolve the sketch ", 83 | "Rotate( [1,0,0],90,", 84 | " Revolve(calculatedGherkin.Face()", 85 | " ,360,[0,1,0], true, true", 86 | " )", 87 | " )" 88 | ] 89 | }, 90 | "width": 50, 91 | "isClosable": false, 92 | "reorderEnabled": true 93 | } 94 | ] 95 | }, 96 | { 97 | "type": "column", 98 | "isClosable": true, 99 | "reorderEnabled": true, 100 | "title": "", 101 | "width": 49.83660130718954, 102 | "content": [ 103 | { 104 | "type": "stack", 105 | "height": 80, 106 | "isClosable": true, 107 | "reorderEnabled": true, 108 | "title": "", 109 | "activeItemIndex": 0, 110 | "content": [ 111 | { 112 | "type": "component", 113 | "componentName": "cascadeView", 114 | "title": "CAD View", 115 | "componentState": { 116 | "componentName": "cascadeView", 117 | "MeshRes": 0.1, 118 | "MeshResRange": [ 119 | 0.01, 120 | 2 121 | ], 122 | "Cache?": true, 123 | "Radius": 30, 124 | "RadiusRange": [ 125 | 20, 126 | 40 127 | ] 128 | }, 129 | "isClosable": false, 130 | "reorderEnabled": true 131 | } 132 | ] 133 | }, 134 | { 135 | "type": "stack", 136 | "height": 20, 137 | "isClosable": true, 138 | "reorderEnabled": true, 139 | "title": "", 140 | "activeItemIndex": 0, 141 | "content": [ 142 | { 143 | "type": "component", 144 | "componentName": "console", 145 | "title": "Console", 146 | "componentState": {}, 147 | "height": 20, 148 | "isClosable": false, 149 | "reorderEnabled": true 150 | } 151 | ] 152 | } 153 | ] 154 | } 155 | ] 156 | } 157 | ], 158 | "isClosable": true, 159 | "reorderEnabled": true, 160 | "title": "", 161 | "openPopouts": [], 162 | "maximisedItemId": null 163 | } -------------------------------------------------------------------------------- /images/gherkin_shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gherkin_shape.png -------------------------------------------------------------------------------- /images/gizmo-rotate-e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gizmo-rotate-e.png -------------------------------------------------------------------------------- /images/gizmo-scale-r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gizmo-scale-r.png -------------------------------------------------------------------------------- /images/gizmo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gizmo.png -------------------------------------------------------------------------------- /images/gizmo.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gizmo.pptx -------------------------------------------------------------------------------- /images/gizmo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gizmo1.png -------------------------------------------------------------------------------- /images/gizmo_translate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gizmo_translate.png -------------------------------------------------------------------------------- /images/gizno_rotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/gizno_rotate.png -------------------------------------------------------------------------------- /images/helix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/helix.png -------------------------------------------------------------------------------- /images/hollow_boxes.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/hollow_boxes.PNG -------------------------------------------------------------------------------- /images/honeycomb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/honeycomb.png -------------------------------------------------------------------------------- /images/honeycomb_experiments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/honeycomb_experiments.png -------------------------------------------------------------------------------- /images/house_drawing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/house_drawing.png -------------------------------------------------------------------------------- /images/ideation.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/ideation.blend -------------------------------------------------------------------------------- /images/ideation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/ideation.png -------------------------------------------------------------------------------- /images/image_list.txt: -------------------------------------------------------------------------------- 1 | This is a list of all images in this directory 2 | -------------------------------------------------------------------------------- /images/import_igs_se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/import_igs_se.png -------------------------------------------------------------------------------- /images/import_step.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/import_step.png -------------------------------------------------------------------------------- /images/import_step_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/import_step_0.png -------------------------------------------------------------------------------- /images/import_step_se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/import_step_se.png -------------------------------------------------------------------------------- /images/import_stl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/import_stl.png -------------------------------------------------------------------------------- /images/imported_fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/imported_fork.png -------------------------------------------------------------------------------- /images/install_app_dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/install_app_dialog.png -------------------------------------------------------------------------------- /images/install_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/install_button.png -------------------------------------------------------------------------------- /images/interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/interface.png -------------------------------------------------------------------------------- /images/jscad_interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/jscad_interface.png -------------------------------------------------------------------------------- /images/lever.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/lever.png -------------------------------------------------------------------------------- /images/loft3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/loft3.png -------------------------------------------------------------------------------- /images/makeface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/makeface.png -------------------------------------------------------------------------------- /images/matcap_change.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/matcap_change.png -------------------------------------------------------------------------------- /images/mesh-res.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/mesh-res.png -------------------------------------------------------------------------------- /images/mirror.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/mirror.png -------------------------------------------------------------------------------- /images/modelling_approaches1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/modelling_approaches1.png -------------------------------------------------------------------------------- /images/named_constraints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/named_constraints.png -------------------------------------------------------------------------------- /images/names_variables_freecad_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/names_variables_freecad_2.png -------------------------------------------------------------------------------- /images/nut.pptx.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/nut.pptx.pptx -------------------------------------------------------------------------------- /images/nut_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/nut_flow.png -------------------------------------------------------------------------------- /images/offset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/offset.png -------------------------------------------------------------------------------- /images/offset.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/offset.pptx -------------------------------------------------------------------------------- /images/openscad-car.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/openscad-car.jpg -------------------------------------------------------------------------------- /images/openscad_interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/openscad_interface.png -------------------------------------------------------------------------------- /images/pipe1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/pipe1.png -------------------------------------------------------------------------------- /images/pipe3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/pipe3.png -------------------------------------------------------------------------------- /images/pipe4.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/pipe4.pdn -------------------------------------------------------------------------------- /images/pipe4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/pipe4.png -------------------------------------------------------------------------------- /images/polar.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/polar.pdn -------------------------------------------------------------------------------- /images/polar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/polar.png -------------------------------------------------------------------------------- /images/polygon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/polygon.png -------------------------------------------------------------------------------- /images/radiusarc.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/radiusarc.pdn -------------------------------------------------------------------------------- /images/radiusarc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/radiusarc.png -------------------------------------------------------------------------------- /images/red_car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/red_car.png -------------------------------------------------------------------------------- /images/red_hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/red_hi.png -------------------------------------------------------------------------------- /images/revolve.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "column", 44 | "isClosable": true, 45 | "reorderEnabled": true, 46 | "title": "", 47 | "width": 50, 48 | "content": [ 49 | { 50 | "type": "stack", 51 | "header": {}, 52 | "isClosable": true, 53 | "reorderEnabled": true, 54 | "title": "", 55 | "activeItemIndex": 0, 56 | "height": 37.68115942028986, 57 | "content": [ 58 | { 59 | "type": "component", 60 | "componentName": "cascadeView", 61 | "title": "CAD View", 62 | "componentState": { 63 | "componentName": "cascadeView", 64 | "MeshRes": 0.1, 65 | "MeshResRange": [ 66 | 0.01, 67 | 2 68 | ], 69 | "Cache?": false, 70 | "Radius": 30, 71 | "RadiusRange": [ 72 | 20, 73 | 40 74 | ] 75 | }, 76 | "isClosable": false, 77 | "reorderEnabled": true 78 | } 79 | ] 80 | }, 81 | { 82 | "type": "stack", 83 | "width": 50, 84 | "height": 62.31884057971014, 85 | "isClosable": true, 86 | "reorderEnabled": true, 87 | "title": "", 88 | "activeItemIndex": 0, 89 | "content": [ 90 | { 91 | "type": "component", 92 | "componentName": "codeEditor", 93 | "title": "* revolve.json", 94 | "componentState": { 95 | "code": [ 96 | "let scribble = new Sketch([20*Math.cos(0),40*Math.sin(0)] )", 97 | "", 98 | "steps = 72;", 99 | "for (i = 2*Math.PI/steps ; i <= 2.0 * Math.PI; i+= 2*Math.PI/steps)", 100 | "{ ", 101 | " scribble.LineTo([20*Math.cos(i),40*Math.sin(i)])", 102 | "}", 103 | "scribble.End(false)", 104 | "", 105 | "let spinner = Revolve(scribble.Wire(),90,[0,1,0],true);", 106 | "let shroud = Revolve(Translate([100,0,0],scribble.Face(true)),90,[0,1,0],true)", 107 | "let cutter = Translate([0,-30,0],Box(300,50,300, true));", 108 | "", 109 | "Difference(shroud, [cutter])", 110 | "Difference(spinner, [cutter])", 111 | "", 112 | "", 113 | "", 114 | "", 115 | "" 116 | ] 117 | }, 118 | "width": 50, 119 | "isClosable": false, 120 | "reorderEnabled": true 121 | } 122 | ] 123 | } 124 | ] 125 | }, 126 | { 127 | "type": "stack", 128 | "width": 50, 129 | "height": 100, 130 | "isClosable": true, 131 | "reorderEnabled": true, 132 | "title": "", 133 | "activeItemIndex": 0, 134 | "content": [ 135 | { 136 | "type": "component", 137 | "componentName": "console", 138 | "title": "Console", 139 | "componentState": {}, 140 | "height": 20, 141 | "isClosable": false, 142 | "reorderEnabled": true 143 | } 144 | ] 145 | } 146 | ] 147 | } 148 | ], 149 | "isClosable": true, 150 | "reorderEnabled": true, 151 | "title": "", 152 | "openPopouts": [], 153 | "maximisedItemId": null 154 | } -------------------------------------------------------------------------------- /images/revolve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/revolve.png -------------------------------------------------------------------------------- /images/revolve2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/revolve2.png -------------------------------------------------------------------------------- /images/revolve3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/revolve3.png -------------------------------------------------------------------------------- /images/revolve5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/revolve5.png -------------------------------------------------------------------------------- /images/revolve6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/revolve6.png -------------------------------------------------------------------------------- /images/revolve_shapes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/revolve_shapes.png -------------------------------------------------------------------------------- /images/rotate_origin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/rotate_origin.png -------------------------------------------------------------------------------- /images/rotated_extrude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/rotated_extrude.png -------------------------------------------------------------------------------- /images/rotated_extrude2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/rotated_extrude2.png -------------------------------------------------------------------------------- /images/rounded_boxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/rounded_boxes.png -------------------------------------------------------------------------------- /images/sagarc.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/sagarc.pdn -------------------------------------------------------------------------------- /images/sagarc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/sagarc.png -------------------------------------------------------------------------------- /images/se_export_iges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/se_export_iges.png -------------------------------------------------------------------------------- /images/se_export_stl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/se_export_stl.png -------------------------------------------------------------------------------- /images/several_boxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/several_boxes.png -------------------------------------------------------------------------------- /images/shapes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/shapes.png -------------------------------------------------------------------------------- /images/shapes2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/shapes2.png -------------------------------------------------------------------------------- /images/shiny-red-hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/shiny-red-hi.png -------------------------------------------------------------------------------- /images/sketch_commands.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/sketch_commands.png -------------------------------------------------------------------------------- /images/sketch_iteration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/sketch_iteration.png -------------------------------------------------------------------------------- /images/sketch_to_shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/sketch_to_shape.png -------------------------------------------------------------------------------- /images/sketch_to_shape.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/sketch_to_shape.pptx -------------------------------------------------------------------------------- /images/slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/slider.png -------------------------------------------------------------------------------- /images/sliders_vacuum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/sliders_vacuum.png -------------------------------------------------------------------------------- /images/splie4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/splie4.png -------------------------------------------------------------------------------- /images/spline1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/spline1.png -------------------------------------------------------------------------------- /images/spline20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/spline20.png -------------------------------------------------------------------------------- /images/spline4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/spline4.png -------------------------------------------------------------------------------- /images/splinesketch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/splinesketch.png -------------------------------------------------------------------------------- /images/step_import_moi3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/step_import_moi3d.png -------------------------------------------------------------------------------- /images/structural_analysis.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/structural_analysis.jpg -------------------------------------------------------------------------------- /images/tailored_level.js: -------------------------------------------------------------------------------- 1 | // test 2 | function lever(r1, r2, d, h, t) 3 | { 4 | // This function creates a lever between two bearings, 5 | // the axles of the bearings are aligned 6 | 7 | // r1 = radius larger bearing 8 | // r2 = radois smaller bearing 9 | // d = distance between two bearings 10 | // h = height or width of the lever 11 | // t = wallthickness around bearing and cutout 12 | 13 | let sinus_a = (r1 - r2) / d ; 14 | let a = Math.asin(sinus_a); 15 | 16 | // points of outer contour of the lever 17 | let p1 = [r1 * Math.sin(a), r1 * Math.cos(a)]; 18 | let p2 = [d + r2 * Math.sin(a), r2 * Math.cos(a)]; 19 | let p3 = [d + r2, 0]; 20 | let p4 = [d + r2 * Math.sin(a), - r2 * Math.cos(a)]; 21 | let p5 = [r1 * Math.sin(a), - r1 * Math.cos(a)]; 22 | let p6 = [- r1, 0 ]; 23 | 24 | // points of cutout of the lever (not used as cutout became too small) 25 | let c1 = [(r1-t) * Math.sin(a), (r1-t) * Math.cos(a)]; 26 | let c2 = [d + (r2-t) * Math.sin(a), (r2-t) * Math.cos(a)]; ; 27 | let c3 = [d - r2 + t , 0]; 28 | let c4 = [d + (r2-t) * Math.sin(a), - (r2-t) * Math.cos(a)]; 29 | let c5 = [(r1-t) * Math.sin(a), - (r1-t) * Math.cos(a)]; 30 | let c6 = [r1-t,0]; 31 | 32 | let sketchLever = new Sketch(p1). 33 | LineTo(p2). 34 | ArcTo(p3,p4). 35 | LineTo(p5). 36 | ArcTo(p6,p1). 37 | End(false).Face(true); 38 | 39 | let leverbody = Extrude(sketchLever,[0,0,h]); 40 | 41 | let big_hole = Cylinder((r1-t), 2* (h + 10), true); 42 | let small_hole = Translate([d, 0,0 ], Cylinder((r2-t), 2* (h + 10), true)); 43 | let rough_lever = Difference(leverbody,[big_hole, small_hole]); 44 | 45 | let cutout = new Sketch(p1). 46 | LineTo(p2). 47 | ArcTo(c3,p4). 48 | LineTo(p5). 49 | ArcTo(c6,p1). 50 | End(false).Face(true); 51 | 52 | let cutoutbody = Extrude(cutout,[0,0,h+10]); 53 | let cutoutsmaller = Offset(cutoutbody, (-1.5 * t)); 54 | 55 | // ALTERNATIVE APPROACH FOR FILLETING 56 | // make shrunk version of cutout a bit smaller and then offset it again with 57 | // the filletradius 58 | let cutoutbigger = Offset(cutoutsmaller, (0.5 * t)); 59 | let cutoutround = cutoutbigger; 60 | let cutout_top = Translate([0,0,(h + t)/2],cutoutround); 61 | let cutout_bot = Translate([0,0,(-h - t)/2 -10],cutoutround); 62 | 63 | let rough_lever2 = Difference(rough_lever, [cutout_top, cutout_bot]); 64 | return rough_lever2; 65 | } 66 | 67 | 68 | function sideviewblock(r1, r2, d, h, t) 69 | { 70 | // r1 = radius larger bearing 71 | // r2 = radois smaller bearing 72 | // d = distance between two bearings 73 | // h = height or width of the lever 74 | // t = wallthickness around bearing and cutout 75 | 76 | let sideview = new Sketch( [-r1-1,0] ) 77 | .LineTo([-r1-1,0.5*h]) 78 | .LineTo([r1,0.5*h]) 79 | .LineTo([d-r2,(0.1*h)+(1.2*t)]) 80 | .LineTo([d+r2,(0.1*h)+(1.2*t)]) 81 | .LineTo([d+r2,(-0.1*h)-(1.2*t)]) 82 | .LineTo([d-r2,(-0.1*h)-(1.2*t)]) 83 | .LineTo([r1,-0.5*h]) 84 | .LineTo([-r1-1,-0.5*h]) 85 | .LineTo([-r1-1,0]) 86 | .End(false,false).Face(); 87 | 88 | let block = Extrude(sideview, [0,0,(2*r1)+(2*t)]); 89 | 90 | let side1 = Rotate([1,0,0],90,block); 91 | let side2 = Translate([0, r1+1,0.5*h],side1); 92 | 93 | return side2; 94 | } 95 | 96 | let sidecut = sideviewblock(30,10,100,40,2); 97 | let levershape = lever(30,10,100,40,2); 98 | Intersection([levershape,sidecut]); 99 | 100 | -------------------------------------------------------------------------------- /images/tailored_lever.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/tailored_lever.png -------------------------------------------------------------------------------- /images/textures/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/blue.png -------------------------------------------------------------------------------- /images/textures/blurry_silver_mirrorball.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/blurry_silver_mirrorball.jpg -------------------------------------------------------------------------------- /images/textures/chrome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/chrome.jpg -------------------------------------------------------------------------------- /images/textures/chrome_mirrorball.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/chrome_mirrorball.jpg -------------------------------------------------------------------------------- /images/textures/dullFrontLitMetal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/dullFrontLitMetal.png -------------------------------------------------------------------------------- /images/textures/grey_matcap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/grey_matcap.png -------------------------------------------------------------------------------- /images/textures/matcap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/matcap.png -------------------------------------------------------------------------------- /images/textures/readme.txt: -------------------------------------------------------------------------------- 1 | This directory contains some matcaps that can be used for CascadeStudio. It seems as if Cascade Studio can accept both PNG and JPG files. The default matcap has a size of 512x512 pixels 2 | -------------------------------------------------------------------------------- /images/textures/red_carpaint-matcap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/red_carpaint-matcap.jpg -------------------------------------------------------------------------------- /images/textures/reflective_red_mirrorball.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/reflective_red_mirrorball.jpg -------------------------------------------------------------------------------- /images/textures/white_dull_matcap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/white_dull_matcap.png -------------------------------------------------------------------------------- /images/textures/white_toon_matcap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/textures/white_toon_matcap.png -------------------------------------------------------------------------------- /images/torso_plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/torso_plan.png -------------------------------------------------------------------------------- /images/turning_torso_complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/turning_torso_complete.png -------------------------------------------------------------------------------- /images/turning_torso_sketch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/turning_torso_sketch.png -------------------------------------------------------------------------------- /images/uHook-01b-gamme-sergePayen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/uHook-01b-gamme-sergePayen.jpg -------------------------------------------------------------------------------- /images/uHook-03-shape-sergePayen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/uHook-03-shape-sergePayen.jpg -------------------------------------------------------------------------------- /images/uneven_chamfer.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "column", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "width": 100, 42 | "content": [ 43 | { 44 | "type": "stack", 45 | "height": 53.6036036036036, 46 | "isClosable": true, 47 | "reorderEnabled": true, 48 | "title": "", 49 | "activeItemIndex": 0, 50 | "content": [ 51 | { 52 | "type": "component", 53 | "componentName": "cascadeView", 54 | "title": "CAD View", 55 | "componentState": { 56 | "componentName": "cascadeView", 57 | "MeshRes": 0.1, 58 | "MeshResRange": [ 59 | 0.01, 60 | 2 61 | ], 62 | "Cache?": true, 63 | "Radius": 30, 64 | "RadiusRange": [ 65 | 20, 66 | 40 67 | ] 68 | }, 69 | "isClosable": false, 70 | "reorderEnabled": true 71 | } 72 | ] 73 | }, 74 | { 75 | "type": "stack", 76 | "header": {}, 77 | "isClosable": true, 78 | "reorderEnabled": true, 79 | "title": "", 80 | "activeItemIndex": 0, 81 | "height": 23.1981981981982, 82 | "content": [ 83 | { 84 | "type": "component", 85 | "componentName": "codeEditor", 86 | "title": "uneven_chamfer.json", 87 | "componentState": { 88 | "code": [ 89 | "function UnevenChamferEdges(shape, dist1, dist2, edgeList, face, keepOriginal) { ", 90 | " let curChamfer = CacheOp(arguments, () => {", 91 | " let mkChamfer = new oc.BRepFilletAPI_MakeChamfer(shape);", 92 | " let foundEdges = 0;", 93 | " ForEachEdge(shape, (index, edge) => {", 94 | " if (edgeList.includes(index)) { mkChamfer.Add(dist1, dist2, edge,face); foundEdges++; }", 95 | " });", 96 | " if (foundEdges == 0) {", 97 | " console.error(\"Chamfer Edges Not Found! Make sure you are looking at the object _before_ the Chamfer is applied!\");", 98 | " return new oc.TopoDS_Solid(shape);", 99 | " }", 100 | " return new oc.TopoDS_Solid(mkChamfer.Shape());", 101 | " });", 102 | " sceneShapes.push(curChamfer);", 103 | " if (!keepOriginal) { sceneShapes = Remove(sceneShapes, shape); }", 104 | " return curChamfer;", 105 | "}", 106 | "", 107 | "", 108 | "box1 = Box(20,20,20)", 109 | "box2 = UnevenChamferEdges(box1,1,3,[1,9,5,11],5, false)", 110 | "", 111 | "", 112 | "", 113 | "", 114 | "", 115 | "//Intersection([box2,box3])", 116 | "", 117 | "", 118 | "// box2= UnevenChamferEdges(box1,1,3,[10,3,8,7],4, false)" 119 | ] 120 | }, 121 | "width": 50, 122 | "isClosable": false, 123 | "reorderEnabled": true 124 | } 125 | ] 126 | }, 127 | { 128 | "type": "stack", 129 | "height": 23.1981981981982, 130 | "isClosable": true, 131 | "reorderEnabled": true, 132 | "title": "", 133 | "activeItemIndex": 0, 134 | "content": [ 135 | { 136 | "type": "component", 137 | "componentName": "console", 138 | "title": "Console", 139 | "componentState": {}, 140 | "height": 20, 141 | "isClosable": false, 142 | "reorderEnabled": true 143 | } 144 | ] 145 | } 146 | ] 147 | } 148 | ], 149 | "isClosable": true, 150 | "reorderEnabled": true, 151 | "title": "", 152 | "openPopouts": [], 153 | "maximisedItemId": null 154 | } -------------------------------------------------------------------------------- /images/unevenchamfer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/unevenchamfer.png -------------------------------------------------------------------------------- /images/vacuum_heads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/vacuum_heads.png -------------------------------------------------------------------------------- /images/vscode_command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/vscode_command.png -------------------------------------------------------------------------------- /images/vscode_extensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/vscode_extensions.png -------------------------------------------------------------------------------- /images/vscode_start_liveserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/vscode_start_liveserver.png -------------------------------------------------------------------------------- /images/web-cad-experiment.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": 3 | {"history":[{"type":"PLANE","params":{"orientation":"XY","depth":0}}],"expressions":""}, 4 | "sketches": [ 5 | {"id":"S:0/SURFACE", "data": {"layers":[{"name":"_dim","style":{"lineWidth":1,"strokeStyle":"#bcffc1","fillStyle":"#00FF00"},"readOnly":false,"data":[]},{"name":"__bounds__","style":{"lineWidth":2,"strokeStyle":"#fff5c3","fillStyle":"#000000"},"readOnly":true,"data":[]},{"name":"sketch","style":{"lineWidth":2,"strokeStyle":"#ffffff","fillStyle":"#000000"},"readOnly":false,"data":[{"id":6,"_class":"TCAD.TWO.Segment","role":null,"points":[[0,[1,-164.17868627034278],[2,-166.88882902124502]],[3,[4,-164.17868627034278],[5,260.4538509421469]]],"children":[6]},{"id":13,"_class":"TCAD.TWO.Segment","role":null,"points":[[7,[8,-164.17868627034278],[9,260.4538509421469]],[10,[11,273.03563190276435],[12,260.4538509421469]]],"children":[13]},{"id":20,"_class":"TCAD.TWO.Segment","role":null,"points":[[14,[15,273.03563190276435],[16,260.4538509421469]],[17,[18,273.03563190276435],[19,-166.88882902124502]]],"children":[20]},{"id":30,"_class":"TCAD.TWO.Arc","role":null,"points":[[21,[22,-164.17868627034278],[23,-166.88882902124502]],[24,[25,273.03563190276435],[26,-166.88882902124502]],[27,[28,54.42847282244034],[29,-146.313424843091]]],"children":[30]},{"id":38,"_class":"TCAD.TWO.Segment","role":"construction","points":[[32,[33,-164.17868627034278],[34,-166.88882902124502]],[35,[36,273.03563190276435],[37,-166.88882902124502]]],"children":[38]}]}],"constraints":[["coi",[7,3]],["coi",[24,17]],["coi",[21,0]],["Vertical",[20]],["Vertical",[6]],["Horizontal",[13]],["coi",[14,10]],["coi",[32,0]],["coi",[35,17]],["Horizontal",[38]]]}} 6 | ,{"id":"S:2/F:6", "data": {"boundary":{"lines":[{"a":{"x":154.178686,"y":260.453851},"b":{"x":-263.035632,"y":260.453851}},{"a":{"x":-263.035632,"y":260.453851},"b":{"x":-263.035632,"y":-166.888829}},{"a":{"x":154.178686,"y":-166.888829},"b":{"x":154.178686,"y":260.453851}}],"arcs":[{"a":{"x":-263.079633,"y":-165.951766},"b":{"x":154.222687,"y":-165.951766},"c":{"x":-54.42847300000028,"y":-146.313425444811}}],"circles":[],"nurbses":[]}}} 7 | ] 8 | } -------------------------------------------------------------------------------- /images/white_hi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/images/white_hi.png -------------------------------------------------------------------------------- /parts/airbudHolder.js: -------------------------------------------------------------------------------- 1 | function FilletRect(x,y,f,center) { 2 | let p0; 3 | let p1; 4 | let p2; 5 | let p3; 6 | if (center == false) 7 | { 8 | p0 = [0,0]; 9 | p1 = [x,0]; 10 | p2 = [x,y]; 11 | p3 = [0,y]; 12 | } 13 | else 14 | { 15 | p0 = [-0.5*x,-0.5*y]; 16 | p1 = [0.5*x, -0.5*y]; 17 | p2 = [0.5*x, 0.5*y]; 18 | p3 = [-0.5*x, 0.5*y]; 19 | } 20 | return new Sketch(p0) 21 | .LineTo(p1).Fillet(f) 22 | .LineTo(p2).Fillet(f) 23 | .LineTo(p3).Fillet(f) 24 | .End(true).Fillet(f) 25 | .Face(); 26 | } 27 | 28 | // Draw ear hook right 29 | let hookPathR = []; 30 | hookPathR[0] = [0,0,0] 31 | hookPathR[1] = [20,10,0] 32 | hookPathR[2] = [28,25,0] 33 | hookPathR[3] = [10,42,0] 34 | hookPathR[4] = [-12,32,0] 35 | hookPathR[5] = [-20,35,0] 36 | 37 | // draw ear hook left 38 | let hookPathL = []; 39 | hookPathL[0] = [0,0,0] 40 | hookPathL[1] = [-20,10,0] 41 | hookPathL[2] = [-28,25,0] 42 | hookPathL[3] = [-10,42,0] 43 | hookPathL[4] = [12,32,0] 44 | hookPathL[5] = [20,35,0] 45 | 46 | // profile of the earhook, 47 | let hookHeight = 3; // thickness of hook 48 | let hookWidth = 3; // width of hook, thinner make it more bendy, larger than 4 fails 49 | let hookRadius =1; // rounding of the hook around the ear to make it more comfortable 50 | 51 | // prepare some variables so you can build right and left hook at same time 52 | let path; 53 | let versions = ["left","right"] 54 | let version; 55 | 56 | for (version in versions) 57 | { 58 | console.log(version) 59 | // version right = 1, left = 0 60 | 61 | let face = Rotate([1,0,0],90,FilletRect(hookWidth,hookHeight,hookRadius),true); 62 | 63 | if (version == 0) 64 | { 65 | path = BSpline(hookPathL); 66 | } 67 | else 68 | { 69 | path = BSpline(hookPathR); 70 | } 71 | 72 | let pipe = Pipe(face,path,false); 73 | 74 | 75 | pipe = Translate([0,0,0.5],pipe); 76 | 77 | // Draw stem of airbud to subtract from other shape 78 | let abWidth = 3 79 | let abHeight = 20 80 | let abLength = 2.5 81 | 82 | let airbudStem = Box(abWidth,abHeight,abLength) 83 | airbudStem = FilletEdges(airbudStem,0.95,[1,3,5,7],false); 84 | airbudStem = Translate([-abWidth/2,-abHeight/2,hookHeight/2-0.2],airbudStem); 85 | let slit = Translate([0,0,5],Box(1.5,20,5,true)) 86 | slit = Union([airbudStem,slit]) 87 | // slit = RemoveInternalEdges(slit) 88 | 89 | 90 | let holderWidth = 7; 91 | let holderLength = 6; 92 | let holderHeight = 12; 93 | let stemHolder = Box(holderWidth,holderHeight,holderLength,true); 94 | stemHolder = Translate([0,0,holderLength/2-hookHeight/2],stemHolder,false) 95 | airbudHook = Union([pipe,stemHolder]) 96 | 97 | airbudHook = Difference(airbudHook,[slit]); 98 | 99 | // right 100 | // 101 | 102 | if (version == 0) 103 | { 104 | airbudHook = FilletEdges(airbudHook,2,[56,16]); 105 | } 106 | else 107 | { 108 | airbudHook = FilletEdges(airbudHook,2,[16,65]); 109 | airbudHook = Translate([50,0,0],airbudHook); 110 | } 111 | 112 | let flatCutter = Translate([0,0,-5],Box(200,100,10,true)); 113 | airbudHook = Difference(airbudHook,[flatCutter]) 114 | 115 | } 116 | -------------------------------------------------------------------------------- /parts/bezier-spline.js: -------------------------------------------------------------------------------- 1 | // preview bezier vs spline curves 2 | 3 | // points 4 | 5 | let p0 = [0,0] 6 | let p1 = [0,15] 7 | let p2 = [10,50] 8 | let p3 = [20,5] 9 | let p4 = [30,30] 10 | let p5 = [40,40] 11 | let p6 = [50,35] 12 | let p7 = [60,40] 13 | let p8 = [70,20] 14 | let p9 = [70,0] 15 | 16 | bezierSpline = new Sketch(p0) 17 | .BezierTo(p1,p2,p3,p4,p5,p6,p7,p8) 18 | .LineTo(p9) 19 | .LineTo(p0) 20 | .End() 21 | .Face() 22 | 23 | Extrude([0,20,0], bezierSpline) 24 | 25 | -------------------------------------------------------------------------------- /parts/booleans.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "column", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "width": 100, 42 | "content": [ 43 | { 44 | "type": "stack", 45 | "height": 65.01501501501501, 46 | "isClosable": true, 47 | "reorderEnabled": true, 48 | "title": "", 49 | "activeItemIndex": 0, 50 | "content": [ 51 | { 52 | "type": "component", 53 | "componentName": "cascadeView", 54 | "title": "CAD View", 55 | "componentState": { 56 | "componentName": "cascadeView", 57 | "MeshRes": 0.1, 58 | "MeshResRange": [ 59 | 0.01, 60 | 2 61 | ], 62 | "Cache?": false, 63 | "Radius": 30, 64 | "RadiusRange": [ 65 | 20, 66 | 40 67 | ] 68 | }, 69 | "isClosable": false, 70 | "reorderEnabled": true 71 | } 72 | ] 73 | }, 74 | { 75 | "type": "stack", 76 | "height": 34.98498498498499, 77 | "isClosable": true, 78 | "reorderEnabled": true, 79 | "title": "", 80 | "activeItemIndex": 1, 81 | "content": [ 82 | { 83 | "type": "component", 84 | "componentName": "console", 85 | "title": "Console", 86 | "componentState": {}, 87 | "height": 20, 88 | "isClosable": false, 89 | "reorderEnabled": true 90 | }, 91 | { 92 | "type": "component", 93 | "componentName": "codeEditor", 94 | "title": "* booleans.json", 95 | "componentState": { 96 | "code": [ 97 | "// Examples of solid shapes", 98 | "let hingeBlock = Box(20,50,20, false)", 99 | "let hingePlate = Box(60,55,5, false)", 100 | "let hingeBody = Union([hingeBlock, hingePlate], false)", 101 | "", 102 | "// let hingeRounding = Translate([10,60,20],Rotate([1,0,0],90,Cylinder(10,60,false)))", 103 | "// let hingeBodyRound = Union([hingeBody, hingeRounding], false) ", 104 | "", 105 | "// let roundedBox = Translate([-5,10,-5],Offset(Box(55,30,40,false),5))", 106 | "// let finalShape = Intersection([hingeBodyRound,roundedBox])", 107 | "// let hingeBore = Translate([10,60,20],Rotate([1,0,0],90,Cylinder(7,70,false)))", 108 | "", 109 | "", 110 | "", 111 | "", 112 | "", 113 | "// let finalShapeHole = Difference(finalShape, [hingeBore])", 114 | "// FilletEdges(finalShapeHole,5,[17],false)", 115 | "" 116 | ] 117 | }, 118 | "width": 50, 119 | "isClosable": false, 120 | "reorderEnabled": true 121 | } 122 | ] 123 | } 124 | ] 125 | } 126 | ], 127 | "isClosable": true, 128 | "reorderEnabled": true, 129 | "title": "", 130 | "openPopouts": [], 131 | "maximisedItemId": null 132 | } -------------------------------------------------------------------------------- /parts/car.js: -------------------------------------------------------------------------------- 1 | // Define car design variables 2 | let car_length = 50; 3 | let car_width = 20; 4 | let overhang_front = 8; 5 | let overhang_rear = 9; 6 | let cabin_width = 16; 7 | let cabin_length = 25; // 33 = station, 25=sedan, 15=pickup 8 | let car_height = 14; 9 | let bonnet_height = 8; 10 | let bonnet_rounding = 4; 11 | let bonnet_length = 15; 12 | let wheel_radius = 5; 13 | let tire_width = 3; 14 | let tire_protrude = 1; 15 | let rim_height = 1; 16 | let tire_compression= 1; 17 | let road_clearance = 3; 18 | 19 | // Derived properties 20 | let wheel_base = car_length - overhang_front - overhang_rear; 21 | let cabin_narrowing = (car_width - cabin_width)/2; 22 | let cabin_base = road_clearance + bonnet_height 23 | let cabin_height = car_height-bonnet_height 24 | 25 | // Draw car body and passenger cabin 26 | let car_body = Translate([0,0,road_clearance],Box(car_length,car_width,bonnet_height)) 27 | let car_cabin = Translate([bonnet_length,cabin_narrowing,cabin_base-0.5], 28 | Box(cabin_length, cabin_width, cabin_height)) 29 | 30 | // Sculpt the car body more aerodynamically 31 | let car_body_rounded = FilletEdges(car_body,bonnet_rounding,[1,5]) 32 | let cabin_aero = ChamferEdges(car_cabin, cabin_height-0.5 , [1,5]) 33 | 34 | // Round all edges 35 | let cabin_rounded = Offset(cabin_aero,1.5); 36 | let car_shrunk = Offset(car_body_rounded,-1); 37 | let car_rounded = Offset(car_shrunk,2); 38 | 39 | // Define wheels and wheel wells (Front/Rear - Left/Right) 40 | let rim = Rotate([1,0,0],-90, Translate( 41 | [overhang_front, 42 | -(wheel_radius-tire_compression), 43 | -(tire_width - tire_protrude)] 44 | , Cylinder(wheel_radius-rim_height,tire_width,true))) 45 | let wheel = Rotate([1,0,0],-90, Translate( [overhang_front, 46 | -(wheel_radius-tire_compression), 47 | (0.5*tire_protrude)], 48 | Cylinder(wheel_radius,tire_width,true))); 49 | let wheel_FL = Difference(wheel,[rim]); 50 | let wheel_well_FL = Offset(wheel,0.8,0.01,true) 51 | let wheel_RL = Translate([wheel_base,0,0], wheel_FL, true) 52 | let wheel_well_RL = Translate([wheel_base,0,0], wheel_well_FL, true) 53 | let wheel_FR = Rotate([0,0,1],180,Translate([-(2*overhang_front),-car_width ,0], wheel_FL, true)) 54 | let wheel_well_FR = Translate([0,car_width-1,0], wheel_well_FL, true) 55 | let wheel_RR = Translate([wheel_base,0,0], wheel_FR, true) 56 | let wheel_well_RR = Translate([wheel_base,0,0], wheel_well_FR, true) 57 | 58 | // Subtract the wheel wells from the car-body 59 | Difference(car_rounded,[wheel_well_FL, 60 | wheel_well_RL, 61 | wheel_well_FR, 62 | wheel_well_RR]) 63 | -------------------------------------------------------------------------------- /parts/drawboard.json: -------------------------------------------------------------------------------- 1 | let clearance = 1; 2 | let partClearance = 5; 3 | let baseLen = 25; 4 | let units = 8; 5 | let dWid = baseLen / 2.414; 6 | let bezelInset = 3; 7 | let boardWidth = units * baseLen + 2 * bezelInset; 8 | 9 | let bezelWidth = 14; 10 | let bezelHeight = 12; 11 | let bezelLength = boardWidth + 2 * bezelWidth - 2 * bezelInset; 12 | let bezelInsetOffset = 2; 13 | 14 | let boardHeight = 3; 15 | let pegHeight = 6; 16 | let pegOffset = pegHeight / 2 + boardHeight; 17 | let pawnHeight = pegHeight + 4; 18 | 19 | let pawnsPerSide = 14; 20 | 21 | let assembled = Checkbox("Assembled", false); 22 | let darkPieces = Checkbox("Dark pieces", false); 23 | 24 | function pawn() { 25 | let pawnLeg = baseLen - clearance; 26 | let basePawn = Box(pawnLeg, pawnLeg, pawnHeight, true); 27 | return Intersection([ 28 | basePawn, 29 | Rotate([0, 0, 1], 45, basePawn) 30 | ]); 31 | } 32 | 33 | function peg() { 34 | let pegLeg = dWid - clearance; 35 | return Rotate([0, 0, 1], 45, Box(pegLeg, pegLeg, pegHeight+0.2, true)); 36 | } 37 | 38 | function baseBoard() { 39 | let board = [Translate([0, 0, boardHeight / 2], Box(boardWidth, boardWidth, boardHeight, true))]; 40 | for (let x = 1; x < units; x++) { 41 | let xOffset = (x - units / 2) * baseLen; 42 | for (let y = 1; y < units; y++) { 43 | let yOffset = (y - units / 2) * baseLen; 44 | board.push(Translate([xOffset, yOffset, pegOffset-0.1], peg())); 45 | } 46 | } 47 | return Union(board); 48 | } 49 | 50 | function bezel() { 51 | return Translate([0, 0, bezelWidth / 2], 52 | FilletEdges( 53 | Difference( 54 | ChamferEdges(Box(bezelLength, bezelHeight, bezelWidth, true), bezelWidth - 0.01, [1, 5]), 55 | [Translate([0, boardHeight-bezelHeight/2, bezelWidth / 2 - bezelInset / 2], Box(bezelLength, boardHeight, bezelInset, true))] 56 | ), 57 | 1.5, [15, 19] 58 | ) 59 | ); 60 | } 61 | 62 | function bezelSet() { 63 | return Rotate([0, 0, 1], 90, Union([ 64 | Translate([0, -(bezelHeight / 2 + partClearance/2), 0], bezel()), 65 | Translate([0, bezelHeight / 2 + partClearance/2, 0], bezel()) 66 | ])); 67 | } 68 | 69 | function pawnSet() { 70 | let pawns = []; 71 | for (let y = 0; y < pawnsPerSide/2; y++) { 72 | pawns.push(Translate([0, boardWidth/2 - baseLen/2 - y * (baseLen + partClearance), 0], pawn())); 73 | pawns.push(Translate([baseLen + partClearance, boardWidth/2 - baseLen/2 -y * (baseLen + partClearance), 0], pawn())); 74 | } 75 | return Union(pawns); 76 | } 77 | 78 | if (assembled) { 79 | Translate([0, 0, bezelInsetOffset], baseBoard()); 80 | let b = Translate([0, boardWidth/2 + bezelWidth - bezelInset, bezelHeight/2], Rotate([1, 0, 0], 90, bezel())); 81 | for (let n=0; n < 4; n++) { 82 | b = Rotate([0, 0, 1], 90, b, true); 83 | } 84 | for (let x=0; x < units; x++) { 85 | for (let y=0; y < units; y++) { 86 | // show that every position could be filled with one of the 28 actual pawns 87 | Translate([-baseLen*units/2 + baseLen/2 + baseLen*x, -baseLen*units/2 + baseLen/2 + baseLen*y, bezelInsetOffset+boardHeight], pawn()); 88 | } 89 | } 90 | } else if (darkPieces) { 91 | Translate([baseLen/2 + partClearance, 0, 0], pawnSet()); 92 | Translate([-(bezelWidth + partClearance), 0, 0], bezelSet()); 93 | } else { 94 | baseBoard(); 95 | Translate([boardWidth/2 + baseLen/2 + partClearance, 0, 0], pawnSet()); 96 | Translate([-(boardWidth/2 + bezelWidth + partClearance), 0, 0], bezelSet()); 97 | } -------------------------------------------------------------------------------- /parts/extrude.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "stack", 44 | "width": 50, 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "activeItemIndex": 0, 49 | "content": [ 50 | { 51 | "type": "component", 52 | "componentName": "codeEditor", 53 | "title": "* Untitled", 54 | "componentState": { 55 | "code": [ 56 | "let circle1 = Circle(5)", 57 | "let circle2 = Translate([30,0,0],Circle(5))", 58 | "let circle3 = Circle(5)", 59 | "", 60 | "", 61 | "Extrude(circle1,[0,0,20])", 62 | "Extrude(circle2,[5,5 ,20])", 63 | "Extrude(Rotate([0,1,0],90, circle3),[50,0,0])", 64 | "" 65 | ] 66 | }, 67 | "width": 50, 68 | "isClosable": false, 69 | "reorderEnabled": true 70 | } 71 | ] 72 | }, 73 | { 74 | "type": "column", 75 | "isClosable": true, 76 | "reorderEnabled": true, 77 | "title": "", 78 | "width": 50, 79 | "content": [ 80 | { 81 | "type": "stack", 82 | "height": 80, 83 | "isClosable": true, 84 | "reorderEnabled": true, 85 | "title": "", 86 | "activeItemIndex": 0, 87 | "content": [ 88 | { 89 | "type": "component", 90 | "componentName": "cascadeView", 91 | "title": "CAD View", 92 | "componentState": { 93 | "componentName": "cascadeView", 94 | "MeshRes": 0.1, 95 | "MeshResRange": [ 96 | 0.01, 97 | 2 98 | ], 99 | "Cache?": true, 100 | "Radius": 30, 101 | "RadiusRange": [ 102 | 20, 103 | 40 104 | ] 105 | }, 106 | "isClosable": false, 107 | "reorderEnabled": true 108 | } 109 | ] 110 | }, 111 | { 112 | "type": "stack", 113 | "height": 20, 114 | "isClosable": true, 115 | "reorderEnabled": true, 116 | "title": "", 117 | "activeItemIndex": 0, 118 | "content": [ 119 | { 120 | "type": "component", 121 | "componentName": "console", 122 | "title": "Console", 123 | "componentState": {}, 124 | "height": 20, 125 | "isClosable": false, 126 | "reorderEnabled": true 127 | } 128 | ] 129 | } 130 | ] 131 | } 132 | ] 133 | } 134 | ], 135 | "isClosable": true, 136 | "reorderEnabled": true, 137 | "title": "", 138 | "openPopouts": [], 139 | "maximisedItemId": null 140 | } -------------------------------------------------------------------------------- /parts/feltHolder.js: -------------------------------------------------------------------------------- 1 | // holder for felt on chair 2 | 3 | let innerDiameter = 14 ; // thickness of pipe of the furniture 4 | let thickness = 1.5 ; // 5 | let outerLength = 30; // length of holder 6 | let delta = 4; // extra length to avoid overlapping edges in booleans 7 | let nippleDiameter = 2.5; // nipple to hold holder in place 8 | let nippleHeight = 3; // diameter of nipple 9 | let extraHeight = 1 ; // extra height above thickness on underside 10 | let extraWidth = 2; // extra width of holder 11 | let gliderRadius = 1; // 12 | let innerLength = outerLength + delta; 13 | 14 | 15 | 16 | let innerRadius = innerDiameter/2; 17 | let outerRadius = innerRadius + thickness; 18 | 19 | let innerCylinder = Translate([0,0,extraHeight+outerRadius],Rotate([0,1,0],90,Cylinder(innerRadius,innerLength,true))); 20 | let outerCylinder = Translate([0,0,extraHeight+outerRadius],Rotate([0,1,0],90,Cylinder(outerRadius,outerLength,true))); 21 | let gliderBox = Box(2*outerRadius+extraHeight,2*outerRadius+extraWidth,outerLength,true); 22 | let outerBox = Translate([0,0,outerRadius],Rotate([0,1,0],90,gliderBox)); 23 | let cutBox = Box(2*outerRadius , 2*outerRadius+delta, innerLength, true); 24 | 25 | let nipple = Cylinder(nippleDiameter/2, extraHeight + thickness + nippleHeight); 26 | nipple = FilletEdges(nipple,nippleDiameter/2,[0],false); 27 | 28 | 29 | cutBox = Rotate([0,1,0],90,cutBox); 30 | cutBox = Translate([0,0,2*outerRadius+delta+extraHeight],cutBox); 31 | 32 | let glider = Union([outerBox,outerCylinder],false); 33 | glider = Difference(glider,[innerCylinder],false); 34 | glider = Difference(glider,[cutBox],false); 35 | glider = FilletEdges(glider,gliderRadius,[0,1,2,3,4,5,6,7,9,10,12,13,14,15,16,17],false); 36 | glider = Union([glider,nipple]); 37 | 38 | -------------------------------------------------------------------------------- /parts/forked_lever_cs.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/parts/forked_lever_cs.pdn -------------------------------------------------------------------------------- /parts/forked_lever_cs_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/parts/forked_lever_cs_30.png -------------------------------------------------------------------------------- /parts/forked_lever_cs_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/parts/forked_lever_cs_50.png -------------------------------------------------------------------------------- /parts/forked_lever_cs_var.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/parts/forked_lever_cs_var.png -------------------------------------------------------------------------------- /parts/furniture.json.txt: -------------------------------------------------------------------------------- 1 | function Rectangle(l, h, center = false){ 2 | let S = new Sketch([0, 0]). 3 | LineTo([l, 0]). 4 | LineTo([l, h]). 5 | LineTo([0, h]). 6 | LineTo([0, 0]). 7 | End().Face(); 8 | 9 | if(center)S = Translate([-l/2, -h/2,0], S); 10 | return S; 11 | } 12 | function tr(l, h, x, y, z) { 13 | return Translate([x, y, z], Rectangle(l, h, false)); 14 | } 15 | 16 | let Base = Extrude( 17 | Union([ 18 | tr( 8, 2, 0, -2, 0), 19 | tr( 8,48, 0, 0, 0), 20 | tr(32,24, 8, 0, 0 ), 21 | tr( 8, 2, 40, -2, 0), 22 | tr( 8,48, 40, 0, 0) 23 | ]), 24 | [0, 0, 36] 25 | ); 26 | 27 | let Fond = Translate([8,24,0], Box(32,24,4)); 28 | let M = Rotate([1,0,0], 90, Union([Base, Fond])); 29 | 30 | let th1 = []; // tranches H 31 | let thBase = Translate([-100,0,-100], Box(200,1,200)); 32 | for(let i of [-36, -24,-16, -2]){ th1.push(Intersection([M, Translate([0,i,0], thBase)])); } 33 | 34 | let tv1 = []; // tranches V 35 | let tvBase = Translate([0,-100,-100], Box(1,200, 200)); 36 | for(let i of [0,7,16,24,33,40,47]){ tv1.push(Intersection([M, Translate([i,0,0], tvBase)])); } 37 | 38 | let ihv = []; // Intersections H et V 39 | for(let i = 0; i < th1.length; i++){ 40 | for(j = 0; j < tv1.length; j++){ 41 | ihv.push(Intersection([th1[i], tv1[j]])); 42 | } 43 | } 44 | 45 | for(let i = 0; i< tv1.length; i++){ Translate([-60, 0, 0], tv1[i]); } 46 | for(let i = 0; i< th1.length; i++){ Translate([0, 60, 0], th1[i]); } 47 | Translate([-60, 60, 0], M); 48 | 49 | -------------------------------------------------------------------------------- /parts/gear.js: -------------------------------------------------------------------------------- 1 | // Example file to create a gear wheel, 2 | // author is Frank Noirot, code taken from CADhub 3 | 4 | function Gear( 5 | numTeeth = 23, 6 | outerRadius = 15, 7 | pitchRadius = 14, 8 | pitchAngle = 20, 9 | insetRadius = 13, 10 | innerRadius = 6, 11 | toothCap = 1.5) { 12 | const startPoint = [0, 0] 13 | const degreesToRadians = radians => Math.PI / 180 * radians 14 | const polarToCartesian = (r, theta) => ([Math.cos(theta) * r, Math.sin(theta) * r]) 15 | let sketch 16 | 17 | for (let i = 0; i <= 360; i += 360 / numTeeth) { 18 | const offsetTheta = Math.atan(toothCap/2 / outerRadius) 19 | const offsetRadius = Math.sqrt(Math.pow(outerRadius, 2) + Math.pow(toothCap, 2)) 20 | const point1 = (f = 1) => polarToCartesian(offsetRadius, degreesToRadians(i) + f * offsetTheta) 21 | 22 | const p2Offset = Math.tan(degreesToRadians(pitchAngle)) * (outerRadius - pitchRadius) 23 | const p2AngleOffset = Math.atan(p2Offset / pitchRadius) 24 | const p2Radius = Math.sqrt(Math.pow(pitchRadius, 2) + Math.pow(p2Offset, 2)) 25 | const point2 = (f = 1, r = p2Radius) => polarToCartesian(r, degreesToRadians(i) + f * (offsetTheta + p2AngleOffset)) 26 | 27 | const point3 = (f = 1) => point2(f, insetRadius) 28 | 29 | if (i === 0) { 30 | sketch = new Sketch(point3(-1)) 31 | } else { 32 | sketch.LineTo(point3(-1)) 33 | } 34 | sketch.LineTo(point2(-1)) 35 | sketch.LineTo(point1(-1)) 36 | sketch.LineTo(point1(1)) 37 | sketch.LineTo(point2(1)) 38 | sketch.LineTo(point3(1)) 39 | } 40 | 41 | return sketch.End(true).Circle([0,0], innerRadius, true).Face() 42 | } 43 | 44 | Extrude(Gear(), [0,0,4]) 45 | -------------------------------------------------------------------------------- /parts/gherkin_6.js: -------------------------------------------------------------------------------- 1 | // function that describes the width of the building 2 | // as a function of the height 3 | // note that at 180 meters high the radius is zero! 4 | function EquationGherkin(x) 5 | { 6 | let pt1 = x*x - 144*x + 5184; 7 | let pt2 = pt1 / 11664; 8 | let pt3 = 1-pt2; 9 | let pt4 = Math.sqrt(pt3); 10 | let y = 28.25 * pt4; 11 | return y 12 | } 13 | 14 | // function to create faces along the outside of the tower 15 | // each parallellogram face covers 4 floors 16 | // each floor is 4 meters high 17 | // first is at reference height, then 8 and 16 meters up 18 | function BuildFacets(num,iteration,height) 19 | { 20 | let fullCircle = 2 * Math.PI 21 | let angle_ref = fullCircle/num * iteration 22 | let angle_aft = fullCircle/num * (iteration-0.5) 23 | let angle_front = fullCircle/num * (iteration+0.5) 24 | // calculate coordinates of vertices of parallellogram 25 | 26 | // bottom vertex 27 | let xref = Math.cos(angle_ref) * EquationGherkin(height) 28 | let yref = Math.sin(angle_ref) * EquationGherkin(height) 29 | 30 | // middle two vertices 31 | let xaft = Math.cos(angle_aft) * EquationGherkin(height+8) 32 | let xfront = Math.cos(angle_front) * EquationGherkin(height+8) 33 | let yaft = Math.sin(angle_aft) * EquationGherkin(height+8) 34 | let yfront = Math.sin(angle_front) * EquationGherkin(height+8) 35 | 36 | // top vertex 37 | let xtop = Math.cos(angle_ref) * EquationGherkin(height+16) 38 | let ytop = Math.sin(angle_ref) * EquationGherkin(height+16) 39 | 40 | // combine coordinates to vertices 41 | let pp0 = [xref, yref, height] 42 | let pp1 = [xaft, yaft, height+8] 43 | let pp2 = [xfront, yfront, height+8] 44 | let pp3 = [xtop, ytop, height+16] 45 | 46 | // create polygons 47 | Polygon([pp0, pp2, pp1]) 48 | Polygon([pp1, pp2, pp3]) 49 | } 50 | 51 | 52 | // construct floors 53 | // 44 floors, 4 meters each = 176 meter, 54 | // height of tower is 180 meters 55 | 56 | // first point on bottom at h=0 57 | let h = 0; 58 | let c0 = [EquationGherkin(h),h]; 59 | 60 | // prepare empty arrays for all faces and all contour points 61 | let face = []; 62 | let gherkin = []; 63 | 64 | // create each floor by revolving a face 65 | let floorThickness = 0.5 66 | let sc=0.97 // remove 3% from radius so that floors do not stick through shell 67 | for (let hi = 0; hi <= 178; hi+=4) 68 | { 69 | let floorPoint1 = [0,0,hi-floorThickness] 70 | let floorPoint2 = [sc*EquationGherkin(hi-floorThickness),0,hi-floorThickness] 71 | let floorPoint3 = [sc*EquationGherkin(hi),0, hi] 72 | let floorPoint4 = [0,0,hi] 73 | 74 | face[hi] = Polygon([floorPoint1,floorPoint2,floorPoint3,floorPoint4],true) 75 | gherkin[hi] = Revolve(face[hi]); 76 | } 77 | 78 | // create inner construction, cylinder 79 | let innerConstruction = Cylinder(1,176,false) 80 | 81 | // create parallellograms on outside 82 | // each parallellogram covers 4 floors, so go up with 16 metres 83 | // until 160 meters (so that top is at 176 meters) 84 | for (let hj = 0; hj <= 160; hj+=16) 85 | { 86 | for ( let k = 0; k <= 16 ; k+= 1) 87 | // each circle is divided into 16 parallellograms 88 | { 89 | BuildFacets(16,k,hj); 90 | } 91 | } 92 | 93 | // do the same but start 8 meters up (so halfway the first set) 94 | // and shift the points halfway between the first 95 | // go up by 32 meters to leave out some p-grams 96 | for (let hk = 8; hk <= 160; hk+=32) 97 | { 98 | for ( let l = 0.5; l <= 16.5 ; l+= 2) 99 | // each circle is divided into 16 parallellograms 100 | // use step 2 i.l.o. 1 to leave out regular pattern 101 | { 102 | BuildFacets(16,l,hk) 103 | } 104 | } 105 | 106 | // finalise regular pattern by adding in some missing facets 107 | for (let hk = 24; hk <= 164; hk+=32) 108 | { 109 | for ( let l = 1.5; l <= 17.5 ; l += 2) 110 | { 111 | BuildFacets(16,l,hk) 112 | } 113 | } 114 | 115 | // near the top add some triangles to finish the perimeter 116 | for (let hk = 176; hk <= 176; hk+=4) 117 | { 118 | for ( let l = 0.5; l <= 16.5 ; l +=1) 119 | { 120 | 121 | let angle_ref = Math.PI/8 * l 122 | let angle_aft = Math.PI/8 * (l-0.5) 123 | let angle_front = Math.PI/8 * (l+0.5) 124 | 125 | let xaft = Math.cos(angle_aft) * EquationGherkin(hk) 126 | let xfront = Math.cos(angle_front) * EquationGherkin(hk) 127 | let yaft = Math.sin(angle_aft) * EquationGherkin(hk) 128 | let yfront = Math.sin(angle_front) * EquationGherkin(hk) 129 | let xref = Math.cos(angle_ref) * EquationGherkin(hk+4) 130 | let yref = Math.sin(angle_ref) * EquationGherkin(hk+4) 131 | 132 | let pp1 = [xaft, yaft, hk] 133 | let pp2 = [xfront, yfront, hk] 134 | let pp3 = [xref, yref, hk+4] 135 | Polygon([pp1, pp2, pp3]) 136 | 137 | } 138 | } 139 | 140 | -------------------------------------------------------------------------------- /parts/gherkin_equation.js: -------------------------------------------------------------------------------- 1 | function equationGherkin(x) 2 | { 3 | let pt1 = x*x - 144*x + 5184; 4 | let pt2 = pt1 / 11664; 5 | let pt3 = 1-pt2; 6 | let pt4 = Math.sqrt(pt3); 7 | let y = 28.25 * pt4; 8 | return y 9 | } 10 | 11 | // evaluate the function starting a height h=0 12 | let h = 0; 13 | let c0 = [equationGherkin(h),h]; 14 | let calculatedGherkin = new Sketch(c0) 15 | 16 | for (let hi = 1; hi <= 180; hi+=4) 17 | { 18 | calculatedGherkin.LineTo( [ equationGherkin(hi) , hi]) 19 | 20 | } 21 | calculatedGherkin.LineTo([0,180]) 22 | calculatedGherkin.LineTo([0,0]) 23 | calculatedGherkin.LineTo(c0); 24 | calculatedGherkin.End(); 25 | // calculatedGherkin.Face(); 26 | 27 | // revolve the sketch 28 | Rotate( [1,0,0],90, 29 | Revolve(calculatedGherkin.Face() 30 | ,360,[0,1,0], true, true 31 | ) 32 | ) -------------------------------------------------------------------------------- /parts/gherkin_profile_correct.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "stack", 44 | "width": 50.163398692810446, 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "activeItemIndex": 0, 49 | "content": [ 50 | { 51 | "type": "component", 52 | "componentName": "codeEditor", 53 | "title": "gherkin_profile_correct.json", 54 | "componentState": { 55 | "code": [ 56 | "function equationGherkin(x) ", 57 | "{", 58 | " let pt1 = x*x - 144*x + 5184;", 59 | " let pt2 = pt1 / 11664;", 60 | " let pt3 = 1-pt2;", 61 | " let pt4 = Math.sqrt(pt3);", 62 | " let y = 28.25 * pt4;", 63 | " return y", 64 | "}", 65 | "", 66 | "// evaluate the function starting a height h=0", 67 | "let h = 0;", 68 | "let c0 = [equationGherkin(h),h];", 69 | "let calculatedGherkin = new Sketch(c0)", 70 | "", 71 | "for (let hi = 1; hi <= 180; hi+=4)", 72 | "{", 73 | " calculatedGherkin.LineTo( [ equationGherkin(hi) , hi])", 74 | "", 75 | "}", 76 | "calculatedGherkin.LineTo([0,180])", 77 | "calculatedGherkin.LineTo([0,0])", 78 | "calculatedGherkin.LineTo(c0);", 79 | "calculatedGherkin.End();", 80 | "// calculatedGherkin.Face();", 81 | "", 82 | "// revolve the sketch ", 83 | "Rotate( [1,0,0],90,", 84 | " Revolve(calculatedGherkin.Face()", 85 | " ,360,[0,1,0], true, true", 86 | " )", 87 | " )" 88 | ] 89 | }, 90 | "width": 50, 91 | "isClosable": false, 92 | "reorderEnabled": true 93 | } 94 | ] 95 | }, 96 | { 97 | "type": "column", 98 | "isClosable": true, 99 | "reorderEnabled": true, 100 | "title": "", 101 | "width": 49.83660130718954, 102 | "content": [ 103 | { 104 | "type": "stack", 105 | "height": 80, 106 | "isClosable": true, 107 | "reorderEnabled": true, 108 | "title": "", 109 | "activeItemIndex": 0, 110 | "content": [ 111 | { 112 | "type": "component", 113 | "componentName": "cascadeView", 114 | "title": "CAD View", 115 | "componentState": { 116 | "componentName": "cascadeView", 117 | "MeshRes": 0.1, 118 | "MeshResRange": [ 119 | 0.01, 120 | 2 121 | ], 122 | "Cache?": true, 123 | "Radius": 30, 124 | "RadiusRange": [ 125 | 20, 126 | 40 127 | ] 128 | }, 129 | "isClosable": false, 130 | "reorderEnabled": true 131 | } 132 | ] 133 | }, 134 | { 135 | "type": "stack", 136 | "height": 20, 137 | "isClosable": true, 138 | "reorderEnabled": true, 139 | "title": "", 140 | "activeItemIndex": 0, 141 | "content": [ 142 | { 143 | "type": "component", 144 | "componentName": "console", 145 | "title": "Console", 146 | "componentState": {}, 147 | "height": 20, 148 | "isClosable": false, 149 | "reorderEnabled": true 150 | } 151 | ] 152 | } 153 | ] 154 | } 155 | ] 156 | } 157 | ], 158 | "isClosable": true, 159 | "reorderEnabled": true, 160 | "title": "", 161 | "openPopouts": [], 162 | "maximisedItemId": null 163 | } -------------------------------------------------------------------------------- /parts/gnsholder.js: -------------------------------------------------------------------------------- 1 | // Holder for a GNS Electronic GNS3000 GPS receiver 2 | 3 | // dimensions of the receiver 4 | let gnsLength = 79.25; 5 | let gnsWidth = 45.25; 6 | let gnsDepth = 11.4; 7 | 8 | // dimensions of the holder 9 | let tolerance = 0.5; // tolerance for holder 10 | let hDepth = 2.0 ; // thickness of holder 11 | 12 | // add tolerance to main dimensions 13 | gnsLength = gnsLength + tolerance; 14 | gnsWidth = gnsWidth + tolerance; 15 | gnsDepth = gnsDepth + tolerance; 16 | 17 | // model the receiver 18 | let gnsBox = Box(gnsLength, gnsWidth, gnsDepth, false); 19 | // round edges 11,10,8,9 20 | let gnsRadius = gnsDepth/2 - tolerance; 21 | let gnsBoxRounded = FilletEdges(gnsBox,gnsRadius,[8,9,10,11],false); 22 | 23 | // model the holder 24 | 25 | // create a hollow shape modelled around the receiver 26 | let holder = Offset(gnsBoxRounded,2,0.01,true); 27 | holder = Difference(holder,[gnsBoxRounded]); 28 | 29 | // cut out some material to allow insertion of the receiver 30 | let cutterDepth = 10; 31 | let cutterTop = Box(gnsLength+cutterDepth,gnsWidth+cutterDepth,gnsDepth+cutterDepth,false); 32 | cutterTop = Translate([-cutterDepth/2,-cutterDepth/2,gnsDepth*0.80], cutterTop); 33 | 34 | let cutterSides = Box(gnsLength*0.80,gnsWidth*1.2,gnsDepth+2,true) 35 | cutterSides = (Offset(cutterSides,4)); 36 | cutterSides = Translate([gnsLength/2,gnsWidth/2,gnsDepth/2+7],cutterSides) 37 | let cutterBottom = Box(gnsLength,gnsWidth*0.7,gnsDepth+2,true) 38 | cutterBottom = Offset(cutterBottom,4) 39 | cutterBottom = Translate([gnsLength/2+hDepth+4,gnsWidth/2,gnsDepth/2+7],cutterBottom) 40 | 41 | // create two holes for a lanyard 42 | let cutterLanyard = Rotate([0,1,0],90,Cylinder(2,hDepth*3,true)) 43 | let cutterLanyard1 = Translate([0,gnsWidth/2+3,gnsDepth/2],cutterLanyard,true); 44 | let cutterLanyard2 = Translate([0,gnsWidth/2-3,gnsDepth/2],cutterLanyard,false); 45 | holder = Difference(holder,[cutterTop,cutterSides,cutterBottom,cutterLanyard1,cutterLanyard2]) 46 | holder = Translate([0,0,hDepth],holder) 47 | holder = FilletEdges(holder,0.5,[41]) // side 1 48 | holder = FilletEdges(holder,0.5,[115]) // side 2 49 | holder = FilletEdges(holder,0.5,[173]) // top1 50 | holder = FilletEdges(holder,0.5,[8]) // top2 51 | holder = FilletEdges(holder,0.5,[67]) // between tops 52 | holder = FilletEdges(holder,0.5,[176]) // bottom 53 | holder = FilletEdges(holder,0.5,[120,122]) // holes outside 54 | holder = FilletEdges(holder,0.5,[13,2]) // holes inside 55 | 56 | // I tried rounding the top edges but this failed as the edges were renumbered every time 57 | 58 | // option: create a strip to tie the receiver with tie wraps to something else 59 | // let stripLength = 10 60 | // let strip = Box(gnsLength+2*stripLength,20,hDepth,true) 61 | // strip = FilletEdges(strip,hDepth/2,[9,5,11,1]) 62 | // strip = Translate([(gnsLength/2),gnsWidth/2,hDepth/2],strip) 63 | -------------------------------------------------------------------------------- /parts/holder.js: -------------------------------------------------------------------------------- 1 | // Holder for a GNS Electronic GNS3000 GPS receiver 2 | 3 | // dimensions of the receiver 4 | let gnsLength = 79.25; 5 | let gnsWidth = 45.25; 6 | let gnsDepth = 11.4; 7 | 8 | // dimensions of the holder 9 | let tolerance = 0.5; // tolerance for holder 10 | let hDepth = 2.0 ; // thickness of holder 11 | 12 | // add tolerance to main dimensions 13 | gnsLength = gnsLength + tolerance; 14 | gnsWidth = gnsWidth + tolerance; 15 | gnsDepth = gnsDepth + tolerance; 16 | 17 | // model the receiver 18 | let gnsBox = Box(gnsLength, gnsWidth, gnsDepth, false); 19 | // round edges 11,10,8,9 20 | let gnsRadius = gnsDepth/2 - tolerance; 21 | let gnsBoxRounded = FilletEdges(gnsBox,gnsRadius,[8,9,10,11],false); 22 | 23 | // model the holder 24 | 25 | // create a hollow shape modelled around the receiver 26 | let holder = Offset(gnsBoxRounded,2,0.01,true); 27 | holder = Difference(holder,[gnsBoxRounded]); 28 | 29 | // cut out some material to allow insertion of the receiver 30 | let cutterDepth = 10; 31 | let cutterTop = Box(gnsLength+cutterDepth,gnsWidth+cutterDepth,gnsDepth+cutterDepth,false); 32 | cutterTop = Translate([-cutterDepth/2,-cutterDepth/2,gnsDepth*0.80], cutterTop); 33 | 34 | let cutterSides = Box(gnsLength*0.80,gnsWidth*1.2,gnsDepth+2,true) 35 | cutterSides = (Offset(cutterSides,4)); 36 | cutterSides = Translate([gnsLength/2,gnsWidth/2,gnsDepth/2+7],cutterSides) 37 | let cutterBottom = Box(gnsLength,gnsWidth*0.7,gnsDepth+2,true) 38 | cutterBottom = Offset(cutterBottom,4) 39 | cutterBottom = Translate([gnsLength/2+hDepth+4,gnsWidth/2,gnsDepth/2+7],cutterBottom) 40 | 41 | // create two holes for a lanyard 42 | let cutterLanyard = Rotate([0,1,0],90,Cylinder(2,hDepth*3,true)) 43 | let cutterLanyard1 = Translate([0,gnsWidth/2+3,gnsDepth/2],cutterLanyard,true); 44 | let cutterLanyard2 = Translate([0,gnsWidth/2-3,gnsDepth/2],cutterLanyard,false); 45 | holder = Difference(holder,[cutterTop,cutterSides,cutterBottom,cutterLanyard1,cutterLanyard2]) 46 | holder = Translate([0,0,hDepth],holder) 47 | 48 | // I tried rounding the top edges but this failed as the edges were renumbered every time 49 | 50 | // option: create a strip to tie the receiver with tie wraps to something else 51 | // let stripLength = 10 52 | // let strip = Box(gnsLength+2*stripLength,20,hDepth,true) 53 | // strip = FilletEdges(strip,hDepth/2,[9,5,11,1]) 54 | // strip = Translate([(gnsLength/2),gnsWidth/2,hDepth/2],strip) 55 | 56 | -------------------------------------------------------------------------------- /parts/holderv2.js: -------------------------------------------------------------------------------- 1 | const defaultParams = { 2 | // dimensions of GNS3000 GPS receiver 3 | gnsLength: 79.25, 4 | gnsWidth: 45.25, 5 | gnsHeight: 11.4, 6 | fit: 1.0, // tolerance to fit receiver in holder 7 | thickness: 2.0, // thickness of holder around receiver 8 | portionTop: 0.97, // height of holder compared to height of receiver, max 0.87 9 | portionSide: 0.7 10 | } 11 | 12 | const r = replicad 13 | 14 | function main( 15 | { }, // functions used in main, can be empty if r.function notation is used 16 | { gnsLength, gnsWidth, gnsHeight, fit, 17 | thickness, portionTop, portionSide} ) // parameters to adjust the model 18 | 19 | { 20 | let length = gnsLength + fit + 10; 21 | let width = gnsWidth + fit; 22 | let height = gnsHeight + fit; 23 | let radius = gnsHeight/2; 24 | 25 | // create shape of GNS3000 receiver 26 | let receiverBody = r.makeBaseBox(length,width,height) 27 | .fillet(radius,(e)=>e.inDirection("X")); 28 | 29 | // create holder by adding thickness to the shape of the GNS receiver 30 | let holder = r.makeBaseBox(length+2*thickness,width+2*thickness,height+2*thickness) 31 | .fillet(radius+thickness,(e)=>e.inDirection("X")) 32 | .translate(0,0,-thickness) 33 | 34 | // number of shapes to create cut-outs in the holder 35 | let cutterTop = r.makeBaseBox(length+4*thickness, width+4*thickness, height) 36 | .translate(0,0,portionTop*height) 37 | let cutterSide= r.makeBaseBox(length*portionSide, width+4*thickness, height) 38 | .translate(8,0,3) 39 | let cutterBottom = r.makeBaseBox(length,width*0.8,height) 40 | .fillet(3,(e)=>e.inDirection("X")) 41 | .translate(length/2,0,2.0) 42 | 43 | 44 | let cutterLanyardL = r.makeCylinder(2,20,[-length/2-10,3.5,5],[1,0,0]) 45 | let cutterLanyardR = r.makeCylinder(2,20,[-length/2-10,-3.5,5],[1,0,0]) 46 | let cutterLanyard = r.makeCompound([cutterLanyardL,cutterLanyardR]) 47 | 48 | 49 | holder = holder.cut(receiverBody) 50 | holder = holder.cut(cutterTop) 51 | holder = holder.cut(cutterSide) 52 | holder = holder.cut(cutterBottom) 53 | holder = holder.cut(cutterLanyard) 54 | //holder = holder.fillet(2.5,(e)=>e.inBox([length/2-5,50,3],[-length/2+5,-50,3+height]).inDirection("Y")) 55 | // holder = holder.fillet(0.3,(e)=>e.inBox([-1.2*length/2,-1.2*width/2,5],[1.2*length/2,1.2*width/2,height])) 56 | holder = holder.fillet(0.5) 57 | 58 | let shapeArray = [ 59 | {shape: receiverBody, name:"receiver", color:"red" }, 60 | {shape: cutterTop, name:"cutterTop", color: "green" , opacity: 0.5}, 61 | {shape: cutterSide, name:"cutterSide", color: "green", opacity:0.5}, 62 | {shape: cutterBottom, name:"cutterBottom", color: "green", opacity:0.5}, 63 | {shape: cutterLanyard, name:"cutterLanyard", color: "green", opacity:0.5}, 64 | {shape: holder, name:"holder", opacity: 1.0}, 65 | ] 66 | 67 | return shapeArray 68 | } -------------------------------------------------------------------------------- /parts/honeycomb_v2.js: -------------------------------------------------------------------------------- 1 | // Function to draw a zig-zag line of a honeycomb 2 | // d = edge length of hexagon 3 | // t = wall thickness between hexagons 4 | // n = number of zig-zags (= 2 cells) 5 | 6 | function HoneycombRow(d,t,n) 7 | { 8 | let x0 = 0; 9 | let y0 = 0; 10 | 11 | let strip = new Sketch([x0, y0]); 12 | 13 | for(let i = 0 ; i < n ; i += 1) 14 | { 15 | let x1 = x0 + d + t; 16 | let y1 = y0 + 0; 17 | let x2 = x1 + (Math.cos(Math.PI/3)*d); 18 | let y2 = y1 - (Math.sin(Math.PI/3)*d); 19 | let x3 = x2 + d; 20 | let y3 = y2 + 0; 21 | let x4 = x3 + (Math.cos(Math.PI/3)*d); 22 | let y4 = y3 + (Math.sin(Math.PI/3)*d); 23 | 24 | strip.LineTo( [ x1 ,y1 ] ); 25 | strip.LineTo( [ x2 ,y2 ] ); 26 | strip.LineTo( [ x3 ,y3 ] ); 27 | strip.LineTo( [ x4 ,y4 ] ); 28 | x0 = x4; 29 | y0 = y4; 30 | } 31 | 32 | let xcur = x0; 33 | let ycur = y0; 34 | let xnext = xcur + (Math.cos(Math.PI/3)*t) 35 | let ynext = ycur - (Math.sin(Math.PI/3)*t) 36 | strip.LineTo([xnext,ynext]) 37 | x0 = xnext; 38 | y0 = ynext; 39 | 40 | for(let j = 0 ; j < n ; j += 1) 41 | { 42 | let x1 = x0 - (Math.cos(Math.PI/3)*d); 43 | let y1 = y0 - (Math.sin(Math.PI/3)*d); 44 | let x2 = x1 - d - t; 45 | let y2 = y1 + 0; 46 | let x3 = x2 - (Math.cos(Math.PI/3)*d); 47 | let y3 = y2 + (Math.sin(Math.PI/3)*d); 48 | let x4 = x3 - d; 49 | let y4 = y3 - 0; 50 | 51 | strip.LineTo( [ x1 ,y1 ] ); 52 | strip.LineTo( [ x2 ,y2 ] ); 53 | strip.LineTo( [ x3 ,y3 ] ); 54 | strip.LineTo( [ x4 ,y4 ] ); 55 | x0 = x4; 56 | y0 = y4; 57 | } 58 | // strip.LineTo([-50,-50]); 59 | strip.LineTo([0,0]); 60 | strip.End(false); 61 | 62 | return strip.Face(true) 63 | 64 | } 65 | 66 | // Function to create a full grid 67 | 68 | // d= side length of hexagon 69 | // t= wall thickness between cells 70 | // h= height of generated honeycomb 71 | // n= number of columns (length of row) 72 | // m= number of rows 73 | 74 | function HoneycombGrid(d,t,h, n,m) 75 | { 76 | 77 | let row_half = Extrude(HoneycombRow(d,t,n),[0,0,h]); 78 | let row_mirror = Translate([0,Math.sin(Math.PI/3)*(-t),20], Rotate([1,0,0],180,row_half)); 79 | let row = Union([row_half,row_mirror]) 80 | let grid; 81 | 82 | for(let k=0 ; k < m-1 ; k += 1 ) 83 | { 84 | let row0 = row; 85 | let row1 = Translate([0, 2 * Math.sin(Math.PI/3) * d, 0], row, true) 86 | grid = Union([row0,row1]); 87 | row = grid; 88 | } 89 | 90 | return grid 91 | 92 | } 93 | 94 | // Test of functions defined above 95 | 96 | let t = 1; 97 | let d = 5; 98 | let n = 6; 99 | let m = 6; 100 | let h = 20; 101 | 102 | HoneycombGrid(d,t,h,n,m); 103 | 104 | -------------------------------------------------------------------------------- /parts/icosahedron.js: -------------------------------------------------------------------------------- 1 | // iso-spheres 2 | 3 | function ProjectSphere(vertex) 4 | // function to project a vertex on to a sphere with radius 1 5 | { 6 | let x = vertex[0]; 7 | let y = vertex[1]; 8 | let z = vertex[2]; 9 | let radius = Math.sqrt(Math.pow(x,2)+Math.pow(y,2)+Math.pow(z,2)) 10 | let scale = 1.0/radius; 11 | let scaledVertex = [scale*x , scale*y, scale*z] 12 | return scaledVertex 13 | } 14 | 15 | function Icosahedron() 16 | { 17 | let golden = (1+Math.sqrt(5))/2 18 | let v = [] 19 | // vertices determined by 4 rectangles 20 | v[0] = [-1, golden, 0]; 21 | v[1] = [ 1, golden, 0]; 22 | v[2] = [-1, -golden, 0]; 23 | v[3] = [ 1, -golden, 0]; 24 | 25 | v[4] = [ 0, -1, golden]; 26 | v[5] = [ 0, 1, golden]; 27 | v[6]= [ 0, -1,-golden]; 28 | v[7] = [ 0, 1,-golden]; 29 | 30 | v[8] = [ golden,0, -1]; 31 | v[9] = [ golden,0, 1]; 32 | v[10]= [ -golden,0, -1]; 33 | v[11] = [ -golden,0, 1]; 34 | 35 | // faces added so that they always have an edge in common 36 | // with the previous ones 37 | let f = [] 38 | // 0-5 39 | f[0] = [v[0],v[11],v[5]] 40 | f[1] = [v[0],v[5],v[1]] 41 | // 0-11 42 | f[2] = [v[0],v[10],v[11]] 43 | // 0-10 44 | f[3] = [v[0],v[7],v[10]] 45 | // 11-5 46 | f[4] = [v[5],v[11],v[4]] 47 | // 5-4 48 | f[5] = [v[4],v[9],v[5]] 49 | // 4-9 50 | f[6] = [v[3],v[9],v[4]] 51 | // 9-3 52 | f[7] = [v[3],v[8],v[9]] 53 | // 3-8 54 | f[8] = [v[3],v[6],v[8]] 55 | //3-6 56 | f[9] = [v[3],v[2],v[6]] 57 | // 2-6 58 | f[10] = [v[6],v[2],v[10]] 59 | // 6-10 60 | f[11] = [v[10],v[7],v[6]] 61 | // 6-7 62 | f[12] = [v[8],v[6],v[7]] 63 | // 6-8 10-7 0-7 64 | f[13] = [v[0],v[1],v[7]] // 65 | f[14] = [v[1],v[5],v[9]] // 66 | f[15] = [v[11],v[10],v[2]] // 67 | f[16] = [v[7],v[1],v[8]] // 68 | f[17] = [v[3],v[4],v[2]] // 69 | f[18] = [v[2],v[4],v[11]] // 70 | f[19] = [v[9],v[8],v[1]] // 71 | 72 | let icosphere = new oc.BRepBuilderAPI_Sewing() 73 | for(let i=0; i<=19 ;i++) 74 | { 75 | icosphere.Add(Polygon(f[i])) 76 | } 77 | icosphere.Perform() 78 | let sewedsphere = icosphere.SewedShape() 79 | console.log(sewedsphere.ShapeType()) // check type of the result 80 | console.log(sewedsphere.Closed()) // check if the shell is closed 81 | 82 | // create a solid 83 | let result = new oc.BRepBuilderAPI_MakeSolid() 84 | result.Add(sewedsphere) 85 | let finalresult = result.Solid() 86 | console.log(finalresult.ShapeType()) 87 | return finalresult 88 | } 89 | 90 | // draw the isosphere 91 | let test= Icosahedron(); 92 | test = Scale(50,test,false) 93 | test = Translate([20,20,220],test,false) 94 | console.log(test.ShapeType()) 95 | 96 | // draw a box 97 | let box = Box(200,200,200) 98 | console.log(box.ShapeType()) 99 | 100 | // draw a standard sphere 101 | let studioSphere = Translate([50,30,20],Sphere(100)) 102 | console.log(studioSphere.ShapeType()) 103 | 104 | box = Difference(box,[studioSphere]) 105 | // let experiment = Difference(box,[test]) 106 | 107 | -------------------------------------------------------------------------------- /parts/inscribed_polygon.json: -------------------------------------------------------------------------------- 1 | // A small function to return an array of points that lie on a circle 2 | 3 | function InscribedPolygonPoints(radius, numPoints) { 4 | const points = [] 5 | for (let theta = 0; theta < 2*Math.PI; theta += 2*Math.PI / numPoints) { 6 | points.push([Math.cos(theta) * radius, Math.sin(theta) * radius, 0]) 7 | } 8 | return points 9 | } 10 | 11 | function InscribedPolygon(radius, numPoints) { 12 | return Polygon(InscribedPolygonPoints(radius, numPoints)) 13 | } 14 | 15 | InscribedPolygon(10, 6) 16 | Translate([25, 0, 10], Rotate([0, 1, 0], -45, Extrude(InscribedPolygon(10, 9), [0, 0, 5]))) 17 | Translate([-20, 0, 0], InscribedPolygon(5, 5)) -------------------------------------------------------------------------------- /parts/lever_tailored.js: -------------------------------------------------------------------------------- 1 | function lever(r1, r2, d, h, t) 2 | { 3 | // This function creates a lever between two bearings, 4 | // the axles of the bearings are aligned 5 | 6 | // r1 = radius larger bearing 7 | // r2 = radois smaller bearing 8 | // d = distance between two bearings 9 | // h = height or width of the lever 10 | // t = wallthickness around bearing and cutout 11 | 12 | let sinus_a = (r1 - r2) / d ; 13 | let a = Math.asin(sinus_a); 14 | 15 | // points of outer contour of the lever 16 | let p1 = [r1 * Math.sin(a), r1 * Math.cos(a)]; 17 | let p2 = [d + r2 * Math.sin(a), r2 * Math.cos(a)]; 18 | let p3 = [d + r2, 0]; 19 | let p4 = [d + r2 * Math.sin(a), - r2 * Math.cos(a)]; 20 | let p5 = [r1 * Math.sin(a), - r1 * Math.cos(a)]; 21 | let p6 = [- r1, 0 ]; 22 | 23 | // points of cutout of the lever (not used as cutout became too small) 24 | let c1 = [(r1-t) * Math.sin(a), (r1-t) * Math.cos(a)]; 25 | let c2 = [d + (r2-t) * Math.sin(a), (r2-t) * Math.cos(a)]; ; 26 | let c3 = [d - r2 + t , 0]; 27 | let c4 = [d + (r2-t) * Math.sin(a), - (r2-t) * Math.cos(a)]; 28 | let c5 = [(r1-t) * Math.sin(a), - (r1-t) * Math.cos(a)]; 29 | let c6 = [r1-t,0]; 30 | 31 | let sketchLever = new Sketch(p1). 32 | LineTo(p2). 33 | ArcTo(p3,p4). 34 | LineTo(p5). 35 | ArcTo(p6,p1). 36 | End(false).Face(true); 37 | 38 | let leverbody = Extrude(sketchLever,[0,0,h]); 39 | 40 | let big_hole = Cylinder((r1-t), 2* (h + 10), true); 41 | let small_hole = Translate([d, 0,0 ], Cylinder((r2-t), 2* (h + 10), true)); 42 | let rough_lever = Difference(leverbody,[big_hole, small_hole]); 43 | 44 | let cutout = new Sketch(p1). 45 | LineTo(p2). 46 | ArcTo(c3,p4). 47 | LineTo(p5). 48 | ArcTo(c6,p1). 49 | End(false).Face(true); 50 | 51 | let cutoutbody = Extrude(cutout,[0,0,h+10]); 52 | let cutoutsmaller = Offset(cutoutbody, (-1.5 * t)); 53 | 54 | // ALTERNATIVE APPROACH FOR FILLETING 55 | // make shrunk version of cutout a bit smaller and then offset it again with 56 | // the filletradius 57 | let cutoutbigger = Offset(cutoutsmaller, (0.5 * t)); 58 | let cutoutround = cutoutbigger; 59 | let cutout_top = Translate([0,0,(h + t)/2],cutoutround); 60 | let cutout_bot = Translate([0,0,(-h - t)/2 -10],cutoutround); 61 | 62 | let rough_lever2 = Difference(rough_lever, [cutout_top, cutout_bot]); 63 | return rough_lever2; 64 | } 65 | // Lever with two bearings 66 | // sides tangent 67 | // with tailored side view. 68 | 69 | function sideviewblock(r1, r2, d, h, t) 70 | { 71 | // r1 = radius larger bearing 72 | // r2 = radois smaller bearing 73 | // d = distance between two bearings 74 | // h = height or width of the lever 75 | // t = wallthickness around bearing and cutout 76 | 77 | let sideview = new Sketch( [-r1-1,0] ) 78 | .LineTo([-r1-1,0.5*h]) 79 | .LineTo([r1,0.5*h]) 80 | .LineTo([d-r2,(0.1*h)+(1.2*t)]) 81 | .LineTo([d+r2,(0.1*h)+(1.2*t)]) 82 | .LineTo([d+r2,(-0.1*h)-(1.2*t)]) 83 | .LineTo([d-r2,(-0.1*h)-(1.2*t)]) 84 | .LineTo([r1,-0.5*h]) 85 | .LineTo([-r1-1,-0.5*h]) 86 | .LineTo([-r1-1,0]) 87 | .End(false,false).Face(); 88 | 89 | let block = Extrude(sideview, [0,0,(2*r1)+(2*t)]); 90 | 91 | let side1 = Rotate([1,0,0],90,block); 92 | let side2 = Translate([0, r1+1,0.5*h],side1); 93 | 94 | return side2; 95 | } 96 | 97 | let sidecut = sideviewblock(30,10,100,40,2); 98 | let levershape = lever(30,10,100,40,2); 99 | Intersection([levershape,sidecut]); 100 | 101 | -------------------------------------------------------------------------------- /parts/lighter_lever.js: -------------------------------------------------------------------------------- 1 | // CascadeStudio Code to create a lever, consisting of two cylinders joined by tangent walls 2 | // 3 | 4 | function lever(r1, r2, d, h, t) 5 | { 6 | // This function creates a lever between two bearings, 7 | // the axles of the bearings are aligned 8 | 9 | // r1 = radius larger bearing 10 | // r2 = radois smaller bearing 11 | // d = distance between two bearings 12 | // h = height or width of the lever 13 | // t = wallthickness around bearing and cutout 14 | 15 | let sinus_a = (r1 - r2) / d ; 16 | let a = Math.asin(sinus_a); 17 | 18 | // points of outer contour of the lever 19 | let p1 = [r1 * Math.sin(a), r1 * Math.cos(a)]; 20 | let p2 = [d + r2 * Math.sin(a), r2 * Math.cos(a)]; 21 | let p3 = [d + r2, 0]; 22 | let p4 = [d + r2 * Math.sin(a), - r2 * Math.cos(a)]; 23 | let p5 = [r1 * Math.sin(a), - r1 * Math.cos(a)]; 24 | let p6 = [- r1, 0 ]; 25 | 26 | // points of cutout of the lever (not used as cutout became too small) 27 | let c1 = [(r1-t) * Math.sin(a), (r1-t) * Math.cos(a)]; 28 | let c2 = [d + (r2-t) * Math.sin(a), (r2-t) * Math.cos(a)]; ; 29 | let c3 = [d - r2 + t , 0]; 30 | let c4 = [d + (r2-t) * Math.sin(a), - (r2-t) * Math.cos(a)]; 31 | let c5 = [(r1-t) * Math.sin(a), - (r1-t) * Math.cos(a)]; 32 | let c6 = [r1-t,0]; 33 | 34 | // sketch of the contour of the lever 35 | let sketchLever = new Sketch(p1). 36 | LineTo(p2). 37 | ArcTo(p3,p4). 38 | LineTo(p5). 39 | ArcTo(p6,p1). 40 | End(false).Face(true); 41 | 42 | let leverbody = Extrude(sketchLever,[0,0,h]); 43 | 44 | let big_hole = Cylinder((r1-t), 2* (h + 10), true); 45 | let small_hole = Translate([d, 0,0 ], Cylinder((r2-t), 2* (h + 10), true)); 46 | let rough_lever = Difference(leverbody,[big_hole, small_hole]); 47 | // let rough_lever = Difference(leverbody,[big_hole, small_hole, cutoutsmaller]); 48 | 49 | // sketch of the contour of the cut-out between the bearings 50 | let cutout = new Sketch(p1). 51 | LineTo(p2). 52 | ArcTo(c3,p4). 53 | LineTo(p5). 54 | ArcTo(c6,p1). 55 | End(false).Face(true); 56 | 57 | let cutoutbody = Extrude(cutout,[0,0,h+10]); 58 | let cutoutsmaller = Offset(cutoutbody, (-1.5 * t)); 59 | 60 | // REMARK ON FILLETING 61 | // filleting the cutout proved to be not practical, as selection of all edges 62 | // seemed nearly impossible 63 | // in the end I selected 50 edges and still one edge was not filleted. 64 | // let cutoutround = FilletEdges(cutoutsmaller, t/2, 65 | // [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, 66 | // 25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50]); 67 | 68 | // ALTERNATIVE APPROACH FOR FILLETING 69 | // make shrunk version of cutout a bit smaller and then offset it again with 70 | // the filletradius 71 | let cutoutbigger = Offset(cutoutsmaller, (0.5 * t)); 72 | let cutoutround = cutoutbigger; 73 | let cutout_top = Translate([0,0,(h + t)/2],cutoutround); 74 | let cutout_bot = Translate([0,0,(-h - t)/2 -10],cutoutround); 75 | 76 | let rough_lever2 = Difference(rough_lever, [cutout_top, cutout_bot]); 77 | 78 | return rough_lever2 79 | 80 | // Another interesting approach with sketches that 81 | // contain closed contours within closed contours. 82 | let sketch_holes = new Sketch(p1). 83 | LineTo(p2). 84 | ArcTo(p3,p4). 85 | LineTo(p5). 86 | ArcTo(p6,p1). 87 | End(true, false) 88 | .Circle([0,0],25, false) 89 | .Circle([d,0],5, false).Face(); 90 | 91 | let t_sketch_holes = Translate([0,100,0],sketch_holes); 92 | Extrude(t_sketch_holes, [0,0,h]); 93 | 94 | } 95 | 96 | lever(30,10,100,40,5) 97 | -------------------------------------------------------------------------------- /parts/loft_plunge.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "stack", 44 | "width": 50, 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "activeItemIndex": 0, 49 | "content": [ 50 | { 51 | "type": "component", 52 | "componentName": "codeEditor", 53 | "title": "* loft_plunge.json", 54 | "componentState": { 55 | "code": [ 56 | "", 57 | "", 58 | "", 59 | "let wire1 = (Circle(30,true));", 60 | "let wire2 = Translate([0,0,5],(Circle(35,true)));", 61 | "let wire3 = Translate([0,0,10],(Circle(30,true)));", 62 | "let wire4 = Translate([0,0,150],(Circle(5,true)));", 63 | "", 64 | "let body = Loft([wire1,wire2,wire3,wire4],true);", 65 | "" 66 | ] 67 | }, 68 | "width": 50, 69 | "isClosable": false, 70 | "reorderEnabled": true 71 | } 72 | ] 73 | }, 74 | { 75 | "type": "column", 76 | "isClosable": true, 77 | "reorderEnabled": true, 78 | "title": "", 79 | "width": 50, 80 | "content": [ 81 | { 82 | "type": "stack", 83 | "height": 80, 84 | "isClosable": true, 85 | "reorderEnabled": true, 86 | "title": "", 87 | "activeItemIndex": 0, 88 | "content": [ 89 | { 90 | "type": "component", 91 | "componentName": "cascadeView", 92 | "title": "CAD View", 93 | "componentState": { 94 | "componentName": "cascadeView", 95 | "MeshRes": 0.1, 96 | "Cache?": true, 97 | "Radius": 30 98 | }, 99 | "isClosable": false, 100 | "reorderEnabled": true 101 | } 102 | ] 103 | }, 104 | { 105 | "type": "stack", 106 | "height": 20, 107 | "isClosable": true, 108 | "reorderEnabled": true, 109 | "title": "", 110 | "activeItemIndex": 0, 111 | "content": [ 112 | { 113 | "type": "component", 114 | "componentName": "console", 115 | "title": "Console", 116 | "componentState": {}, 117 | "height": 20, 118 | "isClosable": false, 119 | "reorderEnabled": true 120 | } 121 | ] 122 | } 123 | ] 124 | } 125 | ] 126 | } 127 | ], 128 | "isClosable": true, 129 | "reorderEnabled": true, 130 | "title": "", 131 | "openPopouts": [], 132 | "maximisedItemId": null 133 | } -------------------------------------------------------------------------------- /parts/mollino-experiments.3dm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/parts/mollino-experiments.3dm -------------------------------------------------------------------------------- /parts/mollino.FCStd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/parts/mollino.FCStd -------------------------------------------------------------------------------- /parts/newsketch.js: -------------------------------------------------------------------------------- 1 | function Dxy(currentPoint,dx,dy) 2 | { 3 | let newPoint = []; 4 | newPoint[0] = currentPoint[0] + dx; 5 | newPoint[1] = currentPoint[1] + dy; 6 | return newPoint 7 | } 8 | 9 | function Dx(currentPoint,dx) 10 | { 11 | let newPoint = []; 12 | newPoint[0] = currentPoint[0] + dx; 13 | newPoint[1] = currentPoint[1] ; 14 | return newPoint 15 | } 16 | 17 | function Dy(currentPoint,dy) 18 | { 19 | let newPoint = []; 20 | newPoint[0] = currentPoint[0]; 21 | newPoint[1] = currentPoint[1] + dy; 22 | return newPoint 23 | } 24 | 25 | function Polar(currentPoint,distance,angleDegToX) 26 | { 27 | let newPoint = []; 28 | let angleRad = angleDegToX * Math.PI/180; 29 | newPoint[0] = currentPoint[0] + distance * Math.cos(angleRad); 30 | newPoint[1] = currentPoint[1] + distance * Math.sin(angleRad); 31 | return newPoint 32 | } 33 | 34 | function PolarX(currentPoint,xdistance,angleDegToX) 35 | { 36 | let newPoint = []; 37 | let angleRad = angleDegToX * Math.PI/180; 38 | newPoint[0] = currentPoint[0] + xdistance; 39 | newPoint[1] = currentPoint[1] + xdistance * Math.tan(angleRad); 40 | return newPoint 41 | } 42 | 43 | function PolarY(currentPoint,ydistance,angleDegToX) 44 | { 45 | let newPoint = []; 46 | let angleRad = angleDegToX * Math.PI/180; 47 | newPoint[0] = currentPoint[0] + ydistance/Math.tan(angleRad); 48 | newPoint[1] = currentPoint[1] + ydistance; 49 | return newPoint 50 | } 51 | 52 | function RadiusArc(currentPoint,endPoint,radius, clockwise) 53 | { 54 | let midPoint = []; 55 | let dx = endPoint[0] - currentPoint[0]; 56 | let dy = endPoint[1] - currentPoint[1]; 57 | let dist = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2)); 58 | let alpha = Math.asin(dy/dist); 59 | let beta = Math.asin((dist/2)/radius); 60 | let sag = radius - (Math.cos(beta) * radius) 61 | if (dx<0){clockwise = !clockwise} 62 | if (clockwise == true) 63 | { 64 | midPoint[0] = currentPoint[0] + dx/2 - Math.sin(alpha)*sag; 65 | midPoint[1] = currentPoint[1] + dy/2 + Math.cos(alpha)*sag; 66 | } 67 | else 68 | { 69 | midPoint[0] = currentPoint[0] + dx/2 + Math.sin(alpha)*sag; 70 | midPoint[1] = currentPoint[1] + dy/2 - Math.cos(alpha)*sag; 71 | } 72 | return midPoint 73 | } 74 | 75 | 76 | function SagArc(currentPoint,endPoint,sag,clockwise) 77 | { 78 | let midPoint = []; 79 | let dx = endPoint[0] - currentPoint[0]; 80 | let dy = endPoint[1] - currentPoint[1]; 81 | let dist = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2)); 82 | let alpha = Math.asin(dy/dist); 83 | if (dx<0){clockwise = !clockwise} 84 | if (clockwise == true) 85 | { 86 | midPoint[0] = currentPoint[0] + dx/2 - Math.sin(alpha)*sag; 87 | midPoint[1] = currentPoint[1] + dy/2 + Math.cos(alpha)*sag; 88 | } 89 | else 90 | { 91 | midPoint[0] = currentPoint[0] + dx/2 + Math.sin(alpha)*sag; 92 | midPoint[1] = currentPoint[1] + dy/2 - Math.cos(alpha)*sag; 93 | } 94 | return midPoint 95 | } 96 | 97 | function MirrorX(currentPoint, yvalue) 98 | { 99 | let mirrorPoint = []; 100 | mirrorPoint[0] = currentPoint[0]; 101 | mirrorPoint[1] = yvalue - (currentPoint[1]-yvalue); 102 | return mirrorPoint 103 | } 104 | 105 | function MirrorY(currentPoint, xvalue) 106 | { 107 | let mirrorPoint = []; 108 | mirrorPoint[0] = xvalue - (currentPoint[0]-xvalue); 109 | mirrorPoint[1] = currentPoint[1]; 110 | return mirrorPoint 111 | } 112 | 113 | 114 | 115 | let p0 = [0,0] 116 | let p1 = Dx(p0, 10); 117 | let p3 = Dy(p1, 10); 118 | let p2 = SagArc(p1,p3,4,true) 119 | let p4 = Polar(p3,10,135) 120 | let p5 = Dx(p4,-10); 121 | let p7 = Dy(p5,-10) 122 | let p6 = RadiusArc(p5,p7,7,false) 123 | let p8 = MirrorY(p6,0) 124 | console.log(p6) 125 | console.log(p8) 126 | 127 | let test = new Sketch(p0) 128 | .LineTo(p1) 129 | .ArcTo(p2,p3) 130 | .LineTo(p4) 131 | .LineTo(p5) 132 | .ArcTo(p6,p7) 133 | .End(true).Face() 134 | Extrude(test,[0,0,20]) 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /parts/newsketch_1.js: -------------------------------------------------------------------------------- 1 | function Dxy(currentPoint,dx,dy) 2 | { 3 | let newPoint = []; 4 | newPoint[0] = currentPoint[0] + dx; 5 | newPoint[1] = currentPoint[1] + dy; 6 | return newPoint 7 | } 8 | 9 | function Dx(currentPoint,dx) 10 | { 11 | let newPoint = []; 12 | newPoint[0] = currentPoint[0] + dx; 13 | newPoint[1] = currentPoint[1] ; 14 | return newPoint 15 | } 16 | 17 | function Dy(currentPoint,dy) 18 | { 19 | let newPoint = []; 20 | newPoint[0] = currentPoint[0]; 21 | newPoint[1] = currentPoint[1] + dy; 22 | return newPoint 23 | } 24 | 25 | function Polar(currentPoint,distance,angleDegToX) 26 | { 27 | let newPoint = []; 28 | let angleRad = angleDegToX * Math.PI/180; 29 | newPoint[0] = currentPoint[0] + distance * Math.cos(angleRad); 30 | newPoint[1] = currentPoint[1] + distance * Math.sin(angleRad); 31 | return newPoint 32 | } 33 | 34 | function PolarX(currentPoint,xdistance,angleDegToX) 35 | { 36 | let newPoint = []; 37 | let angleRad = angleDegToX * Math.PI/180; 38 | newPoint[0] = currentPoint[0] + xdistance; 39 | newPoint[1] = currentPoint[1] + xdistance * Math.tan(angleRad); 40 | return newPoint 41 | } 42 | 43 | function PolarY(currentPoint,ydistance,angleDegToX) 44 | { 45 | let newPoint = []; 46 | let angleRad = angleDegToX * Math.PI/180; 47 | newPoint[0] = currentPoint[0] + ydistance/Math.tan(angleRad); 48 | newPoint[1] = currentPoint[1] + ydistance; 49 | return newPoint 50 | } 51 | 52 | function RadiusArc(currentPoint,endPoint,radius, clockwise) 53 | { 54 | let midPoint = []; 55 | let dx = endPoint[0] - currentPoint[0]; 56 | let dy = endPoint[1] - currentPoint[1]; 57 | let dist = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2)); 58 | let alpha = Math.asin(dy/dist); 59 | let beta = Math.asin((dist/2)/radius); 60 | let sag = radius - (Math.cos(beta) * radius) 61 | if (dx<0){clockwise = !clockwise} 62 | if (clockwise == true) 63 | { 64 | midPoint[0] = currentPoint[0] + dx/2 - Math.sin(alpha)*sag; 65 | midPoint[1] = currentPoint[1] + dy/2 + Math.cos(alpha)*sag; 66 | } 67 | else 68 | { 69 | midPoint[0] = currentPoint[0] + dx/2 + Math.sin(alpha)*sag; 70 | midPoint[1] = currentPoint[1] + dy/2 - Math.cos(alpha)*sag; 71 | } 72 | return midPoint 73 | } 74 | 75 | 76 | function SagArc(currentPoint,endPoint,sag,clockwise) 77 | { 78 | let midPoint = []; 79 | let dx = endPoint[0] - currentPoint[0]; 80 | let dy = endPoint[1] - currentPoint[1]; 81 | let dist = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2)); 82 | let alpha = Math.asin(dy/dist); 83 | if (dx<0){clockwise = !clockwise} 84 | if (clockwise == true) 85 | { 86 | midPoint[0] = currentPoint[0] + dx/2 - Math.sin(alpha)*sag; 87 | midPoint[1] = currentPoint[1] + dy/2 + Math.cos(alpha)*sag; 88 | } 89 | else 90 | { 91 | midPoint[0] = currentPoint[0] + dx/2 + Math.sin(alpha)*sag; 92 | midPoint[1] = currentPoint[1] + dy/2 - Math.cos(alpha)*sag; 93 | } 94 | return midPoint 95 | } 96 | 97 | function MirrorX(currentPoint, yvalue) 98 | { 99 | let mirrorPoint = []; 100 | mirrorPoint[0] = currentPoint[0]; 101 | mirrorPoint[1] = yvalue - (currentPoint[1]-yvalue); 102 | return mirrorPoint 103 | } 104 | 105 | function MirrorY(currentPoint, xvalue) 106 | { 107 | let mirrorPoint = []; 108 | mirrorPoint[0] = xvalue - (currentPoint[0]-xvalue); 109 | mirrorPoint[1] = currentPoint[1]; 110 | return mirrorPoint 111 | } 112 | 113 | 114 | 115 | let p0 = [0,0] 116 | let p1 = Dx(p0, 10); 117 | let p3 = Dy(p1, 10); 118 | let p2 = SagArc(p1,p3,4,true) 119 | let p4 = Polar(p3,10,135) 120 | let p5 = Dx(p4,-10); 121 | let p7 = Dy(p5,-10) 122 | let p6 = RadiusArc(p5,p7,7,false) 123 | let p8 = MirrorY(p6,0) 124 | console.log(p6) 125 | console.log(p8) 126 | 127 | let test = new Sketch(p0) 128 | .LineTo(p1) 129 | .ArcTo(p2,p3) 130 | .LineTo(p4) 131 | .LineTo(p5) 132 | .ArcTo(p6,p7) 133 | .End(true).Face() 134 | Extrude(test,[0,0,20]) 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /parts/nut.js: -------------------------------------------------------------------------------- 1 | // input parameters 2 | let d = 8; // M8 nut diameter of the screw 3 | let f = 13; // DIN 13mm wrench width across flats 4 | let h = 6.5; // height of nut 5 | 6 | // derived parameters 7 | let g = f / Math.cos(Math.PI/6); // width across corners 8 | 9 | // disk with chamfer 10 | let nutBody = Cylinder(g/2,0.8*h,true) 11 | let nutChamferT = Translate([0,0,0.8*h/2],Cone(g/2 ,0.8*g/2, 0.1*h,false)) 12 | let nutChamferB = Translate([0,0,-0.8*h/2],Rotate([1,0,0],180,Cone(g/2,0.8*g/2,0.1*h, false))) 13 | let nutBodyBase = Union([nutBody, nutChamferT, nutChamferB], false) 14 | 15 | // hexagon rod 16 | let box1 = Box(g/2,f,1.1*h,true) 17 | let box2 = Rotate([0,0,1],60,Box(g/2,f,1.1*h,true)) 18 | let box3 = Rotate([0,0,1],120,Box(g/2,f,1.1*h,true)) 19 | let hexagon = Union([box1, box2, box3], false, 0.01, false); 20 | 21 | // intersection of disk and hexagon 22 | let nutShape = Intersection([nutBodyBase,hexagon],false, 0.01,false) 23 | 24 | // cutting hole 25 | let cutterHole = Cylinder(d/2,h*3,true) 26 | let nut = Difference(nutShape, [cutterHole]) 27 | let lowerNut= Translate([0,0,g/2],Rotate([0,1,0],90,nut)) 28 | 29 | // create section through nut 30 | let upperNut= Translate([0,0,h*3.5], nut) 31 | let cutter = Translate([0,-g,0],Box(30,48,h*4,false)) 32 | Difference(upperNut,[cutter]) -------------------------------------------------------------------------------- /parts/plunge-imported-cs.3dm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/parts/plunge-imported-cs.3dm -------------------------------------------------------------------------------- /parts/plunge.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raydeleu/CascadeStudioManual/a747ac266a41bec93137dec334f236023455e5d9/parts/plunge.blend -------------------------------------------------------------------------------- /parts/revolve5.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "stack", 44 | "width": 50, 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "activeItemIndex": 0, 49 | "content": [ 50 | { 51 | "type": "component", 52 | "componentName": "codeEditor", 53 | "title": "* Untitled", 54 | "componentState": { 55 | "code": [ 56 | "// Welcome to Cascade Studio! Here are some useful functions:", 57 | "// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()", 58 | "// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()", 59 | "// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(), ", 60 | "// FilletEdges(), ChamferEdges(),", 61 | "// Slider(), Button(), Checkbox()", 62 | "", 63 | "let x0=10", 64 | "let y0=10", 65 | "let x=30", 66 | "let y=60", 67 | "let p0 = [x0,y0]", 68 | "let p1 = [x,y0]", 69 | "let p2 = [x,y]", 70 | "let p3 = [x0,y]", 71 | "", 72 | "", 73 | "let box1 = new Sketch(p0)", 74 | ".LineTo(p1)", 75 | ".LineTo(p2)", 76 | ".LineTo(p3)", 77 | ".End(true)", 78 | "", 79 | "let revolve1 = Translate([-100,0,0],Revolve(box1.Face(),160,[1,0,0],false,false));", 80 | "let revolve2 = Translate([-50,0,0],Revolve(box1.Wire(),120,[1,0,0],false,false));", 81 | "let revolve3 = Revolve(box1.Face(),90,[1,0,0],false,false);", 82 | "" 83 | ] 84 | }, 85 | "width": 50, 86 | "isClosable": false, 87 | "reorderEnabled": true 88 | } 89 | ] 90 | }, 91 | { 92 | "type": "column", 93 | "isClosable": true, 94 | "reorderEnabled": true, 95 | "title": "", 96 | "width": 50, 97 | "content": [ 98 | { 99 | "type": "stack", 100 | "height": 80, 101 | "isClosable": true, 102 | "reorderEnabled": true, 103 | "title": "", 104 | "activeItemIndex": 0, 105 | "content": [ 106 | { 107 | "type": "component", 108 | "componentName": "cascadeView", 109 | "title": "CAD View", 110 | "componentState": { 111 | "componentName": "cascadeView", 112 | "MeshRes": 0.1, 113 | "MeshResRange": [ 114 | 0.01, 115 | 2 116 | ], 117 | "Cache?": false, 118 | "Radius": 30, 119 | "RadiusRange": [ 120 | 20, 121 | 40 122 | ] 123 | }, 124 | "isClosable": false, 125 | "reorderEnabled": true 126 | } 127 | ] 128 | }, 129 | { 130 | "type": "stack", 131 | "height": 20, 132 | "isClosable": true, 133 | "reorderEnabled": true, 134 | "title": "", 135 | "activeItemIndex": 0, 136 | "content": [ 137 | { 138 | "type": "component", 139 | "componentName": "console", 140 | "title": "Console", 141 | "componentState": {}, 142 | "height": 20, 143 | "isClosable": false, 144 | "reorderEnabled": true 145 | } 146 | ] 147 | } 148 | ] 149 | } 150 | ] 151 | } 152 | ], 153 | "isClosable": true, 154 | "reorderEnabled": true, 155 | "title": "", 156 | "openPopouts": [], 157 | "maximisedItemId": null 158 | } -------------------------------------------------------------------------------- /parts/rotate_extrude_demo.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "stack", 44 | "width": 50, 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "activeItemIndex": 0, 49 | "content": [ 50 | { 51 | "type": "component", 52 | "componentName": "codeEditor", 53 | "title": "* Untitled", 54 | "componentState": { 55 | "code": [ 56 | "", 57 | "", 58 | "function Plane(x,y,wire,centered)", 59 | "{", 60 | "// definition of points ", 61 | "let p1 = [0,0,0]", 62 | "let p2 = [x,0,0]", 63 | "let p3 = [x,y,0]", 64 | "let p4 = [0,y,0]", 65 | "// sketch plane", 66 | "let plane = Polygon([p1,p2,p3,p4],wire)", 67 | "if (centered == true)", 68 | "{Translate([-0.5*x, -0.5*y, 0], plane)}", 69 | "return plane", 70 | "}", 71 | "", 72 | "let planeWire1 = Plane(20,50,true,false)", 73 | "RotatedExtrude(planeWire1,20,20)", 74 | "", 75 | "let planeWire2 = Plane(20,50,true,true)", 76 | "RotatedExtrude(planeWire2,10,10)" 77 | ] 78 | }, 79 | "width": 50, 80 | "isClosable": false, 81 | "reorderEnabled": true 82 | } 83 | ] 84 | }, 85 | { 86 | "type": "column", 87 | "isClosable": true, 88 | "reorderEnabled": true, 89 | "title": "", 90 | "width": 50, 91 | "content": [ 92 | { 93 | "type": "stack", 94 | "height": 80, 95 | "isClosable": true, 96 | "reorderEnabled": true, 97 | "title": "", 98 | "activeItemIndex": 0, 99 | "content": [ 100 | { 101 | "type": "component", 102 | "componentName": "cascadeView", 103 | "title": "CAD View", 104 | "componentState": { 105 | "componentName": "cascadeView", 106 | "MeshRes": 0.1, 107 | "MeshResRange": [ 108 | 0.01, 109 | 2 110 | ], 111 | "Cache?": false, 112 | "Radius": 30, 113 | "RadiusRange": [ 114 | 20, 115 | 40 116 | ] 117 | }, 118 | "isClosable": false, 119 | "reorderEnabled": true 120 | } 121 | ] 122 | }, 123 | { 124 | "type": "stack", 125 | "height": 20, 126 | "isClosable": true, 127 | "reorderEnabled": true, 128 | "title": "", 129 | "activeItemIndex": 0, 130 | "content": [ 131 | { 132 | "type": "component", 133 | "componentName": "console", 134 | "title": "Console", 135 | "componentState": {}, 136 | "height": 20, 137 | "isClosable": false, 138 | "reorderEnabled": true 139 | } 140 | ] 141 | } 142 | ] 143 | } 144 | ] 145 | } 146 | ], 147 | "isClosable": true, 148 | "reorderEnabled": true, 149 | "title": "", 150 | "openPopouts": [], 151 | "maximisedItemId": null 152 | } -------------------------------------------------------------------------------- /parts/rough_lever.js: -------------------------------------------------------------------------------- 1 | // CascadeStudio Code to create a lever, consisting of two cylinders joined by tangent walls 2 | // 3 | 4 | function lever(radius1, radius2, delta_bearings, leverheight, wall_thickness) 5 | { 6 | let sinus_angle = (radius1 - radius2) / delta_bearings 7 | let angle = Math.asin(sinus_angle); 8 | 9 | let p1 = [radius1 * Math.sin(angle), radius1 * Math.cos(angle)]; 10 | let p2 = [delta_bearings + radius2 * Math.sin(angle), radius2 * Math.cos(angle)]; 11 | let p3 = [delta_bearings + radius2, 0]; 12 | let p4 = [delta_bearings + radius2 * Math.sin(angle), - radius2 * Math.cos(angle)]; 13 | let p5 = [radius1 * Math.sin(angle), - radius1 * Math.cos(angle)]; 14 | let p6 = [- radius1, 0 ] 15 | 16 | let sketchLever = new Sketch(p1). 17 | LineTo(p2). 18 | ArcTo(p3,p4). 19 | LineTo(p5). 20 | ArcTo(p6,p1). 21 | End(false).Face(true) 22 | 23 | let leverbody = Extrude(sketchLever,[0,0,leverheight]); 24 | let big_hole = Cylinder((radius1-wall_thickness), 2* (leverheight + 10), true); 25 | let small_hole = Translate([delta_bearings, 0,0 ], Cylinder((radius2-wall_thickness), 2* (leverheight + 10), true)); 26 | let rough_lever = Difference(leverbody,[big_hole, small_hole]) 27 | 28 | return rough_lever 29 | } 30 | 31 | lever(30,10,100,40,3) 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /parts/round_all_clone.js: -------------------------------------------------------------------------------- 1 | const extrusion = Extrude( 2 | new Sketch([-4,0]).Fillet(1) 3 | .LineTo([5,3]).Fillet(1.5) 4 | .LineTo([0,7]).Fillet(0.2) 5 | .LineTo([8,7]).Fillet(10) 6 | .LineTo([20,20]).Fillet(0.8) 7 | .LineTo([10,0]).Fillet(10).End(true).Face(), 8 | [0,0,2]) 9 | 10 | FilletEdges(extrusion, 0.45, [9]) 11 | 12 | // NOTE: 13 | // You only have to find one edge in a chain 14 | // and OpenCascade will find the other edges 15 | // along the same loop or chain. 16 | 17 | -------------------------------------------------------------------------------- /parts/rounded_solid_boxes.js: -------------------------------------------------------------------------------- 1 | function filletsquare (x,y,f) { 2 | return new Sketch([0, 0]) 3 | .LineTo([x, 0]).Fillet(f) 4 | .LineTo([x, y]).Fillet(f) 5 | .LineTo([0, y]).Fillet(f) 6 | .End(true).Fillet(f) 7 | .Face(); 8 | } 9 | 10 | 11 | function RoundAll(shape,fillet) 12 | { 13 | let shrunk_version = Offset(shape,-fillet) 14 | let grown_version = Offset(shrunk_version, fillet) 15 | return grown_version 16 | } 17 | 18 | function ThinWall(shape,thickness) 19 | { 20 | let shape_original = shape; 21 | let shrunk = Offset(shape, -thickness); 22 | let hollow = Difference(shape_original,[shrunk]); 23 | return hollow; 24 | } 25 | 26 | 27 | let t = 0.5; 28 | 29 | // only plan-view rounded through fillets in sketch 30 | let box0 = Translate([-20,0,0],Extrude(filletsquare(10,20,3),[0,0,20])); 31 | 32 | // experiment to make a thin-walled version, cutting it open by subtracting a box 33 | let box_hollow = ThinWall(box0,t) 34 | let boxh2 = Difference(box_hollow,[Translate([-20,10,15],Box(50,50,50))]) 35 | 36 | // all edges rounded individually 37 | // note that only one of the edges in a loop needs to be listed 38 | let box1 = Extrude(filletsquare(10, 20, 5), [0,0,20]); 39 | // let rounded_box = FilletEdges(box1, 2, [3,6,12,15,17]); 40 | let rounded_box = FilletEdges(box1, 2, [3]); 41 | // let double_rounded_box = FilletEdges(rounded_box, 1, [11,12,10,13,6,2]); 42 | let double_rounded_box = FilletEdges(rounded_box, 1, [11]); 43 | 44 | // using a function 45 | let box3 = Translate([20,0,0],Extrude(filletsquare(10,20,3),[0,0,20])); 46 | let rounded_box3 = RoundAll(box3,2) 47 | 48 | // using a function on a rectangular, unfilleted box 49 | let box4 = Translate([40,0,0],RoundAll(Box(10,20,20),5)) 50 | -------------------------------------------------------------------------------- /parts/shapes.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "column", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "width": 100, 42 | "content": [ 43 | { 44 | "type": "stack", 45 | "height": 73.5202492211838, 46 | "isClosable": true, 47 | "reorderEnabled": true, 48 | "title": "", 49 | "activeItemIndex": 0, 50 | "content": [ 51 | { 52 | "type": "component", 53 | "componentName": "cascadeView", 54 | "title": "CAD View", 55 | "componentState": { 56 | "componentName": "cascadeView", 57 | "MeshRes": 0.1, 58 | "MeshResRange": [ 59 | 0.01, 60 | 2 61 | ], 62 | "Cache?": true, 63 | "Radius": 30, 64 | "RadiusRange": [ 65 | 20, 66 | 40 67 | ] 68 | }, 69 | "isClosable": false, 70 | "reorderEnabled": true 71 | } 72 | ] 73 | }, 74 | { 75 | "type": "stack", 76 | "height": 26.479750778816204, 77 | "isClosable": true, 78 | "reorderEnabled": true, 79 | "title": "", 80 | "activeItemIndex": 1, 81 | "content": [ 82 | { 83 | "type": "component", 84 | "componentName": "console", 85 | "title": "Console", 86 | "componentState": {}, 87 | "height": 20, 88 | "isClosable": false, 89 | "reorderEnabled": true 90 | }, 91 | { 92 | "type": "component", 93 | "componentName": "codeEditor", 94 | "title": "* Untitled", 95 | "componentState": { 96 | "code": [ 97 | "// Examples of solid shapes", 98 | "let exampleBox = Box(20,30,15, false)", 99 | "let exampleSphere = Translate([50,10,10],Sphere(10)) ", 100 | "let exampleCylinder = Translate([80,10,0],Cylinder(10,20,false))", 101 | "let exampleCone = Translate([110,10,0],Cone(10,2,20))", 102 | "let exampleText = Translate([125,10,0],Text3D(\"Text\", 15, 0.2,'Roboto'))" 103 | ] 104 | }, 105 | "width": 50, 106 | "isClosable": false, 107 | "reorderEnabled": true 108 | } 109 | ] 110 | } 111 | ] 112 | } 113 | ], 114 | "isClosable": true, 115 | "reorderEnabled": true, 116 | "title": "", 117 | "openPopouts": [], 118 | "maximisedItemId": null 119 | } -------------------------------------------------------------------------------- /parts/spline.js: -------------------------------------------------------------------------------- 1 | function p2xyz(r, d, z = 0) { 2 | let th = d / 180 * Math.PI 3 | let v = ([r * Math.cos(th), r * Math.sin (th), z]) 4 | //Translate(v, Rotate([0, 0, 1], d, Sphere(0.1))) 5 | return (v) 6 | } 7 | 8 | let l = [] 9 | let N=6 10 | let r = 10 11 | let dinc = 360/N 12 | for (let i = 0; i < N ; i++) { 13 | l.push (p2xyz(r * 1.1, i * dinc)) 14 | l.push (p2xyz(r * 1.0, (i + 0.1) * dinc)) 15 | l.push (p2xyz(r * 0.8, (i + 0.5) * dinc)) 16 | l.push (p2xyz(r * 1.0, (i + 0.9) * dinc)) 17 | } 18 | base = BSpline(l, true) 19 | top = Translate([0, 0, 100], Circle(10, true)) 20 | shape1 = Loft([base, top]) 21 | cut1 = Translate([-20, -20, 0], Box(20, 40, 100, false)) 22 | semi = Intersection([shape1, cut1]) 23 | final = Translate([100, 0, 0], Union([semi, Rotate([0, 0, 1], 180, semi)])) 24 | -------------------------------------------------------------------------------- /parts/test-union.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "hasHeaders": true, 4 | "constrainDragToContainer": true, 5 | "reorderEnabled": true, 6 | "selectionEnabled": false, 7 | "popoutWholeStack": false, 8 | "blockedPopoutsThrowError": true, 9 | "closePopoutsOnUnload": true, 10 | "showPopoutIcon": false, 11 | "showMaximiseIcon": false, 12 | "showCloseIcon": false, 13 | "responsiveMode": "onload", 14 | "tabOverlapAllowance": 0, 15 | "reorderOnTabMenuClick": true, 16 | "tabControlOffset": 10 17 | }, 18 | "dimensions": { 19 | "borderWidth": 5, 20 | "borderGrabWidth": 15, 21 | "minItemHeight": 10, 22 | "minItemWidth": 10, 23 | "headerHeight": 20, 24 | "dragProxyWidth": 300, 25 | "dragProxyHeight": 200 26 | }, 27 | "labels": { 28 | "close": "close", 29 | "maximise": "maximise", 30 | "minimise": "minimise", 31 | "popout": "open in new window", 32 | "popin": "pop in", 33 | "tabDropdown": "additional tabs" 34 | }, 35 | "content": [ 36 | { 37 | "type": "row", 38 | "isClosable": true, 39 | "reorderEnabled": true, 40 | "title": "", 41 | "content": [ 42 | { 43 | "type": "stack", 44 | "width": 50, 45 | "isClosable": true, 46 | "reorderEnabled": true, 47 | "title": "", 48 | "activeItemIndex": 0, 49 | "content": [ 50 | { 51 | "type": "component", 52 | "componentName": "codeEditor", 53 | "title": "* test-union.json", 54 | "componentState": { 55 | "code": [ 56 | "", 57 | "let r = 6;", 58 | "let h = 9;", 59 | "let d = 7;", 60 | "let t1 = 40;", 61 | "let t2 = 2;", 62 | "", 63 | "", 64 | "let pil = Union([", 65 | " Cylinder(r, h, false),", 66 | " Translate([0, 0, h], Sphere(r)),", 67 | " Translate([0, 0, 0], Sphere(r)),", 68 | " ]);", 69 | "", 70 | "let pil1 = Rotate([0,1,0],-20,Translate([d,t1,0],pil,true));", 71 | "let pil2 = Rotate([0,1,0],-30,Translate([0,t1,0],pil,true));", 72 | "let pil3 = Rotate([0,1,0],-40,Translate([-d,t1,0],pil,false));", 73 | "", 74 | "let pilcombination = Union([pil1,pil2,pil3]); ", 75 | "", 76 | "Union([", 77 | " Rotate([0, 1, 0], -20, Translate([d, t2, 0], RoundedEndCylinder(6, 9))),", 78 | " Rotate([0, 1, 0], -30, Translate([0, t2, 0], RoundedEndCylinder(6, 9))),", 79 | " Rotate([0, 1, 0], -40, Translate([-d, t2, 0], RoundedEndCylinder(6, 9)))", 80 | "]);", 81 | "", 82 | "", 83 | "function RoundedEndCylinder(radius, height, centered = false) {", 84 | " return Union([", 85 | " Cylinder(radius, height, centered),", 86 | " Translate([0, 0, height], Sphere(radius)),", 87 | " Translate([0, 0, 0], Sphere(radius))", 88 | " ]);", 89 | "}", 90 | "", 91 | "", 92 | "" 93 | ] 94 | }, 95 | "width": 50, 96 | "isClosable": false, 97 | "reorderEnabled": true 98 | } 99 | ] 100 | }, 101 | { 102 | "type": "column", 103 | "isClosable": true, 104 | "reorderEnabled": true, 105 | "title": "", 106 | "width": 50, 107 | "content": [ 108 | { 109 | "type": "stack", 110 | "height": 80, 111 | "isClosable": true, 112 | "reorderEnabled": true, 113 | "title": "", 114 | "activeItemIndex": 0, 115 | "content": [ 116 | { 117 | "type": "component", 118 | "componentName": "cascadeView", 119 | "title": "CAD View", 120 | "componentState": { 121 | "componentName": "cascadeView", 122 | "MeshRes": 0.1, 123 | "Cache?": true, 124 | "Radius": 30 125 | }, 126 | "isClosable": false, 127 | "reorderEnabled": true 128 | } 129 | ] 130 | }, 131 | { 132 | "type": "stack", 133 | "height": 20, 134 | "isClosable": true, 135 | "reorderEnabled": true, 136 | "title": "", 137 | "activeItemIndex": 0, 138 | "content": [ 139 | { 140 | "type": "component", 141 | "componentName": "console", 142 | "title": "Console", 143 | "componentState": {}, 144 | "height": 20, 145 | "isClosable": false, 146 | "reorderEnabled": true 147 | } 148 | ] 149 | } 150 | ] 151 | } 152 | ] 153 | } 154 | ], 155 | "isClosable": true, 156 | "reorderEnabled": true, 157 | "title": "", 158 | "openPopouts": [], 159 | "maximisedItemId": null 160 | } -------------------------------------------------------------------------------- /parts/thread.js: -------------------------------------------------------------------------------- 1 | const toothProfile = new Sketch ([0,0]).Fillet(0.1) 2 | .LineTo([0.4,0.5]).Fillet(0.1) 3 | .LineTo([0.8,0]).Fillet(0.1) 4 | .LineTo([0.85,0]) 5 | .LineTo([-0.05,0]) 6 | .End(true).Wire() 7 | 8 | hackHelix(toothProfile, {rotations: 5, pitch: 1, diameter: 5}) 9 | Cylinder(2.5, 5.05) 10 | 11 | function hackHelix(shape, {diameter = 10, pitch = 1.5, rotations = 5, divisions = 360} = {}) { 12 | // hacky because the correct way to make a thread would be to extrude a 2d shape along a helix 13 | // which I think is supported by opencascade, but maybe not opencascade.js and therefore CascadeStudio 14 | // This will get you by for now though 15 | const degIncrement = 360/divisions 16 | const heightIncrement = pitch/divisions 17 | const circumferance = diameter*Math.PI 18 | const rad2Deg = num => num*180/Math.PI 19 | const pitchAngle = rad2Deg(Math.atan(pitch/circumferance)) 20 | 21 | const loftWires = Array.from({length: divisions*rotations+1}).map( 22 | (_, index) => Rotate([0,0,-1], index*degIncrement, 23 | Translate([0,diameter/2,index*heightIncrement], 24 | Rotate([0,1,0], 90,Rotate([0,-1,0], pitchAngle, shape)) 25 | ) 26 | ) 27 | ) 28 | 29 | return Loft(loftWires) 30 | } 31 | -------------------------------------------------------------------------------- /parts/transform.js: -------------------------------------------------------------------------------- 1 | let boxShape = Box(100,30, 10) 2 | 3 | Translate([0,50,30], boxShape, true); 4 | Rotate([0,1,0], -90, boxShape, true); 5 | 6 | let smallBox = Scale(0.2, boxShape, true); 7 | 8 | let displacedSmallBox = Translate([-50,0,0], smallBox, true); 9 | 10 | let largeBox = Transform([0, 0, 30], [[1, 00, 0], 30], 2.00, displacedSmallBox); 11 | -------------------------------------------------------------------------------- /parts/turning_torso.js: -------------------------------------------------------------------------------- 1 | // planview of turning torso 2 | 3 | let w1 = 17; // width front in meters 4 | let l1 = 17; // length of side walls front 5 | let l2 = 5 ; // length of first tapering part 6 | let l3 = 15; // length of last tapering part 7 | let l4 = 10; // distance from front face to column 8 | let a1 = 10.1; // angle [degrees] of first sidewalls to centerline 9 | let a2 = 50 ; // angle [degrees] of first tapering part to centerline 10 | let a3 = 34 ; // angle [degrees] of last tapering part to centerline 11 | let b1 = 0.8 ; // bulge-out of front wall 12 | let b2 = 1.2 ; // bulge-out of side walls 13 | let d = 10.6; // diameter of column 14 | let h = 190 ; // height of building 15 | let nb = 9 ; // number of blocks 16 | let hgap = 2 ; // height of gap 17 | let h1 = (h)/nb ; // height of block and gap 18 | let hblock = h1-hgap // height per block 19 | 20 | let atot = 90 ; // total rotation of tower 21 | let a5 = atot / (nb) ; // rotation of block 22 | let a4 = a5 * (h1-hgap)/h1 // rotation in each block, containing 5 floors of 6 in total 23 | 24 | // convert degrees to radians 25 | a1 = a1 * Math.PI / 180; 26 | a2 = a2 * Math.PI / 180; 27 | a3 = a3 * Math.PI / 180; 28 | 29 | // definition of points 30 | 31 | let p1x = 0 32 | let p1y = -(w1/2) 33 | let p2x = -b1 34 | let p2y = 0 35 | let p3x = 0 36 | let p3y = +w1/2 37 | let p4x = Math.cos(a1)*l1/2 - Math.sin(a1)*b2 38 | let p4y = p3y + Math.sin(a1)*l1/2 + Math.cos(a1)*b2 39 | let p5x = Math.cos(a1)*l1 40 | let p5y = p3y + Math.sin(a1)*l1 41 | let p6x = p5x + Math.cos(a2)*l2 42 | let p6y = p5y - Math.sin(a2)*l2 43 | let p7x = p6x + Math.cos(a3)*l3 44 | let p7y = 0 45 | let p8x = p6x 46 | let p8y = -p6y 47 | let p9x = p5x 48 | let p9y = -p5y 49 | let p10x = p4x 50 | let p10y = -p4y 51 | 52 | 53 | // combine x and y 54 | let p1 = [ p1x, p1y]; 55 | let p2 = [ p2x, p2y]; 56 | let p3 = [ p3x, p3y]; 57 | let p4 = [ p4x, p4y]; 58 | let p5 = [ p5x, p5y]; 59 | let p6 = [ p6x, p6y]; 60 | let p7 = [ p7x, p7y]; 61 | let p8 = [ p8x, p8y]; 62 | let p9 = [ p9x, p9y]; 63 | let p10 = [ p10x, p10y]; 64 | 65 | 66 | let planview = new Sketch(p1) 67 | .ArcTo(p2,p3) 68 | .ArcTo(p4,p5) 69 | .LineTo(p6) 70 | .LineTo(p7) 71 | .LineTo(p8) 72 | .LineTo(p9) 73 | .ArcTo(p10,p1) 74 | .End(false).Wire(true) 75 | 76 | planview = Translate([-l4,0,0],planview,false) 77 | 78 | let block1 = Translate([0,0,hgap],RotatedExtrude(planview, hblock, a4 )) 79 | let entrance = RotatedExtrude(planview, hgap, a4*(hgap/h1) ) 80 | 81 | // let window1 = Translate([-l4-2,w1/2-2,hgap+1.5],Box(2,1,1.5)) 82 | // let window2 = Translate([-l4-2,w1/2-4,hgap+1.5],Box(1.8,1,1.5)) 83 | // let window3 = Translate([-l4-2,w1/2-6,hgap+1.5],Box(1.6,1,1.5)) 84 | // let window4 = Translate([-l4-2,w1/2-8,hgap+1.5],Box(1.4,1,1.5)) 85 | // let window5 = Translate([-l4-2,w1/2-10,hgap+1.5],Box(1.4,1,1.5)) 86 | // let window6 = Translate([-l4-2,w1/2-12,hgap+1.5],Box(1.6,1,1.5)) 87 | // let window7 = Translate([-l4-2,w1/2-14,hgap+1.5],Box(1.8,1,1.5)) 88 | // let window8 = Translate([-l4-2,w1/2-16,hgap+1.5],Box(2,1,1.5)) 89 | // let block1w = Difference(block1, [window1, window2, window3, window4, window5, window6, window7, window8]); 90 | 91 | let truss1 = Translate([p5x-l4,p5y+0.5,0], Rotate([0,0,1],-28, Rotate([0,1,0], 90, Cylinder(0.40,23.6,false)))) 92 | let truss2 = Translate([p5x-l4,-p5y-0.5,0], Rotate([0,0,1],32, Rotate([0,1,0], 90, Cylinder(0.40,24.5,false)))) 93 | let truss3 = Rotate([0,0,1],a5,Translate([p5x-l4,-p5y-0.5,h1], 94 | Rotate([0,0,1],21.0, Rotate([0,1,0], 133, Cylinder(0.40,30.5,false))))) 95 | let truss4 = Rotate([0,0,1],a5,Translate([p5x-l4,p5y+0.5,h1], 96 | Rotate([0,0,1],-36.5, Rotate([0,1,0], 128, Cylinder(0.40,33,false))))) 97 | let truss5 = Rotate([1,0,0],-a5*1.3,Translate([27.5,0.7,0], Cylinder(0.40,h1+0.5,false))) 98 | 99 | 100 | for (level = 1 ; level <= 8 ; level++) 101 | { 102 | let blockn = Rotate([0,0,1], a5 *(level), Translate([0,0,((h1*level))],block1, true)) 103 | let truss1n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss1, true)) 104 | let truss2n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss2, true)) 105 | let truss3n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss3, true)) 106 | let truss4n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss4, true)) 107 | let truss5n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss5, true)) 108 | } 109 | let truss1top = Rotate([0,0,1], a5 *(nb), Translate([0,0,(h1*(nb))],truss1, true)) 110 | let truss2top= Rotate([0,0,1], a5 *(nb), Translate([0,0,(h1*(nb))],truss2, true)) 111 | let column = Translate([0,0,0],Cylinder(d/2, h , false)) 112 | -------------------------------------------------------------------------------- /parts/turning_torso_v2.js: -------------------------------------------------------------------------------- 1 | // planview of turning torso 2 | let w1 = 17; // width front in meters 3 | let l1 = 17; // length of side walls front 4 | let l2 = 5 ; // length of first tapering part 5 | let l3 = 15; // length of last tapering part 6 | let l4 = 10; // distance from front face to column 7 | let a1 = 10.1; // angle [degrees] of first sidewalls to centerline 8 | let a2 = 50 ; // angle [degrees] of first tapering part to centerline 9 | let a3 = 34 ; // angle [degrees] of last tapering part to centerline 10 | let b1 = 0.8 ; // bulge-out of front wall 11 | let b2 = 1.2 ; // bulge-out of side walls 12 | let d = 10.6; // diameter of column 13 | 14 | let h = 190 ; // height of building 15 | let nb = 9 ; // number of blocks 16 | let hgap = 2 ; // height of gap 17 | let h1 = (h)/nb ; // height of block and gap 18 | let hblock = h1-hgap // height per block 19 | 20 | let atot = 90 ; // total rotation of tower 21 | let a5 = atot / (nb) ; // rotation of block 22 | let a4 = a5 * (h1-hgap)/h1 // rotation in each block, containing 5 floors of 6 in total 23 | 24 | // convert degrees to radians 25 | a1 = a1 * Math.PI / 180; 26 | a2 = a2 * Math.PI / 180; 27 | a3 = a3 * Math.PI / 180; 28 | 29 | // definition of points in the planview 30 | let p1x = 0 31 | let p1y = -(w1/2) 32 | let p2x = -b1 33 | let p2y = 0 34 | let p3x = 0 35 | let p3y = +w1/2 36 | let p4x = Math.cos(a1)*l1/2 - Math.sin(a1)*b2 37 | let p4y = p3y + Math.sin(a1)*l1/2 + Math.cos(a1)*b2 38 | let p5x = Math.cos(a1)*l1 39 | let p5y = p3y + Math.sin(a1)*l1 40 | let p6x = p5x + Math.cos(a2)*l2 41 | let p6y = p5y - Math.sin(a2)*l2 42 | let p7x = p6x + Math.cos(a3)*l3 43 | let p7y = 0 44 | let p8x = p6x 45 | let p8y = -p6y 46 | let p9x = p5x 47 | let p9y = -p5y 48 | let p10x = p4x 49 | let p10y = -p4y 50 | 51 | 52 | // combine x and y 53 | let p1 = [ p1x, p1y]; 54 | let p2 = [ p2x, p2y]; 55 | let p3 = [ p3x, p3y]; 56 | let p4 = [ p4x, p4y]; 57 | let p5 = [ p5x, p5y]; 58 | let p6 = [ p6x, p6y]; 59 | let p7 = [ p7x, p7y]; 60 | let p8 = [ p8x, p8y]; 61 | let p9 = [ p9x, p9y]; 62 | let p10 = [ p10x, p10y]; 63 | 64 | // sketch of the planview 65 | let planview = new Sketch(p1) 66 | .ArcTo(p2,p3) 67 | .ArcTo(p4,p5) 68 | .LineTo(p6) 69 | .LineTo(p7) 70 | .LineTo(p8) 71 | .LineTo(p9) 72 | .ArcTo(p10,p1) 73 | .End(false).Wire(true) 74 | 75 | // translate the planview to have the center of rotation at the location of the column 76 | planview = Translate([-l4,0,0],planview,false) 77 | 78 | // build the first block of 5 floors 79 | let block1 = Translate([0,0,hgap],RotatedExtrude(planview, hblock, a4 )) 80 | let entrance = RotatedExtrude(planview, hgap, a4*(hgap/h1) ) 81 | 82 | // experiment to subtract windows from first block 83 | // let window1 = Translate([-l4-2,w1/2-2,hgap+1.5],Box(2,1,1.5)) 84 | // let window2 = Translate([-l4-2,w1/2-4,hgap+1.5],Box(1.8,1,1.5)) 85 | // let window3 = Translate([-l4-2,w1/2-6,hgap+1.5],Box(1.6,1,1.5)) 86 | // let window4 = Translate([-l4-2,w1/2-8,hgap+1.5],Box(1.4,1,1.5)) 87 | // let window5 = Translate([-l4-2,w1/2-10,hgap+1.5],Box(1.4,1,1.5)) 88 | // let window6 = Translate([-l4-2,w1/2-12,hgap+1.5],Box(1.6,1,1.5)) 89 | // let window7 = Translate([-l4-2,w1/2-14,hgap+1.5],Box(1.8,1,1.5)) 90 | // let window8 = Translate([-l4-2,w1/2-16,hgap+1.5],Box(2,1,1.5)) 91 | // let block1w = Difference(block1, [window1, window2, window3, window4, window5, window6, window7, window8]); 92 | 93 | // definition of the truss for each block 94 | let truss1 = Translate([p5x-l4,p5y+0.5,0], Rotate([0,0,1],-28, Rotate([0,1,0], 90, Cylinder(0.40,23.6,false)))) 95 | let truss2 = Translate([p5x-l4,-p5y-0.5,0], Rotate([0,0,1],32, Rotate([0,1,0], 90, Cylinder(0.40,24.5,false)))) 96 | let truss3 = Rotate([0,0,1],a5,Translate([p5x-l4,-p5y-0.5,h1], 97 | Rotate([0,0,1],21.0, Rotate([0,1,0], 133, Cylinder(0.40,30.5,false))))) 98 | let truss4 = Rotate([0,0,1],a5,Translate([p5x-l4,p5y+0.5,h1], 99 | Rotate([0,0,1],-36.5, Rotate([0,1,0], 128, Cylinder(0.40,33,false))))) 100 | let truss5 = Rotate([1,0,0],-a5*1.3,Translate([27.5,0.7,0], Cylinder(0.40,h1+0.5,false))) 101 | 102 | // repeat 8 blocks and trusses above the first block 103 | for (level = 1 ; level <= 8 ; level++) 104 | { 105 | let blockn = Rotate([0,0,1], a5 *(level), Translate([0,0,((h1*level))],block1, true)) 106 | let truss1n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss1, true)) 107 | let truss2n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss2, true)) 108 | let truss3n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss3, true)) 109 | let truss4n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss4, true)) 110 | let truss5n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss5, true)) 111 | } 112 | let truss1top = Rotate([0,0,1], a5 *(nb), Translate([0,0,(h1*(nb))],truss1, true)) 113 | let truss2top= Rotate([0,0,1], a5 *(nb), Translate([0,0,(h1*(nb))],truss2, true)) 114 | let column = Translate([0,0,0],Cylinder(d/2, h , false)) 115 | -------------------------------------------------------------------------------- /parts/turning_torso_v3.js: -------------------------------------------------------------------------------- 1 | // planview of turning torso 2 | let w1 = 17; // width front in meters 3 | let l1 = 17; // length of side walls front 4 | let l2 = 5 ; // length of first tapering part 5 | let l3 = 15; // length of last tapering part 6 | let l4 = 10; // distance from front face to column 7 | let a1 = 10.1; // angle [degrees] of first sidewalls to centerline 8 | let a2 = 50 ; // angle [degrees] of first tapering part to centerline 9 | let a3 = 34 ; // angle [degrees] of last tapering part to centerline 10 | let b1 = 0.8 ; // bulge-out of front wall 11 | let b2 = 1.2 ; // bulge-out of side walls 12 | let d = 10.6; // diameter of column 13 | 14 | let h = 190 ; // height of building 15 | let nb = 9 ; // number of blocks 16 | let hgap = 2 ; // height of gap 17 | let h1 = (h)/nb ; // height of block and gap 18 | let hblock = h1-hgap // height per block 19 | 20 | let atot = 90 ; // total rotation of tower 21 | let a5 = atot / (nb) ; // rotation of block 22 | let a4 = a5 * (h1-hgap)/h1 // rotation in each block, containing 5 floors of 6 in total 23 | 24 | // convert degrees to radians 25 | a1 = a1 * Math.PI / 180; 26 | a2 = a2 * Math.PI / 180; 27 | a3 = a3 * Math.PI / 180; 28 | 29 | // definition of points in the planview 30 | let p1x = 0 31 | let p1y = -(w1/2) 32 | let p2x = -b1 33 | let p2y = 0 34 | let p3x = 0 35 | let p3y = +w1/2 36 | let p4x = Math.cos(a1)*l1/2 - Math.sin(a1)*b2 37 | let p4y = p3y + Math.sin(a1)*l1/2 + Math.cos(a1)*b2 38 | let p5x = Math.cos(a1)*l1 39 | let p5y = p3y + Math.sin(a1)*l1 40 | let p6x = p5x + Math.cos(a2)*l2 41 | let p6y = p5y - Math.sin(a2)*l2 42 | let p7x = p6x + Math.cos(a3)*l3 43 | let p7y = 0 44 | let p8x = p6x 45 | let p8y = -p6y 46 | let p9x = p5x 47 | let p9y = -p5y 48 | let p10x = p4x 49 | let p10y = -p4y 50 | 51 | 52 | // combine x and y 53 | let p1 = [ p1x, p1y]; 54 | let p2 = [ p2x, p2y]; 55 | let p3 = [ p3x, p3y]; 56 | let p4 = [ p4x, p4y]; 57 | let p5 = [ p5x, p5y]; 58 | let p6 = [ p6x, p6y]; 59 | let p7 = [ p7x, p7y]; 60 | let p8 = [ p8x, p8y]; 61 | let p9 = [ p9x, p9y]; 62 | let p10 = [ p10x, p10y]; 63 | 64 | // sketch of the planview 65 | let planview = new Sketch(p1) 66 | .ArcTo(p2,p3) 67 | .ArcTo(p4,p5) 68 | .LineTo(p6) 69 | .LineTo(p7) 70 | .LineTo(p8) 71 | .LineTo(p9) 72 | .ArcTo(p10,p1) 73 | .End(false).Wire(true) 74 | 75 | // translate the planview to have the center of rotation at the location of the column 76 | planview1 = Translate([-l4,0,0],planview,false); 77 | 78 | // build the first block of 5 floors 79 | let block1 = Translate([0,0,hgap],RotatedExtrude(planview1, hblock, a4 , false)) 80 | let entrance = RotatedExtrude(planview1, hgap, a4*(hgap/h1), false ) 81 | 82 | // experiment to subtract windows from first block 83 | // let window1 = Translate([-l4-2,w1/2-2,hgap+1.5],Box(2,1,1.5)) 84 | // let window2 = Translate([-l4-2,w1/2-4,hgap+1.5],Box(1.8,1,1.5)) 85 | // let window3 = Translate([-l4-2,w1/2-6,hgap+1.5],Box(1.6,1,1.5)) 86 | // let window4 = Translate([-l4-2,w1/2-8,hgap+1.5],Box(1.4,1,1.5)) 87 | // let window5 = Translate([-l4-2,w1/2-10,hgap+1.5],Box(1.4,1,1.5)) 88 | // let window6 = Translate([-l4-2,w1/2-12,hgap+1.5],Box(1.6,1,1.5)) 89 | // let window7 = Translate([-l4-2,w1/2-14,hgap+1.5],Box(1.8,1,1.5)) 90 | // let window8 = Translate([-l4-2,w1/2-16,hgap+1.5],Box(2,1,1.5)) 91 | // let block1w = Difference(block1, [window1, window2, window3, window4, window5, window6, window7, window8]); 92 | 93 | // definition of the truss for each block 94 | let truss1 = Translate([p5x-l4,p5y+0.5,0], Rotate([0,0,1],-28, Rotate([0,1,0], 90, Cylinder(0.40,23.6,false)))) 95 | let truss2 = Translate([p5x-l4,-p5y-0.5,0], Rotate([0,0,1],32, Rotate([0,1,0], 90, Cylinder(0.40,24.5,false)))) 96 | let truss3 = Rotate([0,0,1],a5,Translate([p5x-l4,-p5y-0.5,h1], 97 | Rotate([0,0,1],21.0, Rotate([0,1,0], 133, Cylinder(0.40,30.5,false))))) 98 | let truss4 = Rotate([0,0,1],a5*0.85,Translate([p5x-l4,p5y+0.5,h1], 99 | Rotate([0,0,1],-36.5, Rotate([0,1,0], 128, Cylinder(0.40,32.5,false))))) 100 | let truss5 = Rotate([0,1,0],-1.35, Rotate([1,0,0],-a5*1.25,Translate([27.5,0.7,0], Cylinder(0.40,h1+0.5,false)))) 101 | 102 | // repeat 8 blocks and trusses above the first block 103 | for (level = 1 ; level <= 8 ; level++) 104 | { 105 | let blockn = Rotate([0,0,1], a5 *(level), Translate([0,0,((h1*level))],block1, true)) 106 | let truss1n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss1, true)) 107 | let truss2n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss2, true)) 108 | let truss3n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss3, true)) 109 | let truss4n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss4, true)) 110 | let truss5n = Rotate([0,0,1], a5 *(level), Translate([0,0,(h1*level)],truss5, true)) 111 | } 112 | let truss1top = Rotate([0,0,1], a5 *(nb), Translate([0,0,(h1*(nb))],truss1, true)) 113 | let truss2top= Rotate([0,0,1], a5 *(nb), Translate([0,0,(h1*(nb))],truss2, true)) 114 | let column = Translate([0,0,0],Cylinder(d/2, h , false)) 115 | --------------------------------------------------------------------------------