正在显示
11 个修改的文件
包含
83 行增加
和
67 行删除
lh-modules/lh-smart-feeder/bin/ping.bat
0 → 100644
| @@ -42,13 +42,11 @@ | @@ -42,13 +42,11 @@ | ||
| 42 | <artifactId>lh-common-swagger</artifactId> | 42 | <artifactId>lh-common-swagger</artifactId> |
| 43 | </dependency> | 43 | </dependency> |
| 44 | 44 | ||
| 45 | - <!-- OpenCV --> | 45 | + <!-- https://mvnrepository.com/artifact/org.bytedeco/opencv --> |
| 46 | <dependency> | 46 | <dependency> |
| 47 | - <groupId>org</groupId> | 47 | + <groupId>org.bytedeco</groupId> |
| 48 | <artifactId>opencv</artifactId> | 48 | <artifactId>opencv</artifactId> |
| 49 | - <version>4.5.1</version> | ||
| 50 | - <scope>system</scope> | ||
| 51 | - <systemPath>${project.basedir}\src\main\resources\lib\opencv-451.jar</systemPath> | 49 | + <version>4.5.1-1.5.5</version> |
| 52 | </dependency> | 50 | </dependency> |
| 53 | 51 | ||
| 54 | <!-- 视频处理库 --> | 52 | <!-- 视频处理库 --> |
| @@ -56,7 +54,7 @@ | @@ -56,7 +54,7 @@ | ||
| 56 | <dependency> | 54 | <dependency> |
| 57 | <groupId>org.bytedeco</groupId> | 55 | <groupId>org.bytedeco</groupId> |
| 58 | <artifactId>javacv-platform</artifactId> | 56 | <artifactId>javacv-platform</artifactId> |
| 59 | - <version>1.5.4</version> | 57 | + <version>1.5.5</version> |
| 60 | </dependency> | 58 | </dependency> |
| 61 | 59 | ||
| 62 | <!-- WebSocket --> | 60 | <!-- WebSocket --> |
| @@ -14,6 +14,16 @@ public class VeiwDto implements Serializable { | @@ -14,6 +14,16 @@ public class VeiwDto implements Serializable { | ||
| 14 | 14 | ||
| 15 | private Boolean isText; | 15 | private Boolean isText; |
| 16 | 16 | ||
| 17 | + private Boolean displaySrc; | ||
| 18 | + | ||
| 19 | + public Boolean getDisplaySrc() { | ||
| 20 | + return displaySrc; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public void setDisplaySrc(Boolean displaySrc) { | ||
| 24 | + this.displaySrc = displaySrc; | ||
| 25 | + } | ||
| 26 | + | ||
| 17 | public Boolean getText() { | 27 | public Boolean getText() { |
| 18 | return isText; | 28 | return isText; |
| 19 | } | 29 | } |
| 1 | package com.zhonglai.luhui.smart.feeder.opencv; | 1 | package com.zhonglai.luhui.smart.feeder.opencv; |
| 2 | 2 | ||
| 3 | -import com.ruoyi.common.utils.DESUtil; | ||
| 4 | import com.ruoyi.common.utils.StringUtils; | 3 | import com.ruoyi.common.utils.StringUtils; |
| 5 | -import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig; | ||
| 6 | -import com.zhonglai.luhui.smart.feeder.dto.VeiwDto; | ||
| 7 | -import com.zhonglai.luhui.smart.feeder.service.CameraService; | ||
| 8 | -import com.zhonglai.luhui.smart.feeder.service.FFmCameraService; | ||
| 9 | -import com.zhonglai.luhui.smart.feeder.service.impl.HtmllVeiwServiceImpl; | ||
| 10 | -import com.zhonglai.luhui.smart.feeder.service.impl.JFrameVeiwServiceImpl; | ||
| 11 | -import org.bytedeco.javacv.FrameGrabber; | ||
| 12 | import org.opencv.core.*; | 4 | import org.opencv.core.*; |
| 13 | -import org.opencv.highgui.HighGui; | ||
| 14 | import org.opencv.videoio.VideoCapture; | 5 | import org.opencv.videoio.VideoCapture; |
| 15 | import org.opencv.imgproc.Imgproc; | 6 | import org.opencv.imgproc.Imgproc; |
| 16 | import org.slf4j.Logger; | 7 | import org.slf4j.Logger; |
| 17 | import org.slf4j.LoggerFactory; | 8 | import org.slf4j.LoggerFactory; |
| 18 | 9 | ||
| 19 | import java.io.File; | 10 | import java.io.File; |
| 20 | -import java.io.IOException; | ||
| 21 | import java.util.ArrayList; | 11 | import java.util.ArrayList; |
| 22 | import java.util.Collections; | 12 | import java.util.Collections; |
| 23 | import java.util.List; | 13 | import java.util.List; |
| 14 | +import java.util.concurrent.ExecutorService; | ||
| 15 | +import java.util.concurrent.Executors; | ||
| 24 | 16 | ||
| 25 | 17 | ||
| 26 | public class OpenCVUtil { | 18 | public class OpenCVUtil { |
| @@ -29,13 +21,14 @@ public class OpenCVUtil { | @@ -29,13 +21,14 @@ public class OpenCVUtil { | ||
| 29 | private static final Logger logger = LoggerFactory.getLogger(OpenCVUtil.class); | 21 | private static final Logger logger = LoggerFactory.getLogger(OpenCVUtil.class); |
| 30 | 22 | ||
| 31 | public static void main(String[] args) { | 23 | public static void main(String[] args) { |
| 32 | - System.out.println(DESUtil.decode("5F06AAC657B2E2B287289D25D950A829", "EXU5RUhI1"));; | 24 | + |
| 33 | } | 25 | } |
| 34 | 26 | ||
| 35 | public static VideoCapture readVideoCaptureForRtsp() | 27 | public static VideoCapture readVideoCaptureForRtsp() |
| 36 | { | 28 | { |
| 37 | - FFmCameraService fFmCameraService = new FFmCameraService(); | ||
| 38 | - String ip = fFmCameraService.findCameraIp(); | 29 | +// FFmCameraService fFmCameraService = new FFmCameraService(); |
| 30 | +// String ip = fFmCameraService.findCameraIp(); | ||
| 31 | + String ip = "192.168.0.198"; | ||
| 39 | if(StringUtils.isEmpty(ip)) | 32 | if(StringUtils.isEmpty(ip)) |
| 40 | { | 33 | { |
| 41 | logger.info("未检测到摄像头{},尝试打开本地视频",MP4_FILE_PATH); | 34 | logger.info("未检测到摄像头{},尝试打开本地视频",MP4_FILE_PATH); |
| @@ -71,13 +71,14 @@ public class CameraService { | @@ -71,13 +71,14 @@ public class CameraService { | ||
| 71 | if(null == scheduledFuture || scheduledFuture.isDone()) | 71 | if(null == scheduledFuture || scheduledFuture.isDone()) |
| 72 | { | 72 | { |
| 73 | scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> { | 73 | scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> { |
| 74 | + logger.info("摄像头状态{}",videoIsOpen); | ||
| 74 | if(!videoIsOpen) | 75 | if(!videoIsOpen) |
| 75 | { | 76 | { |
| 76 | openCapture(); | 77 | openCapture(); |
| 77 | } | 78 | } |
| 78 | },0,1, TimeUnit.SECONDS); | 79 | },0,1, TimeUnit.SECONDS); |
| 79 | } | 80 | } |
| 80 | - logger.info("启动摄像头"); | 81 | + logger.info("启动摄像头{}"); |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | /** | 84 | /** |
| 1 | package com.zhonglai.luhui.smart.feeder.service; | 1 | package com.zhonglai.luhui.smart.feeder.service; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.ArrayUtil; | 3 | import cn.hutool.core.util.ArrayUtil; |
| 4 | -import cn.hutool.core.util.ReUtil; | ||
| 5 | -import cn.hutool.core.util.RuntimeUtil; | ||
| 6 | import com.ruoyi.common.utils.StringUtils; | 4 | import com.ruoyi.common.utils.StringUtils; |
| 7 | import org.bytedeco.ffmpeg.global.avutil; | 5 | import org.bytedeco.ffmpeg.global.avutil; |
| 8 | import org.bytedeco.javacv.*; | 6 | import org.bytedeco.javacv.*; |
| 9 | import org.bytedeco.javacv.Frame; | 7 | import org.bytedeco.javacv.Frame; |
| 8 | +import org.slf4j.Logger; | ||
| 9 | +import org.slf4j.LoggerFactory; | ||
| 10 | import org.springframework.stereotype.Service; | 10 | import org.springframework.stereotype.Service; |
| 11 | 11 | ||
| 12 | import java.awt.*; | 12 | import java.awt.*; |
| @@ -14,35 +14,27 @@ import java.awt.image.BufferedImage; | @@ -14,35 +14,27 @@ import java.awt.image.BufferedImage; | ||
| 14 | import java.time.LocalDateTime; | 14 | import java.time.LocalDateTime; |
| 15 | import java.time.format.DateTimeFormatter; | 15 | import java.time.format.DateTimeFormatter; |
| 16 | import java.util.ArrayList; | 16 | import java.util.ArrayList; |
| 17 | -import java.util.List; | ||
| 18 | 17 | ||
| 19 | @Service | 18 | @Service |
| 20 | public class FFmCameraService { | 19 | public class FFmCameraService { |
| 20 | + private static final Logger logger = LoggerFactory.getLogger(FFmCameraService.class); | ||
| 21 | 21 | ||
| 22 | private FFmpegFrameGrabber grabber; | 22 | private FFmpegFrameGrabber grabber; |
| 23 | 23 | ||
| 24 | + private OpenCVFrameConverter.ToOrgOpenCvCoreMat converter2 = new OpenCVFrameConverter.ToOrgOpenCvCoreMat(); | ||
| 25 | + | ||
| 26 | + | ||
| 24 | private static String MAC = "78-a6-a0-d2-bd-e1"; | 27 | private static String MAC = "78-a6-a0-d2-bd-e1"; |
| 25 | - /** | ||
| 26 | - * 查找摄像头 | ||
| 27 | - * @return | ||
| 28 | - */ | ||
| 29 | - public String findCameraIp() | 28 | + |
| 29 | + | ||
| 30 | + public boolean getVideoIsOpen() | ||
| 30 | { | 31 | { |
| 31 | - List<String> list = RuntimeUtil.execForLines("arp", "-a"); | ||
| 32 | - for (String str:list) | ||
| 33 | - { | ||
| 34 | - if(str.indexOf(MAC)>=0) | ||
| 35 | - { | ||
| 36 | - // 使用Hutool提取字符串中的IP地址 | ||
| 37 | - List<String> ips = ReUtil.findAll("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}", str, 0, new ArrayList<>()); | ||
| 38 | - if(null != ips && ips.size()!=0) | ||
| 39 | - { | ||
| 40 | - return ips.get(0); | ||
| 41 | - } | ||
| 42 | - } | ||
| 43 | - } | 32 | + return !grabber.isDeinterlace(); |
| 33 | + } | ||
| 44 | 34 | ||
| 45 | - return null; | 35 | + public void start() |
| 36 | + { | ||
| 37 | + loadCamera(); | ||
| 46 | } | 38 | } |
| 47 | 39 | ||
| 48 | /** | 40 | /** |
| @@ -50,7 +42,7 @@ public class FFmCameraService { | @@ -50,7 +42,7 @@ public class FFmCameraService { | ||
| 50 | */ | 42 | */ |
| 51 | public void loadCamera() | 43 | public void loadCamera() |
| 52 | { | 44 | { |
| 53 | - String ip = findCameraIp(); | 45 | + String ip = "192.168.0.198"; |
| 54 | if(StringUtils.isEmpty(ip)) | 46 | if(StringUtils.isEmpty(ip)) |
| 55 | { | 47 | { |
| 56 | System.out.println("没有找到摄像头:"+MAC); | 48 | System.out.println("没有找到摄像头:"+MAC); |
| @@ -113,6 +105,16 @@ public class FFmCameraService { | @@ -113,6 +105,16 @@ public class FFmCameraService { | ||
| 113 | } | 105 | } |
| 114 | } | 106 | } |
| 115 | 107 | ||
| 108 | + public org.opencv.core.Mat getMat() | ||
| 109 | + { | ||
| 110 | + Frame frame = getFrame(); | ||
| 111 | + if(null == frame) | ||
| 112 | + { | ||
| 113 | + return null; | ||
| 114 | + } | ||
| 115 | + return converter2.convert(frame); | ||
| 116 | + } | ||
| 117 | + | ||
| 116 | public Frame getFrame() { | 118 | public Frame getFrame() { |
| 117 | Frame frame = null; | 119 | Frame frame = null; |
| 118 | try { | 120 | try { |
| @@ -5,16 +5,11 @@ import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter; | @@ -5,16 +5,11 @@ import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter; | ||
| 5 | import com.zhonglai.luhui.smart.feeder.dto.VeiwDto; | 5 | import com.zhonglai.luhui.smart.feeder.dto.VeiwDto; |
| 6 | import com.zhonglai.luhui.smart.feeder.opencv.OpenCVUtil; | 6 | import com.zhonglai.luhui.smart.feeder.opencv.OpenCVUtil; |
| 7 | import com.zhonglai.luhui.smart.feeder.service.impl.HtmllVeiwServiceImpl; | 7 | import com.zhonglai.luhui.smart.feeder.service.impl.HtmllVeiwServiceImpl; |
| 8 | -import org.bytedeco.javacv.Frame; | ||
| 9 | -import org.bytedeco.javacv.Java2DFrameUtils; | ||
| 10 | -import org.bytedeco.javacv.OpenCVFrameConverter; | ||
| 11 | -import org.bytedeco.opencv.opencv_core.IplImage; | ||
| 12 | import org.opencv.core.Mat; | 8 | import org.opencv.core.Mat; |
| 13 | import org.opencv.core.MatOfPoint; | 9 | import org.opencv.core.MatOfPoint; |
| 14 | import org.opencv.core.Scalar; | 10 | import org.opencv.core.Scalar; |
| 15 | import org.opencv.core.Size; | 11 | import org.opencv.core.Size; |
| 16 | import org.opencv.imgproc.Imgproc; | 12 | import org.opencv.imgproc.Imgproc; |
| 17 | -import org.opencv.videoio.VideoCapture; | ||
| 18 | import org.slf4j.Logger; | 13 | import org.slf4j.Logger; |
| 19 | import org.slf4j.LoggerFactory; | 14 | import org.slf4j.LoggerFactory; |
| 20 | import org.springframework.beans.factory.annotation.Autowired; | 15 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -34,7 +29,7 @@ public class FishGroupImageRecognitionService { | @@ -34,7 +29,7 @@ public class FishGroupImageRecognitionService { | ||
| 34 | private static final Logger logger = LoggerFactory.getLogger(FishGroupImageRecognitionService.class); | 29 | private static final Logger logger = LoggerFactory.getLogger(FishGroupImageRecognitionService.class); |
| 35 | 30 | ||
| 36 | @Autowired | 31 | @Autowired |
| 37 | - private CameraService cameraService; | 32 | + private FFmCameraService fFmCameraService; |
| 38 | 33 | ||
| 39 | @Autowired | 34 | @Autowired |
| 40 | private ScheduledExecutorService scheduledExecutorService; | 35 | private ScheduledExecutorService scheduledExecutorService; |
| @@ -69,19 +64,18 @@ public class FishGroupImageRecognitionService { | @@ -69,19 +64,18 @@ public class FishGroupImageRecognitionService { | ||
| 69 | // 创建FrameConverter对象 | 64 | // 创建FrameConverter对象 |
| 70 | public void start() | 65 | public void start() |
| 71 | { | 66 | { |
| 72 | - if(cameraService.getVideoIsOpen()) //摄像头打开才能识别 | 67 | + if(fFmCameraService.getVideoIsOpen()) //摄像头打开才能识别 |
| 73 | { | 68 | { |
| 74 | isRun = true; | 69 | isRun = true; |
| 75 | configurationParameterService.setConfig(ConfigurationParameter.FishGroupImageRecognition,true); | 70 | configurationParameterService.setConfig(ConfigurationParameter.FishGroupImageRecognition,true); |
| 76 | - VideoCapture videoCapture = cameraService.getVideoCapture(); | ||
| 77 | - brightnessIdentifyFishRegion(videoCapture); | 71 | + brightnessIdentifyFishRegion(); |
| 78 | } | 72 | } |
| 79 | } | 73 | } |
| 80 | 74 | ||
| 81 | public void stop() | 75 | public void stop() |
| 82 | { | 76 | { |
| 83 | configurationParameterService.setConfig(ConfigurationParameter.FishGroupImageRecognition,false); | 77 | configurationParameterService.setConfig(ConfigurationParameter.FishGroupImageRecognition,false); |
| 84 | - cameraService.close(); | 78 | + fFmCameraService.close(); |
| 85 | isRun = false; | 79 | isRun = false; |
| 86 | } | 80 | } |
| 87 | 81 | ||
| @@ -124,15 +118,17 @@ public class FishGroupImageRecognitionService { | @@ -124,15 +118,17 @@ public class FishGroupImageRecognitionService { | ||
| 124 | /** | 118 | /** |
| 125 | * 亮度查找水面,透明度过滤鱼群 | 119 | * 亮度查找水面,透明度过滤鱼群 |
| 126 | */ | 120 | */ |
| 127 | - private void brightnessIdentifyFishRegion(VideoCapture videoCapture ) | 121 | + private void brightnessIdentifyFishRegion() |
| 128 | { | 122 | { |
| 129 | logger.info("启动鱼群识别"); | 123 | logger.info("启动鱼群识别"); |
| 130 | // 读取第一帧并获取视频大小 | 124 | // 读取第一帧并获取视频大小 |
| 131 | - Mat previousFrame = new Mat(); | ||
| 132 | - if (!videoCapture.read(previousFrame)) { | 125 | + org.opencv.core.Mat previousFrame = fFmCameraService.getMat(); |
| 126 | + | ||
| 127 | + if (null == previousFrame) { | ||
| 133 | System.out.println("无法读取视频帧"); | 128 | System.out.println("无法读取视频帧"); |
| 134 | return; | 129 | return; |
| 135 | } | 130 | } |
| 131 | + | ||
| 136 | logger.info("鱼群识别时检测摄像头"); | 132 | logger.info("鱼群识别时检测摄像头"); |
| 137 | // 获取水域轮廓 | 133 | // 获取水域轮廓 |
| 138 | if(null != largestContour) | 134 | if(null != largestContour) |
| @@ -150,17 +146,16 @@ public class FishGroupImageRecognitionService { | @@ -150,17 +146,16 @@ public class FishGroupImageRecognitionService { | ||
| 150 | scheduledExecutorService.scheduleWithFixedDelay(() -> { | 146 | scheduledExecutorService.scheduleWithFixedDelay(() -> { |
| 151 | try { | 147 | try { |
| 152 | Boolean fishGroupImageRecognition = ((Boolean)configurationParameterService.getConfig(ConfigurationParameter.FishGroupImageRecognition)); | 148 | Boolean fishGroupImageRecognition = ((Boolean)configurationParameterService.getConfig(ConfigurationParameter.FishGroupImageRecognition)); |
| 153 | - Mat frame = new Mat(); | ||
| 154 | - Boolean isread = videoCapture.read(frame); | 149 | + Mat frame = fFmCameraService.getMat(); |
| 150 | + Boolean isread = false; | ||
| 151 | + if(null != frame) | ||
| 152 | + { | ||
| 153 | + isread = true; | ||
| 154 | + } | ||
| 155 | logger.info("逐帧处理视频,开始处理的判断参数:鱼群图像识别是否开启 {}、摄像头是否可读取 {}",fishGroupImageRecognition,isread); | 155 | logger.info("逐帧处理视频,开始处理的判断参数:鱼群图像识别是否开启 {}、摄像头是否可读取 {}",fishGroupImageRecognition,isread); |
| 156 | if(!isread ) | 156 | if(!isread ) |
| 157 | { | 157 | { |
| 158 | logger.info("摄像头不可读取"); | 158 | logger.info("摄像头不可读取"); |
| 159 | - if(cameraService.getVideoIsOpen()) | ||
| 160 | - { | ||
| 161 | - logger.info("重新初始化"); | ||
| 162 | - cameraService.clean(); | ||
| 163 | - } | ||
| 164 | frame.release(); | 159 | frame.release(); |
| 165 | return; | 160 | return; |
| 166 | } | 161 | } |
| @@ -10,7 +10,7 @@ import java.util.concurrent.ScheduledExecutorService; | @@ -10,7 +10,7 @@ import java.util.concurrent.ScheduledExecutorService; | ||
| 10 | @Configuration | 10 | @Configuration |
| 11 | public class InitService { | 11 | public class InitService { |
| 12 | @Autowired | 12 | @Autowired |
| 13 | - private CameraService cameraService; | 13 | + private FFmCameraService fFmCameraService; |
| 14 | 14 | ||
| 15 | @Autowired | 15 | @Autowired |
| 16 | private ConfigurationParameterService configurationParameterService; | 16 | private ConfigurationParameterService configurationParameterService; |
| @@ -40,7 +40,7 @@ public class InitService { | @@ -40,7 +40,7 @@ public class InitService { | ||
| 40 | //配置参数 | 40 | //配置参数 |
| 41 | configurationParameterService.initConfigurationParameter(); | 41 | configurationParameterService.initConfigurationParameter(); |
| 42 | //摄像头监听 | 42 | //摄像头监听 |
| 43 | - cameraService.start(); | 43 | + fFmCameraService.start(); |
| 44 | //鱼群识别 | 44 | //鱼群识别 |
| 45 | fishGroupImageRecognitionService.run(); | 45 | fishGroupImageRecognitionService.run(); |
| 46 | //鱼群图像识别控制投料控制 | 46 | //鱼群图像识别控制投料控制 |
| @@ -126,6 +126,7 @@ public class MqttCallback implements MqttCallbackExtended { | @@ -126,6 +126,7 @@ public class MqttCallback implements MqttCallbackExtended { | ||
| 126 | case 1: | 126 | case 1: |
| 127 | srsService.run(300); | 127 | srsService.run(300); |
| 128 | fishGroupImageRecognitionService.setText(veiwDto.getText()); | 128 | fishGroupImageRecognitionService.setText(veiwDto.getText()); |
| 129 | + srsService.setDisplaySrc(veiwDto.getDisplaySrc()); | ||
| 129 | break; | 130 | break; |
| 130 | } | 131 | } |
| 131 | } | 132 | } |
| @@ -51,8 +51,17 @@ public class SrsService { | @@ -51,8 +51,17 @@ public class SrsService { | ||
| 51 | 51 | ||
| 52 | 52 | ||
| 53 | private boolean isPush = false; | 53 | private boolean isPush = false; |
| 54 | - | 54 | + private boolean displaySrc = false; |
| 55 | private int endTime = 0; | 55 | private int endTime = 0; |
| 56 | + | ||
| 57 | + public boolean isDisplaySrc() { | ||
| 58 | + return displaySrc; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + public void setDisplaySrc(boolean displaySrc) { | ||
| 62 | + this.displaySrc = displaySrc; | ||
| 63 | + } | ||
| 64 | + | ||
| 56 | public void run(int time) throws Exception { | 65 | public void run(int time) throws Exception { |
| 57 | endTime = DateUtils.getNowTimeMilly()+time; | 66 | endTime = DateUtils.getNowTimeMilly()+time; |
| 58 | if(!isPush) | 67 | if(!isPush) |
| @@ -147,7 +156,12 @@ public class SrsService { | @@ -147,7 +156,12 @@ public class SrsService { | ||
| 147 | // 将curveArea拼接到原来的Mat对象上 | 156 | // 将curveArea拼接到原来的Mat对象上 |
| 148 | Mat pushmat = new Mat(); | 157 | Mat pushmat = new Mat(); |
| 149 | List<Mat> mats = new ArrayList<>(); | 158 | List<Mat> mats = new ArrayList<>(); |
| 150 | - mats.add(src); | 159 | + |
| 160 | + if(displaySrc) | ||
| 161 | + { | ||
| 162 | + mats.add(src); | ||
| 163 | + } | ||
| 164 | + | ||
| 151 | mats.add(curveArea); | 165 | mats.add(curveArea); |
| 152 | Core.vconcat(mats, pushmat); | 166 | Core.vconcat(mats, pushmat); |
| 153 | 167 |
不能预览此文件类型
-
请 注册 或 登录 后发表评论