BRL-CAD
libbrep_brep_tools.h
Go to the documentation of this file.
1 /* L I B B R E P _ B R E P _ T O O L S . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2013-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup libbrep */
21 /** @{ */
22 /** @file libbrep_brep_tools.h
23  *
24  * Utility routines for working with geometry.
25  */
26 
27 #ifndef LIBBREP_LIBBREP_BREP_TOOLS_H
28 #define LIBBREP_LIBBREP_BREP_TOOLS_H
29 
30 #include "common.h"
31 
32 #include <vector>
33 
34 #include "opennurbs.h"
35 #include "brep.h"
36 
37 
38 /* Directions */
39 #ifndef NE
40 # define NE 1
41 #endif
42 #ifndef NW
43 # define NW 2
44 #endif
45 #ifndef SW
46 # define SW 3
47 #endif
48 #ifndef SE
49 # define SE 4
50 #endif
51 
52 
53 #ifndef BREP_EXPORT
54 # if defined(BREP_DLL_EXPORTS) && defined(BREP_DLL_IMPORTS)
55 # error "Only BREP_DLL_EXPORTS or BREP_DLL_IMPORTS can be defined, not both."
56 # elif defined(BREP_DLL_EXPORTS)
57 # define BREP_EXPORT __declspec(dllexport)
58 # elif defined(BREP_DLL_IMPORTS)
59 # define BREP_EXPORT __declspec(dllimport)
60 # else
61 # define BREP_EXPORT
62 # endif
63 #endif
64 
65 /**
66  \brief Return truthfully whether a value is within a specified epsilon distance from zero.
67 
68  @param val value to be tested
69  @param epsilon distance from zero defining the interval to be treated as "near" zero for the test
70 
71  @return @c true if the value is within the near-zero interval specified by epsilon, @c false otherwise.
72 */
73 BREP_EXPORT
74 bool ON_NearZero(double val, double epsilon);
75 
76 /**
77  \brief Search for a horizontal tangent on the curve between two curve parameters.
78 
79  @param curve curve to be tested
80  @param min minimum curve parameter value
81  @param max maximum curve parameter value
82  @param zero_tol tolerance to use when testing for near-zero values
83 
84  @return t parameter corresponding to the point on the curve with the horizontal tangent.
85 */
86 BREP_EXPORT
87 double ON_Curve_Get_Horizontal_Tangent(const ON_Curve* curve, double min, double max, double zero_tol);
88 
89 /**
90  \brief Search for a vertical tangent on the curve between two curve parameters.
91 
92  @param curve curve to be tested
93  @param min minimum curve parameter value
94  @param max maximum curve parameter value
95  @param zero_tol tolerance to use when testing for near-zero values
96 
97  @return t parameter corresponding to the point on the curve with the vertical tangent.
98 */
99 BREP_EXPORT
100 double ON_Curve_Get_Vertical_Tangent(const ON_Curve* curve, double min, double max, double zero_tol);
101 
102 
103 /**
104  \brief Test whether a curve interval contains one or more horizontal or vertical tangents
105 
106  @param curve ON_Curve to be tested
107  @param ct_min minimum t parameter value of the curve interval to be tested
108  @param ct_max maximum t parameter value of the curve interval to be tested
109  @param t_tol tolerance used to decide when a curve is a line tangent to X or Y axis
110 
111  @return @c 0 if there are no tangent points in the interval, @c 1 if there is a single vertical tangent,
112  @c 2 if there is a single horizontal tangent, and @c 3 if multiple tangents are present.
113 */
114 BREP_EXPORT
115 int ON_Curve_Has_Tangent(const ON_Curve* curve, double ct_min, double ct_max, double t_tol);
116 
117 
118 /**
119  * \verbatim
120  * 3-------------------2
121  * | |
122  * | 6 8 |
123  * | |
124  * V| 4 |
125  * | |
126  * | 5 7 |
127  * | |
128  * 0-------------------1
129  * U
130  * \endverbatim
131  */
132 
133 
134 /**
135  \brief Perform flatness test of surface
136 
137  Determine whether a given surface is flat enough, i.e. it falls
138  beneath our simple flatness constraints. The flatness constraint in
139  this case is a sampling of normals across the surface such that the
140  product of their combined dot products is close to 1.
141 
142  @f[ \prod_{i=1}^{7} n_i \dot n_{i+1} = 1 @f]
143 
144  This code is using a slightly different placement of the interior normal
145  tests as compared to <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.90.7500&rep=rep1&type=pdf">Abert's</a> approach:
146 
147  \verbatim
148  +-------------------+
149  | |
150  | + + |
151  | |
152  V | + |
153  | |
154  | + + |
155  | |
156  +-------------------+
157  U
158  \endverbatim
159 
160 
161  The "+" indicates the normal sample.
162 
163  The frenet frames are stored in the frames arrays according
164  to the following index values:
165 
166  \verbatim
167  3-------------------2
168  | |
169  | 6 8 |
170  | |
171  V | 4 |
172  | |
173  | 5 7 |
174  | |
175  0-------------------1
176  U
177  \endverbatim
178 
179  @param frames Array of 9 frenet frames
180  @param f_tol Flatness tolerance - 0 always evaluates to flat, 1 would be a perfectly flat surface. Generally something in the range 0.8-0.9 should suffice in raytracing subdivision (per <a href="http://www.uni-koblenz.de/~cg/Diplomarbeiten/DA_Oliver_Abert.pdf">Abert, 2005</a>)
181 */
182 BREP_EXPORT
183 bool ON_Surface_IsFlat(ON_Plane *frames, double f_tol);
184 
185 /**
186  \brief Perform flatness test of surface in U only
187 
188  Array index conventions are the same as ::ON_Surface_IsFlat.
189 
190  @param frames Array of 9 frenet frames
191  @param s_tol Straightness tolerance - 0 always evaluates to straight, 1 requires perfect straightness
192 */
193 BREP_EXPORT
194 bool ON_Surface_IsFlat_U(ON_Plane *frames, double f_tol);
195 
196 
197 /**
198  \brief Perform flatness test of surface in V only
199 
200  Array index conventions are the same as ::ON_Surface_IsFlat.
201 
202  @param frames Array of 9 frenet frames
203  @param s_tol Straightness tolerance - 0 always evaluates to straight, 1 requires perfect straightness
204 */
205 BREP_EXPORT
206 bool ON_Surface_IsFlat_V(ON_Plane *frames, double f_tol);
207 
208 
209 /**
210  \brief Perform straightness test of surface
211 
212  The straightness test compares flatness criteria to running product of the tangent vector of
213  the frenet frame projected onto each other tangent in the frame set. Array index conventions
214  are the same as ::ON_Surface_IsFlat.
215 
216  @param frames Array of 9 frenet frames
217  @param s_tol Straightness tolerance - 0 always evaluates to straight, 1 requires perfect straightness
218 */
219 BREP_EXPORT
220 bool ON_Surface_IsStraight(ON_Plane *frames, double s_tol);
221 
222 
223 /**
224  \brief Create a surface based on a subset of a parent surface
225 
226  Create a NURBS surface that corresponds to a subset
227  of an input surface, as defined by UV intervals. The
228  t parameters may be NULL, in which case working surfaces
229  will be created by the function. If supplied, existing
230  surfaces are reused to avoid extra malloc operations
231  and memory usage associated with creating the working
232  surfaces.
233 
234  @param srf parent ON_Surface
235  @param u_val U interval of proposed subsurface
236  @param v_val V interval of proposed subsurface
237  @param t1 surface used during split algorithm
238  @param t2 surface used during split algorithm
239  @param t3 surface used during split algorithm
240  @param t4 surface holding final result of split passes
241  @param[out] result final subsurface - holds *t4 if it was non-NULL as an input, else holds a pointer to the new ON_Surface
242 
243  @return @c true if surface creation is successful or if the subsurface
244  is the same as the parent surface, @c false if one or more split
245  operations failed.
246 */
247 BREP_EXPORT
249  const ON_Surface *srf,
250  ON_Interval *u_val,
251  ON_Interval *v_val,
252  ON_Surface **t1,
253  ON_Surface **t2,
254  ON_Surface **t3,
255  ON_Surface **t4,
256  ON_Surface **result
257  );
258 
259 /**
260  \brief Create four sub-surfaces from a parent surface
261 
262  Create four NURBS surfaces that corresponds to subsets
263  of an input surface, as defined by UV intervals and a
264  point within the U and V intervals.
265 
266  \verbatim
267  *---------------------*
268  | | |
269  | q3 | q2 |
270  | | |
271  V |----------+----------|
272  | | |
273  | q0 | q1 |
274  | | |
275  *---------------------*
276  U
277 
278  + is the point (upt, vpt) that defines the quads
279  * points represent the mins and maxes of the U and V domains
280 
281  \endverbatim
282 
283 
284  @param srf parent ON_Surface
285  @param u U interval of parent surface
286  @param v V interval of parent surface
287  @param upt U interval point for quad definition
288  @param upt U interval point for quad definition
289  @param q0 surface calculated by split algorithm
290  @param q1 surface calculated by split algorithm
291  @param q2 surface calculated by split algorithm
292  @param q3 surface calculated by split algorithm
293 
294  @return @c true if surfaces are successfully created, @c false if one or more split
295  operations failed, the q* containers are not NULL, or the upt,vpt coordinates are
296  not contained within the UV interval.
297 */
298 BREP_EXPORT
300  const ON_Surface *srf,
301  const ON_Interval& u,
302  const ON_Interval& v,
303  double upt,
304  double vpt,
305  ON_Surface **q0,
306  ON_Surface **q1,
307  ON_Surface **q2,
308  ON_Surface **q3
309  );
310 
311 
312 #endif /* LIBBREP_LIBBREP_BREP_TOOLS_H */
313 /** @} */
314 
315 // Local Variables:
316 // tab-width: 8
317 // mode: C++
318 // c-basic-offset: 4
319 // indent-tabs-mode: t
320 // c-file-style: "stroustrup"
321 // End:
322 // ex: shiftwidth=4 tabstop=8
Definition: db_flip.c:35
BREP_EXPORT bool ON_Surface_IsFlat_U(ON_Plane *frames, double f_tol)
Perform flatness test of surface in U only.
Header file for the BRL-CAD common definitions.
BREP_EXPORT bool ON_Surface_SubSurface(const ON_Surface *srf, ON_Interval *u_val, ON_Interval *v_val, ON_Surface **t1, ON_Surface **t2, ON_Surface **t3, ON_Surface **t4, ON_Surface **result)
Create a surface based on a subset of a parent surface.
double ON_Curve_Get_Horizontal_Tangent(const ON_Curve *curve, double min, double max, double zero_tol)
Search for a horizontal tangent on the curve between two curve parameters.
double ON_Curve_Get_Vertical_Tangent(const ON_Curve *curve, double min, double max, double zero_tol)
Search for a vertical tangent on the curve between two curve parameters.
BREP_EXPORT bool ON_Surface_IsFlat_V(ON_Plane *frames, double f_tol)
Perform flatness test of surface in V only.
BREP_EXPORT bool ON_Surface_IsStraight(ON_Plane *frames, double s_tol)
Perform straightness test of surface.
int ON_Curve_Has_Tangent(const ON_Curve *curve, double ct_min, double ct_max, double t_tol)
Test whether a curve interval contains one or more horizontal or vertical tangents.
BREP_EXPORT bool ON_Surface_IsFlat(ON_Plane *frames, double f_tol)
Perform flatness test of surface.
BREP_EXPORT bool ON_Surface_Quad_Split(const ON_Surface *srf, const ON_Interval &u, const ON_Interval &v, double upt, double vpt, ON_Surface **q0, ON_Surface **q1, ON_Surface **q2, ON_Surface **q3)
Create four sub-surfaces from a parent surface.
bool ON_NearZero(double val, double epsilon)
Return truthfully whether a value is within a specified epsilon distance from zero.