00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 #ifndef _INTERSECTIONPOINT_H
00034 #define _INTERSECTIONPOINT_H
00035 
00036 
00037 #include "IntersectionPointUtils.h"
00038 #include "LinkType.h"
00039 #include "GeoTol.h"
00040 #include "SecondOrderProperties.h"
00041 #include <boost/shared_ptr.hpp>
00042 #include <vector>
00043 #include <map>
00044 
00045 
00046 namespace Go {
00049 
00050 
00051 
00052 class ParamObjectInt;
00053 class ParamGeomInt;
00054 class ParamSurface;
00055 class IntersectionLink;
00056 
00057 
00060 
00061 class IntersectionPoint {
00062 public:
00074     IntersectionPoint(const ParamObjectInt* obj1, 
00075                       const ParamObjectInt* obj2,
00076                       const boost::shared_ptr<GeoTol> epsge,                  
00077                       const double* obj1_params,
00078                       const double* obj2_params);
00079 
00099     IntersectionPoint(const ParamObjectInt* obj1,
00100                       const ParamObjectInt* obj2,
00101                       const boost::shared_ptr<IntersectionPoint> ip,
00102                       int missing_param);
00103 
00105     ~IntersectionPoint();
00106 
00108     IntersectionPoint() {} 
00109                            
00110     
00114     void write(std::ostream& os) const;
00115 
00119     
00120     
00121     
00122     void read(std::istream& is);
00123 
00126     void writeParams(std::ostream& os) const;
00127 
00130     void writeInfo() const;
00131 
00139     void replaceParameter(double *param);
00140     
00144     Point getPoint() const;
00145 
00149     Point getPoint1() const
00150     { return point1_; }
00151 
00155     Point getPoint2() const
00156     { return point2_; }
00157 
00170     void projectToParamPlanes(const Point& dir, 
00171                               Point& par_1_dir, Point& par_2_dir) const;
00172 
00181     bool hasUniqueTangentDirection() const; 
00182 
00192     bool tangentIsOriented() const;
00193 
00199     double getDist() const
00200     { return dist_; }
00201 
00204     const std::vector<double>& getPar() const
00205     { return par_; }
00206 
00211     double getPar(int idx) const
00212     { return par_[idx]; }
00213 
00217     const double* getPar1() const;
00218 
00222     const double* getPar2() const;
00223 
00226     Point getPar1Point() const;
00229     Point getPar2Point() const;
00230 
00232     int numParams1() const;
00233 
00235     int numParams2() const;
00236 
00249     Point getTangent(bool second_branch = false) const;
00250 
00264     Point getPar1Dir(bool second_branch = false) const;
00265 
00280     Point getPar2Dir(bool second_branch = false) const;
00281 
00283     const ParamObjectInt* getObj1() const
00284     { return obj1_; }
00285 
00287     const ParamObjectInt* getObj2() const
00288     { return obj2_; }
00289 
00295     double startParam(int pardir);
00296 
00302     double endParam(int pardir);
00303 
00307     bool pointIsSingular() const
00308     { return getSingularityType() != ORDINARY_POINT; }
00309 
00312     bool isNearSingular() const;
00313 
00320     double parameterTolerance(int pardir); 
00321 
00335     void fixTangentOrientation(bool flip); 
00336 
00344     void isBoundaryPoint(bool& first, bool& second) const;
00345 
00368     void tangentPointingInwards(bool& first, 
00369                                 bool& second,
00370                                 bool& first_along_boundary,
00371                                 bool& second_along_boundary) const;
00372 
00381     bool isConnectedTo(boost::shared_ptr<IntersectionPoint> p) const
00382     { return isConnectedTo(p.get()); }
00383 
00391     bool isConnectedTo(const IntersectionPoint* point) const;
00392 
00419     boost::shared_ptr<IntersectionLink>
00420     connectTo(IntersectionPoint *const point, 
00421               LinkType type,
00422               boost::shared_ptr<IntersectionLink> model_link
00423               = boost::shared_ptr<IntersectionLink>(),
00424               int added_parameter_dir = -1);
00425 
00452     boost::shared_ptr<IntersectionLink>
00453     connectTo(boost::shared_ptr<IntersectionPoint> point, 
00454               LinkType type,
00455               boost::shared_ptr<IntersectionLink> model_link
00456               = boost::shared_ptr<IntersectionLink>(),
00457               int added_parameter_dir = -1)
00458     { return connectTo(point.get(), type,
00459                        model_link, added_parameter_dir); }
00460 
00466     void disconnectFrom(IntersectionPoint* point);
00467     
00472     int numBranches() const;
00473 
00486     IntPtClassification getClassification(const ParamSurface *surf1, 
00487                                           const ParamSurface *surf2,
00488                                           int branch_num = 0) const;
00489 
00503     IntPtClassification getClassification(const ParamSurface *par_func,
00504                                           double C,
00505                                           int branch_num = 0) const;
00506 
00508     SingularityType getSingularityType() const;
00509 
00512     boost::shared_ptr<GeoTol> getTolerance() 
00513     { return epsge_; }
00514 
00517     boost::shared_ptr<const GeoTol> getTolerance() const
00518     { return epsge_; }
00519 
00523     boost::shared_ptr<IntersectionPoint> parentPoint()
00524     { return parent_point_; }
00525 
00530     void setParentPoint(boost::shared_ptr<IntersectionPoint> p)
00531     {
00532         
00533         parent_point_ = p;
00534     }
00535 
00536     bool hasParentPoint()
00537         {
00538             return (parent_point_.get() != 0);
00539         }
00540 
00543     void flipObjects();
00544 
00566     double getInfluenceArea(int dir, bool forward, bool first_outside,
00567                             double aeps=0.0) const;
00568 
00585     int inInfluenceArea(int pardir, double par, bool first_outside) const;
00586 
00597     void shareInfluenceAreaWith(boost::shared_ptr<IntersectionPoint> other_pt,
00598                                 int pardir);
00599 
00600     
00601     
00605     bool inInfluenceAreaBracket(int pardir, double parval)
00606     { return false; }
00607 
00614     boost::shared_ptr<IntersectionLink>
00615     getIntersectionLink(const IntersectionPoint* point);
00616     
00623     void getNeighbours(std::vector<IntersectionPoint*>& pnts) const;
00624 
00629     void getNeighbourLinks(std::vector<boost::
00630                            shared_ptr<IntersectionLink> >& links) const;
00631 
00635     int numNeighbours()const { return int(intersection_links_.size()); }
00636 
00649     template<class bool_iterator>
00650     void setDifferentiateFromLeft(bool_iterator it) const  
00651     {
00652         int n = numParams1() + numParams2();
00653         ASSERT(n == int(diff_from_left_.size()));
00654         for (int i = 0; i < n; ++i, ++it) {
00655             diff_from_left_[i] = g2_discontinuous_params_[i] && (*it);
00656         }
00657         int key = bool2int(diff_from_left_.begin(), diff_from_left_.end());
00658         cur_active_2nd_order_properties_ = &sec_order_properties_[key];
00659     }
00660 
00666     bool differentiatesFromLeft(int pardir) const
00667     {
00668         ASSERT(pardir >= 0 && pardir < numParams1() + numParams2());
00669         return diff_from_left_[pardir];
00670     }
00671 
00681     int hasIsoLinks(int* const iso_par_dirs) const;
00682 
00693     int commonIsoLinks(int* const iso_par_dirs) const;
00694 
00699     bool containsG2Discontinuity() const 
00700     {
00701         int ki;
00702         for (ki=0; ki < int(g2_discontinuous_params_.size()); ki++)
00703             if (g2_discontinuous_params_[ki])
00704                 return true;
00705         return false;
00706     }
00707 
00711     bool isDegenerate() const;
00712 
00718     bool isSamePoint(const IntersectionPoint* point) const;
00719 
00728     bool checkIntersectionPoint(IntPtInfo& int_pt_info) const;
00729 
00737     bool isInDomain(double* frompar, double* topar) const;
00738 
00741     static const double tangent_tol;
00742 
00743 private:
00744 
00745     
00746 
00747     
00748     
00749     const ParamObjectInt* obj1_; 
00750     const ParamObjectInt* obj2_; 
00751 
00752     Point point1_; 
00753     Point point2_; 
00754     double dist_;  
00755 
00756     
00757     std::vector<double> par_;
00758 
00759     
00760     
00761     boost::shared_ptr<IntersectionPoint> parent_point_;
00762 
00763     
00764     
00765     std::vector<boost::shared_ptr<IntersectionLink> > intersection_links_;
00766     
00767     
00768     boost::shared_ptr<GeoTol> epsge_;
00769 
00770     
00771     mutable std::vector<CachedInterval> cached_influence_area_forwards_;
00772     mutable std::vector<CachedInterval> cached_influence_area_backwards_;
00773 
00774     
00775     
00776     std::vector<bool> g2_discontinuous_params_;
00777     mutable std::map<int, SecondOrderProperties> sec_order_properties_;
00778     mutable SecondOrderProperties* cur_active_2nd_order_properties_;
00779     mutable std::vector<bool> diff_from_left_;
00780 
00781     
00782 
00783     void constructor_implementation(const ParamObjectInt* obj1, 
00784                                     const ParamObjectInt* obj2,
00785                                     boost::shared_ptr<GeoTol> epsge,
00786                                     const double* obj_1_params,
00787                                     const double* obj_2_params);
00788 
00789     inline bool tangent_2d_is_cached() const
00790     { return cur_active_2nd_order_properties_->tangent_2d_is_cached; }
00791 
00792     inline bool singularity_info_is_cached() const
00793     { return cur_active_2nd_order_properties_->singularity_info_is_cached; }
00794 
00795     
00796     void compute_parametrical_tangents() const; 
00797     
00798     
00799     void compute_surface_parametrical_tangents_safe() const;
00800     void compute_function_parametrical_tangents() const; 
00801 
00802     
00803     
00804     SingularityType calculate_tangent_at_singular_point() const;
00805 
00806     
00807     
00808     
00809     static std::vector<bool> 
00810     detect_2nd_order_discontinuities(const ParamObjectInt* o1,
00811                                      const ParamObjectInt* o2,
00812                                      const boost::shared_ptr<GeoTol> gtol,
00813                                      const double* obj1_par,
00814                                      const double* obj2_par);
00815 
00816     void calculate_singularity_type() const;
00817     void calculate_singularity_type_function() const;
00818     void calculate_singularity_type_surface() const; 
00819     void calculate_singularity_type_curves() const ;
00820     void calculate_singularity_type_point() const;
00821     void calculate_singularity_type_curve_surface() const;
00822 
00823     static double determinant(const Point&, const Point&, const Point&);
00824     
00825     
00826     
00827     
00828 
00829     
00830     
00831     
00832     
00833     static void decompose(const Point& T, 
00834                           const Point& b1, 
00835                           const Point& b2, 
00836                           double& b1_coef,
00837                           double& b2_coef);
00838 
00839     
00840     
00841     
00842     
00843     
00844     
00845     
00846     
00847     
00848     static void proj_2_pplane(const Point& dir, 
00849                               const double* par,
00850                               std::vector<bool>::const_iterator from_left,
00851                               const ParamGeomInt* go, 
00852                               Point& par_dir);
00853 
00854     
00855     
00856     
00857     template<class iterator>
00858     static int bool2int(iterator begin_range, iterator end_range)
00859     {
00860         int result = 0;
00861         for (int pos = 0; begin_range != end_range; ++pos, ++begin_range) {
00862             
00863             
00864             if (*begin_range) {
00865                 result |= (1 << pos); 
00866             }
00867         }
00868         return result;
00869     }
00870     
00871     
00872     
00873     template<class iterator>
00874     static void int2bool(int number, iterator cur_pos, iterator end_range)
00875     {
00876         for (int pos = 0; cur_pos != end_range; ++pos, ++cur_pos) {
00877             
00878             
00879             *cur_pos = number & (1 << pos);
00880         }
00881     }
00882 
00883     std::map<int, SecondOrderProperties> 
00884     generate_2nd_order_property_map(const std::vector<bool>& disc_params);
00885 
00886     inline bool exactly_on_point(int pardir, double par) const
00887     { return (fabs(par_[pardir] - par) < epsge_->getRelParRes()); }
00888 
00889     
00890     void clearCache() const
00891     {
00892         std::map<int, SecondOrderProperties>::iterator it;
00893         for (it = sec_order_properties_.begin();
00894              it != sec_order_properties_.end(); ++it) {
00895             (it->second).clear();
00896         }
00897         cached_influence_area_forwards_
00898             = cached_influence_area_backwards_
00899             = std::vector<CachedInterval>(par_.size());
00900         diff_from_left_ = std::vector<bool>(par_.size(), false);
00901         cur_active_2nd_order_properties_ = &sec_order_properties_[0];
00902     }
00903 
00904 };
00905 
00906 
00908 }; 
00909 
00910 
00911 #endif  // _INTERSECTIONPOINT_H
00912