32 package eu.mihosoft.vrl.v3d.ext.openjfx.shape3d;
34 import eu.mihosoft.vrl.v3d.ext.openjfx.shape3d.SubdivisionMesh.BoundaryMode;
35 import eu.mihosoft.vrl.v3d.ext.openjfx.shape3d.SubdivisionMesh.MapBorderMode;
36 import java.util.Arrays;
37 import javafx.beans.property.ObjectProperty;
38 import javafx.beans.property.SimpleIntegerProperty;
39 import javafx.beans.property.SimpleObjectProperty;
40 import javafx.collections.ArrayChangeListener;
41 import javafx.collections.ObservableFloatArray;
42 import javafx.scene.Parent;
43 import javafx.scene.paint.Material;
44 import javafx.scene.shape.CullFace;
45 import javafx.scene.shape.DrawMode;
46 import javafx.scene.shape.MeshView;
47 import javafx.scene.shape.TriangleMesh;
48 import static javafx.scene.shape.TriangleMesh.*;
58 private static final boolean DEBUG =
false;
61 private final MeshView
meshView =
new MeshView();
71 private final ArrayChangeListener<ObservableFloatArray>
meshPointsListener = (t, bln, i, i1) -> {
126 meshProperty.addListener((observable, oldValue, newValue) -> {
127 if (oldValue !=
null) {
137 if (newValue !=
null) {
175 @Override
protected void invalidated() {
214 @Override
protected void invalidated() {
281 @Override
protected void invalidated() {
329 @Override
protected void invalidated() {
371 @Override
protected void invalidated() {
413 if (pmesh ==
null || pmesh.
faces ==
null) {
419 final int pointElementSize =
triangleMesh.getPointElementSize();
420 final int faceElementSize =
triangleMesh.getFaceElementSize();
421 final boolean isWireframe =
getDrawMode() == DrawMode.LINE;
422 if (
DEBUG) System.out.println(
"UPDATE MESH -- "+(isWireframe?
"WIREFRAME":
"SOLID"));
423 final int numOfPoints = pmesh.
getPoints().size() / pointElementSize;
424 if (
DEBUG) System.out.println(
"numOfPoints = " + numOfPoints);
439 int pointsInd = pmesh.
getPoints().size();
440 for(
int[] face: pmesh.
faces) {
441 if (
DEBUG) System.out.println(
"face.length = " + (face.length/2)+
" -- "+Arrays.toString(face));
442 int lastPointIndex = face[face.length-2];
443 if (
DEBUG) System.out.println(
" lastPointIndex = " + lastPointIndex);
444 for (
int p=0;p<face.length;p+=2) {
445 int pointIndex = face[p];
446 if (
DEBUG) System.out.println(
" connecting point["+lastPointIndex+
"] to point[" + pointIndex+
"]");
447 facesArray[facesInd++] = lastPointIndex;
448 facesArray[facesInd++] = 0;
449 facesArray[facesInd++] = pointIndex;
450 facesArray[facesInd++] = 0;
451 facesArray[facesInd++] = pointsInd / pointElementSize;
452 facesArray[facesInd++] = 0;
453 if (
DEBUG) System.out.println(
" facesInd = " + facesInd);
454 pointsInd += pointElementSize;
455 lastPointIndex = pointIndex;
473 int pointsInd = pmesh.
getPoints().size();
474 for(
int[] face: pmesh.
faces) {
475 int lastPointIndex = face[face.length-2];
476 for (
int p=0;p<face.length;p+=2) {
477 int pointIndex = face[p];
479 final float x1 = pointsArray[lastPointIndex * pointElementSize];
480 final float y1 = pointsArray[lastPointIndex * pointElementSize + 1];
481 final float z1 = pointsArray[lastPointIndex * pointElementSize + 2];
482 final float x2 = pointsArray[pointIndex * pointElementSize];
483 final float y2 = pointsArray[pointIndex * pointElementSize + 1];
484 final float z2 = pointsArray[pointIndex * pointElementSize + 2];
486 final float offset = distance/1000;
488 pointsArray[pointsInd++] = x2 + offset;
489 pointsArray[pointsInd++] = y2 + offset;
490 pointsArray[pointsInd++] = z2 + offset;
491 lastPointIndex = pointIndex;
507 final int numOfFacesBefore = pmesh.
faces.length;
509 int [] facesArray =
new int [numOfFacesAfter * faceElementSize];
510 int [] smoothingGroupsArray =
new int [numOfFacesAfter];
512 for(
int f = 0; f < pmesh.
faces.length; f++) {
513 int[] face = pmesh.
faces[f];
515 if (
DEBUG) System.out.println(
"face.length = " + face.length+
" -- "+Arrays.toString(face));
516 int firstPointIndex = face[0];
517 int firstTexIndex = face[1];
518 int lastPointIndex = face[2];
519 int lastTexIndex = face[3];
520 for (
int p=4;p<face.length;p+=2) {
521 int pointIndex = face[p];
522 int texIndex = face[p+1];
523 facesArray[facesInd * faceElementSize] = firstPointIndex;
524 facesArray[facesInd * faceElementSize + 1] = firstTexIndex;
525 facesArray[facesInd * faceElementSize + 2] = lastPointIndex;
526 facesArray[facesInd * faceElementSize + 3] = lastTexIndex;
527 facesArray[facesInd * faceElementSize + 4] = pointIndex;
528 facesArray[facesInd * faceElementSize + 5] = texIndex;
529 smoothingGroupsArray[facesInd] = currentSmoothGroup;
531 lastPointIndex = pointIndex;
532 lastTexIndex = texIndex;
536 triangleMesh.getFaceSmoothingGroups().setAll(smoothingGroupsArray);
548 if (
DEBUG) System.out.println(
"CREATING TRIANGLE MESH");
549 if (
DEBUG) System.out.println(
" points = "+Arrays.toString(((TriangleMesh)
meshView.getMesh()).getPoints().toArray(
null)));
550 if (
DEBUG) System.out.println(
" texCoords = "+Arrays.toString(((TriangleMesh)
meshView.getMesh()).getTexCoords().toArray(
null)));
551 if (
DEBUG) System.out.println(
" faces = "+Arrays.toString(((TriangleMesh)
meshView.getMesh()).getFaces().toArray(
null)));
571 return (
float)Math.sqrt(
572 Math.pow(z2 - z1,2) +
573 Math.pow(x2 - x1,2) +
574 Math.pow(y2 - y1,2));
float distanceBetweenPoints(float x1, float y1, float z1, float x2, float y2, float z2)
ObjectProperty< PolygonMesh > meshProperty()
final ObjectProperty< CullFace > cullFaceProperty()
final ArrayChangeListener< ObservableFloatArray > meshPointsListener
void setMapBorderMode(MapBorderMode mapBorderMode)
ObjectProperty< CullFace > cullFace
ObjectProperty< DrawMode > drawMode
SimpleObjectProperty< MapBorderMode > mapBorderMode
MapBorderMode getMapBorderMode()
final ObjectProperty< DrawMode > drawModeProperty()
final void setDrawMode(DrawMode value)
SimpleObjectProperty< MapBorderMode > mapBorderModeProperty()
ObjectProperty< Material > materialProperty()
void setSubdivisionLevel(int subdivisionLevel)
SubdivisionMesh subdivisionMesh
ObjectProperty< PolygonMesh > meshProperty
final void setCullFace(CullFace value)
SimpleObjectProperty< BoundaryMode > boundaryMode
void setMaterial(Material material)
void setMesh(PolygonMesh mesh)
SimpleObjectProperty< BoundaryMode > boundaryModeProperty()
SimpleIntegerProperty subdivisionLevelProperty
TriangleMesh triangleMesh
final CullFace getCullFace()
static final boolean DEBUG
PolygonMeshView(PolygonMesh mesh)
BoundaryMode getBoundaryMode()
int getSubdivisionLevel()
final ArrayChangeListener< ObservableFloatArray > meshTexCoordListener
final DrawMode getDrawMode()
SimpleIntegerProperty subdivisionLevelProperty()
void setBoundaryMode(BoundaryMode boundaryMode)
ObjectProperty< Material > materialProperty
ObservableFloatArray getTexCoords()
ObservableIntegerArray getFaceSmoothingGroups()
ObservableFloatArray getPoints()
PolygonMesh getOriginalMesh()
void setSubdivisionLevel(int subdivisionLevel)
void setMapBorderMode(SubdivisionMesh.MapBorderMode mapBorderMode)
void setBoundaryMode(SubdivisionMesh.BoundaryMode boundaryMode)