From aabca35ff00b1c8685c22ab44effb36da8fb99fb Mon Sep 17 00:00:00 2001 From: Sam Carlberg Date: Mon, 14 Jan 2019 13:10:13 -0500 Subject: [PATCH] Upgrade to Gradle 5.0 (#900) * Move to Gradle 5.0 Remove buildSrc project Move generated code into core Give each project its own buildscript * Use kotlin DSL where possible * Add spotbugs Fix new a problem identified by spotbugs * Do not run build scans on Travis * Remove evaulationDependsOn * Cleaner codegen tests exclusion * Run OpenCV installation in its own task and allow relative JNI paths * Run code generation tests on Azure Linux --- .gitignore | 3 +- .travis.yml | 2 +- azure-pipelines.yml | 2 +- build.gradle | 606 ------------------ build.gradle.kts | 207 ++++++ buildSrc/build.gradle | 43 -- .../wpi/gripgenerator/CodeGenerator.groovy | 52 -- .../edu/wpi/gripgenerator/FileParser.java | 144 ----- .../wpi/gripgenerator/OpenCVEnumVisitor.java | 109 ---- .../gripgenerator/OpenCVMethodVisitor.java | 46 -- .../gripgenerator/defaults/DefaultValue.java | 71 -- .../defaults/DefaultValueCollector.java | 78 --- .../defaults/EnumDefaultValue.java | 68 -- .../defaults/MethodDefaultValue.java | 35 - .../defaults/NullDefaultValue.java | 46 -- .../defaults/ObjectDefaultValue.java | 76 --- .../defaults/PrimitiveDefaultValue.java | 150 ----- .../gripgenerator/settings/DefinedMethod.java | 254 -------- .../settings/DefinedMethodCollection.java | 111 ---- .../settings/DefinedParamType.java | 254 -------- .../gripgenerator/templates/Enumeration.java | 186 ------ .../gripgenerator/templates/Operation.java | 356 ---------- .../templates/OperationList.java | 112 ---- .../templates/SocketHintDeclaration.java | 184 ------ .../SocketHintDeclarationCollection.java | 308 --------- buildSrc/src/main/resources/.gitignore | 2 - .../gradle-plugins/generator.properties | 0 .../edu/wpi/gripgenerator/FileParserTest.java | 58 -- .../templates/SocketHintDeclarationTest.java | 30 - core/core.gradle.kts | 75 +++ .../composite/PublishVideoOperation.java | 7 +- .../enumeration/BorderTypesEnum.java | 23 + .../opencv_core/enumeration/CmpTypesEnum.java | 20 + .../enumeration/CovarFlagsEnum.java | 40 ++ .../enumeration/CpuFeaturesEnum.java | 14 + .../enumeration/DecompTypesEnum.java | 26 + .../opencv_core/enumeration/DftFlagsEnum.java | 41 ++ .../opencv_core/enumeration/Enum.java | 14 + .../enumeration/ErrorCodeEnum.java | 46 ++ .../enumeration/FileNodeTypeEnum.java | 27 + .../enumeration/FileStorageEnum.java | 14 + .../enumeration/FileStorageModeEnum.java | 23 + .../enumeration/FormatterEnum.java | 14 + .../enumeration/GemmFlagsEnum.java | 17 + .../opencv_core/enumeration/HammingEnum.java | 14 + .../enumeration/HersheyFontsEnum.java | 23 + .../enumeration/KmeansFlagsEnum.java | 20 + .../enumeration/LineTypesEnum.java | 17 + .../opencv_core/enumeration/MatEnum.java | 14 + .../enumeration/NormTypesEnum.java | 16 + .../opencv_core/enumeration/PCAFlagsEnum.java | 16 + .../opencv_core/enumeration/ParamEnum.java | 14 + .../opencv_core/enumeration/RNGEnum.java | 14 + .../enumeration/ReduceTypesEnum.java | 18 + .../opencv_core/enumeration/SVDFlagsEnum.java | 21 + .../enumeration/SolveLPResultEnum.java | 18 + .../enumeration/SortFlagsEnum.java | 23 + .../enumeration/SparseMatEnum.java | 14 + .../enumeration/TermCriteriaTypeEnum.java | 16 + .../opencv_core/enumeration/UMatDataEnum.java | 14 + .../opencv_core/enumeration/UMatEnum.java | 14 + .../enumeration/UMatUsageFlagsEnum.java | 14 + .../AdaptiveThresholdTypesEnum.java | 20 + .../enumeration/ColorConversionCodesEnum.java | 37 ++ .../enumeration/ColormapTypesEnum.java | 27 + .../ConnectedComponentsTypesEnum.java | 21 + .../ContourApproximationModesEnum.java | 21 + .../DistanceTransformLabelTypesEnum.java | 17 + .../DistanceTransformMasksEnum.java | 16 + .../enumeration/DistanceTypesEnum.java | 14 + .../enumeration/FloodFillFlagsEnum.java | 19 + .../enumeration/GrabCutClassesEnum.java | 18 + .../enumeration/GrabCutModesEnum.java | 20 + .../enumeration/HistCompMethodsEnum.java | 32 + .../enumeration/HoughModesEnum.java | 25 + .../enumeration/InterpolationFlagsEnum.java | 30 + .../enumeration/InterpolationMasksEnum.java | 14 + .../LineSegmentDetectorModesEnum.java | 18 + .../enumeration/MorphShapesEnum.java | 19 + .../enumeration/MorphTypesEnum.java | 26 + .../RectanglesIntersectTypesEnum.java | 17 + .../enumeration/RetrievalModesEnum.java | 22 + .../enumeration/SubdivEnum.java | 14 + .../enumeration/TemplateMatchModesEnum.java | 22 + .../enumeration/ThresholdTypesEnum.java | 21 + .../enumeration/UndistortTypesEnum.java | 14 + .../wpi/grip/core/sources/HttpSourceTest.java | 3 +- git.gradle | 20 - gradle/wrapper/gradle-wrapper.jar | Bin 54712 -> 55741 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 2 +- gradlew.bat | 2 +- settings.gradle | 25 +- ui/linuxLauncher/linuxLauncher.gradle | 23 + ui/preloader/preloader.gradle.kts | 13 + .../InputSocketControllerFactoryTest.java | 5 +- ui/ui.gradle.kts | 216 +++++++ 97 files changed, 1695 insertions(+), 3415 deletions(-) delete mode 100644 build.gradle create mode 100644 build.gradle.kts delete mode 100644 buildSrc/build.gradle delete mode 100644 buildSrc/src/main/groovy/edu/wpi/gripgenerator/CodeGenerator.groovy delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/FileParser.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/OpenCVEnumVisitor.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/OpenCVMethodVisitor.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/DefaultValue.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/DefaultValueCollector.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/EnumDefaultValue.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/MethodDefaultValue.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/NullDefaultValue.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/ObjectDefaultValue.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/PrimitiveDefaultValue.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedMethod.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedMethodCollection.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedParamType.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/templates/Enumeration.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/templates/Operation.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/templates/OperationList.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/templates/SocketHintDeclaration.java delete mode 100644 buildSrc/src/main/java/edu/wpi/gripgenerator/templates/SocketHintDeclarationCollection.java delete mode 100644 buildSrc/src/main/resources/.gitignore delete mode 100644 buildSrc/src/main/resources/META-INF/gradle-plugins/generator.properties delete mode 100644 buildSrc/src/test/java/edu/wpi/gripgenerator/FileParserTest.java delete mode 100644 buildSrc/src/test/java/templates/SocketHintDeclarationTest.java create mode 100644 core/core.gradle.kts create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/BorderTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CmpTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CovarFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CpuFeaturesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/DecompTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/DftFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/Enum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ErrorCodeEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileNodeTypeEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileStorageEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileStorageModeEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FormatterEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/GemmFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/HammingEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/HersheyFontsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/KmeansFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/LineTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/MatEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/NormTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/PCAFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ParamEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/RNGEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ReduceTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SVDFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SolveLPResultEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SortFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SparseMatEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/TermCriteriaTypeEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatDataEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatUsageFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/AdaptiveThresholdTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ColorConversionCodesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ColormapTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ConnectedComponentsTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ContourApproximationModesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTransformLabelTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTransformMasksEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/FloodFillFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/GrabCutClassesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/GrabCutModesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/HistCompMethodsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/HoughModesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/InterpolationFlagsEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/InterpolationMasksEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/LineSegmentDetectorModesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/MorphShapesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/MorphTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/RectanglesIntersectTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/RetrievalModesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/SubdivEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/TemplateMatchModesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ThresholdTypesEnum.java create mode 100644 core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/UndistortTypesEnum.java delete mode 100644 git.gradle create mode 100644 ui/linuxLauncher/linuxLauncher.gradle create mode 100644 ui/preloader/preloader.gradle.kts create mode 100644 ui/ui.gradle.kts diff --git a/.gitignore b/.gitignore index 6367279b9b..5f399fd060 100644 --- a/.gitignore +++ b/.gitignore @@ -84,8 +84,7 @@ hs_err_pid* node_modules bower_components -#Generated files should be ignored as the are regenerated as a build step -**/generated +# Generated files should be ignored as the are regenerated as a build step */generated_tests /bin/ ui/PipelineTest.java diff --git a/.travis.yml b/.travis.yml index c474022db7..e44647e699 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,7 @@ install: script: # Only run code generation tests on OSX -- linux requires sudo to install OpenCV dependencies, and that environment # will not be able to run MainWindowTest.testDragOperationFromPaletteToPipeline - - ./gradlew check jacocoTestReport jacocoRootReport --stacktrace -Pheadless=true -PlogTests --scan; + - ./gradlew check jacocoTestReport jacocoRootReport --stacktrace -Pheadless=true -PlogTests; after_success: - if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then codecov ; fi diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 44fd3f5e49..873cd6e548 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -29,7 +29,7 @@ jobs: gradleOptions: '-Xmx3072m -Dorg.gradle.java.home=/usr/lib/jvm/java-8-oracle' jdkUserInputPath: '/usr/lib/jvm/java-8-oracle' publishJUnitResults: false - tasks: 'check jacocoTestReport jacocoRootReport jfxNative -Pheadless=true -PlogTests --stacktrace' + tasks: 'check jacocoTestReport jacocoRootReport jfxNative -Pgeneration -PjniLocation=build/OpenCVJNI -Pheadless=true -PlogTests --stacktrace' # Publish JaCoCo code coverage results from the build - task: PublishCodeCoverageResults@1 diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 5e293e2ad1..0000000000 --- a/build.gradle +++ /dev/null @@ -1,606 +0,0 @@ -import static org.gradle.api.tasks.wrapper.Wrapper.DistributionType - -import groovy.xml.XmlUtil - -buildscript { - repositories { - jcenter() - maven { - url "https://plugins.gradle.org/m2/" - } - maven { - url '/~https://github.com/WPIRoboticsProjects/opencv-maven/raw/mvn-repo' - } - } - - dependencies { - classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.8.0' - classpath 'com.netflix.nebula:gradle-aggregate-javadocs-plugin:3.0.1' - classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.11' - classpath group: 'edu.wpi.first.wpilib.opencv', name: 'opencv-installer', version: '2.0.0' - } -} - -import edu.wpi.first.wpilib.opencv.installer.Installer -import edu.wpi.first.wpilib.opencv.installer.platform.Platform - -plugins { - id 'com.gradle.build-scan' version '1.8' - id 'java' - id 'idea' - id 'eclipse' - id 'jacoco' - id 'com.google.osdetector' version '1.4.0' - id 'com.github.johnrengelman.shadow' version '1.2.4' - id 'com.dorongold.task-tree' version '1.3' - id 'org.ajoberstar.grgit' version '1.7.1' apply false -} -apply plugin: 'nebula-aggregate-javadocs' -apply from: 'git.gradle' - -buildScan { - licenseAgreementUrl = 'https://gradle.com/terms-of-service' - licenseAgree = 'yes' -} - -allprojects { - // Hacky fix to make the build work - tasks.withType(CreateStartScripts) { - mainClassName = "someRandomGiberish" + Math.random() - } -} - -idea.project { - ipr.withXml { provider -> - def node = provider.asNode() - def compilerConfig = node.component.find { it.'@name' == 'CompilerConfiguration' } - compilerConfig.annotationProcessing[0].'@enabled' = 'true' -// def ccfg = node.component.find { it.@name == 'CompilerConfiguration' } -// ccfg.remove(ccfg.annotationProcessing) -// ccfg.append(new NodeBuilder().annotationProcessing() { -// profile(default: true, name: 'Default', enabled: true) { -// processorPath(useClasspath: true) -// } -// }) - } -} - -/* - * Gets the version name from the latest Git tag - * http://ryanharter.com/blog/2013/07/30/automatic-versioning-with-git-and-gradle/ - */ -def getVersionName = { -> - if (project.hasProperty("vers")) return vers - return getGitDescribe() -} - -def getVersionSimple = { -> - if (project.hasProperty("vers")) return vers - return getGitDescribeAbbrev() -} - -configure(subprojects - project(':ui:linuxLauncher')) { - apply plugin: 'java' - apply plugin: 'application' - apply plugin: 'jacoco' - apply plugin: 'net.ltgt.errorprone' - apply plugin: 'checkstyle' - apply plugin: 'pmd' - apply plugin: 'findbugs' - - configurations.errorprone { - resolutionStrategy.force 'com.google.errorprone:error_prone_core:2.0.21' - } - - checkstyle { - configFile = new File(rootDir, "checkstyle.xml") - toolVersion = '6.19' - if (project.hasProperty("ignoreCheckstyle")) { - ignoreFailures = true - } - } - - tasks.withType(Checkstyle) { - // Remove checkstyle dependencies on compilation - // (This neuters :core:checkstyleGenerated, but since that's not needed anyway, who cares) - it.dependsOn = [] - } - - pmd { - consoleOutput = true - sourceSets = [sourceSets.main, sourceSets.test] - reportsDir = file("$project.buildDir/reports/pmd") - ruleSetFiles = files(new File(rootDir, "pmd-ruleset.xml")) - ruleSets = [] - } - - findbugs { - sourceSets = [sourceSets.main, sourceSets.test] - excludeFilter = new File(rootDir, "findBugsSuppressions.xml") - effort = "max" - } - - ext.printReportSafe = { xmlReport -> - if (xmlReport.exists()) { - def bugs = (new XmlParser().parse(xmlReport)).BugInstance - bugs.each { System.out.println(new XmlUtil().serialize(it)) } - } - } - - task findbugsMainReport { - doLast { - printReportSafe(findbugsMain.reports.getXml().destination) - } - } - - task findbugsTestReport { - doLast { - printReportSafe(findbugsTest.reports.getXml().destination) - } - } - - findbugsMain.finalizedBy findbugsMainReport - findbugsTest.finalizedBy findbugsTestReport - - repositories { - mavenCentral() - jcenter() - } - - dependencies { - compile group: 'com.google.code.findbugs', name: 'annotations', version: '3.0.1' - testCompile group: 'net.jodah', name: 'concurrentunit', version: '0.4.2' - testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3' - testCompile group: 'junit', name: 'junit', version: '4.12' - testCompile group: 'com.google.truth', name: 'truth', version: '0.34' - testCompile group: 'com.google.guava', name: 'guava-testlib', version: '22.0' - } - - version = getVersionName() - - compileJava { - options.compilerArgs << "-g" - } - - jacocoTestReport { - reports { - xml.enabled = true - html.enabled = true - } - } - - tasks.withType(Javadoc) { - source compileJava.source - options.addStringOption('Xdoclint:all,-html', '-quiet') - failOnError false - } - - tasks.withType(JavaExec) { - enableAssertions = true - } - - // Turn on test results - test { - testLogging { - if (project.hasProperty('logTests')) { - events "started", "passed", "skipped", "failed" - } else { - events "failed" - } - exceptionFormat "full" - } - doFirst { - filter.includePatterns.each { - include "${it.replaceAll('\\.', "\\${File.separator}")}.class" - } - filter.setIncludePatterns('*') - } - } -} - -def os = osdetector.classifier.replace("osx", "macosx").replace("x86_32", "x86") -def arch = osdetector.arch.replace("x86_64", "x64") - -project(":core") { - apply plugin: 'java' - apply plugin: 'idea' - apply plugin: 'jacoco' - apply plugin: "com.github.johnrengelman.shadow" - - configurations { - shadow - } - - repositories { - flatDir { - dirs 'libs' - } - maven { - url = "http://first.wpi.edu/FRC/roborio/maven/release" - } - maven { - url = "/~https://github.com/WPIRoboticsProjects/rosjava_mvn_repo/raw/master" - } - } - - dependencies { - compile group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1' - compile group: 'org.bytedeco', name: 'javacv', version: '1.1' - compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1' - compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: os - compile group: 'org.bytedeco.javacpp-presets', name: 'opencv-3.0.0-1.1', classifier: 'linux-frc' - compile group: 'org.bytedeco.javacpp-presets', name: 'videoinput', version: '0.200-1.1', classifier: os - compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '0.200-1.1', classifier: os - compile group: 'org.python', name: 'jython', version: '2.7.0' - compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.10' - compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5' - compile group: 'com.google.guava', name: 'guava', version: '20.0' - compile group: 'com.google.auto.value', name: 'auto-value', version: '1.3' - compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0' - compile group: 'org.eclipse.jetty', name:'jetty-server', version:'9.3.14.v20161028' - testCompile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.2' - testCompile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.5' - testCompile group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.2' - compile group: 'commons-cli', name: 'commons-cli', version: '1.3.1' - // We use the no_aop version of Guice because the aop isn't avaiable in arm java - // http://stackoverflow.com/a/15235190/3708426 - // /~https://github.com/google/guice/wiki/OptionalAOP - compile group: 'com.google.inject', name: 'guice', version: '4.1.0', classifier: 'no_aop' - compile group: 'com.google.inject.extensions', name: 'guice-assistedinject', version: '4.1.0' - - // Network publishing dependencies - compile group: 'org.ros.rosjava_core', name: 'rosjava', version: '[0.2,0.3)' - compile group: 'org.ros.rosjava_messages', name: 'grip_msgs', version: '0.0.1' - compile group: 'edu.wpi.first.wpilib.networktables.java', name: 'NetworkTables', version: '3.1.2', classifier: 'desktop' - compile group: 'edu.wpi.first.wpilib.networktables.java', name: 'NetworkTables', version: '3.1.2', classifier: 'arm' - } - - mainClassName = 'edu.wpi.grip.core.Main' - - jar { - manifest { - attributes 'Implementation-Version': version, 'Main-Class': mainClassName - } - } - - shadowJar { - artifacts { - shadow(tasks.shadowJar.archivePath) { - builtBy shadowJar - } - } - - /* The icudt54b directory in Jython takes up 9 megabytes and doesn't seem to do anything useful. */ - exclude 'org/python/icu/impl/data/icudt54b/' - - /* We don't use all of the OpenCV libraries, and they seem to take up a lot of space. If we ever decide to - use any more of these (or perhaps just include them for people to use from Python scripts), the following lines - should be changed, but for now this saves us a lot of space. */ - exclude 'org/bytedeco/javacpp/*/*calib3d*' - exclude 'org/bytedeco/javacpp/*/*optflow*' - exclude 'org/bytedeco/javacpp/*/*photo*' - exclude 'org/bytedeco/javacpp/*/*shape*' - exclude 'org/bytedeco/javacpp/*/*stitching*' - exclude 'org/bytedeco/javacpp/*/*superres*' - exclude 'org/bytedeco/javacpp/*/*videostab*' - exclude 'org/bytedeco/javacpp/*/*xfeatures2d*' - } - - sourceSets { - generated { - java { - /* Note: When referencing this it becomes `srcDirs` */ - srcDir 'src/generated/java' - } - } - } - - task generateCodeFromSource(type: CodeGenerator) { - description 'Generates the Operation Wrappers for the OpenCV methods.\n To skip run with parm `-PskipGenerate`' - dest sourceSets.generated.java.srcDirs - removeExisting true - } - generateCodeFromSource.onlyIf { !project.hasProperty('skipGenerate') } - compileJava.source sourceSets.generated.java, sourceSets.main.java - compileJava.dependsOn generateCodeFromSource - - // IDE setup - eclipse.classpath { - file.whenMerged { cp -> - sourceSets.generated.java.srcDirs.forEach { srcDir -> - def source_folder = new org.gradle.plugins.ide.eclipse.model.SourceFolder(srcDir.getAbsolutePath(), "build/classes/merged") - if (cp.entries.find() { it.path == source_folder.path } == null) - cp.entries.add(source_folder) - } - } - } - - idea.module { - sourceDirs += sourceSets.generated.java.srcDirs - sourceDirs += file('generated') - } -} - -project (":ui:linuxLauncher") { - apply plugin: 'cpp' - - model { - binaries { - all { - cppCompiler.args '-pthread', '-ldl' - linker.args '-pthread', '-ldl' - } - } - components { - linuxLauncher(NativeExecutableSpec) { - sources { - cpp { - source { - srcDir "src/cpp" - } - } - } - } - } - } -} - -project (":ui:preloader") { - apply plugin: 'java' - apply plugin: 'idea' - apply plugin: 'jacoco' - apply plugin: 'application' - - mainClassName = "edu.wpi.grip.preloader.GripPreloader" - - task run(overwrite: true, type: JavaExec) { - classpath = sourceSets.main.runtimeClasspath - main = mainClassName - args 'windowed' - } -} - -project(":ui") { - apply plugin: 'java' - apply plugin: 'idea' - apply plugin: 'jacoco' - apply plugin: 'application' - apply plugin: 'javafx-gradle-plugin' - - repositories { - maven { - url = "http://first.wpi.edu/FRC/roborio/maven/development" - } - } - - configurations { - ideProvider - } - if(!(project.hasProperty('generation') || project.hasProperty('genonly'))){ - sourceSets { - test { - java { - exclude "**/ui/codegeneration" - exclude "**/ui/codegeneration/**" - } - } - } - } - dependencies { - compile project(path: ':core', configuration: 'shadow') - compile project(path: ':ui:preloader') - ideProvider project(path: ':core', configuration: 'compile') - compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.11' - compile group: 'com.hierynomus', name: 'sshj', version: '0.16.0' - compile group: 'org.apache.velocity', name: 'velocity', version: '1.7' - testCompile files(project(':core').sourceSets.test.output.classesDir) - testCompile files(project(':core').sourceSets.test.output.resourcesDir) - testCompile group: 'org.testfx', name: 'testfx-core', version: '4.0.5-alpha' - testCompile group: 'org.testfx', name: 'testfx-junit', version: '4.0.5-alpha' - testRuntime group: 'org.testfx', name: 'openjfx-monocle', version: '1.8.0_20' - testCompile group: 'org.opencv', name: 'opencv-java', version: '3.1.0' - } - - evaluationDependsOn(':core') - evaluationDependsOn(':ui:preloader') - if (System.getProperty("os.name").toLowerCase().contains("linux")) { - jfxNative.dependsOn tasks.getByPath(':ui:linuxLauncher:linuxLauncherExecutable') - } - compileTestJava.dependsOn tasks.getByPath(':core:testClasses') - - idea.module { - scopes.PROVIDED.plus += [configurations.ideProvider] - } - - /* - * Allows you to run the UI tests in headless mode by calling gradle with the -Pheadless=true argument - */ - if (project.hasProperty('headless') && project.headless) { - println "Running UI Tests Headless" - test { - jvmArgs = ['-Djava.awt.headless=true', '-Dtestfx.robot=glass', '-Dtestfx.headless=true', '-Dprism.order=sw', '-Dprism.text=t2k'] - } - } - - task testSharedLib() { - description 'Compiles the shared library used by c++ generation testing.' - doLast { - def syst = osdetector.os - if(syst == "windows") { - exec { - ignoreExitValue true//if clean hasn't been called, directory already exists and mkdir fails. - workingDir 'build/classes/test' - commandLine 'cmd', '/c', 'mkdir', 'pipelib' - } - exec { - workingDir 'build/classes/test/pipelib' - commandLine '"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat"', 'amd64', '&', 'cmake', '-G', 'Visual Studio 14 2015 Win64', '..\\..\\..\\..\\src\\test\\resources\\edu\\wpi\\grip\\ui\\codegeneration\\tools\\' - } - exec { - workingDir 'build/classes/test/pipelib' - commandLine '"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat"', 'amd64', '&', 'cmake', '--build', '.', '--target', 'ALL_BUILD', '--config', 'Release' - } - exec { - workingDir 'build/classes/test' - commandLine 'cmd', '/C', 'copy /Y pipelib\\Release\\* .' - } - exec { - workingDir 'build/classes/test' - commandLine 'cmd', '/C', 'copy /Y pipelib\\pipe\\Release\\* .' - } - exec { - workingDir 'build/classes/test/pipelib' - commandLine 'cmd', '/C', 'copy /Y ..\\..\\..\\..\\src\\test\\resources\\edu\\wpi\\grip\\ui\\codegeneration\\tools\\pipe\\AbsPipeline.h pipe\\' - } - exec { - workingDir 'build/classes/test' - commandLine 'cmd', '/C', 'copy /Y ..\\..\\..\\src\\test\\resources\\edu\\wpi\\grip\\ui\\codegeneration\\tools\\realpipe\\CMakeLists.txt .' - } - } else { - exec { - ignoreExitValue true//if clean hasn't been called, directory already exists and mkdir fails. - workingDir 'build/classes/test' - commandLine 'mkdir', 'pipelib' - } - exec { - workingDir 'build/classes/test/pipelib' - commandLine 'cmake' , '../../../../src/test/resources/edu/wpi/grip/ui/codegeneration/tools/' - } - exec { - workingDir 'build/classes/test/pipelib' - commandLine 'make' - } - exec { - workingDir 'build/classes/test' - if(syst == "osx"){ - commandLine 'cp', 'pipelib/libgenJNI.dylib', '.' - } - if(syst == "linux"){ - commandLine 'cp' , 'pipelib/libgenJNI.so', '.' - } - } - exec { - workingDir 'build/classes/test/pipelib' - commandLine 'cp' , '../../../../src/test/resources/edu/wpi/grip/ui/codegeneration/tools/pipe/AbsPipeline.h', 'pipe/' - } - exec { - workingDir 'build/classes/test' - commandLine 'cp', '../../../src/test/resources/edu/wpi/grip/ui/codegeneration/tools/realpipe/CMakeLists.txt', '.' - } - } - } - } - - if(project.hasProperty('generation') || project.hasProperty('genonly')){ - def syst = osdetector.os - test { - Platform platform = Installer.getPlatform() - Installer.setOpenCvVersion('3.1.0') - def jniLocation = project.getProperties().getOrDefault('jniLocation', platform.defaultJniLocation()) - Installer.installJni("${jniLocation}") - def defaultLibPath = System.getProperty('java.library.path'); - jvmArgs = ["-Djava.library.path=${defaultLibPath}${System.getProperty('path.separator')}${jniLocation}"] - if(project.hasProperty('genonly')){ - useJUnit { - includeCategories 'edu.wpi.grip.ui.codegeneration.GenerationTesting' - } - } - } - } - - jfx { - mainClass = "edu.wpi.grip.ui.Main" - preLoader = "edu.wpi.grip.preloader.GripPreloader" - - identifier = "GRIP" - appName = "GRIP" - vendor = "Worcester Polytechnic Institute" - nativeReleaseVersion = "${getVersionSimple()}-${arch}" - - jfxMainAppJarName = "${jfx.appName}-${jfx.nativeReleaseVersion}.jar" - - // -XX:-OmitStackTraceInFastThrow prevents the JIT from eating stack traces that get thrown a lot - // This is slower but means we actually get the stack traces instead of - // having them become one line like `java.lang.ArrayIndexOutOfBoundsException` - // and as such, would be useless. - // See: https://plumbr.eu/blog/java/on-a-quest-for-missing-stacktraces - // -Xmx limits the heap size. This prevents memory use from ballooning with a lot - // of JavaCV native objects being allocated hanging around waiting to get GC'd. - // -XX:MaxNewSize limits the size of the eden space to force minor GCs to run more often. - // This causes old mats (which take up little space on the heap but a lot of native memory) to get deallocated - // and free up native memory quicker, limiting the memory the app takes up. - jvmArgs = ["-XX:-OmitStackTraceInFastThrow", "-Xmx200m", "-XX:MaxNewSize=32m"] - - bundleArguments = [ - "linux.launcher.url": file('linuxLauncher/build/exe/linuxLauncher/linuxLauncher').toURI().toURL() - ] - } - mainClassName = jfx.mainClass - - tasks.withType(de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxNativeTask) { - doLast { - File[] packageFiles = file("${buildDir}/jfx/native/").listFiles(new FilenameFilter() { - @Override - boolean accept(File dir, String name) { - return name.startsWith('grip-') || name.startsWith('GRIP-') && new File(dir, name).isFile() - } - }) - for (File packageFile : packageFiles) { - String oldName = packageFile.name - String newName = oldName.replaceAll(/^grip/, /GRIP/) - .replaceAll(/64\./, /-x64./) - .replaceAll(/8632\./, /-x86-32./) - packageFile.renameTo(new File(packageFile.parentFile, newName)) - } - } - } -} - - -configure([ - project(":core"), - project(":ui"), - project(":ui:preloader") -]) { - if (project.hasProperty('jvmArgs')) { - run { - jvmArgs = (project.jvmArgs.split("\\s+") as List) - } - } - if (project.hasProperty('args')) { - run { - args = (project.args.split("\\s+") as List) - } - } -} - -/* - * This is roughly based upon this post: - * https://discuss.gradle.org/t/merge-jacoco-coverage-reports-for-multiproject-setups/12100/6 - */ -task jacocoRootReport(type: JacocoReport, group: 'Coverage reports') { - description = 'Generates an aggregate report from all subprojects' - configure(subprojects - project(':ui:linuxLauncher')) { - dependsOn(test) - - additionalSourceDirs = files(sourceSets.main.allSource.srcDirs) - sourceDirectories = files(sourceSets.main.allSource.srcDirs) - classDirectories = files(sourceSets.main.output) - executionData = files(jacocoTestReport.executionData) - - reports { - html.enabled = true - xml.enabled = true - } - - doFirst { - executionData = files(executionData.findAll { it.exists() }) - } - } -} - -task wrapper(type: Wrapper) { - gradleVersion = '4.10.2' - // We want the sources with the wrapper. - distributionType = DistributionType.ALL -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000000..2e7567422f --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,207 @@ +import org.ajoberstar.grgit.Grgit +import com.github.spotbugs.SpotBugsTask + +buildscript { + repositories { + jcenter() + maven { + setUrl("/~https://github.com/WPIRoboticsProjects/opencv-maven/raw/mvn-repo") + } + } + dependencies { + classpath(group = "de.dynamicfiles.projects.gradle.plugins", name = "javafx-gradle-plugin", version = "8.8.2") + classpath(group = "edu.wpi.first.wpilib.opencv", name = "opencv-installer", version = "2.0.0") + } +} + +plugins { + `java` + `jacoco` + `checkstyle` + `pmd` + id("com.github.johnrengelman.shadow") version "4.0.3" + id("com.google.osdetector") version "1.4.0" + id("org.ajoberstar.grgit") version "2.0.0" apply false + id("net.ltgt.errorprone") version "0.0.16" + id("com.github.spotbugs") version "1.6.4" + id("com.gradle.build-scan") version "2.1" +} + +buildScan { + setTermsOfServiceUrl("https://gradle.com/terms-of-service") + setTermsOfServiceAgree("yes") +} + +repositories { + mavenCentral() + jcenter() +} + +tasks.withType().configureEach { + gradleVersion = "5.0" + distributionType = Wrapper.DistributionType.ALL +} + +fun javaSubprojects(action: Project.() -> Unit) { + subprojects.minus(project(":ui:linuxLauncher")).forEach { project -> + project.action() + } +} + +var grgit: Grgit? = null +if (rootProject.file(".git").exists()) { + project.apply { + plugin("org.ajoberstar.grgit") + } + grgit = Grgit.open() +} + +javaSubprojects { + apply { + plugin("java") + plugin("org.gradle.jacoco") + plugin("org.gradle.pmd") + plugin("org.gradle.checkstyle") + plugin("net.ltgt.errorprone") + plugin("com.github.spotbugs") + } + repositories { + mavenCentral() + jcenter() + maven { + name = "WPILib Maven Release" + setUrl("http://first.wpi.edu/FRC/roborio/maven/release") + } + maven { + name = "rosjava Maven" + setUrl("/~https://github.com/rosjava/rosjava_mvn_repo/raw/master") + } + maven { + name = "GRIP ROS Maven" + setUrl("/~https://github.com/WPIRoboticsProjects/rosjava_mvn_repo/raw/master") + } + } + + version = getVersionName() + + dependencies { + "compile"(group = "com.google.code.findbugs", name = "annotations", version = "3.0.1") + "testCompile"(group = "net.jodah", name = "concurrentunit", version = "0.4.2") + "testCompile"(group = "org.hamcrest", name = "hamcrest-all", version = "1.3") + "testCompile"(group = "junit", name = "junit", version = "4.12") + "testCompile"(group = "com.google.truth", name = "truth", version = "0.34") + "testCompile"(group = "com.google.guava", name = "guava-testlib", version = "22.0") + } + + checkstyle { + configFile = rootDir.resolve("checkstyle.xml") + toolVersion = "6.19" + if (project.hasProperty("ignoreCheckstyle")) { + isIgnoreFailures = true + } + } + + pmd { + toolVersion = "5.6.0" + isConsoleOutput = true + val projectSourcesSets = this@javaSubprojects.sourceSets + sourceSets = listOf(projectSourcesSets["main"], projectSourcesSets["test"]) + reportsDir = buildDir.resolve("reports/pmd") + ruleSetFiles = files(rootDir.resolve("pmd-ruleset.xml")) + } + + configurations["errorprone"].apply { + resolutionStrategy.force("com.google.errorprone:error_prone_core:2.3.2") + } + + spotbugs { + toolVersion = "3.1.7" + val javaSources = this@javaSubprojects.sourceSets + sourceSets = setOf(javaSources["main"], javaSources["test"]) + excludeFilter = file("$rootDir/findBugsSuppressions.xml") + effort = "max" + } + + tasks.withType { + reports { + xml.isEnabled = false + emacs.isEnabled = true + } + finalizedBy(task("${name}Report") { + mustRunAfter(this@withType) + doLast { + this@withType + .reports + .emacs + .destination + .takeIf { it.exists() } + ?.readText() + .takeIf { !it.isNullOrBlank() } + ?.also { logger.warn(it) } + } + }) + } + + tasks.named("jacocoTestReport") { + reports { + html.isEnabled = true + xml.isEnabled = true + } + } + + tasks.withType { + source(tasks.named("compileJava").map { it.source }) + } + +} + +tasks.register("jacocoRootReport") { + group = "Coverage reports" + description = "Generates an aggregate report from all subprojects" + + reports { + html.isEnabled = true + xml.isEnabled = true + } + + javaSubprojects { + val sourceSets = (this as ExtensionAware).extensions.getByName("sourceSets") as SourceSetContainer + dependsOn(tasks["test"]) + val srcFiles = files(sourceSets["main"].allSource.srcDirs) + additionalSourceDirs(srcFiles) + sourceDirectories.from(srcFiles) + classDirectories.from(files(sourceSets["main"].output)) + executionData.from(tasks.named("jacocoTestReport").map { it.executionData }) + } + doFirst { + executionData.setFrom(files(executionData.files.filter { it.exists() })) + } +} + +fun Project.getGitCommit(): String { + return grgit?.head()?.abbreviatedId ?: "" +} + +fun Project.getGitDescribe(): String { + return grgit?.describe() ?: "v0.0.0" +} + +fun Project.getGitDescribeAbbrev(): String { + return grgit?.tag?.list()?.last()?.name ?: "v0.0.0" +} + +fun Project.getVersionName(): String { + if (project.hasProperty("vers")) { + val vers: String by properties + return vers + } + return getGitDescribe() +} + +fun Project.getVersionSimple(): String { + if (project.hasProperty("vers")) { + val vers: String by properties + return vers + } + return getGitDescribeAbbrev() +} diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle deleted file mode 100644 index 5244f6ba83..0000000000 --- a/buildSrc/build.gradle +++ /dev/null @@ -1,43 +0,0 @@ -apply plugin: 'groovy' -apply plugin: 'project-report' - -repositories { - mavenCentral() -} - -configurations { - source -} - -dependencies { - compile gradleApi() - compile localGroovy() - compile group: 'com.google.guava', name: 'guava', version: '19.0' - compile group: 'com.github.javaparser', name: 'javaparser-core', version: '2.2.2' - source group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: 'sources' - testCompile group: 'junit', name: 'junit', version: '4.11' -} - -task extractSources(type: Copy) { - from { // use of closure defers evaluation until execution time - configurations.source.collect { zipTree(it) } - } - include '**/*.java' - exclude '**/META-INF/**' - //Otherwise Intellj won't let the files be used as resources - rename { filename -> - filename.replace 'java', 'txt' - - } - into "$projectDir/src/main/resources" -} - -compileGroovy.dependsOn extractSources - -task runScript (dependsOn: 'classes', type: JavaExec) { - main = 'Main' - classpath = sourceSets.main.runtimeClasspath -} - -sourceCompatibility = 1.8 -version = '0.1' \ No newline at end of file diff --git a/buildSrc/src/main/groovy/edu/wpi/gripgenerator/CodeGenerator.groovy b/buildSrc/src/main/groovy/edu/wpi/gripgenerator/CodeGenerator.groovy deleted file mode 100644 index 0d52ed65f3..0000000000 --- a/buildSrc/src/main/groovy/edu/wpi/gripgenerator/CodeGenerator.groovy +++ /dev/null @@ -1,52 +0,0 @@ -// This code provides the "codegen" task, provided by this build item, -// to generate a class named by the user of the build item. - -// Create a class to contain our targets. From inside our class, -// properties in the script's binding are not available. By doing our -// work inside a class, we are protected against a category of easy -// coding errors. It doesn't matter if the class name collides with -// other classes defined in other rules. - -import com.github.javaparser.ast.CompilationUnit -import edu.wpi.gripgenerator.FileParser -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.TaskAction - -class CodeGenerator extends DefaultTask { - /** - * The destination of the source code. - */ - def dest - /** - * Whether or not the contents of the destination directory should be removed prior to the - * generated code being added. - */ - def removeExisting - - @TaskAction - def runAction() { - //Get the target directory - LinkedHashSet destSet = dest; - String targetDirectoryString = destSet.getAt(0).toString() - - //Generate all of the output units - Map files = FileParser.generateAllSourceCode(); - - - File targetDirectory = new File(targetDirectoryString); - - if (removeExisting) targetDirectory.deleteDir(); - - for (String fileName : files.keySet()) { - CompilationUnit fileUnit = files.get(fileName); - File packageDir = new File(targetDirectory, "/" + fileUnit.package.getName().toString().replace('.', '/').replace(' ', '').replace(';', '')); - if (packageDir.exists()) { - //println "The file " + fileName + " already exists"; - } else { - packageDir.mkdirs(); - } - new File(packageDir, fileName + ".java").write(fileUnit.toString()); - } - } - -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/FileParser.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/FileParser.java deleted file mode 100644 index 5a7451683c..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/FileParser.java +++ /dev/null @@ -1,144 +0,0 @@ -package edu.wpi.gripgenerator; - -import com.github.javaparser.JavaParser; -import com.github.javaparser.ParseException; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.FieldAccessExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.type.PrimitiveType; - -import edu.wpi.gripgenerator.defaults.DefaultValueCollector; -import edu.wpi.gripgenerator.defaults.EnumDefaultValue; -import edu.wpi.gripgenerator.defaults.PrimitiveDefaultValue; -import edu.wpi.gripgenerator.templates.OperationList; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -public class FileParser { - /** - * Regex splits the parameter into three distinct capture groups.
  1. The type and the param - * with optional varargs.
  2. The comment that is after the parameter.
  3. The various - * ways that the parameter can end.
- */ - protected static final String methodReorderPattern = "([A-Za-z1-9]+ (?:\\.\\.\\.)" + - "?[a-z][A-Za-z0-9_]*)(/\\*=[^ ]*\\*/)((?:,)|(?:\\s*\\)))"; - - /** - * Reorders the {@link FileParser#methodReorderPattern} capture groups so the JavaParser can - * correctly associate the params with their respective comments. - */ - protected static final String methodNewOrder = "$2$1$3"; - - /** - * There is a bug in the JavaParser that will incorrectly associate comments after a parameter but - * before a comma will incorrectly associate that comment with the next param in the method's - * params. - * - * @param stream The original input file. - * @return The processed output stream. - * @see Javaparser Issue:199 - */ - private static InputStream preProcessStream(InputStream stream) { - //FIXME: This is a hack around. This should be removed once the above noted issue is resolved. - java.util.Scanner s = new java.util.Scanner(stream, StandardCharsets.UTF_8.name()) - .useDelimiter("\\A"); - String input = s.hasNext() ? s.next() : ""; - input = input.replaceAll(methodReorderPattern, methodNewOrder); - return new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)); - } - - private static CompilationUnit readFile(URL url) { - try { - return JavaParser.parse(preProcessStream(url.openStream())); - } catch (IOException e) { - throw new IllegalStateException(e); - } catch (ParseException e) { - throw new IllegalStateException(e); - } - } - - /** - * Generates all of the source code from the opencv bindings - * - * @return A map of the filename with the compilation units - */ - public static Map generateAllSourceCode() { - URL openCvCoreUrl = FileParser.class.getResource("/org/bytedeco/javacpp/opencv_core.txt"); - CompilationUnit compilationUnit = readFile(openCvCoreUrl); - Map returnMap = new HashMap<>(); - DefaultValueCollector collector = new DefaultValueCollector(); - collector.add(new PrimitiveDefaultValue(new PrimitiveType(PrimitiveType.Primitive.Double)) { - @Override - protected Set getDefaultValues() { - return Collections.singleton("CV_PI"); - } - - @Override - public Expression getDefaultValue(String defaultValue) { - return new FieldAccessExpr( - new NameExpr("Math"), - "PI" - ); - } - }); - - collector.add(new EnumDefaultValue("edu.wpi.grip.core.operations.opencv.enumeration", - "FlipCode", "X_AXIS", "Y_AXIS", "BOTH_AXES")); - - OperationList operationList = new OperationList( - new ImportDeclaration(new NameExpr("edu.wpi.grip.generated.opencv_core"), false, true), - new ImportDeclaration(new NameExpr("edu.wpi.grip.generated.opencv_imgproc"), false, true) - ); - - if (compilationUnit != null) { - returnMap.putAll(parseOpenCVCore(compilationUnit, collector, operationList)); - } else { - System.err.print("Invalid File input"); - } - URL openCvImgprocUrl = FileParser.class.getResource("/org/bytedeco/javacpp/opencv_imgproc.txt"); - compilationUnit = readFile(openCvImgprocUrl); - if (compilationUnit != null) { - returnMap.putAll(parseOpenImgprc(compilationUnit, collector, operationList)); - } - return returnMap; - } - - public static Map parseOpenImgprc(CompilationUnit imgprocDeclaration, - DefaultValueCollector collector, - OperationList operations) { - Map compilationUnits = new HashMap<>(); - final String baseClassName = "opencv_imgproc"; - - OpenCVEnumVisitor enumVisitor = new OpenCVEnumVisitor(baseClassName, collector); - enumVisitor.visit(imgprocDeclaration, compilationUnits); - compilationUnits.putAll(enumVisitor.generateCompilationUnits()); - return compilationUnits; - } - - public static Map parseOpenCVCore(CompilationUnit coreDeclaration, - DefaultValueCollector collector, - OperationList operations) { - Map compilationUnits = new HashMap<>(); - final String baseClassName = "opencv_core"; - - OpenCVEnumVisitor enumVisitor = new OpenCVEnumVisitor(baseClassName, collector); - enumVisitor.visit(coreDeclaration, compilationUnits); - compilationUnits.putAll(enumVisitor.generateCompilationUnits()); - - return compilationUnits; - } - - public static void main(String... args) { - FileParser.generateAllSourceCode(); - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/OpenCVEnumVisitor.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/OpenCVEnumVisitor.java deleted file mode 100644 index 2ee569a097..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/OpenCVEnumVisitor.java +++ /dev/null @@ -1,109 +0,0 @@ -package edu.wpi.gripgenerator; - -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.PackageDeclaration; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.FieldDeclaration; -import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.ast.comments.Comment; -import com.github.javaparser.ast.visitor.VoidVisitorAdapter; - -import edu.wpi.gripgenerator.defaults.DefaultValueCollector; -import edu.wpi.gripgenerator.defaults.EnumDefaultValue; -import edu.wpi.gripgenerator.templates.Enumeration; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - - -public class OpenCVEnumVisitor extends VoidVisitorAdapter> { - private static final String enumNamePostFix = "Enum"; - /** - * @see Regex Example - */ - private static final Pattern ENUM_REGEX = Pattern.compile(".*enum cv::([a-zA-Z_]*)?:?:?\\s?" + - "([a-zA-Z_]*)"); - private final String baseClassName; - private final Map> nameValuesMap = new HashMap(); - private final Map nameParentClassMap = new HashMap(); - private final DefaultValueCollector collector; - private PackageDeclaration collectedPackage; - - public OpenCVEnumVisitor(String baseClassName, DefaultValueCollector collector) { - this.baseClassName = baseClassName; - this.collector = collector; - } - - public Map generateCompilationUnits() { - assert collectedPackage != null : "The package was not collected before the compilation units" + - " were generated"; - // Add default values to the collector - final List enumerations = nameValuesMap - .keySet() - .stream() - .map(k -> new Enumeration( - k, - collectedPackage, - baseClassName, - nameParentClassMap.get(k), - nameValuesMap.get(k))) - .collect(Collectors.toList()); - collector.addAll( - enumerations.stream() - .map(e -> new EnumDefaultValue( - e.getPackageDeclaration().getName().getName(), - e.getEnumerationClassName(), - nameValuesMap - .get(e.getEnumerationClassName()) - .stream() - .map(name -> name.getId().getName()).collect(Collectors.toSet()) - )) - .collect(Collectors.toList()) - ); - // Generate the list of enumerations - return enumerations.stream() - .collect(Collectors.toMap(Enumeration::getEnumerationClassName, Enumeration::generateUnit)); - } - - @Override - public void visit(final PackageDeclaration packageDeclaration, final Map arg) { - super.visit(packageDeclaration, arg); - this.collectedPackage = packageDeclaration; - } - - - @Override - public void visit(final FieldDeclaration declaration, final Map arg) { - super.visit(declaration, arg); - - Comment declarationComment = declaration.getComment(); - if (declarationComment != null) { - Matcher matcher = ENUM_REGEX.matcher(declarationComment.toString()); - if (matcher.find()) { - if (declaration.getParentNode() instanceof ClassOrInterfaceDeclaration) { - ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) declaration - .getParentNode(); - - /* Defines the name of the enumeration generated */ - String name = matcher.group(1) + matcher.group(2) + enumNamePostFix; - - nameValuesMap.putIfAbsent(name, new ArrayList()); - nameValuesMap.get(name).addAll(declaration.getVariables()); - if (!clazz.getName().equals(baseClassName)) { - nameParentClassMap.put(name, clazz.getName()); - } - } else { - throw new Error("Parent of Enum declaration was not a ClassOrInterfaceDeclaration"); - } - } - } - } - - -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/OpenCVMethodVisitor.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/OpenCVMethodVisitor.java deleted file mode 100644 index 25b52a6888..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/OpenCVMethodVisitor.java +++ /dev/null @@ -1,46 +0,0 @@ -package edu.wpi.gripgenerator; - -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.visitor.VoidVisitorAdapter; - -import edu.wpi.gripgenerator.settings.DefinedMethod; -import edu.wpi.gripgenerator.settings.DefinedMethodCollection; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -public class OpenCVMethodVisitor extends VoidVisitorAdapter> { - private final List collections; - - public OpenCVMethodVisitor(DefinedMethodCollection... collections) { - this.collections = Arrays.asList(collections); - } - - private DefinedMethodCollection getDefinedCollectionMatchingParentOf(MethodDeclaration - declaration) { - for (DefinedMethodCollection collection : collections) { - if (collection.matchesParent(declaration)) { - return collection; - } - } - return null; - } - - private DefinedMethod getDefinedMethodMatching(MethodDeclaration declaration) { - DefinedMethodCollection collection = getDefinedCollectionMatchingParentOf(declaration); - if (collection != null) { - return collection.getMethodMatching(declaration); - } - return null; - } - - - public void visit(MethodDeclaration declaration, final Map args) { - DefinedMethod method = getDefinedMethodMatching(declaration); - if (method != null) { - method.assignIfBestMatch(declaration); - } - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/DefaultValue.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/DefaultValue.java deleted file mode 100644 index 69e9b39e1d..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/DefaultValue.java +++ /dev/null @@ -1,71 +0,0 @@ -package edu.wpi.gripgenerator.defaults; - - -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.type.Type; - -import java.util.Optional; -import java.util.Set; - -public abstract class DefaultValue { - protected final String packageName; - protected final String name; - - public DefaultValue(String packageName, String name) { - this.packageName = packageName; - this.name = name; - } - - public String getName() { - return name; - } - - /** - * Default values that this default value can be mapped to - */ - protected abstract Set getDefaultValues(); - - /** - * The import declaration that is required for this default value to work. - * - * @return The import declaration or null if none is needed - */ - public ImportDeclaration getImportDeclaration() { - return new ImportDeclaration(new NameExpr(packageName + "." + this.getName()), false, false); - } - - public String getSocketBuilderInitalValueMethodNameToUse() { - return "initialValueSupplier"; - } - - /** - * Gets the expression for the given default value - * - * @param defaultValue The helper default value to define the exact expression to return. For - * example, with enums this will be the enumeration declaration name that is - * the default. - * @return The expression accessing the default value. - */ - public abstract Expression getDefaultValue(String defaultValue); - - /** - * Returns the domain values for this default value. - * - * @return The expression defining the given domain. - */ - public Optional getDomainValue() { - return Optional.empty(); - } - - /** - * @return - */ - public abstract String getViewType(); - - /** - * Gets the type of this default value - */ - public abstract Optional getType(); -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/DefaultValueCollector.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/DefaultValueCollector.java deleted file mode 100644 index 4af8f881ba..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/DefaultValueCollector.java +++ /dev/null @@ -1,78 +0,0 @@ -package edu.wpi.gripgenerator.defaults; - - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class DefaultValueCollector { - private Map defaultValueMap = new HashMap(); - private Map defaultValueEnumNameMap = new HashMap<>(); - - /** - * @param enumDefault Adds the enumDefault to the collector - */ - public void add(EnumDefaultValue enumDefault) { - for (String value : enumDefault.getDefaultValues()) { - defaultValueMap.put(value, enumDefault); - } - defaultValueEnumNameMap.put(enumDefault.getName(), enumDefault); - } - - public void add(DefaultValue defaultValue) { - for (String value : defaultValue.getDefaultValues()) { - defaultValueMap.put(value, defaultValue); - } - } - - public void addAll(Collection enumDefaults) { - enumDefaults.forEach(this::add); - } - - /** - * Adds the given additional values to the enumeration. - * - * @param enumDefaultValue The enum default value to modify - * @param additionalValues The additional values to add to the enum - */ - public void addToEnum(EnumDefaultValue enumDefaultValue, List additionalValues) { - assert defaultValueEnumNameMap.containsValue(enumDefaultValue) : "Enum did not exist in " + - "defaultValueEnumNameMap " + enumDefaultValue; - enumDefaultValue.getDefaultValues().addAll(additionalValues); - for (String value : additionalValues) { - defaultValueMap.put(value, enumDefaultValue); - } - } - - /** - * Get the given enumeration given its name - * - * @param name The name of the enum to retrieve. - * @return The enum that matches this name - */ - public EnumDefaultValue getEnum(String name) { - return defaultValueEnumNameMap.get(name); - } - - /** - * Checks if there is a default value for a given string key - * - * @param value The key to check for - * @return True if the default value exists - */ - public boolean hasDefaultValueFor(String value) { - return defaultValueMap.containsKey(value); - } - - /** - * Retrieves the stored default value for the given key string - * - * @param value The value key - * @return The DefaultValue that is relevant to this default value - */ - public DefaultValue getDefaultValueFor(String value) { - return defaultValueMap.get(value); - } - -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/EnumDefaultValue.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/EnumDefaultValue.java deleted file mode 100644 index 167368df22..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/EnumDefaultValue.java +++ /dev/null @@ -1,68 +0,0 @@ -package edu.wpi.gripgenerator.defaults; - - -import com.github.javaparser.ASTHelper; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.FieldAccessExpr; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.type.Type; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; - -/** - * Constructs a Default Value for an enumeration. - */ -public class EnumDefaultValue extends DefaultValue { - private final Set enumConstantNames; - - public EnumDefaultValue(String packageName, String name, String... enumConstantNames) { - this(packageName, name, new HashSet(Arrays.asList(enumConstantNames))); - } - - public EnumDefaultValue(String packageName, String name, Set enumConstantNames) { - super(packageName, name); - this.enumConstantNames = enumConstantNames; - } - - @Override - protected Set getDefaultValues() { - return enumConstantNames; - } - - @Override - public Expression getDefaultValue(String defaultValue) { - return new FieldAccessExpr( - new NameExpr(name), - defaultValue - ); - } - - @Override - public String getSocketBuilderInitalValueMethodNameToUse() { - return "initialValue"; - } - - @Override - public Optional getDomainValue() { - return Optional.of(new MethodCallExpr( - new NameExpr(name), - "values" - )); - } - - @Override - public String getViewType() { - return "SELECT"; - } - - @Override - public Optional getType() { - return Optional.of(ASTHelper.createReferenceType(this.name, 0)); - } - - -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/MethodDefaultValue.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/MethodDefaultValue.java deleted file mode 100644 index 123802c0af..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/MethodDefaultValue.java +++ /dev/null @@ -1,35 +0,0 @@ -package edu.wpi.gripgenerator.defaults; - -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.NullLiteralExpr; -import com.github.javaparser.ast.type.Type; - -import java.util.Optional; -import java.util.Set; - -public class MethodDefaultValue extends DefaultValue { - - public MethodDefaultValue(String packageName, String name) { - super(packageName, name); - } - - @Override - protected Set getDefaultValues() { - return null; - } - - @Override - public Expression getDefaultValue(String defaultValue) { - return new NullLiteralExpr(); - } - - @Override - public String getViewType() { - return "NONE"; - } - - @Override - public Optional getType() { - return Optional.empty(); - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/NullDefaultValue.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/NullDefaultValue.java deleted file mode 100644 index 5c84f27850..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/NullDefaultValue.java +++ /dev/null @@ -1,46 +0,0 @@ -package edu.wpi.gripgenerator.defaults; - -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.NullLiteralExpr; -import com.github.javaparser.ast.type.Type; - -import java.util.Optional; -import java.util.Set; - -public class NullDefaultValue extends DefaultValue { - - public NullDefaultValue() { - super("", "null"); - } - - @Override - public ImportDeclaration getImportDeclaration() { - return null; - } - - @Override - protected Set getDefaultValues() { - return null; - } - - @Override - public Expression getDefaultValue(String defaultValue) { - return new NullLiteralExpr(); - } - - @Override - public String getSocketBuilderInitalValueMethodNameToUse() { - return "initialValue"; - } - - @Override - public String getViewType() { - return "NONE"; - } - - @Override - public Optional getType() { - return Optional.empty(); - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/ObjectDefaultValue.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/ObjectDefaultValue.java deleted file mode 100644 index 5f51d58601..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/ObjectDefaultValue.java +++ /dev/null @@ -1,76 +0,0 @@ -package edu.wpi.gripgenerator.defaults; - -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.LambdaExpr; -import com.github.javaparser.ast.expr.MethodReferenceExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.expr.ObjectCreationExpr; -import com.github.javaparser.ast.stmt.ExpressionStmt; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.Type; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -public class ObjectDefaultValue extends DefaultValue { - private final ClassOrInterfaceType type; - private final List defaultValues; - - public ObjectDefaultValue(Type type) { - super("", type.toStringWithoutComments()); - this.type = new ClassOrInterfaceType(type.toStringWithoutComments()); - this.defaultValues = Collections.emptyList(); - } - - public ObjectDefaultValue(String type, String... defaultValues) { - super("", type); - this.type = new ClassOrInterfaceType(type); - this.defaultValues = Arrays.asList(defaultValues).stream().map(NameExpr::new).collect - (Collectors.toList()); - } - - @Override - public ImportDeclaration getImportDeclaration() { - return null; - } - - @Override - protected Set getDefaultValues() { - return null; - } - - @Override - public Expression getDefaultValue(String defaultValue) { - if (!this.defaultValues.isEmpty()) { - LambdaExpr provider = new LambdaExpr(); - provider.setBody( - new ExpressionStmt( - new ObjectCreationExpr(null, type, defaultValues) - ) - ); - provider.setParametersEnclosed(true); - return provider; - } else { - MethodReferenceExpr referenceExpr = new MethodReferenceExpr(); - referenceExpr.setScope(new NameExpr(type.getName())); - referenceExpr.setIdentifier("new"); - return referenceExpr; - } - } - - - @Override - public String getViewType() { - return "NONE"; - } - - @Override - public Optional getType() { - return Optional.of(type); - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/PrimitiveDefaultValue.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/PrimitiveDefaultValue.java deleted file mode 100644 index 92c591ec2d..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/defaults/PrimitiveDefaultValue.java +++ /dev/null @@ -1,150 +0,0 @@ -package edu.wpi.gripgenerator.defaults; - -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.expr.ArrayCreationExpr; -import com.github.javaparser.ast.expr.ArrayInitializerExpr; -import com.github.javaparser.ast.expr.BooleanLiteralExpr; -import com.github.javaparser.ast.expr.CharLiteralExpr; -import com.github.javaparser.ast.expr.DoubleLiteralExpr; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.IntegerLiteralExpr; -import com.github.javaparser.ast.type.PrimitiveType; -import com.github.javaparser.ast.type.Type; - -import java.util.Arrays; -import java.util.Optional; -import java.util.Set; - -/** - * Default value for a primitive constant. If the opencv method defines that it takes a primitive - * variable and the comment following defines the default is a primitive not an Enum Declaration - * then this is used. - */ -public class PrimitiveDefaultValue extends DefaultValue { - private PrimitiveType type; - private String viewValue; - private Expression domainValue; - private Optional defaultOverride = Optional.empty(); - - /** - * Allows you to provide a primitive default value with a - * - * @param type The Primitive type of this default value. - * @param defaultOverride Nullable, The default override to use instead of whatever the opencv - * function defines should be used as a default. - */ - public PrimitiveDefaultValue(PrimitiveType type, String defaultOverride) { - this(type); - this.defaultOverride = Optional.ofNullable(defaultOverride); - } - - public PrimitiveDefaultValue(PrimitiveType type) { - super("", type.getType().name()); - this.type = type; - switch (type.getType()) { - case Boolean: - this.viewValue = "CHECKBOX"; - this.domainValue = createDomainValueExpression( - new BooleanLiteralExpr(true), - new BooleanLiteralExpr(false) - ); - break; - case Int: - this.viewValue = "TEXT"; - this.domainValue = createDomainValueExpression( - new IntegerLiteralExpr("Integer.MIN_VALUE"), - new IntegerLiteralExpr("Integer.MAX_VALUE") - ); - break; - case Float: - this.viewValue = "TEXT"; - this.domainValue = createDomainValueExpression( - new DoubleLiteralExpr("-Float.MAX_VALUE"), - new DoubleLiteralExpr("Float.MAX_VALUE") - ); - break; - case Double: - this.viewValue = "TEXT"; - this.domainValue = createDomainValueExpression( - new DoubleLiteralExpr("-Double.MAX_VALUE"), - new DoubleLiteralExpr("Double.MAX_VALUE") - ); - break; - case Char: - this.viewValue = "TEXT"; - this.domainValue = createDomainValueExpression( - new CharLiteralExpr(Character.toString(Character.MIN_VALUE)), - new CharLiteralExpr(Character.toString(Character.MAX_VALUE)) - ); - break; - default: - throw new UnsupportedOperationException("Type " + type.getType() + " is not supported."); - } - } - - /** - * Creates a domain value expression given a list of expressions. - * - * @return The expression for the domain. - */ - private Expression createDomainValueExpression(Expression... expressions) { - return new ArrayCreationExpr(type.toBoxedType(), 1, - new ArrayInitializerExpr( - Arrays.asList(expressions) - ) - ); - } - - @Override - public ImportDeclaration getImportDeclaration() { - return null; - } - - @Override - protected Set getDefaultValues() { - return null; - } - - @Override - public String getSocketBuilderInitalValueMethodNameToUse() { - return "initialValue"; - } - - @Override - public Expression getDefaultValue(String defaultValue) { - if (this.defaultOverride.isPresent()) { - defaultValue = this.defaultOverride.get(); - } - switch (type.getType()) { - case Boolean: - return new BooleanLiteralExpr(Boolean.valueOf(defaultValue)); - case Int: - return new IntegerLiteralExpr(Integer.valueOf(defaultValue).toString()); - case Float: - return new DoubleLiteralExpr(Float.valueOf(defaultValue).toString()); - case Double: - return new DoubleLiteralExpr(Double.valueOf(defaultValue).toString()); - case Char: - assert defaultValue.length() == 1 : "Invalid default value: " + defaultValue + " for type" + - " char"; - return new CharLiteralExpr(defaultValue); - default: - throw new UnsupportedOperationException("Type " + type.getType() + " is not supported."); - } - } - - @Override - public Optional getDomainValue() { - return Optional.of(domainValue); - } - - @Override - public String getViewType() { - return viewValue; - } - - @Override - public Optional getType() { - return Optional.of(type); - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedMethod.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedMethod.java deleted file mode 100644 index 3fd909030b..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedMethod.java +++ /dev/null @@ -1,254 +0,0 @@ -package edu.wpi.gripgenerator.settings; - -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.body.Parameter; - -import edu.wpi.gripgenerator.defaults.DefaultValueCollector; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -/** - * Allows you to define a Method that will be collected as the library is parsed. This object is - * then used to store the method declaration that matches this method. If a better match is found - * later in the parsing then it is used. - */ -public final class DefinedMethod { - private final String methodName; - private final List paramTypes; - private final boolean isCompleteList; - private DefinedMethodCollection collectionOf; - private Optional description = Optional.empty(); - private Optional bestMatchMethod = Optional.empty(); - private boolean finalized = false; - - - /** - * Constructs the defined method. It is assumed that this is not the complete list of parameters. - * - * @param methodName the name of the method - * @param paramTypes the type of param to match. Case sensitive. - */ - public DefinedMethod(String methodName, String... paramTypes) { - this(methodName, false, paramTypes); - } - - /** - * Constructs the defined method. It is assumed that this is not the complete list of parameters. - * - * @param methodName The name of the method. - */ - public DefinedMethod(String methodName) { - this(methodName, false, new ArrayList()); - } - - /** - * Create a defined method - * - * @param methodName The name of the method - * @param isCompleteList true if this should match a method without any params. - */ - public DefinedMethod(String methodName, boolean isCompleteList) { - this(methodName, isCompleteList, new ArrayList()); - } - - /** - * @param methodName The name of the method - * @param isCompleteList true if this should match a method with only the params provided and no - * more. Otherwise will try to find one with these params and additional - * params. - * @param paramTypes The param types to match this method with. - */ - public DefinedMethod(String methodName, boolean isCompleteList, String... paramTypes) { - this(methodName, isCompleteList, Arrays.asList(paramTypes)); - } - - public DefinedMethod(String methodName, boolean isCompleteList, List paramTypes) { - this.methodName = methodName; - this.paramTypes = paramTypes.stream().map(DefinedParamType::new).collect(Collectors.toList()); - this.isCompleteList = isCompleteList; - } - - public DefinedMethod(String methodName, boolean isCompleteList, DefinedParamType... paramTypes) { - this.methodName = methodName; - this.paramTypes = new ArrayList(Arrays.asList(paramTypes)); - this.isCompleteList = isCompleteList; - } - - /** - * Set this DefinedMethod as part of a given collection - * - * @param collection The collection this method is a part of - */ - void setCollectionOf(DefinedMethodCollection collection) { - this.collectionOf = collection; - } - - public String getMethodName() { - return methodName; - } - - /** - * Adds a description to this method. - * - * @param description The description to use for this method. - * @return This. Allows for method chaining off of constructor. - */ - public DefinedMethod addDescription(String description) { - this.description = Optional.of(description); - return this; - } - - public String getDescription() { - if (this.description.isPresent()) { - return this.description.get(); - } else { - return ""; - } - } - - public String getParentObjectName() { - return collectionOf.getClassName(); - } - - /** - * Is this defined method a match to the params of another MethodDeclaration's params - * - * @return true if a match - */ - public boolean isMatch(List params) { - // Check if the last param was a wildcard - if (this.isCompleteList && paramTypes.size() != params.size()) { - return false; - } else if (paramTypes.size() > params.size()) { - return false; - } - - for (int i = 0; i < paramTypes.size(); i++) { - if (!paramTypes.get(i).isMatch(params.get(i))) { - return false; - } - } - return true; - } - - /** - * Assigns this MethodDeclaration if it is a match to the params defined for this method. - * - * @param declaration The declaration to try to assign. - * @return False if assignment has failed. - */ - public boolean assignIfBestMatch(MethodDeclaration declaration) { - assert !finalized : "Assigning on a method that has already been finalized"; - if (!isMatch(declaration.getParameters())) { - //TODO: Perhaps this should throw an error? - return false; - } - if (this.bestMatchMethod.isPresent()) { - if (this.bestMatchMethod.get().getParameters().size() > declaration.getParameters().size()) { - // The method we have is already more complex - return false; - } - } - this.bestMatchMethod = Optional.of(declaration); - return true; - } - - /** - * Finalizes the Method This method takes the MethodDeclaration that has been assigned to it and - * constructs additional {@link DefinedParamType DefinedParamTypes} as needed - * - * @param collector The collector used to assign default values. - * @return true if finalization succeeds or has already been completed. - */ - protected boolean finalizeParamTypes(DefaultValueCollector collector) { - if (finalized) { - return true; - } - this.finalized = true; - if (bestMatchMethod.isPresent()) { - final MethodDeclaration declaration = bestMatchMethod.get(); - - // Iterate over the chosen methods parameters - for (int i = 0; i < declaration.getParameters().size(); i++) { - Parameter param = declaration.getParameters().get(i); - DefinedParamType definedParamType; - assert i < paramTypes.size() : "The size of the params list was less than than the index." + - " Invalid state"; - - if (i == paramTypes.size()) { // Create the defined param for this param because it - // wasn't defined - definedParamType = new DefinedParamType(param.getType().toString()); - paramTypes.add(definedParamType); - } else { // Otherwise grab the predefined one. - definedParamType = paramTypes.get(i); - } - /* - * Sets the defined params direction given the mapping provided to the collector - * in the File Parser. - */ - collectionOf - .getDefaultDirection(param.getId().getName()) - .ifPresent(definedParamType::trySetDirection); - - definedParamType.setParamAs(param); - - String defaultValue = definedParamType.getLiteralDefaultValue(); - if (defaultValue != null && collector.hasDefaultValueFor(defaultValue)) { - definedParamType.setDefaultValue(collector.getDefaultValueFor(defaultValue)); - } - - if (collectionOf.shouldIgnore(param.getId().getName())) { - definedParamType.setIgnored(); - } - } - return this.finalized; - } else { - throw new IllegalStateException("No method was found that matched this method " + - "definition " + toSimpleString()); - } - } - - /** - * Gets the imports required for this Defined Method to compile - * - * @return The list of required imports. - */ - public List getImports() { - return paramTypes.stream().map(p -> p.getImport()).filter(i -> i != null).collect - (Collectors.toList()); - } - - /** - * Gets the finalized list of param types. - * - * @param collector The collector to use - * @return The defined param types. - */ - public List getFinalizedParamTypes(DefaultValueCollector collector) { - if (!this.finalizeParamTypes(collector)) { - return null; - } - return this.paramTypes; - } - - public String toSimpleString() { - return String.format( - "DefinedMethod{methodName='%s', paramTypes=%s, isCompleteList=%s, collectionOf=%s, " + - "description=%s}", - methodName, - paramTypes, - isCompleteList, - collectionOf, - description - ); - } - - public String methodToString() { - return this.bestMatchMethod.get().toString(); - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedMethodCollection.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedMethodCollection.java deleted file mode 100644 index 86478d76b1..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedMethodCollection.java +++ /dev/null @@ -1,111 +0,0 @@ -package edu.wpi.gripgenerator.settings; - -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; - -import edu.wpi.gripgenerator.defaults.DefaultValueCollector; -import edu.wpi.gripgenerator.templates.Operation; -import edu.wpi.gripgenerator.templates.OperationList; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -public class DefinedMethodCollection { - private final String className; - private final Map definedMethodMap; - private final Map> directionDefault = new - HashMap<>(); - private final Set ignoreDefaults = new HashSet<>(); - - public DefinedMethodCollection(String className, DefinedMethod... methodList) { - this(className, Arrays.asList(methodList)); - } - - public DefinedMethodCollection(String className, List methodList) { - this.className = className; - methodList.forEach(m -> m.setCollectionOf(this)); - // Basically turn the list into a map with the method name as the key - this.definedMethodMap = methodList.stream().collect(Collectors.toMap - (DefinedMethod::getMethodName, t -> t)); - } - - public DefinedMethodCollection setDirectionDefaults(DefinedParamType.DefinedParamDirection - direction, String... paramNames) { - directionDefault.putIfAbsent(direction, new HashSet<>()); - directionDefault.get(direction).addAll(Arrays.asList(paramNames)); - return this; - } - - public DefinedMethodCollection setIgnoreDefaults(String... ignoreDefaults) { - this.ignoreDefaults.addAll(Arrays.asList(ignoreDefaults)); - return this; - } - - public boolean matchesParent(MethodDeclaration declaration) { - Node parent = declaration.getParentNode(); - if (parent instanceof ClassOrInterfaceDeclaration) { - return ((ClassOrInterfaceDeclaration) parent).getName().equals(this.className); - } - return false; - } - - public String getClassName() { - return className; - } - - /** - * Gets the default direction for a given param's Variable Identifier - * - * @param check The Variable identifier to check - * @return The direction this has been mapped to - */ - public Optional getDefaultDirection(String check) { - for (DefinedParamType.DefinedParamDirection direction : DefinedParamType - .DefinedParamDirection.values()) { - if (directionDefault.getOrDefault(direction, Collections.EMPTY_SET).contains(check)) { - return Optional.of(direction); - } - } - return Optional.empty(); - } - - public boolean shouldIgnore(String check) { - return ignoreDefaults.contains(check); - } - - - /** - * Tries to find a method matching the given MethodDeclaraion - * - * @param declaration The declaration to match against - * @return The DefinedMethod that matches or null if none exists. - */ - public DefinedMethod getMethodMatching(MethodDeclaration declaration) { - DefinedMethod possibleMatch = definedMethodMap.get(declaration.getName()); - if (possibleMatch != null && possibleMatch.isMatch(declaration.getParameters())) { - return possibleMatch; - } else { - return null; - } - } - - public void generateCompilationUnits(DefaultValueCollector collector, Map compilationUnits, OperationList operations) { - for (DefinedMethod method : definedMethodMap.values()) { - Operation thisOperation = new Operation(collector, method, className); - operations.addOperation(thisOperation); - CompilationUnit cu = thisOperation.getDeclaration(); - //System.out.println(cu); - compilationUnits.put(thisOperation.getOperationClassName(), cu); - } - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedParamType.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedParamType.java deleted file mode 100644 index 0d1d70dc0b..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/settings/DefinedParamType.java +++ /dev/null @@ -1,254 +0,0 @@ -package edu.wpi.gripgenerator.settings; - - -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.FieldAccessExpr; -import com.github.javaparser.ast.expr.NormalAnnotationExpr; -import com.github.javaparser.ast.type.PrimitiveType; -import com.github.javaparser.ast.type.Type; - -import edu.wpi.gripgenerator.defaults.DefaultValue; -import edu.wpi.gripgenerator.defaults.EnumDefaultValue; -import edu.wpi.gripgenerator.defaults.NullDefaultValue; -import edu.wpi.gripgenerator.defaults.ObjectDefaultValue; -import edu.wpi.gripgenerator.defaults.PrimitiveDefaultValue; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import static com.github.javaparser.ASTHelper.createNameExpr; -import static com.github.javaparser.ASTHelper.createReferenceType; -import static com.google.common.base.Preconditions.checkNotNull; - -public class DefinedParamType { - private final String type; - private final Pattern constructorCallExpression = Pattern.compile(".*cv?:?:([A-Z][a-zA-Z_]*)\\(" + - ".*\\)"); - private final Pattern methodCallExpression = Pattern.compile(".*cv?:?:([a-z][a-zA-Z_]*)\\(.*\\)"); - private Optional direction; - private Optional parameter = Optional.empty(); - private Optional defaultValue = Optional.empty(); - private Optional literalDefaultValue = Optional.empty(); - private boolean shoudIgnore = false; - - /** - * Defines a Param type that a method must match. Defaults the value to being an input. - * - * @param type the type of param that this should match - */ - public DefinedParamType(String type) { - this.type = type; - this.direction = Optional.empty(); - } - - /** - * Used for testing only. - */ - public DefinedParamType(String type, Parameter param) { - this(type); - parameter = Optional.of(param); - } - - /** - * @param type The type of param that this should match - * @param direction The direction of the param. Will override whatever defaults are set by the - * method collector - */ - public DefinedParamType(String type, DefinedParamDirection direction) { - this(type); - this.direction = Optional.ofNullable(direction); - } - - public static List fromStrings(List params) { - List paramStates = new ArrayList<>(); - for (String param : params) { - paramStates.add(new DefinedParamType(param)); - } - return paramStates; - } - - public Optional getDefaultValue() { - return defaultValue; - } - - public DefinedParamType setDefaultValue(DefaultValue defaultValue) { - checkNotNull(defaultValue); - //System.out.println("Setting default value " + defaultValue.getName()); - this.defaultValue = Optional.of(defaultValue); - return this; - } - - void setParamAs(Parameter param) { - checkNotNull(param); - this.parameter = Optional.of(param); - Pattern defaultPrimitive = Pattern.compile(".*=([\\-a-zA-Z0-9_\\.]*.*)"); - Pattern defaultEnumPrimitive = Pattern.compile(".*=(?:cv::)([\\-a-zA-Z0-9_\\.]*.*)"); - - if (param.getComment() != null && param.getType() instanceof PrimitiveType) { - //System.out.println("Checking match"); - Matcher matchesPrimitive = defaultPrimitive.matcher(param.getComment().getContent()); - Matcher matchesEnumPrimitive = defaultEnumPrimitive.matcher(param.getComment().getContent()); - //if (matchesPrimitive.find()) System.out.println("Primitive Matcher: " + matchesPrimitive - // .group()); - //if (matchesEnumPrimitive.find()) System.out.println("Enum Matcher: " + - // matchesEnumPrimitive.group(1)); - if (matchesEnumPrimitive.matches()) { - //System.out.println("Matching Enum: " + matchesEnumPrimitive.group(1)); - this.literalDefaultValue = Optional.of(matchesEnumPrimitive.group(1)); - //The default value should be assigned - } else if (matchesPrimitive.matches()) { - //System.out.println("Matching Primitive: " + matchesPrimitive.group(1)); - this.literalDefaultValue = Optional.of(matchesPrimitive.group(1)); - this.defaultValue = Optional.of(new PrimitiveDefaultValue((PrimitiveType) param.getType())); - } - } else if (param.getType() instanceof PrimitiveType) { - this.literalDefaultValue = Optional.of(this.literalDefaultValue.orElse("0")); - this.defaultValue = Optional.of(this.defaultValue.orElse(new PrimitiveDefaultValue( - (PrimitiveType) param.getType()))); - } else if (isOutput() || !listAnnotationsMatching().isEmpty()) { - this.defaultValue = Optional.of(this.defaultValue.orElse(new ObjectDefaultValue(param - .getType()))); - } else { - this.defaultValue = Optional.of(this.defaultValue.orElse(new NullDefaultValue())); - } - //System.out.println(param.getType().getClass()); - } - - public boolean isMatch(Parameter param) { - return type.equals(param.getType().toStringWithoutComments()); - } - - private Type getRealType() { - if (parameter.isPresent()) { - return parameter.get().getType(); - } - return createReferenceType(type, 0); - } - - public Type getType() { - if (defaultValue.isPresent()) { - return defaultValue.get().getType().orElse(getRealType()); - } - return getRealType(); - } - - public Type getTypeBoxedIfPossible() { - return getType() instanceof PrimitiveType ? ((PrimitiveType) getType()).toBoxedType() : - getType(); - } - - private List listAnnotationsMatching() { - if (parameter.isPresent() && parameter.get().getAnnotations() != null) { - Parameter param = parameter.get(); - return param.getAnnotations().stream() - .filter(a -> (a.getName().getName().equals("ByVal") || a.getName().getName().equals - ("ByRef"))) - .filter(a -> a instanceof NormalAnnotationExpr) - .map(a -> (NormalAnnotationExpr) a) - .collect(Collectors.toList()); - } - return Collections.emptyList(); - } - - public String getLiteralDefaultValue() { - return this.literalDefaultValue.orElse(""); - } - - public DefinedParamType setLiteralDefaultValue(String literalDefaultValue) { - this.literalDefaultValue = Optional.of(literalDefaultValue); - return this; - } - - public ImportDeclaration getImport() { - if (defaultValue.isPresent()) { - return defaultValue.get().getImportDeclaration(); - } else { - return null; - } - } - - public boolean isInput() { - return getDirection().isInput(); - } - - public boolean isOutput() { - return getDirection().isOutput(); - } - - public boolean isIgnored() { - return this.shoudIgnore; - } - - /** - * Gets the direction of this param it hasn't been assigned prior to calling this method then it - * is assigned by this call. - * - * @return The direction of this param. - */ - public DefinedParamDirection getDirection() { - if (direction.isPresent()) { - return direction.get(); - } - direction = Optional.of(DefinedParamDirection.INPUT); - return direction.get(); - } - - public String getName() { - return parameter.get().getId().getName(); - } - - /** - * Gets the literal expression that should be passed to the opencv method. This allows for any - * last type conversions or enumerations field accessing - * - * @return The Expression to pass to the opencv method. - */ - public Expression getLiteralExpression() { - if (defaultValue.isPresent() && defaultValue.get() instanceof EnumDefaultValue) { - return new FieldAccessExpr(createNameExpr(getName()), "value"); - } else if (isIgnored()) { - return getDefaultValue() - .orElseThrow(() -> new IllegalStateException("Default Value was not present for ignored" + - " param " + this.toString())) - .getDefaultValue(this.literalDefaultValue - .orElseThrow(() -> new IllegalStateException("Literal Default Value was not defined" + - " for ignored param " + this.toString()))); - } else { - return createNameExpr(getName()); - } - } - - /** - * Makes this param an output if it hasn't been explicitly set in the constructor - */ - void trySetDirection(DefinedParamDirection direction) { - this.direction = Optional.of(this.direction.orElseGet(() -> direction)); - } - - public void setIgnored() { - this.shoudIgnore = true; - } - - public enum DefinedParamDirection { - INPUT, - OUTPUT, - INPUT_AND_OUTPUT; - - public boolean isInput() { - return this.equals(INPUT) || this.equals(INPUT_AND_OUTPUT); - } - - public boolean isOutput() { - return this.equals(OUTPUT) || this.equals(INPUT_AND_OUTPUT); - } - - } - -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/Enumeration.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/Enumeration.java deleted file mode 100644 index 65d548752f..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/Enumeration.java +++ /dev/null @@ -1,186 +0,0 @@ -package edu.wpi.gripgenerator.templates; - -import com.github.javaparser.ASTHelper; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.PackageDeclaration; -import com.github.javaparser.ast.body.ConstructorDeclaration; -import com.github.javaparser.ast.body.EnumConstantDeclaration; -import com.github.javaparser.ast.body.EnumDeclaration; -import com.github.javaparser.ast.body.FieldDeclaration; -import com.github.javaparser.ast.body.ModifierSet; -import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.ast.body.VariableDeclaratorId; -import com.github.javaparser.ast.comments.JavadocComment; -import com.github.javaparser.ast.expr.AssignExpr; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.FieldAccessExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.expr.ThisExpr; -import com.github.javaparser.ast.stmt.BlockStmt; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -public class Enumeration { - private final String importExpression; - private final String baseClassName; - private final Optional parentClassName; - private final String name; - private final List declaratorList; - - public Enumeration(String name, PackageDeclaration packageDeclaration, String baseClassName, - String parentClassName, List declaratorList) { - this.name = name; - this.importExpression = packageDeclaration.getName().toStringWithoutComments() + "."; - this.baseClassName = baseClassName; - this.parentClassName = Optional.ofNullable(parentClassName); - this.declaratorList = declaratorList; - } - - /** - * Gets the class name of the enumeration. - * - * @return This should be used as the file name and will also be the name of the enumeration - */ - public String getEnumerationClassName() { - return name; - } - - public PackageDeclaration getPackageDeclaration() { - return new PackageDeclaration(new NameExpr("edu.wpi.grip.generated." + baseClassName + "" + - ".enumeration")); - } - - /** - * @return The imports for this enumeration - */ - private List generateImports() { - return Collections.singletonList( - new ImportDeclaration(ASTHelper.createNameExpr(importExpression + baseClassName), false, - false) - ); - } - - /** - * Generates the contents of the constructor. - * - * @param valueString The string representing the field that this will be assigned to - * @return The constructor block - */ - private BlockStmt getDefaultConstructorBlockStatement(String valueString) { - BlockStmt block = new BlockStmt(); - AssignExpr assignment = new AssignExpr(new FieldAccessExpr(new ThisExpr(), valueString), new - NameExpr(valueString), AssignExpr.Operator.assign); - ASTHelper.addStmt(block, assignment); - return block; - } - - /** - * Uses the VariableDeclarator from the original source code to generate an equivalent constant in - * the enumeration - * - * @param var The variable from the source declaration. - * @return The generated enum constant - */ - private EnumConstantDeclaration generateEnumConstant(VariableDeclarator var) { - // Create the constant - final NameExpr baseClass = new NameExpr(baseClassName); - final Expression parentAccessor; - // If there is a parent class for this enumeration declaration - if (parentClassName.isPresent()) { - // Then we need to make the access statement longer - parentAccessor = new FieldAccessExpr( - baseClass, - parentClassName.get() - ); - } else { - parentAccessor = baseClass; - } - - // Generate the constant - EnumConstantDeclaration enumConstant = new EnumConstantDeclaration( - null, - var.getId().getName(), - Collections.singletonList( - new FieldAccessExpr(parentAccessor, var.getId().getName()) - ), - null - ); - - // Add the javadoc comment but only if the original had a javadoc comment. - if (var.hasComment() && var.getComment() instanceof JavadocComment) { - enumConstant.setJavaDoc(new JavadocComment(var.getComment().getContent())); - } - return enumConstant; - } - - /** - * Generates all of the enumeration constants. - * - * @return The list of all of the enum constants - */ - private List generateEnumConstantDeclarations() { - return declaratorList - .stream() - .map(v -> generateEnumConstant(v)) - .collect(Collectors.toList()); - } - - /** - * Generates the enumeration class body. - * - * @return The generated Enumeration - */ - private EnumDeclaration generateEnum() { - final String valueString = "value"; - // Create new Enum - EnumDeclaration newEnum = new EnumDeclaration( - ModifierSet.PUBLIC, - null, - getEnumerationClassName(), - null, - generateEnumConstantDeclarations(), - null - ); - // Add a field value for the public final value variable - FieldDeclaration valueField = new FieldDeclaration( - ModifierSet.addModifier(ModifierSet.FINAL, ModifierSet.PUBLIC), - ASTHelper.INT_TYPE, - Collections.singletonList( - new VariableDeclarator(new VariableDeclaratorId(valueString)) - )); - ASTHelper.addMember(newEnum, valueField); - - // Add the constructor to take the opencv value - ConstructorDeclaration enumConstructor = new ConstructorDeclaration( - 0, - null, - null, - name, - Collections.singletonList( - ASTHelper.createParameter(ASTHelper.INT_TYPE, valueString) - ), - null, - getDefaultConstructorBlockStatement(valueString) - ); - ASTHelper.addMember(newEnum, enumConstructor); - return newEnum; - } - - /** - * Kicks off the generation of the enumeration - * - * @return The fully compiled CompilationUnit - */ - public CompilationUnit generateUnit() { - // Generate new compilation unit - return new CompilationUnit( - getPackageDeclaration(), - generateImports(), - Collections.singletonList(generateEnum()) - ); - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/Operation.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/Operation.java deleted file mode 100644 index e930bb7977..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/Operation.java +++ /dev/null @@ -1,356 +0,0 @@ -package edu.wpi.gripgenerator.templates; - -import com.github.javaparser.ASTHelper; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.PackageDeclaration; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.body.ModifierSet; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.ast.body.VariableDeclaratorId; -import com.github.javaparser.ast.comments.BlockComment; -import com.github.javaparser.ast.comments.JavadocComment; -import com.github.javaparser.ast.expr.AnnotationExpr; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.MarkerAnnotationExpr; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr; -import com.github.javaparser.ast.expr.StringLiteralExpr; -import com.github.javaparser.ast.expr.VariableDeclarationExpr; -import com.github.javaparser.ast.stmt.BlockStmt; -import com.github.javaparser.ast.stmt.ExpressionStmt; -import com.github.javaparser.ast.stmt.ForeachStmt; -import com.github.javaparser.ast.stmt.ReturnStmt; -import com.github.javaparser.ast.stmt.Statement; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.VoidType; -import com.google.common.base.Ascii; -import com.google.common.base.CaseFormat; -import com.google.common.collect.Sets; - -import edu.wpi.gripgenerator.defaults.DefaultValueCollector; -import edu.wpi.gripgenerator.settings.DefinedMethod; -import edu.wpi.gripgenerator.settings.DefinedParamType; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import static com.github.javaparser.ASTHelper.createReferenceType; - -public class Operation { - private static final ImportDeclaration OPERATION_IMPORT = new ImportDeclaration(new NameExpr - ("edu.wpi.grip.core.operations.opencv.CVOperation"), false, false); - private static final ImportDeclaration SOCKETS_IMPORT = new ImportDeclaration(new NameExpr("edu" + - ".wpi.grip.core.sockets"), false, true); - private static final ImportDeclaration EVENT_BUS_IMPORT = new ImportDeclaration(new NameExpr - ("com.google.common.eventbus.EventBus"), false, false); - private static final ImportDeclaration CV_CORE_IMPORT = new ImportDeclaration(new NameExpr("org" + - ".bytedeco.javacpp.opencv_core"), true, true); - private static final ClassOrInterfaceType iOperation = new ClassOrInterfaceType("CVOperation"); - private static final AnnotationExpr OVERRIDE_ANNOTATION = new MarkerAnnotationExpr(new NameExpr - ("Override")); - private static final AnnotationExpr SUPPRESS_ANNOTATION = new SingleMemberAnnotationExpr(new - NameExpr("SuppressWarnings"), new StringLiteralExpr("unchecked")); - private final DefinedMethod definedMethod; - private final PackageDeclaration packageDec; - private final SocketHintDeclarationCollection socketHintDeclarationCollection; - private final JavadocComment javadocComment; - private final List operationParams; - - /** - * Constructs an Operation - * - * @param collector The collection of default values. - * @param definedMethod The method that this operation is wrapping - * @param className The name of the class being generated - */ - public Operation(DefaultValueCollector collector, DefinedMethod definedMethod, String className) { - this.definedMethod = definedMethod; - this.packageDec = new PackageDeclaration(new NameExpr("edu.wpi.grip.generated." + className)); - this.operationParams = this.definedMethod.getFinalizedParamTypes(collector); - this.socketHintDeclarationCollection = new SocketHintDeclarationCollection(collector, this - .operationParams); - this.javadocComment = new JavadocComment(" Operation to call " + - "{@link " + className + "#" + definedMethod.getMethodName() + "} "); - - } - - /** - * Gets the CamelCase formatted name version of the class name. - * - * @return The name to be used as the Class and file name. - */ - public String getOperationClassName() { - final String name = definedMethod.getMethodName(); - final CaseFormat format; - if (name.contains("_")) { - format = CaseFormat.LOWER_UNDERSCORE; - } else if (Ascii.isLowerCase(name.charAt(0))) { - format = CaseFormat.LOWER_CAMEL; - } else if (Ascii.isUpperCase(name.charAt(0))) { - format = CaseFormat.UPPER_CAMEL; - } else { - throw new UnsupportedOperationException("Can not convert class name for " + name); - } - return format.to(CaseFormat.UPPER_CAMEL, definedMethod.getMethodName()); - } - - private List getAdditionalImports() { - List imports = new ArrayList(Collections.singletonList(new - ImportDeclaration(new NameExpr("org.bytedeco.javacpp." + definedMethod - .getParentObjectName()), false, false))); - imports.addAll(this.definedMethod.getImports()); - return imports; - } - - /** - * Creates the Name method - */ - private MethodDeclaration getNameMethod() { - MethodDeclaration getName = new MethodDeclaration( - ModifierSet.PUBLIC, - Collections.singletonList(OVERRIDE_ANNOTATION), - null, - createReferenceType("String", 0), - "getName", - null, 0, - null, - null - ); - BlockStmt methodBody = new BlockStmt( - Collections.singletonList(new ReturnStmt( - new StringLiteralExpr("CV " + definedMethod.getMethodName()))) - ); - getName.setBody(methodBody); - return getName; - } - - /** - * Creates the description method - */ - private MethodDeclaration getDescriptionMethod() { - MethodDeclaration getDescription = new MethodDeclaration( - ModifierSet.PUBLIC, - Collections.singletonList(OVERRIDE_ANNOTATION), - null, - createReferenceType("String", 0), - "getDescription", - null, 0, - null, - null - ); - BlockStmt methodBody = new BlockStmt( - Collections.singletonList(new ReturnStmt( - new StringLiteralExpr(this.definedMethod.getDescription()))) - ); - getDescription.setBody(methodBody); - return getDescription; - } - - private MethodDeclaration getCategoryMethod() { - MethodDeclaration getCategory = new MethodDeclaration( - ModifierSet.PUBLIC, - Collections.singletonList(OVERRIDE_ANNOTATION), - null, - createReferenceType("Category", 0), - "getCategory", - null, 0, - null, - null - ); - getCategory.setBody(new BlockStmt(Collections.singletonList(new ReturnStmt(new NameExpr - ("Category.OPENCV"))))); - return getCategory; - } - - /** - * Creates the method that returns the input socket of this operation. - * - * @return The method declaration. - */ - private MethodDeclaration getCreateInputSocketsMethod() { - return new MethodDeclaration( - ModifierSet.PUBLIC, - Arrays.asList(OVERRIDE_ANNOTATION, SUPPRESS_ANNOTATION), - null, - SocketHintDeclarationCollection.getSocketReturnParam("InputSocket"), - "createInputSockets", - Collections.singletonList( - new Parameter(createReferenceType("EventBus", 0), new VariableDeclaratorId("eventBus")) - ), - 0, - null, - socketHintDeclarationCollection.getInputSocketBody() - ); - } - - /** - * Creates the method that returns the output sockets of this operation. - * - * @return The method declaration. - */ - private MethodDeclaration getCreateOutputSocketsMethod() { - return new MethodDeclaration( - ModifierSet.PUBLIC, - Arrays.asList(OVERRIDE_ANNOTATION, SUPPRESS_ANNOTATION), - null, - SocketHintDeclarationCollection.getSocketReturnParam("OutputSocket"), - "createOutputSockets", - Collections.singletonList( - new Parameter(createReferenceType("EventBus", 0), new VariableDeclaratorId("eventBus")) - ), - 0, - null, - socketHintDeclarationCollection.getOutputSocketBody() - ); - } - - - private Expression getFunctionCallExpression() { - return new MethodCallExpr( - new NameExpr(definedMethod.getParentObjectName()), - definedMethod.getMethodName(), - operationParams.stream().map(DefinedParamType::getLiteralExpression).collect - (Collectors.toList()) - ); - } - - /** - * Generates the perform function - * - * @param inputParamId The name of the variable for the input to the function - * @param outputParamId The name of the variable for the output to the function - * @return The list of statements that are performed inside of the perform function. - */ - private List getPerformExpressionList(String inputParamId, String outputParamId) { - assert !inputParamId.equals(outputParamId) : "The input and output param can not be the same"; - List expressionList = socketHintDeclarationCollection.getSocketAssignments - (inputParamId, outputParamId); - List performStatement = expressionList.stream().map(ExpressionStmt::new).collect - (Collectors.toList()); - final String exceptionVariable = "e"; - final String outputSocketForEachVariableId = "outputSocket"; - - performStatement.addAll( - Arrays.asList( - /* Make the operation function call */ - new ExpressionStmt( - getFunctionCallExpression() - ), - /* - * Afterwards iterate over all of the output sockets and call setValue using the - * value - * stored. - */ - new ForeachStmt( - new VariableDeclarationExpr( - 0, - ASTHelper.createReferenceType("OutputSocket", 0), - Collections.singletonList( - new VariableDeclarator( - new VariableDeclaratorId(outputSocketForEachVariableId) - ) - ) - ), - new NameExpr(outputParamId), - new BlockStmt( - Collections.singletonList( - new ExpressionStmt( - new MethodCallExpr( - new NameExpr(outputSocketForEachVariableId), - "setValueOptional", - Collections.singletonList( - new MethodCallExpr( - new NameExpr(outputSocketForEachVariableId), - "getValue" - ) - ) - ) - ) - ) - ) - ) - ) - ); - - - return performStatement; - } - - private MethodDeclaration getPerformMethod() { - String inputParamId = "inputs"; - String outputParamId = "outputs"; - return new MethodDeclaration( - ModifierSet.PUBLIC, - Arrays.asList(OVERRIDE_ANNOTATION), - null, - new VoidType(), - "perform", - Arrays.asList( - new Parameter(SocketHintDeclarationCollection.getSocketReturnParam("InputSocket"), - new VariableDeclaratorId(inputParamId)), - new Parameter(SocketHintDeclarationCollection.getSocketReturnParam("OutputSocket"), - new VariableDeclaratorId(outputParamId)) - ), - 0, - null, - new BlockStmt( - getPerformExpressionList(inputParamId, outputParamId) - ) - ); - } - - /** - * Generates the class definition for the Operation - */ - private ClassOrInterfaceDeclaration getClassDeclaration() { - ClassOrInterfaceDeclaration operation = new ClassOrInterfaceDeclaration(ModifierSet.PUBLIC, - false, getOperationClassName()); - operation.setImplements(Collections.singletonList(iOperation)); - operation.setJavaDoc(javadocComment); - operation.setComment(new BlockComment( - " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" - + " * ===== THIS CODE HAS BEEN DYNAMICALLY GENERATED! DO NOT MODIFY! ==== *\n" - + " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ")); - operation.setMembers(socketHintDeclarationCollection - .getAllSocketHints() - .stream() - .map(SocketHintDeclaration::getDeclaration) - .filter(declaration -> declaration != null) - .collect(Collectors.toList())); - ASTHelper.addMember(operation, getNameMethod()); - ASTHelper.addMember(operation, getDescriptionMethod()); - ASTHelper.addMember(operation, getCategoryMethod()); - ASTHelper.addMember(operation, getCreateInputSocketsMethod()); - ASTHelper.addMember(operation, getCreateOutputSocketsMethod()); - ASTHelper.addMember(operation, getPerformMethod()); - return operation; - } - - /** - * Creates the operation declaration - * - * @return The operation declaration ready to be turned into a file. - */ - public CompilationUnit getDeclaration() { - Set importList = Sets.newHashSet( - OPERATION_IMPORT, - CV_CORE_IMPORT, - SOCKETS_IMPORT, - EVENT_BUS_IMPORT - ); - importList.addAll(getAdditionalImports()); - return new CompilationUnit( - packageDec, - new ArrayList<>(importList), - Collections.singletonList(getClassDeclaration()) - ); - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/OperationList.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/OperationList.java deleted file mode 100644 index 25fd5a323b..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/OperationList.java +++ /dev/null @@ -1,112 +0,0 @@ -package edu.wpi.gripgenerator.templates; - - -import com.github.javaparser.ASTHelper; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.PackageDeclaration; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.body.ModifierSet; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.expr.ObjectCreationExpr; -import com.github.javaparser.ast.stmt.BlockStmt; -import com.github.javaparser.ast.stmt.ExpressionStmt; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.VoidType; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -/** - * The template for the Operation List. This list contains all of the operations that have been - * generated by the generator. - */ -public class OperationList { - private static final String className = "CVOperations"; - private final PackageDeclaration packageDec = new PackageDeclaration(new NameExpr("edu.wpi.grip" + - ".generated")); - private final List imports; - private final List operations; - - /** - * Constructs the operation list - * - * @param imports Any additional imports required for this operation to compile. - */ - public OperationList(ImportDeclaration... imports) { - this.imports = new ArrayList(Arrays.asList(imports)); - this.imports.addAll(Arrays.asList( - new ImportDeclaration(new NameExpr("com.google.common.eventbus.EventBus"), false, false), - new ImportDeclaration(new NameExpr("edu.wpi.grip.core.events.OperationAddedEvent"), - false, false) - )); - this.operations = new ArrayList<>(); - } - - public String getClassName() { - return className; - } - - /** - * Adds an operation to the list of Operations to be used in the pipeline. - * - * @param operation An operation to add. - */ - public void addOperation(Operation operation) { - operations.add(operation); - } - - private ClassOrInterfaceDeclaration getClassDeclaration() { - final ClassOrInterfaceType eventBusType = new ClassOrInterfaceType("EventBus"); - final ClassOrInterfaceType eventType = new ClassOrInterfaceType("OperationAddedEvent"); - - // This method is how the generated code tells the rest of the application about all of the - // generated OpenCV - // operations. It sends an OperationAddedEvent with a new instance of every operation. - final MethodDeclaration addOperations = new MethodDeclaration(ModifierSet.PUBLIC | - ModifierSet.STATIC, - new VoidType(), "addOperations"); - - ASTHelper.addParameter(addOperations, ASTHelper.createParameter(eventBusType, "eventBus")); - - addOperations.setBody(new BlockStmt(this.operations.stream() - .sorted((o1, o2) -> o1.getOperationClassName().toLowerCase().compareToIgnoreCase(o2 - .getOperationClassName())) - .map(Operation::getOperationClassName) - .map(ClassOrInterfaceType::new) - // Create a new instance of each operation - .map(type -> new ObjectCreationExpr(null, type, null)) - // Create a new OperationAddedEvent for every operation - .map(expr -> new ObjectCreationExpr(null, eventType, Collections.singletonList(expr))) - // Post all of the events to the event bus - .map(expr -> new MethodCallExpr(new NameExpr("eventBus"), "post", Collections - .singletonList(expr))) - .map(ExpressionStmt::new) - .collect(Collectors.toList()))); - - final ClassOrInterfaceDeclaration cvoperations = new ClassOrInterfaceDeclaration(ModifierSet - .PUBLIC, false, - "CVOperations"); - cvoperations.setMembers(Collections.singletonList(addOperations)); - return cvoperations; - } - - /** - * Generates the CompilationUnit to print to a file. - * - * @return The CompilationUnit for this class. - */ - public CompilationUnit getDeclaration() { - return new CompilationUnit( - packageDec, - this.imports, - Arrays.asList(getClassDeclaration()) - ); - } - -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/SocketHintDeclaration.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/SocketHintDeclaration.java deleted file mode 100644 index 6fbbfa32b9..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/SocketHintDeclaration.java +++ /dev/null @@ -1,184 +0,0 @@ -package edu.wpi.gripgenerator.templates; - -import com.github.javaparser.ASTHelper; -import com.github.javaparser.ast.body.FieldDeclaration; -import com.github.javaparser.ast.body.ModifierSet; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.ast.body.VariableDeclaratorId; -import com.github.javaparser.ast.expr.ClassExpr; -import com.github.javaparser.ast.expr.FieldAccessExpr; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.expr.ObjectCreationExpr; -import com.github.javaparser.ast.expr.StringLiteralExpr; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.PrimitiveType; -import com.github.javaparser.ast.type.Type; - -import edu.wpi.gripgenerator.defaults.DefaultValueCollector; -import edu.wpi.gripgenerator.settings.DefinedParamType; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import static com.github.javaparser.ASTHelper.createReferenceType; - -/** - * Helps create SocketHint declarations. For example: SocketHintDeclaration testDeclaration = - * new SocketHintDeclaration("Mat", Arrays.asList("src1", "src2")); testDeclaration - * .getDeclaration().toString() will generate private final SocketHint<Mat> - * src1Hint = new SocketHint<Mat>("src1", Mat.class), src2Hint = new - * SocketHint<Mat>("src2", Mat.class); - */ -public class SocketHintDeclaration { - public static final String SOCKET_HINT_CLASS_NAME = "SocketHint"; - public static final String SOCKET_HINT_BUILDER_CLASS_NAME = "Builder"; - public static final String HINT_POSTFIX = "Hint"; - public static final String INPUT_POSTFIX = "Input"; - public static final String OUTPUT_POSTFIX = "Output"; - //End Statics - - private final Type genericType; - private final List paramTypes; - private final boolean isOutput; - private final DefaultValueCollector collector; - - /** - * USED ONLY IN TESTING! - */ - public SocketHintDeclaration(String genericTypeName, List hintNames, boolean isOutput) { - this(null, createReferenceType(genericTypeName, 0), hintNames, isOutput); - } - - public SocketHintDeclaration(DefaultValueCollector collector, Type genericType, List - hintNames, boolean isOutput) { - this.genericType = genericType; - this.paramTypes = hintNames.stream().map(n -> new DefinedParamType( - genericType.toStringWithoutComments(), - new Parameter(genericType, new VariableDeclaratorId(n))) - ).collect(Collectors.toList()); - this.isOutput = isOutput; - this.collector = collector; - } - - - public SocketHintDeclaration(DefaultValueCollector collector, Type genericType, - List paramTypes, DefinedParamType - .DefinedParamDirection state) { - /* Convert this to the 'boxed' type if this is a PrimitiveType */ - if (genericType instanceof PrimitiveType) { - if (((PrimitiveType) genericType).getType().equals(PrimitiveType.Primitive.Boolean)) { - this.genericType = ((PrimitiveType) genericType).getType().toBoxedType(); - } else { - this.genericType = ASTHelper.createReferenceType("Number", 0); - } - } else { - this.genericType = genericType; - } - this.paramTypes = paramTypes; - this.isOutput = state.isOutput(); - this.collector = collector; - } - - public boolean isOutput() { - return this.isOutput; - } - - private FieldAccessExpr getViewEnumElement(String value) { - return new FieldAccessExpr( - new NameExpr("SocketHint.View"), - value - ); - } - - /** - * Creates a socket hint declaration from the constructor. - * - * @return The field declaration - */ - public FieldDeclaration getDeclaration() { - final int modifiers = ModifierSet.addModifier(ModifierSet.FINAL, ModifierSet.PRIVATE); - - final ClassOrInterfaceType socketHintType = new ClassOrInterfaceType(SOCKET_HINT_CLASS_NAME); - socketHintType.setTypeArgs(Collections.singletonList(genericType)); - - final ClassOrInterfaceType socketHintBuilderType = new ClassOrInterfaceType(new - ClassOrInterfaceType(SOCKET_HINT_CLASS_NAME), SOCKET_HINT_BUILDER_CLASS_NAME); - - final List variableDeclarations = new ArrayList<>(); - for (DefinedParamType paramType : paramTypes) { - // Don't generate hint for ignored param - if (paramType.isIgnored()) { - continue; - } - - String hintName = paramType.getName(); - // The variableId - final String fullHintName = hintName - + (isOutput() ? OUTPUT_POSTFIX : INPUT_POSTFIX) - + HINT_POSTFIX; - // The name hint of the socket hint - final StringLiteralExpr stringLiteralExpr = new StringLiteralExpr(hintName); - - variableDeclarations.add( - new VariableDeclarator( - new VariableDeclaratorId(fullHintName), - // Create new instantiation of type socket hint type - socketHintBuilder(socketHintBuilderType, stringLiteralExpr, paramType) - ) - ); - } - if (variableDeclarations.isEmpty()) { - return null; - } - - return new FieldDeclaration(modifiers, socketHintType, variableDeclarations); - } - - private MethodCallExpr socketHintBuilder(ClassOrInterfaceType socketHintBuilderType, - StringLiteralExpr stringLiteralExpr, DefinedParamType - paramType) { - final ClassExpr classExpr = new ClassExpr(genericType); - - final MethodCallExpr[] builtMethod = {new MethodCallExpr( - // Constructor call - new ObjectCreationExpr(null, socketHintBuilderType, Collections.singletonList(classExpr)), - // Identifier method - "identifier", - Collections.singletonList(stringLiteralExpr) - )}; - - paramType.getDefaultValue().ifPresent(defaultValue -> { - - builtMethod[0] = new MethodCallExpr( - builtMethod[0], - defaultValue.getSocketBuilderInitalValueMethodNameToUse(), - Collections.singletonList(defaultValue.getDefaultValue(paramType.getLiteralDefaultValue - ())) - ); - - builtMethod[0] = new MethodCallExpr( - builtMethod[0], - "view", - Collections.singletonList(getViewEnumElement(defaultValue.getViewType())) - ); - - defaultValue.getDomainValue().ifPresent(domain -> { - builtMethod[0] = new MethodCallExpr( - builtMethod[0], - "domain", - Collections.singletonList(domain) - ); - }); - }); - - - return new MethodCallExpr( - builtMethod[0], - "build" - ); - } -} diff --git a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/SocketHintDeclarationCollection.java b/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/SocketHintDeclarationCollection.java deleted file mode 100644 index 557795e75b..0000000000 --- a/buildSrc/src/main/java/edu/wpi/gripgenerator/templates/SocketHintDeclarationCollection.java +++ /dev/null @@ -1,308 +0,0 @@ -package edu.wpi.gripgenerator.templates; - -import com.github.javaparser.ASTHelper; -import com.github.javaparser.ast.body.ModifierSet; -import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.ast.body.VariableDeclaratorId; -import com.github.javaparser.ast.comments.BlockComment; -import com.github.javaparser.ast.expr.ArrayAccessExpr; -import com.github.javaparser.ast.expr.ArrayCreationExpr; -import com.github.javaparser.ast.expr.ArrayInitializerExpr; -import com.github.javaparser.ast.expr.CastExpr; -import com.github.javaparser.ast.expr.EnclosedExpr; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.IntegerLiteralExpr; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.expr.ObjectCreationExpr; -import com.github.javaparser.ast.expr.VariableDeclarationExpr; -import com.github.javaparser.ast.stmt.BlockStmt; -import com.github.javaparser.ast.stmt.ReturnStmt; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.PrimitiveType; -import com.github.javaparser.ast.type.ReferenceType; -import com.github.javaparser.ast.type.Type; -import com.github.javaparser.ast.type.WildcardType; - -import edu.wpi.gripgenerator.defaults.DefaultValueCollector; -import edu.wpi.gripgenerator.settings.DefinedParamType; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class SocketHintDeclarationCollection { - //Kept around to define the order of the params. - private final List paramTypes; - private final Map> inputHintsMap = new HashMap<>(); - private final Map> outputHintsMap = new HashMap<>(); - //Defines the order of the input params - private final List inputParamTypes = new ArrayList<>(); - //Defines the order of the output params - private final List outputParamTypes = new ArrayList<>(); - private final DefaultValueCollector collector; - - /** - * @param paramTypes - */ - public SocketHintDeclarationCollection(DefaultValueCollector collector, List - paramTypes) { - this.paramTypes = paramTypes; - this.collector = collector; - - // Figure out which hint map to put this defined param type into - for (DefinedParamType type : paramTypes) { - if (type.getDirection().isInput()) { - addToInput(type); - } - if (type.getDirection().isOutput()) { - addToOutput(type); - } - } - } - - public static Type getSocketReturnParam(String socketNameType) { - ClassOrInterfaceType socketType = new ClassOrInterfaceType(null, socketNameType); - socketType.setTypeArgs(Arrays.asList(new WildcardType())); - return new ReferenceType(socketType, 1); - } - - private final void addToLists(DefinedParamType type, Map> - assignmentMap, List assignmentList) { - assignmentMap.putIfAbsent(type.getType(), new ArrayList<>()); // Will return null if new - assignmentMap.get(type.getType()).add(type); - if (!assignmentList.contains(type)) { - assignmentList.add(type); - } - } - - private final void addToOutput(DefinedParamType param) { - addToLists(param, outputHintsMap, outputParamTypes); - } - - private final void addToInput(DefinedParamType param) { - addToLists(param, inputHintsMap, inputParamTypes); - } - - private ArrayAccessExpr arrayAccessExpr(String paramId, int index) { - return new ArrayAccessExpr( - new NameExpr(paramId), - new IntegerLiteralExpr(String.valueOf(index)) - ); - } - - private MethodCallExpr getOrSetValueExpression(Expression scope, Expression setExpression) { - return new MethodCallExpr( - scope, - (setExpression == null ? "getValue" : "setValue"), - (setExpression == null ? Collections.emptyList() : Collections.singletonList(setExpression)) - ); - } - - private MethodCallExpr getValueExpression(String paramId, int index) { - return new MethodCallExpr(getOrSetValueExpression(arrayAccessExpr(paramId, index), null), - "get"); - } - - private Expression generateCopyExpression(DefinedParamType type, String inputParmId, int - inputIndex, String outputParamId, int outputIndex) { - // GOAL: ((InputSocket) inputs[0]).getValue().get().assignTo(((OutputSocket) - // outputs[0]).getValue().get()); - final ClassOrInterfaceType outputType = new ClassOrInterfaceType("OutputSocket"); - final ClassOrInterfaceType inputType = new ClassOrInterfaceType("InputSocket"); - outputType.setTypeArgs(Collections.singletonList(type.getType())); - inputType.setTypeArgs(Collections.singletonList(type.getType())); - - final MethodCallExpr copyExpression = new MethodCallExpr( - new MethodCallExpr( - getOrSetValueExpression( - new EnclosedExpr( - new CastExpr( - inputType, - arrayAccessExpr(inputParmId, inputIndex) - ) - ), - null - ), - "get" - ), - "assignTo", - Collections.singletonList( - new MethodCallExpr( - getOrSetValueExpression( - new EnclosedExpr( - new CastExpr( - outputType, - arrayAccessExpr(outputParamId, outputIndex) - ) - ), - null - ), - "get" - ) - ) - ); - copyExpression.setComment(new BlockComment( - " Sets the value of the input Mat to the output because this operation does not have a " + - "destination Mat. " - )); - return copyExpression; - } - - public List getSocketAssignments(String inputParamId, String outputParamId) { - List assignments = new ArrayList<>(); - int inputIndex = 0; - int outputIndex = 0; - for (DefinedParamType paramType : paramTypes) { - // We still need to increment the values if the param is ignored - if (paramType.isIgnored()) { - continue; - } - - int index; - String paramId; - if (inputParamTypes.contains(paramType) && outputParamTypes.contains(paramType)) { - if (paramType.getType().toStringWithoutComments().contains("Mat")) { - assignments.add( - generateCopyExpression(paramType, inputParamId, inputParamTypes.indexOf(paramType), - outputParamId, outputParamTypes.indexOf(paramType)) - ); - } else { - throw new IllegalStateException("Can not generate Input/Output Socket for type: " + - paramType.getType().toString()); - } - - // We have used the input socket - inputIndex++; - } - - // Generate the output socket event if this is an input/output socket - if (outputParamTypes.contains(paramType)) { - paramId = outputParamId; - index = outputIndex; - outputIndex++; - } else if (inputParamTypes.contains(paramType)) { - paramId = inputParamId; - index = inputIndex; - inputIndex++; - } else { - assert false : "The paramType was not in either the input or output list"; - return null; - } - - final MethodCallExpr getValueExpression = getValueExpression(paramId, index); - final Expression assignExpression; - if (paramType.getType() instanceof PrimitiveType && (!((PrimitiveType) paramType.getType()) - .getType().equals(PrimitiveType.Primitive.Boolean))) { - final String numberConversionFunction; - switch (((PrimitiveType) paramType.getType()).getType()) { - case Int: - numberConversionFunction = "intValue"; - break; - case Short: - case Char: - numberConversionFunction = "shortValue"; - break; - case Float: - numberConversionFunction = "floatValue"; - break; - case Double: - numberConversionFunction = "doubleValue"; - break; - case Byte: - numberConversionFunction = "byteValue"; - break; - case Long: - numberConversionFunction = "longValue"; - break; - default: - throw new IllegalStateException("Conversion for type " + paramType.getType() + " is " + - "not defined"); - } - assignExpression = new MethodCallExpr( - new EnclosedExpr( - new CastExpr( - ASTHelper.createReferenceType("Number", 0), - getValueExpression - ) - ), - numberConversionFunction - ); - } else { - assignExpression = new CastExpr( - paramType.getTypeBoxedIfPossible(), - getValueExpression - ); - } - - assignments.add( - new VariableDeclarationExpr( - ModifierSet.FINAL, - paramType.getType(), - Collections.singletonList( - new VariableDeclarator( - new VariableDeclaratorId(paramType.getName()), assignExpression) - ) - ) - ); - } - return assignments; - } - - public ObjectCreationExpr getSocketListParam(DefinedParamType definedParamType, - ClassOrInterfaceType socketType, String - inputOrOutputPostfix) { - //System.out.println("Generating for default " + (definedParamType.getDefaultValue() - // .isPresent() ? definedParamType.getDefaultValue().get().getName().toString() : "null")); - return new ObjectCreationExpr(null, socketType, Arrays.asList( - new NameExpr("eventBus"), - new NameExpr(definedParamType.getName() + inputOrOutputPostfix + SocketHintDeclaration - .HINT_POSTFIX) - )); - } - - private BlockStmt getInputOrOutputSocketBody(List paramTypes, - ClassOrInterfaceType socketType, String - inputOrOutputPostfix) { - List passedExpressions = new ArrayList<>(); - for (DefinedParamType inputParam : paramTypes) { - if (inputParam.isIgnored()) { - continue; - } - passedExpressions.add(getSocketListParam(inputParam, socketType, inputOrOutputPostfix)); - } - BlockStmt returnStatement = new BlockStmt( - Arrays.asList(new ReturnStmt( - new ArrayCreationExpr(socketType, 1, new ArrayInitializerExpr(passedExpressions))) - ) - ); - return returnStatement; - } - - public BlockStmt getInputSocketBody() { - return getInputOrOutputSocketBody(inputParamTypes, new ClassOrInterfaceType("InputSocket"), - SocketHintDeclaration.INPUT_POSTFIX); - } - - public BlockStmt getOutputSocketBody() { - return getInputOrOutputSocketBody(outputParamTypes, new ClassOrInterfaceType("OutputSocket"), - SocketHintDeclaration.OUTPUT_POSTFIX); - } - - public List getAllSocketHints() { - List socketHintDeclarations = new ArrayList<>(); - for (Map.Entry> type : inputHintsMap.entrySet()) { - socketHintDeclarations.add(new SocketHintDeclaration(collector, type.getKey(), type - .getValue(), DefinedParamType.DefinedParamDirection.INPUT)); - } - for (Map.Entry> type : outputHintsMap.entrySet()) { - socketHintDeclarations.add(new SocketHintDeclaration(collector, type.getKey(), type - .getValue(), DefinedParamType.DefinedParamDirection.OUTPUT)); - } - return socketHintDeclarations; - } - -} diff --git a/buildSrc/src/main/resources/.gitignore b/buildSrc/src/main/resources/.gitignore deleted file mode 100644 index 1597fe251f..0000000000 --- a/buildSrc/src/main/resources/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.java -*.txt \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/generator.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/generator.properties deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/buildSrc/src/test/java/edu/wpi/gripgenerator/FileParserTest.java b/buildSrc/src/test/java/edu/wpi/gripgenerator/FileParserTest.java deleted file mode 100644 index 648ca2f35f..0000000000 --- a/buildSrc/src/test/java/edu/wpi/gripgenerator/FileParserTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package edu.wpi.gripgenerator; - -import org.junit.Test; - -import static junit.framework.TestCase.assertEquals; - -public class FileParserTest { - - @Test - public void testReplaceRegexParamAtEnd() { - final String testMethod = "bilateralFilter( @ByVal Mat src, @ByVal Mat dst, int d,\n" + - " double sigmaColor, double sigmaSpace,\n" + - " int borderType/*=cv::BORDER_DEFAULT*/ );"; - final String result = "bilateralFilter( @ByVal Mat src, @ByVal Mat dst, int d,\n" + - " double sigmaColor, double sigmaSpace,\n" + - " /*=cv::BORDER_DEFAULT*/int borderType );"; - String replacedMethod = testMethod.replaceAll(FileParser.methodReorderPattern, FileParser - .methodNewOrder); - assertEquals("Result was not the expected string after regex replacement", result, - replacedMethod); - } - - @Test - public void testReplaceRegexParamAtMiddleAndEnd() { - final String testMethod = "GaussianBlur( @ByVal Mat src, @ByVal Mat dst, @ByVal Size ksize,\n" + - " double sigmaX, double sigmaY/*=0*/,\n" + - " int borderType/*=cv::BORDER_DEFAULT*/ );"; - final String result = "GaussianBlur( @ByVal Mat src, @ByVal Mat dst, @ByVal Size ksize,\n" + - " double sigmaX, /*=0*/double sigmaY,\n" + - " /*=cv::BORDER_DEFAULT*/int borderType );"; - String replacedMethod = testMethod.replaceAll(FileParser.methodReorderPattern, FileParser - .methodNewOrder); - assertEquals("Result was not the expected string after regex replacement", result, - replacedMethod); - } - - @Test - public void testSimpleRearrange() { - final String testString = "CvPoint2D32f c/*=CvPoint2D32f()*/,"; - final String expectedResult = "/*=CvPoint2D32f()*/CvPoint2D32f c,"; - String replacedMethod = testString.replaceAll(FileParser.methodReorderPattern, FileParser - .methodNewOrder); - assertEquals("Result was not the expected string after regex replacement", expectedResult, - replacedMethod); - } - - @Test - public void testNegativeValues() { - final String testMethod = "multiply(@ByVal Mat src1, @ByVal Mat src2,\n" + - " @ByVal Mat dst, double scale/*=1*/, int dtype/*=-1*/);"; - final String expectedResult = "multiply(@ByVal Mat src1, @ByVal Mat src2,\n" + - " @ByVal Mat dst, /*=1*/double scale, /*=-1*/int dtype);"; - String replacedMethod = testMethod.replaceAll(FileParser.methodReorderPattern, FileParser - .methodNewOrder); - assertEquals("Result was not the expected string after regex replacement", expectedResult, - replacedMethod); - } -} diff --git a/buildSrc/src/test/java/templates/SocketHintDeclarationTest.java b/buildSrc/src/test/java/templates/SocketHintDeclarationTest.java deleted file mode 100644 index 330d981f19..0000000000 --- a/buildSrc/src/test/java/templates/SocketHintDeclarationTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package templates; - -import edu.wpi.gripgenerator.templates.SocketHintDeclaration; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import java.util.Arrays; - -import static org.junit.Assert.assertEquals; - -public class SocketHintDeclarationTest { - SocketHintDeclaration testDeclaration = new SocketHintDeclaration("Mat", Arrays.asList("src1", - "src2"), true); - - @Before - public void setUp() throws Exception { - - } - - @Test - @Ignore("No longer accurate") - public void testGetDeclaration() { - final String outputString = "private final SocketHint src1OutputHint = new " + - "SocketHint(\"src1\", Mat.class), src2OutputHint = new SocketHint(\"src2\", Mat" + - ".class);"; - assertEquals(outputString, testDeclaration.getDeclaration().toString()); - } -} diff --git a/core/core.gradle.kts b/core/core.gradle.kts new file mode 100644 index 0000000000..41ca806045 --- /dev/null +++ b/core/core.gradle.kts @@ -0,0 +1,75 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + id("java") + id("java-library") + id("application") + id("com.github.johnrengelman.shadow") + id("com.google.osdetector") +} + +application { + mainClassName = "edu.wpi.grip.core.Main" +} + +val os = osdetector.classifier.replace("osx", "macosx").replace("x86_32", "x86") +val arch = osdetector.arch.replace("x86_64", "x64") + +dependencies { + api(group = "com.google.code.findbugs", name = "jsr305", version = "3.0.1") + api(group = "org.bytedeco", name = "javacv", version = "1.1") + api(group = "org.bytedeco.javacpp-presets", name = "opencv", version = "3.0.0-1.1") + api(group = "org.bytedeco.javacpp-presets", name = "opencv", version = "3.0.0-1.1", classifier = os) + api(group = "org.bytedeco.javacpp-presets", name = "videoinput", version = "0.200-1.1", classifier = os) + api(group = "org.bytedeco.javacpp-presets", name = "ffmpeg", version = "0.200-1.1", classifier = os) + api(group = "org.python", name = "jython", version = "2.7.0") + api(group = "com.thoughtworks.xstream", name = "xstream", version = "1.4.10") + api(group = "org.apache.commons", name = "commons-lang3", version = "3.5") + api(group = "com.google.guava", name = "guava", version = "20.0") + api(group = "com.google.auto.value", name = "auto-value", version = "1.3") + annotationProcessor("com.google.auto.value:auto-value:1.3") + api(group = "com.google.code.gson", name = "gson", version = "2.8.0") + api(group = "org.eclipse.jetty", name = "jetty-server", version = "9.3.14.v20161028") + testCompile(group = "org.apache.httpcomponents", name = "httpclient", version = "4.5.2") + testCompile(group = "org.apache.httpcomponents", name = "httpcore", version = "4.4.5") + testCompile(group = "org.apache.httpcomponents", name = "httpmime", version = "4.5.2") + api(group = "commons-cli", name = "commons-cli", version = "1.3.1") + api(group = "commons-io", name = "commons-io", version = "2.4") + // We use the no_aop version of Guice because the aop isn"t avaiable in arm java + // http://stackoverflow.com/a/15235190/3708426 + // /~https://github.com/google/guice/wiki/OptionalAOP + api(group = "com.google.inject", name = "guice", version = "4.1.0", classifier = "no_aop") + api(group = "com.google.inject.extensions", name = "guice-assistedinject", version = "4.1.0") + + // Network publishing dependencies + api(group = "org.ros.rosjava_core", name = "rosjava", version = "+") + api(group = "org.ros.rosjava_bootstrap", name = "message_generation", version = "+") + api(group = "org.ros.rosjava_messages", name = "std_msgs", version = "+") + api(group = "org.ros.rosjava_messages", name = "grip_msgs", version = "0.0.1") + api(group = "edu.wpi.first.wpilib.networktables.java", name = "NetworkTables", version = "3.1.2", classifier = "desktop") + api(group = "edu.wpi.first.wpilib.networktables.java", name = "NetworkTables", version = "3.1.2", classifier = "arm") +} + +tasks.withType().configureEach { + manifest { + attributes["Implementation-Version"] = version + attributes["Main-Class"] = application.mainClassName + } +} + +tasks.withType().configureEach { + /* The icudt54b directory in Jython takes up 9 megabytes and doesn"t seem to do anything useful. */ + exclude("org/python/icu/impl/data/icudt54b/") + + /* We don"t use all of the OpenCV libraries, and they seem to take up a lot of space. If we ever decide to + use any more of these (or perhaps just include them for people to use from Python scripts), the following lines + should be changed, but for now this saves us a lot of space. */ + exclude("org/bytedeco/javacpp/*/*calib3d*") + exclude("org/bytedeco/javacpp/*/*optflow*") + exclude("org/bytedeco/javacpp/*/*photo*") + exclude("org/bytedeco/javacpp/*/*shape*") + exclude("org/bytedeco/javacpp/*/*stitching*") + exclude("org/bytedeco/javacpp/*/*superres*") + exclude("org/bytedeco/javacpp/*/*videostab*") + exclude("org/bytedeco/javacpp/*/*xfeatures2d*") +} diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java index 6d6bf53dfb..a8d40cd79a 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java @@ -55,6 +55,7 @@ public class PublishVideoOperation implements Operation { private final InputSocket qualitySocket; @SuppressWarnings("PMD.SingularField") private volatile boolean connected = false; + private volatile boolean hasImage = false; /** * Listens for incoming connections on port 1180 and writes JPEG data whenever there's a new * frame. @@ -93,7 +94,9 @@ public class PublishVideoOperation implements Operation { // called with // a new input. synchronized (imageLock) { - imageLock.wait(); + while (!hasImage) { + imageLock.wait(); + } // Copy the image data into a pre-allocated buffer, growing it if necessary bufferSize = imagePointer.limit(); @@ -101,6 +104,7 @@ public class PublishVideoOperation implements Operation { buffer = new byte[imagePointer.limit()]; } imagePointer.get(buffer, 0, bufferSize); + hasImage = false; } // The FRC dashboard image protocol consists of a magic number, the size of the image @@ -177,6 +181,7 @@ public void perform() { synchronized (imageLock) { imencode(".jpeg", inputSocket.getValue().get(), imagePointer, new IntPointer(CV_IMWRITE_JPEG_QUALITY, qualitySocket.getValue().get().intValue())); + hasImage = true; imageLock.notifyAll(); } } diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/BorderTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/BorderTypesEnum.java new file mode 100644 index 0000000000..9ccefea712 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/BorderTypesEnum.java @@ -0,0 +1,23 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum BorderTypesEnum { + + /** `iiiiii|abcdefgh|iiiiiii` with some specified `i` */ + BORDER_CONSTANT(opencv_core.BORDER_CONSTANT), /** `aaaaaa|abcdefgh|hhhhhhh` */ + BORDER_REPLICATE(opencv_core.BORDER_REPLICATE), /** `fedcba|abcdefgh|hgfedcb` */ + BORDER_REFLECT(opencv_core.BORDER_REFLECT), /** `cdefgh|abcdefgh|abcdefg` */ + BORDER_WRAP(opencv_core.BORDER_WRAP), /** `gfedcb|abcdefgh|gfedcba` */ + BORDER_REFLECT_101(opencv_core.BORDER_REFLECT_101), /** `uvwxyz|absdefgh|ijklmno` */ + BORDER_TRANSPARENT(opencv_core.BORDER_TRANSPARENT), /** same as BORDER_REFLECT_101 */ + BORDER_REFLECT101(opencv_core.BORDER_REFLECT101), /** same as BORDER_REFLECT_101 */ + BORDER_DEFAULT(opencv_core.BORDER_DEFAULT), /** do not look outside of ROI */ + BORDER_ISOLATED(opencv_core.BORDER_ISOLATED); + + public final int value; + + BorderTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CmpTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CmpTypesEnum.java new file mode 100644 index 0000000000..9486c3e581 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CmpTypesEnum.java @@ -0,0 +1,20 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum CmpTypesEnum { + + /** src1 is equal to src2. */ + CMP_EQ(opencv_core.CMP_EQ), /** src1 is greater than src2. */ + CMP_GT(opencv_core.CMP_GT), /** src1 is greater than or equal to src2. */ + CMP_GE(opencv_core.CMP_GE), /** src1 is less than src2. */ + CMP_LT(opencv_core.CMP_LT), /** src1 is less than or equal to src2. */ + CMP_LE(opencv_core.CMP_LE), /** src1 is unequal to src2. */ + CMP_NE(opencv_core.CMP_NE); + + public final int value; + + CmpTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CovarFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CovarFlagsEnum.java new file mode 100644 index 0000000000..3277f3867a --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CovarFlagsEnum.java @@ -0,0 +1,40 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum CovarFlagsEnum { + + /** The output covariance matrix is calculated as: + \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...],\f] + The covariance matrix will be nsamples x nsamples. Such an unusual covariance matrix is used + for fast PCA of a set of very large vectors (see, for example, the EigenFaces technique for + face recognition). Eigenvalues of this "scrambled" matrix match the eigenvalues of the true + covariance matrix. The "true" eigenvectors can be easily calculated from the eigenvectors of + the "scrambled" covariance matrix. */ + COVAR_SCRAMBLED(opencv_core.COVAR_SCRAMBLED), /**The output covariance matrix is calculated as: + \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...] \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T,\f] + covar will be a square matrix of the same size as the total number of elements in each input + vector. One and only one of COVAR_SCRAMBLED and COVAR_NORMAL must be specified.*/ + COVAR_NORMAL(opencv_core.COVAR_NORMAL), /** If the flag is specified, the function does not calculate mean from + the input vectors but, instead, uses the passed mean vector. This is useful if mean has been + pre-calculated or known in advance, or if the covariance matrix is calculated by parts. In + this case, mean is not a mean vector of the input sub-set of vectors but rather the mean + vector of the whole set.*/ + COVAR_USE_AVG(opencv_core.COVAR_USE_AVG), /** If the flag is specified, the covariance matrix is scaled. In the + "normal" mode, scale is 1./nsamples . In the "scrambled" mode, scale is the reciprocal of the + total number of elements in each input vector. By default (if the flag is not specified), the + covariance matrix is not scaled ( scale=1 ).*/ + COVAR_SCALE(opencv_core.COVAR_SCALE), /** If the flag is + specified, all the input vectors are stored as rows of the samples matrix. mean should be a + single-row vector in this case.*/ + COVAR_ROWS(opencv_core.COVAR_ROWS), /** If the flag is + specified, all the input vectors are stored as columns of the samples matrix. mean should be a + single-column vector in this case.*/ + COVAR_COLS(opencv_core.COVAR_COLS); + + public final int value; + + CovarFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CpuFeaturesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CpuFeaturesEnum.java new file mode 100644 index 0000000000..03fbf08485 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/CpuFeaturesEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum CpuFeaturesEnum { + + CPU_MMX(opencv_core.CPU_MMX), CPU_SSE(opencv_core.CPU_SSE), CPU_SSE2(opencv_core.CPU_SSE2), CPU_SSE3(opencv_core.CPU_SSE3), CPU_SSSE3(opencv_core.CPU_SSSE3), CPU_SSE4_1(opencv_core.CPU_SSE4_1), CPU_SSE4_2(opencv_core.CPU_SSE4_2), CPU_POPCNT(opencv_core.CPU_POPCNT), CPU_AVX(opencv_core.CPU_AVX), CPU_AVX2(opencv_core.CPU_AVX2), CPU_FMA3(opencv_core.CPU_FMA3), CPU_AVX_512F(opencv_core.CPU_AVX_512F), CPU_AVX_512BW(opencv_core.CPU_AVX_512BW), CPU_AVX_512CD(opencv_core.CPU_AVX_512CD), CPU_AVX_512DQ(opencv_core.CPU_AVX_512DQ), CPU_AVX_512ER(opencv_core.CPU_AVX_512ER), CPU_AVX_512IFMA512(opencv_core.CPU_AVX_512IFMA512), CPU_AVX_512PF(opencv_core.CPU_AVX_512PF), CPU_AVX_512VBMI(opencv_core.CPU_AVX_512VBMI), CPU_AVX_512VL(opencv_core.CPU_AVX_512VL), CPU_NEON(opencv_core.CPU_NEON); + + public final int value; + + CpuFeaturesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/DecompTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/DecompTypesEnum.java new file mode 100644 index 0000000000..9c8c1d9bf6 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/DecompTypesEnum.java @@ -0,0 +1,26 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum DecompTypesEnum { + + /** Gaussian elimination with the optimal pivot element chosen. */ + DECOMP_LU(opencv_core.DECOMP_LU), /** singular value decomposition (SVD) method; the system can be over-defined and/or the matrix + src1 can be singular */ + DECOMP_SVD(opencv_core.DECOMP_SVD), /** eigenvalue decomposition; the matrix src1 must be symmetrical */ + DECOMP_EIG(opencv_core.DECOMP_EIG), /** Cholesky \f$LL^T\f$ factorization; the matrix src1 must be symmetrical and positively + defined */ + DECOMP_CHOLESKY(opencv_core.DECOMP_CHOLESKY), /** QR factorization; the system can be over-defined and/or the matrix src1 can be singular */ + DECOMP_QR(opencv_core.DECOMP_QR), /** while all the previous flags are mutually exclusive, this flag can be used together with + any of the previous; it means that the normal equations + \f$\texttt{src1}^T\cdot\texttt{src1}\cdot\texttt{dst}=\texttt{src1}^T\texttt{src2}\f$ are + solved instead of the original system + \f$\texttt{src1}\cdot\texttt{dst}=\texttt{src2}\f$ */ + DECOMP_NORMAL(opencv_core.DECOMP_NORMAL); + + public final int value; + + DecompTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/DftFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/DftFlagsEnum.java new file mode 100644 index 0000000000..dff7e63427 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/DftFlagsEnum.java @@ -0,0 +1,41 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum DftFlagsEnum { + + /** performs an inverse 1D or 2D transform instead of the default forward + transform. */ + DFT_INVERSE(opencv_core.DFT_INVERSE), /** scales the result: divide it by the number of array elements. Normally, it is + combined with DFT_INVERSE. */ + DFT_SCALE(opencv_core.DFT_SCALE), /** performs a forward or inverse transform of every individual row of the input + matrix; this flag enables you to transform multiple vectors simultaneously and can be used to + decrease the overhead (which is sometimes several times larger than the processing itself) to + perform 3D and higher-dimensional transformations and so forth.*/ + DFT_ROWS(opencv_core.DFT_ROWS), /** performs a forward transformation of 1D or 2D real array; the result, + though being a complex array, has complex-conjugate symmetry (*CCS*, see the function + description below for details), and such an array can be packed into a real array of the same + size as input, which is the fastest option and which is what the function does by default; + however, you may wish to get a full complex array (for simpler spectrum analysis, and so on) - + pass the flag to enable the function to produce a full-size complex output array. */ + DFT_COMPLEX_OUTPUT(opencv_core.DFT_COMPLEX_OUTPUT), /** performs an inverse transformation of a 1D or 2D complex array; the + result is normally a complex array of the same size, however, if the input array has + conjugate-complex symmetry (for example, it is a result of forward transformation with + DFT_COMPLEX_OUTPUT flag), the output is a real array; while the function itself does not + check whether the input is symmetrical or not, you can pass the flag and then the function + will assume the symmetry and produce the real output array (note that when the input is packed + into a real array and inverse transformation is executed, the function treats the input as a + packed complex-conjugate symmetrical array, and the output will also be a real array). */ + DFT_REAL_OUTPUT(opencv_core.DFT_REAL_OUTPUT), /** performs an inverse 1D or 2D transform instead of the default forward transform. */ + DCT_INVERSE(opencv_core.DCT_INVERSE), /** performs a forward or inverse transform of every individual row of the input + matrix. This flag enables you to transform multiple vectors simultaneously and can be used to + decrease the overhead (which is sometimes several times larger than the processing itself) to + perform 3D and higher-dimensional transforms and so forth.*/ + DCT_ROWS(opencv_core.DCT_ROWS); + + public final int value; + + DftFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/Enum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/Enum.java new file mode 100644 index 0000000000..373fdefb05 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/Enum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum Enum { + + ACCESS_READ(opencv_core.ACCESS_READ), ACCESS_WRITE(opencv_core.ACCESS_WRITE), ACCESS_RW(opencv_core.ACCESS_RW), ACCESS_MASK(opencv_core.ACCESS_MASK), ACCESS_FAST(opencv_core.ACCESS_FAST); + + public final int value; + + Enum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ErrorCodeEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ErrorCodeEnum.java new file mode 100644 index 0000000000..f234e8b05d --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ErrorCodeEnum.java @@ -0,0 +1,46 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum ErrorCodeEnum { + + /** everithing is ok */ + StsOk(opencv_core.StsOk), /** pseudo error for back trace */ + StsBackTrace(opencv_core.StsBackTrace), /** unknown /unspecified error */ + StsError(opencv_core.StsError), /** internal error (bad state) */ + StsInternal(opencv_core.StsInternal), /** insufficient memory */ + StsNoMem(opencv_core.StsNoMem), /** function arg/param is bad */ + StsBadArg(opencv_core.StsBadArg), /** unsupported function */ + StsBadFunc(opencv_core.StsBadFunc), /** iter. didn't converge */ + StsNoConv(opencv_core.StsNoConv), /** tracing */ + StsAutoTrace(opencv_core.StsAutoTrace), /** image header is NULL */ + HeaderIsNull(opencv_core.HeaderIsNull), /** image size is invalid */ + BadImageSize(opencv_core.BadImageSize), /** offset is invalid */ + BadOffset(opencv_core.BadOffset), BadDataPtr(opencv_core.BadDataPtr), BadStep(opencv_core.BadStep), BadModelOrChSeq(opencv_core.BadModelOrChSeq), BadNumChannels(opencv_core.BadNumChannels), BadNumChannel1U(opencv_core.BadNumChannel1U), BadDepth(opencv_core.BadDepth), BadAlphaChannel(opencv_core.BadAlphaChannel), BadOrder(opencv_core.BadOrder), BadOrigin(opencv_core.BadOrigin), BadAlign(opencv_core.BadAlign), BadCallBack(opencv_core.BadCallBack), BadTileSize(opencv_core.BadTileSize), BadCOI(opencv_core.BadCOI), BadROISize(opencv_core.BadROISize), MaskIsTiled(opencv_core.MaskIsTiled), /** null pointer */ + StsNullPtr(opencv_core.StsNullPtr), /** incorrect vector length */ + StsVecLengthErr(opencv_core.StsVecLengthErr), /** incorr. filter structure content */ + StsFilterStructContentErr(opencv_core.StsFilterStructContentErr), /** incorr. transform kernel content */ + StsKernelStructContentErr(opencv_core.StsKernelStructContentErr), /** incorrect filter ofset value */ + StsFilterOffsetErr(opencv_core.StsFilterOffsetErr), /** the input/output structure size is incorrect */ + StsBadSize(opencv_core.StsBadSize), /** division by zero */ + StsDivByZero(opencv_core.StsDivByZero), /** in-place operation is not supported */ + StsInplaceNotSupported(opencv_core.StsInplaceNotSupported), /** request can't be completed */ + StsObjectNotFound(opencv_core.StsObjectNotFound), /** formats of input/output arrays differ */ + StsUnmatchedFormats(opencv_core.StsUnmatchedFormats), /** flag is wrong or not supported */ + StsBadFlag(opencv_core.StsBadFlag), /** bad CvPoint */ + StsBadPoint(opencv_core.StsBadPoint), /** bad format of mask (neither 8uC1 nor 8sC1) */ + StsBadMask(opencv_core.StsBadMask), /** sizes of input/output structures do not match */ + StsUnmatchedSizes(opencv_core.StsUnmatchedSizes), /** the data format/type is not supported by the function */ + StsUnsupportedFormat(opencv_core.StsUnsupportedFormat), /** some of parameters are out of range */ + StsOutOfRange(opencv_core.StsOutOfRange), /** invalid syntax/structure of the parsed file */ + StsParseError(opencv_core.StsParseError), /** the requested function/feature is not implemented */ + StsNotImplemented(opencv_core.StsNotImplemented), /** an allocated block has been corrupted */ + StsBadMemBlock(opencv_core.StsBadMemBlock), /** assertion failed */ + StsAssert(opencv_core.StsAssert), GpuNotSupported(opencv_core.GpuNotSupported), GpuApiCallError(opencv_core.GpuApiCallError), OpenGlNotSupported(opencv_core.OpenGlNotSupported), OpenGlApiCallError(opencv_core.OpenGlApiCallError), OpenCLApiCallError(opencv_core.OpenCLApiCallError), OpenCLDoubleNotSupported(opencv_core.OpenCLDoubleNotSupported), OpenCLInitError(opencv_core.OpenCLInitError), OpenCLNoAMDBlasFft(opencv_core.OpenCLNoAMDBlasFft); + + public final int value; + + ErrorCodeEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileNodeTypeEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileNodeTypeEnum.java new file mode 100644 index 0000000000..a075e0cc80 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileNodeTypeEnum.java @@ -0,0 +1,27 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum FileNodeTypeEnum { + + /** empty node */ + NONE(opencv_core.FileNode.NONE), /** an integer */ + INT(opencv_core.FileNode.INT), /** floating-point number */ + REAL(opencv_core.FileNode.REAL), /** synonym or REAL */ + FLOAT(opencv_core.FileNode.FLOAT), /** text string in UTF-8 encoding */ + STR(opencv_core.FileNode.STR), /** synonym for STR */ + STRING(opencv_core.FileNode.STRING), /** integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others */ + REF(opencv_core.FileNode.REF), /** sequence */ + SEQ(opencv_core.FileNode.SEQ), /** mapping */ + MAP(opencv_core.FileNode.MAP), TYPE_MASK(opencv_core.FileNode.TYPE_MASK), /** compact representation of a sequence or mapping. Used only by YAML writer */ + FLOW(opencv_core.FileNode.FLOW), /** a registered object (e.g. a matrix) */ + USER(opencv_core.FileNode.USER), /** empty structure (sequence or mapping) */ + EMPTY(opencv_core.FileNode.EMPTY), /** the node has a name (i.e. it is element of a mapping) */ + NAMED(opencv_core.FileNode.NAMED); + + public final int value; + + FileNodeTypeEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileStorageEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileStorageEnum.java new file mode 100644 index 0000000000..a3ca885362 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileStorageEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum FileStorageEnum { + + UNDEFINED(opencv_core.FileStorage.UNDEFINED), VALUE_EXPECTED(opencv_core.FileStorage.VALUE_EXPECTED), NAME_EXPECTED(opencv_core.FileStorage.NAME_EXPECTED), INSIDE_MAP(opencv_core.FileStorage.INSIDE_MAP); + + public final int value; + + FileStorageEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileStorageModeEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileStorageModeEnum.java new file mode 100644 index 0000000000..393df8413c --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FileStorageModeEnum.java @@ -0,0 +1,23 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum FileStorageModeEnum { + + /** value, open the file for reading */ + READ(opencv_core.FileStorage.READ), /** value, open the file for writing */ + WRITE(opencv_core.FileStorage.WRITE), /** value, open the file for appending */ + APPEND(opencv_core.FileStorage.APPEND), /** flag, read data from source or write data to the internal buffer (which is + * returned by FileStorage::release) */ + MEMORY(opencv_core.FileStorage.MEMORY), /** mask for format flags */ + FORMAT_MASK(opencv_core.FileStorage.FORMAT_MASK), /** flag, auto format */ + FORMAT_AUTO(opencv_core.FileStorage.FORMAT_AUTO), /** flag, XML format */ + FORMAT_XML(opencv_core.FileStorage.FORMAT_XML), /** flag, YAML format */ + FORMAT_YAML(opencv_core.FileStorage.FORMAT_YAML); + + public final int value; + + FileStorageModeEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FormatterEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FormatterEnum.java new file mode 100644 index 0000000000..686bffd90f --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/FormatterEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum FormatterEnum { + + FMT_DEFAULT(opencv_core.Formatter.FMT_DEFAULT), FMT_MATLAB(opencv_core.Formatter.FMT_MATLAB), FMT_CSV(opencv_core.Formatter.FMT_CSV), FMT_PYTHON(opencv_core.Formatter.FMT_PYTHON), FMT_NUMPY(opencv_core.Formatter.FMT_NUMPY), FMT_C(opencv_core.Formatter.FMT_C); + + public final int value; + + FormatterEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/GemmFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/GemmFlagsEnum.java new file mode 100644 index 0000000000..c7884ba562 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/GemmFlagsEnum.java @@ -0,0 +1,17 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum GemmFlagsEnum { + + /** transposes src1 */ + GEMM_1_T(opencv_core.GEMM_1_T), /** transposes src2 */ + GEMM_2_T(opencv_core.GEMM_2_T), /** transposes src3 */ + GEMM_3_T(opencv_core.GEMM_3_T); + + public final int value; + + GemmFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/HammingEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/HammingEnum.java new file mode 100644 index 0000000000..0cf9719831 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/HammingEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum HammingEnum { + + normType(opencv_core.Hamming.normType); + + public final int value; + + HammingEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/HersheyFontsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/HersheyFontsEnum.java new file mode 100644 index 0000000000..c2b4c71abd --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/HersheyFontsEnum.java @@ -0,0 +1,23 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum HersheyFontsEnum { + + /** normal size sans-serif font */ + FONT_HERSHEY_SIMPLEX(opencv_core.FONT_HERSHEY_SIMPLEX), /** small size sans-serif font */ + FONT_HERSHEY_PLAIN(opencv_core.FONT_HERSHEY_PLAIN), /** normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX) */ + FONT_HERSHEY_DUPLEX(opencv_core.FONT_HERSHEY_DUPLEX), /** normal size serif font */ + FONT_HERSHEY_COMPLEX(opencv_core.FONT_HERSHEY_COMPLEX), /** normal size serif font (more complex than FONT_HERSHEY_COMPLEX) */ + FONT_HERSHEY_TRIPLEX(opencv_core.FONT_HERSHEY_TRIPLEX), /** smaller version of FONT_HERSHEY_COMPLEX */ + FONT_HERSHEY_COMPLEX_SMALL(opencv_core.FONT_HERSHEY_COMPLEX_SMALL), /** hand-writing style font */ + FONT_HERSHEY_SCRIPT_SIMPLEX(opencv_core.FONT_HERSHEY_SCRIPT_SIMPLEX), /** more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX */ + FONT_HERSHEY_SCRIPT_COMPLEX(opencv_core.FONT_HERSHEY_SCRIPT_COMPLEX), /** flag for italic font */ + FONT_ITALIC(opencv_core.FONT_ITALIC); + + public final int value; + + HersheyFontsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/KmeansFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/KmeansFlagsEnum.java new file mode 100644 index 0000000000..74153a25f8 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/KmeansFlagsEnum.java @@ -0,0 +1,20 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum KmeansFlagsEnum { + + /** Select random initial centers in each attempt.*/ + KMEANS_RANDOM_CENTERS(opencv_core.KMEANS_RANDOM_CENTERS), /** Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].*/ + KMEANS_PP_CENTERS(opencv_core.KMEANS_PP_CENTERS), /** During the first (and possibly the only) attempt, use the + user-supplied labels instead of computing them from the initial centers. For the second and + further attempts, use the random or semi-random centers. Use one of KMEANS_\*_CENTERS flag + to specify the exact method.*/ + KMEANS_USE_INITIAL_LABELS(opencv_core.KMEANS_USE_INITIAL_LABELS); + + public final int value; + + KmeansFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/LineTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/LineTypesEnum.java new file mode 100644 index 0000000000..d8afcc8d97 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/LineTypesEnum.java @@ -0,0 +1,17 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum LineTypesEnum { + + FILLED(opencv_core.FILLED), /** 4-connected line */ + LINE_4(opencv_core.LINE_4), /** 8-connected line */ + LINE_8(opencv_core.LINE_8), /** antialiased line */ + LINE_AA(opencv_core.LINE_AA); + + public final int value; + + LineTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/MatEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/MatEnum.java new file mode 100644 index 0000000000..4f074580d0 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/MatEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum MatEnum { + + MAGIC_VAL(opencv_core.Mat.MAGIC_VAL), AUTO_STEP(opencv_core.Mat.AUTO_STEP), CONTINUOUS_FLAG(opencv_core.Mat.CONTINUOUS_FLAG), SUBMATRIX_FLAG(opencv_core.Mat.SUBMATRIX_FLAG), MAGIC_MASK(opencv_core.Mat.MAGIC_MASK), TYPE_MASK(opencv_core.Mat.TYPE_MASK), DEPTH_MASK(opencv_core.Mat.DEPTH_MASK); + + public final int value; + + MatEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/NormTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/NormTypesEnum.java new file mode 100644 index 0000000000..197759c7ec --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/NormTypesEnum.java @@ -0,0 +1,16 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum NormTypesEnum { + + NORM_INF(opencv_core.NORM_INF), NORM_L1(opencv_core.NORM_L1), NORM_L2(opencv_core.NORM_L2), NORM_L2SQR(opencv_core.NORM_L2SQR), NORM_HAMMING(opencv_core.NORM_HAMMING), NORM_HAMMING2(opencv_core.NORM_HAMMING2), NORM_TYPE_MASK(opencv_core.NORM_TYPE_MASK), /** flag */ + NORM_RELATIVE(opencv_core.NORM_RELATIVE), /** flag */ + NORM_MINMAX(opencv_core.NORM_MINMAX); + + public final int value; + + NormTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/PCAFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/PCAFlagsEnum.java new file mode 100644 index 0000000000..cd15575fa1 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/PCAFlagsEnum.java @@ -0,0 +1,16 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum PCAFlagsEnum { + + /** indicates that the input samples are stored as matrix rows */ + DATA_AS_ROW(opencv_core.PCA.DATA_AS_ROW), /** indicates that the input samples are stored as matrix columns */ + DATA_AS_COL(opencv_core.PCA.DATA_AS_COL), USE_AVG(opencv_core.PCA.USE_AVG); + + public final int value; + + PCAFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ParamEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ParamEnum.java new file mode 100644 index 0000000000..3740fb6653 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ParamEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum ParamEnum { + + INT(opencv_core.Param.INT), BOOLEAN(opencv_core.Param.BOOLEAN), REAL(opencv_core.Param.REAL), STRING(opencv_core.Param.STRING), MAT(opencv_core.Param.MAT), MAT_VECTOR(opencv_core.Param.MAT_VECTOR), ALGORITHM(opencv_core.Param.ALGORITHM), FLOAT(opencv_core.Param.FLOAT), UNSIGNED_INT(opencv_core.Param.UNSIGNED_INT), UINT64(opencv_core.Param.UINT64), UCHAR(opencv_core.Param.UCHAR); + + public final int value; + + ParamEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/RNGEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/RNGEnum.java new file mode 100644 index 0000000000..9f2a3c5953 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/RNGEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum RNGEnum { + + UNIFORM(opencv_core.RNG.UNIFORM), NORMAL(opencv_core.RNG.NORMAL); + + public final int value; + + RNGEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ReduceTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ReduceTypesEnum.java new file mode 100644 index 0000000000..e943bef5ba --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/ReduceTypesEnum.java @@ -0,0 +1,18 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum ReduceTypesEnum { + + /** the output is the sum of all rows/columns of the matrix. */ + REDUCE_SUM(opencv_core.REDUCE_SUM), /** the output is the mean vector of all rows/columns of the matrix. */ + REDUCE_AVG(opencv_core.REDUCE_AVG), /** the output is the maximum (column/row-wise) of all rows/columns of the matrix. */ + REDUCE_MAX(opencv_core.REDUCE_MAX), /** the output is the minimum (column/row-wise) of all rows/columns of the matrix. */ + REDUCE_MIN(opencv_core.REDUCE_MIN); + + public final int value; + + ReduceTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SVDFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SVDFlagsEnum.java new file mode 100644 index 0000000000..b81d55402a --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SVDFlagsEnum.java @@ -0,0 +1,21 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum SVDFlagsEnum { + + /** allow the algorithm to modify the decomposed matrix; it can save space and speed up + processing. currently ignored. */ + MODIFY_A(opencv_core.SVD.MODIFY_A), /** indicates that only a vector of singular values `w` is to be processed, while u and vt + will be set to empty matrices */ + NO_UV(opencv_core.SVD.NO_UV), /** when the matrix is not square, by default the algorithm produces u and vt matrices of + sufficiently large size for the further A reconstruction; if, however, FULL_UV flag is + specified, u and vt will be full-size square orthogonal matrices.*/ + FULL_UV(opencv_core.SVD.FULL_UV); + + public final int value; + + SVDFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SolveLPResultEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SolveLPResultEnum.java new file mode 100644 index 0000000000..34dd7f45da --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SolveLPResultEnum.java @@ -0,0 +1,18 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum SolveLPResultEnum { + + /** problem is unbounded (target function can achieve arbitrary high values) */ + SOLVELP_UNBOUNDED(opencv_core.SOLVELP_UNBOUNDED), /** problem is unfeasible (there are no points that satisfy all the constraints imposed) */ + SOLVELP_UNFEASIBLE(opencv_core.SOLVELP_UNFEASIBLE), /** there is only one maximum for target function */ + SOLVELP_SINGLE(opencv_core.SOLVELP_SINGLE), /** there are multiple maxima for target function - the arbitrary one is returned */ + SOLVELP_MULTI(opencv_core.SOLVELP_MULTI); + + public final int value; + + SolveLPResultEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SortFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SortFlagsEnum.java new file mode 100644 index 0000000000..9dff6cf33e --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SortFlagsEnum.java @@ -0,0 +1,23 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum SortFlagsEnum { + + /** each matrix row is sorted independently */ + SORT_EVERY_ROW(opencv_core.SORT_EVERY_ROW), /** each matrix column is sorted + * independently; this flag and the previous one are + * mutually exclusive. */ + SORT_EVERY_COLUMN(opencv_core.SORT_EVERY_COLUMN), /** each matrix row is sorted in the ascending + * order. */ + SORT_ASCENDING(opencv_core.SORT_ASCENDING), /** each matrix row is sorted in the + * descending order; this flag and the previous one are also + * mutually exclusive. */ + SORT_DESCENDING(opencv_core.SORT_DESCENDING); + + public final int value; + + SortFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SparseMatEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SparseMatEnum.java new file mode 100644 index 0000000000..6325e797fd --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/SparseMatEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum SparseMatEnum { + + MAGIC_VAL(opencv_core.SparseMat.MAGIC_VAL), MAX_DIM(opencv_core.SparseMat.MAX_DIM), HASH_SCALE(opencv_core.SparseMat.HASH_SCALE), HASH_BIT(opencv_core.SparseMat.HASH_BIT); + + public final int value; + + SparseMatEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/TermCriteriaTypeEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/TermCriteriaTypeEnum.java new file mode 100644 index 0000000000..bd9fa9318c --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/TermCriteriaTypeEnum.java @@ -0,0 +1,16 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum TermCriteriaTypeEnum { + + /** the maximum number of iterations or elements to compute */ + COUNT(opencv_core.TermCriteria.COUNT), MAX_ITER(opencv_core.TermCriteria.MAX_ITER), /** the desired accuracy or change in parameters at which the iterative algorithm stops */ + EPS(opencv_core.TermCriteria.EPS); + + public final int value; + + TermCriteriaTypeEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatDataEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatDataEnum.java new file mode 100644 index 0000000000..5c9544bc28 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatDataEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum UMatDataEnum { + + COPY_ON_MAP(opencv_core.UMatData.COPY_ON_MAP), HOST_COPY_OBSOLETE(opencv_core.UMatData.HOST_COPY_OBSOLETE), DEVICE_COPY_OBSOLETE(opencv_core.UMatData.DEVICE_COPY_OBSOLETE), TEMP_UMAT(opencv_core.UMatData.TEMP_UMAT), TEMP_COPIED_UMAT(opencv_core.UMatData.TEMP_COPIED_UMAT), USER_ALLOCATED(opencv_core.UMatData.USER_ALLOCATED), DEVICE_MEM_MAPPED(opencv_core.UMatData.DEVICE_MEM_MAPPED); + + public final int value; + + UMatDataEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatEnum.java new file mode 100644 index 0000000000..4dc52d9ecc --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum UMatEnum { + + MAGIC_VAL(opencv_core.UMat.MAGIC_VAL), AUTO_STEP(opencv_core.UMat.AUTO_STEP), CONTINUOUS_FLAG(opencv_core.UMat.CONTINUOUS_FLAG), SUBMATRIX_FLAG(opencv_core.UMat.SUBMATRIX_FLAG), MAGIC_MASK(opencv_core.UMat.MAGIC_MASK), TYPE_MASK(opencv_core.UMat.TYPE_MASK), DEPTH_MASK(opencv_core.UMat.DEPTH_MASK); + + public final int value; + + UMatEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatUsageFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatUsageFlagsEnum.java new file mode 100644 index 0000000000..d82fd0fe57 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_core/enumeration/UMatUsageFlagsEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_core.enumeration; + +import org.bytedeco.javacpp.opencv_core; + +public enum UMatUsageFlagsEnum { + + USAGE_DEFAULT(opencv_core.USAGE_DEFAULT), USAGE_ALLOCATE_HOST_MEMORY(opencv_core.USAGE_ALLOCATE_HOST_MEMORY), USAGE_ALLOCATE_DEVICE_MEMORY(opencv_core.USAGE_ALLOCATE_DEVICE_MEMORY), USAGE_ALLOCATE_SHARED_MEMORY(opencv_core.USAGE_ALLOCATE_SHARED_MEMORY), __UMAT_USAGE_FLAGS_32BIT(opencv_core.__UMAT_USAGE_FLAGS_32BIT); + + public final int value; + + UMatUsageFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/AdaptiveThresholdTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/AdaptiveThresholdTypesEnum.java new file mode 100644 index 0000000000..f2a863be5e --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/AdaptiveThresholdTypesEnum.java @@ -0,0 +1,20 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum AdaptiveThresholdTypesEnum { + + /** the threshold value \f$T(x,y)\f$ is a mean of the \f$\texttt{blockSize} \times + \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ minus C */ + ADAPTIVE_THRESH_MEAN_C(opencv_imgproc.ADAPTIVE_THRESH_MEAN_C), /** the threshold value \f$T(x, y)\f$ is a weighted sum (cross-correlation with a Gaussian + window) of the \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ + minus C . The default sigma (standard deviation) is used for the specified blockSize . See + cv::getGaussianKernel*/ + ADAPTIVE_THRESH_GAUSSIAN_C(opencv_imgproc.ADAPTIVE_THRESH_GAUSSIAN_C); + + public final int value; + + AdaptiveThresholdTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ColorConversionCodesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ColorConversionCodesEnum.java new file mode 100644 index 0000000000..32cf3240af --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ColorConversionCodesEnum.java @@ -0,0 +1,37 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum ColorConversionCodesEnum { + + /** add alpha channel to RGB or BGR image */ + COLOR_BGR2BGRA(opencv_imgproc.COLOR_BGR2BGRA), COLOR_RGB2RGBA(opencv_imgproc.COLOR_RGB2RGBA), /** remove alpha channel from RGB or BGR image */ + COLOR_BGRA2BGR(opencv_imgproc.COLOR_BGRA2BGR), COLOR_RGBA2RGB(opencv_imgproc.COLOR_RGBA2RGB), /** convert between RGB and BGR color spaces (with or without alpha channel) */ + COLOR_BGR2RGBA(opencv_imgproc.COLOR_BGR2RGBA), COLOR_RGB2BGRA(opencv_imgproc.COLOR_RGB2BGRA), COLOR_RGBA2BGR(opencv_imgproc.COLOR_RGBA2BGR), COLOR_BGRA2RGB(opencv_imgproc.COLOR_BGRA2RGB), COLOR_BGR2RGB(opencv_imgproc.COLOR_BGR2RGB), COLOR_RGB2BGR(opencv_imgproc.COLOR_RGB2BGR), COLOR_BGRA2RGBA(opencv_imgproc.COLOR_BGRA2RGBA), COLOR_RGBA2BGRA(opencv_imgproc.COLOR_RGBA2BGRA), /** convert between RGB/BGR and grayscale, @ref color_convert_rgb_gray "color conversions" */ + COLOR_BGR2GRAY(opencv_imgproc.COLOR_BGR2GRAY), COLOR_RGB2GRAY(opencv_imgproc.COLOR_RGB2GRAY), COLOR_GRAY2BGR(opencv_imgproc.COLOR_GRAY2BGR), COLOR_GRAY2RGB(opencv_imgproc.COLOR_GRAY2RGB), COLOR_GRAY2BGRA(opencv_imgproc.COLOR_GRAY2BGRA), COLOR_GRAY2RGBA(opencv_imgproc.COLOR_GRAY2RGBA), COLOR_BGRA2GRAY(opencv_imgproc.COLOR_BGRA2GRAY), COLOR_RGBA2GRAY(opencv_imgproc.COLOR_RGBA2GRAY), /** convert between RGB/BGR and BGR565 (16-bit images) */ + COLOR_BGR2BGR565(opencv_imgproc.COLOR_BGR2BGR565), COLOR_RGB2BGR565(opencv_imgproc.COLOR_RGB2BGR565), COLOR_BGR5652BGR(opencv_imgproc.COLOR_BGR5652BGR), COLOR_BGR5652RGB(opencv_imgproc.COLOR_BGR5652RGB), COLOR_BGRA2BGR565(opencv_imgproc.COLOR_BGRA2BGR565), COLOR_RGBA2BGR565(opencv_imgproc.COLOR_RGBA2BGR565), COLOR_BGR5652BGRA(opencv_imgproc.COLOR_BGR5652BGRA), COLOR_BGR5652RGBA(opencv_imgproc.COLOR_BGR5652RGBA), /** convert between grayscale to BGR565 (16-bit images) */ + COLOR_GRAY2BGR565(opencv_imgproc.COLOR_GRAY2BGR565), COLOR_BGR5652GRAY(opencv_imgproc.COLOR_BGR5652GRAY), /** convert between RGB/BGR and BGR555 (16-bit images) */ + COLOR_BGR2BGR555(opencv_imgproc.COLOR_BGR2BGR555), COLOR_RGB2BGR555(opencv_imgproc.COLOR_RGB2BGR555), COLOR_BGR5552BGR(opencv_imgproc.COLOR_BGR5552BGR), COLOR_BGR5552RGB(opencv_imgproc.COLOR_BGR5552RGB), COLOR_BGRA2BGR555(opencv_imgproc.COLOR_BGRA2BGR555), COLOR_RGBA2BGR555(opencv_imgproc.COLOR_RGBA2BGR555), COLOR_BGR5552BGRA(opencv_imgproc.COLOR_BGR5552BGRA), COLOR_BGR5552RGBA(opencv_imgproc.COLOR_BGR5552RGBA), /** convert between grayscale and BGR555 (16-bit images) */ + COLOR_GRAY2BGR555(opencv_imgproc.COLOR_GRAY2BGR555), COLOR_BGR5552GRAY(opencv_imgproc.COLOR_BGR5552GRAY), /** convert RGB/BGR to CIE XYZ, @ref color_convert_rgb_xyz "color conversions" */ + COLOR_BGR2XYZ(opencv_imgproc.COLOR_BGR2XYZ), COLOR_RGB2XYZ(opencv_imgproc.COLOR_RGB2XYZ), COLOR_XYZ2BGR(opencv_imgproc.COLOR_XYZ2BGR), COLOR_XYZ2RGB(opencv_imgproc.COLOR_XYZ2RGB), /** convert RGB/BGR to luma-chroma (aka YCC), @ref color_convert_rgb_ycrcb "color conversions" */ + COLOR_BGR2YCrCb(opencv_imgproc.COLOR_BGR2YCrCb), COLOR_RGB2YCrCb(opencv_imgproc.COLOR_RGB2YCrCb), COLOR_YCrCb2BGR(opencv_imgproc.COLOR_YCrCb2BGR), COLOR_YCrCb2RGB(opencv_imgproc.COLOR_YCrCb2RGB), /** convert RGB/BGR to HSV (hue saturation value), @ref color_convert_rgb_hsv "color conversions" */ + COLOR_BGR2HSV(opencv_imgproc.COLOR_BGR2HSV), COLOR_RGB2HSV(opencv_imgproc.COLOR_RGB2HSV), /** convert RGB/BGR to CIE Lab, @ref color_convert_rgb_lab "color conversions" */ + COLOR_BGR2Lab(opencv_imgproc.COLOR_BGR2Lab), COLOR_RGB2Lab(opencv_imgproc.COLOR_RGB2Lab), /** convert RGB/BGR to CIE Luv, @ref color_convert_rgb_luv "color conversions" */ + COLOR_BGR2Luv(opencv_imgproc.COLOR_BGR2Luv), COLOR_RGB2Luv(opencv_imgproc.COLOR_RGB2Luv), /** convert RGB/BGR to HLS (hue lightness saturation), @ref color_convert_rgb_hls "color conversions" */ + COLOR_BGR2HLS(opencv_imgproc.COLOR_BGR2HLS), COLOR_RGB2HLS(opencv_imgproc.COLOR_RGB2HLS), /** backward conversions to RGB/BGR */ + COLOR_HSV2BGR(opencv_imgproc.COLOR_HSV2BGR), COLOR_HSV2RGB(opencv_imgproc.COLOR_HSV2RGB), COLOR_Lab2BGR(opencv_imgproc.COLOR_Lab2BGR), COLOR_Lab2RGB(opencv_imgproc.COLOR_Lab2RGB), COLOR_Luv2BGR(opencv_imgproc.COLOR_Luv2BGR), COLOR_Luv2RGB(opencv_imgproc.COLOR_Luv2RGB), COLOR_HLS2BGR(opencv_imgproc.COLOR_HLS2BGR), COLOR_HLS2RGB(opencv_imgproc.COLOR_HLS2RGB), COLOR_BGR2HSV_FULL(opencv_imgproc.COLOR_BGR2HSV_FULL), COLOR_RGB2HSV_FULL(opencv_imgproc.COLOR_RGB2HSV_FULL), COLOR_BGR2HLS_FULL(opencv_imgproc.COLOR_BGR2HLS_FULL), COLOR_RGB2HLS_FULL(opencv_imgproc.COLOR_RGB2HLS_FULL), COLOR_HSV2BGR_FULL(opencv_imgproc.COLOR_HSV2BGR_FULL), COLOR_HSV2RGB_FULL(opencv_imgproc.COLOR_HSV2RGB_FULL), COLOR_HLS2BGR_FULL(opencv_imgproc.COLOR_HLS2BGR_FULL), COLOR_HLS2RGB_FULL(opencv_imgproc.COLOR_HLS2RGB_FULL), COLOR_LBGR2Lab(opencv_imgproc.COLOR_LBGR2Lab), COLOR_LRGB2Lab(opencv_imgproc.COLOR_LRGB2Lab), COLOR_LBGR2Luv(opencv_imgproc.COLOR_LBGR2Luv), COLOR_LRGB2Luv(opencv_imgproc.COLOR_LRGB2Luv), COLOR_Lab2LBGR(opencv_imgproc.COLOR_Lab2LBGR), COLOR_Lab2LRGB(opencv_imgproc.COLOR_Lab2LRGB), COLOR_Luv2LBGR(opencv_imgproc.COLOR_Luv2LBGR), COLOR_Luv2LRGB(opencv_imgproc.COLOR_Luv2LRGB), /** convert between RGB/BGR and YUV */ + COLOR_BGR2YUV(opencv_imgproc.COLOR_BGR2YUV), COLOR_RGB2YUV(opencv_imgproc.COLOR_RGB2YUV), COLOR_YUV2BGR(opencv_imgproc.COLOR_YUV2BGR), COLOR_YUV2RGB(opencv_imgproc.COLOR_YUV2RGB), /** YUV 4:2:0 family to RGB */ + COLOR_YUV2RGB_NV12(opencv_imgproc.COLOR_YUV2RGB_NV12), COLOR_YUV2BGR_NV12(opencv_imgproc.COLOR_YUV2BGR_NV12), COLOR_YUV2RGB_NV21(opencv_imgproc.COLOR_YUV2RGB_NV21), COLOR_YUV2BGR_NV21(opencv_imgproc.COLOR_YUV2BGR_NV21), COLOR_YUV420sp2RGB(opencv_imgproc.COLOR_YUV420sp2RGB), COLOR_YUV420sp2BGR(opencv_imgproc.COLOR_YUV420sp2BGR), COLOR_YUV2RGBA_NV12(opencv_imgproc.COLOR_YUV2RGBA_NV12), COLOR_YUV2BGRA_NV12(opencv_imgproc.COLOR_YUV2BGRA_NV12), COLOR_YUV2RGBA_NV21(opencv_imgproc.COLOR_YUV2RGBA_NV21), COLOR_YUV2BGRA_NV21(opencv_imgproc.COLOR_YUV2BGRA_NV21), COLOR_YUV420sp2RGBA(opencv_imgproc.COLOR_YUV420sp2RGBA), COLOR_YUV420sp2BGRA(opencv_imgproc.COLOR_YUV420sp2BGRA), COLOR_YUV2RGB_YV12(opencv_imgproc.COLOR_YUV2RGB_YV12), COLOR_YUV2BGR_YV12(opencv_imgproc.COLOR_YUV2BGR_YV12), COLOR_YUV2RGB_IYUV(opencv_imgproc.COLOR_YUV2RGB_IYUV), COLOR_YUV2BGR_IYUV(opencv_imgproc.COLOR_YUV2BGR_IYUV), COLOR_YUV2RGB_I420(opencv_imgproc.COLOR_YUV2RGB_I420), COLOR_YUV2BGR_I420(opencv_imgproc.COLOR_YUV2BGR_I420), COLOR_YUV420p2RGB(opencv_imgproc.COLOR_YUV420p2RGB), COLOR_YUV420p2BGR(opencv_imgproc.COLOR_YUV420p2BGR), COLOR_YUV2RGBA_YV12(opencv_imgproc.COLOR_YUV2RGBA_YV12), COLOR_YUV2BGRA_YV12(opencv_imgproc.COLOR_YUV2BGRA_YV12), COLOR_YUV2RGBA_IYUV(opencv_imgproc.COLOR_YUV2RGBA_IYUV), COLOR_YUV2BGRA_IYUV(opencv_imgproc.COLOR_YUV2BGRA_IYUV), COLOR_YUV2RGBA_I420(opencv_imgproc.COLOR_YUV2RGBA_I420), COLOR_YUV2BGRA_I420(opencv_imgproc.COLOR_YUV2BGRA_I420), COLOR_YUV420p2RGBA(opencv_imgproc.COLOR_YUV420p2RGBA), COLOR_YUV420p2BGRA(opencv_imgproc.COLOR_YUV420p2BGRA), COLOR_YUV2GRAY_420(opencv_imgproc.COLOR_YUV2GRAY_420), COLOR_YUV2GRAY_NV21(opencv_imgproc.COLOR_YUV2GRAY_NV21), COLOR_YUV2GRAY_NV12(opencv_imgproc.COLOR_YUV2GRAY_NV12), COLOR_YUV2GRAY_YV12(opencv_imgproc.COLOR_YUV2GRAY_YV12), COLOR_YUV2GRAY_IYUV(opencv_imgproc.COLOR_YUV2GRAY_IYUV), COLOR_YUV2GRAY_I420(opencv_imgproc.COLOR_YUV2GRAY_I420), COLOR_YUV420sp2GRAY(opencv_imgproc.COLOR_YUV420sp2GRAY), COLOR_YUV420p2GRAY(opencv_imgproc.COLOR_YUV420p2GRAY), /** YUV 4:2:2 family to RGB */ + COLOR_YUV2RGB_UYVY(opencv_imgproc.COLOR_YUV2RGB_UYVY), COLOR_YUV2BGR_UYVY(opencv_imgproc.COLOR_YUV2BGR_UYVY), COLOR_YUV2RGB_Y422(opencv_imgproc.COLOR_YUV2RGB_Y422), COLOR_YUV2BGR_Y422(opencv_imgproc.COLOR_YUV2BGR_Y422), COLOR_YUV2RGB_UYNV(opencv_imgproc.COLOR_YUV2RGB_UYNV), COLOR_YUV2BGR_UYNV(opencv_imgproc.COLOR_YUV2BGR_UYNV), COLOR_YUV2RGBA_UYVY(opencv_imgproc.COLOR_YUV2RGBA_UYVY), COLOR_YUV2BGRA_UYVY(opencv_imgproc.COLOR_YUV2BGRA_UYVY), COLOR_YUV2RGBA_Y422(opencv_imgproc.COLOR_YUV2RGBA_Y422), COLOR_YUV2BGRA_Y422(opencv_imgproc.COLOR_YUV2BGRA_Y422), COLOR_YUV2RGBA_UYNV(opencv_imgproc.COLOR_YUV2RGBA_UYNV), COLOR_YUV2BGRA_UYNV(opencv_imgproc.COLOR_YUV2BGRA_UYNV), COLOR_YUV2RGB_YUY2(opencv_imgproc.COLOR_YUV2RGB_YUY2), COLOR_YUV2BGR_YUY2(opencv_imgproc.COLOR_YUV2BGR_YUY2), COLOR_YUV2RGB_YVYU(opencv_imgproc.COLOR_YUV2RGB_YVYU), COLOR_YUV2BGR_YVYU(opencv_imgproc.COLOR_YUV2BGR_YVYU), COLOR_YUV2RGB_YUYV(opencv_imgproc.COLOR_YUV2RGB_YUYV), COLOR_YUV2BGR_YUYV(opencv_imgproc.COLOR_YUV2BGR_YUYV), COLOR_YUV2RGB_YUNV(opencv_imgproc.COLOR_YUV2RGB_YUNV), COLOR_YUV2BGR_YUNV(opencv_imgproc.COLOR_YUV2BGR_YUNV), COLOR_YUV2RGBA_YUY2(opencv_imgproc.COLOR_YUV2RGBA_YUY2), COLOR_YUV2BGRA_YUY2(opencv_imgproc.COLOR_YUV2BGRA_YUY2), COLOR_YUV2RGBA_YVYU(opencv_imgproc.COLOR_YUV2RGBA_YVYU), COLOR_YUV2BGRA_YVYU(opencv_imgproc.COLOR_YUV2BGRA_YVYU), COLOR_YUV2RGBA_YUYV(opencv_imgproc.COLOR_YUV2RGBA_YUYV), COLOR_YUV2BGRA_YUYV(opencv_imgproc.COLOR_YUV2BGRA_YUYV), COLOR_YUV2RGBA_YUNV(opencv_imgproc.COLOR_YUV2RGBA_YUNV), COLOR_YUV2BGRA_YUNV(opencv_imgproc.COLOR_YUV2BGRA_YUNV), COLOR_YUV2GRAY_UYVY(opencv_imgproc.COLOR_YUV2GRAY_UYVY), COLOR_YUV2GRAY_YUY2(opencv_imgproc.COLOR_YUV2GRAY_YUY2), COLOR_YUV2GRAY_Y422(opencv_imgproc.COLOR_YUV2GRAY_Y422), COLOR_YUV2GRAY_UYNV(opencv_imgproc.COLOR_YUV2GRAY_UYNV), COLOR_YUV2GRAY_YVYU(opencv_imgproc.COLOR_YUV2GRAY_YVYU), COLOR_YUV2GRAY_YUYV(opencv_imgproc.COLOR_YUV2GRAY_YUYV), COLOR_YUV2GRAY_YUNV(opencv_imgproc.COLOR_YUV2GRAY_YUNV), /** alpha premultiplication */ + COLOR_RGBA2mRGBA(opencv_imgproc.COLOR_RGBA2mRGBA), COLOR_mRGBA2RGBA(opencv_imgproc.COLOR_mRGBA2RGBA), /** RGB to YUV 4:2:0 family */ + COLOR_RGB2YUV_I420(opencv_imgproc.COLOR_RGB2YUV_I420), COLOR_BGR2YUV_I420(opencv_imgproc.COLOR_BGR2YUV_I420), COLOR_RGB2YUV_IYUV(opencv_imgproc.COLOR_RGB2YUV_IYUV), COLOR_BGR2YUV_IYUV(opencv_imgproc.COLOR_BGR2YUV_IYUV), COLOR_RGBA2YUV_I420(opencv_imgproc.COLOR_RGBA2YUV_I420), COLOR_BGRA2YUV_I420(opencv_imgproc.COLOR_BGRA2YUV_I420), COLOR_RGBA2YUV_IYUV(opencv_imgproc.COLOR_RGBA2YUV_IYUV), COLOR_BGRA2YUV_IYUV(opencv_imgproc.COLOR_BGRA2YUV_IYUV), COLOR_RGB2YUV_YV12(opencv_imgproc.COLOR_RGB2YUV_YV12), COLOR_BGR2YUV_YV12(opencv_imgproc.COLOR_BGR2YUV_YV12), COLOR_RGBA2YUV_YV12(opencv_imgproc.COLOR_RGBA2YUV_YV12), COLOR_BGRA2YUV_YV12(opencv_imgproc.COLOR_BGRA2YUV_YV12), /** Demosaicing */ + COLOR_BayerBG2BGR(opencv_imgproc.COLOR_BayerBG2BGR), COLOR_BayerGB2BGR(opencv_imgproc.COLOR_BayerGB2BGR), COLOR_BayerRG2BGR(opencv_imgproc.COLOR_BayerRG2BGR), COLOR_BayerGR2BGR(opencv_imgproc.COLOR_BayerGR2BGR), COLOR_BayerBG2RGB(opencv_imgproc.COLOR_BayerBG2RGB), COLOR_BayerGB2RGB(opencv_imgproc.COLOR_BayerGB2RGB), COLOR_BayerRG2RGB(opencv_imgproc.COLOR_BayerRG2RGB), COLOR_BayerGR2RGB(opencv_imgproc.COLOR_BayerGR2RGB), COLOR_BayerBG2GRAY(opencv_imgproc.COLOR_BayerBG2GRAY), COLOR_BayerGB2GRAY(opencv_imgproc.COLOR_BayerGB2GRAY), COLOR_BayerRG2GRAY(opencv_imgproc.COLOR_BayerRG2GRAY), COLOR_BayerGR2GRAY(opencv_imgproc.COLOR_BayerGR2GRAY), /** Demosaicing using Variable Number of Gradients */ + COLOR_BayerBG2BGR_VNG(opencv_imgproc.COLOR_BayerBG2BGR_VNG), COLOR_BayerGB2BGR_VNG(opencv_imgproc.COLOR_BayerGB2BGR_VNG), COLOR_BayerRG2BGR_VNG(opencv_imgproc.COLOR_BayerRG2BGR_VNG), COLOR_BayerGR2BGR_VNG(opencv_imgproc.COLOR_BayerGR2BGR_VNG), COLOR_BayerBG2RGB_VNG(opencv_imgproc.COLOR_BayerBG2RGB_VNG), COLOR_BayerGB2RGB_VNG(opencv_imgproc.COLOR_BayerGB2RGB_VNG), COLOR_BayerRG2RGB_VNG(opencv_imgproc.COLOR_BayerRG2RGB_VNG), COLOR_BayerGR2RGB_VNG(opencv_imgproc.COLOR_BayerGR2RGB_VNG), /** Edge-Aware Demosaicing */ + COLOR_BayerBG2BGR_EA(opencv_imgproc.COLOR_BayerBG2BGR_EA), COLOR_BayerGB2BGR_EA(opencv_imgproc.COLOR_BayerGB2BGR_EA), COLOR_BayerRG2BGR_EA(opencv_imgproc.COLOR_BayerRG2BGR_EA), COLOR_BayerGR2BGR_EA(opencv_imgproc.COLOR_BayerGR2BGR_EA), COLOR_BayerBG2RGB_EA(opencv_imgproc.COLOR_BayerBG2RGB_EA), COLOR_BayerGB2RGB_EA(opencv_imgproc.COLOR_BayerGB2RGB_EA), COLOR_BayerRG2RGB_EA(opencv_imgproc.COLOR_BayerRG2RGB_EA), COLOR_BayerGR2RGB_EA(opencv_imgproc.COLOR_BayerGR2RGB_EA), COLOR_COLORCVT_MAX(opencv_imgproc.COLOR_COLORCVT_MAX); + + public final int value; + + ColorConversionCodesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ColormapTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ColormapTypesEnum.java new file mode 100644 index 0000000000..2d58505259 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ColormapTypesEnum.java @@ -0,0 +1,27 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum ColormapTypesEnum { + + /** ![autumn](pics/colormaps/colorscale_autumn.jpg) */ + COLORMAP_AUTUMN(opencv_imgproc.COLORMAP_AUTUMN), /** ![bone](pics/colormaps/colorscale_bone.jpg) */ + COLORMAP_BONE(opencv_imgproc.COLORMAP_BONE), /** ![jet](pics/colormaps/colorscale_jet.jpg) */ + COLORMAP_JET(opencv_imgproc.COLORMAP_JET), /** ![winter](pics/colormaps/colorscale_winter.jpg) */ + COLORMAP_WINTER(opencv_imgproc.COLORMAP_WINTER), /** ![rainbow](pics/colormaps/colorscale_rainbow.jpg) */ + COLORMAP_RAINBOW(opencv_imgproc.COLORMAP_RAINBOW), /** ![ocean](pics/colormaps/colorscale_ocean.jpg) */ + COLORMAP_OCEAN(opencv_imgproc.COLORMAP_OCEAN), /** ![summer](pics/colormaps/colorscale_summer.jpg) */ + COLORMAP_SUMMER(opencv_imgproc.COLORMAP_SUMMER), /** ![spring](pics/colormaps/colorscale_spring.jpg) */ + COLORMAP_SPRING(opencv_imgproc.COLORMAP_SPRING), /** ![cool](pics/colormaps/colorscale_cool.jpg) */ + COLORMAP_COOL(opencv_imgproc.COLORMAP_COOL), /** ![HSV](pics/colormaps/colorscale_hsv.jpg) */ + COLORMAP_HSV(opencv_imgproc.COLORMAP_HSV), /** ![pink](pics/colormaps/colorscale_pink.jpg) */ + COLORMAP_PINK(opencv_imgproc.COLORMAP_PINK), /** ![hot](pics/colormaps/colorscale_hot.jpg) */ + COLORMAP_HOT(opencv_imgproc.COLORMAP_HOT), /** ![hot](pics/colormaps/colorscale_parula.jpg) */ + COLORMAP_PARULA(opencv_imgproc.COLORMAP_PARULA); + + public final int value; + + ColormapTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ConnectedComponentsTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ConnectedComponentsTypesEnum.java new file mode 100644 index 0000000000..8edf06a551 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ConnectedComponentsTypesEnum.java @@ -0,0 +1,21 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum ConnectedComponentsTypesEnum { + + /** The leftmost (x) coordinate which is the inclusive start of the bounding + * box in the horizontal direction. */ + CC_STAT_LEFT(opencv_imgproc.CC_STAT_LEFT), /** The topmost (y) coordinate which is the inclusive start of the bounding + * box in the vertical direction. */ + CC_STAT_TOP(opencv_imgproc.CC_STAT_TOP), /** The horizontal size of the bounding box */ + CC_STAT_WIDTH(opencv_imgproc.CC_STAT_WIDTH), /** The vertical size of the bounding box */ + CC_STAT_HEIGHT(opencv_imgproc.CC_STAT_HEIGHT), /** The total area (in pixels) of the connected component */ + CC_STAT_AREA(opencv_imgproc.CC_STAT_AREA), CC_STAT_MAX(opencv_imgproc.CC_STAT_MAX); + + public final int value; + + ConnectedComponentsTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ContourApproximationModesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ContourApproximationModesEnum.java new file mode 100644 index 0000000000..615fc2ae30 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ContourApproximationModesEnum.java @@ -0,0 +1,21 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum ContourApproximationModesEnum { + + /** stores absolutely all the contour points. That is, any 2 subsequent points (x1,y1) and + (x2,y2) of the contour will be either horizontal, vertical or diagonal neighbors, that is, + max(abs(x1-x2),abs(y2-y1))==1. */ + CHAIN_APPROX_NONE(opencv_imgproc.CHAIN_APPROX_NONE), /** compresses horizontal, vertical, and diagonal segments and leaves only their end points. + For example, an up-right rectangular contour is encoded with 4 points. */ + CHAIN_APPROX_SIMPLE(opencv_imgproc.CHAIN_APPROX_SIMPLE), /** applies one of the flavors of the Teh-Chin chain approximation algorithm @cite TehChin89 */ + CHAIN_APPROX_TC89_L1(opencv_imgproc.CHAIN_APPROX_TC89_L1), /** applies one of the flavors of the Teh-Chin chain approximation algorithm @cite TehChin89 */ + CHAIN_APPROX_TC89_KCOS(opencv_imgproc.CHAIN_APPROX_TC89_KCOS); + + public final int value; + + ContourApproximationModesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTransformLabelTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTransformLabelTypesEnum.java new file mode 100644 index 0000000000..c428021659 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTransformLabelTypesEnum.java @@ -0,0 +1,17 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum DistanceTransformLabelTypesEnum { + + /** each connected component of zeros in src (as well as all the non-zero pixels closest to the + connected component) will be assigned the same label */ + DIST_LABEL_CCOMP(opencv_imgproc.DIST_LABEL_CCOMP), /** each zero pixel (and all the non-zero pixels closest to it) gets its own label. */ + DIST_LABEL_PIXEL(opencv_imgproc.DIST_LABEL_PIXEL); + + public final int value; + + DistanceTransformLabelTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTransformMasksEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTransformMasksEnum.java new file mode 100644 index 0000000000..b3ffd5b8c7 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTransformMasksEnum.java @@ -0,0 +1,16 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum DistanceTransformMasksEnum { + + /** mask=3 */ + DIST_MASK_3(opencv_imgproc.DIST_MASK_3), /** mask=5 */ + DIST_MASK_5(opencv_imgproc.DIST_MASK_5), DIST_MASK_PRECISE(opencv_imgproc.DIST_MASK_PRECISE); + + public final int value; + + DistanceTransformMasksEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTypesEnum.java new file mode 100644 index 0000000000..b26519f6f4 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/DistanceTypesEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum DistanceTypesEnum { + + DIST_USER(opencv_imgproc.DIST_USER), DIST_L1(opencv_imgproc.DIST_L1), DIST_L2(opencv_imgproc.DIST_L2), DIST_C(opencv_imgproc.DIST_C), DIST_L12(opencv_imgproc.DIST_L12), DIST_FAIR(opencv_imgproc.DIST_FAIR), DIST_WELSCH(opencv_imgproc.DIST_WELSCH), DIST_HUBER(opencv_imgproc.DIST_HUBER); + + public final int value; + + DistanceTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/FloodFillFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/FloodFillFlagsEnum.java new file mode 100644 index 0000000000..6d874b73a2 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/FloodFillFlagsEnum.java @@ -0,0 +1,19 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum FloodFillFlagsEnum { + + /** If set, the difference between the current pixel and seed pixel is considered. Otherwise, + the difference between neighbor pixels is considered (that is, the range is floating). */ + FLOODFILL_FIXED_RANGE(opencv_imgproc.FLOODFILL_FIXED_RANGE), /** If set, the function does not change the image ( newVal is ignored), and only fills the + mask with the value specified in bits 8-16 of flags as described above. This option only make + sense in function variants that have the mask parameter. */ + FLOODFILL_MASK_ONLY(opencv_imgproc.FLOODFILL_MASK_ONLY); + + public final int value; + + FloodFillFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/GrabCutClassesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/GrabCutClassesEnum.java new file mode 100644 index 0000000000..f71a30f3e8 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/GrabCutClassesEnum.java @@ -0,0 +1,18 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum GrabCutClassesEnum { + + /** an obvious background pixels */ + GC_BGD(opencv_imgproc.GC_BGD), /** an obvious foreground (object) pixel */ + GC_FGD(opencv_imgproc.GC_FGD), /** a possible background pixel */ + GC_PR_BGD(opencv_imgproc.GC_PR_BGD), /** a possible foreground pixel */ + GC_PR_FGD(opencv_imgproc.GC_PR_FGD); + + public final int value; + + GrabCutClassesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/GrabCutModesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/GrabCutModesEnum.java new file mode 100644 index 0000000000..23e0bbcc2f --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/GrabCutModesEnum.java @@ -0,0 +1,20 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum GrabCutModesEnum { + + /** The function initializes the state and the mask using the provided rectangle. After that it + runs iterCount iterations of the algorithm. */ + GC_INIT_WITH_RECT(opencv_imgproc.GC_INIT_WITH_RECT), /** The function initializes the state using the provided mask. Note that GC_INIT_WITH_RECT + and GC_INIT_WITH_MASK can be combined. Then, all the pixels outside of the ROI are + automatically initialized with GC_BGD .*/ + GC_INIT_WITH_MASK(opencv_imgproc.GC_INIT_WITH_MASK), /** The value means that the algorithm should just resume. */ + GC_EVAL(opencv_imgproc.GC_EVAL); + + public final int value; + + GrabCutModesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/HistCompMethodsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/HistCompMethodsEnum.java new file mode 100644 index 0000000000..15333facb1 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/HistCompMethodsEnum.java @@ -0,0 +1,32 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum HistCompMethodsEnum { + + /** Correlation + \f[d(H_1,H_2) = \frac{\sum_I (H_1(I) - \bar{H_1}) (H_2(I) - \bar{H_2})}{\sqrt{\sum_I(H_1(I) - \bar{H_1})^2 \sum_I(H_2(I) - \bar{H_2})^2}}\f] + where + \f[\bar{H_k} = \frac{1}{N} \sum _J H_k(J)\f] + and \f$N\f$ is a total number of histogram bins. */ + HISTCMP_CORREL(opencv_imgproc.HISTCMP_CORREL), /** Chi-Square + \f[d(H_1,H_2) = \sum _I \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)}\f] */ + HISTCMP_CHISQR(opencv_imgproc.HISTCMP_CHISQR), /** Intersection + \f[d(H_1,H_2) = \sum _I \min (H_1(I), H_2(I))\f] */ + HISTCMP_INTERSECT(opencv_imgproc.HISTCMP_INTERSECT), /** Bhattacharyya distance + (In fact, OpenCV computes Hellinger distance, which is related to Bhattacharyya coefficient.) + \f[d(H_1,H_2) = \sqrt{1 - \frac{1}{\sqrt{\bar{H_1} \bar{H_2} N^2}} \sum_I \sqrt{H_1(I) \cdot H_2(I)}}\f] */ + HISTCMP_BHATTACHARYYA(opencv_imgproc.HISTCMP_BHATTACHARYYA), /** Synonym for HISTCMP_BHATTACHARYYA */ + HISTCMP_HELLINGER(opencv_imgproc.HISTCMP_HELLINGER), /** Alternative Chi-Square + \f[d(H_1,H_2) = 2 * \sum _I \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)+H_2(I)}\f] + This alternative formula is regularly used for texture comparison. See e.g. @cite Puzicha1997 */ + HISTCMP_CHISQR_ALT(opencv_imgproc.HISTCMP_CHISQR_ALT), /** Kullback-Leibler divergence + \f[d(H_1,H_2) = \sum _I H_1(I) \log \left(\frac{H_1(I)}{H_2(I)}\right)\f] */ + HISTCMP_KL_DIV(opencv_imgproc.HISTCMP_KL_DIV); + + public final int value; + + HistCompMethodsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/HoughModesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/HoughModesEnum.java new file mode 100644 index 0000000000..26346ddb2d --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/HoughModesEnum.java @@ -0,0 +1,25 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum HoughModesEnum { + + /** classical or standard Hough transform. Every line is represented by two floating-point + numbers \f$(\rho, \theta)\f$ , where \f$\rho\f$ is a distance between (0,0) point and the line, + and \f$\theta\f$ is the angle between x-axis and the normal to the line. Thus, the matrix must + be (the created sequence will be) of CV_32FC2 type */ + HOUGH_STANDARD(opencv_imgproc.HOUGH_STANDARD), /** probabilistic Hough transform (more efficient in case if the picture contains a few long + linear segments). It returns line segments rather than the whole line. Each segment is + represented by starting and ending points, and the matrix must be (the created sequence will + be) of the CV_32SC4 type. */ + HOUGH_PROBABILISTIC(opencv_imgproc.HOUGH_PROBABILISTIC), /** multi-scale variant of the classical Hough transform. The lines are encoded the same way as + HOUGH_STANDARD. */ + HOUGH_MULTI_SCALE(opencv_imgproc.HOUGH_MULTI_SCALE), /** basically *21HT*, described in @cite Yuen90 */ + HOUGH_GRADIENT(opencv_imgproc.HOUGH_GRADIENT); + + public final int value; + + HoughModesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/InterpolationFlagsEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/InterpolationFlagsEnum.java new file mode 100644 index 0000000000..a3fc552559 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/InterpolationFlagsEnum.java @@ -0,0 +1,30 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum InterpolationFlagsEnum { + + /** nearest neighbor interpolation */ + INTER_NEAREST(opencv_imgproc.INTER_NEAREST), /** bilinear interpolation */ + INTER_LINEAR(opencv_imgproc.INTER_LINEAR), /** bicubic interpolation */ + INTER_CUBIC(opencv_imgproc.INTER_CUBIC), /** resampling using pixel area relation. It may be a preferred method for image decimation, as + it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST + method. */ + INTER_AREA(opencv_imgproc.INTER_AREA), /** Lanczos interpolation over 8x8 neighborhood */ + INTER_LANCZOS4(opencv_imgproc.INTER_LANCZOS4), /** mask for interpolation codes */ + INTER_MAX(opencv_imgproc.INTER_MAX), /** flag, fills all of the destination image pixels. If some of them correspond to outliers in the + source image, they are set to zero */ + WARP_FILL_OUTLIERS(opencv_imgproc.WARP_FILL_OUTLIERS), /** flag, inverse transformation + + For example, polar transforms: + - flag is __not__ set: \f$dst( \phi , \rho ) = src(x,y)\f$ + - flag is set: \f$dst(x,y) = src( \phi , \rho )\f$ + */ + WARP_INVERSE_MAP(opencv_imgproc.WARP_INVERSE_MAP); + + public final int value; + + InterpolationFlagsEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/InterpolationMasksEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/InterpolationMasksEnum.java new file mode 100644 index 0000000000..55ef93011d --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/InterpolationMasksEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum InterpolationMasksEnum { + + INTER_BITS(opencv_imgproc.INTER_BITS), INTER_BITS2(opencv_imgproc.INTER_BITS2), INTER_TAB_SIZE(opencv_imgproc.INTER_TAB_SIZE), INTER_TAB_SIZE2(opencv_imgproc.INTER_TAB_SIZE2); + + public final int value; + + InterpolationMasksEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/LineSegmentDetectorModesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/LineSegmentDetectorModesEnum.java new file mode 100644 index 0000000000..37a6059ded --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/LineSegmentDetectorModesEnum.java @@ -0,0 +1,18 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum LineSegmentDetectorModesEnum { + + /** No refinement applied */ + LSD_REFINE_NONE(opencv_imgproc.LSD_REFINE_NONE), /** Standard refinement is applied. E.g. breaking arches into smaller straighter line approximations. */ + LSD_REFINE_STD(opencv_imgproc.LSD_REFINE_STD), /** Advanced refinement. Number of false alarms is calculated, lines are + * refined through increase of precision, decrement in size, etc. */ + LSD_REFINE_ADV(opencv_imgproc.LSD_REFINE_ADV); + + public final int value; + + LineSegmentDetectorModesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/MorphShapesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/MorphShapesEnum.java new file mode 100644 index 0000000000..7380f9c26b --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/MorphShapesEnum.java @@ -0,0 +1,19 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum MorphShapesEnum { + + /** a rectangular structuring element: \f[E_{ij}=1\f] */ + MORPH_RECT(opencv_imgproc.MORPH_RECT), /** a cross-shaped structuring element: + * \f[E_{ij} = \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise}\f] */ + MORPH_CROSS(opencv_imgproc.MORPH_CROSS), /** an elliptic structuring element, that is, a filled ellipse inscribed + * into the rectangle Rect(0, 0, esize.width, 0.esize.height) */ + MORPH_ELLIPSE(opencv_imgproc.MORPH_ELLIPSE); + + public final int value; + + MorphShapesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/MorphTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/MorphTypesEnum.java new file mode 100644 index 0000000000..f70613769f --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/MorphTypesEnum.java @@ -0,0 +1,26 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum MorphTypesEnum { + + /** see cv::erode */ + MORPH_ERODE(opencv_imgproc.MORPH_ERODE), /** see cv::dilate */ + MORPH_DILATE(opencv_imgproc.MORPH_DILATE), /** an opening operation + * \f[\texttt{dst} = \mathrm{open} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \mathrm{erode} ( \texttt{src} , \texttt{element} ))\f] */ + MORPH_OPEN(opencv_imgproc.MORPH_OPEN), /** a closing operation + * \f[\texttt{dst} = \mathrm{close} ( \texttt{src} , \texttt{element} )= \mathrm{erode} ( \mathrm{dilate} ( \texttt{src} , \texttt{element} ))\f] */ + MORPH_CLOSE(opencv_imgproc.MORPH_CLOSE), /** a morphological gradient + * \f[\texttt{dst} = \mathrm{morph\_grad} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \texttt{src} , \texttt{element} )- \mathrm{erode} ( \texttt{src} , \texttt{element} )\f] */ + MORPH_GRADIENT(opencv_imgproc.MORPH_GRADIENT), /** "top hat" + * \f[\texttt{dst} = \mathrm{tophat} ( \texttt{src} , \texttt{element} )= \texttt{src} - \mathrm{open} ( \texttt{src} , \texttt{element} )\f] */ + MORPH_TOPHAT(opencv_imgproc.MORPH_TOPHAT), /** "black hat" + * \f[\texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src}\f] */ + MORPH_BLACKHAT(opencv_imgproc.MORPH_BLACKHAT); + + public final int value; + + MorphTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/RectanglesIntersectTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/RectanglesIntersectTypesEnum.java new file mode 100644 index 0000000000..7e15ff2c2e --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/RectanglesIntersectTypesEnum.java @@ -0,0 +1,17 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum RectanglesIntersectTypesEnum { + + /** No intersection */ + INTERSECT_NONE(opencv_imgproc.INTERSECT_NONE), /** There is a partial intersection */ + INTERSECT_PARTIAL(opencv_imgproc.INTERSECT_PARTIAL), /** One of the rectangle is fully enclosed in the other */ + INTERSECT_FULL(opencv_imgproc.INTERSECT_FULL); + + public final int value; + + RectanglesIntersectTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/RetrievalModesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/RetrievalModesEnum.java new file mode 100644 index 0000000000..cadca9b3d3 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/RetrievalModesEnum.java @@ -0,0 +1,22 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum RetrievalModesEnum { + + /** retrieves only the extreme outer contours. It sets `hierarchy[i][2]=hierarchy[i][3]=-1` for + all the contours. */ + RETR_EXTERNAL(opencv_imgproc.RETR_EXTERNAL), /** retrieves all of the contours without establishing any hierarchical relationships. */ + RETR_LIST(opencv_imgproc.RETR_LIST), /** retrieves all of the contours and organizes them into a two-level hierarchy. At the top + level, there are external boundaries of the components. At the second level, there are + boundaries of the holes. If there is another contour inside a hole of a connected component, it + is still put at the top level. */ + RETR_CCOMP(opencv_imgproc.RETR_CCOMP), /** retrieves all of the contours and reconstructs a full hierarchy of nested contours.*/ + RETR_TREE(opencv_imgproc.RETR_TREE), RETR_FLOODFILL(opencv_imgproc.RETR_FLOODFILL); + + public final int value; + + RetrievalModesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/SubdivEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/SubdivEnum.java new file mode 100644 index 0000000000..89885217da --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/SubdivEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum SubdivEnum { + + PTLOC_ERROR(opencv_imgproc.Subdiv2D.PTLOC_ERROR), PTLOC_OUTSIDE_RECT(opencv_imgproc.Subdiv2D.PTLOC_OUTSIDE_RECT), PTLOC_INSIDE(opencv_imgproc.Subdiv2D.PTLOC_INSIDE), PTLOC_VERTEX(opencv_imgproc.Subdiv2D.PTLOC_VERTEX), PTLOC_ON_EDGE(opencv_imgproc.Subdiv2D.PTLOC_ON_EDGE), NEXT_AROUND_ORG(opencv_imgproc.Subdiv2D.NEXT_AROUND_ORG), NEXT_AROUND_DST(opencv_imgproc.Subdiv2D.NEXT_AROUND_DST), PREV_AROUND_ORG(opencv_imgproc.Subdiv2D.PREV_AROUND_ORG), PREV_AROUND_DST(opencv_imgproc.Subdiv2D.PREV_AROUND_DST), NEXT_AROUND_LEFT(opencv_imgproc.Subdiv2D.NEXT_AROUND_LEFT), NEXT_AROUND_RIGHT(opencv_imgproc.Subdiv2D.NEXT_AROUND_RIGHT), PREV_AROUND_LEFT(opencv_imgproc.Subdiv2D.PREV_AROUND_LEFT), PREV_AROUND_RIGHT(opencv_imgproc.Subdiv2D.PREV_AROUND_RIGHT); + + public final int value; + + SubdivEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/TemplateMatchModesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/TemplateMatchModesEnum.java new file mode 100644 index 0000000000..dc26ba8e3d --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/TemplateMatchModesEnum.java @@ -0,0 +1,22 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum TemplateMatchModesEnum { + + /** \f[R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2\f] */ + TM_SQDIFF(opencv_imgproc.TM_SQDIFF), /** \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f] */ + TM_SQDIFF_NORMED(opencv_imgproc.TM_SQDIFF_NORMED), /** \f[R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y'))\f] */ + TM_CCORR(opencv_imgproc.TM_CCORR), /** \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f] */ + TM_CCORR_NORMED(opencv_imgproc.TM_CCORR_NORMED), /** \f[R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I'(x+x',y+y'))\f] + * where + * \f[\begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}\f] */ + TM_CCOEFF(opencv_imgproc.TM_CCOEFF), /** \f[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }\f] */ + TM_CCOEFF_NORMED(opencv_imgproc.TM_CCOEFF_NORMED); + + public final int value; + + TemplateMatchModesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ThresholdTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ThresholdTypesEnum.java new file mode 100644 index 0000000000..58e62e959c --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/ThresholdTypesEnum.java @@ -0,0 +1,21 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum ThresholdTypesEnum { + + /** \f[\texttt{dst} (x,y) = \fork{\texttt{maxval}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f] */ + THRESH_BINARY(opencv_imgproc.THRESH_BINARY), /** \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f] */ + THRESH_BINARY_INV(opencv_imgproc.THRESH_BINARY_INV), /** \f[\texttt{dst} (x,y) = \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] */ + THRESH_TRUNC(opencv_imgproc.THRESH_TRUNC), /** \f[\texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f] */ + THRESH_TOZERO(opencv_imgproc.THRESH_TOZERO), /** \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] */ + THRESH_TOZERO_INV(opencv_imgproc.THRESH_TOZERO_INV), THRESH_MASK(opencv_imgproc.THRESH_MASK), /** flag, use Otsu algorithm to choose the optimal threshold value */ + THRESH_OTSU(opencv_imgproc.THRESH_OTSU), /** flag, use Triangle algorithm to choose the optimal threshold value */ + THRESH_TRIANGLE(opencv_imgproc.THRESH_TRIANGLE); + + public final int value; + + ThresholdTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/UndistortTypesEnum.java b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/UndistortTypesEnum.java new file mode 100644 index 0000000000..e1fdfc4244 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/generated/opencv_imgproc/enumeration/UndistortTypesEnum.java @@ -0,0 +1,14 @@ +package edu.wpi.grip.generated.opencv_imgproc.enumeration; + +import org.bytedeco.javacpp.opencv_imgproc; + +public enum UndistortTypesEnum { + + PROJ_SPHERICAL_ORTHO(opencv_imgproc.PROJ_SPHERICAL_ORTHO), PROJ_SPHERICAL_EQRECT(opencv_imgproc.PROJ_SPHERICAL_EQRECT); + + public final int value; + + UndistortTypesEnum(int value) { + this.value = value; + } +} diff --git a/core/src/test/java/edu/wpi/grip/core/sources/HttpSourceTest.java b/core/src/test/java/edu/wpi/grip/core/sources/HttpSourceTest.java index 3f5553d187..8a81abc172 100644 --- a/core/src/test/java/edu/wpi/grip/core/sources/HttpSourceTest.java +++ b/core/src/test/java/edu/wpi/grip/core/sources/HttpSourceTest.java @@ -11,7 +11,6 @@ import com.google.common.eventbus.EventBus; -import org.apache.commons.httpclient.URIException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.FileEntity; @@ -42,7 +41,7 @@ public class HttpSourceTest { private CloseableHttpClient postClient; @Before - public void setUp() throws URIException, URISyntaxException { + public void setUp() throws URISyntaxException { GripServer.JettyServerFactory f = new GripServerTest.TestServerFactory(); ContextStore contextStore = new ContextStore(); server = GripServerTest.makeServer(contextStore, f, new Pipeline()); diff --git a/git.gradle b/git.gradle deleted file mode 100644 index eb92543591..0000000000 --- a/git.gradle +++ /dev/null @@ -1,20 +0,0 @@ -def git_provided = false -if (rootProject.file(".git").exists()) { - git_provided = true - project.apply plugin: 'org.ajoberstar.grgit' -} - -ext.getGitCommit = { -> - if (git_provided) return grgit.head().abbreviatedId - return "" -} - -ext.getGitDescribe = { -> - if (git_provided) return grgit.describe() - return "v0.0.0" -} - -ext.getGitDescribeAbbrev = { -> - if (git_provided) return grgit.tag.list().last().getName() - return "v0.0.0" -} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 3a78fc5d34bd310e2cf929f6181bbdbd5314262d..457aad0d98108420a977756b7145c93c8910b076 100644 GIT binary patch delta 49830 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 b|8yMx*;9a("run") { + classpath = sourceSets["main"].runtimeClasspath + main = application.mainClassName + args = listOf("windowed") +} diff --git a/ui/src/test/java/edu/wpi/grip/ui/pipeline/input/InputSocketControllerFactoryTest.java b/ui/src/test/java/edu/wpi/grip/ui/pipeline/input/InputSocketControllerFactoryTest.java index 67ee90720d..dbd072d1fb 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/pipeline/input/InputSocketControllerFactoryTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/pipeline/input/InputSocketControllerFactoryTest.java @@ -14,7 +14,7 @@ import com.google.inject.Injector; import com.google.inject.util.Modules; -import org.junit.Before; +import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -93,8 +93,7 @@ public void start(Stage stage) { stage.show(); } - @Before - @SuppressWarnings("PMD.JUnit4TestShouldUseAfterAnnotation") + @After public void tearDown() { testModule.tearDown(); } diff --git a/ui/ui.gradle.kts b/ui/ui.gradle.kts new file mode 100644 index 0000000000..b982dec998 --- /dev/null +++ b/ui/ui.gradle.kts @@ -0,0 +1,216 @@ +import de.dynamicfiles.projects.gradle.plugins.javafx.JavaFXGradlePluginExtension +import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxNativeTask +import edu.wpi.first.wpilib.opencv.installer.Installer +import java.io.File +import java.io.FileFilter + +plugins { + `application` + id("javafx-gradle-plugin") + id("com.google.osdetector") +} + +if (!(project.hasProperty("generation") || project.hasProperty("genonly"))) { + sourceSets["test"].java { + exclude("**/ui/codegeneration") + exclude("**/ui/codegeneration/**") + } +} + +dependencies { + compile(project(":core")) + compile(project(":ui:preloader")) + //ideProvider project(path= ":core", configuration= "compile") + compile(group = "org.controlsfx", name = "controlsfx", version = "8.40.11") + compile(group = "com.hierynomus", name = "sshj", version = "0.16.0") + compile(group = "org.apache.velocity", name = "velocity", version = "1.7") + + val coreTestOutput = project(":core").dependencyProject.sourceSets["test"].output + testCompile(files(coreTestOutput)) + testCompile(files(coreTestOutput.resourcesDir)) + testCompile(group = "org.testfx", name = "testfx-core", version = "4.0.5-alpha") + testCompile(group = "org.testfx", name = "testfx-junit", version = "4.0.5-alpha") + testRuntime(group = "org.testfx", name = "openjfx-monocle", version = "1.8.0_20") + testCompile(group = "org.opencv", name = "opencv-java", version = "3.1.0") +} + +if (System.getProperty("os.name").toLowerCase().contains("linux")) { + tasks.named("jfxNative") { + dependsOn(":ui:linuxLauncher:linuxLauncherExecutable") + } +} + +tasks.named("compileTestJava") { + dependsOn(":core:testClasses") +} + +/* + * Allows you to run the UI tests in headless mode by calling gradle with the -Pheadless=true argument + */ +if (project.hasProperty("headless")) { + println("Running UI Tests Headless") + tasks.withType() { + jvmArgs = listOf( + "-Djava.awt.headless=true", + "-Dtestfx.robot=glass", + "-Dtestfx.headless=true", + "-Dprism.order=sw", + "-Dprism.text=t2k" + ) + } +} + +tasks.register("testSharedLib") { + description = "Compiles the shared library used by c++ generation testing." + doLast { + val syst = osdetector.os + val testClassesDir = buildDir.resolve("classes/test") + val pipelibDir = testClassesDir.resolve("pipelib") + if (syst == "windows") { + exec { + isIgnoreExitValue = true // if clean hasn"t been called, directory already exists and mkdir fails. + workingDir = testClassesDir + commandLine = listOf("cmd", "/c", "mkdir", "pipelib") + } + exec { + workingDir = pipelibDir + commandLine = listOf("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat", "amd64", "&", "cmake", "-G", "Visual Studio 14 2015 Win64", "..\\..\\..\\..\\src\\test\\resources\\edu\\wpi\\grip\\ui\\codegeneration\\tools\\") + } + exec { + workingDir = pipelibDir + commandLine = listOf("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat", "amd64", "&", "cmake", "--build", ".", "--target", "ALL_BUILD", "--config", "Release") + } + exec { + workingDir = testClassesDir + commandLine = listOf("cmd", "/C", "copy /Y pipelib\\Release\\* .") + } + exec { + workingDir = testClassesDir + commandLine = listOf("cmd", "/C", "copy /Y pipelib\\pipe\\Release\\* .") + } + exec { + workingDir = pipelibDir + commandLine = listOf("cmd", "/C", "copy /Y ..\\..\\..\\..\\src\\test\\resources\\edu\\wpi\\grip\\ui\\codegeneration\\tools\\pipe\\AbsPipeline.h pipe\\") + } + exec { + workingDir = testClassesDir + commandLine = listOf("cmd", "/C", "copy /Y ..\\..\\..\\src\\test\\resources\\edu\\wpi\\grip\\ui\\codegeneration\\tools\\realpipe\\CMakeLists.txt .") + } + } else { + exec { + isIgnoreExitValue = true // if clean hasn"t been called, directory already exists and mkdir fails. + workingDir = testClassesDir + commandLine = listOf("mkdir", "pipelib") + } + exec { + workingDir = pipelibDir + commandLine = listOf("cmake", "../../../../src/test/resources/edu/wpi/grip/ui/codegeneration/tools/") + } + exec { + workingDir = pipelibDir + commandLine = listOf("make") + } + exec { + workingDir = testClassesDir + if (syst == "osx") { + commandLine = listOf("cp", "pipelib/libgenJNI.dylib", ".") + } + if (syst == "linux") { + commandLine = listOf("cp", "pipelib/libgenJNI.so", ".") + } + } + exec { + workingDir = pipelibDir + commandLine = listOf("cp", "../../../../src/test/resources/edu/wpi/grip/ui/codegeneration/tools/pipe/AbsPipeline.h", "pipe/") + } + exec { + workingDir = testClassesDir + commandLine = listOf("cp", "../../../src/test/resources/edu/wpi/grip/ui/codegeneration/tools/realpipe/CMakeLists.txt", ".") + } + } + } +} + +if (project.hasProperty("generation") || project.hasProperty("genonly")) { + val platform = Installer.getPlatform() + val jniLocation: String = project.properties.getOrDefault("jniLocation", platform.defaultJniLocation()).toString() + val jniPath = File(jniLocation).absolutePath + + val installOpenCV = tasks.register("installOpenCV") { + doFirst { + Installer.setOpenCvVersion("3.1.0") + Installer.installJni(jniPath) + } + } + + tasks.withType { + dependsOn(installOpenCV) + val defaultLibPath = System.getProperty("java.library.path"); + jvmArgs = listOf("-Djava.library.path=$defaultLibPath${System.getProperty("path.separator")}$jniPath") + if (project.hasProperty("genonly")) { + useJUnit { + includeCategories = setOf("edu.wpi.grip.ui.codegeneration.GenerationTesting") + } + } + } +} + +val arch = osdetector.arch.replace("x86_64", "x64") + +jfx { + mainClass = "edu.wpi.grip.ui.Main" + preLoader = "edu.wpi.grip.preloader.GripPreloader" + + identifier = "GRIP" + appName = "GRIP" + vendor = "Worcester Polytechnic Institute" + nativeReleaseVersion = "$version-$arch" + + jfxMainAppJarName = "${jfx.appName}-${jfx.nativeReleaseVersion}.jar" + + // -XX:-OmitStackTraceInFastThrow prevents the JIT from eating stack traces that get thrown a lot + // This is slower but means we actually get the stack traces instead of + // having them become one line like `java.lang.ArrayIndexOutOfBoundsException` + // and as such, would be useless. + // See= https://plumbr.eu/blog/java/on-a-quest-for-missing-stacktraces + // -Xmx limits the heap size. This prevents memory use from ballooning with a lot + // of JavaCV native objects being allocated hanging around waiting to get GC"d. + // -XX:MaxNewSize limits the size of the eden space to force minor GCs to run more often. + // This causes old mats (which take up little space on the heap but a lot of native memory) to get deallocated + // and free up native memory quicker, limiting the memory the app takes up. + jvmArgs = listOf("-XX:-OmitStackTraceInFastThrow", "-Xmx200m", "-XX:MaxNewSize=32m") + + bundleArguments = mapOf( + "linux.launcher.url" to file("linuxLauncher/build/exe/linuxLauncher/linuxLauncher").toURI().toURL().toExternalForm() + ) +} + +tasks.named("jfxNative") { + dependsOn(":core:jar") + + // The JavaFX plugin removes all but numeric characters after the app name in the file + // name, so we restore the full name of the file here + doLast { + logger.log(LogLevel.INFO, "Renaming installer packages") + val packageFileFilter = FileFilter { file -> + listOf("exe", "dmg", "pkg", "deb", "rpm").any { + file.extension == it + } + } + val packageFiles = buildDir.resolve("jfx/native").listFiles(packageFileFilter) + packageFiles.forEach { packageFile -> + val newName: String = jfx.jfxMainAppJarName.replace(Regex("""\.jar$"""), ".${packageFile.extension}") + logger.log(LogLevel.DEBUG, "Renaming ${packageFile.name} to $newName") + packageFile.renameTo(packageFile.resolveSibling(newName)) + } + } +} + +application { + mainClassName = jfx.mainClass +} + +val jfx: JavaFXGradlePluginExtension + get() = extensions.getByType(JavaFXGradlePluginExtension::class.java) + +fun jfx(configuration: JavaFXGradlePluginExtension.() -> Unit) = jfx.apply(configuration)