//=========================================================================== // GoTools Core - SINTEF Geometry Tools Core library, version 2.0.1 // // Copyright (C) 2000-2007, 2010 SINTEF ICT, Applied Mathematics, Norway. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., // 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // Contact information: E-mail: tor.dokken@sintef.no // SINTEF ICT, Department of Applied Mathematics, // P.O. Box 124 Blindern, // 0314 Oslo, Norway. // // Other licenses are also available for this software, notably licenses // for: // - Building commercial software. // - Building software whose source code you wish to keep private. //=========================================================================== 00016 #ifndef _BOUNDEDSURFACE_H 00017 #define _BOUNDEDSURFACE_H 00018 00019 00020 #include <boost/smart_ptr.hpp> 00021 #include "GoTools/geometry/ParamSurface.h" 00022 #include "GoTools/geometry/CurveOnSurface.h" 00023 #include "GoTools/geometry/CurveBoundedDomain.h" 00024 #include "GoTools/utils/config.h" 00025 00026 00027 namespace Go 00028 { 00029 00030 class SplineSurface; 00031 00034 class GO_API BoundedSurface : public ParamSurface 00035 { 00036 public: 00037 00039 BoundedSurface(); 00040 00051 BoundedSurface(boost::shared_ptr<ParamSurface> surf, 00052 std::vector<boost::shared_ptr<CurveOnSurface> > loop, 00053 double space_epsilon); 00054 00055 00069 BoundedSurface(boost::shared_ptr<ParamSurface> surf, 00070 std::vector<std::vector<boost::shared_ptr<CurveOnSurface> > > loops, 00071 double space_epsilon); 00072 00090 BoundedSurface(boost::shared_ptr<ParamSurface> surf, 00091 std::vector<std::vector<boost::shared_ptr<CurveOnSurface> > > loops, 00092 std::vector<double> space_epsilons); 00093 00095 BoundedSurface(boost::shared_ptr<ParamSurface> surf, 00096 double space_epsilon); 00097 00099 BoundedSurface(boost::shared_ptr<ParamSurface> surf, 00100 std::vector<CurveLoop>& loops); 00101 00103 virtual ~BoundedSurface(); 00104 00105 00106 // From Streamable 00107 00108 // @afr: These should not be called! 00110 virtual void read (std::istream& is); 00112 virtual void write (std::ostream& os) const; 00113 00114 // From GeomObject 00115 00117 virtual BoundingBox boundingBox() const; 00118 00120 virtual int dimension() const; 00121 00123 virtual ClassType instanceType() const; 00124 00126 static ClassType classType() 00127 { return Class_BoundedSurface; } 00128 00130 virtual BoundedSurface* clone() const 00131 { return new BoundedSurface(*this); } 00132 00134 virtual SplineSurface* asSplineSurface() 00135 { 00136 return surface_->asSplineSurface(); 00137 } 00138 00139 // From ParamSurface 00140 00144 virtual DirectionCone normalCone() const; 00145 00153 virtual DirectionCone tangentCone(bool pardir_is_u) const; 00154 00160 virtual const CurveBoundedDomain& parameterDomain() const; 00161 00167 virtual RectDomain containingDomain() const; 00168 00169 00171 virtual bool inDomain(double u, double v) const; 00172 00173 virtual Point closestInDomain(double u, double v) const; 00174 00180 virtual CurveLoop outerBoundaryLoop(double degenerate_epsilon 00181 = DEFAULT_SPACE_EPSILON) const; 00182 00191 virtual std::vector<CurveLoop> allBoundaryLoops(double degenerate_epsilon 00192 = DEFAULT_SPACE_EPSILON) const; 00193 00201 std::vector<CurveLoop> absolutelyAllBoundaryLoops() const; 00202 00203 00208 virtual void point(Point& pt, double upar, double vpar) const; 00209 00210 00234 virtual void point(std::vector<Point>& pts, 00235 double upar, double vpar, 00236 int derivs, 00237 bool u_from_right = true, 00238 bool v_from_right = true, 00239 double resolution = 1.0e-12) const; 00240 00255 virtual void point(std::vector<Point>& pts, 00256 double upar, double vpar, 00257 int derivs) const; 00258 00259 // using ParamSurface::point; 00264 virtual void normal(Point& n, double upar, double vpar) const; 00265 00268 virtual Point getInternalPoint(double& u, double& v) const; 00269 00280 virtual std::vector<boost::shared_ptr<ParamCurve> > 00281 constParamCurves(double parameter, bool pardir_is_u) const; 00282 00296 virtual std::vector<boost::shared_ptr<ParamSurface> > 00297 subSurfaces(double from_upar, double from_vpar, 00298 double to_upar, double to_vpar, 00299 double fuzzy = DEFAULT_PARAMETER_EPSILON) const; 00300 00319 virtual double nextSegmentVal(int dir, double par, bool forward, double tol) const; 00320 00333 virtual void closestPoint(const Point& pt, 00334 double& clo_u, 00335 double& clo_v, 00336 Point& clo_pt, 00337 double& clo_dist, 00338 double epsilon, 00339 const RectDomain* domain_of_interest = NULL, 00340 double *seed = 0) const; 00341 00342 00345 virtual void closestBoundaryPoint(const Point& pt, 00346 double& clo_u, 00347 double& clo_v, 00348 Point& clo_pt, 00349 double& clo_dist, 00350 double epsilon, 00351 const RectDomain* domain_of_interest = NULL, 00352 double *seed = 0) const; 00353 00376 virtual void getBoundaryInfo(Point& pt1, Point& pt2, 00377 double epsilon, SplineCurve*& cv, 00378 SplineCurve*& crosscv, double knot_tol = 1e-05) const; 00379 00380 00390 void getBoundaryInfo(Point& pt1, Point& pt2, 00391 std::vector<boost::shared_ptr<CurveOnSurface> >& bd_cvs) const; 00392 00394 virtual void turnOrientation(); 00395 00401 virtual void reverseParameterDirection(bool direction_is_u); 00402 00403 // If a segment in a loop in boundary_loops_ is not G1, curve is split. 00404 // Function to be called prior to a topology builder relying on smooth segments. 00405 00412 void makeBoundaryCurvesG1(double kink); 00413 00415 virtual void swapParameterDirection(); 00416 00423 virtual double area(double tol) const; 00424 00431 void setParameterDomain(double u1, double u2, double v1, double v2); 00432 00433 // If a boundary loop is represented as a single curve, it is split into 3 parts. 00434 // Handy tue to current limitations in topology analysator. 00435 00439 void splitSingleLoops(); 00440 00441 // Access functions 00442 00445 boost::shared_ptr<ParamSurface> underlyingSurface() 00446 { return surface_; } 00447 00450 boost::shared_ptr<const ParamSurface> underlyingSurface() const 00451 { return surface_; } 00452 00455 bool hasUnderlyingSpline(boost::shared_ptr<SplineSurface>& srf); 00456 00458 int numberOfLoops() const 00459 { return boundary_loops_.size(); } 00460 00462 boost::shared_ptr<CurveLoop> loop(int idx) 00463 { return boundary_loops_[idx]; } 00464 00475 SplineCurve* constParamCurve(double parameter, bool direction_is_u) const; 00476 00488 virtual bool isDegenerate(bool& b, bool& r, 00489 bool& t, bool& l, double tolerance) const; 00490 00491 00493 virtual void getDegenerateCorners(std::vector<Point>& deg_corners, double tol) const; 00494 00495 virtual void setIterator(IteratorType type) 00496 { 00497 iterator_ = type; 00498 surface_->setIterator(type); 00499 } 00500 00502 virtual bool isIsoTrimmed(double tol) const; 00503 00504 00506 bool orientationIsSet() 00507 { 00508 return (loop_fixed_.size() == boundary_loops_.size()); 00509 } 00510 00511 bool orientationOK() 00512 { 00513 if (loop_fixed_.size() != boundary_loops_.size()) 00514 return false; 00515 for (size_t ki=0; ki<loop_fixed_.size(); ++ki) 00516 if (loop_fixed_[ki]) 00517 return false; 00518 return true; 00519 } 00520 00521 void setOrientationOK() 00522 { 00523 loop_fixed_.resize(boundary_loops_.size()); 00524 std::fill(loop_fixed_.begin(), loop_fixed_.end(), 0); 00525 } 00526 00528 void turnLoopOrientation(int idx); 00529 00534 bool isValid(int& valid_state) const; 00535 00539 bool fixInvalidSurface(double& max_loop_gap); 00540 00544 void analyzeLoops(); 00545 00549 void removeMismatchCurves(double max_tol_mult); 00550 00555 double maxLoopSfDist(int loop_ind, int nmb_seg_samples = 20); 00556 00560 Point getSurfaceParameter(int loop_idx, int cv_idx, double bd_par); 00561 00563 bool simplifyBdLoops(double tol, double ang_tol, double& max_dist); 00564 00567 bool makeUnderlyingSpline(); 00568 00571 bool allIsSpline() const; 00572 00575 BoundedSurface* allSplineCopy() const; 00576 00577 private: 00579 boost::shared_ptr<ParamSurface> surface_; 00580 00584 std::vector<boost::shared_ptr<CurveLoop> > boundary_loops_; 00585 00588 std::vector<int> loop_fixed_; 00589 00590 mutable CurveBoundedDomain domain_; 00591 00592 mutable bool iso_trim_; 00593 mutable double iso_trim_tol_; 00594 00595 // The trim curves should be valid loops. Additionally the first 00596 // element should be the outer ccw loop, all other loops should be 00597 // cw loops lying inside the ccw loop. 00598 int valid_state_; // 0 = not validated (analyze not performed / failed). 00599 // 1 = valid. 00600 // -1 = par & space cv mismatch. 00601 // -2 = par cv(s) missing (required). 00602 // -4 = loop(s) not closed (dir of segments, order, gaps). 00603 // -8 = loops not ordered or direction wrong. 00604 // -15 = -1 -2 -4 -8, i.e. all artifacts/features. 00605 00609 bool fixLoopGaps(double& max_loop_gap, bool analyze); 00610 00618 bool orderBoundaryLoops(bool analyze, 00619 double degenerate_epsilon = DEFAULT_SPACE_EPSILON); 00620 00622 bool parameterCurveMissing(); 00623 00624 // Then we see if the par cv and the space cv match (i.e. if trace 00625 // is the same, as well as direction). 00626 // @@sbr072009 Mismatch in domain and orientation shouldbe handled 00627 // from this class. Missing par cv and mismatch between par & 00628 // space cv should be handled from the outside as it requires more 00629 // machinery. To be implemented! 00630 bool fixParSpaceMismatch(bool analyze, double max_tol_mult, 00631 int nmb_seg_samples); 00632 00633 // We want the boundary curve to be at least c1. To be called from 00634 // public function. 00635 std::vector<boost::shared_ptr<CurveOnSurface> > 00636 splitIntoC1Curves(boost::shared_ptr<CurveOnSurface>& curve, 00637 double space_epsilon, double kink); 00638 00639 // Run through the boundary loops, returning the smallest epsgeo. 00640 double getEpsGeo() const; 00641 00642 // Used to avoid code duplication in two nearly equal 00643 // constructors. 00644 void 00645 constructor_implementation(boost::shared_ptr<ParamSurface> surf, 00646 std::vector<std::vector<boost::shared_ptr<CurveOnSurface> > > 00647 loops, 00648 std::vector<double> space_epsilons); 00649 00650 }; 00651 00652 00653 } // namespace Go 00654 00655 00656 #endif // _BOUNDEDSURFACE_H 00657