Import STL file in JavaFX - java

My problem is that I am trying to import a 3D model from an STL file to a JavaFX application. I followed the code in this link How to create 3d shape from STL in JavaFX 8? and it's only working with the jewel file mentioned there, but I've tried with other STL files and it's not working!
I can't see why it's not working with the other files. Can anyone explain this?
Any help please, as soon as possible!

As you are already using an STL importer from this site, you will find in the same web a 3D model browser you can use to preview your models before importing them to your JavaFX application.
If they can't be imported with this browser, the problem may be related to a non valid STL format in your files.
If they are imported, then the problem may be in your application. Embed the call in a try-catch and post the exception you may enconter.
StlMeshImporter stlImporter = new StlMeshImporter();
try {
stlImporter.read(this.getClass().getResource("<STLfile>.stl"));
}
catch (ImportException e) {
e.printStackTrace();
return;
}
EDIT
If no exception is thrown while reading the model, the next step would be inserting the returned mesh into a MeshView and show it on our scene:
TriangleMesh mesh = stlImporter.getImport();
stlImporter.close();
MeshView mesh=new MeshView(cylinderHeadMesh);
Group root = new Group(mesh);
Scene scene = new Scene(root, 1024, 800, true);
Camera camera = new PerspectiveCamera();
scene.setCamera(camera);
primaryStage.setScene(scene);
primaryStage.show();
Since the model could be too small or too big for our scene (related to the camera and the point of view we are using), we should print the bounding box of our model, and then scale it up or down accordingly:
System.out.println("mesh: "+mesh.getBoundsInLocal().toString());
mesh.setScaleX(1d);
mesh.setScaleY(1d);
mesh.setScaleZ(1d);
Or we could change the camera parameters:
double max = Math.max(mesh.getBoundsInLocal().getWidth(),
Math.max(mesh.getBoundsInLocal().getHeight(),
mesh.getBoundsInLocal().getDepth()));
camera.setTranslateZ(-3*max);

Related

JavaFX ImageView display GIFanimation high GPU [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am creating JavaFX application and made a loading scene. In this scene i want to show some text like loading or initializing and add some loading spinner animated image as a visual notification that something is loading.
I generate a loading .gif animation created via https://loading.io/ and also downloaded it like frames of animation (multiple .png files).
I noticed that in the JavaFX Scene Builder 8.5.0 when I set the .gif in ImageView, my GPU in Windows task manager went up to 20%, on NVidia GeForce RTX 2070 graphic card and in my opinion this is a problem. I tested with a javafx desktop application, to rule out that is not a problem generated by the scene builder application and got similar results.
The next step that i tried is to create my custom animation using javafx.​animation.Timeline. This is the initializing function that i call from the controller initialize(URL location, ResourceBundle resources) function. This function doesn't use the .gif image, it uses the multiple .png images of the same .gif image as frames.
private void initializeAnimation() {
imgLoading.setCache(true);
imgLoading.setCacheHint(CacheHint.SPEED);
Image[] images = new Image[31];
for(int i = 0; i <= 30; i++){
images[i] = new Image(getClass().getResourceAsStream("/es/main/gui/javafx/images/loading/frame-" + i + ".png"));
}
Timeline timeLine = new Timeline();
Collection<KeyFrame> frames = timeLine.getKeyFrames();
Duration frameGap = Duration.millis(100);
Duration frameTime = Duration.ZERO;
for (Image img : images) {
frameTime = frameTime.add(frameGap);
frames.add(new KeyFrame(frameTime, e -> imgLoading.setImage(img)));
}
timeLine.setCycleCount(Timeline.INDEFINITE);
timeLine.play();
}
In the first version i didn't call .setCache() and .setCacheHint() functions, I added them later while testing different variations of the same code. Also i tried adding
-Dprism.forceGPU=true -Dsun.java2d.opengl=true -Dprism.order=es2,es1,sw,j2d
as VMOption or some variants that I have read on this forum on improving graphic related settings for java. At the end, after all the changes, results in my task manager didn't change drastically. In the current version i use up to 17% of my GPU on this scene.
When the scene ends, in the next scene with no .gif images or Timeline's my GPU drops to almost 0%.
Running configurations:
Processor: i9-9900KF
Graphic card: GeForce RTX 2070
Java version "1.8.0_251"
JavaFX version "8.0.251-b08"
Short summary question: How to display animated .gif images correctly in JavaFX without having drastic overhead on the GPU (or CPU when with integrated graphics).
(Edit) 14.09.2020 - Java naming conventions
First thing I didn't noticed that i was not using the same size on my ImageView, so the first thing i changed for testing is adjusting the ImageView the same size as my .gif image (same width and height on both ImageView and .gif image). With this change the GPU percentage lowered to about %5.
As suggested I also upgrading the Java and JavaFX versions:
Tried using the jdk 1.8.0_261 with JavaFX built in version 8.0.261-b12 and got similar results.
Tried using jdk 14.0.2 with JavaFX version 15+9 (latest openjfx-15) and still got similar results.
Short summary: Upgrading the Java and JavaFX version didn't change anything relating this issue. Using the same size helped, but I think I can improve even better with your help.
My guess is you'd probably see some performance gains if you used one or more RotateTransition rather than key frame animation.
Here's a simple example using multiple transitions in a ParallelTransition:
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
#Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 500, 200);
stage.setScene(scene);
Rectangle rect = new Rectangle (100, 40, 100, 100);
rect.setArcHeight(50);
rect.setArcWidth(50);
rect.setFill(Color.VIOLET);
RotateTransition rt = new RotateTransition(Duration.millis(3000));
rt.setByAngle(180);
rt.setAutoReverse(true);
FadeTransition ft = new FadeTransition(Duration.millis(3000));
ft.setFromValue(1.0);
ft.setToValue(0.3);
ft.setCycleCount(4);
ft.setAutoReverse(true);
ParallelTransition pt = new ParallelTransition(rect, ft, rt);
pt.play();
root.getChildren().add(rect);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}

RTSP support library for Javafx

I am new to this Javafx. I need to know rtsp supported library for Javafx I knew few of the media library GStreamer and VLCJ. I don't know which will support this features in Javafx. I have read many portals which I cant get an answer. many of them posted you cant run RTSP in Javafx. please guide me which library is best for RTSP that will support for Javafx.
File f = new File("Video.mp4");
new NativeDiscovery().discover();
EmbeddedMediaPlayerComponent playerComponent = new EmbeddedMediaPlayerComponent();
/*I dont know where to add the playerComponent as we do in swing*/
MediaPlayer mp=playerComponent.getMediaPlayer();
StackPane root = new StackPane();
Scene scene = new Scene(root, 700, 700);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
This is the normal video player in Javafx.
This might be a late answer but I saw the quetsion while I had the same quetsion so check this site out I think it got all the things I have to say https://github.com/mhrimaz/AwesomeJavaFX/blob/master/README.md#frameworks

JavaFX ImageView image not showing

I have an assets folder full of images to implement in a game I'm creating and I want to display these in the window. This is my code so far.
public class javafxtest extends Application {
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
Scene scene = new Scene(root, 600, 600);
Image test = new Image("file:assets/BA.png");
ImageView piece = new ImageView(test);
piece.setX(10);
piece.setY(10);
Rectangle rct = new Rectangle(50, 150, 500, 300);
rct.setFill(Color.GRAY);
root.getChildren().addAll(rct, piece);
primaryStage.setScene(scene);
primaryStage.show();
}
}
This will be for a program to run within IntelliJ/from a jar. The assets folder is in the same directory as this file. I get no file path error so I assume it can find the image, but it doesn't appear on screen and the rectangle does.
Fair warning, I'm learning JavaFX from scratch and I'm finding there's not much explanation as to how things work, so this could be a stupid question.
Accessing the image via the filesystem is the wrong choice when the image is in fact an asset (ie it is distributed along side the .class files that make up your program) because that way you'd have to deal with the installation path (otherwise known as the home path). The correct choice is bundling your image in your JAR, so place your image in the following path:
src/main/resources/assets/BA.png
and access it with:
Image test = new Image("/assets/BA.png");
This is how the file tree should look like in your computer:

How to make Java save my background image in extracted, compiled java program?

When I try to run my extracted/compiled java program I can see pictures cause they are stored on my PC and addressed in the code from my PC. But when I try the same program on another PC, pictures/backgrounds are gone.
How to store pictures into java code while I'm calling them from a disk into ImageView so they are viewable on other systems too ?
I am using JavaFX and FXML, CSS.
You can bundle your images with java program using two ways:
1) put them inside your jar - create a package named eg. "images" and add the images there, then load it using
BufferedImage img = ImageIO.read(getClass().getResourceAsStream("/images/image.jpg"));
2) put them in to the same folder as your jar and load them with:
BufferedImage img = ImageIO.read(new File("image.jpg"));
For you the best way is probably the #1 because youll get just one jar - it is easier to copy such jar and harder to tamper the images.
I've done it like this. Thanks!
#Override
public void start(Stage stage) throws Exception
{
Parent root = FXMLLoader.load(getClass().getResource("/grafika.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add("/application.css");
Image picture1 = new Image("/kava.jpg");
ImageView slika1 = new ImageView(picture1);
slika1.setImage(picture1);
stage.setScene(scene);
stage.setMaxHeight(530);
stage.setMaxWidth(800);
stage.setResizable(false);
stage.show();
}

Saving shapes to file drawn on border pane in javafx

I have a basic application, sort of like a toy box, it doesn't really do anything except let you move shapes around a screen, if you double click the shape, it brings it into the foreground. There is also a menu with menu Items "New, "open", "Save" -
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class RandCMove extends Application
{
public static void main(String [] args)
{
launch(args);
}
public void start(Stage primaryStage)
{
BorderPane root = new BorderPane();
MenuBar menuBar = new MenuBar();
menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
Menu fileMenu = new Menu("File");
MenuItem newMenuItem = new MenuItem("New");
MenuItem openMenuItem = new MenuItem("Open");
MenuItem saveMenuItem = new MenuItem("Save");
MenuItem exitMenuItem = new MenuItem("Exit");
fileMenu.getItems().addAll(newMenuItem,openMenuItem,saveMenuItem,
new SeparatorMenuItem(),exitMenuItem);
menuBar.getMenus().add(fileMenu);
Rectangle rect = new Rectangle();
rect.setWidth(200);
rect.setHeight(200);
rect.setArcHeight(20);
rect.setArcWidth(20);
rect.setFill(Color.RED);
rect.setX(200);
rect.setY(100);
root.setTop(menuBar);
root.getChildren().add(rect);
Circle circle = new Circle(
300,300,100);
Text text = new Text(150,150,"Text");
Font phosphate = Font.font("Phosphate",150);
text.setFont(phosphate);
text.setTranslateY(circle.getBoundsInParent().getMinY()+10);
root.getChildren().add(text);
//Positions the circle under the rectangle
circle.setTranslateY(rect.getBoundsInParent().getMinY()+30);
root.getChildren().add(circle);
// Moves shapes depending on if the cursor on the particular shape
// Brings shape to the front using double click
root.setOnMouseMoved(e ->
{
if(rect.contains(e.getX(),e.getY()))
rect.setOnMouseDragged(f ->{
rect.setX(f.getX());
rect.setY(f.getY());
});
rect.setOnMouseClicked(f ->{
if(f.getClickCount() >= 2)
rect.toFront();
});
if(circle.contains(e.getX(),e.getY()))
circle.setOnMouseDragged(f->{
circle.setCenterX(f.getX());
circle.setCenterY(f.getY());
});
circle.setOnMouseClicked(f ->{
if(f.getClickCount() >= 2)
circle.toFront();
});
if(text.contains(e.getX(),e.getY()))
text.setOnMouseDragged(f ->{
text.setX(f.getX());
text.setY(f.getY());
});
text.setOnMouseClicked(f ->{
if(f.getClickCount() >= 2)
text.toFront();
});
});
Scene scene = new Scene(root,600,600);
primaryStage.setScene(scene);
primaryStage.show();
}
}
I want to be able to save the current state of the shapes on screen, and have them load up as they were upon pressing "Open".
I can't seem to find anything useful on this, can anyone provide some guidance or point me in the right direction? Any assistance would be appreciated!
Applications require preference and configuration data to adapt to the needs of different users and environments. The java.util.prefs package provides a way for applications to store and retrieve user and system preference and configuration data. The data is stored persistently in an implementation-dependent backing store. There are two separate trees of preference nodes, one for user preferences and one for system preferences.
More at:
http://docs.oracle.com/javase/8/docs/technotes/guides/preferences/
This is a non-trivial task. I am not going to provide code for it here, but only a general approach outline:
Serialize your shapes to FXML (you will need to code the serializer yourself).
Each time the user edits the shapes, serialize the to FXML again and save the FXML as a preference (as outlined in Frank Fotangs answer).
When the user first opens the application, read the current preference containing the FXML for the current shapes and load them up using an FXMLLoader.
The same technique can be used for implementing your Open and Save menu options, only instead of writing the serialized data to a preference you will write it to a file location chosen by a FileChooser.
I would really prefer to do this the FX way rather than Fxml.
I think you misunderstand the problem that you need to solve. There is no "FX way" of doing this.
Your problem is that you need to serialize and deserialize nodes from a scene graph, for which the core JavaFX API does not provide a full implementation.
When you create a scene graph using JavaFX using JavaFX APIs, it is an in-memory representation of your scene, only available while your program is executing. What you need to be able to do is persist that scene to a file so that when you shut down your application the data representing the scene is stored somewhere. Then you need to read the data from the file and recreate the scene in memory when the user starts the application back up again. The only way to do this is to serialize the objects to storage when needed and deserialize the objects from storage when the application starts back up again. Read the wikipedia article on serialization to understand the conceptual process.
Now you don't need to use FXML for your serialized format, you could use other formats such as JSON or YAML and other serialization support libraries such as Jackson. However, to me, FXML seems the most logical format to choose because JavaFX ships with the FXMLLoader, which provides an easy to use API to transfer your serialized data (an FXML file representing your scene) into an in-memory structure (the scene graph), via a simple call to the load method.
What makes this task tricky rather than trivial is that the JavaFX API only ships with an FXMLLoader, it does not ship with a corresponding class (e.g. an FXMLSaver), which does the opposite work of taking the in-memory structure (the scene graph) and creating serialized data from it (an FXML file). So you will need to write such logic yourself.
Now, SceneBuilder is an open source project and does include logic to save a scene graph to an FXML file. For instance you can find source code for an FXMLSaver in the SceneBuilder source. Perhaps you could use or adapt that code to save your scene graph objects into a serialized format. In doing so, you wouldn't be using the scene builder application to create and save your scene, instead you would be adapting SceneBuilder source code to be included in your own application which would be creating and saving your scene.

Categories

Resources