diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 989e74ff9..16af67824 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -15,6 +15,8 @@ jobs: runs-on: ubuntu-latest steps: + - name: Install updated FreeType + run: sudo apt-get update;sudo apt-get install libfreetype6 - name: Checkout repository and submodules uses: actions/checkout@v2 with: @@ -37,7 +39,7 @@ jobs: export DISPLAY=:0 - name: Pull a JavaFX JDK - run: wget http://static.azul.com/zulu/bin/zulu8.33.0.1-ca-fx-jdk8.0.192-linux_x64.tar.gz + run: wget http://static.azul.com/zulu/bin/zulu8.78.0.19-ca-fx-jdk8.0.412-linux_x64.tar.gz - name: After JDK download, list directory contnts run: pwd; ls -la @@ -46,7 +48,7 @@ jobs: uses: actions/setup-java@v1 with: java-version: 1.8 - jdkFile: ./zulu8.33.0.1-ca-fx-jdk8.0.192-linux_x64.tar.gz + jdkFile: ./zulu8.78.0.19-ca-fx-jdk8.0.412-linux_x64.tar.gz - name: Build with Gradle @@ -59,17 +61,17 @@ jobs: run: cat /home/runner/work/bowler-script-kernel/bowler-script-kernel/build/reports/tests/test/index.html - name: Test Bezier - run: xvfb-run -s '-screen 0 1024x768x24' java -Dprism.verbose=true -Dprism.forceGPU=true -jar build/libs/bowler-kernel.jar -g https://gist.github.com/4aeeaa49bd3a807eed8f8ff3dea84c48.git BezierEditorDemo.groovy + run: xvfb-run -s '-screen 0 1024x768x24' java -Dprism.order=sw -Dprism.verbose=true -jar build/libs/bowler-kernel.jar -g https://gist.github.com/4aeeaa49bd3a807eed8f8ff3dea84c48.git BezierEditorDemo.groovy - name: start xvfb run: Xvfb :0 & - name: Test Local - run: xvfb-run -s '-screen 0 1024x768x24' java -Dprism.verbose=true -Dprism.forceGPU=true -jar build/libs/bowler-kernel.jar -f kernel-return-test.groovy + run: xvfb-run -s '-screen 0 1024x768x24' java -Dprism.order=sw -Dprism.verbose=true -jar build/libs/bowler-kernel.jar -f kernel-return-test.groovy - name: Clean Cad run: rm -rf $HOME/bowler-workspace/gitcache/github.com/Hephaestus-Arm/HephaestusArm2 - name: build Cad - run: xvfb-run -s '-screen 0 1024x768x24' java -Dprism.verbose=true -Dprism.forceGPU=true -jar build/libs/bowler-kernel.jar -g https://github.com/Hephaestus-Arm/HephaestusArm2.git hephaestus.xml + run: xvfb-run -s '-screen 0 1024x768x24' java -Dprism.order=sw -Dprism.verbose=true -jar build/libs/bowler-kernel.jar -g https://github.com/Hephaestus-Arm/HephaestusArm2.git hephaestus.xml diff --git a/.gitignore b/.gitignore index e36658e55..57e9b71bf 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ physicsTest /test*.stl /test.blend1 /test.* +/doodle/ diff --git a/GithubPasswordManager b/GithubPasswordManager index eda3dc602..9da2226c2 160000 --- a/GithubPasswordManager +++ b/GithubPasswordManager @@ -1 +1 @@ -Subproject commit eda3dc602e1bd50d2340fc9477b76476158c6921 +Subproject commit 9da2226c2553c0ede08a62bcf18c69e43175c2a6 diff --git a/JCSG b/JCSG index a6ad60b1a..7d28ab20c 160000 --- a/JCSG +++ b/JCSG @@ -1 +1 @@ -Subproject commit a6ad60b1a722898c4ed761437d031817ec7a42a8 +Subproject commit 7d28ab20c12b936b32e527d32017b22bdd955c87 diff --git a/build.gradle b/build.gradle index c37148d2b..579b5234b 100755 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,6 @@ buildscript { maven { url "https://repo1.maven.org/maven2/" }, - //jcenter(), mavenCentral(), maven { url "https://plugins.gradle.org/m2/" @@ -115,256 +114,153 @@ String getOsArch() { return System.getProperty("os.arch"); } -//https://oss.sonatype.org/service/local/repositories/releases/content/com/neuronrobotics/nrjavaserial/3.10.1/nrjavaserial-3.10.1.jar repositories { mavenCentral() maven { - url 'https://mlt.jfrog.io/artifactory/mlt-mvn-releases-local/' + url 'https://commonwealthrobotics.com/maven/' + allowInsecureProtocol = true } maven { url 'https://repo.maven.apache.org/maven2/' } - + maven { url 'https://repo1.maven.org/maven2/'} -//https://jcenter.bintray.com< - maven { url 'https://jcenter.bintray.com/'} - - //jcenter() - maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } - //maven { url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' } - maven { url 'https://oss.sonatype.org/content/repositories/releases/' } - //com.neuronrobotics hosting point - maven { url 'https://oss.sonatype.org/content/repositories/staging/' } - - maven { - url "https://repo.myrobotlab.org/artifactory/myrobotlab/" - content { - includeGroup("de.dfki.mary") - } - } + + +// maven { +// url "https://repo.myrobotlab.org/artifactory/myrobotlab/" +// content { +// includeGroup("de.dfki.mary") +// } +// } maven { url 'https://maven-central.storage-download.googleapis.com/repos/central/data/'} maven {url 'https://repo.jenkins-ci.org/public/'} - // maven { - // url "https://dl.bintray.com/ihmcrobotics/maven-release/" - // content { - // includeGroup("us.ihmc") - // } - // } - // maven { - // url "https://dl.bintray.com/ihmcrobotics/maven-vendor/" - // content { - // includeGroup("us.ihmc.thirdparty.jinput") - // } - // } + maven { + url "https://repo.jenkins-ci.org/releases/" + } + + maven { url "https://jitpack.io" } + maven { url "https://repo.eclipse.org/content/groups/releases/" } + maven { url "https://dl.bintray.com/dfki-lt/maven/" } + maven { url "https://raw.github.com/marytts/marytts/master/repository/" } + maven { url "https://repo.jenkins-ci.org/public/" } + } dependencies { + //api 'com.neuronrobotics:JavaCad:2.9.5' + api project('JCSG') + api project('java-bowler') + api project('GithubPasswordManager:GithubPasswordManager') + //compile group: "de.swirtz", name: "ktsRunner", version: "0.0.7" -api 'us.ihmc:jinput:2.0.6-ihmc2' -api group: 'us.ihmc', name: 'ihmc-native-library-loader', version: '1.3.1' -//implementation 'net.java.jinput:jinput:2.0.10' // pegged to Java 17, no MacOS m1 support until java updated -//implementation 'net.java.jinput:jinput:2.0.10:natives-all' + api 'us.ihmc:jinput:2.0.6-ihmc2' + api group: 'us.ihmc', name: 'ihmc-native-library-loader', version: '1.3.1' -api 'com.google.crypto.tink:tink:1.3.0-rc1' + api 'com.google.crypto.tink:tink:1.3.0-rc1' -api group: 'org.json', name: 'json', version: '20180813' + api group: 'org.json', name: 'json', version: '20180813' -api 'gov.nist.math:jama:1.0.2' + api 'gov.nist.math:jama:1.0.2' -api group: 'org.fxmisc.richtext', name: 'richtextfx', version: '0.6' + api group: 'org.fxmisc.richtext', name: 'richtextfx', version: '0.6' -api group: 'org.reactfx', name: 'reactfx', version: '2.0-SNAPSHOT' + api group: 'org.reactfx', name: 'reactfx', version: '2.0-SNAPSHOT' -// https://mvnrepository.com/artifact/org.apache.groovy/groovy -api group: 'org.apache.groovy', name: 'groovy', version: '4.0.22' -//make grapes work -api group: 'org.apache.ivy', name: 'ivy', version: '2.5.1' + // https://mvnrepository.com/artifact/org.apache.groovy/groovy + api group: 'org.apache.groovy', name: 'groovy', version: '4.0.22' + //make grapes work + api group: 'org.apache.ivy', name: 'ivy', version: '2.5.1' //compile group: 'org.controlsfx', name: 'controlsfx', version: '8.0.6' -api group: 'commons-lang', name: 'commons-lang', version: '2.6' -api group: 'commons-codec', name: 'commons-codec', version: '1.7' - - + api group: 'commons-lang', name: 'commons-lang', version: '2.6' + api group: 'commons-codec', name: 'commons-codec', version: '1.7' // https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit - implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '5.13.1.202206130422-r' + api group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '5.13.1.202206130422-r' // https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit.ssh.apache - implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit.ssh.apache', version: '5.13.1.202206130422-r' - + api group: 'org.eclipse.jgit', name: 'org.eclipse.jgit.ssh.apache', version: '5.13.1.202206130422-r' // https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 -api group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.2.1' - - + api group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.2.1' -api group: 'com.squareup.okhttp', name: 'okhttp-urlconnection', version: '2.0.0' -api group: 'org.mockito', name: 'mockito-all', version: '1.9.5' -api group: 'com.infradna.tool', name: 'bridge-method-injector', version: '1.14' + api group: 'com.squareup.okhttp', name: 'okhttp-urlconnection', version: '2.0.0' + api group: 'org.mockito', name: 'mockito-all', version: '1.9.5' + api group: 'com.infradna.tool', name: 'bridge-method-injector', version: '1.14' -api 'com.miglayout:miglayout-swing:4.2' -api 'commons-io:commons-io:2.6' -api group:'org.python',name:'jython',version:'2.5.3' -api group:'org.python',name:'jython-standalone',version:'2.5.2' -api 'org.clojure:clojure:1.8.0' + api 'com.miglayout:miglayout-swing:4.2' + api 'commons-io:commons-io:2.6' + api group:'org.python',name:'jython',version:'2.5.3' + api group:'org.python',name:'jython-standalone',version:'2.5.2' + api 'org.clojure:clojure:1.8.0' // jetty server -api "org.eclipse.jetty:jetty-server:9.0.2.v20130417" -api "org.eclipse.jetty:jetty-servlet:9.0.2.v20130417" -api "org.eclipse.jetty:jetty-servlets:9.0.2.v20130417" -api "org.eclipse.jetty:jetty-webapp:9.0.2.v20130417" -api "javax.servlet:javax.servlet-api:3.1.0" + api "org.eclipse.jetty:jetty-server:9.0.2.v20130417" + api "org.eclipse.jetty:jetty-servlet:9.0.2.v20130417" + api "org.eclipse.jetty:jetty-servlets:9.0.2.v20130417" + api "org.eclipse.jetty:jetty-webapp:9.0.2.v20130417" + api "javax.servlet:javax.servlet-api:3.1.0" + api group: 'java3d', name: 'vecmath', version: '1.3.1' + api 'org.slf4j:slf4j-simple:1.6.1' - //compile 'org.clojure:tools.nrepl:0.2.10' - //compile "overtone:overtone:0.9.1" - //compile "edu.cmu.sphinx:sphinx4-core:5prealpha-SNAPSHOT" - //compile "edu.cmu.sphinx:sphinx4-data:5prealpha-SNAPSHOT" -api group: 'java3d', name: 'vecmath', version: '1.3.1' -api 'org.slf4j:slf4j-simple:1.6.1' + api group:'de.huxhorn.sulky', name:'de.huxhorn.sulky.3rdparty.jlayer', version:'1.0' + api 'com.google.code.gson:gson:2.5' + api 'org.jsoup:jsoup:1.8.3' + api 'org.apache.httpcomponents:httpclient:4.5.1' - - //compile group: 'com.neuronrobotics', name:'GithubPasswordManager', version:'0.6.1' - //compile "com.neuronrobotics:JavaCad:0.14.0" - //compile project('JCSG') -api 'com.neuronrobotics:JavaCad:1.1.1' - - //compile "com.neuronrobotics:CHDK-PTP-Java:0.5.3-SNAPSHOT" - //compile "com.neuronrobotics:java-bowler:3.25.4" -api project('java-bowler') -api project('GithubPasswordManager:GithubPasswordManager') - //compile fileTree (dir: ':java-bowler/libs/', includes: ['*.jar']) - //compile fileTree (dir: '../java-bowler/build/libs/', includes: ['nrsdk-3.23.3-jar-with-dependencies.jar']) - //compile fileTree (dir: '../JCSG/build/libs/', includes: ['JavaCad-0.8.2.jar']) - //compile "com.neuronroboticsp:WalnutiQ:2.3.3" - - - /* - String basedir =System.getenv("OPENCV_DIR")+"/java/opencv-249.jar"; - if(isWindows()){ - basedir =System.getenv("OPENCV_DIR")+"\\..\\..\\java\\opencv-249.jar"; - println("OPENCV_DIR="+basedir); - compile files(basedir) - } - if(isOSX()){ - basedir =System.getenv("OPENCV_DIR")+"../../java/opencv-249.jar"; - println("OPENCV_DIR="+basedir); - if(System.getenv("OPENCV_DIR")!=null) - compile files(basedir) - else - //If you set your OPENCV_DIR environment variable, then we wouldnt have to do hacky things - compile files('/Applications/BowlerStudio.app/Contents/MacOS/opencv249build/bin/opencv-249.jar') - } - if(isLinux()){ - //compile files('/usr/share/java/opencv-249.jar') - if(new File("/usr/share/OpenCV/java/").exists()){ - System.out.println("Using the legacy opencv dir ") - compile fileTree (dir: '/usr/share/OpenCV/java/', includes: ['*opencv-24*.jar']) - }else{ - compile fileTree (dir: '/usr/share/java/', includes: ['*opencv-24*.jar']) - } - } - */ - //compile group: 'jfree', name: 'jfreechart', version: '1.0.12' - //compile group: 'jexcelapi', name: 'jxl', version: '2.4.2' - //compile group: 'com.google.zxing', name: 'zxing-parent', version: '3.2.0' - //compile group:'com.github.ellzord', name:'JALSE', version:'1.0.9' - -api group:'de.huxhorn.sulky', name:'de.huxhorn.sulky.3rdparty.jlayer', version:'1.0' - //compile("org.springframework.boot:spring-boot-starter-web:1.2.7.RELEASE") - -api 'com.google.code.gson:gson:2.5' -api 'org.jsoup:jsoup:1.8.3' -api 'org.apache.httpcomponents:httpclient:4.5.1' - //compile 'cz.advel.jbullet:jbullet:20101010-1' - //compile 'org.bubblecloud.jbullet:jbullet:2.72.2.4'// jars local because mave repo for this went down - //compile "alda:alda:1.0.0-rc14" - - //Deep Learning 4 j and dependancies - /* - compile 'org.deeplearning4j:deeplearning4j-core:0.4-rc3.8' - //compile 'org.nd4j:nd4j-x86:0.4-rc3.8' - compile 'org.deeplearning4j:deeplearning4j-nlp:0.4-rc3.8' - compile 'org.deeplearning4j:deeplearning4j-ui:0.4-rc3.8' - //compile 'com.google.guava:guava:19.0' - compile 'org.nd4j:canova-nd4j-image:0.0.0.14' - compile 'org.nd4j:canova-nd4j-codec:0.0.0.14' - compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.5.1' - */ - // JScience: - //compile 'org.jscience:jscience:4.3.1' - - //compile 'javax.media:jmf:2.1.1e' - - //Weka - //compile 'nz.ac.waikato.cms.weka:weka-stable:3.6.13' - - //Firmata -api 'com.github.kurbatov:firmata4j:2.3.4.1' + api 'com.github.kurbatov:firmata4j:2.3.4.1' testImplementation 'junit:junit:4.10' -//api fileTree (dir: 'libs', includes: ['*.jar']) - // https://mvnrepository.com/artifact/com.github.stephengold/jbullet api group: 'com.github.stephengold', name: 'jbullet', version: '1.0.3' - - implementation('de.dfki.mary:voice-cmu-slt-hsmm:5.2.1') - { + +// implementation('de.dfki.mary:voice-cmu-slt-hsmm:5.2.1') { +// exclude group: 'commons-io', module: 'commons-io' +// exclude group: 'com.twmacinta', module: 'fast-md5' +// exclude group: 'gov.nist.math', module: 'Jampack' +// } + implementation('de.dfki.mary:voice-dfki-poppy-hsmm:5.2') { exclude group: 'commons-io', module: 'commons-io' exclude group: 'com.twmacinta', module: 'fast-md5' exclude group: 'gov.nist.math', module: 'Jampack' } - implementation('de.dfki.mary:voice-dfki-poppy-hsmm:5.2') - { + + implementation('de.dfki.mary:voice-dfki-prudence-hsmm:5.2') { exclude group: 'commons-io', module: 'commons-io' exclude group: 'com.twmacinta', module: 'fast-md5' exclude group: 'gov.nist.math', module: 'Jampack' } -// implementation('de.dfki.mary:voice-cmu-awb-time:5.2') -// { -// exclude group: 'commons-io', module: 'commons-io' -// } - implementation('de.dfki.mary:voice-dfki-prudence-hsmm:5.2') - { + implementation('de.dfki.mary:voice-dfki-spike-hsmm:5.2') { exclude group: 'commons-io', module: 'commons-io' exclude group: 'com.twmacinta', module: 'fast-md5' exclude group: 'gov.nist.math', module: 'Jampack' } - implementation('de.dfki.mary:voice-dfki-spike-hsmm:5.2') - { + implementation('de.dfki.mary:voice-cmu-rms-hsmm:5.2') { exclude group: 'commons-io', module: 'commons-io' + exclude group: 'com.twmacinta', module: 'fast-md5' exclude group: 'gov.nist.math', module: 'Jampack' } - implementation('de.dfki.mary:voice-cmu-rms-hsmm:5.2') - { - exclude group: 'commons-io', module: 'commons-io' - - exclude group: 'com.twmacinta', module: 'fast-md5' - exclude group: 'gov.nist.math', module: 'Jampack' - } - implementation('de.dfki.mary:voice-dfki-obadiah-hsmm:5.2') - { - exclude group: 'commons-io', module: 'commons-io' - - exclude group: 'com.twmacinta', module: 'fast-md5' - exclude group: 'gov.nist.math', module: 'Jampack' - } - implementation('de.dfki.mary:voice-cmu-rms-hsmm:5.2') - { - exclude group: 'commons-io', module: 'commons-io' - - exclude group: 'com.twmacinta', module: 'fast-md5' - exclude group: 'gov.nist.math', module: 'Jampack' - } - implementation('de.dfki.mary:voice-cmu-bdl-hsmm:5.2') - { - exclude group: 'commons-io', module: 'commons-io' - - exclude group: 'com.twmacinta', module: 'fast-md5' - exclude group: 'gov.nist.math', module: 'Jampack' - } - implementation('de.dfki.mary:marytts-lang-en:5.2.1') - { + implementation('de.dfki.mary:voice-dfki-obadiah-hsmm:5.2') { + exclude group: 'commons-io', module: 'commons-io' + + exclude group: 'com.twmacinta', module: 'fast-md5' + exclude group: 'gov.nist.math', module: 'Jampack' + } + implementation('de.dfki.mary:voice-cmu-rms-hsmm:5.2') { + exclude group: 'commons-io', module: 'commons-io' + + exclude group: 'com.twmacinta', module: 'fast-md5' + exclude group: 'gov.nist.math', module: 'Jampack' + } + implementation('de.dfki.mary:voice-cmu-bdl-hsmm:5.2') { + exclude group: 'commons-io', module: 'commons-io' + + exclude group: 'com.twmacinta', module: 'fast-md5' + exclude group: 'gov.nist.math', module: 'Jampack' + } + implementation('de.dfki.mary:marytts-lang-en:5.2.1') { exclude group: 'commons-io', module: 'commons-io' exclude group: 'com.twmacinta', module: 'fast-md5' exclude group: 'gov.nist.math', module: 'Jampack' @@ -383,7 +279,19 @@ api 'com.github.kurbatov:firmata4j:2.3.4.1' //MuJoCo implementation group: 'org.bytedeco', name: 'javacpp', version: '1.5.7' - implementation group: 'com.neuronrobotics', name: 'mujoco-java', version:'3.1.3-pre.11' + implementation group: 'com.neuronrobotics', name: 'mujoco-java', version:'3.1.3-pre.17' + //Java17 update + // JAXB API + implementation 'javax.xml.bind:jaxb-api:2.3.1' + + // JAXB Implementation + implementation 'com.sun.xml.bind:jaxb-impl:2.3.1' + + // JAXB Core + implementation 'com.sun.xml.bind:jaxb-core:2.3.0.1' + + // Java Activation needed by JAXB + implementation 'javax.activation:javax.activation-api:1.2.0' // https://mvnrepository.com/artifact/org.robokind/org.robokind.api.speech implementation group: 'org.robokind', name: 'org.robokind.api.speech', version: '0.9.5' @@ -391,8 +299,7 @@ api 'com.github.kurbatov:firmata4j:2.3.4.1' // https://mvnrepository.com/artifact/net.lingala.zip4j/zip4j implementation group: 'net.lingala.zip4j', name: 'zip4j', version: '2.11.5' // https://mvnrepository.com/artifact/com.alphacephei/vosk - implementation( 'com.alphacephei:vosk:0.3.38') - { + implementation( 'com.alphacephei:vosk:0.3.38') { exclude group: 'net.java.dev.jna', module: 'jna' } // Add OpenCV @@ -404,7 +311,7 @@ api 'com.github.kurbatov:firmata4j:2.3.4.1' implementation 'org.apache.commons:commons-compress:1.26.2' // Addiing advance system execution for advanced editors implementation 'org.apache.commons:commons-exec:1.3' - + implementation 'org.tukaani:xz:1.9' implementation 'org.brotli:dec:0.1.2' // Add this for Brotli support // Add 7z native bindings @@ -412,8 +319,6 @@ api 'com.github.kurbatov:firmata4j:2.3.4.1' implementation 'net.sf.sevenzipjbinding:sevenzipjbinding-all-platforms:16.02-2.01' // inkscape loading implementation group: 'org.apache.xmlgraphics', name: 'batik-all', version: '1.17' - - } @@ -457,13 +362,13 @@ archivesBaseName = "bowler-script-kernel" task javadocJar(type: Jar) { if (project == rootProject) - classifier = 'javadoc' + classifier = 'javadoc' from javadoc } task sourcesJar(type: Jar) { if (project == rootProject) - classifier = 'sources' + classifier = 'sources' from sourceSets.main.allSource } @@ -475,47 +380,4 @@ test { exceptionFormat = 'full' } } -/* - signing { - sign configurations.archives - } - uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - pom.project { - name 'Bowler Scripting Kernel' - packaging 'jar' - // optionally artifactId can be defined here - description 'A command line utility for accsing the bowler framework.' - url 'http://neuronrobotics.com' - scm { - connection 'scm:git:https://github.com/NeuronRobotics/bowler-script-kernel.git' - developerConnection 'scm:git:git@github.com:NeuronRobotics/bowler-script-kernel.git' - url 'https://github.com/NeuronRobotics/bowler-script-kernel' - } - licenses { - license { - name 'The Apache License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - developers { - developer { - id 'madhephaestus' - name 'Kevin Harrington' - email 'kharrington@neuronrobotics.com' - } - } - } - } - } - } - */ diff --git a/build123dTest.py b/build123dTest.py new file mode 100644 index 000000000..2f3836048 --- /dev/null +++ b/build123dTest.py @@ -0,0 +1,3 @@ +from build123d import * + +cube = Box(10, 10, 10) diff --git a/java-bowler b/java-bowler index f0c79d208..23f29281b 160000 --- a/java-bowler +++ b/java-bowler @@ -1 +1 @@ -Subproject commit f0c79d2083d993f5721d608b295e813ab5098c3f +Subproject commit 23f29281be61bacbd0313509bacf74746a63ccb8 diff --git a/settings.gradle b/settings.gradle index 6e36ec4f9..1e26e61b9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ include 'java-bowler' +include 'JCSG' include 'GithubPasswordManager:GithubPasswordManager' diff --git a/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/BezierEditor.java b/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/BezierEditor.java index acc48e76a..60c53ce82 100644 --- a/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/BezierEditor.java +++ b/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/BezierEditor.java @@ -133,21 +133,21 @@ public BezierEditor(File data, int numPoints) { endManip.addSaveListener(() -> { save(); }); - endManip.addEventListener(() -> { + endManip.addEventListener(e -> { update(); }); cp1Manip.addSaveListener(() -> { save(); }); - cp1Manip.addEventListener(() -> { + cp1Manip.addEventListener(e -> { update(); }); cp2Manip.addSaveListener(() -> { save(); }); - cp2Manip.addEventListener(() -> { + cp2Manip.addEventListener(e -> { update(); }); ArrayList parts = new ArrayList<>(); @@ -232,7 +232,7 @@ private TransformNR updateLines(CartesianManipulator m, CartesianManipulator p, TransformNR az = new TransformNR(0, 0, 0, new RotationNR(0, -xyRot, 0)); TransformNR reorented = az.times(vect); - // System.out.println("CP1 "+reorented.getX()+" "+reorented.getY()+" + // com.neuronrobotics.sdk.common.Log.error("CP1 "+reorented.getX()+" "+reorented.getY()+" // "+reorented.getZ()); double xzRot = Math.toDegrees(Math.atan2(reorented.getZ(), reorented.getY())); @@ -325,14 +325,14 @@ public void save() { database.put("bezier", bezData); new Thread(() -> { - System.out.println("Saving to file " + cachejson.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Saving to file " + cachejson.getAbsolutePath()); String writeOut = gson.toJson(database, TT_mapStringString); if (url != null) { try { ScriptingEngine.pushCodeToGit(url, ScriptingEngine.getFullBranch(url), gitfile, writeOut, "Saving Bezier"); } catch (Exception e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } else { @@ -340,7 +340,7 @@ public void save() { try { cachejson.createNewFile(); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } OutputStream out = null; @@ -351,7 +351,7 @@ public void save() { // completes // normally } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } finally { IOUtils.closeQuietly(out); @@ -381,7 +381,7 @@ public void setStartManip(CartesianManipulator start) { start.addSaveListener(() -> { save(); }); - start.addEventListener(() -> { + start.addEventListener(e -> { update(); }); start.addDependant(cp1Manip); diff --git a/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/CartesianManipulator.java b/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/CartesianManipulator.java index 037d0372b..c2764ae30 100644 --- a/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/CartesianManipulator.java +++ b/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/CartesianManipulator.java @@ -9,6 +9,8 @@ import eu.mihosoft.vrl.v3d.CSG; import eu.mihosoft.vrl.v3d.Cylinder; import eu.mihosoft.vrl.v3d.Vector3d; +import javafx.event.EventHandler; +import javafx.scene.input.MouseEvent; import javafx.scene.paint.Color; import javafx.scene.transform.Affine; @@ -17,7 +19,7 @@ public class CartesianManipulator { CSG manip1 = new Cylinder(0, 5, 40, 10).toCSG().setColor(Color.BLUE); CSG manip2 = new Cylinder(0, 5, 40, 10).toCSG().roty(-90).setColor(Color.RED); CSG manip3 = new Cylinder(0, 5, 40, 10).toCSG().rotx(90).setColor(Color.GREEN); - private manipulation[] manipulationList = new manipulation[3]; + private Manipulation[] manipulationList = new Manipulation[3]; TransformNR globalPose; public CartesianManipulator(TransformNR globalPose) { @@ -25,12 +27,17 @@ public CartesianManipulator(TransformNR globalPose) { manip1.setMfg(incoming -> null); manip2.setMfg(incoming -> null); manip3.setMfg(incoming -> null); - manipulationList[0] = new manipulation(manipulationMatrix, new Vector3d(0, 0, 1), manip1, globalPose); - manipulationList[1] = new manipulation(manipulationMatrix, new Vector3d(0, 1, 0), manip3, globalPose); - manipulationList[2] = new manipulation(manipulationMatrix, new Vector3d(1, 0, 0), manip2, globalPose); + manipulationList[0] = new Manipulation(manipulationMatrix, new Vector3d(0, 0, 1), globalPose); + manipulationList[1] = new Manipulation(manipulationMatrix, new Vector3d(0, 1, 0), globalPose); + manipulationList[2] = new Manipulation(manipulationMatrix, new Vector3d(1, 0, 0), globalPose); + int i=0; + for(CSG manip:Arrays.asList(manip1,manip3,manip2)) { + manip.getStorage().set("manipulator", manipulationList[i++].map); + manip.setManipulator(manipulationMatrix); + } } - public void addEventListener(Runnable r) { + public void addEventListener(EventHandler r) { for (int i = 0; i < 3; i++) manipulationList[i].addEventListener(r); } @@ -45,15 +52,15 @@ public List get() { } public double getX() { - return manipulationList[2].currentPose.getX(); + return manipulationList[2].getCurrentPose().getX(); } public double getY() { - return manipulationList[1].currentPose.getY(); + return manipulationList[1].getCurrentPose().getY(); } public double getZ() { - return manipulationList[0].currentPose.getZ(); + return manipulationList[0].getCurrentPose().getZ(); } public void addDependant(CartesianManipulator r) { @@ -68,7 +75,7 @@ public boolean isMoving() { } public void clearListeners() { - // TODO Auto-generated method stub + // Auto-generated method stub for (int i = 0; i < 3; i++) manipulationList[i].clearListeners(); } diff --git a/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/IFrameProvider.java b/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/IFrameProvider.java new file mode 100644 index 000000000..9df2bd4d8 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/IFrameProvider.java @@ -0,0 +1,7 @@ +package com.neuronrobotics.bowlerkernel.Bezier3d; + +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +public interface IFrameProvider { + public TransformNR get(); +} diff --git a/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/Manipulation.java b/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/Manipulation.java new file mode 100644 index 000000000..2d3cb742e --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/Manipulation.java @@ -0,0 +1,375 @@ +package com.neuronrobotics.bowlerkernel.Bezier3d; + +import java.util.ArrayList; +import javafx.scene.paint.Color; +import java.util.HashMap; +import java.util.List; + +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.sdk.addons.kinematics.math.*; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Vector3d; +import javafx.event.EventHandler; +import javafx.event.EventType; +import javafx.scene.input.MouseEvent; +import javafx.scene.paint.Color; +import javafx.scene.transform.Affine; +import javafx.scene.paint.PhongMaterial; + +public class Manipulation { + public HashMap, EventHandler> map = new HashMap<>(); + double startx = 0; + double starty = 0; + double newx = 0; + double newy = 0; + double newz = 0; + boolean dragging = false; + private double increment = 0.000001; + private static IInteractiveUIElementProvider ui = new IInteractiveUIElementProvider() { + }; + + private ArrayList> eventListeners = new ArrayList<>(); + private ArrayList saveListeners = new ArrayList<>(); + private ArrayList dependants = new ArrayList<>(); + private Affine manipulationMatrix; + private TransformNR orintation; + private TransformNR globalPose= new TransformNR(); + private TransformNR currentPose=new TransformNR(); + private IFrameProvider frameOfReference = ()->new TransformNR(); + //private PhongMaterial color;// = new PhongMaterial(getColor()); + //private PhongMaterial highlight = new PhongMaterial(Color.GOLD); + + public enum DragState { + IDLE, Dragging + } + + private DragState state = DragState.IDLE; + private boolean resizeAllowed=true; + + public void addEventListener(EventHandler r) { + if (eventListeners.contains(r)) + return; + eventListeners.add(r); + } + + public void addDependant(Manipulation r) { + if (dependants.contains(r)) + return; + dependants.add(r); + + } + + public void addSaveListener(Runnable r) { + if (saveListeners.contains(r)) + return; + saveListeners.add(r); + } + + public void clearListeners() { + // Auto-generated method stub + saveListeners.clear(); + eventListeners.clear(); + } + + private void fireMove(TransformNR trans, MouseEvent event2) { + for (Manipulation R : dependants) { + R.performMove(trans,event2); + } + //com.neuronrobotics.sdk.common.Log.debug("Mouse event "+event2.getEventType()); + for (EventHandler R : eventListeners) { + R.handle(event2); + } + } + + public void fireSave() { + new Thread(() -> { + for (Runnable R : saveListeners) { + R.run(); + } + }).start(); + } +// public manipulation(Affine mm, Vector3d o, CSG m, TransformNR p) { +// +// } + public Manipulation(Affine mm, Vector3d o, TransformNR p) { + this.manipulationMatrix = mm; + this.orintation = new TransformNR(o.x, o.y, o.z); + //this.manip = m; + //color = new PhongMaterial(m.getColor()); + this.setGlobalPose(p); + setCurrentPose(p.copy()); + getUi().runLater(() -> { + try { + TransformFactory.nrToAffine(getGlobalPose(), manipulationMatrix); + } catch (Throwable t) { + t.printStackTrace(); + } + }); + + map.put(MouseEvent.ANY, getMouseEvents()); + + } + + public EventHandler getMouseEvents() { + return new EventHandler() { + @Override + public void handle(MouseEvent event) { + String name = event.getEventType().getName(); + if(event.isControlDown()) + return; + switch (name) { + case "MOUSE_PRESSED": + if(event.isPrimaryButtonDown()) + pressed(event); + break; + case "MOUSE_DRAGGED": + dragged(event,event); + break; + case "MOUSE_RELEASED": + release(event); + break; + case "MOUSE_MOVED": + // ignore + break; +// case "MOUSE_ENTERED": +// m.getMesh().setMaterial(highlight); +// break; +// case "MOUSE_EXITED": +// if (state == DragState.IDLE) +// m.getMesh().setMaterial(color); +// break; + default: + // com.neuronrobotics.sdk.common.Log.error("UNKNOWN! Mouse event "+name); + break; + } + + } + }; + } + + private void pressed(MouseEvent event) { + setState(DragState.Dragging); + new Thread(() -> { + event.consume(); + dragging = false; + for (Manipulation R : dependants) { + + R.dragging = false; + } + }).start(); + } + + private double getDepthNow() { + return -1600 / getUi().getCamerDepth(); + } + + private void release(MouseEvent event) { + mouseRelease(event); + for (Manipulation R : dependants) + R.mouseRelease(event); + setState(DragState.IDLE); + //manip.getMesh().setMaterial(color); + } + + private void dragged(MouseEvent event, MouseEvent event2) { + if(resizeAllowed) + if(getState()==DragState.Dragging) { + getUi().runLater(() -> { + setDragging(event); + double deltx = (startx - event.getScreenX()); + double delty = (starty - event.getScreenY()); + double x = deltx/ getDepthNow() ; + double y = delty/ getDepthNow() ; + //com.neuronrobotics.sdk.common.Log.error("Moved "+x+" "+y); + if(Double.isFinite(y) && Double.isFinite(x)) { + TransformNR trans = new TransformNR(x, y, 0, new RotationNR()); + performMove(trans,event2); + }else { + com.neuronrobotics.sdk.common.Log.error("ERROR?"); + } + }); + event.consume(); + } + } + + public boolean isMoving() { + return getState() == DragState.Dragging; + } + + private void mouseRelease(MouseEvent event) { + if (dragging) { + dragging = false; + getGlobalPose().setX(newx); + getGlobalPose().setY(newy); + getGlobalPose().setZ(newz); + if(event!=null) + event.consume(); + fireSave(); + } + } + + private void setDragging(MouseEvent event) { + if (dragging == false) { + startx = event.getScreenX(); + starty = event.getScreenY(); + } + dragging = true; + for (Manipulation R : dependants) { + R.setDragging(event); + } + } + + private void performMove(TransformNR trans, MouseEvent event2) { + TransformNR camerFrame = getUi().getCamerFrame(); + TransformNR globalTMP = new TransformNR(camerFrame.getRotation()); + try { + + TransformNR global = globalTMP.times(trans); + TransformNR wp = getFrameOfReference().copy(); + wp.setX(0); + wp.setY(0); + wp.setZ(0); + global=wp.inverse().times(global); + + newx = round((global.getX() * orintation.getX() )); + newy = round((global.getY() * orintation.getY() )); + newz = round((global.getZ() * orintation.getZ() )); + + TransformNR globalTrans = globalPose.copy().setRotation(new RotationNR()); + global.setX(newx); + global.setY(newy); + global.setZ(newz); + global.setRotation(new RotationNR()); + TransformNR o =wp.times(global).times(wp.inverse()).setRotation(new RotationNR()); + global=globalTrans.times(o); + + + global.setRotation(new RotationNR()); + setGlobal(global); + //com.neuronrobotics.sdk.common.Log.error(" drag "+global.getX()+" , "+global.getY()+" ,"+global.getZ()); + + }catch(Throwable t) { + t.printStackTrace(); + } + fireMove(trans,event2); + } + private double round(double in) { + return Math.round(in / increment) * increment; + } + + public void setGlobal(TransformNR global) { +// newx = global.getX(); +// newy = global.getY(); +// newz = global.getZ(); + getCurrentPose().setX(newx); + getCurrentPose().setY(newy); + getCurrentPose().setZ(newz); + getUi().runLater(() -> { + TransformFactory.nrToAffine(global, manipulationMatrix); + }); + } + + public static IInteractiveUIElementProvider getUi() { + return ui; + } + + public static void setUi(IInteractiveUIElementProvider ui) { + Manipulation.ui = ui; + } + public void reset() { + newx = 0; + newy = 0; + newz = 0; + getGlobalPose().setX(0); + getGlobalPose().setY(0); + getGlobalPose().setZ(0); + setGlobal(new TransformNR(0, 0, 0, new RotationNR())); + } + public void set(double newX, double newY, double newZ) { + newx = newX; + newy = newY; + newz = newZ; + getGlobalPose().setX(newX); + getGlobalPose().setY(newY); + getGlobalPose().setZ(newZ); + setGlobal(new TransformNR(newX, newY, newZ, new RotationNR())); + for (EventHandler R : eventListeners) { + R.handle(null); + } + + } + public void setInReferenceFrame(double newX, double newY, double newZ) { + TransformNR inLocal = new TransformNR(newX, newY, newZ); + TransformNR wp = new TransformNR( getFrameOfReference() .getRotation()); + inLocal=wp.times(inLocal); + inLocal.setRotation(new RotationNR()); + //com.neuronrobotics.sdk.common.Log.error("Setting in reference frame:"+inLocal.toSimpleString()); + setGlobal(inLocal); + for (EventHandler R : eventListeners) { + R.handle(null); + } + + } + public TransformNR getGlobalPose() { + return globalPose; + } + public TransformNR getGlobalPoseInReferenceFrame() { + TransformNR globalPose = getGlobalPose().copy(); + TransformNR wp = new TransformNR( getFrameOfReference() .getRotation()); + globalPose=wp.times(globalPose); + globalPose.setRotation(new RotationNR()); + return globalPose; + } + public TransformNR getCurrentPoseInReferenceFrame() { + TransformNR globalPose = getCurrentPose().copy(); + TransformNR wp = new TransformNR( getFrameOfReference() .getRotation()); + globalPose=wp.times(globalPose); + globalPose.setRotation(new RotationNR()); + return globalPose; + } + public void setGlobalPose(TransformNR globalPose) { + this.globalPose = globalPose; + } + + public double getIncrement() { + return increment; + } + + public void setIncrement(double increment) { + this.increment = increment; + } + + public TransformNR getCurrentPose() { + return currentPose; + } + + public void setCurrentPose(TransformNR currentPose) { + this.currentPose = currentPose; + } + + public void cancel() { + release(null); + } + + public TransformNR getFrameOfReference() { + return frameOfReference.get(); + } + + public void setFrameOfReference(IFrameProvider frameOfReference) { + this.frameOfReference = frameOfReference; + } + + public void setUnlocked(boolean resizeAllowed) { + this.resizeAllowed = resizeAllowed; + } + + public DragState getState() { + return state; + } + + public void setState(DragState state) { + this.state = state; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/manipulation.java b/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/manipulation.java deleted file mode 100644 index 1f108085c..000000000 --- a/src/main/java/com/neuronrobotics/bowlerkernel/Bezier3d/manipulation.java +++ /dev/null @@ -1,252 +0,0 @@ -package com.neuronrobotics.bowlerkernel.Bezier3d; - -import java.util.ArrayList; -import javafx.scene.paint.Color; -import java.util.HashMap; - -import com.neuronrobotics.bowlerstudio.physics.TransformFactory; -import com.neuronrobotics.sdk.addons.kinematics.math.*; - -import eu.mihosoft.vrl.v3d.CSG; -import eu.mihosoft.vrl.v3d.Vector3d; -import javafx.event.EventHandler; -import javafx.event.EventType; -import javafx.scene.input.MouseEvent; -import javafx.scene.paint.Color; -import javafx.scene.transform.Affine; -import javafx.scene.paint.PhongMaterial; - -public class manipulation { - HashMap, EventHandler> map = new HashMap<>(); - double startx = 0; - double starty = 0; - double newx = 0; - double newy = 0; - double newz = 0; - TransformNR camFrame = null; - boolean dragging = false; - double depth = 0; - private static IInteractiveUIElementProvider ui = new IInteractiveUIElementProvider() { - }; - - private ArrayList eventListeners = new ArrayList<>(); - private ArrayList saveListeners = new ArrayList<>(); - private ArrayList dependants = new ArrayList<>(); - private Affine manipulationMatrix; - private Vector3d orintation; - private CSG manip; - private TransformNR globalPose; - public TransformNR currentPose; - private PhongMaterial color;// = new PhongMaterial(getColor()); - private PhongMaterial highlight = new PhongMaterial(Color.GOLD); - - private enum DragState { - IDLE, Dragging - } - - private DragState state = DragState.IDLE; - - public void addEventListener(Runnable r) { - if (eventListeners.contains(r)) - return; - eventListeners.add(r); - } - - public void addDependant(manipulation r) { - if (dependants.contains(r)) - return; - dependants.add(r); - } - - public void addSaveListener(Runnable r) { - if (saveListeners.contains(r)) - return; - saveListeners.add(r); - } - - public void clearListeners() { - // TODO Auto-generated method stub - saveListeners.clear(); - eventListeners.clear(); - } - - private void fireMove(TransformNR trans, TransformNR camFrame2) { - for (manipulation R : dependants) { - R.performMove(trans, camFrame2); - } - for (Runnable R : eventListeners) { - R.run(); - } - } - - private void fireSave() { - new Thread(() -> { - for (Runnable R : saveListeners) { - R.run(); - } - }).start(); - } - - public manipulation(Affine mm, Vector3d o, CSG m, TransformNR p) { - this.manipulationMatrix = mm; - this.orintation = o; - this.manip = m; - color = new PhongMaterial(m.getColor()); - this.globalPose = p; - currentPose = p.copy(); - getUi().runLater(() -> { - try { - TransformFactory.nrToAffine(globalPose, manipulationMatrix); - } catch (Throwable t) { - t.printStackTrace(); - } - }); - - map.put(MouseEvent.ANY, new EventHandler() { - @Override - public void handle(MouseEvent event) { - String name = event.getEventType().getName(); - switch (name) { - case "MOUSE_PRESSED": - pressed(event); - break; - case "MOUSE_DRAGGED": - dragged(event); - break; - case "MOUSE_RELEASED": - release(event); - break; - case "MOUSE_MOVED": - // ignore - break; - case "MOUSE_ENTERED": - m.getMesh().setMaterial(highlight); - break; - case "MOUSE_EXITED": - if (state == DragState.IDLE) - m.getMesh().setMaterial(color); - break; - default: - // System.out.println("UNKNOWN! Mouse event "+name); - break; - } - - } - }); - manip.getStorage().set("manipulator", map); - manip.setManipulator(manipulationMatrix); - } - - private void pressed(MouseEvent event) { - state = DragState.Dragging; - new Thread(() -> { - camFrame = getUi().getCamerFrame(); - depth = -1600 / getUi().getCamerDepth(); - event.consume(); - dragging = false; - for (manipulation R : dependants) { - R.camFrame = getUi().getCamerFrame(); - R.depth = -1600 / getUi().getCamerDepth(); - R.dragging = false; - } - }).start(); - } - - private void release(MouseEvent event) { - mouseRelease(event); - for (manipulation R : dependants) - R.mouseRelease(event); - state = DragState.IDLE; - manip.getMesh().setMaterial(color); - } - - private void dragged(MouseEvent event) { - getUi().runLater(() -> { - setDragging(event); - double deltx = (startx - event.getScreenX()); - double delty = (starty - event.getScreenY()); - TransformNR trans = new TransformNR(deltx / depth, delty / depth, 0, new RotationNR()); - - performMove(trans, camFrame); - }); - event.consume(); - } - - public boolean isMoving() { - return state == DragState.Dragging; - } - - private void mouseRelease(MouseEvent event) { - if (dragging) { - dragging = false; - globalPose.setX(newx); - globalPose.setY(newy); - globalPose.setZ(newz); - event.consume(); - fireSave(); - } - } - - private void setDragging(MouseEvent event) { - if (dragging == false) { - startx = event.getScreenX(); - starty = event.getScreenY(); - } - dragging = true; - for (manipulation R : dependants) { - R.setDragging(event); - } - } - - private void performMove(TransformNR trans, TransformNR camFrame2) { - TransformNR globalTMP = camFrame2.copy(); - globalTMP.setX(0); - globalTMP.setY(0); - globalTMP.setZ(0); - TransformNR global = globalTMP.times(trans); - newx = (global.getX() * orintation.x + globalPose.getX()); - newy = (global.getY() * orintation.y + globalPose.getY()); - newz = (global.getZ() * orintation.z + globalPose.getZ()); - global.setX(newx); - global.setY(newy); - global.setZ(newz); - - global.setRotation(new RotationNR()); - setGlobal(global); - // System.out.println(" drag "+global.getX()+" , "+global.getY()+" , - // "+global.getZ()+" "+deltx+" "+delty); - fireMove(trans, camFrame2); - } - - private void setGlobal(TransformNR global) { - currentPose.setX(newx); - currentPose.setY(newy); - currentPose.setZ(newz); - getUi().runLater(() -> { - TransformFactory.nrToAffine(global, manipulationMatrix); - }); - } - - public static IInteractiveUIElementProvider getUi() { - return ui; - } - - public static void setUi(IInteractiveUIElementProvider ui) { - manipulation.ui = ui; - } - - public void set(double newX, double newY, double newZ) { - newx = newX; - newy = newY; - newz = newZ; - globalPose.setX(newX); - globalPose.setY(newY); - globalPose.setZ(newZ); - setGlobal(new TransformNR(newX, newY, newZ, new RotationNR())); - for (Runnable R : eventListeners) { - R.run(); - } - - } - -} diff --git a/src/main/java/com/neuronrobotics/bowlerkernel/BowlerKernelBuildInfo.java b/src/main/java/com/neuronrobotics/bowlerkernel/BowlerKernelBuildInfo.java index 24211628a..9793cd39f 100644 --- a/src/main/java/com/neuronrobotics/bowlerkernel/BowlerKernelBuildInfo.java +++ b/src/main/java/com/neuronrobotics/bowlerkernel/BowlerKernelBuildInfo.java @@ -120,7 +120,7 @@ public static String getBuildDate() { } } catch (IOException e) { } - // System.out.println("Manifest:\n"+s); + // com.neuronrobotics.sdk.common.Log.error("Manifest:\n"+s); return ""; } diff --git a/src/main/java/com/neuronrobotics/bowlerkernel/djl/UniquePersonFactory.java b/src/main/java/com/neuronrobotics/bowlerkernel/djl/UniquePersonFactory.java index 6cd4cdae0..eb28eb82e 100644 --- a/src/main/java/com/neuronrobotics/bowlerkernel/djl/UniquePersonFactory.java +++ b/src/main/java/com/neuronrobotics/bowlerkernel/djl/UniquePersonFactory.java @@ -105,13 +105,13 @@ private UniquePersonFactory(File database) { try { features = PredictorFactory.faceFeatureFactory(); } catch (ModelNotFoundException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } catch (MalformedModelException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } factory = ImageFactory.getInstance(); @@ -144,7 +144,7 @@ public String save() { try { Files.write(path, strToBytes); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } if (workingMemory != null) @@ -262,7 +262,7 @@ private void processBlocking() { if (up.features.size() >= numberOfTrainingHashes) { if (!longTermMemory.contains(up)) { longTermMemory.add(up); - System.out.println("Saving new Face to database " + up.name); + com.neuronrobotics.sdk.common.Log.error("Saving new Face to database " + up.name); save(); } } @@ -280,7 +280,7 @@ private void processBlocking() { try { id = features.predict(cmp); } catch (Throwable ex) { - System.out.println("Image failed h=" + imgBuff.getHeight() + " w=" + imgBuff.getWidth()); + com.neuronrobotics.sdk.common.Log.error("Image failed h=" + imgBuff.getHeight() + " w=" + imgBuff.getWidth()); // ex.printStackTrace(); continue; } @@ -344,7 +344,7 @@ private void processBlocking() { private EventHandler setAction(UniquePerson p) { return event -> { String newName = getUI(p).name.getText(); - System.out.println("Renaming " + p.name + " to " + newName); + com.neuronrobotics.sdk.common.Log.error("Renaming " + p.name + " to " + newName); p.name = newName; new Thread(() -> save()).start(); }; @@ -415,7 +415,7 @@ private boolean processMemory(HashMap tmpPe @Override public ArrayList getNamespacesImp() { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } @@ -480,7 +480,7 @@ public void setDatabase(File database) { database.createNewFile(); save(); } catch (IOException e1) { - // TODO Auto-generated catch block + // Auto-generated catch block e1.printStackTrace(); } else { @@ -490,7 +490,7 @@ public void setDatabase(File database) { longTermMemory = gson.fromJson(jsonString, TT_mapStringString); resetHash(); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/AudioPlayer.java b/src/main/java/com/neuronrobotics/bowlerstudio/AudioPlayer.java index 72e5db80a..f8f62641e 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/AudioPlayer.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/AudioPlayer.java @@ -271,7 +271,7 @@ public float getGainValue() { public void setGain(float fGain) { // if (line != null) - // System.out.println(((FloatControl) + // com.neuronrobotics.sdk.common.Log.error(((FloatControl) // line.getControl(FloatControl.Type.MASTER_GAIN)).getValue()) // Set the value @@ -284,7 +284,7 @@ public void setGain(float fGain) { // OR (Math.log(fGain == 0.0 ? 0.0000 : fGain) / Math.log(10.0)) // if (line != null) - // System.out.println(((FloatControl) + // com.neuronrobotics.sdk.common.Log.error(((FloatControl) // line.getControl(FloatControl.Type.MASTER_GAIN)).getValue()) } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/BowlerKernel.java b/src/main/java/com/neuronrobotics/bowlerstudio/BowlerKernel.java index f534b7b1f..345e24e13 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/BowlerKernel.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/BowlerKernel.java @@ -50,13 +50,18 @@ import com.neuronrobotics.bowlerstudio.creature.IgenerateBed; import com.neuronrobotics.bowlerstudio.creature.MobileBaseCadManager; import com.neuronrobotics.bowlerstudio.printbed.PrintBedManager; +import com.neuronrobotics.bowlerstudio.scripting.CaDoodleLoader; import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.CaDoodleFile; import com.neuronrobotics.bowlerstudio.vitamins.VitaminBomManager; import com.neuronrobotics.sdk.addons.kinematics.MobileBase; import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.CSGServer; import eu.mihosoft.vrl.v3d.ICSGProgress; import eu.mihosoft.vrl.v3d.JavaFXInitializer; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import javafx.application.Platform; import javafx.scene.control.Tab; import javafx.scene.transform.Affine; @@ -70,6 +75,7 @@ public class BowlerKernel { // private static final String CSG = null; private static File historyFile = new File(ScriptingEngine.getWorkspace().getAbsolutePath() + "/bowler.history"); + private static boolean kernelMode = true; private static void loadHistoryLocal() { historyFile = new File(ScriptingEngine.getWorkspace().getAbsolutePath() + "/bowler.history"); @@ -78,7 +84,7 @@ private static void loadHistoryLocal() { try { historyFile.createNewFile(); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } history.add("println SDKBuildInfo.getVersion()"); @@ -99,15 +105,16 @@ private static void loadHistoryLocal() { } private static void fail() { - System.err.println( + com.neuronrobotics.sdk.common.Log.error( "Usage: \r\njava -jar BowlerScriptKernel.jar -s .. # This will load one script after the next "); - System.err.println( + com.neuronrobotics.sdk.common.Log.error( "java -jar BowlerScriptKernel.jar -p .. # This will load one script then take the list of objects returned and pss them to the next script as its 'args' variable "); - System.err.println( + com.neuronrobotics.sdk.common.Log.error( "java -jar BowlerScriptKernel.jar -r (Optional)(-s or -p) .. # This will start a shell in the requested langauge and run the files provided. "); - System.err.println("java -jar BowlerScriptKernel.jar -g # this will run a file from git"); - - System.exit(1); + com.neuronrobotics.sdk.common.Log + .error("java -jar BowlerScriptKernel.jar -g # this will run a file from git"); + if (isKernelMode()) + System.exit(1); } /** @@ -127,8 +134,10 @@ public static void runArgumentsAfterStartup(String[] args, long startTime) boolean gitRun = false; String gitRepo = null; String gitFile = null; + boolean runCSGServer = false; + File keys = null; + int port = 3742; for (String s : args) { - if (gitRun) { if (gitRepo == null) { gitRepo = s; @@ -139,7 +148,34 @@ public static void runArgumentsAfterStartup(String[] args, long startTime) if (s.startsWith("-g")) { gitRun = true; } + if (s.toLowerCase().contains("-csgserver")) { + runCSGServer = true; + continue; + } + if (runCSGServer) { + if (keys == null) { + keys = new File(s); + continue; + } else { + try { + port = Integer.parseInt(s); + }catch(NumberFormatException ex) { + ex.printStackTrace(); + } + } + } } + if (runCSGServer) { + CSGServer.setDirectory(ScriptingEngine.getWorkspace()); + CSGServer server = new CSGServer(port, keys); + try { + server.start(); + } catch (Exception e) { + e.printStackTrace(); + } + return; + } + Object ret = null; File baseWorkspaceFile = null; if (gitRun && gitRepo != null) { @@ -159,12 +195,12 @@ public static void runArgumentsAfterStartup(String[] args, long startTime) } } if (!fileExists) { - System.err.println("\n\nERROR file does not exist: " + gitFile); + com.neuronrobotics.sdk.common.Log.error("\n\nERROR file does not exist: " + gitFile); gitFile = null; } if (gitFile != null) try { - ret = ScriptingEngine.gitScriptRun(gitRepo, gitFile, null); + ret = ScriptingEngine.gitScriptRun(CSGDatabase.getInstance(),gitRepo, gitFile, null); url = gitRepo; baseWorkspaceFile = ScriptingEngine.getRepositoryCloneDirectory(url); @@ -174,9 +210,9 @@ public static void runArgumentsAfterStartup(String[] args, long startTime) fail(); } else { - System.out.println("Files in git:"); + com.neuronrobotics.sdk.common.Log.error("Files in git:"); for (String f : files) { - System.out.println("\t" + f); + com.neuronrobotics.sdk.common.Log.error("\t" + f); } } finish(startTime); @@ -185,7 +221,7 @@ public static void runArgumentsAfterStartup(String[] args, long startTime) // "BowlerStudioVitamins/stl/servo/smallservo.stl"); // // ArrayList cad = (ArrayList )ScriptingEngine.inlineGistScriptRun("4814b39ee72e9f590757", "javaCad.groovy" , null); -// System.out.println(servo.exists()+" exists: "+servo); +// com.neuronrobotics.sdk.common.Log.error(servo.exists()+" exists: "+servo); boolean startLoadingScripts = false; for (String s : args) { @@ -193,23 +229,24 @@ public static void runArgumentsAfterStartup(String[] args, long startTime) try { File f = new File(s); - File parentFile = f.getParentFile(); - if(parentFile==null) { - parentFile=new File("."); + String location; + try { + location = ScriptingEngine.locateGitTopLevelDirectory(f).getAbsolutePath(); + } catch (Exception ex) { + location = new File(".").getAbsolutePath(); } - String location =parentFile.getAbsolutePath(); - if(location.endsWith(".")) { - location=location.substring(0,location.length()-1); - } - if(!location.endsWith("/")) { - location+="/"; + if (location.endsWith(".")) { + location = location.substring(0, location.length() - 1); + } + if (!location.endsWith("/")) { + location += "/"; } baseWorkspaceFile = new File(location); - - System.out.println("Using working directory "+baseWorkspaceFile.getAbsolutePath()); - f=new File(baseWorkspaceFile.getAbsolutePath()+"/"+f.getName()); - System.out.println("File "+f.getName()); - ret = ScriptingEngine.inlineFileScriptRun(f, null); + + com.neuronrobotics.sdk.common.Log.debug("Using working directory " + baseWorkspaceFile.getAbsolutePath()); + f = new File(baseWorkspaceFile.getAbsolutePath() + "/" + s); + com.neuronrobotics.sdk.common.Log.error("File " + f.getName()); + ret = ScriptingEngine.inlineFileScriptRun(CSGDatabase.getInstance(),f, null); } catch (Throwable e) { e.printStackTrace(); fail(); @@ -230,7 +267,7 @@ public static void runArgumentsAfterStartup(String[] args, long startTime) if (startLoadingScripts) { try { - ret = ScriptingEngine.inlineFileScriptRun(new File(s), (ArrayList) ret); + ret = ScriptingEngine.inlineFileScriptRun(CSGDatabase.getInstance(),new File(s), (ArrayList) ret); } catch (Throwable e) { e.printStackTrace(); fail(); @@ -241,7 +278,7 @@ public static void runArgumentsAfterStartup(String[] args, long startTime) } } if (startLoadingScripts) { - processReturnedObjectsStart(ret, null); + processReturnedObjectsStart(ret, new File(".")); finish(startTime); return; } @@ -266,12 +303,12 @@ public static void runArgumentsAfterStartup(String[] args, long startTime) if (!runShell) { finish(startTime); } - System.out.println("Starting Bowler REPL in langauge: " + shellTypeStorage); + com.neuronrobotics.sdk.common.Log.error("Starting Bowler REPL in langauge: " + shellTypeStorage); // sample from // http://jline.sourceforge.net/testapidocs/src-html/jline/example/Example.html if (!Terminal.getTerminal().isSupported()) { - System.out.println("Terminal not supported " + Terminal.getTerminal()); + com.neuronrobotics.sdk.common.Log.error("Terminal not supported " + Terminal.getTerminal()); } // Terminal.getTerminal().initializeTerminal(); @@ -326,7 +363,7 @@ public void run() { if (line.equalsIgnoreCase("history") || line.equalsIgnoreCase("h")) { List h = reader.getHistory().getHistoryList(); for (String s : h) { - System.out.println(s); + com.neuronrobotics.sdk.common.Log.error(s); } continue; } @@ -339,9 +376,9 @@ public void run() { continue; } try { - ret = ScriptingEngine.inlineScriptStringRun(line, null, shellTypeStorage); + ret = ScriptingEngine.inlineScriptStringRun(CSGDatabase.getInstance(),line, null, shellTypeStorage); if (ret != null) { - System.out.println(ret); + com.neuronrobotics.sdk.common.Log.error(ret); } processReturnedObjectsStart(ret, null); } catch (Error e) { @@ -361,26 +398,17 @@ private static void startupProcedures(String[] args) JavaFXInitializer.go(); } catch (Throwable t) { t.printStackTrace(); - System.err.println("ERROR No UI engine availible"); + com.neuronrobotics.sdk.common.Log.error("ERROR No UI engine availible"); } ScriptingEngine.waitForLogin(); if (args.length == 0) { fail(); } - ScriptingEngine.gitScriptRun("https://github.com/CommonWealthRobotics/DeviceProviders.git", "loadAll.groovy", - null); - } + CSGDatabase.setInstance(new CSGDatabaseInstance(new File(ScriptingEngine.getWorkspace().getAbsoluteFile() + "/csgDatabase.json"))); - private static void finish(long startTime) { - System.out.println( - "Process took " + (((double) (System.currentTimeMillis() - startTime))) / 60000.0 + " minutes"); - System.exit(0); - } - - private static void processReturnedObjectsStart(Object ret, File baseWorkspaceFile) { - processUIOpening(ret); - if(baseWorkspaceFile!=null) - System.out.println("Processing file in directory "+baseWorkspaceFile.getAbsolutePath()); + ScriptingEngine.gitScriptRun(CSGDatabase.getInstance(),"https://github.com/CommonWealthRobotics/DeviceProviders.git", "loadAll.groovy", + null); + CSG.setPreventNonManifoldTriangles(true); CSG.setProgressMoniter(new ICSGProgress() { @Override public void progressUpdate(int currentIndex, int finalIndex, String type, @@ -389,51 +417,70 @@ public void progressUpdate(int currentIndex, int finalIndex, String type, } }); + } + + private static void finish(long startTime) { + com.neuronrobotics.sdk.common.Log + .error("Process took " + (((double) (System.currentTimeMillis() - startTime))) / 60000.0 + " minutes"); + System.exit(0); + } + + public static void processReturnedObjectsStart(Object ret, File baseWorkspaceFile) { + CSG.setPreventNonManifoldTriangles(true); + processUIOpening(ret); + if (baseWorkspaceFile != null) + com.neuronrobotics.sdk.common.Log.debug("Processing file in directory " + baseWorkspaceFile.getAbsolutePath()); + if (baseWorkspaceFile != null) { - File baseDirForFiles = new File("./manufacturing/"); + + File baseDirForFiles = new File(baseWorkspaceFile.getAbsolutePath() + "/manufacturing/"); if (baseDirForFiles.exists()) { // baseDirForFiles.mkdir(); File bomCSV = new File( - baseWorkspaceFile.getAbsolutePath() + "/" + VitaminBomManager.MANUFACTURING_BOM_CSV); + baseWorkspaceFile.getAbsolutePath() + "/" + VitaminBomManager.getManufacturingBomCsv()); if (bomCSV.exists()) { - File file = new File(baseDirForFiles.getAbsolutePath() + "/bom.csv"); - if (file.exists()) - file.delete(); + File file = new File( + baseWorkspaceFile.getAbsolutePath() + "/" + VitaminBomManager.getManufacturingBomCsv()); +// if (file.exists()) +// file.delete(); try { Files.copy(bomCSV.toPath(), file.toPath()); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } File bom = new File( - baseWorkspaceFile.getAbsolutePath() + "/" + VitaminBomManager.MANUFACTURING_BOM_JSON); + baseWorkspaceFile.getAbsolutePath() + "/" + VitaminBomManager.getManufacturingBomJson()); if (bom.exists()) { - File file = new File(baseDirForFiles.getAbsolutePath() + "/bom.json"); - if (file.exists()) - file.delete(); + File file = new File( + baseWorkspaceFile.getAbsolutePath() + "/" + VitaminBomManager.getManufacturingBomJson()); +// if (file.exists()) +// file.delete(); try { Files.copy(bom.toPath(), file.toPath()); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } + } else { + baseDirForFiles.mkdirs(); } } ArrayList csgBits = new ArrayList<>(); try { processReturnedObjects(ret, csgBits); String url = ScriptingEngine.locateGitUrl(baseWorkspaceFile); - System.out.println("Loading printbed URL "+url); + com.neuronrobotics.sdk.common.Log.error("Loading printbed URL " + url); PrintBedManager printBedManager = new PrintBedManager(baseWorkspaceFile, csgBits); - if(printBedManager.hasPrintBed()) + if (printBedManager.hasPrintBed()) csgBits = printBedManager.makePrintBeds(); else { - System.out.println("Exporting files without print bed"); + com.neuronrobotics.sdk.common.Log.error("Exporting files without print bed"); } - new CadFileExporter().generateManufacturingParts(csgBits, new File(".")); + new CadFileExporter().generateManufacturingParts(csgBits, baseWorkspaceFile); } catch (Throwable t) { t.printStackTrace(); fail(); @@ -441,12 +488,12 @@ public void progressUpdate(int currentIndex, int finalIndex, String type, } private static void processUIOpening(Object ret) { - if(Tab.class.isInstance(ret)) { - System.out.println("Launching User Defined UI"); - Tab t=(Tab)ret; + if (Tab.class.isInstance(ret)) { + com.neuronrobotics.sdk.common.Log.error("Launching User Defined UI"); + Tab t = (Tab) ret; CompletableFuture future = new CompletableFuture<>(); - BowlerKernel.runLater(()->{ + BowlerKernel.runLater(() -> { // Get the content from the tab javafx.scene.Node content = t.getContent(); // Create a new stage @@ -472,7 +519,7 @@ private static void processUIOpening(Object ret) { newStage.setOnCloseRequest(event -> { // Exit the JVM when the window is closed future.complete(true); - Platform.exit(); + BowlerKernel.runLater(() -> Platform.exit()); }); FontSizeManager.addListener(fontNum -> { int tmp = fontNum - 10; @@ -481,10 +528,10 @@ private static void processUIOpening(Object ret) { root.setStyle("-fx-font-size: " + tmp + "pt"); newStage.sizeToScene(); }); - if(IStageReceiver.class.isInstance(ret)) { - System.out.println("UI is a IStageReceiver"); - IStageReceiver r=(IStageReceiver)ret; - BowlerKernel.runLater(()->{ + if (IStageReceiver.class.isInstance(ret)) { + com.neuronrobotics.sdk.common.Log.error("UI is a IStageReceiver"); + IStageReceiver r = (IStageReceiver) ret; + BowlerKernel.runLater(() -> { r.receiveStage(newStage, scene); }); } @@ -495,13 +542,13 @@ private static void processUIOpening(Object ret) { scene.getRoot().layout(); }); try { - future.get(); + future.get(); System.exit(0); } catch (Exception e) { e.printStackTrace(); } } - + } private static void processReturnedObjects(Object ret, ArrayList csgBits) { @@ -514,6 +561,10 @@ private static void processReturnedObjects(Object ret, ArrayList csgBits) { if (CSG.class.isInstance(ret)) { csgBits.add((CSG) ret); } + if (CaDoodleFile.class.isInstance(ret)) { + processReturnedObjects(CaDoodleLoader.process((CaDoodleFile) ret,false), csgBits); + return; + } if (MobileBase.class.isInstance(ret)) { MobileBase ret2 = (MobileBase) ret; MobileBaseCadManager m = MobileBaseCadManager.get(ret2); @@ -521,19 +572,19 @@ private static void processReturnedObjects(Object ret, ArrayList csgBits) { @Override public void setSelectedCsg(Collection selectedCsg) { - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public void setSelected(Affine rootListener) { - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public void setAllCSG(Collection toAdd, File source) { - // TODO Auto-generated method stub + // Auto-generated method stub } @@ -545,13 +596,13 @@ public void highlightException(File fileEngineRunByName, Throwable ex) { @Override public Set getVisibleCSGs() { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } @Override public void addCSG(Collection toAdd, File source) { - // TODO Auto-generated method stub + // Auto-generated method stub } }); @@ -578,7 +629,7 @@ public void addCSG(Collection toAdd, File source) { m._generateStls(ret2, dir, false); return; } - System.out.println("Found arrangeBed API in CAD engine"); + com.neuronrobotics.sdk.common.Log.error("Found arrangeBed API in CAD engine"); List totalAssembly = bed.arrangeBed(ret2); ret2.disconnect(); Thread.sleep(1000); @@ -589,24 +640,24 @@ public void addCSG(Collection toAdd, File source) { // Get maximum size of heap in bytes. The heap cannot grow beyond this size.// // Any attempt will result in an OutOfMemoryException. long heapMaxSize = Runtime.getRuntime().maxMemory(); - // System.out.println("Heap remaining + // com.neuronrobotics.sdk.common.Log.error("Heap remaining // "+(heapMaxSize-Runtime.getRuntime().totalMemory())); - // System.out.println("Of Heap "+(heapMaxSize)); + // com.neuronrobotics.sdk.common.Log.error("Of Heap "+(heapMaxSize)); for (int i = 0; i < totalAssembly.size(); i++) { List tmp = Arrays.asList(totalAssembly.get(i)); totalAssembly.set(i, null); - // System.out.println("Before Heap remaining + // com.neuronrobotics.sdk.common.Log.error("Before Heap remaining // "+(heapMaxSize-Runtime.getRuntime().totalMemory())); new CadFileExporter(m.getUi()).generateManufacturingParts(tmp, dir); tmp = null; System.gc(); - // System.out.println("After Heap remaining + // com.neuronrobotics.sdk.common.Log.error("After Heap remaining // "+(heapMaxSize-Runtime.getRuntime().totalMemory())); } } catch (Exception e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); fail(); } @@ -627,7 +678,7 @@ public static ArrayList loadHistory() throws IOException { } public static void writeHistory(List history) { - System.out.println("Saving history"); + com.neuronrobotics.sdk.common.Log.error("Saving history"); FileOutputStream fos; try { fos = new FileOutputStream(historyFile); @@ -639,10 +690,10 @@ public static void writeHistory(List history) { bw.close(); } catch (FileNotFoundException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } @@ -680,7 +731,7 @@ public static int speak(String msg, Number rate, Number pitch, Number voiceNumbe } TextToSpeech tts = new TextToSpeech(); // cd .. - tts.getAvailableVoices().stream().forEach(voice -> System.out.println("Voice: " + voice)); + tts.getAvailableVoices().stream().forEach(voice -> com.neuronrobotics.sdk.common.Log.error("Voice: " + voice)); // Setting the Current Voice // voice =(tts.getAvailableVoices().toArray()[0].toString()); String voice = "dfki-poppy-hsmm"; @@ -699,7 +750,7 @@ else if (voiceNumber.doubleValue() > 100) tts.setVoice(voice); - System.out.println("Using voice " + voice); + com.neuronrobotics.sdk.common.Log.error("Using voice " + voice); RobotiserEffect vocalTractLSE = new RobotiserEffect(); // russian drunk effect vocalTractLSE.setParams("amount:" + pitch.intValue()); @@ -707,12 +758,12 @@ else if (voiceNumber.doubleValue() > 100) // TTS say something that we actually are typing into the first variable // tts.getAudioEffects().stream().forEach(audioEffect -> { // if(audioEffect.getName().contains("Rate")) { -// System.out.println("-----Name-----"); -// System.out.println(audioEffect.getName()); -// System.out.println("-----Examples-----"); -// System.out.println(audioEffect.getExampleParameters()); -// System.out.println("-----Help Text------"); -// System.out.println(audioEffect.getHelpText() + "\n\n"); +// com.neuronrobotics.sdk.common.Log.error("-----Name-----"); +// com.neuronrobotics.sdk.common.Log.error(audioEffect.getName()); +// com.neuronrobotics.sdk.common.Log.error("-----Examples-----"); +// com.neuronrobotics.sdk.common.Log.error(audioEffect.getExampleParameters()); +// com.neuronrobotics.sdk.common.Log.error("-----Help Text------"); +// com.neuronrobotics.sdk.common.Log.error(audioEffect.getHelpText() + "\n\n"); // } // }); String effect = ""; @@ -744,7 +795,7 @@ else if (voiceNumber.doubleValue() > 100) effect += "+" + volumeEffect.getFullEffectAsString(); if (pitch.intValue() > 0) effect += "+" + vocalTractLSE.getFullEffectAsString(); - System.out.println(msg + "-->" + effect); + com.neuronrobotics.sdk.common.Log.error(msg + "-->" + effect); tts.getMarytts().setAudioEffects(effect); tts.speak(msg, 2.0f, false, true, progress); @@ -754,15 +805,15 @@ else if (voiceNumber.doubleValue() > 100) public static void upenURL(String string) { - System.err.println("Opening " + string); + com.neuronrobotics.sdk.common.Log.error("Opening " + string); try { upenURL(new URI(string)); } catch (URISyntaxException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } catch (Throwable e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } @@ -772,7 +823,7 @@ public static void upenURL(URI htmlUrl) { try { Desktop.getDesktop().browse(htmlUrl); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } @@ -809,5 +860,12 @@ public static void runLater(Runnable r, Throwable ex) { }); } + public static boolean isKernelMode() { + return kernelMode; + } + + public static void setKernelMode(boolean kernelMode) { + BowlerKernel.kernelMode = kernelMode; + } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/CoquiDockerManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/CoquiDockerManager.java index fb6d62c6c..0704e9689 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/CoquiDockerManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/CoquiDockerManager.java @@ -81,7 +81,7 @@ private CoquiDockerManager(String voice) throws InterruptedException, InvalidRem } managers.clear(); managers.put(voice, this); - System.out.println("Coqui Voice " + voice); + com.neuronrobotics.sdk.common.Log.error("Coqui Voice " + voice); String[] parts = voice.split("/"); String voiceSlug = "-" + parts[parts.length - 1]; ScriptingEngine.cloneRepo("https://github.com/Halloween2020TheChild/CoquiDocker.git", null); @@ -107,13 +107,13 @@ private CoquiDockerManager(String voice) throws InterruptedException, InvalidRem for (Container c : allCOntainers) { if (forMe != null) continue; - System.out.println("Container: " + c); + com.neuronrobotics.sdk.common.Log.error("Container: " + c); String[] names = c.getNames(); for (String n : names) { String cs = "/" + imageName + voiceSlug; - System.out.println("Checking " + n + " to " + cs); + com.neuronrobotics.sdk.common.Log.error("Checking " + n + " to " + cs); boolean PortMatch=false; ContainerPort[] conPorts = c.getPorts(); for(ContainerPort cp:conPorts) { @@ -143,11 +143,11 @@ private CoquiDockerManager(String voice) throws InterruptedException, InvalidRem @Override public void onNext(BuildResponseItem item) { // Handle build output (optional) - System.out.println(item.getStream()); + com.neuronrobotics.sdk.common.Log.debug(item.getStream()); super.onNext(item); } }).awaitImageId(); - System.out.println("Docker image built successfully."); + com.neuronrobotics.sdk.common.Log.error("Docker image built successfully."); try { ExposedPort port = ExposedPort.tcp(hostPort); Ports portBindings = new Ports(); @@ -161,7 +161,7 @@ public void onNext(BuildResponseItem item) { @Override public void onNext(WaitResponse item) { // Handle build output (optional) - System.out.println(item.toString()); + com.neuronrobotics.sdk.common.Log.error(item.toString()); super.onNext(item); } }).awaitCompletion(); @@ -170,7 +170,7 @@ public void onNext(WaitResponse item) { @Override public void onNext(Frame item) { String string = item.toString(); - System.out.println(string); + com.neuronrobotics.sdk.common.Log.error(string); if(string.contains("Press CTRL+C to quit")) { started=true; } @@ -187,14 +187,14 @@ public void onNext(Frame item) { } while(!started) { Thread.sleep(1000); - System.out.println("Waiting for server to start"); + com.neuronrobotics.sdk.common.Log.error("Waiting for server to start"); } } public void disconnect() { - // TODO Auto-generated method stub + // Auto-generated method stub dockerClient.killContainerCmd(id).exec(); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/IssueReportingExceptionHandler.java b/src/main/java/com/neuronrobotics/bowlerstudio/IssueReportingExceptionHandler.java index 645d1efb6..c7fa0e69c 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/IssueReportingExceptionHandler.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/IssueReportingExceptionHandler.java @@ -69,7 +69,7 @@ public static void runLater(Runnable r, Throwable ex) { } public void except(Throwable e, String stacktraceFromCatch) { - System.out.println(stacktraceFromCatch); + com.neuronrobotics.sdk.common.Log.error(stacktraceFromCatch); new Thread(() -> { String stacktrace = org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(e); StackTraceElement[] element = e.getStackTrace(); @@ -96,7 +96,7 @@ public void except(Throwable e, String stacktraceFromCatch) { try { Thread.sleep(5000); } catch (InterruptedException e1) { - // TODO Auto-generated catch block + // Auto-generated catch block e1.printStackTrace(); } // wait for the Issue to be reported System.exit(-5); @@ -107,7 +107,7 @@ public void except(Throwable e, String stacktraceFromCatch) { try { Thread.sleep(5000); } catch (InterruptedException e1) { - // TODO Auto-generated catch block + // Auto-generated catch block e1.printStackTrace(); } // wait for the Issue to be reported System.exit(-5); @@ -133,10 +133,10 @@ public void except(Throwable e, String stacktraceFromCatch) { + "```\n" + stacktrace + "\n```" + "\n\nCaught and reported at: \n" + "```\n" + stacktraceFromCatch + "\n```\n" + "\nIssueReportingExceptionHandler Created at:\n" + "\n```\n" + stacktraceFromHandlerInstantiation + "\n```\n"; - System.err.println(body); - System.err.println("\r\n\r\nBug Reported!\r\n\r\n"); - System.out.println(body); - System.out.println("\r\n\r\nBug Reported!\r\n\r\n"); + com.neuronrobotics.sdk.common.Log.error(body); + com.neuronrobotics.sdk.common.Log.error("\r\n\r\nBug Reported!\r\n\r\n"); + com.neuronrobotics.sdk.common.Log.error(body); + com.neuronrobotics.sdk.common.Log.error("\r\n\r\nBug Reported!\r\n\r\n"); GitHub github = PasswordManager.getGithub(); if (github == null || github.isAnonymous()) @@ -171,7 +171,7 @@ private void runReport(StackTraceElement[] element, String body, GitHub github) String source = getTitle(element); for (GHIssue i : issues) { - System.err.println("Issues are :" + i.getTitle()); + com.neuronrobotics.sdk.common.Log.error("Issues are :" + i.getTitle()); if (i.getTitle().contains(source)) { List comments = i.getComments(); // Check to see if i created this issue @@ -217,7 +217,7 @@ private void runReport(StackTraceElement[] element, String body, GitHub github) BowlerKernel.upenURL(i.getHtmlUrl().toURI()); } catch (Throwable e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } processing = false; @@ -240,7 +240,7 @@ public void except(Throwable t) { return; } if (Platform.isFxApplicationThread()) { - System.err.println("Exception in Javafx thread! \n" + com.neuronrobotics.sdk.common.Log.error("Exception in Javafx thread! \n" + org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(t)); //throw new RuntimeException(t); return; diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/TextToSpeech.java b/src/main/java/com/neuronrobotics/bowlerstudio/TextToSpeech.java index 4a80fd253..fa398fbd3 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/TextToSpeech.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/TextToSpeech.java @@ -81,7 +81,7 @@ public int speak(String text , float gainValue , boolean daemon , boolean join, Logger.getLogger(getClass().getName()).log(Level.WARNING, "IO Exception", ex); } catch (InterruptedException ex) { Logger.getLogger(getClass().getName()).log(Level.WARNING, "Interrupted ", ex); - System.out.println("Speaking clean exit"); + com.neuronrobotics.sdk.common.Log.error("Speaking clean exit"); tts.cancel(); tts.interrupt(); return 1; diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/assets/AssetFactory.java b/src/main/java/com/neuronrobotics/bowlerstudio/assets/AssetFactory.java index 07a16ae8c..1c58f0ad7 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/assets/AssetFactory.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/assets/AssetFactory.java @@ -1,6 +1,7 @@ package com.neuronrobotics.bowlerstudio.assets; import com.neuronrobotics.bowlerstudio.IssueReportingExceptionHandler; +import com.neuronrobotics.bowlerstudio.scripting.PasswordManager; import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; //import javafx.embed.swing.SwingFXUtils; @@ -25,171 +26,177 @@ public class AssetFactory { - public static final String repo = "BowlerStudioImageAssets"; - private static String gitSource = "https://github.com/CommonWealthRobotics/" + repo + ".git"; - private static HashMap cache = new HashMap<>(); - private static HashMap loaders = new HashMap<>(); - private static String assetRepoBranch = ""; - - private AssetFactory() { - } - - public static FXMLLoader loadLayout(String file, boolean refresh) throws Exception { - File fxmlFIle = loadFile(file); - URL fileURL = fxmlFIle.toURI().toURL(); - - if (loaders.get(file) == null || refresh) { - loaders.put(file, new FXMLLoader(fileURL)); - } - - loaders.get(file).setLocation(fileURL); - return loaders.get(file); - } - - public static FXMLLoader loadLayout(String file) throws Exception { - return loadLayout(file, false); - } - - public static File loadFile(String file) throws Exception { - return ScriptingEngine - .fileFromGit( - getGitSource(),// git repo, change this if you fork this demo - getAssetRepoBranch(), - file// File from within the Git repo - ); - } - - public static void writeImage(Image img, File file) { - int width = (int) img.getWidth(); - int height = (int) img.getHeight(); - PixelReader reader = img.getPixelReader(); - byte[] buffer = new byte[width * height * 4]; - javafx.scene.image.WritablePixelFormat format = javafx.scene.image.PixelFormat.getByteBgraInstance(); - reader.getPixels(0, 0, width, height, format, buffer, 0, width * 4); - try { - BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file)); - for(int count = 0; count < buffer.length; count += 4) { - out.write(buffer[count + 2]); - out.write(buffer[count + 1]); - out.write(buffer[count]); - out.write(buffer[count + 3]); - } - out.flush(); - out.close(); - } catch(IOException e) { - e.printStackTrace(); - } - } - - @SuppressWarnings("restriction") - public static Image loadAsset(String file) throws Exception { - if (cache.get(file) == null) { - File f = loadFile(file); - if (f.getName().endsWith(".fxml")) { - loadLayout(file); - return null; - } else if ((f == null || !f.exists()) && f.getName().endsWith(".png")) { - WritableImage obj_img = new WritableImage(30, 30); - byte alpha = (byte) 0; - for (int cx = 0; cx < obj_img.getWidth(); cx++) { - for (int cy = 0; cy < obj_img.getHeight(); cy++) { - int color = obj_img.getPixelReader().getArgb(cx, cy); - int mc = (alpha << 24) | 0x00ffffff; - int newColor = color & mc; - obj_img.getPixelWriter().setArgb(cx, cy, newColor); - } - } - - cache.put(file, obj_img); - System.out.println("No image at " + file); - - try { - new RuntimeException().printStackTrace(); - File imageFile = ScriptingEngine.createFile(getGitSource(), file, "create file"); - try { - String fileName = imageFile.getName(); - writeImage(obj_img, imageFile); - - } catch (Exception ignored) { - } - ScriptingEngine.createFile(getGitSource(), file, "saving new content"); - } catch (Exception e) { - e.printStackTrace(); - } - } else if (f.getName().endsWith(".png")) { - cache.put(file, new Image(f.toURI().toString())); - }else { - return null; - } - } - return cache.get(file); - } - - public static javafx.scene.image.ImageView loadIcon(String file) { - try { - ImageView imageView = new ImageView(loadAsset(file)); - FontSizeManager.addListener(fontNum->{ - imageView.setScaleX(FontSizeManager.getImageScale()); - imageView.setScaleY(FontSizeManager.getImageScale()); - }); - return imageView; - } catch (Exception e) { - e.printStackTrace(); - try { - return new ImageView(loadAsset("BowlerStudio.png")); - } catch (Exception e1) { - new IssueReportingExceptionHandler().except(e1); - throw new RuntimeException(e1); + public static final String repo = "BowlerStudioImageAssets"; + private static String gitSource = "https://github.com/CommonWealthRobotics/" + repo + ".git"; + private static HashMap cache = new HashMap<>(); + private static HashMap loaders = new HashMap<>(); + private static String assetRepoBranch = "main"; + + private AssetFactory() { + } + + static { + com.neuronrobotics.sdk.common.Log.info("AssetFactory loaded"); + // new RuntimeException().printStackTrace(); + } + + public static FXMLLoader loadLayout(String file, boolean refresh) throws Exception { + File fxmlFIle = loadFile(file); + URL fileURL = fxmlFIle.toURI().toURL(); + + if (loaders.get(file) == null || refresh) { + loaders.put(file, new FXMLLoader(fileURL)); + } + + loaders.get(file).setLocation(fileURL); + return loaders.get(file); + } + + public static FXMLLoader loadLayout(String file) throws Exception { + return loadLayout(file, false); + } + + public static File loadFile(String file) throws Exception { + return ScriptingEngine.fileFromGit(getGitSource(), // git repo, change this if you fork this demo + getAssetRepoBranch(), file// File from within the Git repo + ); + } + + public static void writeImage(Image img, File file) { + int width = (int) img.getWidth(); + int height = (int) img.getHeight(); + PixelReader reader = img.getPixelReader(); + byte[] buffer = new byte[width * height * 4]; + javafx.scene.image.WritablePixelFormat format = javafx.scene.image.PixelFormat + .getByteBgraInstance(); + reader.getPixels(0, 0, width, height, format, buffer, 0, width * 4); + try { + BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file)); + for (int count = 0; count < buffer.length; count += 4) { + out.write(buffer[count + 2]); + out.write(buffer[count + 1]); + out.write(buffer[count]); + out.write(buffer[count + 3]); + } + out.flush(); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("restriction") + public static Image loadAsset(String file) throws Exception { + if (cache.get(file) == null) { + //com.neuronrobotics.sdk.common.Log.debug("Loading asset " + file); + File f = loadFile(file); + if (f.getName().endsWith(".fxml")) { + loadLayout(file); + return null; + } else if (f.getName().endsWith(".png") && f.exists()) { + cache.put(file, new Image(f.toURI().toString())); + } else if ((f == null || !f.exists()) && f.getName().endsWith(".png")) { + WritableImage obj_img = new WritableImage(30, 30); + byte alpha = (byte) 0; + for (int cx = 0; cx < obj_img.getWidth(); cx++) { + for (int cy = 0; cy < obj_img.getHeight(); cy++) { + int color = obj_img.getPixelReader().getArgb(cx, cy); + int mc = (alpha << 24) | 0x00ffffff; + int newColor = color & mc; + obj_img.getPixelWriter().setArgb(cx, cy, newColor); + } + } + + cache.put(file, obj_img); + if (PasswordManager.loggedIn()) { + com.neuronrobotics.sdk.common.Log.error("No image at " + file); + + try { + new RuntimeException().printStackTrace(); + File imageFile = ScriptingEngine.createFile(getGitSource(), file, "create file"); + try { + String fileName = imageFile.getName(); + writeImage(obj_img, imageFile); + + } catch (Exception ignored) { + } + ScriptingEngine.createFile(getGitSource(), file, "saving new content"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + return null; + } + } + return cache.get(file); + } + + public static javafx.scene.image.ImageView loadIcon(String file) { + try { + ImageView imageView = new ImageView(loadAsset(file)); + FontSizeManager.addListener(fontNum -> { + imageView.setScaleX(FontSizeManager.getImageScale()); + imageView.setScaleY(FontSizeManager.getImageScale()); + }); + return imageView; + } catch (Exception e) { + e.printStackTrace(); + try { + return new ImageView(loadAsset("BowlerStudio.png")); + } catch (Exception e1) { + new IssueReportingExceptionHandler().except(e1); + throw new RuntimeException(e1); + } + } + } + + public static String getGitSource() throws Exception { + return gitSource; + } + + public static void setGitSource(String gitSource, String assetRepoBranch) throws Exception { + com.neuronrobotics.sdk.common.Log.error("Assets from: " + gitSource + "#" + assetRepoBranch); + // new Exception().printStackTrace(); + setAssetRepoBranch(assetRepoBranch); + AssetFactory.gitSource = gitSource; + cache.clear(); + loadAllAssets(); + } + + public static void loadAllAssets() throws Exception { + com.neuronrobotics.sdk.common.Log.info("Loading assets"); + List files; + try { + files = ScriptingEngine.filesInGit(gitSource, StudioBuildInfo.getVersion(), null); + } catch (Exception ex) { + files = ScriptingEngine.filesInGit(getGitSource()); + } + for (String file : files) { + //com.neuronrobotics.sdk.common.Log.error("Loading asset file: " + file); + loadAsset(file); + } + } + + public static String getAssetRepoBranch() { + return assetRepoBranch; + } + + public static void setAssetRepoBranch(String assetRepoBranch) { + AssetFactory.assetRepoBranch = assetRepoBranch; + } + + public static void deleteFolder(File folder) { + File[] files = folder.listFiles(); + if (files != null) { // some JVMs return null for empty dirs + for (File f : files) { + if (f.isDirectory()) { + deleteFolder(f); + } else { + f.delete(); + } + } + } + folder.delete(); } - } - } - - public static String getGitSource() throws Exception { - return gitSource; - } - - public static void setGitSource(String gitSource, String assetRepoBranch) throws Exception { - System.err.println("Assets from: " + gitSource + "#" + assetRepoBranch); - //new Exception().printStackTrace(); - setAssetRepoBranch(assetRepoBranch); - AssetFactory.gitSource = gitSource; - cache.clear(); - loadAllAssets(); - } - - public static void loadAllAssets() throws Exception { - System.err.println("Loading assets"); - List files; - try { - files = ScriptingEngine.filesInGit(gitSource, StudioBuildInfo.getVersion(), null); - }catch(Exception ex) { - files = ScriptingEngine.filesInGit(gitSource); - } - for (String file : files) { - System.err.println("Loading asset file: "+file); - loadAsset(file); - } - } - - public static String getAssetRepoBranch() { - return assetRepoBranch; - } - - public static void setAssetRepoBranch(String assetRepoBranch) { - AssetFactory.assetRepoBranch = assetRepoBranch; - } - - public static void deleteFolder(File folder) { - File[] files = folder.listFiles(); - if (files != null) { //some JVMs return null for empty dirs - for (File f : files) { - if (f.isDirectory()) { - deleteFolder(f); - } else { - f.delete(); - } - } - } - folder.delete(); - } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/assets/ConfigurationDatabase.java b/src/main/java/com/neuronrobotics/bowlerstudio/assets/ConfigurationDatabase.java index 2c22875b0..ff824bbb8 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/assets/ConfigurationDatabase.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/assets/ConfigurationDatabase.java @@ -18,10 +18,19 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import com.neuronrobotics.bowlerstudio.IssueReportingExceptionHandler; +import com.neuronrobotics.bowlerstudio.scripting.DownloadManager; import com.neuronrobotics.bowlerstudio.scripting.IGithubLoginListener; import com.neuronrobotics.bowlerstudio.scripting.PasswordManager; import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; + +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; + import java.nio.charset.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + import org.apache.commons.io.*; public class ConfigurationDatabase { @@ -57,6 +66,7 @@ public static Set keySet(String name) { } public static boolean containsKey(String paramsKey, String string) { boolean containsKey = false; + getDatabase(); synchronized(database){ containsKey = ConfigurationDatabase.getParamMap(paramsKey).containsKey(string); } @@ -89,7 +99,7 @@ public static Object getObject(String paramsKey, String objectKey, Object defau getDatabase(); synchronized(database){ if (getParamMap(paramsKey).get(objectKey) == null) { - //System.err.println("Cant find: " + paramsKey + ":" + objectKey); + //com.neuronrobotics.sdk.common.Log.error("Cant find: " + paramsKey + ":" + objectKey); setObject(paramsKey, objectKey, defaultValue); } ret= getParamMap(paramsKey).get(objectKey); @@ -141,11 +151,11 @@ public static void save() { try (PrintWriter out = new PrintWriter(f.getAbsolutePath())) { out.println(writeOut); } catch (FileNotFoundException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); return; } - System.out.println("Saved "+f.getName()); + //com.neuronrobotics.sdk.common.Log.error("Saved "+f.getName()); } @SuppressWarnings("unchecked") @@ -156,11 +166,14 @@ public static void getDatabase() { File loadFile = loadFile(); if(loadFile.exists()) try { - database = Collections.synchronizedMap((HashMap>) ScriptingEngine.inlineFileScriptRun(loadFile, null)); + File parent =loadFile.getParentFile(); + File db = new File(parent.getAbsolutePath()+DownloadManager.delim()+"CSGdatabase.json"); + CSGDatabaseInstance instance = new CSGDatabaseInstance(db); + Object inlineFileScriptRun = ScriptingEngine.inlineFileScriptRun(instance,loadFile, null); + database = Collections.synchronizedMap((HashMap>) inlineFileScriptRun); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // databse is empty } if (database == null) { @@ -172,33 +185,93 @@ public static void getDatabase() { } public static File loadFile() { - File f = new File(ScriptingEngine.getWorkspace().getAbsolutePath()+"/ConfigurationDatabase.json"); + Path appDataDirectory = getAppDataDirectory(); + File dir = appDataDirectory.toFile(); + if(!dir.exists()) { + dir.mkdirs(); + } + File f = new File(appDataDirectory+"/ConfigurationDatabase.json"); if(!f.exists()) { try { f.createNewFile(); } catch (IOException e) { throw new RuntimeException(e.getMessage()); } - String username = PasswordManager.getLoginID(); - if(username!=null) - try { - File file =ScriptingEngine.fileFromGit("https://github.com/"+username+"/BowlerStudioConfiguration.git", "database.json"); - if(file.exists()) { - String contents= FileUtils.readFileToString(file, StandardCharsets.UTF_8); - try (PrintWriter out = new PrintWriter(f.getAbsolutePath())) { - out.println(contents); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } } return f; } + public static Path getAppDataDirectory() { + String appName="CaDoodle"; + String os = System.getProperty("os.name").toLowerCase(); + + if (os.contains("win")) { + return getWindowsAppData(appName); + } else if (os.contains("mac")) { + return getMacAppData(appName); + } else { + return getLinuxAppData(appName); + } + } + + public static Path getWindowsAppData(String appName) { + // Try LOCALAPPDATA first (safe, never synced to OneDrive) + String localAppData = System.getenv("LOCALAPPDATA"); + if (localAppData != null && !localAppData.isEmpty()) { + return Paths.get(localAppData, appName); + } + + // Next try APPDATA + String appData = System.getenv("APPDATA"); + if (appData != null && !appData.isEmpty()) { + return ensureNoOneDrive(Paths.get(appData), appName); + } + + // Fallback to user.home + String userHome = System.getProperty("user.home"); + Path homePath = Paths.get(userHome); + homePath = stripOneDrive(homePath); // sanitize + return homePath.resolve("AppData").resolve("Local").resolve(appName); + } + + private static Path ensureNoOneDrive(Path path, String appName) { + Path sanitized = stripOneDrive(path); + return sanitized.resolve(appName); + } + + private static Path stripOneDrive(Path path) { + // Look for "OneDrive" component in the path and cut everything after it + for (int i = 0; i < path.getNameCount(); i++) { + if (path.getName(i).toString().equalsIgnoreCase("OneDrive")) { + // Return path up to but not including "OneDrive" + return path.getRoot().resolve(path.subpath(0, i)); + } + } + return path; + } + + private static Path getMacAppData(String appName) { + String userHome = System.getProperty("user.home"); + return Paths.get(userHome, "Library", "Application Support", appName); + } + + private static Path getLinuxAppData(String appName) { + // Follow XDG Base Directory Specification + String xdgConfigHome = System.getenv("XDG_CONFIG_HOME"); + if (xdgConfigHome != null && !xdgConfigHome.isEmpty()) { + return Paths.get(xdgConfigHome, appName); + } + + String userHome = System.getProperty("user.home"); + return Paths.get(userHome, ".config", appName); + } + + public static void ensureDirectoryExists(Path directory) { + try { + Files.createDirectories(directory); + } catch (IOException e) { + throw new RuntimeException("Failed to create app data directory: " + directory, e); + } + } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/assets/StudioBuildInfo.java b/src/main/java/com/neuronrobotics/bowlerstudio/assets/StudioBuildInfo.java index b5c58f6f9..6cba98058 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/assets/StudioBuildInfo.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/assets/StudioBuildInfo.java @@ -86,7 +86,7 @@ public static String getBuildDate() { } } catch (IOException ignored) { } - // System.out.println("Manifest:\n"+s); + // com.neuronrobotics.sdk.common.Log.error("Manifest:\n"+s); return ""; } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/creature/CadFileExporter.java b/src/main/java/com/neuronrobotics/bowlerstudio/creature/CadFileExporter.java index a3520d40e..57d2ff6cd 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/creature/CadFileExporter.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/creature/CadFileExporter.java @@ -10,11 +10,13 @@ import org.apache.commons.io.FilenameUtils; import com.neuronrobotics.bowlerstudio.scripting.BlenderLoader; +import com.neuronrobotics.bowlerstudio.scripting.FreecadLoader; import eu.mihosoft.vrl.v3d.CSG; import eu.mihosoft.vrl.v3d.FileUtil; import eu.mihosoft.vrl.v3d.JavaFXInitializer; import eu.mihosoft.vrl.v3d.Transform; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import eu.mihosoft.vrl.v3d.svg.SVGExporter; import javafx.scene.transform.Affine; @@ -29,37 +31,37 @@ public CadFileExporter(){ @Override public void setSelectedCsg(Collection selectedCsg) { - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public void setAllCSG(Collection toAdd, File source) { - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public void highlightException(File fileEngineRunByName, Throwable ex) { - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public Set getVisibleCSGs() { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } @Override public void addCSG(Collection toAdd, File source) { - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public void setSelected(Affine rootListener) { - // TODO Auto-generated method stub + // Auto-generated method stub } }; @@ -82,7 +84,11 @@ public ArrayList generateManufacturingParts(List totalAssembly , File } int index=0; ArrayList svgParts = new ArrayList<>(); + ArrayList blendParts = new ArrayList<>(); + ArrayList freecadParts = new ArrayList<>(); String svgName =null; + String blendName=null; + String freecadName=null; String nameBase =""; for(CSG part: totalAssembly){ String name = part.getName(); @@ -99,8 +105,8 @@ public ArrayList generateManufacturingParts(List totalAssembly , File try { allCadStl.add(makeStl(nameBase,manufactured));// default to stl }catch(Throwable t) { - System.err.println("Failed to generate "+part.getName()); - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error("Failed to generate "+part.getName()); + com.neuronrobotics.sdk.common.Log.error(t); } }else{ @@ -109,10 +115,6 @@ public ArrayList generateManufacturingParts(List totalAssembly , File allCadStl.add(makeObj(nameBase,manufactured));// ui.setCsg(manufactured , null); } - if(format.toLowerCase().contains("blend")){ - allCadStl.add(makeBlender(nameBase,manufactured));// - ui.setCsg(manufactured , null); - } if(format.toLowerCase().contains("stl")){ allCadStl.add(makeStl(nameBase,manufactured));// default to stl ui.setCsg(manufactured , null); @@ -124,7 +126,22 @@ public ArrayList generateManufacturingParts(List totalAssembly , File svgParts.add(manufactured); ui.setAllCSG(svgParts , null); } - + if(format.toLowerCase().contains("blend")){ + //allCadStl.add(makeBlender(nameBase,manufactured));// + ui.setCsg(manufactured , null); + if(blendName==null){ + blendName =part.toString(); + } + blendParts.add(manufactured); + } + if(format.toLowerCase().contains("freecad")){ + //allCadStl.add(makeBlender(nameBase,manufactured));// + ui.setCsg(manufactured , null); + if(freecadName==null){ + freecadName =part.toString(); + } + freecadParts.add(manufactured); + } } } @@ -132,28 +149,45 @@ public ArrayList generateManufacturingParts(List totalAssembly , File if(svgParts.size()>0){ allCadStl.add(makeSvg(nameBase,svgParts));// default to stl } - + if(blendParts.size()>0){ + allCadStl.add(makeBlender(nameBase,blendParts));// default to stl + } + if(freecadParts.size()>0){ + allCadStl.add(makeFreecad(nameBase,freecadParts));// default to stl + } + com.neuronrobotics.sdk.common.Log.debug("Finished Export!"); return allCadStl; } + private File makeFreecad(String nameBase,List current ) throws IOException{ + File blend = new File(nameBase + ".FCStd"); + com.neuronrobotics.sdk.common.Log.debug("Writing "+blend.getAbsolutePath()); + for(CSG tmp:current) + FreecadLoader.addCSGToFreeCAD( blend,tmp); + return blend; + } + private File makeStl(String nameBase,CSG tmp ) throws IOException{ File stl = new File(nameBase + ".stl"); - +// boolean manifold=CSG.isPreventNonManifoldTriangles(); +// CSG.setPreventNonManifoldTriangles(false); FileUtil.write(Paths.get(stl.getAbsolutePath()), tmp.toStlString()); - System.out.println("Writing "+stl.getAbsolutePath()); + //CSG.setPreventNonManifoldTriangles(manifold); + com.neuronrobotics.sdk.common.Log.debug("Writing "+stl.getAbsolutePath()); return stl; } private File makeObj(String nameBase,CSG tmp ) throws IOException{ File stl = new File(nameBase + ".obj"); FileUtil.write(Paths.get(stl.getAbsolutePath()), tmp.toObjString()); - System.out.println("Writing "+stl.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.debug("Writing "+stl.getAbsolutePath()); return stl; } - private File makeBlender(String nameBase,CSG tmp ) throws IOException{ + private File makeBlender(String nameBase,List current ) throws IOException{ File blend = new File(nameBase + ".blend"); - System.out.println("Writing "+blend.getAbsolutePath()); - BlenderLoader.toBlenderFile(tmp, blend); + com.neuronrobotics.sdk.common.Log.debug("Writing "+blend.getAbsolutePath()); + for(CSG tmp:current) + BlenderLoader.toBlenderFile(null,tmp, blend); return blend; } @@ -182,10 +216,10 @@ private File makeSvg(String nameBase, List currentCsg) throws IOException { } - System.out.println("Writing " + stl.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.debug("Writing " + stl.getAbsolutePath()); } catch (Throwable t) { - System.err.println("ERROR, NO pixelization engine availible for slicing"); - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error("ERROR, NO pixelization engine availible for slicing"); + com.neuronrobotics.sdk.common.Log.error(t); } return stl; diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/creature/ControllerFeatures.java b/src/main/java/com/neuronrobotics/bowlerstudio/creature/ControllerFeatures.java new file mode 100644 index 000000000..19d74d04a --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/creature/ControllerFeatures.java @@ -0,0 +1,210 @@ +package com.neuronrobotics.bowlerstudio.creature; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; + +import eu.mihosoft.vrl.v3d.Plane; + +public class ControllerFeatures { + @Expose(serialize = true, deserialize = true) + int servoChannels = 0; + @Expose(serialize = true, deserialize = true) + int vexV5Motors = 0; + @Expose(serialize = true, deserialize = true) + int hiwonderBus = 0; + @Expose(serialize = true, deserialize = true) + int dynamixelBus = 0; + @Expose(serialize = true, deserialize = true) + int steppers = 0; + @Expose(serialize = true, deserialize = true) + int motorChannels = 0; + @Expose(serialize = true, deserialize = true) + int analogSensorChannels = 0; + @Expose(serialize = true, deserialize = true) + int cameras = 0; + @Expose(serialize = true, deserialize = true) + int digitalSensorChannels = 0; + @Expose(serialize = true, deserialize = true) + int inertialSensors = 0; + @Expose(serialize = true, deserialize = true) + int distanceSensors = 0; + @Expose(serialize = true, deserialize = true) + int pointCloudSensors = 0; + @Expose(serialize = true, deserialize = true) + List voltages; + @Expose(serialize = true, deserialize = true) + double batteryWattHour = 0; + @Expose(serialize = true, deserialize = true) + double batteryPeakWatt = 0; + + public void add(ControllerFeatures f) { + if (f == null) + return; + vexV5Motors = getVexV5Motors() + f.vexV5Motors; + hiwonderBus = getHiwonderBus() + f.hiwonderBus; + dynamixelBus = getDynamixelBus() + f.dynamixelBus; + steppers = getSteppers() + f.steppers; + servoChannels += f.servoChannels; + motorChannels += f.motorChannels; + analogSensorChannels += f.analogSensorChannels; + cameras += f.cameras; + digitalSensorChannels += f.digitalSensorChannels; + inertialSensors += f.inertialSensors; + distanceSensors += f.distanceSensors; + pointCloudSensors += f.pointCloudSensors; + ArrayList toadd = new ArrayList(); + for (Double v : f.getBatteryVoltage()) { + boolean found = false; + for (Double d : getBatteryVoltage()) { + if (Math.abs(v - d) < Plane.getEPSILON()) { + found = true; + } + } + if (!found) + toadd.add(v); + } + getBatteryVoltage().addAll(toadd); + batteryPeakWatt += f.batteryPeakWatt; + batteryWattHour += f.batteryWattHour; + } + + public boolean check(ControllerFeatures f) { + if (f == null) + return false; + if (getVexV5Motors() < f.getVexV5Motors()) + return false; + if (getHiwonderBus() < f.getHiwonderBus()) + return false; + if (getDynamixelBus() < f.getDynamixelBus()) + return false; + if (getSteppers() < f.getSteppers()) + return false; + if (servoChannels < f.servoChannels) + return false; + if (motorChannels < f.motorChannels) + return false; + if (analogSensorChannels < f.analogSensorChannels) + return false; + if (cameras < f.cameras) + return false; + if (digitalSensorChannels < f.digitalSensorChannels) + return false; + if (inertialSensors < f.inertialSensors) + return false; + if (distanceSensors < f.distanceSensors) + return false; + if (pointCloudSensors < f.pointCloudSensors) + return false; + for (Double v : f.getBatteryVoltage()) { + boolean found = false; + for (Double d : getBatteryVoltage()) { + if (Math.abs(v - d) < Plane.getEPSILON()) { + found = true; + } + } + if (!found) + return false; + else + break; + } + if (batteryPeakWatt < f.batteryPeakWatt) + return false; + if (batteryWattHour < f.batteryWattHour) + return false; + return true; + } + + public void subtract(ControllerFeatures f) { + if (f == null) + return; + vexV5Motors = getVexV5Motors() - f.vexV5Motors; + hiwonderBus = getHiwonderBus() - f.hiwonderBus; + dynamixelBus = getDynamixelBus() - f.dynamixelBus; + steppers = getSteppers() - f.steppers; + servoChannels -= f.servoChannels; + motorChannels -= f.motorChannels; + analogSensorChannels -= f.analogSensorChannels; + cameras -= f.cameras; + digitalSensorChannels -= f.digitalSensorChannels; + inertialSensors -= f.inertialSensors; + distanceSensors -= f.distanceSensors; + pointCloudSensors -= f.pointCloudSensors; + batteryPeakWatt -= f.batteryPeakWatt; + batteryWattHour -= f.batteryWattHour; + } + + @Override + public String toString() { + return "\n\tServos: " + servoChannels + "\n" + "\tmotorChannels: " + motorChannels + "\n" + + "\tanalogSensorChannels: " + analogSensorChannels + "\n" + "\tcameras: " + cameras + "\n" + + "\tdigitalSensorChannels: " + digitalSensorChannels + "\n" + "\tinertialSensors: " + inertialSensors + + "\n" + "\tdistanceSensors: " + distanceSensors + "\n" + "\tpointCloudSensors: " + pointCloudSensors + + "\n" + "\tbatteryPeakWatt: " + batteryPeakWatt + "\n" + "\tbatteryWattHour: " + batteryWattHour + "\n" + + "\tVoltages: " + voltages + "\n"; + } + + public int getServoChannels() { + return servoChannels; + } + + public int getMotorChannels() { + return motorChannels; + } + + public int getAnalogSensorChannels() { + return analogSensorChannels; + } + + public int getCameras() { + return cameras; + } + + public int getDigitalSensorChannels() { + return digitalSensorChannels; + } + + public int getInertialSensors() { + return inertialSensors; + } + + public int getDistanceSensors() { + return distanceSensors; + } + + public int getPointCloudSensors() { + return pointCloudSensors; + } + + public List getBatteryVoltage() { + if (voltages == null) + voltages = new ArrayList(); + return voltages; + } + + public double getBatteryPeakWatts() { + return batteryPeakWatt; + } + + public double getBatteryWattHours() { + return batteryWattHour; + } + + public int getVexV5Motors() { + return vexV5Motors; + } + + public int getHiwonderBus() { + return hiwonderBus; + } + + public int getDynamixelBus() { + return dynamixelBus; + } + + public int getSteppers() { + return steppers; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/creature/ControllerOption.java b/src/main/java/com/neuronrobotics/bowlerstudio/creature/ControllerOption.java new file mode 100644 index 000000000..07f0358b4 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/creature/ControllerOption.java @@ -0,0 +1,242 @@ +package com.neuronrobotics.bowlerstudio.creature; + +import static com.neuronrobotics.bowlerstudio.scripting.DownloadManager.delim; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidRemoteException; +import org.eclipse.jgit.api.errors.TransportException; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import com.google.gson.reflect.TypeToken; +import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.CaDoodleFile; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.AddRobotController; +import com.neuronrobotics.bowlerstudio.vitamins.Vitamins; +import com.neuronrobotics.sdk.addons.kinematics.VitaminLocation; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; +import javafx.scene.image.Image; +import javafx.scene.paint.Color; + +public class ControllerOption { + public static final String URL_OF_OPTIONS = "https://github.com/CommonWealthRobotics/BowlerStudioExampleRobots.git"; + @Expose(serialize = true, deserialize = true) + String type; + @Expose(serialize = true, deserialize = true) + String imageGit; + @Expose(serialize = true, deserialize = true) + String imageFile; + @Expose(serialize = true, deserialize = true) + List vitaminType; + @Expose(serialize = true, deserialize = true) + List vitaminSize; + @Expose(serialize = true, deserialize = true) + List vitaminPose; + @Expose(serialize = true, deserialize = true) + String linkLoaderGit; + @Expose(serialize = true, deserialize = true) + String linkLoaderFile; + @Expose(serialize = true, deserialize = true) + String linkDeviceName; + @Expose(serialize = true, deserialize = true) + String linkDeviceType; + @Expose(serialize = true, deserialize = true) + String firmwareGit; + @Expose(serialize = true, deserialize = true) + String firmwareFile; + @Expose(serialize = true, deserialize = true) + ControllerFeatures provides; + @Expose(serialize = true, deserialize = true) + ControllerFeatures consumes; + + // Internal variables + private boolean built=false; + javafx.scene.image.Image image = null; + CSG indicator = null; + File stlFile = null; + private ArrayList back; + private String baseName; + + public void build(CaDoodleFile f) { + if(built) + return; + built=true; + image = new Image(getImageFile().toURI().toString()); + String absolutePath = ScriptingEngine.getWorkspace().getAbsolutePath() + delim() + "uicache"; + File dir = new File(absolutePath); + if (!dir.exists()) + dir.mkdirs(); + stlFile = new File(absolutePath + delim() + type + ".stl"); + if ( stlFile.exists()) { + indicator = Vitamins.get(f.getCsgDBinstance(),stlFile); + getIndicator().setColor(Color.WHITE); + return; + }else { + AddRobotController arc = new AddRobotController().setController(this); + arc.setCaDoodleFile(f); + List so = arc.process(new ArrayList<>()); + for (CSG c : so) { + for (String s : c.getParameters(f.getCsgDBinstance())) { + f.getCsgDBinstance().delete(s); + } + } + indicator = so.get(0); + if (so.size() > 1) { + for(int i=1;i getOptions() + throws InvalidRemoteException, TransportException, GitAPIException, IOException { + try { + Type TT_CaDoodleFile = new TypeToken>() { + }.getType(); + Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting() + .excludeFieldsWithoutExposeAnnotation().create(); + + File f = ScriptingEngine.fileFromGit(URL_OF_OPTIONS, "controllerOptions.json"); + String content = FileUtils.readFileToString(f, StandardCharsets.UTF_8); + return gson.fromJson(content, TT_CaDoodleFile); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + return new ArrayList(); + } + } + + public String getLinkDeviceName() { + return linkDeviceName; + } + public CSG getVitaminCSG(CSGDatabaseInstance instance,int index) { + try { + return Vitamins.get(instance,vitaminType.get(index), vitaminSize.get(index)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + public List getVitaminType() { + return vitaminType; + } + public int getVitaminNumber() { + return vitaminSize.size(); + } + public List getVitaminSize() { + return vitaminSize; + } + + public String getLinkDeviceType() { + return linkDeviceType; + } + + public javafx.scene.image.Image getImage() { + return image; + } + public TransformNR getVitaminPose(int index) { + return getVitaminPose().get(index); + } + public List getVitaminPose() { + if(vitaminPose==null) + return new ArrayList<>(Arrays.asList(new TransformNR())); + return vitaminPose; + } + + public CSG getIndicator() { + return indicator; + } + + public ControllerFeatures getProvides() { + return provides; + } + + public ControllerFeatures getConsumes() { + return consumes; + } + + public ArrayList getVitamins(TransformNR location, String baseName) { + if(back==null ) { + this.baseName = baseName; + back = new ArrayList(); + for (int i = 0; i < getVitaminNumber(); i++) { + TransformNR offset = location.times(getVitaminPose(i)); + back.add(new VitaminLocation(false,baseName+"_"+i, vitaminType.get(i), vitaminSize.get(i), offset) + ); + } + } + return back; + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/creature/DHLimbBuilder.java b/src/main/java/com/neuronrobotics/bowlerstudio/creature/DHLimbBuilder.java new file mode 100644 index 000000000..ea53bfaba --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/creature/DHLimbBuilder.java @@ -0,0 +1,5 @@ +package com.neuronrobotics.bowlerstudio.creature; + +public class DHLimbBuilder { + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/creature/LimbOption.java b/src/main/java/com/neuronrobotics/bowlerstudio/creature/LimbOption.java new file mode 100644 index 000000000..b6d17a310 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/creature/LimbOption.java @@ -0,0 +1,191 @@ +package com.neuronrobotics.bowlerstudio.creature; + +import static com.neuronrobotics.bowlerstudio.scripting.DownloadManager.delim; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import javax.imageio.ImageIO; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidRemoteException; +import org.eclipse.jgit.api.errors.TransportException; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import com.google.gson.reflect.TypeToken; +import com.neuronrobotics.bowlerstudio.BowlerKernel; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.bowlerstudio.scripting.RobotHelper; +import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.CaDoodleFile; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.AddRobotLimb; +import com.neuronrobotics.bowlerstudio.vitamins.Vitamins; +import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics; +import com.neuronrobotics.sdk.addons.kinematics.MobileBase; +import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.FileUtil; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import javafx.scene.paint.Color; + +public class LimbOption { + @Expose(serialize = true, deserialize = true) + LimbType type; + @Expose(serialize = true, deserialize = true) + String name; + @Expose(serialize = true, deserialize = true) + String url; + @Expose(serialize = true, deserialize = true) + String file; + @Expose(serialize = true, deserialize = true) + boolean composite; + @Expose(serialize = true, deserialize = true) + ControllerFeatures consumes; + @Expose(serialize = true, deserialize = true) + ControllerFeatures provides; + public static final TransformNR LimbRotationOffset=new TransformNR(new RotationNR(0, 90, -90)); + + private CSG indicator; + private Image image; + + public DHParameterKinematics getLimb(String uniqueName) throws Exception { + String xmlContent = ScriptingEngine.codeFromGit(url, file)[0]; + if (!composite) { + DHParameterKinematics newLimb = new DHParameterKinematics(null, IOUtils.toInputStream(xmlContent, "UTF-8")); + newLimb.setScriptingName(uniqueName); + return newLimb; + } else { + MobileBase base = RobotHelper.fileToRobot(url, file); + DHParameterKinematics newLimb = base.getAllDHChains().get(0); + newLimb.setScriptingName(uniqueName); + return newLimb; + } + } + + public static ArrayList getOptions() + throws InvalidRemoteException, TransportException, GitAPIException, IOException { + try { + Type TT_CaDoodleFile = new TypeToken>() { + }.getType(); + Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting() + .excludeFieldsWithoutExposeAnnotation().create(); + File f = ScriptingEngine.fileFromGit(ControllerOption.URL_OF_OPTIONS, "limbOptions.json"); + String content = FileUtils.readFileToString(f, StandardCharsets.UTF_8); + return gson.fromJson(content, TT_CaDoodleFile); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + return new ArrayList(); + } + } + + @Override + public String toString() { + return getType() + " " + getName() + " " + url + "/" + file + "\n\tConsumes:" + getConsumes() + "\n\tProvides:" + getProvides(); + } + + public ControllerFeatures getConsumes() { + return consumes; + } + + public ControllerFeatures getProvides() { + return provides; + } + + public LimbType getType() { + return type; + } + + public String getName() { + return name; + } + + public void build(CaDoodleFile f) throws IOException { + String absolutePath = ScriptingEngine.getWorkspace().getAbsolutePath() + delim() + "uicache"; + File dir = new File(absolutePath); + if (!dir.exists()) + dir.mkdirs(); + File imageFile = new File(absolutePath + delim() + type + name + ".png"); + File stlFile = new File(absolutePath + delim() + type + name + ".stl"); + if (imageFile.exists() && stlFile.exists()) { + indicator = Vitamins.get(f.getCsgDBinstance(),stlFile); + indicator=indicator.transformed(TransformFactory.nrToCSG(LimbRotationOffset)); + indicator.setColor(Color.WHITE); + image = new Image(imageFile.toURI().toString()); + return; + } + AddRobotLimb add = new AddRobotLimb().setLimb(this) + .setLocation(new TransformNR()); + add.setCaDoodleFile(f); + add.forceLoad=true; + MobileBaseBuilder value = new MobileBaseBuilder(Files.createTempDirectory(name + "-").toFile().getAbsolutePath(), "testfile"); + add.setBuilderName("tmp"); + add.getRobots().put("tmp", value); + List so = add.process(new ArrayList<>()); + add.getRobots().remove("tmp"); + for (CSG c : so) { + for (String s : c.getParameters(f.getCsgDBinstance())) { + f.getCsgDBinstance().delete(s); + } + } + BowlerKernel.runLater(() -> { + image = ThumbnailImage.get(f.getCsgDBinstance(),so); + }); + while(image==null) { + try { + Thread.sleep(20); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + } + try { + BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null); + ImageIO.write(bufferedImage, "png", imageFile); + System.err.println("Thumbnail saved successfully to " + imageFile.getAbsolutePath()); + } catch (Exception e) { + // com.neuronrobotics.sdk.common.Log.error("Error saving image: " + + // e.getMessage()); + com.neuronrobotics.sdk.common.Log.error(e); + } + indicator = get(so.get(0)); + if (so.size() > 1) { + for(int i=1;i controllers = new ArrayList(); + ArrayList limbs = new ArrayList(); + ArrayList mods = new ArrayList(); + private MobileBase mobileBase; + private String gitURL; + private String xmlName = null; + + // Channel management + private Map> deviceChannelMap = new HashMap<>(); + + // Constructor for creating a new MobileBase + public MobileBaseBuilder(String gitURL, String name) { + this.gitURL = gitURL; + this.mobileBase = new MobileBase(); + this.mobileBase.setScriptingName(name); + initializeChannelMap(); + } + + // Constructor for extending an existing MobileBase + public MobileBaseBuilder(MobileBase existingBase) { + this.gitURL = existingBase.getGitSelfSource()[0]; + this.mobileBase = existingBase; + initializeChannelMap(); + scanExistingChannels(); + } + + // Copy functionality from the menu factory + public MobileBaseBuilder copyFrom(MobileBase source, String newName) { + try { + mobileBase.setScriptingName(newName); + + // Copy engines + if (source.getGitCadEngine() != null) { + mobileBase.setGitCadEngine(copyGitFile(source.getGitCadEngine(), gitURL)); + } + if (source.getGitWalkingEngine() != null) { + mobileBase.setGitWalkingEngine(copyGitFile(source.getGitWalkingEngine(), gitURL)); + } + + // Copy appendages + for (DHParameterKinematics leg : source.getLegs()) { + DHParameterKinematics copiedLeg = copyDHParameterKinematics(leg); + mobileBase.getLegs().add(copiedLeg); + } + + for (DHParameterKinematics arm : source.getAppendages()) { + DHParameterKinematics copiedArm = copyDHParameterKinematics(arm); + mobileBase.getAppendages().add(copiedArm); + } + + for (DHParameterKinematics wheel : source.getSteerable()) { + DHParameterKinematics copiedWheel = copyDHParameterKinematics(wheel); + mobileBase.getSteerable().add(copiedWheel); + } + + for (DHParameterKinematics wheel : source.getDrivable()) { + DHParameterKinematics copiedWheel = copyDHParameterKinematics(wheel); + mobileBase.getDrivable().add(copiedWheel); + } + + // Copy transforms + mobileBase.setFiducialToGlobalTransform(source.getRobotToFiducialTransform()); + mobileBase.setIMUFromCentroid(source.getIMUFromCentroid()); + } catch (Exception e) { + Log.error("Failed to copy from source MobileBase: " + e.getMessage()); + } + return this; + } + +// // Constructor for extending an existing MobileBase with new name +// public MobileBaseBuilder(String gitURL, MobileBase existingBase, String newName) { +// this.gitURL = gitURL; +// this.mobileBase = existingBase; +// this.mobileBase.setScriptingName(newName); +// initializeChannelMap(); +// scanExistingChannels(); +// } + + public MobileBase cloneMobileBase(MobileBase source) { + try { + // Create a deep copy by serializing and deserializing XML + String xml = source.getXml(); + MobileBase clone = new MobileBase(); + clone.setScriptingName(source.getScriptingName()); + + // Copy all appendages + for (DHParameterKinematics leg : source.getLegs()) { + clone.getLegs().add(copyDHParameterKinematics(leg)); + } + for (DHParameterKinematics arm : source.getAppendages()) { + clone.getAppendages().add(copyDHParameterKinematics(arm)); + } + for (DHParameterKinematics wheel : source.getSteerable()) { + clone.getSteerable().add(copyDHParameterKinematics(wheel)); + } + for (DHParameterKinematics wheel : source.getDrivable()) { + clone.getDrivable().add(copyDHParameterKinematics(wheel)); + } + + // Copy transforms + if (source.getRobotToFiducialTransform() != null) { + clone.setRobotToFiducialTransform(source.getRobotToFiducialTransform()); + } + if (source.getIMUFromCentroid() != null) { + clone.setIMUFromCentroid(source.getIMUFromCentroid()); + } + + // Copy engines + if (source.getGitCadEngine() != null) { + clone.setGitCadEngine(source.getGitCadEngine()); + } + if (source.getGitWalkingEngine() != null) { + clone.setGitWalkingEngine(source.getGitWalkingEngine()); + } + + return clone; + } catch (Exception e) { + Log.error("Failed to clone MobileBase: " + e.getMessage()); + return new MobileBase(); + } + } + + private void initializeChannelMap() { + // Initialize with empty channel maps - will be populated as needed + } + + private void scanExistingChannels() { + // Scan all existing appendages to build current channel usage map + scanAppendageChannels(mobileBase.getLegs()); + scanAppendageChannels(mobileBase.getAppendages()); + scanAppendageChannels(mobileBase.getSteerable()); + scanAppendageChannels(mobileBase.getDrivable()); + } + + private void scanAppendageChannels(List appendages) { + for (DHParameterKinematics appendage : appendages) { + for (LinkConfiguration conf : appendage.getLinkConfigurations()) { + String deviceName = conf.getDeviceScriptingName(); + int channel = conf.getHardwareIndex(); + if (deviceName != null) { + reserveDeviceChannel(deviceName, channel); + } + } + } + } + + // Getter for the current MobileBase instance + public MobileBase getMobileBase() { + return mobileBase; + } + + public MobileBaseBuilder setXmlName(String xmlName) { + this.xmlName = xmlName; + return this; + } + + public MobileBaseBuilder setGitCadEngine(String gitURL, String filename) { + mobileBase.setGitCadEngine(new String[] { gitURL, filename }); + return this; + } + + public MobileBaseBuilder setGitWalkingEngine(String gitURL, String filename) { + mobileBase.setGitWalkingEngine(new String[] { gitURL, filename }); + return this; + } + + public MobileBaseBuilder setRobotToFiducialTransform(TransformNR transform) { + mobileBase.setRobotToFiducialTransform(transform); + return this; + } + + public MobileBaseBuilder setIMUFromCentroid(TransformNR transform) { + mobileBase.setIMUFromCentroid(transform); + return this; + } + + public MobileBaseBuilder setBodyMass(double mass) { + // Note: MobileBase doesn't seem to have a setBodyMass method + // You may need to add this functionality to MobileBase or handle it differently + return this; + } + + // Leg management + public MobileBaseBuilder addLeg(DHParameterKinematics leg) { + if (leg != null) { + configureAppendage(leg); + mobileBase.getLegs().add(leg); + } + return this; + } + + public MobileBaseBuilder addDefaultLeg(String legName) { + try { + String xmlContent = ScriptingEngine.codeFromGit( + "https://github.com/CommonWealthRobotics/BowlerStudioExampleRobots.git", "defaultleg.xml")[0]; + DHParameterKinematics newLeg = new DHParameterKinematics(null, IOUtils.toInputStream(xmlContent, "UTF-8")); + newLeg.setScriptingName(legName); + return addLeg(newLeg); + } catch (Exception e) { + Log.error("Failed to add default leg: " + e.getMessage()); + return this; + } + } + + // Arm management + public MobileBaseBuilder addArm(DHParameterKinematics arm) { + if (arm != null) { + configureAppendage(arm); + mobileBase.getAppendages().add(arm); + } + return this; + } + + public MobileBaseBuilder addDefaultArm(String armName) { + try { + String xmlContent = ScriptingEngine.codeFromGit( + "https://github.com/CommonWealthRobotics/BowlerStudioExampleRobots.git", "defaultarm.xml")[0]; + DHParameterKinematics newArm = new DHParameterKinematics(null, IOUtils.toInputStream(xmlContent, "UTF-8")); + newArm.setScriptingName(armName); + return addArm(newArm); + } catch (Exception e) { + Log.error("Failed to add default arm: " + e.getMessage()); + return this; + } + } + + // Wheel management + public MobileBaseBuilder addSteerableWheel(DHParameterKinematics wheel) { + if (wheel != null) { + configureAppendage(wheel); + mobileBase.getSteerable().add(wheel); + } + return this; + } + + public MobileBaseBuilder addDefaultSteerableWheel(String wheelName) { + try { + String xmlContent = ScriptingEngine.codeFromGit( + "https://github.com/CommonWealthRobotics/BowlerStudioExampleRobots.git", "defaultSteerable.xml")[0]; + DHParameterKinematics newWheel = new DHParameterKinematics(null, + IOUtils.toInputStream(xmlContent, "UTF-8")); + newWheel.setScriptingName(wheelName); + return addSteerableWheel(newWheel); + } catch (Exception e) { + Log.error("Failed to add default steerable wheel: " + e.getMessage()); + return this; + } + } + + public MobileBaseBuilder addFixedWheel(DHParameterKinematics wheel) { + if (wheel != null) { + configureAppendage(wheel); + mobileBase.getDrivable().add(wheel); + } + return this; + } + + public MobileBaseBuilder addFixedWheelFromOptions(String wheelType) { + try { + @SuppressWarnings("unchecked") + HashMap> options = (HashMap>) ScriptingEngine + .gitScriptRun(CSGDatabase.getInstance(),"https://github.com/CommonWealthRobotics/BowlerStudioExampleRobots.git", + "wheelOptions.json"); + + if (options.containsKey(wheelType)) { + HashMap values = options.get(wheelType); + + if (wheelType.toLowerCase().contains("fixed")) { + String xmlContent = ScriptingEngine.codeFromGit(values.get("scriptGit").toString(), + values.get("scriptFile").toString())[0]; + DHParameterKinematics newWheel = new DHParameterKinematics(null, + IOUtils.toInputStream(xmlContent, "UTF-8")); + return addFixedWheel(newWheel); + } else { + MobileBase base = RobotHelper.fileToRobot(values.get("scriptGit").toString(), + values.get("scriptFile").toString()); + DHParameterKinematics newWheel = base.getDrivable().get(0); + return addFixedWheel(newWheel); + } + } + } catch (Exception e) { + Log.error("Failed to add wheel from options: " + e.getMessage()); + } + return this; + } + + // Parallel group management + public MobileBaseBuilder addParallelGroup(ParallelGroup group) { + if (group != null) { + // Note: Need to add parallel group support to MobileBase if not already present + // mobileBase.getParallelGroups().add(group); + } + return this; + } + + // Channel management methods + public MobileBaseBuilder reserveDeviceChannel(String deviceName, int channel) { + deviceChannelMap.computeIfAbsent(deviceName, k -> new HashMap<>()).put(channel, true); + return this; + } + + private void configureAppendage(DHParameterKinematics appendage) { + // Set CAD engine if available + String[] cadEngine = mobileBase.getGitCadEngine(); + if (cadEngine != null) { + appendage.setGitCadEngine(cadEngine); + } + + // Configure channels for all links + for (LinkConfiguration conf : appendage.getLinkConfigurations()) { + assignNextAvailableChannel(conf); + } + } + + private void assignNextAvailableChannel(LinkConfiguration conf) { + // Try to find an available channel + for (Map.Entry> deviceEntry : deviceChannelMap.entrySet()) { + String deviceName = deviceEntry.getKey(); + Map channels = deviceEntry.getValue(); + + for (int i = 0; i < 48; i++) { + if (!channels.containsKey(i)) { + conf.setDeviceScriptingName(deviceName); + conf.setHardwareIndex(i); + channels.put(i, true); + return; + } + } + } + + // If no channels available, create a new device + String newDeviceName = conf.getDeviceScriptingName() + "_new"; + conf.setDeviceScriptingName(newDeviceName); + conf.setHardwareIndex(0); + reserveDeviceChannel(newDeviceName, 0); + } + + private DHParameterKinematics copyDHParameterKinematics(DHParameterKinematics source) throws Exception { + // Create a copy by serializing and deserializing XML + String xml = source.getXml(); + DHParameterKinematics copy = new DHParameterKinematics(null, IOUtils.toInputStream(xml, "UTF-8")); + + // Copy git engines + if (source.getGitCadEngine() != null) { + copy.setGitCadEngine(copyGitFile(source.getGitCadEngine(), gitURL)); + } + if (source.getGitDhEngine() != null) { + copy.setGitDhEngine(copyGitFile(source.getGitDhEngine(), gitURL)); + } + + return copy; + } + + private String[] copyGitFile(String[] sourceGit, String targetGit) { + return ScriptingEngine.copyGitFile(sourceGit[0], targetGit, sourceGit[1]); + } + + public File getFile() throws Exception { + return ScriptingEngine.fileFromGit(gitURL, mobileBase.getScriptingName() + ".xml"); + } + + public MobileBase build() throws Exception { + if (!mobileBase.isAvailable()) + mobileBase.connect(); + String filename = (xmlName != null) ? xmlName : mobileBase.getScriptingName(); + mobileBase.setGitSelfSource(new String[] { gitURL, filename }); + for (int i = 0; i < controllers.size(); i++) { + AddRobotController con = controllers.get(i); + for (VitaminLocation l : con.getVitamins(con.getName() + "_" + i)) { + try { + if (!mobileBase.hasVitamin(l)) + mobileBase.addVitamin(l); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + } + } + } + for (int i = 0; i < limbs.size(); i++) { + AddRobotLimb limb = limbs.get(i); + if (mobileBase.getLimbByName(limb.getName()) == null) { + TransformNR location = limb.getLocation(); + DHParameterKinematics kin = limb.getLimb().getLimb(limb.getName()); + kin.setRobotToFiducialTransform(location.copy()); + // TODO add the channel mapping here + kin.connect(); + kin.zero(); + switch (limb.getLimb().getType()) { + case arm: + case flap: + case hand: + case head: + mobileBase.getAppendages().add(kin); + break; + case leg: + mobileBase.getLegs().add(kin); + break; + case steerable: + mobileBase.getSteerable().add(kin); + break; + case wheel: + mobileBase.getFixed().add(kin); + break; + default: + throw new RuntimeException("Unknown limb type in builder! " + limb.getLimb().getType()); + } + } + } + ArrayList toRemove = new ArrayList(); + for (int i = 0; i < mods.size(); i++) { + ModifyLimb mod = mods.get(i); + DHParameterKinematics kin = mod.getLimb(); + if (kin == null) + continue; + + TransformNR base = mod.getBase(); + if (base != null) { + //com.neuronrobotics.sdk.common.Log.debug("Base set to " + base); + kin.setRobotToFiducialTransform(base); + } + if (mod.getTip() != null) { + try { + kin.setDesiredTaskSpaceTransform(mod.getTip(), 0); + }catch(Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + toRemove.add(mod); + } + } + } + mods.removeAll(toRemove); + getCadManager().render(); + // Push to git + ScriptingEngine.pushCodeToGit(gitURL, null, filename, mobileBase.getXml(), "Builder Write XML", true); + return mobileBase; + } + + public void addController(AddRobotController controller) { + if (!controllers.contains(controller)) + getControllers().add(controller); + } + + public void removeController(AddRobotController controller) { + if (controllers.contains(controller)) + getControllers().remove(controller); + for (int i = 0; i < controllers.size(); i++) { + AddRobotController con = controllers.get(i); + for (VitaminLocation l : con.getVitamins(con.getName() + "_" + i)) { + try { + mobileBase.removeVitamin(l); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + } + } + } + } + + public ArrayList getControllers() { + return controllers; + } + + public ControllerFeatures getCapibilities() { + ControllerFeatures test = new ControllerFeatures(); + for (AddRobotController c : controllers) { + test.add(c.getController().getProvides()); + test.subtract(c.getController().getConsumes()); + } + for (AddRobotLimb c : limbs) { + test.add(c.getLimb().getProvides()); + test.subtract(c.getLimb().getConsumes()); + } + return test; + } + + public void addLimb(AddRobotLimb controller) { + addLimb(controller, false); + } + + public void addLimb(AddRobotLimb controller, boolean forceLoad) { + LimbOption consumes = controller.getLimb(); + if (!checkOptionSupported(consumes) && !forceLoad) { + throw new RuntimeException("Robot doesnt have enough resources to support " + controller.getLimb()); + } + if (!getLimmbs().contains(controller)) + getLimmbs().add(controller); + } + + public boolean checkOptionSupported(LimbOption consumes) { + return getCapibilities().check(consumes.consumes); + } + + public void addModification(ModifyLimb modifyLimb) { + if (!mods.contains(modifyLimb)) + mods.add(modifyLimb); + } + + public void removeModification(ModifyLimb modifyLimb) { + if (mods.contains(modifyLimb)) + mods.remove(modifyLimb); + } + + public void removeLimb(AddRobotLimb controller) { + if (getLimmbs().contains(controller)) + getLimmbs().remove(controller); + mobileBase.deleteLimbByName(controller.getName()); + } + + public ArrayList getLimmbs() { + return limbs; + } + + public MobileBaseCadManager getCadManager() { + MobileBaseCadManager mobileBaseCadManager = MobileBaseCadManager.get(mobileBase); + mobileBaseCadManager.setAutoRegen(false); + mobileBaseCadManager.setConfigurationViewerMode(false); + return mobileBaseCadManager; + } + +} \ No newline at end of file diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/creature/MobileBaseCadManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/creature/MobileBaseCadManager.java index 3f906a5c6..6a8a8b415 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/creature/MobileBaseCadManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/creature/MobileBaseCadManager.java @@ -24,6 +24,7 @@ import com.neuronrobotics.bowlerstudio.IssueReportingExceptionHandler; import com.neuronrobotics.bowlerstudio.physics.TransformFactory; import com.neuronrobotics.bowlerstudio.printbed.PrintBedManager; +import com.neuronrobotics.bowlerstudio.scripting.DownloadManager; import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; import com.neuronrobotics.bowlerstudio.util.FileChangeWatcher; import com.neuronrobotics.bowlerstudio.util.FileWatchDeviceWrapper; @@ -49,6 +50,7 @@ import com.neuronrobotics.sdk.addons.kinematics.parallel.ParallelGroup; import com.neuronrobotics.sdk.common.BowlerAbstractDevice; import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener; +import com.neuronrobotics.sdk.common.Log; import com.neuronrobotics.sdk.pid.PIDLimitEvent; import com.neuronrobotics.sdk.util.ThreadUtil; @@ -57,6 +59,7 @@ import eu.mihosoft.vrl.v3d.Transform; import eu.mihosoft.vrl.v3d.Vector3d; import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import javafx.beans.property.*; import javafx.scene.transform.Affine; import javafx.application.Platform; @@ -75,10 +78,9 @@ public class MobileBaseCadManager implements Runnable { private HashMap> DHtoCadMap = new HashMap<>(); private HashMap> LinktoCadMap = new HashMap<>(); private HashMap> BasetoCadMap = new HashMap<>(); - private HashMap vitaminCad=new HashMap<>(); - private HashMap vitaminDisplay=new HashMap<>(); - private HashMap vitaminLocation=new HashMap<>(); - + private HashMap vitaminCad = new HashMap<>(); + private HashMap vitaminDisplay = new HashMap<>(); + private HashMap vitaminLocation = new HashMap<>(); private boolean cadGenerating = false; private boolean showingStl = false; @@ -95,73 +97,77 @@ public class MobileBaseCadManager implements Runnable { private Thread renderWrangler = null; private HashMap cadScriptCache = new HashMap<>(); private static ArrayList toRun = new ArrayList(); - private ArrayList rendersync=new ArrayList<>(); + private ArrayList rendersync = new ArrayList<>(); private boolean forceChage = true; - public CSG getVitamin(VitaminLocation vitamin) throws Exception { - return getVitamin(vitamin,new Affine(),null); + + + public CSG getVitamin(CSGDatabaseInstance db,VitaminLocation vitamin) throws Exception { + return getVitamin(db,vitamin, new Affine(), null); } - public ArrayList getVitamins(IVitaminHolder link,Affine manipulator) { + public ArrayList getVitamins(CSGDatabaseInstance db,IVitaminHolder link, Affine manipulator) { ArrayList vitamins = link.getVitamins(); - return toVitaminCad(vitamins,manipulator,null); + return toVitaminCad(db,vitamins, manipulator, null); } - public ArrayList getOriginVitamins(IVitaminHolder link,Affine manipulator,TransformNR offset){ + + public ArrayList getOriginVitamins(CSGDatabaseInstance db,IVitaminHolder link, Affine manipulator, TransformNR offset) { ArrayList vitamins = link.getOriginVitamins(); - return toVitaminCad(vitamins,manipulator,offset); + return toVitaminCad(db,vitamins, manipulator, offset); } - public ArrayList getDefaultVitamins(IVitaminHolder link,Affine manipulator){ + + public ArrayList getDefaultVitamins(CSGDatabaseInstance db,IVitaminHolder link, Affine manipulator) { ArrayList vitamins = link.getDefaultVitamins(); - return toVitaminCad(vitamins,manipulator,null); + return toVitaminCad(db,vitamins, manipulator, null); } - public ArrayList getPreviousLinkVitamins(IVitaminHolder link,Affine manipulator){ + + public ArrayList getPreviousLinkVitamins(CSGDatabaseInstance db,IVitaminHolder link, Affine manipulator) { ArrayList vitamins = link.getPreviousLinkVitamins(); - return toVitaminCad(vitamins,manipulator,null); + return toVitaminCad(db,vitamins, manipulator, null); } - - private ArrayList toVitaminCad(ArrayList vitamins,Affine manipulator, TransformNR offset) { + private ArrayList toVitaminCad(CSGDatabaseInstance db,ArrayList vitamins, Affine manipulator, TransformNR offset) { ArrayList parts = new ArrayList(); - for(VitaminLocation vi:vitamins) { + for (VitaminLocation vi : vitamins) { CSG vitamin; try { - vitamin = getVitamin(vi,manipulator,offset); + vitamin = getVitamin(db,vi, manipulator, offset); parts.add(vitamin); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } return parts; } - - - public ArrayList getVitamins(AbstractLink link) { + + public ArrayList getVitamins(CSGDatabaseInstance db,AbstractLink link) { LinkConfiguration conf = link.getLinkConfiguration(); - return getVitamins(conf, (Affine) link.getGlobalPositionListener()); + return getVitamins(db,conf, (Affine) link.getGlobalPositionListener()); } - - public ArrayList getVitamins(AbstractLink link,Affine manipulator) { + public ArrayList getVitamins(CSGDatabaseInstance db,AbstractLink link, Affine manipulator) { LinkConfiguration conf = link.getLinkConfiguration(); - return getVitamins(conf, manipulator); + return getVitamins(db,conf, manipulator); } - public ArrayList getVitamins(MobileBase base) { + + public ArrayList getVitamins(CSGDatabaseInstance db,MobileBase base) { Affine rootListener = (Affine) base.getRootListener(); - return getVitamins(base, rootListener); + return getVitamins(db,base, rootListener); } - public CSG getVitamin(VitaminLocation vitamin,Affine manipulator,TransformNR offset) { - if(!vitaminCad.containsKey(vitamin)) { + + public CSG getVitamin(CSGDatabaseInstance instance,VitaminLocation vitamin, Affine manipulator, TransformNR offset) { + if (!vitaminCad.containsKey(vitamin)) { CSG starting; try { - CSG origin = vitaminMakeCSG(vitamin); - starting=origin.transformed(TransformFactory.nrToCSG(vitamin.getLocation())); - if(offset!=null) - starting=starting.transformed(TransformFactory.nrToCSG(offset)); + CSG origin = vitaminMakeCSG(instance,vitamin); + starting = origin.transformed(TransformFactory.nrToCSG(vitamin.getLocation())); + if (offset != null) + starting = starting.transformed(TransformFactory.nrToCSG(offset)); starting.setIsWireFrame(true); - starting.syncProperties(origin); + starting.syncProperties(instance,origin); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); return null; } vitaminCad.put(vitamin, starting); @@ -170,37 +176,38 @@ public CSG getVitamin(VitaminLocation vitamin,Affine manipulator,TransformNR off return vitaminCad.get(vitamin); } - public static CSG vitaminMakeCSG(VitaminLocation vitamin) throws Exception { - if(vitamin.isScript()) { - Object o =ScriptingEngine.gitScriptRun(vitamin.getType(), vitamin.getSize()); - ArrayList flat= new ArrayList(); - Vitamins.flatten(flat,o); - return CSG.unionAll( flat); - }else - return Vitamins.get(vitamin.getType(), vitamin.getSize()); + public static CSG vitaminMakeCSG(CSGDatabaseInstance instance,VitaminLocation vitamin) throws Exception { + if (vitamin.isScript()) { + Object o = ScriptingEngine.gitScriptRun(instance,vitamin.getType(), vitamin.getSize()); + ArrayList flat = new ArrayList(); + Vitamins.flatten(flat, o); + return CSG.unionAll(flat); + } else + return Vitamins.get(instance,vitamin.getType(), vitamin.getSize()); } - public CSG getVitaminDisplay(VitaminLocation vitamin,Affine manipulator, TransformNR offset){ - if(!vitaminDisplay.containsKey(vitamin)) { + + public CSG getVitaminDisplay(CSGDatabaseInstance instance,VitaminLocation vitamin, Affine manipulator, TransformNR offset) { + if (!vitaminDisplay.containsKey(vitamin)) { CSG starting; Affine offsetDisplay = new Affine(); try { - starting = vitaminMakeCSG(vitamin); - if(offset!=null){ - BowlerKernel.runLater(()->{ - TransformFactory.nrToAffine(offset,offsetDisplay); + starting = vitaminMakeCSG(instance,vitamin); + if (offset != null) { + BowlerKernel.runLater(() -> { + TransformFactory.nrToAffine(offset, offsetDisplay); }); } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); return null; } starting.setManipulator(manipulator); - Affine frameOffset=new Affine(); - Affine cameraFrame=new Affine(); + Affine frameOffset = new Affine(); + Affine cameraFrame = new Affine(); setFrames(vitamin, frameOffset, cameraFrame); vitaminLocation.put(vitamin, cameraFrame); - vitamin.addChangeListener(()->{ + vitamin.addChangeListener(() -> { setFrames(vitamin, frameOffset, cameraFrame); }); @@ -211,6 +218,7 @@ public CSG getVitaminDisplay(VitaminLocation vitamin,Affine manipulator, Transfo } return vitaminDisplay.get(vitamin); } + private void setFrames(VitaminLocation vitamin, Affine frameOffset, Affine cameraFrame) { BowlerKernel.runLater(() -> { TransformNR translationComponent = vitamin.getLocation().copy().setRotation(new RotationNR()); @@ -222,201 +230,211 @@ private void setFrames(VitaminLocation vitamin, Affine frameOffset, Affine camer public Affine getVitaminAffine(VitaminLocation vitamin) { Affine a = vitaminLocation.get(vitamin); - if(a!=null) + if (a != null) return a; - throw new RuntimeException("Affine not present! "+vitamin.getName()); + throw new RuntimeException("Affine not present! " + vitamin.getName()); } - - public ArrayList getOriginVitaminsDisplay(IVitaminHolder link,Affine manipulator,TransformNR offset){ + + public ArrayList getOriginVitaminsDisplay(CSGDatabaseInstance db,IVitaminHolder link, Affine manipulator, TransformNR offset) { ArrayList vitamins = link.getOriginVitamins(); - return vitaminsToDisplay(vitamins,manipulator,offset); + return vitaminsToDisplay(db,vitamins, manipulator, offset); } - public ArrayList getDefaultVitaminsDisplay(IVitaminHolder link,Affine manipulator){ + + public ArrayList getDefaultVitaminsDisplay(CSGDatabaseInstance db,IVitaminHolder link, Affine manipulator) { ArrayList vitamins = link.getDefaultVitamins(); - return vitaminsToDisplay(vitamins,manipulator); + return vitaminsToDisplay(db,vitamins, manipulator); } - public ArrayList getPreviousLinkVitaminsDisplay(IVitaminHolder link,Affine manipulator){ + + public ArrayList getPreviousLinkVitaminsDisplay(CSGDatabaseInstance db,IVitaminHolder link, Affine manipulator) { ArrayList vitamins = link.getPreviousLinkVitamins(); - return vitaminsToDisplay(vitamins,manipulator); + return vitaminsToDisplay(db,vitamins, manipulator); } - - public ArrayList getVitaminsDisplay(IVitaminHolder link,Affine manipulator) { - - return vitaminsToDisplay(link.getVitamins(),manipulator); + + public ArrayList getVitaminsDisplay(CSGDatabaseInstance db,IVitaminHolder link, Affine manipulator) { + + return vitaminsToDisplay(db,link.getVitamins(), manipulator); } - - public ArrayList vitaminsToDisplay(ArrayList l,Affine manipulator){ - return vitaminsToDisplay(l,manipulator,null); + + public ArrayList vitaminsToDisplay(CSGDatabaseInstance db,ArrayList l, Affine manipulator) { + return vitaminsToDisplay(db,l, manipulator, null); } - public ArrayList vitaminsToDisplay(ArrayList l,Affine manipulator, TransformNR offset){ + + public ArrayList vitaminsToDisplay(CSGDatabaseInstance db,ArrayList l, Affine manipulator, TransformNR offset) { ArrayList parts = new ArrayList(); - for(VitaminLocation vi:l) { + for (VitaminLocation vi : l) { CSG vitamin; try { - vitamin = getVitaminDisplay(vi,manipulator, offset); + vitamin = getVitaminDisplay(db,vi, manipulator, offset); parts.add(vitamin); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } return parts; } - - public ArrayList getVitaminsDisplay(AbstractLink link) { + + public ArrayList getVitaminsDisplay(CSGDatabaseInstance db,AbstractLink link) { LinkConfiguration conf = link.getLinkConfiguration(); - return getVitaminsDisplay(conf, (Affine) link.getGlobalPositionListener()); + return getVitaminsDisplay(db,conf, (Affine) link.getGlobalPositionListener()); } - public ArrayList getVitaminsDisplay(AbstractLink link,Affine manipulator) { + + public ArrayList getVitaminsDisplay(CSGDatabaseInstance db,AbstractLink link, Affine manipulator) { LinkConfiguration conf = link.getLinkConfiguration(); - return getVitaminsDisplay(conf, manipulator); + return getVitaminsDisplay(db,conf, manipulator); } - - public ArrayList getVitaminsDisplay(MobileBase base) { + public ArrayList getVitaminsDisplay(CSGDatabaseInstance db,MobileBase base) { Affine rootListener = (Affine) base.getRootListener(); - return getVitaminsDisplay(base, rootListener); + return getVitaminsDisplay(db,base, rootListener); } - + public void render() { run(); - forceChage=true; - while(forceChage) + forceChage = true; + while (forceChage) ThreadUtil.wait(1); } + public void addIRenderSynchronizationEvent(IRenderSynchronizationEvent ev) { - if(rendersync.contains(ev)) + if (rendersync.contains(ev)) return; rendersync.add(ev); } + public void removeIRenderSynchronizationEvent(IRenderSynchronizationEvent ev) { - if(rendersync.contains(ev)) + if (rendersync.contains(ev)) rendersync.remove(ev); } - + private void fireIRenderSynchronizationEvent() { - for(int i=0;ihighest.x) - highest.x=high.x; - if(high.y>highest.y) - highest.y=high.y; - if(high.z>highest.z) - highest.z=high.z; + + if (highest == null) + highest = high; + if (high.x > highest.x) + highest.x = high.x; + if (high.y > highest.y) + highest.y = high.y; + if (high.z > highest.z) + highest.z = high.z; } - for(DHParameterKinematics k:cat.getAllDHChains()) { - for(int i=0;ihighest.x) - highest.x=high.x; - if(high.y>highest.y) - highest.y=high.y; - if(high.z>highest.z) - highest.z=high.z; + + if (highest == null) + highest = high; + if (high.x > highest.x) + highest.x = high.x; + if (high.y > highest.y) + highest.y = high.y; + if (high.z > highest.z) + highest.z = high.z; } } } return highest; } + public Vector3d computeLowestPoint() { render(); - MobileBase cat=base; + MobileBase cat = base; MobileBaseCadManager cadMan = MobileBaseCadManager.get(cat); - Vector3d lowest =null; - Affine l =(Affine) cat.getRootListener(); + Vector3d lowest = null; + Affine l = (Affine) cat.getRootListener(); TransformNR tmp = TransformFactory.affineToNr(l); Transform baseloc = TransformFactory.nrToCSG(tmp); - for(CSG c:cadMan.getBasetoCadMap().get(cat)) { + for (CSG c : cadMan.getBasetoCadMap().get(cat)) { CSG moved = c.transformed(baseloc); double z = moved.getMinZ(); - double y= moved.getMinY(); - double x=moved.getMinX(); + double y = moved.getMinY(); + double x = moved.getMinX(); Vector3d low = new Vector3d(x, y, z); - - if(lowest==null) - lowest=low; - if(low.x toAdd, File source) { - // TODO Auto-generated method stub - // TODO Auto-generated method stub + // Auto-generated method stub + // Auto-generated method stub list.clear(); list.addAll(toAdd); } @Override public void addCSG(Collection toAdd, File source) { - // TODO Auto-generated method stub + // Auto-generated method stub list.addAll(toAdd); } @Override public Set getVisibleCSGs() { - // TODO Auto-generated method stub + // Auto-generated method stub return new HashSet(list); } @Override public void setSelectedCsg(Collection selectedCsg) { - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public void setSelected(Affine rootListener) { - // TODO Auto-generated method stub + // Auto-generated method stub } }; @@ -532,13 +551,14 @@ public void onBaseToFiducialUpdate(AbstractKinematicsNR source, TransformNR rege l.onIOnMobileBaseRenderChange(); } }; - ILinkConfigurationChangeListener confL= new ILinkConfigurationChangeListener() { + ILinkConfigurationChangeListener confL = new ILinkConfigurationChangeListener() { @Override public void event(LinkConfiguration newConf) { l.onIOnMobileBaseRenderChange(); } - + }; + @Override public void run() { base.addIOnMobileBaseRenderChange(l); @@ -551,14 +571,14 @@ public void run() { kin.addRegistrationListener(r); } // render on any configuration change - addConfL(base,confL); + addConfL(base, confL); setName("MobileBaseCadManager Render Thread for " + base.getScriptingName()); while (base.isAvailable()) { try { do { Thread.sleep(5); - if(forceChage) { - forceChage=false; + if (forceChage) { + forceChage = false; l.onIOnMobileBaseRenderChange(); } } while (rendering || changed == false); @@ -594,8 +614,8 @@ public void run() { jointPosesTmp.clear(); jointPosesTmp = null; - Affine[] iterator = tmp.keySet().stream().toArray(size->new Affine[size]); - TransformNR[] vals = tmp.values().stream().toArray(size->new TransformNR[size]); + Affine[] iterator = tmp.keySet().stream().toArray(size -> new Affine[size]); + TransformNR[] vals = tmp.values().stream().toArray(size -> new TransformNR[size]); tmp.clear(); if (iterator.length > 0) { BowlerKernel.runLater(() -> { @@ -605,7 +625,7 @@ public void run() { TransformFactory.nrToAffine(vals[i], af); } } catch (Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } rendering = false; fireIRenderSynchronizationEvent(); @@ -628,32 +648,34 @@ public void run() { } t.clear(); } catch (Throwable tr) { - tr.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(tr); } }); Thread.sleep(32); } } catch (Throwable t) { // rendering not availible - System.err.println("Exception for render engine " + base.getScriptingName()); - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log + .error("Exception for render engine " + base.getScriptingName()); + com.neuronrobotics.sdk.common.Log.error(t); try { Thread.sleep(100); } catch (InterruptedException e) { break; } } - + } renderWrangler = null; } + private void addConfL(MobileBase base, ILinkConfigurationChangeListener confL2) { - if(base==null) + if (base == null) return; - for(DHParameterKinematics k:base.getAllDHChains()) { - for(int i=0;i map2, HashMap jointPoses) { - TransformNR back =updateBase(b, baseLoc, map2); + TransformNR back = updateBase(b, baseLoc, map2); for (DHParameterKinematics k : b.getAllDHChains()) { updateLimb(k, back, map2, jointPoses); } @@ -691,7 +713,7 @@ private void updateMobileBase(MobileBase b, TransformNR baseLoc, HashMap map2, HashMap jointPoses) { - //updateBase(k, baseLoc, map2); + // updateBase(k, baseLoc, map2); TransformNR previous = k.getFiducialToGlobalTransform(); k.setGlobalToFiducialTransform(baseLoc, false); ArrayList ll = k.getChain().getChain(jointPoses.get(k)); @@ -719,8 +741,8 @@ private void updateLimb(DHParameterKinematics k, TransformNR baseLoc, HashMap { + Object cadForBodyEngine = scriptFromFileInfo(getDb(),b.getScriptingName(), b.getGitCadEngine(), () -> { run(); generateCad(); }); @@ -868,10 +890,10 @@ private IgenerateBody getIgenerateBody(MobileBase b) throws Throwable{ return null; } - private IgenerateCad getIgenerateCad(DHParameterKinematics dh) throws Throwable{ + private IgenerateCad getIgenerateCad(DHParameterKinematics dh) throws Throwable { if (isConfigMode()) return getConfigurationDisplay(); - Object cadForBodyEngine = scriptFromFileInfo(dh.getScriptingName(),dh.getGitCadEngine(), () -> { + Object cadForBodyEngine = scriptFromFileInfo(getDb(),dh.getScriptingName(), dh.getGitCadEngine(), () -> { run(); generateCad(); }); @@ -881,8 +903,8 @@ private IgenerateCad getIgenerateCad(DHParameterKinematics dh) throws Throwable{ return null; } - public IgenerateBed getIgenerateBed() throws Throwable{ - Object cadForBodyEngine = scriptFromFileInfo(base.getScriptingName(),base.getGitCadEngine(), () -> { + public IgenerateBed getIgenerateBed() throws Throwable { + Object cadForBodyEngine = scriptFromFileInfo(getDb(),base.getScriptingName(), base.getGitCadEngine(), () -> { run(); }); if (IgenerateBed.class.isInstance(cadForBodyEngine)) { @@ -891,17 +913,17 @@ public IgenerateBed getIgenerateBed() throws Throwable{ return null; } - private ICadGenerator getConfigurationDisplay()throws Throwable { + private ICadGenerator getConfigurationDisplay() throws Throwable { if (cadEngineConfiguration == null) { - String[] args = new String[] { - "https://github.com/CommonWealthRobotics/DHParametersCadDisplay.git", "dhcad.groovy" }; - Object cadForBodyEngine = scriptFromFileInfo("ConfigDisplay", args, () -> { + String[] args = new String[] { "https://github.com/CommonWealthRobotics/DHParametersCadDisplay.git", + "dhcad.groovy" }; + Object cadForBodyEngine = scriptFromFileInfo(getDb(),"ConfigDisplay", args, () -> { cadEngineConfiguration = null; try { getConfigurationDisplay(); } catch (Throwable e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } MobileBaseCadManager mobileBaseCadManager = null; try { @@ -923,6 +945,10 @@ private ICadGenerator getConfigurationDisplay()throws Throwable { return cadEngineConfiguration; } + private CSGDatabaseInstance getDb() { + return MobileBaseLoader.get(base).getDb(); + } + public ArrayList generateBody() { return generateBody(getMobileBase(), true); } @@ -936,7 +962,7 @@ public ArrayList generateBody(MobileBase base, boolean clear) { getAllCad().clear(); setAllCad(new ArrayList<>()); } - //System.gc(); + // System.gc(); MobileBase device = base; if (getBasetoCadMap().get(device) == null) { getBasetoCadMap().put(device, new ArrayList()); @@ -974,9 +1000,14 @@ public ArrayList generateBody(MobileBase base, boolean clear) { } else getUi().highlightException(null, new Exception()); ArrayList arrayList = getBasetoCadMap().get(device); + if (arrayList == null) { + arrayList = new ArrayList(); + getBasetoCadMap().put(device, arrayList); + } + if (clear) { arrayList.clear(); - //System.gc(); + // System.gc(); } for (CSG c : getAllCad()) { arrayList.add(c); @@ -991,11 +1022,11 @@ public ArrayList generateBody(MobileBase base, boolean clear) { } catch (Throwable e) { getUi().highlightException(getCadScriptFromMobileBase(device), e); } - System.out.println("Displaying Body"); + com.neuronrobotics.sdk.common.Log.error("Displaying Body"); setProgress(0.35); // clears old robot and places base getUi().setAllCSG(getBasetoCadMap().get(device), getCadScriptFromMobileBase(device)); - System.out.println("Rendering limbs"); + com.neuronrobotics.sdk.common.Log.error("Rendering limbs"); setProgress(0.4); ArrayList limbs = base.getAllDHChains(); double numLimbs = limbs.size(); @@ -1017,7 +1048,7 @@ public ArrayList generateBody(MobileBase base, boolean clear) { } else { if (clear) { arrayList.clear(); - //System.gc(); + // System.gc(); } ArrayList linksCad = generateCad(l); @@ -1039,7 +1070,7 @@ public ArrayList generateBody(MobileBase base, boolean clear) { getAllCad().addAll(m.generateBody(m.base, false)); } showingStl = false; - //setProgress(1); + // setProgress(1); // PhysicsEngine.clear(); // MobileBasePhysicsManager m = new MobileBasePhysicsManager(base, // baseCad, getSimplecad()); @@ -1053,8 +1084,8 @@ public File getCadScriptFromLimnb(DHParameterKinematics l) { try { return ScriptingEngine.fileFromGit(l.getGitCadEngine()[0], l.getGitCadEngine()[1]); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } return null; } @@ -1063,8 +1094,8 @@ public File getCadScriptFromMobileBase(MobileBase device) { try { return ScriptingEngine.fileFromGit(device.getGitCadEngine()[0], device.getGitCadEngine()[1]); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } return null; } @@ -1078,7 +1109,8 @@ private void set(MobileBase base, int limb, int link) { DHParameterKinematics dh = limbs.get(limb); double partsTotal = numLimbs * dh.getNumberOfLinks(); double progress = ((double) ((limb * dh.getNumberOfLinks()) + link)) / partsTotal; - // System.out.println("Cad progress " + progress + " limb " + limb + " link " + + // com.neuronrobotics.sdk.common.Log.error("Cad progress " + progress + " limb " + // + limb + " link " + // link + " total parts " + partsTotal); setProgress(0.333 + (2 * (progress / 3))); } @@ -1099,46 +1131,46 @@ public ArrayList generateStls(MobileBase base, File baseDirForFiles, boole File dir = new File(baseDirForFiles.getAbsolutePath() + "/" + base.getScriptingName()); if (!dir.exists()) dir.mkdirs(); - IgenerateBed bed=null; + IgenerateBed bed = null; String baseURL = base.getGitSelfSource()[0]; File baseWorkspaceFile = ScriptingEngine.getRepositoryCloneDirectory(baseURL); bed = getPrintBed(dir, bed, baseWorkspaceFile); if (bed == null || kinematic) { return _generateStls(base, dir, kinematic); } - - System.out.println("Found arrangeBed API in CAD engine"); + + com.neuronrobotics.sdk.common.Log.error("Found arrangeBed API in CAD engine"); List totalAssembly = bed.arrangeBed(base); getUi().setAllCSG(totalAssembly, getCadScriptFromMobileBase(base)); - return new CadFileExporter(getUi()).generateManufacturingParts(totalAssembly, dir); } + public IgenerateBed getPrintBed(File baseDirForFiles, IgenerateBed bed, File baseWorkspaceFile) throws IOException { - File bomCSV = new File(baseWorkspaceFile.getAbsolutePath()+"/"+VitaminBomManager.MANUFACTURING_BOM_CSV); - if(bomCSV.exists()) { - - File file = new File(baseDirForFiles.getAbsolutePath()+"/bom.csv"); - if(file.exists()) + File bomCSV = new File(baseWorkspaceFile.getAbsolutePath() + "/" + VitaminBomManager.getManufacturingBomCsv()); + if (bomCSV.exists()) { + + File file = new File(baseDirForFiles.getAbsolutePath() + "/bom.csv"); + if (file.exists()) file.delete(); - Files.copy(bomCSV.toPath(),file.toPath()); + Files.copy(bomCSV.toPath(), file.toPath()); } - File bom = new File(baseWorkspaceFile.getAbsolutePath()+"/"+VitaminBomManager.MANUFACTURING_BOM_JSON); - if(bom.exists()) { - File file = new File(baseDirForFiles.getAbsolutePath()+"/bom.json"); - if(file.exists()) + File bom = new File(baseWorkspaceFile.getAbsolutePath() + "/" + VitaminBomManager.getManufacturingBomJson()); + if (bom.exists()) { + File file = new File(baseDirForFiles.getAbsolutePath() + "/bom.json"); + if (file.exists()) file.delete(); - Files.copy(bom.toPath(),file.toPath()); + Files.copy(bom.toPath(), file.toPath()); } - try{ - bed= getIgenerateBed(); - }catch(Throwable T) { + try { + bed = getIgenerateBed(); + } catch (Throwable T) { throw new RuntimeException(T.getMessage()); } - if(bed == null) { - File printArrangment = new File(baseWorkspaceFile.getAbsolutePath()+"/"+PrintBedManager.file); - if(printArrangment.exists()) { - bed = new UserManagedPrintBed(printArrangment,this); + if (bed == null) { + File printArrangment = new File(baseWorkspaceFile.getAbsolutePath() + "/" + PrintBedManager.file); + if (printArrangment.exists()) { + bed = new UserManagedPrintBed(printArrangment, this); } } return bed; @@ -1178,24 +1210,30 @@ public ArrayList _generateStls(MobileBase base, File baseDirForFiles, bool else totalAssembly.add(tmp); LinkConfiguration conf = getLinkConfiguration(parts.get(j)); - if(conf!=null) { + if (conf != null) { String linkNum = conf.getLinkIndex() + "_Link_"; - + File dir = new File(baseDirForFiles.getAbsolutePath() + "/" + base.getScriptingName() + "/" + l.getScriptingName()); if (!dir.exists()) dir.mkdirs(); - - File stl = new File( - dir.getAbsolutePath() + "/" + linkNum + name + "_limb_" + i + "_Part_" + j + ".stl"); - System.out.println("Writing STL for " + name+" to "+stl.getAbsolutePath()); + + File stl = new File(dir.getAbsolutePath() + "/" + linkNum + name + "_limb_" + i + "_Part_" + + j + ".stl"); + com.neuronrobotics.sdk.common.Log + .error("Writing STL for " + name + " to " + stl.getAbsolutePath()); + boolean manifold = CSG.isPreventNonManifoldTriangles(); + // CSG.setPreventNonManifoldTriangles(false); FileUtil.write(Paths.get(stl.getAbsolutePath()), tmp.toStlString()); + + CSG.setPreventNonManifoldTriangles(manifold); allCadStl.add(stl); // totalAssembly.add(tmp); getUi().setAllCSG(totalAssembly, getCadScriptFromMobileBase(base)); set(base, i, j); - }else { - System.err.println("ERROR "+parts.get(j).getName()+" has no link associated "); + } else { + com.neuronrobotics.sdk.common.Log + .error("ERROR " + parts.get(j).getName() + " has no link associated "); } } } catch (Exception ex) { @@ -1263,6 +1301,7 @@ public void setMobileBase(MobileBase b) { } } this.base = b; + cadmap.put(base, this); MobileBaseLoader.get(base);// load the dependant scripts base.updatePositions(); @@ -1270,7 +1309,7 @@ public void setMobileBase(MobileBase b) { for (DHParameterKinematics k : base.getAllDHChains()) { k.setRenderWrangler(this); } - base.setConfigurationUpdate(()->{ + base.setConfigurationUpdate(() -> { generateCad(); }); run(); @@ -1282,8 +1321,8 @@ public void setMobileBase(MobileBase b) { @Override public void onDisconnect(BowlerAbstractDevice arg0) { if (arg0 != base) { - new Exception("This listener called from the wrong device!! " + arg0.getScriptingName()) - .printStackTrace(); + com.neuronrobotics.sdk.common.Log.error( + new Exception("This listener called from the wrong device!! " + arg0.getScriptingName())); return; } base.setRenderWrangler(null); @@ -1299,7 +1338,7 @@ public void onDisconnect(BowlerAbstractDevice arg0) { @Override public void onConnect(BowlerAbstractDevice arg0) { - // TODO Auto-generated method stub + // Auto-generated method stub } }); @@ -1335,6 +1374,7 @@ public ArrayList generateCad(DHParameterKinematics dh) { try { newcad = generatorToUse.generateCad(dh, i); } catch (Throwable t) { + Log.error(t); getUi().highlightException(null, t); } if (newcad == null) { @@ -1361,7 +1401,7 @@ public ArrayList generateCad(DHParameterKinematics dh) { @Override public void onLinkPositionUpdate(AbstractLink arg0, double arg1) { - // TODO Auto-generated method stub + // Auto-generated method stub } @@ -1382,7 +1422,7 @@ public void onLinkLimit(AbstractLink arg0, PIDLimitEvent arg1) { } } catch (Throwable e) { - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(e); getUi().highlightException(getCadScriptFromLimnb(dh), e); } return dhLinks; @@ -1395,7 +1435,7 @@ public void selectCsgByMobileBase(MobileBase base) { getUi().setSelectedCsg(csg); } catch (Exception ex) { // getUi().highlightException(null, ex); - System.err.println("Base not loaded yet"); + com.neuronrobotics.sdk.common.Log.error("Base not loaded yet"); } } @@ -1408,7 +1448,7 @@ public void selectCsgByLimb(MobileBase base, DHParameterKinematics limb) { getUi().setSelected((Affine) limb.getRootListener()); } catch (Exception ex) { // getUi().highlightException(null, ex); - System.err.println("Limb not loaded yet"); + com.neuronrobotics.sdk.common.Log.error("Limb not loaded yet"); } } @@ -1418,12 +1458,14 @@ public void selectCsgByLink(MobileBase base, LinkConfiguration limb) { ArrayList limCad = MobileBaseCadManager.get(base).getLinktoCadMap().get(limb); getUi().setSelectedCsg(limCad); } catch (Exception ex) { - System.err.println("Limb not loaded yet"); + com.neuronrobotics.sdk.common.Log.error("Limb not loaded yet"); } } + public void generateCad() { - generateCadWithEnd((Runnable)null); + generateCadWithEnd((Runnable) null); } + public void generateCadWithEnd(Runnable done) { if (cadGenerating || !getAutoRegen()) return; @@ -1449,7 +1491,7 @@ public void run() { try { setAllCad(generateBody(device, true)); } catch (Exception e) { - + getUi().highlightException(getCadScriptFromMobileBase(device), e); } @@ -1464,27 +1506,29 @@ public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } setProgress(1); - if(done!=null) { + if (done != null) { try { done.run(); - }catch(Throwable t) { - t.printStackTrace(); + } catch (Throwable t) { + com.neuronrobotics.sdk.common.Log.error(t); } } System.gc(); } }.start(); } + private void setProgress(double val) { - if(cadGenerating==false) { - val=1; + if (cadGenerating == false) { + val = 1; } getProcesIndictor().set(val); } + public void onTabClosing() { } @@ -1506,12 +1550,12 @@ public ArrayList getAllCad() { } public void setAllCad(ArrayList allCad) { - for (CSG part : allCad) - for (String p : part.getParameters()) { - CSGDatabase.addParameterListener(p, (arg0, arg1) -> { - // generateCad(); //TODO Undo this after debugging - }); - } +// for (CSG part : allCad) +// for (String p : part.getParameters()) { +// CSGDatabase.addParameterListener(p, (arg0, arg1) -> { +// // generateCad(); //TODO Undo this after debugging +// }); +// } if (this.allCad != null && this.allCad != allCad) this.allCad.clear(); @@ -1533,8 +1577,6 @@ public static MobileBaseCadManager get(MobileBase device, IMobileBaseUI ui) { return mobileBaseCadManager; } - - public static MobileBaseCadManager get(MobileBase device) { if (cadmap.get(device) == null) { for (MobileBase mb : cadmap.keySet()) { @@ -1552,14 +1594,14 @@ public static MobileBaseCadManager get(MobileBase device) { @Override public void onDisconnect(BowlerAbstractDevice source) { - // TODO Auto-generated method stub + // Auto-generated method stub ui2.list.clear(); } @Override public void onConnect(BowlerAbstractDevice source) { - // TODO Auto-generated method stub + // Auto-generated method stub } }); @@ -1634,61 +1676,67 @@ public void setUi(IMobileBaseUI ui) { } public void setConfigurationViewerMode(boolean b) { - System.out.println("Setting config mode " + b); + com.neuronrobotics.sdk.common.Log.error("Setting config mode " + b); setConfigMode(b); for (MobileBaseCadManager m : slaves) { m.setConfigurationViewerMode(b); } } + public void invalidateModelCache() { - // TODO Auto-generated method stub - + // Auto-generated method stub + } + /** * @return the configMode */ public boolean isConfigMode() { return configMode; } + /** * @param configMode the configMode to set */ public void setConfigMode(boolean configMode) { this.configMode = configMode; } + public boolean isCADstarted() { - // TODO Auto-generated method stub + // Auto-generated method stub return cadGenerating; } public static MobileBaseCadManager get(IVitaminHolder holder) { Set keySet = cadmap.keySet(); - for(MobileBase b:keySet) { - MobileBaseCadManager m =checkforBase(holder, b); - if (m!=null) + for (MobileBase b : keySet) { + MobileBaseCadManager m = checkforBase(holder, b); + if (m != null) return m; } return null; } + private static MobileBaseCadManager checkforBase(IVitaminHolder holder, MobileBase b) { - if(b==holder) + if (b == holder) return get(b); - for(DHParameterKinematics k:b.getAllDHChains()) { - for(int i=0;i map = new HashMap<>(); private MobileBase base; private IDriveEngine defaultDriveEngine; + private CSGDatabaseInstance db; + public CSGDatabaseInstance getDb() { + return db; + } + public void setDb(CSGDatabaseInstance db) { + this.db = db; + } private MobileBaseLoader(MobileBase base) { this.setBase(base); @@ -41,14 +55,14 @@ public File setDefaultDhParameterKinematics(DHParameterKinematics device) { File code = null; try { code = ScriptingEngine.fileFromGit(device.getGitDhEngine()[0], device.getGitDhEngine()[1]); - DhInverseSolver defaultDHSolver = (DhInverseSolver) ScriptingEngine.inlineFileScriptRun(code, null); + DhInverseSolver defaultDHSolver = (DhInverseSolver) ScriptingEngine.inlineFileScriptRun(getDb(),code, null); File c = code; FileWatchDeviceWrapper.watch(device, code,new IFileChangeListener() { @Override public void onFileDelete(File fileThatIsDeleted) { - // TODO Auto-generated method stub + // Auto-generated method stub } @@ -56,8 +70,8 @@ public void onFileDelete(File fileThatIsDeleted) { public void onFileChange(File fileThatChanged, WatchEvent event) { try { - System.out.println("D-H Solver changed, updating " + device.getScriptingName()); - DhInverseSolver d = (DhInverseSolver) ScriptingEngine.inlineFileScriptRun(c, null); + com.neuronrobotics.sdk.common.Log.error("D-H Solver changed, updating " + device.getScriptingName()); + DhInverseSolver d = (DhInverseSolver) ScriptingEngine.inlineFileScriptRun(getDb(),c, null); device.setInverseSolver(d); } catch (Exception ex) { MobileBaseCadManager.get(base).getUi().highlightException(c, ex); @@ -90,7 +104,7 @@ public void setGitWalkingEngine(String git, String file, MobileBase device) { try { code = ScriptingEngine.fileFromGit(git, file); } catch (Exception ex) { - ex.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(ex);; ScriptingEngine.deleteRepo(git); try { code = ScriptingEngine.fileFromGit(git, file); @@ -105,7 +119,7 @@ public void setGitWalkingEngine(String git, String file, MobileBase device) { @Override public void onFileDelete(File fileThatIsDeleted) { - // TODO Auto-generated method stub + // Auto-generated method stub } @@ -113,8 +127,8 @@ public void onFileDelete(File fileThatIsDeleted) { public void onFileChange(File fileThatChanged, WatchEvent event){ try { - System.out.println("Walking Gait Script changed, updating " + device.getScriptingName()); - defaultDriveEngine = (IDriveEngine) ScriptingEngine.inlineFileScriptRun(c, null); + com.neuronrobotics.sdk.common.Log.error("Walking Gait Script changed, updating " + device.getScriptingName()); + defaultDriveEngine = (IDriveEngine) ScriptingEngine.inlineFileScriptRun(getDb(),c, null); device.setWalkingDriveEngine(defaultDriveEngine); } catch (Exception ex) { MobileBaseCadManager.get(base).getUi().highlightException(c, ex); @@ -123,7 +137,7 @@ public void onFileChange(File fileThatChanged, WatchEvent event){ }); try { - defaultDriveEngine = (IDriveEngine) ScriptingEngine.inlineFileScriptRun(c, null); + defaultDriveEngine = (IDriveEngine) ScriptingEngine.inlineFileScriptRun(getDb(),c, null); device.setWalkingDriveEngine(defaultDriveEngine); } catch (Exception ex) { MobileBaseCadManager.get(base).getUi().highlightException(c, ex); @@ -170,6 +184,25 @@ public MobileBase getBase() { public void setBase(MobileBase base) { this.base = base; + try { + String[] self = base.getGitSelfSource(); + File selfFile =ScriptingEngine.fileFromGit(self); + File parent = selfFile.getParentFile(); + File database = new File(parent.getAbsolutePath()+DownloadManager.delim()+"csgDatabase.json"); + setDb(new CSGDatabaseInstance(database)); + } catch (InvalidRemoteException e) { + // TODO Auto-generated catch block + Log.error(e); + } catch (TransportException e) { + // TODO Auto-generated catch block + Log.error(e); + } catch (GitAPIException e) { + // TODO Auto-generated catch block + Log.error(e); + } catch (IOException e) { + // TODO Auto-generated catch block + Log.error(e); + } } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/creature/ThumbnailImage.java b/src/main/java/com/neuronrobotics/bowlerstudio/creature/ThumbnailImage.java new file mode 100644 index 000000000..37aa0d425 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/creature/ThumbnailImage.java @@ -0,0 +1,156 @@ +package com.neuronrobotics.bowlerstudio.creature; + +import java.util.ArrayList; +import java.util.List; + +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.Bounds; +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Vector3d; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; +import javafx.scene.Group; +import javafx.scene.Scene; +import javafx.scene.SceneAntialiasing; +import javafx.scene.SnapshotParameters; +import javafx.scene.image.WritableImage; +import javafx.scene.paint.Color; +import javafx.scene.paint.PhongMaterial; +import javafx.scene.shape.CullFace; +import javafx.scene.shape.MeshView; +import javafx.scene.transform.Transform; +import javafx.scene.PerspectiveCamera; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.transform.Affine; +import javafx.scene.transform.Rotate; +import javafx.geometry.Rectangle2D; + +public class ThumbnailImage { + public static Bounds getSellectedBounds(List incoming) { + Vector3d min = null; + Vector3d max = null; + for (CSG c : incoming) { + if(c.isHide()) + continue; + if(c.isInGroup()) + continue; + Vector3d min2 = c.getBounds().getMin().clone(); + Vector3d max2 = c.getBounds().getMax().clone(); + if (min == null) + min = min2; + if (max == null) + max = max2; + if (min2.x < min.x) + min.x = min2.x; + if (min2.y < min.y) + min.y = min2.y; + if (min2.z < min.z) + min.z = min2.z; + if (max.x < max2.x) + max.x = max2.x; + if (max.y < max2.y) + max.y = max2.y; + if (max.z < max2.z) + max.z = max2.z; + } + if(max==null) + max=new Vector3d(0,0,0); + if(min==null) + min=new Vector3d(0,0,0); + return new Bounds(min, max); + } + + public static WritableImage get(CSGDatabaseInstance instance,List c) { + ArrayList csgList=new ArrayList() ; + for(CSG cs:c) { + if(cs.getManipulator()!=null) { + TransformNR nr = TransformFactory.affineToNr(cs.getManipulator()); + csgList.add(cs.transformed(TransformFactory.nrToCSG(nr)).syncProperties(instance,cs)); + }else + csgList.add(cs); + } + // Create a group to hold all the meshes + Group root = new Group(); + + // Add all meshes to the group + Bounds b = getSellectedBounds(csgList); + + double yOffset = (b.getMax().y-b.getMin().y)/2; + double xOffset =(b.getMax().x -b.getMin().x)/2; + double zCenter = (b.getMax().z -b.getMin().z)/2; + for (CSG csg : csgList) { + if(csg.isHide()) + continue; + if(csg.isInGroup()) + continue; + try { + MeshView meshView = csg.movez(-zCenter).getMesh(); + PhongMaterial material = new PhongMaterial(); + if (csg.isHole()) { + material.setDiffuseColor(new Color(0.25, 0.25, 0.25, 0.75)); + meshView.setMaterial(material); + meshView.setOpacity(0.25); + } + material.setSpecularColor(javafx.scene.paint.Color.WHITE); + meshView.setCullFace(CullFace.BACK); + root.getChildren().add(meshView); + }catch(Throwable t) { + com.neuronrobotics.sdk.common.Log.error(t); + } + } + + // Calculate the bounds of all CSGs combined + double totalz = b.getMax().z - b.getMin().z; + double totaly = b.getMax().y - b.getMin().y; + double totalx = b.getMax().x - b.getMin().x; + + // Create a perspective camera + PerspectiveCamera camera = new PerspectiveCamera(true); + + // Calculate camera position to fit all objects in view + double maxDimension = Math.max(totalx, Math.max(totaly, totalz)); + double cameraDistance = (maxDimension / Math.tan(Math.toRadians(camera.getFieldOfView() / 2)))*0.8 ; + + TransformNR camoffset = new TransformNR(xOffset, yOffset, 0); + TransformNR camDist = new TransformNR(0, 0, -cameraDistance); + TransformNR rot = new TransformNR(new RotationNR(-150, 45, 0)); + + Affine af = TransformFactory.nrToAffine(camoffset.times(rot.times(camDist))); + camera.getTransforms().add(af); + // Position the camera +// camera.setTranslateX(); +// camera.setTranslateY(); +// camera.setTranslateZ(); +// // Apply rotations to the root group instead of the camera +// root.getTransforms().addAll( +// new Rotate(-5, Rotate.Y_AXIS), +// new Rotate(-45, Rotate.X_AXIS) +// ); + // Create a scene with the group and camera + int i = 1000; + Scene scene = new Scene(root, i, i, true, SceneAntialiasing.BALANCED); + scene.setFill(Color.TRANSPARENT); + scene.setCamera(camera); + + // Set up snapshot parameters + SnapshotParameters params = new SnapshotParameters(); + params.setFill(Color.TRANSPARENT); + params.setCamera(camera); + params.setDepthBuffer(true); + params.setTransform(Transform.scale(1, 1)); + // Set the near and far clip + camera.setNearClip(0.1); // Set the near clip plane + camera.setFarClip(9000.0); // Set the far clip plane + + + // Create the WritableImage first + WritableImage snapshot = new WritableImage(i, i); + + root.snapshot(params, snapshot); + + return snapshot; + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/lipsync/RhubarbManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/lipsync/RhubarbManager.java index 1cd1f2430..8f6d5db73 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/lipsync/RhubarbManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/lipsync/RhubarbManager.java @@ -41,7 +41,7 @@ public void processRaw(File f, String ttsLocation) throws Exception { + RhubarbVersion + "-" + os + "/rhubarb" + exeExtention); timeCodedVisemes = new ArrayList<>(); if (!exe.exists()) { - System.out.println("Downloading " + exe.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Downloading " + exe.getAbsolutePath()); String zipfileName = "Rhubarb-Lip-Sync-" + RhubarbVersion + "-" + os + ".zip"; String urlStr = "https://github.com/DanielSWolf/rhubarb-lip-sync/releases/download/v" + RhubarbVersion + "/" + zipfileName; @@ -73,7 +73,7 @@ public void processRaw(File f, String ttsLocation) throws Exception { Process process; String command = exe +" --dialogFile "+ttsLocation+" --machineReadable -f json " + f.getAbsolutePath(); - System.out.println(command); + com.neuronrobotics.sdk.common.Log.error(command); process = Runtime.getRuntime().exec(command); int exitCode = process.waitFor(); @@ -83,8 +83,8 @@ public void processRaw(File f, String ttsLocation) throws Exception { String utf8 = StandardCharsets.UTF_8.toString(); IOUtils.copy(is, writer, utf8); String result = writer.toString(); - // System.out.println(status); - // System.out.println(result); + // com.neuronrobotics.sdk.common.Log.error(status); + // com.neuronrobotics.sdk.common.Log.error(result); Type TT_mapStringString = new TypeToken>() { }.getType(); Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create(); @@ -99,7 +99,7 @@ public void processRaw(File f, String ttsLocation) throws Exception { // double percent = end / duration * 100.0; // AudioStatus val = AudioStatus.get(cue.get("value").toString().charAt(0)); -// System.out.println("End at " + percent + " " + val); +// com.neuronrobotics.sdk.common.Log.error("End at " + percent + " " + val); // HashMap map = new HashMap<>(); // map.put(val, percent); TimeCodedViseme map = new TimeCodedViseme(val, start, end, duration); @@ -112,7 +112,7 @@ public void processRaw(File f, String ttsLocation) throws Exception { public AudioInputStream startProcessing(AudioInputStream ais, String TTSString) { File audio = new File(ScriptingEngine.getWorkspace().getAbsolutePath() + "/tmp-tts.wav"); try { - System.out.println("Begin writing.."); + com.neuronrobotics.sdk.common.Log.error("Begin writing.."); AudioSystem.write(ais, AudioFileFormat.Type.WAVE, audio); ais = AudioSystem.getAudioInputStream(audio); File text = new File(ScriptingEngine.getWorkspace().getAbsolutePath() + "/tmp-tts.txt"); @@ -127,9 +127,9 @@ public AudioInputStream startProcessing(AudioInputStream ais, String TTSString) } // rhubarb! processRaw(audio, text.getAbsolutePath()); - System.out.println("Done writing!"); + com.neuronrobotics.sdk.common.Log.error("Done writing!"); } catch (Exception e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/lipsync/VoskLipSync.java b/src/main/java/com/neuronrobotics/bowlerstudio/lipsync/VoskLipSync.java index 41638bf93..b8aa7df5f 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/lipsync/VoskLipSync.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/lipsync/VoskLipSync.java @@ -120,7 +120,7 @@ public static void setModelName(String modelName) { FileOutputStream fis = new FileOutputStream(zipfile); byte[] buffer = new byte[1024]; int count = 0; - System.out.println("Downloading Vosk Model " + getModelName()); + com.neuronrobotics.sdk.common.Log.error("Downloading Vosk Model " + getModelName()); while ((count = bis.read(buffer, 0, 1024)) != -1) { fis.write(buffer, 0, count); System.out.print("."); @@ -130,7 +130,7 @@ public static void setModelName(String modelName) { String source = zipfile.getAbsolutePath(); String destination = ScriptingEngine.getWorkspace().getAbsolutePath(); - System.out.println("Unzipping Vosk Model " + getModelName()); + com.neuronrobotics.sdk.common.Log.error("Unzipping Vosk Model " + getModelName()); ZipFile zipFile = new ZipFile(source); zipFile.extractAll(destination); } @@ -370,7 +370,7 @@ public void processRaw(File f, String ttsLocation) throws UnsupportedAudioFileEx BufferedWriter writer = new BufferedWriter(new FileWriter(json.getAbsolutePath())); writer.write(s); writer.close(); - System.out.println("Lip Sync data writen to " + json.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Lip Sync data writen to " + json.getAbsolutePath()); timeCodedVisemesCache.clear(); } catch (Throwable tr) { tr.printStackTrace(); @@ -398,7 +398,7 @@ public AudioInputStream startProcessing(AudioInputStream ais, String TTSString) File audio = new File(ScriptingEngine.getWorkspace().getAbsolutePath() + "/tmp-tts.wav"); try { long start = System.currentTimeMillis(); - System.out.println("Vosk Lip Sync Begin writing.."); + com.neuronrobotics.sdk.common.Log.error("Vosk Lip Sync Begin writing.."); AudioSystem.write(ais, AudioFileFormat.Type.WAVE, audio); ais = AudioSystem.getAudioInputStream(audio); File text = new File(ScriptingEngine.getWorkspace().getAbsolutePath() + "/tmp-tts.txt"); @@ -413,9 +413,9 @@ public AudioInputStream startProcessing(AudioInputStream ais, String TTSString) } // rhubarb! processRaw(audio, text.getAbsolutePath()); - System.out.println("Vosk Lip Sync Done writing! took " + (System.currentTimeMillis() - start)); + com.neuronrobotics.sdk.common.Log.error("Vosk Lip Sync Done writing! took " + (System.currentTimeMillis() - start)); } catch (Exception e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } @@ -490,14 +490,14 @@ public static String promptFromMicrophone() throws IOException, LineUnavailableE // println "Listening..." } } else { - // System.out.println(recognizer.getPartialResult()); + // com.neuronrobotics.sdk.common.Log.error(recognizer.getPartialResult()); } } } catch (Throwable t) { t.printStackTrace(); } recognizer.close(); - // System.out.println(result); + // com.neuronrobotics.sdk.common.Log.error(result); microphone.close(); return result; } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/opencv/OpenCVManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/opencv/OpenCVManager.java index 61f04cff9..bca3f0426 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/opencv/OpenCVManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/opencv/OpenCVManager.java @@ -52,7 +52,7 @@ public boolean connectDeviceImp() { @Override public ArrayList getNamespacesImp() { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/physics/CSGPhysicsManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/physics/CSGPhysicsManager.java index 8d40ecc3e..ec3de2d0f 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/physics/CSGPhysicsManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/physics/CSGPhysicsManager.java @@ -83,7 +83,7 @@ protected CSG loadCSGToPoints(CSG baseCSG, boolean adjustCenter, Transform pose, //if(polygons.size()>1000) // polygons = getBoundingBox(finalCSG).getPolygons(); for (Polygon p : polygons) { - for (Vertex v : p.vertices) { + for (Vertex v : p.getVertices()) { arg0.add(new Vector3f((float) v.getX(), (float) v.getY(), (float) v.getZ())); } } @@ -106,7 +106,7 @@ public void setup(CollisionShape fallShape, Transform pose, double mass, Physics this.setCore(core); // setup the motion state for the ball - System.out.println("Starting Object at " + TransformFactory.bulletToNr(pose)); + com.neuronrobotics.sdk.common.Log.error("Starting Object at " + TransformFactory.bulletToNr(pose)); DefaultMotionState fallMotionState = new DefaultMotionState(pose); // This we're going to give mass so it responds to gravity Vector3f fallInertia = new Vector3f(0, 0, 0); diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/physics/HingeCSGPhysicsManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/physics/HingeCSGPhysicsManager.java index 8bf7ab2a8..1d0da0382 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/physics/HingeCSGPhysicsManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/physics/HingeCSGPhysicsManager.java @@ -43,14 +43,14 @@ public void update(float timeStep) { getCore().remove(this); setConstraint(null); getCore().add(this); - System.out.println( + com.neuronrobotics.sdk.common.Log.error( "ERROR Link Broken, Strength: " + getMuscleStrength() + " applied impluse " + constraint .getAppliedImpulse()); } } else if (constraint != null && flagBroken) { constraint.enableAngularMotor(false, 0, 0); } - //System.out.println("Constraint = "+constraint+" controller= "+getController()+" broken= "+flagBroken); + //com.neuronrobotics.sdk.common.Log.error("Constraint = "+constraint+" controller= "+getController()+" broken= "+flagBroken); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/physics/MobileBasePhysicsManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/physics/MobileBasePhysicsManager.java index 3387b9e18..5d63506db 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/physics/MobileBasePhysicsManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/physics/MobileBasePhysicsManager.java @@ -116,7 +116,7 @@ public MobileBasePhysicsManager(MobileBase base, ArrayList baseCad, Maxz = c.getMaxZ(); } } - // System.out.println("Minimum z = "+minz); + // com.neuronrobotics.sdk.common.Log.error("Minimum z = "+minz); Transform start = new Transform(); base.setFiducialToGlobalTransform(new TransformNR()); // TransformNR globe= base.getFiducialToGlobalTransform(); @@ -279,7 +279,7 @@ public void run() { ILinkListener ll = new ILinkListener() { @Override public void onLinkPositionUpdate(AbstractLink source, double engineeringUnitsValue) { - // System.out.println(" + // com.neuronrobotics.sdk.common.Log.error(" // value="+engineeringUnitsValue); hingePhysicsManager.setTarget(Math.toRadians(-engineeringUnitsValue)); diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/physics/MuJoCoPhysicsManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/physics/MuJoCoPhysicsManager.java index 9e24c8a9b..5e711c818 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/physics/MuJoCoPhysicsManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/physics/MuJoCoPhysicsManager.java @@ -147,7 +147,7 @@ public void controlStep(MuJoCoModelManager manager) { double target = Math.toRadians(link.getCurrentEngineeringUnits()) * gearRatios.get(link); // double error = target-positions.get(s); // double effort = error * kp; - // System.out.println("Actuator "+s+" position "+positions.get(s)+" effort + // com.neuronrobotics.sdk.common.Log.error("Actuator "+s+" position "+positions.get(s)+" effort // "+effort); setEfforts.put(s, target); } @@ -173,11 +173,11 @@ public void controlStep(MuJoCoModelManager manager) { rotxAcceleration, rotyAcceleration, rotzAcceleration, currentTimeMillis())); } catch (NullPointerException e) { // startup sync problems, ignore - System.out.println(e.getMessage()); + com.neuronrobotics.sdk.common.Log.error(e.getMessage()); } } - // System.out.println("Body "+s+" pose "+); + // com.neuronrobotics.sdk.common.Log.error("Body "+s+" pose "+); } } } @@ -309,14 +309,14 @@ public long stepAndWait() { try { Thread.sleep(diff); } catch (InterruptedException e) { - // TODO Auto-generated catch block + // Auto-generated catch block throw new RuntimeException(e); } } else if (diff == 0) { if (Thread.interrupted()) throw new RuntimeException("Interrupted exception!"); } else { - // System.err.println("MuJoCo Real time broken, expected + // com.neuronrobotics.sdk.common.Log.error("MuJoCo Real time broken, expected // "+getTimestepMilliSeconds()+" took "+time); } if (Thread.interrupted()) @@ -364,7 +364,7 @@ public File getXMLFile() throws IOException, JAXBException { } else { tempFile = new File(workingDir.getAbsolutePath() + "/" + name + ".xml"); } - System.out.println("Writing " + tempFile.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Writing " + tempFile.getAbsolutePath()); Files.write(Paths.get(tempFile.getAbsolutePath()), xml.getBytes()); return tempFile; } @@ -546,7 +546,7 @@ public void loadBase(MobileBase cat, org.mujoco.xml.BodyarchType.Builder link double val = part.getMassKG(mass) * KgtoMujocoMass; geom.withMass(BigDecimal.valueOf(val)); } else { - System.out.println("\nUsing density for "+part.getName()); + com.neuronrobotics.sdk.common.Log.error("\nUsing density for "+part.getName()); } } @@ -614,7 +614,7 @@ public void loadBase(MobileBase cat, org.mujoco.xml.BodyarchType.Builder link double val = csg.getMassKG(linkMass/numPartsWithoutMassLink) * KgtoMujocoMass; geom.withMass(BigDecimal.valueOf(val)); } else { - System.out.println("\nUsing density for "+csg.getName()); + com.neuronrobotics.sdk.common.Log.error("\nUsing density for "+csg.getName()); } } } @@ -778,7 +778,7 @@ public org.mujoco.xml.BodyarchType.Builder loadLink(MobileBase cat, DHParamet } } } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } else { @@ -954,7 +954,7 @@ public void putCSGInAssets(String nameOfCSG, CSG hull, boolean isFree) throws IO Files.write(Paths.get(tempFile.getAbsolutePath()), obj.getBytes()); System.out.print(" " + (System.currentTimeMillis() - start+"\n")); } else { - System.out.println("Loading cache " + tempFile.getName()); + com.neuronrobotics.sdk.common.Log.error("Loading cache " + tempFile.getName()); } if (isFree) { asset.addTexture().withRgb1(toColorString(hull.getColor())).withRgb2(toColorString(hull.getColor())) @@ -994,11 +994,11 @@ public void waitForCad(MobileBaseCadManager cadMan, long start) { try { Thread.sleep(1000); } catch (InterruptedException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } - System.out.println("Waiting for cad to process " + percent); + com.neuronrobotics.sdk.common.Log.error("Waiting for cad to process " + percent); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/physics/PhysicsCore.java b/src/main/java/com/neuronrobotics/bowlerstudio/physics/PhysicsCore.java index 0e18de322..2306cb471 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/physics/PhysicsCore.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/physics/PhysicsCore.java @@ -170,7 +170,7 @@ public void startPhysicsThread(int ms) { if (took < msTime) { ThreadUtil.wait((int) (msTime - took)); } else { - System.out.println("Real time physics broken: " + took); + com.neuronrobotics.sdk.common.Log.error("Real time physics broken: " + took); } } catch (Exception E) { E.printStackTrace(); @@ -201,7 +201,7 @@ public void step(float timeStep) { getDynamicsWorld().stepSimulation(timeStep, getSimulationSubSteps()); if ((((float) (System.currentTimeMillis() - startTime)) / 1000.0f) > timeStep) { - // System.out.println(" Compute took too long "+timeStep); + // com.neuronrobotics.sdk.common.Log.error(" Compute took too long "+timeStep); } for (IPhysicsManager o : getPhysicsObjects()) { o.update(timeStep); diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/physics/PhysicsEngine.java b/src/main/java/com/neuronrobotics/bowlerstudio/physics/PhysicsEngine.java index d2730271c..ff1f40e85 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/physics/PhysicsEngine.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/physics/PhysicsEngine.java @@ -73,7 +73,7 @@ public static PhysicsCore get() { try { mainEngine = new PhysicsCore(); } catch (Exception e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/physics/TransformFactory.java b/src/main/java/com/neuronrobotics/bowlerstudio/physics/TransformFactory.java index b406ad530..8cf94cbea 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/physics/TransformFactory.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/physics/TransformFactory.java @@ -8,10 +8,11 @@ import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR; import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; +import eu.mihosoft.vrl.v3d.Transform; import javafx.application.Platform; import javafx.scene.transform.Affine; -// TODO: Auto-generated Javadoc +// Auto-generated Javadoc /** * A factory for creating Transform objects. @@ -189,4 +190,8 @@ public static TransformNR csgToNR(eu.mihosoft.vrl.v3d.Transform csg) { return new TransformNR(t1.x, t1.y, t1.z, new RotationNR(q1.w, q1.x, q1.y, q1.z)); } + public static Transform affineToCSG(Affine manipulator) { + return nrToCSG(affineToNr(manipulator)); + } + } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/printbed/PrintBedManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/printbed/PrintBedManager.java index 40ce000e9..1d470deb0 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/printbed/PrintBedManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/printbed/PrintBedManager.java @@ -55,7 +55,7 @@ public PrintBedManager(File dir, ArrayList parts) { try { this.url=ScriptingEngine.locateGitUrl(dir); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } setHasPrintBed(init(dir, parts)); @@ -65,9 +65,9 @@ public boolean init(File dir, ArrayList parts) { if (url == null) return false; File f = new File(dir.getAbsolutePath() + "/" + file); - System.out.println("Searching for printbed at "+f); + com.neuronrobotics.sdk.common.Log.error("Searching for printbed at "+f); if (f.exists()) { - System.out.println("Print Bed file found! "+f.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Print Bed file found! "+f.getAbsolutePath()); String source; byte[] bytes; try { @@ -79,7 +79,7 @@ public boolean init(File dir, ArrayList parts) { } }else { - System.out.println("Print Bed NOT file found! "+f.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Print Bed NOT file found! "+f.getAbsolutePath()); return false; } if (database == null) { @@ -104,7 +104,7 @@ public boolean init(File dir, ArrayList parts) { if(names.contains(name)) continue; names.add(name); - System.out.println(bit.getName() + " on " + index + " rot " + zrot + " y " + yval); + com.neuronrobotics.sdk.common.Log.error(bit.getName() + " on " + index + " rot " + zrot + " y " + yval); if (database.locations.get(name) == null) { database.locations.put(name, new TransformNR()); } @@ -169,7 +169,7 @@ public ArrayList makePrintBeds() { bed.addExportFormat(s); } if (bed != null) { - //System.out.println("Mesh fixing for "+name); + //com.neuronrobotics.sdk.common.Log.error("Mesh fixing for "+name); //bed=bed.union(bed); bed.setName(name); } @@ -201,7 +201,7 @@ private synchronized void saveLocal() { // ScriptingEngine.commit(url, ScriptingEngine.getBranch(url), file, content, "Save Print Bed Locations", // true); } catch (Exception e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/printbed/PrintBedObject.java b/src/main/java/com/neuronrobotics/bowlerstudio/printbed/PrintBedObject.java index 7cb0f5abf..939cec0d2 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/printbed/PrintBedObject.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/printbed/PrintBedObject.java @@ -3,11 +3,13 @@ import java.util.Arrays; import java.util.List; -import com.neuronrobotics.bowlerkernel.Bezier3d.manipulation; +import com.neuronrobotics.bowlerkernel.Bezier3d.Manipulation; import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; import eu.mihosoft.vrl.v3d.CSG; import eu.mihosoft.vrl.v3d.Vector3d; +import javafx.event.EventHandler; +import javafx.scene.input.MouseEvent; import javafx.scene.transform.Affine; public class PrintBedObject { @@ -17,7 +19,7 @@ public class PrintBedObject { private double yMin; private CSG part; private String name; - private manipulation manip; + private Manipulation manip; private Affine affine = new Affine(); private TransformNR globalPose; public PrintBedObject(String name, CSG part, double xMax, double xMin, double yMax, double yMin, TransformNR startPose){ @@ -29,11 +31,13 @@ public PrintBedObject(String name, CSG part, double xMax, double xMin, double yM this.yMin = yMin; this.globalPose = startPose; - manip = new manipulation(affine, new Vector3d(1, 1, 0), part, startPose); - manip.addSaveListener(() -> System.out.println("Saving PrintBedObject "+name)); + manip = new Manipulation(affine, new Vector3d(1, 1, 0), startPose); + part.getStorage().set("manipulator",manip.map); + part.setManipulator(affine); + manip.addSaveListener(() -> com.neuronrobotics.sdk.common.Log.error("Saving PrintBedObject "+name)); checkBounds(); } - public void addEventListener(Runnable r) { + public void addEventListener(EventHandler r) { manip.addEventListener(r); } @@ -45,15 +49,15 @@ public List get() { } public double getX() { - return manip.currentPose.getX(); + return manip.getCurrentPose().getX(); } public double getY() { - return manip.currentPose.getY(); + return manip.getCurrentPose().getY(); } public double getZ() { - return manip.currentPose.getZ(); + return manip.getCurrentPose().getZ(); } public void checkBounds() { double minYTest = part.getMinY()-yMin+globalPose.getY(); diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ArduinoLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ArduinoLoader.java index f9be1654c..6f786eb83 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ArduinoLoader.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ArduinoLoader.java @@ -6,6 +6,8 @@ import java.util.Arrays; import java.util.HashMap; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; + public class ArduinoLoader implements IScriptingLanguage { @@ -14,7 +16,7 @@ public class ArduinoLoader implements IScriptingLanguage { @SuppressWarnings("unchecked") @Override - public Object inlineScriptRun(File code, ArrayList args) throws Exception { + public Object inlineScriptRun(CSGDatabaseInstance db,File code, ArrayList args) throws Exception { if (args == null) { args = new ArrayList<>(); } @@ -38,14 +40,14 @@ public Object inlineScriptRun(File code, ArrayList args) throws Exceptio } File ino = findIno(code); if (ino == null) { - //System.out.println("Error: no .ino file found!"); + //com.neuronrobotics.sdk.common.Log.error("Error: no .ino file found!"); return null; } commands.add("upload"); commands.add(ino.getAbsolutePath()); - //System.out.println("Arduino Load: \n"+execString); + //com.neuronrobotics.sdk.common.Log.error("Arduino Load: \n"+execString); Thread ret = DownloadManager.run(null, ino.getParentFile(), System.out, commands); ret.join(); @@ -82,8 +84,8 @@ private File findIno(File start) { } @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { - // TODO Auto-generated method stub + public Object inlineScriptRun(CSGDatabaseInstance db,String code, ArrayList args) throws Exception { + // Auto-generated method stub return null; } @@ -164,7 +166,7 @@ public static String getARDUINOExec() { @Override public ArrayList getFileExtenetion() { - // TODO Auto-generated method stub + // Auto-generated method stub return new ArrayList<>(Arrays.asList( ".ino",".c", ".h", ".cpp", ".hpp")); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/BashLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/BashLoader.java index bd22c24d5..d1021f6ce 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/BashLoader.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/BashLoader.java @@ -9,10 +9,12 @@ import com.neuronrobotics.video.OSUtil; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; + public class BashLoader implements IScriptingLanguage { @Override - public Object inlineScriptRun(File code, ArrayList args) throws Exception { + public Object inlineScriptRun(CSGDatabaseInstance db,File code, ArrayList args) throws Exception { // List asList = Arrays.asList("bash",code.getAbsolutePath()); ArrayList commands = new ArrayList<>(); commands.add("bash"); @@ -39,10 +41,10 @@ public Object inlineScriptRun(File code, ArrayList args) throws Exceptio while ((s = stdInput.readLine()) != null || (e = errInput.readLine()) != null) { if (s != null) { back.add(s); - System.out.println(s); + com.neuronrobotics.sdk.common.Log.error(s); } if (e != null) - System.out.println(e); + com.neuronrobotics.sdk.common.Log.error(e); // } process.waitFor(); @@ -55,7 +57,7 @@ public Object inlineScriptRun(File code, ArrayList args) throws Exceptio } @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { + public Object inlineScriptRun(CSGDatabaseInstance db,String code, ArrayList args) throws Exception { throw new RuntimeException("Bash scripts have to be sent as files"); } @@ -82,7 +84,7 @@ public String getDefaultContents() { @Override public boolean getIsTextFile() { - // TODO Auto-generated method stub + // Auto-generated method stub return true; } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/BlenderLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/BlenderLoader.java index 6aae7f81a..4d9f045dc 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/BlenderLoader.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/BlenderLoader.java @@ -15,22 +15,23 @@ import eu.mihosoft.vrl.v3d.CSG; import eu.mihosoft.vrl.v3d.FileUtil; import eu.mihosoft.vrl.v3d.STL; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import javafx.scene.paint.Color; public class BlenderLoader implements IScriptingLanguage { @Override - public Object inlineScriptRun(File code, ArrayList args) throws Exception { + public Object inlineScriptRun(CSGDatabaseInstance db,File code, ArrayList args) throws Exception { File stl = File.createTempFile(code.getName(), ".stl"); stl.deleteOnExit(); - toSTLFile(code,stl); - CSG back = Vitamins.get(stl,true); + toSTLFile(db,code,stl); + CSG back = Vitamins.get(db,stl,true); back.setColor(Color.ORANGE); return back; } @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { + public Object inlineScriptRun(CSGDatabaseInstance db,String code, ArrayList args) throws Exception { throw new RuntimeException("Blender can not run from a string"); } @@ -45,33 +46,25 @@ public ArrayList getFileExtenetion() { ext.add("blend"); return ext; } - public static void toBlenderFile(CSG stlIn,File blenderfile) throws IOException { + public static void toBlenderFile(CSGDatabaseInstance db,CSG stlIn,File blenderfile) throws IOException { File stl = getTmpSTL(stlIn); - toBlenderFile(stl, blenderfile); + toBlenderFile(db,stl, blenderfile); } - public static File getTmpSTL(CSG stlIn) throws IOException { - String name = stlIn.getName(); - if(name.length()==0) - name="CSG_EXPORT"; - File stl = File.createTempFile(name, ".stl"); - stl.deleteOnExit(); - FileUtil.write(Paths.get(stl.getAbsolutePath()), stlIn.toStlString()); - return stl; - } - public static void toBlenderFile(File incoming,File blenderfile) { - System.out.println("Converting to Blender file before loading"); + + public static void toBlenderFile(CSGDatabaseInstance db,File stl,File blenderfile) { + com.neuronrobotics.sdk.common.Log.error("Converting to Blender file before loading"); File stlIn; try { - stlIn = File.createTempFile(incoming.getName(), ".stl"); + stlIn = File.createTempFile(stl.getName(), ".stl"); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); return; } stlIn.deleteOnExit(); - scaleStl(incoming,stlIn,0.001); + scaleStl(db,stl,stlIn,0.001); File dir = stlIn.getAbsoluteFile().getParentFile(); try { @@ -93,21 +86,58 @@ public static void toBlenderFile(File incoming,File blenderfile) { t.join(); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); return; } } - public static void scaleStl(File incoming, File outgoing, double scale) { - CSG back = Vitamins.get(incoming,true).scale(scale); + public static void scaleStl(CSGDatabaseInstance db,File incoming, File outgoing, double scale) { + CSG back = Vitamins.get(db,incoming,true).scale(scale); try { + boolean manifold=CSG.isPreventNonManifoldTriangles(); + CSG.setPreventNonManifoldTriangles(false); FileUtil.write(Paths.get(outgoing.getAbsolutePath()), back.toStlString()); + + CSG.setPreventNonManifoldTriangles(manifold); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } - public static void toSTLFile(File blenderfile,File stlout) throws InvalidRemoteException, TransportException, GitAPIException, IOException, InterruptedException { + public static CSG remesh(CSGDatabaseInstance db,CSG incoming, double MMVoxel,CSGDatabaseInstance instance) throws Exception { + File stl = DownloadManager.getTmpSTL(incoming); + remeshSTLFile(db,stl, MMVoxel); + CSG back = Vitamins.get(db,stl,true); + return back.syncProperties(instance,incoming).setName(incoming.getName()); + } + public static void remeshSTLFile(CSGDatabaseInstance db,File stlout,double MMVoxel) throws Exception { + File blend = File.createTempFile(stlout.getName(), ".blend"); + blend.delete(); + toBlenderFile(db,stlout, blend); + remeshToSTLFile(db,blend, stlout, MMVoxel); + } + public static void remeshToSTLFile(CSGDatabaseInstance db,File blenderfile,File stlout,double MMVoxel) throws InvalidRemoteException, TransportException, GitAPIException, IOException, InterruptedException { + File exe = getConfigExecutable("blender", null); + File export = ScriptingEngine.fileFromGit( + "https://github.com/CommonWealthRobotics/blender-bowler-cli.git", + "remesh.py"); + ArrayList args = new ArrayList<>(); + + if(stlout.exists()) + stlout.delete(); + args.add(exe.getAbsolutePath()); + + args.add("--background"); + args.add("--python"); + args.add(export.getAbsolutePath()); + args.add("--"); + args.add(blenderfile.getAbsolutePath()); + args.add(""+(MMVoxel/1000.0)); + args.add(stlout.getAbsolutePath()); + legacySystemRun(null, stlout.getAbsoluteFile().getParentFile(), System.out, args); + scaleStl(db,stlout,stlout,1000.0); + } + public static void toSTLFile(CSGDatabaseInstance db,File blenderfile,File stlout) throws InvalidRemoteException, TransportException, GitAPIException, IOException, InterruptedException { File exe = getConfigExecutable("blender", null); File export = ScriptingEngine.fileFromGit( "https://github.com/CommonWealthRobotics/blender-bowler-cli.git", @@ -125,7 +155,7 @@ public static void toSTLFile(File blenderfile,File stlout) throws InvalidRemoteE args.add(blenderfile.getAbsolutePath()); args.add(stlout.getAbsolutePath()); legacySystemRun(null, stlout.getAbsoluteFile().getParentFile(), System.out, args); - scaleStl(stlout,stlout,1000.0); + scaleStl(db,stlout,stlout,1000.0); } @Override public void getDefaultContents(File source) { @@ -133,7 +163,7 @@ public void getDefaultContents(File source) { String absolutePath = source.getAbsolutePath(); File parent = new File(absolutePath).getParentFile(); if(source.exists()) { - System.out.println("Blender file exists, being overwritten to blank "+absolutePath); + com.neuronrobotics.sdk.common.Log.error("Blender file exists, being overwritten to blank "+absolutePath); source.delete(); } ArrayList args = new ArrayList<>(); @@ -148,18 +178,18 @@ public void getDefaultContents(File source) { try { DownloadManager.legacySystemRun(null, parent, System.out, args); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } @Override public boolean getIsTextFile() { - // TODO Auto-generated method stub + // Auto-generated method stub return false; } @@ -170,7 +200,7 @@ public static void main(String[] args) throws InvalidRemoteException, TransportE File testblend = new File("test.blend"); if(!testblend.exists()) loader.getDefaultContents(testblend); - loader.toSTLFile(testblend, new File("testBlender.stl")); + loader.toSTLFile(null,testblend, new File("testBlender.stl")); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/Build123dLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/Build123dLoader.java new file mode 100644 index 000000000..89db491be --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/Build123dLoader.java @@ -0,0 +1,108 @@ +package com.neuronrobotics.bowlerstudio.scripting; +import static com.neuronrobotics.bowlerstudio.scripting.DownloadManager.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; + +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidRemoteException; +import org.eclipse.jgit.api.errors.TransportException; + +import com.neuronrobotics.bowlerstudio.vitamins.Vitamins; +import com.neuronrobotics.sdk.common.Log; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.FileUtil; +import eu.mihosoft.vrl.v3d.STL; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; +import javafx.scene.paint.Color; + +public class Build123dLoader implements IScriptingLanguage { + + @Override + public Object inlineScriptRun(CSGDatabaseInstance db,File code, ArrayList args) throws Exception { + File stl = File.createTempFile(sanitizeString(code.getName()), ".stl"); + stl.deleteOnExit(); + HashMap params=new HashMap(); + if(args!=null) { + Object o = args.get(0); + if(HashMap.class.isInstance(o)) { + params=(HashMap)o; + } + } + + toSTLFile(code,stl,params); + CSG back = Vitamins.get(db,stl,true); + back.setColor(Color.ANTIQUEWHITE); + return back; + } + + @Override + public Object inlineScriptRun(CSGDatabaseInstance db,String code, ArrayList args) throws Exception { + throw new RuntimeException("Build123d can not run from a string"); + } + + @Override + public String getShellType() { + return "Build123d"; + } + + @Override + public ArrayList getFileExtenetion() { + ArrayList ext = new ArrayList<>(); + ext.add("py"); + ext.add("build123d"); + return ext; + } + + + + + public static void toSTLFile(File build123dScript,File stlout, HashMap params) throws InvalidRemoteException, TransportException, GitAPIException, IOException, InterruptedException { + File exe = getConfigExecutable("build123d", null); + File dir = getDestinationDir("build123d"); + if(params==null) + params=new HashMap(); + ArrayList args = new ArrayList<>(); + + if(stlout.exists()) + stlout.delete(); + args.add(exe.getAbsolutePath()); + args.add("run"); + args.add("python"); + for(String key:params.keySet()) { + args.add("-D"); + args.add(key+"="+params.get(key)); + } + args.add(build123dScript.getAbsolutePath()); +// args.add("-o"); +// args.add(stlout.getAbsolutePath()); + legacySystemRun(null, dir, System.out, args); + } + @Override + public String getDefaultContents() { + return "from build123d import *\n" + + "\n" + + "cube = Box(10, 10, 10)"; + } + + @Override + public boolean getIsTextFile() { + return true; + } + + public static void main(String[] args) throws InvalidRemoteException, TransportException, GitAPIException, IOException, InterruptedException { + Build123dLoader loader = new Build123dLoader(); + Log.enableDebugPrint(); + // create test file + File testblend = new File("build123dTest.py"); + if(!testblend.exists()) + loader.getDefaultContents(testblend); + HashMap params = new HashMap(); + toSTLFile(testblend, new File("build123dTest.py.stl"),params); + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/CaDoodleLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/CaDoodleLoader.java new file mode 100644 index 000000000..3ed1a2465 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/CaDoodleLoader.java @@ -0,0 +1,78 @@ +package com.neuronrobotics.bowlerstudio.scripting; + +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.CaDoodleFile; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; + +public class CaDoodleLoader implements IScriptingLanguage { + @Override + public Object inlineScriptRun(CSGDatabaseInstance db,File code, ArrayList args) throws Exception { + CaDoodleFile loaded = CaDoodleFile.fromFile(code); + Object process = process(loaded,false); + loaded.close(); + return process; + } + + @Override + public Object inlineScriptRun(CSGDatabaseInstance db,String code, ArrayList args) throws Exception { + CaDoodleFile loaded = CaDoodleFile.fromJsonString(code); + Object process = process(loaded,false); + loaded.close(); + return process; + } + + public static Object process(CaDoodleFile loaded,boolean includeAlwaysShow) { + List incoming = loaded.getCurrentState(); + ArrayList back = new ArrayList(); + back.addAll(incoming); + for(CSG c: incoming) { + if((c.isInGroup() && (!c.isAlwaysShow() && includeAlwaysShow )) || c.isHide()) { + back.remove(c); + } + } + return back; + } + + @Override + public String getShellType() { + return "CaDoodle"; + } + + @Override + public boolean getIsTextFile() { + return true; + } + + /** + * Get the contents of an empty file + * + * @return + */ + public String getDefaultContents() { + return "{\n" + + " \"opperations\": [],\n" + + " \"currentIndex\": 0,\n" + + " \"projectName\": \"A Test Project\"\n" + + "}"; + } + + @Override + public ArrayList getFileExtenetion() { + return new ArrayList<>(Arrays.asList("doodle","cadoodle")); + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ClojureHelper.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ClojureHelper.java index 547aa0856..3ba56c4ff 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ClojureHelper.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ClojureHelper.java @@ -9,6 +9,7 @@ import clojure.lang.RT; import clojure.lang.Symbol; import clojure.lang.Var; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; /** * Class containing static utility methods for Java to Clojure interop @@ -62,22 +63,22 @@ public static Object eval(String string) { } @Override - public Object inlineScriptRun(File code, ArrayList args) { + public Object inlineScriptRun(CSGDatabaseInstance db,File code, ArrayList args) { byte[] bytes; try { bytes = Files.readAllBytes(code.toPath()); String s = new String(bytes, "UTF-8"); - return inlineScriptRun(s, args); + return inlineScriptRun( db,s, args); } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e1); } - // System.out.println("Clojure returned of type="+ret.getClass()+" value="+ret); + // com.neuronrobotics.sdk.common.Log.error("Clojure returned of type="+ret.getClass()+" value="+ret); return null; } @Override - public Object inlineScriptRun(String code, ArrayList args) { + public Object inlineScriptRun(CSGDatabaseInstance db,String code, ArrayList args) { return ClojureHelper.eval(code); } @@ -89,7 +90,7 @@ public String getShellType() { @Override public boolean getIsTextFile() { - // TODO Auto-generated method stub + // Auto-generated method stub return true; } @@ -104,7 +105,7 @@ public String getDefaultContents() { @Override public ArrayList getFileExtenetion() { - // TODO Auto-generated method stub + // Auto-generated method stub return new ArrayList<>(Arrays.asList("clj", "cljs", "cljc")); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/DownloadManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/DownloadManager.java index 60e4fc351..eb500bb53 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/DownloadManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/DownloadManager.java @@ -3,6 +3,8 @@ import org.apache.commons.exec.*; import org.apache.commons.exec.environment.EnvironmentUtils; +import static com.neuronrobotics.bowlerstudio.scripting.DownloadManager.sanitizeString; + import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; @@ -33,8 +35,11 @@ import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -53,30 +58,89 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; +import com.neuronrobotics.bowlerstudio.BowlerKernel; +import com.neuronrobotics.bowlerstudio.assets.FontSizeManager; +import com.neuronrobotics.sdk.common.Log; import com.neuronrobotics.video.OSUtil; +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.FileUtil; +import javafx.scene.Node; +import javafx.scene.control.Alert; //import javafx.scene.control.Alert; import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; //import javafx.scene.control.ButtonType; //import javafx.scene.control.Alert.AlertType; import javafx.scene.image.Image; - +import javafx.stage.Stage; import net.sf.sevenzipjbinding.*; import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream; public class DownloadManager { + private static String STUDIO_INSTALL = "BowlerStudioInstall"; private static String editorsURL = "https://github.com/CommonWealthRobotics/ExternalEditorsBowlerStudio.git"; - private static String bindir = System.getProperty("user.home") + delim()+"bin"+delim()+"BowlerStudioInstall"+delim(); + private static String bindir = System.getProperty("user.home") + delim()+"bin"+delim()+getSTUDIO_INSTALL()+delim(); private static int ev = 0; private static String cmd = ""; + private static HashSet failedURLs = new HashSet(); + private static IDownloadManagerEvents downloadEvents = new IDownloadManagerEvents() { + + @Override + public void startDownload() { + // Auto-generated method stub + + } + + @Override + public void finishDownload() { + // Auto-generated method stub + + } + }; + public static String sanitizeString(String s) { + if(s.contains(" ")) + s=s.replace(' ', '_'); + return s; + } + public static File getTmpSTL(CSG stlIn) throws IOException { + String name = stlIn.getName(); + if(name.length()==0) + name="CSG_EXPORT"; + File stl = File.createTempFile(sanitizeString(name), ".stl"); + stl.deleteOnExit(); + boolean manifold=CSG.isPreventNonManifoldTriangles(); + CSG.setPreventNonManifoldTriangles(false); + FileUtil.write(Paths.get(stl.getAbsolutePath()), stlIn.toStlString()); + CSG.setPreventNonManifoldTriangles(manifold); + return stl; + } private static IApprovalForDownload approval = new IApprovalForDownload() { @Override public boolean get(String name, String url) { - System.out.println("Command line mode, assuming yes to downloading \n" + name + " \nfrom \n" + url); + com.neuronrobotics.sdk.common.Log.debug("Command line mode, assuming yes to downloading \n" + name + " \nfrom \n" + url); return true; } + + @Override + public void onInstallFail(String url) { + com.neuronrobotics.sdk.common.Log.error("Plugin needs to be installed from "+url); + } + public void notifyOfFailure(String name) { + com.neuronrobotics.sdk.common.Log.error("Plugin failed "+name); + } + }; + private static GitLogProgressMonitor psudoSplash = new GitLogProgressMonitor() { + + @Override + public void onLogUpdate(String update, Exception e) { + // Auto-generated method stub + + } + }; + private static String jvmURL; public static Thread run(IExternalEditor editor, File dir, PrintStream out, List finalCommand) { return run(new HashMap(), editor, dir, out, finalCommand); @@ -119,7 +183,7 @@ public static void legacySystemRun(Map envincoming, File dir, Pr if (envincoming != null) { envir.putAll(envincoming); for (String s : envincoming.keySet()) { - System.out.println("Environment var set: " + s + " to " + envir.get(s)); + com.neuronrobotics.sdk.common.Log.debug("Environment var set: " + s + " to " + envir.get(s)); } } // setting the directory @@ -151,7 +215,7 @@ public static void legacySystemRun(Map envincoming, File dir, Pr int ev = process.exitValue(); // out.println("Running "+commands); if (ev != 0) { - System.out.println("ERROR PROCESS Process exited with " + ev); + com.neuronrobotics.sdk.common.Log.error("ERROR PROCESS Process exited with " + ev); } while (process.isAlive()) { Thread.sleep(100); @@ -214,11 +278,11 @@ private static void startOutputReader(final InputStream is, final String type, P out.println(line); } } catch (IOException e) { - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(e); } }).start(); } - + @SuppressWarnings("unchecked") public static Map getEnvironment(String exeType) { String key = discoverKey(); @@ -242,7 +306,7 @@ public static Map getEnvironment(String exeType) { Map environment; Object o = vm.get("environment"); if (o != null) { - System.out.println("Environment found for " + exeType + " on " + key); + com.neuronrobotics.sdk.common.Log.debug("Environment found for " + exeType + " on " + key); return (Map) o; } @@ -250,26 +314,51 @@ public static Map getEnvironment(String exeType) { } } } catch (Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } return new HashMap<>(); } - public static File getRunExecutable(String exeType, IExternalEditor editor) { - return getExecutable(exeType, editor, "executable"); + return getRunExecutable(exeType,editor,false); + } + public static File getRunExecutable(String exeType, IExternalEditor editor,boolean justChecking) { + String executable = "executable"; + retryLoop(exeType, editor, executable,justChecking); + return getExecutable(exeType, editor, executable,justChecking); } public static File getConfigExecutable(String exeType, IExternalEditor editor) { - return getExecutable(exeType, editor, "configExecutable"); + String executable = "configExecutable"; + retryLoop(exeType, editor, executable,false); + return getExecutable(exeType, editor, executable,false); } - - private static File getExecutable(String exeType, IExternalEditor editor, String executable) { + + private static void retryLoop(String exeType, IExternalEditor editor, String executable,boolean justChecking) { + if(justChecking) + return; + for(int i=0;i<3;i++) { + if(getExecutable(exeType, editor, executable,justChecking).exists()) { + return; + } + com.neuronrobotics.sdk.common.Log.error(new RuntimeException("Download or extraction failed, retrying")); + } + if(!failedURLs.contains(jvmURL)) { + failedURLs.add(jvmURL); + approval.notifyOfFailure(exeType); + approval.onInstallFail(jvmURL); + } + } + public static File getDestinationDir(String exeType) { + return new File(bindir + exeType); + } + private static File getExecutable(String exeType, IExternalEditor editor, String executable,boolean justChecking) { String key = discoverKey(); try { for (String f : ScriptingEngine.filesInGit(editorsURL)) { File file = ScriptingEngine.fileFromGit(editorsURL, f); + Log.debug("Looking at json file "+file.getAbsolutePath()); if (file.getName().toLowerCase().startsWith(exeType.toLowerCase()) && file.getName().toLowerCase().endsWith(".json")) { String jsonText = new String(Files.readAllBytes(file.toPath())); @@ -280,13 +369,17 @@ private static File getExecutable(String exeType, IExternalEditor editor, String Map vm = (Map) database.get(key); if (vm != null) { String targetdir = exeType; - System.out.println("Configuration found for " + exeType + " on " + key); + com.neuronrobotics.sdk.common.Log.debug("Configuration found for " + exeType + " on " + key); String baseURL = vm.get("url").toString(); String type = vm.get("type").toString(); String name = vm.get("name").toString(); + String ospath =null; + try { + ospath=vm.get("ospath").toString(); + }catch(Throwable t) {} String exeInZip = vm.get(executable).toString(); String configexe = vm.get("configExecutable").toString(); - String jvmURL = baseURL + name + "." + type; + jvmURL = baseURL + name + "." + type; Map environment; Object o = vm.get("environment"); if (o != null) { @@ -294,10 +387,15 @@ private static File getExecutable(String exeType, IExternalEditor editor, String } else environment = new HashMap<>(); File dest = new File(bindir + targetdir); - String cmd = bindir + targetdir + "/" + exeInZip; - if (!new File(cmd).exists()) { + String cmd = bindir + targetdir + delim() + exeInZip; + if(ospath!=null) { + String string = ospath+delim()+exeInZip; + if(new File(string).exists()) + cmd=string; + } + if (!new File(cmd).exists() && !justChecking) { if(exeType.toLowerCase().contentEquals("freecad")) { - FreecadLoader.update(vm); + //FreecadLoader.update(vm); baseURL = vm.get("url").toString(); name = vm.get("name").toString(); exeInZip = vm.get(executable).toString(); @@ -316,7 +414,7 @@ private static File getExecutable(String exeType, IExternalEditor editor, String File jvmArchive = download("", jvmURL, 800000000, bindir, name + "." + type, exeType); if (dest.exists()) { - System.out.println("Erasing stale dir " + dest.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Erasing stale dir " + dest.getAbsolutePath()); deleteDirectory(dest); } if (type.toLowerCase().contains("zip")) { @@ -350,53 +448,59 @@ private static File getExecutable(String exeType, IExternalEditor editor, String if (installer != null) { runInstaller((List) installer); } + Object setup = vm.get("setup"); + if (setup != null) { + String setupScript = setup.toString(); + File setupEXE = new File(getDestinationDir(exeType).getAbsolutePath()+delim()+setupScript); + runInstaller(setupEXE,exeType); + } Object configurations = database.get("Meta-Configuration"); if (configurations != null) { List configs = (List) configurations; - System.out.println("Got Configurations " + configs.size()); + com.neuronrobotics.sdk.common.Log.error("Got Configurations " + configs.size()); ev = -1; IExternalEditor errorcheckerEditor = new IExternalEditor() { @Override public void onProcessExit(int e) { ev = e; - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public String nameOfEditor() { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } @Override - public void launch(File file, Button advanced) { - // TODO Auto-generated method stub + public void launch(File file, Button advanced,Runnable r) { + // Auto-generated method stub } @Override public Class getSupportedLangauge() { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } @Override public URL getInstallURL() throws MalformedURLException { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } @Override public Image getImage() { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } }; for (int i = 0; i < configs.size(); i++) { - System.out.println("Running " + exeType + " Configuration " + (i + 1) + " of " + com.neuronrobotics.sdk.common.Log.error("Running " + exeType + " Configuration " + (i + 1) + " of " + configs.size()); ArrayList toRun = new ArrayList<>(); toRun.add(bindir + targetdir + "/" + configexe); @@ -406,7 +510,7 @@ public Image getImage() { } // = +" "+configs.get(i); - // System.out.println(toRun); + // com.neuronrobotics.sdk.common.Log.error(toRun); Thread thread = run(errorcheckerEditor, new File(bindir), System.out, toRun); thread.join(); @@ -419,7 +523,7 @@ public Image getImage() { } } else { - System.out.println("Not extraction, Application exists " + cmd); + com.neuronrobotics.sdk.common.Log.error("Not extraction, Application exists " + cmd); } return new File(cmd); @@ -427,8 +531,8 @@ public Image getImage() { } } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } throw new RuntimeException("Executable for OS: " + key + " has no entry for " + exeType); @@ -438,14 +542,18 @@ private static void saveFile(File file, String json) { try { FileUtils.writeStringToFile(file, json, Charset.forName("UTF-8")); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } - private static void runInstaller(List installerList) { for (String installer : installerList) { File installerFile = getRunExecutable(installer, null); + runInstaller( installerFile, installer); + } + } + private static void runInstaller(File installerFile,String installer) { + if(installerFile.getAbsolutePath().toLowerCase().endsWith("msi")) { List command = new ArrayList<>(); command.add("msiexec.exe"); @@ -457,19 +565,27 @@ private static void runInstaller(List installerList) { try { tcopy.join(); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } + }else if(installerFile.getAbsolutePath().toLowerCase().endsWith("sh")) { + Thread tcopy = run(null, getDestinationDir(installer), System.out, Arrays.asList("bash",installerFile.getAbsolutePath())); + try { + tcopy.join(); + } catch (InterruptedException e) { + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } }else { - Thread tcopy = run(null, new File("."), System.out, Arrays.asList(installerFile.getAbsolutePath())); + Thread tcopy = run(null, getDestinationDir(installer), System.out, Arrays.asList(installerFile.getAbsolutePath())); try { tcopy.join(); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } - } + } private static boolean deleteDirectory(File directoryToBeDeleted) { @@ -490,8 +606,8 @@ private static void standaloneEXE(String type, String name, String targetdir, St try { Files.move(Paths.get(bindir + name + "." + type), Paths.get(cmd), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } new File(cmd).setExecutable(true); } @@ -505,7 +621,7 @@ private static void dmgExtract(File jvmArchive, String string, String appDir) { Set before = Stream.of(listFiles).filter(file -> file.isDirectory()).map(File::getName) .collect(Collectors.toSet()); Thread t = run(null, new File("."), System.out, - Arrays.asList("hdiutil", "attach", jvmArchive.getAbsolutePath())); + Arrays.asList("hdiutil", "attach","-verbose", jvmArchive.getAbsolutePath())); try { t.join(); Thread.sleep(2000);// wait for mount to settle @@ -515,7 +631,7 @@ private static void dmgExtract(File jvmArchive, String string, String appDir) { after.removeAll(before); Object[] array = after.toArray(); String newMount = (String) array[0]; - System.out.println("Extracted " + jvmArchive.getAbsolutePath() + " is mounted at " + newMount); + com.neuronrobotics.sdk.common.Log.debug("Extracted " + jvmArchive.getAbsolutePath() + " is mounted at " + newMount); // asr restore --source "$MOUNT_POINT" --target "$DEST_PATH" --erase --noprompt if (!location.exists()) { location.mkdirs(); @@ -528,12 +644,12 @@ private static void dmgExtract(File jvmArchive, String string, String appDir) { Arrays.asList("hdiutil", "detach", "/Volumes/" + newMount)); tdetach.join(); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); return; } // wait for the mount to finish - System.out.println("Extracted " + jvmArchive.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Extracted " + jvmArchive.getAbsolutePath()); } @@ -548,7 +664,7 @@ public static boolean isExecutable(ZipArchiveEntry entry) { private static void extract7zSystemCall(String archivePath, String outputPath) { File outputDir = new File(outputPath); if (outputDir.exists()) { - System.err.println("Deleting partial extraction, using system 7z"); + com.neuronrobotics.sdk.common.Log.error("Deleting partial extraction, using system 7z"); deleteDirectory(outputDir); } outputDir.mkdirs(); @@ -564,11 +680,11 @@ private static void extract7zSystemCall(String archivePath, String outputPath) { try { legacySystemRun(null, outputDir, System.out, args); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } @@ -576,8 +692,8 @@ public static void extract7zArchive(String archivePath, String outputPath) { try (RandomAccessFile randomAccessFile = new RandomAccessFile(archivePath, "r"); IInArchive inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile))) { - System.out.println("Archive size: " + randomAccessFile.length() + " bytes"); - System.out.println("Items in archive: " + inArchive.getNumberOfItems()); + com.neuronrobotics.sdk.common.Log.debug("Archive size: " + randomAccessFile.length() + " bytes"); + com.neuronrobotics.sdk.common.Log.debug("Items in archive: " + inArchive.getNumberOfItems()); for (int i = 0; i < inArchive.getNumberOfItems(); i++) { Boolean isFolder = (Boolean) inArchive.getProperty(i, PropID.IS_FOLDER); @@ -586,11 +702,11 @@ public static void extract7zArchive(String archivePath, String outputPath) { } } - System.out.println("Extraction completed successfully."); + com.neuronrobotics.sdk.common.Log.debug("Extraction completed successfully."); } catch (Exception e) { - System.err.println("Error extracting archive: " + e.getMessage()); - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error("Error extracting archive: " + e.getMessage()); + com.neuronrobotics.sdk.common.Log.error(e); } } @@ -606,12 +722,12 @@ private static void extractItem(IInArchive inArchive, int index, String outputPa } ExtractOperationResult result; - + downloadEvents.startDownload(); try (FileOutputStream fos = new FileOutputStream(outputFile)) { result = inArchive.extractSlow(index, new ISequentialOutStream() { public int write(byte[] data) throws SevenZipException { try { - System.out.println("Inflate 7z .. " + outputFile.getAbsolutePath()); + psudoSplash.onLogUpdate("Inflate 7z .. " + outputFile.getName(),null); fos.write(data); } catch (IOException e) { throw new SevenZipException("Error writing to file: " + e.getMessage()); @@ -620,11 +736,11 @@ public int write(byte[] data) throws SevenZipException { } }); } - + downloadEvents.finishDownload(); if (result == ExtractOperationResult.OK) { - System.out.println("Extracted: " + path); + com.neuronrobotics.sdk.common.Log.debug("Extracted: " + path); } else { - System.err.println("Error extracting " + path + ": " + result); + com.neuronrobotics.sdk.common.Log.error("Error extracting " + path + ": " + result); } } @@ -643,17 +759,17 @@ public int write(byte[] data) throws SevenZipException { * (entry.isDirectory()) { continue; } File outputFile = new File(outputDir, * entry.getName()); File parent = outputFile.getParentFile(); if * (!parent.exists()) { parent.mkdirs(); } - * System.out.println("Inflating 7z "+outputFile.getAbsolutePath()); try + * com.neuronrobotics.sdk.common.Log.error("Inflating 7z "+outputFile.getAbsolutePath()); try * (FileOutputStream out = new FileOutputStream(outputFile)) { byte[] content = * new byte[(int) entry.getSize()]; sevenZFile.read(content, 0, content.length); * out.write(content); } } - * System.out.println("Extraction completed successfully."); } catch + * com.neuronrobotics.sdk.common.Log.error("Extraction completed successfully."); } catch * (IOException e) { e.printStackTrace(System.out); } } * * } */ public static void unzip(File path, String dir) throws Exception { - System.out.println("Unzipping " + path.getName() + " into " + dir); + com.neuronrobotics.sdk.common.Log.debug("Unzipping " + path.getName() + " into " + dir); String fileBaseName = FilenameUtils.getBaseName(path.getName().toString()); Path destFolderPath = new File(dir).toPath(); @@ -674,17 +790,17 @@ public static void unzip(File path, String dir) throws Exception { String text = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)) .lines().collect(Collectors.joining("\n")); Path target = Paths.get(".", text); - System.out.println("Creating symlink " + entryPath + " with " + target); + com.neuronrobotics.sdk.common.Log.debug("Creating symlink " + entryPath + " with " + target); Files.createSymbolicLink(entryPath, target); continue; } } catch (Exception ex) { - ex.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(ex);; } try (OutputStream out = new FileOutputStream(entryPath.toFile())) { IOUtils.copy(in, out); - System.out.println("Inflating " + entryPath); + com.neuronrobotics.sdk.common.Log.debug("Inflating " + entryPath); } if (isExecutable(entry)) { @@ -717,12 +833,13 @@ public static void extractTarXz(String inputFile, String outputDir) throws IOExc Files.createDirectories(outDir); } - try (FileInputStream fis = new FileInputStream(inputFile); - XZCompressorInputStream xzIn = new XZCompressorInputStream(fis); - TarArchiveInputStream tarIn = new TarArchiveInputStream(xzIn)) { - + try { + FileInputStream fis = new FileInputStream(inputFile); + XZCompressorInputStream xzIn = new XZCompressorInputStream(fis); + TarArchiveInputStream tarIn = new TarArchiveInputStream(xzIn); TarArchiveEntry entry; - while ((entry = tarIn.getNextTarEntry()) != null) { + downloadEvents.startDownload(); + while ((entry = tarIn.getNextEntry()) != null) { Path outPath = outDir.resolve(entry.getName()); if (entry.isSymbolicLink()) { @@ -730,13 +847,13 @@ public static void extractTarXz(String inputFile, String outputDir) throws IOExc try { Files.createSymbolicLink(outPath, target); } catch (IOException | UnsupportedOperationException e) { - System.err.println("Failed to create symlink " + outPath + ". Copying target instead."); + com.neuronrobotics.sdk.common.Log.error("Failed to create symlink " + outPath + ". Copying target instead."); // Fallback: copy the target file instead Path resolvedTarget = outPath.getParent().resolve(target).normalize(); if (Files.exists(resolvedTarget)) { Files.copy(resolvedTarget, outPath); } else { - System.err.println("Symlink target does not exist: " + resolvedTarget); + com.neuronrobotics.sdk.common.Log.error("Symlink target does not exist: " + resolvedTarget); } } } else if (entry.isDirectory()) { @@ -746,7 +863,7 @@ public static void extractTarXz(String inputFile, String outputDir) throws IOExc try (OutputStream out = Files.newOutputStream(outPath)) { byte[] buffer = new byte[1024]; int len; - System.out.println("Inflate Tar XZ " + outPath.toAbsolutePath()); + psudoSplash.onLogUpdate("Inflate Tar XZ " + outPath.getFileName(),null); while ((len = tarIn.read(buffer)) != -1) { out.write(buffer, 0, len); } @@ -760,11 +877,17 @@ public static void extractTarXz(String inputFile, String outputDir) throws IOExc } } } + }catch(Throwable ex) { + downloadEvents.finishDownload(); + com.neuronrobotics.sdk.common.Log.error(ex);; + new File(inputFile).delete(); + throw ex; } + downloadEvents.finishDownload(); } public static void untar(File tarFile, String dir) throws Exception { - System.out.println("Untaring " + tarFile.getName() + " into " + dir); + com.neuronrobotics.sdk.common.Log.debug("Untaring " + tarFile.getName() + " into " + dir); File dest = new File(dir); dest.mkdir(); @@ -780,7 +903,7 @@ public static void untar(File tarFile, String dir) throws Exception { // tarIn is a TarArchiveInputStream while (tarEntry != null) {// create a file with the same name as the tarEntry File destPath = new File(dest.toString() + System.getProperty("file.separator") + tarEntry.getName()); - System.out.println("Inflating: " + destPath.getCanonicalPath()); + com.neuronrobotics.sdk.common.Log.debug("Inflating: " + destPath.getCanonicalPath()); if (tarEntry.isDirectory()) { destPath.mkdirs(); } else { @@ -803,7 +926,7 @@ public static void untar(File tarFile, String dir) throws Exception { } private static String bits(byte b) { - return String.format("%6s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0'); + return String.format(Locale.US,"%6s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0'); } public static boolean isWin() { @@ -853,15 +976,28 @@ public static String discoverKey() { } return key; } - - public static File download(String version, String downloadJsonURL, long sizeOfJson, String bindir, String filename, + /** + * + * @param version A string indicating version, this will be the folder name + * @param URL The direct URL of the download + * @param sizeOfFile The number of bytes in the file + * @param directoryInWhichFileIsStored The root directory into which this will all be downloaded + * @param filename The resulting filename + * @param downloadName User level name for asking about the download + * @return + * @throws MalformedURLException + * @throws IOException + * @throws FileNotFoundException + * @throws InterruptedException + */ + public static File download(String version, String URL, long sizeOfFile, String directoryInWhichFileIsStored, String filename, String downloadName) throws MalformedURLException, IOException, FileNotFoundException, InterruptedException { - URL url = new URL(downloadJsonURL); + URL url = new URL(URL); URLConnection connection = url.openConnection(); InputStream is = connection.getInputStream(); - ProcessInputStream pis = new ProcessInputStream(is, (int) sizeOfJson); + ProcessInputStream pis = new ProcessInputStream(is, (int) sizeOfFile); pis.addListener(new Listener() { long timeSinceePrint = System.currentTimeMillis(); @@ -869,7 +1005,7 @@ public static File download(String version, String downloadJsonURL, long sizeOfJ public void process(double percent) { if (System.currentTimeMillis() - timeSinceePrint > 1000) { timeSinceePrint = System.currentTimeMillis(); - System.out.println("Download "+filename+" percent " + (int) (percent * 100)); + psudoSplash.onLogUpdate((int) (percent * 100)+" % "+filename ,null); } // if(progress!=null) // Platform.runLater(() -> { @@ -882,30 +1018,48 @@ public void process(double percent) { if (!folder.exists() || !exe.exists()) { - if (approval.get(downloadName, downloadJsonURL)) { - System.out.println("Start Downloading " + filename); + if (approval.get(downloadName, URL)) { + com.neuronrobotics.sdk.common.Log.debug("Start Downloading " + filename); + com.neuronrobotics.sdk.common.Log.debug("From "+URL); } else { pis.close(); throw new RuntimeException("No Application insalled"); } - - folder.mkdirs(); - exe.createNewFile(); - byte dataBuffer[] = new byte[1024]; - int bytesRead; + downloadEvents.startDownload(); + rawFileDownload(pis, folder, exe); + com.neuronrobotics.sdk.common.Log.debug("Finished downloading " + filename); + psudoSplash.onLogUpdate((int) (1 * 100)+" % " +filename , null); + downloadEvents.finishDownload(); + } else { + com.neuronrobotics.sdk.common.Log.debug("Not downloading, it existst " + filename); + } + return exe; + } + private static void rawFileDownload(ProcessInputStream pis, File folder, File output) + throws IOException, FileNotFoundException { + folder.mkdirs(); + output.createNewFile(); + byte dataBuffer[] = new byte[1024 * 1000]; + int bytesRead; + File exe = File.createTempFile("tmp", output.getName()); + try { FileOutputStream fileOutputStream = new FileOutputStream(exe.getAbsoluteFile()); - while ((bytesRead = pis.read(dataBuffer, 0, 1024)) != -1) { + + while ((bytesRead = pis.read(dataBuffer, 0, dataBuffer.length)) != -1) { fileOutputStream.write(dataBuffer, 0, bytesRead); } fileOutputStream.close(); pis.close(); - System.out.println("Finished downloading " + filename); - System.out.println("Download percent " + (int) (1 * 100)); - } else { - System.out.println("Not downloading, it existst " + filename); + FileOutputStream out = new FileOutputStream(output.getAbsoluteFile()); + Files.copy(exe.toPath(), out); + out.flush(); + out.close(); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + output.delete(); } - return exe; + exe.delete(); } /** @@ -931,17 +1085,17 @@ public static String delim() { // try { // PasswordManager.login(); // } catch (IOException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); +// // Auto-generated catch block +// com.neuronrobotics.sdk.common.Log.error(e); // } // File f = getRunExecutable("eclipse",null); // String ws = EclipseExternalEditor.getEclipseWorkspace(); // if(f.exists()) { -// System.out.println("Executable retrived:\n"+f.getAbsolutePath()); +// com.neuronrobotics.sdk.common.Log.error("Executable retrived:\n"+f.getAbsolutePath()); // run(getEnvironment("eclipse"),null,f.getParentFile(), System.err,Arrays.asList(f.getAbsolutePath(),"-data", ws)); // } // else -// System.out.println("Failed to load file!\n"+f.getAbsolutePath()); +// com.neuronrobotics.sdk.common.Log.error("Failed to load file!\n"+f.getAbsolutePath()); // } public static IApprovalForDownload getApproval() { @@ -951,5 +1105,25 @@ public static IApprovalForDownload getApproval() { public static void setApproval(IApprovalForDownload approval) { DownloadManager.approval = approval; } + public static void addLogListener(GitLogProgressMonitor psudoSplash) { + DownloadManager.psudoSplash = psudoSplash; + } + public static IDownloadManagerEvents getDownloadEvents() { + return downloadEvents; + } + public static void setDownloadEvents(IDownloadManagerEvents de) { + if(downloadEvents!=null) + downloadEvents = de; + } + public static String getSTUDIO_INSTALL() { + return STUDIO_INSTALL; + } + public static void setSTUDIO_INSTALL(String sTUDIO_INSTALL) { + STUDIO_INSTALL = sTUDIO_INSTALL; + } + public static boolean isDownloadedAlready(String string) { + File f= DownloadManager.getRunExecutable(string, null,true); + return f.exists(); + } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/FXMLBowlerLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/FXMLBowlerLoader.java index d82b5d74b..eaf676cd5 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/FXMLBowlerLoader.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/FXMLBowlerLoader.java @@ -7,7 +7,7 @@ public class FXMLBowlerLoader implements IScriptingLanguage { @Override - public Object inlineScriptRun(File xml, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File xml, ArrayList args) throws Exception { javafx.fxml.FXMLLoader loader = new javafx.fxml.FXMLLoader(xml.toURI().toURL()); javafx.scene.layout.Pane newLoadedPane = loader.load(); // Create a tab @@ -18,18 +18,18 @@ public Object inlineScriptRun(File xml, ArrayList args) throws Exception } @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) throws Exception { throw new RuntimeException("This engine only supports files"); } @Override public String getShellType() { - // TODO Auto-generated method stub + // Auto-generated method stub return "fxml"; } @Override public boolean getIsTextFile() { - // TODO Auto-generated method stub + // Auto-generated method stub return true; } /** @@ -42,7 +42,7 @@ public String getDefaultContents() { } @Override public ArrayList getFileExtenetion() { - // TODO Auto-generated method stub + // Auto-generated method stub return new ArrayList<>(Arrays.asList("fxml","FXML","FxML")); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/FreecadLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/FreecadLoader.java index 04634b107..5764df013 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/FreecadLoader.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/FreecadLoader.java @@ -34,6 +34,7 @@ import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.ColinearPointsException; import eu.mihosoft.vrl.v3d.Cube; import eu.mihosoft.vrl.v3d.JavaFXInitializer; import eu.mihosoft.vrl.v3d.Polygon; @@ -48,17 +49,17 @@ public class FreecadLoader implements IScriptingLanguage { @Override - public Object inlineScriptRun(File code, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File code, ArrayList args) throws Exception { File stl = File.createTempFile(code.getName(), ".stl"); stl.deleteOnExit(); toSTLFile(code,stl); - CSG back = Vitamins.get(stl,true); + CSG back = Vitamins.get(db,stl,true); back.setColor(Color.BLUE); return back; } @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) throws Exception { throw new RuntimeException("Freecad file can not be instantiated from a string"); } @@ -97,7 +98,7 @@ public void getDefaultContents(File freecadGenFile) { args.add(freecadGenFile.getAbsolutePath()); legacySystemRun(null, freecadGenFile.getAbsoluteFile().getParentFile(), System.out, args); }catch(Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } } @@ -105,7 +106,7 @@ public static void addCSGToFreeCAD(File freecadModel,CSG incoming) throws IOExce addCSGToFreeCAD(freecadModel,incoming,incoming.getSlicePlanes()); } public static void addCSGToFreeCAD(File freecadModel,CSG toSlice, List slicePlanes) throws IOException { - File tmp = BlenderLoader.getTmpSTL(toSlice); + File tmp =getTmpSTL(toSlice); String name = toSlice.getName(); if(name.length()==0) { name="CSG_TO_FREECAD"; @@ -113,45 +114,26 @@ public static void addCSGToFreeCAD(File freecadModel,CSG toSlice, List polygons = Slice.slice(toSlice, pose, 0); - String svgName = toSlice.getName(); - if(svgName.length()==0) - svgName="SVG_EXPORT"; - svgName+="_"+planes; - File svg = File.createTempFile(svgName, ".svg"); - SVGExporter.export(polygons, svg, false); - addSVGToFreeCAD(freecadModel,svg,pose,svgName,name+"_body"); - planes++; + List polygons; + try { + polygons = Slice.slice(toSlice, pose, 0); + String svgName = toSlice.getName(); + if(svgName.length()==0) + svgName="SVG_EXPORT"; + svgName+="_"+planes; + File svg = File.createTempFile(svgName, ".svg"); + SVGExporter.export(polygons, svg, false); + addSVGToFreeCAD(freecadModel,svg,pose,svgName,name+"_body"); + planes++; + } catch (ColinearPointsException e) { + // TODO Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + } addSTLToFreecad(freecadModel,tmp,name); } - public static File simplifySVG(File incoming, double threshhold) { - try { - File inkscape = DownloadManager.getConfigExecutable("inkscape", null); - File svg = File.createTempFile(incoming.getName(), ".svg"); - List args = Arrays.asList( - inkscape.getAbsolutePath(), - "--actions", - "\"select-all:all;path-simplify:threshold=" + threshhold+ ";;export-overwrite;export-do;quit-inkscape\"", - incoming.getAbsolutePath() - ); - legacySystemRun(null, inkscape.getAbsoluteFile().getParentFile(), System.out, args); - args = Arrays.asList( - inkscape.getAbsolutePath(), - "--export-plain-svg", - "--export-type=svg", - "--vacuum-defs", - "--export-filename="+svg.getAbsolutePath(), - incoming.getAbsolutePath() - ); - legacySystemRun(null, inkscape.getAbsoluteFile().getParentFile(), System.out, args); - return svg; - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return incoming; - } + public static void addSVGToFreeCAD(File freecadModel,File SVG, Transform pose, String name, String bodyName) { TransformNR nr=TransformFactory.csgToNR(pose); RotationNR r=nr.getRotation(); @@ -178,7 +160,7 @@ public static void addSVGToFreeCAD(File freecadModel,File SVG, Transform pose, S args.add(bodyName); legacySystemRun(null, export.getAbsoluteFile().getParentFile(), System.out, args); }catch(Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } } public static void addSTLToFreecad(File freecadModel, File stlToAdd,String meshName) { @@ -198,7 +180,7 @@ public static void addSTLToFreecad(File freecadModel, File stlToAdd,String meshN args.add(meshName); legacySystemRun(null, export.getAbsoluteFile().getParentFile(), System.out, args); }catch(Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } } public static void toSTLFile(File freecadModel,File stlout) throws InvalidRemoteException, TransportException, GitAPIException, IOException, InterruptedException { @@ -218,7 +200,7 @@ public static void toSTLFile(File freecadModel,File stlout) throws InvalidRemote legacySystemRun(null, export.getAbsoluteFile().getParentFile(), System.out, args); }catch(Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } } public static void open(File freecadModel) { @@ -239,7 +221,7 @@ public static void open(File freecadModel) { else legacySystemRun(null, freecadModel.getAbsoluteFile().getParentFile(), System.out, args); }catch(Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } } /** @@ -261,7 +243,7 @@ public static void main(String[] args) throws InvalidRemoteException, TransportE File stlToImport =ScriptingEngine.fileFromGit( "https://github.com/NeuronRobotics/NASACurisoity.git" , "STL/upper-arm.STL"); - CSG toSlice = Vitamins.get(stlToImport,true); + CSG toSlice = Vitamins.get(null,stlToImport,true); // toSlice=toSlice.union( // new Cube(20).toCSG() // .toXMin() @@ -289,7 +271,7 @@ private static String readAll(Reader rd) throws IOException { return sb.toString(); } public static void update(Map vm) throws MalformedURLException, IOException { - String url= "https://api.github.com/repos/FreeCAD/FreeCAD-Bundle/releases/tags/weekly-builds"; + String url= "https://api.github.com/repos/FreeCAD/FreeCAD-Bundle/releases/tags/1.0rc2"; InputStream is = new URL(url).openStream(); String type = vm.get("type").toString(); @@ -331,7 +313,7 @@ public static void update(Map vm) throws MalformedURLException, continue; } String name = assetName.replace("."+type, ""); - System.out.println("Updating Freecad assets to "+name); + com.neuronrobotics.sdk.common.Log.error("Updating Freecad assets to "+name); vm.put("name",name); if(isMac()) continue; diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GitLogProgressMonitor.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GitLogProgressMonitor.java index 3315971b7..7e9a42e98 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GitLogProgressMonitor.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GitLogProgressMonitor.java @@ -1,5 +1,5 @@ package com.neuronrobotics.bowlerstudio.scripting; public interface GitLogProgressMonitor { - public abstract void onUpdate(String update, Exception e); + public abstract void onLogUpdate(String update, Exception e); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GitTimeoutThread.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GitTimeoutThread.java deleted file mode 100644 index 17d41fb17..000000000 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GitTimeoutThread.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.neuronrobotics.bowlerstudio.scripting; - -import org.eclipse.jgit.api.Git; - -import com.neuronrobotics.bowlerstudio.IssueReportingExceptionHandler; - -public class GitTimeoutThread extends Thread { - Git git; - String ref; - private RuntimeException ex; - long startTime=0; - public GitTimeoutThread(Git g) { - git=g; - ref = git.getRepository().getConfig().getString("remote", "origin", "url"); - setException(new RuntimeException( - "Git opened here, timeout on close!!\nWhen Done with the git object, Call:\n ScriptingEngine.closeGit(git);\n" - + ref + "\n")); - } - public void run() { - resetTimer(); - try { - while((startTime+(1000*120))>System.currentTimeMillis()) - Thread.sleep(1000); - git.close(); - ScriptingEngine.gitOpenTimeout.remove(git); - new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), getException()); - } catch (InterruptedException e) { - // exited clean - } - } - public void resetTimer() { - startTime=System.currentTimeMillis(); - } - public RuntimeException getException() { - return ex; - } - private void setException(RuntimeException ex) { - this.ex = ex; - } -} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GroovyHelper.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GroovyHelper.java index 18fa67f60..ca5465934 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GroovyHelper.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/GroovyHelper.java @@ -6,9 +6,12 @@ import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.codehaus.groovy.control.CompilationFailedException; import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.control.customizers.*; @@ -16,54 +19,51 @@ import com.neuronrobotics.sdk.common.BowlerAbstractDevice; import com.neuronrobotics.sdk.common.DeviceManager; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; + public class GroovyHelper implements IScriptingLanguage, IScriptingLanguageDebugger { + private Object inline(String code, ArrayList args, CSGDatabaseInstance db2) throws Exception { + CompilerConfiguration cc = new CompilerConfiguration(); + cc.addCompilationCustomizers(new ImportCustomizer().addStarImports(ScriptingEngine.getImports()) + + ); + + Binding binding = new Binding(); + + binding.setVariable("args", args); + binding.setVariable("csgdb", db2); + GroovyShell shell = new GroovyShell(GroovyHelper.class.getClassLoader(), binding, cc); + if(!code.contains("csgdb")) { + //Vitamins.get( + code=code.replace("Vitamins.get(", "Vitamins.get(csgdb,"); + + code=code.replace("CaDoodleVitamin.", "new CaDoodleVitamin(csgdb)."); + code=code.replace("StringParameter(", "StringParameter(csgdb,"); + code=code.replace("LengthParameter(", "LengthParameter(csgdb,"); + code=code.replace("setParameter(", "setParameter(csgdb,"); + + code=code.replace("import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase", ""); + code=code.replace("CSGDatabase", "csgdb"); + + code=code.replace("inlineGistScriptRun(", "inlineGistScriptRun(csgdb,"); + code=code.replace("inlineFileScriptRun(", "inlineFileScriptRun(csgdb,"); + code=code.replace("inlineScriptRun(", "inlineScriptRun(csgdb,"); + code=code.replace("inlineScriptStringRun(", "inlineScriptStringRun(csgdb,"); + code=code.replace("gitScriptRun(", "gitScriptRun(csgdb,"); + } + + Script script = shell.parse(code); + return script.run(); + + } + + @Override + public String getShellType() { + return "Groovy"; + } - private Object inline(Object code, ArrayList args) throws Exception { - CompilerConfiguration cc = new CompilerConfiguration(); - cc.addCompilationCustomizers(new ImportCustomizer() - .addStarImports(ScriptingEngine.getImports()) - - ); - - Binding binding = new Binding(); -// for (String pm : DeviceManager.listConnectedDevice()) { -// BowlerAbstractDevice bad = DeviceManager.getSpecificDevice(null, pm); -// try { -// // groovy needs the objects cas to thier actual type befor -// // passing into the scipt -// -// binding.setVariable(bad.getScriptingName(), -// Class.forName(bad.getClass().getName()) -// .cast(bad)); -// } catch (Throwable e) { -// //throw e; -// } -//// System.err.println("Device " + bad.getScriptingName() + " is " -//// + bad); -// } - binding.setVariable("args", args); - - GroovyShell shell = new GroovyShell(GroovyHelper.class - .getClassLoader(), binding, cc); - //System.out.println(code + "\n\nStart\n\n"); - Script script; - if (String.class.isInstance(code)) { - script = shell.parse((String) code); - } else if (File.class.isInstance(code)) { - script = shell.parse((File) code); - } else { - return null; - } - return script.run(); - - } - - - @Override - public String getShellType() { - return "Groovy"; - } /** * Get the contents of an empty file * @@ -73,41 +73,43 @@ public String getDefaultContents() { return "// code here"; } - @Override - public Object inlineScriptRun(File code, ArrayList args) throws Exception { - return inline(code, args); - } - - - @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { - return inline(code, args); - } - - - @Override - public boolean getIsTextFile() { - // TODO Auto-generated method stub - return true; - } - - @Override - public ArrayList getFileExtenetion() { - // TODO Auto-generated method stub - return new ArrayList<>(Arrays.asList( "groovy","java")); - } - - @Override - public IDebugScriptRunner compileDebug(File f) { - // TODO Auto-generated method stub - return new IDebugScriptRunner() { - - @Override - public String[] step() { - // TODO Auto-generated method stub - return new String[]{"fileame.groovy", "345"}; - } - }; - } + @Override + public Object inlineScriptRun(CSGDatabaseInstance db, File code, ArrayList args) throws Exception { + String jsonString = null; + InputStream inPut = null; + inPut = FileUtils.openInputStream(code); + jsonString = IOUtils.toString(inPut); + return inline(jsonString, args, db); + } + + @Override + public Object inlineScriptRun(CSGDatabaseInstance db, String code, ArrayList args) throws Exception { + return inline(code, args, db); + } + + @Override + public boolean getIsTextFile() { + // Auto-generated method stub + return true; + } + + @Override + public ArrayList getFileExtenetion() { + // Auto-generated method stub + return new ArrayList<>(Arrays.asList("groovy", "java")); + } + + @Override + public IDebugScriptRunner compileDebug(File f) { + // Auto-generated method stub + return new IDebugScriptRunner() { + + @Override + public String[] step() { + // Auto-generated method stub + return new String[] { "fileame.groovy", "345" }; + } + }; + } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IApprovalForDownload.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IApprovalForDownload.java index dac19f0af..9a9bd120f 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IApprovalForDownload.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IApprovalForDownload.java @@ -2,4 +2,6 @@ public interface IApprovalForDownload { boolean get(String name, String url); + void onInstallFail(String url); + void notifyOfFailure(String name); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IDownloadManagerEvents.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IDownloadManagerEvents.java new file mode 100644 index 000000000..eef4d26c8 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IDownloadManagerEvents.java @@ -0,0 +1,6 @@ +package com.neuronrobotics.bowlerstudio.scripting; + +public interface IDownloadManagerEvents { + public void startDownload(); + public void finishDownload(); +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IExternalEditor.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IExternalEditor.java index 3f2e7f5e1..5f71675f4 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IExternalEditor.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IExternalEditor.java @@ -31,7 +31,7 @@ default boolean isSupportedByExtention(File file) { return false; } - void launch(File file, Button advanced); + void launch(File file, Button advanced,Runnable onExit); String nameOfEditor(); diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IGitAccessor.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IGitAccessor.java new file mode 100644 index 000000000..12af69b58 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IGitAccessor.java @@ -0,0 +1,7 @@ +package com.neuronrobotics.bowlerstudio.scripting; + +import org.eclipse.jgit.api.Git; + +public interface IGitAccessor { + public void run(Git git) throws Exception; +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IScriptingLanguage.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IScriptingLanguage.java index 7a2797ace..e356eed5b 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IScriptingLanguage.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/IScriptingLanguage.java @@ -11,6 +11,7 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.util.io.AutoLFInputStream.IsBinaryException; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import javafx.scene.Group; /** @@ -23,7 +24,7 @@ * @author hephaestus */ public interface IScriptingLanguage { - + /** * This interface is for adding additional language support. * @@ -31,7 +32,7 @@ public interface IScriptingLanguage { * @param args the incoming arguments as a list of objects * @return the objects returned form the code that ran */ - public abstract Object inlineScriptRun(File code, ArrayList args) throws Exception; + public abstract Object inlineScriptRun(CSGDatabaseInstance db,File code, ArrayList args) throws Exception; /** * This interface is for adding additional language support. @@ -40,7 +41,7 @@ public interface IScriptingLanguage { * @param args the incoming arguments as a list of objects * @return the objects returned form the code that ran */ - public abstract Object inlineScriptRun(String code, ArrayList args) throws Exception; + public abstract Object inlineScriptRun(CSGDatabaseInstance db,String code, ArrayList args) throws Exception; /** * Returns the HashMap key for this language @@ -86,7 +87,7 @@ default void getDefaultContents(File source) { out.close(); // don't swallow close Exception if copy completes // normally } catch (Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } finally { try { out.close(); @@ -104,7 +105,7 @@ default void getDefaultContents(File source) { * @return */ default String getDefaultContents() { - // TODO Auto-generated method stub + // Auto-generated method stub throw new RuntimeException("This shell " + getShellType() + " has binary files "); } @@ -118,8 +119,8 @@ default void getDefaultContents(String gitURL, String fileSlug) { try { getDefaultContents(ScriptingEngine.fileFromGit(gitURL, fileSlug)); } catch (GitAPIException | IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/JsonRunner.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/JsonRunner.java index 7bccb9573..c4bd16366 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/JsonRunner.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/JsonRunner.java @@ -24,16 +24,16 @@ public class JsonRunner implements IScriptingLanguage { private static Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create(); @Override - public Object inlineScriptRun(File code, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File code, ArrayList args) throws Exception { String jsonString = null; InputStream inPut = null; inPut = FileUtils.openInputStream(code); jsonString = IOUtils.toString(inPut); - return inlineScriptRun(jsonString, args); + return inlineScriptRun( db,jsonString, args); } @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) throws Exception { // perfoem the GSON parse HashMap> database = gson.fromJson(code, TT_mapStringString); @@ -61,7 +61,7 @@ public String getDefaultContents() { @Override public ArrayList getFileExtenetion() { - // TODO Auto-generated method stub + // Auto-generated method stub return new ArrayList<>(Arrays.asList("json")); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/JythonHelper.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/JythonHelper.java index 03d03a66b..a338e7b06 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/JythonHelper.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/JythonHelper.java @@ -24,7 +24,7 @@ public class JythonHelper implements IScriptingLanguage { @Override - public Object inlineScriptRun(String code, ArrayList args) { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) { Properties props = new Properties(); PythonInterpreter.initialize(System.getProperties(), props, new String[]{""}); @@ -42,10 +42,10 @@ public Object inlineScriptRun(String code, ArrayList args) { // Class.forName(bad.getClass().getName()) // .cast(bad)); // } catch (ClassNotFoundException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); +// // Auto-generated catch block +// com.neuronrobotics.sdk.common.Log.error(e); // } -// System.err.println("Device " + bad.getScriptingName() + " is " +// com.neuronrobotics.sdk.common.Log.error("Device " + bad.getScriptingName() + " is " // + bad); // } interp.set("args", args); @@ -57,17 +57,17 @@ public Object inlineScriptRun(String code, ArrayList args) { try { results.add(interp.get("csg", CSG.class)); } catch (Exception e) { - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(e); } try { results.add(interp.get("tab", Tab.class)); } catch (Exception e) { - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(e); } try { results.add(interp.get("device", BowlerAbstractDevice.class)); } catch (Exception e) { - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(e); } Log.debug("Jython return = " + results); @@ -75,15 +75,15 @@ public Object inlineScriptRun(String code, ArrayList args) { } @Override - public Object inlineScriptRun(File code, ArrayList args) { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File code, ArrayList args) { byte[] bytes; try { bytes = Files.readAllBytes(code.toPath()); String s = new String(bytes, "UTF-8"); - return inlineScriptRun(s, args); + return inlineScriptRun( db,s, args); } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e1); } return null; } @@ -103,14 +103,14 @@ public String getDefaultContents() { } @Override public boolean getIsTextFile() { - // TODO Auto-generated method stub + // Auto-generated method stub return true; } @Override public ArrayList getFileExtenetion() { - // TODO Auto-generated method stub - return new ArrayList<>(Arrays.asList("py", "jy")); + // Auto-generated method stub + return new ArrayList<>(Arrays.asList( "jy")); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ObjLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ObjLoader.java new file mode 100644 index 000000000..dc6158918 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ObjLoader.java @@ -0,0 +1,47 @@ +package com.neuronrobotics.bowlerstudio.scripting; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; + +import com.neuronrobotics.bowlerstudio.vitamins.Vitamins; + +import eu.mihosoft.vrl.v3d.CSG; + +public class ObjLoader implements IScriptingLanguage { + + @Override + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File code, ArrayList args) throws Exception { + CSG sllLoaded = Vitamins.get(db,code); + return sllLoaded; + } + + @Override + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) throws Exception { + throw new RuntimeException("This engine only supports files"); + } + + @Override + public String getShellType() { + return "obj"; + } + @Override + public boolean getIsTextFile() { + // Auto-generated method stub + return false; + } + /** + * Get the contents of an empty file + * + * @return + */ + public String getDefaultContents() { + return null; + } + @Override + public ArrayList getFileExtenetion() { + // Auto-generated method stub + return new ArrayList<>(Arrays.asList("obj","OBJ","Obj")); + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/OpenSCADLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/OpenSCADLoader.java new file mode 100644 index 000000000..e16948c24 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/OpenSCADLoader.java @@ -0,0 +1,102 @@ +package com.neuronrobotics.bowlerstudio.scripting; +import static com.neuronrobotics.bowlerstudio.scripting.DownloadManager.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; + +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidRemoteException; +import org.eclipse.jgit.api.errors.TransportException; + +import com.neuronrobotics.bowlerstudio.vitamins.Vitamins; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.FileUtil; +import eu.mihosoft.vrl.v3d.STL; +import javafx.scene.paint.Color; + +public class OpenSCADLoader implements IScriptingLanguage { + + @Override + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File code, ArrayList args) throws Exception { + File stl = File.createTempFile(sanitizeString(code.getName()), ".stl"); + stl.deleteOnExit(); + HashMap params=new HashMap(); + if(args!=null) { + Object o = args.get(0); + if(HashMap.class.isInstance(o)) { + params=(HashMap)o; + } + } + + toSTLFile(code,stl,params); + CSG back = Vitamins.get(db,stl,true); + back.setColor(Color.YELLOW); + return back; + } + + @Override + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) throws Exception { + throw new RuntimeException("Blender can not run from a string"); + } + + @Override + public String getShellType() { + return "OpenSCAD"; + } + + @Override + public ArrayList getFileExtenetion() { + ArrayList ext = new ArrayList<>(); + ext.add("scad"); + ext.add("SCad"); + + return ext; + } + + + + + public static void toSTLFile(File openscadfile,File stlout, HashMap params) throws InvalidRemoteException, TransportException, GitAPIException, IOException, InterruptedException { + File exe = getConfigExecutable("openscad", null); + if(params==null) + params=new HashMap(); + ArrayList args = new ArrayList<>(); + + if(stlout.exists()) + stlout.delete(); + args.add(exe.getAbsolutePath()); + for(String key:params.keySet()) { + args.add("-D"); + args.add(key+"="+params.get(key)); + } + args.add("-o"); + args.add(stlout.getAbsolutePath()); + args.add(openscadfile.getAbsolutePath()); + legacySystemRun(null, stlout.getAbsoluteFile().getParentFile(), System.out, args); + } + @Override + public String getDefaultContents() { + return "cube([30, 20, 10]);"; + } + + @Override + public boolean getIsTextFile() { + return true; + } + + public static void main(String[] args) throws InvalidRemoteException, TransportException, GitAPIException, IOException, InterruptedException { + OpenSCADLoader loader = new OpenSCADLoader(); + + // create test file + File testblend = new File("test.scad"); + if(!testblend.exists()) + loader.getDefaultContents(testblend); + HashMap params = new HashMap(); + toSTLFile(testblend, new File("testscad.stl"),params); + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/RobotHelper.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/RobotHelper.java index a9442065c..40578f60a 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/RobotHelper.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/RobotHelper.java @@ -10,6 +10,9 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidRemoteException; +import org.eclipse.jgit.api.errors.TransportException; import com.neuronrobotics.bowlerstudio.creature.MobileBaseLoader; import com.neuronrobotics.sdk.addons.kinematics.DHLink; @@ -20,7 +23,28 @@ public class RobotHelper implements IScriptingLanguage { @Override - public Object inlineScriptRun(File code, ArrayList args) { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File code, ArrayList args) { + return fileToRobot(code); + } + public static MobileBase fileToRobot(String url,String file) { + try { + return fileToRobot(ScriptingEngine.fileFromGit(url, file)) ; + } catch (InvalidRemoteException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (TransportException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (GitAPIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + public static MobileBase fileToRobot(File code) { byte[] bytes; try { bytes = Files.readAllBytes(code.toPath()); @@ -31,27 +55,27 @@ public Object inlineScriptRun(File code, ArrayList args) { mb.setGitSelfSource(ScriptingEngine.findGitTagFromFile(code)); return MobileBaseLoader.get(mb).getBase(); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); return null; } } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e1); } - // System.out.println("Clojure returned of type="+ret.getClass()+" value="+ret); + // com.neuronrobotics.sdk.common.Log.error("Clojure returned of type="+ret.getClass()+" value="+ret); return null; } @Override - public Object inlineScriptRun(String code, ArrayList args) { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) { MobileBase mb = null; try { mb = new MobileBase(IOUtils.toInputStream(code, "UTF-8")); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); return null; } @@ -65,7 +89,7 @@ public String getShellType() { @Override public boolean getIsTextFile() { - // TODO Auto-generated method stub + // Auto-generated method stub return true; } @@ -122,7 +146,7 @@ public void getDefaultContents(String gitURL, String slug) { out.close(); // don't swallow close Exception if copy completes // normally } catch(Throwable t){ - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); }finally { try { out.close(); @@ -134,7 +158,7 @@ public void getDefaultContents(String gitURL, String slug) { @Override public ArrayList getFileExtenetion() { - // TODO Auto-generated method stub + // Auto-generated method stub return new ArrayList<>(Arrays.asList("xml")); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ScriptingEngine.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ScriptingEngine.java index 8465cfece..680067f12 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ScriptingEngine.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/ScriptingEngine.java @@ -6,7 +6,10 @@ import com.neuronrobotics.sdk.util.ThreadUtil; import com.neuronrobotics.video.OSUtil; +import eu.mihosoft.vrl.v3d.CSG; import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; + import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.eclipse.jgit.api.CloneCommand; @@ -63,6 +66,7 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.text.DecimalFormat; import java.util.ArrayList; @@ -89,9 +93,50 @@ public class ScriptingEngine {// this subclasses boarder pane for the widgets // sake, because multiple inheritance is TOO // hard for java... private static final int TIME_TO_WAIT_BETWEEN_GIT_PULL = 100000; + /** * */ + public static void flatten(ArrayList flat, Object o) { + if (CSG.class.isInstance(o)) + flat.add((CSG) o); + if (List.class.isInstance(o)) { + for (Object ob : (List) o) { + flatten(flat, ob); + } + } + + } + + public static void flatenInterna(CSGDatabaseInstance instance,Object o, Class type, ArrayList flattened) { + if (type.isInstance(o)) + flattened.add((T) o); + else if (List.class.isInstance(o)) { + for (Object ob : (List) o) { + flatenInterna(instance,ob, type, flattened); + } + } else if (Map.class.isInstance(o)) { + Map m = (Map) o; + for (Object key : m.keySet()) { + flatenInterna(instance,m.get(key), type, flattened); + flatenInterna(instance,key, type, flattened); + } + } + } + + public static List flaten(CSGDatabaseInstance instance,String git, String file, Class type, ArrayList args) throws Exception { + ArrayList flattened = new ArrayList(); + Object o = gitScriptRun(instance,git, file, args); + flatenInterna(instance,o, type, flattened); + return flattened; + } + + public static List flaten(CSGDatabaseInstance instance,File f, Class type, ArrayList args) throws Exception { + ArrayList flattened = new ArrayList(); + Object o = inlineFileScriptRun(instance,f, args); + flatenInterna(instance,o, type, flattened); + return flattened; + } private static final ArrayList logListeners = new ArrayList<>(); @@ -110,9 +155,8 @@ public class ScriptingEngine {// this subclasses boarder pane for the widgets "com.neuronrobotics.bowlerstudio.scripting", "com.neuronrobotics.bowlerstudio.tabs", "com.neuronrobotics.bowlerstudio.physics", "com.neuronrobotics.bowlerstudio.physics", "com.neuronrobotics.bowlerstudio.vitamins", "com.neuronrobotics.bowlerstudio.creature", - "com.neuronrobotics.bowlerstudio.threed","com.neuronrobotics.sdk.util.ThreadUtil", - "eu.mihosoft.vrl.v3d.Transform", - "com.neuronrobotics.bowlerstudio.vitamins.Vitamins" }; + "com.neuronrobotics.bowlerstudio.threed", "com.neuronrobotics.sdk.util.ThreadUtil", + "eu.mihosoft.vrl.v3d.Transform", "com.neuronrobotics.bowlerstudio.vitamins.Vitamins" }; private static HashMap filesRun = new HashMap<>(); @@ -131,11 +175,16 @@ public class ScriptingEngine {// this subclasses boarder pane for the widgets private static HashMap> onCommitEventListeners = new HashMap<>(); // static IssueReportingExceptionHandler exp = new // IssueReportingExceptionHandler(); - static HashMap gitOpenTimeout = new HashMap<>(); + // static HashMap gitOpenTimeout = new HashMap<>(); + static HashMap open = new HashMap(); + + private static String delim; + + private static String appName = "BowlerLauncher"; static { PasswordManager.hasNetwork(); - + addScriptingLanguage(new StlLoader()); addScriptingLanguage(new ClojureHelper()); addScriptingLanguage(new GroovyHelper()); addScriptingLanguage(new JythonHelper()); @@ -149,11 +198,14 @@ public class ScriptingEngine {// this subclasses boarder pane for the widgets addScriptingLanguage(new BlenderLoader()); addScriptingLanguage(new FreecadLoader()); addScriptingLanguage(new FXMLBowlerLoader()); + addScriptingLanguage(new OpenSCADLoader()); + addScriptingLanguage(new CaDoodleLoader()); + addScriptingLanguage(new ObjLoader()); } public static void setWorkspace(File file) { workspace = file; - System.err.println("Workspace: " + workspace.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.debug("Workspace: " + workspace.getAbsolutePath()); if (!workspace.exists()) { workspace.mkdir(); } @@ -189,7 +241,7 @@ public static void clearLogListener() { logListeners.clear(); } - private static Git cloneRepoLocalSelectAuth(String remoteURI, File dir, boolean useSSH) + private static void cloneRepoLocalSelectAuth(String remoteURI, File dir, boolean useSSH, IGitAccessor accessor) throws InvalidRemoteException, TransportException, GitAPIException { CloneCommand setURI = Git.cloneRepository().setURI(remoteURI); @@ -203,12 +255,18 @@ private static Git cloneRepoLocalSelectAuth(String remoteURI, File dir, boolean } Git git = setURI.call(); - gitOpenTimeout.put(git, makeTimeoutThread(git)); - return git; + open.put(dir.getAbsolutePath(), git); + try { + accessor.run(git); + } catch (Exception e) { + // TODO Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + gitclose(git); } /** - * CLoe git and start a timeout timer + * Clone git and start a timeout timer * * @param remoteURI * @param branch @@ -218,21 +276,22 @@ private static Git cloneRepoLocalSelectAuth(String remoteURI, File dir, boolean * @throws TransportException * @throws GitAPIException */ - private static Git cloneRepoLocal(String remoteURI, File dir) + private static void cloneRepoLocal(String remoteURI, File dir, IGitAccessor accessor) throws InvalidRemoteException, TransportException, GitAPIException { boolean startsWith = remoteURI.startsWith("git@"); - try { - return cloneRepoLocalSelectAuth(remoteURI, dir, startsWith); + cloneRepoLocalSelectAuth(remoteURI, dir, startsWith, accessor); } catch (org.eclipse.jgit.api.errors.JGitInternalException ex) { if (ex.getMessage().contains("already exists and is not an empty directory")) { deleteRepo(remoteURI); - return cloneRepoLocal(remoteURI, dir); + cloneRepoLocal(remoteURI, dir, accessor); + return; } throw ex; } catch (org.eclipse.jgit.api.errors.TransportException ex) { if (ex.getMessage().contains("Auth fail") && !startsWith) { - return cloneRepoLocalSelectAuth(remoteURI, dir, true); + cloneRepoLocalSelectAuth(remoteURI, dir, true, accessor); + return; } throw ex; } @@ -251,14 +310,14 @@ private static ProgressMonitor getProgressMoniter(String type, String remoteURI) @Override public void update(int completed) { - for (Iterator iterator = gitOpenTimeout.keySet().iterator(); iterator.hasNext();) { - Git g = iterator.next(); - GitTimeoutThread t = gitOpenTimeout.get(g); - if (t.ref.toLowerCase().contentEquals(remoteURI.toLowerCase())) { - t.resetTimer(); - break; - } - } +// for (Iterator iterator = gitOpenTimeout.keySet().iterator(); iterator.hasNext();) { +// Git g = iterator.next(); +// GitTimeoutThread t = gitOpenTimeout.get(g); +// if (t.ref.toLowerCase().contentEquals(remoteURI.toLowerCase())) { +// t.resetTimer(); +// break; +// } +// } sum += completed; DecimalFormat df = new DecimalFormat("###.#"); @@ -270,13 +329,14 @@ public void update(int completed) { } String str = format + "% " + stage + " " + reponame + " " + tasks + " of task " + type; if (timeofLastUpdate + 500 < System.currentTimeMillis()) { - if(printProgress)System.out.println(str); + if (printProgress) + com.neuronrobotics.sdk.common.Log.debug(str); timeofLastUpdate = System.currentTimeMillis(); } - // System.err.println(str); + // com.neuronrobotics.sdk.common.Log.error(str); for (GitLogProgressMonitor l : logListeners) { - l.onUpdate(str, e); + l.onLogUpdate(str, e); } } @@ -293,16 +353,18 @@ public boolean isCancelled() { @Override public void endTask() { String string = "100% " + stage + " " + reponame + " " + type; - if(printProgress)System.out.println(string); + if (printProgress) + com.neuronrobotics.sdk.common.Log.debug(string); for (GitLogProgressMonitor l : logListeners) { - l.onUpdate(string, e); + l.onLogUpdate(string, e); } } @Override public void beginTask(String title, int totalWork) { stage = title; - // System.out.println("Setting totalWork to "+totalWork+" for stage "+stage); + // com.neuronrobotics.sdk.common.Log.error("Setting totalWork to "+totalWork+" + // for stage "+stage); total = totalWork; sum = 0; tasks += 1; @@ -317,29 +379,26 @@ public void beginTask(String title, int totalWork) { * @param url * @return */ - public static Git openGit(String url) { + public static void openGit(String url, IGitAccessor accessor) { Repository localRepo; try { localRepo = getRepository(url); - return openGit(localRepo); + openGit(localRepo, accessor); + return; } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } throw new RuntimeException("IOException making repo"); } - public static boolean isUrlAlreadyOpen(String URL) { + public static boolean isUrlAlreadyOpen(File URL) { if (URL == null) return false; - Object[] keySet; - synchronized(gitOpenTimeout) { - keySet = gitOpenTimeout.keySet().toArray(); - } - for (int i = 0; i < keySet.length; i++) { - Git g = (Git)keySet[i]; - GitTimeoutThread t = gitOpenTimeout.get(g); - if (t.ref.toLowerCase().contentEquals(URL.toLowerCase())) { + Set keySet = open.keySet(); + + for (String s : keySet) { + if (s.toLowerCase().contentEquals(URL.getAbsolutePath())) { // t.getException().printStackTrace(System.err); return true; } @@ -354,41 +413,42 @@ public static boolean isUrlAlreadyOpen(String URL) { * @return */ - public static Git openGit(Repository localRepo) { - - Object[] keySet; - synchronized(gitOpenTimeout) { - keySet = gitOpenTimeout.keySet().toArray(); - } - for (int j = 0; j < keySet.length; j++) { - Object gO = keySet[j]; - Git g=(Git)gO; - if (g.getRepository().getDirectory().getAbsolutePath() - .contentEquals(localRepo.getDirectory().getAbsolutePath())) { - GitTimeoutThread t = gitOpenTimeout.get(g); - int i = 0; - while (gitOpenTimeout.containsKey(g)) { - - System.out.println( - "Git is locked by other process, blocking " + localRepo.getDirectory().getAbsolutePath()); - System.out.println("Git locked " + t.ref); - if (i > 3) { - t.getException().printStackTrace(System.out); - System.out.println("Blocking process: "); - - new Exception().printStackTrace(System.out); + public static void openGit(Repository localRepo, IGitAccessor accessor) { + Git git = null; + boolean alreadyOpen = false; + try { + String absolutePath = localRepo.getDirectory().getAbsolutePath(); + for (String s : open.keySet()) { + Git g = open.get(s); + if (g != null) + if (g.getRepository().getDirectory().getAbsolutePath().contentEquals(absolutePath)) { + git = g; + alreadyOpen = true; + break; } - i++; - ThreadUtil.wait(1000); + } + if (!alreadyOpen) { + git = new Git(localRepo); + open.put(absolutePath, git); + } + if (accessor != null) { + try { + accessor.run(git); + } catch (Throwable t) { + // new IssueReportingExceptionHandler().except(t); + throw new RuntimeException(t); } - break; } + if (!alreadyOpen) + gitclose(git); + } catch (Throwable t) { + // new IssueReportingExceptionHandler().except(t); + if (!alreadyOpen) + if (git != null) { + gitclose(git); + } + throw new RuntimeException(t); } - - Git git = new Git(localRepo); - - gitOpenTimeout.put(git, makeTimeoutThread(git)); - return git; } /** @@ -396,35 +456,14 @@ public static Git openGit(Repository localRepo) { * * @param git */ - public static void closeGit(Git git) { + private static void gitclose(Git git) { if (git == null) return; - if (gitOpenTimeout.containsKey(git)) { - Thread thread = gitOpenTimeout.remove(git); - if (thread != null) { - thread.interrupt(); - } else { - new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), - new RuntimeException("Closing a git object that was not opened with a timeout!")); - } - } - git.getRepository().close(); + open.remove(git.getRepository().getDirectory().getAbsolutePath()); + // git.getRepository().close(); git.close(); } - /** - * Make a timeout thread for printing an exception whenever a git object is - * opened and not closed within 5 seconds - * - * @return - */ - private static GitTimeoutThread makeTimeoutThread(Git git) { - - GitTimeoutThread thread = new GitTimeoutThread(git); - thread.start(); - return thread; - } - public static void addOnCommitEventListeners(String url, Runnable event) { synchronized (onCommitEventListeners) { if (!onCommitEventListeners.containsKey(url)) { @@ -448,6 +487,7 @@ public static void removeOnCommitEventListeners(String url, Runnable event) { } } + /** * This interface is for adding additional language support. * @@ -455,18 +495,19 @@ public static void removeOnCommitEventListeners(String url, Runnable event) { * @param args the incoming arguments as a list of objects * @return the objects returned form the code that ran */ - public static Object inlineScriptRun(File code, ArrayList args, String shellTypeStorage) throws Exception { + public static Object inlineScriptRun(CSGDatabaseInstance instance,File code, ArrayList args, String shellTypeStorage) throws Exception { if (filesRun.get(code.getName()) == null) { filesRun.put(code.getName(), code); - // System.out.println("Loading "+code.getAbsolutePath()); + // com.neuronrobotics.sdk.common.Log.error("Loading "+code.getAbsolutePath()); } - if (langauges.get(shellTypeStorage) != null) { - return langauges.get(shellTypeStorage).inlineScriptRun(code, args); + IScriptingLanguage iScriptingLanguage = langauges.get(shellTypeStorage); + if (iScriptingLanguage != null) { + Object inlineScriptRun = iScriptingLanguage.inlineScriptRun(instance,code, args); + return inlineScriptRun; } return null; } - /** * This interface is for adding additional language support. * @@ -474,15 +515,16 @@ public static Object inlineScriptRun(File code, ArrayList args, String s * @param args the incoming arguments as a list of objects * @return the objects returned form the code that ran */ - public static Object inlineScriptStringRun(String line, ArrayList args, String shellTypeStorage) + public static Object inlineScriptStringRun(CSGDatabaseInstance instance, String line, ArrayList args, String shellTypeStorage) throws Exception { if (langauges.get(shellTypeStorage) != null) { - return langauges.get(shellTypeStorage).inlineScriptRun(line, args); + return langauges.get(shellTypeStorage).inlineScriptRun(instance,line, args); } return null; } + public static void addScriptingLanguage(IScriptingLanguage lang) { langauges.put(lang.getShellType(), lang); } @@ -501,25 +543,78 @@ public static void removeIGithubLoginListener(IGithubLoginListener l) { public static File getWorkspace() { if (workspace == null) { - String relative = FileSystemView.getFileSystemView().getDefaultDirectory().getPath(); - // https://github.com/CommonWealthRobotics/BowlerStudio/issues/378 - if (OSUtil.isOSX() || OSUtil.isLinux()) - if (!relative.endsWith("Documents")) { - relative = relative + "/Documents"; - } - if (OSUtil.isWindows()) { - if (!relative.endsWith("Documents")) { - relative = relative + "\\Documents"; - } - } - - File file = new File(relative + "/bowler-workspace/"); + File relative = getWorkingDirectory(); + File file = new File(relative.getAbsolutePath() + delim + "bowler-workspace" + delim); file.mkdirs(); setWorkspace(file); } return workspace; } + public static void createSymlinkInDocuments(File appDataDir) throws IOException { + String userHome = System.getProperty("user.home"); + Path documentsDir = Paths.get(userHome, "Documents"); + Path symlinkPath = documentsDir.resolve(appDataDir.getName()); + + // Delete existing symlink if it exists + if (Files.exists(symlinkPath)) { + return; + } + + // Create the symlink + Files.createSymbolicLink(symlinkPath, appDataDir.toPath()); + com.neuronrobotics.sdk.common.Log.debug("Symlink created: " + symlinkPath); + } + private static Path getWindowsAppData(String appName) { + // Try APPDATA first, then LOCALAPPDATA, then fallback + String appData = System.getenv("APPDATA"); + if (appData != null) { + return Paths.get(appData, appName); + } + + String localAppData = System.getenv("LOCALAPPDATA"); + if (localAppData != null) { + return Paths.get(localAppData, appName); + } + + // Fallback + String userHome = System.getProperty("user.home"); + return Paths.get(userHome, "AppData", "Roaming", appName); + } + public static File getWorkingDirectory() { + String relative = Paths.get(System.getProperty("user.home"), "Documents").toString(); + if (OSUtil.isOSX()) { + File appDataDir = new File(System.getProperty("user.home") + "/Library/Application Support/" + appName); + + if (!appDataDir.exists()) { + if (!appDataDir.mkdirs()) { + throw new RuntimeException("Failed to create app data directory"); + } + } + relative = appDataDir.getAbsolutePath(); + try { + createSymlinkInDocuments(appDataDir); + } catch (IOException e) { + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + } + delim = "/"; + if (OSUtil.isLinux()) + if (!relative.endsWith("Documents")) { + relative = relative + delim + "Documents"; + } + if (OSUtil.isWindows()) { + delim = "\\"; + if (!relative.endsWith("Documents")) { + relative = relative + delim + "Documents"; + } + } + File file = new File(relative + delim); + file.mkdirs(); + return file; + } + public static String getShellType(String name) { for (IScriptingLanguage l : langauges.values()) { if (l.isSupportedFileExtenetion(name)) @@ -548,7 +643,7 @@ public static void logout() throws IOException { } public static GitHub setupAnyonmous() throws IOException { - //ScriptingEngine.setAutoupdate(false); + // ScriptingEngine.setAutoupdate(false); return PasswordManager.setupAnyonmous(); } @@ -585,11 +680,11 @@ private static List returnFirstGist(String html) { Elements links = doc.select("script"); for (int i = 0; i < links.size(); i++) { Element e = links.get(i); - /// System.out.println("Found gist embed: "+e); + /// com.neuronrobotics.sdk.common.Log.error("Found gist embed: "+e); Attributes n = e.attributes(); String jSSource = n.get("src"); if (jSSource.contains("https://gist.github.com/")) { - // System.out.println("Source = "+jSSource); + // com.neuronrobotics.sdk.common.Log.error("Source = "+jSSource); String slug = jSSource; String js = slug.split(".js")[0]; String[] id = js.split("/"); @@ -631,7 +726,7 @@ public static List getCurrentGist(String addr, Object engine) { */ public static void waitForLogin() throws IOException, InvalidRemoteException, TransportException, GitAPIException { if (!PasswordManager.hasNetwork()) { - System.err.println("No network, cant log in"); + com.neuronrobotics.sdk.common.Log.error("No network, cant log in"); return; } try { @@ -639,18 +734,18 @@ public static void waitForLogin() throws IOException, InvalidRemoteException, Tr if (PasswordManager.loggedIn()) return; if (PasswordManager.getLoginID() == null) { - System.err.println("No login ID found!"); + com.neuronrobotics.sdk.common.Log.error("No login ID found!"); return; } if (PasswordManager.getPassword() == null) { - System.err.println("No login api key found!"); + com.neuronrobotics.sdk.common.Log.error("No login api key found!"); return; } - System.err.println("Performing Login"); + com.neuronrobotics.sdk.common.Log.debug("Performing Login"); PasswordManager.waitForLogin(); if (!PasswordManager.loggedIn()) { - System.err.println("\nERROR: Wrong Password!\n"); + com.neuronrobotics.sdk.common.Log.error("\nERROR: Wrong Password!\n"); login(); } @@ -661,22 +756,20 @@ public static void waitForLogin() throws IOException, InvalidRemoteException, Tr } public static void waitForRepo(String remoteURI, String reason) { - while (ScriptingEngine.isUrlAlreadyOpen(remoteURI)) { - ThreadUtil.wait(500); - for (Iterator iterator = gitOpenTimeout.keySet().iterator(); iterator.hasNext();) { - Git g = iterator.next(); - GitTimeoutThread t = gitOpenTimeout.get(g); - if (t.ref.toLowerCase().contentEquals(remoteURI.toLowerCase())) { - - System.err.println("\n\n\nPaused " + reason + " by another thread, waiting for repo " + remoteURI); - new Exception().printStackTrace(System.err); - System.err.println("Paused by:"); - t.getException().printStackTrace(System.err); - System.err.println("\n\n\n"); - - } + if (isNotURL(remoteURI)) { + return; + } + try { + File f = getRepository(remoteURI).getDirectory(); + while (ScriptingEngine.isUrlAlreadyOpen(f)) { + ThreadUtil.wait(500); + System.err.println("Waiting..."); } + } catch (IOException e) { + // TODO Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } + } public static void deleteRepo(String remoteURI) { @@ -708,25 +801,25 @@ private static void deleteFolder(File folder) { try { FileChangeWatcher.notifyOfDelete(f); FileChangeWatcher.close(f); - System.out.println("Deleting File " + f.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.debug("Deleting File " + f.getAbsolutePath()); if (!f.delete()) { - System.err.println("File failed to delete! " + f); + com.neuronrobotics.sdk.common.Log.debug("File failed to delete! " + f); } } catch (Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } - // System.out.println("Deleting " + f.getAbsolutePath()); + // com.neuronrobotics.sdk.common.Log.error("Deleting " + f.getAbsolutePath()); } } } try { - System.out.println("Deleting Folder " + folder.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Deleting Folder " + folder.getAbsolutePath()); folder.delete(); } catch (Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } if (folder.exists()) { - System.err.println("Folder failed to delete! " + folder); + com.neuronrobotics.sdk.common.Log.error("Folder failed to delete! " + folder); deleteFolder(folder); } @@ -821,10 +914,10 @@ private static boolean ensureExistance(File desired) throws IOException { File parent = desired.getParentFile(); if (!parent.exists()) { parent.mkdirs(); - System.err.println("Creating " + parent.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Creating " + parent.getAbsolutePath()); } if (!desired.exists() && parent.exists()) { - System.err.println("Creating " + desired.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Creating " + desired.getAbsolutePath()); desired.createNewFile(); createdFlag = true; } @@ -833,16 +926,39 @@ private static boolean ensureExistance(File desired) throws IOException { public static void commit(String id, String branch, String FileName, String content, String commitMessage, boolean flagNewFile) throws Exception { - commit(id, branch, FileName, content, commitMessage, flagNewFile, null); + if (isNotURL(id)) { + try { + File f = new File(id); + if (f.exists() && f.isDirectory()) { + com.neuronrobotics.sdk.common.Log.debug("remoteURI is actually a directory " + f); + OutputStream out = null; + try { + out = FileUtils.openOutputStream(new File(f + "/" + FileName), false); + IOUtils.write(content, out, Charset.defaultCharset()); + out.close(); // don't swallow close Exception if copy + // completes + // normally + } finally { + IOUtils.closeQuietly(out); + } + return; + } + } catch (Exception ex) { + // not a file i guess... + } + } + openGit(id, git -> { + commit(id, branch, FileName, content, commitMessage, flagNewFile, git); + }); } @SuppressWarnings("deprecation") - public static void commit(String id, String branch, String FileName, String content, String commitMessage, + private static void commit(String id, String branch, String FileName, String content, String commitMessage, boolean flagNewFile, Git gitRef) throws Exception { - if(content !=null) - if("Binary File".contentEquals(content)){ - content=null; - } + if (content != null) + if ("Binary File".contentEquals(content)) { + content = null; + } if (PasswordManager.getUsername() == null) login(); if (!hasNetwork()) @@ -858,13 +974,11 @@ public static void commit(String id, String branch, String FileName, String cont Repository localRepo = new FileRepository(gitRepoFile.getAbsoluteFile()); Git git = gitRef; if (git == null) - git = openGit(localRepo); + throw new RuntimeException("Fail! Git must exist before commiting"); try { // latest version if (flagNewFile) { git.add().addFilepattern(FileName).call(); } - if (gitRef == null) - closeGit(git); if (content != null) { OutputStream out = null; try { @@ -880,45 +994,63 @@ public static void commit(String id, String branch, String FileName, String cont commit(id, branch, commitMessage, gitRef); } catch (Exception ex) { - if (gitRef == null) - closeGit(git); - throw ex; } - if (gitRef == null) - closeGit(git); try { - if (!desired.getName().contentEquals("csgDatabase.json")) { - String[] gitID = ScriptingEngine.findGitTagFromFile(desired, gitRef); - String remoteURI = gitID[0]; - ArrayList f = ScriptingEngine.filesInGit(remoteURI, gitRef); - for (String s : f) { - if (s.contentEquals("csgDatabase.json")) { - - File dbFile = ScriptingEngine.fileFromGit(gitID[0], s); - if (!CSGDatabase.getDbFile().equals(dbFile)) - CSGDatabase.setDbFile(dbFile); - CSGDatabase.saveDatabase(); - @SuppressWarnings("resource") - String c = new Scanner(dbFile).useDelimiter("\\Z").next(); - ScriptingEngine.commit(remoteURI, branch, s, c, "saving CSG database", false, gitRef); - } - } - } +// if (!desired.getName().contentEquals("csgDatabase.json")) { +// String[] gitID = ScriptingEngine.findGitTagFromFile(desired, gitRef); +// String remoteURI = gitID[0]; +// ArrayList f = ScriptingEngine.filesInGit(remoteURI, gitRef); +// for (String s : f) { +// if (s.contentEquals("csgDatabase.json")) { +// +// File dbFile = ScriptingEngine.fileFromGit(gitID[0], s); +// if (!CSGDatabase.getDbFile().equals(dbFile)) +// CSGDatabase.setInstance(new CSGDatabaseInstance(dbFile)); +// CSGDatabase.saveDatabase(); +// @SuppressWarnings("resource") +// String c = new Scanner(dbFile).useDelimiter("\\Z").next(); +// commit(remoteURI, branch, s, c, "saving CSG database", false, gitRef); +// } +// } +// } } catch (Exception e) { // ignore CSG database - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(e); } } @SuppressWarnings("deprecation") public static void pushCodeToGit(String remoteURI, String branch, String FileName, String content, String commitMessage, boolean flagNewFile) throws Exception { + if (isNotURL(remoteURI)) { + try { + File f = new File(remoteURI); + if (f.exists() && f.isDirectory()) { + com.neuronrobotics.sdk.common.Log.debug("remoteURI is actually a directory " + f); + OutputStream out = null; + try { + out = FileUtils.openOutputStream(new File(f + "/" + FileName), false); + IOUtils.write(content, out, Charset.defaultCharset()); + out.close(); // don't swallow close Exception if copy + // completes + // normally + } finally { + IOUtils.closeQuietly(out); + } + return; + } + } catch (Exception ex) { + // not a file i guess... + } + } + waitForRepo(remoteURI, "push"); - if(content!=null) - if("Binary File".contentEquals(content)){ - content=null; + if (content != null) + if ("Binary File".contentEquals(content)) { + content = null; } + commit(remoteURI, branch, FileName, content, commitMessage, flagNewFile); if (PasswordManager.getUsername() == null) login(); @@ -945,40 +1077,40 @@ public static void pushCodeToGit(String remoteURI, String branch, String FileNam File gitRepoFile = new File(localPath + "/.git"); Repository localRepo = new FileRepository(gitRepoFile.getAbsoluteFile()); - Git git = null; + // Git git = null; try { try { pull(remoteURI, branch); } catch (java.lang.RuntimeException exp) { } - git = openGit(localRepo); - // latest version - if (flagNewFile) { - git.add().addFilepattern(FileName).call(); - } - if (content != null) { - OutputStream out = null; - try { - out = FileUtils.openOutputStream(desired, false); - IOUtils.write(content, out); - out.close(); // don't swallow close Exception if copy - // completes - // normally - } finally { - IOUtils.closeQuietly(out); + String c = content; + openGit(localRepo, git -> { + // latest version + if (flagNewFile) { + git.add().addFilepattern(FileName).call(); } - } - if (git.getRepository().getConfig().getString("remote", "origin", "url").startsWith("git@")) - git.push().setTransportConfigCallback(transportConfigCallback) - .setProgressMonitor(getProgressMoniter("Pushing ", remoteURI)).call(); - else - git.push().setCredentialsProvider(PasswordManager.getCredentialProvider()) - .setProgressMonitor(getProgressMoniter("Pushing ", remoteURI)).call(); - closeGit(git); - System.out.println("PUSH OK! file: " + desired + " on branch " + getBranch(remoteURI)); + if (c != null) { + OutputStream out = null; + try { + out = FileUtils.openOutputStream(desired, false); + IOUtils.write(c, out, Charset.defaultCharset()); + out.close(); // don't swallow close Exception if copy + // completes + // normally + } finally { + IOUtils.closeQuietly(out); + } + } + if (git.getRepository().getConfig().getString("remote", "origin", "url").startsWith("git@")) + git.push().setTransportConfigCallback(transportConfigCallback) + .setProgressMonitor(getProgressMoniter("Pushing ", remoteURI)).call(); + else + git.push().setCredentialsProvider(PasswordManager.getCredentialProvider()) + .setProgressMonitor(getProgressMoniter("Pushing ", remoteURI)).call(); + }); + com.neuronrobotics.sdk.common.Log.debug("PUSH OK! file: " + desired + " on branch " + getBranch(remoteURI)); } catch (Exception ex) { - ex.printStackTrace(); - closeGit(git); + com.neuronrobotics.sdk.common.Log.error(ex);; String[] gitID = ScriptingEngine.findGitTagFromFile(desired); String id = gitID[0]; @@ -991,7 +1123,7 @@ public static String[] codeFromGit(String id, String FileName) throws Exception File targetFile = fileFromGit(id, FileName); if (targetFile.exists()) { - // System.err.println("Loading file: + // com.neuronrobotics.sdk.common.Log.error("Loading file: // "+targetFile.getAbsoluteFile()); // Target file is ready to go String text = new String(Files.readAllBytes(Paths.get(targetFile.getAbsolutePath())), @@ -999,7 +1131,7 @@ public static String[] codeFromGit(String id, String FileName) throws Exception return new String[] { text, FileName, targetFile.getAbsolutePath() }; } - return null; + throw new RuntimeException("File missing! " + targetFile.getAbsolutePath()); } private static String[] codeFromGistID(String id, String FileName) throws Exception { @@ -1007,7 +1139,7 @@ private static String[] codeFromGistID(String id, String FileName) throws Except File targetFile = fileFromGit(giturl, FileName); if (targetFile.exists()) { - System.err.println("Gist at GIT : " + giturl); + com.neuronrobotics.sdk.common.Log.debug("Gist at GIT : " + giturl); // Target file is ready to go String text = new String(Files.readAllBytes(Paths.get(targetFile.getAbsolutePath())), StandardCharsets.UTF_8); @@ -1017,25 +1149,90 @@ private static String[] codeFromGistID(String id, String FileName) throws Except return null; } - public static Object inlineFileScriptRun(File f, ArrayList args) throws Exception { + public static Object inlineFileScriptRun(CSGDatabaseInstance instance,File f, ArrayList args) throws Exception { - return inlineScriptRun(f, args, getShellType(f.getName())); + return inlineScriptRun(instance,f, args, getShellType(f.getName())); + } + public static Object inlineGistScriptRun(CSGDatabaseInstance db,String gistID, String Filename, ArrayList args) throws Exception { + String[] gistData = codeFromGistID(gistID, Filename); + return inlineScriptRun(db,new File(gistData[2]), args, getShellType(gistData[1])); } + + @Deprecated public static Object inlineGistScriptRun(String gistID, String Filename, ArrayList args) throws Exception { String[] gistData = codeFromGistID(gistID, Filename); - return inlineScriptRun(new File(gistData[2]), args, getShellType(gistData[1])); + Log.error(new Exception("Depricated script mode, use CSGDatabaseInstance")); + return inlineScriptRun(CSGDatabase.getInstance(),new File(gistData[2]), args, getShellType(gistData[1])); } - - public static Object gitScriptRun(String gitURL, String Filename) throws Exception { - return gitScriptRun(gitURL, Filename, null); + @Deprecated + public static Object inlineFileScriptRun(File f, ArrayList args) throws Exception { + Log.error(new Exception("Depricated script mode, use CSGDatabaseInstance")); + return inlineScriptRun(CSGDatabase.getInstance(),f, args, getShellType(f.getName())); } + @Deprecated + public static Object gitScriptRun(String gitURL, String Filename) throws Exception { + Log.error(new Exception("Depricated script mode, use CSGDatabaseInstance")); + return gitScriptRun(CSGDatabase.getInstance(),gitURL, Filename, null); + } + /** + * This interface is for adding additional language support. + * + * @param code file content of the code to be executed + * @param args the incoming arguments as a list of objects + * @return the objects returned form the code that ran + */ + @Deprecated + public static Object inlineScriptRun(File code, ArrayList args, String shellTypeStorage) throws Exception{ + Log.error(new Exception("Depricated script mode, use CSGDatabaseInstance")); + CSGDatabaseInstance prevDB = CSGDatabase.getInstance(); + try { + if (!code.getName().toLowerCase().contentEquals("csgdatabase.json")) { + File p = code.getParentFile(); + for (String s : p.list()) { + if (s.toLowerCase().contentEquals("csgdatabase.json")) { + prevDB = (new CSGDatabaseInstance( + new File(p.getAbsoluteFile() + DownloadManager.delim() + s))); + } + } + } + } catch (Exception e) { + Log.error(e); + } + return inlineScriptRun(prevDB, code, args, shellTypeStorage); + } + /** + * This interface is for adding additional language support. + * + * @param line the text content of the code to be executed + * @param args the incoming arguments as a list of objects + * @return the objects returned form the code that ran + */ + @Deprecated + public static Object inlineScriptStringRun(String line, ArrayList args, String shellTypeStorage) + throws Exception { + Log.error(new Exception("Depricated script mode, use CSGDatabaseInstance")); + return inlineScriptStringRun(CSGDatabase.getInstance(),line,args,shellTypeStorage); + } + @Deprecated public static Object gitScriptRun(String gitURL, String Filename, ArrayList args) throws Exception { - String[] gistData = codeFromGit(gitURL, Filename); - return inlineScriptRun(new File(gistData[2]), args, getShellType(gistData[1])); + Log.error(new Exception("Depricated script mode, use CSGDatabaseInstance")); + return gitScriptRun(CSGDatabase.getInstance(), gitURL, Filename, args); + } + + + public static Object gitScriptRun(CSGDatabaseInstance db,String gitURL, String Filename) throws Exception { + return gitScriptRun(db,gitURL, Filename, null); } + public static Object gitScriptRun(CSGDatabaseInstance db,String gitURL, String Filename, ArrayList args) throws Exception { + return inlineScriptRun(db,fileFromGit(gitURL, Filename), args, getShellType(Filename)); + } + public static File fileFromGit(String[] self) + throws InvalidRemoteException, TransportException, GitAPIException, IOException { + return fileFromGit(self[0], null, self[1]); + } public static File fileFromGit(String remoteURI, String fileInRepo) throws InvalidRemoteException, TransportException, GitAPIException, IOException { return fileFromGit(remoteURI, null, fileInRepo); @@ -1046,6 +1243,9 @@ public static File fileFromGit(String remoteURI, String fileInRepo) // https://github.com/CommonWealthRobotics/BowlerStudioVitamins.git public static File fileFromGit(String remoteURI, String branch, String fileInRepo) throws InvalidRemoteException, TransportException, GitAPIException, IOException { + if (branch != null) + if (branch.length() == 0) + branch = null; File gitRepoFile = cloneRepo(remoteURI, branch); return new File(gitRepoFile.getAbsolutePath() + "/" + fileInRepo); } @@ -1058,7 +1258,7 @@ public static File uriToFile(String remoteURI) { File gistDir = new File(getWorkspace().getAbsolutePath() + "/gitcache/" + gitSplit + "/.git"); return gistDir; } catch (ArrayIndexOutOfBoundsException ex) { - System.err.println("Failed to parse " + remoteURI); + com.neuronrobotics.sdk.common.Log.error("Failed to parse " + remoteURI); throw ex; } @@ -1120,31 +1320,31 @@ public static void deleteBranch(String remoteURI, String toDelete) throws Except // CheckoutCommand checkout; // String source = getFullBranch(remoteURI); - Git git; + openGit(localRepo, git -> { + String d = toDelete; + if (!toDelete.contains("heads")) { + d = "heads/" + d; + } + if (!toDelete.contains("refs")) { + d = "refs/" + d; + } + Exception ex = null; + try { + // delete branch 'branchToDelete' locally + git.branchDelete().setBranchNames(d).call(); - git = openGit(localRepo); - if (!toDelete.contains("heads")) { - toDelete = "heads/" + toDelete; - } - if (!toDelete.contains("refs")) { - toDelete = "refs/" + toDelete; - } - Exception ex = null; - try { - // delete branch 'branchToDelete' locally - git.branchDelete().setBranchNames(toDelete).call(); + // delete branch 'branchToDelete' on remote 'origin' + RefSpec refSpec = new RefSpec().setSource(null).setDestination(d); + git.push().setRefSpecs(refSpec).setRemote("origin") + .setCredentialsProvider(PasswordManager.getCredentialProvider()) + .setProgressMonitor(getProgressMoniter("Pushing ", remoteURI)).call(); + } catch (Exception e) { + ex = e; + } + if (ex != null) + throw ex; + }); - // delete branch 'branchToDelete' on remote 'origin' - RefSpec refSpec = new RefSpec().setSource(null).setDestination(toDelete); - git.push().setRefSpecs(refSpec).setRemote("origin") - .setCredentialsProvider(PasswordManager.getCredentialProvider()) - .setProgressMonitor(getProgressMoniter("Pushing ", remoteURI)).call(); - } catch (Exception e) { - ex = e; - } - closeGit(git); - if (ex != null) - throw ex; } public static String newBranch(String remoteURI, String newBranch) @@ -1160,41 +1360,32 @@ public static void newBranch(String remoteURI, String newBranch, RevCommit sourc waitForRepo(remoteURI, "newBranch"); Repository localRepo = getRepository(remoteURI); - Git git = null; try { for (String s : listBranchNames(remoteURI)) { if (s.contains(newBranch)) { // throw new RuntimeException(newBranch + " can not be created because " + s + " // is too similar"); - - git = openGit(localRepo); - shallowCheckout(remoteURI, newBranch, git); - closeGit(git); + openGit(localRepo, git -> { + shallowCheckout(remoteURI, newBranch, git); + }); return; } } } catch (Exception e) { - e.printStackTrace(); - closeGit(git); + com.neuronrobotics.sdk.common.Log.error(e); } - git = openGit(localRepo); - try { + openGit(localRepo, git -> { try { - if (source == null) - source = git.log().setMaxCount(1).call().iterator().next(); - newBranchLocal(newBranch, remoteURI, git, source); + RevCommit s = source; + if (s == null) + s = git.log().setMaxCount(1).call().iterator().next(); + newBranchLocal(newBranch, remoteURI, git, s); } catch (NoHeadException ex) { newBranchLocal(newBranch, remoteURI, git, null); } - } catch (Throwable ex) { - closeGit(git); - throw ex; - } - - closeGit(git); - + }); } private static void newBranchLocal(String newBranch, String remoteURI, Git git, RevCommit source) @@ -1210,10 +1401,10 @@ private static void newBranchLocal(String newBranch, String remoteURI, Git git, setName.setForce(true); } setName.call(); - System.out.println("Created new branch " + remoteURI + "\t\t" + newBranch); + com.neuronrobotics.sdk.common.Log.debug("Created new branch " + remoteURI + "\t\t" + newBranch); } catch (org.eclipse.jgit.api.errors.RefNotFoundException ex) { - System.err.println("ERROR Creating " + newBranch + " in " + remoteURI); - ex.printStackTrace(); + com.neuronrobotics.sdk.common.Log.debug("ERROR Creating " + newBranch + " in " + remoteURI); + com.neuronrobotics.sdk.common.Log.error(ex);; } catch (org.eclipse.jgit.api.errors.RefAlreadyExistsException ex) { // just checkout the existing branch then } @@ -1241,7 +1432,7 @@ private static boolean hasAtLeastOneReference(Git git) throws Exception { if (ref.getObjectId() != null) { List branchList = listBranches(remoteURI, git); if (branchList.size() > 0) { - // System.out.println("Found "+branchList.size()+" + // com.neuronrobotics.sdk.common.Log.error("Found "+branchList.size()+" // branches"); return true; } @@ -1262,20 +1453,23 @@ public static List listBranches(String remoteURI) throws Exception { Repository localRepo = new FileRepository(gitRepoFile.getAbsoluteFile()); // https://gist.github.com/0e6454891a3b3f7c8f28.git - List Ret; - Git git = openGit(localRepo); - Ret = listBranches(remoteURI, git); - closeGit(git); - return Ret; + ArrayList back = new ArrayList(); + openGit(localRepo, git -> { + List Ret = listBranches(remoteURI, git); + back.addAll(Ret); + }); + return back; } public static List listBranches(String remoteURI, Git git) throws Exception { // https://gist.github.com/0e6454891a3b3f7c8f28.git - // System.out.println("Listing references from: "+remoteURI); - // System.out.println(" branch: "+getFullBranch(remoteURI)); + // com.neuronrobotics.sdk.common.Log.error("Listing references from: + // "+remoteURI); + // com.neuronrobotics.sdk.common.Log.error(" branch: + // "+getFullBranch(remoteURI)); List list = git.branchList().setListMode(ListMode.ALL).call(); - // System.out.println(" size : "+list.size()); + // com.neuronrobotics.sdk.common.Log.error(" size : "+list.size()); return list; } @@ -1288,16 +1482,12 @@ public static List listLocalBranches(String remoteURI) throws IOException { Repository localRepo = new FileRepository(gitRepoFile.getAbsoluteFile()); // https://gist.github.com/0e6454891a3b3f7c8f28.git - Git git = openGit(localRepo); - try { + ArrayList back = new ArrayList(); + openGit(localRepo, git -> { List list = git.branchList().call(); - closeGit(git); - return list; - } catch (Exception ex) { - - } - closeGit(git); - return new ArrayList<>(); + back.addAll(list); + }); + return back; } public static List listLocalBranchNames(String remoteURI) throws Exception { @@ -1305,7 +1495,8 @@ public static List listLocalBranchNames(String remoteURI) throws Excepti List list = listLocalBranches(remoteURI); for (Ref ref : list) { - // System.out.println("Branch: " + ref + " " + ref.getName() + " " + + // com.neuronrobotics.sdk.common.Log.error("Branch: " + ref + " " + + // ref.getName() + " " + // ref.getObjectId().getName()); branchNames.add(ref.getName()); } @@ -1317,7 +1508,8 @@ public static List listBranchNames(String remoteURI) throws Exception { List list = listBranches(remoteURI); for (Ref ref : list) { - // System.out.println("Branch: " + ref + " " + ref.getName() + " " + + // com.neuronrobotics.sdk.common.Log.error("Branch: " + ref + " " + + // ref.getName() + " " + // ref.getObjectId().getName()); branchNames.add(ref.getName()); } @@ -1337,8 +1529,7 @@ public static void pull(String remoteURI, String branch) throws IOException, Che } Repository localRepo = new FileRepository(gitRepoFile.getAbsoluteFile()); - Git git = openGit(localRepo); - try { + openGit(localRepo, git -> { String ref = git.getRepository().getConfig().getString("remote", "origin", "url"); try { @@ -1360,64 +1551,57 @@ public static void pull(String remoteURI, String branch) throws IOException, Che throw ex; } - closeGit(git); - // new Exception(ref).printStackTrace(); } catch (CheckoutConflictException ex) { -// closeGit(git); -// resolveConflict(remoteURI, ex, git); -// pull(remoteURI, branch); - closeGit(git); + PasswordManager.checkInternet(); throw ex; } catch (WrongRepositoryStateException e) { - e.printStackTrace(); - closeGit(git); + com.neuronrobotics.sdk.common.Log.error(e); + PasswordManager.checkInternet(); // deleteRepo(remoteURI); throw e; } catch (InvalidConfigurationException e) { PasswordManager.checkInternet(); - closeGit(git); + throw new RuntimeException("remoteURI " + remoteURI + " branch " + branch + " " + e.getMessage()); } catch (DetachedHeadException e) { PasswordManager.checkInternet(); - closeGit(git); + throw new RuntimeException("remoteURI " + remoteURI + " branch " + branch + " " + e.getMessage()); } catch (InvalidRemoteException e) { PasswordManager.checkInternet(); - closeGit(git); + throw new InvalidRemoteException("remoteURI " + remoteURI + " branch " + branch + " " + e.getMessage()); } catch (CanceledException e) { PasswordManager.checkInternet(); - closeGit(git); + throw new RuntimeException("remoteURI " + remoteURI + " branch " + branch + " " + e.getMessage()); } catch (RefNotFoundException e) { PasswordManager.checkInternet(); - closeGit(git); + throw new RuntimeException("remoteURI " + remoteURI + " branch " + branch + " " + e.getMessage()); } catch (RefNotAdvertisedException e) { PasswordManager.checkInternet(); - closeGit(git); + try { if (branch != null) newBranch(remoteURI, branch); else { - git = openGit(remoteURI); - RevCommit source = git.log().setMaxCount(1).call().iterator().next(); + openGit(remoteURI, g -> { + RevCommit source = g.log().setMaxCount(1).call().iterator().next(); - newBranchLocal("main", remoteURI, git, source); - closeGit(git); + newBranchLocal("main", remoteURI, g, source); + }); } } catch (Exception ex) { - closeGit(git); - ex.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(ex);; throw new RuntimeException("remoteURI " + remoteURI + " branch " + branch + " " + ex.getMessage()); } } catch (NoHeadException e) { PasswordManager.checkInternet(); - closeGit(git); throw e; // try { // closeGit(git); @@ -1428,37 +1612,27 @@ public static void pull(String remoteURI, String branch) throws IOException, Che // } } catch (TransportException e) { - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(e); PasswordManager.checkInternet(); if (git.getRepository().getConfig().getString("remote", "origin", "url").startsWith("git@")) { try { git.pull().setTransportConfigCallback(transportConfigCallback) .setProgressMonitor(getProgressMoniter("Pull ", remoteURI)).call(); - closeGit(git); } catch (Exception ex) { - closeGit(git); throw new RuntimeException( "remoteURI " + remoteURI + " branch " + branch + " " + e.getMessage()); } } else { - closeGit(git); throw new RuntimeException("remoteURI " + remoteURI + " branch " + branch + " " + e.getMessage()); } } catch (GitAPIException e) { - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(e); PasswordManager.checkInternet(); - closeGit(git); throw new RuntimeException("remoteURI " + remoteURI + " branch " + branch + " " + e.getMessage()); } - } catch (InvalidRemoteException e) { - PasswordManager.checkInternet(); - closeGit(git); - throw new InvalidRemoteException("remoteURI " + remoteURI + " branch " + branch + " " + e.getMessage()); - } catch (Throwable t) { - closeGit(git); - } + }); } @@ -1474,21 +1648,14 @@ public static void checkoutCommit(String remoteURI, String branch, String commit waitForRepo(remoteURI, "checkoutCommit"); File gitRepoFile = ScriptingEngine.uriToFile(remoteURI); if (!gitRepoFile.exists() || !gitRepoFile.getAbsolutePath().endsWith(".git")) { - System.err.println("Invailid git file!" + gitRepoFile.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.debug("Invailid git file!" + gitRepoFile.getAbsolutePath()); throw new RuntimeException("Invailid git file!" + gitRepoFile.getAbsolutePath()); } Repository localRepo = new FileRepository(gitRepoFile); - Git git = openGit(localRepo); - try { + openGit(localRepo, git -> { git.checkout().setName(commitHash).call(); git.checkout().setCreateBranch(true).setName(branch).setStartPoint(commitHash).call(); - - } catch (Exception ex) { - ex.printStackTrace(); - } - - closeGit(git); - + }); } public static void checkout(String remoteURI, RevCommit commit) @@ -1513,7 +1680,7 @@ public static void checkout(String remoteURI, String branch) // cloneRepo(remoteURI, branch); File gitRepoFile = uriToFile(remoteURI); if (!gitRepoFile.exists() || !gitRepoFile.getAbsolutePath().endsWith(".git")) { - System.err.println("Invailid git file!" + gitRepoFile.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.debug("Invailid git file!" + gitRepoFile.getAbsolutePath()); throw new RuntimeException("Invailid git file!" + gitRepoFile.getAbsolutePath()); } @@ -1525,58 +1692,50 @@ public static void checkout(String remoteURI, String branch) branch = currentBranch; if (currentBranch.length() < branch.length() || !currentBranch.endsWith(branch)) { - System.err.println("Current branch is " + currentBranch + " need " + branch); + com.neuronrobotics.sdk.common.Log.error("Current branch is " + currentBranch + " need " + branch); - Git git = null; try { Collection branches = getAllBranches(remoteURI); - git = openGit(localRepo); - for (Ref R : branches) { - if (R.getName().endsWith(branch)) { - System.err.println("\nFound upstream " + R.getName()); - shallowCheckout(remoteURI, branch, git); - closeGit(git); + String br = branch; + openGit(localRepo, git -> { + for (Ref R : branches) { + if (R.getName().endsWith(br)) { + com.neuronrobotics.sdk.common.Log.debug("Found upstream " + R.getName()); + shallowCheckout(remoteURI, br, git); + } } - } - // The ref does not exist upstream, create - try { - PasswordManager.checkInternet(); - closeGit(git); - newBranch(remoteURI, branch); - } catch (org.eclipse.jgit.api.errors.TransportException ex) { - // Not logged in yet, just return - PasswordManager.checkInternet(); - closeGit(git); - return; - } catch (RefAlreadyExistsException e) { - PasswordManager.checkInternet(); - closeGit(git); - throw new RuntimeException(e); - } catch (RefNotFoundException e) { - PasswordManager.checkInternet(); - closeGit(git); - throw new RuntimeException(e); - } catch (InvalidRefNameException e) { - PasswordManager.checkInternet(); - closeGit(git); - throw new RuntimeException(e); - } catch (CheckoutConflictException e) { - resolveConflict(remoteURI, e, git); - } catch (GitAPIException e) { - PasswordManager.checkInternet(); - closeGit(git); - throw new RuntimeException(e); - } catch (Exception e) { - PasswordManager.checkInternet(); - closeGit(git); - throw new RuntimeException(e); - } + // The ref does not exist upstream, create + try { + PasswordManager.checkInternet(); + newBranch(remoteURI, br); + } catch (org.eclipse.jgit.api.errors.TransportException ex) { + // Not logged in yet, just return + PasswordManager.checkInternet(); + return; + } catch (RefAlreadyExistsException e) { + PasswordManager.checkInternet(); + throw new RuntimeException(e); + } catch (RefNotFoundException e) { + PasswordManager.checkInternet(); + throw new RuntimeException(e); + } catch (InvalidRefNameException e) { + PasswordManager.checkInternet(); + throw new RuntimeException(e); + } catch (CheckoutConflictException e) { + resolveConflict(remoteURI, e, git); + } catch (GitAPIException e) { + PasswordManager.checkInternet(); + throw new RuntimeException(e); + } catch (Exception e) { + PasswordManager.checkInternet(); + throw new RuntimeException(e); + } + }); + } catch (Exception ex) { PasswordManager.checkInternet(); - closeGit(git); throw new RuntimeException(ex); } - closeGit(git); } } @@ -1609,9 +1768,9 @@ private static boolean resolveConflict(String remoteURI, CheckoutConflictExcepti Status stat = git.status().call(); Set changed = stat.getModified(); if (changed.size() > 0) { - System.out.println("Modified "); + com.neuronrobotics.sdk.common.Log.debug("Modified "); for (String p : changed) { - System.out.println("Modified Conflict with: " + p); + com.neuronrobotics.sdk.common.Log.debug("Modified Conflict with: " + p); byte[] bytes; String content = ""; try { @@ -1621,12 +1780,12 @@ private static boolean resolveConflict(String remoteURI, CheckoutConflictExcepti commit(remoteURI, getBranch(remoteURI), p, content, "auto-save in ScriptingEngine.resolveConflict", false, git); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e1); } } @@ -1634,17 +1793,17 @@ private static boolean resolveConflict(String remoteURI, CheckoutConflictExcepti } Set untracked = stat.getUntracked(); if (untracked.size() > 0) { - System.out.println("Untracked "); + com.neuronrobotics.sdk.common.Log.error("Untracked "); for (String p : untracked) { - System.out.println("Untracked Conflict with: " + p); + com.neuronrobotics.sdk.common.Log.error("Untracked Conflict with: " + p); File f = fileFromGit(remoteURI, p); f.delete(); } return resolveConflict(remoteURI, con, git); } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } return true; } @@ -1656,7 +1815,18 @@ private static boolean resolveConflict(String remoteURI, CheckoutConflictExcepti * @return The local directory containing the .git */ public static File cloneRepo(String remoteURI, String branch) { - + if (isNotURL(remoteURI)) { + try { + File f = new File(remoteURI); + if (f.exists() && f.isDirectory()) { + com.neuronrobotics.sdk.common.Log.debug("remoteURI is actually a directory " + f); + return f; + } + } catch (Exception ex) { + // not a file i guess... + } + } + // Assume it is a URL File gistDir = getRepositoryCloneDirectory(remoteURI); String localPath = gistDir.getAbsolutePath(); File gitRepoFile = new File(localPath + "/.git"); @@ -1666,36 +1836,27 @@ public static File cloneRepo(String remoteURI, String branch) { if (!hasNetwork()) return null;// No login info means there is no way to publish waitForRepo(remoteURI, "cloneRepo"); - System.out.println("Cloning files from: " + remoteURI); + com.neuronrobotics.sdk.common.Log.debug("Cloning files from: " + remoteURI); if (branch != null) - System.out.println(" branch: " + branch); - System.out.println(" to: " + localPath); + com.neuronrobotics.sdk.common.Log.debug(" branch: " + branch); + com.neuronrobotics.sdk.common.Log.debug(" to: " + localPath); Throwable ex = null; // Clone the repo - Git git = null; try { if (branch == null) { - git = cloneRepoLocal(remoteURI, dir); - hasAtLeastOneReference(git); - closeGit(git); + cloneRepoLocal(remoteURI, dir, git -> { + hasAtLeastOneReference(git); + }); branch = getFullBranch(remoteURI); } else { - git = cloneRepoLocal(remoteURI, dir); - hasAtLeastOneReference(git); - closeGit(git); + cloneRepoLocal(remoteURI, dir, git -> { + hasAtLeastOneReference(git); + }); checkout(remoteURI, branch); } - - } catch (org.eclipse.jgit.api.errors.JGitInternalException exe) { - closeGit(git); - // deleteRepo(remoteURI); - throw exe; - } catch (Throwable e) { - e.printStackTrace(); - closeGit(git); - PasswordManager.checkInternet(); - throw new RuntimeException(e); + } catch (Throwable t) { + com.neuronrobotics.sdk.common.Log.error(t); } } @@ -1703,7 +1864,12 @@ public static File cloneRepo(String remoteURI, String branch) { try { checkout(remoteURI, branch); } catch (Exception e) { - throw new RuntimeException(e); + try { + // try the checkout with no branch specified + return cloneRepo(remoteURI, null); + } catch (Exception ex) { + throw new RuntimeException(e); + } } } @@ -1711,6 +1877,10 @@ public static File cloneRepo(String remoteURI, String branch) { } + private static boolean isNotURL(String remoteURI) { + return !remoteURI.startsWith("http") && !remoteURI.startsWith("git@"); + } + public static String locateGitUrl(File f) throws IOException { return locateGitUrl(f, null); } @@ -1719,16 +1889,22 @@ public static String locateGitUrl(File f, Git ref) throws IOException { File gitRepoFile = new File(f.getAbsolutePath()); while (gitRepoFile != null) { if (new File(gitRepoFile.getAbsolutePath() + "/.git/config").exists()) { - // System.err.println("Fount git repo for file: "+gitRepoFile); + // com.neuronrobotics.sdk.common.Log.error("Fount git repo for file: + // "+gitRepoFile); Repository localRepo = new FileRepository(gitRepoFile.getAbsoluteFile() + "/.git"); - Git git = ref; - if (git == null) - git = openGit(localRepo); - String url = git.getRepository().getConfig().getString("remote", "origin", "url"); + // Git git = ref; + if (ref == null) { + ArrayList s = new ArrayList(); + File fi = gitRepoFile; + openGit(localRepo, git -> { + s.add(locateGitUrl(fi, git)); + }); + return s.get(0); + } + String url = ref.getRepository().getConfig().getString("remote", "origin", "url"); if (!url.endsWith(".git")) url += ".git"; - if (ref == null) - closeGit(git); + localRepo.close(); return url; } gitRepoFile = gitRepoFile.getParentFile(); @@ -1737,20 +1913,21 @@ public static String locateGitUrl(File f, Git ref) throws IOException { return null; } - public static Git locateGit(File f) throws IOException { + public static File locateGitTopLevelDirectory(File f) throws IOException { File gitRepoFile = f; while (gitRepoFile != null) { gitRepoFile = gitRepoFile.getParentFile(); if (gitRepoFile != null) if (new File(gitRepoFile.getAbsolutePath() + "/.git/config").exists()) { - // System.err.println("Fount git repo for file: "+gitRepoFile); - Repository localRepo = new FileRepository(gitRepoFile.getAbsoluteFile() + "/.git"); - return openGit(localRepo); - + return gitRepoFile; } } + throw new RuntimeException("File " + f + " is not in a git repository"); + } - throw new RuntimeException("File "+f+" is not in a git repository"); + public static void locateGit(File f, IGitAccessor access) throws IOException { + Repository localRepo = new FileRepository(locateGitTopLevelDirectory(f).getAbsoluteFile() + "/.git"); + openGit(localRepo, access); } public static String getText(URL website) throws Exception { @@ -1824,15 +2001,13 @@ public static String findLocalPath(File currentFile, Git git) { @SuppressWarnings("unused") public static String findLocalPath(File currentFile) { - Git git = null; try { - git = locateGit(currentFile); - String ret = findLocalPath(currentFile, git); - closeGit(git); - return ret; + ArrayList s = new ArrayList(); + locateGit(currentFile, git -> { + s.add(findLocalPath(currentFile, git)); + }); + return s.get(0); } catch (IOException e) { - if (git != null) - closeGit(git); throw new RuntimeException(e); } @@ -1844,55 +2019,39 @@ public static String[] findGitTagFromFile(File currentFile) throws IOException { public static String[] findGitTagFromFile(File currentFile, Git ref) throws IOException { String string = locateGitUrl(currentFile, ref); - Git git = ref; - if (git == null) - git = locateGit(currentFile); - try { - String[] strings = new String[] { string, findLocalPath(currentFile, git) }; - if (ref == null) - closeGit(git); - return strings; - } catch (Throwable t) { - t.printStackTrace(); - if (ref == null) - closeGit(git); - throw t; + String[] strings = new String[2]; + if (ref == null) + locateGit(currentFile, git -> { + String[] str = findGitTagFromFile(currentFile, git); + strings[0] = str[0]; + strings[1] = str[1]; + }); + else { + strings[0] = string; + strings[1] = findLocalPath(currentFile, ref); } + return strings; + } public static boolean checkOwner(String url) { - Git git = null; - try { - git = openGit(getRepository(url)); - } catch (IOException e1) { - closeGit(git); - throw new RuntimeException(e1); - } - boolean owned = checkOwner(git); - closeGit(git); - return owned; + ArrayList owners = new ArrayList(); + openGit(url, git -> { + owners.add(checkOwner(git)); + }); + return owners.get(0); } public static boolean checkOwner(File currentFile) { + ArrayList owners = new ArrayList(); try { - Git git; - try { - git = locateGit(currentFile); - } catch (Exception e1) { - - return false; - } - boolean owned; - try { - owned = checkOwner(git); - } catch (Throwable t) { - owned = false; - } - closeGit(git); - return owned; - } catch (Throwable t) { + locateGit(currentFile, git -> { + owners.add(checkOwner(git)); + }); + } catch (Throwable e1) { return false; } + return owners.get(0); } private static boolean checkOwner(Git git) { @@ -1953,7 +2112,7 @@ public static String fork(String sourceURL, String newRepoName, String newRepoDe } catch (org.kohsuke.github.HttpException ex) { if (ex.getMessage().contains("name already exists on this account")) { repository = github.getRepository(PasswordManager.getLoginID() + "/" + newRepoName); - System.out.println("Repo exists!"); + com.neuronrobotics.sdk.common.Log.error("Repo exists!"); return repository.getHttpTransportUrl(); } throw ex; @@ -1961,33 +2120,34 @@ public static String fork(String sourceURL, String newRepoName, String newRepoDe String gitRepo = repository.getHttpTransportUrl(); ArrayList files = filesInGit(sourceURL); - Git git = locateGit(fileFromGit(sourceURL, files.get(0))); - Repository sourceRepoObject = git.getRepository(); - try { - sourceRepoObject.getConfig().setString("remote", "origin", "url", gitRepo); - if (git.getRepository().getConfig().getString("remote", "origin", "url").startsWith("git@")) - git.push().setTransportConfigCallback(transportConfigCallback) - .setProgressMonitor(getProgressMoniter("Pushing ", gitRepo)).call(); - else - git.push().setCredentialsProvider(PasswordManager.getCredentialProvider()) - .setProgressMonitor(getProgressMoniter("Pushing ", gitRepo)).call(); - closeGit(git); - - filesInGit(gitRepo); - - return gitRepo; - } catch (org.kohsuke.github.HttpException ex) { - closeGit(git); - if (ex.getMessage().contains("name already exists on this account")) { - return PasswordManager.getGithub().getRepository(PasswordManager.getLoginID() + "/" + newRepoName) - .getHttpTransportUrl(); + ArrayList back = new ArrayList(); + locateGit(fileFromGit(sourceURL, files.get(0)), git -> { + Repository sourceRepoObject = git.getRepository(); + try { + sourceRepoObject.getConfig().setString("remote", "origin", "url", gitRepo); + if (git.getRepository().getConfig().getString("remote", "origin", "url").startsWith("git@")) + git.push().setTransportConfigCallback(transportConfigCallback) + .setProgressMonitor(getProgressMoniter("Pushing ", gitRepo)).call(); + else + git.push().setCredentialsProvider(PasswordManager.getCredentialProvider()) + .setProgressMonitor(getProgressMoniter("Pushing ", gitRepo)).call(); + + filesInGit(gitRepo); + + back.add(gitRepo); + } catch (org.kohsuke.github.HttpException ex) { + if (ex.getMessage().contains("name already exists on this account")) { + back.add(PasswordManager.getGithub().getRepository(PasswordManager.getLoginID() + "/" + newRepoName) + .getHttpTransportUrl()); + } + com.neuronrobotics.sdk.common.Log.error(ex);; + } catch (Throwable ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; } - ex.printStackTrace(); - } catch (Throwable ex) { - ex.printStackTrace(); - } - closeGit(git); - throw new RuntimeException("Repo could not be forked and does not exist"); + if (back.size() == 0) + throw new RuntimeException("Repo could not be forked and does not exist"); + }); + return back.get(0); } public static GHRepository makeNewRepoNoFailOver(String newName, String description) @@ -2002,13 +2162,13 @@ public static GHRepository makeNewRepoNoFailOver(String newName, String descript repo = github.getRepositoryById("" + repo.getId()); return repo; } catch (Exception ex) { - ex.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(ex);; } try { Thread.sleep(1000); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } return repo; @@ -2032,8 +2192,8 @@ public static GHRepository makeNewRepo(String newName, String description) throw commit(url, "main", "firstCommit"); newBranch(url, "main"); } catch (IOException | GitAPIException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } catch (org.kohsuke.github.HttpException ex) { if (ex.getMessage().contains("name already exists on this account")) { @@ -2047,15 +2207,16 @@ public static GHRepository makeNewRepo(String newName, String description) throw public static String locateGitUrlString(File f) { try { - Git locateGit = ScriptingEngine.locateGit(f); - Repository repository = locateGit.getRepository(); - String string = repository.getConfig().getString("remote", "origin", "url"); - ScriptingEngine.closeGit(locateGit); - return string; - + ArrayList back = new ArrayList(); + locateGit(f, locateGit -> { + Repository repository = locateGit.getRepository(); + String string = repository.getConfig().getString("remote", "origin", "url"); + back.add(string); + }); + return back.get(0); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } return null; } @@ -2066,7 +2227,7 @@ public static String urlToString(URL htmlUrl) { public static String urlToGist(URL htmlUrl) { String externalForm = urlToString(htmlUrl); - System.out.println(externalForm); + com.neuronrobotics.sdk.common.Log.debug(externalForm); return ScriptingEngine.urlToGist(externalForm); } @@ -2078,6 +2239,17 @@ public static List getAllLangauges() { return langs; } + public static List getAllExtentions() { + ArrayList langs = new ArrayList<>(); + for (String L : getLangaugesMap().keySet()) { + IScriptingLanguage lang = getLangaugesMap().get(L); + for (String s : lang.getFileExtenetion()) { + langs.add(s); + } + } + return langs; + } + public static HashMap getLangaugesMap() { return langauges; } @@ -2142,16 +2314,18 @@ public static String[] copyGitFile(String sourceGit, String targetGit, String fi } String[] newFileCode; try { + com.neuronrobotics.sdk.common.Log.debug("Opening " + targetFilename + " from " + targetGit); newFileCode = ScriptingEngine.codeFromGit(targetGit, targetFilename); if (newFileCode == null) newFileCode = new String[] { "" }; if (newFileCode[0].length() < 10) { - System.out.println("Copy Content to " + targetGit + "/" + targetFilename); + com.neuronrobotics.sdk.common.Log.debug("Copy Content to " + targetGit + "/" + targetFilename); ScriptingEngine.pushCodeToGit(targetGit, ScriptingEngine.getFullBranch(targetGit), targetFilename, WalkingEngine[0], "copy file content"); } } catch (Exception e) { - throw new RuntimeException(e); + ScriptingEngine.pushCodeToGit(targetGit, ScriptingEngine.getFullBranch(targetGit), targetFilename, + WalkingEngine[0], "copy file content"); } } catch (Exception e1) { throw new RuntimeException(e1); @@ -2174,9 +2348,11 @@ public static Ref getBranch(String remoteURI, String branch) throws IOException, public static Collection getAllBranches(String remoteURI) throws IOException, GitAPIException { cloneRepo(remoteURI, null); - Git git = openGit(getRepository(remoteURI)); - String ref = git.getRepository().getConfig().getString("remote", "origin", "url"); - closeGit(git); + ArrayList refs = new ArrayList(); + openGit(getRepository(remoteURI), git -> { + refs.add(git.getRepository().getConfig().getString("remote", "origin", "url")); + }); + String ref = refs.get(0); System.out.print("Getting branches " + ref + " "); if (ref != null && ref.startsWith("git@")) { @@ -2238,11 +2414,15 @@ private static void commit(String url, String branch, String message) private static void commit(String url, String branch, String message, Git passedRef) throws IOException, GitAPIException, NoHeadException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, AbortedByHookException { - Git git = passedRef; - if (git == null) - git = openGit(getRepository(url)); + + if (passedRef == null) { + openGit(getRepository(url), git -> { + commit(url, branch, message, git); + }); + return; + } try { - git.commit().setAll(true).setMessage(message).call(); + passedRef.commit().setAll(true).setMessage(message).call(); ArrayList arrayList = onCommitEventListeners.get(url); if (arrayList != null) { for (int i = 0; i < arrayList.size(); i++) { @@ -2250,17 +2430,13 @@ private static void commit(String url, String branch, String message, Git passed try { r.run(); } catch (Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } } } } catch (Throwable t) { - if (passedRef == null) - closeGit(git); throw t; } - if (passedRef == null) - closeGit(git); } public static File getAppData() { @@ -2306,32 +2482,31 @@ public static int versionCompare(String v1, String v2) { public static List getAllTags(String gitRepo) { ArrayList tags = new ArrayList<>(); - Git jGit = openGit(gitRepo); - List call; - try { - call = jGit.tagList().call(); - for (Ref ref : call) { - String string = ref.getName().split("/")[2]; - tags.add(string); - } - } catch (Throwable e) { - // TODO Auto-generated catch block - e.printStackTrace(); - - } - Collections.sort(tags, new Comparator() { - public int compare(String object1, String object2) { - return versionCompare(object1, object2); + openGit(gitRepo, jGit -> { + List call; + try { + call = jGit.tagList().call(); + for (Ref ref : call) { + String string = ref.getName().split("/")[2]; + tags.add(string); + } + } catch (Throwable e) { + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } + Collections.sort(tags, new Comparator() { + public int compare(String object1, String object2) { + return versionCompare(object1, object2); + } + }); }); - closeGit(jGit); return tags; } public static boolean tagExists(String remoteURI, String newTag) { List tags = getAllTags(remoteURI); for (String s : tags) { - System.out.println("Checking " + newTag + " against " + s); + com.neuronrobotics.sdk.common.Log.debug("Checking " + newTag + " against " + s); if (s.contentEquals(newTag)) { return true; } @@ -2340,18 +2515,16 @@ public static boolean tagExists(String remoteURI, String newTag) { } public static void tagRepo(String remoteURI, String newTag) { - System.out.println("Tagging " + remoteURI + " at " + newTag); + com.neuronrobotics.sdk.common.Log.debug("Tagging " + remoteURI + " at " + newTag); if (tagExists(remoteURI, newTag)) { - System.out.println("ERROR! Tag exists " + remoteURI + "@" + newTag); + com.neuronrobotics.sdk.common.Log.error("ERROR! Tag exists " + remoteURI + "@" + newTag); return; } - Git git = openGit(remoteURI); - // Creating tag - try { + openGit(remoteURI, git -> { try { git.tag().setName(newTag).setForceUpdate(true).call(); } catch (Throwable t) { - t.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(t); } if (git.getRepository().getConfig().getString("remote", "origin", "url").startsWith("git@")) git.push().setPushTags().setTransportConfigCallback(transportConfigCallback) @@ -2359,11 +2532,7 @@ public static void tagRepo(String remoteURI, String newTag) { else git.push().setPushTags().setCredentialsProvider(PasswordManager.getCredentialProvider()) .setProgressMonitor(getProgressMoniter("Pushing ", remoteURI)).call(); - } catch (GitAPIException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - closeGit(git); + }); } public static boolean isPrintProgress() { @@ -2373,32 +2542,41 @@ public static boolean isPrintProgress() { public static void setPrintProgress(boolean printProgress) { ScriptingEngine.printProgress = printProgress; } - - public static void ignore(String url,String filepattern) throws Exception { + + public static void ignore(String url, String filepattern) throws Exception { File ignorefile = fileFromGit(url, ".gitignore"); - String contents=""; - if(ignorefile.exists()) { + String contents = ""; + if (ignorefile.exists()) { BufferedReader reader; try { reader = new BufferedReader(new FileReader(ignorefile)); String line = reader.readLine(); while (line != null) { - if(line.contains(filepattern)) { - System.out.println(""+filepattern+" exists in "+ignorefile.getAbsolutePath()); + if (line.contains(filepattern)) { + com.neuronrobotics.sdk.common.Log + .debug("" + filepattern + " exists in " + ignorefile.getAbsolutePath()); reader.close(); return; } - contents+=line+"\n"; + contents += line + "\n"; // read next line line = reader.readLine(); } reader.close(); } catch (IOException e) { - e.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(e); } } - contents+=filepattern; - pushCodeToGit(url, null, ".gitignore", contents, "Adding ignore for "+filepattern); + contents += filepattern; + pushCodeToGit(url, null, ".gitignore", contents, "Adding ignore for " + filepattern); + } + + public static String getAppName() { + return appName; + } + + public static void setAppName(String appName) { + ScriptingEngine.appName = appName; } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/SequenceRunner.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/SequenceRunner.java index 3254ebb7c..1dd0f45c7 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/SequenceRunner.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/SequenceRunner.java @@ -19,16 +19,16 @@ public class SequenceRunner implements IScriptingLanguage { @Override - public Object inlineScriptRun(File code, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File code, ArrayList args) throws Exception { String jsonString = null; InputStream inPut = null; inPut = FileUtils.openInputStream(code); jsonString = IOUtils.toString(inPut); - return inlineScriptRun(jsonString, args); + return inlineScriptRun( db,jsonString, args); } @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) throws Exception { new TimeSequence().execute(code); return null; @@ -55,7 +55,7 @@ public String getDefaultContents() { @Override public ArrayList getFileExtenetion() { - // TODO Auto-generated method stub + // Auto-generated method stub return new ArrayList<>(Arrays.asList("sequence")); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/StlLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/StlLoader.java index 39f9216f9..c2c3275ad 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/StlLoader.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/StlLoader.java @@ -11,24 +11,24 @@ public class StlLoader implements IScriptingLanguage { @Override - public Object inlineScriptRun(File code, ArrayList args) throws Exception { - CSG sllLoaded = Vitamins.get(code); + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File code, ArrayList args) throws Exception { + CSG sllLoaded = Vitamins.get(db,code); return sllLoaded; } @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) throws Exception { throw new RuntimeException("This engine only supports files"); } @Override public String getShellType() { - // TODO Auto-generated method stub + // Auto-generated method stub return "Stl"; } @Override public boolean getIsTextFile() { - // TODO Auto-generated method stub + // Auto-generated method stub return false; } /** @@ -41,8 +41,8 @@ public String getDefaultContents() { } @Override public ArrayList getFileExtenetion() { - // TODO Auto-generated method stub - return new ArrayList<>(Arrays.asList("stl")); + // Auto-generated method stub + return new ArrayList<>(Arrays.asList("stl","STL","Stl")); } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/SvgLoader.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/SvgLoader.java index ab5e0256c..b6b3dfe47 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/SvgLoader.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/SvgLoader.java @@ -6,6 +6,8 @@ import java.util.HashMap; import java.util.List; +import com.neuronrobotics.bowlerstudio.util.GeometrySimplification; + import eu.mihosoft.vrl.v3d.CSG; import eu.mihosoft.vrl.v3d.Polygon; import eu.mihosoft.vrl.v3d.svg.SVGExporter; @@ -15,13 +17,21 @@ public class SvgLoader implements IScriptingLanguage { @Override - public Object inlineScriptRun(File code, ArrayList args) throws Exception { - SVGLoad s = new SVGLoad(code.toURI()); - return run(s); + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,File code, ArrayList args) throws Exception { + try { + SVGLoad s = new SVGLoad(code.toURI()); + return run(s); + }catch(Exception e) { + com.neuronrobotics.sdk.common.Log.error(e); + com.neuronrobotics.sdk.common.Log.error("SVG had error, attempting to fix "+code.getAbsolutePath()); + File tmp=GeometrySimplification.simplifySVG(code); + SVGLoad s = new SVGLoad(tmp.toURI()); + return run(s); + } } @Override - public Object inlineScriptRun(String code, ArrayList args) throws Exception { + public Object inlineScriptRun(eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance db,String code, ArrayList args) throws Exception { SVGLoad s = new SVGLoad(code); return run(s); } @@ -40,9 +50,11 @@ private Object run(SVGLoad s) { double depth =5+(layers.size()*5); for(int i=0;i extrudeLayerToCSG = s.extrudeLayer(depth,layerName); //extrudeLayerToCSG.setColor(Color.web(SVGExporter.colorNames.get(i))); - polys.add(extrudeLayerToCSG); + polys.addAll(extrudeLayerToCSG); depth-=5; } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/AbstractAddFrom.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/AbstractAddFrom.java new file mode 100644 index 000000000..3f454eb2d --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/AbstractAddFrom.java @@ -0,0 +1,53 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.io.File; +import java.nio.file.NoSuchFileException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import com.google.gson.annotations.Expose; + +public abstract class AbstractAddFrom extends CaDoodleOperation implements INamedOperation{ + @Expose (serialize = false, deserialize = false) + protected HashSet namesAdded = new HashSet<>(); + @Expose (serialize = false, deserialize = false) + protected int nameIndex = 0; + @Expose(serialize = true, deserialize = true) + protected String name = null; + public HashSet getNamesAdded() { + return namesAdded; + } + public List getNamesAddedInThisOperation(){ + ArrayList names= new ArrayList(); + names.addAll(getNamesAdded()); + return names; + } + + public String getName() { + if (name == null) { + name=(RandomStringFactory.generateRandomString()); + } + return name; + } + +// public void setName(String name) { +// this.name = name; +// } + + public String getOrderedName() { + String result= getName(); + if(nameIndex!=0){ + result+= "_"+nameIndex; + } + nameIndex++; + namesAdded.add(result); + return result; + } + + public abstract File getFile()throws NoSuchFileException; + @Override + public String toString() { + return getType()+" with name "+getName(); + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/AddFromFile.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/AddFromFile.java new file mode 100644 index 000000000..6fbd2494c --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/AddFromFile.java @@ -0,0 +1,391 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.awt.Color; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import static com.neuronrobotics.bowlerstudio.scripting.DownloadManager.*; +import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.bowlerstudio.vitamins.VitaminBomManager; +import com.neuronrobotics.sdk.addons.kinematics.VitaminLocation; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; +import com.neuronrobotics.sdk.common.Log; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Cube; +import eu.mihosoft.vrl.v3d.PropertyStorage; +import eu.mihosoft.vrl.v3d.Transform; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; +import eu.mihosoft.vrl.v3d.parametrics.StringParameter; + +public class AddFromFile extends AbstractAddFrom { + @Expose(serialize = true, deserialize = true) + private TransformNR location = null; + //private ArrayList options = new ArrayList(); + @Expose(serialize = true, deserialize = true) + private Boolean preventBoM = false; + + public AddFromFile set(File source, CaDoodleFile cf) { + setCaDoodleFile(cf); + for (String s : ScriptingEngine.getAllExtentions()) { + if (source.getName().toLowerCase().endsWith(s.toLowerCase())) { + toLocal(source, getName(),cf); + try { + getFile(); + } catch (NoSuchFileException e) { + // TODO Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + break; + } + return this; + } + } + throw new RuntimeException("File Extention not supported: " + source.getName()); + } + + @Override + public String getType() { + return "Add Object"; + } + + @Override + public List process(List incoming) { + nameIndex = 0; + ArrayList back = new ArrayList(); + back.addAll(incoming); + if (getName() == null) { + + } + CSGDatabaseInstance instance = getCaDoodleFile().getCsgDBinstance(); + try { +// ArrayListargs = new ArrayList<>(); +// args.addAll(Arrays.asList(getName() )); + ArrayList collect = new ArrayList<>(); + File file = getFile(); + if (!file.exists()) { + throw new RuntimeException("Failed to find file"); + } + + ArrayList args = new ArrayList<>(); + args.addAll(Arrays.asList(name)); + HashMap configs = new HashMap(); + configs.put("name", name); + configs.put("PreventBomAdd", preventBoM); + args.add(configs); + boolean isDoodle = file.getName().toLowerCase().endsWith(".doodle"); +// if(isDoodle) { +// Path tempFile = Files.createTempFile("CSGDatabase", ".tmp"); +// instance=(new CSGDatabaseInstance(tempFile.toFile())); +// } + List flattenedCSGs; + try { + flattenedCSGs = ScriptingEngine.flaten(instance,file, CSG.class, args); + }catch(Throwable t) { + com.neuronrobotics.sdk.common.Log.error(t); + flattenedCSGs=new ArrayList(); + flattenedCSGs.add(new Cube(10).toCSG().setColor(javafx.scene.paint.Color.HOTPINK)); + } + for (int i = 0; i < flattenedCSGs.size(); i++) { + CSG csg = flattenedCSGs.get(i); + if(isDoodle && csg.isInGroup()) + continue; + try { + CSG processedCSG = processGiven(csg, i, getOrderedName(),file,name,getLocation(),getCaDoodleFile().getCsgDBinstance()); + collect.add(processedCSG); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + } + } + //CSGDatabase.setInstance(instance); + for(CSG csg1:collect) + csg1.setParameter(getCaDoodleFile().getCsgDBinstance(),getFileLocationparam(getCaDoodleFile().getCsgDBinstance(),file,name)); + back.addAll(collect); + } catch (Exception e) { + //CSGDatabase.setInstance(instance); + Log.error(e); + throw new RuntimeException(e); + } + return back; + } + + public static File copyFileToNewDirectory(File sourceFile, File targetDirectory, String newBaseName) + throws IOException { + if (!sourceFile.exists()) { + throw new IOException("Source file does not exist: " + sourceFile.getAbsolutePath()); + } + + if (!targetDirectory.exists()) { + if (!targetDirectory.mkdirs()) { + throw new IOException("Failed to create target directory: " + targetDirectory.getAbsolutePath()); + } + } + + String fileName = sourceFile.getName(); + String fileExtension = ""; + int dotIndex = fileName.lastIndexOf('.'); + if (dotIndex > 0 && dotIndex < fileName.length() - 1) { + fileExtension = fileName.substring(dotIndex); + } + + String newFileName = newBaseName + fileExtension; + File targetFile = new File(targetDirectory, newFileName); + + Path sourcePath = sourceFile.toPath(); + Path targetPath = targetFile.toPath(); + + Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING); + return targetFile; + } + + public static File toLocal(File file, String name,CaDoodleFile cf ) { + if(cf==null) + return file; + File parentFileIncoming = file.getParentFile(); + String strValue = cf.getSelf().getAbsolutePath(); + File parentFile = new File(strValue).getParentFile(); + String source = parentFile.getAbsolutePath(); + boolean isDoodle = file.getName().toLowerCase().endsWith(".doodle"); + if (parentFileIncoming != null) { + String parentIncoming = parentFileIncoming.getAbsolutePath(); + String lowerCase = parentIncoming.toLowerCase(); + String lowerCase2 = source.toLowerCase(); + boolean namesNotEqual = !lowerCase.contentEquals(lowerCase2); + boolean exists = file.exists(); + if (namesNotEqual && exists) { + if (!isDoodle) { + File copied; + try { + copied = copyFileToNewDirectory(file, parentFile, name); + file = copied; + } catch (IOException e) { + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + } else { + // doodle copy + File doodleParent = file.getParentFile(); + File targetParent = new File(parentFile.getAbsoluteFile() + delim() + name); + targetParent.mkdirs(); + recursiveCopy(doodleParent.getAbsolutePath(),targetParent.getAbsolutePath()); + file = new File(targetParent.getAbsolutePath()+delim()+file.getName()); + try { + CaDoodleFile f = CaDoodleFile.fromFile(file); + f.setProjectName(cf.getMyProjectName()+"->"+f.getMyProjectName()); + f.save(); + } catch (Exception e) { + com.neuronrobotics.sdk.common.Log.error(e); + throw new RuntimeException(e); + } + } + } + } + return file; + } + + /** + * Recursively copies all files and folders from the source directory to the + * target directory. + * + * @param sourceDir The source directory path + * @param targetDir The target directory path + * @return true if the copy operation was successful, false otherwise + */ + public static boolean recursiveCopy(String sourceDir, String targetDir) { + File source = new File(sourceDir); + File target = new File(targetDir); + + // Validate inputs + if (!source.exists()) { + System.err.println("Error: Source directory '" + sourceDir + "' does not exist."); + return false; + } + + if (!source.isDirectory()) { + System.err.println("Error: Source '" + sourceDir + "' is not a directory."); + return false; + } + if(source.getName().contentEquals("timeline")) + return true; + + // Create target directory if it doesn't exist + if (!target.exists()) { + if (!target.mkdirs()) { + System.err.println("Error: Could not create target directory '" + targetDir + "'."); + return false; + } + com.neuronrobotics.sdk.common.Log.debug("Created target directory: " + targetDir); + } + + try { + return copyDirectory(source, target); + } catch (IOException e) { + System.err.println("Error during copy operation: " + e.getMessage()); + return false; + } + } + + /** + * Helper method to copy a directory recursively. + * + * @param sourceDir The source directory + * @param targetDir The target directory + * @return true if the copy operation was successful + * @throws IOException If an I/O error occurs + */ + private static boolean copyDirectory(File sourceDir, File targetDir) throws IOException { + // Get all files and directories in the source directory + File[] files = sourceDir.listFiles(); + + if (files == null) { + System.err.println("Warning: Could not list contents of directory: " + sourceDir.getAbsolutePath()); + return false; + } + + for (File file : files) { + // Construct the target path + File targetFile = new File(targetDir, file.getName()); + + if (file.isDirectory()) { + // Create the target directory if it doesn't exist + if (!targetFile.exists() && !targetFile.mkdirs()) { + System.err.println("Error: Could not create directory: " + targetFile.getAbsolutePath()); + return false; + } + + // Recursively copy the subdirectory + if (!copyDirectory(file, targetFile)) { + return false; + } + } else { + // Copy the file, preserving attributes + try { + Path sourcePath = file.toPath(); + Path targetPath = targetFile.toPath(); + + Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING, + StandardCopyOption.COPY_ATTRIBUTES); + + com.neuronrobotics.sdk.common.Log.debug("Copied: " + sourcePath + " -> " + targetPath); + } catch (IOException e) { + System.err.println("Error copying file " + file.getAbsolutePath() + ": " + e.getMessage()); + throw e; + } + } + } + + return true; + } + + public static File getFile(String name,CaDoodleFile cf) { + String strValue = cf.getSelf().getAbsolutePath(); + File parentFile = new File(strValue).getParentFile(); + for (File f : parentFile.listFiles()) { + if (f.getName().contains(name)) { + if (f.isDirectory()) { + // is a doodle file + for (File d : f.listFiles()) { + if (d.getName().toLowerCase().endsWith(".doodle")) { + return d; + } + } + } else { + for (String s : ScriptingEngine.getAllExtentions()) { + if (f.getName().toLowerCase().endsWith(s.toLowerCase())) { + return f; + } + } + } + } + + } + throw new RuntimeException("File not found! " + name); + } +// +// private String getStrValue() { +// +// return getParameter("UnKnown").getStrValue(); +// } + + private static CSG processGiven(CSG csg, int i, String name, File f,String task,TransformNR location,CSGDatabaseInstance instance) { + Transform nrToCSG = TransformFactory.nrToCSG(location); + boolean isDoodle = f.getName().toLowerCase().endsWith(".doodle"); + if(isDoodle) { + csg.setStorage(new PropertyStorage()); + } + + CSG processedCSG = csg + .transformed(nrToCSG).syncProperties(instance,csg).setRegenerate(previous -> { + try { + File file =f; + //CSGDatabaseInstance instance = CSGDatabase.getInstance(); + CSGDatabaseInstance instancetmp = null; + + if(isDoodle) { + Path tempFile = Files.createTempFile("CSGDatabase", ".tmp"); + instancetmp = new CSGDatabaseInstance(tempFile.toFile()); + //CSGDatabase.setInstance(instancetmp); + } + String fileLocation = file.getAbsolutePath(); + com.neuronrobotics.sdk.common.Log.error("Regenerating " + fileLocation); + List flattenedCSGs = ScriptingEngine.flaten(instancetmp,file, CSG.class, null); + + CSG csg1 = flattenedCSGs.get(i); + if(isDoodle) { + csg1.setStorage(new PropertyStorage()); + } + //CSGDatabase.setInstance(instance); + csg1.setParameter(instance,getFileLocationparam(instance,f,task)); + return processGiven(csg1, i, name,f,task,location,instance); + } catch (Exception e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + return previous; + }).setName(name); + MoveCenter.set(task, processedCSG, nrToCSG); + return processedCSG; + } + + private static StringParameter getFileLocationparam(CSGDatabaseInstance instance, File pathname,String task) { + StringParameter stringParameter = new StringParameter(instance,task + "_CaDoodle_File", pathname.getAbsolutePath(), new ArrayList()); + stringParameter.setStrValue(pathname.getAbsolutePath()); + return stringParameter; + } + + public TransformNR getLocation() { + if (location == null) + location = new TransformNR(); + return location; + } + + public AddFromFile setLocation(TransformNR location) { + this.location = location; + return this; + } + + public Boolean getPreventBoM() { + return preventBoM; + } + + public AddFromFile setPreventBoM(Boolean preventBoM) { + this.preventBoM = preventBoM; + return this; + } + + @Override + public File getFile() throws NoSuchFileException { + return getFile(name,getCaDoodleFile()); + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/AddFromScript.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/AddFromScript.java new file mode 100644 index 000000000..e3eda1020 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/AddFromScript.java @@ -0,0 +1,137 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import org.eclipse.jgit.api.errors.GitAPIException; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; +import com.neuronrobotics.sdk.common.Log; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.PropertyStorage; +import eu.mihosoft.vrl.v3d.Transform; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; + +public class AddFromScript extends AbstractAddFrom { + @Expose(serialize = true, deserialize = true) + private String gitULR = ""; + @Expose(serialize = true, deserialize = true) + private String fileRel = ""; + + @Expose(serialize = true, deserialize = true) + private TransformNR location =null; + @Expose(serialize = true, deserialize = true) + private Boolean preventBoM = false; + + public AddFromScript set(String git, String f) { + gitULR = git; + fileRel = f; + return this; + } + + @Override + public String getType() { + return "Add Object"; + } + + @Override + public List process(List incoming) { + return process(incoming, fileRel); + } + + public List process(List incoming, String fileName) { + + nameIndex = 0; + ArrayList back = new ArrayList(); + back.addAll(incoming); + boolean isDoodle = fileName.toLowerCase().endsWith(".doodle"); + + try { + ArrayList args = new ArrayList<>(); + args.addAll(Arrays.asList(getName())); + HashMap configs = new HashMap(); + configs.put("name", getName()); + configs.put("PreventBomAdd", preventBoM); + args.add(configs); + CSGDatabaseInstance instance = getCaDoodleFile().getCsgDBinstance(); + if(isDoodle) { + Path tempFile = Files.createTempFile("CSGDatabase", ".tmp"); + instance=(new CSGDatabaseInstance(tempFile.toFile())); + } + List flaten = ScriptingEngine.flaten(instance,gitULR, fileName, CSG.class, args); + for(CSG c:flaten) + for(String s:c.getParameters(instance)) { + Log.debug("Parameter added "+s); + } + ArrayList collect = new ArrayList<>(); + collect.addAll(flaten); + for(int i=0;i names = new ArrayList(); + @Expose (serialize = true, deserialize = true) + public Allignment z=null; + @Expose (serialize = true, deserialize = true) + public Allignment y=null; + @Expose (serialize = true, deserialize = true) + public Allignment x=null; + @Expose (serialize = true, deserialize = true) + private TransformNR workplane=null; + @Expose (serialize = true, deserialize = true) + public StoragbeBounds bounds=null; + @Expose(serialize = true, deserialize = true) + protected String name = null; + public String getName() { + if (name == null) { + setName(RandomStringFactory.generateRandomString()); + } + return name; + } + + public void setName(String name) { + this.name = name; + } + @Override + public String getType() { + return "Allign"; + } + + @Override + public String toString(){ + String string = getType()+" "+x+" "+y+" "+z; + for(String n:getNamesAddedInThisOperation()) { + string+=" "+n; + } + return string; + } + + @Override + public List process(List incoming) { + ArrayList back = new ArrayList(); + back.addAll(incoming); + + Bounds bounds2 ;// + if(bounds!=null) { + bounds2=bounds.getBounds(); + }else { + throw new RuntimeException("Allign can not be initialized without bounds!"); + } + HashMap moves= new HashMap<>(); + HashMap objects = new HashMap(); + for(String name :names) { + for(CSG tmp:back) { + if(!tmp.getName().contentEquals(name)) + continue; + objects.put(name, tmp); + CSG c = tmp.transformed(TransformFactory.nrToCSG(getWorkplane(tmp)).inverse()); + TransformNR tf = performTransform(bounds2, c); + moves.put(c.getName(),tf); + } + } + for(String name:moves.keySet()) { + TransformNR nr = moves.get(name); + TransformNR wp = getWorkplane(objects.get(name)); + TransformNR wpinv = wp.inverse(); + + TransformNR times = wp.times(nr.times(wpinv)); + Transform tf = TransformFactory.nrToCSG(times); + CaDoodleFile.applyToAllConstituantElements(false, name, back, (incoming1, depth) ->{ + ArrayList b = new ArrayList<>(); + CSG c=incoming1.transformed(tf); + sync(incoming1,c); + MoveCenter.set(getName() , c, times); + b.add(c); + return b; + }, 1,new HashSet()); + } + return back; + } + +// private void collectToMove(ArrayList toMove, ArrayList back, String name) { +// ArrayList toSearch = new ArrayList(); +// toSearch.addAll(back); +// for (int i = 0; i < toSearch.size(); i++) { +// CSG c = toSearch.get(i); +// if(name.contentEquals(c.getName())) { +// toMove.add(c); +// } +// } +// } + + private TransformNR performTransform(Bounds reference, CSG incoming) { + //CSG c = incoming; + double tx=0,ty=0,tz=0; + if(z!=null) { + switch(z) { + case negative: + tz=-incoming.getMinZ()+reference.getMinZ(); + break; + case middle: + tz=-incoming.getCenterZ()+reference.getCenterZ(); + break; + case positive: + tz=-incoming.getMaxZ()+reference.getMaxZ(); + break; + default: + break; + } + } + if(x!=null) { + switch(x) { + case negative: + tx=-incoming.getMinX()+reference.getMinX(); + break; + case middle: + tx=-incoming.getCenterX()+reference.getCenterX(); + break; + case positive: + tx=-incoming.getMaxX()+reference.getMaxX(); + break; + default: + break; + + } + } + if(y!=null) { + switch(y) { + case negative: + ty=-incoming.getMinY()+reference.getMinY(); + break; + case middle: + ty=-incoming.getCenterY()+reference.getCenterY(); + break; + case positive: + ty=-incoming.getMaxY()+reference.getMaxY(); + break; + default: + break; + + } + } + return new TransformNR(tx,ty,tz); + } + + private CSG sync(CSG incoming, CSG c) { + return c.syncProperties(getCaDoodleFile().getCsgDBinstance(),incoming).setName(incoming.getName()).setColor(incoming.getColor()); + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public Allign setNames(List names) { + this.names = names; + return this; + } + public Allign setAllignParams(Allignment X, Allignment Y,Allignment Z) { + x=X; + y=Y; + z=Z; + return this; + } + + public TransformNR getWorkplane(CSG c) { + if(workplane==null) + workplane= new TransformNR(); + Affine af = c.getManipulator(); + TransformNR afNR = TransformFactory.affineToNr(af).inverse(); + return afNR.times(workplane); + } + + public Allign setWorkplane(TransformNR workplane) { + this.workplane = workplane; + return this; + } + + public Bounds getBounds() { + return bounds.getBounds(); + } + + public Allign setBounds(Bounds bounds) { + this.bounds = new StoragbeBounds(bounds); + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Allignment.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Allignment.java new file mode 100644 index 000000000..e2759593a --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Allignment.java @@ -0,0 +1,7 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +public enum Allignment { + positive, + negative, + middle, +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleFile.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleFile.java new file mode 100644 index 000000000..950d12b22 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleFile.java @@ -0,0 +1,1375 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.Type; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; + +import javax.imageio.ImageIO; +import javafx.scene.image.WritableImage; +import org.apache.commons.io.FileUtils; +import org.apache.hc.client5.http.impl.Operations; +import org.python.google.common.io.Files; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import com.google.gson.reflect.TypeToken; +import com.neuronrobotics.bowlerstudio.BowlerKernel; +import com.neuronrobotics.bowlerstudio.creature.MobileBaseBuilder; +import com.neuronrobotics.bowlerstudio.creature.ThumbnailImage; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.bowlerstudio.scripting.DownloadManager; +import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.MakeRobot; +import com.neuronrobotics.bowlerstudio.vitamins.VitaminBomManager; +import com.neuronrobotics.sdk.addons.kinematics.MobileBase; +import com.neuronrobotics.sdk.addons.kinematics.VitaminLocation; +import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; +import com.neuronrobotics.sdk.common.Log; +import com.neuronrobotics.sdk.common.TickToc; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.FileUtil; +import eu.mihosoft.vrl.v3d.Polygon; +import eu.mihosoft.vrl.v3d.PropertyStorage; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; +import eu.mihosoft.vrl.v3d.parametrics.IParametric; +import eu.mihosoft.vrl.v3d.parametrics.Parameter; +import eu.mihosoft.vrl.v3d.parametrics.StringParameter; +import javafx.application.Platform; +import javafx.embed.swing.SwingFXUtils; + +import static com.neuronrobotics.bowlerstudio.scripting.DownloadManager.*; + +public class CaDoodleFile { + public static final String NO_NAME = "NoName"; + @Expose(serialize = true, deserialize = true) + private ArrayList opperations = new ArrayList(); + @Expose(serialize = true, deserialize = true) + private int currentIndex = 0; + @Expose(serialize = true, deserialize = true) + private long timeCreated = -1; + @Expose(serialize = true, deserialize = true) + private String projectName = NO_NAME; + @Expose(serialize = true, deserialize = true) + private TransformNR rulerLocation = new TransformNR(); + @Expose(serialize = true, deserialize = true) + + // Non Serialised private variables + private TransformNR workplane = new TransformNR(); + private File self; +// @Expose (serialize = false, deserialize = false) +// private List currentState = new ArrayList(); + private double percentInitialized = 0; + private final HashMap> cache = new HashMap>(); + private static Type TT_CaDoodleFile = new TypeToken() { + }.getType(); + private static Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting() + .excludeFieldsWithoutExposeAnnotation() + .registerTypeAdapterFactory(new CaDoodleJsonOperationAdapterFactory()).create(); + private final ArrayList listeners = new ArrayList(); + private final ArrayList opperationRunner = new ArrayList(); + private boolean regenerating; + private final CopyOnWriteArrayList toProcess = new CopyOnWriteArrayList(); + private javafx.scene.image.WritableImage img; + private boolean initializing; + private static HashMap bomManagers = new HashMap<>(); + private VitaminBomManager bom; + private IAcceptPruneForward accept = null; + private long timeOfLastUpdate = 0; + private OperationResult result = OperationResult.APPEND; + private ICadoodleSaveStatusUpdate defaultSaver = new ICadoodleSaveStatusUpdate() { + @Override + public void renderSplashFrame(int percent, String message) { + com.neuronrobotics.sdk.common.Log.debug(percent + "% " + message); + } + }; + private ICadoodleSaveStatusUpdate saveUpdate = null; + private boolean timelineOpen = false; + private HashMap robots = new HashMap(); + private CSGDatabaseInstance csgDBinstance; + private File objectDir; + + public ArrayList getMobileBases() { + ArrayList back = new ArrayList(); + for (MobileBaseBuilder b : robots.values()) { + back.add(b.getMobileBase()); + } + return back; + } + + public void close() { + // new Exception("CaDoodle File Closed here").printStackTrace(); + for (CaDoodleOperation op : getOpperations()) { + op.setCaDoodleFile(null); + } +// for (CaDoodleOperation op : cache.keySet()) { +// clearCache(op); +// } +// cache.clear(); + clearListeners(); + toProcess.clear(); + img = null; + for (Thread t : opperationRunner) + t.interrupt(); + + } + + private int opToIndex(CaDoodleOperation op) { + for (int i = 0; i < opperations.size(); i++) { + if (op == opperations.get(i)) + return i; + } + throw new IndexOutOfBoundsException(); + } + + private boolean inCache(CaDoodleOperation op) { + int opIndex = opToIndex(op); + File cacheFile = new File(objectDir.getAbsolutePath() + delim() + opIndex); + return cacheFile.exists(); + } + + private List getCachedCSGs(CaDoodleOperation op) { + if (Platform.isFxApplicationThread()) { + new RuntimeException("This should not be called from the UI thread!").printStackTrace();; + } + if (cache.get(op) == null && objectDir !=null) { + try { + int opIndex = opToIndex(op); + File cacheFile = new File(objectDir.getAbsolutePath() + delim() + opIndex); + if(cacheFile.exists()) { + Log.debug("Loading Cached Objects from file: " + cacheFile.getAbsolutePath()); + // Log.error(new Exception()); + ObjectInputStream ois = new ObjectInputStream(new FileInputStream(cacheFile)); + memoryCheck(); + cache.put(op, (List) ois.readObject()); + ois.close(); + } + } catch (Exception ex) { + Log.error(ex); + } + } + return cache.get(op); + } + + private void memoryCheck() { + if (getFreeMemory() > 75) { + com.neuronrobotics.sdk.common.Log.error("\n\nClearing Memory use: " + getFreeMemory() + "\n\n"); +// Set keySet = cache.keySet(); +// int index = 0; +// for (CaDoodleOperation op : keySet) { +// List cachedCopy = cache.get(op); +// getSaveUpdate().renderSplashFrame((int) (((double) index) / ((double) keySet.size()) * 100), +// "Clearing Ram to Disk"); +// int opIndex = opToIndex(op); +// File cacheFile = new File(objectDir.getAbsolutePath() + delim() + opIndex); +// if (!isInitialized()) +// if (cacheFile.exists()) +// return; +// if (cacheFile.exists()) +// cacheFile.delete(); +// try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(cacheFile))) { +// oos.writeObject(cachedCopy); +// Log.debug("Saved " + cacheFile.getAbsolutePath()); +// } catch (Exception ex) { +// Log.error(ex); +// throw new RuntimeException(ex); +// } +// index++; +// } +// cache.clear(); + System.gc(); + } else { + // com.neuronrobotics.sdk.common.Log.debug("Memory use: " + getFreeMemory()); + } + } + + private void placeCSGsInCache(CaDoodleOperation op, List cachedCopy) { + memoryCheck(); + // clear the stale cache value + List back = cache.remove(op); + if (back != null) + back.clear(); + cache.put(op, cachedCopy); + } + + private void clearCache(CaDoodleOperation key) { + int opIndex = opToIndex(key); + File cacheFile = new File(objectDir.getAbsolutePath() + delim() + opIndex); + if (cacheFile.exists()) + cacheFile.delete(); + + List back = cache.remove(key); + if (back != null) + back.clear(); + } + + public CaDoodleFile clearListeners() { + listeners.clear(); + return this; + } + + public CaDoodleFile removeListener(ICaDoodleStateUpdate l) { + if (listeners.contains(l)) + listeners.remove(l); + return this; + } + + public CaDoodleFile addListener(ICaDoodleStateUpdate l) { + if (!listeners.contains(l)) + listeners.add(l); + return this; + } + + public void initialize() { +// if (initializing) +// throw new RuntimeException("Can not initialize while initializing."); + fireInitializationStart(); + initializing = true; + if (timeCreated < 0) + timeCreated = System.currentTimeMillis(); + if (self != null) { + File parent = self.getAbsoluteFile().getParentFile(); + File imageCacheDir = new File(parent.getAbsolutePath() + delim() + "timeline"); + if (!imageCacheDir.exists()) + imageCacheDir.mkdir(); + objectDir = new File(parent.getAbsolutePath() + delim() + "timeline" + delim() + "objectCache"); + if (!objectDir.exists()) + objectDir.mkdir(); + File db = new File(self.getAbsoluteFile().getParent() + delim() + "CSGdatabase.json"); + setCsgDBinstance(new CSGDatabaseInstance(db)); + // CSGDatabase.setInstance(getCsgDBinstance()); + bom = CaDoodleFile.getBillOfMaterials(this); + bom.clear(); + bom.save(); + } + int indexStarting = getCurrentIndex(); + if (indexStarting == 0) { + indexStarting = opperations.size(); + } + this.currentIndex = 0; + setPercentInitialized(0); + opperations = opperations.stream().filter(Objects::nonNull).collect(Collectors.toCollection(ArrayList::new)); + if (indexStarting > opperations.size()) + indexStarting = opperations.size(); + for (int i = 0; i < getOpperations().size(); i++) { + CaDoodleOperation op = getOpperations().get(i); + if (op == null) + continue; + setPercentInitialized(((double) i) / (double) getOpperations().size()); + // if(!inCache(op)) + try { + process(op); + } catch (Throwable t) { + com.neuronrobotics.sdk.common.Log.error(t); + indexStarting = i + 1; + break; + // opperations.remove(op); + } + } + setCurrentIndex(indexStarting); + updateCurrentFromCache(); + loadImageFromFile(); + setPercentInitialized(1); + for (ICaDoodleStateUpdate l : listeners) { + try { + l.onInitializationDone(); + } catch (Throwable e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + } + updateBoM(); + initializing = false; + } + + private void updateBoM() { + if (bom == null) + return; + bom.clear(); + bom.save(); + for (CSG c : getCurrentState()) { + String type = null; + String size = null; + for (String param : c.getParameters(getCsgDBinstance())) { + if (!param.contains(c.getName())) + continue; + if (param.contains("_CaDoodle_Vitamin_Type")) { + Parameter p = getCsgDBinstance().get(param); + type = p.getStrValue(); + } + if (param.contains("_CaDoodle_Vitamin_Size")) { + Parameter p = getCsgDBinstance().get(param); + size = p.getStrValue(); + } + if (type != null && size != null) { + bom.addVitamin(new VitaminLocation(false, c.getName(), type, size, new TransformNR())); + break; + } + } + } + bom.save(); + } + + public static VitaminBomManager getBillOfMaterials(CaDoodleFile cf) { + + String strValue = cf.getSelf().getAbsolutePath(); + File file = new File(strValue).getParentFile(); + if (bomManagers.get(strValue) == null) { + bomManagers.put(strValue, new VitaminBomManager(file)); + } + return bomManagers.get(strValue); + } + +// private static String getCadoodleFileLocation() { +// +// return get; +// } + + public Thread regenerateFrom(CaDoodleOperation source) { + if (initializing) + return null; + if (isRegenerating() || isOperationRunning() || source == null) { + com.neuronrobotics.sdk.common.Log.error(new Exception("Operation Running, bailing")); + return null; + } + fireRegenerateStart(source); + int endIndex = getCurrentIndex(); + double size = getOpperations().size(); + if (endIndex != size) { +// new Exception("Regenerationg from a position back in time " + endIndex + " but have " + size) +// .printStackTrace(); + } + Thread t = null; + CaDoodleFile cf = this; + + t = new Thread() { + public void run() { + this.setName("Regeneration Threads"); + try { + timeOfLastUpdate = System.currentTimeMillis(); + setRegenerating(true); + // com.neuronrobotics.sdk.common.Log.error("Regenerating Object from + // "+source.getType()); + int opIndex = 0; + for (int i = 0; i < size; i++) { + CaDoodleOperation op = getOpperations().get(i); + if (source == op) { + opIndex = i; + break; + } + } + setCurrentIndex(opIndex); + try { + for (; getCurrentIndex() < size;) { + int percent = (int) (((double) getCurrentIndex()) / ((double) getOpperations().size()) + * 100.0); + setCurrentIndex(getCurrentIndex() + 1); + setPercentInitialized(((double) getCurrentIndex()) / size); + // com.neuronrobotics.sdk.common.Log.error("Regenerating "+currentIndex); + int currentIndex2 = getCurrentIndex() - 1; + CaDoodleOperation op = getOpperations().get(currentIndex2); + getSaveUpdate().renderSplashFrame(percent, + "Regenerating " + op.getType() + " " + currentIndex2); + getTimelineImageFile(op).delete(); + // clearCache(op); + try { + op.setCaDoodleFile(cf); + List process = op.process(getPreviouState()); + storeResultInCache(op, process); + setCurrentState(op, process); + } catch (Throwable tr) { + com.neuronrobotics.sdk.common.Log.error(tr); + } + } + if (getCurrentIndex() != endIndex) { + setCurrentIndex(endIndex); + updateCurrentFromCache(); + } + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex); + ; + } + setPercentInitialized(1); + updateBoM(); + setRegenerating(false); + fireSaveSuggestion(); + fireRegenerateDone(); + } catch (Throwable th) { + com.neuronrobotics.sdk.common.Log.error(th); + } + opperationRunner.remove(this); + } + }; + opperationRunner.add(t); + t.start(); + return t; + } + + public Thread regenerateCurrent() { + if (isOperationRunning()) { + com.neuronrobotics.sdk.common.Log.error(new Exception("Operation Running, bailing")); + + return opperationRunner.get(0); + } + if (initializing) { + Thread t = new Thread(); + t.start(); + return t; + } + CaDoodleOperation op = getCurrentOpperation(); + + fireRegenerateStart(op); + Thread t = null; + CaDoodleFile cf = this; + t = new Thread() { + public void run() { + timeOfLastUpdate = System.currentTimeMillis(); + + // TickToc.setEnabled(true); + + this.setName("regenerateCurrent Thread"); + + TickToc.tic("Start regenerate"); + op.setCaDoodleFile(cf); + List process = op.process(getPreviouState()); + TickToc.tic("Finish regenerate"); + int currentIndex2 = getCurrentIndex(); + getTimelineImageFile(currentIndex2).delete(); + TickToc.tic("Get timeline file"); + storeResultInCache(op, process); + TickToc.tic("Stored results in cache"); + setCurrentState(op, process); + TickToc.tic("set current state"); + fireSaveSuggestion(); + TickToc.tic("Fired save suggestion"); + fireRegenerateDone(); + TickToc.tic("Fired regeneration Done"); + opperationRunner.remove(this); + } + }; + opperationRunner.add(t); + t.start(); + return t; + + } + + private void process(CaDoodleOperation op) { + op.setCaDoodleFile(this); + List process = op.process(getCurrentState()); + if (MakeRobot.class.isInstance(op)) { + MakeRobot mr = (MakeRobot) op; + getRobots().put(mr.getName(), mr.getBuilder()); + } + int currentIndex2 = getCurrentIndex(); + storeResultInCache(op, process); + setCurrentIndex(currentIndex2 + 1); + setCurrentState(op, process); + + } + + public boolean isOperationRunning() { + for (int i = 0; i < opperationRunner.size(); i++) { + Thread t = opperationRunner.get(i); + if (t != null) { + if (!t.isAlive()) { + opperationRunner.remove(t); + // new Exception("Thread failed to remove itself + // "+t.getName()).printStackTrace(); + continue; + } + if (Thread.currentThread().getId() == t.getId()) + return false; + return true; + } + } + return false; + } + + public Thread addOpperation(CaDoodleOperation o) throws CadoodleConcurrencyException { + if (o == null) + throw new NullPointerException(); + toProcess.add(o); + if (isOperationRunning()) { + com.neuronrobotics.sdk.common.Log.error(new Exception("Operation Running, bailing")); + return opperationRunner.get(0); + } + Thread t = null; + t = new Thread() { + public void run() { + + timeOfLastUpdate = System.currentTimeMillis(); + while (toProcess.size() > 0) { + result = OperationResult.APPEND; + this.setName("addOpperation Thread " + toProcess.size()); + CaDoodleOperation op = toProcess.remove(0); + com.neuronrobotics.sdk.common.Log.debug("Adding Operation " + op); + if (getCurrentIndex() != getOpperations().size()) { + try { + fireRegenerateStart(op); + setResult(pruneForward(op)); + } catch (Exception e) { + com.neuronrobotics.sdk.common.Log.error(e); + break; + } + } + if (getResult() == OperationResult.APPEND || getResult() == OperationResult.PRUNE) { + try { + getOpperations().add(op); + process(op); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex); + ; + } + } + if (getResult() == OperationResult.INSERT) { + getOpperations().add(getCurrentIndex(), op); + process(op); + try { + regenerateFrom(op).join(); + } catch (InterruptedException e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + updateCurrentFromCache(); + } + if (getResult() == OperationResult.ABORT) { + setCurrentState(getCurrentOpperation(), getCurrentState()); + } + updateBoM(); + fireSaveSuggestion(); + fireRegenerateDone(); + } + opperationRunner.remove(this); + } + }; + opperationRunner.add(t); + t.start(); + return t; + } + + public Thread deleteOperation(CaDoodleOperation op) { + if (op == null) + throw new NullPointerException(); + if (isOperationRunning()) { + com.neuronrobotics.sdk.common.Log.error(new Exception("Operation Running, bailing")); + return opperationRunner.get(0); + } + Thread t = null; + t = new Thread() { + public void run() { + timeOfLastUpdate = System.currentTimeMillis(); + this.setName("addOpperation Thread " + toProcess.size()); + int index = 0; + for (int i = 0; i < getOpperations().size(); i++) + if (getOpperations().get(i) == op) + index = i; + getOpperations().remove(op); + op.pruneCleanup(); +// if (index == getOpperations().size()) +// index -= 1; + if (index < 1) + index = 1; + CaDoodleOperation newTar = getOpperations().get(index - 1); + setCurrentIndex(index); + try { + regenerateFrom(newTar).join(); + } catch (InterruptedException e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + updateCurrentFromCache(); + updateBoM(); + fireSaveSuggestion(); + opperationRunner.remove(this); + } + }; + opperationRunner.add(t); + t.start(); + return t; + } + + public static CSG getByName(List back, String name) { + for (CSG c : back) { + if (c.getName().contentEquals(name)) + return c; + } + throw new RuntimeException("Fail! there was no object named " + name); + } + + public static int applyToAllConstituantElements(boolean addRet, List targetNames, ArrayList back, + ICadoodleRecursiveEvent p, int depth) { + HashSet appliedMemory = new HashSet(); + for (int i = 0; i < targetNames.size(); i++) { + String s = targetNames.get(i); + try { + CSG c = getByName(back, s); + if (c.isInGroup()) + continue; + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex); + ; + } + applyToAllConstituantElements(addRet, s, back, p, depth, appliedMemory); + } + return back.size(); + } + + public static int applyToAllConstituantElements(boolean addRet, String targetName, ArrayList back, + ICadoodleRecursiveEvent p, int depth, HashSet appliedMemory) { + if (appliedMemory.contains(targetName)) + return back.size(); + appliedMemory.add(targetName); + ArrayList immutable = new ArrayList<>(); + immutable.addAll(back); + for (int i = 0; i < immutable.size(); i++) { + CSG csg = immutable.get(i); + if ( csg==null || csg.isLock()) + continue; + // boolean inGroup = csg.isInGroup(); + boolean thisCSGIsInGroupNamedAfterTarget = csg.checkGroupMembership(targetName); + String thisCSGName = csg.getName(); + boolean thisCSGIsTheTarget = thisCSGName.contentEquals(targetName); + boolean groupResult = csg.isGroupResult(); + + if (thisCSGIsTheTarget) { + // move it + ArrayList tmpToAdd = p.process(csg, depth); + if (addRet) { + back.addAll(tmpToAdd); + } else { + for (int j = 0; j < back.size(); j++) { + if (back.get(j).getName().contentEquals(csg.getName())) { + back.remove(j); + break; + } + } + back.addAll(tmpToAdd); + } + continue; + } + if (thisCSGIsInGroupNamedAfterTarget) { + // composite group + applyToAllConstituantElements(addRet, thisCSGName, back, p, depth + 1, appliedMemory); + } + } + back.removeAll(Collections.singleton(null)); + return back.size(); + } + + public File getTimelineImageFile(CaDoodleOperation test) { + for (int i = 0; i < getOpperations().size(); i++) { + CaDoodleOperation key = getOpperations().get(i); + if (key == test) { + File file = getTimelineImageFile(i); + return file; + } + } + throw new RuntimeException("File not found!"); + } + + public File getTimelineImageFile(int i) { + File parent = getSelf().getAbsoluteFile().getParentFile(); + File file = new File(parent.getAbsolutePath() + delim() + "timeline" + delim() + (i + 1) + ".png"); + return file; + } + + private OperationResult pruneForward(CaDoodleOperation op) throws Exception { + if (op == null) + throw new NullPointerException(); + OperationResult res = OperationResult.INSERT; + if (getAccept() != null) { + res = getAccept().accept(); + if (res == OperationResult.ABORT) { + return res; + } + } + if (getCurrentIndex() > 0) + for (int i = getCurrentIndex() - 1; i < getOpperations().size(); i++) { + CaDoodleOperation key = getOpperations().get(i); + if (i >= getCurrentIndex()) { + clearCache(key); + } + File imageCache = getTimelineImageFile(i); + // System.err.println("Deleting " + imageCache.getAbsolutePath()); + imageCache.delete(); + } + if (res == OperationResult.PRUNE) { + List subList = (List) getOpperations().subList(0, getCurrentIndex()); + for (int i = getCurrentIndex(); i < getOpperations().size(); i++) { + getOpperations().get(i).pruneCleanup(); + } + ArrayList newList = new ArrayList(); + newList.addAll(subList); + setOpperations(newList); + com.neuronrobotics.sdk.common.Log.error("Pruning forward here!"); + fireSaveSuggestion(); + } + return res; + } + + private void storeResultInCache(CaDoodleOperation op, List process) { + ArrayList cachedCopy = new ArrayList(); + HashSet names = new HashSet<>(); + for (CSG c : process) { + if (names.contains(c.getName())) + throw new RuntimeException("There can not be 2 objects with the same name after an " + op.getType() + + " opperation! " + c.getName()); + names.add(c.getName()); + CSG cachedVer = cloneCSG(c).setStorage(new PropertyStorage()).syncProperties(getCsgDBinstance(), c) + .setName(c.getName()).setRegenerate(c.getRegenerate()); + if (cachedVer.isHole() != c.isHole() || cachedVer.isHide() != c.isHide()) { + throw new RuntimeException("Lost properties"); + } + cachedCopy.add(cachedVer); + // cachedCopy.add(c); + } + placeCSGsInCache(op, cachedCopy); + + } + + public static double getFreeMemory() { + Runtime runtime = Runtime.getRuntime(); + long maxMemory = runtime.maxMemory(); // Maximum memory the JVM will attempt to use + long totalMemory = runtime.totalMemory(); // Total memory currently allocated to the JVM + long freeMemory = runtime.freeMemory(); // Free memory within the allocated memory + long usedMemory = totalMemory - freeMemory; // Actually used memory + + // Calculate the percentage of maximum memory that's currently being used + return (usedMemory * 100.0) / maxMemory; + } + + private CSG cloneCSG(CSG dyingCSG) { + CSG csg = new CSG(); + + ArrayList collect = new ArrayList(); + for (Polygon p : dyingCSG.getPolygons()) { + if (p == null) + continue; + try { + collect.add(p); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex); + ; + } + } + csg.setPolygons(collect); + Set params = dyingCSG.getParameters(getCsgDBinstance()); + for (String param : params) { + boolean existing = false; + for (String s : csg.getParameters(getCsgDBinstance())) { + if (s.contentEquals(param)) + existing = true; + } + if (!existing) { + Parameter vals = getCsgDBinstance().get(param); + if (vals != null) + csg.setParameter(getCsgDBinstance(), vals, + getCsgDBinstance().getMapOfparametrics(dyingCSG).get(param)); + } + } + if (csg.getName().length() == 0) + csg.setName(dyingCSG.getName()); + csg.setColor(dyingCSG.getColor()); + return csg; + } + + public void back() { + CaDoodleOperation op = getCurrentOpperation(); + if (isBackAvailible()) + setCurrentIndex(getCurrentIndex() - 1); + updateCurrentFromCache(); + if (ICadoodleOperationUndo.class.isInstance(op)) { + ICadoodleOperationUndo un = (ICadoodleOperationUndo) op; + un.undo(); + } + fireSaveSuggestion(); + } + + public void forward() { + if (isForwardAvailible()) + setCurrentIndex(getCurrentIndex() + 1); + updateCurrentFromCache(); + CaDoodleOperation op = getCurrentOpperation(); + if (ICadoodleOperationUndo.class.isInstance(op)) { + ICadoodleOperationUndo un = (ICadoodleOperationUndo) op; + un.redo(); + } + fireSaveSuggestion(); + } + + public void moveToOpIndex(int newIndex) { + if (newIndex > getOpperations().size()) + return; + if (newIndex < 0) + return; + int ci = getCurrentIndex(); + int ni = newIndex + 1; + boolean forward = ci < ni; + if (forward) { + for (int i = ci; i < ni + 1; i++) { + try { + CaDoodleOperation op = opperations.get(i - 1); + if (ICadoodleOperationUndo.class.isInstance(op)) { + ICadoodleOperationUndo un = (ICadoodleOperationUndo) op; + un.redo(); + } + } catch (Exception ex) { + Log.error(ex); + } + } + } else { + for (int i = ni; i < ci + 1; i++) { + CaDoodleOperation op = opperations.get(i - 1); + if (ICadoodleOperationUndo.class.isInstance(op)) { + ICadoodleOperationUndo un = (ICadoodleOperationUndo) op; + un.undo(); + } + } + } + setCurrentIndex(ni); + updateCurrentFromCache(); + fireSaveSuggestion(); + } + + public boolean isBackAvailible() { + return getCurrentIndex() > 1; + } + + private void updateCurrentFromCache() { + CaDoodleOperation key = getCurrentOpperation(); + if (key == null) + return; + com.neuronrobotics.sdk.common.Log.debug("Current opperation results: " + key.getType()); + setCurrentState(key, getCurrentState()); + } + + public CaDoodleOperation getCurrentOpperation() { + if (getCurrentIndex() == 0) + return null; + return getOpperations().get(getCurrentIndex() - 1); + } + + public boolean isForwardAvailible() { + return getCurrentIndex() < getOpperations().size(); + } + + public File getSelf() { + if (self == null) { + try { + self = File.createTempFile(DownloadManager.sanitizeString(projectName), ".doodle"); + } catch (IOException e) { + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + } + return self; + } + + public CaDoodleFile setSelf(File self) { + this.self = self; + return this; + } + + public List getCurrentState() { + return getStateAtOperation(getCurrentOpperation()); + } + + public List getStateAtOperation(CaDoodleOperation op) { + if (getCurrentIndex() == 0) + return new ArrayList(); + List list = getCachedCSGs(op); + if (list == null) + list = new ArrayList(); + return list; + } + + public List getSelect(List selectedSnapshot) { + List cur = getCurrentState(); + ArrayList back = new ArrayList(); + if (cur != null) + for (CSG c : cur) { + for (String s : selectedSnapshot) { + if (c.getName().contentEquals(s)) { + back.add(c); + } + } + } + return back; + } + + public List getPreviouState() { + if (getCurrentIndex() < 2) + return new ArrayList(); + CaDoodleOperation key = getOpperations().get(getCurrentIndex() - 2); + + return getCachedCSGs(key); + } + + private void setCurrentState(CaDoodleOperation op, List currentState) { + for (ICaDoodleStateUpdate l : listeners) { + try { + l.onUpdate(currentState, op, this); + } catch (Throwable e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + } + } + + private void fireSaveSuggestion() { + + for (ICaDoodleStateUpdate l : listeners) { + try { + l.onSaveSuggestion(); + } catch (Throwable e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + } + } + + private void fireInitializationStart() { + + for (ICaDoodleStateUpdate l : listeners) { + try { + l.onInitializationStart(); + } catch (Throwable e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + } + } + + private void fireRegenerateDone() { + + for (ICaDoodleStateUpdate l : listeners) { + try { + TickToc.tic("Fire " + l.getClass()); + l.onRegenerateDone(); + } catch (Throwable e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + } + } + + private void fireRegenerateStart(CaDoodleOperation source) { + + for (ICaDoodleStateUpdate l : listeners) { + try { + l.onRegenerateStart(source); + } catch (Throwable e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + } + } + + private void fireWorkplaneChange() { + + for (ICaDoodleStateUpdate l : listeners) { + try { + l.onWorkplaneChange(workplane); + } catch (Throwable e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + } + } + + public String getMyProjectName() { + return projectName; + } + + public CaDoodleFile setProjectName(String projectName) { + this.projectName = projectName; + return this; + } + + public String toJson() { + String ret = null; + synchronized (this) { + ret = gson.toJson(this); + } + return ret; + } + + public File save() throws IOException { + if (timeCreated < 0) + timeCreated = System.currentTimeMillis(); + String contents = toJson(); + List currentState = getCurrentState(); + CSG thumb = null; + for (CSG c : currentState) { + if (c.isInGroup()) + continue; + if (c.isHide()) + continue; + if (thumb == null) + thumb = c; + else { + thumb = thumb.dumbUnion(c); + } + } + String string = getSTLThumbnailLocation(); + int currentIndex2 = getCurrentIndex(); + if (isTimelineOpen()) + getSaveUpdate().renderSplashFrame(1, "Save Doodle to " + getSelf().getName()); + if (thumb != null) { + boolean manif = CSG.isPreventNonManifoldTriangles(); + if (manif) + CSG.setPreventNonManifoldTriangles(false); + FileUtil.write(Paths.get(string), thumb.toStlString()); + if (manif) + CSG.setPreventNonManifoldTriangles(true); + } + FileUtils.write(getSelf(), contents, StandardCharsets.UTF_8, false); + // } + int num = 0; + for (int i = 0; i < opperations.size(); i++) { + File f = getTimelineImageFile(i); + CaDoodleOperation op = opperations.get(i); + int percent = (int) (((double) i) / ((double) opperations.size()) * 100.0); + List process = getCachedCSGs(op); + if (!f.exists() && process != null) + try { + num++; + if (isTimelineOpen()) + getSaveUpdate().renderSplashFrame(percent, "Save Timeline Image " + i + ".png"); + + setSaveImage(process, op); + + } catch (IOException e) { + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + } + if (bom != null) + bom.save(); + if (isTimelineOpen()) + getSaveUpdate().renderSplashFrame(100, "Doofle save Done "); + fireTimelineUpdate(num); + // System.gc(); + return getSelf(); + } + + public File getSTLThumbnailFile() { + File back = new File(getSTLThumbnailLocation()); + return back; + } + + public String getSTLThumbnailLocation() { + File folder = getSelf().getAbsoluteFile().getParentFile(); + if (!folder.exists()) + folder.mkdirs(); + String string = folder.getAbsolutePath() + delim() + "thumbnail.stl"; + return string; + } + + private void setSaveImage(List currentState, CaDoodleOperation op) throws IOException { + if (getSelf() == null) + return; + int currentIndex2 = 0; + for (int i = 0; i < getOpperations().size(); i++) + if (getOpperations().get(i) == op) + currentIndex2 = i; +// if(currentIndex2==0) +// return; + File parent = getSelf().getAbsoluteFile().getParentFile(); + File imageFolder = new File(parent.getAbsolutePath() + delim() + "timeline" + delim()); + if (!imageFolder.exists()) + imageFolder.mkdirs(); + File imageCache = new File(parent.getAbsolutePath() + delim() + "timeline" + delim() + currentIndex2 + ".png"); + File image = new File(parent.getAbsolutePath() + delim() + "snapshot.png"); + + if (imageCache.exists()) + return; + try { + WritableImage image2 = loadingImageFromUIThread(currentState); + if (image2 != null) { + BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image2, null); + try { + ImageIO.write(bufferedImage, "png", imageCache); + } catch (IOException e) { + // com.neuronrobotics.sdk.common.Log.error("Error saving image: " + + // e.getMessage()); + com.neuronrobotics.sdk.common.Log.error(e); + } + do { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + com.neuronrobotics.sdk.common.Log.error(e); + return; + } + } while (!imageCache.exists()); + if (getOpperations().get(getOpperations().size() - 1) == op) { + Files.copy(imageCache, image); + } + System.err.println("Thumbnail saved successfully to " + imageCache.getAbsolutePath()); + } + } catch (Throwable t) { + com.neuronrobotics.sdk.common.Log.error(t); + } + } + + private void fireTimelineUpdate(int number) { + for (ICaDoodleStateUpdate s : listeners) { + s.onTimelineUpdate(number); + } + } + + public WritableImage loadImageFromFile() { + try { + File parent = getSelf().getAbsoluteFile().getParentFile(); + File image = new File(parent.getAbsolutePath() + delim() + "snapshot.png"); + if (image.exists()) { + BufferedImage bufferedImage = ImageIO.read(image); + if (bufferedImage != null) { + img = SwingFXUtils.toFXImage(bufferedImage, null); + } + } else { + loadingImageFromUIThread(getCurrentState()); + } + } catch (Exception e) { + com.neuronrobotics.sdk.common.Log.error("Error loading image: " + e.getMessage()); + com.neuronrobotics.sdk.common.Log.error(e); + } + return img; + } + + private javafx.scene.image.WritableImage loadingImageFromUIThread(List currentState) { + if (currentState == null) + throw new RuntimeException("Can not be null"); + ArrayList holder = new ArrayList(); + try { + BowlerKernel.runLater(() -> { + holder.add(ThumbnailImage.get(getCsgDBinstance(), currentState)); + }); + } catch (Throwable ex) { + com.neuronrobotics.sdk.common.Log.error(ex); + ; + return null; + } + long start = System.currentTimeMillis(); + while (holder.size() == 0) { + try { + Thread.sleep(16); + // com.neuronrobotics.sdk.common.Log.error("Waiting for image to write"); + } catch (InterruptedException e) { + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + break; + } + if (System.currentTimeMillis() - start > 25000 && holder.size() == 0) { + throw new RuntimeException("Failed to create image"); + } + } + return holder.get(0); + } + + public static CaDoodleFile fromJsonString(String content) throws Exception { + return fromJsonString(content, null, null, true); + } + + public static CaDoodleFile fromJsonString(String content, ICaDoodleStateUpdate listener, File self, + boolean initialize) throws Exception { + CaDoodleFile file = gson.fromJson(content, TT_CaDoodleFile); + if (file == null) { + file = new CaDoodleFile(); + file.setProjectName(RandomStringFactory.getNextRandomName()); + file.getTimeCreated(); + } + if (listener != null) { + file.addListener(listener); + } + if (self != null) { + file.setSelf(self); + } + if (initialize) { + file.initialize(); + } + return file; + } + + public static CaDoodleFile fromFile(File f) throws Exception { + return fromFile(f, null, true); + } + + public static String getProjectName(File f) throws Exception { + com.neuronrobotics.sdk.common.Log.debug("CaDoodle file reading from " + f.getAbsolutePath()); + String content = FileUtils.readFileToString(f, StandardCharsets.UTF_8); + CaDoodleFile file = fromJsonString(content, null, f, false); + return file.getMyProjectName(); + } + + public static CaDoodleFile fromFile(File f, ICaDoodleStateUpdate listener, boolean initialize) throws Exception { + com.neuronrobotics.sdk.common.Log.debug("CaDoodle file loading from " + f.getAbsolutePath()); + String content = FileUtils.readFileToString(f, StandardCharsets.UTF_8); + CaDoodleFile file = fromJsonString(content, listener, f, initialize); + return file; + } + + public ArrayList getOpperations() { + return opperations; + } + + public void setOpperations(ArrayList opperations) { + this.opperations = opperations; + currentIndex = opperations.size(); + } + + public TransformNR getWorkplane() { + if (workplane == null) + workplane = new TransformNR(); + return workplane; + } + + public void setWorkplane(TransformNR workplane) { + this.workplane = workplane; + fireWorkplaneChange(); + fireSaveSuggestion(); + } + + public int getCurrentIndex() { + return currentIndex; + } + + public void setCurrentIndex(int currentIndex) { +// if(currentIndex==0) +// new Exception("Current Index set to " + currentIndex).printStackTrace(); + if ((currentIndex - 1) >= getOpperations().size()) + throw new RuntimeException("Fail! Can not set an index greater than the availible operations"); + this.currentIndex = currentIndex; + } + + public javafx.scene.image.WritableImage getImage() { + return img; + } + + public javafx.scene.image.WritableImage setImage(javafx.scene.image.WritableImage img) { + this.img = img; + return img; + } + + public boolean isInitialized() { + return !(percentInitialized < 1); + } + + /** + * A value from 0 to 1 representing how complete the initialization is + * + * @return + */ + public double getPercentInitialized() { + return percentInitialized; + } + + private void setPercentInitialized(double percentInitialized) { + if (percentInitialized > 1 || percentInitialized < 0) + throw new NumberFormatException("Number must be between 0 and 1"); + this.percentInitialized = percentInitialized; + } + + public long getTimeCreated() { + if (timeCreated < 0) { + timeCreated = System.currentTimeMillis(); + } + return timeCreated; + } + + public boolean isRegenerating() { + return regenerating; + } + + private void setRegenerating(boolean regenerating) { + this.regenerating = regenerating; + } + + public TransformNR getRulerLocation() { + return rulerLocation; + } + + public void setRulerLocation(TransformNR rulerLocation) { + rulerLocation.setRotation(new RotationNR()); + this.rulerLocation = rulerLocation; + fireWorkplaneChange(); + fireSaveSuggestion(); + } + + public IAcceptPruneForward getAccept() { + return accept; + } + + public void setAccept(IAcceptPruneForward accept) { + this.accept = accept; + } + + public long timeSinceLastUpdate() { + return System.currentTimeMillis() - timeOfLastUpdate; + } + + public OperationResult getResult() { + return result; + } + + public void setResult(OperationResult result) { + this.result = result; + } + + public ICadoodleSaveStatusUpdate getSaveUpdate() { + if (saveUpdate == null) + return defaultSaver; + return saveUpdate; + } + + public void setSaveUpdate(ICadoodleSaveStatusUpdate saveUpdate) { + this.saveUpdate = saveUpdate; + } + + public void setTimelineVisable(boolean timelineOpen) { + this.timelineOpen = timelineOpen; + } + + public boolean isTimelineOpen() { + return timelineOpen; + } + + public void setTimeCreated(long timeCreated) { + this.timeCreated = timeCreated; + } + + /** + * @return the robots + */ + public HashMap getRobots() { + return robots; + } + + /** + * @param robots the robots to set + */ + public void setRobots(HashMap robots) { + this.robots = robots; + } + + public CSGDatabaseInstance getCsgDBinstance() { + return csgDBinstance; + } + + private void setCsgDBinstance(CSGDatabaseInstance csgDBinstance) { + this.csgDBinstance = csgDBinstance; + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleJsonOperationAdapterFactory.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleJsonOperationAdapterFactory.java new file mode 100644 index 000000000..da4daedcd --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleJsonOperationAdapterFactory.java @@ -0,0 +1,93 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.AddRobotController; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.AddRobotLimb; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.MakeRobot; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.ModifyLimb; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class CaDoodleJsonOperationAdapterFactory implements TypeAdapterFactory { + private final Map> typeRegistry = new HashMap<>(); + private final Map, String> classRegistry = new HashMap<>(); + + public CaDoodleJsonOperationAdapterFactory() { + registerType("AddFromFile", AddFromFile.class); + registerType("AddFromScript", AddFromScript.class); + registerType("AddRobotController", AddRobotController.class); + registerType("AddRobotLimb", AddRobotLimb.class); + registerType("Allign", Allign.class); + registerType("Delete", Delete.class); + registerType("Group", Group.class); + registerType("Hide", Hide.class); + registerType("Lock", Lock.class); + registerType("MakeRobot", MakeRobot.class); + registerType("Mirror", Mirror.class); + registerType("MoveCenter", MoveCenter.class); + registerType("ModifyLimb", ModifyLimb.class); + registerType("Paste", Paste.class); + registerType("Resize", Resize.class); + registerType("Show", Show.class); + registerType("ToHole", ToHole.class); + registerType("ToSolid", ToSolid.class); + registerType("UnGroup", UnGroup.class); + registerType("UnLock", UnLock.class); + registerType("Sweep", Sweep.class); + + } + + private void registerType(String typeName, Class clazz) { + typeRegistry.put(typeName, clazz); + classRegistry.put(clazz, typeName); + } + + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + if (!CaDoodleOperation.class.isAssignableFrom(type.getRawType())) { + return null; + } + + final TypeAdapter jsonElementAdapter = gson.getAdapter(JsonElement.class); + + return new TypeAdapter() { + @Override + public void write(JsonWriter out, T value) throws IOException { + JsonObject jsonObject = new JsonObject(); + String typeName = classRegistry.get(value.getClass()); + if (typeName == null) { + throw new JsonParseException("Unknown class: " + value.getClass()); + } + jsonObject.addProperty("type", typeName); + @SuppressWarnings("unchecked") + TypeAdapter delegateAdapter = (TypeAdapter) gson.getDelegateAdapter( + CaDoodleJsonOperationAdapterFactory.this, TypeToken.get((Class) value.getClass())); + JsonElement dataElement = delegateAdapter.toJsonTree(value); + jsonObject.add("data", dataElement); + jsonElementAdapter.write(out, jsonObject); + } + + @Override + public T read(JsonReader in) throws IOException { + JsonObject jsonObject = jsonElementAdapter.read(in).getAsJsonObject(); + JsonElement typeElement = jsonObject.get("type"); + JsonElement dataElement = jsonObject.get("data"); + String typeName = typeElement.getAsString(); + Class clazz = typeRegistry.get(typeName); + if (clazz == null) { + throw new JsonParseException("Unknown type: " + typeName); + } + TypeAdapter delegateAdapter = gson + .getDelegateAdapter(CaDoodleJsonOperationAdapterFactory.this, TypeToken.get(clazz)); + //com.neuronrobotics.sdk.common.Log.error("JSON Parsing " + typeName); + return (T) delegateAdapter.fromJsonTree(dataElement); + } + }.nullSafe(); + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleOperation.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleOperation.java new file mode 100644 index 000000000..7a6443c0e --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleOperation.java @@ -0,0 +1,71 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + +import com.neuronrobotics.bowlerstudio.creature.MobileBaseBuilder; + +import eu.mihosoft.vrl.v3d.CSG; + +public abstract class CaDoodleOperation { + private CaDoodleFile cf = null; + public abstract String getType(); + public abstract List process(List incoming); + public abstract List getNamesAddedInThisOperation(); + public void pruneCleanup() { + + } + + public CaDoodleFile getCaDoodleFile() { + return cf; + } + + public void setCaDoodleFile(CaDoodleFile cf) { + this.cf = cf; + } + /** + * @return the robots + */ + public HashMap getRobots() { + return cf.getRobots(); + } + + public String getBuilder(List selected, List state) { + if(selected==null) + return null; + for(CSG c: state) { + for(String s:selected) { + if(s.contentEquals(c.getName())) { + Optional mobileBaseName= c.getMobileBaseName(); + if(mobileBaseName.isPresent()) { + MobileBaseBuilder b = getRobots().get(mobileBaseName.get()); + if(b!=null) { + return mobileBaseName.get(); + } + } + } + } + } + return null; + } + public String getLimbName(List selected, List state) { + if(selected==null) + return null; + for(CSG c: state) { + for(String s:selected) { + if(s.contentEquals(c.getName())) { + Optional limbNameOption= c.getLimbName(); + if(limbNameOption.isPresent()) { + MobileBaseBuilder b = getRobots().get(c.getMobileBaseName().get()); + if(b!=null) { + if(b.getMobileBase().getLimbByName(limbNameOption.get())!=null) + return limbNameOption.get(); + } + } + } + } + } + return null; + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleVitamin.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleVitamin.java new file mode 100644 index 000000000..1e6194ff8 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CaDoodleVitamin.java @@ -0,0 +1,131 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Optional; +import java.util.Set; + +import com.neuronrobotics.bowlerstudio.vitamins.Vitamins; +import com.neuronrobotics.sdk.addons.kinematics.VitaminLocation; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; +import eu.mihosoft.vrl.v3d.parametrics.IRegenerate; +import eu.mihosoft.vrl.v3d.parametrics.Parameter; +import eu.mihosoft.vrl.v3d.parametrics.StringParameter; + +public class CaDoodleVitamin { + private CSGDatabaseInstance instance; + public CaDoodleVitamin(CSGDatabaseInstance myinstance) { + instance=myinstance; + } + public CSG get(String typencoming, ArrayList args) { + String name = args.get(0).toString(); + ArrayListtypes=new ArrayList<>(); + types.addAll(Vitamins.listVitaminTypes()); + StringParameter typeParam = new StringParameter(instance,name + "_CaDoodle_Vitamin_Type", typencoming,types); + String type=typeParam.getStrValue(); + ArrayList listVitaminSizes = Vitamins.listVitaminSizes(type); + try { + return get( type, listVitaminSizes.get(0), args); + }catch(Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + throw ex; + } + } + public boolean isVitamin(CSG c) { + for(String s:instance.getParameters(c)) { + if(s.contains("_CaDoodle_Vitamin_") && s.contains(c.getName())) { + return true; + } + } + return false; + } + public CSG get(String typencoming,String defaultValue, ArrayList args) { + String name = args.get(0).toString(); + + ArrayListtypes=new ArrayList<>(); + types.addAll(Vitamins.listVitaminTypes()); + StringParameter typeParam = new StringParameter(instance,name + "_CaDoodle_Vitamin_Type", typencoming, + types); + String type=typeParam.getStrValue(); + ArrayList listVitaminSizes = Vitamins.listVitaminSizes(type); + + StringParameter size = new StringParameter(instance,type + " Default", defaultValue, listVitaminSizes); + + String strValue = size.getStrValue(); + if(strValue.length() == 0) { + size.setStrValue(listVitaminSizes.get(0)); + } + String string = "_CaDoodle_Vitamin_Size"; + StringParameter word = new StringParameter(instance,name + string, strValue, + listVitaminSizes); + boolean sizeExists=false; + for(String s:Vitamins.listVitaminSizes(type)) { + if(s.contentEquals(word.getStrValue())) { + sizeExists=true; + break; + } + } + if(!sizeExists) { + + word.setStrValue(strValue); + } + size.setStrValue(word.getStrValue()); + if (args.size() > 1) { + HashMap object = (HashMap) args.get(1); + if (!(Boolean) object.get("PreventBomAdd")) { + +// VitaminLocation vl = new VitaminLocation(false, name, type, word.getStrValue(), new TransformNR()); +// //com.neuronrobotics.sdk.common.Log.debug("BoM update "+vl); +// CaDoodleFile.getBoM().addVitamin(vl, true); + } + } + CSG part; + try { +// com.neuronrobotics.sdk.common.Log.debug("Generating Vitamin "+type+" "+word.getStrValue()+" for vitamin named "+name); + part = Vitamins.get(instance,type, word.getStrValue()).setIsHole(true); + instance.saveDatabase(); + Set params = part.getParameters(instance); + + part.setParameter(instance,word); + part.setParameter(instance,typeParam); + params = part.getParameters(instance); + part.setName(name); +// com.neuronrobotics.sdk.common.Log.debug("Parameters on Vitamin: "+name); +// for(String s:params) { +// com.neuronrobotics.sdk.common.Log.debug("\t"+s); +// } + CSG back = part.setRegenerate(new IRegenerate() { + @Override + public CSG regenerate(CSG previous) { + Optional pv = previous.getStorage().getValue("PreviousName"); + String name2 = null; + if(pv.isPresent()) + name2=pv.get().toString(); + else + name2=name; + //com.neuronrobotics.sdk.common.Log.debug("Regenerating source \n\t"+name+" on part \n\t"+name2); + ArrayList ar = new ArrayList<>(); + ar.addAll(args); + ar.set(0, previous.getName()); + Parameter s = instance.get(name2+"_CaDoodle_Vitamin_Size"); + Parameter t = instance.get(name2+"_CaDoodle_Vitamin_Type"); + if(t==null) { + com.neuronrobotics.sdk.common.Log.debug(" Error, type is null, previous "+name2+" has no parameters somehow??"); + } + return get(t.getStrValue(),s.getStrValue(), ar); + } + }); + //back.getStorage().set("PreviousName", name); + //back.setIsAlwaysShow(true); + return back; + } catch (Exception e) { + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + throw new RuntimeException("Failed to load vitamin of type " + type); + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CadoodleConcurrencyException.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CadoodleConcurrencyException.java new file mode 100644 index 000000000..dcd132897 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/CadoodleConcurrencyException.java @@ -0,0 +1,11 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +public class CadoodleConcurrencyException extends RuntimeException { + + private static final long serialVersionUID = -1210401639337288969L; + + public CadoodleConcurrencyException(String string) { + super(string); + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Delete.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Delete.java new file mode 100644 index 000000000..292a70eb4 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Delete.java @@ -0,0 +1,62 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.bowlerstudio.vitamins.VitaminBomManager; +import com.neuronrobotics.sdk.addons.kinematics.VitaminLocation; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; + +public class Delete extends CaDoodleOperation { + @Expose(serialize = true, deserialize = true) + private TransformNR location = new TransformNR(); + @Expose(serialize = true, deserialize = true) + private List names = new ArrayList(); + + @Override + public String getType() { + return "Delete"; + } + + @Override + public List process(List incoming) { + ArrayList back = new ArrayList(); + back.addAll(incoming); + + CaDoodleFile.applyToAllConstituantElements(false, names, back, new ICadoodleRecursiveEvent() { + @Override + public ArrayList process(CSG incoming, int depth) { + + ArrayList b = new ArrayList<>(); + b.add(null); + return b; + } + },1); + + return back; + } + + public TransformNR getLocation() { + return location; + } + + public Delete setLocation(TransformNR location) { + this.location = location; + return this; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public Delete setNames(List names) { + this.names = names; + return this; + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Group.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Group.java new file mode 100644 index 000000000..7cd5bf41f --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Group.java @@ -0,0 +1,179 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.io.File; +import java.nio.file.NoSuchFileException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.parametrics.IParametric; +import javafx.scene.paint.Color; +import javafx.scene.transform.Affine; + +public class Group extends AbstractAddFrom { + @Expose(serialize = true, deserialize = true) + private List names = new ArrayList(); + @Expose(serialize = true, deserialize = true) + public String groupID = null; + @Expose(serialize = true, deserialize = true) + public boolean hull = false; + @Expose(serialize = true, deserialize = true) + public boolean intersect = false; + + @Override + public String getType() { + return "Group"; + } + + @Override + public List process(List incoming) { + ArrayList holes = new ArrayList(); + ArrayList solids = new ArrayList(); + ArrayList back = new ArrayList(); + ArrayList replace = new ArrayList(); + back.addAll(incoming); + String mobileBase=null; + boolean noscale=false; + Affine manip = null; + boolean nomove=false; + for (CSG csg : incoming) { + if (csg.isLock()) + continue; + + for (String name : names) { + if (name.contentEquals(csg.getName())) { + if(csg.isNoScale()) + noscale=true; + if(csg.isMotionLock() ) + nomove=true; + Optional mobileBaseName = csg.getMobileBaseName(); + if(mobileBaseName.isPresent()) { + if(mobileBase==null) + mobileBase= mobileBaseName.get(); + if(!mobileBase.contentEquals(mobileBaseName.get())) { + continue;// skip grouping any item that is of a different mobile base; + } + } + if(csg.hasManipulator()) + manip=csg.getManipulator(); + replace.add(csg); + CSG clone = csg.clone(); + + CSG c = clone.syncProperties(getCaDoodleFile().getCsgDBinstance(),csg).setRegenerate(csg.getRegenerate()).setName(name); + c.addGroupMembership(getGroupID()); + back.add(c); + if(csg.hasManipulator()) { + c=c.transformed(TransformFactory.nrToCSG(TransformFactory.affineToNr(manip))) + .syncProperties(getCaDoodleFile().getCsgDBinstance(),csg).setRegenerate(csg.getRegenerate()).setName(name); + c.addGroupMembership(getGroupID()); + } + if (csg.isHole()) { + holes.add(c); + } else + solids.add(c); + + } + } + } + for (CSG c : replace) { + back.remove(c); + } + CSG result = null; + if (holes.size() > 0 && solids.size() == 0) { + result = CSG.unionAll(holes); + if (hull) + result = result.hull(); + result.setIsHole(true); + + } else { + CSG holecutter = null; + if (holes.size() > 0) { + if (intersect) + holecutter = intersect(holes); + else + holecutter = holes.size()==1?holes.get(0):CSG.unionAll(holes); + if (hull) + holecutter = holecutter.hull(); + } + if (intersect) + result = intersect(solids); + else + result =solids.size()==1?solids.get(0).clone(): CSG.unionAll(solids); + Color c = result.getColor(); + if (hull) { + result = result.hull(); + } + if (holecutter != null) { + if(result.getBounds().isBoundsTouching(holecutter.getBounds())) { + result = result.difference(holecutter); + } + } + + result.setIsHole(false); + result.setColor(c); + } + if(manip!=null) { + result=result.transformed(TransformFactory.nrToCSG(TransformFactory.affineToNr(manip).inverse())); + result.setManipulator(manip); + } + if(mobileBase!=null) + result.setMobileBaseName(mobileBase); + HashMap mapOfparametrics = result.getMapOfparametrics(getCaDoodleFile().getCsgDBinstance()); + if (mapOfparametrics != null) + mapOfparametrics.clear(); + result.addIsGroupResult(getGroupID()); + result.setName(getGroupID()); + result.setNoScale(noscale); + result.setIsMotionLock(nomove); + result.setIsAlwaysShow(false); + namesAdded.add(result.getName()); + back.add(result); + return back; + } + + private CSG intersect(ArrayList solids) { + CSG first = solids.get(0); + for(int i=1;i getNamesAddedInThisOperation() { + ArrayList n= new ArrayList(); + n.addAll(getNamesAdded()); + n.addAll(names); + return n; + } + + public Group setNames(List names) { + this.names = names; + return this; + } + + public String getGroupID() { + if (groupID == null) + groupID = RandomStringFactory.generateRandomString(); + return groupID; + } + + public Group setIntersect(boolean intersect) { + this.intersect = intersect; + return this; + } + + public Group setHull(boolean hull) { + this.hull = hull; + return this; + } + + @Override + public File getFile() throws NoSuchFileException { + throw new NoSuchFileException(null); + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Hide.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Hide.java new file mode 100644 index 000000000..41b3c468f --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Hide.java @@ -0,0 +1,48 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; + +import eu.mihosoft.vrl.v3d.CSG; + +public class Hide extends CaDoodleOperation{ + @Expose (serialize = true, deserialize = true) + private List names = new ArrayList(); + @Override + public String getType() { + return "Hide"; + } + + @Override + public List process(List incoming) { + ArrayList replace = new ArrayList(); + ArrayList back = new ArrayList(); + back.addAll(incoming); + for(CSG c: incoming) { + for(String name:names) { + if(name.contentEquals(c.getName())) { + replace.add(c); + CSG b=c.clone().setRegenerate(c.getRegenerate()).syncProperties(getCaDoodleFile().getCsgDBinstance(),c); + b.setIsHide(true); + back.add(b); + } + } + } + for(CSG c:replace) { + back.remove(c); + } + return back; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public Hide setNames(List names) { + this.names = names; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/IAcceptPruneForward.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/IAcceptPruneForward.java new file mode 100644 index 000000000..9aa4b32da --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/IAcceptPruneForward.java @@ -0,0 +1,5 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +public interface IAcceptPruneForward { + public OperationResult accept(); +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICaDoodleStateUpdate.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICaDoodleStateUpdate.java new file mode 100644 index 000000000..df56ab1b0 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICaDoodleStateUpdate.java @@ -0,0 +1,18 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.List; + +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; + +public interface ICaDoodleStateUpdate { + public void onUpdate(List currentState, CaDoodleOperation source,CaDoodleFile file ); + public void onSaveSuggestion(); + public void onInitializationDone(); + public void onInitializationStart(); + public void onRegenerateDone(); + public void onRegenerateStart(CaDoodleOperation source); + public void onWorkplaneChange(TransformNR newWP); + public void onTimelineUpdate(int numberOfNew); +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICadoodleOperationUndo.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICadoodleOperationUndo.java new file mode 100644 index 000000000..4f25890d4 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICadoodleOperationUndo.java @@ -0,0 +1,6 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +public interface ICadoodleOperationUndo { + public void undo(); + public void redo(); +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICadoodleRecursiveEvent.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICadoodleRecursiveEvent.java new file mode 100644 index 000000000..5511804e1 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICadoodleRecursiveEvent.java @@ -0,0 +1,9 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; + +import eu.mihosoft.vrl.v3d.CSG; + +public interface ICadoodleRecursiveEvent { + public ArrayList process(CSG incoming,int depth); +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICadoodleSaveStatusUpdate.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICadoodleSaveStatusUpdate.java new file mode 100644 index 000000000..539d5b074 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ICadoodleSaveStatusUpdate.java @@ -0,0 +1,5 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +public interface ICadoodleSaveStatusUpdate { + public void renderSplashFrame(int percent, String message); +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/INamedOperation.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/INamedOperation.java new file mode 100644 index 000000000..f1ca524e0 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/INamedOperation.java @@ -0,0 +1,5 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +public interface INamedOperation { + public String getName(); +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Lock.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Lock.java new file mode 100644 index 000000000..8953ccd3b --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Lock.java @@ -0,0 +1,48 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; + +import eu.mihosoft.vrl.v3d.CSG; + +public class Lock extends CaDoodleOperation { + @Expose (serialize = true, deserialize = true) + private List names = new ArrayList(); + @Override + public String getType() { + return "Lock"; + } + + @Override + public List process(List incoming) { + ArrayList replace = new ArrayList(); + ArrayList back = new ArrayList(); + back.addAll(incoming); + for(CSG c: incoming) { + for(String name:names) { + if(name.contentEquals(c.getName())) { + replace.add(c); + CSG b=c.clone().setRegenerate(c.getRegenerate()).syncProperties(getCaDoodleFile().getCsgDBinstance(),c); + b.setIsLock(true); + back.add(b); + } + } + } + for(CSG c:replace) { + back.remove(c); + } + return back; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public Lock setNames(List names) { + this.names = names; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Mirror.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Mirror.java new file mode 100644 index 000000000..d95206033 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Mirror.java @@ -0,0 +1,162 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Transform; +import javafx.scene.transform.Affine; + +public class Mirror extends CaDoodleOperation { + @Expose(serialize = true, deserialize = true) + private MirrorOrentation location; + @Expose(serialize = true, deserialize = true) + private List names = new ArrayList(); + @Expose(serialize = true, deserialize = true) + private TransformNR workplane = null; + @Expose(serialize = true, deserialize = true) + protected String name = null; + private int index; + public String getName() { + if (name == null) { + setName(RandomStringFactory.generateRandomString()); + } + return name; + } + + public void setName(String name) { + this.name = name; + } + @Override + public String getType() { + return "Move Center"; + } + + private CSG sync(CSG incoming, CSG c) { + return c.syncProperties(getCaDoodleFile().getCsgDBinstance(),incoming).setName(incoming.getName()).setColor(incoming.getColor()); + } + + @Override + public List process(List incoming) { + ArrayList back = new ArrayList(); + back.addAll(incoming); + index = 0; + for (String name : names) { + for (CSG csg : incoming) { + if(!csg.getName().contentEquals(name)) + continue; +// if(csg.isNoScale()) +// continue; + CSG base = csg.transformed(TransformFactory.nrToCSG(getWorkplane(csg)).inverse()); + Transform mirroringCenter = new Transform().movex(base.getCenterX()).movey(base.getCenterY()) + .movez(base.getCenterZ()); + Transform sc = new Transform(); + if (location == MirrorOrentation.x) { + sc=new Transform().scaleX(-1); + } + if (location == MirrorOrentation.y) { + sc=new Transform().scaleY(-1); + } + if (location == MirrorOrentation.z) { + sc=new Transform().scaleZ(-1); + } + Transform scale=sc; + + CaDoodleFile.applyToAllConstituantElements(false, name, back, (incoming1, depth) -> { + ArrayList b = new ArrayList<>(); + Transform inverse = TransformFactory.nrToCSG(getWorkplane(incoming1)).inverse(); + CSG t = incoming1.transformed(inverse); + CSG centered = t.transformed(mirroringCenter.inverse()); + centered = centered.transformed(scale); + centered = centered.transformed(mirroringCenter); + Transform wp = TransformFactory.nrToCSG(getWorkplane(incoming1)); + centered = centered.transformed(wp); + CSG tf = centered.setName(name).syncProperties(getCaDoodleFile().getCsgDBinstance(),incoming1); + sync(incoming1, tf); + MoveCenter.set(getName()+(index++) , tf, inverse); + MoveCenter.set(getName()+(index++) , tf, mirroringCenter.inverse()); + MoveCenter.set(getName()+(index++) , tf, scale); + MoveCenter.set(getName()+(index++) , tf, mirroringCenter); + MoveCenter.set(getName()+(index++) , tf, wp); + b.add(tf); + return b; + }, 1,new HashSet() +); + } + } + return back; +// back.addAll(incoming +// .stream() +// .map(csg->{ +// +// for(String name:names) { +// if(csg.isLock()) +// continue; +// if(csg.getName().contentEquals(name)) +// return mirror(csg, name) +// ; +// } +// return csg; +// }) +// .collect(Collectors.toCollection(ArrayList::new)) +// ); +// return back; + } + + private CSG mirror(CSG csg, String name) { + CSG t = csg.transformed(TransformFactory.nrToCSG(getWorkplane(csg)).inverse()); + Transform mirroringCenter = new Transform().movex(t.getCenterX()).movex(t.getCenterY()).movez(t.getCenterZ()); + + CSG centered = t.transformed(mirroringCenter.inverse()); + if (location == MirrorOrentation.x) { + centered = centered.mirrorx(); + } + if (location == MirrorOrentation.y) { + centered = centered.mirrory(); + } + if (location == MirrorOrentation.z) { + centered = centered.mirrorz(); + } + centered = centered.transformed(mirroringCenter); + centered = centered.transformed(TransformFactory.nrToCSG(getWorkplane(csg))); + return centered.setName(name).syncProperties(getCaDoodleFile().getCsgDBinstance(),csg); + } + + public MirrorOrentation getLocation() { + return location; + } + + public Mirror setLocation(MirrorOrentation location) { + this.location = location; + return this; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public Mirror setNames(List names) { + this.names = names; + return this; + } + + public TransformNR getWorkplane(CSG c) { + if (workplane == null) + workplane = new TransformNR(); + Affine af = c.getManipulator(); + TransformNR afNR = TransformFactory.affineToNr(af).inverse(); + return afNR.times(workplane); + } + + public Mirror setWorkplane(TransformNR workplane) { + this.workplane = workplane; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/MirrorOrentation.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/MirrorOrentation.java new file mode 100644 index 000000000..ee3456c57 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/MirrorOrentation.java @@ -0,0 +1,5 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +public enum MirrorOrentation { + x,y,z; +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/MoveCenter.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/MoveCenter.java new file mode 100644 index 000000000..5140e99f0 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/MoveCenter.java @@ -0,0 +1,131 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.bowlerstudio.vitamins.VitaminBomManager; +import com.neuronrobotics.sdk.addons.kinematics.VitaminLocation; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.PropertyStorage; +import eu.mihosoft.vrl.v3d.Transform; + +public class MoveCenter extends CaDoodleOperation{ + @Expose(serialize = true, deserialize = true) + private TransformNR location = new TransformNR(); + @Expose(serialize = true, deserialize = true) + private List names = new ArrayList(); + @Expose(serialize = true, deserialize = true) + protected String name = null; + + public String getName() { + if (name == null) { + name=(RandomStringFactory.generateRandomString()); + } + return name; + } + + @Override + public String getType() { + return "Move Center"; + } + public static void set(String name, CSG c, TransformNR tf) { + set(name,c,TransformFactory.nrToCSG(tf)); + } + public static void set(String name, CSG c, Transform tf) { + if (tf == null) + throw new NullPointerException(); + if (name == null) + throw new NullPointerException(); + if (c == null) + throw new NullPointerException(); + PropertyStorage storage = c.getStorage(); + Optional o = storage.getValue("TFSet"); + ArrayList tfs = null; + if (!o.isPresent()) { + tfs = new ArrayList(); + storage.set("TFSet", tfs); + } else { + tfs = (ArrayList) o.get(); + } + boolean contains = false; + for (String s : tfs) { + if (s.contentEquals(name)) { + contains = true; + break; + } + } + storage.set(name, tf); + if (!contains) + tfs.add(name); + } + + public static Transform getTotalOffset(CSG c) { + Transform nrToCSG = new Transform(); + PropertyStorage storage = c.getStorage(); + Optional o = storage.getValue("TFSet"); + if (o.isPresent()) { + Transform start = new Transform(); + ArrayList tfs = (ArrayList) o.get(); + for (String s : tfs) { + try { + Transform transTmp = new Transform().apply((Transform) storage.getValue(s).get()); + start = transTmp.apply(start); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + } + } + nrToCSG = start; + } + return nrToCSG; + } + + @Override + public List process(List incoming) { + ArrayList back = new ArrayList(); + back.addAll(incoming); + + CaDoodleFile.applyToAllConstituantElements(false, names, back, new ICadoodleRecursiveEvent() { + @Override + public ArrayList process(CSG incoming, int depth) { + + Transform nrToCSG2 = TransformFactory.nrToCSG(location); + if(incoming.isMotionLock()) { + nrToCSG2=new Transform(); + } + CSG tmpToAdd = incoming.transformed(nrToCSG2).syncProperties(getCaDoodleFile().getCsgDBinstance(),incoming).setName(incoming.getName()); + ArrayList b = new ArrayList<>(); + b.add(tmpToAdd); + set(getName(), tmpToAdd, location); + return b; + } + },1); + + return back; + } + + public TransformNR getLocation() { + return location; + } + + public MoveCenter setLocation(TransformNR location) { + this.location = location; + return this; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public MoveCenter setNames(List names) { + this.names = names; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/OperationResult.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/OperationResult.java new file mode 100644 index 000000000..4e857b010 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/OperationResult.java @@ -0,0 +1,19 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +public enum OperationResult { + PRUNE, INSERT, ABORT, APPEND, ASK; + + // Static factory method (case-insensitive) + public static OperationResult fromString(String name) { + for (OperationResult value : OperationResult.values()) { + if (value.name().equalsIgnoreCase(name)) { + return value; + } + } + throw new IllegalArgumentException("No enum constant OperationResult with name: " + name); + } + @Override + public String toString() { + return name(); // Or name().toLowerCase(), etc. + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Paste.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Paste.java new file mode 100644 index 000000000..afebc98b4 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Paste.java @@ -0,0 +1,153 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.io.File; +import java.nio.file.NoSuchFileException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.bowlerstudio.vitamins.VitaminBomManager; +import com.neuronrobotics.sdk.addons.kinematics.VitaminLocation; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Transform; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.Parameter; + +public class Paste extends AbstractAddFrom { + @Expose(serialize = true, deserialize = true) + private TransformNR location = new TransformNR(); + @Expose(serialize = true, deserialize = true) + private List names = new ArrayList(); +// @Expose(serialize = true, deserialize = true) +// public double offset = 10; + private int index; + private HashMap cpMap = new HashMap(); + + @Override + public String getType() { + return "Paste"; + } + + @Override + public List process(List incoming) { + ArrayList back = new ArrayList(); + back.addAll(incoming); + index = 1; + cpMap.clear(); + + CaDoodleFile.applyToAllConstituantElements(false, names, back, new ICadoodleRecursiveEvent() { + @Override + public ArrayList process(CSG ic, int depth) { + ArrayList copyPasteMoved = copyPasteMoved(back, ic,depth); + return copyPasteMoved; + } + },1); + + for (String from : cpMap.keySet()) { + CSG source = CaDoodleFile.getByName(back, from); + if (source.isGroupResult()) { + ArrayList c = constituants(back, from); + if(c.size()<1) { + new RuntimeException("A group result must have at least 1 constituants!").printStackTrace();; + continue; + } + String newGroupName = CaDoodleFile.getByName(back, cpMap.get(from)).getName(); + for (String s : c) { + CSG dest = CaDoodleFile.getByName(back, s); + dest.removeGroupMembership(from); + dest.addGroupMembership(newGroupName); + } + } + } + return back; + } + + private ArrayList constituants(ArrayList b, String name) { + ArrayList c = new ArrayList(); + for (String ky:cpMap.keySet()) { + CSG byName = CaDoodleFile.getByName(b,ky); + String name2 = cpMap.get(ky); + CSG byName2 = CaDoodleFile.getByName(b,name2); + for(CSG csg:Arrays.asList(byName,byName2)){ + if (csg.checkGroupMembership(name)) { + // only add objects that were created by this operation + if (csg.getName().contains(getName())) + c.add(csg.getName()); + } + } + } + return c; + } + + + + private ArrayList copyPasteMoved(ArrayList back, CSG c, int depth) { + String prevName = c.getName(); + String name = getName() +( index == 0 ? "" : "_" + index); + CSG clone = c.clone(); + clone.setRegenerate(c.getRegenerate()).setName(name); + clone.getStorage().set("PreviousName", prevName); + Transform nrToCSG = MoveCenter.getTotalOffset(c); + + Transform nrToCSG2 = TransformFactory.nrToCSG(location); + CSG newOne = null; + if (new CaDoodleVitamin(getCaDoodleFile().getCsgDBinstance()).isVitamin(c)) { + CSG regenerate = clone.getRegenerate().regenerate(clone); + newOne = regenerate.transformed(nrToCSG).transformed(nrToCSG2); + newOne.setRegenerate(regenerate.getRegenerate()); + }else { + newOne = clone.transformed(nrToCSG2); + newOne.setRegenerate(c.getRegenerate()); + } + newOne.syncProperties(getCaDoodleFile().getCsgDBinstance(),c).setName(name); + MoveCenter.set(name, newOne, location); + index++; + getNamesAdded().add(name); + ArrayList b = new ArrayList<>(); + b.add(c); + b.add(newOne); + //com.neuronrobotics.sdk.common.Log.debug("Copy "+c.getName()+" to "+newOne.getName()); + cpMap.put(c.getName(), newOne.getName()); + return b; + } + + public TransformNR getLocation() { + return location; + } + + public Paste setLocation(TransformNR location) { + this.location = location; + return this; + } + + public List getNamesAddedInThisOperation() { + ArrayList n= new ArrayList(); + n.addAll(getNamesAdded()); + n.addAll(names); + return n; + } + + public Paste setNames(List names) { + this.names = names; + return this; + } + +// public Paste setOffset(double offset) { +// this.offset = offset; +// return this; +// } + + @Override + public File getFile() throws NoSuchFileException { + throw new NoSuchFileException(null); + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/RandomStringFactory.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/RandomStringFactory.java new file mode 100644 index 000000000..5c3d03e06 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/RandomStringFactory.java @@ -0,0 +1,86 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.Random; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase; + +public class RandomStringFactory { + @Expose (serialize = false, deserialize = false) + private static final String CHAR_POOL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + @Expose (serialize = false, deserialize = false) + private static final int STRING_LENGTH = 10; + + public static String[] adjectives = { + "Effervescent", "Zestful", "Vivacious", "Ebullient", "Sprightly", + "Exuberant", "Jocund", "Mirthful", "Zippy", "Gleeful", + "Buoyant", "Chipper", "Peppy", "Perky", "Jaunty", + "Blithe", "Joyous", "Spirited", "Vibrant", "Lively", + "Zealous", "Jubilant", "Merry", "Elated", "Euphoric", + "Bubbly", "Chirpy", "Animated", "Bouncy", "Energetic", + "Frisky", "Sparkling", "Vivid", "Zappy", "Zippy", + "Snappy", "Peppy", "Effulgent", "Radiant", "Luminous", + "Beaming", "Glowing", "Incandescent", "Resplendent", "Lustrous", + "Glistening", "Scintillating", "Efflorescent", "Blooming", "Flourishing", + "Thriving", "Burgeoning", "Prolific", "Teeming", + "Abundant", "Plentiful", "Bountiful", "Copious", "Profuse", + "Exuberant", "Luxuriant", "Lush", "Verdant", "Fertile", + "Productive", "Fruitful", "Generative", "Creative", "Imaginative", + "Inventive", "Ingenious", "Clever", "Brilliant", "Dazzling", + "Bright", "Luminous", "Radiant", "Gleaming", "Glittering", + "Sparkling", "Twinkling", "Shimmering", "Glowing", "Beaming", + "Effulgent", "Resplendent", "Splendid", "Magnificent", + "Majestic", "Grand", "Glorious", "Superb", "Marvelous", + "Wonderful", "Fantastic", "Fabulous", "Astounding", "Amazing" + }; + + public static String[] creaturesMachines = { + "Dragon", "Robot", "Unicorn", "Cyborg", "Griffin", + "Automaton", "Phoenix", "Mech", "Kraken", + "Chimera", "Golem", "Pegasus", "Android", "Hydra", + "Centaur", "Drone", "Sphinx", "Exosuit", "Minotaur", + "Cyclops", "Hologram", "Werewolf", "Nanobot", "Gorgon", + "Replicant", "Banshee", "Hovercraft", "Basilisk", "Jetpack", + "Gargoyle", "Teleporter", "Forcefield", + "Submarine", "Cerberus", "Hoverboard", "Siren", "Skycycle", + "Yeti", "Hoverbike", "Sasquatch", "Hyperloop", "Thunderbird", + "Gyrocopter", "Leviathan", "Airship", "Behemoth", "Starship", + "Colossus", "Monowheel", "Titan", "Rocketship", "Gremlin", + "Hovercar", "Imp", "Zeppelin", "Ogre", "Monorail", + "Troll", "Gnome", "Leprechaun", + "Hyperpod", "Fairy", "Gyrocar", "Elf", "Ornithopter", + "Hoversuit", "Specter", "Levitator", "Phantom", + "Telekinetic", "Goblin", "Gravicycle", "Dwarf", + "Jetbike", "Hobgoblin", "Ekranoplan", + "Aerotrain", "Sprite", "Maglev", "Aerosled", + "Cybertooth", "Ifrit", "Warpod", "Elemental", + "Hoversled", "Goliath", "Warpcraft", "Juggernaut", "Vortexer" + }; + + private static int index = ((Double) ConfigurationDatabase.get( + "CaDoodle", + "projectNameIndex", + (Math.random()*creaturesMachines.length))).intValue(); + + + public static String getNextRandomName() { + index++; + if(index>=creaturesMachines.length) + index=0; + ConfigurationDatabase.put("CaDoodle", "projectNameIndex", index); + return adjectives[(int) (Math.random()*adjectives.length)]+"_"+creaturesMachines[index]; + } + + public static String generateRandomString() { + Random random = new Random(); + StringBuilder stringBuilder = new StringBuilder(STRING_LENGTH); + + for (int i = 0; i < STRING_LENGTH; i++) { + int randomIndex = random.nextInt(CHAR_POOL.length()); + stringBuilder.append(CHAR_POOL.charAt(randomIndex)); + } + + return getNextRandomName()+"_"+stringBuilder.toString(); + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Resize.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Resize.java new file mode 100644 index 000000000..da16c3a6c --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Resize.java @@ -0,0 +1,239 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.creature.IMobileBaseUI; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.Bounds; +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Transform; +import eu.mihosoft.vrl.v3d.Vector3d; + +public class Resize extends CaDoodleOperation { + + @Expose(serialize = true, deserialize = true) + private List names = new ArrayList(); + + @Expose(serialize = true, deserialize = true) + private TransformNR height = null; + @Expose(serialize = true, deserialize = true) + private TransformNR leftFront = null; + @Expose(serialize = true, deserialize = true) + private TransformNR rightRear = null; + @Expose(serialize = true, deserialize = true) + private TransformNR workplane = new TransformNR(); + @Expose(serialize = false, deserialize = false) + private IMobileBaseUI debug; + + @Override + public String getType() { + return "Resize"; + } + + private class ResizeEvent { + Transform scaleZ; + Transform scale; + double movez; + double movey; + double movex; + } + + public Bounds getSellectedBounds(List incoming) { + Vector3d min = null; + Vector3d max = null; + for (CSG i : incoming) { + CSG c = i.transformed(TransformFactory.nrToCSG(getWorkplane().inverse())); + Vector3d min2 = c.getBounds().getMin().clone(); + Vector3d max2 = c.getBounds().getMax().clone(); + if (min == null) + min = min2; + if (max == null) + max = max2; + if (min2.x < min.x) + min.x = min2.x; + if (min2.y < min.y) + min.y = min2.y; + if (min2.z < min.z) + min.z = min2.z; + if (max.x < max2.x) + max.x = max2.x; + if (max.y < max2.y) + max.y = max2.y; + if (max.z < max2.z) + max.z = max2.z; + } + if (min == null || max == null) { + com.neuronrobotics.sdk.common.Log.debug("Found bounds to be null "); + + throw new RuntimeException("Min and max can not be null"); + } + return new Bounds(min, max); + } + + @Override + public List process(List incoming) { + ArrayList back = new ArrayList(); + back.addAll(incoming); + HashMap groupsProcessed = new HashMap<>(); + ArrayList selected = new ArrayList(); + for (CSG c : incoming) { + if (c.isLock()) + continue; + if (c.isNoScale()) + continue; + for (String name : names) { + if (c.getName().contentEquals(name)) { + selected.add(c); + } + } + } + if (selected.size() > 0) { + Bounds b = getSellectedBounds(selected); + for (String name : names) { + resizeByName(name, back, groupsProcessed, b); + } + } + return back; + } + + private void resizeByName(String name, ArrayList back, HashMap groupsProcessed, + Bounds bounds) { + for (int i = 0; i < back.size(); i++) { + CSG starting = back.get(i); + if (starting.getName().contentEquals(name)) { + double zScale = height.getZ() - bounds.getMin().z; + double scalez = zScale / (bounds.getMax().z - bounds.getMin().z); + + Transform scaleZ = new Transform().scaleZ(scalez); + CSG transformed = starting.transformed(TransformFactory.nrToCSG(getWorkplane().inverse())); + if (debug != null) { + debug.setCsg(transformed, null); + } + CSG resizeUp = transformed.transformed(scaleZ); + if (debug != null) { + debug.setCsg(resizeUp, null); + } + double zMove = -(bounds.getMin().z * scalez) + bounds.getMin().z; + resizeUp = resizeUp.movez(zMove); + if (debug != null) { + debug.setCsg(resizeUp, null); + } + double xdimen = Math.abs(leftFront.getX() - rightRear.getX()); + double ydimen = Math.abs(leftFront.getY() - rightRear.getY()); + double scalex = xdimen / (bounds.getMax().x - bounds.getMin().x); + double scaley = ydimen / (bounds.getMax().y - bounds.getMin().y); + double x = rightRear.getX(); + double y = rightRear.getY(); + + if (leftFront.getX() < x) { + scalex = -scalex; + } + if (leftFront.getY() < y) { + scaley = -scaley; + } + Transform scale = new Transform().scale(scalex, scaley, 1); + resizeUp = resizeUp.transformed(scale); + if (debug != null) { + debug.setCsg(resizeUp, null); + } + + double xMove = -(bounds.getMin().x * scalex) + x; + double yMove = -(bounds.getMin().y * scaley) + y; + resizeUp = resizeUp.movex(xMove).movey(yMove); + if (debug != null) { + debug.setCsg(resizeUp, null); + } + resizeUp = resizeUp.transformed(TransformFactory.nrToCSG(getWorkplane())); + if (debug != null) { + debug.setCsg(resizeUp, null); + } + resizeUp.syncProperties(getCaDoodleFile().getCsgDBinstance(),starting).setName(name); + ResizeEvent ev = new ResizeEvent(); + ev.movex = xMove; + ev.movey = yMove; + ev.movez = zMove; + ev.scale = scale; + ev.scaleZ = scaleZ; + back.set(i, resizeUp); + groupsProcessed.put(name, ev); + + if (starting.isGroupResult()) { + processCompositMembers(name, back, groupsProcessed); + } + } + } + } + + private void processCompositMembers(String name, ArrayList back, + HashMap groupsProcessed) { + for (int i = 0; i < back.size(); i++) { + CSG c = back.get(i); + if (c.isInGroup() && c.checkGroupMembership(name)) { + + ResizeEvent ev = groupsProcessed.get(name); + CSG transformed = c.transformed(TransformFactory.nrToCSG(getWorkplane().inverse())); + if (debug != null) { + debug.setCsg(transformed, null); + } + CSG gc = transformed.transformed(ev.scaleZ); + gc = gc.movez(ev.movez); + gc = gc.transformed(ev.scale); + gc = gc.movex(ev.movex).movey(ev.movey).transformed(TransformFactory.nrToCSG(getWorkplane())); + gc.syncProperties(getCaDoodleFile().getCsgDBinstance(),c).setName(c.getName()); + back.set(i, gc); + if (c.isGroupResult()) { + groupsProcessed.put(c.getName(), ev); + processCompositMembers(c.getName(), back, groupsProcessed); + } + } + } + } + + public Resize setResize(TransformNR h, TransformNR lf, TransformNR rr) { + height = h; + leftFront = lf; + rightRear = rr; + if (Math.abs(lf.getZ() - rr.getZ()) > 0.00001) { + throw new RuntimeException("The control points of the corners must be at the same Z value \n" + + lf.toSimpleString() + "\n" + rr.toSimpleString()); + } + if (rightRear.getY() >= leftFront.getY() && rightRear.getX() >= leftFront.getX()) + return setResize(h, rr, lf);// they were swapped, just fix it and move along +// if(rightRear.getY()>=leftFront.getY() || rightRear.getX()>=leftFront.getX()) +// throw new RuntimeException("Scale must be positive!"); + return this; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public Resize setNames(List names) { + this.names = names; + return this; + } + + public TransformNR getWorkplane() { + if (workplane == null) + workplane = new TransformNR(); + return workplane; + } + + public Resize setWorkplane(TransformNR workplane) { + this.workplane = workplane; + return this; + } + + public Resize setDebugger(IMobileBaseUI engine) { + this.debug = engine; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Show.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Show.java new file mode 100644 index 000000000..240d6cd5b --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Show.java @@ -0,0 +1,48 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; + +import eu.mihosoft.vrl.v3d.CSG; + +public class Show extends CaDoodleOperation{ + @Expose (serialize = true, deserialize = true) + private List names = new ArrayList(); + @Override + public String getType() { + return "Show"; + } + + @Override + public List process(List incoming) { + ArrayList replace = new ArrayList(); + ArrayList back = new ArrayList(); + back.addAll(incoming); + for(CSG c: incoming) { + for(String name:names) { + if(name.contentEquals(c.getName())) { + replace.add(c); + CSG b=c.clone().setRegenerate(c.getRegenerate()).syncProperties(getCaDoodleFile().getCsgDBinstance(),c); + b.setIsHide(false); + back.add(b); + } + } + } + for(CSG c:replace) { + back.remove(c); + } + return back; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public Show setNames(List names) { + this.names = names; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/StoragbeBounds.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/StoragbeBounds.java new file mode 100644 index 000000000..9e438cc1a --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/StoragbeBounds.java @@ -0,0 +1,57 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import com.google.gson.annotations.Expose; + +import eu.mihosoft.vrl.v3d.Bounds; +import eu.mihosoft.vrl.v3d.Vector3d; + +public class StoragbeBounds { + /** + * The x coordinate. + */ + @Expose (serialize = true, deserialize = true) + public double minx; + + /** + * The y coordinate. + */ + @Expose (serialize = true, deserialize = true) + public double miny; + + /** + * The z coordinate. + */ + @Expose (serialize = true, deserialize = true) + public double minz; + /** + * The x coordinate. + */ + @Expose (serialize = true, deserialize = true) + public double maxx; + + /** + * The y coordinate. + */ + @Expose (serialize = true, deserialize = true) + public double maxy; + + /** + * The z coordinate. + */ + @Expose (serialize = true, deserialize = true) + public double maxz; + public StoragbeBounds(Bounds b) { + minx=b.getMin().x; + miny=b.getMin().y; + minz=b.getMin().z; + maxx=b.getMax().x; + maxy=b.getMax().y; + maxz=b.getMax().z; + } + public Bounds getBounds() { + Vector3d min = new Vector3d(minx, miny, minz); + Vector3d max = new Vector3d(maxx, maxy, maxz); + return new Bounds(min, max); + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Sweep.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Sweep.java new file mode 100644 index 000000000..3de56ecb1 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/Sweep.java @@ -0,0 +1,342 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.bowlerstudio.scripting.DownloadManager; +import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.Bounds; +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.ColinearPointsException; +import eu.mihosoft.vrl.v3d.Cube; +import eu.mihosoft.vrl.v3d.Extrude; +import eu.mihosoft.vrl.v3d.Plane; +import eu.mihosoft.vrl.v3d.Polygon; +import eu.mihosoft.vrl.v3d.Transform; +import eu.mihosoft.vrl.v3d.ITransformProvider; +import eu.mihosoft.vrl.v3d.Vector3d; +import eu.mihosoft.vrl.v3d.ext.org.poly2tri.PolygonUtil; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.LengthParameter; +import eu.mihosoft.vrl.v3d.parametrics.Parameter; +import eu.mihosoft.vrl.v3d.parametrics.StringParameter; +import eu.mihosoft.vrl.v3d.svg.SVGLoad; +import javafx.scene.paint.Color; + +public class Sweep extends AbstractAddFrom { + @Expose(serialize = true, deserialize = true) + private TransformNR location = null; + private static ArrayList options = new ArrayList(); + private static ArrayList nopt = new ArrayList(); + @Expose(serialize = true, deserialize = true) + private Boolean preventBoM = false; + + private LengthParameter z = null; + private LengthParameter rad = null; + private LengthParameter step = null; + private LengthParameter angle = null; + private LengthParameter spiral = null; + @Expose(serialize = true, deserialize = true) + private double defz = 0; + @Expose(serialize = true, deserialize = true) + private double defrad = 10; + @Expose(serialize = true, deserialize = true) + private double defstep = 30; + @Expose(serialize = true, deserialize = true) + private double defangle = 360; + @Expose(serialize = true, deserialize = true) + private double defSpiral = 0; + + public Sweep set(File source, CaDoodleFile cf) throws Exception { + if (!source.getName().toLowerCase().endsWith(".svg")) + throw new Exception("Sweep can only take files with the .svg extention"); + com.neuronrobotics.sdk.common.Log.debug("Saving Local Copy of " + source.getAbsolutePath()); + AddFromFile.toLocal(source, getName(), cf); + setCaDoodleFile(cf); + try { + getFile(); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex); + ; + } + return this; + } + + @Override + public String getType() { + return "Sweep"; + } + + public CSG sweep(Polygon p, String name, Bounds b) { + double sweepTot = angle(name).getMM(); + double d = sweepTot / 360; + int steps = (int) (steps(name).getMM() * d); + double angle = sweepTot / steps; + Parameter zp = zoffset(name); + double z = zp.getMM() * d / steps; + double radius = radius(name).getMM(); + if (angle < 0) + angle = -angle; + double sprl = spiralStep(name).getMM(); + Transform centerandAllignedPolygon = new Transform().movex(-b.getMinX()).movey(-b.getMinY()); + Transform increment = new Transform().rotY(-angle).movey(z); + Transform radiusT = new Transform().movex(radius); + Polygon transformedP; + try { + transformedP = p.transformed(centerandAllignedPolygon); + + ITransformProvider pr = (unit, domain) -> { + return new Transform().movex(sprl * unit * d); + }; + return Extrude.sweep(transformedP, increment, radiusT, steps, pr).rotx(-90).setName(name); + } catch (ColinearPointsException e) { + // TODO Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + return new Cube(10).toCSG().setColor(Color.PINK); + } + + public LengthParameter radius(String name) { + String key = name + "_CaDoodle_Rad"; + if (rad == null) + rad = new LengthParameter(getCaDoodleFile().getCsgDBinstance(),key, getDefrad(), nopt); + if (rad.getMM() < 0) + rad.setMM(0); + return rad; + } + + public LengthParameter zoffset(String name) { + String key = name + "_CaDoodle_Z-per"; + if (z == null) + z = new LengthParameter(getCaDoodleFile().getCsgDBinstance(),key, getDefz(), nopt); + return z; + } + + public LengthParameter steps(String name) { + String key = name + "_CaDoodle_Step"; + if (step == null) + step = new LengthParameter(getCaDoodleFile().getCsgDBinstance(),key, getDefstep(), nopt); + if (step.getMM() < 3) + step.setMM(3); + return step; + } + + public LengthParameter angle(String name) { + String key = name + "_CaDoodle_Angle"; + if (angle == null) + angle = new LengthParameter(getCaDoodleFile().getCsgDBinstance(),key, getDefangle(), nopt); + if (angle.getMM() < 0.001) + angle.setMM(0.001); + return angle; + } + + public LengthParameter spiralStep(String name) { + String key = name + "_CaDoodle_Spiral"; + if (spiral == null) + spiral = new LengthParameter(getCaDoodleFile().getCsgDBinstance(),key, getDefSpiral(), nopt); + if (spiral.getMM() < 0) + spiral.setMM(0); + return spiral; + } + + @Override + public List process(List incoming) { + nameIndex = 0; + ArrayList back = new ArrayList(); + back.addAll(incoming); + if (getName() == null) { + + } + try { +// ArrayListargs = new ArrayList<>(); +// args.addAll(Arrays.asList(getName() )); + ArrayList collect = new ArrayList<>(); + File file = getFile(); + com.neuronrobotics.sdk.common.Log.debug("Loading File " + file.getAbsolutePath()); + if (!file.exists()) { + throw new RuntimeException("Failed to find file"); + } + + ArrayList args = new ArrayList<>(); + args.addAll(Arrays.asList(name)); + HashMap configs = new HashMap(); + configs.put("name", name); + configs.put("PreventBomAdd", preventBoM); + args.add(configs); + // List flattenedCSGs = ScriptingEngine.flaten(file, CSG.class, args); + SVGLoad s = new SVGLoad(file.toURI()); + HashMap> polygons = s.toPolygons(); + Object[] array = polygons.keySet().toArray(); + int j = 0; + Bounds b = getBounds(polygons); + for (int i = 0; i < array.length; i++) { + String key = (String) array[i]; + for (Polygon P : polygons.get(key)) { + + String orderedName = getOrderedName(); + CSG processedCSG = processGiven(P, b, j++, orderedName); + collect.add(processedCSG); + } + } + + back.addAll(collect); + } catch (Exception e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + return back; + } + + public Bounds getBounds(HashMap> polygons) { + Vector3d min = null; + Vector3d max = null; + // TickToc.tic("getSellectedBounds "+incoming.size()); + for (String s : polygons.keySet()) + for (Polygon csg : polygons.get(s)) { + + Bounds b = csg.getBounds(); + Vector3d min2 = b.getMin().clone(); + Vector3d max2 = b.getMax().clone(); + if (min == null) + min = min2; + if (max == null) + max = max2; + if (min2.x < min.x) + min.x = min2.x; + if (min2.y < min.y) + min.y = min2.y; + if (min2.z < min.z) + min.z = min2.z; + if (max.x < max2.x) + max.x = max2.x; + if (max.y < max2.y) + max.y = max2.y; + if (max.z < max2.z) + max.z = max2.z; + // TickToc.tic("Bounds for "+c.getName()); + } + + return new Bounds(min, max); + } + + @Override + public File getFile() throws NoSuchFileException { + return AddFromFile.getFile(name, getCaDoodleFile()); + } + + private CSG processGiven(Polygon p, Bounds b, int j, String name) { + Color c = p.getColor(); + if (c == null) + c = Color.ROSYBROWN; + boolean hole = p.isHole(); + CSG csg = sweep(p, name, b); + + Transform nrToCSG = TransformFactory.nrToCSG(getLocation()); + String pathname; + try { + pathname = getFile().getAbsolutePath(); + } catch (NoSuchFileException e) { + throw new RuntimeException(e); + } + + StringParameter parameter = new StringParameter(getCaDoodleFile().getCsgDBinstance(),name + "_CaDoodle_File", pathname, options); + Parameter steps = steps(name); + Parameter angle = angle(name); + Parameter z = zoffset(name); + Parameter radius = radius(name); + parameter.setStrValue(pathname); + CSG processedCSG = csg.transformed(nrToCSG).syncProperties(getCaDoodleFile().getCsgDBinstance(),csg) + .setParameter(getCaDoodleFile().getCsgDBinstance(), parameter) + .setParameter(getCaDoodleFile().getCsgDBinstance(), steps) + .setParameter(getCaDoodleFile().getCsgDBinstance(), angle) + .setParameter(getCaDoodleFile().getCsgDBinstance(), z) + .setParameter(getCaDoodleFile().getCsgDBinstance(), radius) + .setParameter(getCaDoodleFile().getCsgDBinstance(), spiralStep(pathname)) + .setColor(c).setIsHole(hole) + .setRegenerate(previous -> { + try { + File file = getFile(); + String fileLocation = file.getAbsolutePath(); + com.neuronrobotics.sdk.common.Log.error("Regenerating " + fileLocation); + return processGiven(p, b, j, name); + } catch (Exception e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + return previous; + }).setName(name); + MoveCenter.set(getName(), processedCSG, nrToCSG); + return processedCSG; + } + + public TransformNR getLocation() { + if (location == null) + location = new TransformNR(); + return location; + } + + public Sweep setLocation(TransformNR location) { + this.location = location; + return this; + } + + public Boolean getPreventBoM() { + return preventBoM; + } + + public Sweep setPreventBoM(Boolean preventBoM) { + this.preventBoM = preventBoM; + return this; + } + + public double getDefz() { + return defz; + } + + public void setDefz(double defz) { + this.defz = defz; + } + + public double getDefrad() { + return defrad; + } + + public void setDefrad(double defrad) { + this.defrad = defrad; + } + + public double getDefstep() { + return defstep; + } + + public void setDefstep(double defstep) { + this.defstep = defstep; + } + + public double getDefangle() { + return defangle; + } + + public void setDefangle(double defangle) { + this.defangle = defangle; + } + + public double getDefSpiral() { + return defSpiral; + } + + public void setDefSpiral(double defSpiral) { + this.defSpiral = defSpiral; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ToHole.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ToHole.java new file mode 100644 index 000000000..a4db3cc5d --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ToHole.java @@ -0,0 +1,50 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; + +import eu.mihosoft.vrl.v3d.CSG; + +public class ToHole extends CaDoodleOperation{ + @Expose (serialize = true, deserialize = true) + private List names = new ArrayList(); + @Override + public String getType() { + return "To Hole"; + } + + @Override + public List process(List incoming) { + ArrayList replace = new ArrayList(); + ArrayList back = new ArrayList(); + back.addAll(incoming); + for(CSG c: incoming) { + if(c.isLock()) + continue; + for(String name:names) { + if(name.contentEquals(c.getName())) { + replace.add(c); + CSG b=c.clone().setRegenerate(c.getRegenerate()).syncProperties(getCaDoodleFile().getCsgDBinstance(),c); + b.setIsHole(true); + back.add(b); + } + } + } + for(CSG c:replace) { + back.remove(c); + } + return back; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public ToHole setNames(List names) { + this.names = names; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ToSolid.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ToSolid.java new file mode 100644 index 000000000..5c3209eca --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/ToSolid.java @@ -0,0 +1,78 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; + +import eu.mihosoft.vrl.v3d.CSG; +import javafx.scene.paint.Color; + +public class ToSolid extends CaDoodleOperation{ + @Expose (serialize = true, deserialize = true) + private List names = new ArrayList(); + @Expose (serialize = true, deserialize = true) + private double r=1.0; + @Expose (serialize = true, deserialize = true) + private double g=0; + @Expose (serialize = true, deserialize = true) + private double b=0; + @Expose (serialize = true, deserialize = true) + private double a=1.0; + @Expose (serialize = true, deserialize = true) + private boolean useColor=false; + + @Override + public String getType() { + return "To Solid"; + } + + @Override + public List process(List incoming) { + ArrayList replace = new ArrayList(); + ArrayList back = new ArrayList(); + back.addAll(incoming); + for(CSG c: incoming) { + if(c.isLock()) + continue; + for(String name:names) { + if(name.contentEquals(c.getName())) { + replace.add(c); + CSG t=c.clone().setRegenerate(c.getRegenerate()).syncProperties(getCaDoodleFile().getCsgDBinstance(),c); + t.setIsHole(false); + if(useColor) { + t.setColor(getColor()); + } + back.add(t); + } + } + } + for(CSG c:replace) { + back.remove(c); + } + return back; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public ToSolid setNames(List names) { + this.names = names; + return this; + } + + public Color getColor() { + return new Color(r,g,b,a); + } + + public ToSolid setColor(Color color) { + r=color.getRed(); + g=color.getGreen(); + b=color.getBlue(); + a=color.getOpacity(); + useColor=true; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/UnGroup.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/UnGroup.java new file mode 100644 index 000000000..965382b95 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/UnGroup.java @@ -0,0 +1,65 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.io.File; +import java.nio.file.NoSuchFileException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import com.google.gson.annotations.Expose; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Transform; + +public class UnGroup extends CaDoodleOperation{ + @Expose(serialize = true, deserialize = true) + private List names = new ArrayList(); + + @Override + public String getType() { + return "Un-Group"; + } + @Override + public List process(List incoming) { + ArrayList back = new ArrayList(); + back.addAll(incoming); + + for (CSG csg : incoming) { + for (String name : names) { + if (csg.isGroupResult()) + if (csg.getName().contentEquals(name)) { + back.remove(csg); + } + if (csg.isInGroup()) { + if (csg.checkGroupMembership(name)) { + // release this object from the group + Transform nrToCSG = MoveCenter.getTotalOffset(csg); + CSG transformed=csg; + if(new CaDoodleVitamin(getCaDoodleFile().getCsgDBinstance()).isVitamin(csg)) { + CSG regenerate = csg.getRegenerate().regenerate(csg); + transformed = regenerate.transformed(nrToCSG); + } + CSG readd= transformed.setRegenerate(csg.getRegenerate()).syncProperties(getCaDoodleFile().getCsgDBinstance(),csg).setName(csg.getName()); + + readd.removeGroupMembership(name); + back.remove(csg); + back.add(readd); + } + } + + } + } + + return back; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public UnGroup setNames(List names) { + this.names = names; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/UnLock.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/UnLock.java new file mode 100644 index 000000000..f4e1b3a60 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/UnLock.java @@ -0,0 +1,48 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; + +import eu.mihosoft.vrl.v3d.CSG; + +public class UnLock extends CaDoodleOperation{ + @Expose (serialize = true, deserialize = true) + private List names = new ArrayList(); + @Override + public String getType() { + return "Un-Lock"; + } + + @Override + public List process(List incoming) { + ArrayList replace = new ArrayList(); + ArrayList back = new ArrayList(); + back.addAll(incoming); + for(CSG c: incoming) { + for(String name:names) { + if(name.contentEquals(c.getName())) { + replace.add(c); + CSG b=c.clone().setRegenerate(c.getRegenerate()).syncProperties(getCaDoodleFile().getCsgDBinstance(),c); + b.setIsLock(false); + back.add(b); + } + } + } + for(CSG c:replace) { + back.remove(c); + } + return back; + } + + public List getNamesAddedInThisOperation() { + return names; + } + + public UnLock setNames(List names) { + this.names = names; + return this; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/AddRobotController.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/AddRobotController.java new file mode 100644 index 000000000..86b6448e8 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/AddRobotController.java @@ -0,0 +1,116 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot; + +import java.io.File; +import java.io.FileNotFoundException; +import java.nio.file.NoSuchFileException; +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.creature.ControllerOption; +import com.neuronrobotics.bowlerstudio.creature.MobileBaseBuilder; +import com.neuronrobotics.bowlerstudio.physics.TransformFactory; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.AbstractAddFrom; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.Group; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.MoveCenter; +import com.neuronrobotics.sdk.addons.kinematics.VitaminLocation; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Transform; + +public class AddRobotController extends AbstractAddFrom { + @Expose(serialize = true, deserialize = true) + private String builderName; + @Expose(serialize = true, deserialize = true) + private ControllerOption controller; + @Expose(serialize = true, deserialize = true) + private TransformNR location = null; + @Expose(serialize = true, deserialize = true) + private List names; + + @Override + public void pruneCleanup() { + if (builderName != null) { + MobileBaseBuilder builder = getRobots().get(getBuilderName()); + builder.removeController(this); + } + } + + @Override + public File getFile() throws NoSuchFileException { + throw new NoSuchFileException(""); + } + + @Override + public String getType() { + return "AddRobotController"; + } + + public ArrayList getVitamins(String prefix){ + return controller.getVitamins(location,prefix); + } + + public AddRobotController setNames(List names) { + this.names = names; + return this; + } + + @Override + public List process(List incoming) { + nameIndex = 0; + ArrayList back = new ArrayList(); + back.addAll(incoming); + builderName = getBuilder(names, incoming); + try { + controller.runLinkLoader(); + } catch (FileNotFoundException e) { + } + for (int i = 0; i < controller.getVitaminNumber(); i++) { + CSG csg = controller.getVitaminCSG(getCaDoodleFile().getCsgDBinstance(),i).cloneShallow(); + TransformNR offset = getLocation().times(controller.getVitaminPose(i)); + Transform nrToCSG = TransformFactory.nrToCSG(offset); + String orderedName = getOrderedName(); + csg.setIsHole(true); + csg.setNoScale(true); + csg.setIsAlwaysShow(true); + if (getBuilderName() != null) { + csg.setMobileBaseName(getBuilderName()); + } + CSG tmp = csg.transformed(nrToCSG).syncProperties(getCaDoodleFile().getCsgDBinstance(),csg).setRegenerate(csg.getRegenerate()) + .setName(orderedName); + back.add(tmp); + MoveCenter.set(getName(), tmp, nrToCSG); + } + if(builderName!=null) { + MobileBaseBuilder builder = getRobots().get(getBuilderName()); + builder.addController(this); + } + return back; + } + + public ControllerOption getController() { + return controller; + } + + public AddRobotController setController(ControllerOption controller) { + this.controller = controller; + return this; + } + + public TransformNR getLocation() { + if (location == null) + location = new TransformNR(); + return location; + } + + public AddRobotController setLocation(TransformNR location) { + this.location = location; + return this; + } + + public String getBuilderName() { + return builderName; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/AddRobotLimb.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/AddRobotLimb.java new file mode 100644 index 000000000..3b608be38 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/AddRobotLimb.java @@ -0,0 +1,107 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot; + +import java.io.File; +import java.nio.file.NoSuchFileException; +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.creature.ControllerOption; +import com.neuronrobotics.bowlerstudio.creature.LimbOption; +import com.neuronrobotics.bowlerstudio.creature.MobileBaseBuilder; +import com.neuronrobotics.bowlerstudio.creature.MobileBaseCadManager; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.AbstractAddFrom; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.Group; +import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics; +import com.neuronrobotics.sdk.addons.kinematics.MobileBase; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; + +public class AddRobotLimb extends AbstractAddFrom{ + @Expose(serialize = true, deserialize = true) + private String builderName; + @Expose(serialize = true, deserialize = true) + private LimbOption limb; + @Expose(serialize = true, deserialize = true) + private TransformNR location = null; + @Expose(serialize = true, deserialize = true) + private List names; + public boolean forceLoad = false; + @Override + public void pruneCleanup() { + if (getBuilderName() != null) { + MobileBaseBuilder builder = getRobots().get(getBuilderName()); + builder.removeLimb(this); + } + } + @Override + public File getFile() throws NoSuchFileException { + throw new NoSuchFileException(""); + } + + @Override + public String getType() { + return "AddRobotLimb"; + } + + @Override + public List process(List incoming) { + nameIndex=0; + if(builderName==null) + setBuilderName(getBuilder(names, incoming)); + ArrayList back = new ArrayList(); + back.addAll(incoming); + if(getBuilderName()!=null) { + MobileBaseBuilder builder = getRobots().get(getBuilderName()); + builder.addLimb(this,forceLoad); + try { + builder.build(); + } catch (Exception e) { + com.neuronrobotics.sdk.common.Log.error(e); + } + + DHParameterKinematics newLimb = builder.getMobileBase().getLimbByName(getName()); + if(newLimb==null) + throw new RuntimeException("Failed to create a limb!"); + MobileBaseCadManager manager=builder.getCadManager(); + ArrayList limbCad = manager.generateCad(newLimb); + for(CSG c:limbCad) { + c.setName(getOrderedName()); + c.setLimbName(name); + c.setMobileBaseName(getBuilderName()); + c.setNoScale(true); + c.setIsMotionLock(true); + back.add(c); + } + manager.render(); + } + return back; + } + public AddRobotLimb setLimb(LimbOption o) { + limb = o; + return this; + } + public AddRobotLimb setNames(List names) { + this.names = names; + return this; + } + public LimbOption getLimb() { + return limb; + } + public AddRobotLimb setLocation(TransformNR location) { + this.location = location.copy(); + return this; + } + public TransformNR getLocation() { + if(location==null) + location=new TransformNR(); + return location; + } + public String getBuilderName() { + return builderName; + } + public void setBuilderName(String builderName) { + this.builderName = builderName; + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/MakeRobot.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/MakeRobot.java new file mode 100644 index 000000000..d7156a4e6 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/MakeRobot.java @@ -0,0 +1,80 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot; + +import java.io.File; +import java.nio.file.NoSuchFileException; +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.creature.MobileBaseBuilder; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.AbstractAddFrom; +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.parametrics.StringParameter; + +public class MakeRobot extends AbstractAddFrom { + @Expose(serialize = true, deserialize = true) + private List assignedAsBase = new ArrayList(); + //@Expose(serialize = true, deserialize = true) + MobileBaseBuilder builder; + + @Override + public String getType() { + return "MakeRobot"; + } + + @Override + public List process(List incoming) { + try { + getBuilder().build(); + for(CSG c:incoming) { + for(String s:assignedAsBase) { + if(c.getName().contentEquals(s)) { + c.setMobileBaseName(getName()); + } + } + } + } catch (Exception e) { + // TODO Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + return incoming; + } + + @Override + public List getNamesAddedInThisOperation() { + return new ArrayList(); + } + + @Override + public File getFile() throws NoSuchFileException { + try { + return getBuilder().getFile(); + } catch (Exception e) { + throw new NoSuchFileException(getName()); + } + } + + public List getNames() { + return assignedAsBase; + } + + public void setNames(List assignedAsBase) { + if(assignedAsBase.size()==0) + throw new RuntimeException("Can not create a robot without specifying a base"); + this.assignedAsBase = assignedAsBase; + } + + /** + * @return the builder + */ + public MobileBaseBuilder getBuilder() { + if (builder == null) { + String strValue = getCaDoodleFile().getSelf().getAbsolutePath(); + File parentFile = new File(strValue).getParentFile(); + String source = parentFile.getAbsolutePath(); + builder = new MobileBaseBuilder(source, getName() + "-mobilbase.xml"); + } + return builder; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/ModifyLimb.java b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/ModifyLimb.java new file mode 100644 index 000000000..a3c2fc62f --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/scripting/cadoodle/robot/ModifyLimb.java @@ -0,0 +1,224 @@ +package com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot; + +import java.io.File; +import java.nio.file.NoSuchFileException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import com.google.gson.annotations.Expose; +import com.neuronrobotics.bowlerstudio.creature.LimbOption; +import com.neuronrobotics.bowlerstudio.creature.MobileBaseBuilder; +import com.neuronrobotics.bowlerstudio.creature.MobileBaseCadManager; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.AbstractAddFrom; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.ICadoodleOperationUndo; +import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; + +public class ModifyLimb extends AbstractAddFrom implements ICadoodleOperationUndo { + @Expose(serialize = true, deserialize = true) + String limbName; + @Expose(serialize = true, deserialize = true) + private TransformNR base = null; + @Expose(serialize = true, deserialize = true) + private TransformNR tip = null; + @Expose(serialize = true, deserialize = true) + private TransformNR elbow = null; + + @Expose(serialize = true, deserialize = true) + boolean undo = false; + + @Expose(serialize = true, deserialize = true) + private TransformNR basePrevious = null; + @Expose(serialize = true, deserialize = true) + private TransformNR tipPrevious = null; + @Expose(serialize = true, deserialize = true) + private TransformNR elbowPrevious = null; + @Expose(serialize = true, deserialize = true) + private List names; + + private String builderName; + private DHParameterKinematics newLimb; + + @Override + public void pruneCleanup() { + if (getBuilderName() != null) { + MobileBaseBuilder builder = getRobots().get(getBuilderName()); + undo(); + builder.removeModification(this); + } + } + + public String getBuilderName() { + return builderName; + } + + public void setBuilderName(String builderName) { + this.builderName = builderName; + } + + @Override + public String getType() { + return "ModifyLimb"; + } + + @Override + public List process(List incoming) { + if (names == null) + throw new RuntimeException("Names can not be null"); + nameIndex = 0; + if (builderName == null) + setBuilderName(getBuilder(names, incoming)); + limbName = getLimbName(names, incoming); + + ArrayList back = new ArrayList(); + back.addAll(incoming); + if (getBuilderName() != null && limbName != null) { + MobileBaseBuilder builder = getRobots().get(getBuilderName()); + builder.addModification(this); + if (getLimb() == null) + setLimb(builder.getMobileBase().getLimbByName(limbName)); + if (getLimb() == null) + throw new RuntimeException("Failed to create a limb!"); + redo(); + MobileBaseCadManager manager = builder.getCadManager(); + if (elbow != null) { + ArrayList limbCad = manager.generateCad(getLimb()); + for (CSG c : incoming) { + Optional limbName2 = c.getLimbName(); + if (limbName2.isPresent()) + if (limbName2.get().contains(limbName)) { + back.remove(c); + } + } + for (CSG c : limbCad) { + c.setName(getOrderedName()); + c.setLimbName(limbName); + c.setMobileBaseName(getBuilderName()); + c.setNoScale(true); + c.setIsMotionLock(true); + back.add(c); + } + } + manager.render(); + } else { + throw new RuntimeException("Failed to find limb: " + limbName + " or builder: " + builderName); + } + return back; + } + + @Override + public File getFile() throws NoSuchFileException { + throw new NoSuchFileException(""); + } + + /** + * @return the base + */ + public TransformNR getBase() { + return !isUndo() ? base : basePrevious; + } + + /** + * @param base the base to set + */ + public ModifyLimb setBase(TransformNR base) { + this.base = base; + return this; + } + + /** + * @return the tip + */ + public TransformNR getTip() { + return !isUndo() ? tip : tipPrevious; + } + + /** + * @param tip the tip to set + */ + public ModifyLimb setTip(TransformNR tip) { + this.tip = tip; + return this; + } + + /** + * @return the elbow + */ + public TransformNR getElbow() { + return !isUndo() ? elbow : elbowPrevious; + } + + /** + * @param elbow the elbow to set + */ + public ModifyLimb setElbow(TransformNR elbow) { + this.elbow = elbow; + return this; + } + + public ModifyLimb setNames(List names) { + this.names = names; + return this; + } + + /** + * @return the newLimb + */ + public DHParameterKinematics getLimb() { + return newLimb; + } + + /** + * @param newLimb the newLimb to set + */ + public ModifyLimb setLimb(DHParameterKinematics newLimb) { + this.newLimb = newLimb; + basePrevious = newLimb.getRobotToFiducialTransform().copy(); + tipPrevious = newLimb.getCurrentTaskSpaceTransform().copy(); + return this; + } + + @Override + public void undo() { + MobileBaseBuilder builder = getRobots().get(getBuilderName()); + setUndo(true); + //com.neuronrobotics.sdk.common.Log.debug("Undo ModifyLimb"); + try { + builder.build(); + } catch (Exception e) { + // TODO Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + } + + @Override + public void redo() { + MobileBaseBuilder builder = getRobots().get(getBuilderName()); + setUndo(false); + //com.neuronrobotics.sdk.common.Log.debug("Redo ModifyLimb"); + try { + builder.build(); + } catch (Exception e) { + // TODO Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); + } + } + + /** + * @return the undo + */ + public boolean isUndo() { + return undo; + } + + /** + * @param undo the undo to set + */ + public void setUndo(boolean undo) { + this.undo = undo; + } + +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/sequence/SequenceEvent.java b/src/main/java/com/neuronrobotics/bowlerstudio/sequence/SequenceEvent.java index 656d87d9b..1af6e3ce9 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/sequence/SequenceEvent.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/sequence/SequenceEvent.java @@ -77,7 +77,7 @@ public void setMsDuration(int msDuration) { @Override public void done(InterpolationMoveState state) { - // TODO Auto-generated method stub + // Auto-generated method stub } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/sequence/TimeSequence.java b/src/main/java/com/neuronrobotics/bowlerstudio/sequence/TimeSequence.java index 125339cc0..09978e5b7 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/sequence/TimeSequence.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/sequence/TimeSequence.java @@ -16,6 +16,9 @@ import com.neuronrobotics.sdk.common.DeviceManager; import com.neuronrobotics.sdk.util.ThreadUtil; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; + import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; @@ -90,8 +93,8 @@ public void execute(String content) throws Exception { } public void runSequence() throws Exception { - System.out.println("Initialize Sequence"); - ScriptingEngine.gitScriptRun(getUrl(), getFile()); + com.neuronrobotics.sdk.common.Log.error("Initialize Sequence"); + ScriptingEngine.gitScriptRun(CSGDatabase.getInstance(),getUrl(), getFile()); HashMap devices = getDevices(); long start = System.currentTimeMillis(); @@ -103,13 +106,13 @@ public void runSequence() throws Exception { for (String mine : devices.keySet()) { for (String key : getDevicesInSequence()) if (mine.contentEquals(key)) { - System.out.println("Found Device " + key); + com.neuronrobotics.sdk.common.Log.error("Found Device " + key); HashMap devSeq = getSequence(key); Thread t = new Thread(() -> { for (int i = 0; i < finalDur && !Thread.interrupted(); i++) { SequenceEvent event = devSeq.get("" + i); if (event != null) { - System.out.println(key + " Execute @ " + i); + com.neuronrobotics.sdk.common.Log.error(key + " Execute @ " + i); event.execute((DHParameterKinematics) devices.get(key)); } try { @@ -122,7 +125,7 @@ public void runSequence() throws Exception { threads.add(t); } } - System.out.println("Running sequence"); + com.neuronrobotics.sdk.common.Log.error("Running sequence"); for (Thread t : threads) { t.start(); } @@ -135,7 +138,7 @@ public void runSequence() throws Exception { t.interrupt(); } } - System.out.println( + com.neuronrobotics.sdk.common.Log.error( "Running complete, took " + (System.currentTimeMillis() - start) + " expcted " + getDuration()); } @@ -163,7 +166,7 @@ private void addWavFileRun(ArrayList threads) throws InvalidRemoteExcept while (audioClip.isRunning() && !Thread.interrupted()) { double pos = (double) audioClip.getMicrosecondPosition() / 1000.0; double percent = pos / len * 100.0; - // System.out.println("Current " + pos + " Percent = " + percent); + // com.neuronrobotics.sdk.common.Log.error("Current " + pos + " Percent = " + percent); ThreadUtil.wait(10); } } catch (Throwable t) { @@ -172,7 +175,7 @@ private void addWavFileRun(ArrayList threads) throws InvalidRemoteExcept audioClip.stop(); audioClip.close(); ((AudioInputStream) audioStream).close(); - System.out.println("Audio clip exited "+getWavurl()+" : "+getWavfile()); + com.neuronrobotics.sdk.common.Log.error("Audio clip exited "+getWavurl()+" : "+getWavfile()); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/util/FileChangeWatcher.java b/src/main/java/com/neuronrobotics/bowlerstudio/util/FileChangeWatcher.java index 04581edf3..9c8a8d5b6 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/util/FileChangeWatcher.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/util/FileChangeWatcher.java @@ -41,7 +41,7 @@ import com.neuronrobotics.bowlerstudio.IssueReportingExceptionHandler; -// TODO: Auto-generated Javadoc +// Auto-generated Javadoc /** * The Class FileChangeWatcher. */ @@ -114,7 +114,7 @@ public static FileChangeWatcher watch(File fileToWatch) throws IOException { String path = fileToWatch.getAbsolutePath(); if (activeListener.get(path) == null) { activeListener.put(path, new FileChangeWatcher(fileToWatch)); - System.err.println("Adding file to listening " + fileToWatch.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.debug("Adding file to listening " + fileToWatch.getAbsolutePath()); } return activeListener.get(path); } @@ -130,14 +130,14 @@ public static FileChangeWatcher watch(File fileToWatch) throws IOException { private FileChangeWatcher(File fileToWatch) throws IOException { this.setFileToWatch(fileToWatch); - //System.err.println("\n\n\n\tWatching "+fileToWatch.getAbsolutePath()+"\n\n\n"); + //com.neuronrobotics.sdk.common.Log.error("\n\n\n\tWatching "+fileToWatch.getAbsolutePath()+"\n\n\n"); this.watcher = FileSystems.getDefault().newWatchService(); this.keys = new HashMap(); Path dir = Paths.get(fileToWatch.getParent()); if (recursive) { System.out.format("Scanning %s ...\n", dir); registerAll(dir); - System.out.println("Done."); + com.neuronrobotics.sdk.common.Log.error("Done."); } else { register(dir); } @@ -149,7 +149,7 @@ public void run() { while (run) { try { - //System.err.println("Checking File: " + getFileToWatch().getAbsolutePath()); + //com.neuronrobotics.sdk.common.Log.error("Checking File: " + getFileToWatch().getAbsolutePath()); watch(); } catch (Exception ex) { ex.printStackTrace(); @@ -158,7 +158,7 @@ public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } @@ -270,7 +270,7 @@ public void watch() { Path dir = keys.get(key); if (dir == null) { - System.err.println("WatchKey not recognized!!"); + com.neuronrobotics.sdk.common.Log.error("WatchKey not recognized!!"); return; } @@ -292,7 +292,7 @@ public void watch() { } // print out event // System.out.format("%s: %s\n", event.kind().name(), child); - System.err.println("File Changed: " + getFileToWatch().getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("File Changed: " + getFileToWatch().getAbsolutePath()); for (int i = 0; i < listeners.size(); i++) { listeners.get(i).onFileChange(child.toFile(), event); @@ -300,7 +300,7 @@ public void watch() { // overwrites } } catch (Exception e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } @@ -354,10 +354,10 @@ public void close() { //new Exception("File watcher closed " + fileToWatch.getAbsolutePath()).printStackTrace(); this.run = false; try { - System.err.println("Closing watcher for "+fileToWatch.getAbsolutePath()); + com.neuronrobotics.sdk.common.Log.error("Closing watcher for "+fileToWatch.getAbsolutePath()); watcher.close(); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } activeListener.remove(fileToWatch.getAbsolutePath()); diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/util/FileWatchDeviceWrapper.java b/src/main/java/com/neuronrobotics/bowlerstudio/util/FileWatchDeviceWrapper.java index e08bcf155..24f7019ff 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/util/FileWatchDeviceWrapper.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/util/FileWatchDeviceWrapper.java @@ -16,19 +16,19 @@ public static FileChangeWatcher watch(BowlerAbstractDevice device, File code,IFi @Override public void onDisconnect(BowlerAbstractDevice arg0) { - // TODO Auto-generated method stub + // Auto-generated method stub watcher.removeIFileChangeListener(cadWatcher); } @Override public void onConnect(BowlerAbstractDevice arg0) { - // TODO Auto-generated method stub + // Auto-generated method stub } }); return watcher; } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block //BowlerStudioController.highlightException(code, e); } return null; diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/util/GeometrySimplification.java b/src/main/java/com/neuronrobotics/bowlerstudio/util/GeometrySimplification.java new file mode 100644 index 000000000..46f1648d3 --- /dev/null +++ b/src/main/java/com/neuronrobotics/bowlerstudio/util/GeometrySimplification.java @@ -0,0 +1,78 @@ +package com.neuronrobotics.bowlerstudio.util; + +import static com.neuronrobotics.bowlerstudio.scripting.DownloadManager.legacySystemRun; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +import com.neuronrobotics.bowlerstudio.scripting.BlenderLoader; +import com.neuronrobotics.bowlerstudio.scripting.DownloadManager; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; + +public class GeometrySimplification { + /** + * Re-mesh the CSG to a voxelated mesh + * @param incoming the incoming CSG + * @param MMVoxel the mm dimentions of the voxel + * @return a re-meshed CSG + * @throws Exception + */ + public static CSG remesh(CSG incoming, double MMVoxel,CSGDatabaseInstance instance) throws Exception { + return BlenderLoader.remesh(null,incoming, MMVoxel,instance); + } + /** + * RE-mesh an STL file in place + * This modifys the original STL + * @param stlout the file in which he STL is stored + * @param MMVoxel the mm dimention of the voxels + * @throws Exception + */ + public static void remeshSTLFile(File stlout,double MMVoxel) throws Exception { + BlenderLoader.remeshSTLFile(null,stlout, MMVoxel); + } + /** + * Simplify an SVG file + * @param incoming the incoming SVG file + * @param threshhold the threshhold value (default is 0.002 + * @return A new SVG file that is changed + */ + public static File simplifySVG(File incoming) { + return simplifySVG(incoming,0.002); + } + /** + * Simplify an SVG file + * @param incoming the incoming SVG file + * @param threshhold the threshhold value (default is 0.002 + * @return A new SVG file that is changed + */ + public static File simplifySVG(File incoming, double threshhold) { + try { + File inkscape = DownloadManager.getConfigExecutable("inkscape", null); + File svg = File.createTempFile(incoming.getName(), ".svg"); + List args = Arrays.asList( + inkscape.getAbsolutePath(), + "--actions", + "\"select-all:all;path-simplify:threshold=" + threshhold+ ";;export-overwrite;export-do;quit-inkscape\"", + incoming.getAbsolutePath() + ); + legacySystemRun(null, inkscape.getAbsoluteFile().getParentFile(), System.out, args); + args = Arrays.asList( + inkscape.getAbsolutePath(), + "--export-plain-svg", + "--export-type=svg", + "--vacuum-defs", + "--export-filename="+svg.getAbsolutePath(), + incoming.getAbsolutePath() + ); + legacySystemRun(null, inkscape.getAbsoluteFile().getParentFile(), System.out, args); + return svg; + } catch (Exception e) { + // Auto-generated catch block + e.printStackTrace(); + } + return incoming; + } +} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/util/IFileChangeListener.java b/src/main/java/com/neuronrobotics/bowlerstudio/util/IFileChangeListener.java index 38fcf66ed..d4a066c2e 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/util/IFileChangeListener.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/util/IFileChangeListener.java @@ -3,7 +3,7 @@ import java.io.File; import java.nio.file.WatchEvent; -// TODO: Auto-generated Javadoc +// Auto-generated Javadoc /** * The listener interface for receiving IFileChange events. * The class that is interested in processing a IFileChange diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/IVitamin.java b/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/IVitamin.java deleted file mode 100644 index 3587c27f0..000000000 --- a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/IVitamin.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.neuronrobotics.bowlerstudio.vitamins; - -import eu.mihosoft.vrl.v3d.CSG; - -public interface IVitamin { - - public CSG toCSG(); -} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/MicroServo.java b/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/MicroServo.java deleted file mode 100644 index 01adb41cf..000000000 --- a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/MicroServo.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.neuronrobotics.bowlerstudio.vitamins; - -import java.io.File; -import java.io.IOException; - -import com.neuronrobotics.imageprovider.NativeResource; - -import eu.mihosoft.vrl.v3d.CSG; -import eu.mihosoft.vrl.v3d.STL; -import eu.mihosoft.vrl.v3d.Transform; - -public class MicroServo implements IVitamin { - - private static CSG servoModel; - - static { - - try { - File stl = NativeResource.inJarLoad(IVitamin.class, "hxt900-servo.stl"); - servoModel = STL.file(stl.toPath()); - servoModel = servoModel.transformed(new Transform().translateZ(-19.3)); - servoModel = servoModel.transformed(new Transform().translateX(5.4)); - -// stl = NativeResource.inJarLoad(IVitamin.class ,"arm.stl"); -// servoModel=servoModel.union(STL.file(stl.toPath())); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Override - public CSG toCSG() { - return servoModel.clone(); - } - -} diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/Purchasing.java b/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/Purchasing.java index 021b93e6e..068779eb7 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/Purchasing.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/Purchasing.java @@ -81,8 +81,8 @@ public static void saveDatabase(String type) throws Exception { "Pushing changed Database");//commit message } catch (org.eclipse.jgit.api.errors.TransportException ex) { - System.out.println("You need to fork " + getGitRpoDatabase() + " to have permission to save"); - System.out.println( + com.neuronrobotics.sdk.common.Log.error("You need to fork " + getGitRpoDatabase() + " to have permission to save"); + com.neuronrobotics.sdk.common.Log.error( "You do not have permission to push to this repo, change the GIT repo to your fork with setGitRpoDatabase(String gitRpoDatabase) "); throw ex; } @@ -184,8 +184,8 @@ public static ArrayList listVitaminTypes() { } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } return types; } @@ -231,7 +231,7 @@ public static ArrayList listVitaminVariants(String type, String size) { } catch (java.net.ConnectException ce) { // server or cart is not availible, reject vitamin } catch (Exception ex) { - ex.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(ex);; } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/VitaminBomManager.java b/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/VitaminBomManager.java index 5fbb34120..365d12073 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/VitaminBomManager.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/VitaminBomManager.java @@ -26,32 +26,32 @@ import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import javafx.scene.paint.Color; public class VitaminBomManager { - public static final String MANUFACTURING_BOM_BASE = "manufacturing/bom"; - public static final String MANUFACTURING_BOM_JSON = MANUFACTURING_BOM_BASE + ".json"; - public static final String MANUFACTURING_BOM_CSV = MANUFACTURING_BOM_BASE + ".csv"; + private static final String MANUFACTURING_BOM_BASE = "manufacturing/BillOfMaterials"; + private static final String MANUFACTURING_BOM_JSON = getManufacturingBomBase() + ".json"; + private static final String MANUFACTURING_BOM_CSV = getManufacturingBomBase() + ".csv"; private static boolean saving = false; -// private class VitaminLocation { -// String name; -// String type; -// String size; -// TransformNR pose; -// } - Type type = new TypeToken>>() { }.getType(); - Gson gson = new GsonBuilder().disableHtmlEscaping() - .excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + Gson gson = new GsonBuilder().disableHtmlEscaping().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting() + .create(); private HashMap> database = null;// - private String baseURL; + private String baseURL = null; + private File baseWorkspaceFile; public VitaminBomManager(String url) throws IOException { + this(ScriptingEngine.getRepositoryCloneDirectory(url)); baseURL = url; - File baseWorkspaceFile = ScriptingEngine.getRepositoryCloneDirectory(baseURL); - File bom = new File(baseWorkspaceFile.getAbsolutePath() + "/" + MANUFACTURING_BOM_JSON); + + } + + public VitaminBomManager(File parentFile) { + baseWorkspaceFile = parentFile; + File bom = getBomFile(); if (!bom.exists()) { if (!bom.getParentFile().exists()) { bom.getParentFile().mkdir(); @@ -59,8 +59,8 @@ public VitaminBomManager(String url) throws IOException { try { bom.createNewFile(); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } else { String source; @@ -68,50 +68,79 @@ public VitaminBomManager(String url) throws IOException { try { bytes = Files.readAllBytes(bom.toPath()); source = new String(bytes, "UTF-8"); - if(source.length()>0) + if (source.length() > 0) database = gson.fromJson(source, type); } catch (Exception ex) { - ex.printStackTrace(); + com.neuronrobotics.sdk.common.Log.error(ex);; } } - if(database==null) { - database=new HashMap>(); + if (database == null) { + database = new HashMap>(); save(); } } - -// public void set(String name, String type, String size, TransformNR location) { -// VitaminLocation newElement = getElement(name); -// if (newElement == null) { -// newElement = new VitaminLocation(name,type,size,location); -// } -// newElement.setLocation(location); -// newElement.setSize(size); -// newElement.setType(type); -// addVitamin(newElement); -// // newElement.url=(String) getConfiguration(name).get("source"); -// } - - public void addVitamin(VitaminLocation newElement) { + public File getBomCsv() { + return new File(baseWorkspaceFile.getAbsolutePath() + "/" + getManufacturingBomCsv()); + } + public File getBomFile() { + return new File(baseWorkspaceFile.getAbsolutePath() + "/" + getManufacturingBomJson()); + } + public VitaminLocation getByName(String name) { + for(String keys:database.keySet()) { + ArrayList arrayList = database.get(keys); + for (int i = 0; i < arrayList.size(); i++) { + VitaminLocation vl = arrayList.get(i); + if(vl.getName().contentEquals(name)) { + return vl; + } + } + } + return null; + } + public VitaminBomManager addVitamin(VitaminLocation newElement) { + return addVitamin(newElement,true); + } + public VitaminBomManager addVitamin(VitaminLocation newElement, boolean save) { + for(String keys:database.keySet()) { + ArrayList arrayList = database.get(keys); + for (int i = 0; i < arrayList.size(); i++) { + VitaminLocation vl = arrayList.get(i); + if(vl.getName().contentEquals(newElement.getName())) { + arrayList.remove(vl); + break; + } + } + } String key = newElement.getType() + ":" + newElement.getSize(); // synchronized (database) { if (database.get(key) == null) { database.put(key, new ArrayList()); } - boolean toAdd=!database.get(key).contains(newElement); + ArrayList arrayList = database.get(key); + + boolean toAdd = !arrayList.contains(newElement); + for (int i = 0; i < arrayList.size(); i++) { + VitaminLocation loc = arrayList.get(i); + if(loc.getName().contentEquals(newElement.getName())) { + arrayList.set(i,newElement); + return this; + } + } if (toAdd) - database.get(key).add(newElement); + arrayList.add(newElement); // } - save(); + if(save)save(); + return this; } - public CSG get(String name) { + public CSG get(CSGDatabaseInstance db,String name) { VitaminLocation e = getElement(name); if (e == null) throw new RuntimeException("Vitamin must be defined before it is used: " + name); try { - CSG transformed = MobileBaseCadManager.vitaminMakeCSG(e).transformed(TransformFactory.nrToCSG(e.getLocation())); + CSG transformed = MobileBaseCadManager.vitaminMakeCSG(db,e) + .transformed(TransformFactory.nrToCSG(e.getLocation())); transformed.setManufacturing(incominng -> { return null; }); @@ -119,8 +148,8 @@ public CSG get(String name) { return transformed; } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e1); } return null; } @@ -130,11 +159,11 @@ public TransformNR getCoMLocation(String name) { try { double x = (double) getConfiguration(name).get("massCentroidX"); double y = (double) getConfiguration(name).get("massCentroidY"); - + double z = (double) getConfiguration(name).get("massCentroidZ"); return e.getLocation().copy().translateX(x).translateY(y).translateZ(z); - }catch(Exception ex) { + } catch (Exception ex) { return e.getLocation().copy(); } } @@ -142,28 +171,29 @@ public TransformNR getCoMLocation(String name) { public double getMassKg(String name) { try { return (double) getConfiguration(name).get("massKg"); - }catch(Exception ex) { - ex.printStackTrace(); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; return 0.001; } } - public Map getConfiguration(String name) throws Exception{ + public Map getConfiguration(String name) throws Exception { VitaminLocation e = getElement(name); if (e == null) throw new RuntimeException("Vitamin must be defined before it is used: " + name); - if(e.isScript()) + if (e.isScript()) throw new RuntimeException("Script Vitamins do not have configurations"); return Vitamins.getConfiguration(e.getType(), e.getSize()); } - private VitaminLocation getElement(String name) { + public VitaminLocation getElement(String name) { // synchronized (database) { for (String testName : database.keySet()) { ArrayList list = database.get(testName); for (VitaminLocation el : list) { - if (el.getName().contentEquals(name)) + String name2 = el.getName(); + if (name2.contentEquals(name)) return el; } } @@ -171,13 +201,14 @@ private VitaminLocation getElement(String name) { return null; } - public void clear() { + public VitaminBomManager clear() { // synchronized (database) { database.clear(); // } + return this; } - private void saveLocal() { + private synchronized void saveLocal() { saving = true; String csv = "name,qty,source,unit price (USD)\n"; String content = null; @@ -190,50 +221,44 @@ private void saveLocal() { if (list.size() > 0) { VitaminLocation e = list.get(0); String size = database.get(key).size() + ""; - String URL =null; - Object object =null; - if(!e.isScript()) + String URL = null; + Object object = null; + if (!e.isScript()) try { Map configuration = getConfiguration(e.getName()); - URL=(String) configuration.get("source"); - object= configuration.get("price"); - }catch(Exception ex) { - ex.printStackTrace(); + URL = (String) configuration.get("source"); + object = configuration.get("price"); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; } - if(URL==null) { - URL="http://commonwealthrobotics.com"; + if (URL == null) { + URL = "http://commonwealthrobotics.com"; } - if(object==null) - object="0.01"; - - csv += key + "," + size + "," + URL +","+object+ "\n"; - } else { - System.out.println("Failure on " + key); - } - } + if (object == null) + object = "0.01"; - try { - String current = ScriptingEngine.codeFromGit(baseURL, MANUFACTURING_BOM_CSV)[0]; - String currentJ = ScriptingEngine.codeFromGit(baseURL, MANUFACTURING_BOM_JSON)[0]; - if (current.contentEquals(csv) && currentJ.contentEquals(content)) { - //System.out.println("No update, BoM current"); - saving = false; - return; - } - } catch (Exception e1) { - // file doesnt exist + csv += key + "," + size + "," + URL + "," + object + "\n"; + } } + if (baseURL != null) + try { + String current = ScriptingEngine.codeFromGit(baseURL, getManufacturingBomCsv())[0]; + String currentJ = ScriptingEngine.codeFromGit(baseURL, getManufacturingBomJson())[0]; + if (current.contentEquals(csv) && currentJ.contentEquals(content)) { + // com.neuronrobotics.sdk.common.Log.error("No update, BoM current"); + saving = false; + return; + } + } catch (Exception e1) { + // file doesnt exist + } try { - write(MANUFACTURING_BOM_JSON, content); - write(MANUFACTURING_BOM_CSV, csv); -// ScriptingEngine.commit(baseURL, ScriptingEngine.getBranch(baseURL), MANUFACTURING_BOM_JSON, content, -// "Save Bill Of Material", true); -// ScriptingEngine.commit(baseURL, ScriptingEngine.getBranch(baseURL), MANUFACTURING_BOM_CSV, csv, -// "Save Bill Of Material", true); + write(getManufacturingBomJson(), content); + write(getManufacturingBomCsv(), csv); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } saving = false; @@ -241,7 +266,7 @@ private void saveLocal() { private void write(String file, String content) throws InvalidRemoteException, TransportException, GitAPIException, IOException { - File f = ScriptingEngine.fileFromGit(baseURL, file); + File f = new File(baseWorkspaceFile.getAbsolutePath() + "/" + file); if (!f.getParentFile().exists()) f.getParentFile().mkdir(); if (!f.exists()) { @@ -252,25 +277,52 @@ private void write(String file, String content) writer.close(); } - public void save() { + public VitaminBomManager save() { saveLocal(); + return this; } - public void loadBaseVitamins(MobileBase base) { - for(VitaminLocation v:base.getVitamins()) { + public VitaminBomManager loadBaseVitamins(MobileBase base) { + for (VitaminLocation v : base.getVitamins()) { addVitamin(v); } - for(DHParameterKinematics k:base.getAllDHChains()) { - for(int i=0;i arrayList = database.get(keys); + for (int i = 0; i < arrayList.size(); i++) { + VitaminLocation vl = arrayList.get(i); + if(vl.getName().contentEquals(loc.getName())) { + arrayList.remove(vl); + return; + } + } + } } } diff --git a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/Vitamins.java b/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/Vitamins.java index 237788740..1c528384e 100644 --- a/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/Vitamins.java +++ b/src/main/java/com/neuronrobotics/bowlerstudio/vitamins/Vitamins.java @@ -1,20 +1,27 @@ package com.neuronrobotics.bowlerstudio.vitamins; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import com.neuronrobotics.sdk.common.Log; import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Cube; import eu.mihosoft.vrl.v3d.STL; import eu.mihosoft.vrl.v3d.Transform; +import eu.mihosoft.vrl.v3d.ext.openjfx.importers.obj.ObjImporter; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import eu.mihosoft.vrl.v3d.parametrics.LengthParameter; import eu.mihosoft.vrl.v3d.parametrics.StringParameter; +import javafx.scene.paint.Color; import com.neuronrobotics.bowlerstudio.BowlerKernel; import com.neuronrobotics.bowlerstudio.IssueReportingExceptionHandler; @@ -32,6 +39,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; + import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.eclipse.jgit.api.errors.CheckoutConflictException; @@ -50,24 +59,26 @@ public class Vitamins { private static String jsonRootDir = "json/"; - private static final Map fileLastLoaded = new HashMap(); - private static final Map>> databaseSet = new HashMap>>(); - private static final String defaultgitRpoDatabase = "https://github.com/madhephaestus/Hardware-Dimensions.git"; - private static String gitRpoDatabase = defaultgitRpoDatabase; + private static final Map fileLastLoaded = new ConcurrentHashMap(); + private static final Map>> databaseSet = new ConcurrentHashMap>>(); + private static final String sourceRepo = "CommonWealthRobotics/Hardware-Dimensions"; + private static final String defaultGit = "https://github.com/" + getSourcerepo() + ".git"; + private static String gitRpoDatabase = defaultGit; // Create the type, this tells GSON what datatypes to instantiate when parsing // and saving the json - private static Type TT_mapStringString = new TypeToken>>() { + private static Type TT_mapStringString = new TypeToken>>() { }.getType(); // chreat the gson object, this is the parsing factory private static Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create(); private static boolean checked; - private static HashMap changeListeners = new HashMap(); + private static ConcurrentHashMap changeListeners = new ConcurrentHashMap(); + public static void clear() { - System.out.println("Vitamins Database Cleraing, reloading files"); - for(String keys:databaseSet.keySet()) { - HashMap> data = databaseSet.get(keys); - for(String key2:data.keySet()) { - HashMap data2 = data.get(key2); + //com.neuronrobotics.sdk.common.Log.error("Vitamins Database Cleraing, reloading files"); + for (String keys : databaseSet.keySet()) { + ConcurrentHashMap> data = databaseSet.get(keys); + for (String key2 : data.keySet()) { + ConcurrentHashMap data2 = data.get(key2); data2.clear(); } data.clear(); @@ -75,16 +86,28 @@ public static void clear() { databaseSet.clear(); fileLastLoaded.clear(); } + @Deprecated public static CSG get(File resource) { - return get(resource,false); + return get(CSGDatabase.getInstance(),resource, false); } + @Deprecated public static CSG get(File resource, boolean forceRefresh) { + return get(CSGDatabase.getInstance(), resource, forceRefresh); + } + public static CSG get(CSGDatabaseInstance db,File resource) { + return get(db,resource, false); + } - if (fileLastLoaded.get(resource.getAbsolutePath()) == null||forceRefresh) { + public static CSG get(CSGDatabaseInstance db,File resource, boolean forceRefresh) { + + if (fileLastLoaded.get(resource.getAbsolutePath()) == null || forceRefresh) { // forces the first time the files is accessed by the application tou pull an // update try { - fileLastLoaded.put(resource.getAbsolutePath(), STL.file(resource.toPath())); + if(resource.getName().toLowerCase().endsWith(".stl")) + fileLastLoaded.put(resource.getAbsolutePath(), STL.file(resource.toPath())); +// if(resource.getName().toLowerCase().endsWith(".obj")) +// fileLastLoaded.put(resource.getAbsolutePath(), new ObjImporter(new FileInputStream(resource)).); // try { // FileChangeWatcher f = FileChangeWatcher.watch(resource); // f.addIFileChangeListener(new IFileChangeListener() { @@ -101,45 +124,46 @@ public static CSG get(File resource, boolean forceRefresh) { // } // }); // } catch (IOException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); +// // Auto-generated catch block +// com.neuronrobotics.sdk.common.Log.error(e); // } } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } - - return fileLastLoaded.get(resource.getAbsolutePath()).clone(); - } - - public static CSG get(String type, String id, String purchasingVariant) throws Exception { - String key = type + id + purchasingVariant; - if (fileLastLoaded.get(key) == null) { - PurchasingData purchasData = Purchasing.get(type, id, purchasingVariant); - for (String variable : purchasData.getVariantParameters().keySet()) { - double data = purchasData.getVariantParameters().get(variable); - LengthParameter parameter = new LengthParameter(variable, data, - (ArrayList) Arrays.asList(data, data)); - parameter.setMM(data); - } - - try { - fileLastLoaded.put(key, get(type, id)); - } catch (Exception e) { - e.printStackTrace(); - - gitRpoDatabase = defaultgitRpoDatabase; - clear(); - return get(type, id); - } - - } - - CSG vitToGet = fileLastLoaded.get(type + id); - // System.err.println("Loading "+vitToGet); - return vitToGet; - } + CSG csg = fileLastLoaded.get(resource.getAbsolutePath()); + + return csg.clone().setRegenerate(csg.getRegenerate()); + } + +// public static CSG get(String type, String id, String purchasingVariant) throws Exception { +// String key = type + id + purchasingVariant; +// if (fileLastLoaded.get(key) == null) { +//// PurchasingData purchasData = Purchasing.get(type, id, purchasingVariant); +//// for (String variable : purchasData.getVariantParameters().keySet()) { +//// double data = purchasData.getVariantParameters().get(variable); +//// LengthParameter parameter = new LengthParameter(variable, data, +//// (ArrayList) Arrays.asList(data, data)); +//// parameter.setMM(data); +//// } +// +// try { +// fileLastLoaded.put(key, get(type, id)); +// } catch (Exception e) { +// com.neuronrobotics.sdk.common.Log.error(e); +// +// setGitRepoDatabase(gitRpoDatabase); +// clear(); +// return get(type, id); +// } +// +// } +// +// CSG vitToGet = fileLastLoaded.get(type + id); +// // com.neuronrobotics.sdk.common.Log.error("Loading "+vitToGet); +// return vitToGet; +// } public static boolean isGitURL(String text2) { if (!text2.endsWith(".git")) @@ -150,66 +174,63 @@ public static boolean isGitURL(String text2) { new java.net.URL(text2); } catch (Exception ex) { if (!text2.startsWith("git@")) { - ex.printStackTrace(); - return false ; + com.neuronrobotics.sdk.common.Log.error(ex);; + return false; } } return true; } + public static void flatten(ArrayList flat, Object o) { - if(CSG.class.isInstance(o)) - flat.add((CSG)o); - if(List.class.isInstance(o)) { - for(Object ob:(List)o) { - flatten(flat,ob); - } + ScriptingEngine.flatten(flat, o); + } +// public static CSG get(String type, String id) throws Exception { +// return get(CSGDatabase.getInstance(),type,id); +// } + public static CSG get(CSGDatabaseInstance instance,String type, String id) throws Exception { + if (isGitURL(type)) { + Object o = ScriptingEngine.gitScriptRun(instance,type, id); + ArrayList flat = new ArrayList(); + Vitamins.flatten(flat, o); + return CSG.unionAll(flat); } - - } - - public static CSG get(String type, String id) throws Exception { - if(isGitURL(type)) { - Object o =ScriptingEngine.gitScriptRun(type, id); - ArrayList flat= new ArrayList(); - Vitamins.flatten(flat,o); - return CSG.unionAll( flat); - } - return get(type, id, 0); + return get(instance,type, id, 0); } - private static CSG get(String type, String id, int depthGauge) throws Exception { + private static CSG get(CSGDatabaseInstance instance,String type, String id, int depthGauge) throws Exception { String key = type + id; - + Map script = getMeta(type); + Object file = null; + Object repostring =null; try { CSG newVitamin = null; - Map script = getMeta(type); - StringParameter size = new StringParameter(type + " Default", id, Vitamins.listVitaminSizes(type)); + StringParameter size = new StringParameter(instance,type + " Default", id, Vitamins.listVitaminSizes(type)); size.setStrValue(id); - Object file = script.get("scriptGit"); - Object repostring = script.get("scriptFile"); + file = script.get("scriptGit"); + repostring = script.get("scriptFile"); Object repo = repostring; if (file != null && repo != null) { ArrayList servoMeasurments = new ArrayList(); servoMeasurments.add(id); - newVitamin = (CSG) ScriptingEngine.gitScriptRun(script.get("scriptGit").toString(), // git location of + newVitamin = (CSG) ScriptingEngine.gitScriptRun(instance,script.get("scriptGit").toString(), // git location of // the library repostring.toString(), // file to load servoMeasurments); Map configuration = Vitamins.getConfiguration(type, id); - newVitamin.setName(type +"-"+ id); + newVitamin.setName(type + "-" + id); newVitamin.setManufacturing(incoming -> null); + newVitamin.setNoScale(true); try { Transform com = new Transform() - .movex(Double.parseDouble(configuration.get("massCentroidX").toString())) - .movey(Double.parseDouble(configuration.get("massCentroidY").toString())) - .movez(Double.parseDouble(configuration.get("massCentroidZ").toString())); + .movex(Double.parseDouble(configuration.get("massCentroidX").toString())) + .movey(Double.parseDouble(configuration.get("massCentroidY").toString())) + .movez(Double.parseDouble(configuration.get("massCentroidZ").toString())); newVitamin.getStorage().set("massKg", configuration.get("massKg")); newVitamin.getStorage().set("massCentroid", com); - return newVitamin; - }catch(Exception ex) { - //System.err.println(type +"-"+ id+" Failed"); - //ex.printStackTrace(); + } catch (Exception ex) { + // com.neuronrobotics.sdk.common.Log.error(type +"-"+ id+" Failed"); + // com.neuronrobotics.sdk.common.Log.error(ex);; return newVitamin; } } else { @@ -217,206 +238,226 @@ private static CSG get(String type, String id, int depthGauge) throws Exception return null; } } catch (Exception e) { - e.printStackTrace(); - gitRpoDatabase = defaultgitRpoDatabase; + com.neuronrobotics.sdk.common.Log.error(e); + setGitRepoDatabase(gitRpoDatabase); + //ScriptingEngine.deleteRepo(script.get("scriptGit").toString()); clear(); if (depthGauge < 2) { - return get(type, id, depthGauge + 1); + return get(instance,type, id, depthGauge + 1); } else { - return null; + return new Cube(20).toCSG().setColor(Color.RED); } } } + public static String getScriptGitURL(String type) { Map script = getMeta(type); - - + return script.get("scriptGit").toString(); } + + public static void loadAllScriptFiles() { + for (String type : listVitaminTypes()) { + getScriptFile(type); + } + } + public static File getScriptFile(String type) { Map script = getMeta(type); - + try { return ScriptingEngine.fileFromGit(script.get("scriptGit").toString(), script.get("scriptFile").toString()); } catch (InvalidRemoteException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } catch (TransportException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } catch (GitAPIException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } return null; } - public static Map getMeta(String type) { - return getConfigurationRW(type, "meta"); + public static ConcurrentHashMap getMeta(String type) { + return getConfiguration(type, "meta"); } public static void setScript(String type, String git, String file) throws Exception { setParameter(type, "meta", "scriptGit", git); setParameter(type, "meta", "scriptFile", file); } - - public static Map getConfiguration(String type, String id){ - return Collections.unmodifiableMap(getConfigurationRW( type, id)); + + public static ConcurrentHashMap getConfiguration(String type, String id) { + ConcurrentHashMap> database = getDatabase(type); + if (id== null) { + id=Vitamins.listVitaminSizes(type).get(0); + } + + ConcurrentHashMap ConcurrentHashMap = database.get(id); + try { + Object[] array = ConcurrentHashMap.keySet().toArray(); + for (int i = 0; i < array.length; i++) { + String key = (String) array[i]; + sanatize(key, ConcurrentHashMap); + } + return ConcurrentHashMap; + }catch(Exception ex) { + //com.neuronrobotics.sdk.common.Log.error(ex);; + } + return new ConcurrentHashMap(); } - public static void putMeasurment(String type, String size,String measurementName, Object measurmentValue) { - getConfigurationRW(type,size).put(measurementName, measurmentValue); + + public static void putMeasurment(String type, String size, String measurementName, Object measurmentValue) { + ConcurrentHashMap configurationRW = getConfigurationRW(type, size); + configurationRW.put(measurementName, measurmentValue); + sanatize(measurementName, configurationRW); } - public static Object getMeasurement(String type, String size,String measurementName) { - return getConfigurationRW(type,size).get(measurementName); + + public static Object getMeasurement(String type, String size, String measurementName) { + return getConfigurationRW(type, size).get(measurementName); } - public static HashMap getConfigurationRW(String type, String id) { - HashMap> database = getDatabase(type); - if (database.get(id) == null) { - database.put(id, new HashMap()); + + public static ConcurrentHashMap getConfigurationRW(String type, String id) { + ConcurrentHashMap> database = getDatabase(type); + if (id == null) { + id=Vitamins.listVitaminSizes(type).get(0); } - for(int j=0;j<5;j++) { - try { - HashMap hashMap = database.get(id); - Object[] array = hashMap.keySet().toArray(); - for (int i=0;i ConcurrentHashMap = database.get(id); + if(ConcurrentHashMap == null) { + ConcurrentHashMap=new ConcurrentHashMap (); + + database.put(id, ConcurrentHashMap); } - return new HashMap(); + Object[] array = ConcurrentHashMap.keySet().toArray(); + for (int i = 0; i < array.length; i++) { + String key = (String) array[i]; + sanatize(key, ConcurrentHashMap); + } + return ConcurrentHashMap; + } public static String makeJson(String type) { return gson.toJson(getDatabase(type), TT_mapStringString); } - public static void saveDatabase(String type) throws Exception { + public static boolean saveDatabase(String type) throws Exception { // Save contents and publish them String jsonString = makeJson(type); try { - //new Exception().printStackTrace(); - ScriptingEngine.pushCodeToGit(getGitRepoDatabase(), // git repo, change this if you fork this demo - ScriptingEngine.getFullBranch(getGitRepoDatabase()), // branch or tag + // new Exception().printStackTrace(); + String gitRepoDatabase = getGitRepoDatabase(); + ScriptingEngine.pushCodeToGit(gitRepoDatabase, // git repo, change this if you fork this demo + null, // branch or tag getRootFolder() + type + ".json", // local path to the file in git jsonString, // content of the file - "Making changes to "+type+" by "+PasswordManager.getUsername()+"\n\nAuto-save inside com.neuronrobotics.bowlerstudio.vitamins.Vitamins inside bowler-scripting-kernel");// commit message - //System.err.println(jsonString); - System.out.println("Database saved "+getVitaminFile(type,null,false).getAbsolutePath()); - } catch (org.eclipse.jgit.api.errors.TransportException ex) { - System.out.println("You need to fork " + defaultgitRpoDatabase + " to have permission to save"); - System.out.println( - "You do not have permission to push to this repo, change the GIT repo to your fork with setGitRpoDatabase(String gitRpoDatabase) "); + "Making changes to " + type + " by " + PasswordManager.getUsername() + + "\n\nAuto-save inside com.neuronrobotics.bowlerstudio.vitamins.Vitamins inside bowler-scripting-kernel");// commit + // message + // com.neuronrobotics.sdk.common.Log.error(jsonString); + //com.neuronrobotics.sdk.common.Log.error("Database saved " + getVitaminFile(type, null, false).getAbsolutePath()); + } catch (Exception ex) { + if(ex.getMessage().contains("Cannot commit on a repo with state: MERGING")) { + ScriptingEngine.deleteRepo(getGitRepoDatabase()); + saveDatabase(type); + return true; + } + com.neuronrobotics.sdk.common.Log.error(ex);; throw ex; } - + return true; } - public static void saveDatabaseForkIfMissing(String type) throws Exception { + + public static void saveDatabaseForkIfMissing(String type,String username) throws Exception { org.kohsuke.github.GitHub github = PasswordManager.getGithub(); - GHRepository repo = github.getRepository("madhephaestus/Hardware-Dimensions"); - try { - saveDatabase(type); - } catch (org.eclipse.jgit.api.errors.TransportException ex) { - System.err.println("Forked repo is missing!"); - - GHRepository newRepo = repo.fork(); - Thread.sleep(6000); - Vitamins.gitRpoDatabase = newRepo.getGitTransportUrl().replaceAll("git://", "https://"); - saveDatabase(type); - - } - if(PasswordManager.getUsername().contentEquals("madhephaestus")) - return; + GHRepository repo = github.getRepository(getSourcerepo()); + GHRepository newRepo; try { - GHRepository myrepo = github.getRepository(PasswordManager.getUsername()+"/Hardware-Dimensions"); - List asList1 = myrepo.queryPullRequests().state(GHIssueState.OPEN).head("madhephaestus:master") - .list().asList(); - Thread.sleep(200);// Some asynchronus delay here, not sure why... - if(asList1.size()==0) { - try { - GHPullRequest request = myrepo.createPullRequest("Update from source", - "madhephaestus:master", - "master", - "## Upstream add vitamins", - false, false); - if(request!=null) { - processSelfPR(request); - } - }catch(org.kohsuke.github.HttpException ex) { - // no commits have been made to master - } - - }else { - processSelfPR(asList1.get(0)); - } - String head = PasswordManager.getUsername()+":master"; - List asList = repo.queryPullRequests() - .state(GHIssueState.OPEN) - .head(head) - .list().asList(); - if(asList.size()==0) { - System.err.println("Creating PR for "+head); - GHPullRequest request = repo.createPullRequest("User Added vitamins to "+type, - head, - "master", - "## User added vitamins", - true, true); + newRepo=github.getRepository(username+"/Hardware-Dimensions"); + String newURL = newRepo.getGitTransportUrl().replaceAll("git://", "https://"); + ScriptingEngine.pull(newURL); + ArrayList files = ScriptingEngine.filesInGit(newURL); + if(type!=null) + saveDatabase(type); + } catch (Exception ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; + //com.neuronrobotics.sdk.common.Log.error("Forked repo is missing!"); + + newRepo = github.getRepository(getSourcerepo()).fork(); + while(true) { try { - BowlerKernel.upenURL(request.getHtmlUrl().toURI()); - } catch (URISyntaxException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Thread.sleep(6000); + String newURL = newRepo.getGitTransportUrl().replaceAll("git://", "https://"); + Vitamins.setGitRepoDatabase(newURL); + break; + }catch(Exception exc) { + System.err.println("Waiting for repo to finish forking"); + com.neuronrobotics.sdk.common.Log.error(exc); } - }else { - } - }catch(Exception ex) { - new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(),ex); + saveDatabase(type); + } - + +// try { +// GHRepository myrepo = github.getRepository(username+ "/Hardware-Dimensions"); +// List asList1 = myrepo.queryPullRequests().state(GHIssueState.OPEN) +// .head("madhephaestus:master").list().asList(); +// Thread.sleep(200);// Some asynchronus delay here, not sure why... +// if (asList1.size() == 0) { +// try { +// GHPullRequest request = myrepo.createPullRequest("Update from source", "madhephaestus:master", +// "master", "## Upstream add vitamins", false, false); +// if (request != null) { +// processSelfPR(request); +// } +// } catch (org.kohsuke.github.HttpException ex) { +// // no commits have been made to master +// } +// +// } else { +// processSelfPR(asList1.get(0)); +// } +// +// } catch (Exception ex) { +// new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), ex); +// } } private static void processSelfPR(GHPullRequest request) throws IOException { - if(request== null) + if (request == null) return; try { if (request.getMergeable()) { request.merge("Auto Merging Master"); reLoadDatabaseFromFiles(); - System.out.println("Merged Hardware-Dimensions madhephaestus:master into "+PasswordManager.getUsername()+":master"); + //com.neuronrobotics.sdk.common.Log.error("Merged Hardware-Dimensions madhephaestus:master into " + // + PasswordManager.getUsername() + ":master"); } else { try { BowlerKernel.upenURL(request.getHtmlUrl().toURI()); } catch (URISyntaxException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } } - }catch(java.lang.NullPointerException ex) { - ex.printStackTrace(); + } catch (java.lang.NullPointerException ex) { + com.neuronrobotics.sdk.common.Log.error(ex);; } } + public static void newVitamin(String type, String id) throws Exception { - HashMap> database = getDatabase(type); + ConcurrentHashMap> database = getDatabase(type); if (database.keySet().size() > 0) { String exampleKey = null; for (String key : database.keySet()) { @@ -441,15 +482,15 @@ public static void newVitamin(String type, String id) throws Exception { public static void setParameter(String type, String id, String parameterName, Object parameter) throws Exception { - HashMap config = getConfigurationRW(type, id); + ConcurrentHashMap config = getConfigurationRW(type, id); config.put(parameterName, parameter); - sanatize(parameterName, config); + sanatize(parameterName, config); // saveDatabase(type); } - private static void sanatize(String parameterName, HashMap config) { - Object parameter=config.get(parameterName); + private static void sanatize(String parameterName, ConcurrentHashMap config) { + Object parameter = config.get(parameterName); try { config.put(parameterName, Double.parseDouble(parameter.toString())); } catch (NumberFormatException ex) { @@ -457,7 +498,7 @@ private static void sanatize(String parameterName, HashMap conf } } - public static HashMap> getDatabase(String type) { + public static ConcurrentHashMap> getDatabase(String type) { if (databaseSet.get(type) == null) { // we are using the default vitamins configuration // https://github.com/madhephaestus/Hardware-Dimensions.git @@ -469,46 +510,45 @@ public static HashMap> getDatabase(String type) // attempt to load the JSON file from the GIt Repo and pars the JSON string File f; try { - - Runnable onChange=null; - if(changeListeners.get(type)==null) { - changeListeners.put(type,() -> { + + Runnable onChange = null; + if (changeListeners.get(type) == null) { + changeListeners.put(type, () -> { // If the file changes, clear the database and load the new data - System.out.println("Re-loading "+type); - databaseSet.put(type,null); - new RuntimeException().printStackTrace(); + //com.neuronrobotics.sdk.common.Log.error("Re-loading " + type); + databaseSet.put(type, null); + com.neuronrobotics.sdk.common.Log.error(new RuntimeException()); }); - onChange=changeListeners.get(type); + onChange = changeListeners.get(type); } - - - f = getVitaminFile(type,onChange,true); - HashMap> database; - if(f.exists()) { - + f = getVitaminFile(type, onChange, true); + + ConcurrentHashMap> database; + if (f.exists()) { + inPut = FileUtils.openInputStream(f); - + jsonString = IOUtils.toString(inPut); inPut.close(); - System.out.println("JSON loading Loading "+type+" "+jsonString.length()); + //com.neuronrobotics.sdk.common.Log.error("JSON loading Loading " + type + " " + jsonString.length()); // perfoem the GSON parse database = gson.fromJson(jsonString, TT_mapStringString); - if(database==null) + if (database == null) throw new RuntimeException("Database failed to read"); - }else { - database=new HashMap>(); + } else { + database = new ConcurrentHashMap>(); } databaseSet.put(type, database); for (String key : databaseSet.get(type).keySet()) { - HashMap conf = database.get(key); + ConcurrentHashMap conf = database.get(key); for (String confKey : conf.keySet()) { try { double num = Double.parseDouble(conf.get(confKey).toString()); conf.put(confKey, num); } catch (NumberFormatException ex) { - // ex.printStackTrace(); + // com.neuronrobotics.sdk.common.Log.error(ex);; // leave as a string conf.put(confKey, conf.get(confKey).toString()); } @@ -516,8 +556,8 @@ public static HashMap> getDatabase(String type) } } catch (Exception e) { - e.printStackTrace(); - databaseSet.put(type, new HashMap>()); + com.neuronrobotics.sdk.common.Log.error(e); + databaseSet.put(type, new ConcurrentHashMap>()); } } return databaseSet.get(type); @@ -526,12 +566,11 @@ public static HashMap> getDatabase(String type) public static File getVitaminFile(String type, Runnable onChange, boolean oneShot) throws InvalidRemoteException, TransportException, GitAPIException, IOException { - - - File f= ScriptingEngine.fileFromGit(getGitRepoDatabase(), // git repo, change this if you fork this demo + + File f = ScriptingEngine.fileFromGit(getGitRepoDatabase(), // git repo, change this if you fork this demo getRootFolder() + type + ".json"// File from within the Git repo ); - if(onChange!=null) { + if (onChange != null) { // FileChangeWatcher watcher = FileChangeWatcher.watch(f); // watcher.addIFileChangeListener((fileThatChanged, event) -> { // onChange.run(); @@ -543,36 +582,40 @@ public static File getVitaminFile(String type, Runnable onChange, boolean oneSho private static String getRootFolder() { return getJsonRootDir(); } - public static ArrayList listVitaminActuators() { - ArrayList actuators = new ArrayList(); - + + public static CopyOnWriteArrayList listVitaminActuators() { + CopyOnWriteArrayList actuators = new CopyOnWriteArrayList(); + for (String vitaminsType : Vitamins.listVitaminTypes()) { - if (isActuator( vitaminsType)) + if (isActuator(vitaminsType)) actuators.add(vitaminsType); } return actuators; } - public static ArrayList listVitaminShafts() { - ArrayList actuators = new ArrayList(); + + public static CopyOnWriteArrayList listVitaminShafts() { + CopyOnWriteArrayList actuators = new CopyOnWriteArrayList(); for (String vitaminsType : Vitamins.listVitaminTypes()) { - if (isShaft( vitaminsType)) + if (isShaft(vitaminsType)) actuators.add(vitaminsType); } return actuators; } - + public static boolean isShaft(String vitaminsType) { Map meta = Vitamins.getMeta(vitaminsType); if (meta != null && meta.containsKey("shaft")) return true; return false; } + public static boolean isActuator(String vitaminsType) { Map meta = Vitamins.getMeta(vitaminsType); if (meta != null && meta.containsKey("actuator")) return true; return false; } + public static void setIsShaft(String type) { Vitamins.getMeta(type).remove("motor"); Vitamins.getMeta(type).put("shaft", "true"); @@ -582,12 +625,14 @@ public static void setIsActuator(String type) { Vitamins.getMeta(type).remove("shaft"); Vitamins.getMeta(type).put("actuator", "true"); } - public static ArrayList listVitaminTypes() { - ArrayList types = new ArrayList(); + public static CopyOnWriteArrayList listVitaminTypes() { + + CopyOnWriteArrayList types = new CopyOnWriteArrayList(); File folder; - try { - folder = new File(ScriptingEngine.getRepositoryCloneDirectory(getGitRepoDatabase()).getAbsoluteFile()+"/"+getRootFolder()); + try { + folder = new File(ScriptingEngine.getRepositoryCloneDirectory(getGitRepoDatabase()).getAbsoluteFile() + "/" + + getRootFolder()); File[] listOfFiles = folder.listFiles(); for (File f : listOfFiles) { @@ -597,8 +642,8 @@ public static ArrayList listVitaminTypes() { } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e); } Collections.sort(types); return types; @@ -607,7 +652,7 @@ public static ArrayList listVitaminTypes() { public static ArrayList listVitaminSizes(String type) { ArrayList types = new ArrayList(); - HashMap> database = getDatabase(type); + ConcurrentHashMap> database = getDatabase(type); Set keys = database.keySet(); for (Iterator iterator = keys.iterator(); iterator.hasNext();) { String s = iterator.next(); @@ -621,29 +666,29 @@ public static ArrayList listVitaminSizes(String type) { return types; } - public static String getGitRepoDatabase() { + public static String getGitRepoDatabase() { if (!checked) { checked = true; - try { - if (PasswordManager.getUsername() != null) { - //ScriptingEngine.setAutoupdate(true); - org.kohsuke.github.GitHub github = PasswordManager.getGithub(); - try { - GHRepository repo =github.getRepository(PasswordManager.getLoginID() + "/Hardware-Dimensions" ); - if(repo!=null) { - String myAssets = repo.getGitTransportUrl().replaceAll("git://", "https://"); - // System.out.println("Using my version of Viamins: "+myAssets); - setGitRepoDatabase(myAssets); - }else { - throw new org.kohsuke.github.GHFileNotFoundException(); - } - }catch(Exception ex) { - setGitRepoDatabase(defaultgitRpoDatabase); - } - } - } catch (Exception ex) { - new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), ex); - } +// try { +// if (PasswordManager.getUsername() != null) { +// // ScriptingEngine.setAutoupdate(true); +// org.kohsuke.github.GitHub github = PasswordManager.getGithub(); +// try { +// GHRepository repo = github.getRepository(PasswordManager.getLoginID() + "/Hardware-Dimensions"); +// if (repo != null) { +// String myAssets = repo.getGitTransportUrl().replaceAll("git://", "https://"); +// // com.neuronrobotics.sdk.common.Log.error("Using my version of Viamins: "+myAssets); +// setGitRepoDatabase(myAssets); +// } else { +// throw new org.kohsuke.github.GHFileNotFoundException(); +// } +// } catch (Exception ex) { +// setGitRepoDatabase(defaultGit); +// } +// } +// } catch (Exception ex) { +// new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), ex); +// } ScriptingEngine.cloneRepo(gitRpoDatabase, "master"); try { ScriptingEngine.pull(gitRpoDatabase); @@ -657,26 +702,27 @@ public static String getGitRepoDatabase() { } public static void reLoadDatabaseFromFiles() { - + setGitRepoDatabase(getGitRepoDatabase()); try { ScriptingEngine.pull(getGitRepoDatabase()); - }catch (CheckoutConflictException|NoHeadException e) { + } catch (CheckoutConflictException | NoHeadException e) { ScriptingEngine.deleteRepo(getGitRepoDatabase()); try { ScriptingEngine.pull(getGitRepoDatabase()); } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); + // Auto-generated catch block + com.neuronrobotics.sdk.common.Log.error(e1); } - }catch (Exception e) { + } catch (Exception e) { new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), e); } listVitaminTypes(); - + } + public static void setGitRepoDatabase(String gitRpoDatabase) { - Vitamins.gitRpoDatabase = gitRpoDatabase; + Vitamins.gitRpoDatabase=gitRpoDatabase; databaseSet.clear(); fileLastLoaded.clear(); @@ -691,6 +737,8 @@ public static void setJsonRootDir(String jsonRootDir) throws IOException { setGitRepoDatabase(getGitRepoDatabase()); } - + public static String getSourcerepo() { + return sourceRepo; + } } diff --git a/src/main/java/com/neuronrobotics/imageprovider/AbstractImageProvider.java b/src/main/java/com/neuronrobotics/imageprovider/AbstractImageProvider.java index 0f3eb2a3c..d31e4ae06 100644 --- a/src/main/java/com/neuronrobotics/imageprovider/AbstractImageProvider.java +++ b/src/main/java/com/neuronrobotics/imageprovider/AbstractImageProvider.java @@ -41,7 +41,7 @@ public abstract class AbstractImageProvider extends NonBowlerDevice { @Override public void onAsyncResponse(BowlerDatagram data) { - // TODO Auto-generated method stub + // Auto-generated method stub } diff --git a/src/main/java/com/neuronrobotics/imageprovider/NativeResource.java b/src/main/java/com/neuronrobotics/imageprovider/NativeResource.java index 386e61518..df8f74a95 100644 --- a/src/main/java/com/neuronrobotics/imageprovider/NativeResource.java +++ b/src/main/java/com/neuronrobotics/imageprovider/NativeResource.java @@ -40,7 +40,7 @@ private void inJarLoad(String name)throws UnsatisfiedLinkError, NativeResourceEx loadResource(resourceLocation); testNativeCode(); } catch (IOException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } @@ -49,8 +49,8 @@ private void inJarLoad(String name)throws UnsatisfiedLinkError, NativeResourceEx public static File inJarLoad(Class inputClass, String name) throws IOException{ InputStream resourceSource = inputClass.getResourceAsStream(name); File resourceLocation = prepResourceLocation(name); - //System.out.println("Resource selected "+resourceSource); - //System.out.println("Resource target "+resourceLocation); + //com.neuronrobotics.sdk.common.Log.error("Resource selected "+resourceSource); + //com.neuronrobotics.sdk.common.Log.error("Resource target "+resourceLocation); copyResource(resourceSource, resourceLocation); return resourceLocation; @@ -58,8 +58,8 @@ public static File inJarLoad(Class inputClass, String name) throws IOException{ public static File inJarLoad(InputStream inputStream, String name) throws IOException{ InputStream resourceSource = inputStream; File resourceLocation = prepResourceLocation(name); - //System.out.println("Resource selected "+resourceSource); - //System.out.println("Resource target "+resourceLocation); + //com.neuronrobotics.sdk.common.Log.error("Resource selected "+resourceSource); + //com.neuronrobotics.sdk.common.Log.error("Resource target "+resourceLocation); copyResource(resourceSource, resourceLocation); return resourceLocation; @@ -99,17 +99,17 @@ private InputStream locateResource(String name) { } } }else{ - System.err.println("Can't load native file: "+name+" for os arch: "+ getOsArch()); + com.neuronrobotics.sdk.common.Log.error("Can't load native file: "+name+" for os arch: "+ getOsArch()); return null; } - //System.out.println("Loading "+file); + //com.neuronrobotics.sdk.common.Log.error("Loading "+file); return getClass().getResourceAsStream(file); } private void loadResource(File resource) { if(!resource.canRead()) throw new RuntimeException("Cant open JNI file: "+resource.getAbsolutePath()); - //System.out.println("Loading: "+resource.getAbsolutePath()); + //com.neuronrobotics.sdk.common.Log.error("Loading: "+resource.getAbsolutePath()); System.load(resource.getAbsolutePath()); } @@ -190,13 +190,13 @@ public static File prepResourceLocation(String fileName) throws NativeResourceEx if(fd == null || !fd.canRead()) { throw new NativeResourceException("Unable to deploy native resource"); } - //System.out.println("Local file: "+fd.getAbsolutePath()); + //com.neuronrobotics.sdk.common.Log.error("Local file: "+fd.getAbsolutePath()); return fd; } public static boolean is64Bit() { - ////System.out.println("Arch: "+getOsArch()); + ////com.neuronrobotics.sdk.common.Log.error("Arch: "+getOsArch()); return getOsArch().startsWith("x86_64") || getOsArch().startsWith("amd64"); } public static boolean isARM() { @@ -210,7 +210,7 @@ public static boolean isCortexA8(){ return false; } public static boolean isWindows() { - ////System.out.println("OS name: "+getOsName()); + ////com.neuronrobotics.sdk.common.Log.error("OS name: "+getOsName()); return getOsName().toLowerCase().startsWith("windows") ||getOsName().toLowerCase().startsWith("microsoft") || getOsName().toLowerCase().startsWith("ms"); } diff --git a/src/main/java/com/neuronrobotics/imageprovider/StaticFileProvider.java b/src/main/java/com/neuronrobotics/imageprovider/StaticFileProvider.java index 9a59e90e4..8de2ffc35 100644 --- a/src/main/java/com/neuronrobotics/imageprovider/StaticFileProvider.java +++ b/src/main/java/com/neuronrobotics/imageprovider/StaticFileProvider.java @@ -27,19 +27,19 @@ protected boolean captureNewImage(BufferedImage imageData) { @Override public void disconnectDeviceImp() { - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public boolean connectDeviceImp() { - // TODO Auto-generated method stub + // Auto-generated method stub return false; } @Override public ArrayList getNamespacesImp() { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } diff --git a/src/main/java/com/neuronrobotics/imageprovider/URLImageProvider.java b/src/main/java/com/neuronrobotics/imageprovider/URLImageProvider.java index c58ab1480..b1c835c5f 100644 --- a/src/main/java/com/neuronrobotics/imageprovider/URLImageProvider.java +++ b/src/main/java/com/neuronrobotics/imageprovider/URLImageProvider.java @@ -29,19 +29,19 @@ protected boolean captureNewImage(BufferedImage imageData) { @Override public void disconnectDeviceImp() { - // TODO Auto-generated method stub + // Auto-generated method stub } @Override public boolean connectDeviceImp() { - // TODO Auto-generated method stub + // Auto-generated method stub return false; } @Override public ArrayList getNamespacesImp() { - // TODO Auto-generated method stub + // Auto-generated method stub return null; } diff --git a/src/main/java/com/neuronrobotics/imageprovider/VirtualCameraFactory.java b/src/main/java/com/neuronrobotics/imageprovider/VirtualCameraFactory.java index df52cef36..fda1614d6 100644 --- a/src/main/java/com/neuronrobotics/imageprovider/VirtualCameraFactory.java +++ b/src/main/java/com/neuronrobotics/imageprovider/VirtualCameraFactory.java @@ -8,11 +8,11 @@ public class VirtualCameraFactory { @Override public AbstractImageProvider getVirtualCamera() { - // TODO Auto-generated method stub + // Auto-generated method stub try { return new URLImageProvider(new URL("http://commonwealthrobotics.com/img/AndrewHarrington/2014-09-15-86.jpg")); } catch (MalformedURLException e) { - // TODO Auto-generated catch block + // Auto-generated catch block throw new RuntimeException(e); } } diff --git a/src/main/java/com/neuronrobotics/sdk/addons/gamepad/BowlerJInputDevice.java b/src/main/java/com/neuronrobotics/sdk/addons/gamepad/BowlerJInputDevice.java index a22dab883..3b0c58726 100644 --- a/src/main/java/com/neuronrobotics/sdk/addons/gamepad/BowlerJInputDevice.java +++ b/src/main/java/com/neuronrobotics/sdk/addons/gamepad/BowlerJInputDevice.java @@ -17,7 +17,7 @@ import eu.mihosoft.vrl.v3d.JavaFXInitializer; -// TODO: Auto-generated Javadoc +// Auto-generated Javadoc /** * The Class BowlerJInputDevice. */ @@ -96,7 +96,7 @@ private void setControllerByName(List names) { controller = c; break; } else - System.out.println("Non match: " + c.getName() + " " + n); + com.neuronrobotics.sdk.common.Log.error("Non match: " + c.getName() + " " + n); } } } @@ -149,12 +149,12 @@ public void run() { setControllerByName(searches); break; } catch (Throwable t) { - System.out.println("BowlerJInputDevice Waiting for device to be availible"); + com.neuronrobotics.sdk.common.Log.error("BowlerJInputDevice Waiting for device to be availible"); t.printStackTrace(); try { Thread.sleep(1000); } catch (InterruptedException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } @@ -227,7 +227,7 @@ public String getControllerName() { * @param controller the new controller */ public void setController(Controller controller) { - System.out.println("Found! " + controller.getName()); + com.neuronrobotics.sdk.common.Log.error("Found! " + controller.getName()); this.name = controller.getName(); controller.poll(); EventQueue queue = controller.getEventQueue(); @@ -277,7 +277,7 @@ public void addListeners(IGameControlEvent l) { */ @Override public ArrayList getNamespacesImp() { - // TODO Auto-generated method stub + // Auto-generated method stub return new ArrayList(); } @@ -322,13 +322,13 @@ public static void main(String[] args) throws InterruptedException { BowlerJInputDevice g = new BowlerJInputDevice("X-Box","Gamesir","Dragon"); // g.connect(); // Connect to it. g.addListeners((name, value) -> { - System.out.println(g); + com.neuronrobotics.sdk.common.Log.error(g); }); while (g.isAvailable()) Thread.sleep(100); - System.out.println("Controller clean exit"); + com.neuronrobotics.sdk.common.Log.error("Controller clean exit"); } catch (Throwable t) { - System.out.println("Waiting for device to be availible"); + com.neuronrobotics.sdk.common.Log.error("Waiting for device to be availible"); t.printStackTrace(); Thread.sleep(1000); } diff --git a/src/main/java/com/neuronrobotics/sdk/addons/gamepad/ControllerEnvironment.java b/src/main/java/com/neuronrobotics/sdk/addons/gamepad/ControllerEnvironment.java index 97ecc7cbc..58fd47170 100644 --- a/src/main/java/com/neuronrobotics/sdk/addons/gamepad/ControllerEnvironment.java +++ b/src/main/java/com/neuronrobotics/sdk/addons/gamepad/ControllerEnvironment.java @@ -96,7 +96,7 @@ protected static void libfix() { File test = new File(absolutePathToDirectory); if (!test.isDirectory()) absolutePathToDirectory = test.getParentFile().getAbsolutePath(); - // System.out.println("Setting net.java.games.input.librarypath : + // com.neuronrobotics.sdk.common.Log.error("Setting net.java.games.input.librarypath : // "+absolutePathToDirectory); System.setProperty("net.java.games.input.librarypath", absolutePathToDirectory); } diff --git a/src/main/java/com/neuronrobotics/sdk/addons/gamepad/JogTrainerWidget.java b/src/main/java/com/neuronrobotics/sdk/addons/gamepad/JogTrainerWidget.java index 4063b50d3..4d0c861af 100644 --- a/src/main/java/com/neuronrobotics/sdk/addons/gamepad/JogTrainerWidget.java +++ b/src/main/java/com/neuronrobotics/sdk/addons/gamepad/JogTrainerWidget.java @@ -98,7 +98,7 @@ public void handle(ActionEvent event) { List maps = PersistantControllerMap.getDefaultMaps(); int i = 0; - System.out.println("There are "+maps.size()+" rows"); + com.neuronrobotics.sdk.common.Log.error("There are "+maps.size()+" rows"); for (i = 0; i < maps.size(); i++) { String map = maps.get(i); @@ -194,10 +194,10 @@ public void onEvent(String name, float value) { values.put(name,value); timeOfLastAxisSet.put(name, System.currentTimeMillis()); if(abs>0.2) - System.out.println("value for "+name+" seems noisy "+value+" most recent was "+values.get(name)); + com.neuronrobotics.sdk.common.Log.error("value for "+name+" seems noisy "+value+" most recent was "+values.get(name)); return; }else { - System.out.println("Value changed! "+name+" "+float1+" to "+value); + com.neuronrobotics.sdk.common.Log.error("Value changed! "+name+" "+float1+" to "+value); values.put(name, value); timeOfLastAxisSet.put(name, System.currentTimeMillis()); } @@ -205,8 +205,8 @@ public void onEvent(String name, float value) { for(String s:listOfMappedAxis) { if(s.contentEquals(name)) { - System.out.println("mapping skipped for "+name); - System.out.println(gameController); + com.neuronrobotics.sdk.common.Log.error("mapping skipped for "+name); + com.neuronrobotics.sdk.common.Log.error(gameController); return;// This axis name is already mapped and will not be mapped again } } @@ -216,7 +216,7 @@ public void onEvent(String name, float value) { } axisWaiting=name; - System.out.println("Adding Axis "+name); + com.neuronrobotics.sdk.common.Log.error("Adding Axis "+name); listOfMappedAxis.add(name); timeOfLastAxisSet.put(name,System.currentTimeMillis()); @@ -236,17 +236,17 @@ public void onEvent(String name, float value) { } public static void run(BowlerJInputDevice c) { - //System.out.println("Launching Controller mapping"); + //com.neuronrobotics.sdk.common.Log.error("Launching Controller mapping"); BowlerKernel.runLater(new Runnable() { @Override public void run() { - //System.out.println("Creating stage"); + //com.neuronrobotics.sdk.common.Log.error("Creating stage"); Stage s = new Stage(); new Thread() { public void run() { JogTrainerWidget controller = new JogTrainerWidget(c); try { - //System.out.println("Loading FXML"); + //com.neuronrobotics.sdk.common.Log.error("Loading FXML"); controller.start(s); } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/CoreScheduler.java b/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/CoreScheduler.java index 060cf9b9f..452fa9ff8 100644 --- a/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/CoreScheduler.java +++ b/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/CoreScheduler.java @@ -19,7 +19,7 @@ import com.neuronrobotics.sdk.dyio.DyIO; import com.neuronrobotics.sdk.dyio.peripherals.ServoChannel; import com.neuronrobotics.sdk.util.ThreadUtil; -// TODO: Auto-generated Javadoc +// Auto-generated Javadoc /** * The Class CoreScheduler. @@ -117,10 +117,10 @@ public void loadFromFile(File f){ } catch (IOException e) { throw new RuntimeException(e); } - //System.out.println("Parsing File..."); + //com.neuronrobotics.sdk.common.Log.error("Parsing File..."); NodeList nList = doc.getElementsByTagName("ServoOutputSequenceGroup"); for (int temp = 0; temp < nList.getLength(); temp++) { - //System.out.println("Leg # "+temp); + //com.neuronrobotics.sdk.common.Log.error("Leg # "+temp); Node nNode = nList.item(temp); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; @@ -134,7 +134,7 @@ public void loadFromFile(File f){ setLoopTime(Integer.parseInt(getTagValue("loopTime",eElement))); NodeList links = eElement.getElementsByTagName("ServoOutputSequence"); for (int i = 0; i < links.getLength(); i++) { - //System.out.println("\tLink # "+i); + //com.neuronrobotics.sdk.common.Log.error("\tLink # "+i); Node lNode = links.item(i); if (lNode.getNodeType() == Node.ELEMENT_NODE) { Element lElement = (Element) lNode; @@ -158,7 +158,7 @@ public void loadFromFile(File f){ int current = data[j]; int after = data[j+1]; if(current == 0 &&before!=0 && after!=0){ - System.out.println("Smoothing xml"); + com.neuronrobotics.sdk.common.Log.error("Smoothing xml"); data[j]=(before+after)/2; } } @@ -177,10 +177,10 @@ public void loadFromFile(File f){ } }else{ - //System.out.println("Not Element Node"); + //com.neuronrobotics.sdk.common.Log.error("Not Element Node"); } } - System.out.println("Populated Scheduler"); + com.neuronrobotics.sdk.common.Log.error("Populated Scheduler"); } /** @@ -193,7 +193,7 @@ public void loadFromFile(File f){ private static String getTagValue(String sTag, Element eElement){ NodeList nlList= eElement.getElementsByTagName(sTag).item(0).getChildNodes(); Node nValue = (Node) nlList.item(0); - //System.out.println("\t\t"+sTag+" = "+nValue.getNodeValue()); + //com.neuronrobotics.sdk.common.Log.error("\t\t"+sTag+" = "+nValue.getNodeValue()); return nValue.getNodeValue(); } @@ -209,7 +209,7 @@ public void setAudioFile(File f) { filename=f.getAbsolutePath(); mp3 = new SequencerWAV(f.getAbsolutePath()); msDuration = mp3.getTrackLength(); - System.out.println("Setting track length: "+msDuration); + com.neuronrobotics.sdk.common.Log.error("Setting track length: "+msDuration); setSequenceParams( msDuration, 0); } @@ -259,7 +259,7 @@ public boolean isPlaying() { * @return the servo output schedule channel */ public ServoOutputScheduleChannel addServoChannel(int dyIOChannel){ - System.out.println("Adding DyIO channel: "+dyIOChannel); + com.neuronrobotics.sdk.common.Log.error("Adding DyIO channel: "+dyIOChannel); ServoChannel srv = new ServoChannel(getDyIO().getChannel(dyIOChannel)); srv.SetPosition(srv.getValue()); srv.flush(); @@ -290,7 +290,7 @@ public void removeServoOutputScheduleChannel(ServoOutputScheduleChannel s){ public void setSequenceParams(int setpoint,long StartOffset){ msDuration=setpoint; this.StartOffset=StartOffset; - //System.out.println("Starting scheduler setpoint="+setpoint+" offset="+StartOffset); + //com.neuronrobotics.sdk.common.Log.error("Starting scheduler setpoint="+setpoint+" offset="+StartOffset); if(getSt()==null) setSt(new SchedulerThread(msDuration,StartOffset)); if(mp3!=null) @@ -475,14 +475,14 @@ public void run(){ } flushTime = System.currentTimeMillis()-start; if(flushTime>getLoopTime()){ - System.err.println("Flush took:"+flushTime+ " and loop time="+getLoopTime()); + com.neuronrobotics.sdk.common.Log.error("Flush took:"+flushTime+ " and loop time="+getLoopTime()); flushTime=getLoopTime(); } }else{ try { Thread.sleep(10); } catch (InterruptedException e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); } } @@ -543,7 +543,7 @@ private class SchedulerThread extends Thread{ public SchedulerThread(double ms,final long so){ time = ms; StartOffset=so; - //System.out.println("Slider value of init="+StartOffset); + //com.neuronrobotics.sdk.common.Log.error("Slider value of init="+StartOffset); if(mp3!=null) { mp3.setCurrentTime((int) (StartOffset)); } @@ -556,7 +556,7 @@ public SchedulerThread(double ms,final long so){ * Play step. */ public void playStep(){ - //System.out.println("Stepping scheduler"); + //com.neuronrobotics.sdk.common.Log.error("Stepping scheduler"); boolean playing; long current; if(mp3==null){ @@ -580,7 +580,7 @@ public void playStep(){ * @see java.lang.Thread#run() */ public void run(){ - //System.out.println("Starting timer"); + //com.neuronrobotics.sdk.common.Log.error("Starting timer"); do{ do{ while(pause){ @@ -590,7 +590,7 @@ public void run(){ long start = System.currentTimeMillis(); playStep(); ThreadUtil.wait(getLoopTime()); - //System.out.println("Flush took "+(System.currentTimeMillis()-start)); + //com.neuronrobotics.sdk.common.Log.error("Flush took "+(System.currentTimeMillis()-start)); }while(isRun()); setCurrentTime(0); setPause(true); diff --git a/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/ISchedulerListener.java b/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/ISchedulerListener.java index 2e0bf7a53..ad8d642e9 100644 --- a/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/ISchedulerListener.java +++ b/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/ISchedulerListener.java @@ -1,6 +1,6 @@ package com.neuronrobotics.sdk.dyio.sequencer; -// TODO: Auto-generated Javadoc +// Auto-generated Javadoc /** * The listener interface for receiving IScheduler events. * The class that is interested in processing a IScheduler diff --git a/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/SequencerWAV.java b/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/SequencerWAV.java index c0be2082f..7aa805860 100644 --- a/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/SequencerWAV.java +++ b/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/SequencerWAV.java @@ -30,7 +30,7 @@ public SequencerWAV(String filename) { } catch (Exception e) { - System.out.println("Problem playing file " + filename+"\r\n"); + com.neuronrobotics.sdk.common.Log.error("Problem playing file " + filename+"\r\n"); //e.printStackTrace(); throw new RuntimeException(e); } @@ -139,12 +139,12 @@ public static void main(String[] args) { SequencerWAV mp3 = new SequencerWAV("track.mp3"); mp3.play(); - System.out.println("Track length= "+mp3.getTrackLength()); + com.neuronrobotics.sdk.common.Log.error("Track length= "+mp3.getTrackLength()); while(mp3.isPlaying() ){ - System.out.println("Current "+mp3.getCurrentTime() +" Percent = "+mp3.getPercent()); + com.neuronrobotics.sdk.common.Log.error("Current "+mp3.getCurrentTime() +" Percent = "+mp3.getPercent()); ThreadUtil.wait(100); } - System.out.println("Finished "+mp3.getCurrentTime()+" of "+mp3.getTrackLength()); + com.neuronrobotics.sdk.common.Log.error("Finished "+mp3.getCurrentTime()+" of "+mp3.getTrackLength()); System.exit(0); //mediaPlayer. diff --git a/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/ServoOutputScheduleChannel.java b/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/ServoOutputScheduleChannel.java index e652b09b2..6e3cd30df 100644 --- a/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/ServoOutputScheduleChannel.java +++ b/src/main/java/com/neuronrobotics/sdk/dyio/sequencer/ServoOutputScheduleChannel.java @@ -7,7 +7,7 @@ import com.neuronrobotics.sdk.dyio.peripherals.IServoPositionUpdateListener; import com.neuronrobotics.sdk.dyio.peripherals.ServoChannel; -// TODO: Auto-generated Javadoc +// Auto-generated Javadoc /** * The Class ServoOutputScheduleChannel. */ @@ -79,7 +79,7 @@ public int getChannelNumber(){ * Pause recording. */ public void pauseRecording(){ - System.out.println("pausing recording"); + com.neuronrobotics.sdk.common.Log.error("pausing recording"); if(input != null) input.removeAnalogInputListener(this); setRecording(false); @@ -91,7 +91,7 @@ public void pauseRecording(){ public void resumeRecording(){ if(input==null) initInput(); - System.out.println("resuming recording"); + com.neuronrobotics.sdk.common.Log.error("resuming recording"); setRecording(true); } @@ -117,7 +117,7 @@ private void initInput() { } if(input.getChannel().getChannelNumber() != analogInputChannelNumber) { - System.out.println("Re-Setting analog input channel: "+analogInputChannelNumber); + com.neuronrobotics.sdk.common.Log.error("Re-Setting analog input channel: "+analogInputChannelNumber); input.removeAllAnalogInputListeners(); input=new AnalogInputChannel(output.getChannel().getDevice().getChannel(analogInputChannelNumber),true); } @@ -149,7 +149,7 @@ public void onTimeUpdate(double ms) { //output.SetPosition(data.get(index).input); - //System.out.println("Setting servo "+getChannelNumber()+" value="+getCurrentValue()); + //com.neuronrobotics.sdk.common.Log.error("Setting servo "+getChannelNumber()+" value="+getCurrentValue()); } @@ -161,7 +161,7 @@ public void setIntervalTime(int msInterval, int totalTime) { setInterval(msInterval); int slices = totalTime/msInterval; if(data.size()==0){ - System.out.println("Setting up sample data: "+msInterval+"ms for: "+totalTime); + com.neuronrobotics.sdk.common.Log.error("Setting up sample data: "+msInterval+"ms for: "+totalTime); data = new ArrayList(); setCurrentTargetValue(getCurrentValue()); if(getCurrentTargetValue()>getOutputMax()){ @@ -186,14 +186,14 @@ public void setIntervalTime(int msInterval, int totalTime) { public void onAnalogValueChange(AnalogInputChannel chan, double value) { double centerOffset =getInputCenter()-(512*getInputScale()); - //System.out.println("Center Offset="+centerOffset); + //com.neuronrobotics.sdk.common.Log.error("Center Offset="+centerOffset); double scaled = (value*getInputScale()); double recentered = (scaled+centerOffset); setCurrentTargetValue((int) recentered ); - //System.out.println("Analog value="+(int)value+" scaled="+(int)scaled +" recentered="+(int)recentered); + //com.neuronrobotics.sdk.common.Log.error("Analog value="+(int)value+" scaled="+(int)scaled +" recentered="+(int)recentered); if(getCurrentTargetValue()>getOutputMax()){ setCurrentTargetValue(getOutputMax()); } @@ -383,7 +383,7 @@ public void setData(int[] data2) { * Start test. */ public void startTest() { - System.out.println("Starting test for output: "+getChannelNumber()); + com.neuronrobotics.sdk.common.Log.error("Starting test for output: "+getChannelNumber()); initInput(); directTester = new Tester(); directTester.start(); @@ -463,7 +463,7 @@ public void flush(){ * @param analogInputChannelNumber the new analog input channel number */ public void setAnalogInputChannelNumber(int analogInputChannelNumber) { - //System.out.println("Setting analog input number: "+analogInputChannelNumber); + //com.neuronrobotics.sdk.common.Log.error("Setting analog input number: "+analogInputChannelNumber); this.analogInputChannelNumber = analogInputChannelNumber; } @@ -499,12 +499,12 @@ private class Tester extends Thread { * @see java.lang.Thread#run() */ public void run() { - //System.out.println("Starting Test"); + //com.neuronrobotics.sdk.common.Log.error("Starting Test"); while(running) { flush(); try {Thread.sleep((long) getInterval());} catch (InterruptedException e) {} } - //System.out.println("Test Done"); + //com.neuronrobotics.sdk.common.Log.error("Test Done"); } /** @@ -520,7 +520,7 @@ public void kill() { */ @Override public void onReset() { - // TODO Auto-generated method stub + // Auto-generated method stub } @@ -529,7 +529,7 @@ public void onReset() { */ @Override public void onPlay() { - // TODO Auto-generated method stub + // Auto-generated method stub } @@ -538,7 +538,7 @@ public void onPlay() { */ @Override public void onPause() { - // TODO Auto-generated method stub + // Auto-generated method stub } diff --git a/test/java/src/junit/bowler/ArduinoLoaderTest.java b/test/java/src/junit/bowler/ArduinoLoaderTest.java index de813d2e6..7484f0c43 100644 --- a/test/java/src/junit/bowler/ArduinoLoaderTest.java +++ b/test/java/src/junit/bowler/ArduinoLoaderTest.java @@ -13,6 +13,8 @@ import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabaseInstance; import gnu.io.NRSerialPort; public class ArduinoLoaderTest { @@ -32,7 +34,7 @@ public void test() throws Exception { ArrayList params = new ArrayList<>(); params.add(board); params.add(portname); - ScriptingEngine.gitScriptRun("https://github.com/madhephaestus/Blink.git", "Blink.ino", params); + ScriptingEngine.gitScriptRun(CSGDatabase.getInstance(),"https://github.com/madhephaestus/Blink.git", "Blink.ino", params); } } diff --git a/test/java/src/junit/bowler/BlenderLoadingTest.java b/test/java/src/junit/bowler/BlenderLoadingTest.java index de97fbbdc..0d3c2e5be 100644 --- a/test/java/src/junit/bowler/BlenderLoadingTest.java +++ b/test/java/src/junit/bowler/BlenderLoadingTest.java @@ -5,19 +5,27 @@ import org.junit.Test; import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.bowlerstudio.util.GeometrySimplification; import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.Cube; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; public class BlenderLoadingTest { @Test public void test() throws Exception { - CSG loaded =(CSG)ScriptingEngine.gitScriptRun( + CSG loaded =(CSG)ScriptingEngine.gitScriptRun(CSGDatabase.getInstance(), "https://github.com/madhephaestus/TestRepo.git", "TestRepo4.blend"); if(loaded.getPolygons().size()!=12) fail("Failed to load polygon!"); - System.out.println("Blender file loaded num polys: "+loaded.getPolygons().size()); + com.neuronrobotics.sdk.common.Log.error("Blender file loaded num polys: "+loaded.getPolygons().size()); + CSG cube = new Cube(100).toCSG(); + CSG remeshed = GeometrySimplification.remesh(cube, 10.0,CSGDatabase.getInstance()); + if(remeshed.getPolygons().size()!=1452) + fail("Blender failed to remesh"); + com.neuronrobotics.sdk.common.Log.error("Remeshing produced: "+remeshed.getPolygons().size()); } } diff --git a/test/java/src/junit/bowler/Build123dTest.java b/test/java/src/junit/bowler/Build123dTest.java new file mode 100644 index 000000000..ac794358c --- /dev/null +++ b/test/java/src/junit/bowler/Build123dTest.java @@ -0,0 +1,37 @@ +package junit.bowler; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidRemoteException; +import org.eclipse.jgit.api.errors.TransportException; +import org.junit.Test; + +import com.neuronrobotics.bowlerstudio.scripting.Build123dLoader; +import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.sdk.common.Log; + +public class Build123dTest { + + @Test + public void test() throws InvalidRemoteException, TransportException, GitAPIException, IOException, InterruptedException { + Build123dLoader loader = new Build123dLoader(); + Log.enableDebugPrint(); + // create test file + File testblend = new File("build123dTest.py"); + if(!testblend.exists()) + loader.getDefaultContents(testblend); + HashMap params = new HashMap(); + Build123dLoader.toSTLFile(testblend, new File("build123dTest.py.stl"),params); + + File gears = ScriptingEngine.fileFromGit("https://github.com/GarryBGoode/gggears.git", "examples/examples.py"); + Build123dLoader.toSTLFile(gears, new File("gears.stl"),params); + + + } + +} diff --git a/test/java/src/junit/bowler/CaDoodleWorkflowTest.java b/test/java/src/junit/bowler/CaDoodleWorkflowTest.java new file mode 100644 index 000000000..171c46c38 --- /dev/null +++ b/test/java/src/junit/bowler/CaDoodleWorkflowTest.java @@ -0,0 +1,280 @@ +package junit.bowler; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import org.junit.Test; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import com.neuronrobotics.bowlerstudio.creature.ControllerOption; +import com.neuronrobotics.bowlerstudio.creature.LimbOption; +import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; + +import java.lang.reflect.Type; + +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.AddFromScript; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.CaDoodleFile; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.Group; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.MoveCenter; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.Paste; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.Resize; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.ToHole; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.ToSolid; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.UnGroup; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.AddRobotController; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.AddRobotLimb; +import com.neuronrobotics.bowlerstudio.scripting.cadoodle.robot.MakeRobot; +import com.neuronrobotics.sdk.addons.kinematics.MobileBase; +import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR; +import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR; + +import eu.mihosoft.vrl.v3d.CSG; +import eu.mihosoft.vrl.v3d.JavaFXInitializer; +import javafx.scene.paint.Color; + +public class CaDoodleWorkflowTest { + + @Test + public void test() throws Exception { + JavaFXInitializer.go(); + CaDoodleFile cf = new CaDoodleFile() + .setSelf(new File("doodle/Test.doodle")) + .setProjectName("A Test Project"); + + String jsonContent = cf.toJson(); + com.neuronrobotics.sdk.common.Log.error(jsonContent); + + AddFromScript cube1 = new AddFromScript() + .set("https://github.com/madhephaestus/CaDoodle-Example-Objects.git", + "sphere.groovy"); + AddFromScript cube2 = new AddFromScript() + .set("https://github.com/madhephaestus/CaDoodle-Example-Objects.git", + "sphere.groovy"); + cf.addOpperation(cube1).join(); + Listback= cf.getCurrentState(); + if(back.size()!=1) + fail("Adding a cube should have added one!"); + String nameOne = back.get(0).getName(); + cf.addOpperation(cube2).join();; + back=cf.getCurrentState(); + if(back.size()!=2) + fail("Adding a cube should have added one more!"); + String nameTwo = back.get(1).getName(); + if(nameOne.contentEquals(nameTwo)) + fail("Names must be unique!"); + com.neuronrobotics.sdk.common.Log.error("Name one : "+nameOne ); + com.neuronrobotics.sdk.common.Log.error("Name two : "+nameTwo ); + double distaance =10; + MoveCenter move = new MoveCenter() + .setLocation(new TransformNR(distaance,0,0)) + .setNames(Arrays.asList(nameTwo)) + ; + cf.addOpperation(move).join();; + back=cf.getCurrentState(); + if(back.size()!=2) + fail("Same number of objects after"); + double centerX = back.get(1).getCenterX(); + if(centerX!=distaance) + fail("Move failed "); + if(back.get(0).getCenterX()!=0) + fail("Move misapplied "); + jsonContent = cf.toJson(); + //com.neuronrobotics.sdk.common.Log.error(jsonContent); + cf.save(); + CaDoodleFile loaded = CaDoodleFile.fromFile(cf.getSelf()); + if(!MoveCenter.class.isInstance(loaded.getOpperations().get(2))) { + fail("Third Opperation is supposed to be a move"); + } + if(!AddFromScript.class.isInstance(loaded.getOpperations().get(1))) { + fail(" Opperation is supposed to be a AddFromScript"); + } + if(!AddFromScript.class.isInstance(loaded.getOpperations().get(0))) { + fail(" Opperation is supposed to be a AddFromScript"); + } + loaded.back(); + MoveCenter move2 = new MoveCenter() + .setLocation(new TransformNR(distaance,distaance,0)) + .setNames(Arrays.asList(nameOne)) + ; + MoveCenter move3 = new MoveCenter() + .setLocation(new TransformNR(0,0,0,new RotationNR(0,45,0))) + .setNames(Arrays.asList(nameOne)) + ; + loaded.addOpperation(move3).join();; + back=loaded.getCurrentState(); + loaded.addOpperation(move2).join();; + back=loaded.getCurrentState(); + double centerX2 = back.get(1).getCenterX(); + if(centerX2!=distaance) + fail("Move failed "); + if(back.get(1).getCenterY()!=distaance) + fail("Move failed "); + ToHole hole= new ToHole().setNames(Arrays.asList(nameOne)); + loaded.addOpperation(hole).join();; + back=loaded.getCurrentState(); + Group group = new Group().setNames(Arrays.asList(nameOne,nameTwo)); + loaded.addOpperation(group).join();; + back=loaded.getCurrentState(); + if(back.size()!=3) + fail("Group Failed "); + if(!back.get(0).isInGroup()) { + fail("THis should not be in a group anymore"); + } + if(!back.get(1).isInGroup()) { + fail("THis should not be in a group anymore"); + } + if(back.get(2).isInGroup()) { + fail("THis should not be in a group anymore"); + } + if(!back.get(2).isGroupResult()) { + fail("THis should be aa group result"); + } + String groupName = back.get(2).getName(); + com.neuronrobotics.sdk.common.Log.error("Group Name : "+groupName); + TransformNR height = new TransformNR(0,0,40); + TransformNR leftFront = new TransformNR(40,80,0); + TransformNR rightRear = new TransformNR(-10,10,0); + Resize resize = new Resize() + .setResize(height, leftFront, rightRear) + .setNames(Arrays.asList(groupName)) + ; + loaded.addOpperation(resize).join();; + back=loaded.getCurrentState(); + ToSolid solid = new ToSolid() + .setNames(Arrays.asList(groupName)) + .setColor(Color.BLUE); + loaded.addOpperation(solid).join();; + back=loaded.getCurrentState(); + UnGroup ug = new UnGroup().setNames(Arrays.asList(groupName)); + loaded.addOpperation(ug).join();; + back=loaded.getCurrentState(); + if(back.get(0).isInGroup()) { + fail("THis should not be in a group anymore"); + } + if(back.get(1).isInGroup()) { + fail("THis should not be in a group anymore"); + } + + + loaded.addOpperation( + new Group() + .setNames(Arrays.asList(nameOne,nameTwo)) + ).join();; + back=loaded.getCurrentState(); + List cacheOfGroup = loaded.getCurrentState(); + + String newGroupName = cacheOfGroup.get(cacheOfGroup.size()-1).getName(); + + loaded.addOpperation( + new Paste().setNames(Arrays.asList(newGroupName))).join();; + back=loaded.getCurrentState(); + ArrayList selectAll = new ArrayList(); + for(CSG c:back) { + if(c.isGroupResult()) + selectAll.add(c.getName()); + } + loaded.addOpperation( + new UnGroup().setNames(selectAll)).join();; + back=loaded.getCurrentState(); + if(back.get(0).isInGroup()) { + fail("THis should not be in a group anymore"); + } + if(back.get(1).isInGroup()) { + fail("THis should not be in a group anymore"); + } + if(back.get(2).isInGroup()) { + fail("THis should not be in a group anymore"); + } + if(back.get(3).isInGroup()) { + fail("THis should not be in a group anymore"); + } + ToHole h= new ToHole().setNames(Arrays.asList(nameTwo)); + loaded.addOpperation(h).join();; + back=loaded.getCurrentState(); + loaded.save(); + + for(int i=0;i<3;i++) { + loaded.back(); + } + List goBackResult = loaded.getCurrentState(); + back=goBackResult; + if(goBackResult.size()!=3) { + fail(" Number of elements after back incorrect!"); + } + if(back.get(2).isInGroup()) { + fail("THis should not be in a group anymore"); + } + if(!back.get(2).isGroupResult()) { + fail("THis should be a group result"); + } + if(!back.get(0).isInGroup()) { + fail("This should be in a group"); + } + if(!back.get(1).isInGroup()) { + fail("This should be in a group"); + } + + loaded.save(); + + String before = loaded.toJson(); + loaded=CaDoodleFile.fromJsonString(before); + String after =loaded.toJson(); + if(!before.contentEquals(after)) + fail("Load and export mismatch"); + loaded.setSelf(cf.getSelf()); + + com.neuronrobotics.sdk.common.Log.error(after); + while(loaded.isForwardAvailible()) + loaded.forward(); + selectAll = new ArrayList(); + for(CSG c:loaded.getCurrentState()) { + selectAll.add(c.getName()); + } + MakeRobot mr = new MakeRobot(); + mr.setNames(selectAll); + + loaded.addOpperation(mr).join(); + loaded.save(); + ScriptingEngine.pull(ControllerOption.URL_OF_OPTIONS); + ArrayList controllers = ControllerOption.getOptions(); + for(ControllerOption o:controllers) { + System.out.println(o); + AddRobotController con = new AddRobotController() + .setNames(selectAll) + .setController(o); + loaded.addOpperation(con).join(); + } + loaded.save(); + ArrayList limbs = LimbOption.getOptions(); + TransformNR tf = new TransformNR(); + for(LimbOption o:limbs) { + if(mr.getBuilder().checkOptionSupported(o)) { + System.out.println(o); + tf = new TransformNR(0,0,30).times(tf); + AddRobotLimb limb = new AddRobotLimb() + .setLimb(o) + .setNames(selectAll) + .setLocation(tf); + loaded.addOpperation(limb).join(); + }else { + System.out.println("Unsupported limb "+o); + } + //break; + } + for(MobileBase mb:loaded.getMobileBases()) { + System.out.println("Base "+mb); + mb.disconnect(); + } + System.out.println("Saving"); + loaded.save(); + System.out.println("Save finished"); + } + +} diff --git a/test/java/src/junit/bowler/GitHub.java b/test/java/src/junit/bowler/GitHub.java index 6c4288779..8f79f00b5 100644 --- a/test/java/src/junit/bowler/GitHub.java +++ b/test/java/src/junit/bowler/GitHub.java @@ -25,7 +25,7 @@ public class GitHub { public void test() throws Exception { //ScriptingEngine.login(); // String remoteURI = "https://github.com/madhephaestusdemo/WalkTest_madhephaestusdemo.git"; -// System.out.println(ScriptingEngine.getRepositoryCloneDirectory(remoteURI)); +// com.neuronrobotics.sdk.common.Log.error(ScriptingEngine.getRepositoryCloneDirectory(remoteURI)); // ScriptingEngine.pull(remoteURI); //ScriptingEngine.fork("https://github.com/madhephaestus/6dofServoArm.git", "forktest6dof", "testing yo!"); @@ -37,46 +37,46 @@ public void test() throws Exception { } ScriptingEngine.setAutoupdate(true); } catch (Exception ex) { - System.out.println("User not logged in, test can not run"); + com.neuronrobotics.sdk.common.Log.error("User not logged in, test can not run"); } org.kohsuke.github.GitHub github = ScriptingEngine.getGithub(); while (github == null) { github = ScriptingEngine.getGithub(); ThreadUtil.wait(2000); - System.out.println("Waiting for github"); + com.neuronrobotics.sdk.common.Log.error("Waiting for github"); } Map orgs = github.getMyOrganizations(); for (String org : orgs.keySet()) { - System.out.println("Org: " + org); + com.neuronrobotics.sdk.common.Log.error("Org: " + org); GHOrganization ghorg = orgs.get(org); Map repos = ghorg.getRepositories(); for (String orgRepo : repos.keySet()) { - System.out.println("\tRepo " + org + " " + orgRepo); + com.neuronrobotics.sdk.common.Log.error("\tRepo " + org + " " + orgRepo); } } Map> teams = github.getMyTeams(); for (String team : teams.keySet()) { - System.out.println("Team " + team); + com.neuronrobotics.sdk.common.Log.error("Team " + team); Set ghteam = teams.get(team); for (GHTeam ghT : ghteam) { - System.out.println("\tGHTeam " + ghT.getName()); + com.neuronrobotics.sdk.common.Log.error("\tGHTeam " + ghT.getName()); Map repos = ghT.getRepositories(); for (String repoName : repos.keySet()) { - System.out.println("\t\tGHTeam " + ghT.getName() + " repo " + repoName); + com.neuronrobotics.sdk.common.Log.error("\t\tGHTeam " + ghT.getName() + " repo " + repoName); } } } GHMyself self = github.getMyself(); Map myPublic = self.getAllRepositories(); for (String myRepo : myPublic.keySet()) { - System.out.println("Repo " + myRepo); + com.neuronrobotics.sdk.common.Log.error("Repo " + myRepo); GHRepository ghrepo = myPublic.get(myRepo); // if(ghrepo.getOwnerName().contains("demo")) - System.out.println("\tOwner: " + ghrepo.getOwnerName() + " " + myRepo); + com.neuronrobotics.sdk.common.Log.error("\tOwner: " + ghrepo.getOwnerName() + " " + myRepo); } PagedIterable watching = self.listSubscriptions(); for (GHRepository g : watching) { - System.out.println("Watching " + g.getOwnerName() + " " + g.getFullName()); + com.neuronrobotics.sdk.common.Log.error("Watching " + g.getOwnerName() + " " + g.getFullName()); } String gitURL ="https://github.com/madhephaestus/clojure-utils.git"; ArrayList listofFiles = ScriptingEngine.filesInGit(gitURL, @@ -84,39 +84,39 @@ public void test() throws Exception { if (listofFiles.size() == 0) fail(); for (String s : listofFiles) { - System.out.println("Files " + s); + com.neuronrobotics.sdk.common.Log.error("Files " + s); } String asstsRepo="https://github.com/madhephaestus/BowlerStudioImageAssets.git"; // https://github.com/madhephaestus/BowlerStudioImageAssets.git ScriptingEngine.deleteRepo(asstsRepo); List call = ScriptingEngine.listBranches(asstsRepo); - System.out.println("Branches # " + call.size()); + com.neuronrobotics.sdk.common.Log.error("Branches # " + call.size()); if (call.size() > 0) { for (Ref ref : call) { - System.out.println("Branch: Ref= " + ref + " name= " + ref.getName() + " ID = " + ref.getObjectId().getName()); } + com.neuronrobotics.sdk.common.Log.error("Branch: Ref= " + ref + " name= " + ref.getName() + " ID = " + ref.getObjectId().getName()); } } else { fail(); } ScriptingEngine.checkout(asstsRepo, call.get(0).getName()); call = ScriptingEngine.listLocalBranches(asstsRepo); - System.out.println("Local Branches # " + call.size()); + com.neuronrobotics.sdk.common.Log.error("Local Branches # " + call.size()); if (call.size() > 0) { for (Ref ref : call) { - System.out.println("Branch: Ref= " + ref + " name= " + ref.getName() + " ID = " + ref.getObjectId().getName()); + com.neuronrobotics.sdk.common.Log.error("Branch: Ref= " + ref + " name= " + ref.getName() + " ID = " + ref.getObjectId().getName()); } } else { fail(); } - //System.out.println("Creating branch # " ); + //com.neuronrobotics.sdk.common.Log.error("Creating branch # " ); // ScriptingEngine.newBranch(asstsRepo, "0.20.0"); // try{ // ScriptingEngine.deleteBranch(asstsRepo, "0.20.0"); // }catch(Exception e){ // e.printStackTrace(); // } - System.out.println("Current Branch # " + ScriptingEngine.getFullBranch(asstsRepo)); + com.neuronrobotics.sdk.common.Log.error("Current Branch # " + ScriptingEngine.getFullBranch(asstsRepo)); */ } diff --git a/test/java/src/junit/bowler/JettyTest.java b/test/java/src/junit/bowler/JettyTest.java index cc9c62433..09b6af59a 100644 --- a/test/java/src/junit/bowler/JettyTest.java +++ b/test/java/src/junit/bowler/JettyTest.java @@ -38,7 +38,7 @@ public void startJetty() throws Exception { ScriptingEngine.setupAnyonmous(); // ScriptingEngine.setAutoupdate(true); } catch (Exception ex) { - System.out.println("User not logged in, test can not run"); + com.neuronrobotics.sdk.common.Log.error("User not logged in, test can not run"); } File indexOfTutorial = ScriptingEngine .fileFromGit("https://github.com/CommonWealthRobotics/CommonWealthRobotics.github.io.git", @@ -55,7 +55,7 @@ public void startJetty() throws Exception { ResourceHandler resource_handler = new ResourceHandler(); resource_handler.setDirectoriesListed(true); resource_handler.setWelcomeFiles(new String[]{"index.html"}); - System.out.println("Serving " + indexOfTutorial.getParent()); + com.neuronrobotics.sdk.common.Log.error("Serving " + indexOfTutorial.getParent()); resource_handler.setResourceBase(indexOfTutorial.getParent()); HandlerList handlers = new HandlerList(); @@ -75,7 +75,7 @@ public void test() throws InvalidRemoteException, TransportException, GitAPIExce try { java.io.InputStream url = new URL(HOME_Local_URL).openStream(); try { - System.out.println(org.apache.commons.io.IOUtils.toString(url)); + com.neuronrobotics.sdk.common.Log.error(org.apache.commons.io.IOUtils.toString(url)); } finally { org.apache.commons.io.IOUtils.closeQuietly(url); } diff --git a/test/java/src/junit/bowler/JsonTester.java b/test/java/src/junit/bowler/JsonTester.java index 9bce704ad..a37cf9c45 100644 --- a/test/java/src/junit/bowler/JsonTester.java +++ b/test/java/src/junit/bowler/JsonTester.java @@ -25,20 +25,20 @@ public void test() throws Exception { ScriptingEngine.setupAnyonmous(); //ScriptingEngine.setAutoupdate(true); }catch (Exception ex){ - System.out.println("User not logged in, test can not run"); + com.neuronrobotics.sdk.common.Log.error("User not logged in, test can not run"); } File f = ScriptingEngine .fileFromGit( "https://github.com/madhephaestus/BowlerStudioExampleRobots.git",// git repo, change this if you fork this demo "exampleRobots.json"// File from within the Git repo ); - System.out.println("File: "+f); + com.neuronrobotics.sdk.common.Log.error("File: "+f); HashMap> map = (HashMap>) ScriptingEngine .inlineFileScriptRun(f, null); for(String menuTitle:map.keySet()){ HashMap script = map.get(menuTitle); - System.out.println((String)script.get("scriptGit")); - System.out.println((String)script.get("scriptFile")); ; + com.neuronrobotics.sdk.common.Log.error((String)script.get("scriptGit")); + com.neuronrobotics.sdk.common.Log.error((String)script.get("scriptFile")); ; } */ diff --git a/test/java/src/junit/bowler/MobileBaseBuilderTest.java b/test/java/src/junit/bowler/MobileBaseBuilderTest.java new file mode 100644 index 000000000..7525c440e --- /dev/null +++ b/test/java/src/junit/bowler/MobileBaseBuilderTest.java @@ -0,0 +1,26 @@ +package junit.bowler; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.neuronrobotics.bowlerstudio.creature.MobileBaseBuilder; +import com.neuronrobotics.bowlerstudio.scripting.PasswordManager; +import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import com.neuronrobotics.sdk.addons.kinematics.MobileBase; + +public class MobileBaseBuilderTest { + + @Test + public void test() throws Exception { + ScriptingEngine.login(); + MobileBaseBuilder builder = new MobileBaseBuilder( + "https://github.com/madhephaestus/TestRepo.git", "BuiltRobot") + .setXmlName("RobRobotExample.xml"); + + MobileBase base = builder.build(); + + + } + +} diff --git a/test/java/src/junit/bowler/MobileBaseLoading.java b/test/java/src/junit/bowler/MobileBaseLoading.java index 4c024e94e..da933afdf 100644 --- a/test/java/src/junit/bowler/MobileBaseLoading.java +++ b/test/java/src/junit/bowler/MobileBaseLoading.java @@ -25,13 +25,13 @@ public void test() throws Exception { IMobileBaseUI mobileBaseUI = new IMobileBaseUI() { @Override public void setAllCSG(Collection collection, File file) { - System.out.println("Setting CSG's # " +collection.size()); + com.neuronrobotics.sdk.common.Log.error("Setting CSG's # " +collection.size()); numCSG=collection.size(); } @Override public void addCSG(Collection collection, File file) { - System.out.println("Adding CSG's # " +collection.size()); + com.neuronrobotics.sdk.common.Log.error("Adding CSG's # " +collection.size()); } @@ -55,7 +55,7 @@ public void setSelectedCsg(Collection collection) { @Override public void progressUpdate(int currentIndex, int finalIndex, String type, CSG intermediateShape) { - // TODO Auto-generated method stub + // Auto-generated method stub } }); @@ -68,10 +68,10 @@ public void progressUpdate(int currentIndex, int finalIndex, String type, CSG in // MobileBaseCadManager.get(mobileBase).getUi(). DeviceManager.addConnection(mobileBase, mobileBase.getScriptingName()); mobileBaseCadManager.generateCad(); - System.out.println("Waiting for cad to generate"); + com.neuronrobotics.sdk.common.Log.error("Waiting for cad to generate"); ThreadUtil.wait(1000); while (MobileBaseCadManager.get(mobileBase).getProcesIndictor().get() < 1 ) { - //System.out.println("Waiting: " + MobileBaseCadManager.get(mobileBase).getProcesIndictor().get()); + //com.neuronrobotics.sdk.common.Log.error("Waiting: " + MobileBaseCadManager.get(mobileBase).getProcesIndictor().get()); ThreadUtil.wait(1000); } if(numCSG==0) diff --git a/test/java/src/junit/bowler/MuJoCoBowlerIntegrationTest.java b/test/java/src/junit/bowler/MuJoCoBowlerIntegrationTest.java index 4929bc94c..6e8a13fd7 100644 --- a/test/java/src/junit/bowler/MuJoCoBowlerIntegrationTest.java +++ b/test/java/src/junit/bowler/MuJoCoBowlerIntegrationTest.java @@ -26,7 +26,7 @@ public void test() throws Exception { // JavaFXInitializer.go(); // } catch (Throwable t) { // t.printStackTrace(); -// System.err.println("ERROR No UI engine availible"); +// com.neuronrobotics.sdk.common.Log.error("ERROR No UI engine availible"); // } // ArrayList bases = new ArrayList<>(); // ArrayList free =new ArrayList<>(); @@ -39,7 +39,7 @@ public void test() throws Exception { // terrain= (ArrayList) ScriptingEngine.gitScriptRun( // "https://github.com/madhephaestus/VexHighStakes2024.git", // "field.groovy"); -// System.out.println("Parts size = "+parts.size()); +// com.neuronrobotics.sdk.common.Log.error("Parts size = "+parts.size()); // //terrain.add(new Cube(10000,10000,100).toCSG().toZMax()); // free.addAll(parts); // MuJoCoPhysicsManager manager = new MuJoCoPhysicsManager("javaCadTest", bases, free, terrain, new File("./physicsTest")); @@ -58,7 +58,7 @@ public void test() throws Exception { // } // fail("Real time broken! "+took+" instead of expected "+manager.getCurrentSimulationTimeSeconds()); // }else { -// System.out.println("Time "+now); +// com.neuronrobotics.sdk.common.Log.error("Time "+now); // } // long timeSinceStart = System.currentTimeMillis()-start; // double sec = ((double)timeSinceStart)/1000.0; @@ -67,7 +67,7 @@ public void test() throws Exception { // } // } // manager.close(); -// System.out.println("Success!"); +// com.neuronrobotics.sdk.common.Log.error("Success!"); } diff --git a/test/java/src/junit/bowler/MuJoCoTest.java b/test/java/src/junit/bowler/MuJoCoTest.java index d50485a33..f24d1a8ce 100644 --- a/test/java/src/junit/bowler/MuJoCoTest.java +++ b/test/java/src/junit/bowler/MuJoCoTest.java @@ -9,12 +9,11 @@ public class MuJoCoTest { @Test public void test() { - System.out.println("mujocoJNILoadTest"); - System.out.println(System.getProperty("org.bytedeco.javacpp.logger.debug")); + com.neuronrobotics.sdk.common.Log.error("mujocoJNILoadTest"); System.setProperty("org.bytedeco.javacpp.logger.debug", "true"); MuJoCoLib lib = new MuJoCoLib(); - System.out.println("Starting " + MuJoCoLib.mj_versionString().getString()); + com.neuronrobotics.sdk.common.Log.error("Starting " + MuJoCoLib.mj_versionString().getString()); } } diff --git a/test/java/src/junit/bowler/PyTorchResNetTest.java b/test/java/src/junit/bowler/PyTorchResNetTest.java index 8bf336a04..013fb4de5 100644 --- a/test/java/src/junit/bowler/PyTorchResNetTest.java +++ b/test/java/src/junit/bowler/PyTorchResNetTest.java @@ -20,13 +20,13 @@ public class PyTorchResNetTest { // @Test // public void testResNet() throws Exception { -// System.err.println(Thread.currentThread().getStackTrace()[1].getMethodName()); +// com.neuronrobotics.sdk.common.Log.error(Thread.currentThread().getStackTrace()[1].getMethodName()); // // } // // @Test // public void testretinaface() throws Exception { -// System.err.println(Thread.currentThread().getStackTrace()[1].getMethodName()); +// com.neuronrobotics.sdk.common.Log.error(Thread.currentThread().getStackTrace()[1].getMethodName()); // // BufferedImage bimg = ImageIO.read(new URL(imageUrl)); // @@ -43,7 +43,7 @@ public class PyTorchResNetTest { // // @Test // public void testUltraNet() throws Exception { -// System.err.println(Thread.currentThread().getStackTrace()[1].getMethodName()); +// com.neuronrobotics.sdk.common.Log.error(Thread.currentThread().getStackTrace()[1].getMethodName()); // // BufferedImage bimg = ImageIO.read(new URL(imageUrl)); // @@ -82,12 +82,12 @@ private static void saveBoundingBoxImage(Image img, DetectedObjects detection, S Path imagePath = outputDir.resolve(type + ".png").toAbsolutePath(); img.save(Files.newOutputStream(imagePath), "png"); - System.out.println("Face detection result image has been saved in: {} " + imagePath); + com.neuronrobotics.sdk.common.Log.error("Face detection result image has been saved in: {} " + imagePath); } // @Test public void testYolo() throws Exception { - System.err.println(Thread.currentThread().getStackTrace()[1].getMethodName()); + com.neuronrobotics.sdk.common.Log.error(Thread.currentThread().getStackTrace()[1].getMethodName()); Predictor predictor = PredictorFactory.imageContentsFactory(ImagePredictorType.yolov5); for (int i = 0; i < 3; i++) { @@ -101,7 +101,7 @@ public void testYolo() throws Exception { // // @Test // public void testFeatures() throws Exception { -// System.err.println(Thread.currentThread().getStackTrace()[1].getMethodName()); +// com.neuronrobotics.sdk.common.Log.error(Thread.currentThread().getStackTrace()[1].getMethodName()); // BufferedImage img = ImageIO.read(new URL(imageUrl)); // BufferedImage img2 = ImageIO.read(new URL(image2URL)); // BufferedImage img3 = ImageIO.read(new URL(image3URL)); @@ -112,12 +112,12 @@ public void testYolo() throws Exception { // float[] back3 = predictor.predict(ImageFactory.getInstance().fromImage(img3)); // float[] back4 = predictor.predict(ImageFactory.getInstance().fromImage(ImageIO.read(new URL(notme)))); // -// System.out.println(" Comprair 1 to 2 " + PredictorFactory.calculSimilarFaceFeature(back, back2)); -// System.out.println(" Comprair 1 to 3 " + PredictorFactory.calculSimilarFaceFeature(back, back3)); -// System.out.println(" Comprair 2 to 3 " + PredictorFactory.calculSimilarFaceFeature(back2, back3)); -// System.out.println(" Comprair 1 to 4 " + PredictorFactory.calculSimilarFaceFeature(back, back4)); +// com.neuronrobotics.sdk.common.Log.error(" Comprair 1 to 2 " + PredictorFactory.calculSimilarFaceFeature(back, back2)); +// com.neuronrobotics.sdk.common.Log.error(" Comprair 1 to 3 " + PredictorFactory.calculSimilarFaceFeature(back, back3)); +// com.neuronrobotics.sdk.common.Log.error(" Comprair 2 to 3 " + PredictorFactory.calculSimilarFaceFeature(back2, back3)); +// com.neuronrobotics.sdk.common.Log.error(" Comprair 1 to 4 " + PredictorFactory.calculSimilarFaceFeature(back, back4)); // -// System.out.println(Arrays.toString(back)); +// com.neuronrobotics.sdk.common.Log.error(Arrays.toString(back)); // // } diff --git a/test/java/src/junit/bowler/SequenceTest.java b/test/java/src/junit/bowler/SequenceTest.java index 518f08975..5c1944b98 100644 --- a/test/java/src/junit/bowler/SequenceTest.java +++ b/test/java/src/junit/bowler/SequenceTest.java @@ -9,12 +9,14 @@ import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine; +import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase; + public class SequenceTest { @Test public void test() throws Exception { try { - ScriptingEngine.gitScriptRun("https://github.com/madhephaestus/sequencetest.git", "test.sequence"); + ScriptingEngine.gitScriptRun(CSGDatabase.getInstance(),"https://github.com/madhephaestus/sequencetest.git", "test.sequence"); }catch(Throwable t) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); diff --git a/test/java/src/junit/bowler/TTSTest.java b/test/java/src/junit/bowler/TTSTest.java index 7ad42e4b0..0dcfd42bd 100644 --- a/test/java/src/junit/bowler/TTSTest.java +++ b/test/java/src/junit/bowler/TTSTest.java @@ -20,8 +20,8 @@ public void TTSText() { @Override public void update(double percentage, AudioStatus status) { - // TODO Auto-generated method stub - System.out.println(percentage+" "+status.toString()); + // Auto-generated method stub + com.neuronrobotics.sdk.common.Log.error(percentage+" "+status.toString()); } }; //BowlerKernel.speak("Coqui one text to speech", 200, 0, 800, 1.0, 1.0,sp); @@ -34,7 +34,7 @@ public void update(double percentage, AudioStatus status) { // for(int i=800;i<(800+CoquiDockerManager.getNummberOfOptions());i++) { // BowlerKernel.speak("Coqui " + i + " text to speech", 200, 0, i, 1.0, 1.0,null); -// System.out.println("\n\nVoice finished"); +// com.neuronrobotics.sdk.common.Log.error("\n\nVoice finished"); // } } diff --git a/test/java/src/junit/bowler/TestCheckout.java b/test/java/src/junit/bowler/TestCheckout.java index f37599d55..5279fb1da 100644 --- a/test/java/src/junit/bowler/TestCheckout.java +++ b/test/java/src/junit/bowler/TestCheckout.java @@ -25,14 +25,14 @@ public void test() throws IOException, GitAPIException { try { String []name = select.getName().split("/"); String myName = name[name.length-1]; - System.out.println("Selecting Branch\r\n"+url+" \t\t"+myName); + com.neuronrobotics.sdk.common.Log.error("Selecting Branch\r\n"+url+" \t\t"+myName); String was = ScriptingEngine.getBranch(url); ScriptingEngine.checkout(url, myName); String s = ScriptingEngine.getBranch(url); assertTrue("Changing from "+was+" to "+myName+" got "+s,myName.contains(s)); } catch (Exception e) { - // TODO Auto-generated catch block + // Auto-generated catch block e.printStackTrace(); fail(); } diff --git a/test/java/src/junit/bowler/WekaTester.java b/test/java/src/junit/bowler/WekaTester.java index 8a8e1d385..86b42f7c0 100644 --- a/test/java/src/junit/bowler/WekaTester.java +++ b/test/java/src/junit/bowler/WekaTester.java @@ -8,7 +8,7 @@ public class WekaTester { @Test public void test() { - //TODO + } }