1

I have the following test code, where I try to clip a MeshView with a circle. I also tried putting the meshView into a group then clipping that, but this result in a black circle.

Is there a way to clip a MeshView, preferably without putting it into a group?

import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.image.Image
import scalafx.scene.paint.{Color, PhongMaterial}
import scalafx.scene.shape.{TriangleMesh, Circle, MeshView}
import scalafx.scene.{Group, PerspectiveCamera, Scene, SceneAntialiasing}

object Test4 extends JFXApp {
  stage = new PrimaryStage {
    scene = new Scene(500, 500, true, SceneAntialiasing.Balanced) {
      fill = Color.LightGray
      val clipCircle = Circle(150.0)
      val meshView = new MeshView(new RectangleMesh(500,500)) {
        // takes a while to load
        material = new PhongMaterial(Color.White, new Image("https://peach.blender.org/wp-content/uploads/bbb-splash.png"), null, null, null)
      }
    //  val meshGroup = new Group(meshView)
      meshView.setClip(clipCircle)
      root = new Group {children = meshView; translateX = 250.0; translateY = 250.0; translateZ = 560.0}
      camera = new PerspectiveCamera(false)
    }
  }
}

class RectangleMesh(Width: Float, Height: Float) extends TriangleMesh {
  points = Array(
    -Width / 2, Height / 2, 0,
    -Width / 2, -Height / 2, 0,
    Width / 2, Height / 2, 0,
    Width / 2, -Height / 2, 0
  )
  texCoords = Array(
    1, 1,
    1, 0,
    0, 1,
    0, 0
  )
  faces = Array(
    2, 2, 1, 1, 0, 0,
    2, 2, 3, 3, 1, 1
  )
José Pereda
  • 44,311
  • 7
  • 104
  • 132
workingdog
  • 43
  • 4

1 Answers1

0

The clippling actually works fine over the MeshView wrapped around a Group.

If you check JavaDoc for setClip():

There is a known limitation of mixing Clip with a 3D Transform. Clipping is essentially a 2D image operation. The result of a Clip set on a Group node with 3D transformed children will cause its children to be rendered in order without Z-buffering applied between those children.

As a result of this:

Group meshGroup = new Group(meshView);
meshGroup.setClip(clipCircle);

you will have a 2D image, and it seems Material is not applied. However you can check there's a mesh, by seting this:

meshView.setDrawMode(DrawMode.LINE);

So in your case, adjusting dimensions:

@Override
public void start(Stage primaryStage) {
    Circle clipCircle = new Circle(220.0);
    MeshView meshView = new MeshView(new RectangleMesh(400,400));
    meshView.setDrawMode(DrawMode.LINE);
    Group meshGroup = new Group(meshView);
    meshGroup.setClip(clipCircle);
    PerspectiveCamera camera = new PerspectiveCamera(false);

    StackPane root = new StackPane();
    final Circle circle = new Circle(220.0);
    circle.setFill(Color.TRANSPARENT);
    circle.setStroke(Color.RED);
    root.getChildren().addAll(meshGroup, circle);

    Scene scene = new Scene(root, 500, 500, true, SceneAntialiasing.BALANCED);
    scene.setCamera(camera);

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

will give this:

clip

In the end, clipping doesn't make sense with 3D shapes. For that you can use just 2D shape to get the result you want.

If you want 3D clipping have a look at CSG operations. Check this question for a JavaFX based solution.

Community
  • 1
  • 1
José Pereda
  • 44,311
  • 7
  • 104
  • 132
  • I'll have a look at CSG operations. If I understand your answer correctly, you are saying it can't be done. – workingdog Jul 22 '15 at 04:30
  • 3D clipping will be a CSG boolean operation, so it can be done... I didn't say it couldn't. In the question I mention you have a sample of boolean operations between 3D shapes, using [JCSG](https://github.com/miho/JCSG) and [FXyz](https://github.com/Birdasaur/FXyz) libraries. – José Pereda Jul 22 '15 at 08:13
  • I'm still looking at CSG boolean operations, I was using FXyz already and did not know about CSG. Both libraries are great. Since clip() on a mesh does not work without destroying the Material, I came up with a workaround to do clipping using Shape.subtract. It almost work but there is a problem. How to get the outer boundary points of a mesh in sequence. I don't understand the generic sequencing of the points in a complex mesh like the Cloth, and so cannot workout a formula to pick just the points I need to create a polygon. https://gist.github.com/anonymous/49977e526a501905d1fb – workingdog Jul 24 '15 at 02:50