├── settings.gradle ├── .gitignore ├── resources └── img │ ├── screenshot-01.png │ ├── screenshot-02.png │ ├── screenshot-03.png │ ├── screenshot-04.png │ └── screenshot-05.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .travis.yml ├── src └── main │ ├── resources │ └── eu │ │ └── mihosoft │ │ └── vrl │ │ └── fxscad │ │ ├── java-keywords.css │ │ ├── BreadBoardConnector.jfxscad │ │ ├── BatteryHolder.jfxscad │ │ ├── ServoMount.jfxscad │ │ ├── BoardMount.jfxscad │ │ ├── Wheel.jfxscad │ │ └── Main.fxml │ └── java │ └── eu │ └── mihosoft │ └── vrl │ └── fxscad │ ├── OutputFilter.java │ ├── JFXScad.java │ ├── VFX3DUtil.java │ ├── RedirectableStream.java │ └── MainController.java ├── LICENSE ├── README.md ├── gradlew.bat ├── libs └── gradle │ └── javafx.plugin └── gradlew /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'JFXScad' 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /.nb-gradle/private/ 3 | /.idea/ 4 | .idea/ 5 | -------------------------------------------------------------------------------- /resources/img/screenshot-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miho/JFXScad/HEAD/resources/img/screenshot-01.png -------------------------------------------------------------------------------- /resources/img/screenshot-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miho/JFXScad/HEAD/resources/img/screenshot-02.png -------------------------------------------------------------------------------- /resources/img/screenshot-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miho/JFXScad/HEAD/resources/img/screenshot-03.png -------------------------------------------------------------------------------- /resources/img/screenshot-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miho/JFXScad/HEAD/resources/img/screenshot-04.png -------------------------------------------------------------------------------- /resources/img/screenshot-05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miho/JFXScad/HEAD/resources/img/screenshot-05.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miho/JFXScad/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun May 28 15:46:30 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | 5 | before_install: 6 | - "export DISPLAY=:99.0" 7 | - "export TERM=dumb" 8 | - "sh -e /etc/init.d/xvfb start" 9 | 10 | install: 11 | - TERM=dumb ./gradlew --refresh-dependencies --stacktrace 12 | 13 | script: 14 | - TERM=dumb ./gradlew build --stacktrace 15 | 16 | after_failure: 17 | - "cat ./build/test-results/*.xml" 18 | -------------------------------------------------------------------------------- /src/main/resources/eu/mihosoft/vrl/fxscad/java-keywords.css: -------------------------------------------------------------------------------- 1 | /* 2 | To change this license header, choose License Headers in Project Properties. 3 | To change this template file, choose Tools | Templates 4 | and open the template in the editor. 5 | */ 6 | /* 7 | Created on : 28.03.2014, 23:11:29 8 | Author : Michael Hoffer <info@michaelhoffer.de> 9 | */ 10 | 11 | .keyword { 12 | -fx-fill: brown; 13 | -fx-font-weight: bold; 14 | } -------------------------------------------------------------------------------- /src/main/java/eu/mihosoft/vrl/fxscad/OutputFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | package eu.mihosoft.vrl.fxscad; 8 | 9 | /** 10 | * 11 | * @author Michael Hoffer <info@michaelhoffer.de> 12 | */ 13 | @FunctionalInterface 14 | public interface OutputFilter { 15 | public boolean onMatch(String s); 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 by Michael Hoffer 2 | 3 | This program is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU Lesser General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public License 14 | along with this program. If not, see . 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JFXScad 2 | ========== 3 | 4 | [![Build Status](https://travis-ci.org/miho/JFXScad.svg?branch=master)](https://travis-ci.org/miho/JFXScad) 5 | 6 | JavaFX 3D Printing IDE based on [JCSG](https://github.com/miho/JCSG). 7 | 8 | ![](/resources/img/screenshot-02.png) 9 | 10 | ![](/resources/img/screenshot-03.png) 11 | 12 | ## How to Build JFXScad 13 | 14 | ### Requirements 15 | 16 | - Java >= 1.8 17 | - Internet connection (dependencies are downloaded automatically) 18 | - IDE: [Gradle](http://www.gradle.org/) Plugin (not necessary for command line usage) 19 | 20 | ### IDE (with Gradle Plugin) 21 | 22 | Open the `JFXScad` [Gradle](http://www.gradle.org/) project in your favourite IDE (tested with NetBeans 8) and build it 23 | by calling the `assemble` task. 24 | 25 | ### IDE (without Gradle Plugin) 26 | 27 | #### Eclipse 28 | 29 | Call the `eclipse` task from the command line and import the project to your workspace. 30 | 31 | #### IntelliJ 32 | 33 | Call the `idea` task from the command line and open the project. 34 | 35 | ### Command Line 36 | 37 | Navigate to the [Gradle](http://www.gradle.org/) project (e.g., `path/to/JFXScad`) and enter the following command 38 | 39 | #### Bash (Linux/OS X/Cygwin/other Unix-like shell) 40 | 41 | ```sh 42 | sh gradlew assemble 43 | ``` 44 | 45 | To run the JFXScad via gradle type: 46 | 47 | ```sh 48 | sh gradlew run 49 | ``` 50 | 51 | #### Windows (CMD) 52 | 53 | ```batch 54 | gradlew assemble 55 | ``` 56 | 57 | To run the JFXScad via gradle type: 58 | 59 | ```batch 60 | gradlew run 61 | ``` 62 | -------------------------------------------------------------------------------- /src/main/resources/eu/mihosoft/vrl/fxscad/BreadBoardConnector.jfxscad: -------------------------------------------------------------------------------- 1 | public class BreadBoardConnector { 2 | 3 | private double boardMountingThickness = 2.0; 4 | 5 | private double breadBoardThickness = 9; 6 | 7 | private double connectorDepth = 20; 8 | 9 | private double pegHeight = 1; 10 | private double pegToothHeight = 0.3; 11 | private double pegOverlap = 0.6; 12 | 13 | private double boardMountingWidth = 8.1; 14 | 15 | private double breadBoardToPiMountDistance = 21; 16 | 17 | public CSG toCSG() { 18 | 19 | double th = 2; 20 | double smh = boardMountingWidth; 21 | double bmth = boardMountingThickness; 22 | double bbpbd = breadBoardToPiMountDistance ; 23 | double bbth = breadBoardThickness - th; 24 | 25 | double pth = pegToothHeight; 26 | double ph = pegHeight; 27 | double po = pegOverlap; 28 | 29 | return Extrude.points(Vector3d.xyz(0, 0, connectorDepth), 30 | Vector3d.xy(-th, -th), 31 | Vector3d.xy(smh + pth + ph, -th), 32 | Vector3d.xy(smh + pth + Math.max(ph / 3, 0.4), 0 + po), 33 | Vector3d.xy(smh + pth, 0 + po), 34 | Vector3d.xy(smh, 0), 35 | Vector3d.xy(0, 0), 36 | Vector3d.xy(0, bmth), 37 | Vector3d.xy(smh, bmth), 38 | Vector3d.xy(smh, bmth + th), 39 | Vector3d.xy(0, bmth + th), 40 | Vector3d.xy(0, bmth +bbpbd-th), 41 | Vector3d.xy(smh, bmth +bbpbd-th), 42 | Vector3d.xy(smh, bmth + th + bbpbd - th), 43 | Vector3d.xy(0, bmth + th + bbpbd - th), 44 | Vector3d.xy(0, bmth + th + bbpbd + bbth), 45 | Vector3d.xy(smh, bmth + th +bbpbd + bbth), 46 | Vector3d.xy(smh, bmth + th +bbpbd + bbth + th), 47 | Vector3d.xy(0, bmth + th +bbpbd + bbth + th), 48 | Vector3d.xy(-th, bmth + th +bbpbd + bbth + th) 49 | ); 50 | 51 | } 52 | } 53 | 54 | result = new BreadBoardConnector().toCSG() -------------------------------------------------------------------------------- /src/main/resources/eu/mihosoft/vrl/fxscad/BatteryHolder.jfxscad: -------------------------------------------------------------------------------- 1 | public class BatteryHolder { 2 | 3 | private double mountingThickness = 2.0; 4 | 5 | private double boardToBoardSpacing = 30.0; 6 | 7 | private double connectorDepth = 15; 8 | 9 | private double pegHeight = 1; 10 | private double pegToothHeight = 0.3; 11 | private double pegOverlap = 0.6; 12 | 13 | private double boardMountingWidth = 8.11; 14 | 15 | private double batteryHeight = 21.5; 16 | private double batteryLength = 53.5; 17 | 18 | private double footHeight = 10; 19 | private double footSize = 10; 20 | 21 | 22 | public CSG toCSG() { 23 | 24 | double th = 2; 25 | double smh = boardMountingWidth; 26 | double mth = mountingThickness; 27 | 28 | double pth = pegToothHeight; 29 | double ph = pegHeight; 30 | double po = pegOverlap; 31 | 32 | double o = 13; 33 | 34 | return Extrude.points(Vector3d.xyz(0, 0, connectorDepth), 35 | Vector3d.xy(-th, -th), 36 | Vector3d.xy(smh + pth + ph+o, -th), 37 | Vector3d.xy(smh + pth + Math.max(ph / 3, 0.4)+o, 0 + po), 38 | Vector3d.xy(smh + pth+o, 0 + po), 39 | Vector3d.xy(smh+o, 0), 40 | Vector3d.xy(0+o, 0), 41 | Vector3d.xy(0+o, mth), 42 | Vector3d.xy(smh+o, mth), 43 | Vector3d.xy(smh+o, mth + th), 44 | Vector3d.xy(0, mth + th), 45 | Vector3d.xy(0, mth + th + batteryHeight), 46 | Vector3d.xy(batteryLength, mth + th + batteryHeight), 47 | Vector3d.xy(batteryLength, mth + th + batteryHeight * 0.3), 48 | Vector3d.xy(batteryLength + th, mth + th + batteryHeight * 0.3), 49 | Vector3d.xy(batteryLength + th, mth + th + batteryHeight + th), 50 | Vector3d.xy(0, mth + th + batteryHeight + th), 51 | Vector3d.xy(0, mth + th + batteryHeight + th + footHeight - th * 2), 52 | Vector3d.xy(footSize, mth + th + batteryHeight + th + footHeight - th), 53 | Vector3d.xy(footSize, mth + th + batteryHeight + th + footHeight), 54 | Vector3d.xy(-th, mth + th + batteryHeight + th + footHeight) 55 | ); 56 | } 57 | } 58 | 59 | result = new BatteryHolder().toCSG() 60 | -------------------------------------------------------------------------------- /src/main/java/eu/mihosoft/vrl/fxscad/JFXScad.java: -------------------------------------------------------------------------------- 1 | package eu.mihosoft.vrl.fxscad; 2 | 3 | import java.io.IOException; 4 | import java.util.logging.Level; 5 | import java.util.logging.Logger; 6 | import javafx.application.Application; 7 | import javafx.fxml.FXMLLoader; 8 | import javafx.scene.Parent; 9 | import javafx.scene.PerspectiveCamera; 10 | import javafx.scene.Scene; 11 | import javafx.scene.control.TextArea; 12 | import javafx.stage.Stage; 13 | 14 | public class JFXScad extends Application { 15 | 16 | private static TextArea log; 17 | private static MainController controller; 18 | 19 | /** 20 | * @param args the command line arguments 21 | */ 22 | public static void main(String[] args) { 23 | launch(args); 24 | } 25 | 26 | @Override 27 | public void start(Stage primaryStage) throws Exception { 28 | Parent main = loadFromFXML(); 29 | 30 | Scene scene = new Scene(main, 1024, 768,true); 31 | 32 | scene.getStylesheets().add(JFXScad.class.getResource("java-keywords.css"). 33 | toExternalForm()); 34 | 35 | PerspectiveCamera camera = new PerspectiveCamera(); 36 | 37 | scene.setCamera(camera); 38 | 39 | primaryStage.setTitle("JavaFXScad"); 40 | primaryStage.setScene(scene); 41 | primaryStage.setMinWidth(1024); 42 | primaryStage.setMinHeight(768); 43 | primaryStage.show(); 44 | } 45 | 46 | public static Parent loadFromFXML() { 47 | 48 | if (controller!=null) { 49 | throw new IllegalStateException("UI already loaded"); 50 | } 51 | 52 | FXMLLoader fxmlLoader = new FXMLLoader( 53 | JFXScad.class.getResource("Main.fxml")); 54 | try { 55 | fxmlLoader.load(); 56 | } catch (IOException ex) { 57 | Logger.getLogger(JFXScad.class.getName()). 58 | log(Level.SEVERE, null, ex); 59 | } 60 | 61 | Parent root = fxmlLoader.getRoot(); 62 | 63 | root.getStylesheets().add(JFXScad.class.getResource("java-keywords.css"). 64 | toExternalForm()); 65 | 66 | controller = fxmlLoader.getController(); 67 | log = controller.getLogView(); 68 | 69 | 70 | return root; 71 | } 72 | 73 | public static TextArea getLogView() { 74 | 75 | if (log==null) { 76 | throw new IllegalStateException("Load the UI first."); 77 | } 78 | 79 | return log; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /src/main/resources/eu/mihosoft/vrl/fxscad/ServoMount.jfxscad: -------------------------------------------------------------------------------- 1 | public class ServoMount { 2 | 3 | //standard servo 4 | private double servoWidth = 40.0; 5 | private double servoThickness = 19.0; 6 | private double borderThickness = 2; 7 | private double overlap = 3; 8 | private double servoMountHeight = 20; 9 | 10 | private double boardMountingThickness = 2; 11 | private double boardHolderLength = 12; 12 | 13 | private double boardMountingWidth = 8.1; 14 | 15 | private double pegHeight= 1; 16 | private double pegToothHeight = 0.6; 17 | private double pegOverlap = 0.5; 18 | 19 | public CSG toCSGSimple() { 20 | 21 | return Extrude.points(Vector3d.xyz(0, 0, servoMountHeight), 22 | Vector3d.xy(0, servoThickness), 23 | Vector3d.xy(overlap, servoThickness), 24 | Vector3d.xy(-borderThickness, servoThickness + borderThickness), 25 | Vector3d.xy(-borderThickness, -borderThickness), 26 | Vector3d.xy(servoWidth + borderThickness, -borderThickness), 27 | Vector3d.xy(servoWidth + borderThickness, servoThickness + borderThickness), 28 | Vector3d.xy(servoWidth - overlap, servoThickness), 29 | Vector3d.xy(servoWidth, servoThickness), 30 | Vector3d.xy(servoWidth, 0), 31 | Vector3d.xy(0, 0) 32 | ); 33 | } 34 | 35 | public CSG toCSG() { 36 | CSG bm1 = boardMount().transformed(Transform.unity().rotY(90).rotZ(90). 37 | translate(borderThickness, borderThickness, -boardHolderLength + borderThickness)); 38 | CSG bm2 = bm1.transformed(Transform.unity(). 39 | translateX(servoWidth -boardHolderLength + borderThickness*2)); 40 | CSG sm = toCSGSimple(); 41 | 42 | return sm.union(bm1).union(bm2); 43 | } 44 | 45 | private CSG boardMount() { 46 | 47 | double h = boardMountingWidth; 48 | 49 | List points = Arrays.asList(Vector3d.ZERO, 50 | Vector3d.xy(0, -borderThickness), 51 | Vector3d.xy(boardMountingThickness + borderThickness, -borderThickness), 52 | Vector3d.xy(boardMountingThickness + borderThickness, h + pegToothHeight+pegHeight), 53 | Vector3d.xy(boardMountingThickness - pegOverlap, h + pegToothHeight), 54 | Vector3d.xy(boardMountingThickness, h), 55 | Vector3d.xy(boardMountingThickness, 0) 56 | ); 57 | 58 | Collections.reverse(points); 59 | 60 | return Extrude.points(Vector3d.xyz(0,0,boardHolderLength), 61 | points 62 | ); 63 | } 64 | 65 | } 66 | 67 | 68 | result = new ServoMount().toCSG() -------------------------------------------------------------------------------- /src/main/resources/eu/mihosoft/vrl/fxscad/BoardMount.jfxscad: -------------------------------------------------------------------------------- 1 | public class RaspberryPiBPlusMount { 2 | 3 | public CSG board() { 4 | double board_thickness = 2; 5 | double bottom_thickness = 2; 6 | 7 | double board_mounting_height = 4; 8 | 9 | double outer_offset = 4; 10 | double inner_offset = 4; 11 | 12 | double board_width = 85; 13 | double board_height = 56; 14 | double bw = board_width; 15 | double bh = board_height; 16 | 17 | double sd1 = 14; 18 | double sd2 = 11; 19 | double sd3 = 18; 20 | 21 | Polygon board_points_exact = Polygon.fromPoints( 22 | Vector3d.xy(0, 0), 23 | Vector3d.xy(0, bh), 24 | Vector3d.xy(bw, bh), 25 | Vector3d.xy(bw, bh - sd1), 26 | Vector3d.xy(bw - sd3, bh - sd1), 27 | Vector3d.xy(bw - sd3, sd2), 28 | Vector3d.xy(bw, sd2), 29 | Vector3d.xy(bw, 0) 30 | ); 31 | 32 | // outer offset 33 | double ox1 = outer_offset; 34 | double oy1 = outer_offset; 35 | 36 | // inner offset 37 | double ox2 = inner_offset; 38 | double oy2 = inner_offset; 39 | 40 | CSG outer = Extrude.points( 41 | Vector3d.xyz(0, 0, bottom_thickness), 42 | Vector3d.xy(0-ox1,0-oy1), 43 | Vector3d.xy(0-ox1,bh+oy1), 44 | Vector3d.xy(bw+ox1,bh+oy1), 45 | Vector3d.xy(bw+ox1,sd2), 46 | Vector3d.xy(bw+ox1,0-oy1) 47 | ); 48 | 49 | CSG inner = Extrude.points( 50 | Vector3d.xyz(0, 0, bottom_thickness), 51 | Vector3d.xy(0+ox2,0+oy2), 52 | Vector3d.xy(0+ox2,bh-oy2), 53 | Vector3d.xy(bw-ox2,bh-oy2), 54 | Vector3d.xy(bw-ox2,sd2-oy2), 55 | Vector3d.xy(bw-ox2,0+oy2) 56 | ); 57 | 58 | return outer.difference(inner).transformed(Transform.unity().rotX(180).translateY(-bh)); 59 | } 60 | 61 | public CSG boardAndPegs() { 62 | 63 | double board_width = 85.6; 64 | double board_height = 56; 65 | double bw = board_width; 66 | double bh = board_height; 67 | 68 | double outer_offset = 4; 69 | 70 | double bottom_thickness = 2; 71 | 72 | CSG board = board(); 73 | 74 | CSG peg1 = RaspberryPeg.peg().transformed( 75 | Transform.unity().scaleY(0.9)).transformed( 76 | Transform.unity().translate(0,bh-36,-bottom_thickness)); 77 | 78 | CSG peg2 = RaspberryPeg.peg().transformed(Transform.unity().scaleY(2)). 79 | transformed(Transform.unity().translate(22,bh,-bottom_thickness). 80 | rotZ(90)); 81 | 82 | 83 | CSG peg3 = RaspberryPeg.peg().transformed(Transform.unity(). 84 | translate(bw-outer_offset,bh,-bottom_thickness).rotZ(90)); 85 | 86 | CSG peg4 = RaspberryPeg.peg().transformed(Transform.unity(). 87 | translate(bw,bh-outer_offset*2,-bottom_thickness).rotZ(180)); 88 | CSG peg4b = RaspberryPeg.peg().transformed(Transform.unity(). 89 | translate(bw,outer_offset,-bottom_thickness).rotZ(180)); 90 | 91 | CSG peg5 = RaspberryPeg.peg().transformed(Transform.unity().scaleY(2)). 92 | transformed(Transform.unity().translate(bw-19,0,-bottom_thickness). 93 | rotZ(270)); 94 | 95 | CSG peg6 = RaspberryPeg.peg().transformed(Transform.unity(). 96 | translate(bw-62,0,-bottom_thickness).rotZ(270)); 97 | 98 | CSG union = board.union(peg1,peg2,peg3,peg4,peg4b,peg5,peg6); 99 | 100 | return union; 101 | 102 | } 103 | } 104 | 105 | result = new RaspberryPiBPlusMount().boardAndPegs() -------------------------------------------------------------------------------- /src/main/resources/eu/mihosoft/vrl/fxscad/Wheel.jfxscad: -------------------------------------------------------------------------------- 1 | public class ServoWheel { 2 | 3 | private double toothLength = 0.7; 4 | private double toothWidth = 0.1; 5 | private double toothHeight = 0.3; 6 | private int toothCount = 25; 7 | private double headHeight = 4; 8 | private double headDiameter = 5.92; 9 | private double headScrewDiameter = 2.5; 10 | private double headThickness = 1.1; 11 | 12 | private ServoHead servoHead = new ServoHead( 13 | toothLength, toothWidth, toothHeight, toothCount, 14 | headHeight, headDiameter, headScrewDiameter, headThickness); 15 | 16 | private int numberOfArms = 3; 17 | double innerWidth = 7; 18 | double outerWidth = 3.5; 19 | double thickness = 2; 20 | double radius = 27.5; 21 | double ringThickness = 3; 22 | double wheelThickness = 5; 23 | 24 | double minorArmLength = radius * 0.75; 25 | double minorArmHeight = headHeight; 26 | double minorArmThickness = 2.5; 27 | 28 | double outerRingThickness = wheelThickness/3.0*2; 29 | double outerRingDepth = 0.5; 30 | 31 | public CSG toCSG() { 32 | 33 | double dt = 360.0 / numberOfArms; 34 | 35 | CSG arms = null; 36 | 37 | for (int i = 0; i < numberOfArms; i++) { 38 | 39 | CSG arm = servoArm(innerWidth, outerWidth, thickness, radius, ringThickness, minorArmThickness, minorArmLength, minorArmHeight).transformed(unity().rotZ(dt * i)); 40 | 41 | if (arms == null) { 42 | arms = arm; 43 | } else { 44 | arms = arms.union(arm); 45 | } 46 | } 47 | 48 | CSG sHead = servoHead.servoHeadFemale(); 49 | 50 | CSG screwHole = new Cylinder(headScrewDiameter / 2.0, ringThickness * 2, 16).toCSG(); 51 | 52 | if (arms != null) { 53 | sHead = sHead.union(arms); 54 | } 55 | 56 | sHead = sHead.difference(screwHole); 57 | 58 | CSG outerWheelCylinder = new Cylinder(radius, wheelThickness, 64).toCSG(); 59 | CSG innerWheelCylinder = new Cylinder(radius - ringThickness, wheelThickness, 64).toCSG(); 60 | 61 | CSG ring = outerWheelCylinder.difference(innerWheelCylinder); 62 | 63 | CSG wheel = ring.union(sHead); 64 | 65 | 66 | 67 | CSG outerRingOutCylinder = new Cylinder(radius, outerRingThickness, 64).toCSG(); 68 | CSG outerRingInnerCylinder = new Cylinder(radius-outerRingDepth, outerRingThickness, 64).toCSG(); 69 | 70 | CSG outerRing = outerRingOutCylinder.difference(outerRingInnerCylinder). 71 | transformed(unity().translateZ(wheelThickness*0.5-outerRingThickness*0.5)); 72 | 73 | wheel = wheel.difference(outerRing); 74 | 75 | return wheel; 76 | } 77 | 78 | public CSG servoArm( 79 | double innerWidth, double outerWidth, double thickness, double radius, double wheelThickness, double minorArmThickness, double minorArmLegth, double minorArmHeight) { 80 | CSG mainArm = Extrude.points(Vector3d.z(thickness), 81 | Vector3d.xy(-innerWidth * 0.5, 0), 82 | Vector3d.xy(innerWidth * 0.5, 0), 83 | Vector3d.xy(outerWidth * 0.5, radius - wheelThickness), 84 | Vector3d.xy(-outerWidth * 0.5, radius - wheelThickness) 85 | ); 86 | 87 | CSG minorArm = Extrude.points(Vector3d.z(minorArmThickness), 88 | Vector3d.xy(headDiameter * 0.5 + headThickness * 0.5, thickness), 89 | Vector3d.xy(minorArmLegth - headDiameter * 0.5 - headThickness * 0.5, thickness), 90 | Vector3d.xy(headDiameter * 0.5 + headThickness * 0.5, minorArmHeight + thickness * 0.5)).transformed(unity().rot(-90, 0, 0).translateZ(-minorArmThickness * 0.5)); 91 | 92 | minorArm = minorArm.transformed(unity().rotZ(-90)); 93 | 94 | return mainArm.union(minorArm); 95 | 96 | } 97 | 98 | } 99 | 100 | 101 | result = new ServoWheel().toCSG() 102 | -------------------------------------------------------------------------------- /libs/gradle/javafx.plugin: -------------------------------------------------------------------------------- 1 | /* 2 | * Bootstrap script for the Gradle JavaFX Plugin. 3 | * (based on http://plugins.jasoft.fi/vaadin.plugin) 4 | * 5 | * The script will add the plugin to the build script 6 | * dependencies and apply the plugin to the project. If you do not want 7 | * this behavior you can copy and paste the below configuration into your 8 | * own build script and define your own repository and version for the plugin. 9 | */ 10 | 11 | import org.gradle.api.GradleException; 12 | 13 | 14 | 15 | buildscript { 16 | repositories { 17 | mavenLocal() 18 | maven { 19 | name = 'BinTray' 20 | url = 'http://dl.bintray.com/content/shemnon/javafx-gradle/' 21 | } 22 | maven { 23 | name = 'CloudBees Snapshot' 24 | url = 'http://repository-javafx-gradle-plugin.forge.cloudbees.com/snapshot' 25 | } 26 | ivy { 27 | url = 'http://repository-javafx-gradle-plugin.forge.cloudbees.com/snapshot' 28 | } 29 | mavenCentral() 30 | } 31 | dependencies { 32 | try { 33 | assert (jfxrtDir != null) 34 | } catch (RuntimeException re) { 35 | ext.jfxrtDir = "." 36 | } 37 | 38 | ext.searchFile = {Map places, List searchPaths, String searchID -> 39 | File result = null; 40 | places.each { k, v -> 41 | if (result != null) return; 42 | project.logger.debug("Looking for $searchID in $k") 43 | def dir = v() 44 | if (dir == null) { 45 | project.logger.debug("$k not set") 46 | } else { 47 | project.logger.debug("$k is $dir") 48 | searchPaths.each { s -> 49 | if (result != null) return; 50 | File f = new File(dir, s); 51 | project.logger.debug("Trying $f.path") 52 | if (f.exists() && f.file) { 53 | project.logger.debug("found $searchID as $result") 54 | result = f; 55 | } 56 | } 57 | } 58 | } 59 | if (!result?.file) { 60 | throw new GradleException("Could not find $searchID, please set one of ${places.keySet()}"); 61 | } else { 62 | project.logger.info("$searchID: ${result}") 63 | return result 64 | } 65 | } 66 | ext.findJFXJar = { 67 | return searchFile([ 68 | 'jfxrtDir in Gradle Properties': {jfxrtDir}, 69 | 'JFXRT_HOME in System Environment': {System.env['JFXRT_HOME']}, 70 | 'JAVA_HOME in System Environment': {System.env['JAVA_HOME']}, 71 | 'java.home in JVM properties': {System.properties['java.home']} 72 | ], 73 | ['jfxrt.jar', 'lib/jfxrt.jar', 'lib/ext/jfxrt.jar', 'jre/lib/jfxrt.jar', 'jre/lib/ext/jfxrt.jar'], 74 | 'JavaFX Runtime Jar') 75 | } 76 | 77 | ext.findAntJavaFXJar = { 78 | return searchFile([ 79 | 'jfxrtDir in Gradle Properties': {jfxrtDir}, 80 | 'JFXRT_HOME in System Environment': {System.env['JFXRT_HOME']}, 81 | 'JAVA_HOME in System Environment': {System.env['JAVA_HOME']}, 82 | 'java.home in JVM properties': {System.properties['java.home']} 83 | ], 84 | ['ant-javafx.jar', 'lib/ant-javafx.jar', '../lib/ant-javafx.jar'], 85 | 'JavaFX Packager Tools') 86 | } 87 | 88 | 89 | classpath 'org.bitbucket.shemnon.javafxplugin:gradle-javafx-plugin:8.1.1' 90 | classpath project.files(findAntJavaFXJar()) 91 | classpath project.files(findJFXJar()) 92 | } 93 | } 94 | 95 | if (!project.plugins.findPlugin(org.bitbucket.shemnon.javafxplugin.JavaFXPlugin)) { 96 | project.apply(plugin: org.bitbucket.shemnon.javafxplugin.JavaFXPlugin) 97 | } -------------------------------------------------------------------------------- /src/main/resources/eu/mihosoft/vrl/fxscad/Main.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 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 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |