Example #1
0
/////////////////////////////////////
// put_visibility()
/////////////////////////////////////
void
HatchingGroupFixed::put_visibility(TAGformat &d) const
{
   err_mesg(ERR_LEV_SPAM, "HatchingGroupFixed::put_visibility()"); 

   BMESHptr m = _patch->mesh();
   LMESHptr lm = dynamic_pointer_cast<LMESH>(m);
   if (lm)
      m = lm->cur_mesh();

   Bface_list::size_type k;
   vector<int> indices;
   CBface_list& faces = m->faces();
        
   for (k=0; k< faces.size(); k++) {
      HatchingSimplexDataFixed *hsdf = HatchingSimplexDataFixed::find(faces[k]);
      if (hsdf) {
         if (hsdf->exists(this))
            indices.push_back(faces[k]->index());
      }
   }
   err_mesg(ERR_LEV_SPAM, "HatchingGroupFixed::put_visibility() - Stored %d tri indices.", indices.size());

   d.id();
   *d << indices;
   d.end_id();
}
Example #2
0
void
LMESH::_merge(BMESHptr bm)
{
   // merge the given mesh into this one.

   // error checking was done before this protected method was called.
   // so this convenient cast is safe:
   LMESHptr m = static_pointer_cast<LMESH>(bm);

   // merge subdivision meshes (recursively) first. but if this one
   // has fewer levels of subdivision, truncate the other one to the
   // same number of levels.
   if (_subdiv_mesh && m->_subdiv_mesh)
      _subdiv_mesh->_merge(m->_subdiv_mesh);
   else
      m->delete_subdiv_mesh(); // ensure it has no finer level meshes

   // Get the dirty vertices from m and put them into this
   // mesh's dirty list:
   m->_dirty_verts.clear_bits(Lvert::DIRTY_VERT_LIST_BIT);
   while (!m->_dirty_verts.empty()) {
      add_dirty_vert((Lvert*)m->_dirty_verts.back());
      m->_dirty_verts.pop_back();
   }

   // this concludes the LMESH-specific aspect of the merge
   // method. now just continue with the normal merge...
   BMESH::_merge(bm);
}
Example #3
0
/////////////////////////////////////
// get_visibility()
/////////////////////////////////////
void
HatchingGroupFixed::get_visibility(TAGformat &d)
{
   err_mesg(ERR_LEV_SPAM, "HatchingGroupFixed::get_visibility()"); 

   BMESHptr m = _patch->mesh();
   LMESHptr lm = dynamic_pointer_cast<LMESH>(m);
   if (lm)
      m = lm->cur_mesh();

   vector<int>::size_type k;
   int ctr=0;
   vector<int> indices;
   CBface_list& faces = m->faces();

   *d >> indices;

   for (k=0; k<indices.size(); k++) {
      HatchingSimplexDataFixed *hsdf =
         HatchingSimplexDataFixed::find(faces[indices[k]]);
      if (!hsdf) {
         hsdf = new HatchingSimplexDataFixed(faces[indices[k]]);
         ctr++;
      }
      hsdf->add(this);
   }

   err_mesg(ERR_LEV_SPAM, "HatchingGroupFixed::get_visibility() - Flagged %d tris and added %d new simplex data.", indices.size(), ctr);
}
Example #4
0
/////////////////////////////////////
// load_scene()
/////////////////////////////////////
void
BaseJOTapp::load_scene()
{
   while (_argc > 1) {
      if (_argv[1][0] == '-') {
         char flag = _argv[1][1];
         pop_arg();
         switch(flag) {
          case 'm':
            load_sm_file(_argv[1]);
            break;
          case 'o':
            load_obj_file(_argv[1]);
            break;
          case 'j':
            load_jot_file(_argv[1]);
            break;
          default:
            print_usage();
            WORLD::Quit();
         }
      } else {
         if (!load_sm_file(_argv[1]))
            load_jot_file(_argv[1]);
      }
      pop_arg();
   }

   if (0) {
      LMESHptr m = new LMESH;
      m->Sphere();
      create_mesh(m, "sphere");
   }

   // Do "viewall" if:
   //   (1) the camera was not specified in file, and
   //   (2) at least one 3D object is outside the view frustum.

   for (int i=0; i<_windows.num(); i++)
      if (_windows[i]->_view->cam()->data()->loaded_from_file())
         return;

   for (int j=0; j<DRAWN.num(); j++) {
      GEOM* geom = GEOM::upcast(DRAWN[j]);
      if (geom && geom->bbox().is_off_screen()) {
         VIEW::peek()->viewall();
         return; // once is enough
      }
   }
}
Example #5
0
void 
LMESH::set_parent(LMESH* parent)
{
   assert(parent);
   _parent_mesh = parent; 
   _subdiv_level = parent->subdiv_level() + 1;
   LMESHptr c = control_mesh();
   assert(c != nullptr);
   if (c->has_name()) {
      char tmp[32];
      sprintf(tmp, "%d", _subdiv_level);
      set_name(c->get_name() + "-sub" + tmp);
   }
}
Example #6
0
inline void
add_face(LMESHptr& mesh, Face* f)
{
   assert(mesh && f);
   switch (f->nverts) {
    case 3:     // triangle
      mesh->add_face(f->verts[2], f->verts[1], f->verts[0]);
      break;
    case 4:     // quad
      mesh->add_quad(f->verts[3], f->verts[2], f->verts[1], f->verts[0]);
      break;
    default:    // other
      // XXX - should fix this to convert to triangles
      err_msg("ply2sm: can't add face: %d-gon", f->nverts);
   }
}
Example #7
0
int 
main(int argc, char *argv[])
{
   int num_levels = 1;

   if (argc == 2)
      num_levels = max(atoi(argv[1]), 0);
   else if(argc != 1) {
      err_msg("Usage: %s [ num_levels ] < mesh.sm > mesh-sub.sm", argv[0]);
      return 1;
   }

   LMESHptr mesh = LMESH::read_jot_stream(cin);
   if (!mesh || mesh->empty())
      return 1; // didn't work
   mesh->set_subdiv_loc_calc(new LoopLoc());

   if (Config::get_var_bool("JOT_PRINT_MESH")) {
      cerr << "input mesh:" << endl;
      mesh->print();
   }

   if (num_levels > 0)
      mesh->update_subdivision(num_levels);

   if (Config::get_var_bool("JOT_PRINT_MESH")) {
      cerr << "level " << num_levels << " mesh:" << endl;
      mesh->cur_mesh()->print();
   }

   mesh->cur_mesh()->write_stream(cout);

   return 0;
}
Example #8
0
inline void
read_vert(LMESHptr mesh, istream& in)
{
   double x, y, z;
   in >> x >> y >> z;
   skip_line(in);
   assert(mesh);
   mesh->add_vertex(Wpt(x,y,z));
}
Example #9
0
inline Bvert_list
copy_verts(CBvert_list& verts, LMESHptr mesh)
{
   Bvert_list ret(verts.size());
   for (Bvert_list::size_type i=0; i<verts.size(); i++) {
      ret.push_back(mesh->add_vertex(verts[i]->loc()));
   }
   return ret;
}
Example #10
0
bool
LMESH::update_subdivision(CBface_list& faces, int k)
{
   static bool debug = Config::get_var_bool("DEBUG_BFACE_LIST_SUBDIVISION",false);

   if (debug) {
      cerr << "LMESH::update_subdivision: " << faces.size()
           << " faces to level "<< k << endl;
   }

   if (k  < 0)
      return false;

   if (faces.empty())
      return true;

   LMESHptr m = dynamic_pointer_cast<LMESH>(faces.mesh());
   if (!m) {
      err_adv(debug, "  error: non-LMESH");
      return false;
   }

   // Ensure mesh is up-to-date wrt controllers
   BMESHobs::broadcast_update_request(m);

   if (k == 0)
      return true;

   // generate lext-level mesh if needed
   if (!m->allocate_subdiv_mesh()) {
      err_adv(debug, "  error: can't allocate subdiv mesh");
      return false;
   }

   // update subdivision for the one-ring, 1-level down
   update_faces(faces.one_ring_faces(), debug);
   update_faces(faces.secondary_faces(), debug);

   assert(m->subdiv_mesh());
   m->subdiv_mesh()->changed(VERT_POSITIONS_CHANGED);

   // then recurse
   return update_subdivision(get_subdiv_faces(faces,1), k-1);
}
Example #11
0
LMESHptr 
Bbase::get_inflate_mesh() const
{
   TEXBODY* tex = texbody();
   if (!tex) {
      err_msg("Bbase::get_inflate_mesh: Error: geom is non-TEXBODY");
      return 0;
   }

   LMESHptr ret = LMESH::upcast(tex->get_inflate_mesh(mesh()));
   if (!ret) {
      return 0;
   }

   // Use the same subdivision scheme:
   ret->set_subdiv_loc_calc(_mesh->loc_calc()->dup());

   return ret;
}
Example #12
0
inline LMESHptr
get_inflate_mesh(LMESHptr skel_mesh)
{
   if (!skel_mesh)
      return nullptr;
   TEXBODY* tex = dynamic_cast<TEXBODY*>(skel_mesh->geom());
   if (!tex)
      return nullptr;
   return dynamic_pointer_cast<LMESH>(tex->get_inflate_mesh(skel_mesh));
}
Example #13
0
LMESHptr
LMESH::get_lmesh(const string& exact_name)
{
   // Return an LMESH with the given name.  If one already exists,
   // return that one.  Otherwise create a new LMESH with the desired
   // name.  Fails (returns null) if the name is invalid (null string)
   // or the name is already taken by a BMESH that is not an LMESH.

   bool debug = NameLookup<BMESH>::_debug;

   // Make sure they're not asking for the null string:
   if (exact_name == "") {
      if (debug)
         cerr << "LMESH::get_lmesh: error: name is empty" << endl;
      return nullptr;
   }

   // Does a mesh with the requested name exist?
   BMESHptr mesh = dynamic_cast<BMESH*>(NameLookup<BMESH>::lookup(exact_name))->shared_from_this();

   // If no mesh of that name exists, create a new one:
   if (!mesh) {
      LMESHptr ret = make_shared<LMESH>();
      assert(ret && !ret->has_name());
      ret->set_name(exact_name);
      return ret;
   }

   // A BMESH with the requested name already exists;
   // if it is not also an LMESH, this is an error:
   LMESHptr lm = dynamic_pointer_cast<LMESH>(mesh);
   if (debug && !lm) {
      cerr << "LMESH::get_lmesh: error: found requested name: "
           << exact_name
           << ", but it is not an LMESH"
           << endl;
   }
   return lm;
}
Example #14
0
int 
main(int argc, char *argv[])
{
   bool do_gauss_seidel = 0;

   if (argc == 2 && str_ptr(argv[1]) == str_ptr("-g"))
      do_gauss_seidel = 1;
   else if(argc != 1)
   {
      err_msg("Usage: %s [ -g ] < mesh.sm > mesh-fit.sm", argv[0]);
      return 1;
   }

   LMESHptr mesh = LMESH::read_jot_stream(cin);
   if (!mesh || mesh->empty())
      return 1; // didn't work

   fit(mesh, do_gauss_seidel);

   mesh->write_stream(cout);

   return 0;
}
Example #15
0
void
Lface::delete_subdiv_elements()
{
   // Make this lightweight, so you can call
   // it when you're not sure if you need to:
   if (!is_set(SUBDIV_ALLOCATED_BIT))
      return;
   clear_bit(SUBDIV_ALLOCATED_BIT);

   // After this we need to get treated as a "dirty" face.
   // That means the vertices have to be dirty
   lv(1)->mark_dirty();
   lv(2)->mark_dirty();
   lv(3)->mark_dirty();

   LMESHptr submesh = lmesh()->subdiv_mesh();
   assert(submesh);

   // Removing a face (or edge) also causes it to remove
   // *its* subdiv elements.  I.e., this is recursive.

   Lface* subface;
   if ((subface = subdiv_face_center()))
      submesh->remove_face(subface);
   if ((subface = subdiv_face1()))
      submesh->remove_face(subface);
   if ((subface = subdiv_face2()))
      submesh->remove_face(subface);
   if ((subface = subdiv_face3()))
      submesh->remove_face(subface);

   Ledge* subedge;
   if ((subedge = subdiv_edge1()))
      submesh->remove_edge(subedge);
   if ((subedge = subdiv_edge2()))
      submesh->remove_edge(subedge);
   if ((subedge = subdiv_edge3()))
      submesh->remove_edge(subedge);
}
Example #16
0
SubdivUpdater::SubdivUpdater(LMESHptr m, CBvert_list& verts) :
   _parent(nullptr)
{
   // Screened in SubdivUpdater::create():
   assert(m && m == verts.mesh());

   _mesh = m;
   _verts = verts;

   // Get bbases, add to inputs
   _inputs = Bbase::find_owners(verts).bnodes();

   if (debug) {
      err_msg("SubdivUpdater::SubdivUpdater:");
      cerr << "  "; print_dependencies();
      err_msg("  level %d, %d verts, %d boss memes",
              m->subdiv_level(), verts.size(),
              Bbase::find_boss_vmemes(verts).size());
   }

   // If not covered, create parent
   if (!Bbase::is_covered(verts)) {
   
      // Get parent verts list
      Bvert_list parents = LMESH::get_subdiv_inputs(verts);

      // If non-empty create parent SubdivUpdater
      if (!parents.empty()) {

         // Create parent subdiv updater on parent verts
         // and add to _inputs
         _parent = create(parents);
         _inputs += _parent;
      }

   }

   hookup();
}
Example #17
0
   CAMwidget_anchor() : GEOM() {
      // Start with an empty LMESH:
      LMESHptr mesh = new LMESH();

      // Ensure mesh knows its containing GEOM:
      mesh->set_geom(this);

      // Make a ball shape
      mesh->Icosahedron();
      mesh->refine();           // smooth it once

      // Regardless of current rendering mode,
      // always use Gouraud shading:
      mesh->set_render_style(SmoothShadeTexture::static_name());

      // Color the Patch blue:
      mesh->patch(0)->set_color(COLOR(0.1, 0.1, 0.9));

      // Store the mesh:
      _body = mesh;

      set_name("CAMwidget_anchor");
   }
Example #18
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 #19
0
inline string
get_name(LMESHptr m)
{
   return (m && m->geom()) ? m->geom()->name() :
      (m ? "null geom" : "null mesh");
}
Example #20
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());
}