Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

ShapeSpace.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <iomanip>
00003 #include <vector>
00004 #include <sstream>
00005 #include <string>
00006 #include <float.h>
00007 #include <cmath>
00008 
00009 #include "ShapeRoot.h"
00010 #include "ShapeAgent.h"
00011 #include "ShapeLine.h"
00012 #include "ShapeEllipse.h"
00013 #include "ShapePoint.h"
00014 #include "ShapeSphere.h"
00015 #include "ShapeBlob.h"
00016 #include "ShapePolygon.h"
00017 #include "ShapeBrick.h"
00018 #include "ShapePyramid.h"
00019 #include "ShapeLocalizationParticle.h"
00020 #include "ShapeMarker.h"
00021 #include "ShapeCylinder.h"
00022 #include "ShapeSift.h"
00023 #include "ShapeAprilTag.h"
00024 #include "ShapeGraphics.h"
00025 
00026 #include "BaseData.h"
00027 #include "SketchSpace.h"
00028 #include "ShapeSpace.h"
00029 #include "VRmixin.h"
00030 
00031 using namespace std;
00032 
00033 #ifdef PLATFORM_APERIOS
00034 // missing isfinite, Aibo crashes when it does denormalized float ops anyway... :(
00035 static int isfinite(float s) { return (s == s) && ((s == 0) || (s != 2*s)); }
00036 #endif
00037 
00038 namespace DualCoding {
00039 
00040 ShapeSpace::ShapeSpace(SketchSpace* dualSkS, int init_id, std::string const _name, 
00041            ReferenceFrameType_t _refFrameType) : 
00042   name(_name.length() == 0 ? dualSkS->name : _name),
00043   dualSpace(dualSkS), id_counter(init_id), shapeCache(),
00044   refFrameType(_refFrameType)
00045 {
00046   shapeCache = std::vector<ShapeRoot>(30);
00047   shapeCache.clear();
00048 }
00049 
00050 ShapeSpace::~ShapeSpace(void) {
00051   //cout << "Deleting ShapeSpace " << name << " at " << this << endl;
00052   // do not call clear() here; VRmixin::theAgent's reference count (in AgentData) may be wrong if the static Shape was already deleted
00053 };
00054 
00055 ShapeRoot& ShapeSpace::addShape(BaseData *p) {
00056   p->id = ++id_counter;
00057   shapeCache.push_back(ShapeRoot(p));
00058   return shapeCache[shapeCache.size()-1];
00059 };
00060 
00061 void ShapeSpace::importShapes(std::vector<ShapeRoot>& foreign_shapes) {
00062   for (std::vector<ShapeRoot>::const_iterator it = foreign_shapes.begin();
00063        it != foreign_shapes.end();
00064        ++it) importShape(*it);
00065 }
00066 
00067 BaseData* ShapeSpace::importShape(const ShapeRoot& foreign_shape) {
00068   BaseData *own = foreign_shape->clone();
00069   own->space = this;
00070   own->parentId = 0;
00071   own->lastMatchId = foreign_shape.id;
00072   own->refcount = 0;
00073   addShape(own);
00074   return own;  // return value is used by MapBuilder::importLocalToWorld
00075 }
00076 
00077 void ShapeSpace::deleteShape(ShapeRoot &b) {
00078   if ( b.isValid() )
00079     for ( std::vector<ShapeRoot>::iterator it = shapeCache.begin();
00080     it != shapeCache.end(); ++it ) {
00081       if ( it->id == b.id ) {
00082   shapeCache.erase(it);
00083   break;
00084       }
00085     }
00086   else
00087     std::cerr << "ERROR: Attempt to delete an invalid " << b << std::endl;
00088 }
00089 
00090 void ShapeSpace::deleteShapes(std::vector<ShapeRoot>& shapes_vec) {
00091   for (size_t i=0; i < shapes_vec.size(); i++)
00092     deleteShape(shapes_vec[i]);
00093 }
00094 
00095 void ShapeSpace::clear() {
00096   shapeCache.clear();
00097   if ( this == &VRmixin::worldShS && VRmixin::theAgent.isValid() )
00098     shapeCache.push_back(VRmixin::theAgent);
00099 }
00100 
00101 void ShapeSpace::applyTransform(const fmat::Transform& Tmat, const ReferenceFrameType_t newref) {
00102   std::vector<ShapeRoot> allShapes_vec = allShapes();
00103   const size_t nshapes = allShapes_vec.size();
00104   for(size_t i = 0; i < nshapes; i++)
00105     allShapes_vec[i]->applyTransform(Tmat,newref);
00106 }
00107 
00108 Point ShapeSpace::getCentroid() {
00109   std::vector<ShapeRoot> allShapes_vec = allShapes();
00110   return(getCentroidOfSubset(allShapes_vec));
00111 }
00112 
00113 Point ShapeSpace::getCentroidOfSubset(const std::vector<ShapeRoot>& subsetShapes_vec) {
00114   const size_t nshapes = subsetShapes_vec.size();
00115   Point subset_centroid_pt = Point(0,0);  
00116   for(size_t cur_shape = 0; cur_shape < nshapes; cur_shape++)
00117     subset_centroid_pt += subsetShapes_vec[cur_shape]->getCentroid();
00118   return(subset_centroid_pt/(float)nshapes);  
00119 }
00120 
00121 std::vector<ShapeRoot> ShapeSpace::allShapes(ShapeType_t type) {
00122   allShapes();  // make sure cache is valid;
00123   std::vector<ShapeRoot> result;
00124   for ( std::vector<ShapeRoot>::const_iterator it = shapeCache.begin();
00125   it != shapeCache.end(); it++ )
00126     if ( (*it)->getType() == type )
00127       result.push_back(*it);
00128   return result;
00129 }
00130 
00131 std::vector<ShapeRoot> ShapeSpace::allShapes(rgb color) {
00132   std::vector<ShapeRoot> result(shapeCache.size());
00133   result.clear();
00134   for ( std::vector<ShapeRoot>::const_iterator it = shapeCache.begin();
00135   it != shapeCache.end(); ++it )
00136     if ( (*it)->getColor() == color )
00137       result.push_back(*it);
00138   return result;
00139 }
00140 
00141 std::string ShapeSpace::getShapeListForGUI(void) {
00142   std::vector<ShapeRoot> &allShapes_vec = allShapes();
00143   std::ostringstream liststream;
00144   // must used fixed output format because Java can't parse scientific notation
00145 #define writept(x) fixed << setprecision(2) << x.coordX() << " " << fixed << setprecision(2) << x.coordY() << " " << fixed << setprecision(2) << x.coordZ()
00146   for(unsigned int i = 0; i < allShapes_vec.size(); i++) {
00147     if ( allShapes_vec[i]->isViewable() ) {
00148       liststream << "shape" << endl;
00149       liststream << "id: " << allShapes_vec[i]->getId() << endl;
00150       liststream << "parentId: " << allShapes_vec[i]->getParentId() << endl;
00151       liststream << "name: " << allShapes_vec[i]->getName() << endl;
00152       liststream << "shapetype: " << allShapes_vec[i]->getType() << endl;
00153       liststream << "color: " << toString(allShapes_vec[i]->getColor()) << endl;
00154       liststream << "cxyz: " << writept(allShapes_vec[i]->getCentroid()) << endl;
00155     
00156       if(allShapes_vec[i]->isType(lineDataType)) { // lineshape
00157   const Shape<LineData>& current = ShapeRootTypeConst(allShapes_vec[i],LineData);
00158   liststream << "e1xyz: " << writept(current->end1Pt()) << endl; 
00159   liststream << "e2xyz: " << writept(current->end2Pt()) << endl; 
00160   liststream << "r:" << current->getRhoNorm() << endl;
00161   liststream << "theta: " << current->getThetaNorm() << endl;
00162   liststream << "end1: " << (current->end1Pt().isValid()) << " " 
00163        << (current->end1Pt().isActive()) << endl;
00164   liststream << "end2: " << (current->end2Pt().isValid()) << " "
00165        << (current->end2Pt().isActive()) << endl;
00166       } 
00167     
00168       else if (allShapes_vec[i]->isType(ellipseDataType)) { // ellipseshape
00169   const Shape<EllipseData>& current = ShapeRootTypeConst(allShapes_vec[i],EllipseData);
00170   liststream << "axes: " << current->getSemimajor()
00171        << " " << current->getSemiminor() << endl;
00172   liststream << "orientation: " << current->getOrientation() 
00173        << endl;
00174       } 
00175 
00176       else if (allShapes_vec[i]->isType(pointDataType)) { // pointshape
00177   ;
00178       }
00179 
00180       else if (allShapes_vec[i]->isType(agentDataType)) { // agentshape
00181   const Shape<AgentData>& current = ShapeRootTypeConst(allShapes_vec[i],AgentData);
00182   liststream << "orientation: " << current->getOrientation() << endl;
00183   fmat::Column<3> offset = current->getBoundingBoxOffset();
00184   fmat::Column<3> halfDimXYZ = current->getBoundingBoxHalfDims();
00185   liststream << "offsetX: " << offset[0] << endl;
00186   liststream << "offsetY: " << offset[1] << endl;
00187   //offsetZ needs to be written when dealing with 3D bounding box
00188   liststream << "halfDimX: " << halfDimXYZ[0] << endl;
00189   liststream << "halfDimY: " << halfDimXYZ[1] << endl;
00190   //dimH needs to be written when dealing with 3D bounding box
00191       }
00192 
00193       else if (allShapes_vec[i]->isType(sphereDataType)) { // sphereshape
00194   const Shape<SphereData>& current = ShapeRootTypeConst(allShapes_vec[i],SphereData);
00195   liststream << "radius: " << current->getRadius() << endl;
00196       }
00197 
00198       else if (allShapes_vec[i]->isType(polygonDataType)) { // polygonshape
00199   const Shape<PolygonData>& current = ShapeRootTypeConst(allShapes_vec[i],PolygonData);
00200 liststream << "num_vtx: " << current->getVertices().size() << endl;
00201   for (std::vector<Point>::const_iterator vtx_it = current->getVertices().begin();
00202        vtx_it != current->getVertices().end(); vtx_it++)
00203     liststream << "vertex: " << writept((*vtx_it)) << endl;
00204   liststream << "end1_valid: " << (current->end1Ln().end1Pt().isValid()) << endl;
00205   liststream << "end2_valid: " << (current->end2Ln().end2Pt().isValid()) << endl;
00206       }
00207     
00208       else if (allShapes_vec[i]->isType(blobDataType)) { // blobshape
00209   const Shape<BlobData>& current = ShapeRootTypeConst(allShapes_vec[i],BlobData);
00210   const char* colorname = ProjectInterface::getColorName(current->getColor());
00211   liststream << "colorname: " << (colorname != NULL ? string(colorname) : toString(current->getColor())) << endl;
00212   liststream << "area: " << current->getArea() << endl;
00213   liststream << "orient: " << current->orientation << endl;
00214   liststream << "topLeft: " << writept(current->topLeft) << endl;
00215   liststream << "topRight: " << writept(current->topRight) << endl;
00216   liststream << "bottomLeft: " << writept(current->bottomLeft) << endl;
00217   liststream << "bottomRight :" << writept(current->bottomRight) << endl;
00218       }
00219       else if (allShapes_vec[i]->isType(brickDataType)) { // brickshape
00220   const Shape<BrickData>& current = ShapeRootTypeConst(allShapes_vec[i],BrickData);
00221   liststream << "GFL: " << writept(current->getGFL()) << endl;
00222   liststream << "GBL: " << writept(current->getGBL()) << endl;
00223   liststream << "GFR: " << writept(current->getGFR()) << endl;
00224   liststream << "GBR: " << writept(current->getGBR()) << endl;
00225   liststream << "TFL: " << writept(current->getTFL()) << endl;
00226   liststream << "TBL: " << writept(current->getTBL()) << endl;
00227   liststream << "TFR: " << writept(current->getTFR()) << endl;
00228   liststream << "TBR: " << writept(current->getTBR()) << endl;
00229       }
00230       else if (allShapes_vec[i]->isType(pyramidDataType)) { // pyramidshape
00231   const Shape<PyramidData>& current = ShapeRootTypeConst(allShapes_vec[i],PyramidData);
00232   liststream << "FL: " << writept(current->getFL()) << endl;
00233   liststream << "BL: " << writept(current->getBL()) << endl;
00234   liststream << "FR: " << writept(current->getFR()) << endl;
00235   liststream << "BR: " << writept(current->getBR()) << endl;
00236   liststream << "Top: " << writept(current->getTop()) << endl;
00237       }
00238       else if (allShapes_vec[i]->isType(localizationParticleDataType)) { // localizationparticleshape
00239   const Shape<LocalizationParticleData>& current = ShapeRootTypeConst(allShapes_vec[i],LocalizationParticleData);
00240   const float weight = current->getWeight();
00241   liststream << "orient/weight: " << current->getOrientation()
00242       << " " << (!isfinite(weight) ? (weight>0 ? FLT_MAX : -FLT_MAX) : weight) << endl;
00243       }
00244       else if (allShapes_vec[i]->isType(markerDataType)) { // markershape
00245   const Shape<MarkerData>& current = ShapeRootTypeConst(allShapes_vec[i],MarkerData);
00246   liststream << MarkerData::getMarkerTypeName(current->typeOfMarker) << ":" << current->getMarkerDescription() << endl;
00247       }
00248       else if (allShapes_vec[i]->isType(cylinderDataType)) {
00249   const Shape<CylinderData>& current = ShapeRootTypeConst(allShapes_vec[i], CylinderData);
00250   liststream << "radius: " << current->getRadius() << endl << "height: " << current->getHeight() << endl;
00251       }
00252       else if (allShapes_vec[i]->isType(siftDataType)) { // siftshape
00253   const Shape<SiftData>& current = ShapeRootTypeConst(allShapes_vec[i],SiftData);
00254   liststream << "objectName: " << current->getObjectName() << endl;
00255   liststream << "objectID: " << current->getObjectID() << endl;
00256   liststream << "modelName: " << current->getModelName() << endl;
00257   liststream << "topLeft: " << writept(current->getTopLeft()) << endl;
00258   liststream << "topRight: " << writept(current->getTopRight()) << endl;
00259   liststream << "bottomLeft: " << writept(current->getBottomLeft()) << endl;
00260   liststream << "bottomRight :" << writept(current->getBottomRight()) << endl;
00261       }
00262       else if (allShapes_vec[i]->isType(aprilTagDataType)) { // apriltagshape
00263   const Shape<AprilTagData>& current = ShapeRootTypeConst(allShapes_vec[i],AprilTagData);
00264   const AprilTags::TagDetection &td = current->getTagDetection();
00265   liststream << "tagID: " << current->getTagID() << endl;
00266   liststream << "orient: " << td.getXYOrientation() << endl;
00267   liststream << "hammingDistance: " << td.hammingDistance << endl;
00268   liststream << "p0: " << td.p[0].first << " " << td.p[0].second << endl;
00269   liststream << "p1: " << td.p[1].first << " " << td.p[1].second << endl;
00270   liststream << "p2: " << td.p[2].first << " " << td.p[2].second << endl;
00271   liststream << "p3: " << td.p[3].first << " " << td.p[3].second << endl;
00272       }
00273       else if (allShapes_vec[i]->isType(graphicsDataType)) { // graphicsshape
00274   const Shape<GraphicsData>& current = ShapeRootTypeConst(allShapes_vec[i],GraphicsData);
00275   liststream << "numelts: " << current->elements.size() << endl;
00276   for (unsigned int j = 0; j < current->elements.size(); j++) {
00277     const GraphicsData::GraphicsElement *elt = current->elements[j];
00278     switch ( elt->getType() ) {
00279       
00280     case GraphicsData::lineGType: {
00281       const GraphicsData::LineElement *line = 
00282         dynamic_cast<const GraphicsData::LineElement*>(elt);
00283       liststream << "lineElement: " << elt->getType() << " " << toString(elt->getColor()) << " "
00284            << line->pt1.first << " " << line->pt1.second << " "
00285            << line->pt2.first << " " << line->pt2.second << endl;
00286       break; }
00287       
00288     case GraphicsData::polygonGType: {
00289       const GraphicsData::PolygonElement *polygon =
00290         dynamic_cast<const GraphicsData::PolygonElement*>(elt);
00291       liststream<< "polygonElement: " << elt->getType() << " "<< toString(elt->getColor()) << endl;
00292       liststream << "numvtx: "<< polygon->vertices.size() << endl;
00293       for (unsigned int k = 0; k < polygon->vertices.size(); k++) {
00294         std::pair<float,float> vert = polygon->vertices[k];
00295         liststream << "vertex: " << vert.first << " " << vert.second << endl;
00296       }
00297         liststream << "closed: " << (polygon->closed ? "true" : "false") << endl;
00298       break; }
00299       
00300     case GraphicsData::ellipseGType: {
00301       const GraphicsData::EllipseElement *ellipse = 
00302         dynamic_cast<const GraphicsData::EllipseElement*>(elt);
00303       liststream << "ellipseElement: " << elt->getType() << " " << toString(elt->getColor()) << endl;
00304       liststream << "centroid: " << ellipse->center.first << " " << ellipse->center.second << endl;
00305       liststream << "semimajor: " << ellipse->semimajor << endl;
00306       liststream << "semiminor: " << ellipse->semiminor << endl;
00307       liststream << "orientation: " << ellipse->orientation << endl;
00308       break; }
00309 
00310     case GraphicsData::textGType: {
00311       const GraphicsData::TextElement *text =
00312         dynamic_cast<const GraphicsData::TextElement*>(elt);
00313       liststream << "TextElement: " << elt->getType() << " " << toString(elt->getColor()) << endl;
00314       liststream << "Startpoint: " << text->startpt.first << " " << text->startpt.second << endl;
00315       liststream << "Message: " << text->msg << endl;
00316       break; }
00317       
00318     case GraphicsData::locParticleGType: {
00319       const GraphicsData::LocalizationParticleElement *locParticle =
00320         dynamic_cast<const GraphicsData::LocalizationParticleElement*>(elt);
00321       liststream << "localizationParticleElement: " << elt->getType() << " " << toString(elt->getColor()) << endl;
00322       liststream << "Centoidxy: " << locParticle->getCentroid().coordX() << " " << locParticle->getCentroid().coordY() <<  endl;
00323       liststream << "orientation: " << locParticle->getOrientation() << endl;
00324       break; }
00325       
00326     default:
00327       std::cerr << "Bad GraphicsElement type: " << elt->getType() << std::endl;
00328     }
00329   }
00330       }
00331     }
00332   }
00333 #undef writept
00334   return liststream.str();  
00335 }
00336 
00337 void ShapeSpace::printParams() {
00338   cout << endl;
00339   cout << "SHAPE SPACE : PARAMETERS BEGIN" << endl;
00340   int cur, num;
00341   
00342   std::vector<ShapeRoot> &allShapes_vec = allShapes();
00343   num = (int)(allShapes_vec.size());
00344   
00345   for(cur = 0; cur < num; cur++) {
00346     
00347     cout << "SHAPE " <<  allShapes_vec[cur].getId() 
00348    << " (" << cur+1 << " of " << num << ")" 
00349    << endl;
00350     
00351     allShapes_vec[cur]->printParams();
00352     
00353     cout << "===========================================" << endl;
00354     cout << endl;
00355     
00356   }
00357   
00358   cout << endl;
00359   cout << "SHAPE SPACE : PARAMETERS END" << endl;
00360 }
00361 
00362 void ShapeSpace::printSummary()
00363 {
00364   // JJW will this cause a memory leak?
00365   std::vector<ShapeRoot> allShapes_vec = allShapes();
00366   int cur;
00367   int num = (int)(allShapes_vec.size());
00368   cout << "SHAPE SPACE : SUMMARY BEGIN" << endl;
00369   std::vector<int> shape_counts;
00370   shape_counts.resize(numDataTypes,0);
00371   
00372   cout << endl << "Shape Listing:" << endl;
00373   for(cur = 0; cur < num; cur++) {
00374     cout << "Shape " << allShapes_vec[cur].getId() 
00375    << " (" << cur+1 << " of " << num << ")."
00376    << "\tType: " << allShapes_vec[cur]->getTypeName() 
00377    << endl;
00378     shape_counts[allShapes_vec[cur]->getType()]++;
00379   }
00380   
00381   cout << endl << "Shape Counts:" << endl;
00382   num = numDataTypes;
00383   for(cur = 0; cur < num; cur++) {
00384     cout << "Shape Type " << cur << " " << data_name(cur) 
00385    << ":\t" << shape_counts[cur] << endl;
00386   }
00387   cout << endl;
00388   
00389   cout << "SHAPE SPACE : SUMMARY END" << endl;
00390 }
00391 
00392 void ShapeSpace::deleteShapeType(ShapeType_t t) {
00393   std::vector<ShapeRoot> temp;
00394   temp.reserve(shapeCache.size());
00395   for ( std::vector<ShapeRoot>::const_iterator it = shapeCache.begin();
00396   it != shapeCache.end(); it++ )
00397     if ( (*it)->getType() != t )
00398       temp.push_back(*it);
00399   shapeCache = temp;
00400 }
00401 
00402 } // namespace

DualCoding 5.1CVS
Generated Fri Mar 16 05:23:47 2012 by Doxygen 1.6.3