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 unComputeError() { setError(0); }
43     public void reComputeError() {
44         unComputeError();
45         computeError();
46     }
47     public abstract void setError(float nerror);
48     public abstract void computeError();
49     public abstract HasQuadric nearest();
50     public void applyQuadricToNeighbor() {
51         HasQuadric new_nearest = nearest();
52         if (nearest_in_other_mesh != null && new_nearest == nearest_in_other_mesh) return;
53
54         if (nearest_in_other_mesh != null) unApplyQuadricToNeighbor();
55         if (nearest_in_other_mesh != null) throw new Error();
56
57         nearest_in_other_mesh = new_nearest;
58
59         if (nearest_in_other_mesh!=null) {
60             nearest_in_other_mesh.unComputeError();
61             nearest_in_other_mesh.quadric = nearest_in_other_mesh.quadric.plus(fundamentalQuadric());
62             nearest_in_other_mesh.quadric_count++;
63             nearest_in_other_mesh.computeError();
64         }
65
66         reComputeError();
67     }
68     public Matrix fundamentalQuadric() {
69         if (fundamentalQuadric == null) recomputeFundamentalQuadric();
70         return fundamentalQuadric;
71     }
72     public void unApplyQuadricToNeighbor() {
73         if (nearest_in_other_mesh == null) return;
74         if (fundamentalQuadric == null) return;
75         nearest_in_other_mesh.unComputeError();
76         nearest_in_other_mesh.quadric = nearest_in_other_mesh.quadric.minus(fundamentalQuadric);
77         nearest_in_other_mesh.quadric_count--;
78         if (nearest_in_other_mesh.quadric_count==0)
79             nearest_in_other_mesh.quadric = Matrix.ZERO;
80         nearest_in_other_mesh.computeError();
81         nearest_in_other_mesh = null;
82     }
83 }