コード例 #1
0
ファイル: inflate.C プロジェクト: ArnaudGastinel/jot-lib
//! Given the starting face "orig_face" and an offset amount "dist",
//! determine the appropriate edit level, re-map orig_face to that
//! level, and "inflate" the portion of the mesh reachable from
//! orig_face by amount dist. The offset may be made relative to the
//! local edge length.
bool
INFLATE::do_inflate(
   Bface*               orig_face,
   double               dist,
   Bsurface*&           output,
   Bface_list*&         reversed_faces,
   MULTI_CMDptr         cmd)
{

   // Reject garbage
   if (fabs(dist) < epsAbsMath()) {
      err_adv(debug, "INFLATE::do_inflate: bad offset distance: %f", dist);
      return 0;
   }

   // Throw out trash
   if (!get_lmesh(orig_face)) {
      err_adv(debug, "INFLATE::do_inflate: error: bad face");
      return 0;
   }
   Lface* face = (Lface*)orig_face;

   err_adv(debug, "INFLATE::do_inflate: face at level %d", subdiv_level(face));

   // Decide which level to do inflation -- should match offset dist

   int rel_level = 0;
   // XXX - it may not be a good idea
   //if (!choose_level(face, dist, rel_level))    // defined above
   //   return 0;

   // Remap face to chosen level
   face = remap(face, rel_level);
   if (!face) {
      err_adv(debug, "INFLATE::do_inflate: can't remap %d from level %d",
              rel_level, subdiv_level(face));
      return 0;
   }
   assert(face && face->mesh());
   err_adv(debug, "chosen edit level: %d", subdiv_level(face));

   // Get set of reachable faces:
   Bface_list set = Bface_list::reachable_faces(face);
   assert(set.mesh() != NULL);
   err_adv(debug, "reachable faces: %d, subdiv level: %d, total faces: %d",
           set.num(), set.mesh()->subdiv_level(), set.mesh()->nfaces());

   if (!set.is_consistently_oriented()) {
      err_msg("INFLATE::do_inflate: rejecting inconsistently \
              oriented surface...");
      return 0;
   }
コード例 #2
0
ファイル: sweep.cpp プロジェクト: QuLogic/jot-lib
//! Given a set of enclosed face, activate the widget to sweep out a
//! shape. Checks for errors, returns true on success.
bool
SWEEP_DISK::setup(CGESTUREptr& gest, double dur)
{

   static bool debug =
      Config::get_var_bool("DEBUG_SWEEP_SETUP",false) || debug_all;

   if (!(gest && gest->is_dslash())) {
      err_adv(debug, "SWEEP_DISK::setup: bad gesture");
      return false;
   }

   // XXX - shouldn't require it is a Panel:
   Panel* p = dynamic_cast<Panel*>(Bsurface::hit_ctrl_surface(gest->start()));
   if (!p) {
      err_adv(debug, "SWEEP_DISK::setup: non-panel");
      return false;
   }

   Bface_list faces = p->bfaces();

   _boundary = faces.get_boundary();
   if (_boundary.num_line_strips() != 1) {
      err_adv(debug, "SWEEP_DISK::setup: error: boundary is not a single piece");
      return false;
   }

   // Get the best-fit plane, rejecting if the boundary Wpt_list
   // doesn't lie within 0.1 of its total length from the plane:
   if (!_boundary.verts().pts().get_plane(_plane, 0.1)) {
      err_adv(debug,"SWEEP_DISK::setup: Error: can't find plane");
      return false;
   }
   
   // Find the center
   Wpt o = _boundary.verts().pts().average();

   // decide guideline direction (normal to plane):
   Wvec n = _plane.normal();
   if (VIEW::eye_vec(o) * n > 0)
      n = -n;

   // decide the length for the guideline:
   double len = world_length(o, GUIDE_LEN);

   // compute guideline endpoint:
   Wpt b = o + n.normalized()*len;

   // try basic setup
   if (!SWEEP_BASE::setup(dynamic_pointer_cast<LMESH>(faces.mesh()), o, b, dur))
      return false;

   // ******** From here on we accept it ********

   _enclosed_faces = faces;

   return true;
}
コード例 #3
0
ファイル: skin.C プロジェクト: ArnaudGastinel/jot-lib
static int
max_subdiv_edit_level(Bface_list all, Bface_list core=Bface_list())
{
   // what is the deepest subdiv level that is either:
   //   - controlled by a Bbase
   //   - has holes cut
   //   - has new surface regions attached

   err_adv(debug, "max_subdiv_edit_level:");
   if (all.empty()) {
      assert(core.empty());
      err_adv(debug, "  face list is empty");
      return 0;
   }
   assert(all.mesh() && all.contains_all(core));

   int R = 0;   // level at which deepest edits happened
   int k = 0;   // current level being examined
   while (!all.empty()) {
      k++;
      all = get_subdiv_faces(all,1);
      if (all.empty())
         break;

      // check for controllers
      if (!Bbase::find_owners(all).empty()) {
         err_adv(debug, "  controllers at level %d", k);
         R = k;
      }

      // check for holes at this level:
      if (all.has_any_secondary()) {
         all = all.primary_faces();
         err_adv(debug, "  hole at level %d", k);
         R = k; // holes exist at this level
      }

      // check for new regions
      if (core.empty())
         continue;
      core = get_subdiv_faces(core,1);
      Bface_list new_faces = core.two_ring_faces().primary_faces();
      // see if any of these new ones are actually new:
      new_faces.set_flags(1);
      all.clear_flags();
      new_faces = new_faces.filter(SimplexFlagFilter(1));
      if (!new_faces.empty()) {
         all.append(new_faces);
         err_adv(debug, "  new faces at level %d", k);
         R = k;  // new stuff exists at this level
      }
   }
   return R;
}
コード例 #4
0
ファイル: sweep.cpp プロジェクト: QuLogic/jot-lib
//! Being re-activated
bool 
SWEEP_DISK::setup(Panel* p, Bpoint_list points, Bcurve_list curves, Bsurface_list surfs, Wpt_list profile)
{
   static bool debug =
      Config::get_var_bool("DEBUG_SWEEP_SETUP",false) || debug_all;

   // XXX - some of the code here is the same as the code in the other setup method
   //     - better to wrap these code into a helper method
   Bface_list faces = p->bfaces();

   _boundary = faces.get_boundary();
   if (_boundary.num_line_strips() != 1) {
      err_adv(debug, "SWEEP_DISK::setup: error: boundary is not a single piece");
      return false;
   }

   // Get the best-fit plane, rejecting if the boundary Wpt_list
   // doesn't lie within 0.1 of its total length from the plane:
   if (!_boundary.verts().pts().get_plane(_plane, 0.1)) {
      err_adv(debug,"SWEEP_DISK::setup: Error: can't find plane");
      return false;
   }
   
   // Find the center
   Wpt o = _boundary.verts().pts().average();

   // decide guideline direction (normal to plane):
   Wvec n = _plane.normal();
   if (VIEW::eye_vec(o) * n > 0)
      n = -n;

   // decide the length for the guideline:
   double len = world_length(o, GUIDE_LEN);

   // compute guideline endpoint:
   Wpt b = o + n.normalized()*len;

   // try basic setup
   if (!SWEEP_BASE::setup(dynamic_pointer_cast<LMESH>(faces.mesh()), o, b, default_timeout()))
      return false;

   // ******** From here on we accept it ********

   _points = points;
   _curves = curves;
   _surfs = surfs;
   _surfs.mesh()->toggle_show_secondary_faces();
   _profile = profile;
   _enclosed_faces = faces;

   return true;
}
コード例 #5
0
ファイル: inflate.C プロジェクト: ArnaudGastinel/jot-lib
//! Given boundary curve (near-planar), activate the
//! widget to inflate ...
bool
INFLATE::setup(Bface *bf, double dist, double dur)
{

   reset();

   // Given the starting face f and an offset amount h,
   // determine the appropriate edit level, re-map f to that
   // level, and "inflate" the portion of the mesh reachable
   // from f by h, relative to the local edge length.

   // reject garbage
   if (!(bf && LMESH::isa(bf->mesh()))) {
      err_adv(debug, "INFLATE::setup: error: bad face");
      return 0;
   }
   Lface* f = (Lface*)bf;

   err_adv(debug, "setup: face at level %d", bf->mesh()->subdiv_level());

   // get avg edge length of edges in face:
   double avg_len = avg_strong_edge_len(f);
   if (avg_len < epsAbsMath()) {
      err_adv(debug, "INFLATE::setup: bad average edge length: %f", avg_len);
      return 0;
   }


   // Get set of reachable faces:
   Bface_list set
      = Bface_list::reachable_faces(f);
   assert(set.mesh() != NULL);
   err_adv(debug, "reachable faces: %d, subdiv level: %d, total faces: %d",
           set.num(), set.mesh()->subdiv_level(), set.mesh()->nfaces());

   // given face set should be an entire connected piece.
   if (!is_maximal_connected(set
          )) {
      err_adv(debug, "INFLATE::setup: rejecting subset of surface...");
      return 0;
   }

   Bface_list p = set;//get_top_level(set);
   assert(LMESH::isa(p.mesh()));
   err_adv(debug, "top level: %d faces (out of %d)",
           p.num(), p.mesh()->nfaces());

   BMESH* m = p.mesh();
   if (!m) {
      err_adv(debug, "INFLATE::setup: Error: null mesh");
      return 0;
   }
   if (!LMESH::isa(m)) {
      err_adv(debug, "INFLATE::setup: Error: non-LMESH");
      return 0;
   }
   if (!p.is_consistently_oriented()) {
      err_adv(debug, "INFLATE::setup: Error: inconsistently oriented faces");
      return 0;
   }

   // We ensured the mesh in an LMESH so this is okay:
   _boundary=p.get_boundary();

   if (_boundary.edges().empty()) {
      err_adv(debug, "INFLATE::setup: Error: No boundary. Quitting.");
      _boundary.reset();
      return 0;
   }

   // ******** From here on, we accept it ********

   err_adv(debug, "Inflating... %d boundary loops",
           _boundary.num_line_strips());

   _faces = p;
   _mode = false;
   _d     = _boundary.cur_edges().avg_len();
   _mesh  = (LMESH*)m;
   _orig_face = bf;
   _preview_dist = dist;

   // Set the timeout duration
   set_timeout(dur);

   // Become the active widget and get in the world's DRAWN list:
   activate();

   return true;
}