32 package eu.mihosoft.vrl.v3d.ext.openjfx.importers;
34 import eu.mihosoft.vrl.v3d.Vector3d;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.BitSet;
38 import java.util.HashMap;
39 import java.util.Iterator;
40 import java.util.LinkedList;
41 import java.util.List;
43 import java.util.Queue;
44 import javafx.scene.shape.TriangleMesh;
45 import javax.vecmath.Vector3f;
57 private Queue<Integer>
q;
83 notVisited =
new BitSet(
faces.length);
84 notVisited.set(0,
faces.length,
true);
85 q =
new LinkedList<Integer>();
96 int index = notVisited.previousSetBit(
faces.length - 1);
99 notVisited.set(index,
false);
100 List<Integer> res =
new ArrayList<Integer>();
101 while (!
q.isEmpty()) {
102 Integer faceIndex =
q.remove();
105 List<Integer> adjFaces = adjacentFaces.get(edge);
106 if (adjFaces ==
null) {
109 Integer adjFaceIndex = adjFaces.get(adjFaces.get(0).equals(faceIndex) ? 1 : 0);
110 if (!
visited.get(adjFaceIndex)) {
113 notVisited.set(adjFaceIndex,
false);
126 return !notVisited.isEmpty();
134 for (
int f = 0; f <
faces.length; f++) {
135 int[] face =
faces[f];
137 int n = face.length/2;
139 int from = face[(n-1) * 2];
140 int fromNormal = faceNormal[n-1];
141 for (
int i = 0; i < n; i++) {
142 int to = face[i * 2];
143 int toNormal = faceNormal[i];
144 Edge edge =
new Edge(from, to, fromNormal, toNormal);
147 fromNormal = toNormal;
158 Map<Edge, List<Integer>> adjacentFaces =
new HashMap<Edge, List<Integer>>();
159 for (
int f = 0; f <
faceEdges.length; f++) {
161 if (!adjacentFaces.containsKey(edge)) {
162 adjacentFaces.put(edge,
new ArrayList<Integer>());
164 adjacentFaces.get(edge).add(f);
167 for (Iterator<Map.Entry<
Edge, List<Integer>>> it = adjacentFaces.entrySet().iterator(); it.hasNext(); ) {
168 Map.Entry<
Edge, List<Integer>> e = it.next();
169 if (e.getValue().size() != 2) {
174 return adjacentFaces;
183 Vector3f getNormal(
int index) {
198 if (n1.x == 1.0e20f || n1.y == 1.0e20f || n1.z == 1.0e20f
199 || n2.x == 1.0e20f || n2.y == 1.0e20f || n2.z == 1.0e20f) {
203 Vector3f myN1 =
new Vector3f(n1);
205 Vector3f myN2 =
new Vector3f(n2);
217 Map<Edge, List<Integer>> smoothEdges =
new HashMap<Edge, List<Integer>>();
219 for (
int face = 0; face <
faceEdges.length; face++) {
221 List<Integer> adjFaces = adjacentFaces.get(edge);
222 if (adjFaces ==
null || adjFaces.size() != 2) {
226 int adjFace = adjFaces.get(adjFaces.get(0) == face ? 1 : 0);
228 int adjEdgeInd = Arrays.asList(adjFaceEdges).indexOf(edge);
229 if (adjEdgeInd == -1) {
230 System.out.println(
"Can't find edge " + edge +
" in face " + adjFace);
231 System.out.println(Arrays.asList(adjFaceEdges));
234 Edge adjEdge = adjFaceEdges[adjEdgeInd];
236 if (edge.isSmooth(adjEdge)) {
237 if (!smoothEdges.containsKey(edge)) {
238 smoothEdges.put(edge, adjFaces);
254 List<List<Integer>> groups =
new ArrayList<List<Integer>>();
257 groups.add(smoothGroup);
271 for (
int i = 0; i < groups.size(); i++) {
272 List<Integer> list = groups.get(i);
273 if (list.size() == 1) {
274 smGroups[list.get(0)] = 0;
276 for (
int j = 0; j < list.size(); j++) {
277 Integer faceIndex = list.get(j);
278 smGroups[faceIndex] = 1 << curGroup;
280 if (curGroup++ == 31) {
300 Map<Edge, List<Integer>> smoothEdges =
getSmoothEdges(adjacentFaces);
317 int fromNormal, toNormal;
327 public Edge(
int from,
int to,
int fromNormal,
int toNormal) {
328 this.from = Math.min(from, to);
329 this.to = Math.max(from, to);
330 this.fromNormal = Math.min(fromNormal, toNormal);
331 this.toNormal = Math.max(fromNormal, toNormal);
341 boolean smooth = (
isNormalsEqual(getNormal(fromNormal), getNormal(edge.fromNormal)) &&
isNormalsEqual(getNormal(toNormal), getNormal(edge.toNormal))) ||
352 hash = 41 * hash + this.from;
353 hash = 41 * hash + this.to;
365 if (getClass() != obj.getClass()) {
369 if (this.from != other.from) {
372 if (this.to != other.to) {
402 int faceElementSize = mesh.getFaceElementSize();
403 int[][]
faces =
new int[flatFaces.length/faceElementSize][faceElementSize];
404 for (
int f = 0; f <
faces.length; f++) {
405 for (
int e = 0; e < faceElementSize; e++) {
406 faces[f][e] = flatFaces[f * faceElementSize + e];
409 int pointElementSize = mesh.getPointElementSize();
410 int[][]
faceNormals =
new int[flatFaceNormals.length/pointElementSize][pointElementSize];
412 for (
int e = 0; e < pointElementSize; e++) {
413 faceNormals[f][e] = flatFaceNormals[f * pointElementSize + e];
boolean equals(Object obj)
boolean isSmooth(Edge edge)
Edge(int from, int to, int fromNormal, int toNormal)
List< List< Integer > > calcConnComponents(Map< Edge, List< Integer >> smoothEdges)
Map< Edge, List< Integer > > getAdjacentFaces()
static boolean isNormalsEqual(Vector3f n1, Vector3f n2)
static final float normalAngle
static int[] calcSmoothGroups(TriangleMesh mesh, int[] flatFaces, int[] flatFaceNormals, float[] normals)
SmoothingGroups(int faces[][], int[][] faceNormals, float[] normals)
boolean hasNextConnectedComponent()
int[] generateSmGroups(List< List< Integer >> groups)
Map< Edge, List< Integer > > getSmoothEdges(Map< Edge, List< Integer >> adjacentFaces)
List< Integer > getNextConnectedComponent(Map< Edge, List< Integer >> adjacentFaces)
static int[] calcSmoothGroups(int[][] faces, int[][] faceNormals, float[] normals)