Я хочу создать шаблон заливки для среза для 3D-печати в JavaFX/Java

Я создаю фрагменты SVG из файлов STL. Файлы SVG состоят из множества строк. Короткая версия - я не могу использовать встроенную функциональность JavaFX для создания шаблона заполнения SVG. Причиной было то, что SVG не был создан правильно, потому что код выполняет перемещение, затем строку, а затем перемещение и затем строку. Чтобы использовать функцию заливки, я думаю, вам нужно сделать один ход, а затем много строк. Слишком давно, чтобы вспомнить точную проблему.

Это то, что я делаю сейчас, чтобы решить проблему с сохранением шаблона заполнения, шаблона заполнения соты, в файле. Это, конечно, может храниться в памяти, но это для тестирования. Затем я сохраняю полый срез во втором файле. Мне нужно объединить два, так что удаляются только те части сота, которые находятся внутри слоя / среза, а остальное. Соты должны быть белыми, а ломтик также должен быть белым. План состоял в том, чтобы сделать соты белыми, когда я скопирую их в срез.

Я попробовал два метода.

Первым методом, который я попробовал, было копирование пикселей из шаблона заливки в слой / срез. Я попытался найти, где линии слоя, а затем попытаться выяснить, где внутри и снаружи. Я провалил. Код будет прикреплен к нижней части этого вопроса.

Второй способ, который я попробовал, состоял в том, чтобы использовать blendMode, но ни один из режимов, кажется, не делает то, что мне нужно.

Первый код метода Я попытался сохранить соты и слои в разных цветах, я попытался сохранить их друг над другом, а затем удалить соты. Здесь вы можете видеть, что я пытаюсь выяснить, что внутри, а что снаружи, но я не мог заставить его работать

package javaapplication3;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import javax.imageio.ImageIO;

public class JavaApplication3 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            File file = new File("C:\\Temp\\Mandibular\\MandibularsolidNOreferencepoints.gizmofill0.gizmoslice.png");
            BufferedImage bufImage = ImageIO.read(file);

            WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);

            PixelReader pixelReader = writableImage.getPixelReader();
            int width = (int) writableImage.getWidth();
            int height = (int) writableImage.getHeight();

            WritableImage dest = new WritableImage(width, height);
            PixelWriter writer = dest.getPixelWriter();
            boolean isOnLine = false;
            boolean previousIsOnLine = false;
            boolean isInside = false;
            for (int x = 0; x < width; x++) {
                for (int y = 00; y < height; y++) {
                    // reading a pixel from src image,
                    // then writing a pixel to dest image
                    Color color = pixelReader.getColor(x, y);
                    double red = color.getRed();
                    double green = color.getGreen();
                    double blue = color.getBlue();

                    if (red == 0 && green == 1 && blue == 0) {
                        //isInside = !isInside;
                        isOnLine = true;
                    } else {
                        previousIsOnLine = isOnLine;
                        isOnLine = false;
                    }

                    if (previousIsOnLine) {
                        isInside = !isInside;
                    }

                    /*if (isOnLine && red == 1 && green == 0 && blue == 0) {
                        isInside = true;
                        isOnLine = false;
                    }*/

                    if (isOnLine || isInside) {
                        writer.setColor(x, y, color);
                    }
                    /*if (isOnLine || isInside && (red > 0 && green == 0 && blue == 0)) {
                        writer.setColor(x, y, Color.WHITE);
                    }*/

                }
            }


            File outputFile = new File("C:\\Temp\\Mandibular\\test.png");
            ImageIO.write(SwingFXUtils.fromFXImage(dest, null), "png", outputFile);

        } catch (IOException ex) {
            Logger.getLogger(JavaApplication3.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

Второй метод с использованием blend Я попробовал разные blendModes и закончил последним layerView.setBlendMode(BlendMode.SRC_ATOP); это явно не делает то, что мне нужно. Я просто проверил каждый, чтобы увидеть, что может работать

package javafxapplication15;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Button;
import javafx.scene.effect.BlendMode;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javax.imageio.ImageIO;

public class JavaFXApplication15 extends Application {
    private void doWork() {
        try {
            // TODO code application logic here
            File file = new File("C:\\Temp\\Mandibular\\MandibularsolidNOreferencepoints.gizmofill0.gizmoslice.png");
            BufferedImage layerImage = ImageIO.read(file);

            file = new File("C:\\Temp\\Mandibular\\MandibularsolidNOreferencepoints.gizmofill-1.gizmoslice.png");
            BufferedImage fillImage = ImageIO.read(file);

            WritableImage layerWritableImage = SwingFXUtils.toFXImage(layerImage, null);
            WritableImage fillWritableImage = SwingFXUtils.toFXImage(fillImage, null);

            WritableImage temp = copyImageOntoFillPattern(fillWritableImage, layerWritableImage);


            File outputFile = new File("C:\\Temp\\Mandibular\\test.png");
            ImageIO.write(SwingFXUtils.fromFXImage(temp, null), "png", outputFile);
        } catch (IOException ex) {
            Logger.getLogger(JavaFXApplication15.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
    private WritableImage copyImageOntoFillPattern(final WritableImage fillPatternImage, final WritableImage sourceImage) {

        ImageView fillPatternView = new ImageView(fillPatternImage);
        ImageView layerView = new ImageView(sourceImage);
        layerView.setBlendMode(BlendMode.SRC_ATOP);

        Group blend = new Group(fillPatternView, layerView);

        blend.snapshot(null, sourceImage);
        SnapshotParameters param = new SnapshotParameters();
        final WritableImage snapshotCombined = blend.snapshot(param, null);
        return snapshotCombined;
    }

    @Override
    public void start(Stage primaryStage) {
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");
                doWork();
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

Слой

Сотовый образец заполнения и слой

1 ответ

Решение

Я щелкнул около часа, чтобы изменить файл.fxml.

Вот содержимое файла, мне нужно преобразовать его в код, который я могу запустить, но теперь он не должен быть слишком сложным.

Слой необходимо заполнить, цвет заливки не имеет значения. Я сделал его зеленым, чтобы его можно было увидеть на веб-сайте, но я, вероятно, создам его белым, когда создам его в своем слайсере. Я также сделал соты красного цвета, чтобы их было легче увидеть. Я показываю изображение SceneBuilder, где он работал

Сейчас я просто создаю соты белого цвета, а слой сплошного белого цвета, и все будет отлично.

Срез или слой

ячеистый

Комбинация в Scene Builder

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.effect.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>


<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Group blendMode="HARD_LIGHT">
         <children>
            <ImageView blendMode="DIFFERENCE" cache="true" fitHeight="418.0" fitWidth="591.0" pickOnBounds="true" preserveRatio="true">
               <image>
                  <Image url="@outline.png" />
               </image>
            </ImageView>
            <ImageView blendMode="SRC_ATOP" fitHeight="451.0" fitWidth="688.0" pickOnBounds="true" preserveRatio="true">
               <image>
                  <Image url="@honeycomb.png" />
               </image>
               <effect>
                  <Blend mode="ADD" />
               </effect>
            </ImageView>
         </children>
      </Group>
   </children>
</AnchorPane>
Другие вопросы по тегам