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 _INTERSECTIONCURVE_H
00034 #define _INTERSECTIONCURVE_H
00035
00036
00037 #include "IntersectionPoint.h"
00038 #include "IntersectionLink.h"
00039 #include "ParamCurve.h"
00040 #include <boost/shared_ptr.hpp>
00041 #include <list>
00042 #include <vector>
00043
00044
00045 namespace Go {
00048
00049
00050
00051 enum EvalKind {SPACECURVE, PARAMCURVE_1, PARAMCURVE_2};
00052 enum TangentDomain {GEOM, PARAM1, PARAM2};
00053 enum EstimateDirection {FORWARDS, BACKWARDS};
00054
00055
00056 class Zero_Parameter_Span_Error {};
00057 class ParamSurfaceInt;
00058 class IntersectionCurve;
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00090
00091
00092 class IntersectionCurve {
00093
00094 public:
00096 virtual ~IntersectionCurve() {};
00097
00100 virtual boost::shared_ptr<ParamCurve>
00101 getCurve() const = 0;
00102
00111 virtual boost::shared_ptr<ParamCurve>
00112 getParamCurve(int obj_nmb) const = 0;
00113
00120 virtual void getParamSpan(double& start, double& end) const = 0;
00121
00132 virtual void evaluateAt(double pval, Point& pos, Point& tan) = 0;
00133
00141 virtual void refine(const double& pos_tol, const double& angle_tol) = 0;
00142
00147 virtual bool isIsocurve() const = 0;
00148
00153 virtual bool isDegenerated() const = 0;
00154
00163 boost::shared_ptr<IntersectionPoint> getGuidePoint(int index) const;
00164
00178 virtual bool
00179 getGuidePointTangent(boost::shared_ptr<IntersectionPoint> pt,
00180 Point& tan, int type = 0) const;
00181
00182
00186 int numGuidePoints() const { return ipoints_.size();}
00187
00191 void writeIPointsToStream(std::ostream& os) const;
00192
00193 protected:
00194
00195 template<class iterator>
00196 IntersectionCurve(iterator begin, iterator end)
00197 : ipoints_(begin, end) {}
00198
00199
00200 std::list<boost::shared_ptr<IntersectionPoint> > ipoints_;
00201
00202
00203
00204
00205 template<class iterator> friend
00206 boost::shared_ptr<IntersectionCurve>
00207 constructIntersectionCurve(const iterator begin,
00208 const iterator end);
00209
00210
00211 };
00212
00213
00215
00216
00217 class DegeneratedIntersectionCurve : public IntersectionCurve {
00218
00219 public:
00220 virtual ~DegeneratedIntersectionCurve();
00221
00222 virtual boost::shared_ptr<ParamCurve> getCurve() const;
00223
00224 virtual boost::shared_ptr<ParamCurve> getParamCurve(int obj_nmb) const;
00225
00226 virtual bool isIsocurve() const
00227 { return false; }
00228
00229 virtual bool isDegenerated() const
00230 { return true; }
00231
00232 virtual void getParamSpan(double& start, double& end) const
00233 {
00234 start = 0;
00235 end = 1;
00236 }
00237
00238 virtual void refine(const double& pos_tol, const double& angle_tol)
00239 {
00240 MESSAGE("Tried to refine a degenerate curve. Ignoring...");
00241 }
00242
00243 virtual void evaluateAt(double pval, Point& pos, Point& tan)
00244 {
00245 pos = ipoints_.front()->getPoint();
00246 tan = ipoints_.front()->getTangent();
00247 }
00248
00249 private:
00250
00251 template<class iterator>
00252 DegeneratedIntersectionCurve(const iterator begin, const iterator end)
00253 : IntersectionCurve(begin, end)
00254 {
00255 MESSAGE("Created a degenerate IntersectionCurve object.");
00256 }
00257
00258 template<class iterator>
00259 static bool degenerated_range(const iterator begin, const iterator end);
00260
00261 template<class iterator> friend
00262 boost::shared_ptr<IntersectionCurve>
00263 constructIntersectionCurve(const iterator begin,
00264 const iterator end);
00265 };
00266
00267
00269
00270
00271 class NonEvaluableIntersectionCurve : public IntersectionCurve
00272
00273 {
00274 public:
00275 virtual ~NonEvaluableIntersectionCurve();
00276
00277 virtual boost::shared_ptr<ParamCurve> getCurve() const
00278 { return boost::shared_ptr<ParamCurve>(); }
00279
00280 virtual boost::shared_ptr<ParamCurve> getParamCurve(int obj_nmb) const
00281 { return boost::shared_ptr<ParamCurve>(); }
00282
00283 virtual void getParamSpan(double& start, double& end) const
00284 { start = end = 0; }
00285
00286 virtual void evaluateAt(double pval, Point& pos, Point& tan)
00287 {
00288 MESSAGE("Warning! Tried to evaluate non-evaluable IntersectionCurve.\n"
00289 "Nothing done.");
00290 }
00291
00292 virtual void refine(const double& pos_tol, const double& angle_tol)
00293 {
00294 MESSAGE("Warning! Tried to refine non-evaluable IntersectionCurve.\n"
00295 "Nothing done.");
00296 }
00297
00298 virtual bool isIsocurve() const
00299 { return false; }
00300
00301 virtual bool isDegenerated() const
00302 { return false; }
00303
00304 private:
00305 template<class iterator>
00306 NonEvaluableIntersectionCurve(const iterator begin, const iterator end)
00307 : IntersectionCurve(begin, end)
00308 {
00309 MESSAGE("Warning! Created a non-evaluable IntersectionCurve.");
00310 }
00311 template<class iterator> friend
00312 boost::shared_ptr<IntersectionCurve>
00313 constructIntersectionCurve(const iterator begin,
00314 const iterator end);
00315 };
00316
00317
00320
00321
00322 class IsoparametricIntersectionCurve : public IntersectionCurve
00323
00324 {
00325 public:
00326 virtual ~IsoparametricIntersectionCurve() {};
00327
00328 virtual boost::shared_ptr<ParamCurve> getCurve() const;
00329
00330 virtual boost::shared_ptr<ParamCurve> getParamCurve(int obj_nmb) const;
00331
00332 virtual bool isIsocurve() const
00333 { return true; }
00334
00335 virtual bool isDegenerated() const
00336 { return false; }
00337
00338 virtual void refine(const double& pos_tol, const double& angle_tol)
00339 {
00340 MESSAGE("Tried to refine an isoparametric curve. Ignoring...");
00341 }
00342
00343 virtual void getParamSpan(double& start, double& end) const
00344 {
00345 start = isopar_geom_curve_->startparam();
00346 end = isopar_geom_curve_->endparam();
00347 }
00348
00349 virtual void evaluateAt(double pval, Point& pos, Point& tan)
00350 {
00351 temp_.resize(2);
00352 isopar_geom_curve_->point(temp_, pval, 1);
00353 pos = temp_[0];
00354 tan = temp_[1];
00355 }
00356
00357 protected:
00358 boost::shared_ptr<ParamCurve> isopar_geom_curve_;
00359 boost::shared_ptr<ParamCurve> isopar_param_curve_1_;
00360 boost::shared_ptr<ParamCurve> isopar_param_curve_2_;
00361 mutable std::vector<Go::Point> temp_;
00362
00363 template<class iterator>
00364 IsoparametricIntersectionCurve(const iterator begin, const iterator end,
00365 int isopar)
00366 : IntersectionCurve(begin, end)
00367 {
00368 precalculate_iso_curves(isopar);
00369 }
00370
00371 void precalculate_iso_curves(int isopar);
00372
00373 template<class iterator>
00374 static std::vector<int>
00375 resolve_isoparametric_directions(const iterator begin,
00376 const iterator end);
00377
00378 template<class iterator> friend
00379 boost::shared_ptr<IntersectionCurve>
00380 constructIntersectionCurve(const iterator begin,
00381 const iterator end);
00382 };
00383
00384
00387
00388
00389 class InterpolatedIntersectionCurve : public IntersectionCurve
00390
00391 {
00392 public:
00393 virtual ~InterpolatedIntersectionCurve() {}
00394
00395 virtual void refine(const double& pos_tol, const double& angle_tol);
00396
00397 virtual boost::shared_ptr<ParamCurve> getCurve() const;
00398
00399 virtual boost::shared_ptr<ParamCurve> getParamCurve(int obj_nmb) const;
00400
00401 virtual bool isIsocurve() const
00402 { return false; }
00403
00404 virtual bool isDegenerated() const
00405 { return false; }
00406
00407 virtual void getParamSpan(double& start, double& end) const
00408 {
00409 start = 0;
00410 end = 1;
00411 }
00412
00413 virtual void evaluateAt(double pval, Point& pos, Point& tan);
00414
00415 virtual bool
00416 getGuidePointTangent(boost::shared_ptr<IntersectionPoint> pt,
00417 Point& tan, int type) const;
00418
00419
00420 void write(std::ostream& os) const;
00421
00422
00423 void read(std::istream& is) const;
00424
00425 private:
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 std::map<boost::shared_ptr<IntersectionPoint>,
00438 std::pair<Go::Array<Go::Point, 3>, bool> > tangents_;
00439 double certified_pos_tol_;
00440 double certified_angle_tol_;
00441 mutable std::vector<Go::Point> temp_;
00442 mutable bool geom_cached_;
00443 mutable bool par1_cached_;
00444 mutable bool par2_cached_;
00445 mutable boost::shared_ptr<ParamCurve> cached_geom_curve_;
00446 mutable boost::shared_ptr<ParamCurve> cached_param_curve_1_;
00447 mutable boost::shared_ptr<ParamCurve> cached_param_curve_2_;
00448
00449 template<class iterator>
00450 InterpolatedIntersectionCurve(const iterator begin, const iterator end)
00451 : IntersectionCurve(begin, end),
00452 certified_pos_tol_(std::numeric_limits<double>::max()),
00453 certified_angle_tol_(std::numeric_limits<double>::max()),
00454 geom_cached_(false),
00455 par1_cached_(false),
00456 par2_cached_(false)
00457 {
00458 resolve_tangents();
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468 void resolve_tangents();
00469
00470
00471
00472
00473
00474 void choose_differentiation_side(std::list<boost::
00475 shared_ptr<IntersectionPoint> >::
00476 const_iterator pt) const;
00477
00478
00479
00480
00481 void invert_sequence_if_necessary();
00482
00483
00484
00485
00486
00487 std::list<boost::shared_ptr<IntersectionPoint> >::iterator
00488 choose_reference_direction();
00489
00490
00491
00492
00493
00494 void make_consistent_orientation(std::list<boost::
00495 shared_ptr<IntersectionPoint> >::
00496 iterator ref_elem);
00497
00498
00499
00500
00501 void flip_tangent(std::list<boost::
00502 shared_ptr<IntersectionPoint> >::iterator pt,
00503 bool flip);
00504
00505
00506
00507
00508 bool determine_flip(std::list<boost::
00509 shared_ptr<IntersectionPoint> >::const_iterator prec,
00510 std::list<boost::
00511 shared_ptr<IntersectionPoint> >::const_iterator mid,
00512 std::list<boost::
00513 shared_ptr<IntersectionPoint> >::const_iterator next);
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 Point tangent_of(std::list<boost::
00526 shared_ptr<IntersectionPoint> >::const_iterator pt) const;
00527
00528
00529
00530
00531
00532
00533 Point param_tangent_of(std::list<boost::
00534 shared_ptr<IntersectionPoint> >::const_iterator pt,
00535 bool second_obj) const;
00536
00537
00538
00539
00540
00541
00542
00543 void establish_curve_spesific_tangent(std::list<boost::
00544 shared_ptr<IntersectionPoint> >::
00545 const_iterator pt);
00546
00547
00548
00549
00550
00551 bool context_tangent_estimate(std::list<boost::
00552 shared_ptr<IntersectionPoint> >::
00553 const_iterator pt,
00554 TangentDomain tdom,
00555 EstimateDirection,
00556 Point& result) const;
00557
00558
00559
00560
00561
00562
00563
00564
00565 void refine_interval_recursive(std::list<boost::
00566 shared_ptr<IntersectionPoint> >::
00567 iterator start_point,
00568 const double& pos_tol,
00569 const double& angle_tol);
00570
00571
00572
00573
00574 bool eval_surf_point(const Point& midpoint_pos,
00575 const Point& midpoint_tan,
00576 const ParamSurfaceInt* psurf1,
00577 const Point& midpoint_param_pos_1,
00578 const ParamSurfaceInt* psurf2,
00579 const Point& midpoint_param_pos_2,
00580 Point& surface_point,
00581 Point& surface_tangent,
00582 Point& surface_1_param,
00583 Point& surface_2_param,
00584 int& jstat) const;
00585
00586 void hermite_interpol(std::list<boost::shared_ptr<IntersectionPoint> >::
00587 iterator start_point,
00588 std::list<boost::shared_ptr<IntersectionPoint> >::
00589 iterator end_point,
00590 Point& mid_position,
00591 Point& mid_tangent,
00592 EvalKind kind) const;
00593
00594 template<class iterator> friend
00595 boost::shared_ptr<IntersectionCurve>
00596 constructIntersectionCurve(const iterator begin,
00597 const iterator end);
00598 };
00599
00600
00601
00602
00603
00604 template<class iterator>
00605 boost::shared_ptr<IntersectionCurve>
00606 constructIntersectionCurve(const iterator begin,
00607 const iterator end)
00608
00609 {
00610 typedef IsoparametricIntersectionCurve IsoCurve;
00611 typedef DegeneratedIntersectionCurve DegenCurve;
00612 typedef InterpolatedIntersectionCurve InterpolCurve;
00613 typedef NonEvaluableIntersectionCurve NonEvalCurve;
00614
00615
00616
00617
00618
00619
00620 std::vector<int> isopar
00621 = IsoCurve::resolve_isoparametric_directions(begin, end);
00622 if (isopar.size() > 0) {
00623
00624
00625 try {
00626 return boost::shared_ptr<IntersectionCurve>
00627 (new IsoCurve(begin, end, isopar[0]));
00628 } catch (Zero_Parameter_Span_Error& e) {
00629
00630
00631 MESSAGE("Warning: tried to generate an isocurve but made"
00632 " a degenerated curve instead.");
00633 return boost::shared_ptr<IntersectionCurve>
00634 (new DegenCurve(begin, end));
00635 }
00636 } else if (DegenCurve::degenerated_range(begin, end)) {
00637
00638
00639 return boost::shared_ptr<IntersectionCurve>
00640 (new DegenCurve(begin, end));
00641 }
00642
00643
00644
00645 boost::shared_ptr<IntersectionCurve> res;
00646 try {
00647 res = boost::shared_ptr<IntersectionCurve>
00648 (new InterpolCurve(begin, end));
00649 } catch(...) {
00650
00651
00652
00653 res = boost::shared_ptr<IntersectionCurve>
00654 (new NonEvalCurve(begin, end));
00655 }
00656 return res;
00657 }
00658
00659
00660
00661 template<class iterator> std::vector<int> IsoparametricIntersectionCurve::
00662 resolve_isoparametric_directions(const iterator begin, const iterator end)
00663
00664 {
00665
00666
00667 std::vector<boost::shared_ptr<IntersectionPoint> > points(begin, end);
00668 ASSERT(points.size() >= 2);
00669
00670 int num_par = points.front()->numParams1()
00671 + points.front()->numParams2();
00672 std::vector<bool> iso_candidates(num_par, true);
00673
00674
00675
00676 int i;
00677 for (i = 0; i < int(points.size()) - 1; ++i) {
00678
00679 boost::shared_ptr<IntersectionLink> link
00680 = points[i]->getIntersectionLink(points[i+1].get());
00681 ASSERT(link.get() != 0);
00682 for (int par = 0; par < num_par; ++par) {
00683 if (!link->isIsoparametricIn(par)) {
00684 iso_candidates[par] = false;
00685 }
00686 }
00687 }
00688
00689
00690
00691 std::vector<int> result;
00692 for (i = 0; i < num_par; ++i) {
00693 if (iso_candidates[i]) {
00694 result.push_back(i);
00695 }
00696 }
00697 return result;
00698 }
00699
00700
00701 template<class iterator> bool DegeneratedIntersectionCurve::
00702 degenerated_range(const iterator begin, const iterator end)
00703
00704 {
00705 const double tol = (*begin)->getTolerance()->getEpsge();
00706
00707
00708
00709
00710 Point ref_pos = (*begin)->getPoint();
00711 bool found = false;
00712 for (iterator i = begin; i != end && !found; ++i) {
00713 Point cur_pos = (*i)->getPoint();
00714 found = (ref_pos.dist2(cur_pos) > tol * tol);
00715 }
00716 return !found;
00717 }
00718
00719
00721 };
00722
00723
00724 #endif // _INTERSECTIONCURVE_H
00725
00726