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 float oldscore = 0;
8     public Matrix errorQuadric() { return quadric; }
9     public boolean quadricStale = false;
10     /** the nearest vertex in the "score_against" mesh */
11     public HasQuadric nearest_in_other_mesh;
12
13     /** the number of vertices in the other mesh for which this is the nearest_in_other_mesh */
14     public int    quadric_count;
15
16     /** the total error quadric (contributions from all vertices in other mesh for which this is nearest) */
17     public Matrix quadric = Matrix.ZERO;
18
19     public Matrix fundamentalQuadric = null;
20
21         public void recomputeFundamentalQuadricIfNeighborChanged() {
22             HasQuadric oldv = nearest_in_other_mesh;
23             HasQuadric newv = nearest();
24             if (oldv==newv) return;
25             recomputeFundamentalQuadric();
26             if (oldv!=null) oldv.recomputeFundamentalQuadricIfNeighborChanged();
27             // for some reason this causes an infinite loop
28             //if (newv!=null) newv.recomputeFundamentalQuadricIfNeighborChanged();
29         }
30         public void recomputeFundamentalQuadricIfStale() {
31             if (quadricStale || fundamentalQuadric==null) 
32                 recomputeFundamentalQuadric();
33         }
34         public void recomputeFundamentalQuadric() {
35             unApplyQuadricToNeighbor();
36             if (quadricStale || fundamentalQuadric==null) _recomputeFundamentalQuadric();
37             applyQuadricToNeighbor();
38         }
39     public abstract void _recomputeFundamentalQuadric();
40     public abstract void reComputeErrorAround();
41     public abstract void reComputeError();
42     public abstract void unComputeError();
43     public abstract void computeError();
44     public abstract HasQuadric nearest();
45         public void applyQuadricToNeighbor() {
46             HasQuadric new_nearest = nearest();
47             if (nearest_in_other_mesh != null && new_nearest == nearest_in_other_mesh) return;
48
49             if (nearest_in_other_mesh != null) unApplyQuadricToNeighbor();
50             if (nearest_in_other_mesh != null) throw new Error();
51
52             nearest_in_other_mesh = new_nearest;
53
54             if (nearest_in_other_mesh!=null) {
55                 nearest_in_other_mesh.unComputeError();
56                 nearest_in_other_mesh.quadric = nearest_in_other_mesh.quadric.plus(fundamentalQuadric());
57                 nearest_in_other_mesh.quadric_count++;
58                 nearest_in_other_mesh.computeError();
59             }
60
61             reComputeError();
62         }
63         public Matrix fundamentalQuadric() {
64             if (fundamentalQuadric == null) recomputeFundamentalQuadric();
65             return fundamentalQuadric;
66         }
67         public void unApplyQuadricToNeighbor() {
68             if (nearest_in_other_mesh == null) return;
69             if (fundamentalQuadric == null) return;
70             nearest_in_other_mesh.unComputeError();
71             nearest_in_other_mesh.quadric = nearest_in_other_mesh.quadric.minus(fundamentalQuadric);
72             nearest_in_other_mesh.quadric_count--;
73             if (nearest_in_other_mesh.quadric_count==0)
74                 nearest_in_other_mesh.quadric = Matrix.ZERO;
75             nearest_in_other_mesh.computeError();
76             nearest_in_other_mesh = null;
77         }
78 }