Example #1
0
/******************************************************************************
Write out a jot .sm file.
******************************************************************************/
void
write_sm()
{
   LMESHptr mesh = make_shared<LMESH>();
   
   int i=0;

   //******** Build the mesh ********

   err_adv(debug, "read ply file: %d vertices, %d faces\n", nverts, nfaces);

   err_adv(debug, "building mesh:");

   // Add vertices to mesh
   err_adv(debug, "  adding vertices...");
   for (i = 0; i < nverts; i++)
      mesh->add_vertex(Wpt(vlist[i]->x, vlist[i]->y, vlist[i]->z));
   err_adv(debug, "  done\n");

   // Add per-vertex colors if needed
   if (per_vertex_color) {
      err_adv(debug, "  adding colors...");
      for (i = 0; i < nverts; i++)
         mesh->bv(i)->set_color(COLOR(vlist[i]->r, vlist[i]->g, vlist[i]->b));
      err_adv(debug, "  done\n");
   }

   // Add faces
   err_adv(debug, "  adding faces...");
   for (i = 0; i < nfaces; i++)
      add_face(mesh, flist[i]);
   err_adv(debug, "  done\n");

   //******** Filter the mesh ********

   err_adv(debug, "filtering mesh...");

   // Remove any isolated vertices
   for (i=mesh->nverts()-1; i>=0; i--) {
      if (mesh->bv(i)->degree() == 0) {
         mesh->remove_vertex(mesh->bv(i));
      }
   }
   mesh->changed();

   // Remove duplicate vertices while we're at it
   mesh->remove_duplicate_vertices(false); // don't keep the bastards

   // Check for consistent orientation of normals
   bool is_bad = false;
   for (i=0; i<mesh->nedges(); i++)
      if (!mesh->be(i)->consistent_orientation())
         is_bad = true;
   if (is_bad)
      err_msg("Warning: inconsistently oriented triangles -- can't fix");

   // Optional: recenter mesh
   if (Config::get_var_bool("JOT_RECENTER"))
      mesh->recenter();

   // Optional: print stats
   if (Config::get_var_bool("JOT_PRINT_MESH"))
      mesh->print();

   err_adv(debug, "done\n");

   //******** Write mesh ********

   err_adv(debug, "writing mesh...");
   mesh->write_stream(cout);
   err_adv(debug, "done\n");
}
Example #2
0
void
fit(LMESHptr& mesh, bool do_gauss_seidel)
{
   if (mesh->empty())
      return;

   // time this
   stop_watch clock;

   double max_err = mesh->get_bb().dim().length() * 1e-5;
   int n = mesh->nverts();

   // get original control point locations
   Wpt_list C(n);   // original control points
   Wpt_list L(n);   // current limit points
   for (int i=0; i<n; i++) {
      C += mesh->bv(i)->loc();
      L += Wpt::Origin();
   }

   // do 50 iterations...
   double prev_err = 0;
   for (int k=0; k<50; k++) {
      double err = 0;
      if (do_gauss_seidel) {
         // Gauss-Seidel iteration: use updated values from the
         // current iteration as they are computed...
         for (int j=0; j<n; j++) {
            // don't need that L[] array...
            Wpt limit;
            mesh->lv(j)->limit_loc(limit);
            Wvec delt = C[j] - limit;
            err += delt.length();
            mesh->bv(j)->offset_loc(delt);
         }
      } else {
         // compute the new offsets from the offsets computed in the
         // previous iteration
         int j;
         for (j=0; j<n; j++)
            mesh->lv(j)->limit_loc(L[j]);
         for (j=0; j<n; j++) {
            Wvec delt = C[j] - L[j];
            err += delt.length();
            mesh->bv(j)->offset_loc(delt);

         }
      }
      // compute the average error:
      err /= n;
      if (prev_err != 0) {
         err_msg("Iter %d: avg error: %f, reduction: %f",
                 k, err, err/prev_err);
      } else {
         err_msg("Iter %d: avg error: %f", k, err);
      }
      prev_err = err;
      if (err < max_err)
         break;
   }

   err_msg("fitting took %.2f seconds", clock.elapsed_time());
}