1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 ////////////////////////////////////////////////////////////////
18 //
19 //   Definition of virtual parametric surface
20 //
21 ////////////////////////////////////////////////////////////////
22 
23 #if !defined(OPENNURBS_SURFACE_INC_)
24 #define OPENNURBS_SURFACE_INC_
25 
26 class ON_Curve;
27 class ON_NurbsSurface;
28 class ON_SurfaceTree;
29 
30 ////////////////////////////////////////////////////////////////
31 //
32 //   Definition of virtual parametric surface
33 //
34 ////////////////////////////////////////////////////////////////
35 
36 class ON_Mesh;
37 class ON_MeshParameters;
38 class ON_PolyCurve;
39 class ON_CurveProxy;
40 class ON_Surface;
41 
42 class ON_CLASS ON_Surface : public ON_Geometry
43 {
44   ON_OBJECT_DECLARE(ON_Surface);
45 
46 public:
47   // virtual ON_Object::DestroyRuntimeCache override
48   void DestroyRuntimeCache( bool bDelete = true );
49 
50   // pure virtual class for surface objects
51 public:
52 
53   // flags for isoparametric curves
54   // note: odd values are all "x" = constant
55   // and even values > 0 are all "y" = constant
56   // ON_BrepTrim::m_iso uses these flags
57   enum ISO
58   {
59     not_iso = 0, // curve is not an isoparameteric curve
60     x_iso   = 1, // curve is a "x" = constant (vertical) isoparametric
61                  // curve in the interior of the surface's domain
62     y_iso   = 2, // curve is a "y" = constant (horizontal) isoparametric
63                  // curve in the interior of the surface's domain
64     W_iso   = 3, // curve is a "x" = constant isoparametric curve
65                  // along the west side of the surface's domain
66     S_iso   = 4, // curve is a "y" = constant isoparametric curve
67                  // along the south side of the surface's domain
68     E_iso   = 5, // curve is a "x" = constant isoparametric curve
69                  // along the east side of the surface's domain
70     N_iso   = 6, // curve is a "y" = constant isoparametric curve
71                  // along the north side of the surface's domain
72     iso_count = 7
73   };
74 
75 public:
76   ON_Surface();
77   ON_Surface(const ON_Surface&);
78   ON_Surface& operator=(const ON_Surface&);
79   virtual ~ON_Surface();
80 
81   // virtual ON_Object::SizeOf override
82   unsigned int SizeOf() const;
83 
84   // virtual ON_Geometry override
85   bool EvaluatePoint( const class ON_ObjRef& objref, ON_3dPoint& P ) const;
86 
87   /*
88   Description:
89     Get a duplicate of the surface.
90   Returns:
91     A duplicate of the surface.
92   Remarks:
93     The caller must delete the returned surface.
94     For non-ON_SurfaceProxy objects, this simply duplicates the surface using
95     ON_Object::Duplicate.
96     For ON_SurfaceProxy objects, this duplicates the actual proxy surface
97     geometry and, if necessary, transposes the result to that
98     the returned surfaces's parameterization and locus match the proxy surface's.
99   */
100   virtual
101   ON_Surface* DuplicateSurface() const;
102 
103   //////////
104   // override ON_Object::ObjectType() - returns ON::surface_object
105   ON::object_type ObjectType() const;
106 
107 
108   /////////////////////////////
109   //
110   // virtual ON_Geometry functions
111   //
112 
113   /*
114   Description:
115     Overrides virtual ON_Geometry::HasBrepForm and returns true.
116   Result:
117     Returns true.
118   See Also:
119     ON_Brep::Create( ON_Surface&* )
120   */
121   ON_BOOL32 HasBrepForm() const;
122 
123   /*
124   Description:
125     Overrides virtual ON_Geometry::HasBrepForm.
126     Uses ON_Brep::Create( ON_Surface&* ) to create a brep
127     form.  The surface is copied for use in the returned
128     brep.
129   Parameters:
130     brep - [in] if not NULL, brep is used to store the brep
131         form of the surface.
132   Result:
133     Returns a pointer to on ON_Brep or NULL.  If the brep
134     parameter is not NULL, then brep is returned if the
135     surface has a brep form and NULL is returned if the
136     geometry does not have a brep form.
137   Remarks:
138     The caller is responsible for managing the brep memory.
139   */
140   ON_Brep* BrepForm( ON_Brep* brep = NULL ) const;
141 
142   ////////////////////////////////////////////////////////////////////
143   // surface interface
144 
145   ON_BOOL32 GetDomain(
146          int dir,              // 0 gets first parameter, 1 gets second parameter
147          double* t0,
148          double* t1
149          ) const;
150 
151   bool SetDomain(
152     int dir, // 0 sets first parameter's domain, 1 gets second parameter's domain
153     ON_Interval domain
154     );
155 
156   virtual
157   ON_BOOL32 SetDomain(
158     int dir, // 0 sets first parameter's domain, 1 gets second parameter's domain
159     double t0,
160     double t1
161     );
162 
163   virtual
164   ON_Interval Domain(
165     int dir // 0 gets first parameter's domain, 1 gets second parameter's domain
166     ) const = 0;
167 
168   /*
169   Description:
170     Get an estimate of the size of the rectangle that would
171     be created if the 3d surface where flattened into a rectangle.
172   Parameters:
173     width - [out]  (corresponds to the first surface parameter)
174     height - [out] (corresponds to the first surface parameter)
175   Example:
176 
177           // Reparameterize a surface to minimize distortion
178           // in the map from parameter space to 3d.
179           ON_Surface* surf = ...;
180           double width, height;
181           if ( surf->GetSurfaceSize( &width, &height ) )
182           {
183             srf->SetDomain( 0, ON_Interval( 0.0, width ) );
184             srf->SetDomain( 1, ON_Interval( 0.0, height ) );
185           }
186 
187   Returns:
188     true if successful.
189   */
190   virtual
191   ON_BOOL32 GetSurfaceSize(
192       double* width,
193       double* height
194       ) const;
195 
196 
197   virtual
198   int SpanCount(
199     int dir // 0 gets first parameter's domain, 1 gets second parameter's domain
200     ) const = 0; // number of smooth nonempty spans in the parameter direction
201 
202   virtual
203   ON_BOOL32 GetSpanVector( // span "knots"
204         int dir, // 0 gets first parameter's domain, 1 gets second parameter's domain
205         double* span_vector // array of length SpanCount() + 1
206         ) const = 0; //
207 
208   //////////
209   // If t is in the domain of the surface, GetSpanVectorIndex() returns the
210   // span vector index "i" such that span_vector[i] <= t <= span_vector[i+1].
211   // The "side" parameter determines which span is selected when t is at the
212   // end of a span.
213   virtual
214   ON_BOOL32 GetSpanVectorIndex(
215         int dir , // 0 gets first parameter's domain, 1 gets second parameter's domain
216         double t,      // [IN] t = evaluation parameter
217         int side,         // [IN] side 0 = default, -1 = from below, +1 = from above
218         int* span_vector_index,        // [OUT] span vector index
219         ON_Interval* span_interval // [OUT] domain of the span containing "t"
220         ) const;
221 
222   virtual
223   int Degree( // returns maximum algebraic degree of any span
224                   // ( or a good estimate if curve spans are not algebraic )
225     int dir // 0 gets first parameter's domain, 1 gets second parameter's domain
226     ) const = 0;
227 
228   virtual ON_BOOL32 GetParameterTolerance( // returns tminus < tplus: parameters tminus <= s <= tplus
229          int dir,        // 0 gets first parameter, 1 gets second parameter
230          double t,       // t = parameter in domain
231          double* tminus, // tminus
232          double* tplus   // tplus
233          ) const;
234 
235   /*
236   Description:
237     Test a 2d curve to see if it is iso parameteric in the surface's
238     parameter space.
239   Parameters:
240     curve - [in] curve to test
241     curve_domain = [in] optional sub domain of the curve
242   Returns:
243     Isoparametric status of the curve.
244   Remarks:
245     Because it may transpose domains, ON_SurfaceProxy overrides
246     this function.  All other surface classes just use
247     the base class implementation.
248   */
249   virtual
250   ISO IsIsoparametric(
251         const ON_Curve& curve,
252         const ON_Interval* curve_domain = NULL
253         ) const;
254 
255   /*
256   Description:
257     Test a 2d bounding box to see if it is iso parameteric in the surface's
258     parameter space.
259   Parameters:
260     bbox - [in] bounding box to test
261   Returns:
262     Isoparametric status of the bounding box.
263   Remarks:
264     Because it may transpose domains, ON_SurfaceProxy overrides
265     this function.  All other surface classes just use
266     the base class implementation.
267   */
268   virtual
269   ISO IsIsoparametric(
270         const ON_BoundingBox& bbox
271         ) const;
272 
273   /*
274   Description:
275     Test a surface to see if it is planar.
276   Parameters:
277     plane - [out] if not NULL and true is returned,
278                   the plane parameters are filled in.
279     tolerance - [in] tolerance to use when checking
280   Returns:
281     true if there is a plane such that the maximum distance from
282     the surface to the plane is <= tolerance.
283   */
284   virtual
285   ON_BOOL32 IsPlanar(
286         ON_Plane* plane = NULL,
287         double tolerance = ON_ZERO_TOLERANCE
288         ) const;
289 
290   /*
291   Description:
292     Determine if the surface is a portion of a sphere.
293   Parameters:
294     sphere - [out] if not NULL and true is returned,
295       then the sphere definition is returned.
296     tolerance - [in]
297       tolerance to use when checking
298   Returns:
299     True if the surface is a portion of a sphere.
300   */
301   bool IsSphere(
302         ON_Sphere* sphere = NULL,
303         double tolerance = ON_ZERO_TOLERANCE
304         ) const;
305 
306   /*
307   Description:
308     Determine if the surface is a portion of a cylinder.
309   Parameters:
310     cylinder - [out] if not NULL and true is returned,
311       then the cylinder definition is returned.
312     tolerance - [in]
313       tolerance to use when checking
314   Returns:
315     True if the surface is a portion of a cylinder.
316   */
317   bool IsCylinder(
318         ON_Cylinder* cylinder = NULL,
319         double tolerance = ON_ZERO_TOLERANCE
320         ) const;
321 
322   /*
323   Description:
324     Determine if the surface is a portion of a cone.
325   Parameters:
326     cone - [out] if not NULL and true is returned,
327       then the cone definition is returned.
328     tolerance - [in]
329       tolerance to use when checking
330   Returns:
331     True if the surface is a portion of a cone.
332   */
333   bool IsCone(
334         ON_Cone* cone = NULL,
335         double tolerance = ON_ZERO_TOLERANCE
336         ) const;
337 
338   /*
339   Description:
340     Determine if the surface is a portion of a torus.
341   Parameters:
342     torus - [out] if not NULL and true is returned,
343       then the torus definition is returned.
344     tolerance - [in]
345       tolerance to use when checking
346   Returns:
347     True if the surface is a portion of a torus.
348   */
349   bool IsTorus(
350         ON_Torus* torus = NULL,
351         double tolerance = ON_ZERO_TOLERANCE
352         ) const;
353 
354   virtual
355   ON_BOOL32 IsClosed(   // true if surface is closed in direction
356         int        // dir  0 = "s", 1 = "t"
357         ) const;
358 
359   virtual
360   ON_BOOL32 IsPeriodic( // true if surface is periodic in direction (default is false)
361         int        // dir  0 = "s", 1 = "t"
362         ) const;
363 
364   virtual
365   ON_BOOL32 IsSingular( // true if surface side is collapsed to a point
366         int        // side of parameter space to test
367                    // 0 = south, 1 = east, 2 = north, 3 = west
368         ) const;
369 
370   /*
371   Returns:
372     True if the surface defines a solid, like a sphere or torus.
373     False if the surface does not define a solid, like a plane or cone.
374   */
375   bool IsSolid() const;
376 
377   /*
378   Description:
379     Test if a surface parameter value is at a singularity.
380   Parameters:
381     s - [in] surface parameter to test
382     t - [in] surface parameter to test
383     bExact - [in] if true, test if s,t is exactly at a singularity
384       if false, test if close enough to cause numerical problems.
385   Returns:
386     true if surface is singular at (s,t)
387   */
388   bool IsAtSingularity(
389     double s,
390     double t,
391     bool bExact = true
392     ) const;
393 
394   /*
395   Description:
396     Test if a surface parameter value is at a seam.
397   Parameters:
398     s - [in] surface parameter to test
399     t - [in] surface parameter to test
400   Returns:
401     0 if not a seam,
402     1 if s == Domain(0)[i] and srf(s, t) == srf(Domain(0)[1-i], t)
403     2 if t == Domain(1)[i] and srf(s, t) == srf(s, Domain(1)[1-i])
404     3 if 1 and 2 are true.
405   */
406   int IsAtSeam(
407     double s,
408     double t
409     ) const;
410 
411   /*
412   Description:
413     Search for a derivatitive, tangent, or curvature
414     discontinuity.
415   Parameters:
416     dir - [in] If 0, then "u" parameter is checked.  If 1, then
417                the "v" parameter is checked.
418     c - [in] type of continity to test for.
419     t0 - [in] Search begins at t0. If there is a discontinuity
420               at t0, it will be ignored.  This makes it
421               possible to repeatedly call GetNextDiscontinuity
422               and step through the discontinuities.
423     t1 - [in] (t0 != t1)  If there is a discontinuity at t1 is
424               will be ingored unless c is a locus discontinuity
425               type and t1 is at the start or end of the curve.
426     t - [out] if a discontinuity is found, then *t reports the
427           parameter at the discontinuity.
428     hint - [in/out] if GetNextDiscontinuity will be called
429        repeatedly, passing a "hint" with initial value *hint=0
430        will increase the speed of the search.
431     dtype - [out] if not NULL, *dtype reports the kind of
432         discontinuity found at *t.  A value of 1 means the first
433         derivative or unit tangent was discontinuous.  A value
434         of 2 means the second derivative or curvature was
435         discontinuous.  A value of 0 means teh curve is not
436         closed, a locus discontinuity test was applied, and
437         t1 is at the start of end of the curve.
438     cos_angle_tolerance - [in] default = cos(1 degree) Used only
439         when c is ON::G1_continuous or ON::G2_continuous.  If the
440         cosine of the angle between two tangent vectors is
441         <= cos_angle_tolerance, then a G1 discontinuity is reported.
442     curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used
443         only when c is ON::G2_continuous.  If K0 and K1 are
444         curvatures evaluated from above and below and
445         |K0 - K1| > curvature_tolerance, then a curvature
446         discontinuity is reported.
447   Returns:
448     Parametric continuity tests c = (C0_continuous, ..., G2_continuous):
449 
450       true if a parametric discontinuity was found strictly
451       between t0 and t1. Note well that all curves are
452       parametrically continuous at the ends of their domains.
453 
454     Locus continuity tests c = (C0_locus_continuous, ...,G2_locus_continuous):
455 
456       true if a locus discontinuity was found strictly between
457       t0 and t1 or at t1 is the at the end of a curve.
458       Note well that all open curves (IsClosed()=false) are locus
459       discontinuous at the ends of their domains.  All closed
460       curves (IsClosed()=true) are at least C0_locus_continuous at
461       the ends of their domains.
462   */
463   virtual
464   bool GetNextDiscontinuity(
465                   int dir,
466                   ON::continuity c,
467                   double t0,
468                   double t1,
469                   double* t,
470                   int* hint=NULL,
471                   int* dtype=NULL,
472                   double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE,
473                   double curvature_tolerance=ON_SQRT_EPSILON
474                   ) const;
475 
476   /*
477   Description:
478     Test continuity at a surface parameter value.
479   Parameters:
480     c - [in] continuity to test for
481     s - [in] surface parameter to test
482     t - [in] surface parameter to test
483     hint - [in] evaluation hint
484     point_tolerance - [in] if the distance between two points is
485         greater than point_tolerance, then the surface is not C0.
486     d1_tolerance - [in] if the difference between two first derivatives is
487         greater than d1_tolerance, then the surface is not C1.
488     d2_tolerance - [in] if the difference between two second derivatives is
489         greater than d2_tolerance, then the surface is not C2.
490     cos_angle_tolerance - [in] default = cos(1 degree) Used only when
491         c is ON::G1_continuous or ON::G2_continuous.  If the cosine
492         of the angle between two normal vectors
493         is <= cos_angle_tolerance, then a G1 discontinuity is reported.
494     curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used only when
495         c is ON::G2_continuous.  If K0 and K1 are curvatures evaluated
496         from above and below and |K0 - K1| > curvature_tolerance,
497         then a curvature discontinuity is reported.
498   Returns:
499     true if the surface has at least the c type continuity at the parameter t.
500   */
501   virtual
502   bool IsContinuous(
503     ON::continuity c,
504     double s,
505     double t,
506     int* hint = NULL,
507     double point_tolerance=ON_ZERO_TOLERANCE,
508     double d1_tolerance=ON_ZERO_TOLERANCE,
509     double d2_tolerance=ON_ZERO_TOLERANCE,
510     double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE,
511     double curvature_tolerance=ON_SQRT_EPSILON
512     ) const;
513 
514   virtual
515   ON_BOOL32 Reverse(  // reverse parameterizatrion, Domain changes from [a,b] to [-b,-a]
516     int // dir  0 = "s", 1 = "t"
517     ) = 0;
518 
519   virtual
520   ON_BOOL32 Transpose() = 0; // transpose surface parameterization (swap "s" and "t")
521 
522   // simple evaluation interface - no error handling
523   ON_3dPoint  PointAt( double, double ) const;
524   ON_3dVector NormalAt( double, double ) const;
525   ON_BOOL32 FrameAt( double u, double v, ON_Plane& frame) const;
526 
527   ON_BOOL32 EvPoint( // returns false if unable to evaluate
528          double u, double v,   // evaluation parameters
529          ON_3dPoint& point,    // returns value of surface
530          int quadrant = 0,     // optional - determines which side to evaluate from
531                                //         0 = default
532                                //         1 from NE quadrant
533                                //         2 from NW quadrant
534                                //         3 from SW quadrant
535                                //         4 from SE quadrant
536          int* hint = 0         // optional - evaluation hint (int[2]) used to speed
537                                //            repeated evaluations
538          ) const;
539 
540   ON_BOOL32 Ev1Der( // returns false if unable to evaluate
541          double u, double v,   // evaluation parameters (s,t)
542          ON_3dPoint& point,    // returns value of surface
543          ON_3dVector& du,      // first partial derivatives (Ds)
544          ON_3dVector& dv,      // (Dt)
545          int quadrant = 0,     // optional - determines which side to evaluate from
546                                //         0 = default
547                                //         1 from NE quadrant
548                                //         2 from NW quadrant
549                                //         3 from SW quadrant
550                                //         4 from SE quadrant
551          int* hint = 0         // optional - evaluation hint (int[2]) used to speed
552                                //            repeated evaluations
553          ) const;
554 
555   ON_BOOL32 Ev2Der( // returns false if unable to evaluate
556          double u, double v,   // evaluation parameters (s,t)
557          ON_3dPoint& point,    // returns value of surface
558          ON_3dVector& du,      // first partial derivatives (Ds)
559          ON_3dVector& dv,      // (Dt)
560          ON_3dVector& duu,     // second partial derivatives (Dss)
561          ON_3dVector& duv,     // (Dst)
562          ON_3dVector& dvv,     // (Dtt)
563          int quadrant= 0,      // optional - determines which side to evaluate from
564                                //         0 = default
565                                //         1 from NE quadrant
566                                //         2 from NW quadrant
567                                //         3 from SW quadrant
568                                //         4 from SE quadrant
569          int* hint = 0         // optional - evaluation hint (int[2]) used to speed
570                                //            repeated evaluations
571          ) const;
572 
573   ON_BOOL32 EvNormal( // returns false if unable to evaluate
574          double u, double v,   // evaluation parameters (s,t)
575          ON_3dPoint& point,    // returns value of surface
576          ON_3dVector& normal,  // unit normal
577          int quadrant = 0,     // optional - determines which side to evaluate from
578                                //         0 = default
579                                //         1 from NE quadrant
580                                //         2 from NW quadrant
581                                //         3 from SW quadrant
582                                //         4 from SE quadrant
583          int* hint = 0         // optional - evaluation hint (int[2]) used to speed
584                                //            repeated evaluations
585          ) const;
586 
587   ON_BOOL32 EvNormal( // returns false if unable to evaluate
588          double u, double v,   // evaluation parameters (s,t)
589          ON_3dVector& normal,  // unit normal
590          int quadrant = 0,     // optional - determines which side to evaluate from
591                                //         0 = default
592                                //         1 from NE quadrant
593                                //         2 from NW quadrant
594                                //         3 from SW quadrant
595                                //         4 from SE quadrant
596          int* hint = 0         // optional - evaluation hint (int[2]) used to speed
597                                //            repeated evaluations
598          ) const;
599 
600   ON_BOOL32 EvNormal( // returns false if unable to evaluate
601          double u, double v,   // evaluation parameters (s,t)
602          ON_3dPoint& point,    // returns value of surface
603          ON_3dVector& du,      // first partial derivatives (Ds)
604          ON_3dVector& dv,      // (Dt)
605          ON_3dVector& normal,  // unit normal
606          int = 0,              // optional - determines which side to evaluate from
607                                //         0 = default
608                                //         1 from NE quadrant
609                                //         2 from NW quadrant
610                                //         3 from SW quadrant
611                                //         4 from SE quadrant
612          int* = 0              // optional - evaluation hint (int[2]) used to speed
613                                //            repeated evaluations
614          ) const;
615 
616   // work horse evaluator
617   virtual
618   ON_BOOL32 Evaluate( // returns false if unable to evaluate
619          double u, double v,   // evaluation parameters
620          int num_der,          // number of derivatives (>=0)
621          int array_stride,     // array stride (>=Dimension())
622          double* der_array,    // array of length stride*(ndir+1)*(ndir+2)/2
623          int quadrant = 0,     // optional - determines which quadrant to evaluate from
624                                //         0 = default
625                                //         1 from NE quadrant
626                                //         2 from NW quadrant
627                                //         3 from SW quadrant
628                                //         4 from SE quadrant
629          int* hint = 0         // optional - evaluation hint (int[2]) used to speed
630                                //            repeated evaluations
631          ) const = 0;
632 
633   /*
634   Description:
635     Get isoparametric curve.
636   Parameters:
637     dir - [in] 0 first parameter varies and second parameter is constant
638                  e.g., point on IsoCurve(0,c) at t is srf(t,c)
639                  This is a horizontal line from left to right
640                1 first parameter is constant and second parameter varies
641                  e.g., point on IsoCurve(1,c) at t is srf(c,t
642                  This is a vertical line from bottom to top
643 
644     c - [in] value of constant parameter
645   Returns:
646     Isoparametric curve.
647   Remarks:
648     In this function "dir" indicates which direction the resulting
649     curve runs.  0: horizontal, 1: vertical
650     In the other ON_Surface functions that take a "dir"
651     argument, "dir" indicates if "c" is a "u" or "v" parameter.
652   */
653   virtual
654   ON_Curve* IsoCurve(
655          int dir,
656          double c
657          ) const;
658 
659   /*
660   Description:
661     Removes the portions of the surface outside of the specified interval.
662 
663   Parameters:
664     dir - [in] 0  The domain specifies an sub-interval of Domain(0)
665                   (the first surface parameter).
666                1  The domain specifies an sub-interval of Domain(1)
667                   (the second surface parameter).
668     domain - [in] interval of the surface to keep. If dir is 0, then
669         the portions of the surface with parameters (s,t) satisfying
670         s < Domain(0).Min() or s > Domain(0).Max() are trimmed away.
671         If dir is 1, then the portions of the surface with parameters
672         (s,t) satisfying t < Domain(1).Min() or t > Domain(1).Max()
673         are trimmed away.
674   */
675   virtual
676   ON_BOOL32 Trim(
677          int dir,
678          const ON_Interval& domain
679          );
680 
681   /*
682    Description:
683      Pure virtual function. Default returns false.
684      Where possible, analytically extends surface to include domain.
685    Parameters:
686      dir - [in] 0  new Domain(0) will include domain.
687                    (the first surface parameter).
688                 1  new Domain(1) will include domain.
689                    (the second surface parameter).
690      domain - [in] if domain is not included in surface domain,
691      surface will be extended so that its domain includes domain.
692      Will not work if surface is closed in direction dir.
693      Original surface is identical to the restriction of the
694      resulting surface to the original surface domain,
695    Returns:
696      true if successful.
697      */
698   virtual
699   bool Extend(
700     int dir,
701     const ON_Interval& domain
702     );
703 
704 
705   /*
706   Description:
707     Splits (divides) the surface into two parts at the
708     specified parameter.
709 
710   Parameters:
711     dir - [in] 0  The surface is split vertically.  The "west" side
712                   is returned in "west_or_south_side" and the "east"
713                   side is returned in "east_or_north_side".
714                1  The surface is split horizontally.  The "south" side
715                   is returned in "west_or_south_side" and the "north"
716                   side is returned in "east_or_north_side".
717     c - [in] value of constant parameter in interval returned
718                by Domain(dir)
719     west_or_south_side - [out] west/south portion of surface returned here
720     east_or_north_side - [out] east/north portion of surface returned here
721 
722   Example:
723 
724           ON_NurbsSurface srf = ...;
725           int dir = 1;
726           ON_NurbsSurface* south_side = 0;
727           ON_NurbsSurface* north_side = 0;
728           srf.Split( dir, srf.Domain(dir).Mid() south_side, north_side );
729 
730   */
731   virtual
732   ON_BOOL32 Split(
733          int dir,
734          double c,
735          ON_Surface*& west_or_south_side,
736          ON_Surface*& east_or_north_side
737          ) const;
738 
739   /*
740   Description:
741     Get a NURBS surface representation of this surface.
742   Parameters:
743     nurbs_surface - [out] NURBS representation returned here
744     tolerance - [in] tolerance to use when creating NURBS
745         representation.
746     s_subdomain - [in] if not NULL, then the NURBS representation
747         for this portion of the surface is returned.
748     t_subdomain - [in] if not NULL, then the NURBS representation
749         for this portion of the surface is returned.
750   Returns:
751     0   unable to create NURBS representation
752         with desired accuracy.
753     1   success - returned NURBS parameterization
754         matches the surface's to wthe desired accuracy
755     2   success - returned NURBS point locus matches
756         the surface's to the desired accuracy and the
757         domain of the NURBS surface is correct.  On
758         However, This surface's parameterization and
759         the NURBS surface parameterization may not
760         match to the desired accuracy.  This situation
761         happens when getting NURBS representations of
762         surfaces that have a transendental parameterization
763         like spheres, cylinders, and cones.
764   Remarks:
765     This is a low-level virtual function.  If you do not need
766     the parameterization information provided by the return code,
767     then ON_Surface::NurbsSurface may be easier to use.
768   See Also:
769     ON_Surface::NurbsSurface
770   */
771   virtual
772   int GetNurbForm(
773         ON_NurbsSurface& nurbs_surface,
774         double tolerance = 0.0
775         ) const;
776 
777 
778   /*
779   Description:
780     Is there a NURBS surface representation of this surface.
781   Parameters:
782   Returns:
783     0   unable to create NURBS representation
784         with desired accuracy.
785     1   success - NURBS parameterization
786         matches the surface's
787     2   success - NURBS point locus matches
788         the surface's and the
789         domain of the NURBS surface is correct.
790         However, This surface's parameterization and
791         the NURBS surface parameterization may not
792         match.  This situation
793         happens when getting NURBS representations of
794         surfaces that have a transendental parameterization
795         like spheres, cylinders, and cones.
796   Remarks:
797     This is a low-level virtual function.
798   See Also:
799     ON_Surface::GetNurbForm
800     ON_Surface::NurbsSurface
801   */
802   virtual
803   int HasNurbForm() const;
804 
805   // Description:
806   //   Get a NURBS surface representation of this surface.
807   // Parameters:
808   //   pNurbsSurface - [in/out] if not NULL, this pNurbsSurface
809   //   will be used to store the NURBS representation
810   //   of the surface and will be returned.
811   //   tolerance - [in] tolerance to use when creating NURBS
812   //       surface representation.
813   //   s_subdomain - [in] if not NULL, then the NURBS representation
814   //       for this portion of the surface is returned.
815   //   t_subdomain - [in] if not NULL, then the NURBS representation
816   //       for this portion of the surface is returned.
817   // Returns:
818   //   NULL or a NURBS representation of the surface.
819   // Remarks:
820   //   See ON_Surface::GetNurbForm for important details about
821   //   the NURBS surface parameterization.
822   // See Also:
823   //   ON_Surface::GetNurbForm
824   ON_NurbsSurface* NurbsSurface(
825         ON_NurbsSurface* pNurbsSurface = NULL,
826         double tolerance = 0.0,
827         const ON_Interval* s_subdomain = NULL,
828         const ON_Interval* t_subdomain = NULL
829         ) const;
830 
831   virtual
832   bool GetSurfaceParameterFromNurbFormParameter(
833         double nurbs_s, double nurbs_t,
834         double* surface_s, double* surface_t
835         ) const;
836 
837   virtual
838   bool GetNurbFormParameterFromSurfaceParameter(
839         double surface_s, double surface_t,
840         double* nurbs_s,  double* nurbs_t
841         ) const;
842 
843 
844   // If the geometry surface is modified in any way, then
845   // call DestroySurfaceTree().
846   void DestroySurfaceTree();
847 };
848 
849 class ON_CLASS ON_SurfaceProperties
850 {
851   // Surface properties
852 public:
853   // The constructor sets all fields to zero.
854   ON_SurfaceProperties();
855 
856   /*
857   Parameters:
858     surface - [in]
859       If surface is not null, then it is used to set the surface properties.
860       If surface is null, then all surface properties are set to to zero.
861   Remarks:
862     Does not modify the value of m_tag.
863   */
864   void Set( const ON_Surface* surface );
865 
866   bool m_bIsSet;           // True if Set() has been callled with a non-null surface.
867 
868   bool m_bHasSingularity;  // true if at least one m_bSingular[] setting is true.
869   bool m_bIsSingular[4];   // m_bSingular[i] = ON_Surface::IsSingular(i)
870 
871   bool m_bHasSeam;         // true if at least one m_bClosed[] setting is true.
872   bool m_bIsClosed[2];     // m_bClosed[i] = ON_Surface::IsClosed(i)
873 
874 private:
875   bool m_bReserved[7];
876 
877 public:
878   ON_Interval m_domain[2]; // m_domain[i] = ON_Surface.Domain(i)
879 
880 private:
881   unsigned char m_reserved[16];
882 
883 public:
884   // Last pointer passed to ON_SurfaceProperties::Set().
885   const ON_Surface* m_surface;
886 
887   // The constructor sets this value to zero.
888   // Nothing in opennurbs modifies or uses this value.
889   ON__INT_PTR m_tag;
890 };
891 
892 #if defined(ON_DLL_TEMPLATE)
893 // This stuff is here because of a limitation in the way Microsoft
894 // handles templates and DLLs.  See Microsoft's knowledge base
895 // article ID Q168958 for details.
896 #pragma warning( push )
897 #pragma warning( disable : 4231 )
898 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Surface*>;
899 #pragma warning( pop )
900 #endif
901 
902 class ON_CLASS ON_SurfaceArray : public ON_SimpleArray<ON_Surface*>
903 {
904 public:
905   ON_SurfaceArray( int = 0 );
906   ~ON_SurfaceArray();
907 
908   ON_BOOL32 Write( ON_BinaryArchive& ) const;
909   ON_BOOL32 Read( ON_BinaryArchive& );
910 
911   void Destroy(); // deletes surfaces in array and sets count to 0
912 
913   ON_BOOL32 Duplicate( ON_SurfaceArray& ) const; // operator= copies the pointer values
914                                      // duplicate copies the surfaces themselves
915 };
916 
917 
918 #endif
919