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