checkpoint
[anneal.git] / src / edu / berkeley / qfat / geom / HasQuadric.java
1 package edu.berkeley.qfat.geom;
2 import javax.media.opengl.*;
3
4 /** any object associated with a specific point in 3D space */
5 public abstract class HasQuadric extends HasPoint {
6
7     public Matrix errorQuadric() { return quadric; }
8     public boolean quadricStale = false;
9     /** the nearest vertex in the "score_against" mesh */
10     public HasQuadric nearest_in_other_mesh;
11
12     /** the number of vertices in the other mesh for which this is the nearest_in_other_mesh */
13     public int    quadric_count;
14
15     /** the total error quadric (contributions from all vertices in other mesh for which this is nearest) */
16     public Matrix quadric = Matrix.ZERO;
17
18     public Matrix fundamentalQuadric = null;
19
20     public void recomputeFundamentalQuadricIfNeighborChanged() {
21         HasQuadric oldv = nearest_in_other_mesh;
22         HasQuadric newv = nearest();
23         if (oldv==newv) return;
24         recomputeFundamentalQuadric();
25         if (oldv!=null) oldv.recomputeFundamentalQuadricIfNeighborChanged();
26         // for some reason this causes an infinite loop
27         //if (newv!=null) newv.recomputeFundamentalQuadricIfNeighborChanged();
28     }
29     public void recomputeFundamentalQuadricIfStale() {
30         if (quadricStale || fundamentalQuadric==null) 
31             recomputeFundamentalQuadric();
32     }
33     public void recomputeFundamentalQuadric() {
34         unApplyQuadricToNeighbor();
35         if (quadricStale || fundamentalQuadric==null) {
36             fundamentalQuadric = _recomputeFundamentalQuadric();
37             quadricStale = false;
38         }
39         applyQuadricToNeighbor();
40     }
41     public abstract Matrix _recomputeFundamentalQuadric();
42         public void reComputeError() {
43             unComputeError();
44             computeError();
45         }
46     public abstract void unComputeError();
47     public abstract void computeError();
48     public abstract HasQuadric nearest();
49     public void applyQuadricToNeighbor() {
50         HasQuadric new_nearest = nearest();
51         if (nearest_in_other_mesh != null && new_nearest == nearest_in_other_mesh) return;
52
53         if (nearest_in_other_mesh != null) unApplyQuadricToNeighbor();
54         if (nearest_in_other_mesh != null) throw new Error();
55
56         nearest_in_other_mesh = new_nearest;
57
58         if (nearest_in_other_mesh!=null) {
59             nearest_in_other_mesh.unComputeError();
60             nearest_in_other_mesh.quadric = nearest_in_other_mesh.quadric.plus(fundamentalQuadric());
61             nearest_in_other_mesh.quadric_count++;
62             nearest_in_other_mesh.computeError();
63         }
64
65         reComputeError();
66     }
67     public Matrix fundamentalQuadric() {
68         if (fundamentalQuadric == null) recomputeFundamentalQuadric();
69         return fundamentalQuadric;
70     }
71     public void unApplyQuadricToNeighbor() {
72         if (nearest_in_other_mesh == null) return;
73         if (fundamentalQuadric == null) return;
74         nearest_in_other_mesh.unComputeError();
75         nearest_in_other_mesh.quadric = nearest_in_other_mesh.quadric.minus(fundamentalQuadric);
76         nearest_in_other_mesh.quadric_count--;
77         if (nearest_in_other_mesh.quadric_count==0)
78             nearest_in_other_mesh.quadric = Matrix.ZERO;
79         nearest_in_other_mesh.computeError();
80         nearest_in_other_mesh = null;
81     }
82 }