32 package eu.mihosoft.vrl.v3d.ext.openjfx.shape3d.symbolic;
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.ArrayList;
37 import java.util.HashMap;
38 import java.util.HashSet;
39 import java.util.List;
42 import javafx.geometry.Point2D;
113 for (
int p = 0; p < oldFaces.length; p += 2) {
125 for (
int p = 0; p < oldFaces.length; p += 2) {
126 faces[newFacesInd][2] =
getPointNewIndex(faceInfo, (p / 2 + 1) % faceInfo.edges.length);
127 faces[newFacesInd][3] =
getTexCoordNewIndex(faceInfo, (p / 2 + 1) % faceInfo.edges.length);
138 for (
int p = 0; p < oldFaces.length; p += 2) {
168 private void addEdge(Edge edge, FaceInfo faceInfo) {
170 if (edgeInfo ==
null) {
171 edgeInfo =
new EdgeInfo();
172 edgeInfo.edge = edge;
175 edgeInfo.faces.add(faceInfo);
185 private void addPoint(
int point, FaceInfo faceInfo, Edge edge) {
187 if (pointInfo ==
null) {
191 pointInfo.edges.add(edge);
192 pointInfo.faces.add(faceInfo);
203 if (pointInfo ==
null) {
207 pointInfo.edges.add(edge);
220 int n = face.length / 2;
221 FaceInfo faceInfo =
new FaceInfo(n);
226 int from = face[(n-1) * 2];
227 int texFrom = face[(n-1) * 2 + 1];
233 for (
int i = 0; i < n; i++) {
234 int to = face[i * 2];
235 int texTo = face[i * 2 + 1];
238 Point2D midTexCoord =
new Point2D((fu + tu) / 2, (fv + tv) / 2);
239 Edge edge =
new Edge(from, to);
240 faceInfo.edges[i] = edge;
241 faceInfo.edgeTexCoords[i] = midTexCoord;
246 u += tu / n; v += tv / n;
250 faceInfo.texCoord =
new Point2D(u, v);
257 int n = face.length / 2;
258 int[] faceVertices =
new int[n];
259 for (
int i = 0; i < n; i++) {
260 faceVertices[i] = face[i * 2];
265 for(EdgeInfo edgeInfo :
edgeInfos.values()) {
266 int[] edgeFacePoints =
new int[edgeInfo.faces.size()];
267 for (
int f = 0; f < edgeInfo.faces.size(); f++) {
268 edgeFacePoints[f] = edgeInfo.faces.get(f).facePoint;
270 edgeInfo.edgePoint =
points.
addEdgePoint(edgeFacePoints, edgeInfo.edge.from, edgeInfo.edge.to, edgeInfo.isBoundary());
282 int origPoint = srcPointIndex;
284 int[] facePoints =
new int[pointInfo.faces.size()];
285 for (
int f = 0; f < facePoints.length; f++) {
286 facePoints[f] = pointInfo.faces.get(f).facePoint;
288 int[] edgePoints =
new int[pointInfo.edges.size()];
289 boolean[] isEdgeBoundary =
new boolean[pointInfo.edges.size()];
290 int[] fromEdgePoints =
new int[pointInfo.edges.size()];
291 int[] toEdgePoints =
new int[pointInfo.edges.size()];
293 for (Edge edge : pointInfo.edges) {
295 edgePoints[i] = edgeInfo.edgePoint;
296 isEdgeBoundary[i] = edgeInfo.isBoundary();
297 fromEdgePoints[i] = edgeInfo.edge.from;
298 toEdgePoints[i] = edgeInfo.edge.to;
302 return destPointIndex;
313 private void calcControlTexCoord(FaceInfo faceInfo,
int srcPointIndex,
int srcTexCoordIndex,
int destTexCoordIndex){
320 for (
int i = 0; i < faceInfo.edges.length; i++) {
321 if ((faceInfo.edges[i].to == srcPointIndex) || (faceInfo.edges[i].from == srcPointIndex)) {
322 u += faceInfo.edgeTexCoords[i].getX() / 4;
323 v += faceInfo.edgeTexCoords[i].getY() / 4;
326 texCoords[destTexCoordIndex * 2] = (float) u;
327 texCoords[destTexCoordIndex * 2 + 1] = (float) v;
341 int destPointIndex =
reindex[srcPointIndex] - 1;
342 if (destPointIndex == -1) {
344 reindex[srcPointIndex] = destPointIndex + 1;
346 return destPointIndex;
357 Edge edge = faceInfo.edges[edgeInd];
359 return edgeInfo.edgePoint;
369 return faceInfo.facePoint;
384 return destTexCoordIndex;
397 texCoords[destTexCoordIndex * 2] = (float) faceInfo.edgeTexCoords[edgeInd].getX();
398 texCoords[destTexCoordIndex * 2 + 1] = (float) faceInfo.edgeTexCoords[edgeInd].getY();
399 return destTexCoordIndex;
409 int destTexCoordIndex = faceInfo.newTexCoordIndex - 1;
410 if (destTexCoordIndex == -1) {
412 faceInfo.newTexCoordIndex = destTexCoordIndex + 1;
414 texCoords[destTexCoordIndex * 2] = (float) faceInfo.texCoord.getX();
415 texCoords[destTexCoordIndex * 2 + 1] = (float) faceInfo.texCoord.getY();
417 return destTexCoordIndex;
423 private static class Edge {
434 public Edge(
int from,
int to) {
435 this.from = Math.min(from, to);
436 this.to = Math.max(from, to);
443 public int hashCode() {
445 hash = 41 * hash + this.from;
446 hash = 41 * hash + this.to;
454 public boolean equals(Object obj) {
458 if (getClass() != obj.getClass()) {
462 if (this.from != other.from) {
465 if (this.to != other.to) {
475 private static class EdgeInfo {
484 List<FaceInfo> faces =
new ArrayList<>(2);
491 public boolean isBoundary() {
492 return faces.size() == 1;
502 List<FaceInfo> faces =
new ArrayList<>(4);
505 Set<Edge> edges =
new HashSet<>(4);
513 for (Edge edge : edges) {
515 if (edgeInfo.isBoundary())
527 for (Edge edge : edges) {
529 if (!edgeInfo.isBoundary())
539 private static class FaceInfo {
554 Point2D[] edgeTexCoords;
561 public FaceInfo(
int n) {
563 edgeTexCoords =
new Point2D[n];
int addFacePoint(int[] vertices)
int addEdgePoint(int[] facePoints, int fromPoint, int toPoint, boolean isBoundary)
int addControlPoint(int[] facePoints, int[] edgePoints, int[] fromEdgePoints, int[] toEdgePoints, boolean[] isEdgeBoundary, int origPoint, boolean isBoundary, boolean hasInternalEdge)
int[] faceSmoothingGroups
SymbolicPointArray points
boolean hasInternalEdge()
int getPointNewIndex(FaceInfo faceInfo, int edgeInd)
void addEdge(Edge edge, FaceInfo faceInfo)
SymbolicPolygonMesh subdivide()
int getPointNewIndex(int srcPointIndex)
int getPointNewIndex(FaceInfo faceInfo)
MapBorderMode mapBorderMode
Map< Edge, EdgeInfo > edgeInfos
int getTexCoordNewIndex(FaceInfo faceInfo, int edgeInd)
SymbolicSubdivisionBuilder(SymbolicPolygonMesh oldMesh, BoundaryMode boundaryMode, MapBorderMode mapBorderMode)
void addPoint(int point, Edge edge)
int getTexCoordNewIndex(FaceInfo faceInfo)
int getTexCoordNewIndex(FaceInfo faceInfo, int srcPointIndex, int srcTexCoordIndex)
int calcControlPoint(int srcPointIndex)
SubdividedPointArray points
SymbolicPolygonMesh oldMesh
void calcControlTexCoord(FaceInfo faceInfo, int srcPointIndex, int srcTexCoordIndex, int destTexCoordIndex)
BoundaryMode boundaryMode
void addPoint(int point, FaceInfo faceInfo, Edge edge)
static SymbolicPolygonMesh subdivide(SymbolicPolygonMesh oldMesh, BoundaryMode boundaryMode, MapBorderMode mapBorderMode)