00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "std/stop_watch.H"
00019 #include "mi.H"
00020 #include "lmesh.H"
00021
00022 void
00023 fit(LMESHptr& mesh, bool do_gauss_seidel)
00024 {
00025 if (mesh->empty())
00026 return;
00027
00028
00029 stop_watch clock;
00030
00031 double max_err = mesh->get_bb().dim().length() * 1e-5;
00032 int n = mesh->nverts();
00033
00034
00035 Wpt_list C(n);
00036 Wpt_list L(n);
00037 for (int i=0; i<n; i++) {
00038 C += mesh->bv(i)->loc();
00039 L += Wpt::Origin();
00040 }
00041
00042
00043 double prev_err = 0;
00044 for (int k=0; k<50; k++) {
00045 double err = 0;
00046 if (do_gauss_seidel) {
00047
00048
00049 for (int j=0; j<n; j++) {
00050
00051 Wpt limit;
00052 mesh->lv(j)->limit_loc(limit);
00053 Wvec delt = C[j] - limit;
00054 err += delt.length();
00055 mesh->bv(j)->offset_loc(delt);
00056 }
00057 } else {
00058
00059
00060 int j;
00061 for (j=0; j<n; j++)
00062 mesh->lv(j)->limit_loc(L[j]);
00063 for (j=0; j<n; j++) {
00064 Wvec delt = C[j] - L[j];
00065 err += delt.length();
00066 mesh->bv(j)->offset_loc(delt);
00067
00068 }
00069 }
00070
00071 err /= n;
00072 if (prev_err != 0) {
00073 err_msg("Iter %d: avg error: %f, reduction: %f",
00074 k, err, err/prev_err);
00075 } else {
00076 err_msg("Iter %d: avg error: %f", k, err);
00077 }
00078 prev_err = err;
00079 if (err < max_err)
00080 break;
00081 }
00082
00083 err_msg("fitting took %.2f seconds", clock.elapsed_time());
00084 }
00085
00086 int
00087 main(int argc, char *argv[])
00088 {
00089 bool do_gauss_seidel = 0;
00090
00091 if (argc == 2 && str_ptr(argv[1]) == str_ptr("-g"))
00092 do_gauss_seidel = 1;
00093 else if(argc != 1)
00094 {
00095 err_msg("Usage: %s [ -g ] < mesh.sm > mesh-fit.sm", argv[0]);
00096 return 1;
00097 }
00098
00099 LMESHptr mesh = LMESH::read_jot_stream(cin);
00100 if (!mesh || mesh->empty())
00101 return 1;
00102
00103 fit(mesh, do_gauss_seidel);
00104
00105 mesh->write_stream(cout);
00106
00107 return 0;
00108 }
00109
00110