@@ -49,95 +49,15 @@ public MemorySegment toManifold(CSG csg) throws Throwable {
4949 if (csg == null )
5050 throw new IllegalArgumentException ("csg must not be null" );
5151
52- List <Polygon > polygons = csg .getPolygons ();
53- if (polygons == null || polygons .isEmpty ())
54- throw new IllegalArgumentException ("CSG has no polygons" );
55-
56- // Build an indexed triangle mesh.
57- // Use a tolerance-free exact key so we don't merge
58- // numerically-close-but-distinct verts.
59- Map <String , Integer > vertexIndex = new HashMap <>();
60- List <double []> vertexList = new ArrayList <>();
61- List <Long > triList = new ArrayList <>();
62-
63- for (Polygon incoming : polygons ) {
64- for (Polygon poly : PolygonUtil .triangulatePolygon (incoming )) {
65- List <Vertex > pverts = poly .getVertices ();
66- if (pverts == null || pverts .size () < 3 )
67- continue ;
68-
69- // Fan triangulation: (0,1,2), (0,2,3), (0,3,4), ...
70- int i0 = intern (pverts .get (0 ), vertexIndex , vertexList );
71- for (int i = 1 ; i < pverts .size () - 1 ; i ++) {
72- int i1 = intern (pverts .get (i ), vertexIndex , vertexList );
73- int i2 = intern (pverts .get (i + 1 ), vertexIndex , vertexList );
74-
75- // Skip degenerate triangles (two or more identical indices).
76- if (i0 == i1 || i1 == i2 || i0 == i2 )
77- continue ;
78-
79- triList .add ((long ) i0 );
80- triList .add ((long ) i1 );
81- triList .add ((long ) i2 );
82- }
83- }
84- }
8552
86- if (triList .isEmpty ())
87- throw new IllegalArgumentException ("CSG produced no valid triangles after triangulation" );
53+ double [] vertices = csg .getVertices ();
8854
89- long nVerts = vertexList .size ();
90- long nTris = triList .size () / 3 ;
91-
92- // Flatten vertex list into a primitive array.
93- double [] vertices = new double [(int ) (nVerts * 3 )];
94- for (int i = 0 ; i < nVerts ; i ++) {
95- double [] v = vertexList .get (i );
96- vertices [i * 3 ] = v [0 ];
97- vertices [i * 3 + 1 ] = v [1 ];
98- vertices [i * 3 + 2 ] = v [2 ];
99- }
100-
101- // Flatten triangle index list.
102- long [] triangles = new long [triList .size ()];
103- for (int i = 0 ; i < triList .size (); i ++) {
104- triangles [i ] = triList .get (i );
105- }
106-
107- MemorySegment ms = manifold .importMeshGL64 (vertices , triangles , nVerts , nTris );
55+ long [] triangles = csg .getTriangles ();
56+ MemorySegment ms = manifold .importMeshGL64 (vertices , triangles , vertices .length , triangles .length );
10857 checkResult (ms );
10958 return ms ;
11059 }
11160
112- /**
113- * Returns the index of {@code v} in {@code vertexList}, inserting it if not
114- * already present. The key is an exact string representation of (x, y, z) using
115- * {@link Double#toHexString} so that only bit-identical positions are merged,
116- * matching the BSP's behavior.
117- */
118- private static int intern (Vertex v , Map <String , Integer > index , List <double []> list ) {
119- // 1. Lower the precision slightly. 1e9 is too high for 'double' stability
120- // after multiple CSG operations. 1e7 (0.1 nanometer) is the "sweet spot".
121- double precision = 1e7 ;
122-
123- long x = Math .round (v .pos .x * precision );
124- long y = Math .round (v .pos .y * precision );
125- long z = Math .round (v .pos .z * precision );
126-
127- String key = x + "," + y + "," + z ;
128-
129- return index .computeIfAbsent (key , k -> {
130- int idx = list .size ();
131- // Use the RAW position for the first instance of this vertex.
132- // This keeps the geometry as true to the BSP as possible.
133- list .add (new double [] { v .pos .x , v .pos .y , v .pos .z });
134- return idx ;
135- });
136- }
137- // -------------------------------------------------------------------------
138- // helpers
139-
140-
14161 /**
14262 * Converts a native manifold {@link MemorySegment} to a JCSG {@link CSG}.
14363 *
@@ -168,31 +88,9 @@ public CSG fromManifold(MemorySegment ms) throws Throwable {
16888 if (triCount == 0 )
16989 return new CSG ();
17090
171- ArrayList <Polygon > polygons = new ArrayList <>(triCount );
172-
173- for (int t = 0 ; t < triCount ; t ++) {
174- int base = t * 3 ;
175-
176- Vector3d p0 = vertexAt (verts , (int ) tris [base ]);
177- Vector3d p1 = vertexAt (verts , (int ) tris [base + 1 ]);
178- Vector3d p2 = vertexAt (verts , (int ) tris [base + 2 ]);
179-
180- List <Vertex > vertices = Arrays .asList (new Vertex (p0 ), new Vertex (p1 ), new Vertex (p2 ));
181-
182- polygons .add (new Polygon (vertices ));
183- }
184-
185- return CSG .fromPolygons (polygons );
91+ return new CSG (verts , tris , verts .length , triCount );
18692 }
18793
188- // -------------------------------------------------------------------------
189- // helpers
190-
191-
192- private static Vector3d vertexAt (double [] verts , int index ) {
193- int base = index * 3 ;
194- return new Vector3d (verts [base ], verts [base + 1 ], verts [base + 2 ]);
195- }
19694
19795 /**
19896 * Slices the given CSG at Z=0 and returns the resulting cross-section as a list
@@ -366,7 +264,7 @@ private void checkResult(MemorySegment... memorySegments) throws Throwable {
366264 System .out .println ("Tris: " + manifold .numTri (ms ));
367265 System .out .println ("Genus: " + manifold .genus (ms ));
368266 throw new NonManifoldShapeError ("Error was " + err );
369- }else {
267+ } else {
370268 System .out .println ("Manifold check ok!" );
371269 }
372270 }
@@ -387,7 +285,7 @@ public CSG hull(List<Vector3d> points) throws Throwable {
387285
388286 CSG fromManifold = fromManifold (mem );
389287 manifold .delete (mem );
390- mem = null ;
288+ mem = null ;
391289 return fromManifold ;
392290 } finally {
393291 manifold .delete (mem );
0 commit comments