1 /* =============================================================================
5 * =============================================================================
7 * Copyright (C) Stanford University, 2006. All Rights Reserved.
10 * =============================================================================
12 * For the license of bayes/sort.h and bayes/sort.c, please see the header
15 * ------------------------------------------------------------------------
17 * For the license of kmeans, please see kmeans/LICENSE.kmeans
19 * ------------------------------------------------------------------------
21 * For the license of ssca2, please see ssca2/COPYRIGHT
23 * ------------------------------------------------------------------------
25 * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the
26 * header of the files.
28 * ------------------------------------------------------------------------
30 * For the license of lib/rbtree.h and lib/rbtree.c, please see
31 * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree
33 * ------------------------------------------------------------------------
35 * Unless otherwise noted, the following license applies to STAMP files:
37 * Copyright (c) 2007, Stanford University
38 * All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions are
44 * * Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
47 * * Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in
49 * the documentation and/or other materials provided with the
52 * * Neither the name of Stanford University nor the names of its
53 * contributors may be used to endorse or promote products derived
54 * from this software without specific prior written permission.
56 * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY
57 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
59 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
61 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
62 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
64 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
66 * THE POSSIBILITY OF SUCH DAMAGE.
68 * =============================================================================
72 element rootElementPtr;
73 Queue_t initBadQueuePtr;
75 RBTree boundarySetPtr;
77 /* =============================================================================
79 * =============================================================================
81 public mesh(double angle) {
83 rootElementPtr = null;
84 initBadQueuePtr = new Queue_t(-1);
86 boundarySetPtr = new RBTree(0);
90 /* =============================================================================
92 * =============================================================================
94 void TMmesh_insert (element elementPtr, avltree edgeMapPtr) {
96 * Assuming fully connected graph, we just need to record one element.
97 * The root element is not needed for the actual refining, but rather
98 * for checking the validity of the final mesh.
100 if (rootElementPtr==null) {
101 rootElementPtr=elementPtr;
105 * Record existence of each of this element's edges
107 int numEdge = elementPtr.element_getNumEdge();
108 for (int i = 0; i < numEdge; i++) {
109 edge edgePtr = elementPtr.element_getEdge(i);
110 if (!edgeMapPtr.contains(edgePtr)) {
111 /* Record existance of this edge */
113 edgeMapPtr.insert(edgePtr, elementPtr);
114 yada.Assert(isSuccess);
117 * Shared edge; update each element's neighborList
120 element sharerPtr = (element)edgeMapPtr.find(edgePtr);
121 yada.Assert(sharerPtr!=null); /* cannot be shared by >2 elements */
122 elementPtr.element_addNeighbor(sharerPtr);
123 sharerPtr.element_addNeighbor(elementPtr);
124 isSuccess = edgeMapPtr.remove(edgePtr);
125 yada.Assert(isSuccess);
126 isSuccess = edgeMapPtr.insert(edgePtr,
127 null); /* marker to check >2 sharers */
128 yada.Assert(isSuccess);
133 * Check if really encroached
136 edge encroachedPtr = elementPtr.element_getEncroachedPtr();
137 if (encroachedPtr!=null) {
138 if (!boundarySetPtr.contains(encroachedPtr)) {
139 elementPtr.element_clearEncroached();
145 /* =============================================================================
147 * =============================================================================
149 public void TMmesh_remove(element elementPtr) {
150 yada.Assert(!elementPtr.element_isGarbage());
153 * If removing root, a new root is selected on the next mesh_insert, which
154 * always follows a call a mesh_remove.
156 if (rootElementPtr == elementPtr) {
161 * Remove from neighbors
164 List_t neighborListPtr = elementPtr.element_getNeighborListPtr();
165 List_Node it=neighborListPtr.head;
167 while (it.nextPtr!=null) {
169 element neighborPtr = (element)it.dataPtr;
170 List_t neighborNeighborListPtr = neighborPtr.element_getNeighborListPtr();
171 boolean status = neighborNeighborListPtr.remove(elementPtr);
175 elementPtr.element_setIsGarbage(true);
179 /* =============================================================================
180 * TMmesh_insertBoundary
181 * =============================================================================
183 boolean TMmesh_insertBoundary(edge boundaryPtr) {
184 return boundarySetPtr.insert(boundaryPtr,null);
188 /* =============================================================================
189 * TMmesh_removeBoundary
190 * =============================================================================
192 boolean TMmesh_removeBoundary(edge boundaryPtr) {
193 return boundarySetPtr.deleteObjNode(boundaryPtr);
197 /* =============================================================================
199 * =============================================================================
201 void createElement(coordinate[] coordinates, int numCoordinate,
202 avltree edgeMapPtr) {
203 element elementPtr = new element(coordinates, numCoordinate, angle);
204 yada.Assert(elementPtr!=null);
206 if (numCoordinate == 2) {
207 edge boundaryPtr = elementPtr.element_getEdge(0);
208 boolean status = boundarySetPtr.insert(boundaryPtr, null);
212 TMmesh_insert(elementPtr, edgeMapPtr);
214 if (elementPtr.element_isBad()) {
215 boolean status = initBadQueuePtr.queue_push(elementPtr);
221 /* =============================================================================
224 * Returns number of elements read from file
226 * Refer to http://www.cs.cmu.edu/~quake/triangle.html for file formats.
227 * =============================================================================
229 int mesh_read(String fileNamePrefix) {
230 char inputBuff[]=new char[256];
234 avltree edgeMapPtr = new avltree(0);
240 String fileName=fileNamePrefix+".node";
241 FileInputStream inputFile = new FileInputStream(fileName);
242 bytereader br=new bytereader(inputFile);
243 int numEntry=br.getInt();
244 int numDimension=br.getInt();
245 yada.Assert(numDimension == 2); /* must be 2-D */
246 int numCoordinate = numEntry + 1; /* numbering can start from 1 */
247 coordinate coordinates[] = new coordinate[numCoordinate];
248 for(i=0;i<numCoordinate;i++)
249 coordinates[i]=new coordinate();
251 for (i = 0; i < numEntry; i++) {
258 coordinates[id].x = x;
259 coordinates[id].y = y;
261 yada.Assert(i == numEntry);
265 * Read .poly file, which contains boundary segments
267 fileName=fileNamePrefix+".poly";
268 inputFile = new FileInputStream(fileName);
269 br=new bytereader(inputFile);
270 numEntry=br.getInt();
271 numDimension=br.getInt();
272 yada.Assert(numEntry == 0); /* .node file used for vertices */
273 yada.Assert(numDimension == 2); /* must be edge */
274 numEntry=br.getInt();
275 for (i = 0; i < numEntry; i++) {
279 coordinate insertCoordinates[]=new coordinate[2];
283 yada.Assert(a >= 0 && a < numCoordinate);
284 yada.Assert(b >= 0 && b < numCoordinate);
285 insertCoordinates[0] = coordinates[a];
286 insertCoordinates[1] = coordinates[b];
287 createElement(insertCoordinates, 2, edgeMapPtr);
289 yada.Assert(i == numEntry);
290 numElement += numEntry;
294 * Read .ele file, which contains triangles
296 fileName=fileNamePrefix+".ele";
297 inputFile = new FileInputStream(fileName);
298 br=new bytereader(inputFile);
299 numEntry=br.getInt();
300 numDimension=br.getInt();
301 yada.Assert(numDimension == 3); /* must be triangle */
302 for (i = 0; i < numEntry; i++) {
307 coordinate insertCoordinates[]=new coordinate[3];
312 yada.Assert(a >= 0 && a < numCoordinate);
313 yada.Assert(b >= 0 && b < numCoordinate);
314 yada.Assert(c >= 0 && c < numCoordinate);
315 insertCoordinates[0] = coordinates[a];
316 insertCoordinates[1] = coordinates[b];
317 insertCoordinates[2] = coordinates[c];
318 createElement(insertCoordinates, 3, edgeMapPtr);
320 yada.Assert(i == numEntry);
321 numElement += numEntry;
327 /* =============================================================================
329 * -- Returns NULL if none
330 * =============================================================================
332 element mesh_getBad() {
333 return (element)initBadQueuePtr.queue_pop();
337 /* =============================================================================
339 * =============================================================================
341 void mesh_shuffleBad (Random randomPtr) {
342 initBadQueuePtr.queue_shuffle(randomPtr);
346 /* =============================================================================
348 * =============================================================================
350 boolean mesh_check(int expectedNumElement) {
351 int numBadTriangle = 0;
352 int numFalseNeighbor = 0;
355 System.out.println("Checking final mesh:");
357 Queue_t searchQueuePtr = new Queue_t(-1);
358 avltree visitedMapPtr = new avltree(1);
361 * Do breadth-first search starting from rootElementPtr
363 yada.Assert(rootElementPtr!=null);
364 searchQueuePtr.queue_push(rootElementPtr);
365 while (!searchQueuePtr.queue_isEmpty()) {
366 List_t neighborListPtr;
368 element currentElementPtr = (element)searchQueuePtr.queue_pop();
369 if (visitedMapPtr.contains(currentElementPtr)) {
372 boolean isSuccess = visitedMapPtr.insert(currentElementPtr, null);
373 yada.Assert(isSuccess);
374 if (!currentElementPtr.checkAngles()) {
377 neighborListPtr = currentElementPtr.element_getNeighborListPtr();
379 List_Node it=neighborListPtr.head;
380 while (it.nextPtr!=null) {
382 element neighborElementPtr =
385 * Continue breadth-first search
387 if (!visitedMapPtr.contains(neighborElementPtr)) {
388 isSuccess = searchQueuePtr.queue_push(neighborElementPtr);
389 yada.Assert(isSuccess);
391 } /* for each neighbor */
395 } /* breadth-first search */
397 System.out.println("Number of elements = "+ numElement);
398 System.out.println("Number of bad triangles = "+ numBadTriangle);
400 return (!(numBadTriangle > 0 ||
401 numFalseNeighbor > 0 ||
402 numElement != expectedNumElement));