Branch data Line data Source code
1 : : //-------------------------------------------------------------------------
2 : : // Filename : SplitSurfaceTool.hpp
3 : : //
4 : : // Purpose : Split a single or chain of surfaces (e.g., split a fillet
5 : : // down the middle so that a mesh sweep can occur, or split
6 : : // across a surface). Used by the "split surface" commands.
7 : : //
8 : : // Special Notes :
9 : : //
10 : : // Creator : Steve Storm
11 : : //
12 : : // Creation Date : 10/06/2002
13 : : //-------------------------------------------------------------------------
14 : :
15 : : #ifndef SPLITSURFACETOOL_HPP
16 : : #define SPLITSURFACETOOL_HPP
17 : :
18 : : #include "CubitDefines.h"
19 : : #include "RefEdge.hpp"
20 : : #include "RefVertex.hpp"
21 : : #include "CoEdge.hpp"
22 : : class Cubit2DPoint;
23 : : class RefVertex;
24 : : class RefEdge;
25 : : class RefFace;
26 : : class TDSplitSurface;
27 : : //class Curve;
28 : : class GeometryModifyEngine;
29 : :
30 : : template <class X> class DLIList;
31 : :
32 : : //! Tool class for splitting surfaces.
33 : : class CUBIT_GEOM_EXPORT SplitSurfaceTool
34 : : {
35 : :
36 : : public:
37 : :
38 : : SplitSurfaceTool();
39 [ # # ][ # # ]: 0 : ~SplitSurfaceTool(){}
40 : :
41 : : //! Preview function for simple surface splitting. Temporary Curves are
42 : : //! created on the RefFace and displayed. The curves are created from
43 : : //! the input vec_lists (straight lines, arcs or splines). The input
44 : : //! locations are the original input locations from the user, which are
45 : : //! displayed as well as the Curves. The clear_previous_previews flag
46 : : //! controls whether previous previews are cleared from the graphics
47 : : //! window.
48 : : CubitStatus preview( RefFace *ref_face_ptr,
49 : : DLIList<CubitVector*> &locations,
50 : : DLIList<DLIList<CubitVector*>*> &vec_lists,
51 : : CubitBoolean create_ref_edges_flg,
52 : : CubitBoolean clear_previous_previews = CUBIT_TRUE );
53 : :
54 : : //! Overloaded preview function to handle multiple surfaces (see above).
55 : : CubitStatus preview( DLIList<RefFace*> &ref_face_list,
56 : : DLIList<CubitVector*> &locations,
57 : : DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists,
58 : : CubitBoolean create_ref_edges_flg,
59 : : CubitBoolean clear_previous_previews = CUBIT_TRUE );
60 : :
61 : : //@{
62 : : //! Calculate the split curves based on the surface and user parameters.
63 : : //! The curves are created from the input vec_lists (straight lines,
64 : : //! arcs or splines). The input locations are the original input locations
65 : : //! from the user.
66 : : CubitStatus calculate_split_curves( RefFace *ref_face_ptr,
67 : : DLIList<DLIList<CubitVector*>*> &vec_lists,
68 : : DLIList<Curve*> &curve_list );
69 : : CubitStatus calculate_split_curves( Surface *surf_ptr,
70 : : DLIList<DLIList<CubitVector*>*> &vec_lists,
71 : : DLIList<Curve*> &curve_list );
72 : : //@}
73 : :
74 : : //! Calculates the curves to split a chain of surfaces.
75 : : //! ref_face_list - chain of surfaces to split. Can be given in any order
76 : : //! as long as they are connected. Can be a continuous
77 : : //! loop of surfaces. If a single surface is given, by
78 : : //! default it will be split along the narrowest aspect
79 : : //! ratio of the surface (i.e., along a fillet). Periodic
80 : : //! surfaces are not handled.
81 : : //! num_segs - the number of segments to create (must be >= 2 );
82 : : //! fraction - the fraction along the surfaces to split, not valid if
83 : : //! num_segs > 2. This value is not used if a distance is
84 : : //! specified instead.
85 : : //! distance - if 2 segments, allow the split to be at a user specified
86 : : //! distance across the surface. Specify -1.0 to use the
87 : : //! fraction instead.
88 : : //! from_curve_ptr - (OPTIONAL) if user specified a fraction or distance,
89 : : //! orient from this curve. If not specified, a default
90 : : //! is chosen automatically.
91 : : //! corner_vertex_list - (OPTIONAL) the user can specify the corners of the,
92 : : //! chain, typically if the detected corners are incorrect.
93 : : //! The split direction is from corners 0-1 to
94 : : //! corners 2-3 (for single surfaces, if not overridden
95 : : //! by curve_dir_ptr).
96 : : //! through_vertex_list - (OPTIONAL) user specifies forced vertices for the split
97 : : //! to run through (on curves). Not valid with
98 : : //! more than 2 segments.
99 : : //! curve_dir_ptr - (OPTIONAL) for single surfaces, the direction of split can be
100 : : //! specified by picking a curve on the surface.
101 : : //! preview_flg - if CUBIT_TRUE, just draw the curves that will be used to split
102 : : //! instead of actually splitting.
103 : : //! create_ref_edges_flg - valid only if preview_flg=CUBIT_TRUE. If CUBIT_TRUE,
104 : : //! create RefEdges *instead* of splitting.
105 : : //! Note this function also utilizes five additional settings which are
106 : : //! supplied through the set_tolerance, set_parametric_flg,
107 : : //! set_auto_detect_triangles_flg, set_side_angle_threshold,
108 : : //! and set_point_angle_threshold functions.
109 : : CubitStatus calculate_split_curves( DLIList<RefFace*> &ref_face_list,
110 : : int num_segs, double fraction,
111 : : double distance, RefEdge *from_curve_ptr,
112 : : DLIList<RefVertex*> &corner_vertex_list,
113 : : DLIList<RefVertex*> &through_vertex_list,
114 : : RefEdge *curve_dir_ptr,
115 : : CubitBoolean preview_flg,
116 : : CubitBoolean create_ref_edges_flg,
117 : : CubitBoolean just_curves_flg,
118 : : DLIList<DLIList<Curve*>*> &curve_lists_list );
119 : :
120 : : //! Split function for simple surface splitting. Temporary Curves are
121 : : //! created on the RefFace and used to split the RefFace. The curves are
122 : : //! created from the input vec_lists (straight lines, arcs or splines).
123 : : //! The input locations are the original input locations from the user,
124 : : //! which are displayed for user reference.
125 : : CubitStatus split_surface( RefFace *ref_face_ptr,
126 : : DLIList<DLIList<CubitVector*>*> &vec_lists );
127 : :
128 : : //! Overloaded split function to allow multiple surfaces to be split (see above).
129 : : CubitStatus split_surface( DLIList<RefFace*> &ref_face_list,
130 : : DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists );
131 : :
132 : : //! Split function for simple surface splitting using a list of predefined curves
133 : : CubitStatus split_surface( RefFace *ref_face_ptr, DLIList<Curve*> &curve_list);
134 : :
135 : : //! Splits the chain of surfaces.
136 : : //! ref_face_list - chain of surfaces to split. Can be given in any order
137 : : //! as long as they are connected. Can be a continuous
138 : : //! loop of surfaces. If a single surface is given, by
139 : : //! default it will be split along the narrowest aspect
140 : : //! ratio of the surface (i.e., along a fillet). Periodic
141 : : //! surfaces are not handled.
142 : : //! num_segs - the number of segments to create (must be >= 2 );
143 : : //! fraction - the fraction along the surfaces to split, not valid if
144 : : //! num_segs > 2. This value is not used if a distance is
145 : : //! specified instead.
146 : : //! distance - if 2 segments, allow the split to be at a user specified
147 : : //! distance across the surface. Specify -1.0 to use the
148 : : //! fraction instead.
149 : : //! from_curve_ptr - (OPTIONAL) if user specified a fraction or distance,
150 : : //! orient from this curve. If not specified, a default
151 : : //! is chosen automatically.
152 : : //! corner_vertex_list - (OPTIONAL) the user can specify the corners of the,
153 : : //! chain, typically if the detected corners are incorrect.
154 : : //! The split direction is from corners 0-1 to
155 : : //! corners 2-3 (for single surfaces, if not overridden
156 : : //! by curve_dir_ptr).
157 : : //! through_vertex_list - (OPTIONAL) user specifies forced vertices for the split
158 : : //! to run through (on curves). Not valid with
159 : : //! more than 2 segments.
160 : : //! curve_dir_ptr - (OPTIONAL) for single surfaces, the direction of split can be
161 : : //! specified by picking a curve on the surface.
162 : : //! preview_flg - if CUBIT_TRUE, just draw the curves that will be used to split
163 : : //! instead of actually splitting.
164 : : //! create_ref_edges_flg - valid only if preview_flg=CUBIT_TRUE. If CUBIT_TRUE,
165 : : //! create RefEdges *instead* of splitting.
166 : : //! Note this function also utilizes five additional settings which are
167 : : //! supplied through the set_tolerance, set_parametric_flg,
168 : : //! set_auto_detect_triangles_flg, set_side_angle_threshold,
169 : : //! and set_point_angle_threshold functions.
170 : : CubitStatus split_surfaces( DLIList<RefFace*> &ref_face_list,
171 : : int num_segs,
172 : : double fraction,
173 : : double distance,
174 : : RefEdge *from_curve_ptr,
175 : : DLIList<RefVertex*> &corner_vertex_list,
176 : : DLIList<RefVertex*> &through_vertex_list,
177 : : RefEdge *curve_dir_ptr = NULL,
178 : : CubitBoolean preview_flg = CUBIT_FALSE,
179 : : CubitBoolean create_ref_edges_flg = CUBIT_FALSE );
180 : :
181 : : //! Same as above except this method simply returns a list of lists of
182 : : //! Curves (one list per input RefFace). This method is intended for
183 : : //! use by a programmer (rather than a user from GeometryCommands).
184 : : //! Note it is the calling functions responsibility to free the memory
185 : : //! allocated in curve_lists_list, as well as the Curves (note this can
186 : : //! be accomplished with the function free_curves_lists).
187 : : CubitStatus split_surfaces( DLIList<RefFace*> &ref_face_list,
188 : : int num_segs,
189 : : double fraction,
190 : : double distance,
191 : : RefEdge *from_curve_ptr,
192 : : DLIList<RefVertex*> &corner_vertex_list,
193 : : DLIList<RefVertex*> &through_vertex_list,
194 : : RefEdge *curve_dir_ptr,
195 : : DLIList<DLIList<Curve*>*> &curve_lists_list );
196 : :
197 : : //! Same as above except this method simply returns a simple list of Curves.
198 : : CubitStatus split_surfaces( DLIList<RefFace*> &ref_face_list,
199 : : int num_segs,
200 : : double fraction,
201 : : double distance,
202 : : RefEdge *from_curve_ptr,
203 : : DLIList<RefVertex*> &corner_vertex_list,
204 : : DLIList<RefVertex*> &through_vertex_list,
205 : : RefEdge *curve_dir_ptr,
206 : : DLIList<Curve*> &curve_list );
207 : :
208 : : //! Splits surfaces by extending curves at the end of hardlines across the
209 : : //! surface. Only works on planar surfaces and by extending linear curves.
210 : : //! If specified vertex list is provided, only try to extend curves
211 : : //! attached to those vertices, and error out if unable to perform the
212 : : //! operation using any vertex. If no vertex list is provided, find
213 : : //! appropriate vertices automatically, and limit the split to gaps less
214 : : //! than or equal to the specified "split surface extend gap threshold".
215 : : //! {ref_face_list} - list of connected surfaces to split
216 : : //! {ref_vertex_list} - (OPTIONAL) - vertices to extend from. Function will
217 : : //! error out if unable to extend from any vertex. If
218 : : //! not supplied, function will automatically find
219 : : //! valid vertices to extend from on the surfaces, and
220 : : //! will limit the split to gaps less than or equal to
221 : : //! the specified extend gap threshold (see setting
222 : : //! below).
223 : : //! {preview_flg} - routine only displays graphics preview of splits
224 : : //! {create_ref_edges_flg} - valid only if preview_flg=CUBIT_TRUE. If
225 : : //! CUBIT_TRUE, create RefEdges *instead* of
226 : : //! splitting.
227 : : //! Note this function also utilizes thress additional settings which are
228 : : //! supplied through the set_extend_gap_threshold, set_extend_tolerance and
229 : : //! set_extend_normal functions.
230 : : CubitStatus split_surfaces_extend( DLIList<RefFace*> &ref_face_list,
231 : : DLIList<RefVertex*> &ref_vertex_list,
232 : : CubitBoolean preview_flg = CUBIT_FALSE,
233 : : CubitBoolean create_ref_edges_flg = CUBIT_FALSE );
234 : :
235 : : //! Free the curves and lists memory. If free_curves_flg is CUBIT_TRUE,
236 : : //! free the Curves as well (however, the function checks if a RefEdge is
237 : : //! attached to the Curve - if a RefEdge is attached the Curve is not freed).
238 : : void free_curves_lists( DLIList<DLIList<Curve*>*> &curve_lists_list,
239 : : CubitBoolean free_curves_flg = CUBIT_TRUE );
240 : :
241 : : //! Set the tolerance (function returns previous tolerance)
242 : : static void set_tolerance( double tol );
243 : :
244 : : //! Get the tolerance. In layman's terms, the tolerance controls how
245 : : //! closely the split actually follows the center of the surface. In the
246 : : //! code, it determines how accurately to facet the bounding curves (the
247 : : //! facets are used to interpolate points on the surface using a mapping
248 : : //! concept). It is also used in an iterative procedure in fitting splines
249 : : //! to the line segments generated by the mapping (just fitting a spline
250 : : //! through the interpolated points was found to give very bad results -
251 : : //! instead we check the deviation of the spline from the line segments and
252 : : //! add additional points until the resultant spline is within tolerance to
253 : : //! the line segments.
254 : : static double get_tolerance();
255 : :
256 : : //! Set the auto detect triangles flag
257 : : static void set_auto_detect_triangles_flg( CubitBoolean auto_detect_flg );
258 : :
259 : : //! Get the auto detect triangles flag
260 : : static CubitBoolean get_auto_detect_triangles_flg();
261 : :
262 : : //! Set the side angle threshold
263 : : static void set_side_angle_threshold( double angle );
264 : :
265 : : //! Get the side angle threshold. If there is a corner angle within this
266 : : //! threshold to 180 and another corner angle less than the point threshold, a
267 : : //! triangle is created.
268 : : static double get_side_angle_threshold();
269 : :
270 : : //! Set the point angle threshold
271 : : static void set_point_angle_threshold( double tol );
272 : :
273 : : //! Get the point angle threshold. If there is a corner angle less than
274 : : //! this value and another corner angle within the side threshold to 180, a
275 : : //! triangle is created.
276 : : static double get_point_angle_threshold();
277 : :
278 : : //! Set the parametric flag
279 : : static void set_parametric_flg( CubitBoolean parametric_flg );
280 : :
281 : : //! Get the parametric flag. If the parametric_flg is CUBIT_TRUE, find
282 : : //! spline locations in the parametric space of the surface, otherwise
283 : : //! initially find the spline locations in 3D space then project back to
284 : : //! the surface. Typically, the parametric space gives better results
285 : : //! (on curvy surfaces, it will result in a spline that is much closer to
286 : : //! the middle of the surface). However, sometimes the parameter space
287 : : //! is bad or the mapping algorigm gets confused (frequently on conic
288 : : //! surfaces, resulting in points revolved 180 deg away), so the 3D method
289 : : //! gives a better result. Note the default is thus 3D.
290 : : static CubitBoolean get_parametric_flg();
291 : :
292 : : //! Set the extend gap threshold. Only split if gap is less than this.
293 : : static void set_extend_gap_threshold( double threshold = CUBIT_DBL_MAX );
294 : :
295 : : //! Get the extend gap threshold.
296 : : static double get_extend_gap_threshold();
297 : :
298 : : //! Set the extend tolerance. Snaps to vertices along curves within this
299 : : //! tolerance so as to avoid creating short curves when splitting surfaces
300 : : //! with the extend method.
301 : : static void set_extend_tolerance( double tol );
302 : :
303 : : //! Get the extend tolerance.
304 : : static double get_extend_tolerance();
305 : :
306 : : //! Set the extend normal flag. If projecting normal to curve is less
307 : : //! distance, use that instead of extending curve, if this setting is
308 : : //! true.
309 : : static void set_extend_normal_flg( CubitBoolean extend_normal_flg );
310 : :
311 : : //! Return extend normal setting.
312 : : static CubitBoolean get_extend_normal_flg();
313 : :
314 : : //! Initialize settings for this class
315 : : static void initialize_settings();
316 : :
317 : : //! preview the curves
318 : : CubitStatus draw_preview( DLIList<Curve*> &curve_list, int color=CUBIT_BLUE_INDEX );
319 : :
320 : : Curve *create_curve( DLIList<CubitVector*> &vec_list,
321 : : Surface *surf_ptr,
322 : : double tolerance = GEOMETRY_RESABS,
323 : : CubitBoolean iterate = CUBIT_FALSE,
324 : : CubitBoolean draw_pnts = CUBIT_FALSE,
325 : : CubitBoolean project_curve = CUBIT_TRUE );
326 : : //- Creates a curve given the input points. The function will attempt
327 : : //- to use a straight line or arc, if possible. In order to create
328 : : //- a straight line or arc, all of the input points must lie within
329 : : //- 0.5*tolerance of a line or arc (0.5 to minimize the total deviation,
330 : : //- exception - if tolerance==GEOMETRY_RESABS do not take 0.5), and the
331 : : //- line or arc must lie within resabs of the surface (so that imprinting
332 : : //- can occur). If iterate is TRUE, if a line or arc cannot be created,
333 : : //- the function will iterate until a spline is created that lies within
334 : : //- tolerance of the line segments input in vec_list (i.e., the resultant
335 : : //- spline approximates a series of line segments). If draw_pnts is TRUE,
336 : : //- the function will draw the resultant spline points. If project_curve
337 : : //- is CUBIT_TRUE, project the curve to the surface (this option was
338 : : //- added to speed up previewing - for that we skip the project).
339 : :
340 : : private:
341 : :
342 : : CubitStatus split_surfaces( DLIList<RefFace*> &ref_face_list,
343 : : int num_segs,
344 : : double fraction,
345 : : double distance,
346 : : RefEdge *from_curve_ptr,
347 : : DLIList<RefVertex*> &corner_vertex_list,
348 : : DLIList<RefVertex*> &through_vertex_list,
349 : : RefEdge *curve_dir_ptr,
350 : : CubitBoolean preview_flg,
351 : : CubitBoolean create_ref_edges_flg,
352 : : CubitBoolean just_curves_flg,
353 : : DLIList<DLIList<Curve*>*> &curve_lists_list );
354 : : //- Main workhorse function for automatic splitting. See above for
355 : : //- description of inputs. Note if just_curves_flg==CUBIT_TRUE, the
356 : : //- preview_flg and create_ref_edges_flg are ignored. See above for
357 : : //- description of the inputs.
358 : :
359 : : CubitStatus check_valid_faces();
360 : : //- Check each face for multiple loops, hardlines and against looping on
361 : : //- themselves (if more than one face).
362 : :
363 : : CubitStatus order_face_list();
364 : : //- Order the refFaceChain from one end of surface chain to the other.
365 : : //- This function also detects the isLoop condition (a continuous loop
366 : : //- of surfaces).
367 : :
368 : : CubitStatus get_neighbors( RefFace *seed_ref_face,
369 : : DLIList<RefFace*> &input_ref_faces,
370 : : DLIList<RefFace*> &neighbor_ref_faces );
371 : : //- Get all the neighbors of the input seed RefFace. Note second
372 : : //- list is intended to be copied in.
373 : :
374 : : CubitStatus get_outer_loops();
375 : : //- Get all of the outer loops - outerCurveLoop, outerCoEdgeLoop,
376 : : //- outerVertexList. Make sure they start at the start surface
377 : : //- in the chain.
378 : :
379 : : CubitStatus get_outer_coedge_loop();
380 : : //- Given the ordered refFaceChain, finds the outerCoEdgeLoop.
381 : :
382 : : CubitStatus find_loop_start( CoEdge *&start_co_edge_ptr );
383 : : //- Finds the start of the loop when constructing the outerCoEdgeLoop
384 : :
385 : : CubitStatus get_outer_vertices( DLIList<RefVertex*> &ref_vertex_list );
386 : : //- Fill the given vertex list using the outerCoEdgeLoop. This is
387 : : //- simply an ordered list of the vertices in the loop.
388 : :
389 : : CubitStatus get_outer_curves( DLIList<RefEdge*> &ref_edge_list );
390 : : //- Fill the given refedge list using the outerCoEdgeLoop. This is
391 : : //- simply an ordered list of refedges in the loop.
392 : :
393 : : CubitStatus pick_4_corners();
394 : : //- For a chain of surfaces. Uses angle angle criteria to pick the
395 : : //- corner vertices so that a mapping algorithm can be used to find
396 : : //- the split locations on the surfaces. Two vertices must be on
397 : : //- the start surface, and two on the end.
398 : :
399 : : CubitStatus pick_expanded_corners( RefFace *ref_face_ptr,
400 : : DLIList<CoEdge*> &co_edge_list,
401 : : int &offset, double epsilon,
402 : : int &A_i, int &B_i );
403 : : //- Used by pick_4_corners. Finds the two best corners on the given
404 : : //- RefFace (which will be either the start or the end surface of the
405 : : //- chain). If there are multiple vertices with the same angle, it
406 : : //- will find the pair that are the farthest from the center.
407 : :
408 : : CubitStatus pick_4_corners_simple();
409 : : //- For a single surface. Just finds the 4 corners closest to PI/2.
410 : :
411 : : CubitStatus update_corners_for_triangle();
412 : : //- Determines whether any corners are close to 180 degrees (above
413 : : //- angleTolerance). On a single surface, the corner that is
414 : : //- closest to 180 and above angleTolerance is removed. The next
415 : : //- angle farthest from PI/2 is chosen as the corner of the triangle.
416 : : //- For a chain, both ends of the chain are checked.
417 : :
418 : : CubitStatus remove_corner( int corner_to_remove, int collapsed_corner,
419 : : CubitBoolean set_collapsed_first );
420 : : //- Removes a corner making a triangle. If set_collapsed_first is
421 : : //- CUBIT_TRUE, then the collapsed side is set to the first corner,
422 : : //- meaning the split will originate there.
423 : :
424 : : CubitStatus fill_corners( int best_corner_1, int best_corner_2,
425 : : int best_corner_3, int best_corner_4 );
426 : : //- Fill the cornerCoEdge array given the position of the corners
427 : :
428 : : CubitStatus fill_side_intervals( int best_corner_1, int best_corner_2,
429 : : int best_corner_3, int best_corner_4 );
430 : : //- Fill sideInterval array given teh position of the corners
431 : :
432 : : CubitStatus order_selected_corners( DLIList<RefVertex*> &outer_vertex_list );
433 : : //- If the user specified corners, this function will reorient the lists
434 : : //- so that the desired split direction will occur. It also does error
435 : : //- checking on the users selected corners.
436 : :
437 : : int number_in_list( DLIList<RefVertex*> &corner_vertex_list,
438 : : RefVertex *ref_vertex_ptr );
439 : : //- Count the number of times the given RefVertex exists in the list
440 : :
441 : : CubitBoolean is_in_outer_loop( RefVertex *ref_vertex_ptr );
442 : : //- Determines whether the given vertex exists in the outer loop
443 : :
444 : : CubitStatus compute_angles( double *&angles, double &turn_angle_sum );
445 : : //- This finds an array of angles around the outer loop for finding
446 : : //- corners. Note the angles array is allocated - the calling function
447 : : //- must free it. turn_angle_sum is currently not used.
448 : :
449 : : void order_corners( int &corner_1, int &corner_2,
450 : : int &corner_3, int &corner_4 );
451 : : void order_corners( int &corner_1, int &corner_2,
452 : : int &corner_3 );
453 : : //- Given the best corners in any order, these functions just sort them
454 : : //- from lowest to highest.
455 : :
456 : : CubitStatus adjust_for_split_direction( RefEdge *curve_dir_ptr,
457 : : RefEdge *from_curve_ptr,
458 : : DLIList<RefVertex*> &corner_vertex_list );
459 : : //- Adjust the lists so that the split direction is proper. See function
460 : : //- for logic details (i.e., always split along chains of surfaces, attempt
461 : : //- to split along highest aspect ratio for single surfaces, etc.).
462 : :
463 : : double get_side_length( int side );
464 : : //- Determines the length of a given side of the logical rectangle.
465 : :
466 : : double compute_next_angle( DLIList<CoEdge*> &co_edge_list );
467 : : //- Finds the next angle when walking around outerCoEdgeLoop finding
468 : : //- angles for corner picking. It steps the list.
469 : :
470 : : CubitStatus reorient_loop( int start_offset );
471 : : //- Reorients the global loop (outerCoEdgeLoop) so that it starts at the beginning.
472 : :
473 : : CubitStatus shuffle_corners_forward();
474 : : //- This shuffles the outer loop, side interval and corner array forward
475 : : //- by sideInterval[0] (ie., useful when changing the split direction for
476 : : //- a single surface).
477 : :
478 : : CubitStatus shuffle_zero_side_forward();
479 : : //- This shuffles the zero interval side (present on triangles) forward.
480 : : //- Side interval and corner array affected. This function is necessary
481 : : //- if user specifies a 'direction' or 'from' curve when splitting a triangle.
482 : :
483 : : CubitStatus populate_curve_loops();
484 : : //- Populates the CoEdge lists in the surface tooldatas. The CoEdge lists
485 : : //- are organized by side of the logical rectangle on each surface in
486 : : //- refFaceChain.
487 : :
488 : : CubitBoolean is_edge_in_list( RefEdge *ref_edge_ptr, DLIList<CoEdge*> &co_edge_list );
489 : : //- Determines if the given RefEdge is the child of any of the CoEdges in co_edge_list
490 : :
491 : : CubitStatus check_face_loop( RefFace *ref_face_ptr, CubitBoolean &is_loop );
492 : : //- Checks a single surface to see if it is a loop.
493 : :
494 : : CubitStatus check_for_loop( RefFace *ref_face_ptr1, RefFace *ref_face_ptr2,
495 : : CubitBoolean &is_loop,
496 : : CoEdge *&start_co_edge_ptr );
497 : : //- Checks a two-surface chain to see if it is a loop. If it is a loop, it can
498 : : //- return the starting coedge as well (warning - if not a loop, the starting
499 : : //- coedge is not set).
500 : :
501 : : CubitStatus ordered_co_edges( RefFace *ref_face_ptr, DLIList<CoEdge*> &co_edge_list );
502 : : //- Get an ordered list of coedges from the RefFace. The RefFace must only
503 : : //- contain one loop.
504 : :
505 : : CoEdge *get_next_co_edge( CoEdge *prev_co_edge_ptr, DLIList<CoEdge*> &co_edge_list );
506 : : //- Given the previous CoEdge, get the next CoEdge using the CoEdges in
507 : : //- the given list.
508 : :
509 : : RefVertex *start_vertex( CoEdge *co_edge_ptr );
510 : : //- Get the starting vertex of the given CoEdge.
511 : :
512 : : RefVertex *end_vertex( CoEdge *co_edge_ptr );
513 : : //- Get the ending vertex of the given CoEdge.
514 : :
515 : : CoEdge *get_complimentary_co_edge( CoEdge *co_edge_ptr,
516 : : DLIList<CoEdge*> co_edge_list );
517 : : //- Find the CoEdge from co_edge_list that shares a common RefEdge with
518 : : //- the input co_edge_ptr. Returns NULL if no complimentary CoEdge is
519 : : //- found. Note the input co_edge_list is copied so that it's list
520 : : //- position is not changed.
521 : :
522 : : CubitStatus get_attached_coedges_start( CoEdge *co_edge_ptr,
523 : : DLIList<CoEdge*> &co_edge_list,
524 : : DLIList<CoEdge*> &attached_co_edge_list );
525 : : //- Get coedges from co_edge_list whose start vertices are attached to the start
526 : : //- vertex of co_edge_ptr
527 : :
528 : : CubitStatus remove_other_corner_coedges( CoEdge *co_edge_1, CoEdge *co_edge_2,
529 : : DLIList<CoEdge*> &all_co_edge_list,
530 : : DLIList<CoEdge*> &att_co_edge_list );
531 : : //- For isLoop situation, removes CoEdges from the "attached_co_edge_list"
532 : : //- that are connected to the other shared corner. The inputs are the
533 : : //- previous and next CoEdges surrounding this (not the other) corner.
534 : :
535 : : CubitStatus add_tooldata( DLIList<CoEdge*> &co_edge_list, int vertex_type );
536 : : //- Add a tooldata to each of the CoEdges in co_edge_list containing the
537 : : //- vertex_type at the start of the CoEdge.
538 : :
539 : : CubitBoolean is_vertex_on_side( RefVertex *ref_vertex_ptr, int side );
540 : : //- Determines if the given vertex lies on the given side. Note the
541 : : //- vertex is checked spatially, not literally as if in the vertices
542 : : //- in the outer loop.
543 : :
544 : : CubitBoolean is_vertex_in_surface( RefVertex *ref_vertex_ptr, RefFace *ref_face );
545 : : //- Determines if the given vertex is in the given RefFace.
546 : :
547 : : CubitBoolean is_curve_in_outer_loop( RefEdge *ref_edge_ptr );
548 : : //- Determines if the given curve lies in the outer loop of curves.
549 : :
550 : : CubitBoolean is_curve_on_side( RefEdge *ref_edge_ptr, int side );
551 : : //- Determines if the given curve lies on the given side.
552 : :
553 : : CubitBoolean is_chain_two_triangles();
554 : : //- Determines wheither the chain of surfaces is actually two connected
555 : : //- triangles (see diagram in function).
556 : :
557 : : CubitBoolean is_triangle();
558 : : //- Determines if a single surface chain is a triangle
559 : :
560 : : CubitStatus check_through_vertices( const char *type );
561 : : //- Determines if the through vertices are on valid sides of the surface.
562 : : //- Call this function after adjusting for a Curve direction.
563 : : //- This function only checks - it gives an error if through vertices are
564 : : //- on invalid sides. Type is either "direction" or "from", for the error
565 : : //- message ("direction" if the direction exists and was checked previously,
566 : : //- "from" if only a from curve was given).
567 : :
568 : : CoEdge* prev_co_edge( CoEdge *co_edge_ptr );
569 : : //- From the outerCoEdgeLoop, get the CoEdge previous to the one given.
570 : :
571 : : CubitStatus position_co_edge_list( int i, DLIList<CoEdge*> &co_edge_list );
572 : : //- Position the co_edge_list to the start of the loop
573 : :
574 : : CubitStatus get_a_coedges( DLIList<CoEdge*> &co_edge_list,
575 : : DLIList<CoEdge*> &a_coedges );
576 : : CubitStatus get_b_coedges( DLIList<CoEdge*> &co_edge_list,
577 : : DLIList<CoEdge*> &b_coedges );
578 : : CubitStatus get_c_coedges( DLIList<CoEdge*> &co_edge_list,
579 : : DLIList<CoEdge*> &c_coedges );
580 : : CubitStatus get_d_coedges( DLIList<CoEdge*> &co_edge_list,
581 : : int num_so_far, DLIList<CoEdge*> &d_coedges );
582 : : //- These functions find the coedges on each side of the logical rectangle,
583 : : //- using the vertex classifications
584 : :
585 : : CubitStatus find_spline_curves( RefFace *ref_face_ptr, int num_segs,
586 : : double distance,
587 : : DLIList<Curve*> *curve_list_ptr,
588 : : double tolerance,
589 : : CubitBoolean parametric_flg = CUBIT_FALSE,
590 : : CubitBoolean preview_flg = CUBIT_FALSE,
591 : : CubitBoolean create_ref_edges_flg = CUBIT_FALSE );
592 : : //- Uses a mapping algorithm to calculate the interior points to pass
593 : : //- spline(s) through and creates the Curve(s) for the surface. By default,
594 : : //- it will do the mapping in the 3D space of the surface. It can be
595 : : //- overridden to use the parametric space if a surface parametric space
596 : : //- exists. If preview_flg is TRUE, then the interior spline points are
597 : : //- drawn for the user to query. This setting, along with the create_ref_edges_flg
598 : : //- also helps to determine whether to project the curves to the surface.
599 : : //- In OCC, projecting is very slow, so we skip it when previewing; however
600 : : //- we use it if the user is ultimately creating RefEdges (note the RefEdges
601 : : //- will not be created within this function).
602 : :
603 : : CubitStatus fill_boundary_coords( TDSplitSurface *tdss, int nr, int nc,
604 : : CubitVector ***coords );
605 : : //- Fills the boundary array for the mapping algorithm in 3D
606 : :
607 : : CubitStatus draw_boundary_coords( TDSplitSurface *tdss );
608 : : //- Debug function - just draws the coords for each side, if debug 100 is on
609 : :
610 : : CubitStatus smooth_interior_coords( RefFace *ref_face_ptr,
611 : : TDSplitSurface *tdss,
612 : : double tolerance,
613 : : int nr, int nc, double distance,
614 : : CubitVector ***coords );
615 : : //- Smooths the interior coords in 3D so that the split location is correct.
616 : : //- Respect distance if not -1.0.
617 : :
618 : : CubitStatus fill_interior_coords( TDSplitSurface *tdss, int nr, int nc,
619 : : CubitVector ***coords );
620 : : //- Fills the interior coordinates using a mapping algorithm in 3D
621 : :
622 : : CubitVector *make_interior_coord( CubitVector ***coords, int nr, int nc,
623 : : double ada, double tse, int j, int i );
624 : : //- Calculates an interior coordinate using the mapping algorithm in 3D
625 : :
626 : : CubitStatus fill_boundary_coords( TDSplitSurface *tdss, int nr, int nc,
627 : : Cubit2DPoint ***coords );
628 : : //- Fills the boundary array for the mapping algorithm in 2D
629 : :
630 : : Cubit2DPoint *get_uv_point( RefFace *ref_face_ptr, CubitVector *vec_ptr );
631 : : //- Given an input 3D point gets a UV point on the given surface
632 : :
633 : : CubitStatus fill_interior_coords( TDSplitSurface *tdss, int nr, int nc,
634 : : Cubit2DPoint ***coords );
635 : : //- Fills the interior coordinates using a mapping algorithm in 2D
636 : :
637 : : CubitStatus get_tse_array( TDSplitSurface *tdss, int tse_ints,
638 : : DLIList<double> &tse_array );
639 : : //- For the mapping algorithm, finds an array of tse which are the
640 : : //- average fractional distances across the AC direction of the surface
641 : :
642 : : Cubit2DPoint *make_interior_coord( Cubit2DPoint ***coords, int nr, int nc,
643 : : double ada, double tse, int j, int i );
644 : : //- Calculates an interior coordinate using the mapping algorithm in 2D
645 : :
646 : : CubitStatus draw_points( DLIList<CubitVector*> &pnt_list, int color,
647 : : int flush = CUBIT_TRUE );
648 : : CubitStatus draw_point( CubitVector &pnt, int color, int flush = CUBIT_FALSE );
649 : : //- Draw points
650 : :
651 : : CubitStatus draw_preview( Curve *curve_ptr, CubitBoolean flush=CUBIT_TRUE,
652 : : int color=CUBIT_BLUE_INDEX );
653 : : //- Draw the curves
654 : :
655 : : CubitStatus create_ref_edges( DLIList<Curve*> &curve_list,
656 : : DLIList<RefEdge*> &ref_edge_list );
657 : : //- Create RefEdges from the given Curves. Appends to the output list.
658 : :
659 : : int number_coedges( RefEdge *ref_edge_ptr, RefFace *ref_face_ptr );
660 : : //- Finds the number of coedges for the given edge on the given surface
661 : :
662 : : void delete_surf_tooldatas( DLIList<RefFace*> &ref_face_list );
663 : : //- Deletes tooldatas from the given ref_face_list
664 : :
665 : : void delete_coedge_tooldatas( DLIList<CoEdge*> &co_edge_list );
666 : : //- Deletes tooldatas from the given co_edge_list
667 : :
668 : : void delete_vertex_tooldatas( DLIList<RefVertex*> &ref_vertex_list );
669 : : //- Deletes tooldatas from the given ref_vertex_list
670 : :
671 : : void list_sides_debug();
672 : : //- Lists the sides for debugging purposes
673 : :
674 : : CubitBoolean check_points_straight( Surface *surf_ptr,
675 : : DLIList<CubitVector*> &point_list,
676 : : double tolerance );
677 : : //- Check to see if the points approximate a straight line, within
678 : : //- tolerance. Also, if surface is not a plane, all points are projected
679 : : //- to the resultant line and checked to make sure they lie within resabs
680 : : //- (GEOMETRY_RESABS or a user specified tolerance) to the surf_ptr so
681 : : //- that an imprint will be successful. If only two points are input,
682 : : //- additional locations along the line are checked.
683 : :
684 : : Curve* check_points_arc( Surface *surf_ptr,
685 : : GeometryModifyEngine *gme,
686 : : DLIList<CubitVector*> &point_list,
687 : : double resabs,
688 : : double tolerance );
689 : : //- Check to see if the input points approximate an arc. If there are
690 : : //- only two input points, try to create an arc if the surface is a
691 : : //- cone, sphere or torus.
692 : :
693 : : Curve* check_if_arc( GeometryModifyEngine *gme,
694 : : Surface *surf_ptr,
695 : : DLIList<CubitVector*> &point_list,
696 : : CubitVector &start_pnt,
697 : : CubitVector &mid_pnt,
698 : : CubitVector &end_pnt,
699 : : double resabs,
700 : : double tolerance,
701 : : double &deviation );
702 : : //- Supplemental function for check_points_arc. This function can be
703 : : //- called multiple times from check_points_arc as we try to iterate
704 : : //- to a solution.
705 : :
706 : : CubitStatus get_arc_mid_pnt( Surface *surf_ptr,
707 : : CubitVector &start_pnt,
708 : : CubitVector &end_pnt,
709 : : CubitVector &mid_pnt,
710 : : double tolerance );
711 : : //- Given the start and end points, and the surface, this function finds
712 : : //- a third point on the arc.
713 : :
714 : : Curve* create_arc_two( GeometryModifyEngine *gme,
715 : : Surface *surf_ptr,
716 : : CubitVector &start_pnt,
717 : : CubitVector &end_pnt,
718 : : double resabs,
719 : : double tolerance );
720 : : //- Given the surface and two points, attempt to find an arc that lies
721 : : //- on the surface.
722 : :
723 : : Curve* create_arc_three( GeometryModifyEngine *gme,
724 : : Surface *surf_ptr,
725 : : CubitVector &start_pnt,
726 : : CubitVector &mid_pnt,
727 : : CubitVector &end_pnt,
728 : : double resabs );
729 : : //- Given the surface and three points, attempt to find an arc that lies
730 : : //- on the surface.
731 : :
732 : : CubitStatus reflect_arc_pnt( CubitVector &vec1,
733 : : CubitVector &vec2,
734 : : CubitVector &vec3,
735 : : CubitVector &pnt_to_reflect,
736 : : CubitVector &out_pnt );
737 : : //- Given three points and another input point, create an arc and
738 : : //- reflect the input point about the arc center.
739 : :
740 : : CubitBoolean is_point_on_surface( Surface *surf_ptr, CubitVector &pnt,
741 : : double resabs );
742 : : //- Determine if the input point is within the given resabs of the surface.
743 : :
744 : : int count_surfaces_in_owning_body( RefFace *ref_face_ptr, Body *&body_ptr );
745 : : //- Returns: Number of surfaces in the owning body of the RefFace
746 : : //- -1 - RefFace is free (no owning body)
747 : : //- -2 - RefFace is owned by more than one body
748 : : //- Also returns the owning body via argument list
749 : :
750 : : int count_surfaces_in_body( Body *body_ptr );
751 : : //- Return number of surfaces in the body
752 : :
753 : : int count_curves_in_body( Body *body_ptr );
754 : : //- Return number of curves in the body
755 : :
756 : : void cleanup_for_extend_op( DLIList<RefVertex*> &ref_vertex_list,
757 : : DLIList<DLIList<Surface*>*> &body_surf_list_list,
758 : : DLIList<DLIList<DLIList<Curve*>*>*> &curve_lists_lists_list,
759 : : CubitBoolean free_curves_flg = CUBIT_TRUE );
760 : : //- This function cleans up after the split extend operation. It removes
761 : : //- the tooldatas from the vertices and frees the lists memory. If
762 : : //- free_curves_flg is CUBIT_TRUE, free the Curves as well (however, the
763 : : //- function checks if a RefEdge is attached to the Curve - if a RefEdge
764 : : //- is attached the Curve is not freed).
765 : :
766 : : void find_nearest_curve_for_normal_projection(
767 : : RefEdge* hit_edge_ptr, CubitVector& start_loc, RefFace* face,
768 : : CubitVector& ray_dir, RefEdge*& new_edge_ptr, CubitVector& new_end_loc);
769 : : //- This function is used when the split extend command is used with normal = TRUE and
770 : : //- the hardline does not intersect the curve found by fire_ray at a 90 degree angle.
771 : : //- This function traverses the curve's neighbors to find a curve that can be split normal.
772 : :
773 : : static CubitBoolean parametricFlg; // Split parametrically or not (3D)
774 : : static double splitTolerance; // Length tolerance for tessellations, etc.
775 : : static CubitBoolean autoDetectTriangles; // Detect triangles automatically?
776 : : static double sideAngleThreshold; // Closest corner within this threshold
777 : : // to 180 is removed (if pointAngleThreshold
778 : : // criteria also met)
779 : : static double pointAngleThreshold; // Corner with angle below this becomes
780 : : // the triangle point (if sideAngleThreshold
781 : : // criteria also met)
782 : :
783 : : static double extendGapThreshold; // Only gaps below this value are split
784 : : static CubitBoolean extendNormalFlg; // If true, extend normal to curve
785 : : // instead of in curve direction if
786 : : // distance is less
787 : : static double extendTolerance; // If split end is equal or closer than this
788 : : // to a vertex along a curve snap to the
789 : : // vertex.
790 : :
791 : : DLIList<RefFace*> refFaceChain;
792 : : DLIList<RefVertex*> throughVertexList;
793 : : DLIList<CoEdge*> outerCoEdgeLoop;
794 : : CoEdge *cornerCoEdge[4]; // Corner at start of given CoEdge
795 : : CubitBoolean isLoop; // A continuous loop of surfaces?
796 : : int sideInterval[4];
797 : : };
798 : :
799 : : inline void
800 : 0 : SplitSurfaceTool::set_tolerance( double tol )
801 : 0 : { splitTolerance = tol; }
802 : :
803 : : inline double
804 : 0 : SplitSurfaceTool::get_tolerance()
805 : 0 : { return splitTolerance; }
806 : :
807 : : inline void
808 : 0 : SplitSurfaceTool::set_auto_detect_triangles_flg( CubitBoolean flg )
809 : 0 : { autoDetectTriangles = flg; }
810 : :
811 : : inline CubitBoolean
812 : 0 : SplitSurfaceTool::get_auto_detect_triangles_flg()
813 : 0 : { return autoDetectTriangles; }
814 : :
815 : : inline void
816 : 0 : SplitSurfaceTool::set_side_angle_threshold( double tol )
817 : 0 : { sideAngleThreshold = tol; }
818 : :
819 : : inline double
820 : 0 : SplitSurfaceTool::get_side_angle_threshold()
821 : 0 : { return sideAngleThreshold; }
822 : :
823 : : inline void
824 : 0 : SplitSurfaceTool::set_point_angle_threshold( double tol )
825 : 0 : { pointAngleThreshold = tol; }
826 : :
827 : : inline double
828 : 0 : SplitSurfaceTool::get_point_angle_threshold()
829 : 0 : { return pointAngleThreshold; }
830 : :
831 : : inline void
832 : 0 : SplitSurfaceTool::set_parametric_flg( CubitBoolean parametric_flg )
833 : 0 : { parametricFlg = parametric_flg; }
834 : :
835 : : inline CubitBoolean
836 : 0 : SplitSurfaceTool::get_parametric_flg()
837 : 0 : { return parametricFlg; }
838 : :
839 : : inline void
840 : 0 : SplitSurfaceTool::set_extend_gap_threshold( double gap )
841 : 0 : { extendGapThreshold = gap; }
842 : :
843 : : inline double
844 : 0 : SplitSurfaceTool::get_extend_gap_threshold()
845 : 0 : { return extendGapThreshold; }
846 : :
847 : : inline void
848 : 0 : SplitSurfaceTool::set_extend_tolerance( double tol )
849 : 0 : { extendTolerance = tol; }
850 : :
851 : : inline double
852 : 0 : SplitSurfaceTool::get_extend_tolerance()
853 : 0 : { return extendTolerance; }
854 : :
855 : : inline void
856 : 0 : SplitSurfaceTool::set_extend_normal_flg( CubitBoolean extend_normal_flg )
857 : 0 : { extendNormalFlg = extend_normal_flg; }
858 : :
859 : : inline CubitBoolean
860 : 0 : SplitSurfaceTool::get_extend_normal_flg()
861 : 0 : { return extendNormalFlg; }
862 : :
863 : : #endif
864 : :
|