Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

TargetData.cc

Go to the documentation of this file.
00001 //-*-c++-*-
00002 
00003 #include "BaseData.h"    // superclass
00004 #include "Point.h"       // Point data member
00005 #include "ShapeTypes.h"  // TargetDataType
00006 
00007 #include "SketchSpace.h"
00008 #include "Sketch.h"
00009 #include "visops.h"
00010 
00011 #include "ShapeSpace.h"  // required by DATASTUFF_CC
00012 #include "ShapeRoot.h"   // required by DATASTUFF_CC
00013 
00014 #include "TargetData.h"
00015 #include "ShapeTarget.h"
00016 
00017 #include "BlobData.h"
00018 #include "ShapeBlob.h"
00019 #include "VRmixin.h"
00020 
00021 using namespace std;
00022 
00023 namespace DualCoding {
00024 
00025 TargetData::TargetData(ShapeSpace& _space, const EndPoint &_frontLeftPt, const EndPoint &_frontRightPt, const EndPoint &_backLeftPt, const EndPoint &_backRightPt, const EndPoint &_frontIntersect, const EndPoint &_backIntersect, const float _height)
00026                      : BaseData(_space, getStaticType()),
00027                        frontLine(_space, _frontLeftPt, _frontRightPt),
00028                        backLine(_space, _backLeftPt, _backRightPt),
00029                        frontValid((_frontLeftPt != Point(0, 0, 0)) && (_frontRightPt != Point(0, 0, 0))),
00030                        backValid((_backLeftPt != Point(0, 0, 0)) && (_backRightPt != Point(0, 0, 0))),
00031                        frontIntersect(_frontIntersect),
00032                        backIntersect(_backIntersect),
00033                        orientation(0.0),
00034                        length(0.0),
00035                        width(0.0),
00036                        height(_height) {
00037   update_derived_properties();
00038 }
00039 
00040 DATASTUFF_CC(TargetData);
00041 
00042 BoundingBox TargetData::getBoundingBox() const {
00043   return BoundingBox(frontLine.getBoundingBox(), backLine.getBoundingBox());
00044 }
00045 
00046 bool TargetData::isMatchFor(const ShapeRoot& other) const {
00047   if (!(isSameTypeAs(other) && isSameColorAs(other))) {
00048     return false;
00049   }
00050   else {
00051     const Shape<TargetData>& other_target = ShapeRootTypeConst(other,TargetData);
00052     return isMatchFor(other_target.getData());
00053   }
00054 }
00055 
00056 bool TargetData::isMatchFor(const TargetData& other_target) const {
00057   // 2 targets match if either of their lines match
00058   if (frontValid && !frontLine.isMatchFor(other_target.frontLine) && backValid && !backLine.isMatchFor(other_target.backLine))
00059     return false;
00060   return true;
00061 }
00062 
00063 void TargetData::update_derived_properties() {
00064   EndPoint &frontLeftPt  = getFrontLeftPt();
00065   EndPoint &frontRightPt = getFrontRightPt();
00066   EndPoint &backLeftPt   = getBackLeftPt();
00067   EndPoint &backRightPt  = getBackRightPt();
00068   
00069   // Determine if the front and back lines are valid
00070   frontValid  = true;
00071   backValid   = true;
00072   if ((frontLeftPt == Point(0, 0, 0)) || (frontRightPt == Point(0, 0, 0))) {
00073     frontValid = false;
00074   }
00075   if ((backLeftPt == Point(0, 0, 0)) || (backRightPt == Point(0, 0, 0))) {
00076     backValid = false;
00077   }
00078   if (frontValid && backValid && (getRefFrameType() != camcentric)) {
00079     // Lines should not be in the negative z plane
00080     if (frontLine.getCentroid().coordZ() < 0) {
00081       frontValid = false;
00082     }
00083     if (backLine.getCentroid().coordZ() < 0) {
00084       backValid = false;
00085     }
00086     // Remove short lines if the other line is long
00087     if ((frontLine.getLength() < 50.0f) && backValid && (backLine.getLength() > 50.0f)) {
00088       frontValid = false;
00089     }
00090     else if ((backLine.getLength() < 50.0f) && frontValid && (frontLine.getLength() > 50.0f)) {
00091       backValid = false;
00092     }
00093   }
00094   
00095   // Reset the front/back lines if they are invalid
00096   if (!frontValid) {
00097     frontLeftPt  = Point(0, 0, 0);
00098     frontRightPt = Point(0, 0, 0);
00099     frontLeftPt.setValid(false);
00100     frontRightPt.setValid(false);
00101     frontLine.update_derived_properties();
00102     
00103     frontIntersect = Point(0, 0, 0);
00104     frontIntersect.setValid(false);
00105   }
00106   if (!backValid) {
00107     backLeftPt  = Point(0, 0, 0);
00108     backRightPt = Point(0, 0, 0);
00109     backLeftPt.setValid(false);
00110     backRightPt.setValid(false);
00111     backLine.update_derived_properties();
00112     
00113     backIntersect = Point(0, 0, 0);
00114     backIntersect.setValid(false);
00115   }
00116   
00117   // Determine if the front/back intersection points are valid
00118   if (frontIntersect == Point(0, 0, 0)) {
00119     frontIntersect.setValid(false);
00120   }
00121   if (backIntersect == Point(0, 0, 0)) {
00122     backIntersect.setValid(false);
00123   }
00124   
00125   // Check left/right points based on intersection points
00126   if (frontIntersect.isValid() || backIntersect.isValid()) {
00127     if (frontIntersect.isValid()) {
00128       bool swap = false;
00129       
00130       // The right point will be closer to the intersection if both points are valid/invalid
00131       if (frontValid && (frontLeftPt.isValid() == frontRightPt.isValid())
00132        && (frontLeftPt.distanceFrom(frontIntersect) < frontRightPt.distanceFrom(frontIntersect))) {
00133         swap = true;
00134       }
00135       // Assumption: the right point will be the valid point otherwise
00136       else if (frontValid && frontLeftPt.isValid() && !frontRightPt.isValid()) {
00137         swap = true;
00138       }
00139       
00140       
00141       if (swap) {
00142         // Front left and right are reversed
00143         EndPoint temp = frontLeftPt;
00144         frontLeftPt = frontRightPt;
00145         frontRightPt = temp;
00146         frontLine.update_derived_properties();
00147       }
00148       
00149       // If back intersection is invalid, then determine back left/right based on distance from front left/right
00150       if (backValid && !backIntersect.isValid()) {
00151         float leftMax  = max(frontLeftPt.distanceFrom(backLeftPt), frontRightPt.distanceFrom(backLeftPt));
00152         float rightMax = max(frontLeftPt.distanceFrom(backRightPt), frontRightPt.distanceFrom(backRightPt));
00153         
00154         // Look at the point that's further away
00155         swap = false;
00156         if (leftMax > rightMax) {
00157           if (frontLeftPt.distanceFrom(backLeftPt) > frontRightPt.distanceFrom(backLeftPt)) {
00158             swap = true;
00159           }
00160         }
00161         else {
00162           if (frontRightPt.distanceFrom(backRightPt) > frontLeftPt.distanceFrom(backRightPt)) {
00163             swap = true;
00164           }
00165         }
00166         
00167         if (swap) {
00168           // Back left and right are reversed
00169           EndPoint temp = backLeftPt;
00170           backLeftPt = backRightPt;
00171           backRightPt = temp;
00172           backLine.update_derived_properties();
00173         }
00174       }
00175     }
00176     if (backIntersect.isValid()) {
00177       bool swap = false;
00178       
00179       // The right point will be closer to the intersection if both points are valid/invalid
00180       if (backValid && (backLeftPt.isValid() == backRightPt.isValid())
00181        && (backLeftPt.distanceFrom(backIntersect) < backRightPt.distanceFrom(backIntersect))) {
00182         swap = true;
00183       }
00184       // Assumption: the right point will be the valid point otherwise
00185       else if (backValid && backLeftPt.isValid() && !backRightPt.isValid()) {
00186         swap = true;
00187       }
00188       
00189       
00190       if (swap) {
00191         // Back left and right are reversed
00192         EndPoint temp = backLeftPt;
00193         backLeftPt = backRightPt;
00194         backRightPt = temp;
00195         backLine.update_derived_properties();
00196       }
00197       
00198       // If front intersection is invalid, then determine front left/right based on distance from back left/right
00199       if (frontValid && !frontIntersect.isValid()) {
00200         float leftMax  = max(backLeftPt.distanceFrom(frontLeftPt), backRightPt.distanceFrom(frontLeftPt));
00201         float rightMax = max(backLeftPt.distanceFrom(frontRightPt), backRightPt.distanceFrom(frontRightPt));
00202         
00203         // Look at the point that's further away
00204         swap = false;
00205         if (leftMax > rightMax) {
00206           if (backLeftPt.distanceFrom(frontLeftPt) > backRightPt.distanceFrom(frontLeftPt)) {
00207             swap = true;
00208           }
00209         }
00210         else {
00211           if (backRightPt.distanceFrom(frontRightPt) > backLeftPt.distanceFrom(frontRightPt)) {
00212             swap = true;
00213           }
00214         }
00215         
00216         if (swap) {
00217           // Front left and right are reversed
00218           EndPoint temp = frontLeftPt;
00219           frontLeftPt = frontRightPt;
00220           frontRightPt = temp;
00221           frontLine.update_derived_properties();
00222         }
00223       }
00224     }
00225   }
00226   
00227   float front_dx = frontRightPt.coordX() - frontLeftPt.coordX();
00228   float front_dy = frontRightPt.coordY() - frontLeftPt.coordY();
00229   float back_dx  = backRightPt.coordX() - backLeftPt.coordX();
00230   float back_dy  = backRightPt.coordY() - backLeftPt.coordY();
00231   
00232   if (frontValid && backValid) {
00233     // Calculate the length/width
00234     length = max(frontLine.getLength(), backLine.getLength());
00235     width  = max(frontLine.perpendicularDistanceFrom( backLine.getCentroid() ), backLine.perpendicularDistanceFrom( frontLine.getCentroid() ));
00236 
00237     // Calculate the orientation based on the front and back line
00238     AngSignPi front_orientation = AngSignPi(atan2(front_dy, front_dx) + M_PI / 2);
00239     AngSignPi back_orientation  = AngSignPi(atan2(back_dy, back_dx) + M_PI / 2);
00240     
00241     // Check left/right of line by coming up with a point that's 1000mm away,
00242     // and if the point is closer to the other line, then orientation should be flipped
00243     float dist = 1000.0f;
00244     Point frontPt( getCentroid().coordX() + dist * cos(front_orientation), getCentroid().coordY() + dist * sin(front_orientation), getCentroid().coordZ() );
00245     if ((width > 50.0f) && (frontLine.perpendicularDistanceFrom( frontPt ) > backLine.perpendicularDistanceFrom( frontPt ))) {
00246       // Front left and right are reversed
00247       EndPoint temp = frontLeftPt;
00248       frontLeftPt = frontRightPt;
00249       frontRightPt = temp;
00250       frontLine.update_derived_properties();
00251       
00252       front_dx = frontRightPt.coordX() - frontLeftPt.coordX();
00253       front_dy = frontRightPt.coordY() - frontLeftPt.coordY();
00254       front_orientation = AngSignPi(atan2(front_dy, front_dx) + M_PI / 2);
00255     }
00256     
00257     Point backPt( getBackCentroid().coordX() - dist * cos(back_orientation), getBackCentroid().coordY() - dist * sin(back_orientation), getBackCentroid().coordZ() );
00258     if ((width > 50.0f) && (backLine.perpendicularDistanceFrom( backPt ) > frontLine.perpendicularDistanceFrom( backPt ))) {
00259       // Back left and right are reversed
00260       EndPoint temp = backLeftPt;
00261       backLeftPt = backRightPt;
00262       backRightPt = temp;
00263       backLine.update_derived_properties();
00264       
00265       back_dx  = backRightPt.coordX() - backLeftPt.coordX();
00266       back_dy  = backRightPt.coordY() - backLeftPt.coordY();
00267       back_orientation  = AngSignPi(atan2(back_dy, back_dx) + M_PI / 2);
00268     }
00269     
00270     // Use the orientation of the line with most valid points
00271     int frontValidCount = 0, backValidCount = 0;
00272     if (frontLeftPt.isValid()) frontValidCount++;
00273     if (frontRightPt.isValid()) frontValidCount++;
00274     if (backLeftPt.isValid()) backValidCount++;
00275     if (backRightPt.isValid()) backValidCount++;
00276     
00277     if (frontValidCount == backValidCount) {
00278       // Take the average of the 2 orientations
00279       orientation = AngSignPi(atan2(sin(front_orientation) + sin(back_orientation), cos(front_orientation) + cos(back_orientation)));
00280     }
00281     else if (frontValidCount > backValidCount) {
00282       orientation = front_orientation;
00283     }
00284     else {
00285       orientation = back_orientation;
00286     }
00287   }
00288   // If only one line is valid, obtain the length/orientation from it
00289   else if (frontValid) {
00290     length = frontLine.getLength();
00291     width = 0;
00292     orientation = AngSignPi(atan2(front_dy, front_dx) + M_PI / 2);
00293   }
00294   else if (backValid) {
00295     length = backLine.getLength();
00296     width = 0;
00297     orientation = AngSignPi(atan2(back_dy, back_dx) + M_PI / 2);
00298   }
00299   else {
00300     length = 0;
00301     width = 0;
00302     orientation = 0;
00303   }
00304   
00305 }
00306 
00307 bool TargetData::updateParams(const ShapeRoot& other, bool force) {
00308   const Shape<TargetData>& other_target = ShapeRootTypeConst(other,TargetData);
00309   if (other_target->confidence <= 0)
00310     return false;
00311     
00312   const int other_conf = other_target->confidence;
00313   confidence += other_conf;
00314   
00315   height = (height*confidence + other_target->getHeight()*other_conf) / (confidence+other_conf);
00316   
00317   // Update front line
00318   EndPoint &frontLeftPt  = getFrontLeftPt();
00319   EndPoint &frontRightPt = getFrontRightPt();
00320   if (!frontValid) {
00321     frontLeftPt  = other_target->getFrontLeftPt();
00322     frontRightPt = other_target->getFrontRightPt();
00323   }
00324   else if (other_target->isFrontValid()) {
00325     NEW_SHAPE(otherFrontLine, LineData, other_target->frontLine);
00326     frontLine.updateParams(otherFrontLine, force);
00327     otherFrontLine.getSpace().deleteShape(otherFrontLine);
00328   }
00329   
00330   // Update back line
00331   EndPoint &backLeftPt  = getBackLeftPt();
00332   EndPoint &backRightPt = getBackRightPt();
00333   if (!backValid) {
00334     backLeftPt  = other_target->getBackLeftPt();
00335     backRightPt = other_target->getBackRightPt();
00336   }
00337   else if (other_target->isBackValid()) {
00338     NEW_SHAPE(otherBackLine, LineData, other_target->backLine);
00339     backLine.updateParams(otherBackLine, force);
00340     otherBackLine.getSpace().deleteShape(otherBackLine);
00341   }
00342   
00343   // Update front intersection point
00344   if (frontIntersect == Point(0, 0, 0)) {
00345     frontIntersect = other_target->getFrontIntersect();
00346   }
00347   else if (other_target->getFrontIntersect() != Point(0, 0, 0)) {
00348     if (frontIntersect.isValid() == other_target->getFrontIntersect().isValid()) {
00349       frontIntersect.updateParams(other_target->getFrontIntersect());
00350     }
00351     else if (other_target->getFrontIntersect().isValid()) {
00352       frontIntersect = other_target->getFrontIntersect();
00353     }
00354   }
00355   
00356   // Update back intersection point
00357   if (backIntersect == Point(0, 0, 0)) {
00358     backIntersect = other_target->getBackIntersect();
00359   }
00360   else if (other_target->getBackIntersect() != Point(0, 0, 0)) {
00361     if (backIntersect.isValid() == other_target->getBackIntersect().isValid()) {
00362       backIntersect.updateParams(other_target->getBackIntersect());
00363     }
00364     else if (other_target->getBackIntersect().isValid()) {
00365       backIntersect = other_target->getBackIntersect();
00366     }
00367   }
00368   
00369   update_derived_properties();
00370   
00371   return true;
00372 }
00373 
00374 void TargetData::mergeWith(const ShapeRoot& other) {
00375   const Shape<TargetData>& other_target = ShapeRootTypeConst(other,TargetData);
00376   if (other_target->confidence <= 0)
00377     return;
00378   const int other_conf = other_target->confidence;
00379   confidence += other_conf;
00380   
00381   height = (height*confidence + other_target->height*other_conf) / (confidence+other_conf);
00382   NEW_SHAPE(otherFrontLine, LineData, other_target->frontLine);
00383   NEW_SHAPE(otherBackLine, LineData, other_target->backLine);
00384   frontLine.mergeWith(otherFrontLine);
00385   backLine.mergeWith(otherBackLine);
00386   otherFrontLine.getSpace().deleteShape(otherFrontLine);
00387   otherBackLine.getSpace().deleteShape(otherBackLine);
00388   
00389   frontIntersect.updateParams(other_target->getFrontIntersect());
00390   backIntersect.updateParams(other_target->getBackIntersect());
00391   
00392   update_derived_properties();
00393 }
00394 
00395 void TargetData::printParams() const {
00396   cout << "Type = " << getTypeName() << endl;
00397   cout << "Shape ID = " << getId() << endl;
00398   cout << "Parent ID = " << getParentId() << endl;
00399   
00400   // Print all parameters.
00401   const EndPoint frontLeftPt  = getFrontLeftPt();
00402   const EndPoint frontRightPt = getFrontRightPt();
00403   const EndPoint backLeftPt   = getBackLeftPt();
00404   const EndPoint backRightPt  = getBackRightPt();
00405   const Point centroid = getCentroid();
00406   
00407   cout << endl;
00408   cout << "centroid = (" << centroid.coordX() << ", " << centroid.coordY() << ", " << centroid.coordZ() << ")" << endl;
00409   cout << "front left pt = (" << frontLeftPt.coordX() << ", " << frontLeftPt.coordY() << ", " << frontLeftPt.coordZ() << "), valid = " << frontLeftPt.isValid() << endl;
00410   cout << "front right pt = (" << frontRightPt.coordX() << ", " << frontRightPt.coordY() << ", " << frontRightPt.coordZ() << "), valid = " << frontRightPt.isValid() << endl;
00411   cout << "back left pt = (" << backLeftPt.coordX() << ", " << backLeftPt.coordY() << ", " << backLeftPt.coordZ() << "), valid = " << backLeftPt.isValid() << endl;
00412   cout << "back right pt = (" << backRightPt.coordX() << ", " << backRightPt.coordY() << ", " << backRightPt.coordZ() << "), valid = " << backRightPt.isValid() << endl;
00413   cout << "front intersect = (" << frontIntersect.coordX() << ", " << frontIntersect.coordY() << ", " << frontIntersect.coordZ() << "), valid = " << frontIntersect.isValid() << endl;
00414   cout << "back intersect = (" << backIntersect.coordX() << ", " << backIntersect.coordY() << ", " << backIntersect.coordZ() << "), valid = " << backIntersect.isValid() << endl;
00415   cout << "front valid = " << frontValid << endl;
00416   cout << "back valid = " << backValid << endl;
00417   cout << "orientation = " << (float)orientation * 180.0 / M_PI << " deg" << endl;
00418   cout << "length = " << length << endl;
00419   cout << "width = " << width << endl;
00420   cout << "height = " << height << endl;
00421 }
00422 
00423 void TargetData::applyTransform(const NEWMAT::Matrix& Tmat, const ReferenceFrameType_t newref) {
00424   if (frontValid)
00425     frontLine.applyTransform(Tmat, newref);
00426   if (backValid)
00427     backLine.applyTransform(Tmat, newref);
00428   if (frontIntersect != Point(0, 0, 0))
00429     frontIntersect.applyTransform(Tmat, newref);
00430   if (backIntersect != Point(0, 0, 0))
00431     backIntersect.applyTransform(Tmat, newref);
00432   update_derived_properties();
00433 }
00434 
00435 void TargetData::projectToGround(const NEWMAT::Matrix& camToBase, const NEWMAT::ColumnVector& groundplane) {
00436   // project the lines to elevated ground space
00437   NEWMAT::ColumnVector target_plane = groundplane;
00438   float displacement = height * sqrt(target_plane(1) * target_plane(1) + target_plane(2) * target_plane(2) + target_plane(3) * target_plane(3));
00439   target_plane(4) += target_plane(3) >= 0 ? displacement : -displacement;
00440   
00441   if (frontValid)
00442     frontLine.projectToGround(camToBase, target_plane);
00443   if (backValid)
00444     backLine.projectToGround(camToBase, target_plane);
00445   if (frontIntersect != Point(0, 0, 0))
00446     frontIntersect.projectToGround(camToBase, target_plane);
00447   if (backIntersect != Point(0, 0, 0))
00448     backIntersect.projectToGround(camToBase, target_plane);
00449   update_derived_properties();
00450 }
00451 
00452 // Doesn't actually render a target to sketch space
00453 Sketch<bool>* TargetData::render() const {
00454   SketchSpace &SkS = space->getDualSpace();
00455   
00456   Sketch<bool>& draw_result = 
00457     *new Sketch<bool>(SkS, "render("+getName()+")");
00458   draw_result->setParentId(getViewableId());
00459   draw_result->setColor(getColor());
00460   
00461   NEWMAT::ColumnVector ctr(getCentroid().getCoords());
00462   SkS.applyTmat(ctr);
00463   int const cx = int(ctr(1));
00464   int const cy = int(ctr(2));
00465   draw_result = false;
00466   draw_result(cx, cy) = true;  
00467   return &draw_result;
00468 }
00469 
00470 TargetData& TargetData::operator=(const TargetData& other) {
00471   if (&other == this)
00472     return *this;
00473   BaseData::operator=(other);
00474   
00475   frontLine      = other.frontLine;
00476   backLine       = other.backLine;
00477   frontValid     = other.frontValid;
00478   backValid      = other.backValid;
00479   frontIntersect = other.frontIntersect;
00480   backIntersect  = other.backIntersect;
00481   orientation    = other.orientation;
00482   length         = other.length;
00483   width          = other.width;
00484   height         = other.height;
00485   
00486   return *this;
00487 }
00488 
00489 float TargetData::perpendicularDistanceFrom(Point point) {
00490   if (frontValid && backValid)
00491     return min(frontLine.perpendicularDistanceFrom(point), backLine.perpendicularDistanceFrom(point));
00492   else if (frontValid)
00493     return frontLine.perpendicularDistanceFrom(point);
00494   else if (backValid)
00495     return backLine.perpendicularDistanceFrom(point);
00496   else
00497     return 0;
00498 }
00499 
00500 Shape<TargetData> TargetData::extractLineTarget(std::string frontColor, std::string backColor, std::string rightColor, std::string occluderColor, const float height) {
00501   // get the front, back and right stuff
00502   NEW_SKETCH(camFrame, uchar, VRmixin::sketchFromSeg());    
00503   NEW_SKETCH(frontStuff, bool, visops::colormask(camFrame, frontColor));
00504   NEW_SKETCH(backStuff, bool, visops::colormask(camFrame, backColor));
00505   NEW_SKETCH(rightStuff, bool, visops::colormask(camFrame, rightColor));
00506   NEW_SKETCH(occluders, bool, visops::colormask(camFrame, occluderColor));
00507 
00508   NEW_SHAPEVEC(frontBlobs, BlobData, BlobData::extractBlobs(frontStuff, 100));
00509   NEW_SHAPEVEC(backBlobs, BlobData, BlobData::extractBlobs(backStuff, 100));
00510   NEW_SHAPEVEC(rightBlobs, BlobData, BlobData::extractBlobs(rightStuff, 100));
00511   
00512   // assume the biggest blob forms the front line
00513   NEW_SKETCH(frontSketch, bool, frontBlobs.size() > 0 ? frontBlobs[0]->getRendering() : visops::zeros(camFrame));
00514   // assume the biggest blob forms the back line
00515   NEW_SKETCH(backSketch, bool, backBlobs.size() > 0 ? backBlobs[0]->getRendering() : visops::zeros(camFrame));
00516   // assume the biggest blob forms the right line
00517   NEW_SKETCH(rightSketch, bool, rightBlobs.size() > 0 ? rightBlobs[0]->getRendering() : visops::zeros(camFrame));
00518   
00519   Shape<TargetData> result = extractLineTarget(frontSketch, backSketch, rightSketch, occluders, height);
00520   
00521   // delete temporary camera shapes
00522   //camShS.deleteShapes(horBlobs);
00523   //camShS.deleteShapes(vertBlobs);
00524   
00525   return result;
00526 }
00527 
00528 Shape<TargetData> TargetData::extractLineTarget(Sketch<bool>& frontSketch, Sketch<bool>& backSketch, Sketch<bool>& rightSketch, Sketch<bool>& occluders, const float height) {
00529   NEW_SHAPE(frontLine, LineData, LineData::extractLine(frontSketch, occluders | rightSketch));
00530   NEW_SHAPE(backLine, LineData, LineData::extractLine(backSketch, occluders | rightSketch));
00531   NEW_SHAPE(rightLine, LineData, LineData::extractLine(rightSketch, occluders));
00532 
00533   Shape<TargetData> result = extractLineTarget(frontLine, backLine, rightLine, frontSketch->getColor(), height);
00534   
00535   // delete temporary camera shapes
00536   if (frontLine.isValid())
00537     frontLine.getSpace().deleteShape(frontLine);
00538   if (backLine.isValid())
00539     backLine.getSpace().deleteShape(backLine);
00540   if (rightLine.isValid())
00541     rightLine.getSpace().deleteShape(rightLine);
00542   
00543   return result;
00544 }
00545 
00546 Shape<TargetData> TargetData::extractLineTarget(Shape<LineData>& frontLine, Shape<LineData>& backLine, Shape<LineData>& rightLine, rgb color, const float height) {
00547   
00548   // create the target using the front and back lines
00549   if (frontLine.isValid() && backLine.isValid()) {
00550     EndPoint frontIntersect = Point(0, 0, 0);
00551     EndPoint backIntersect = Point(0, 0, 0);
00552     if (rightLine.isValid()) {
00553       frontIntersect = frontLine->intersectionWithLine(rightLine);
00554       backIntersect  = backLine->intersectionWithLine(rightLine);
00555       frontIntersect.setValid(frontLine->pointOnLine(frontIntersect));
00556       backIntersect.setValid(backLine->pointOnLine(backIntersect));
00557     }
00558     else {
00559       frontIntersect.setValid(false);
00560       backIntersect.setValid(false);
00561     }
00562   
00563     Shape<TargetData> result(frontLine.getSpace(), frontLine->leftPt(), frontLine->rightPt(), backLine->leftPt(), backLine->rightPt(), frontIntersect, backIntersect, height);
00564     result->setColor(color);
00565     return result;
00566   }
00567   else if (frontLine.isValid()) {
00568     EndPoint left = Point(0, 0, 0);
00569     EndPoint right = Point(0, 0, 0);
00570     left.setValid(false);
00571     right.setValid(false);
00572     
00573     EndPoint frontIntersect = Point(0, 0, 0);
00574     EndPoint backIntersect = Point(0, 0, 0);
00575     frontIntersect.setValid(false);
00576     backIntersect.setValid(false);
00577     
00578     if (rightLine.isValid()) {
00579       frontIntersect = frontLine->intersectionWithLine(rightLine);
00580       frontIntersect.setValid(frontLine->pointOnLine(frontIntersect));
00581     }
00582     
00583     Shape<TargetData> result(frontLine.getSpace(), frontLine->rightPt(), frontLine->leftPt(), right, left, frontIntersect, backIntersect, height);
00584     result->setColor(color);
00585     return result;
00586   }
00587   else if (backLine.isValid()) {
00588     EndPoint left = Point(0, 0, 0);
00589     EndPoint right = Point(0, 0, 0);
00590     left.setValid(false);
00591     right.setValid(false);
00592     
00593     EndPoint frontIntersect = Point(0, 0, 0);
00594     EndPoint backIntersect = Point(0, 0, 0);
00595     frontIntersect.setValid(false);
00596     backIntersect.setValid(false);
00597     
00598     if (rightLine.isValid()) {
00599       backIntersect = backLine->intersectionWithLine(rightLine);
00600       backIntersect.setValid(backLine->pointOnLine(backIntersect));
00601     }
00602     
00603     Shape<TargetData> result(backLine.getSpace(), right, left, backLine->rightPt(), backLine->leftPt(), frontIntersect, backIntersect, height);
00604     result->setColor(color);
00605     return result;
00606   }
00607   else {
00608     ShapeRoot invalid; // need to define a named variable to avoid warning on next line
00609     return ShapeRootType(invalid, TargetData);
00610   }
00611 
00612 }
00613 
00614 } // namespace

DualCoding 4.0
Generated Thu Nov 22 00:52:37 2007 by Doxygen 1.5.4