GroupScan.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:10k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. // GroupScan.cc                RigidScan aggregation
  2. // created 11/26/98            Matt Ginzton (magi@cs)
  3. #include "GroupScan.h"
  4. #include "MeshTransport.h"
  5. #include "DisplayMesh.h"
  6. #define FOR_EACH_CHILD(it) 
  7.    for (DisplayableMesh** it = children.begin(); it < children.end(); it++)
  8. #define FOR_EACH_CONST_CHILD(it) 
  9.    for (vector<DisplayableMesh*>::const_iterator it = children.begin(); 
  10.         it < children.end(); it++)
  11. GroupScan::GroupScan()
  12. {
  13. }
  14. GroupScan::GroupScan (const vector<DisplayableMesh*>& members, bool dirty)
  15. {
  16.   bDirty = dirty;
  17.   children = members;
  18.   rebuildResolutions();
  19.   computeBBox();
  20. }
  21. GroupScan::~GroupScan()
  22. {
  23.   cout << "Destroying scan group: " << children.size() << " members" << endl;
  24.   //  FOR_EACH_CHILD (it)    delete (*it);
  25. }
  26. bool
  27. GroupScan::AddScan (DisplayableMesh* scan)
  28. {
  29.   children.push_back (scan);
  30.   computeBBox();
  31.   rebuildResolutions();
  32.   return true;
  33. }
  34. bool
  35. GroupScan::RemoveScan (DisplayableMesh* scan)
  36. {
  37.   FOR_EACH_CHILD (it) {
  38.     if (*it == scan) {
  39.       children.erase (it);
  40.       rebuildResolutions();
  41.       computeBBox();
  42.       // this scan has been xformed by whatever our xform is...
  43.       RigidScan* rs = scan->getMeshData();
  44.       rs->setXform (getXform() * rs->getXform());
  45.       return true;
  46.     }
  47.   }
  48.   return false;
  49. }
  50. bool 
  51. GroupScan::write(const crope &fname)
  52. {
  53.   if (fname.empty()) {
  54.       // try to save to default name; quit if there isn't one
  55.     if (name.empty()) return false;
  56.   } else {
  57.     if (name != fname)  {
  58.       cout << "Saving to filename " << fname << endl;
  59.       set_name(fname);
  60.     }
  61.   }
  62.  
  63.   ofstream fout (name.c_str());
  64.   if (fout) {
  65.     FOR_EACH_CHILD(it) {
  66.       const char* str = (*it)->getMeshData()->get_name().c_str();
  67.       for (int i = 0; i < strlen(str); i++) 
  68. fout.put(str[i]);
  69.       fout.put('n');
  70.     } 
  71.     fout.put ('n');
  72.     fout.close();
  73.     bDirty = false; 
  74.     return true;
  75.   } 
  76.   return false;
  77. }
  78. MeshTransport*
  79. GroupScan::mesh(bool perVertex, bool stripped,
  80. ColorSource color, int colorSize)
  81. {
  82.   //cout << "GroupScan::mesh called for " << children.size() << " children"
  83.   //     << endl;
  84.   if (stripped && !perVertex) {
  85.     cerr << "No t-strips without per-vertex properties";
  86.     return NULL;
  87.   }
  88.   MeshTransport* mt = new MeshTransport;
  89.   bool bAnySucceeded = false;
  90.   FOR_EACH_CHILD (it) {
  91.     RigidScan* rs = (*it)->getMeshData();
  92.     MeshTransport* cmt = rs->mesh (perVertex, stripped, color, colorSize);
  93.     if (cmt) {
  94.       // append geometry and topology
  95.       mt->appendMT (cmt, rs->getXform());
  96.       delete cmt;
  97.       bAnySucceeded = true;
  98.       //cout << " . " << tri_inds.size() << endl;
  99.     }
  100.   }
  101.   if (!bAnySucceeded) {
  102.     delete mt;
  103.     mt = NULL;
  104.   }
  105.   return mt;
  106. }
  107. void
  108. GroupScan::computeBBox (void)
  109. {
  110.   bbox.clear();
  111.   rot_ctr = Pnt3();
  112.   FOR_EACH_CHILD (it) {
  113.     RigidScan* rs = (*it)->getMeshData();
  114.     Bbox childBox = rs->worldBbox();
  115.     if (childBox.valid()) {
  116.       bbox.add (childBox);
  117.       rot_ctr += rs->worldCenter();
  118.     }
  119.   }
  120.   if (children.size())
  121.     rot_ctr /= children.size();
  122.   rot_ctr = bbox.center();
  123. }
  124. crope
  125. GroupScan::getInfo (void)
  126. {
  127.   char info[1000];
  128.   sprintf (info, "Scan group containing %ld members.nn",
  129.    children.size());
  130.   return crope (info) + RigidScan::getInfo();
  131. }
  132. bool 
  133. GroupScan::is_modified (void) {
  134.   return bDirty;
  135. }
  136. bool
  137. GroupScan::get_children (vector<RigidScan*>& _children) const
  138. {
  139.   _children.reserve (children.size());
  140.   FOR_EACH_CONST_CHILD (it) {
  141.     _children.push_back ((*it)->getMeshData());
  142.   }
  143.   return true;
  144. }
  145. bool
  146. GroupScan::get_children_for_display (vector<DisplayableMesh*>& _children) const
  147. {
  148.   _children = children;
  149.   return true;
  150. }
  151. void
  152. GroupScan::rebuildResolutions (void)
  153. {
  154.   // we have as many resolutions as our best-endowed child...
  155.   // find out how many that is.
  156.   int nRes = 0;
  157.   FOR_EACH_CHILD (it) {
  158.     nRes = max (nRes, (*it)->getMeshData()->num_resolutions());
  159.   }
  160.   // now, build our res data (snapping to nearest existing resolution of
  161.   // poorer children, if necessary)
  162.   int iPolysVis = 0;
  163.   resolutions.clear();
  164.   for (int i = 0; i < nRes; i++) {
  165.     int nThisRes = 0;
  166.     bool bInMem = true;
  167.     bool bDesiredInMem = true;
  168.     FOR_EACH_CHILD (it) {
  169.       RigidScan* rs = (*it)->getMeshData();
  170.       vector<res_info> childres;
  171.       rs->existing_resolutions (childres);
  172.       int iChildRes = i * childres.size() / nRes;
  173.       nThisRes += childres[iChildRes].abs_resolution;
  174.       if (!childres[iChildRes].in_memory)
  175. bInMem = false;
  176.       if (!childres[iChildRes].desired_in_mem)
  177. bDesiredInMem = false;
  178.       if (i == 0)  // only do this once for each child
  179. iPolysVis += childres[rs->current_resolution_index()].abs_resolution;
  180.     }
  181.     insert_resolution (nThisRes, crope(), bInMem, bDesiredInMem);
  182.   }
  183.   // switch to best approximation of average current resolution
  184.   for (i = 0; i < nRes; i++) {
  185.     if (iPolysVis >= resolutions[i].abs_resolution)
  186.       break;
  187.   }
  188.   if (i == nRes)
  189.     select_coarsest();
  190.   else
  191.     switchToResLevel (i);
  192. }
  193. bool
  194. GroupScan::switchToResLevel (int iRes)
  195. {
  196.   if (!ResolutionCtrl::switchToResLevel (iRes))
  197.     return false;
  198.   int ok = true;
  199.   FOR_EACH_CHILD (it) {
  200.     ResolutionCtrl* rc = (*it)->getMeshData();
  201.     vector<res_info> ri;
  202.     rc->existing_resolutions (ri);
  203.     if (!rc->select_by_count (ri[iRes].abs_resolution))
  204.       ok = false;
  205.   }
  206.   return ok;
  207. }
  208. bool
  209. GroupScan::load_resolution (int iRes)
  210. {
  211.   if (resolutions[iRes].in_memory)
  212.     return true;
  213.   FOR_EACH_CHILD (it) {
  214.     if (!(*it)->getMeshData()->load_resolution (iRes))
  215.       return false;
  216.   }
  217.   resolutions[iRes].in_memory = true;
  218.   return true;
  219. }
  220. bool
  221. GroupScan::release_resolution (int nPolys)
  222. {
  223.    int iRes = findLevelForRes(nPolys);
  224.    if (iRes == -1) {
  225.     cerr << "Group resolution doesn't exist!" << endl;
  226.     return false;
  227.    }
  228.    if (!resolutions[iRes].in_memory)
  229.      return true;
  230.    
  231.    FOR_EACH_CHILD (it) {
  232.      RigidScan *scan = (*it)->getMeshData();
  233.      
  234.      if (!scan->release_resolution (scan->findResForLevel(iRes)))
  235.        return false;
  236.    }
  237.   resolutions[iRes].in_memory = false;
  238.   return true;
  239. }
  240. bool
  241. GroupScan::filter_inplace (const VertexFilter &filter)
  242. {
  243.   return false;
  244. }
  245. RigidScan* 
  246. GroupScan::filtered_copy (const VertexFilter &filter)
  247. {
  248.   BailDetector bail;
  249.   RigidScan *newchild, *oldchild;
  250.   vector <DisplayableMesh*> newchildren;
  251.   VertexFilter *childFilter;
  252.   
  253.   cout << "Clip " << children.size() << " children: " << flush;
  254.   FOR_EACH_CHILD(it) {
  255.     
  256.     oldchild = (*it)->getMeshData();
  257.     // need to transform each child by the group transform b4 filtering
  258.     childFilter = filter.transformedClone((float*)oldchild->getXform());
  259.     newchild = oldchild->filtered_copy(*childFilter);
  260.   
  261.     if (newchild) {
  262.       if (newchild->num_resolutions() > 0 ) {
  263. crope newname;
  264. newname = oldchild->get_basename()
  265.   + "Clip." + oldchild->get_nameending();
  266. newchild->set_name(newname);
  267. DisplayableMesh *dm;
  268. GroupScan *g = dynamic_cast<GroupScan*>(newchild);
  269. if (!g) {
  270.   if (newchild->num_vertices() >= 3) {
  271.     dm = theScene->addMeshSet(newchild, false);
  272.     newchildren.push_back(dm);
  273.   }
  274. } else {
  275.   dm = GetMeshForRigidScan(newchild);
  276.   assert(dm);
  277.   newchildren.push_back(dm); 
  278. }
  279. //newchildren.push_back(dm);
  280.       }
  281.     }
  282.     
  283.     cout << "." << flush;
  284.     if (bail()) {
  285.       cerr << "Warning: group clip interrupted; results are partial" << endl;
  286.       break;
  287.     }
  288.   }
  289.   cout << " " << newchildren.size() << " of my kids made it." << endl;
  290.   char buf[256];
  291.   sprintf (buf, "%sClip.%s", basename.c_str(), ending.c_str());
  292.   
  293.   // groupScans will make its own copy of buf
  294.   
  295.   if (!newchildren.size()) return new GroupScan;
  296.   DisplayableMesh *groupmesh = groupScans (newchildren, buf, true);
  297.   
  298.   groupmesh->getMeshData()->setXform(getXform());
  299.   
  300.   return groupmesh->getMeshData();
  301. }
  302.   
  303. void
  304. GroupScan::subsample_points(float rate, vector<Pnt3> &p,
  305.     vector<Pnt3> &n)
  306. {
  307.   vector<Pnt3> cp, cn;
  308.   p.clear();
  309.   n.clear();
  310.   FOR_EACH_CHILD (it) {
  311.     RigidScan* rs = (*it)->getMeshData();
  312.     cp.clear();
  313.     cn.clear();
  314.     rs->subsample_points (rate, cp, cn);
  315.     // apply local transformations
  316.     Xform<float> xf = rs->getXform();
  317.     if (xf != Xform<float>()) {
  318.       for (Pnt3* pi = cp.begin(); pi < cp.end(); pi++) {
  319. xf (*pi);
  320.       }
  321.       xf.removeTranslation();
  322.       for (pi = cn.begin(); pi < cn.end(); pi++) {
  323. xf (*pi);
  324.       }
  325.     }
  326.     
  327.     //cout << "- adding " << cp.size() << " points from child" << endl;
  328.     p.insert (p.end(), cp.begin(), cp.end());
  329.     n.insert (n.end(), cn.begin(), cn.end());
  330.   }
  331.   //cout << "added " << p.size() << " points total" << endl;
  332. }
  333. bool
  334. GroupScan::closest_point(const Pnt3 &p, const Pnt3 &n,
  335.  Pnt3 &cl_pnt, Pnt3 &cl_nrm,
  336.  float thr, bool bdry_ok)
  337. {
  338.   Pnt3 cp, cn;
  339.   Pnt3 mp, mn;
  340.   float closest = 1e33;
  341.   bool bAny = false;
  342.   Xform<float> xf, xfn;
  343.   RigidScan* winner = NULL;
  344.   //cout << "closest_point for " << children.size() << " children" << endl;
  345.   FOR_EACH_CHILD (it) {
  346.     RigidScan* rs = (*it)->getMeshData();
  347.     xf = rs->getXform();
  348.     xfn = xf;
  349.     xfn.removeTranslation();
  350.     mp = p; mp.invxform (xf);
  351.     mn = n; mn.invxform (xfn);
  352.     if (!rs->closest_point (mp, mn, cp, cn, thr, bdry_ok))
  353.       continue;
  354.     bAny = true;
  355.     float dist = (mp-cp).norm2();
  356.     //cout << "- distance^2 from child is " << dist << endl;
  357.     if (dist < closest) {
  358.       winner = rs;
  359.       cl_pnt = cp;
  360.       cl_nrm = cn;
  361.       closest = dist;
  362.     }
  363.   }
  364.   // the output is still in the coordinate system of the winning subscan
  365.   if (bAny) {
  366.     assert (winner != NULL);
  367.     xf = winner->getXform();
  368.     xf (cl_pnt);
  369.     xf.removeTranslation();
  370.     xf (cl_nrm);
  371.   }
  372.   //cout << "distance^2 from group is " << closest << endl;
  373.   return bAny;
  374. }
  375. bool
  376. GroupScan::write_metadata (MetaData data)
  377. {
  378.   bool success = true;
  379.   FOR_EACH_CHILD (it) {
  380.     RigidScan* rs = (*it)->getMeshData();
  381.     Xform<float> saved_xf;
  382.     if (data == md_xform) {
  383.       saved_xf = rs->getXform();
  384.       rs->setXform(getXform() * saved_xf);
  385.     }
  386.     if (!rs->write_metadata (data))
  387.       success = false;
  388.     if (data == md_xform) {
  389.       rs->setXform(saved_xf);
  390.     }
  391.   }
  392.   return success;
  393. }