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 _SFSELFINTERSECTOR_H
00034 #define _SFSELFINTERSECTOR_H
00035
00036
00037 #include "Intersector.h"
00038
00039
00040 namespace Go {
00043
00044
00045
00046 class ParamSurfaceInt;
00047 class SurfaceAssembly;
00048
00049
00050 struct SingBox
00051 {
00052 std::vector<std::pair<double, int> > box_limit_;
00053 boost::shared_ptr<IntersectionPoint> sing_;
00054
00055 SingBox(std::vector<std::pair<double, int> > box,
00056 boost::shared_ptr<IntersectionPoint> sing)
00057 {
00058 box_limit_ = box;
00059 sing_ = sing;
00060 }
00061 };
00062
00063 struct SingUnion
00064 {
00065 double limit_[4];
00066 std::vector<int> singbox_idx_;
00067
00068 SingUnion(double box[], std::vector<int> idx)
00069 {
00070 for (int ki=0; ki<4; ki++)
00071 limit_[ki] = box[ki];
00072 singbox_idx_ = idx;
00073 }
00074
00075 bool isInside(double *mima)
00076 {
00077 if (limit_[0] < mima[0])
00078 return false;
00079 if (limit_[1] > mima[1])
00080 return false;
00081 if (limit_[2] < mima[2])
00082 return false;
00083 if (limit_[3] > mima[3])
00084 return false;
00085 return true;
00086 }
00087 };
00088
00089
00091
00092 class SfSelfIntersector : public Intersector {
00093 public:
00094
00099 SfSelfIntersector(boost::shared_ptr<ParamSurfaceInt> surf,
00100 double epsge, Intersector *prev = NULL);
00101
00106 SfSelfIntersector(boost::shared_ptr<ParamSurfaceInt> surf,
00107 boost:: shared_ptr<GeoTol> epsge,
00108 Intersector *prev = NULL);
00109
00111 virtual ~SfSelfIntersector();
00112
00116 virtual void compute(bool compute_at_boundary = true);
00117
00120 virtual int numParams() const
00121 { return 2; }
00122
00125 void setMaxRec(int max_rec)
00126 { max_rec = max_rec_; }
00127
00130 int getNmbComplexDomain()
00131 { return complex_domain_.size(); }
00132
00134 virtual bool isSelfIntersection()
00135 { return true; }
00136
00137 protected:
00138
00139
00140
00141 bool computeG1();
00142
00143
00144
00145 std::vector<boost::shared_ptr<ParamSurfaceInt> >
00146 getNonSelfintersecting()
00147 { return non_selfint_; }
00148
00149 virtual void print_objs() {}
00150
00151 virtual int getBoundaryIntersections()
00152 { return 0; }
00153
00154 virtual int performInterception()
00155 { return 0; }
00156
00157 virtual int simpleCase()
00158 { return 0; }
00159
00160 virtual bool isLinear()
00161 { return false; }
00162
00163 virtual bool complexityReduced()
00164 { return false; }
00165
00166 virtual void handleComplexity() {}
00167
00168 virtual int checkCoincidence()
00169 { return 0; }
00170
00171 virtual void microCase() {}
00172
00173 virtual int updateIntersections()
00174 { return 0; }
00175
00176 virtual int repairIntersections();
00177
00178 virtual int linearCase()
00179 { return 0; }
00180
00181 virtual int doSubdivide()
00182 { return 0; }
00183
00184 virtual void printDebugInfo() {}
00185
00186 virtual void addComplexDomain(RectDomain dom)
00187 { complex_domain_.push_back(dom); }
00188
00189 private:
00190
00191 boost::shared_ptr<ParamSurfaceInt> surf_;
00192
00193
00194
00195
00196 std::vector<boost::shared_ptr<ParamSurfaceInt> > non_selfint_;
00197 int max_rec_;
00198 std::vector<RectDomain> complex_domain_;
00199 boost::shared_ptr<SurfaceAssembly> div_sf_;
00200 std::vector<SingBox> sing_box_;
00201 std::vector<SingUnion> sing_union_;
00202
00203
00204 bool setSubdivision();
00205
00206 bool getSingularities(std::vector<boost::
00207 shared_ptr<IntersectionPoint> >& sing);
00208
00209 void
00210 getPrevDivision(std::vector<std::pair<double,int> >& divpar_u,
00211 std::vector<std::pair<double,int> >& divpar_v);
00212
00213 void sortSingularities(std::vector<boost::
00214 shared_ptr<IntersectionPoint> >& sing,
00215 std::vector<std::pair<double,int> >& divpar_u,
00216 std::vector<std::pair<double,int> >& divpar_v);
00217
00218 bool defineSingTopology(std::vector<boost::
00219 shared_ptr<IntersectionPoint> >& sing,
00220 std::vector<std::pair<double,int> >& divpar_u,
00221 std::vector<std::pair<double,int> >& divpar_v,
00222 std::vector<RectDomain>& sing_domain);
00223
00224 void splitUnions(std::vector<std::pair<double,int> >& divpar_u,
00225 std::vector<std::pair<double,int> >& divpar_v);
00226
00227 void divideOneUnion(std::vector<std::pair<double,int> >& divpar_u,
00228 std::vector<std::pair<double,int> >& divpar_v);
00229
00230 bool isSeparated(boost::shared_ptr<IntersectionPoint> sing1,
00231 boost::shared_ptr<IntersectionPoint> sing2,
00232 std::vector<std::pair<double,int> >& divpar_u,
00233 std::vector<std::pair<double,int> >& divpar_v);
00234
00235 std::vector<std::pair<double, std::pair<double, double> > >
00236 getOverlapBox(double minval, double maxval, int dir);
00237
00238 double
00239 getSplitValue(std::vector<std::pair<double, std::pair<double, double> > >& overlap,
00240 double minval, double maxval, double divval);
00241
00242 void validateSingularities(std::vector<boost::
00243 shared_ptr<IntersectionPoint> >& sing);
00244
00245 void refineSingularityLinks(std::vector<boost::
00246 shared_ptr<IntersectionPoint> >& sing,
00247 std::vector<std::pair<double,int> >& divpar,
00248 int dir);
00249
00250 void makeDivisionLines(std::vector<boost::
00251 shared_ptr<IntersectionPoint> >& sing,
00252 std::vector<double>& sing_par, int dir,
00253 double start, double end,
00254 std::vector<std::pair<double,int> >& divpar);
00255
00256 bool hasBoundaryIntersections(boost::shared_ptr<ParamSurfaceInt> sub_sf);
00257
00258 void computeBoundaryIntersections(boost::shared_ptr<ParamSurfaceInt>
00259 sub_sf,
00260 IntersectionPoint *sing,
00261 int is_handled[]);
00262
00263 void getNmbDivision(int& div1, int& div2);
00264
00265 void setDivisionValues(std::vector<std::pair<double,int> >& divpar,
00266 int& nmbpar, int dir);
00267
00268 void checkDivisionLines(std::vector<boost::
00269 shared_ptr<IntersectionPoint> >& sing,
00270 std::vector<std::pair<double,int> >& divpar_u,
00271 std::vector<std::pair<double,int> >& divpar_v);
00272
00273 void checkOneDivLine(std::vector<boost::
00274 shared_ptr<IntersectionPoint> >& sing,
00275 int dir, double frac,
00276 std::vector<std::pair<double,int> >& div1,
00277 std::vector<std::pair<double,int> >& div2);
00278
00279 void getMaxCurvatures(boost::shared_ptr<ParamSurfaceInt> surf, int nsample,
00280 std::vector<std::pair<double,double> >& max_curv1,
00281 std::vector<std::pair<double,double> >& max_curv2);
00282
00283
00284 bool shareSingularity(boost::shared_ptr<ParamSurfaceInt> sub1,
00285 boost::shared_ptr<ParamSurfaceInt> sub2,
00286 double sing[]);
00287
00288 bool hasSingularity(boost::shared_ptr<ParamSurfaceInt> curr_sub);
00289
00290 void modifyDivisionValues(std::vector<boost::shared_ptr<IntersectionPoint> >& sing,
00291 std::vector<std::pair<double,int> >& divpar, int dir);
00292
00293 bool closeKnot(double par, std::vector<double>& knots, size_t& knot_idx,
00294 double par_div, double& curr_knot);
00295
00296 void estimateSingBox(boost::shared_ptr<ParamSurfaceInt> normsf,
00297 double param[],
00298 std::vector<std::pair<double, int> >& sing_box);
00299
00300 void makeSingularityUnions();
00301
00302 double getMinCurvatureRadAlongCurve(boost::shared_ptr<ParamSurfaceInt> normsf,
00303 int dir, double par,
00304 double tmin, double tmax, double param[]);
00305
00306 double getMinDistAlongCurve(double par[], int dir, double par,
00307 double tmin, double tmax);
00308
00309 int isInComplexDomain(boost::shared_ptr<ParamSurfaceInt> subsf);
00310
00311 void writeDebugComplex(int file, std::vector<RectDomain>& domain);
00312
00313 };
00314
00315
00317 }
00318
00319
00320 #endif // _SFSELFINTERSECTOR_H
00321
00322
00323