Branch data Line data Source code
1 : : //-------------------------------------------------------------------------
2 : : // Filename : SplitSurfaceTool.cpp
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 : : // Split Surface <id> Across [Pair] Location <options multiple locs>
9 : : // [Preview [Create]]
10 : : // Split Surface <id> Across Location <multiple locs> Onto Curve <id>
11 : : // [Preview [Create]]
12 : : // Split Surface <id_list> Extend [Vertex <id_list> | Auto] [Preview [Create]]
13 : : //
14 : : // Split Surface <id_list> [Corner Vertex <id_list>] [Direction Curve <id>]
15 : : // [Segment <val> | Fraction|Distance <val> [From Curve <id>]]
16 : : // [Through Vertex <id_list>] [Parametric <on|OFF>] [Tolerance <value>]
17 : : // [Preview [Create]]
18 : : //
19 : : // Special Notes :
20 : : //
21 : : // Creator : Steve Storm
22 : : //
23 : : // Creation Date : 10/06/2002
24 : : //-------------------------------------------------------------------------
25 : :
26 : : #include "SplitSurfaceTool.hpp"
27 : : #include "AnalyticGeometryTool.hpp"
28 : : #include "Body.hpp"
29 : : #include "RefFace.hpp"
30 : : #include "Point.hpp"
31 : : #include "Curve.hpp"
32 : : #include "Surface.hpp"
33 : : #include "Loop.hpp"
34 : : #include "CubitMessage.hpp"
35 : : #include "GeometryModifyTool.hpp"
36 : : #include "GeometryModifyEngine.hpp"
37 : : #include "GeometryQueryTool.hpp"
38 : : #include "CubitUtil.hpp"
39 : : #include "DLIList.hpp"
40 : : #include "TDSplitSurface.hpp"
41 : : #include "GfxDebug.hpp"
42 : : #include "GfxPreview.hpp"
43 : : #include "Cubit2DPoint.hpp"
44 : : #include "GMem.hpp"
45 : : #include "SettingHandler.hpp"
46 : :
47 : : CubitBoolean SplitSurfaceTool::parametricFlg = CUBIT_FALSE;
48 : : double SplitSurfaceTool::splitTolerance = 1.0;
49 : : CubitBoolean SplitSurfaceTool::autoDetectTriangles = CUBIT_TRUE;
50 : : double SplitSurfaceTool::sideAngleThreshold = 27.0; // From 180
51 : : double SplitSurfaceTool::pointAngleThreshold = 45.0; // Below is a point
52 : : double SplitSurfaceTool::extendGapThreshold = CUBIT_DBL_MAX;
53 : : CubitBoolean SplitSurfaceTool::extendNormalFlg = CUBIT_FALSE;
54 : : double SplitSurfaceTool::extendTolerance = .1;
55 : :
56 [ # # ][ # # ]: 0 : SplitSurfaceTool::SplitSurfaceTool()
57 : : {
58 : : int i;
59 [ # # ]: 0 : for(i=0; i<4; i++)
60 : : {
61 : 0 : sideInterval[i] = 0;
62 : 0 : cornerCoEdge[i] = NULL;
63 : : }
64 : 0 : isLoop = CUBIT_FALSE;
65 : 0 : }
66 : :
67 : : //Initialize all settings in this class
68 : : void
69 : 0 : SplitSurfaceTool::initialize_settings()
70 : : {
71 : : SettingHandler::instance()->add_setting("Split Surface Tolerance",
72 : : SplitSurfaceTool::set_tolerance,
73 : 0 : SplitSurfaceTool::get_tolerance);
74 : :
75 : : SettingHandler::instance()->add_setting("Split Surface Parametric",
76 : : SplitSurfaceTool::set_parametric_flg,
77 : 0 : SplitSurfaceTool::get_parametric_flg);
78 : :
79 : : SettingHandler::instance()->add_setting("Split Surface Auto Detect Triangles",
80 : : SplitSurfaceTool::set_auto_detect_triangles_flg,
81 : 0 : SplitSurfaceTool::get_auto_detect_triangles_flg);
82 : :
83 : : SettingHandler::instance()->add_setting("Split Surface Side Angle Threshold",
84 : : SplitSurfaceTool::set_side_angle_threshold,
85 : 0 : SplitSurfaceTool::get_side_angle_threshold);
86 : :
87 : : SettingHandler::instance()->add_setting("Split Surface Point Angle Threshold",
88 : : SplitSurfaceTool::set_point_angle_threshold,
89 : 0 : SplitSurfaceTool::get_point_angle_threshold);
90 : :
91 : : SettingHandler::instance()->add_setting("Split Surface Extend Gap Threshold",
92 : : SplitSurfaceTool::set_extend_gap_threshold,
93 : 0 : SplitSurfaceTool::get_extend_gap_threshold);
94 : :
95 : : SettingHandler::instance()->add_setting("Split Surface Extend Tolerance",
96 : : SplitSurfaceTool::set_extend_tolerance,
97 : 0 : SplitSurfaceTool::get_extend_tolerance);
98 : :
99 : : SettingHandler::instance()->add_setting("Split Surface Extend Normal",
100 : : SplitSurfaceTool::set_extend_normal_flg,
101 : 0 : SplitSurfaceTool::get_extend_normal_flg);
102 : 0 : }
103 : :
104 : : CubitStatus
105 : 0 : SplitSurfaceTool::preview( RefFace *ref_face_ptr,
106 : : DLIList<CubitVector*> &locations,
107 : : DLIList<DLIList<CubitVector*>*> &vec_lists,
108 : : CubitBoolean create_ref_edges_flg,
109 : : CubitBoolean clear_previous_previews )
110 : : {
111 : : // Create curves from the input vec_lists (locations are just the original
112 : : // locations the user specified - these need to be drawn)
113 : : int i, j;
114 : : Curve *curve_ptr;
115 : : DLIList<CubitVector*> *vec_list_ptr;
116 [ # # ]: 0 : vec_lists.reset();
117 [ # # ]: 0 : DLIList<Surface*> surfs;
118 : :
119 [ # # ]: 0 : Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
120 : :
121 : : // Support composite surfaces by getting the surfaces underlying
122 : : // the composite and creating split curves for them individually.
123 [ # # ]: 0 : GeometryQueryEngine *gqe = surf_ptr->get_geometry_query_engine();
124 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> tbs;
125 [ # # ]: 0 : gqe->get_underlying_surfaces(surf_ptr, tbs);
126 [ # # ][ # # ]: 0 : if(tbs.size() > 0)
127 : : {
128 [ # # ][ # # ]: 0 : for(j=tbs.size(); j>0; j--)
129 [ # # ][ # # ]: 0 : surfs.append(dynamic_cast<Surface*>(tbs.get_and_step()));
[ # # ]
130 : : }
131 : : else
132 [ # # ]: 0 : surfs.append(surf_ptr);
133 : :
134 : : // Clear previous previews if necessary
135 [ # # ]: 0 : if( clear_previous_previews == CUBIT_TRUE )
136 [ # # ]: 0 : GfxPreview::clear();
137 : :
138 [ # # ][ # # ]: 0 : for( i=vec_lists.size(); i--; )
139 : : {
140 [ # # ]: 0 : vec_list_ptr = vec_lists.get_and_step();
141 : :
142 [ # # ]: 0 : vec_list_ptr->reset();
143 [ # # ][ # # ]: 0 : if( vec_list_ptr->size() < 2 )
144 : : {
145 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to create a curve from less than two locations.\n" );
[ # # ][ # # ]
146 : 0 : continue;
147 : : }
148 : :
149 [ # # ][ # # ]: 0 : for(j=surfs.size(); j>0; j--)
150 : : {
151 [ # # ]: 0 : Surface *cur_surf = surfs.get_and_step();
152 [ # # ]: 0 : curve_ptr = create_curve( *vec_list_ptr, cur_surf );
153 : :
154 [ # # ]: 0 : if( curve_ptr )
155 : : {
156 [ # # ]: 0 : if( create_ref_edges_flg == CUBIT_TRUE )
157 : : {
158 : : RefEdge *ref_edge_ptr;
159 [ # # ][ # # ]: 0 : ref_edge_ptr = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
160 [ # # ]: 0 : if( ref_edge_ptr )
161 [ # # ][ # # ]: 0 : PRINT_INFO( "Created new curve %d\n", ref_edge_ptr->id() );
[ # # ][ # # ]
[ # # ]
162 : : }
163 : : else
164 : : {
165 [ # # ]: 0 : draw_preview( curve_ptr, CUBIT_FALSE );
166 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
167 : : }
168 : : }
169 : : }
170 : : }
171 : :
172 : : // Draw locations too
173 [ # # ]: 0 : draw_points( locations, CUBIT_BLUE_INDEX );
174 : :
175 [ # # ]: 0 : return CUBIT_SUCCESS;
176 : : }
177 : :
178 : : CubitStatus
179 : 0 : SplitSurfaceTool::preview( DLIList<RefFace*> &ref_face_list,
180 : : DLIList<CubitVector*> &locations,
181 : : DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists,
182 : : CubitBoolean create_ref_edges_flg,
183 : : CubitBoolean clear_previous_previews )
184 : : {
185 : : //Reset ref_face_list and list_of_vec_lists (just in case)
186 : 0 : ref_face_list.reset();
187 : 0 : list_of_vec_lists.reset();
188 : :
189 : : // Clear previous previews if necessary
190 [ # # ]: 0 : if( clear_previous_previews == CUBIT_TRUE )
191 : 0 : GfxPreview::clear();
192 : :
193 : : int qq;
194 [ # # ]: 0 : for( qq = ref_face_list.size(); qq > 0 ; qq--)
195 : : {
196 : : //Initialize the values to be used upon each iteration
197 [ # # ]: 0 : RefFace* ref_face_ptr = ref_face_list.get_and_step();
198 [ # # ][ # # ]: 0 : DLIList<DLIList<CubitVector*>*> vec_lists = *( list_of_vec_lists.get_and_step() );
199 : :
200 : : int i, j;
201 : : Curve *curve_ptr;
202 : : DLIList<CubitVector*> *vec_list_ptr;
203 [ # # ]: 0 : vec_lists.reset();
204 [ # # ][ # # ]: 0 : DLIList<Surface*> surfs;
205 : :
206 [ # # ]: 0 : Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
207 : :
208 : : // Support composite surfaces by getting the surfaces underlying
209 : : // the composite and creating split curves for them individually.
210 [ # # ]: 0 : GeometryQueryEngine *gqe = surf_ptr->get_geometry_query_engine();
211 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> tbs;
212 [ # # ]: 0 : gqe->get_underlying_surfaces(surf_ptr, tbs);
213 [ # # ][ # # ]: 0 : if(tbs.size() > 0)
214 : : {
215 [ # # ][ # # ]: 0 : for(j=tbs.size(); j>0; j--)
216 [ # # ][ # # ]: 0 : surfs.append(dynamic_cast<Surface*>(tbs.get_and_step()));
[ # # ]
217 : : }
218 : : else
219 [ # # ]: 0 : surfs.append(surf_ptr);
220 : :
221 [ # # ][ # # ]: 0 : for( i=vec_lists.size(); i--; )
222 : : {
223 [ # # ]: 0 : vec_list_ptr = vec_lists.get_and_step();
224 : :
225 [ # # ]: 0 : vec_list_ptr->reset();
226 [ # # ][ # # ]: 0 : if( vec_list_ptr->size() < 2 )
227 : : {
228 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to create a curve from less than two locations.\n" );
[ # # ][ # # ]
229 : 0 : continue;
230 : : }
231 : :
232 [ # # ][ # # ]: 0 : for(j=surfs.size(); j>0; j--)
233 : : {
234 [ # # ]: 0 : Surface *cur_surf = surfs.get_and_step();
235 [ # # ]: 0 : curve_ptr = create_curve( *vec_list_ptr, cur_surf );
236 : :
237 [ # # ]: 0 : if( curve_ptr )
238 : : {
239 [ # # ]: 0 : if( create_ref_edges_flg == CUBIT_TRUE )
240 : : {
241 : : RefEdge *ref_edge_ptr;
242 [ # # ][ # # ]: 0 : ref_edge_ptr = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
243 [ # # ]: 0 : if( ref_edge_ptr )
244 [ # # ][ # # ]: 0 : PRINT_INFO( "Created new curve %d\n", ref_edge_ptr->id() );
[ # # ][ # # ]
[ # # ]
245 : : }
246 : : else
247 : : {
248 [ # # ]: 0 : draw_preview( curve_ptr, CUBIT_FALSE );
249 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
250 : : }
251 : : }
252 : : }
253 : : }
254 [ # # ]: 0 : }
255 : :
256 : : // Draw locations too
257 : 0 : draw_points( locations, CUBIT_BLUE_INDEX );
258 : :
259 : 0 : return CUBIT_SUCCESS;
260 : : }
261 : :
262 : : // Create the curves used by the splitting algorithm.
263 : : // Note: calling code is responsible for cleaning up the
264 : : // created curves when it is done with them.
265 : : CubitStatus
266 : 0 : SplitSurfaceTool::calculate_split_curves( RefFace *ref_face_ptr,
267 : : DLIList<DLIList<CubitVector*>*> &vec_lists,
268 : : DLIList<Curve*>& curve_list )
269 : : {
270 : 0 : Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
271 : :
272 : 0 : return calculate_split_curves(surf_ptr, vec_lists, curve_list);
273 : : }
274 : :
275 : : CubitStatus
276 : 0 : SplitSurfaceTool::calculate_split_curves( Surface *surf_ptr,
277 : : DLIList<DLIList<CubitVector*>*> &vec_lists,
278 : : DLIList<Curve*>& curve_list )
279 : : {
280 : : int i;
281 : : Curve *curve_ptr;
282 : : DLIList<CubitVector*> *vec_list_ptr;
283 [ # # ]: 0 : vec_lists.reset();
284 : :
285 [ # # ][ # # ]: 0 : for( i=vec_lists.size(); i--; )
286 : : {
287 [ # # ]: 0 : vec_list_ptr = vec_lists.get_and_step();
288 : :
289 [ # # ]: 0 : vec_list_ptr->reset();
290 [ # # ][ # # ]: 0 : if( vec_list_ptr->size() < 2 )
291 : : {
292 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to create a curve from less than two locations.\n" );
[ # # ][ # # ]
293 : 0 : continue;
294 : : }
295 : :
296 [ # # ]: 0 : curve_ptr = create_curve( *vec_list_ptr, surf_ptr );
297 : :
298 [ # # ]: 0 : if( curve_ptr )
299 : : {
300 [ # # ]: 0 : curve_list.append( curve_ptr );
301 [ # # ][ # # ]: 0 : if( DEBUG_FLAG( 100 ) )
[ # # ]
302 [ # # ]: 0 : draw_preview( curve_ptr, CUBIT_TRUE, CUBIT_RED_INDEX );
303 : : }
304 : : }
305 : :
306 [ # # ][ # # ]: 0 : if( !curve_list.size() )
307 : 0 : return CUBIT_FAILURE;
308 : :
309 : 0 : return CUBIT_SUCCESS;
310 : : }
311 : :
312 : : CubitStatus
313 : 0 : SplitSurfaceTool::split_surface( RefFace *ref_face_ptr, DLIList<Curve*> &curve_list)
314 : : {
315 : : // Count number of surfaces in owning body prior to split - this is used to
316 : : // determine if split is actually successful.
317 : : Body *body_ptr;
318 [ # # ]: 0 : int num_surfaces_prior = count_surfaces_in_owning_body( ref_face_ptr, body_ptr );
319 [ # # ]: 0 : int num_curves_prior = count_curves_in_body( body_ptr );
320 : :
321 [ # # ]: 0 : if( num_surfaces_prior == -1 )
322 : : {
323 [ # # ][ # # ]: 0 : PRINT_ERROR( "Cannot split a surface that is not part of a volume\n" );
[ # # ][ # # ]
324 : 0 : return CUBIT_FAILURE;
325 : : }
326 [ # # ]: 0 : else if( num_surfaces_prior == -2 )
327 : : {
328 [ # # ][ # # ]: 0 : PRINT_ERROR( "Cannot split a surface that is contained by multiple volumes\n" );
[ # # ][ # # ]
329 : 0 : return CUBIT_FAILURE;
330 : : }
331 : :
332 : : // Clear any previews
333 [ # # ]: 0 : GfxPreview::clear();
334 : :
335 : : // Perform the split on the real (e.g. OCC) geometry.
336 [ # # ]: 0 : Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
337 : :
338 [ # # ]: 0 : DLIList<Surface*> surface_list;
339 [ # # ]: 0 : surface_list.append( surf_ptr );
340 [ # # ][ # # ]: 0 : DLIList<DLIList<Curve*>*> curve_lists_list;
341 [ # # ]: 0 : curve_lists_list.append( &curve_list );
342 : :
343 : : Body *new_body_ptr;
344 : :
345 [ # # ]: 0 : if( GeometryModifyTool::instance()->imprint( surface_list,
346 [ # # ][ # # ]: 0 : curve_lists_list, new_body_ptr ) == CUBIT_FAILURE )
347 : : {
348 [ # # ][ # # ]: 0 : while( curve_list.size() )
349 [ # # ][ # # ]: 0 : delete curve_list.pop();
[ # # ]
350 : 0 : return CUBIT_FAILURE;
351 : : }
352 : :
353 [ # # ][ # # ]: 0 : while( curve_list.size() )
354 [ # # ][ # # ]: 0 : delete curve_list.pop();
[ # # ]
355 : :
356 : : // Draw locations too
357 : : // draw_points( locations, CUBIT_BLUE_INDEX );
358 : :
359 [ # # ]: 0 : int num_surfaces_after = count_surfaces_in_body( body_ptr );
360 : :
361 [ # # ]: 0 : if( num_surfaces_after > num_surfaces_prior )
362 : 0 : return CUBIT_SUCCESS;
363 : : else
364 : : {
365 [ # # ]: 0 : int num_curves_after = count_curves_in_body( body_ptr );
366 [ # # ]: 0 : if( num_curves_after > num_curves_prior )
367 : 0 : return CUBIT_SUCCESS;
368 : : }
369 : :
370 [ # # ][ # # ]: 0 : PRINT_ERROR( "Split failed - surface %d was not split\n", ref_face_ptr->id() );
[ # # ][ # # ]
[ # # ]
371 [ # # ]: 0 : return CUBIT_FAILURE;
372 : : }
373 : :
374 : : CubitStatus
375 : 0 : SplitSurfaceTool::split_surface( RefFace *ref_face_ptr,
376 : : DLIList<DLIList<CubitVector*>*> &vec_lists )
377 : : {
378 : : // Count number of surfaces in owning body prior to split - this is used to
379 : : // determine if split is actually successful.
380 : : Body *body_ptr;
381 [ # # ]: 0 : int num_surfaces_prior = count_surfaces_in_owning_body( ref_face_ptr, body_ptr );
382 [ # # ]: 0 : if( num_surfaces_prior == -1 )
383 : : {
384 [ # # ][ # # ]: 0 : PRINT_ERROR( "Cannot split a surface that is not part of a volume\n" );
[ # # ][ # # ]
385 : 0 : return CUBIT_FAILURE;
386 : : }
387 [ # # ]: 0 : else if( num_surfaces_prior == -2 )
388 : : {
389 [ # # ][ # # ]: 0 : PRINT_ERROR( "Cannot split a surface that is contained by multiple volumes\n" );
[ # # ][ # # ]
390 : 0 : return CUBIT_FAILURE;
391 : : }
392 [ # # ]: 0 : int num_curves_prior = count_curves_in_body( body_ptr );
393 : :
394 [ # # ]: 0 : int original_id = ref_face_ptr->id();
395 [ # # ]: 0 : Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
396 : :
397 : : // Clear any previews
398 [ # # ]: 0 : GfxPreview::clear();
399 : :
400 : : // Find the splitting curves
401 [ # # ]: 0 : DLIList<DLIList<Curve*>*> curve_lists_list;
402 : :
403 : : // Support composite surfaces by getting the surfaces underlying
404 : : // the composite and creating split curves for them individually.
405 [ # # ]: 0 : GeometryQueryEngine *gqe = surf_ptr->get_geometry_query_engine();
406 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> tbs;
407 [ # # ]: 0 : gqe->get_underlying_surfaces(surf_ptr, tbs);
408 : 0 : CubitStatus err = CUBIT_SUCCESS;
409 [ # # ][ # # ]: 0 : if(tbs.size() > 0)
410 : : {
411 : 0 : err = CUBIT_FAILURE;
412 [ # # ][ # # ]: 0 : for(int k=tbs.size(); k>0; k--)
413 : : {
414 [ # # ][ # # ]: 0 : Surface *srf = dynamic_cast<Surface*>(tbs.get_and_step());
415 [ # # ]: 0 : if(srf)
416 : : {
417 [ # # ][ # # ]: 0 : DLIList<Curve*> *curve_list = new DLIList<Curve*>;
418 [ # # ]: 0 : CubitStatus tmp_status = calculate_split_curves( srf, vec_lists, *curve_list );
419 : : // If at least one split is successful return success. We anticipate that some curves
420 : : // won't imprint on some of the underlying surfaces of the composite surface. Because
421 : : // we are allowing success this way there are sometimes errors that get printed even
422 : : // though we are calling it a success. Need to find a good way to fix this.
423 [ # # ]: 0 : if(tmp_status)
424 : 0 : err = CUBIT_SUCCESS;
425 [ # # ]: 0 : curve_lists_list.append(curve_list);
426 : : }
427 : : }
428 : : }
429 : : else
430 : : {
431 [ # # ][ # # ]: 0 : DLIList<Curve*> *curve_list = new DLIList<Curve*>;
432 [ # # ]: 0 : err = calculate_split_curves( ref_face_ptr, vec_lists, *curve_list );
433 [ # # ]: 0 : curve_lists_list.append(curve_list);
434 : : }
435 : :
436 [ # # ]: 0 : if( err == CUBIT_FAILURE )
437 : : {
438 [ # # ][ # # ]: 0 : while(curve_lists_list.size())
439 : : {
440 [ # # ]: 0 : DLIList<Curve*> *cur_list = curve_lists_list.pop();
441 [ # # ][ # # ]: 0 : while(cur_list->size())
442 : : {
443 [ # # ]: 0 : Curve* curve_ptr = cur_list->pop();
444 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
445 : : }
446 [ # # ][ # # ]: 0 : delete cur_list;
447 : : }
448 : 0 : return CUBIT_FAILURE;
449 : : }
450 : :
451 : : // Perform the split on the real (e.g. OCC) geometry.
452 [ # # ][ # # ]: 0 : DLIList<Surface*> surface_list;
453 [ # # ]: 0 : surface_list.append( surf_ptr );
454 : :
455 : : Body *new_body_ptr;
456 : :
457 [ # # ]: 0 : if( GeometryModifyTool::instance()->imprint( surface_list,
458 [ # # ][ # # ]: 0 : curve_lists_list, new_body_ptr ) == CUBIT_FAILURE )
459 : : {
460 [ # # ][ # # ]: 0 : while(curve_lists_list.size())
461 : : {
462 [ # # ]: 0 : DLIList<Curve*> *cur_list = curve_lists_list.pop();
463 [ # # ][ # # ]: 0 : while(cur_list->size())
464 : : {
465 [ # # ]: 0 : Curve* curve_ptr = cur_list->pop();
466 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
467 : : }
468 [ # # ][ # # ]: 0 : delete cur_list;
469 : : }
470 : 0 : return CUBIT_FAILURE;
471 : : }
472 : :
473 [ # # ][ # # ]: 0 : while(curve_lists_list.size())
474 : : {
475 [ # # ]: 0 : DLIList<Curve*> *cur_list = curve_lists_list.pop();
476 [ # # ][ # # ]: 0 : while(cur_list->size())
477 : : {
478 [ # # ]: 0 : Curve* curve_ptr = cur_list->pop();
479 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
480 : : }
481 [ # # ][ # # ]: 0 : delete cur_list;
482 : : }
483 : :
484 : : // Draw locations too
485 : : //draw_points( locations, CUBIT_BLUE_INDEX );
486 : :
487 [ # # ]: 0 : int num_surfaces_after = count_surfaces_in_body( body_ptr );
488 : :
489 [ # # ]: 0 : if( num_surfaces_after > num_surfaces_prior )
490 : 0 : return CUBIT_SUCCESS;
491 : : else
492 : : {
493 [ # # ]: 0 : int num_curves_after = count_curves_in_body( body_ptr );
494 [ # # ]: 0 : if( num_curves_after > num_curves_prior )
495 : 0 : return CUBIT_SUCCESS;
496 : : }
497 : :
498 [ # # ][ # # ]: 0 : PRINT_ERROR( "Split failed - surface %d was not split\n", original_id );
[ # # ][ # # ]
499 [ # # ]: 0 : return CUBIT_FAILURE;
500 : : }
501 : : //ADDED BY GJS (CAT) 6/26/08 @ 11:00am
502 : : CubitStatus
503 : 0 : SplitSurfaceTool::split_surface( DLIList<RefFace*> &ref_face_list,
504 : : DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists )
505 : : {
506 : : //Initialize inputs to imprint function call
507 [ # # ]: 0 : DLIList<Surface*> surface_list;
508 [ # # ][ # # ]: 0 : DLIList<DLIList<Curve*>*> curve_lists_list;
509 : :
510 : : // Clear any previews
511 [ # # ]: 0 : GfxPreview::clear();
512 : :
513 : : //Reset all lists
514 [ # # ]: 0 : ref_face_list.reset();
515 [ # # ]: 0 : list_of_vec_lists.reset();
516 : :
517 : : int hh;
518 [ # # ][ # # ]: 0 : for( hh = ref_face_list.size() ; hh > 0 ; hh--)
519 : : {
520 : : // Count number of surfaces in owning body prior to split - this is used to
521 : : // determine if split is actually successful. 0
522 [ # # ]: 0 : RefFace* ref_face_ptr = ref_face_list.get_and_step();
523 : : Body* body_ptr;
524 : :
525 [ # # ]: 0 : int num_surfaces_prior = count_surfaces_in_owning_body( ref_face_ptr, body_ptr );
526 [ # # ]: 0 : if( num_surfaces_prior == -1 )
527 : : {
528 [ # # ][ # # ]: 0 : PRINT_ERROR( "Cannot split a surface that is not part of a volume\n" );
[ # # ][ # # ]
529 : 0 : return CUBIT_FAILURE;
530 : : }
531 [ # # ]: 0 : else if( num_surfaces_prior == -2 )
532 : : {
533 [ # # ][ # # ]: 0 : PRINT_ERROR( "Cannot split a surface that is contained by multiple volumes\n" );
[ # # ][ # # ]
534 : 0 : return CUBIT_FAILURE;
535 : : }
536 [ # # ]: 0 : ref_face_ptr->id();
537 [ # # ]: 0 : Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
538 : :
539 : :
540 : :
541 : : // Support composite surfaces by getting the surfaces underlying
542 : : // the composite and creating split curves for them individually.
543 [ # # ]: 0 : GeometryQueryEngine *gqe = surf_ptr->get_geometry_query_engine();
544 [ # # ]: 0 : DLIList<TopologyBridge*> tbs;
545 [ # # ]: 0 : gqe->get_underlying_surfaces(surf_ptr, tbs);
546 : 0 : CubitStatus err = CUBIT_SUCCESS;
547 [ # # ][ # # ]: 0 : if(tbs.size() > 0)
548 : : {
549 : 0 : err = CUBIT_FAILURE;
550 [ # # ][ # # ]: 0 : for(int k=tbs.size(); k>0; k--)
551 : : {
552 [ # # ][ # # ]: 0 : Surface *srf = dynamic_cast<Surface*>(tbs.get_and_step());
553 [ # # ]: 0 : if(srf)
554 : : {
555 [ # # ][ # # ]: 0 : DLIList<Curve*> *curve_list = new DLIList<Curve*>;
556 [ # # ][ # # ]: 0 : DLIList<DLIList<CubitVector*>*> temp_vec_lists = *( list_of_vec_lists.get_and_step() );
557 [ # # ]: 0 : CubitStatus tmp_status = calculate_split_curves( srf, temp_vec_lists, *curve_list );
558 : : // If at least one split is successful return success. We anticipate that some curves
559 : : // won't imprint on some of the underlying surfaces of the composite surface. Because
560 : : // we are allowing success this way there are sometimes errors that get printed even
561 : : // though we are calling it a success. Need to find a good way to fix this.
562 [ # # ]: 0 : if(tmp_status)
563 : 0 : err = CUBIT_SUCCESS;
564 [ # # ][ # # ]: 0 : curve_lists_list.append(curve_list);
565 : : }
566 : : }
567 : : }
568 : : else
569 : : {
570 [ # # ][ # # ]: 0 : DLIList<Curve*> *curve_list = new DLIList<Curve*>;
571 [ # # ][ # # ]: 0 : DLIList<DLIList<CubitVector*>*> temp_vec_lists = *( list_of_vec_lists.get_and_step() );
572 [ # # ]: 0 : err = calculate_split_curves( ref_face_ptr, temp_vec_lists, *curve_list );
573 [ # # ][ # # ]: 0 : curve_lists_list.append(curve_list);
574 : : }
575 : :
576 [ # # ]: 0 : if( err == CUBIT_FAILURE )
577 : : {
578 [ # # ][ # # ]: 0 : while(curve_lists_list.size())
579 : : {
580 [ # # ]: 0 : DLIList<Curve*> *cur_list = curve_lists_list.pop();
581 [ # # ][ # # ]: 0 : while(cur_list->size())
582 [ # # ][ # # ]: 0 : delete cur_list->pop();
[ # # ]
583 [ # # ][ # # ]: 0 : delete cur_list;
584 : : }
585 : 0 : return CUBIT_FAILURE;
586 : : }
587 : :
588 [ # # ][ # # ]: 0 : surface_list.append( surf_ptr );
[ # # ]
589 : 0 : }
590 : :
591 : : // Perform the split on the real (e.g. OCC) geometry.
592 : : Body *new_body_ptr;
593 : :
594 [ # # ]: 0 : if( GeometryModifyTool::instance()->imprint( surface_list,
595 [ # # ][ # # ]: 0 : curve_lists_list, new_body_ptr ) == CUBIT_FAILURE )
596 : : {
597 [ # # ][ # # ]: 0 : while(curve_lists_list.size())
598 : : {
599 [ # # ]: 0 : DLIList<Curve*> *cur_list = curve_lists_list.pop();
600 [ # # ][ # # ]: 0 : while(cur_list->size())
601 [ # # ][ # # ]: 0 : delete cur_list->pop();
[ # # ]
602 [ # # ][ # # ]: 0 : delete cur_list;
603 : : }
604 : 0 : return CUBIT_FAILURE;
605 : : }
606 : :
607 [ # # ][ # # ]: 0 : while(curve_lists_list.size())
608 : : {
609 [ # # ]: 0 : DLIList<Curve*> *cur_list = curve_lists_list.pop();
610 [ # # ][ # # ]: 0 : while(cur_list->size())
611 [ # # ][ # # ]: 0 : delete cur_list->pop();
[ # # ]
612 [ # # ][ # # ]: 0 : delete cur_list;
613 : : }
614 : :
615 : : //NOTE: current assumption is failure will not occur since user does not
616 : : // control input parameters to this function (may need to fix).
617 : : //int num_surfaces_after = count_surfaces_in_body( body_ptr );
618 : :
619 : : //if( num_surfaces_after > num_surfaces_prior )
620 : : // return CUBIT_SUCCESS;
621 : : //else
622 : : //{
623 : : // int num_curves_after = count_curves_in_body( body_ptr );
624 : : // if( num_curves_after > num_curves_prior )
625 : : // return CUBIT_SUCCESS;
626 : : //}
627 : :
628 : : //PRINT_ERROR( "Split failed - surface %d was not split\n", original_id );
629 : : //return CUBIT_FAILURE;
630 : :
631 [ # # ]: 0 : return CUBIT_SUCCESS;
632 : : }
633 : :
634 : : CubitStatus
635 : 0 : SplitSurfaceTool::draw_points( DLIList<CubitVector*> &pnt_list, int color,
636 : : int flush )
637 : : {
638 : : int i;
639 [ # # ]: 0 : for( i=pnt_list.size(); i--; )
640 : : {
641 : 0 : CubitVector *pnt_ptr = pnt_list.get_and_step();
642 : 0 : draw_point( *pnt_ptr, color );
643 : : }
644 : :
645 [ # # ]: 0 : if( flush )
646 : : {
647 : 0 : GfxPreview::flush();
648 : : }
649 : :
650 : 0 : return CUBIT_SUCCESS;
651 : : }
652 : :
653 : : CubitStatus
654 : 0 : SplitSurfaceTool::draw_point( CubitVector &pnt, int color, int flush )
655 : : {
656 : 0 : GfxPreview::draw_point( pnt, color );
657 [ # # ]: 0 : if( flush )
658 : : {
659 : 0 : GfxPreview::flush();
660 : : }
661 : 0 : return CUBIT_SUCCESS;
662 : : }
663 : :
664 : : CubitStatus
665 : 0 : SplitSurfaceTool::split_surfaces( DLIList<RefFace*> &ref_face_list,
666 : : int num_segs,
667 : : double fraction,
668 : : double distance,
669 : : RefEdge *from_curve_ptr,
670 : : DLIList<RefVertex*> &corner_vertex_list,
671 : : DLIList<RefVertex*> &through_vertex_list,
672 : : RefEdge *curve_dir_ptr,
673 : : CubitBoolean preview_flg,
674 : : CubitBoolean create_ref_edges_flg )
675 : : {
676 : : CubitStatus status;
677 : :
678 : 0 : CubitBoolean just_curves_flg = CUBIT_FALSE;
679 [ # # ]: 0 : DLIList<DLIList<Curve*>*> curve_lists_list;
680 : :
681 : : // Clear any previous previews
682 [ # # ]: 0 : GfxPreview::clear();
683 : :
684 : : // Call the primary function
685 : : status = split_surfaces( ref_face_list, num_segs, fraction, distance,
686 : : from_curve_ptr, corner_vertex_list,
687 : : through_vertex_list, curve_dir_ptr,
688 : : preview_flg, create_ref_edges_flg,
689 [ # # ]: 0 : just_curves_flg, curve_lists_list );
690 : :
691 [ # # ]: 0 : free_curves_lists( curve_lists_list );
692 : :
693 [ # # ]: 0 : return status;
694 : : }
695 : :
696 : : CubitStatus
697 : 0 : SplitSurfaceTool::split_surfaces( DLIList<RefFace*> &ref_face_list,
698 : : int num_segs,
699 : : double fraction,
700 : : double distance,
701 : : RefEdge *from_curve_ptr,
702 : : DLIList<RefVertex*> &corner_vertex_list,
703 : : DLIList<RefVertex*> &through_vertex_list,
704 : : RefEdge *curve_dir_ptr,
705 : : DLIList<DLIList<Curve*>*> &curve_lists_list )
706 : : {
707 : : CubitStatus status;
708 : 0 : CubitBoolean preview_flg = CUBIT_FALSE;
709 : 0 : CubitBoolean create_ref_edges_flg = CUBIT_FALSE;
710 : 0 : CubitBoolean just_curves_flg = CUBIT_TRUE;
711 : :
712 : : // Call the primary function
713 : : status = split_surfaces( ref_face_list, num_segs, fraction, distance,
714 : : from_curve_ptr, corner_vertex_list,
715 : : through_vertex_list, curve_dir_ptr,
716 : : preview_flg, create_ref_edges_flg,
717 : 0 : just_curves_flg, curve_lists_list );
718 : :
719 : 0 : return status;
720 : : }
721 : :
722 : : CubitStatus
723 : 0 : SplitSurfaceTool::split_surfaces( DLIList<RefFace*> &ref_face_list,
724 : : int num_segs,
725 : : double fraction,
726 : : double distance,
727 : : RefEdge *from_curve_ptr,
728 : : DLIList<RefVertex*> &corner_vertex_list,
729 : : DLIList<RefVertex*> &through_vertex_list,
730 : : RefEdge *curve_dir_ptr,
731 : : DLIList<Curve*> &curve_list )
732 : : {
733 : : CubitStatus status;
734 : 0 : CubitBoolean preview_flg = CUBIT_FALSE;
735 : 0 : CubitBoolean create_ref_edges_flg = CUBIT_FALSE;
736 : 0 : CubitBoolean just_curves_flg = CUBIT_TRUE;
737 [ # # ]: 0 : DLIList<DLIList<Curve*>*> curve_lists_list;
738 : :
739 : : // Call the primary function
740 : : status = split_surfaces( ref_face_list, num_segs, fraction, distance,
741 : : from_curve_ptr, corner_vertex_list,
742 : : through_vertex_list, curve_dir_ptr,
743 : : preview_flg, create_ref_edges_flg,
744 [ # # ]: 0 : just_curves_flg, curve_lists_list );
745 : :
746 : : // Convert the curves to the simple curve_list
747 : : int i, j;
748 [ # # ]: 0 : curve_lists_list.reset();
749 [ # # ][ # # ]: 0 : for( i=curve_lists_list.size(); i--; )
750 : : {
751 [ # # ]: 0 : DLIList<Curve*> *curve_list_ptr = curve_lists_list.get_and_step();
752 : :
753 [ # # ]: 0 : curve_list_ptr->reset();
754 [ # # ][ # # ]: 0 : for( j=curve_list_ptr->size(); j--; )
755 : : {
756 [ # # ]: 0 : Curve *curve_ptr = curve_list_ptr->get_and_step();
757 [ # # ]: 0 : curve_list.append( curve_ptr );
758 : : }
759 : : }
760 : :
761 [ # # ]: 0 : free_curves_lists( curve_lists_list, CUBIT_FALSE );
762 : :
763 [ # # ]: 0 : return status;
764 : : }
765 : :
766 : : CubitStatus
767 : 0 : SplitSurfaceTool::calculate_split_curves( DLIList<RefFace*> &ref_face_list,
768 : : int num_segs,
769 : : double fraction,
770 : : double distance,
771 : : RefEdge *from_curve_ptr,
772 : : DLIList<RefVertex*> &corner_vertex_list,
773 : : DLIList<RefVertex*> &through_vertex_list,
774 : : RefEdge *curve_dir_ptr,
775 : : CubitBoolean preview_flg,
776 : : CubitBoolean create_ref_edges_flg,
777 : : CubitBoolean just_curves_flg,
778 : : DLIList<DLIList<Curve*>*> &curve_lists_list )
779 : : {
780 : : int i;
781 [ # # ]: 0 : refFaceChain = ref_face_list;
782 [ # # ]: 0 : throughVertexList = through_vertex_list;
783 : :
784 : : // Get tolerance and parametric_flg from member variables
785 : 0 : double tolerance = splitTolerance;
786 : 0 : CubitBoolean parametric_flg = parametricFlg;
787 : :
788 : : // Check for valid fraction
789 [ # # ][ # # ]: 0 : if( fraction<0.0 || fraction>1.0 )
790 : : {
791 [ # # ][ # # ]: 0 : PRINT_ERROR( "Fraction must be between 0.0 and 1.0 - aborting.\n" );
[ # # ][ # # ]
792 : 0 : return CUBIT_FAILURE;
793 : : }
794 : :
795 : : // Check for valid number of segments
796 [ # # ]: 0 : if( num_segs < 2 )
797 : : {
798 [ # # ][ # # ]: 0 : PRINT_ERROR( "Number of specified segments must be >= 2\n" );
[ # # ][ # # ]
799 : 0 : return CUBIT_FAILURE;
800 : : }
801 : :
802 : : // Not valid to specify through vertices with multiple segments
803 [ # # ][ # # ]: 0 : if( num_segs > 2 && throughVertexList.size() )
[ # # ][ # # ]
804 : : {
805 [ # # ][ # # ]: 0 : PRINT_ERROR( "Through vertices specified - not valid if number of segments > 2\n" );
[ # # ][ # # ]
806 : 0 : return CUBIT_FAILURE;
807 : : }
808 : :
809 : : // Check number of through vertices
810 [ # # ][ # # ]: 0 : if( throughVertexList.size() > refFaceChain.size()+1 )
[ # # ]
811 : : {
812 [ # # ][ # # ]: 0 : PRINT_ERROR( "Too many 'through' vertices specified.\n"
[ # # ]
813 [ # # ]: 0 : " Can only be equal to one more than the number of surfaces to split.\n" );
814 : 0 : return CUBIT_FAILURE;
815 : : }
816 : :
817 : : // If a distance was specified, set the parametric flag to FALSE
818 [ # # ]: 0 : if( distance != -1.0 )
819 : 0 : parametric_flg = CUBIT_FALSE;
820 : :
821 : : // Check the individual surfaces for errors (multiple loops, hardlines)
822 [ # # ][ # # ]: 0 : if( check_valid_faces() == CUBIT_FAILURE )
823 : 0 : return CUBIT_FAILURE;
824 : :
825 : : // Order the face list from one end of the chain to the other. This function
826 : : // also checks for the isLoop condition.
827 [ # # ][ # # ]: 0 : if( order_face_list() == CUBIT_FAILURE )
828 : 0 : return CUBIT_FAILURE;
829 [ # # ][ # # ]: 0 : if( DEBUG_FLAG(154) )
[ # # ]
830 : : {
831 [ # # ]: 0 : DLIList<CubitEntity*> cubit_faces;
832 [ # # ][ # # ]: 0 : CAST_LIST(refFaceChain, cubit_faces, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
833 : : CubitUtil::list_entity_ids( "\nOrdered surface list: ",
834 [ # # ][ # # ]: 0 : cubit_faces, 80, "\n", CUBIT_FALSE );
835 : : }
836 : :
837 : : // Get all the outer loops, in the proper order. This also makes sure
838 : : // they start at the beginning of the first surface in the chain.
839 [ # # ][ # # ]: 0 : if( get_outer_loops() == CUBIT_FAILURE )
840 : 0 : return CUBIT_FAILURE;
841 : :
842 : : // Make sure direction and from curves are valid, if specified
843 [ # # ][ # # ]: 0 : if( curve_dir_ptr && !is_curve_in_outer_loop( curve_dir_ptr ) )
[ # # ][ # # ]
844 : : {
845 [ # # ][ # # ]: 0 : PRINT_ERROR( "Specified direction curve %d not found on side of logical rectangle\n",
[ # # ][ # # ]
846 [ # # ]: 0 : curve_dir_ptr->id() );
847 : 0 : return CUBIT_FAILURE;
848 : : }
849 [ # # ][ # # ]: 0 : if( from_curve_ptr && !is_curve_in_outer_loop( from_curve_ptr ) )
[ # # ][ # # ]
850 : : {
851 [ # # ][ # # ]: 0 : PRINT_ERROR( "Specified from curve %d not found on side of logical rectangle\n",
[ # # ][ # # ]
852 [ # # ]: 0 : from_curve_ptr->id() );
853 : 0 : return CUBIT_FAILURE;
854 : : }
855 : :
856 : : // Find the corners
857 [ # # ][ # # ]: 0 : if( corner_vertex_list.size() )
858 : : {
859 [ # # ][ # # ]: 0 : if( corner_vertex_list.size() != 4 )
860 : : {
861 [ # # ][ # # ]: 0 : PRINT_ERROR( "You must select exactly 4 corner vertices\n" );
[ # # ][ # # ]
862 : 0 : return CUBIT_FAILURE;
863 : : }
864 : :
865 [ # # ]: 0 : if( isLoop )
866 : : {
867 [ # # ][ # # ]: 0 : PRINT_WARNING( "Ignoring specified corners since continuous loop situation\n" );
[ # # ][ # # ]
868 : : }
869 : : else
870 : : {
871 : : // Now order these vertices properly w/respect to the outerCoEdgeLoop
872 [ # # ][ # # ]: 0 : if( order_selected_corners( corner_vertex_list ) == CUBIT_FAILURE )
873 : 0 : return CUBIT_FAILURE;
874 : : }
875 : : }
876 : : else
877 : : {
878 : : // Pick the corners based on angle criteria
879 [ # # ][ # # ]: 0 : if( refFaceChain.size() > 1 )
880 : : {
881 [ # # ][ # # ]: 0 : if( pick_4_corners() == CUBIT_FAILURE )
882 : 0 : return CUBIT_FAILURE;
883 : : }
884 : : else
885 : : {
886 : : // Single surface case
887 [ # # ][ # # ]: 0 : if( pick_4_corners_simple() == CUBIT_FAILURE )
888 : 0 : return CUBIT_FAILURE;
889 : : }
890 : : }
891 : :
892 : : // Adjust the surface to the split direction. This function also adjusts
893 : : // and checks for errors if a throughVertexList was specified.
894 [ # # ][ # # ]: 0 : if( adjust_for_split_direction( curve_dir_ptr, from_curve_ptr, corner_vertex_list )
895 : : == CUBIT_FAILURE )
896 : 0 : return CUBIT_FAILURE;
897 : :
898 : : // If previewing, draw the corners in RED
899 [ # # ]: 0 : if( preview_flg == CUBIT_TRUE )
900 : : {
901 [ # # ][ # # ]: 0 : CubitVector temp_vec = start_vertex(cornerCoEdge[0])->coordinates();
902 : :
903 [ # # ]: 0 : draw_point( temp_vec, CUBIT_RED_INDEX );
904 [ # # ][ # # ]: 0 : temp_vec = start_vertex(cornerCoEdge[1])->coordinates();
[ # # ]
905 [ # # ]: 0 : draw_point( temp_vec, CUBIT_RED_INDEX );
906 [ # # ][ # # ]: 0 : temp_vec = start_vertex(cornerCoEdge[2])->coordinates();
[ # # ]
907 [ # # ]: 0 : draw_point( temp_vec, CUBIT_RED_INDEX );
908 [ # # ][ # # ]: 0 : temp_vec = start_vertex(cornerCoEdge[3])->coordinates();
[ # # ]
909 [ # # ]: 0 : draw_point( temp_vec, CUBIT_RED_INDEX, CUBIT_TRUE );
910 : : }
911 : :
912 [ # # ][ # # ]: 0 : if( DEBUG_FLAG(154) )
[ # # ]
913 : : {
914 [ # # ]: 0 : DLIList<RefEdge*> curve_list;
915 [ # # ]: 0 : get_outer_curves( curve_list );
916 [ # # ][ # # ]: 0 : DLIList<CubitEntity*> cubit_edges;
917 [ # # ][ # # ]: 0 : CAST_LIST(curve_list, cubit_edges, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
918 : : CubitUtil::list_entity_ids( "Ordered curves outer loop: ",
919 [ # # ]: 0 : cubit_edges, 80, "\n", CUBIT_FALSE );
920 : :
921 [ # # ][ # # ]: 0 : PRINT_INFO( "Best corner 1 = Vertex %d\n", start_vertex(cornerCoEdge[0])->id() );
[ # # ][ # # ]
[ # # ][ # # ]
922 [ # # ][ # # ]: 0 : PRINT_INFO( "Best corner 2 = Vertex %d\n", start_vertex(cornerCoEdge[1])->id() );
[ # # ][ # # ]
[ # # ][ # # ]
923 [ # # ][ # # ]: 0 : PRINT_INFO( "Best corner 3 = Vertex %d\n", start_vertex(cornerCoEdge[2])->id() );
[ # # ][ # # ]
[ # # ][ # # ]
924 [ # # ][ # # ]: 0 : PRINT_INFO( "Best corner 4 = Vertex %d\n", start_vertex(cornerCoEdge[3])->id() );
[ # # ][ # # ]
[ # # ][ # # ]
925 : :
926 [ # # ][ # # ]: 0 : PRINT_INFO( "Side interval #1 = %d\n", sideInterval[0] );
[ # # ][ # # ]
927 [ # # ][ # # ]: 0 : PRINT_INFO( "Side interval #2 = %d\n", sideInterval[1] );
[ # # ][ # # ]
928 [ # # ][ # # ]: 0 : PRINT_INFO( "Side interval #3 = %d\n", sideInterval[2] );
[ # # ][ # # ]
929 [ # # ][ # # ]: 0 : PRINT_INFO( "Side interval #4 = %d\n", sideInterval[3] );
[ # # ][ # # ]
[ # # ]
930 : : }
931 : :
932 : : // Add a tooldata to each surface for later use
933 : : RefFace *ref_face_ptr;
934 [ # # ]: 0 : refFaceChain.reset();
935 [ # # ][ # # ]: 0 : for( i=refFaceChain.size(); i--; )
936 : : {
937 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
938 [ # # ][ # # ]: 0 : ref_face_ptr->add_TD( new TDSplitSurface( ref_face_ptr ) );
[ # # ]
939 : : }
940 : :
941 : : // Add curve loops to each tooldata. These curve loops will form the
942 : : // boundary of a mapped mesh algorithm that will find the interior
943 : : // points for the split locations.
944 [ # # ][ # # ]: 0 : if( populate_curve_loops() == CUBIT_FAILURE )
945 : : {
946 [ # # ]: 0 : delete_surf_tooldatas( refFaceChain );
947 : 0 : return CUBIT_FAILURE;
948 : : }
949 : :
950 : : // Now build up the coordinates and get the curve(s) for each surface
951 : : // curve_lists_list will contain a list of curve lists for each surface
952 : :
953 : : // Keep track of new RefEdges created
954 [ # # ]: 0 : DLIList<RefEdge*> new_ref_edge_list;
955 : :
956 : : TDSplitSurface *tdss;
957 [ # # ]: 0 : refFaceChain.reset();
958 [ # # ][ # # ]: 0 : for(i=refFaceChain.size(); i--; )
959 : : {
960 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
961 : : tdss = (TDSplitSurface *)ref_face_ptr->
962 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
963 : :
964 : : // Setup matched curve tessellations on all curves (the tessellations
965 : : // are "matched" from side to side - the points on each side are
966 : : // at identical parameter values along the side). This is not a
967 : : // perfect solution but seems to work okay for the typical geometry
968 : : // types this tool is used on.
969 [ # # ]: 0 : if( tdss->tessellate_sides( tolerance, fraction, distance, num_segs,
970 [ # # ]: 0 : throughVertexList ) == CUBIT_FAILURE )
971 : : {
972 [ # # ]: 0 : delete_vertex_tooldatas( through_vertex_list );
973 [ # # ]: 0 : delete_surf_tooldatas( refFaceChain );
974 : 0 : return CUBIT_FAILURE;
975 : : }
976 : :
977 : : // curve_list_ptr will contain a list of curves for the individual surface
978 [ # # ][ # # ]: 0 : DLIList<Curve*> *curve_list_ptr = new DLIList<Curve*>;
979 [ # # ]: 0 : curve_lists_list.append( curve_list_ptr );
980 : :
981 : : // Use a mapping concept to get the spline coordinates of the curve to
982 : : // split with. The function find_spline_curves will populate curve_list_ptr
983 : : // with potentially multiple curves (typically there will only be one curve
984 : : // though).
985 [ # # ]: 0 : if( find_spline_curves( ref_face_ptr, num_segs, distance, curve_list_ptr,
986 : : tolerance, parametric_flg, preview_flg,
987 [ # # ]: 0 : create_ref_edges_flg ) == CUBIT_FAILURE )
988 : : {
989 [ # # ]: 0 : delete_vertex_tooldatas( throughVertexList );
990 [ # # ]: 0 : delete_surf_tooldatas( refFaceChain );
991 : 0 : return CUBIT_FAILURE;
992 : : }
993 : :
994 [ # # ]: 0 : if( just_curves_flg == CUBIT_TRUE )
995 : 0 : continue;
996 : :
997 [ # # ]: 0 : if( preview_flg == CUBIT_TRUE )
998 : : {
999 [ # # ]: 0 : if( create_ref_edges_flg == CUBIT_FALSE )
1000 [ # # ]: 0 : draw_preview( *curve_list_ptr );
1001 : : else
1002 : : {
1003 [ # # ]: 0 : create_ref_edges( *curve_list_ptr, new_ref_edge_list );
1004 : :
1005 : : // This just draws each curve as we go, same as preview does
1006 [ # # ]: 0 : GfxPreview::flush();
1007 : : }
1008 : : }
1009 : : }
1010 : :
1011 : : // Let the user know if new curves were created
1012 [ # # ][ # # ]: 0 : if( preview_flg == CUBIT_TRUE && create_ref_edges_flg == CUBIT_TRUE
1013 [ # # ][ # # ]: 0 : && new_ref_edge_list.size() )
[ # # ]
1014 : : {
1015 [ # # ]: 0 : DLIList<CubitEntity*> cubit_entity_list;
1016 [ # # ][ # # ]: 0 : CAST_LIST( new_ref_edge_list, cubit_entity_list, CubitEntity );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1017 [ # # ][ # # ]: 0 : CubitUtil::list_entity_ids( "Created new curves: ", cubit_entity_list );
1018 : : }
1019 : :
1020 : : // Determine if all of the 'through' vertices were used - if not give a warning
1021 [ # # ][ # # ]: 0 : if( throughVertexList.size() )
1022 : : {
1023 [ # # ]: 0 : DLIList<RefVertex*> non_used_through_vertex_list;
1024 : : RefVertex *ref_vertex_ptr;
1025 [ # # ]: 0 : throughVertexList.reset();
1026 [ # # ][ # # ]: 0 : for( i=throughVertexList.size(); i--; )
1027 : : {
1028 [ # # ]: 0 : ref_vertex_ptr = throughVertexList.get_and_step();
1029 : : tdss = (TDSplitSurface *)ref_vertex_ptr->
1030 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
1031 [ # # ]: 0 : if( !tdss )
1032 [ # # ]: 0 : non_used_through_vertex_list.append( ref_vertex_ptr );
1033 : : }
1034 : :
1035 [ # # ][ # # ]: 0 : if( non_used_through_vertex_list.size() )
1036 : : {
1037 [ # # ]: 0 : DLIList<CubitEntity*> cubit_verts;
1038 [ # # ][ # # ]: 0 : CAST_LIST(non_used_through_vertex_list, cubit_verts, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1039 : : CubitUtil::list_entity_ids( "WARNING - unused 'through' vertices: ",
1040 [ # # ]: 0 : cubit_verts, 80, "\n", CUBIT_FALSE );
1041 [ # # ][ # # ]: 0 : PRINT_INFO(" They were not found on the split path.\n" );
[ # # ][ # # ]
[ # # ]
1042 [ # # ]: 0 : }
1043 : : }
1044 : :
1045 : : // Remove tooldatas
1046 [ # # ]: 0 : delete_vertex_tooldatas( throughVertexList );
1047 [ # # ]: 0 : delete_surf_tooldatas( refFaceChain );
1048 : :
1049 [ # # ]: 0 : return CUBIT_SUCCESS;
1050 : : }
1051 : :
1052 : : //- Begin Private Functions
1053 : : CubitStatus
1054 : 0 : SplitSurfaceTool::split_surfaces( DLIList<RefFace*> &ref_face_list,
1055 : : int num_segs,
1056 : : double fraction,
1057 : : double distance,
1058 : : RefEdge *from_curve_ptr,
1059 : : DLIList<RefVertex*> &corner_vertex_list,
1060 : : DLIList<RefVertex*> &through_vertex_list,
1061 : : RefEdge *curve_dir_ptr,
1062 : : CubitBoolean preview_flg,
1063 : : CubitBoolean create_ref_edges_flg,
1064 : : CubitBoolean just_curves_flg,
1065 : : DLIList<DLIList<Curve*>*> &curve_lists_list )
1066 : : {
1067 : :
1068 : : // Find the splitting curves
1069 [ # # ]: 0 : if( calculate_split_curves( ref_face_list, num_segs, fraction, distance,
1070 : : from_curve_ptr, corner_vertex_list, through_vertex_list,
1071 : : curve_dir_ptr, preview_flg, create_ref_edges_flg,
1072 : 0 : just_curves_flg, curve_lists_list ) == CUBIT_FAILURE )
1073 : 0 : return CUBIT_FAILURE;
1074 : :
1075 : : // Do the splitting
1076 [ # # ][ # # ]: 0 : if( preview_flg==CUBIT_FALSE && just_curves_flg==CUBIT_FALSE )
1077 : : {
1078 : : int i;
1079 [ # # ]: 0 : DLIList<Surface*> surface_list;
1080 [ # # ]: 0 : refFaceChain.reset();
1081 [ # # ][ # # ]: 0 : for( i=refFaceChain.size(); i--; )
1082 [ # # ][ # # ]: 0 : surface_list.append( refFaceChain.get_and_step()->get_surface_ptr() );
[ # # ]
1083 : :
1084 : : Body *new_body_ptr;
1085 [ # # ]: 0 : if( GeometryModifyTool::instance()->imprint( surface_list,
1086 [ # # ][ # # ]: 0 : curve_lists_list, new_body_ptr ) == CUBIT_FAILURE )
1087 : : {
1088 [ # # ][ # # ]: 0 : return CUBIT_FAILURE;
1089 : 0 : }
1090 : : }
1091 : :
1092 : 0 : return CUBIT_SUCCESS;
1093 : : }
1094 : :
1095 : : void
1096 : 0 : SplitSurfaceTool::free_curves_lists( DLIList<DLIList<Curve*>*> &curve_lists_list,
1097 : : CubitBoolean free_curves_flg)
1098 : : {
1099 [ # # ]: 0 : while( curve_lists_list.size() )
1100 : : {
1101 : 0 : DLIList<Curve*> *curve_list_ptr = curve_lists_list.pop();
1102 : :
1103 [ # # ]: 0 : if( free_curves_flg == CUBIT_TRUE )
1104 : : {
1105 [ # # ]: 0 : while( curve_list_ptr->size() )
1106 : : {
1107 : 0 : Curve *curve_ptr = curve_list_ptr->pop();
1108 : :
1109 : : // If there is no RefEdge attached to this Curve, delete it
1110 [ # # ]: 0 : RefEdge* ref_edge_ptr = dynamic_cast<RefEdge*>(curve_ptr->topology_entity());
1111 [ # # ]: 0 : if( !ref_edge_ptr )
1112 : 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
1113 : : }
1114 : : }
1115 : :
1116 [ # # ]: 0 : delete curve_list_ptr;
1117 : : }
1118 : 0 : }
1119 : :
1120 : : void
1121 : 0 : SplitSurfaceTool::delete_surf_tooldatas( DLIList<RefFace*> &ref_face_list )
1122 : : {
1123 : : int i;
1124 [ # # ]: 0 : for( i=ref_face_list.size(); i--; )
1125 : : {
1126 : 0 : RefFace *ref_face_ptr = ref_face_list.get_and_step();
1127 : 0 : ref_face_ptr->delete_TD( &TDSplitSurface::is_split_surface );
1128 : : }
1129 : 0 : }
1130 : :
1131 : : void
1132 : 0 : SplitSurfaceTool::delete_coedge_tooldatas( DLIList<CoEdge*> &co_edge_list )
1133 : : {
1134 : : int i;
1135 [ # # ]: 0 : for( i=co_edge_list.size(); i--; )
1136 : : {
1137 : 0 : CoEdge *co_edge_ptr = co_edge_list.get_and_step();
1138 : 0 : co_edge_ptr->delete_TD( &TDSplitSurface::is_split_surface );
1139 : : }
1140 : 0 : }
1141 : :
1142 : : void
1143 : 0 : SplitSurfaceTool::delete_vertex_tooldatas( DLIList<RefVertex*> &ref_vertex_list )
1144 : : {
1145 : : int i;
1146 [ # # ]: 0 : for( i=ref_vertex_list.size(); i--; )
1147 : : {
1148 : 0 : RefVertex *ref_vertex_ptr = ref_vertex_list.get_and_step();
1149 : 0 : ref_vertex_ptr->delete_TD( &TDSplitSurface::is_split_surface );
1150 : : }
1151 : 0 : }
1152 : :
1153 : : CubitStatus
1154 : 0 : SplitSurfaceTool::check_valid_faces()
1155 : : {
1156 : : // Make sure each face doesn't have multiple loops or hardlines
1157 : : int i;
1158 : : RefFace *ref_face_ptr;
1159 : : CubitBoolean is_loop;
1160 [ # # ]: 0 : refFaceChain.reset();
1161 [ # # ][ # # ]: 0 : for( i=refFaceChain.size(); i--; )
1162 : : {
1163 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
1164 [ # # ][ # # ]: 0 : if( check_face_loop( ref_face_ptr, is_loop ) == CUBIT_FAILURE )
1165 : 0 : return CUBIT_FAILURE;
1166 : :
1167 [ # # ][ # # ]: 0 : if( refFaceChain.size()>1 && is_loop==CUBIT_TRUE )
[ # # ][ # # ]
1168 : : {
1169 [ # # ][ # # ]: 0 : PRINT_ERROR( "Surface %d loops back on itself - cannot split chain.\n",
[ # # ][ # # ]
1170 [ # # ]: 0 : ref_face_ptr->id() );
1171 : 0 : return CUBIT_FAILURE;
1172 : : }
1173 : : }
1174 : 0 : return CUBIT_SUCCESS;
1175 : : }
1176 : :
1177 : : CubitStatus
1178 : 0 : SplitSurfaceTool::order_face_list()
1179 : : {
1180 : : int i;
1181 : 0 : RefFace *ref_face_ptr = NULL;
1182 : :
1183 [ # # ][ # # ]: 0 : if( refFaceChain.size() > 1 )
1184 : : {
1185 : : // First make sure surfaces are at least connected
1186 [ # # ]: 0 : refFaceChain.reset();
1187 [ # # ][ # # ]: 0 : for( i=refFaceChain.size(); i--; )
1188 : : {
1189 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
1190 : :
1191 [ # # ]: 0 : DLIList<RefFace*> neighbor_ref_faces;
1192 [ # # ]: 0 : get_neighbors( ref_face_ptr, refFaceChain, neighbor_ref_faces );
1193 [ # # ][ # # ]: 0 : if( neighbor_ref_faces.size() == 0 )
1194 : : {
1195 [ # # ][ # # ]: 0 : PRINT_ERROR( "You must select a continuous chain of surfaces.\n"
[ # # ][ # # ]
1196 : : " Surface %d is not attached to the other surfaces.\n",
1197 [ # # ]: 0 : ref_face_ptr->id() );
1198 [ # # ][ # # ]: 0 : return CUBIT_FAILURE;
1199 : : }
1200 : 0 : }
1201 : : }
1202 : :
1203 [ # # ][ # # ]: 0 : if( refFaceChain.size() < 3 )
1204 : : {
1205 [ # # ][ # # ]: 0 : if( refFaceChain.size() == 1 )
1206 : : {
1207 : : // Check for isLoop situation. Assume we have a loop if some of
1208 : : // the RefEdges have 2 CoEdges that don't immediately loop back
1209 : : // on themselves (this is a hardline).
1210 [ # # ]: 0 : ref_face_ptr = refFaceChain.get();
1211 [ # # ][ # # ]: 0 : if( check_face_loop( ref_face_ptr, isLoop ) == CUBIT_FAILURE )
1212 : 0 : return CUBIT_FAILURE;
1213 : :
1214 : 0 : return CUBIT_SUCCESS;
1215 : : }
1216 : :
1217 [ # # ][ # # ]: 0 : if( refFaceChain.size() == 2 )
1218 : : {
1219 : : // Check for isLoop situation. Assume we have a loop if two separate
1220 : : // chains of curves from the first surface are shared by the second
1221 : : // surface.
1222 [ # # ]: 0 : refFaceChain.reset();
1223 [ # # ]: 0 : RefFace *ref_face_ptr1 = refFaceChain.get_and_step();
1224 [ # # ]: 0 : RefFace *ref_face_ptr2 = refFaceChain.get();
1225 : 0 : CoEdge *start_co_edge_ptr = NULL; // Dummy
1226 [ # # ][ # # ]: 0 : if( check_for_loop( ref_face_ptr1, ref_face_ptr2, isLoop, start_co_edge_ptr )
1227 : : == CUBIT_FAILURE )
1228 : 0 : return CUBIT_FAILURE;
1229 : : }
1230 : 0 : return CUBIT_SUCCESS;
1231 : : }
1232 : :
1233 : : // Get the face list going from one end to the other
1234 [ # # ]: 0 : DLIList<RefFace*> ordered_face_list;
1235 : :
1236 : : // Find an end - would have only one attached face
1237 : 0 : int found = 0;
1238 [ # # ]: 0 : refFaceChain.reset();
1239 [ # # ][ # # ]: 0 : for( i=refFaceChain.size(); i--; )
1240 : : {
1241 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
1242 : :
1243 [ # # ]: 0 : DLIList<RefFace*> neighbor_ref_faces;
1244 [ # # ]: 0 : get_neighbors( ref_face_ptr, refFaceChain, neighbor_ref_faces );
1245 [ # # ][ # # ]: 0 : if( neighbor_ref_faces.size() == 1 )
1246 : : {
1247 : 0 : found = 1;
1248 : 0 : break;
1249 : : }
1250 [ # # ][ # # ]: 0 : else if( neighbor_ref_faces.size() == 0 )
1251 : : {
1252 [ # # ][ # # ]: 0 : PRINT_ERROR( "You must select a continuous chain of surfaces.\n"
[ # # ][ # # ]
1253 : : " Surface %d is not attached to the other surfaces.\n",
1254 [ # # ]: 0 : ref_face_ptr->id() );
1255 [ # # ]: 0 : return CUBIT_FAILURE;
[ # # # ]
1256 : : }
1257 : 0 : }
1258 : :
1259 : : // Check for continuous loop of surfaces
1260 [ # # ]: 0 : if( !found )
1261 : : {
1262 : : // This is a continuous loop of surfaces - just use the first one the
1263 : : // user picked as starting surface of the patch.
1264 : 0 : isLoop = CUBIT_TRUE;
1265 [ # # ]: 0 : refFaceChain.reset();
1266 [ # # ]: 0 : ref_face_ptr = refFaceChain.get();
1267 : : }
1268 : :
1269 : : // Walk across the surfaces
1270 [ # # ]: 0 : ordered_face_list.append( ref_face_ptr );
1271 [ # # ][ # # ]: 0 : DLIList<RefFace*> remaining_face_list = refFaceChain;
1272 [ # # ]: 0 : remaining_face_list.remove( ref_face_ptr );
1273 [ # # ]: 0 : remaining_face_list.reset();
1274 [ # # ]: 0 : int num_faces = refFaceChain.size()-1;
1275 : :
1276 [ # # ]: 0 : for( i=num_faces; i--; )
1277 : : {
1278 [ # # ]: 0 : DLIList<RefFace*> neighbor_ref_faces;
1279 [ # # ]: 0 : get_neighbors( ref_face_ptr, remaining_face_list, neighbor_ref_faces );
1280 [ # # ][ # # ]: 0 : if( (!isLoop && neighbor_ref_faces.size() != 1) ||
[ # # ][ # # ]
1281 [ # # ][ # # ]: 0 : (i==num_faces-1 && isLoop && neighbor_ref_faces.size() != 2) ||
[ # # ][ # # ]
[ # # ]
1282 [ # # ][ # # ]: 0 : (i!=num_faces-1 && isLoop && neighbor_ref_faces.size() != 1) )
[ # # ]
1283 : : {
1284 [ # # ][ # # ]: 0 : PRINT_ERROR( "Selected surfaces do not appear to form logical rectangle\n" );
[ # # ][ # # ]
1285 : 0 : return CUBIT_FAILURE;
1286 : : }
1287 [ # # ]: 0 : neighbor_ref_faces.reset();
1288 [ # # ]: 0 : ref_face_ptr = neighbor_ref_faces.get();
1289 [ # # ]: 0 : ordered_face_list.append( ref_face_ptr );
1290 [ # # ][ # # ]: 0 : remaining_face_list.remove( ref_face_ptr );
[ # # ]
1291 : 0 : }
1292 : :
1293 [ # # ]: 0 : refFaceChain.clean_out();
1294 [ # # ]: 0 : ordered_face_list.reset();
1295 [ # # ]: 0 : refFaceChain = ordered_face_list;
1296 : :
1297 [ # # ]: 0 : return CUBIT_SUCCESS;
1298 : : }
1299 : :
1300 : : CubitStatus
1301 : 0 : SplitSurfaceTool::check_face_loop( RefFace *ref_face_ptr, CubitBoolean &is_loop )
1302 : : {
1303 : 0 : is_loop = CUBIT_FALSE;
1304 : :
1305 : : // Get list of coedges for this surface
1306 [ # # ]: 0 : DLIList<CoEdge*> co_edge_list;
1307 [ # # ][ # # ]: 0 : if( ordered_co_edges( ref_face_ptr, co_edge_list ) == CUBIT_FAILURE )
1308 : 0 : return CUBIT_FAILURE;
1309 : :
1310 : : int i;
1311 [ # # ]: 0 : co_edge_list.reset();
1312 : : CoEdge *co_edge_ptr;
1313 [ # # ][ # # ]: 0 : DLIList<RefEdge*> ref_edge_list;
1314 : : RefEdge *ref_edge_ptr;
1315 : 0 : int prev_i = -99;
1316 : 0 : RefEdge *prev_ref_edge_ptr = NULL;
1317 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
1318 : : {
1319 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
1320 [ # # ]: 0 : ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
1321 : :
1322 [ # # ][ # # ]: 0 : if( ref_edge_list.is_in_list( ref_edge_ptr ) )
1323 : : {
1324 : : // This may be a loop.
1325 : 0 : is_loop = CUBIT_TRUE;
1326 : :
1327 : : // Make sure it is not a hardline. Check for situation where loop
1328 : : // turns back on itself.
1329 : :
1330 [ # # ][ # # ]: 0 : if( ref_edge_ptr==prev_ref_edge_ptr && prev_i==i+1 )
1331 : : {
1332 [ # # ][ # # ]: 0 : PRINT_ERROR( "Detected hardline in Surface %d - cannot split.\n",
[ # # ][ # # ]
1333 [ # # ]: 0 : ref_face_ptr->id() );
1334 : 0 : return CUBIT_FAILURE;
1335 : : }
1336 : : }
1337 : :
1338 : 0 : prev_i = i;
1339 : 0 : prev_ref_edge_ptr = ref_edge_ptr;
1340 : :
1341 [ # # ]: 0 : ref_edge_list.append( ref_edge_ptr );
1342 : : }
1343 : :
1344 [ # # ]: 0 : return CUBIT_SUCCESS;
1345 : : }
1346 : :
1347 : : CubitStatus
1348 : 0 : SplitSurfaceTool::check_for_loop( RefFace *ref_face_ptr1, RefFace *ref_face_ptr2,
1349 : : CubitBoolean &is_loop, CoEdge *&start_co_edge_ptr )
1350 : : {
1351 : : // This algorithm is not perfect, but should cover most cases.
1352 : : RefEdge *ref_edge_ptr;
1353 : :
1354 : 0 : is_loop = CUBIT_FALSE;
1355 : :
1356 : : // Get list of coedges for the first surface
1357 [ # # ]: 0 : DLIList<CoEdge*> co_edge_list1;
1358 [ # # ][ # # ]: 0 : if( ordered_co_edges( ref_face_ptr1, co_edge_list1 ) == CUBIT_FAILURE )
1359 : 0 : return CUBIT_FAILURE;
1360 : :
1361 : : // Get list of refedges for the second surface
1362 [ # # ][ # # ]: 0 : DLIList<RefEdge*> ref_edge_list2;
1363 [ # # ][ # # ]: 0 : DLIList<Loop*> loop_list;
1364 [ # # ]: 0 : ref_face_ptr2->ordered_loops( loop_list );
1365 [ # # ][ # # ]: 0 : if( loop_list.size() > 1 )
1366 : : {
1367 [ # # ][ # # ]: 0 : PRINT_ERROR( "Only surfaces with a single loop are allowed.\n"
[ # # ][ # # ]
[ # # ]
1368 : : " Surface %d has %d loops.\n", ref_face_ptr2->id(),
1369 [ # # ]: 0 : loop_list.size() );
1370 : 0 : return CUBIT_FAILURE;
1371 : : }
1372 [ # # ][ # # ]: 0 : loop_list.get()->ordered_ref_edges( ref_edge_list2 );
1373 : :
1374 : : // Walk around the first surface
1375 : :
1376 : : // First, position the list at a starting coedge - one that is shared with
1377 : : // the other surface.
1378 : : int i, j;
1379 [ # # ]: 0 : co_edge_list1.reset();
1380 [ # # ][ # # ]: 0 : for( i=0; i<co_edge_list1.size(); i++ )
1381 : : {
1382 [ # # ][ # # ]: 0 : ref_edge_ptr = co_edge_list1.get()->get_ref_edge_ptr();
1383 : :
1384 [ # # ][ # # ]: 0 : if( ref_edge_list2.is_in_list( ref_edge_ptr ) )
1385 : : {
1386 [ # # ]: 0 : if( i==0 ) // Backup until we are at the start
1387 : : {
1388 [ # # ][ # # ]: 0 : for( j=co_edge_list1.size(); j--; )
1389 : : {
1390 [ # # ]: 0 : co_edge_list1.back();
1391 [ # # ][ # # ]: 0 : ref_edge_ptr = co_edge_list1.get()->get_ref_edge_ptr();
1392 [ # # ][ # # ]: 0 : if( ref_edge_list2.is_in_list( ref_edge_ptr ) )
1393 : 0 : continue;
1394 [ # # ]: 0 : co_edge_list1.step();
1395 : : }
1396 : : }
1397 : 0 : break;
1398 : : }
1399 [ # # ]: 0 : co_edge_list1.step();
1400 : : }
1401 : :
1402 : : // Now the list is positioned at the start of one of the shared chains of
1403 : : // curves.
1404 [ # # ]: 0 : start_co_edge_ptr = co_edge_list1.get();
1405 : :
1406 : : // Walk along the first surface
1407 : 0 : int found_break = 0;
1408 [ # # ][ # # ]: 0 : for( i=co_edge_list1.size(); i--; )
1409 : : {
1410 [ # # ][ # # ]: 0 : ref_edge_ptr = co_edge_list1.get_and_step()->get_ref_edge_ptr();
1411 : :
1412 [ # # ][ # # ]: 0 : if( found_break && ref_edge_list2.is_in_list( ref_edge_ptr ) )
[ # # ][ # # ]
1413 : : {
1414 : 0 : is_loop = CUBIT_TRUE;
1415 : 0 : return CUBIT_SUCCESS;
1416 : : }
1417 : :
1418 [ # # ][ # # ]: 0 : if( !ref_edge_list2.is_in_list( ref_edge_ptr ) )
1419 : 0 : found_break = 1;
1420 : : }
1421 : :
1422 [ # # ]: 0 : return CUBIT_SUCCESS;
1423 : : }
1424 : :
1425 : : CubitStatus
1426 : 0 : SplitSurfaceTool::get_neighbors( RefFace *seed_ref_face,
1427 : : DLIList<RefFace*> &input_ref_faces,
1428 : : DLIList<RefFace*> &neighbor_ref_faces )
1429 : : {
1430 : : int i, j;
1431 : :
1432 : : // Copy the input_ref_faces_copy list so as to not change it
1433 [ # # ][ # # ]: 0 : DLIList<RefFace*> input_ref_faces_copy(input_ref_faces.size());
1434 [ # # ]: 0 : input_ref_faces_copy = input_ref_faces;
1435 : :
1436 : : // Get the edges
1437 [ # # ][ # # ]: 0 : DLIList<RefEdge*> ref_edge_list;
1438 [ # # ]: 0 : seed_ref_face->ref_edges( ref_edge_list );
1439 : :
1440 : : // Get all ref_faces attached to these edges
1441 : : RefEdge *ref_edge_ptr;
1442 : : RefFace *ref_face_ptr;
1443 [ # # ][ # # ]: 0 : for( i=ref_edge_list.size(); i--; )
1444 : : {
1445 [ # # ]: 0 : ref_edge_ptr = ref_edge_list.get_and_step();
1446 : :
1447 [ # # ]: 0 : DLIList<RefFace*> attached_ref_faces;
1448 [ # # ]: 0 : ref_edge_ptr->ref_faces( attached_ref_faces );
1449 : :
1450 [ # # ][ # # ]: 0 : for( j=attached_ref_faces.size(); j--; )
1451 : : {
1452 [ # # ]: 0 : ref_face_ptr = attached_ref_faces.get_and_step();
1453 : :
1454 [ # # ]: 0 : if( ref_face_ptr == seed_ref_face )
1455 : 0 : continue;
1456 : :
1457 : : // Don't consider ref_faces that aren't in the input list
1458 [ # # ][ # # ]: 0 : if( input_ref_faces_copy.is_in_list( ref_face_ptr ) )
1459 : : {
1460 [ # # ]: 0 : neighbor_ref_faces.append_unique( ref_face_ptr );
1461 : : }
1462 : : }
1463 [ # # ]: 0 : }
1464 : :
1465 : : // Respect the incoming order of ref_faces
1466 [ # # ][ # # ]: 0 : if( neighbor_ref_faces.size() == 2 )
1467 : : {
1468 [ # # ]: 0 : input_ref_faces_copy.reset();
1469 [ # # ]: 0 : neighbor_ref_faces.reset();
1470 [ # # ]: 0 : RefFace *first_neighbor = neighbor_ref_faces.get_and_step();
1471 [ # # ]: 0 : RefFace *second_neighbor = neighbor_ref_faces.get_and_step();
1472 [ # # ][ # # ]: 0 : for( i=input_ref_faces_copy.size(); i--; )
1473 : : {
1474 [ # # ]: 0 : ref_face_ptr = input_ref_faces_copy.get_and_step();
1475 [ # # ]: 0 : if( ref_face_ptr == first_neighbor )
1476 : 0 : break;
1477 [ # # ]: 0 : else if( ref_face_ptr == second_neighbor )
1478 : : {
1479 : : // Reverse the order
1480 [ # # ]: 0 : neighbor_ref_faces.reverse();
1481 : 0 : break;
1482 : : }
1483 : : }
1484 : : }
1485 : :
1486 [ # # ]: 0 : return CUBIT_SUCCESS;
1487 : : }
1488 : :
1489 : : CubitStatus
1490 : 0 : SplitSurfaceTool::get_outer_loops()
1491 : : {
1492 : : // Get the outer curve loop
1493 [ # # ]: 0 : if( get_outer_coedge_loop() == CUBIT_FAILURE )
1494 : 0 : return CUBIT_FAILURE;
1495 : :
1496 : : // If we found a loop, we already setup the rest of the datastructures
1497 [ # # ]: 0 : if( isLoop )
1498 : 0 : return CUBIT_SUCCESS;
1499 : :
1500 : : // Make sure the loop has at least 3 vertices, to form at least a
1501 : : // degenerate rectangle
1502 [ # # ]: 0 : if( outerCoEdgeLoop.size() < 3 )
1503 : : {
1504 [ # # ][ # # ]: 0 : PRINT_ERROR( "Selected surfaces do not appear to form logical rectangle\n" );
1505 : 0 : return CUBIT_FAILURE;
1506 : : }
1507 : :
1508 : : // Orient the loops so they start at the first CoEdge of the
1509 : : // starting RefFace in the chain
1510 [ # # ]: 0 : if( refFaceChain.size() > 1 )
1511 : : {
1512 : 0 : refFaceChain.reset();
1513 : 0 : RefFace *first_ref_face = refFaceChain.get();
1514 : :
1515 : : // Move forward in the vertex list until we are on a surface
1516 : : // other than the first one
1517 : : int i;
1518 : 0 : CoEdge *co_edge_ptr = NULL;
1519 : 0 : outerCoEdgeLoop.reset();
1520 [ # # ]: 0 : for( i=outerCoEdgeLoop.size(); i--; )
1521 : : {
1522 : 0 : co_edge_ptr = outerCoEdgeLoop.get_and_step();
1523 [ # # ]: 0 : if( co_edge_ptr->get_ref_face() != first_ref_face )
1524 : 0 : break;
1525 : : }
1526 : :
1527 : : // Now move forward in the list until we are on the first surface
1528 [ # # ]: 0 : for( i=outerCoEdgeLoop.size(); i--; )
1529 : : {
1530 : 0 : co_edge_ptr = outerCoEdgeLoop.get();
1531 [ # # ]: 0 : if( co_edge_ptr->get_ref_face() == first_ref_face )
1532 : 0 : break;
1533 : 0 : outerCoEdgeLoop.step();
1534 : : }
1535 : :
1536 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "First vertex on first surface = %d\n", start_vertex( co_edge_ptr )->id() );
[ # # ]
1537 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "Index of vertex list = %d\n", outerCoEdgeLoop.get_index() );
[ # # ]
1538 : :
1539 : : // Reorient the lists appropriately
1540 : 0 : reorient_loop( outerCoEdgeLoop.get_index() );
1541 : :
1542 [ # # ]: 0 : if( DEBUG_FLAG(154) )
1543 : : {
1544 [ # # ]: 0 : DLIList<RefVertex*> ref_vertex_list;
1545 [ # # ]: 0 : get_outer_vertices( ref_vertex_list );
1546 [ # # ][ # # ]: 0 : DLIList<CubitEntity*> cubit_verts;
1547 [ # # ][ # # ]: 0 : CAST_LIST(ref_vertex_list, cubit_verts, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1548 : : CubitUtil::list_entity_ids( "New vertex list: ",
1549 [ # # ][ # # ]: 0 : cubit_verts, 80, "\n", CUBIT_FALSE );
1550 : : }
1551 : : }
1552 : :
1553 : 0 : return CUBIT_SUCCESS;
1554 : : }
1555 : :
1556 : : CubitStatus
1557 : 0 : SplitSurfaceTool::get_outer_coedge_loop()
1558 : : {
1559 : :
1560 : : // Walk around the loop
1561 : :
1562 : : // Start by gathering a list of all coedges
1563 : : int i;
1564 [ # # ]: 0 : DLIList<CoEdge*> co_edge_list;
1565 : :
1566 : : RefFace *ref_face_ptr;
1567 [ # # ]: 0 : refFaceChain.reset();
1568 [ # # ][ # # ]: 0 : for( i=refFaceChain.size(); i--; )
1569 : : {
1570 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
1571 [ # # ][ # # ]: 0 : if( ordered_co_edges( ref_face_ptr, co_edge_list ) == CUBIT_FAILURE )
1572 : 0 : return CUBIT_FAILURE;
1573 : : }
1574 : :
1575 : : // PRINT_INFO( "Entire coedge loop, starting at beginning -\n" );
1576 : : // PRINT_INFO( "-------------------------------------------\n" );
1577 : : // co_edge_list.reset();
1578 : : // for( i=co_edge_list.size(); i--; )
1579 : : // {
1580 : : // CoEdge *co_edge_ptr = co_edge_list.get_and_step();
1581 : : // PRINT_INFO( " Curve %d on Surface %d\n",
1582 : : // co_edge_ptr->get_ref_edge_ptr()->id(),
1583 : : // co_edge_ptr->get_ref_face()->id() );
1584 : : // }
1585 : :
1586 : : CoEdge *start_co_edge_ptr;
1587 [ # # ][ # # ]: 0 : if( find_loop_start( start_co_edge_ptr ) == CUBIT_FAILURE )
1588 : : {
1589 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to find loop start\n" ); // TODO: better message
[ # # ][ # # ]
1590 : 0 : return CUBIT_FAILURE;
1591 : : }
1592 : :
1593 : : // PRINT_INFO( "Loop start = Curve %d on Surface %d\n",
1594 : : // start_co_edge_ptr->get_ref_edge_ptr()->id(),
1595 : : // start_co_edge_ptr->get_ref_face()->id() );
1596 : :
1597 : : // Remove CoEdges on curves shared between surfaces (except for the starting
1598 : : // chain for isLoop situation). For isLoop, lets create a list of those to
1599 : : // be added back in later (keep_co_edge_list).
1600 [ # # ][ # # ]: 0 : DLIList<CoEdge*> keep_co_edge_list;
1601 : : CoEdge *shared_co_edge_ptr;
1602 : : CoEdge *co_edge_ptr;
1603 [ # # ]: 0 : if( isLoop )
1604 : : {
1605 : : // Method - traverse co_edge_list, adding coedges to keep_co_edge_list
1606 : : // until we don't find a coedge that shares a RefEdge with another coedge.
1607 : : // We use the term "complimentary" CoEdge to refer to the other CoEdge that
1608 : : // shares the common RefEdge.
1609 : : //
1610 : : // To illustrate, in the diagram below, assume S1 is the first surface and
1611 : : // S2 is the last surface in the surface loop we are splitting (note that
1612 : : // S1 can equal S2). C1, C2 and C3 make up the "chain" of curvs, or "seam"
1613 : : // that is between S1 and S2. Note that C1 has 2 CoEdges, one owned by S1
1614 : : // and one owned by S2. So, starting at C1 on S1, we step through the list
1615 : : // until we encounter a CoEdge that does not have a "complimentary" CoEdge.
1616 : : // Just keep track of the CoEdges as we go.
1617 : : //
1618 : : // ------------+------------
1619 : : // . | .
1620 : : // . |C1 .
1621 : : // . | .
1622 : : // . ^ + | .
1623 : : // . | | | .
1624 : : // . S2 | |C2 | S1 .
1625 : : // . | | v .
1626 : : // . + .
1627 : : // . | .
1628 : : // . |C3 .
1629 : : // . | .
1630 : : // ------------+------------
1631 : :
1632 : : // For this code, it is important that all the ordered coedges from the
1633 : : // starting surface are at the beginning of the co_edge_list (otherwise, we
1634 : : // will traverse partway up the first chain and then back). So we rebuild
1635 : : // co_edge_list - putting all the ordered coedges from the first surface at
1636 : : // the beginning of co_edge_list.
1637 [ # # ]: 0 : DLIList<CoEdge*> temp_co_edge_list = co_edge_list;
1638 [ # # ]: 0 : temp_co_edge_list.move_to( start_co_edge_ptr );
1639 [ # # ]: 0 : co_edge_list.clean_out();
1640 : :
1641 [ # # ]: 0 : RefFace *start_ref_face_ptr = start_co_edge_ptr->get_ref_face();
1642 : :
1643 [ # # ][ # # ]: 0 : for( i=temp_co_edge_list.size(); i--; )
1644 : : {
1645 [ # # ]: 0 : co_edge_ptr = temp_co_edge_list.get();
1646 [ # # ][ # # ]: 0 : if( co_edge_ptr->get_ref_face() == start_ref_face_ptr )
1647 : : {
1648 [ # # ]: 0 : co_edge_list.append( co_edge_ptr );
1649 [ # # ]: 0 : temp_co_edge_list.change_to( NULL );
1650 : : }
1651 [ # # ]: 0 : temp_co_edge_list.step();
1652 : : }
1653 [ # # ]: 0 : temp_co_edge_list.remove_all_with_value( NULL );
1654 : :
1655 [ # # ]: 0 : co_edge_list += temp_co_edge_list;
1656 : :
1657 : : // PRINT_INFO( "Entire coedge loop -\n" );
1658 : : // PRINT_INFO( "--------------------\n" );
1659 : : // co_edge_list.reset();
1660 : : // for( i=co_edge_list.size(); i--; )
1661 : : // {
1662 : : // CoEdge *co_edge_ptr = co_edge_list.get_and_step();
1663 : : // PRINT_INFO( " Curve %d on Surface %d\n",
1664 : : // co_edge_ptr->get_ref_edge_ptr()->id(),
1665 : : // co_edge_ptr->get_ref_face()->id() );
1666 : : // }
1667 : :
1668 : : // PRINT_INFO( "Coedges to keep - \n" );
1669 [ # # ]: 0 : co_edge_list.reset();
1670 [ # # ]: 0 : co_edge_ptr = co_edge_list.get();
1671 [ # # ]: 0 : RefFace *ref_ref_face_ptr = co_edge_ptr->get_ref_face();
1672 : : RefFace *shared_ref_face_ptr;
1673 [ # # ][ # # ]: 0 : shared_co_edge_ptr = get_complimentary_co_edge( co_edge_ptr, co_edge_list );
[ # # ]
1674 [ # # ]: 0 : RefFace *ref_shared_ref_face_ptr = shared_co_edge_ptr->get_ref_face();
1675 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
1676 : : {
1677 : : // Keep track of the starting and ending chain which we will lose in the
1678 : : // code below that removes all coedges that share a refedge. To do this,
1679 : : // add coedges until we don't find a shared one, or the reference surfaces
1680 : : // change (ref_ref_face_ptr || ref_shared_ref_face_ptr). Why look at
1681 : : // the reference surfaces? Because there could be a triangle as in the
1682 : : // diagram below.
1683 : : //
1684 : : // ------------+-------------
1685 : : // . | .
1686 : : // . |C1 .
1687 : : // . | .
1688 : : // . ^ + | S1 .
1689 : : // . | | | .
1690 : : // . S2 | |C2 | / .
1691 : : // . | | v / .
1692 : : // . + / .
1693 : : // . | / .
1694 : : // . |C3 / S3 .
1695 : : // . | / .
1696 : : // ------------+-------------
1697 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
1698 [ # # ]: 0 : ref_face_ptr = co_edge_ptr->get_ref_face();
1699 [ # # ][ # # ]: 0 : shared_co_edge_ptr = get_complimentary_co_edge( co_edge_ptr, co_edge_list );
[ # # ]
1700 [ # # ]: 0 : if( !shared_co_edge_ptr )
1701 : 0 : break;
1702 [ # # ]: 0 : shared_ref_face_ptr = shared_co_edge_ptr->get_ref_face();
1703 [ # # ][ # # ]: 0 : if( ref_face_ptr==ref_ref_face_ptr &&
1704 : : shared_ref_face_ptr==ref_shared_ref_face_ptr )
1705 : : {
1706 [ # # ]: 0 : keep_co_edge_list.append( co_edge_ptr );
1707 : : // PRINT_INFO( " Keeping Curve %d on Surface %d\n",
1708 : : // co_edge_ptr->get_ref_edge_ptr()->id(),
1709 : : // co_edge_ptr->get_ref_face()->id() );
1710 [ # # ]: 0 : keep_co_edge_list.append( shared_co_edge_ptr );
1711 : : // PRINT_INFO( " Keeping Curve %d on Surface %d\n",
1712 : : // shared_co_edge_ptr->get_ref_edge_ptr()->id(),
1713 : : // shared_co_edge_ptr->get_ref_face()->id() );
1714 : : }
1715 : : else
1716 : : break;
1717 [ # # ]: 0 : }
1718 : : }
1719 : :
1720 : : // Remove all coedges that share a RefEdge
1721 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
1722 : : {
1723 : : // Add coedges until we don't find a shared one - this adds just the
1724 : : // first chain.
1725 [ # # ]: 0 : co_edge_ptr = co_edge_list.get();
1726 [ # # ]: 0 : if( co_edge_ptr == NULL )
1727 : : {
1728 [ # # ]: 0 : co_edge_list.step();
1729 : 0 : continue;
1730 : : }
1731 [ # # ][ # # ]: 0 : shared_co_edge_ptr = get_complimentary_co_edge( co_edge_ptr, co_edge_list );
[ # # ]
1732 [ # # ]: 0 : if( shared_co_edge_ptr )
1733 : : {
1734 : : // This is not very efficient, but okay since we have relatively short
1735 : : // lists.
1736 [ # # ]: 0 : co_edge_list.move_to( shared_co_edge_ptr );
1737 : : // PRINT_INFO( " Removing Curve %d on Surface %d\n",
1738 : : // shared_co_edge_ptr->get_ref_edge_ptr()->id(),
1739 : : // shared_co_edge_ptr->get_ref_face()->id() );
1740 : :
1741 [ # # ]: 0 : co_edge_list.change_to( NULL );
1742 [ # # ]: 0 : co_edge_list.move_to( co_edge_ptr );
1743 : : // PRINT_INFO( " Removing Curve %d on Surface %d\n",
1744 : : // co_edge_ptr->get_ref_edge_ptr()->id(),
1745 : : // co_edge_ptr->get_ref_face()->id() );
1746 : :
1747 [ # # ]: 0 : co_edge_list.change_to( NULL );
1748 : : }
1749 [ # # ]: 0 : co_edge_list.step();
1750 : : }
1751 : :
1752 [ # # ]: 0 : co_edge_list.remove_all_with_value( NULL );
1753 : :
1754 : : // Add back in the removed coedges if isLoop
1755 [ # # ]: 0 : if( isLoop )
1756 : : {
1757 : : // Put them at the beginning for a slight efficiency gain
1758 [ # # ]: 0 : DLIList<CoEdge*> temp_co_edge_list = co_edge_list;
1759 [ # # ]: 0 : co_edge_list.clean_out();
1760 [ # # ]: 0 : co_edge_list += keep_co_edge_list;
1761 [ # # ][ # # ]: 0 : co_edge_list += temp_co_edge_list;
1762 : : }
1763 : :
1764 : : // Walk around the loop until we encounter the start coedge again.
1765 : : // Note loop is positioned at starting coedge.
1766 : 0 : CoEdge *prev_co_edge_ptr = start_co_edge_ptr;
1767 [ # # ]: 0 : outerCoEdgeLoop.append( start_co_edge_ptr );
1768 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
1769 : : {
1770 [ # # ]: 0 : co_edge_ptr = get_next_co_edge( prev_co_edge_ptr, co_edge_list );
1771 : :
1772 [ # # ]: 0 : if( co_edge_ptr == NULL )
1773 : : {
1774 [ # # ][ # # ]: 0 : PRINT_ERROR( "Selected surfaces do not appear to form logical rectangle\n" );
[ # # ][ # # ]
1775 : 0 : return CUBIT_FAILURE;
1776 : : }
1777 : :
1778 [ # # ]: 0 : if( co_edge_ptr == start_co_edge_ptr ) // We're done
1779 : 0 : break;
1780 : :
1781 [ # # ]: 0 : outerCoEdgeLoop.append( co_edge_ptr );
1782 : 0 : prev_co_edge_ptr = co_edge_ptr;
1783 [ # # ]: 0 : co_edge_list.remove( co_edge_ptr );
1784 : : }
1785 : :
1786 : : // Set the corners and such if isLoop
1787 [ # # ]: 0 : if( isLoop )
1788 : : {
1789 : : // Start of first curve is first corner
1790 : 0 : int best_corner_1, best_corner_2, best_corner_3=-1, best_corner_4=-1;
1791 : :
1792 : 0 : best_corner_1 = 0;
1793 [ # # ]: 0 : best_corner_2 = keep_co_edge_list.size()/2;
1794 [ # # ]: 0 : outerCoEdgeLoop.reset();
1795 [ # # ][ # # ]: 0 : for( i=0; i<outerCoEdgeLoop.size()+1; i++ )
1796 : : {
1797 [ # # ]: 0 : co_edge_ptr = outerCoEdgeLoop.get_and_step();
1798 [ # # ]: 0 : if( i == best_corner_1 )
1799 : : {
1800 : 0 : cornerCoEdge[0] = co_edge_ptr;
1801 : 0 : continue;
1802 : : }
1803 : :
1804 [ # # ]: 0 : if( i == best_corner_2 )
1805 : : {
1806 : 0 : cornerCoEdge[1] = co_edge_ptr;
1807 : 0 : continue;
1808 : : }
1809 : :
1810 [ # # ][ # # ]: 0 : if( start_vertex(co_edge_ptr) == start_vertex(cornerCoEdge[1]) )
[ # # ]
1811 : : {
1812 : 0 : best_corner_3 = i;
1813 : 0 : cornerCoEdge[2] = co_edge_ptr;
1814 : 0 : continue;
1815 : : }
1816 : :
1817 [ # # ][ # # ]: 0 : if( start_vertex(co_edge_ptr) == start_vertex(cornerCoEdge[0]) )
[ # # ]
1818 : : {
1819 [ # # ][ # # ]: 0 : if( i==outerCoEdgeLoop.size() )
1820 : 0 : best_corner_4 = i-1;
1821 : : else
1822 : 0 : best_corner_4 = i;
1823 : 0 : cornerCoEdge[3] = co_edge_ptr;
1824 : 0 : break;
1825 : : }
1826 : : }
1827 : :
1828 [ # # ][ # # ]: 0 : if( best_corner_3==-1 || best_corner_4==-1 )
1829 : : {
1830 [ # # ][ # # ]: 0 : PRINT_ERROR( "unable to find corners\n" );
[ # # ][ # # ]
1831 : 0 : return CUBIT_FAILURE;
1832 : : }
1833 : :
1834 [ # # ]: 0 : fill_side_intervals( best_corner_1, best_corner_2, best_corner_3, best_corner_4 );
1835 : : }
1836 : :
1837 [ # # ]: 0 : return CUBIT_SUCCESS;
1838 : : }
1839 : :
1840 : : CubitStatus
1841 : 0 : SplitSurfaceTool::find_loop_start( CoEdge *&start_co_edge_ptr )
1842 : : {
1843 : : // For non-isLoop situation, start of loop will be first non-shared curve
1844 : : // on surface loop
1845 : :
1846 : : int i, j;
1847 : : RefFace *ref_face_ptr;
1848 [ # # ]: 0 : if( !isLoop )
1849 : : {
1850 : : // First, get the outer curve loop of the surfaces
1851 [ # # ]: 0 : refFaceChain.reset();
1852 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
1853 : :
1854 [ # # ]: 0 : DLIList<CoEdge*> co_edge_list;
1855 [ # # ][ # # ]: 0 : if( ordered_co_edges( ref_face_ptr, co_edge_list ) == CUBIT_FAILURE )
1856 : 0 : return CUBIT_FAILURE;
1857 : :
1858 : : // If we have one surface just return
1859 [ # # ]: 0 : co_edge_list.reset();
1860 [ # # ][ # # ]: 0 : if( refFaceChain.size() == 1 )
1861 : : {
1862 [ # # ]: 0 : start_co_edge_ptr = co_edge_list.get();
1863 : 0 : return CUBIT_SUCCESS;
1864 : : }
1865 : :
1866 : : // Get the list of coedges in the next surface in the chain
1867 [ # # ]: 0 : ref_face_ptr = refFaceChain.get();
1868 [ # # ][ # # ]: 0 : DLIList<CoEdge*> next_co_edge_list;
1869 [ # # ][ # # ]: 0 : if( ordered_co_edges( ref_face_ptr, next_co_edge_list ) == CUBIT_FAILURE )
1870 : 0 : return CUBIT_FAILURE;
1871 : :
1872 : : // Find a coedge on first surface that shares a curve with the next surface
1873 : : CoEdge *co_edge_ptr;
1874 : : RefEdge *ref_edge_ptr;
1875 [ # # ]: 0 : co_edge_list.reset();
1876 : 0 : int found = 0;
1877 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
1878 : : {
1879 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
1880 [ # # ]: 0 : ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
1881 [ # # ][ # # ]: 0 : if( is_edge_in_list( ref_edge_ptr, next_co_edge_list ) )
1882 : : {
1883 : 0 : found = 1;
1884 : 0 : break;
1885 : : }
1886 : : }
1887 : :
1888 : : // This should never happen
1889 [ # # ]: 0 : if( !found )
1890 : : {
1891 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to find curves shared between surfaces\n" );
[ # # ][ # # ]
1892 : 0 : return CUBIT_FAILURE;
1893 : : }
1894 : :
1895 : : // Loop until we find a curve not shared with the other surface - this
1896 : : // is the start
1897 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
1898 : : {
1899 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
1900 [ # # ]: 0 : ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
1901 [ # # ][ # # ]: 0 : if( !is_edge_in_list( ref_edge_ptr, next_co_edge_list ) )
1902 : : {
1903 : 0 : start_co_edge_ptr = co_edge_ptr;
1904 : 0 : return CUBIT_SUCCESS;
1905 : : }
1906 : : }
1907 : :
1908 : : // This should never happen
1909 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to find start of loop - please report this\n" );
[ # # ][ # # ]
1910 [ # # ]: 0 : return CUBIT_FAILURE;
1911 : : }
1912 : :
1913 : : // isLoop situation
1914 [ # # ][ # # ]: 0 : if( refFaceChain.size() == 1 )
1915 : : {
1916 : : // Find first edge that has two coedges on this surface - this is the
1917 : : // start of the list
1918 [ # # ]: 0 : refFaceChain.reset();
1919 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
1920 : :
1921 [ # # ]: 0 : DLIList<CoEdge*> co_edge_list;
1922 [ # # ][ # # ]: 0 : if( ordered_co_edges( ref_face_ptr, co_edge_list ) == CUBIT_FAILURE )
1923 : 0 : return CUBIT_FAILURE;
1924 : :
1925 [ # # ]: 0 : co_edge_list.reset();
1926 [ # # ][ # # ]: 0 : for( i=0; i<co_edge_list.size(); i++ )
1927 : : {
1928 [ # # ][ # # ]: 0 : RefEdge *ref_edge_ptr = co_edge_list.get()->get_ref_edge_ptr();
1929 [ # # ][ # # ]: 0 : if( number_coedges( ref_edge_ptr, ref_face_ptr ) == 2 )
1930 : : {
1931 [ # # ]: 0 : if( i==0 ) // Backup until we are at the start
1932 : : {
1933 [ # # ][ # # ]: 0 : for( j=co_edge_list.size(); j--; )
1934 : : {
1935 [ # # ]: 0 : co_edge_list.back();
1936 [ # # ][ # # ]: 0 : ref_edge_ptr = co_edge_list.get()->get_ref_edge_ptr();
1937 [ # # ][ # # ]: 0 : if( number_coedges( ref_edge_ptr, ref_face_ptr ) == 1 )
1938 : 0 : break;
1939 [ # # ]: 0 : co_edge_list.step();
1940 : : }
1941 : : }
1942 : 0 : break;
1943 : : }
1944 [ # # ]: 0 : co_edge_list.step();
1945 : : }
1946 : :
1947 [ # # ]: 0 : start_co_edge_ptr = co_edge_list.get();
1948 [ # # ]: 0 : return CUBIT_SUCCESS;
1949 : : }
1950 : :
1951 [ # # ][ # # ]: 0 : if( refFaceChain.size() == 2 )
1952 : : {
1953 [ # # ]: 0 : refFaceChain.reset();
1954 [ # # ]: 0 : RefFace *ref_face_ptr1 = refFaceChain.get_and_step();
1955 [ # # ]: 0 : RefFace *ref_face_ptr2 = refFaceChain.get();
1956 : : CubitBoolean is_loop; // Dummy
1957 [ # # ]: 0 : return check_for_loop( ref_face_ptr1, ref_face_ptr2, is_loop, start_co_edge_ptr );
1958 : : }
1959 : :
1960 : : // Case refFaceChain.size() > 2
1961 : :
1962 : : // Use first and last surfaces. Also, adjust order of refFaceChain to
1963 : : // account for user's selection of start and end vertex, if selected.
1964 [ # # ]: 0 : refFaceChain.reset();
1965 [ # # ]: 0 : RefFace *start_surf = refFaceChain.get_and_back();
1966 [ # # ]: 0 : RefFace *end_surf = refFaceChain.get();
1967 : :
1968 : : // Get list of coedges for the first surface
1969 [ # # ]: 0 : DLIList<CoEdge*> start_co_edge_list;
1970 [ # # ][ # # ]: 0 : if( ordered_co_edges( start_surf, start_co_edge_list ) == CUBIT_FAILURE )
1971 : 0 : return CUBIT_FAILURE;
1972 : :
1973 : : // Get list of refedges for the last surface
1974 [ # # ][ # # ]: 0 : DLIList<RefEdge*> end_ref_edge_list;
1975 [ # # ][ # # ]: 0 : DLIList<Loop*> loop_list;
1976 [ # # ]: 0 : end_surf->ordered_loops( loop_list );
1977 [ # # ][ # # ]: 0 : loop_list.get()->ordered_ref_edges( end_ref_edge_list );
1978 : :
1979 : : // Walk around the first surface
1980 : : RefEdge *ref_edge_ptr;
1981 : :
1982 : : // First, position the list at a starting coedge - one that is shared with
1983 : : // the other surface.
1984 [ # # ]: 0 : start_co_edge_list.reset();
1985 [ # # ][ # # ]: 0 : for( i=0; i<start_co_edge_list.size(); i++ )
1986 : : {
1987 [ # # ][ # # ]: 0 : ref_edge_ptr = start_co_edge_list.get()->get_ref_edge_ptr();
1988 : :
1989 [ # # ][ # # ]: 0 : if( end_ref_edge_list.is_in_list( ref_edge_ptr ) )
1990 : : {
1991 [ # # ]: 0 : if( i==0 ) // Backup until we are at the start
1992 : : {
1993 [ # # ][ # # ]: 0 : for( j=start_co_edge_list.size(); j--; )
1994 : : {
1995 [ # # ]: 0 : start_co_edge_list.back();
1996 [ # # ][ # # ]: 0 : ref_edge_ptr = start_co_edge_list.get()->get_ref_edge_ptr();
1997 [ # # ][ # # ]: 0 : if( end_ref_edge_list.is_in_list( ref_edge_ptr ) )
1998 : 0 : continue;
1999 [ # # ]: 0 : start_co_edge_list.step();
2000 : : }
2001 : : }
2002 : 0 : break;
2003 : : }
2004 [ # # ]: 0 : start_co_edge_list.step();
2005 : : }
2006 : :
2007 : : // Now the list is positioned at the start of one of the shared chains of
2008 : : // curves.
2009 [ # # ]: 0 : start_co_edge_ptr = start_co_edge_list.get();
2010 : :
2011 [ # # ]: 0 : return CUBIT_SUCCESS;
2012 : : }
2013 : :
2014 : : CubitStatus
2015 : 0 : SplitSurfaceTool::get_outer_vertices( DLIList<RefVertex*> &ref_vertex_list )
2016 : : {
2017 : : int i;
2018 : :
2019 : 0 : outerCoEdgeLoop.reset();
2020 [ # # ]: 0 : for( i=outerCoEdgeLoop.size(); i--; )
2021 [ # # ]: 0 : ref_vertex_list.append( start_vertex( outerCoEdgeLoop.get_and_step() ) );
2022 : :
2023 : 0 : return CUBIT_SUCCESS;
2024 : : }
2025 : :
2026 : : CubitStatus
2027 : 0 : SplitSurfaceTool::get_outer_curves( DLIList<RefEdge*> &ref_edge_list )
2028 : : {
2029 : : int i;
2030 : :
2031 : 0 : outerCoEdgeLoop.reset();
2032 [ # # ]: 0 : for( i=outerCoEdgeLoop.size(); i--; )
2033 [ # # ]: 0 : ref_edge_list.append( outerCoEdgeLoop.get_and_step()->get_ref_edge_ptr() );
2034 : :
2035 : 0 : return CUBIT_SUCCESS;
2036 : : }
2037 : :
2038 : : CubitStatus
2039 : 0 : SplitSurfaceTool::populate_curve_loops()
2040 : : {
2041 : : int i;
2042 : : RefFace *ref_face_ptr;
2043 : : TDSplitSurface *tdss;
2044 : :
2045 [ # # ][ # # ]: 0 : if( refFaceChain.size() == 1 )
2046 : : {
2047 [ # # ]: 0 : ref_face_ptr = refFaceChain.get();
2048 [ # # ]: 0 : tdss = (TDSplitSurface *)ref_face_ptr->get_TD(&TDSplitSurface::is_split_surface);
2049 [ # # ]: 0 : tdss->add_coedges( outerCoEdgeLoop, sideInterval );
2050 : 0 : return CUBIT_SUCCESS;
2051 : : }
2052 : :
2053 : : // Steps
2054 : : // 1. Go through each CoEdge on outside, adding TD to each CoEdge
2055 : : // (with data for the start vertex of the CoEdge), marking them
2056 : : // per the code in the diagram below.
2057 : : //
2058 : : // 6 5 4
2059 : : // +----+---+
2060 : : // | |
2061 : : // | |
2062 : : // 7+ +3
2063 : : // | |
2064 : : // 7+----+---+3
2065 : : // | |
2066 : : // | |
2067 : : // 7+ +3
2068 : : // | |
2069 : : // 7+-+---+--+3
2070 : : // | |
2071 : : // | |
2072 : : // 7+ +3
2073 : : // | |
2074 : : // +---+----+
2075 : : // 0 1 2
2076 : : //
2077 : : //
2078 : : // 2. Traverse through the curves in each surface, assigning
2079 : : // curves to proper side of surface utilizing vertex classification
2080 : : // from above.
2081 : :
2082 : : // First gather a list of all coedges
2083 [ # # ]: 0 : DLIList<CoEdge*> all_co_edge_list;
2084 [ # # ]: 0 : refFaceChain.reset();
2085 [ # # ][ # # ]: 0 : for( i=refFaceChain.size(); i--; )
2086 : : {
2087 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
2088 [ # # ]: 0 : ordered_co_edges( ref_face_ptr, all_co_edge_list );
2089 : : }
2090 : :
2091 [ # # ]: 0 : refFaceChain.reset();
2092 [ # # ]: 0 : RefFace *start_surf = refFaceChain.get();
2093 [ # # ]: 0 : refFaceChain.last();
2094 [ # # ]: 0 : RefFace *end_surf = refFaceChain.get();
2095 : :
2096 : : // STEP 1
2097 : : CoEdge *co_edge_ptr;
2098 : 0 : int type = 0;
2099 [ # # ]: 0 : outerCoEdgeLoop.reset();
2100 [ # # ]: 0 : outerCoEdgeLoop.back();
2101 [ # # ]: 0 : CoEdge *prev_co_edge_ptr = outerCoEdgeLoop.get_and_step();
2102 [ # # ][ # # ]: 0 : for( i=0; i<outerCoEdgeLoop.size(); i++ )
2103 : : {
2104 [ # # ]: 0 : co_edge_ptr = outerCoEdgeLoop.get_and_step();
2105 : :
2106 : : // Get all CoEdges whose start vertices are attached to the start of this
2107 : : // CoEdge.
2108 [ # # ]: 0 : DLIList<CoEdge*> att_co_edge_list;
2109 [ # # ]: 0 : get_attached_coedges_start( co_edge_ptr, all_co_edge_list, att_co_edge_list );
2110 : : // This should never happen, but check anyway
2111 [ # # ][ # # ]: 0 : if( att_co_edge_list.size() == 0 )
2112 : : {
2113 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to find any curves attached to the start of Curve %d\n",
[ # # ][ # # ]
[ # # ]
2114 [ # # ]: 0 : co_edge_ptr->get_ref_edge_ptr()->id() );
2115 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2116 : 0 : return CUBIT_FAILURE;
2117 : : }
2118 : :
2119 : : // Remove CoEdges from outerCoEdgeLoop
2120 [ # # ]: 0 : att_co_edge_list -= outerCoEdgeLoop;
2121 : :
2122 : : // Add back in the current co_edge_ptr
2123 [ # # ]: 0 : att_co_edge_list.append( co_edge_ptr );
2124 : :
2125 : : // Special case - need to remove possible wrong CoEdges. If isLoop remove
2126 : : // all of the other CoEdges that are on the outerCoEdgeLoop (particularly
2127 : : // necessary as we traverse up and down the "seam", and at the corners).
2128 : : // If a corner, we need to deal with a possible triangle there by keeping
2129 : : // the proper CoEdge.
2130 [ # # ]: 0 : if( isLoop )
2131 : : {
2132 : : // Find corner number from i
2133 : 0 : int corner = -1;
2134 [ # # ]: 0 : if( i == 0 )
2135 : 0 : corner = 0;
2136 [ # # ]: 0 : else if( i == sideInterval[0] )
2137 : 0 : corner = 1;
2138 [ # # ]: 0 : else if( i == sideInterval[0] + sideInterval[1] )
2139 : 0 : corner = 2;
2140 [ # # ]: 0 : else if( i== sideInterval[0] + sideInterval[1] + sideInterval[2] )
2141 : 0 : corner = 3;
2142 : :
2143 [ # # ]: 0 : if( corner != -1 )
2144 : : {
2145 : : // Remove coedges that belong to the other corner shared by this corner
2146 [ # # ]: 0 : if( remove_other_corner_coedges( prev_co_edge_ptr, co_edge_ptr,
2147 [ # # ]: 0 : all_co_edge_list, att_co_edge_list ) == CUBIT_FAILURE )
2148 : : {
2149 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2150 : 0 : return CUBIT_FAILURE;
2151 : : }
2152 : : }
2153 : : }
2154 : :
2155 : : // DEBUG
2156 : : // if( att_co_edge_list.size() > 1 )
2157 : : // {
2158 : : // PRINT_INFO( "Att_co_edge_list.size() = %d\n", att_co_edge_list.size() );
2159 : : // att_co_edge_list.reset();
2160 : : // for( int k=att_co_edge_list.size(); k--; )
2161 : : // PRINT_INFO( " Adding TD to Curve = %d, Surface = %d\n", att_co_edge_list.get()->
2162 : : // get_ref_edge_ptr()->id(), att_co_edge_list.get_and_step()->get_ref_face()->id() );
2163 : : // }
2164 : : // else
2165 : : // PRINT_INFO( " Adding TD to Curve %d on Surface %d\n",
2166 : : // att_co_edge_list.get()->get_ref_edge_ptr()->id(),
2167 : : // att_co_edge_list.get()->get_ref_face()->id() );
2168 : :
2169 [ # # # # : 0 : switch (type)
# # ]
2170 : : {
2171 : : case 0:
2172 [ # # ][ # # ]: 0 : if( add_tooldata( att_co_edge_list, 0 ) == CUBIT_FAILURE )
2173 : : {
2174 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2175 : 0 : return CUBIT_FAILURE;
2176 : : }
2177 [ # # ]: 0 : if( cornerCoEdge[0] != cornerCoEdge[1] )
2178 : 0 : type = 1;
2179 : : else
2180 : 0 : type = 3;
2181 : 0 : break;
2182 : : case 1:
2183 [ # # ]: 0 : if( co_edge_ptr != cornerCoEdge[1] )
2184 : : {
2185 [ # # ][ # # ]: 0 : if( add_tooldata( att_co_edge_list, 1 ) == CUBIT_FAILURE )
2186 : : {
2187 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2188 : 0 : return CUBIT_FAILURE;
2189 : : }
2190 : : }
2191 : : else
2192 : : {
2193 [ # # ][ # # ]: 0 : if( add_tooldata( att_co_edge_list, 2 ) == CUBIT_FAILURE )
2194 : : {
2195 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2196 : 0 : return CUBIT_FAILURE;
2197 : : }
2198 [ # # ]: 0 : if( cornerCoEdge[1] != cornerCoEdge[2] )
2199 : 0 : type = 3;
2200 : : else
2201 : 0 : type = 5;
2202 : : }
2203 : 0 : break;
2204 : : case 3:
2205 [ # # ]: 0 : if( co_edge_ptr != cornerCoEdge[2] )
2206 : : {
2207 [ # # ][ # # ]: 0 : if( add_tooldata( att_co_edge_list, 3 ) == CUBIT_FAILURE )
2208 : : {
2209 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2210 : 0 : return CUBIT_FAILURE;
2211 : : }
2212 : : }
2213 : : else
2214 : : {
2215 [ # # ][ # # ]: 0 : if( add_tooldata( att_co_edge_list, 4 ) == CUBIT_FAILURE )
2216 : : {
2217 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2218 : 0 : return CUBIT_FAILURE;
2219 : : }
2220 [ # # ]: 0 : if( cornerCoEdge[2] != cornerCoEdge[3] )
2221 : 0 : type = 5;
2222 : : else
2223 : 0 : type = 7;
2224 : : }
2225 : 0 : break;
2226 : : case 5:
2227 [ # # ]: 0 : if( co_edge_ptr != cornerCoEdge[3] )
2228 : : {
2229 [ # # ][ # # ]: 0 : if( add_tooldata( att_co_edge_list, 5 ) == CUBIT_FAILURE )
2230 : : {
2231 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2232 : 0 : return CUBIT_FAILURE;
2233 : : }
2234 : : }
2235 : : else
2236 : : {
2237 [ # # ][ # # ]: 0 : if( add_tooldata( att_co_edge_list, 6 ) == CUBIT_FAILURE )
2238 : : {
2239 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2240 : 0 : return CUBIT_FAILURE;
2241 : : }
2242 : 0 : type = 7;
2243 : : }
2244 : 0 : break;
2245 : : case 7:
2246 [ # # ][ # # ]: 0 : if( add_tooldata( att_co_edge_list, 7 ) == CUBIT_FAILURE )
2247 : : {
2248 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2249 : 0 : return CUBIT_FAILURE;
2250 : : }
2251 : 0 : break;
2252 : : }
2253 : :
2254 [ # # ][ # # ]: 0 : prev_co_edge_ptr = co_edge_ptr;
2255 : :
2256 : 0 : }
2257 : :
2258 : : // Debug
2259 [ # # ][ # # ]: 0 : if( DEBUG_FLAG(154) )
[ # # ]
2260 : : {
2261 [ # # ]: 0 : outerCoEdgeLoop.reset();
2262 [ # # ][ # # ]: 0 : for( i=outerCoEdgeLoop.size(); i--; )
2263 : : {
2264 [ # # ]: 0 : co_edge_ptr = outerCoEdgeLoop.get_and_step();
2265 : : TDSplitSurface *tdssv = (TDSplitSurface *)co_edge_ptr->
2266 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
2267 : :
2268 [ # # ][ # # ]: 0 : PRINT_INFO( "Vertex %d - type %d\n", start_vertex( co_edge_ptr )->id(),
[ # # ][ # # ]
[ # # ][ # # ]
2269 [ # # ]: 0 : tdssv->get_type() );
2270 : : }
2271 : : }
2272 : :
2273 : : // STEP 2
2274 [ # # ]: 0 : refFaceChain.reset();
2275 [ # # ][ # # ]: 0 : for( i=0; i<refFaceChain.size(); i++ )
2276 : : {
2277 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
2278 : : tdss = (TDSplitSurface *)ref_face_ptr->
2279 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
2280 : :
2281 : : // Get loop of coedges on this surface
2282 [ # # ]: 0 : DLIList<CoEdge*> co_edge_list;
2283 [ # # ]: 0 : ordered_co_edges( ref_face_ptr, co_edge_list );
2284 : :
2285 : : // Now, get to the start of the loop. This will either be on vertex 0 or
2286 : : // the last vertex 7 (see diagram above).
2287 [ # # ]: 0 : position_co_edge_list( i, co_edge_list );
2288 : :
2289 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "Surface %d: start of loop = curve %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2290 [ # # ]: 0 : ref_face_ptr->id(), co_edge_list.get()->get_ref_edge_ptr()->id() );
2291 : :
2292 : : // Now that we have the loop positioned properly, we can add the proper
2293 : : // curves (classified by side) to the TD on the surface.
2294 [ # # ][ # # ]: 0 : DLIList<CoEdge*> side_coedges;
[ # # ]
2295 : 0 : int num_so_far = 0;
2296 : : // Check for special case - side A collapsed - triangle tip at start of
2297 : : // split
2298 [ # # ][ # # ]: 0 : if( ref_face_ptr == start_surf && cornerCoEdge[0] == cornerCoEdge[1] )
2299 : : ;
2300 : : else
2301 [ # # ]: 0 : get_a_coedges( co_edge_list, side_coedges );
2302 [ # # ]: 0 : num_so_far = side_coedges.size();
2303 : :
2304 : : // Side A could be collapsed (in case of triangle tip at start of split)
2305 [ # # ][ # # ]: 0 : if( side_coedges.size() )
2306 [ # # ]: 0 : tdss->add_a_coedges( side_coedges );
2307 : : else
2308 [ # # ][ # # ]: 0 : tdss->add_a_coedges( side_coedges, start_vertex( cornerCoEdge[0] ) );
2309 : :
2310 [ # # ]: 0 : side_coedges.clean_out();
2311 [ # # ]: 0 : get_b_coedges( co_edge_list, side_coedges );
2312 [ # # ]: 0 : num_so_far += side_coedges.size();
2313 : : // Side B could be collapsed (if we are on a triangle)
2314 [ # # ][ # # ]: 0 : if( side_coedges.size() )
2315 [ # # ]: 0 : tdss->add_b_coedges( side_coedges );
2316 : : else
2317 [ # # ][ # # ]: 0 : tdss->add_b_coedges( side_coedges, start_vertex( co_edge_list.get() ) );
[ # # ]
2318 : :
2319 [ # # ]: 0 : side_coedges.clean_out();
2320 : : // Check for special case - side C collapsed - triangle tip at end of
2321 : : // split
2322 [ # # ][ # # ]: 0 : if( ref_face_ptr == end_surf && cornerCoEdge[2] == cornerCoEdge[3] )
2323 : : ;
2324 : : else
2325 [ # # ]: 0 : get_c_coedges( co_edge_list, side_coedges );
2326 [ # # ]: 0 : num_so_far += side_coedges.size();
2327 : :
2328 : : // Side C could be collapsed (in case of triangle tip at end of split)
2329 [ # # ][ # # ]: 0 : if( side_coedges.size() )
2330 [ # # ]: 0 : tdss->add_c_coedges( side_coedges );
2331 : : else
2332 [ # # ][ # # ]: 0 : tdss->add_c_coedges( side_coedges, start_vertex( cornerCoEdge[2] ) );
2333 : :
2334 [ # # ]: 0 : side_coedges.clean_out();
2335 [ # # ]: 0 : if( get_d_coedges( co_edge_list, num_so_far,
2336 [ # # ]: 0 : side_coedges ) == CUBIT_FAILURE )
2337 : : {
2338 : : // Remove tooldatas from coedges
2339 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2340 : 0 : return CUBIT_FAILURE;
2341 : : }
2342 : :
2343 : : // Side D could be collapsed (if we are on a triangle)
2344 [ # # ][ # # ]: 0 : if( side_coedges.size() )
2345 [ # # ]: 0 : tdss->add_d_coedges( side_coedges );
2346 : : else
2347 [ # # ][ # # ]: 0 : tdss->add_d_coedges( side_coedges, start_vertex( co_edge_list.get() ) );
[ # # ][ # # ]
[ # # ]
2348 : 0 : }
2349 : :
2350 : : // Remove tooldatas from coedges
2351 [ # # ]: 0 : delete_coedge_tooldatas( all_co_edge_list );
2352 : :
2353 [ # # ]: 0 : return CUBIT_SUCCESS;
2354 : : }
2355 : :
2356 : : CubitStatus
2357 : 0 : SplitSurfaceTool::ordered_co_edges( RefFace *ref_face_ptr,
2358 : : DLIList<CoEdge*> &co_edge_list )
2359 : : {
2360 [ # # ]: 0 : DLIList<Loop*> loop_list;
2361 [ # # ]: 0 : ref_face_ptr->ordered_loops( loop_list );
2362 : :
2363 [ # # ][ # # ]: 0 : if( loop_list.size() > 1 )
2364 : : {
2365 [ # # ][ # # ]: 0 : PRINT_ERROR( "Only surfaces with a single loop are allowed.\n"
[ # # ][ # # ]
[ # # ]
2366 : : " Surface %d has %d loops.\n", ref_face_ptr->id(),
2367 [ # # ]: 0 : loop_list.size() );
2368 : :
2369 : : //if you are splitting a single surface across a vertex pair
2370 : : //recomment the 'split surface <id> across' command
2371 [ # # ][ # # ]: 0 : if( 1 == refFaceChain.size() && 2 == throughVertexList.size() )
[ # # ][ # # ]
[ # # ]
2372 [ # # ][ # # ]: 0 : PRINT_INFO("Perhaps try the 'Split Surface <id> Across ...' command instead.\n");
[ # # ][ # # ]
2373 : :
2374 : 0 : return CUBIT_FAILURE;
2375 : : }
2376 : :
2377 [ # # ][ # # ]: 0 : if( loop_list.size() == 0 )
2378 : : {
2379 [ # # ][ # # ]: 0 : PRINT_ERROR( "Surface %d does not contain any loops - cannot split\n",
[ # # ][ # # ]
2380 [ # # ]: 0 : ref_face_ptr->id() );
2381 : 0 : return CUBIT_FAILURE;
2382 : : }
2383 : :
2384 [ # # ][ # # ]: 0 : loop_list.get()->ordered_co_edges( co_edge_list );
2385 : :
2386 [ # # ]: 0 : return CUBIT_SUCCESS;
2387 : : }
2388 : :
2389 : : CoEdge *
2390 : 0 : SplitSurfaceTool::get_next_co_edge( CoEdge *prev_co_edge_ptr,
2391 : : DLIList<CoEdge*> &co_edge_list )
2392 : : {
2393 [ # # ]: 0 : RefVertex *end_vertex_ptr = end_vertex( prev_co_edge_ptr );
2394 : :
2395 : : // Find all potential connected coedges
2396 : : int i;
2397 : : CoEdge *co_edge_ptr;
2398 [ # # ]: 0 : DLIList<CoEdge*> connected_co_edge_list;
2399 [ # # ]: 0 : co_edge_list.reset();
2400 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
2401 : : {
2402 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
2403 [ # # ][ # # ]: 0 : if( end_vertex_ptr == start_vertex( co_edge_ptr ) )
2404 [ # # ]: 0 : connected_co_edge_list.append( co_edge_ptr );
2405 : : }
2406 : :
2407 : : // We should always have one or two connected coedges - if not error
2408 [ # # ][ # # ]: 0 : if( connected_co_edge_list.size() == 0 )
2409 : : {
2410 [ # # ][ # # ]: 0 : PRINT_ERROR( "Didn't find connected coedge after Curve %d on Surface %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2411 : : prev_co_edge_ptr->get_ref_edge_ptr()->id(),
2412 [ # # ]: 0 : prev_co_edge_ptr->get_ref_face()->id() );
2413 : 0 : return NULL;
2414 : : }
2415 [ # # ][ # # ]: 0 : else if( connected_co_edge_list.size() == 1 )
2416 : : {
2417 [ # # ]: 0 : return connected_co_edge_list.get();
2418 : : }
2419 [ # # ][ # # ]: 0 : else if( connected_co_edge_list.size() > 2 )
2420 : : {
2421 [ # # ][ # # ]: 0 : PRINT_ERROR( "Found %d coedges after Curve %d on Surface %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2422 : : connected_co_edge_list.size(),
2423 : : prev_co_edge_ptr->get_ref_edge_ptr()->id(),
2424 [ # # ]: 0 : prev_co_edge_ptr->get_ref_face()->id() );
2425 : 0 : return NULL;
2426 : : }
2427 [ # # ][ # # ]: 0 : else if( connected_co_edge_list.size() == 2 )
2428 : : {
2429 : : // Avoid looping back on ourselves
2430 [ # # ]: 0 : connected_co_edge_list.reset();
2431 [ # # ][ # # ]: 0 : if( prev_co_edge_ptr->get_ref_edge_ptr() ==
2432 [ # # ][ # # ]: 0 : connected_co_edge_list.get()->get_ref_edge_ptr() )
2433 [ # # ]: 0 : return connected_co_edge_list.step_and_get();
2434 : : else
2435 [ # # ]: 0 : return connected_co_edge_list.get();
2436 : : }
2437 : :
2438 [ # # ]: 0 : return NULL;
2439 : : }
2440 : :
2441 : : CubitBoolean
2442 : 0 : SplitSurfaceTool::is_edge_in_list( RefEdge *ref_edge_ptr, DLIList<CoEdge*> &co_edge_list )
2443 : : {
2444 : : int i;
2445 : : CoEdge *co_edge_ptr;
2446 [ # # ]: 0 : for( i=co_edge_list.size(); i--; )
2447 : : {
2448 : 0 : co_edge_ptr = co_edge_list.get_and_step();
2449 [ # # ]: 0 : if( co_edge_ptr->get_ref_edge_ptr() == ref_edge_ptr )
2450 : 0 : return CUBIT_TRUE;
2451 : : }
2452 : 0 : return CUBIT_FALSE;
2453 : : }
2454 : :
2455 : : RefVertex *
2456 : 0 : SplitSurfaceTool::start_vertex( CoEdge *co_edge_ptr )
2457 : : {
2458 [ # # ]: 0 : if( co_edge_ptr == NULL )
2459 : 0 : return NULL;
2460 : :
2461 : 0 : RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
2462 : :
2463 [ # # ]: 0 : if ( co_edge_ptr->get_sense() == CUBIT_REVERSED )
2464 : 0 : return ref_edge_ptr->end_vertex();
2465 : : else
2466 : 0 : return ref_edge_ptr->start_vertex();
2467 : : }
2468 : :
2469 : : RefVertex *
2470 : 0 : SplitSurfaceTool::end_vertex( CoEdge *co_edge_ptr )
2471 : : {
2472 [ # # ]: 0 : if( co_edge_ptr == NULL )
2473 : 0 : return NULL;
2474 : :
2475 : 0 : RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
2476 : :
2477 [ # # ]: 0 : if ( co_edge_ptr->get_sense() == CUBIT_REVERSED )
2478 : 0 : return ref_edge_ptr->start_vertex();
2479 : : else
2480 : 0 : return ref_edge_ptr->end_vertex();
2481 : : }
2482 : :
2483 : : CoEdge *
2484 : 0 : SplitSurfaceTool::get_complimentary_co_edge( CoEdge *co_edge_ptr,
2485 : : DLIList<CoEdge*> co_edge_list )
2486 : : {
2487 : : // Note: co_edge_list must be copied so that the calling code's list
2488 : : // position is not changed.
2489 : 0 : RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
2490 : : CoEdge *shared_co_edge_ptr;
2491 : : int i;
2492 [ # # ]: 0 : for( i=co_edge_list.size(); i--; )
2493 : : {
2494 : 0 : shared_co_edge_ptr = co_edge_list.get_and_step();
2495 [ # # ]: 0 : if( shared_co_edge_ptr == NULL )
2496 : 0 : continue;
2497 [ # # ]: 0 : if( shared_co_edge_ptr == co_edge_ptr )
2498 : 0 : continue;
2499 [ # # ]: 0 : if( shared_co_edge_ptr->get_ref_edge_ptr() == ref_edge_ptr )
2500 : 0 : return shared_co_edge_ptr;
2501 : : }
2502 : 0 : return NULL;
2503 : : }
2504 : :
2505 : : CubitStatus
2506 : 0 : SplitSurfaceTool::get_attached_coedges_start( CoEdge *co_edge_ptr,
2507 : : DLIList<CoEdge*> &co_edge_list,
2508 : : DLIList<CoEdge*> &attached_co_edge_list )
2509 : : {
2510 : : int i;
2511 : : CoEdge *attached_co_edge_ptr;
2512 : :
2513 : : RefVertex *start_vertex_ptr;
2514 [ # # ]: 0 : start_vertex_ptr = start_vertex( co_edge_ptr );
2515 : :
2516 : : RefVertex *attached_start_vertex_ptr;
2517 : :
2518 [ # # ]: 0 : co_edge_list.reset();
2519 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
2520 : : {
2521 [ # # ]: 0 : attached_co_edge_ptr = co_edge_list.get_and_step();
2522 : :
2523 [ # # ]: 0 : attached_start_vertex_ptr = start_vertex( attached_co_edge_ptr );
2524 : :
2525 [ # # ]: 0 : if( attached_start_vertex_ptr == start_vertex_ptr )
2526 [ # # ]: 0 : attached_co_edge_list.append( attached_co_edge_ptr );
2527 : : }
2528 : :
2529 : 0 : return CUBIT_SUCCESS;
2530 : : }
2531 : :
2532 : : CubitStatus
2533 : 0 : SplitSurfaceTool::remove_other_corner_coedges( CoEdge *co_edge_1,
2534 : : CoEdge *co_edge_2,
2535 : : DLIList<CoEdge*> &all_co_edge_list,
2536 : : DLIList<CoEdge*> &att_co_edge_list )
2537 : : {
2538 : : // If only one attached coedge there is nothing to do
2539 [ # # ][ # # ]: 0 : if( att_co_edge_list.size() == 1 )
2540 : : {
2541 : : // It should be co_edge_2
2542 [ # # ][ # # ]: 0 : if( att_co_edge_list.get() != co_edge_2 )
2543 : : {
2544 [ # # ][ # # ]: 0 : PRINT_ERROR( "Internal error in split surface function - please report this.\n" );
[ # # ][ # # ]
2545 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( " Function remove_other_coedges.\n" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2546 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( " Using curves %d and %d on surface %d, got curve %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2547 : : co_edge_1->get_ref_edge_ptr()->id(), co_edge_2->get_ref_edge_ptr()->id(),
2548 [ # # ]: 0 : co_edge_1->get_ref_face()->id(), att_co_edge_list.get()->get_ref_edge_ptr()->id() );
2549 : 0 : return CUBIT_FAILURE;
2550 : : }
2551 : 0 : return CUBIT_SUCCESS;
2552 : : }
2553 : :
2554 : : // If we got this far, there are CoEdges we must examine to determine if they
2555 : : // belong with this corner or the other corner that shares this vertex.
2556 : :
2557 [ # # ]: 0 : DLIList<CoEdge*> keep_co_edge_list;
2558 : :
2559 : : // Always keep co_edge_2 (the tooldata represents the start vertex on this coedge)
2560 [ # # ]: 0 : keep_co_edge_list.append( co_edge_2 );
2561 [ # # ]: 0 : att_co_edge_list.remove( co_edge_2 );
2562 : :
2563 : : // Traverse from co_edge_2
2564 [ # # ][ # # ]: 0 : DLIList<CoEdge*> keep_co_edge_list2;
2565 : 0 : int done = 0;
2566 : 0 : CoEdge *comp_co_edge_ptr = co_edge_2;
2567 : : CoEdge *co_edge_ptr;
2568 [ # # ]: 0 : while( !done )
2569 : : {
2570 [ # # ]: 0 : RefFace *ref_face_ptr = comp_co_edge_ptr->get_ref_face();
2571 [ # # ]: 0 : DLIList<CoEdge*> co_edge_list;
2572 [ # # ]: 0 : ordered_co_edges( ref_face_ptr, co_edge_list );
2573 [ # # ]: 0 : co_edge_list.move_to( comp_co_edge_ptr );
2574 [ # # ]: 0 : co_edge_list.back();
2575 [ # # ]: 0 : co_edge_ptr = co_edge_list.get();
2576 [ # # ]: 0 : if( co_edge_ptr == co_edge_1 )
2577 : 0 : break;
2578 : :
2579 [ # # ][ # # ]: 0 : comp_co_edge_ptr = get_complimentary_co_edge( co_edge_ptr, all_co_edge_list );
[ # # ]
2580 : :
2581 [ # # ]: 0 : keep_co_edge_list2.append( comp_co_edge_ptr );
2582 : :
2583 : : // Avoid infinite loop, in case of something we didn't anticipate
2584 [ # # ][ # # ]: 0 : if( keep_co_edge_list2.size() > att_co_edge_list.size() )
[ # # ]
2585 : : {
2586 [ # # ][ # # ]: 0 : PRINT_ERROR( "Internal error in split surface function - please report this.\n" );
[ # # ][ # # ]
2587 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( " Function remove_other_coedges #1.\n" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2588 [ # # ]: 0 : return CUBIT_FAILURE;
[ # # # ]
2589 : : }
2590 : 0 : }
2591 : :
2592 : : int i;
2593 [ # # ][ # # ]: 0 : for( i=keep_co_edge_list2.size(); i--; )
2594 : : {
2595 [ # # ]: 0 : co_edge_ptr = keep_co_edge_list2.get_and_step();
2596 [ # # ][ # # ]: 0 : if( !att_co_edge_list.is_in_list( co_edge_ptr ) )
2597 : : {
2598 [ # # ][ # # ]: 0 : PRINT_ERROR( "Internal error in split surface function - please report this.\n" );
[ # # ][ # # ]
2599 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( " Function remove_other_coedges #2.\n" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2600 : 0 : return CUBIT_FAILURE;
2601 : : }
2602 : : }
2603 : :
2604 [ # # ]: 0 : keep_co_edge_list += keep_co_edge_list2;
2605 : :
2606 [ # # ]: 0 : att_co_edge_list.clean_out();
2607 : :
2608 [ # # ]: 0 : att_co_edge_list = keep_co_edge_list;
2609 : :
2610 [ # # ]: 0 : return CUBIT_SUCCESS;
2611 : : }
2612 : :
2613 : : CubitStatus
2614 : 0 : SplitSurfaceTool::add_tooldata( DLIList<CoEdge*> &co_edge_list, int vertex_type )
2615 : : {
2616 : : int i;
2617 : : CoEdge *co_edge_ptr;
2618 [ # # ]: 0 : for( i=co_edge_list.size(); i--; )
2619 : : {
2620 : 0 : co_edge_ptr = co_edge_list.get_and_step();
2621 : :
2622 : : // Something's wrong if we have are trying to put a tooldata on a CoEdge that
2623 : : // already has one.
2624 [ # # ]: 0 : if( (TDSplitSurface *)co_edge_ptr->get_TD(&TDSplitSurface::is_split_surface) )
2625 : : {
2626 [ # # ][ # # ]: 0 : PRINT_ERROR( "Internal error in split surface function - please report this.\n" );
2627 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( " Function add_tooldata.\n" );
[ # # ]
2628 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( " Curve = %d on surface %d\n", co_edge_ptr->get_ref_edge_ptr()->id(),
2629 [ # # ]: 0 : co_edge_ptr->get_ref_face()->id() );
2630 : 0 : return CUBIT_FAILURE;
2631 : : }
2632 : :
2633 [ # # ]: 0 : co_edge_ptr->add_TD( new TDSplitSurface( vertex_type ) );
2634 : : }
2635 : 0 : return CUBIT_SUCCESS;
2636 : : }
2637 : :
2638 : : CubitStatus
2639 : 0 : SplitSurfaceTool::pick_4_corners()
2640 : : {
2641 : : // Special case - for the loop situation the corners are already picked
2642 [ # # ]: 0 : if( isLoop )
2643 : 0 : return CUBIT_SUCCESS;
2644 : :
2645 : : // Find 4 reasonable corners preferably close to PI/2. We find at least
2646 : : // 2 corners from the starting surface and 2 from the ending surface.
2647 : :
2648 : : // Note that at this point, the vertex loop starts at the beginning
2649 : : // of the first surface in the chain.
2650 : :
2651 : : // Check for trivial case
2652 [ # # ][ # # ]: 0 : if( outerCoEdgeLoop.size() == 4 )
2653 : : {
2654 [ # # ]: 0 : outerCoEdgeLoop.reset();
2655 [ # # ]: 0 : cornerCoEdge[0] = outerCoEdgeLoop.get_and_step();
2656 [ # # ]: 0 : cornerCoEdge[1] = outerCoEdgeLoop.get_and_step();
2657 [ # # ]: 0 : cornerCoEdge[2] = outerCoEdgeLoop.get_and_step();
2658 [ # # ]: 0 : cornerCoEdge[3] = outerCoEdgeLoop.get();
2659 : :
2660 : 0 : sideInterval[0] = 1;
2661 : 0 : sideInterval[1] = 1;
2662 : 0 : sideInterval[2] = 1;
2663 : 0 : sideInterval[3] = 1;
2664 : :
2665 : 0 : return CUBIT_SUCCESS;
2666 : : }
2667 : :
2668 : : // Initialize variables
2669 [ # # ]: 0 : refFaceChain.reset();
2670 [ # # ]: 0 : RefFace *start_surf = refFaceChain.get();
2671 [ # # ]: 0 : refFaceChain.last();
2672 [ # # ]: 0 : RefFace *end_surf = refFaceChain.get();
2673 [ # # ]: 0 : outerCoEdgeLoop.reset();
2674 : : CoEdge *co_edge_ptr;
2675 : 0 : int A_i=-1, B_i=-1, D_i=-1, E_i=-1;
2676 : :
2677 : : // Walk along the loop, to find the best corners for the first and last
2678 : : // surfaces. The leading edge (B) tries to push forward, but the rear (A)
2679 : : // tries to hang back. Move the lead forward, then check to see if the rear
2680 : : // should move into it's old spot.
2681 : :
2682 : : // Note that the outerCoEdgeLoop starts at the first vertex of the starting
2683 : : // surface (shown after A in this diagram).
2684 : : //
2685 : : // Final result for this patch results in corners where the 0's are shown.
2686 : :
2687 : : //
2688 : : // E D
2689 : : // 0-----+-------+------0
2690 : : // | | | |
2691 : : // F | | | |
2692 : : // +------+ | | +------+
2693 : : // | | | | ^
2694 : : // | End | | Start | | Loop
2695 : : // | Surface | | Surface | | Direction
2696 : : // | | | | |
2697 : : // +------+ | | +------+
2698 : : // | | | | C
2699 : : // | | | |
2700 : : // 0-----+-------+------0 B
2701 : : // A
2702 : : //
2703 : :
2704 : 0 : double epsilon = .001745; // Angles considered comparable within about .1 degrees.
2705 : 0 : int offset = 0;
2706 : :
2707 [ # # ]: 0 : pick_expanded_corners( start_surf, outerCoEdgeLoop, offset, epsilon, A_i, B_i );
2708 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "First pass picked %d and %d on surf %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2709 [ # # ]: 0 : A_i, B_i, start_surf->id() );
2710 : :
2711 : : // Advance the vertex and coedge lists until we are on the end_surf
2712 : :
2713 : : // Special case - if vertices are shared between start and end surface, we
2714 : : // want the opportunity to use the start vertex on the end surface, even
2715 : : // though we may have already picked it. We want to consider it again so
2716 : : // that we can find the best corners on the end surface. Since we will
2717 : : // always find at least two corners on a surface, if we did not consider
2718 : : // all vertices on the end surface, we might find a garbage vertex. If
2719 : : // we do pick up a duplicate, we will clean it out and find the next best
2720 : : // vertex later. If we did not do this, in the figure below, the first
2721 : : // pass through pick_expanded corners would find C1 and C2. The next
2722 : : // pass would find C3 and C4. We don't want C4, but we would pick it
2723 : : // just because pick_expanded_corners must pick exactly two corners.
2724 : : // Instead, lets pick C2 and C3 the next time around and pickup the lower
2725 : : // left corner as a cleanup step later.
2726 : : //
2727 : : // C4
2728 : : // C1 +--------+--------------------+ C3
2729 : : // | \ |
2730 : : // | \ |
2731 : : // | \ end |
2732 : : // | \ |
2733 : : // | \ |
2734 : : // | start \ |
2735 : : // | \ |
2736 : : // | \ |
2737 : : // | \ |
2738 : : // | \ |
2739 : : // +--------+--------------------+ C2
2740 : :
2741 : : // Backup (to consider last vertex again, as explained above)
2742 [ # # ]: 0 : outerCoEdgeLoop.back();
2743 : 0 : offset--;
2744 : :
2745 : : int i;
2746 [ # # ][ # # ]: 0 : for( i=0; i<outerCoEdgeLoop.size(); i++ )
2747 : : {
2748 [ # # ]: 0 : co_edge_ptr = outerCoEdgeLoop.get();
2749 [ # # ][ # # ]: 0 : if( is_vertex_in_surface( start_vertex(co_edge_ptr), end_surf ) )
[ # # ]
2750 : 0 : break;
2751 : :
2752 : 0 : offset++;
2753 [ # # ]: 0 : outerCoEdgeLoop.step();
2754 : : }
2755 : :
2756 [ # # ]: 0 : pick_expanded_corners( end_surf, outerCoEdgeLoop, offset, epsilon, D_i, E_i );
2757 : :
2758 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "Second pass picked %d and %d on surf %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2759 [ # # ]: 0 : D_i, E_i, end_surf->id() );
2760 : :
2761 [ # # ][ # # ]: 0 : if( E_i == outerCoEdgeLoop.size() )
2762 : 0 : E_i = 0;
2763 : :
2764 : : // Error checking
2765 [ # # ]: 0 : if( A_i==B_i )
2766 : 0 : B_i = -1;
2767 [ # # ]: 0 : if( A_i==D_i )
2768 : 0 : D_i = -1;
2769 [ # # ]: 0 : if( A_i==E_i )
2770 : 0 : E_i = -1;
2771 [ # # ]: 0 : if( B_i==D_i )
2772 : 0 : D_i = -1;
2773 [ # # ]: 0 : if( B_i==E_i )
2774 : 0 : E_i = -1;
2775 [ # # ]: 0 : if( D_i==E_i )
2776 : 0 : E_i = -1;
2777 : :
2778 [ # # ][ # # ]: 0 : if( A_i==-1 || B_i==-1 || D_i==-1 || E_i==-1 )
[ # # ][ # # ]
2779 : : {
2780 : : // Most likely error case is that we only found three corners. Here
2781 : : // is an example where this can happen. Notice that the upper left
2782 : : // corner did not get selected. This is because when processing the
2783 : : // left surface, the best corners were found that were "expanded out"
2784 : : // the farthest - thus we missed the "inside" corner.
2785 : : //
2786 : : //
2787 : : // +-----------------------------+ C
2788 : : // | /|
2789 : : // | / |
2790 : : // | / |
2791 : : // | / |
2792 : : // | / |
2793 : : // | / |
2794 : : // | / |
2795 : : // | / |
2796 : : // | / |
2797 : : // | / |
2798 : : // C +--------+--------------------+ C
2799 : :
2800 : : //
2801 : : // In this case, lets just cop out and find the next best corner(s)
2802 : 0 : int num = 0;
2803 [ # # ]: 0 : if( A_i==-1 )
2804 : 0 : num++;
2805 [ # # ]: 0 : if( B_i==-1 )
2806 : 0 : num++;
2807 [ # # ]: 0 : if( D_i==-1 )
2808 : 0 : num++;
2809 [ # # ]: 0 : if( E_i==-1 )
2810 : 0 : num++;
2811 : :
2812 [ # # ]: 0 : if( num>2 )
2813 : : {
2814 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to pick corners - please specify manually.\n"
[ # # ]
2815 [ # # ]: 0 : " Type 'help split surface' for proper syntax\n" );
2816 : 0 : return CUBIT_FAILURE;
2817 : : }
2818 : :
2819 : 0 : int best_corner_1 = -1, best_corner_2 = -1;
2820 : :
2821 : : double diff;
2822 : 0 : double pi2 = CUBIT_PI/2.0;
2823 : 0 : double min = CUBIT_DBL_MAX;
2824 [ # # ]: 0 : outerCoEdgeLoop.reset();
2825 [ # # ][ # # ]: 0 : for( i=0; i<outerCoEdgeLoop.size(); i++ )
2826 : : {
2827 [ # # ]: 0 : co_edge_ptr = outerCoEdgeLoop.get();
2828 : :
2829 [ # # ][ # # ]: 0 : if( i==A_i || i==B_i || i==D_i || i==E_i ||
[ # # ][ # # ]
[ # # ][ # # ]
2830 [ # # ][ # # ]: 0 : (!is_vertex_in_surface( start_vertex(co_edge_ptr), start_surf ) &&
[ # # ]
2831 [ # # ][ # # ]: 0 : !is_vertex_in_surface( start_vertex(co_edge_ptr), end_surf ) ) )
2832 : : {
2833 [ # # ]: 0 : outerCoEdgeLoop.step();
2834 : 0 : continue;
2835 : : }
2836 : :
2837 [ # # ]: 0 : diff = fabs( pi2 - compute_next_angle( outerCoEdgeLoop ) );
2838 : :
2839 [ # # ]: 0 : if( diff < min )
2840 : : {
2841 : 0 : best_corner_1 = i;
2842 : 0 : min = diff;
2843 : : }
2844 : : }
2845 : :
2846 [ # # ]: 0 : if( best_corner_1 == -1 )
2847 : : {
2848 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to pick corners - please specify manually.\n"
[ # # ]
2849 [ # # ]: 0 : " Type 'help split surface' for proper syntax\n" );
2850 : 0 : return CUBIT_FAILURE;
2851 : : }
2852 : :
2853 [ # # ]: 0 : if( num>1 )
2854 : : {
2855 : 0 : min = CUBIT_DBL_MAX;
2856 [ # # ]: 0 : outerCoEdgeLoop.reset();
2857 [ # # ][ # # ]: 0 : for( i=0; i<outerCoEdgeLoop.size(); i++ )
2858 : : {
2859 [ # # ]: 0 : co_edge_ptr = outerCoEdgeLoop.get();
2860 : :
2861 [ # # ][ # # ]: 0 : if( i==A_i || i==B_i || i==D_i || i==E_i ||
[ # # ][ # # ]
[ # # ]
2862 [ # # ][ # # ]: 0 : i==best_corner_1 ||
2863 [ # # ][ # # ]: 0 : (!is_vertex_in_surface( start_vertex(co_edge_ptr), start_surf ) &&
[ # # ]
2864 [ # # ][ # # ]: 0 : !is_vertex_in_surface( start_vertex(co_edge_ptr), end_surf ) ) )
2865 : : {
2866 [ # # ]: 0 : outerCoEdgeLoop.step();
2867 : 0 : continue;
2868 : : }
2869 : :
2870 [ # # ]: 0 : diff = fabs( pi2 - compute_next_angle( outerCoEdgeLoop ) );
2871 : :
2872 [ # # ]: 0 : if( diff < min )
2873 : : {
2874 : 0 : best_corner_2 = i;
2875 : 0 : min = diff;
2876 : : }
2877 : : }
2878 [ # # ]: 0 : if( best_corner_2 == -1 )
2879 : : {
2880 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to pick corners - please specify manually.\n"
[ # # ]
2881 [ # # ]: 0 : " Type 'help split surface' for proper syntax\n" );
2882 : 0 : return CUBIT_FAILURE;
2883 : : }
2884 : : }
2885 : :
2886 : : int best_corner[6];
2887 : :
2888 : : // Find the four corners we have
2889 : 0 : i = 0;
2890 [ # # ]: 0 : if( A_i != -1 )
2891 : 0 : best_corner[i++] = A_i;
2892 [ # # ]: 0 : if( B_i != -1 )
2893 : 0 : best_corner[i++] = B_i;
2894 [ # # ]: 0 : if( D_i != -1 )
2895 : 0 : best_corner[i++] = D_i;
2896 [ # # ]: 0 : if( E_i != -1 )
2897 : 0 : best_corner[i++] = E_i;
2898 [ # # ]: 0 : if( best_corner_1 != -1 )
2899 : 0 : best_corner[i++] = best_corner_1;
2900 [ # # ]: 0 : if( best_corner_2 != -1 )
2901 : 0 : best_corner[i++] = best_corner_2;
2902 : :
2903 [ # # ]: 0 : if( i>4 )
2904 : : {
2905 [ # # ][ # # ]: 0 : PRINT_ERROR( "Internal error in split surface function - please report\n" );
[ # # ][ # # ]
2906 : 0 : return CUBIT_FAILURE;
2907 : : }
2908 : :
2909 [ # # ]: 0 : order_corners( best_corner[0], best_corner[1], best_corner[2], best_corner[3] );
2910 : :
2911 : 0 : A_i = best_corner[0];
2912 : 0 : B_i = best_corner[1];
2913 : 0 : D_i = best_corner[2];
2914 : 0 : E_i = best_corner[3];
2915 : : }
2916 : :
2917 : : // Fill cornerCoEdge array
2918 [ # # ]: 0 : fill_corners( A_i, B_i, D_i, E_i );
2919 : :
2920 : : // Make sure we found at least two vertices on start surf and two vertices
2921 : : // on end surf
2922 [ # # ][ # # ]: 0 : if( !is_vertex_in_surface( start_vertex(cornerCoEdge[0]), start_surf ) ||
[ # # ][ # # ]
2923 [ # # ][ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[1]), start_surf ) ||
[ # # ]
2924 [ # # ][ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[2]), end_surf ) ||
[ # # ][ # # ]
2925 [ # # ][ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[3]), end_surf ) )
2926 : : {
2927 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to pick corners - please specify manually.\n"
[ # # ]
2928 [ # # ]: 0 : " Type 'help split surface' for proper syntax\n" );
2929 : 0 : return CUBIT_FAILURE;
2930 : : }
2931 : :
2932 : : // Fill sideInterval array
2933 [ # # ]: 0 : fill_side_intervals( A_i, B_i, D_i, E_i );
2934 : :
2935 : : // Get loops in proper position (from start)
2936 [ # # ]: 0 : reorient_loop( A_i );
2937 : :
2938 [ # # ]: 0 : if( autoDetectTriangles == CUBIT_TRUE )
2939 : : {
2940 : : // Check to see if any corners are close to 180 and should be removed
2941 : : // to create a triangle or triangles
2942 [ # # ][ # # ]: 0 : if( update_corners_for_triangle() == CUBIT_FAILURE )
2943 : 0 : return CUBIT_FAILURE;
2944 : : }
2945 : :
2946 : 0 : return CUBIT_SUCCESS;
2947 : : }
2948 : :
2949 : : CubitStatus
2950 : 0 : SplitSurfaceTool::pick_expanded_corners( RefFace *ref_face_ptr,
2951 : : DLIList<CoEdge*> &co_edge_list,
2952 : : int &offset, double epsilon, int &A_i, int &B_i )
2953 : : {
2954 : : CoEdge *co_edge_ptr;
2955 : 0 : double pi2 = CUBIT_PI/2.0; // Target angle (find vertices closest to this)
2956 : 0 : double A = -1.0, B = -1.0, C;
2957 : : int old_B_i;
2958 : : double old_B;
2959 : :
2960 : 0 : A_i = -1;
2961 : 0 : B_i = -1;
2962 : :
2963 : 0 : int initial_offset = offset;
2964 : :
2965 : : int i;
2966 [ # # ]: 0 : for( i=0; i<co_edge_list.size(); i++ )
2967 : : {
2968 : 0 : co_edge_ptr = co_edge_list.get();
2969 : :
2970 : : // If no longer in the surface we are done
2971 [ # # ]: 0 : if( !is_vertex_in_surface( start_vertex(co_edge_ptr), ref_face_ptr ) )
2972 : : {
2973 : 0 : A_i += initial_offset;
2974 : 0 : B_i += initial_offset;
2975 : 0 : return CUBIT_SUCCESS;
2976 : : }
2977 : :
2978 : : // Calculate difference of angle from PI/2. Looking for smaller C as
2979 : : // compared to previous A & B. This also steps the lists.
2980 : 0 : C = fabs( pi2 - compute_next_angle( co_edge_list ) );
2981 : :
2982 [ # # ]: 0 : if( A == -1.0 ) // Initialization of A
2983 : : {
2984 : 0 : A_i = i;
2985 : 0 : A = C;
2986 : : }
2987 [ # # ]: 0 : else if( B == -1.0 ) // Initialization of B
2988 : : {
2989 : 0 : B_i = i;
2990 : 0 : B = C;
2991 : : }
2992 : : // Check if B should move forward (it wants to!)
2993 [ # # ][ # # ]: 0 : else if( fabs(C - B) < epsilon || C < B ) // C == B || C < B
2994 : : { // C <= B (effectively)
2995 : : // Push B forward to C's spot.
2996 : 0 : old_B = B;
2997 : 0 : old_B_i = B_i;
2998 : 0 : B = C;
2999 : 0 : B_i = i;
3000 : :
3001 : : // Check if A should move into B's old spot (it doesn't want to!)
3002 [ # # ][ # # ]: 0 : if( !(fabs(old_B - A)<epsilon) && old_B < A ) // old_B != A && old_B < A
3003 : : { // old_B < A (effectively)
3004 : : // Push A forward to B's old spot
3005 : 0 : A = old_B;
3006 : 0 : A_i = old_B_i;
3007 : : }
3008 : : }
3009 : : // Also look for smaller C as compared to A
3010 [ # # ][ # # ]: 0 : else if( !(fabs(C - A)<epsilon) && C < A ) // C != A && C < A
3011 : : { // C < A (effectively)
3012 : : // Push B forward to C's spot.
3013 : 0 : old_B = B;
3014 : 0 : old_B_i = B_i;
3015 : 0 : B = C;
3016 : 0 : B_i = i;
3017 : :
3018 : : // Push A forward to B's old spot
3019 : 0 : A = old_B;
3020 : 0 : A_i = old_B_i;
3021 : : }
3022 : 0 : offset++;
3023 : : }
3024 : :
3025 : 0 : A_i += initial_offset;
3026 : 0 : B_i += initial_offset;
3027 : 0 : return CUBIT_SUCCESS;
3028 : : }
3029 : :
3030 : : CubitStatus
3031 : 0 : SplitSurfaceTool::pick_4_corners_simple()
3032 : : {
3033 : : // Special case - for the loop situation the corners are already picked
3034 [ # # ]: 0 : if( isLoop )
3035 : 0 : return CUBIT_SUCCESS;
3036 : :
3037 : : // We simply find the 4 corners closest to PI/2 - used
3038 : : // when we only have one surface. Results sometimes
3039 : : // aren't ideal....but user can pick corners in these
3040 : : // situations.
3041 : :
3042 : : // Store best quadruple
3043 : : int best_corner_1, best_corner_2, best_corner_3, best_corner_4;
3044 : :
3045 [ # # ]: 0 : const int number_vertices = outerCoEdgeLoop.size();
3046 [ # # ]: 0 : if( number_vertices == 3 )
3047 : : {
3048 : : // Triangle - special case (default to split to first tip of triangle)
3049 : 0 : best_corner_1 = 0;
3050 : 0 : best_corner_2 = 0;
3051 : 0 : best_corner_3 = 1;
3052 : 0 : best_corner_4 = 2;
3053 : : }
3054 : : else
3055 : : {
3056 : 0 : const int num_angles = number_vertices;
3057 : :
3058 : : // Compute angles
3059 : : double *angles;
3060 : 0 : double turn_angle_sum = 0.;
3061 [ # # ]: 0 : compute_angles( angles, turn_angle_sum );
3062 : :
3063 : : // For now just find the 4 vertices that are closest to PI/2
3064 : : int i;
3065 : : double diff;
3066 : 0 : double pi2 = CUBIT_PI/2.0;
3067 : 0 : double min = CUBIT_DBL_MAX;
3068 [ # # ]: 0 : for( i=0; i<num_angles; i++ )
3069 : : {
3070 : 0 : diff = fabs( pi2 - angles[i] );
3071 [ # # ]: 0 : if( diff < min )
3072 : : {
3073 : 0 : best_corner_1 = i;
3074 : 0 : min = diff;
3075 : : }
3076 : : }
3077 : :
3078 : 0 : min = CUBIT_DBL_MAX;
3079 [ # # ]: 0 : for( i=0; i<num_angles; i++ )
3080 : : {
3081 : 0 : diff = fabs( pi2 - angles[i] );
3082 [ # # ][ # # ]: 0 : if( diff < min && i != best_corner_1 )
3083 : : {
3084 : 0 : best_corner_2 = i;
3085 : 0 : min = diff;
3086 : : }
3087 : : }
3088 : :
3089 : 0 : min = CUBIT_DBL_MAX;
3090 [ # # ]: 0 : for( i=0; i<num_angles; i++ )
3091 : : {
3092 : 0 : diff = fabs( pi2 - angles[i] );
3093 [ # # ][ # # ]: 0 : if( diff < min && i != best_corner_1 && i != best_corner_2 )
[ # # ]
3094 : : {
3095 : 0 : best_corner_3 = i;
3096 : 0 : min = diff;
3097 : : }
3098 : : }
3099 : :
3100 : 0 : min = CUBIT_DBL_MAX;
3101 [ # # ]: 0 : for( i=0; i<num_angles; i++ )
3102 : : {
3103 : 0 : diff = fabs( pi2 - angles[i] );
3104 [ # # ][ # # ]: 0 : if( diff < min && i != best_corner_1 && i != best_corner_2 && i != best_corner_3 )
[ # # ][ # # ]
3105 : : {
3106 : 0 : best_corner_4 = i;
3107 : 0 : min = diff;
3108 : : }
3109 : : }
3110 : :
3111 [ # # ]: 0 : delete [] angles;
3112 : :
3113 [ # # ]: 0 : order_corners( best_corner_1, best_corner_2, best_corner_3, best_corner_4 );
3114 : : }
3115 : :
3116 : : // Fill cornerCoEdge and sideInterval arrays
3117 [ # # ]: 0 : fill_corners( best_corner_1, best_corner_2, best_corner_3, best_corner_4 );
3118 [ # # ]: 0 : fill_side_intervals( best_corner_1, best_corner_2, best_corner_3, best_corner_4 );
3119 : :
3120 : : // Get loops in proper position (from start)
3121 [ # # ]: 0 : reorient_loop( best_corner_1 );
3122 : :
3123 [ # # ]: 0 : if( autoDetectTriangles == CUBIT_TRUE )
3124 : : {
3125 : : // Check to see if any corners are close to 180 and should be removed
3126 : : // to create a triangle
3127 [ # # ][ # # ]: 0 : if( update_corners_for_triangle() == CUBIT_FAILURE )
3128 : 0 : return CUBIT_FAILURE;
3129 : : }
3130 : :
3131 : 0 : return CUBIT_SUCCESS;
3132 : : }
3133 : :
3134 : : CubitStatus
3135 : 0 : SplitSurfaceTool::update_corners_for_triangle()
3136 : : {
3137 : : // Get four angles, in degrees
3138 : : double angle[4];
3139 [ # # ]: 0 : outerCoEdgeLoop.reset();
3140 [ # # ]: 0 : angle[0] = 180.0/CUBIT_PI * compute_next_angle( outerCoEdgeLoop );
3141 [ # # ]: 0 : outerCoEdgeLoop.step( sideInterval[0]-1 );
3142 [ # # ]: 0 : angle[1] = 180.0/CUBIT_PI * compute_next_angle( outerCoEdgeLoop );
3143 [ # # ]: 0 : outerCoEdgeLoop.step( sideInterval[1]-1 );
3144 [ # # ]: 0 : angle[2] = 180.0/CUBIT_PI * compute_next_angle( outerCoEdgeLoop );
3145 [ # # ]: 0 : outerCoEdgeLoop.step( sideInterval[2]-1 );
3146 [ # # ]: 0 : angle[3] = 180.0/CUBIT_PI * compute_next_angle( outerCoEdgeLoop );
3147 : :
3148 [ # # ][ # # ]: 0 : if( refFaceChain.size() > 1 )
3149 : : {
3150 : : // If a chain, do for both sides. Check end surface first (otherwise
3151 : : // arrays could be previously modified when checking the other side)
3152 : 0 : int corner_to_remove = -1;
3153 : 0 : int collapsed_corner = -1;
3154 : :
3155 [ # # ][ # # ]: 0 : if( fabs(180.0-angle[2])<=sideAngleThreshold && angle[3] <= pointAngleThreshold )
3156 : : {
3157 : 0 : corner_to_remove = 2;
3158 : 0 : collapsed_corner = 3;
3159 : : }
3160 [ # # ][ # # ]: 0 : else if( fabs(180.0-angle[3])<=sideAngleThreshold && angle[2] <= pointAngleThreshold )
3161 : : {
3162 : 0 : corner_to_remove = 3;
3163 : 0 : collapsed_corner = 2;
3164 : : }
3165 : :
3166 [ # # ]: 0 : if( corner_to_remove != -1 )
3167 [ # # ]: 0 : remove_corner( corner_to_remove, collapsed_corner, CUBIT_FALSE );
3168 : :
3169 : : // Now check start surface
3170 : 0 : corner_to_remove = -1;
3171 : 0 : collapsed_corner = -1;
3172 : :
3173 [ # # ][ # # ]: 0 : if( fabs(180.0-angle[0])<=sideAngleThreshold && angle[1] <= pointAngleThreshold )
3174 : : {
3175 : 0 : corner_to_remove = 0;
3176 : 0 : collapsed_corner = 1;
3177 : : }
3178 [ # # ][ # # ]: 0 : else if( fabs(180.0-angle[1])<=sideAngleThreshold && angle[0] <= pointAngleThreshold )
3179 : : {
3180 : 0 : corner_to_remove = 1;
3181 : 0 : collapsed_corner = 0;
3182 : : }
3183 : :
3184 [ # # ]: 0 : if( corner_to_remove != -1 )
3185 [ # # ]: 0 : remove_corner( corner_to_remove, collapsed_corner, CUBIT_TRUE );
3186 : : }
3187 : : else
3188 : : {
3189 : : // Determine angle within sideAngleThreshold and closest to 180
3190 : 0 : double diff = CUBIT_DBL_MAX;
3191 : 0 : int best_side_corner = -1;
3192 : : int i;
3193 [ # # ]: 0 : for( i=0; i<4; i++ )
3194 : : {
3195 [ # # ][ # # ]: 0 : if( fabs(180.0-angle[i])<=sideAngleThreshold && fabs(180.0-angle[i])<diff )
3196 : : {
3197 : 0 : best_side_corner = i;
3198 : 0 : diff = fabs(180.0-angle[i]);
3199 : : }
3200 : : }
3201 : :
3202 [ # # ]: 0 : if( best_side_corner == -1 )
3203 : : {
3204 : : //PRINT_INFO( "No angle within criteria above sideAngleThreshold\n" );
3205 : 0 : return CUBIT_SUCCESS;
3206 : : }
3207 : :
3208 : : //PRINT_INFO( "Best side corner = %d, angle = %f\n", best_side_corner,
3209 : : // angle[best_side_corner] );
3210 : :
3211 : : // Determine angle most below pointAngleThreshold
3212 : 0 : diff = CUBIT_DBL_MAX;
3213 : 0 : int best_point_corner = -1;
3214 [ # # ]: 0 : for( i=0; i<4; i++ )
3215 : : {
3216 [ # # ][ # # ]: 0 : if( angle[i] <= pointAngleThreshold && (pointAngleThreshold-angle[i]) < diff )
3217 : : {
3218 : 0 : best_point_corner = i;
3219 : 0 : diff = pointAngleThreshold - angle[i];
3220 : : }
3221 : : }
3222 : :
3223 [ # # ]: 0 : if( best_point_corner == -1 )
3224 : : {
3225 : : //PRINT_INFO( "No angle within criteria below pointAngleThreshold\n" );
3226 : 0 : return CUBIT_SUCCESS;
3227 : : }
3228 : :
3229 : : //PRINT_INFO( "Best point corner = %d, angle = %f\n", best_point_corner,
3230 : : // angle[best_point_corner] );
3231 : :
3232 [ # # ][ # # ]: 0 : if( best_side_corner != -1 && best_point_corner != -1 )
3233 [ # # ]: 0 : remove_corner( best_side_corner, best_point_corner, CUBIT_TRUE );
3234 : : }
3235 : :
3236 : 0 : return CUBIT_SUCCESS;
3237 : : }
3238 : :
3239 : : CubitStatus
3240 : 0 : SplitSurfaceTool::remove_corner( int corner_to_remove, int collapsed_corner,
3241 : : CubitBoolean set_collapsed_first )
3242 : : {
3243 : : // Need to adjust:
3244 : : // outerCoEdgeLoop
3245 : : // cornerCoEdge
3246 : : // sideInterval
3247 : :
3248 : : // Shuffle the corners so that corner to remove is 2nd corner
3249 [ # # # # : 0 : switch( corner_to_remove )
# ]
3250 : : {
3251 : : case 0:
3252 : 0 : shuffle_corners_forward();
3253 : 0 : shuffle_corners_forward();
3254 : 0 : shuffle_corners_forward();
3255 : 0 : collapsed_corner += 1;
3256 : :
3257 : : // Ensure collapsed_corner does not wrap the array (note we could have used
3258 : : // the remainder function instead, as follows:
3259 : : // int remainder = 0;
3260 : : // collapsed_corner = (remainder=collapsed_corner%4) ? remainder : collapsed_corner;
3261 [ # # ]: 0 : if( collapsed_corner == 4 )
3262 : 0 : collapsed_corner = 0;
3263 : :
3264 : 0 : break;
3265 : : case 1:
3266 : 0 : break;
3267 : : case 2:
3268 : 0 : shuffle_corners_forward();
3269 : 0 : collapsed_corner -= 1;
3270 : 0 : break;
3271 : : case 3:
3272 : 0 : shuffle_corners_forward();
3273 : 0 : shuffle_corners_forward();
3274 : 0 : collapsed_corner -= 2;
3275 : 0 : break;
3276 : : }
3277 : :
3278 [ # # ]: 0 : if( collapsed_corner < 0 )
3279 : 0 : collapsed_corner += 4;
3280 : :
3281 [ # # # # : 0 : switch( collapsed_corner )
# ]
3282 : : {
3283 : : case 0:
3284 : 0 : sideInterval[1] = sideInterval[0] + sideInterval[1];
3285 : 0 : sideInterval[0] = 0;
3286 : 0 : break;
3287 : : case 1:
3288 [ # # ][ # # ]: 0 : PRINT_ERROR( "Algorithm error in auto-detecting triangle - please report.\n" );
3289 : 0 : return CUBIT_FAILURE;
3290 : : case 2:
3291 : 0 : sideInterval[0] = sideInterval[0] + sideInterval[1];
3292 : 0 : sideInterval[1] = 0;
3293 : 0 : break;
3294 : : case 3:
3295 : 0 : sideInterval[0] = sideInterval[0] + sideInterval[1];
3296 : 0 : sideInterval[1] = sideInterval[2];
3297 : 0 : sideInterval[2] = 0;
3298 : : }
3299 : :
3300 : : // Now redo cornerCoEdge array
3301 : 0 : outerCoEdgeLoop.reset();
3302 : 0 : cornerCoEdge[0] = outerCoEdgeLoop.get();
3303 : 0 : outerCoEdgeLoop.step( sideInterval[0] );
3304 : 0 : cornerCoEdge[1] = outerCoEdgeLoop.get();
3305 : 0 : outerCoEdgeLoop.step( sideInterval[1] );
3306 : 0 : cornerCoEdge[2] = outerCoEdgeLoop.get();
3307 : 0 : outerCoEdgeLoop.step( sideInterval[2] );
3308 : 0 : cornerCoEdge[3] = outerCoEdgeLoop.get();
3309 : :
3310 [ # # ]: 0 : if( set_collapsed_first == CUBIT_TRUE )
3311 : : {
3312 : : // Adjust the arrays so that collapsed_corner is at the front
3313 [ # # # ]: 0 : switch( collapsed_corner )
3314 : : {
3315 : : case 2:
3316 : 0 : shuffle_corners_forward();
3317 : 0 : break;
3318 : : case 3:
3319 : 0 : shuffle_corners_forward();
3320 : 0 : shuffle_corners_forward();
3321 : 0 : shuffle_corners_forward();
3322 : : }
3323 : : }
3324 : : else
3325 : : {
3326 : : // Return to original position
3327 [ # # # # : 0 : switch( corner_to_remove )
# ]
3328 : : {
3329 : : case 0:
3330 : 0 : shuffle_corners_forward();
3331 : 0 : break;
3332 : : case 1:
3333 : 0 : break;
3334 : : case 2:
3335 : 0 : shuffle_corners_forward();
3336 : 0 : shuffle_corners_forward();
3337 : 0 : shuffle_corners_forward();
3338 : 0 : break;
3339 : : case 3:
3340 : 0 : shuffle_corners_forward();
3341 : 0 : shuffle_corners_forward();
3342 : 0 : break;
3343 : : }
3344 : : }
3345 : :
3346 : 0 : return CUBIT_SUCCESS;
3347 : : }
3348 : :
3349 : : CubitStatus
3350 : 0 : SplitSurfaceTool::fill_corners( int best_corner_1, int best_corner_2,
3351 : : int best_corner_3, int best_corner_4 )
3352 : : {
3353 : 0 : outerCoEdgeLoop.reset();
3354 : 0 : outerCoEdgeLoop.step(best_corner_1);
3355 : 0 : cornerCoEdge[0] = outerCoEdgeLoop.get();
3356 : :
3357 : 0 : outerCoEdgeLoop.reset();
3358 : 0 : outerCoEdgeLoop.step(best_corner_2);
3359 : 0 : cornerCoEdge[1] = outerCoEdgeLoop.get();
3360 : :
3361 : 0 : outerCoEdgeLoop.reset();
3362 : 0 : outerCoEdgeLoop.step(best_corner_3);
3363 : 0 : cornerCoEdge[2] = outerCoEdgeLoop.get();
3364 : :
3365 : 0 : outerCoEdgeLoop.reset();
3366 : 0 : outerCoEdgeLoop.step(best_corner_4);
3367 : 0 : cornerCoEdge[3] = outerCoEdgeLoop.get();
3368 : :
3369 : 0 : return CUBIT_SUCCESS;
3370 : : }
3371 : :
3372 : : CubitStatus
3373 : 0 : SplitSurfaceTool::fill_side_intervals( int best_corner_1, int best_corner_2,
3374 : : int best_corner_3, int best_corner_4 )
3375 : : {
3376 : 0 : sideInterval[0] = best_corner_2 - best_corner_1;
3377 : 0 : sideInterval[1] = best_corner_3 - best_corner_2;
3378 : 0 : sideInterval[2] = best_corner_4 - best_corner_3;
3379 : 0 : sideInterval[3] = best_corner_1 + outerCoEdgeLoop.size() - best_corner_4;
3380 : :
3381 : 0 : return CUBIT_SUCCESS;
3382 : : }
3383 : :
3384 : : CubitStatus
3385 : 0 : SplitSurfaceTool::compute_angles( double *&angles, double &turn_angle_sum )
3386 : : {
3387 : 0 : const int num_angles = outerCoEdgeLoop.size();
3388 [ # # ]: 0 : angles = new double[ num_angles ];
3389 : 0 : turn_angle_sum = 0.;
3390 : 0 : outerCoEdgeLoop.reset();
3391 : : int i;
3392 [ # # ]: 0 : for(i=0; i<num_angles; i++)
3393 : : {
3394 : 0 : angles[i] = compute_next_angle( outerCoEdgeLoop );
3395 : : //turn_angle_sum += CUBIT_PI - angles[i]; // Not currently used
3396 : : }
3397 : 0 : return CUBIT_SUCCESS;
3398 : : }
3399 : :
3400 : : double
3401 : 0 : SplitSurfaceTool::compute_next_angle( DLIList<CoEdge*> &co_edge_list )
3402 : : {
3403 [ # # ]: 0 : CoEdge *co_edge_1 = co_edge_list.prev();
3404 [ # # ]: 0 : CoEdge *co_edge_2 = co_edge_list.get_and_step();
3405 : :
3406 : : // Coordinates of common point
3407 [ # # ][ # # ]: 0 : CubitVector vertex_point = start_vertex( co_edge_2 )->coordinates();
3408 : :
3409 : : // Find normal to the the face at the common vertex
3410 [ # # ]: 0 : RefFace *ref_face1 = co_edge_1->get_ref_face();
3411 [ # # ]: 0 : CubitVector normal1 = ref_face1->normal_at(vertex_point, NULL);
3412 : :
3413 [ # # ]: 0 : RefFace *ref_face2 = co_edge_2->get_ref_face();
3414 [ # # ]: 0 : CubitVector normal2 = ref_face2->normal_at(vertex_point, NULL);
3415 : :
3416 [ # # ][ # # ]: 0 : CubitVector normal = (normal1 + normal2)/2; // Average
3417 : :
3418 : : // Find directed tangents to determine interior angle
3419 : : // Use sense of edge with respect to this face's loop.
3420 [ # # ][ # # ]: 0 : CubitVector tangent_1, tangent_2;
3421 [ # # ][ # # ]: 0 : co_edge_1->get_ref_edge_ptr()->tangent( vertex_point, tangent_1 );
3422 [ # # ][ # # ]: 0 : co_edge_2->get_ref_edge_ptr()->tangent( vertex_point, tangent_2 );
3423 : :
3424 [ # # ][ # # ]: 0 : if ( co_edge_1->get_sense() == CUBIT_REVERSED )
3425 [ # # ][ # # ]: 0 : tangent_1 = -tangent_1;
3426 [ # # ][ # # ]: 0 : if ( co_edge_2->get_sense() == CUBIT_REVERSED )
3427 [ # # ][ # # ]: 0 : tangent_2 = -tangent_2;
3428 : :
3429 : : // At this point we have the tangents going in the correct loop
3430 : : // sense.
3431 : : // Now get tangent pointing away from the center for the correct
3432 : : // angle
3433 [ # # ][ # # ]: 0 : tangent_1 = -tangent_1;
3434 : :
3435 : : // Return angle from given tangents and normal to face
3436 [ # # ]: 0 : double angle = normal.vector_angle( tangent_2, tangent_1 );
3437 : :
3438 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( " Angle at vertex %d = %f\n", start_vertex( co_edge_2 )->id(),
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
3439 [ # # ]: 0 : angle*180.0/CUBIT_PI );
3440 : 0 : return angle;
3441 : : }
3442 : :
3443 : : void
3444 : 0 : SplitSurfaceTool::order_corners( int &corner_1, int &corner_2,
3445 : : int &corner_3, int &corner_4 )
3446 : : {
3447 : : // sort the corners by indices
3448 : : int swap_temp;
3449 : : #define SWAP( a, b ) swap_temp = (a); (a) = (b); (b) = swap_temp
3450 [ # # ]: 0 : if ( corner_1 > corner_2 ) {
3451 : 0 : SWAP( corner_1, corner_2 );
3452 : : }
3453 [ # # ]: 0 : if ( corner_2 > corner_3 ) {
3454 : 0 : SWAP( corner_2, corner_3 );
3455 : : }
3456 [ # # ]: 0 : if ( corner_3 > corner_4 ) {
3457 : 0 : SWAP( corner_3, corner_4 );
3458 : : }
3459 : : // 4 is now set
3460 : 0 : order_corners( corner_1, corner_2, corner_3 );
3461 : : #undef SWAP
3462 : 0 : }
3463 : :
3464 : : void
3465 : 0 : SplitSurfaceTool::order_corners( int &corner_1, int &corner_2,
3466 : : int &corner_3 )
3467 : : {
3468 : : // sort the corners by indices
3469 : : int swap_temp;
3470 : : #define SWAP( a, b ) swap_temp = (a); (a) = (b); (b) = swap_temp
3471 [ # # ]: 0 : if ( corner_1 > corner_2 ) {
3472 : 0 : SWAP( corner_1, corner_2 );
3473 : : }
3474 [ # # ]: 0 : if ( corner_2 > corner_3 ) {
3475 : 0 : SWAP( corner_2, corner_3 );
3476 : : }
3477 : : // 3 is now set
3478 [ # # ]: 0 : if ( corner_1 > corner_2 ) {
3479 : 0 : SWAP( corner_1, corner_2 );
3480 : : }
3481 : : // 2 is now set
3482 : : // 1 is set as its the only one left
3483 : : #undef SWAP
3484 : 0 : }
3485 : :
3486 : : CubitStatus
3487 : 0 : SplitSurfaceTool::order_selected_corners( DLIList<RefVertex*> &corner_vertex_list )
3488 : : {
3489 : : int i;
3490 : :
3491 : : RefVertex *ref_vertex_ptr;
3492 : : CoEdge *co_edge_ptr;
3493 : :
3494 : : // Verify that these corners exist in the outerCoEdgeLoop
3495 [ # # ]: 0 : for( i = corner_vertex_list.size(); i--; )
3496 : : {
3497 : 0 : ref_vertex_ptr = corner_vertex_list.get_and_step();
3498 : :
3499 [ # # ]: 0 : if( is_in_outer_loop( ref_vertex_ptr ) == CUBIT_FALSE )
3500 : : {
3501 [ # # ]: 0 : PRINT_ERROR( "Selected corner, Vertex %d, not found in outer loop of patch.\n",
3502 [ # # ]: 0 : ref_vertex_ptr->id() );
3503 : 0 : return CUBIT_FAILURE;
3504 : : }
3505 : : }
3506 : :
3507 : : // We need to start at the first corner the user selected - shuffle the
3508 : : // lists to do this.
3509 : 0 : corner_vertex_list.reset();
3510 : 0 : RefVertex *start_corner = corner_vertex_list.get();
3511 : :
3512 : 0 : int offset = 0;
3513 : 0 : outerCoEdgeLoop.reset();
3514 [ # # ]: 0 : for( i=outerCoEdgeLoop.size(); i--; )
3515 : : {
3516 : 0 : ref_vertex_ptr = start_vertex( outerCoEdgeLoop.get_and_step() );
3517 [ # # ]: 0 : if( ref_vertex_ptr == start_corner )
3518 : 0 : break;
3519 : 0 : offset++;
3520 : : }
3521 : :
3522 : : // Now shuffle the lists to get them into the proper order
3523 [ # # ]: 0 : if( offset )
3524 : : {
3525 [ # # ]: 0 : outerCoEdgeLoop.reset();
3526 [ # # ]: 0 : DLIList<CoEdge*> outer_co_edge_loop = outerCoEdgeLoop;
3527 : :
3528 [ # # ]: 0 : outerCoEdgeLoop.clean_out();
3529 : :
3530 [ # # ]: 0 : outer_co_edge_loop.reset();
3531 : :
3532 : : // Set the loop at start offset
3533 [ # # ]: 0 : outer_co_edge_loop.step( offset );
3534 [ # # ][ # # ]: 0 : for( i=outer_co_edge_loop.size(); i--; )
3535 : : {
3536 [ # # ][ # # ]: 0 : outerCoEdgeLoop.append( outer_co_edge_loop.get_and_step() );
3537 [ # # ]: 0 : }
3538 : : }
3539 : :
3540 : : // Cruise through the outer coedge list to get the proper corner order
3541 : 0 : int corner = 0;
3542 : 0 : int num = 0;
3543 : 0 : int side_interval = 0;
3544 : 0 : outerCoEdgeLoop.reset();
3545 : :
3546 : 0 : co_edge_ptr = outerCoEdgeLoop.get_and_step();
3547 : :
3548 : : // Special case for first corner (always at first corner to start)
3549 : 0 : num = number_in_list( corner_vertex_list, start_vertex(co_edge_ptr) );
3550 [ # # ]: 0 : if( num > 2 )
3551 : : {
3552 [ # # ]: 0 : PRINT_ERROR( "Vertex %d was selected for %d of the corners - max is 2\n",
3553 [ # # ]: 0 : start_vertex(co_edge_ptr)->id(), num );
3554 : 0 : return CUBIT_FAILURE;
3555 : : }
3556 : :
3557 : 0 : cornerCoEdge[corner++] = co_edge_ptr;
3558 [ # # ]: 0 : if( num == 2 )
3559 : : {
3560 : 0 : sideInterval[corner-1] = 0;
3561 : 0 : cornerCoEdge[corner++] = co_edge_ptr;
3562 : : }
3563 : :
3564 [ # # ]: 0 : for( i=1; i<outerCoEdgeLoop.size(); i++ )
3565 : : {
3566 : 0 : co_edge_ptr = outerCoEdgeLoop.get_and_step();
3567 : 0 : side_interval++;
3568 : :
3569 : 0 : num = number_in_list( corner_vertex_list, start_vertex(co_edge_ptr) );
3570 [ # # ]: 0 : if( num > 2 )
3571 : : {
3572 [ # # ]: 0 : PRINT_ERROR( "Vertex %d was selected for %d of the corners - max is 2\n",
3573 [ # # ]: 0 : start_vertex(co_edge_ptr)->id(), num );
3574 : 0 : return CUBIT_FAILURE;
3575 : : }
3576 : :
3577 [ # # ]: 0 : if( num > 0 )
3578 : : {
3579 : 0 : sideInterval[corner-1] = side_interval;
3580 : 0 : side_interval = 0;
3581 : 0 : cornerCoEdge[corner++] = co_edge_ptr;
3582 : :
3583 [ # # ]: 0 : if( num == 2 )
3584 : : {
3585 : 0 : sideInterval[corner-1] = 0;
3586 : 0 : cornerCoEdge[corner++] = co_edge_ptr;
3587 : : }
3588 : : }
3589 : : }
3590 : :
3591 : 0 : sideInterval[3] = outerCoEdgeLoop.size() - sideInterval[0] - sideInterval[1] - sideInterval[2];
3592 : :
3593 : 0 : return CUBIT_SUCCESS;
3594 : : }
3595 : :
3596 : : int
3597 : 0 : SplitSurfaceTool::number_in_list( DLIList<RefVertex*> &corner_vertex_list,
3598 : : RefVertex *ref_vertex_ptr )
3599 : : {
3600 : 0 : int num = 0;
3601 : : int i;
3602 : 0 : corner_vertex_list.reset();
3603 : : RefVertex *check_ptr;
3604 [ # # ]: 0 : for( i=4; i--; )
3605 : : {
3606 : 0 : check_ptr = corner_vertex_list.get_and_step();
3607 [ # # ]: 0 : if( check_ptr == ref_vertex_ptr )
3608 : 0 : num++;
3609 : : }
3610 : :
3611 : 0 : return num;
3612 : : }
3613 : :
3614 : : CubitBoolean
3615 : 0 : SplitSurfaceTool::is_in_outer_loop( RefVertex *ref_vertex_ptr )
3616 : : {
3617 : : int i;
3618 : 0 : outerCoEdgeLoop.reset();
3619 : :
3620 [ # # ]: 0 : for( i=outerCoEdgeLoop.size(); i--; )
3621 : : {
3622 [ # # ]: 0 : if( ref_vertex_ptr == start_vertex( outerCoEdgeLoop.get_and_step() ) )
3623 : 0 : return CUBIT_TRUE;
3624 : : }
3625 : 0 : return CUBIT_FALSE;
3626 : : }
3627 : :
3628 : : CubitStatus
3629 : 0 : SplitSurfaceTool::adjust_for_split_direction( RefEdge *curve_dir_ptr,
3630 : : RefEdge *from_curve_ptr,
3631 : : DLIList<RefVertex*> &corner_vertex_list )
3632 : : {
3633 : : // Adjust the loops to the split direction. The split direction is
3634 : : // determined as follows:
3635 : : // 1) For multiple surfaces - always across the chain.
3636 : : //
3637 : : // split direction
3638 : : // c2 <--------> c1
3639 : : // +---------+-----------+-----------+
3640 : : // | | | |
3641 : : // |_ _ _ |_ _ _ _ | _ _ _ _|
3642 : : // | | split | |side 0
3643 : : // | | | |
3644 : : // +---------+-----------+-----------+
3645 : : // c3 side 3 c0
3646 : : //
3647 : : // 2) If a "from" curve is specfied, put the "from" curve on
3648 : : // side 3, so that the fraction and distance goes from the
3649 : : // right side.
3650 : :
3651 : :
3652 : : // For single surfaces, the logic is a little more tricky:
3653 : : // 1) From optional "direction" curve given by user (parallel to split)
3654 : : // 2) From optional "from" curve given by user (parallel to split)
3655 : : // 3) From optional through vertex list given by user.
3656 : : // 4) From optional corner vertices given by user, if given in a
3657 : : // sensible order (ie., not criss-crossed). Split direction
3658 : : // will be perpendicular to the side from first to second
3659 : : // selected corner (ie., perpendicular to c0-c1 in the
3660 : : // diagram below).
3661 : : // 5) From aspect ratio of patch - split along "skinny" direction.
3662 : :
3663 : : // split direction
3664 : : // c2 <--------> c1
3665 : : // +-------------------------------+
3666 : : // | |
3667 : : // |_ _ _ _ _ _ _ _ _ _ _|
3668 : : // | split |
3669 : : // | |
3670 : : // +-------------------------------+
3671 : : // c3 c0
3672 : : //
3673 : : // In all cases check for incompatible inputs (i.e., conflicting
3674 : : // "direction" and "from" curves, conflicting "through" vertices
3675 : : // on single surfaces, etc.)
3676 : :
3677 : 0 : corner_vertex_list.reset();
3678 : :
3679 [ # # ][ # # ]: 0 : if( refFaceChain.size() > 1 && corner_vertex_list.size() )
[ # # ]
3680 : : {
3681 : 0 : refFaceChain.reset();
3682 : 0 : RefFace *start_surf = refFaceChain.get();
3683 : 0 : refFaceChain.last();
3684 : 0 : RefFace *end_surf = refFaceChain.get();
3685 : :
3686 : : // We might have to shuffle the selected corners to orient them to split
3687 : : // across the surfaces. To be valid, we must have the two starting
3688 : : // corners in the start surface and the two ending corners in the end
3689 : : // surface. Shuffle the corners until this condition is met. If
3690 : : // we shuffle three times and the condition is still not met, we have
3691 : : // been given invalid vertices.
3692 : : //
3693 : : // Here is a case we must be able to handle, with corners specified
3694 : : // as shown. We must shuffle three times.
3695 : :
3696 : : // C3 C2
3697 : : // +-----+------------------+
3698 : : // |\ \ |
3699 : : // | \ \ |
3700 : : // | \ \ end |
3701 : : // | \ \ |
3702 : : // | \ \ |
3703 : : // | \ \ |
3704 : : // | \ \ |
3705 : : // | \ \ |
3706 : : // | \ \ |
3707 : : // | start \ \ |
3708 : : // | \ \ |
3709 : : // | \\|
3710 : : // +------------------------+
3711 : : // C0 C1
3712 : :
3713 [ # # ][ # # ]: 0 : if( !is_vertex_in_surface( start_vertex(cornerCoEdge[0]), start_surf ) ||
3714 [ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[1]), start_surf ) ||
3715 [ # # ][ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[2]), end_surf ) ||
3716 : 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[3]), end_surf ) )
3717 : : {
3718 : 0 : shuffle_corners_forward();
3719 [ # # ][ # # ]: 0 : if( !is_vertex_in_surface( start_vertex(cornerCoEdge[0]), start_surf ) ||
3720 [ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[1]), start_surf ) ||
3721 [ # # ][ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[2]), end_surf ) ||
3722 : 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[3]), end_surf ) )
3723 : : {
3724 : 0 : shuffle_corners_forward();
3725 [ # # ][ # # ]: 0 : if( !is_vertex_in_surface( start_vertex(cornerCoEdge[0]), start_surf ) ||
3726 [ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[1]), start_surf ) ||
3727 [ # # ][ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[2]), end_surf ) ||
3728 : 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[3]), end_surf ) )
3729 : : {
3730 : 0 : shuffle_corners_forward();
3731 [ # # ][ # # ]: 0 : if( !is_vertex_in_surface( start_vertex(cornerCoEdge[0]), start_surf ) ||
3732 [ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[1]), start_surf ) ||
3733 [ # # ][ # # ]: 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[2]), end_surf ) ||
3734 : 0 : !is_vertex_in_surface( start_vertex(cornerCoEdge[3]), end_surf ) )
3735 : : {
3736 [ # # ]: 0 : PRINT_ERROR( "Selected vertices are invalid. Two vertices must be on\n"
3737 [ # # ]: 0 : " start surface and two on end surface of chain.\n" );
3738 : 0 : return CUBIT_FAILURE;
3739 : : }
3740 : : }
3741 : : }
3742 : : }
3743 : : }
3744 [ # # ]: 0 : if( refFaceChain.size() > 1 )
3745 : : {
3746 [ # # ]: 0 : if( curve_dir_ptr )
3747 : : {
3748 : : // Check for rare case with two triangles - that case allows a switch in
3749 : : // direction
3750 [ # # ]: 0 : if( is_chain_two_triangles() )
3751 : : {
3752 [ # # # # ]: 0 : if( is_curve_on_side( curve_dir_ptr, 0 ) ||
[ # # ]
3753 : 0 : is_curve_on_side( curve_dir_ptr, 2 ) )
3754 : : {
3755 : 0 : shuffle_corners_forward();
3756 : : }
3757 : :
3758 [ # # ]: 0 : if( throughVertexList.size() > 2 )
3759 : : {
3760 [ # # ][ # # ]: 0 : PRINT_ERROR( "For two triangle case, you can only specify 2 'through' vertices.\n" );
3761 : 0 : return CUBIT_FAILURE;
3762 : : }
3763 : :
3764 : : // Make sure through vertices (if any) are on side 0 or 2
3765 [ # # ]: 0 : if( check_through_vertices( "'direction'" ) == CUBIT_FAILURE )
3766 : 0 : return CUBIT_FAILURE;
3767 : : }
3768 : : else
3769 [ # # ][ # # ]: 0 : PRINT_WARNING( "Curve direction ignored - not necessary for a chain of surfaces.\n" );
3770 : : }
3771 : :
3772 : : // Flip sides if user selected a from curve
3773 [ # # ]: 0 : if( from_curve_ptr )
3774 : : {
3775 : : // Check for rare case with two triangles - that case allows a switch in
3776 : : // direction
3777 [ # # ]: 0 : if( is_chain_two_triangles() )
3778 : : {
3779 [ # # # # ]: 0 : if( is_curve_on_side( from_curve_ptr, 0 ) ||
[ # # ]
3780 : 0 : is_curve_on_side( from_curve_ptr, 2 ) )
3781 : : {
3782 [ # # ]: 0 : if( curve_dir_ptr )
3783 : : {
3784 [ # # ][ # # ]: 0 : PRINT_ERROR( "From curve must be parallel to direction of split.\n" );
3785 : 0 : return CUBIT_FAILURE;
3786 : : }
3787 : : else
3788 : 0 : shuffle_corners_forward();
3789 : : }
3790 : :
3791 : : // Next two checks are redundant if a direction was specified, but that
3792 : : // doesn't hurt anything.
3793 [ # # ]: 0 : if( throughVertexList.size() > 2 )
3794 : : {
3795 [ # # ][ # # ]: 0 : PRINT_ERROR( "For two triangle case, you can only specify 2 'through' vertices.\n" );
3796 : 0 : return CUBIT_FAILURE;
3797 : : }
3798 : :
3799 : : // Make sure through vertices (if any) are on side 0 or 2
3800 [ # # ]: 0 : if( check_through_vertices( "'from'" ) == CUBIT_FAILURE )
3801 : 0 : return CUBIT_FAILURE;
3802 : : }
3803 : : else
3804 : : {
3805 : : // Make sure this curve is on side 3
3806 [ # # # # ]: 0 : if( is_curve_on_side( from_curve_ptr, 0 ) ||
[ # # ]
3807 : 0 : is_curve_on_side( from_curve_ptr, 2 ) )
3808 : : {
3809 [ # # ][ # # ]: 0 : PRINT_ERROR( "From curve must be parallel to direction of split.\n" );
3810 : 0 : return CUBIT_FAILURE;
3811 : : }
3812 [ # # ]: 0 : if( is_curve_on_side( from_curve_ptr, 1 ) )
3813 : : {
3814 : 0 : shuffle_corners_forward();
3815 : 0 : shuffle_corners_forward();
3816 : : }
3817 : : }
3818 : : }
3819 : 0 : return CUBIT_SUCCESS;
3820 : : }
3821 : : else
3822 : : // SINGLE surface
3823 : : {
3824 : : // Special case for triangle
3825 [ # # ][ # # ]: 0 : if( is_triangle() && (curve_dir_ptr || from_curve_ptr ) )
[ # # ][ # # ]
3826 : : {
3827 : : // For a triangle, curve_dir_ptr and from_curve_ptr mean the same
3828 : : // thing. Do a check.
3829 [ # # ][ # # ]: 0 : if( curve_dir_ptr && from_curve_ptr && (from_curve_ptr != curve_dir_ptr) )
[ # # ]
3830 : : {
3831 [ # # ]: 0 : PRINT_ERROR( "For triangle case, specifying both a 'direction' and 'from'\n"
3832 [ # # ]: 0 : " curve is redundant - these have the same meaning.\n" );
3833 : 0 : return CUBIT_FAILURE;
3834 : : }
3835 : :
3836 [ # # ][ # # ]: 0 : if( from_curve_ptr && !curve_dir_ptr )
3837 : 0 : curve_dir_ptr = from_curve_ptr;
3838 : :
3839 : : // Desired state: 0 interval side opposite the side that curve_dir_ptr
3840 : : // is on. Then ensure that side past selected curve is side 0. A
3841 : : // tricky bit of logic!
3842 : :
3843 : : // Start out by setting zero side to side 0
3844 [ # # ]: 0 : if( sideInterval[1] == 0 )
3845 : : {
3846 : 0 : shuffle_corners_forward();
3847 : : }
3848 [ # # ]: 0 : else if (sideInterval[2] == 0 )
3849 : : {
3850 : 0 : shuffle_corners_forward();
3851 : 0 : shuffle_corners_forward();
3852 : : }
3853 [ # # ]: 0 : else if( sideInterval[3] == 0 )
3854 : : {
3855 : 0 : shuffle_corners_forward();
3856 : 0 : shuffle_corners_forward();
3857 : 0 : shuffle_corners_forward();
3858 : : }
3859 : :
3860 : : // Move zero side and ensure that side past selected curve is side 0.
3861 [ # # ]: 0 : if( is_curve_on_side( curve_dir_ptr, 1 ) )
3862 : : {
3863 : : // Zero side should be 3
3864 : 0 : shuffle_zero_side_forward();
3865 : 0 : shuffle_zero_side_forward();
3866 : :
3867 : 0 : shuffle_corners_forward();
3868 : : }
3869 [ # # ]: 0 : else if( is_curve_on_side( curve_dir_ptr, 2 ) )
3870 : : {
3871 : 0 : shuffle_corners_forward();
3872 : 0 : shuffle_corners_forward();
3873 : 0 : shuffle_corners_forward();
3874 : : }
3875 [ # # ]: 0 : else if( is_curve_on_side( curve_dir_ptr, 3 ) )
3876 : : {
3877 : 0 : shuffle_zero_side_forward();
3878 : : }
3879 : :
3880 : : // Check through vertices to make sure they are valid
3881 [ # # ]: 0 : if( check_through_vertices( "'direction'" ) == CUBIT_FAILURE )
3882 : 0 : return CUBIT_FAILURE;
3883 : :
3884 : 0 : return CUBIT_SUCCESS;
3885 : : }
3886 [ # # ]: 0 : else if( curve_dir_ptr )
3887 : : {
3888 : : // Curve should be on side 1 or 3 - otherwise adjust the loops forward
3889 [ # # ]: 0 : if( is_curve_on_side( curve_dir_ptr, 0 ) )
3890 : 0 : shuffle_corners_forward();
3891 [ # # ]: 0 : else if( is_curve_on_side( curve_dir_ptr, 2 ) )
3892 : 0 : shuffle_corners_forward();
3893 : :
3894 : : // Now check if there is a from curve too, along with curve direction
3895 [ # # ]: 0 : if( from_curve_ptr )
3896 : : {
3897 [ # # # # ]: 0 : if( is_curve_on_side( from_curve_ptr, 0 ) ||
[ # # ]
3898 : 0 : is_curve_on_side( from_curve_ptr, 2 ) )
3899 : : {
3900 [ # # ]: 0 : PRINT_ERROR( "'Direction' and 'From' curves must be on same or opposite\n"
3901 [ # # ]: 0 : " sides of logical rectangle\n" );
3902 : 0 : return CUBIT_FAILURE;
3903 : : }
3904 : : // Must be on side 3
3905 [ # # ]: 0 : if( is_curve_on_side( from_curve_ptr, 1 ) )
3906 : : {
3907 : 0 : shuffle_corners_forward();
3908 : 0 : shuffle_corners_forward();
3909 : : }
3910 : : }
3911 : :
3912 : : // Check through vertices to make sure they are valid
3913 [ # # ]: 0 : if( check_through_vertices( "'direction'" ) == CUBIT_FAILURE )
3914 : 0 : return CUBIT_FAILURE;
3915 : :
3916 : 0 : return CUBIT_SUCCESS;
3917 : : }
3918 : :
3919 : : // Single surface WITHOUT a direction given
3920 [ # # ]: 0 : if( from_curve_ptr )
3921 : : {
3922 : : // Curve should be on side 3 - otherwise adjust the loops forward
3923 [ # # ]: 0 : if( is_curve_on_side( from_curve_ptr, 2 ) )
3924 : : {
3925 : 0 : shuffle_corners_forward();
3926 : 0 : shuffle_corners_forward();
3927 : 0 : shuffle_corners_forward();
3928 : : }
3929 [ # # ]: 0 : else if( is_curve_on_side( from_curve_ptr, 1 ) )
3930 : : {
3931 : 0 : shuffle_corners_forward();
3932 : 0 : shuffle_corners_forward();
3933 : : }
3934 [ # # ]: 0 : else if( is_curve_on_side( from_curve_ptr, 0 ) )
3935 : 0 : shuffle_corners_forward();
3936 : :
3937 : : // Check through vertices to make sure they are valid
3938 [ # # ]: 0 : if( check_through_vertices( "'from'" ) == CUBIT_FAILURE )
3939 : 0 : return CUBIT_FAILURE;
3940 : :
3941 : 0 : return CUBIT_SUCCESS;
3942 : : }
3943 : :
3944 : : // Single surface WITHOUT a 'direction' or 'from' curve given - if through
3945 : : // vertices let them determine the split direction.
3946 [ # # ]: 0 : if( throughVertexList.size() > 2 )
3947 : : {
3948 [ # # ][ # # ]: 0 : PRINT_ERROR( "For a single surface, you can only specify 2 'through' vertices.\n" );
3949 : 0 : return CUBIT_FAILURE;
3950 : : }
3951 : :
3952 : 0 : RefVertex *start_vertex_ptr = NULL;
3953 : 0 : RefVertex *end_vertex_ptr = NULL;
3954 : 0 : throughVertexList.reset();
3955 [ # # ]: 0 : if( throughVertexList.size() > 0 )
3956 : 0 : start_vertex_ptr = throughVertexList.get_and_step();
3957 [ # # ]: 0 : if( throughVertexList.size() > 1 )
3958 : 0 : end_vertex_ptr = throughVertexList.get();
3959 : :
3960 : : // First check for start and end vertices
3961 [ # # ][ # # ]: 0 : if( start_vertex_ptr || end_vertex_ptr )
3962 : : {
3963 [ # # ]: 0 : if( start_vertex_ptr )
3964 : : {
3965 : : // Check if on side A
3966 [ # # ]: 0 : if( !is_vertex_on_side( start_vertex_ptr, 0 ) )
3967 : : {
3968 : : // Shuffle forward and check again
3969 : 0 : shuffle_corners_forward();
3970 [ # # ]: 0 : if( !is_vertex_on_side( start_vertex_ptr, 0 ) )
3971 : : {
3972 : : // Shuffle forward and check again
3973 : 0 : shuffle_corners_forward();
3974 [ # # ]: 0 : if( !is_vertex_on_side( start_vertex_ptr, 0 ) )
3975 : : {
3976 : : // Shuffle forward and check again
3977 : 0 : shuffle_corners_forward();
3978 [ # # ]: 0 : if( !is_vertex_on_side( start_vertex_ptr, 0 ) )
3979 : : {
3980 [ # # ]: 0 : PRINT_ERROR( "Specified 'through' vertex %d is not valid\n",
3981 [ # # ]: 0 : start_vertex_ptr->id() );
3982 : 0 : return CUBIT_FAILURE;
3983 : : }
3984 : : }
3985 : : }
3986 : : }
3987 : : }
3988 [ # # ]: 0 : if( end_vertex_ptr )
3989 : : {
3990 : : // Check if on side C
3991 [ # # ]: 0 : if( !is_vertex_on_side( end_vertex_ptr, 2 ) )
3992 : : {
3993 : : // Shuffle forward and check again
3994 : 0 : shuffle_corners_forward();
3995 [ # # ]: 0 : if( !is_vertex_on_side( end_vertex_ptr, 2 ) )
3996 : : {
3997 : : // Shuffle forward and check again
3998 : 0 : shuffle_corners_forward();
3999 [ # # ]: 0 : if( !is_vertex_on_side( end_vertex_ptr, 2 ) )
4000 : : {
4001 : : // Shuffle forward and check again
4002 : 0 : shuffle_corners_forward();
4003 [ # # ]: 0 : if( !is_vertex_on_side( end_vertex_ptr, 2 ) )
4004 : : {
4005 [ # # ]: 0 : PRINT_ERROR( "Specified 'through' vertex %d is not valid\n",
4006 [ # # ]: 0 : end_vertex_ptr->id() );
4007 : 0 : return CUBIT_FAILURE;
4008 : : }
4009 : : }
4010 : : }
4011 : : }
4012 : : }
4013 [ # # ][ # # ]: 0 : if( start_vertex_ptr && end_vertex_ptr )
4014 : : {
4015 [ # # # # ]: 0 : if( !is_vertex_on_side( start_vertex_ptr, 0 ) ||
[ # # ]
4016 : 0 : !is_vertex_on_side( end_vertex_ptr, 2 ) )
4017 : : {
4018 [ # # ][ # # ]: 0 : PRINT_ERROR( "Specified 'through' vertices invalid - both not on split path.\n" );
4019 : 0 : return CUBIT_FAILURE;
4020 : : }
4021 : : }
4022 : :
4023 : 0 : return CUBIT_SUCCESS;
4024 : :
4025 : : }
4026 : :
4027 : : // If second corner is 1 or 3, use the direction implied. Otherwise,
4028 : : // user gave corners in a criss-crossed manner and we can't gain any
4029 : : // implied direction from them.
4030 [ # # # # ]: 0 : else if( corner_vertex_list.size() &&
[ # # ]
4031 : 0 : corner_vertex_list.step_and_get() == start_vertex( cornerCoEdge[1]) )
4032 : 0 : return CUBIT_SUCCESS;
4033 [ # # # # ]: 0 : else if( corner_vertex_list.size() &&
[ # # ]
4034 : 0 : corner_vertex_list.get() == start_vertex( cornerCoEdge[3]) )
4035 : : ;
4036 : : else
4037 : : {
4038 : : // We use aspect ratio to determine split direction. Split along
4039 : : // narrowest direction.
4040 : :
4041 : : // Skip if we have a triangle
4042 [ # # ]: 0 : if( is_triangle() )
4043 : 0 : return CUBIT_SUCCESS;
4044 : :
4045 : 0 : double len0 = get_side_length( 0 );
4046 : 0 : double len1 = get_side_length( 1 );
4047 : 0 : double len2 = get_side_length( 2 );
4048 : 0 : double len3 = get_side_length( 3 );
4049 : :
4050 : 0 : double ratio = (len0+len2) / (len1+len3);
4051 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "Ratio = %f\n", ratio );
[ # # ]
4052 : :
4053 [ # # ]: 0 : if( ratio < 1.0001 )
4054 : 0 : return CUBIT_SUCCESS;
4055 : : else
4056 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "Ratio deems we adjust forward\n" );
[ # # ]
4057 : : }
4058 : :
4059 : : // If we got this far, we need to adjust the split direction - move
4060 : : // loops forward by sideInterval[0] (start at corner 1)
4061 : 0 : shuffle_corners_forward();
4062 : : }
4063 : :
4064 : 0 : return CUBIT_SUCCESS;
4065 : : }
4066 : :
4067 : : CubitBoolean
4068 : 0 : SplitSurfaceTool::is_chain_two_triangles()
4069 : : {
4070 [ # # ]: 0 : if( refFaceChain.size() != 2 )
4071 : 0 : return CUBIT_FALSE;
4072 : :
4073 : : // C3-0-1-2 C2-3-0-1
4074 : : // +------------------------+
4075 : : // |\ |
4076 : : // | \ |
4077 : : // | \ end |
4078 : : // | \ |
4079 : : // | \ |
4080 : : // | \ |
4081 : : // | \ |
4082 : : // | \ |
4083 : : // | \ |
4084 : : // | start \ |
4085 : : // | \ |
4086 : : // | \ |
4087 : : // +------------------------+
4088 : : // C0-1-2-3 C1-2-3-0
4089 : :
4090 : : // 4 possibilities (see diagram above - corners 0-1-2-3 or 1-2-3-0 etc
4091 : : // going ccw from bottom left)
4092 : :
4093 : 0 : CoEdge *c0 = cornerCoEdge[0];
4094 : 0 : CoEdge *c1 = cornerCoEdge[1];
4095 : 0 : CoEdge *c2 = cornerCoEdge[2];
4096 : 0 : CoEdge *c3 = cornerCoEdge[3];
4097 : :
4098 [ # # ][ # # ]: 0 : if( (prev_co_edge(c0)->get_ref_face() == c0->get_ref_face() &&
4099 [ # # ]: 0 : prev_co_edge(c1)->get_ref_face() != c1->get_ref_face() &&
4100 [ # # ]: 0 : prev_co_edge(c2)->get_ref_face() == c2->get_ref_face() &&
4101 [ # # ][ # # ]: 0 : prev_co_edge(c3)->get_ref_face() != c3->get_ref_face() ) ||
4102 : :
4103 [ # # ]: 0 : (prev_co_edge(c1)->get_ref_face() == c1->get_ref_face() &&
4104 [ # # ]: 0 : prev_co_edge(c2)->get_ref_face() != c2->get_ref_face() &&
4105 [ # # ]: 0 : prev_co_edge(c3)->get_ref_face() == c3->get_ref_face() &&
4106 : 0 : prev_co_edge(c0)->get_ref_face() != c0->get_ref_face() ) )
4107 : : {
4108 : : // 2-triangle case
4109 : 0 : return CUBIT_TRUE;
4110 : : }
4111 : :
4112 : 0 : return CUBIT_FALSE;
4113 : : }
4114 : :
4115 : : CubitBoolean
4116 : 0 : SplitSurfaceTool::is_triangle()
4117 : : {
4118 [ # # ][ # # ]: 0 : if( sideInterval[0]==0 || sideInterval[1]==0 ||
[ # # ]
4119 [ # # ]: 0 : sideInterval[2]==0 || sideInterval[3]==0 )
4120 : 0 : return CUBIT_TRUE;
4121 : : else
4122 : 0 : return CUBIT_FALSE;
4123 : : }
4124 : :
4125 : : CubitStatus
4126 : 0 : SplitSurfaceTool::check_through_vertices( const char *type )
4127 : : {
4128 [ # # ]: 0 : if( throughVertexList.size() )
4129 : : {
4130 : 0 : RefVertex *start_vertex_ptr = NULL;
4131 : 0 : RefVertex *end_vertex_ptr = NULL;
4132 : 0 : throughVertexList.reset();
4133 : 0 : start_vertex_ptr = throughVertexList.get_and_step();
4134 [ # # ]: 0 : if( throughVertexList.size() > 1 )
4135 : 0 : end_vertex_ptr = throughVertexList.get();
4136 : :
4137 [ # # ]: 0 : if( start_vertex_ptr )
4138 : : {
4139 [ # # # # ]: 0 : if( is_vertex_on_side( start_vertex_ptr, 0 ) ||
[ # # ]
4140 : 0 : is_vertex_on_side( start_vertex_ptr, 2 ) )
4141 : : ;
4142 : : else
4143 : : {
4144 [ # # ]: 0 : if( throughVertexList.size() == 1 )
4145 [ # # ]: 0 : PRINT_ERROR( "Through vertice(s) not compatible with %s curve given\n",
4146 [ # # ]: 0 : type );
4147 : : else
4148 [ # # ]: 0 : PRINT_ERROR( "Through vertices not compatible with %s curve given\n",
4149 [ # # ]: 0 : type);
4150 : 0 : return CUBIT_FAILURE;
4151 : : }
4152 : : }
4153 [ # # ]: 0 : if( end_vertex_ptr )
4154 : : {
4155 [ # # # # ]: 0 : if( is_vertex_on_side( end_vertex_ptr, 0 ) ||
[ # # ]
4156 : 0 : is_vertex_on_side( end_vertex_ptr, 2 ) )
4157 : : ;
4158 : : else
4159 : : {
4160 [ # # ][ # # ]: 0 : PRINT_ERROR( "%s", "Through vertices not compatible with %s curve given\n" );
4161 : 0 : return CUBIT_FAILURE;
4162 : : }
4163 : : }
4164 : : }
4165 : 0 : return CUBIT_SUCCESS;
4166 : : }
4167 : :
4168 : : CoEdge *
4169 : 0 : SplitSurfaceTool::prev_co_edge( CoEdge *co_edge_ptr )
4170 : : {
4171 : 0 : outerCoEdgeLoop.move_to( co_edge_ptr );
4172 : 0 : return outerCoEdgeLoop.prev();
4173 : : }
4174 : :
4175 : : double
4176 : 0 : SplitSurfaceTool::get_side_length( int side )
4177 : : {
4178 : : int i;
4179 : : RefEdge *ref_edge_ptr;
4180 : 0 : double length = 0.0;
4181 : 0 : outerCoEdgeLoop.reset();
4182 [ # # # # : 0 : switch( side )
# ]
4183 : : {
4184 : : case 0:
4185 [ # # ]: 0 : for( i=sideInterval[0]; i--; )
4186 : : {
4187 : 0 : ref_edge_ptr = outerCoEdgeLoop.get_and_step()->get_ref_edge_ptr();
4188 : 0 : length += ref_edge_ptr->measure();
4189 : : }
4190 : 0 : break;
4191 : :
4192 : : case 1:
4193 : 0 : outerCoEdgeLoop.step( sideInterval[0] );
4194 [ # # ]: 0 : for( i=sideInterval[1]; i--; )
4195 : : {
4196 : 0 : ref_edge_ptr = outerCoEdgeLoop.get_and_step()->get_ref_edge_ptr();
4197 : 0 : length += ref_edge_ptr->measure();
4198 : : }
4199 : 0 : break;
4200 : :
4201 : : case 2:
4202 : :
4203 : 0 : outerCoEdgeLoop.step( sideInterval[0]+sideInterval[1] );
4204 [ # # ]: 0 : for( i=sideInterval[2]; i--; )
4205 : : {
4206 : 0 : ref_edge_ptr = outerCoEdgeLoop.get_and_step()->get_ref_edge_ptr();
4207 : 0 : length += ref_edge_ptr->measure();
4208 : : }
4209 : 0 : break;
4210 : :
4211 : : case 3:
4212 : :
4213 : 0 : outerCoEdgeLoop.step( sideInterval[0]+sideInterval[1]+sideInterval[2] );
4214 [ # # ]: 0 : for( i=sideInterval[3]; i--; )
4215 : : {
4216 : 0 : ref_edge_ptr = outerCoEdgeLoop.get_and_step()->get_ref_edge_ptr();
4217 : 0 : length += ref_edge_ptr->measure();
4218 : : }
4219 : 0 : break;
4220 : : }
4221 : :
4222 : 0 : return length;
4223 : : }
4224 : :
4225 : : CubitStatus
4226 : 0 : SplitSurfaceTool::reorient_loop( int start_offset )
4227 : : {
4228 [ # # ]: 0 : if( start_offset == 0 )
4229 : 0 : return CUBIT_SUCCESS;
4230 : :
4231 [ # # ][ # # ]: 0 : DLIList<CoEdge*> outer_co_edge_loop( outerCoEdgeLoop.size() );
4232 : :
4233 [ # # ]: 0 : outerCoEdgeLoop.reset();
4234 [ # # ]: 0 : outerCoEdgeLoop.step( start_offset );
4235 : :
4236 : : int i;
4237 [ # # ][ # # ]: 0 : for( i=outerCoEdgeLoop.size(); i--; )
4238 [ # # ][ # # ]: 0 : outer_co_edge_loop.append( outerCoEdgeLoop.get_and_step() );
4239 : :
4240 [ # # ]: 0 : outerCoEdgeLoop.clean_out();
4241 : :
4242 [ # # ]: 0 : outer_co_edge_loop.reset();
4243 : :
4244 [ # # ]: 0 : outerCoEdgeLoop = outer_co_edge_loop;
4245 : :
4246 [ # # ]: 0 : return CUBIT_SUCCESS;
4247 : : }
4248 : :
4249 : : CubitStatus
4250 : 0 : SplitSurfaceTool::shuffle_corners_forward()
4251 : : {
4252 : : // Simply move loops forward by sideInterval[0] (start at corner 1)
4253 : 0 : reorient_loop( sideInterval[0] );
4254 : :
4255 : : // Shuffle sideInterval and cornerCoEdge too
4256 : 0 : int side_interval_temp = sideInterval[0];
4257 : 0 : sideInterval[0] = sideInterval[1];
4258 : 0 : sideInterval[1] = sideInterval[2];
4259 : 0 : sideInterval[2] = sideInterval[3];
4260 : 0 : sideInterval[3] = side_interval_temp;
4261 : :
4262 : 0 : CoEdge *corner_coedge_temp = cornerCoEdge[0];
4263 : 0 : cornerCoEdge[0] = cornerCoEdge[1];
4264 : 0 : cornerCoEdge[1] = cornerCoEdge[2];
4265 : 0 : cornerCoEdge[2] = cornerCoEdge[3];
4266 : 0 : cornerCoEdge[3] = corner_coedge_temp;
4267 : :
4268 : 0 : return CUBIT_SUCCESS;
4269 : : }
4270 : :
4271 : : CubitStatus
4272 : 0 : SplitSurfaceTool::shuffle_zero_side_forward()
4273 : : {
4274 [ # # ]: 0 : if( sideInterval[0] == 0 )
4275 : : {
4276 : 0 : cornerCoEdge[1] = cornerCoEdge[2];
4277 : 0 : sideInterval[0] = sideInterval[1];
4278 : 0 : sideInterval[1] = 0;
4279 : : }
4280 [ # # ]: 0 : else if( sideInterval[1] == 0 )
4281 : : {
4282 : 0 : cornerCoEdge[2] = cornerCoEdge[3];
4283 : 0 : sideInterval[1] = sideInterval[2];
4284 : 0 : sideInterval[2] = 0;
4285 : : }
4286 [ # # ]: 0 : else if( sideInterval[2] == 0 )
4287 : : {
4288 : 0 : cornerCoEdge[3] = cornerCoEdge[0];
4289 : 0 : sideInterval[2] = sideInterval[3];
4290 : 0 : sideInterval[3] = 0;
4291 : : }
4292 [ # # ]: 0 : else if( sideInterval[3] == 0 )
4293 : : {
4294 : 0 : cornerCoEdge[0] = cornerCoEdge[1];
4295 : 0 : sideInterval[3] = sideInterval[0];
4296 : 0 : sideInterval[0] = 0;
4297 : : }
4298 : 0 : return CUBIT_SUCCESS;
4299 : : }
4300 : :
4301 : : CubitBoolean
4302 : 0 : SplitSurfaceTool::is_vertex_on_side( RefVertex *ref_vertex_ptr, int side )
4303 : : {
4304 : : // Note this will return CUBIT_TRUE if the input vertex is on one of the
4305 : : // specified corners.
4306 : :
4307 : : // Position outerCoEdge loop to start of corner (note switch statement
4308 : : // falls through - case 3 will step 3 times).
4309 [ # # ]: 0 : outerCoEdgeLoop.reset();
4310 [ # # # # ]: 0 : switch( side )
4311 : : {
4312 : : case 3:
4313 [ # # ]: 0 : outerCoEdgeLoop.step( sideInterval[2] );
4314 : : case 2:
4315 [ # # ]: 0 : outerCoEdgeLoop.step( sideInterval[1] );
4316 : : case 1:
4317 [ # # ]: 0 : outerCoEdgeLoop.step( sideInterval[0] );
4318 : : }
4319 : :
4320 [ # # ]: 0 : CoEdge *co_edge_ptr = outerCoEdgeLoop.get();
4321 [ # # ]: 0 : CubitVector ref_coords = ref_vertex_ptr->coordinates();
4322 : :
4323 [ # # ]: 0 : if( sideInterval[side] == 0 )
4324 : : {
4325 : : // Compare coordinates
4326 [ # # ]: 0 : RefVertex *start_vertex_ptr = start_vertex( co_edge_ptr );
4327 [ # # ]: 0 : if( start_vertex_ptr == ref_vertex_ptr )
4328 : 0 : return CUBIT_TRUE;
4329 [ # # ][ # # ]: 0 : if( ref_coords.about_equal( start_vertex_ptr->coordinates() ) )
[ # # ]
4330 : 0 : return CUBIT_TRUE;
4331 : : else
4332 : 0 : return CUBIT_FALSE;
4333 : : }
4334 : :
4335 : : // Check if it is on each coedge
4336 : : CubitPointContainment pnt_containment;
4337 : : int i;
4338 [ # # ]: 0 : for( i=sideInterval[side]; i--; )
4339 : : {
4340 [ # # ]: 0 : co_edge_ptr = outerCoEdgeLoop.get_and_step();
4341 : : pnt_containment = co_edge_ptr->get_ref_edge_ptr()->
4342 [ # # ][ # # ]: 0 : point_containment( ref_coords );
4343 [ # # ]: 0 : if( pnt_containment == CUBIT_PNT_ON )
4344 : 0 : return CUBIT_TRUE;
4345 : : }
4346 : :
4347 : 0 : return CUBIT_FALSE;
4348 : : }
4349 : :
4350 : : CubitBoolean
4351 : 0 : SplitSurfaceTool::is_vertex_in_surface( RefVertex *ref_vertex_ptr,
4352 : : RefFace *ref_face_ptr )
4353 : : {
4354 : : // Base on finding RefFaces since there will typically be fewer RefFaces
4355 : : // to search than RefVertices
4356 [ # # ]: 0 : DLIList<RefFace*> ref_face_list;
4357 [ # # ]: 0 : ref_vertex_ptr->ref_faces( ref_face_list );
4358 [ # # ][ # # ]: 0 : return ref_face_list.is_in_list( ref_face_ptr );
4359 : : }
4360 : :
4361 : : CubitBoolean
4362 : 0 : SplitSurfaceTool::is_curve_in_outer_loop( RefEdge *ref_edge_ptr )
4363 : : {
4364 : 0 : outerCoEdgeLoop.reset();
4365 : : int i;
4366 [ # # ]: 0 : for( i=outerCoEdgeLoop.size(); i--; )
4367 : : {
4368 [ # # ]: 0 : if( ref_edge_ptr == outerCoEdgeLoop.get_and_step()->get_ref_edge_ptr() )
4369 : 0 : return CUBIT_TRUE;
4370 : : }
4371 : 0 : return CUBIT_FALSE;
4372 : : }
4373 : :
4374 : : CubitBoolean
4375 : 0 : SplitSurfaceTool::is_curve_on_side( RefEdge *ref_edge_ptr, int side )
4376 : : {
4377 [ # # ]: 0 : if( sideInterval[side] == 0 )
4378 : 0 : return CUBIT_FALSE;
4379 : :
4380 : : // Position outerCoEdge loop to start of corner (note switch statement
4381 : : // falls through - case 3 will step 3 times).
4382 : 0 : outerCoEdgeLoop.reset();
4383 [ # # # # ]: 0 : switch( side )
4384 : : {
4385 : : case 3:
4386 : 0 : outerCoEdgeLoop.step( sideInterval[2] );
4387 : : case 2:
4388 : 0 : outerCoEdgeLoop.step( sideInterval[1] );
4389 : : case 1:
4390 : 0 : outerCoEdgeLoop.step( sideInterval[0] );
4391 : : }
4392 : :
4393 : : // Compare against each coedge on the given side
4394 : : int i;
4395 [ # # ]: 0 : for( i=sideInterval[side]; i--; )
4396 : : {
4397 [ # # ]: 0 : if( ref_edge_ptr == outerCoEdgeLoop.get_and_step()->get_ref_edge_ptr() )
4398 : 0 : return CUBIT_TRUE;
4399 : : }
4400 : :
4401 : 0 : return CUBIT_FALSE;
4402 : : }
4403 : :
4404 : : CubitStatus
4405 : 0 : SplitSurfaceTool::position_co_edge_list( int i, DLIList<CoEdge*> &co_edge_list )
4406 : : {
4407 : : // 6 5 4
4408 : : // +----+---+
4409 : : // | |
4410 : : // | |
4411 : : // 7+ +3
4412 : : // | |
4413 : : // 7+----+---+3
4414 : : // | |
4415 : : // | |
4416 : : // 7+ +3
4417 : : // | |
4418 : : // 7+-+---+--+3
4419 : : // | |
4420 : : // | |
4421 : : // 7+ +3
4422 : : // | |
4423 : : // +---+----+
4424 : : // 0 1 2
4425 : : // Now, get to the start of the loop. This will either be on vertex 0 or
4426 : : // the last vertex 7 (see diagram above).
4427 : :
4428 : : CoEdge *co_edge_ptr;
4429 : : CoEdge *next_co_edge_ptr;
4430 : 0 : co_edge_list.reset();
4431 [ # # ]: 0 : for( i=co_edge_list.size(); i--; )
4432 : : {
4433 : 0 : co_edge_ptr = co_edge_list.get_and_step();
4434 : 0 : next_co_edge_ptr = co_edge_list.get_and_back();
4435 : :
4436 : : // Get the tooldata from the start vertex
4437 : : TDSplitSurface *tdssv_start = (TDSplitSurface *)co_edge_ptr->
4438 : 0 : get_TD(&TDSplitSurface::is_split_surface);
4439 : :
4440 [ # # ]: 0 : if( tdssv_start )
4441 : : {
4442 [ # # ]: 0 : if( tdssv_start->get_type() == 0 )
4443 : 0 : break; // This is the start
4444 [ # # ]: 0 : else if (tdssv_start->get_type() == 7)
4445 : : {
4446 : : // Check end of curve - if not a 7 or 0 we are done
4447 : : TDSplitSurface *tdssv_end = (TDSplitSurface *)next_co_edge_ptr->
4448 : 0 : get_TD(&TDSplitSurface::is_split_surface);
4449 [ # # ]: 0 : if( !tdssv_end )
4450 : 0 : break;
4451 [ # # ][ # # ]: 0 : if( tdssv_end->get_type() != 7 && tdssv_end->get_type() != 0 )
[ # # ]
4452 : 0 : break;
4453 : : }
4454 [ # # ]: 0 : else if (tdssv_start->get_type() == 6)
4455 : : {
4456 : : // Check end of curve - if not a 7 or 0 we are done
4457 : : // (it will typically be NULL or type 3 - see top surface
4458 : : // in diagram below)
4459 : : //
4460 : : // 6 5 4
4461 : : // +---+----+
4462 : : // | \ |
4463 : : // | \ |
4464 : : // | + |
4465 : : // | \|
4466 : : // 7+-+---+--+3
4467 : : // | |
4468 : : // | |
4469 : : // 7+ +3
4470 : : // | |
4471 : : // +---+----+
4472 : : // 0 1 2
4473 : :
4474 : : TDSplitSurface *tdssv_end = (TDSplitSurface *)next_co_edge_ptr->
4475 : 0 : get_TD(&TDSplitSurface::is_split_surface);
4476 [ # # ]: 0 : if( !tdssv_end )
4477 : 0 : break;
4478 [ # # ][ # # ]: 0 : if( tdssv_end->get_type() != 7 && tdssv_end->get_type() != 0 )
[ # # ]
4479 : 0 : break;
4480 : : }
4481 : : }
4482 : 0 : co_edge_list.step();
4483 : : }
4484 : :
4485 : 0 : return CUBIT_SUCCESS;
4486 : : }
4487 : :
4488 : : CubitStatus
4489 : 0 : SplitSurfaceTool::get_a_coedges( DLIList<CoEdge*> &co_edge_list,
4490 : : DLIList<CoEdge*> &a_coedges )
4491 : : {
4492 : : // Get all curves until end vertex type = 2 or 3 or 4 (3 or 4 in case of triangle)
4493 : : int i;
4494 : : CoEdge *co_edge_ptr;
4495 : : CoEdge *next_co_edge_ptr;
4496 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
4497 : : {
4498 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
4499 [ # # ]: 0 : a_coedges.append( co_edge_ptr );
4500 : :
4501 [ # # ]: 0 : next_co_edge_ptr = co_edge_list.get();
4502 : :
4503 : : // Get the tooldata from the next coedge (need value on end vertex of
4504 : : // first coedge).
4505 : : TDSplitSurface *tdss = (TDSplitSurface *)next_co_edge_ptr->
4506 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
4507 : :
4508 [ # # ]: 0 : if( !tdss )
4509 : 0 : continue;
4510 : :
4511 [ # # ][ # # ]: 0 : if( tdss->get_type() == 2 || tdss->get_type() == 3
[ # # ][ # # ]
4512 [ # # ][ # # ]: 0 : || tdss->get_type() == 4 )
[ # # ]
4513 : 0 : break;
4514 : : }
4515 : 0 : return CUBIT_SUCCESS;
4516 : : }
4517 : :
4518 : : CubitStatus
4519 : 0 : SplitSurfaceTool::get_b_coedges( DLIList<CoEdge*> &co_edge_list,
4520 : : DLIList<CoEdge*> &b_coedges )
4521 : : {
4522 : : // Keep getting curves as long as end vertex type = 3 or 4 (stop at 4)
4523 : : int i;
4524 : : CoEdge *co_edge_ptr;
4525 : : CoEdge *next_co_edge_ptr;
4526 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
4527 : : {
4528 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
4529 [ # # ]: 0 : next_co_edge_ptr = co_edge_list.get_and_back();
4530 : :
4531 : : // Get the tooldata from the end vertex
4532 : : TDSplitSurface *tdss = (TDSplitSurface *)next_co_edge_ptr->
4533 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
4534 : :
4535 [ # # ]: 0 : if( !tdss )
4536 : 0 : return CUBIT_SUCCESS;
4537 : :
4538 [ # # ][ # # ]: 0 : if( tdss->get_type() == 4 )
4539 : : {
4540 [ # # ]: 0 : b_coedges.append( co_edge_ptr );
4541 [ # # ]: 0 : co_edge_list.step();
4542 : 0 : return CUBIT_SUCCESS;
4543 : : }
4544 : :
4545 [ # # ][ # # ]: 0 : if( tdss->get_type() == 3 )
4546 : : {
4547 [ # # ]: 0 : b_coedges.append( co_edge_ptr );
4548 [ # # ]: 0 : co_edge_list.step();
4549 : 0 : continue;
4550 : : }
4551 : :
4552 : 0 : return CUBIT_SUCCESS;
4553 : : }
4554 : 0 : return CUBIT_SUCCESS;
4555 : : }
4556 : :
4557 : : CubitStatus
4558 : 0 : SplitSurfaceTool::get_c_coedges( DLIList<CoEdge*> &co_edge_list,
4559 : : DLIList<CoEdge*> &c_coedges )
4560 : : {
4561 : : // Keep getting curves until end vertex type = 6 or 7 or 0 (for triangle)
4562 : : int i;
4563 : : CoEdge *co_edge_ptr;
4564 : : CoEdge *next_co_edge_ptr;
4565 [ # # ][ # # ]: 0 : for( i=co_edge_list.size(); i--; )
4566 : : {
4567 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
4568 [ # # ]: 0 : next_co_edge_ptr = co_edge_list.get_and_back();
4569 : :
4570 : : // Get the tooldata from the end vertex
4571 : : TDSplitSurface *tdss = (TDSplitSurface *)next_co_edge_ptr->
4572 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
4573 : :
4574 [ # # ]: 0 : if( !tdss )
4575 : : {
4576 [ # # ]: 0 : c_coedges.append( co_edge_ptr );
4577 [ # # ]: 0 : co_edge_list.step();
4578 : 0 : continue;
4579 : : }
4580 : :
4581 [ # # ][ # # ]: 0 : if( tdss->get_type() == 6 || tdss->get_type() == 7 ||
[ # # ][ # # ]
[ # # ][ # # ]
4582 [ # # ]: 0 : tdss->get_type() == 0 )
4583 : : {
4584 [ # # ]: 0 : c_coedges.append( co_edge_ptr );
4585 [ # # ]: 0 : co_edge_list.step();
4586 : 0 : return CUBIT_SUCCESS;
4587 : : }
4588 : :
4589 [ # # ]: 0 : c_coedges.append( co_edge_ptr );
4590 [ # # ]: 0 : co_edge_list.step();
4591 : :
4592 : : }
4593 : 0 : return CUBIT_SUCCESS;
4594 : : }
4595 : :
4596 : : CubitStatus
4597 : 0 : SplitSurfaceTool::get_d_coedges( DLIList<CoEdge*> &co_edge_list,
4598 : : int num_so_far, DLIList<CoEdge*> &d_coedges )
4599 : : {
4600 : : // Get remaining curves
4601 [ # # ][ # # ]: 0 : if( co_edge_list.size() == num_so_far )
4602 : 0 : return CUBIT_SUCCESS;
4603 : :
4604 [ # # ][ # # ]: 0 : if( num_so_far > co_edge_list.size() )
4605 : : {
4606 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unexpected error in algorithm; aborting.\n" );
[ # # ][ # # ]
4607 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( " Surface = %d, num_so_far = %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4608 [ # # ]: 0 : co_edge_list.get()->get_ref_face()->id(), num_so_far );
4609 : 0 : return CUBIT_FAILURE;
4610 : : }
4611 : :
4612 : : int i;
4613 : : CoEdge *co_edge_ptr;
4614 [ # # ][ # # ]: 0 : for( i=co_edge_list.size()-num_so_far; i--; )
4615 : : {
4616 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
4617 [ # # ]: 0 : d_coedges.append( co_edge_ptr );
4618 : : }
4619 : :
4620 : 0 : return CUBIT_SUCCESS;
4621 : : }
4622 : :
4623 : : void
4624 : 0 : SplitSurfaceTool::list_sides_debug()
4625 : : {
4626 [ # # ]: 0 : if( !DEBUG_FLAG(154) )
4627 : 0 : return;
4628 : :
4629 : : int i, j;
4630 : : RefFace *ref_face_ptr;
4631 : : TDSplitSurface *tdss;
4632 : :
4633 : 0 : refFaceChain.reset();
4634 [ # # ]: 0 : for( i=refFaceChain.size(); i--; )
4635 : : {
4636 [ # # ]: 0 : ref_face_ptr = refFaceChain.get_and_step();
4637 : : tdss = (TDSplitSurface *)ref_face_ptr->
4638 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
4639 : :
4640 [ # # ][ # # ]: 0 : PRINT_INFO( "Surface %d:\n", ref_face_ptr->id() );
[ # # ][ # # ]
[ # # ]
4641 : :
4642 : : DLIList<CoEdge*> *side_co_edge_list;
4643 [ # # ]: 0 : side_co_edge_list = tdss->get_a_coedges();
4644 [ # # ]: 0 : DLIList<RefEdge*> side_ref_edge_list;
4645 [ # # ]: 0 : side_co_edge_list->reset();
4646 [ # # ][ # # ]: 0 : for( j=side_co_edge_list->size(); j--; )
4647 [ # # ][ # # ]: 0 : side_ref_edge_list.append( side_co_edge_list->get_and_step()->get_ref_edge_ptr() );
[ # # ]
4648 : :
4649 [ # # ][ # # ]: 0 : DLIList<CubitEntity*> cubit_edges;
4650 [ # # ][ # # ]: 0 : CAST_LIST(side_ref_edge_list, cubit_edges, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4651 : : CubitUtil::list_entity_ids( "Side 0: ",
4652 [ # # ]: 0 : cubit_edges, 80, "\n", CUBIT_FALSE );
4653 : :
4654 [ # # ]: 0 : side_co_edge_list = tdss->get_b_coedges();
4655 [ # # ]: 0 : side_ref_edge_list.clean_out();
4656 [ # # ]: 0 : side_co_edge_list->reset();
4657 [ # # ][ # # ]: 0 : for( j=side_co_edge_list->size(); j--; )
4658 [ # # ][ # # ]: 0 : side_ref_edge_list.append( side_co_edge_list->get_and_step()->get_ref_edge_ptr() );
[ # # ]
4659 : :
4660 [ # # ][ # # ]: 0 : CAST_LIST(side_ref_edge_list, cubit_edges, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4661 : : CubitUtil::list_entity_ids( "Side 1: ",
4662 [ # # ]: 0 : cubit_edges, 80, "\n", CUBIT_FALSE );
4663 : :
4664 [ # # ]: 0 : side_co_edge_list = tdss->get_c_coedges();
4665 [ # # ]: 0 : side_ref_edge_list.clean_out();
4666 [ # # ]: 0 : side_co_edge_list->reset();
4667 [ # # ][ # # ]: 0 : for( j=side_co_edge_list->size(); j--; )
4668 [ # # ][ # # ]: 0 : side_ref_edge_list.append( side_co_edge_list->get_and_step()->get_ref_edge_ptr() );
[ # # ]
4669 : :
4670 [ # # ][ # # ]: 0 : CAST_LIST(side_ref_edge_list, cubit_edges, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4671 : : CubitUtil::list_entity_ids( "Side 2: ",
4672 [ # # ]: 0 : cubit_edges, 80, "\n", CUBIT_FALSE );
4673 : :
4674 [ # # ]: 0 : side_co_edge_list = tdss->get_d_coedges();
4675 [ # # ]: 0 : side_ref_edge_list.clean_out();
4676 [ # # ]: 0 : side_co_edge_list->reset();
4677 [ # # ][ # # ]: 0 : for( j=side_co_edge_list->size(); j--; )
4678 [ # # ][ # # ]: 0 : side_ref_edge_list.append( side_co_edge_list->get_and_step()->get_ref_edge_ptr() );
[ # # ]
4679 : :
4680 [ # # ][ # # ]: 0 : CAST_LIST(side_ref_edge_list, cubit_edges, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4681 : : CubitUtil::list_entity_ids( "Side 3: ",
4682 [ # # ]: 0 : cubit_edges, 80, "\n", CUBIT_FALSE );
4683 [ # # ]: 0 : }
4684 : : }
4685 : :
4686 : : CubitStatus
4687 : 0 : SplitSurfaceTool::find_spline_curves( RefFace *ref_face_ptr, int num_segs,
4688 : : double distance,
4689 : : DLIList<Curve*> *curve_list_ptr,
4690 : : double tolerance,
4691 : : CubitBoolean parametric_flg,
4692 : : CubitBoolean preview_flg,
4693 : : CubitBoolean create_ref_edges_flg )
4694 : : {
4695 : : int i, j;
4696 : :
4697 : : TDSplitSurface *tdss = (TDSplitSurface *)ref_face_ptr->
4698 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
4699 : :
4700 : 0 : TopologyBridge* bridge = 0;
4701 : : // GeometryModifyEngine* gme =
4702 [ # # ][ # # ]: 0 : GeometryModifyTool::instance()->get_engine( ref_face_ptr, &bridge );
4703 [ # # ]: 0 : Surface* surf_ptr = dynamic_cast<Surface*>(bridge);
4704 : :
4705 : : // Interpolate to find the spline points
4706 : : //
4707 : : // sideC
4708 : : // a[nr-1][i]
4709 : : // _________________________________________
4710 : : // (0,1)| |(1,1)
4711 : : // | |
4712 : : // | |
4713 : : // | |
4714 : : // | |
4715 : : // | |
4716 : : // a[j][0] | |
4717 : : // | | a[j][nc-1]
4718 : : // sideD | |
4719 : : // | ada (row) | sideB
4720 : : // | ^ |
4721 : : // | | |
4722 : : // | | (tse,ada) |
4723 : : // | | |
4724 : : // | +----->tse (column) |
4725 : : // (0,0)|_________________________________________|(1,0)
4726 : : // a[0][i]
4727 : : // sideA
4728 : :
4729 : : // Split direction is vertical in the above diagram.
4730 : :
4731 [ # # ][ # # ]: 0 : if( ref_face_ptr->is_parametric() && parametric_flg==CUBIT_TRUE )
[ # # ][ # # ]
4732 : : {
4733 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "Using 2D mapping to find interior points\n" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4734 : : // Do the mapping in parametric space - we have found this is
4735 : : // more accurate (especially since we don't have the benefit of
4736 : : // any elemental smoothing when we are done). However, we have
4737 : : // also found that occasionally, especially on conic surfaces,
4738 : : // the mapping will create points in the wrong space of the
4739 : : // surface (i.e., on the "other side".). For this reason we
4740 : : // default to 3D mapping.
4741 : : // Allocate a matrix of CubitVector pointers
4742 [ # # ]: 0 : int nr = tdss->coord_list_size_b(); // number of rows
4743 : 0 : int nc = num_segs+1; // number of columns
4744 : : Cubit2DPoint ***coords;
4745 [ # # ][ # # ]: 0 : coords = new Cubit2DPoint **[nr];
4746 : :
4747 [ # # ]: 0 : for( j=0; j<nr; j++ )
4748 [ # # ][ # # ]: 0 : coords[j] = new Cubit2DPoint *[nc];
4749 : :
4750 : : // Initialize
4751 [ # # ]: 0 : for( i=0; i<nr; i++ )
4752 : : {
4753 [ # # ]: 0 : for( j=0; j<nc; j++ )
4754 : 0 : coords[i][j] = NULL;
4755 : : }
4756 : :
4757 : : // Fill the boundary coordinates into coords
4758 [ # # ]: 0 : fill_boundary_coords( tdss, nr, nc, coords );
4759 : :
4760 : : // Fill the interior coords
4761 [ # # ]: 0 : fill_interior_coords( tdss, nr, nc, coords );
4762 : :
4763 : : // Generate the 3D vectors
4764 [ # # ]: 0 : CubitVector vec;
4765 : :
4766 [ # # ]: 0 : for( j=1; j<nc-1; j++ )
4767 : : {
4768 [ # # ]: 0 : DLIList<CubitVector*> spline_points;
4769 [ # # ]: 0 : for( i=0; i<nr; i++ )
4770 : : {
4771 [ # # ][ # # ]: 0 : vec = ref_face_ptr->position_from_u_v( coords[i][j]->x(), coords[i][j]->y() );
[ # # ][ # # ]
4772 [ # # ][ # # ]: 0 : spline_points.append( new CubitVector( vec ) );
[ # # ]
4773 : : }
4774 : :
4775 : : // Create the curve from the vectors
4776 : 0 : CubitBoolean project_curve = CUBIT_TRUE;
4777 [ # # ][ # # ]: 0 : if( preview_flg == CUBIT_TRUE && create_ref_edges_flg == CUBIT_FALSE )
4778 : 0 : project_curve = CUBIT_FALSE;
4779 : : Curve *curve_ptr = create_curve( spline_points, surf_ptr, tolerance,
4780 [ # # ]: 0 : CUBIT_TRUE, preview_flg, project_curve );
4781 : :
4782 : : // Free spline points
4783 [ # # ][ # # ]: 0 : while( spline_points.size() ) delete spline_points.pop();
[ # # ]
4784 : :
4785 [ # # ]: 0 : if( curve_ptr == NULL )
4786 : : {
4787 : : // Just fail if a curve can't be created
4788 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to create curve on Surface %d\n", ref_face_ptr->id() );
[ # # ][ # # ]
[ # # ]
4789 [ # # ][ # # ]: 0 : while( curve_list_ptr->size() ) delete curve_list_ptr->pop();
[ # # ][ # # ]
[ # # ]
4790 : 0 : return CUBIT_FAILURE;
4791 : : }
4792 : : else
4793 : : {
4794 [ # # ][ # # ]: 0 : curve_list_ptr->append( curve_ptr );
[ # # ]
4795 : : }
4796 : 0 : }
4797 : :
4798 : : // Free memory - all of the Cubit2DPoints were allocated
4799 [ # # ]: 0 : for( i=0; i<nr; i++ )
4800 : : {
4801 [ # # ]: 0 : for( j=0; j<nc; j++ )
4802 : 0 : delete coords[i][j];
4803 : : }
4804 : :
4805 : : // Free matrix memory
4806 [ # # ]: 0 : for( i=0; i<nr; i++ )
4807 [ # # ]: 0 : delete []coords[i];
4808 [ # # ]: 0 : delete []coords;
4809 : 0 : coords = NULL;
4810 : : }
4811 : : else
4812 : : {
4813 : : // Need to do the mapping in 3D space and project back to surface
4814 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "Using 3D mapping to find interior points\n" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4815 : :
4816 : : // Allocate a matrix of CubitVector pointers
4817 [ # # ]: 0 : int nr = tdss->coord_list_size_b(); // number of rows
4818 : 0 : int nc = num_segs+1; // number of columns
4819 : : CubitVector ***coords;
4820 [ # # ][ # # ]: 0 : coords = new CubitVector **[nr];
4821 : :
4822 [ # # ]: 0 : for( i=0; i<nr; i++ )
4823 [ # # ][ # # ]: 0 : coords[i] = new CubitVector *[nc];
4824 : :
4825 : : // Initialize
4826 [ # # ]: 0 : for( i=0; i<nr; i++ )
4827 : : {
4828 [ # # ]: 0 : for( j=0; j<nc; j++ )
4829 : 0 : coords[i][j] = NULL;
4830 : : }
4831 : :
4832 : : // Fill the boundary coordinates into coords
4833 [ # # ]: 0 : fill_boundary_coords( tdss, nr, nc, coords );
4834 : :
4835 : : // Fill the interior coords
4836 [ # # ]: 0 : fill_interior_coords( tdss, nr, nc, coords );
4837 : :
4838 : : // Smooth the 3D points (note - don't check result - the function only gives
4839 : : // a warning if it fails).
4840 [ # # ]: 0 : smooth_interior_coords( ref_face_ptr, tdss, tolerance, nr, nc, distance, coords );
4841 : :
4842 : : // Create split curves
4843 [ # # ]: 0 : for( j=1; j<nc-1; j++ )
4844 : : {
4845 [ # # ]: 0 : DLIList<CubitVector*> spline_points;
4846 [ # # ]: 0 : for( i=0; i<nr; i++ )
4847 : : {
4848 [ # # ]: 0 : ref_face_ptr->move_to_surface( *(coords[i][j]) );
4849 [ # # ][ # # ]: 0 : spline_points.append( new CubitVector( *(coords[i][j]) ) );
[ # # ]
4850 : : }
4851 : :
4852 : : // Create the curve from the vectors
4853 : 0 : CubitBoolean project_curve = CUBIT_TRUE;
4854 [ # # ][ # # ]: 0 : if( preview_flg == CUBIT_TRUE && create_ref_edges_flg == CUBIT_FALSE )
4855 : 0 : project_curve = CUBIT_FALSE;
4856 : : Curve *curve_ptr = create_curve( spline_points, surf_ptr, tolerance,
4857 [ # # ]: 0 : CUBIT_TRUE, preview_flg, project_curve );
4858 : :
4859 : : // Free spline points
4860 [ # # ][ # # ]: 0 : while( spline_points.size() ) delete spline_points.pop();
[ # # ]
4861 : :
4862 [ # # ]: 0 : if( curve_ptr == NULL )
4863 : : {
4864 : : // Just fail if a curve can't be created
4865 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to create curve on Surface %d\n", ref_face_ptr->id() );
[ # # ][ # # ]
[ # # ]
4866 [ # # ][ # # ]: 0 : while( curve_list_ptr->size() ) delete curve_list_ptr->pop();
[ # # ][ # # ]
[ # # ]
4867 : 0 : return CUBIT_FAILURE;
4868 : : }
4869 : : else
4870 [ # # ][ # # ]: 0 : curve_list_ptr->append( curve_ptr );
[ # # ]
4871 : 0 : }
4872 : :
4873 : : // Free interior points (the boundary locations were not allocated for
4874 : : // the matrix)
4875 [ # # ]: 0 : for( i=1; i<nr-1; i++ )
4876 : : {
4877 [ # # ]: 0 : for( j=1; j<nc-1; j++ )
4878 : 0 : delete coords[i][j];
4879 : : }
4880 : :
4881 : : // Free matrix memory
4882 [ # # ]: 0 : for( i=0; i<nr; i++ )
4883 [ # # ]: 0 : delete []coords[i];
4884 [ # # ]: 0 : delete []coords;
4885 : 0 : coords = NULL;
4886 : : }
4887 : :
4888 : 0 : return CUBIT_SUCCESS;
4889 : : }
4890 : :
4891 : : CubitStatus
4892 : 0 : SplitSurfaceTool::fill_boundary_coords( TDSplitSurface *tdss, int nr,
4893 : : int nc, CubitVector ***coords )
4894 : : {
4895 : : // sideC
4896 : : // coords[nr-1][c]
4897 : : // _________________________________________
4898 : : // (0,1)| |(1,1)
4899 : : // | |
4900 : : // | |
4901 : : // | |
4902 : : // | |
4903 : : // | |
4904 : : // coords[r][0] | |
4905 : : // | | coords[r][nc-1]
4906 : : // sideD | |
4907 : : // | ada (row) | sideB
4908 : : // | ^ |
4909 : : // | | |
4910 : : // | | (tse,ada) |
4911 : : // | | |
4912 : : // | +----->tse (column) |
4913 : : // (0,0)|_________________________________________|(1,0)
4914 : : // coords[0][c]
4915 : : // sideA
4916 : :
4917 : : // Split direction is vertical in the above diagram.
4918 : :
4919 : : // Debug (with DEBUG_FLAG_154)
4920 : 0 : draw_boundary_coords( tdss );
4921 : :
4922 : : int r, c;
4923 : :
4924 : : // Note: sideB and sideD contain the corner coords (sideA and sideC just
4925 : : // contain the interior coords)
4926 : 0 : tdss->coord_list_reset_a();
4927 : 0 : tdss->coord_list_reset_b();
4928 : 0 : tdss->coord_list_last_c(); // Will need to be traversed backwards
4929 : 0 : tdss->coord_list_last_d(); // Will need to be traversed backwards
4930 : :
4931 [ # # ]: 0 : for( r=0; r<nr; r++ )
4932 : : {
4933 : : // Rows go up B and D (note these contain the corner coords)
4934 : 0 : coords[r][0] = tdss->coord_list_get_and_back_d();
4935 : 0 : coords[r][nc-1] = tdss->coord_list_get_and_step_b();
4936 : : }
4937 : :
4938 [ # # ]: 0 : for( c=1; c<nc-1; c++ )
4939 : : {
4940 : : // Columns go up A and C (note these DO NOT contain the corner coords)
4941 : 0 : coords[0][c] = tdss->coord_list_get_and_step_a();
4942 : 0 : coords[nr-1][c] = tdss->coord_list_get_and_back_c();
4943 : : }
4944 : :
4945 : 0 : return CUBIT_SUCCESS;
4946 : : }
4947 : :
4948 : : // Debug function
4949 : : CubitStatus
4950 : 0 : SplitSurfaceTool::draw_boundary_coords( TDSplitSurface *tdss )
4951 : : {
4952 [ # # ][ # # ]: 0 : if( !DEBUG_FLAG(154) )
[ # # ]
4953 : 0 : return CUBIT_SUCCESS;
4954 : :
4955 : : int i;
4956 : : CubitVector *vec_ptr;
4957 : : CoEdge *co_edge_ptr;
4958 : : DLIList<CoEdge*> *co_edge_list_ptr;
4959 [ # # ]: 0 : DLIList<RefEdge*> curve_list;
4960 [ # # ][ # # ]: 0 : DLIList<CubitEntity*> cubit_curves;
4961 : :
4962 : : // Note: sideB and sideD contain the corner coords (sideA and sideC just
4963 : : // contain the interior coords)
4964 : :
4965 [ # # ][ # # ]: 0 : PRINT_INFO( "Surface %d, Side A, %d coords, YELLOW\n",
[ # # ][ # # ]
[ # # ][ # # ]
4966 [ # # ]: 0 : tdss->ref_face_ptr()->id(), tdss->coord_list_size_a() );
4967 : :
4968 [ # # ]: 0 : co_edge_list_ptr = tdss->get_a_coedges();
4969 [ # # ]: 0 : co_edge_list_ptr->reset();
4970 [ # # ][ # # ]: 0 : for( i=co_edge_list_ptr->size(); i--; )
4971 : : {
4972 [ # # ]: 0 : co_edge_ptr = co_edge_list_ptr->get_and_step();
4973 [ # # ][ # # ]: 0 : curve_list.append( co_edge_ptr->get_ref_edge_ptr() );
4974 : : }
4975 [ # # ][ # # ]: 0 : CAST_LIST(curve_list, cubit_curves, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4976 : : CubitUtil::list_entity_ids( " Curves: ",
4977 [ # # ]: 0 : cubit_curves, 80, "\n", CUBIT_FALSE );
4978 : :
4979 [ # # ]: 0 : tdss->coord_list_reset_a();
4980 [ # # ][ # # ]: 0 : for( i=tdss->coord_list_size_a(); i--; )
4981 : : {
4982 [ # # ]: 0 : vec_ptr = tdss->coord_list_get_and_step_a();
4983 [ # # ][ # # ]: 0 : PRINT_DEBUG_100( " create vertex %f %f %f color yellow\n", vec_ptr->x(),
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4984 [ # # ]: 0 : vec_ptr->y(), vec_ptr->z() );
4985 [ # # ]: 0 : GfxDebug::draw_point( *vec_ptr, CUBIT_YELLOW_INDEX );
4986 : : }
4987 : :
4988 [ # # ][ # # ]: 0 : PRINT_INFO( "Surface %d, Side B, %d coords, MAGENTA\n",
[ # # ][ # # ]
[ # # ][ # # ]
4989 [ # # ]: 0 : tdss->ref_face_ptr()->id(), tdss->coord_list_size_b() );
4990 : :
4991 [ # # ]: 0 : co_edge_list_ptr = tdss->get_b_coedges();
4992 [ # # ]: 0 : co_edge_list_ptr->reset();
4993 [ # # ]: 0 : curve_list.clean_out();
4994 [ # # ][ # # ]: 0 : for( i=co_edge_list_ptr->size(); i--; )
4995 : : {
4996 [ # # ]: 0 : co_edge_ptr = co_edge_list_ptr->get_and_step();
4997 [ # # ][ # # ]: 0 : curve_list.append( co_edge_ptr->get_ref_edge_ptr() );
4998 : : }
4999 [ # # ]: 0 : cubit_curves.clean_out();
5000 [ # # ][ # # ]: 0 : CAST_LIST(curve_list, cubit_curves, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5001 : : CubitUtil::list_entity_ids( " Curves: ",
5002 [ # # ]: 0 : cubit_curves, 80, "\n", CUBIT_FALSE );
5003 : :
5004 [ # # ]: 0 : tdss->coord_list_reset_b();
5005 [ # # ][ # # ]: 0 : for( i=tdss->coord_list_size_b(); i--; )
5006 : : {
5007 [ # # ]: 0 : vec_ptr = tdss->coord_list_get_and_step_b();
5008 [ # # ][ # # ]: 0 : PRINT_DEBUG_100( " create vertex %f %f %f color magenta\n", vec_ptr->x(),
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5009 [ # # ]: 0 : vec_ptr->y(), vec_ptr->z() );
5010 [ # # ]: 0 : GfxDebug::draw_point( *vec_ptr, CUBIT_MAGENTA_INDEX );
5011 : : }
5012 : :
5013 [ # # ][ # # ]: 0 : PRINT_INFO( "Surface %d, Side C, %d coords, GREEN\n",
[ # # ][ # # ]
[ # # ][ # # ]
5014 [ # # ]: 0 : tdss->ref_face_ptr()->id(), tdss->coord_list_size_c() );
5015 : :
5016 [ # # ]: 0 : co_edge_list_ptr = tdss->get_c_coedges();
5017 [ # # ]: 0 : co_edge_list_ptr->reset();
5018 [ # # ]: 0 : curve_list.clean_out();
5019 [ # # ][ # # ]: 0 : for( i=co_edge_list_ptr->size(); i--; )
5020 : : {
5021 [ # # ]: 0 : co_edge_ptr = co_edge_list_ptr->get_and_step();
5022 [ # # ][ # # ]: 0 : curve_list.append( co_edge_ptr->get_ref_edge_ptr() );
5023 : : }
5024 [ # # ]: 0 : cubit_curves.clean_out();
5025 [ # # ][ # # ]: 0 : CAST_LIST(curve_list, cubit_curves, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5026 : : CubitUtil::list_entity_ids( " Curves: ",
5027 [ # # ]: 0 : cubit_curves, 80, "\n", CUBIT_FALSE );
5028 : :
5029 [ # # ]: 0 : tdss->coord_list_reset_c();
5030 [ # # ][ # # ]: 0 : for( i=tdss->coord_list_size_c(); i--; )
5031 : : {
5032 [ # # ]: 0 : vec_ptr = tdss->coord_list_get_and_step_c();
5033 [ # # ][ # # ]: 0 : PRINT_DEBUG_100( " create vertex %f %f %f color green\n", vec_ptr->x(),
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5034 [ # # ]: 0 : vec_ptr->y(), vec_ptr->z() );
5035 [ # # ]: 0 : GfxDebug::draw_point( *vec_ptr, CUBIT_GREEN_INDEX );
5036 : : }
5037 : :
5038 [ # # ][ # # ]: 0 : PRINT_INFO( "Surface %d, Side D, %d coords, RED\n",
[ # # ][ # # ]
[ # # ][ # # ]
5039 [ # # ]: 0 : tdss->ref_face_ptr()->id(), tdss->coord_list_size_d() );
5040 : :
5041 [ # # ]: 0 : co_edge_list_ptr = tdss->get_d_coedges();
5042 [ # # ]: 0 : co_edge_list_ptr->reset();
5043 [ # # ]: 0 : curve_list.clean_out();
5044 [ # # ][ # # ]: 0 : for( i=co_edge_list_ptr->size(); i--; )
5045 : : {
5046 [ # # ]: 0 : co_edge_ptr = co_edge_list_ptr->get_and_step();
5047 [ # # ][ # # ]: 0 : curve_list.append( co_edge_ptr->get_ref_edge_ptr() );
5048 : : }
5049 [ # # ]: 0 : cubit_curves.clean_out();
5050 [ # # ][ # # ]: 0 : CAST_LIST(curve_list, cubit_curves, CubitEntity);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5051 : : CubitUtil::list_entity_ids( " Curves: ",
5052 [ # # ]: 0 : cubit_curves, 80, "\n", CUBIT_FALSE );
5053 : :
5054 [ # # ]: 0 : tdss->coord_list_reset_d();
5055 [ # # ][ # # ]: 0 : for( i=tdss->coord_list_size_d(); i--; )
5056 : : {
5057 [ # # ]: 0 : vec_ptr = tdss->coord_list_get_and_step_d();
5058 [ # # ][ # # ]: 0 : PRINT_DEBUG_100( " create vertex %f %f %f color red\n", vec_ptr->x(),
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5059 [ # # ]: 0 : vec_ptr->y(), vec_ptr->z() );
5060 [ # # ]: 0 : GfxDebug::draw_point( *vec_ptr, CUBIT_RED_INDEX );
5061 : : }
5062 : :
5063 [ # # ]: 0 : GfxDebug::flush();
5064 : :
5065 [ # # ]: 0 : return CUBIT_SUCCESS;
5066 : : }
5067 : :
5068 : : // Cloned from MapToolSupport, except MapToolSupport does not accurately
5069 : : // calculate ada and tse
5070 : : CubitStatus
5071 : 0 : SplitSurfaceTool::fill_interior_coords( TDSplitSurface *tdss,
5072 : : int nr, int nc, CubitVector ***coords )
5073 : : {
5074 : : int r, c;
5075 : :
5076 : 0 : int ada_ints = nr-1;
5077 : 0 : int tse_ints = nc-1;
5078 : :
5079 : : double ada, tse;
5080 : :
5081 [ # # ]: 0 : DLIList<double> tse_array;
5082 [ # # ][ # # ]: 0 : if( get_tse_array( tdss, tse_ints, tse_array ) == CUBIT_FAILURE )
5083 : 0 : return CUBIT_FAILURE;
5084 : :
5085 : : // Create all the new coords in the interior of the array
5086 [ # # ]: 0 : if( tdss )
5087 : : {
5088 : : // Initialize list position
5089 : :
5090 : : // Must use side that is not collapsed
5091 [ # # ][ # # ]: 0 : if( tdss->is_b_collapsed() && tdss->is_d_collapsed() )
[ # # ][ # # ]
[ # # ]
5092 : : ; // Nothing to do
5093 [ # # ][ # # ]: 0 : else if( tdss->is_b_collapsed() == CUBIT_FALSE )
5094 : : {
5095 [ # # ]: 0 : tdss->param_list_reset_b();
5096 [ # # ]: 0 : ada = tdss->param_list_get_and_step_b();
5097 : : }
5098 : : else
5099 : : {
5100 : : // Must go backwards on this list
5101 [ # # ]: 0 : tdss->param_list_last_d();
5102 [ # # ]: 0 : ada = tdss->param_list_get_and_back_d();
5103 : : }
5104 : : }
5105 [ # # ]: 0 : for( r=1; r<ada_ints; r++ )
5106 : : {
5107 [ # # ]: 0 : if( tdss )
5108 : : {
5109 [ # # ][ # # ]: 0 : if( tdss->is_b_collapsed() && tdss->is_d_collapsed() )
[ # # ][ # # ]
[ # # ]
5110 : 0 : ada = (double)r/(double)ada_ints;
5111 [ # # ][ # # ]: 0 : else if( tdss->is_b_collapsed() )
5112 [ # # ][ # # ]: 0 : ada = tdss->param_list_get_and_back_d()/tdss->length_d();
5113 : : else
5114 [ # # ][ # # ]: 0 : ada = tdss->param_list_get_and_step_b()/tdss->length_b();
5115 : : }
5116 : : else
5117 : : {
5118 : 0 : ada = (double)r/(double)ada_ints;
5119 : : }
5120 : :
5121 [ # # ]: 0 : tse_array.reset();
5122 [ # # ]: 0 : for( c=1; c<tse_ints; c++ )
5123 : : {
5124 [ # # ]: 0 : tse = tse_array.get_and_step();
5125 : :
5126 : : // Create a new coord at the mapped location on the face
5127 [ # # ]: 0 : coords[r][c] = make_interior_coord( coords, nr, nc, ada, tse, r, c );
5128 : : }
5129 : : }
5130 : :
5131 [ # # ]: 0 : return CUBIT_SUCCESS;
5132 : : }
5133 : :
5134 : : CubitStatus
5135 : 0 : SplitSurfaceTool::smooth_interior_coords( RefFace *ref_face_ptr,
5136 : : TDSplitSurface *tdss,
5137 : : double tolerance,
5138 : : int nr, int nc, double distance,
5139 : : CubitVector ***coords )
5140 : : {
5141 : : int r, c; // Row, Column
5142 : : CubitVector *vec_ptr;
5143 : :
5144 : : // Preserve original coordinates and restore to those if there is an error
5145 : : // (just give warning).
5146 [ # # ]: 0 : DLIList<CubitVector*> backup_coords( nr*nc );
5147 [ # # ]: 0 : for( r=0; r<nr; r++ )
5148 : : {
5149 [ # # ]: 0 : for( c=0; c<nc; c++ )
5150 [ # # ][ # # ]: 0 : backup_coords.append( new CubitVector( *coords[r][c] ) );
[ # # ]
5151 : : }
5152 : :
5153 : : // Problem: after doing a 3D map, when the interior coordinates are projected
5154 : : // back to the surface they may not lie at the correct percentage across the
5155 : : // surface (thus a fillet may not be split exactly in the middle).
5156 : :
5157 : : // Solution: create spline curves on the surface (perpendicular to the split
5158 : : // direction) at each coordinate. Move the coordinate to the proper fraction
5159 : : // distance along the spline curve. The trick is to find the proper fraction
5160 : : // distance - we use a mapping concept to determine the fraction. The real
5161 : : // need for the "fraction map" is that point A and point B in the diagram
5162 : : // below can be at different percentages along sideA and sideC, so the
5163 : : // internal fractions need to be "smoothed out". An alternative to this
5164 : : // "spline" technique might be to do something like real Winslow smoothing,
5165 : : // but that would require a lot more work to implement...
5166 : :
5167 : : // Setup fraction "map" (actual surface split is vertical in diagram below) -
5168 : : // note the splines perpendicular to the split direction).
5169 : : //
5170 : : // sideC A
5171 : : // _________________________+________+____________
5172 : : // (0,1)| |(1,1)
5173 : : // | |
5174 : : // | |
5175 : : // +............spline......+........+.............+
5176 : : // | |
5177 : : // | |
5178 : : // | |
5179 : : // | |
5180 : : // sideD +............spline.....+........+..............+
5181 : : // | |
5182 : : // | y (row) | sideB (tessellations)
5183 : : // | ^ |
5184 : : // | | |
5185 : : // | | (x,y) |
5186 : : // | | |
5187 : : // | +----->x (column) B |
5188 : : // (0,0)|_____________________+________ +______________ |(1,0)
5189 : : //
5190 : : // sideA (split locations)
5191 : :
5192 : : Cubit2DPoint ***frac_coords;
5193 [ # # ][ # # ]: 0 : frac_coords = new Cubit2DPoint **[nr];
5194 : :
5195 [ # # ]: 0 : for( r=0; r<nr; r++ )
5196 [ # # ][ # # ]: 0 : frac_coords[r] = new Cubit2DPoint *[nc];
5197 : :
5198 : : // Initialize
5199 [ # # ]: 0 : for( r=0; r<nr; r++ )
5200 : : {
5201 [ # # ]: 0 : for( c=0; c<nc; c++ )
5202 : 0 : frac_coords[r][c] = NULL;
5203 : : }
5204 : :
5205 : : // Fill the boundary "fractions" into frac_coords
5206 : :
5207 [ # # ][ # # ]: 0 : frac_coords[0][0] = new Cubit2DPoint( 0.0, 0.0 );
5208 [ # # ][ # # ]: 0 : frac_coords[0][nc-1] = new Cubit2DPoint( 1.0, 0.0 );
5209 [ # # ][ # # ]: 0 : frac_coords[nr-1][0] = new Cubit2DPoint( 0.0, 1.0 );
5210 [ # # ][ # # ]: 0 : frac_coords[nr-1][nc-1] = new Cubit2DPoint( 1.0, 1.0 );
5211 : :
5212 : : // Note: sideB and sideD contain the corner coords (sideA and sideC just
5213 : : // contain the interior coord)
5214 [ # # ]: 0 : tdss->param_list_reset_a();
5215 [ # # ]: 0 : tdss->param_list_reset_b();
5216 [ # # ]: 0 : tdss->param_list_get_and_step_b(); // Move off the corner
5217 [ # # ]: 0 : tdss->param_list_last_c(); // Will need to be traversed backwards
5218 [ # # ]: 0 : tdss->param_list_last_d(); // Will need to be traversed backwards
5219 [ # # ]: 0 : tdss->param_list_get_and_back_d(); // Move off the corner
5220 : :
5221 : : double frac_a, frac_b, frac_c, frac_d;
5222 : :
5223 [ # # ]: 0 : for( r=1; r<nr-1; r++ )
5224 : : {
5225 : : // Rows go up B and D (note these contain the corner coords)
5226 [ # # ][ # # ]: 0 : if( tdss->is_b_collapsed() && tdss->is_d_collapsed() )
[ # # ][ # # ]
[ # # ]
5227 : : {
5228 : 0 : frac_b = double(r)/double(nr-1);
5229 : 0 : frac_d = frac_b;
5230 : : }
5231 [ # # ][ # # ]: 0 : else if( tdss->is_d_collapsed() )
5232 : : {
5233 : : // Use B for both sides
5234 [ # # ][ # # ]: 0 : frac_b = tdss->param_list_get_and_step_b()/tdss->length_b();
5235 : 0 : frac_d = frac_b;
5236 : : }
5237 [ # # ][ # # ]: 0 : else if( tdss->is_b_collapsed() )
5238 : : {
5239 : : // Use D for both sides
5240 [ # # ][ # # ]: 0 : frac_d = (tdss->length_d()-tdss->param_list_get_and_back_d())/tdss->length_d();
[ # # ]
5241 : 0 : frac_b = frac_d;
5242 : : }
5243 : : else
5244 : : {
5245 [ # # ][ # # ]: 0 : frac_b = tdss->param_list_get_and_step_b()/tdss->length_b();
5246 [ # # ][ # # ]: 0 : frac_d = (tdss->length_d()-tdss->param_list_get_and_back_d())/tdss->length_d();
[ # # ]
5247 : : }
5248 : :
5249 [ # # ][ # # ]: 0 : frac_coords[r][0] = new Cubit2DPoint( 0.0, frac_d );
5250 [ # # ][ # # ]: 0 : frac_coords[r][nc-1] = new Cubit2DPoint( 1.0, frac_b );
5251 : :
5252 : : // PRINT_INFO( "frac_coords[%d][0] = %f, %f\n", r, frac_coords[r][0]->x(),
5253 : : // frac_coords[r][0]->y() );
5254 : : // PRINT_INFO( "frac_coords[%d][%d] = %f, %f\n", r, nc-1, frac_coords[r][nc-1]->x(),
5255 : : // frac_coords[r][nc-1]->y() );
5256 : : }
5257 : :
5258 [ # # ]: 0 : for( c=1; c<nc-1; c++ )
5259 : : {
5260 : : // Columns go up A and C (note these DO NOT contain the corner coords)
5261 [ # # ][ # # ]: 0 : if( tdss->is_a_collapsed() && tdss->is_c_collapsed() )
[ # # ][ # # ]
[ # # ]
5262 : : {
5263 : 0 : frac_a = double(c)/double(nc-1);
5264 : 0 : frac_c = frac_a;
5265 : : }
5266 [ # # ][ # # ]: 0 : else if( tdss->is_a_collapsed() )
5267 : : {
5268 : : // Use C for both sides
5269 [ # # ][ # # ]: 0 : frac_c = (tdss->length_c()-tdss->param_list_get_and_back_c())/tdss->length_c();
[ # # ]
5270 : 0 : frac_a = frac_c;
5271 : : }
5272 [ # # ][ # # ]: 0 : else if( tdss->is_c_collapsed() )
5273 : : {
5274 : : // Use A for both sides
5275 [ # # ][ # # ]: 0 : frac_a = tdss->param_list_get_and_step_a()/tdss->length_a();
5276 : 0 : frac_c = frac_a;
5277 : : }
5278 : : else
5279 : : {
5280 [ # # ][ # # ]: 0 : frac_a = tdss->param_list_get_and_step_a()/tdss->length_a();
5281 [ # # ][ # # ]: 0 : frac_c = (tdss->length_c()-tdss->param_list_get_and_back_c())/tdss->length_c();
[ # # ]
5282 : : }
5283 : :
5284 [ # # ][ # # ]: 0 : frac_coords[0][c] = new Cubit2DPoint( frac_a, 0.0 );
5285 [ # # ][ # # ]: 0 : frac_coords[nr-1][c] = new Cubit2DPoint( frac_c, 1.0 );
5286 : :
5287 : : // PRINT_INFO( "frac_coords[0][%d] = %f, %f\n", c, frac_coords[0][c]->x(),
5288 : : // frac_coords[0][c]->y() );
5289 : : // PRINT_INFO( "frac_coords[%d][%d] = %f, %f\n", nr-1, c, frac_coords[nr-1][c]->x(),
5290 : : // frac_coords[nr-1][c]->y() );
5291 : : }
5292 : :
5293 : : // Fill interior coordinates
5294 [ # # ]: 0 : fill_interior_coords( tdss, nr, nc, frac_coords );
5295 : :
5296 : : // Now create the splines
5297 : :
5298 : 0 : TopologyBridge* bridge = 0;
5299 : : GeometryModifyEngine* gme =
5300 [ # # ][ # # ]: 0 : GeometryModifyTool::instance()->get_engine( ref_face_ptr, &bridge );
5301 : : // Surface* surf_ptr = dynamic_cast<Surface*>(bridge);
5302 : :
5303 [ # # ]: 0 : for( r=1; r<nr-1; r++ )
5304 : : {
5305 : : // Move interior points to surface
5306 [ # # ]: 0 : for( c=1; c<nc-1; c++ )
5307 [ # # ]: 0 : ref_face_ptr->move_to_surface( *(coords[r][c]) );
5308 : :
5309 : : // Make a spline across the surface
5310 [ # # ]: 0 : DLIList<CubitVector*> spline_points;
5311 [ # # ]: 0 : for( c=0; c<nc; c++ )
5312 [ # # ]: 0 : spline_points.append( coords[r][c] );
5313 : :
5314 [ # # ]: 0 : spline_points.reset();
5315 [ # # ]: 0 : CubitVector *start_pnt = spline_points.get_and_back();
5316 [ # # ]: 0 : CubitVector *end_pnt = spline_points.get();
5317 : :
5318 [ # # ]: 0 : TBPoint *start_Point = gme->make_Point( *start_pnt );
5319 [ # # ]: 0 : TBPoint *end_Point = gme->make_Point( *end_pnt );
5320 [ # # ][ # # ]: 0 : if( start_Point == NULL || end_Point == NULL )
5321 : : {
5322 [ # # ][ # # ]: 0 : PRINT_WARNING( "Unable to adjust split positions - split may be inaccurate\n" );
[ # # ][ # # ]
5323 : :
5324 : : // Restore ALL original points & move to surface
5325 [ # # ]: 0 : backup_coords.reset();
5326 [ # # ]: 0 : for( r=0; r<nr; r++ )
5327 : : {
5328 [ # # ]: 0 : for( c=0; c<nc; c++ )
5329 : : {
5330 [ # # ]: 0 : vec_ptr = backup_coords.get_and_step();
5331 [ # # ]: 0 : ref_face_ptr->move_to_surface( *vec_ptr );
5332 [ # # ]: 0 : coords[r][c]->set( *vec_ptr );
5333 : 0 : delete vec_ptr;
5334 : : }
5335 : : }
5336 : :
5337 : : // Free memory
5338 [ # # ][ # # ]: 0 : if( start_Point ) start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
[ # # ]
5339 [ # # ][ # # ]: 0 : if( end_Point ) end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
[ # # ]
5340 [ # # ]: 0 : for( r=0; r<nr; r++ )
5341 : : {
5342 [ # # ]: 0 : for( c=0; c<nc; c++ )
5343 : 0 : delete frac_coords[r][c];
5344 : : }
5345 [ # # ]: 0 : for( r=0; r<nr; r++ )
5346 [ # # ]: 0 : delete []frac_coords[r];
5347 [ # # ]: 0 : delete []frac_coords;
5348 : 0 : frac_coords = NULL;
5349 : :
5350 : 0 : return CUBIT_FAILURE;
5351 : : }
5352 : :
5353 : : // Here, note it is not necessary to create the curve on the surface
5354 : : Curve *curve_ptr = gme->make_Curve( SPLINE_CURVE_TYPE, start_Point, end_Point,
5355 [ # # ]: 0 : spline_points );
5356 : :
5357 : : // Debug
5358 [ # # ][ # # ]: 0 : if( DEBUG_FLAG( 100 ) )
[ # # ]
5359 [ # # ]: 0 : draw_preview( curve_ptr, CUBIT_TRUE, CUBIT_RED_INDEX );
5360 : :
5361 [ # # ]: 0 : if( curve_ptr == NULL )
5362 : : {
5363 [ # # ][ # # ]: 0 : PRINT_WARNING( "Unable to adjust split positions - split may be inaccurate\n" );
[ # # ][ # # ]
5364 : :
5365 : : // Restore ALL original points & move to surface
5366 [ # # ]: 0 : backup_coords.reset();
5367 [ # # ]: 0 : for( r=0; r<nr; r++ )
5368 : : {
5369 [ # # ]: 0 : for( c=0; c<nc; c++ )
5370 : : {
5371 [ # # ]: 0 : vec_ptr = backup_coords.get_and_step();
5372 [ # # ]: 0 : ref_face_ptr->move_to_surface( *vec_ptr );
5373 [ # # ]: 0 : coords[r][c]->set( *vec_ptr );
5374 : 0 : delete vec_ptr;
5375 : : }
5376 : : }
5377 : :
5378 : : // Free memory
5379 [ # # ]: 0 : for( r=0; r<nr; r++ )
5380 : : {
5381 [ # # ]: 0 : for( c=0; c<nc; c++ )
5382 : 0 : delete frac_coords[r][c];
5383 : : }
5384 [ # # ]: 0 : for( r=0; r<nr; r++ )
5385 [ # # ]: 0 : delete []frac_coords[r];
5386 [ # # ]: 0 : delete []frac_coords;
5387 : 0 : frac_coords = NULL;
5388 : :
5389 : 0 : return CUBIT_FAILURE;
5390 : : }
5391 : :
5392 : : // Space interior points along the Curve per the original fractions
5393 [ # # ]: 0 : spline_points.reset();
5394 [ # # ]: 0 : spline_points.step();
5395 [ # # ]: 0 : double curve_length = curve_ptr->measure();
5396 [ # # ]: 0 : for ( c=1; c<nc-1; c++ )
5397 : : {
5398 [ # # ]: 0 : vec_ptr = spline_points.get_and_step();
5399 : :
5400 : : // Find total length of curve and multiply by the fraction
5401 : : double mv_distance;
5402 [ # # ]: 0 : if( distance == -1.0 )
5403 [ # # ]: 0 : mv_distance = curve_length*(frac_coords[r][c]->x());
5404 : : else
5405 : 0 : mv_distance = distance;
5406 : :
5407 [ # # ]: 0 : CubitVector curve_position;
5408 [ # # ][ # # ]: 0 : if( curve_ptr->point_from_arc_length ( *start_pnt, mv_distance, curve_position )
5409 : : == CUBIT_FAILURE )
5410 : : {
5411 [ # # ][ # # ]: 0 : PRINT_WARNING( "Unable to adjust split positions - split may be inaccurate\n" );
[ # # ][ # # ]
5412 : :
5413 : : // Restore ALL original points & move to surface
5414 [ # # ]: 0 : backup_coords.reset();
5415 [ # # ]: 0 : for( r=0; r<nr; r++ )
5416 : : {
5417 [ # # ]: 0 : for( c=0; c<nc; c++ )
5418 : : {
5419 [ # # ]: 0 : vec_ptr = backup_coords.get_and_step();
5420 [ # # ]: 0 : ref_face_ptr->move_to_surface( *vec_ptr );
5421 [ # # ]: 0 : coords[r][c]->set( *vec_ptr );
5422 : 0 : delete vec_ptr;
5423 : : }
5424 : : }
5425 : :
5426 : : // Free memory
5427 [ # # ]: 0 : for( r=0; r<nr; r++ )
5428 : : {
5429 [ # # ]: 0 : for( c=0; c<nc; c++ )
5430 : 0 : delete frac_coords[r][c];
5431 : : }
5432 : :
5433 : : // Free matrix memory
5434 [ # # ]: 0 : for( r=0; r<nr; r++ )
5435 [ # # ]: 0 : delete []frac_coords[r];
5436 [ # # ]: 0 : delete []frac_coords;
5437 : 0 : frac_coords = NULL;
5438 : :
5439 : : // Free spline
5440 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
5441 : 0 : return CUBIT_FAILURE;
5442 : : }
5443 : :
5444 [ # # ]: 0 : vec_ptr->set( curve_position );
5445 : : }
5446 : :
5447 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
[ # # ][ # # ]
5448 : : //GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
5449 : 0 : }
5450 : :
5451 : : // Free memory - all of the frac_coords were allocated
5452 [ # # ]: 0 : for( r=0; r<nr; r++ )
5453 : : {
5454 [ # # ]: 0 : for( c=0; c<nc; c++ )
5455 : 0 : delete frac_coords[r][c];
5456 : : }
5457 : :
5458 : : // Free matrix memory
5459 [ # # ]: 0 : for( r=0; r<nr; r++ )
5460 [ # # ]: 0 : delete []frac_coords[r];
5461 [ # # ]: 0 : delete []frac_coords;
5462 : 0 : frac_coords = NULL;
5463 : :
5464 : : // Free backup coords
5465 [ # # ][ # # ]: 0 : while( backup_coords.size() )
5466 [ # # ]: 0 : delete backup_coords.pop();
5467 : :
5468 [ # # ]: 0 : return CUBIT_SUCCESS;
5469 : : }
5470 : :
5471 : : CubitVector*
5472 : 0 : SplitSurfaceTool::make_interior_coord( CubitVector ***coords,
5473 : : int nr, int nc,
5474 : : double ada, double tse,
5475 : : int r, int c )
5476 : : {
5477 : : double temp_x, temp_y, temp_z;
5478 : : CubitVector *vec;
5479 : 0 : int ada_ints = nr-1;
5480 : 0 : int tse_ints = nc-1;
5481 : :
5482 : 0 : temp_x = (1.0 - ada)*coords[0][c]->x()
5483 : 0 : + ada*coords[ada_ints][c]->x()
5484 : 0 : + (1.0 - tse)*coords[r][0]->x()
5485 : 0 : + tse*coords[r][tse_ints]->x()
5486 : 0 : - (1.0 - tse)*(1.0 - ada)*coords[0][0]->x()
5487 : 0 : - (1.0 - tse)*ada*coords[ada_ints][0]->x()
5488 : 0 : - tse*(1.0 - ada)*coords[0][tse_ints]->x()
5489 : 0 : - tse*ada*coords[ada_ints][tse_ints]->x();
5490 : :
5491 : 0 : temp_y = (1.0 - ada)*coords[0][c]->y()
5492 : 0 : + ada*coords[ada_ints][c]->y()
5493 : 0 : + (1.0 - tse)*coords[r][0]->y()
5494 : 0 : + tse*coords[r][tse_ints]->y()
5495 : 0 : - (1.0 - tse)*(1.0 - ada)*coords[0][0]->y()
5496 : 0 : - (1.0 - tse)*ada*coords[ada_ints][0]->y()
5497 : 0 : - tse*(1.0 - ada)*coords[0][tse_ints]->y()
5498 : 0 : - tse*ada*coords[ada_ints][tse_ints]->y();
5499 : :
5500 : 0 : temp_z = (1.0 - ada)*coords[0][c]->z()
5501 : 0 : + ada*coords[ada_ints][c]->z()
5502 : 0 : + (1.0 - tse)*coords[r][0]->z()
5503 : 0 : + tse*coords[r][tse_ints]->z()
5504 : 0 : - (1.0 - tse)*(1.0 - ada)*coords[0][0]->z()
5505 : 0 : - (1.0 - tse)*ada*coords[ada_ints][0]->z()
5506 : 0 : - tse*(1.0 - ada)*coords[0][tse_ints]->z()
5507 : 0 : - tse*ada*coords[ada_ints][tse_ints]->z();
5508 : :
5509 [ # # ]: 0 : vec = new CubitVector( temp_x, temp_y, temp_z );
5510 : :
5511 : 0 : return vec;
5512 : : }
5513 : :
5514 : : CubitStatus
5515 : 0 : SplitSurfaceTool::fill_boundary_coords( TDSplitSurface *tdss, int nr,
5516 : : int nc, Cubit2DPoint ***coords )
5517 : : {
5518 : : // sideC
5519 : : // coords[nr-1][c]
5520 : : // _________________________________________
5521 : : // (0,1)| |(1,1)
5522 : : // | |
5523 : : // | |
5524 : : // | |
5525 : : // | |
5526 : : // | |
5527 : : // coords[r][0] | |
5528 : : // | | coords[r][nc-1]
5529 : : // sideD | |
5530 : : // | ada (row) | sideB
5531 : : // | ^ |
5532 : : // | | |
5533 : : // | | (tse,ada) |
5534 : : // | | |
5535 : : // | +----->tse (column) |
5536 : : // (0,0)|_________________________________________|(1,0)
5537 : : // coords[0][c]
5538 : : // sideA
5539 : :
5540 : : // Split direction is vertical in the above diagram.
5541 : :
5542 : : // Debug (with DEBUG_FLAG_154)
5543 : 0 : draw_boundary_coords( tdss );
5544 : :
5545 : : int r, c;
5546 : 0 : RefFace *ref_face_ptr = tdss->ref_face_ptr();
5547 : :
5548 : : // Note: sideB and sideD contain the corner coords (sideA and sideC just
5549 : : // contain the interior coords)
5550 : 0 : tdss->coord_list_reset_a();
5551 : 0 : tdss->coord_list_reset_b();
5552 : 0 : tdss->coord_list_last_c(); // Will need to be traversed backwards
5553 : 0 : tdss->coord_list_last_d(); // Will need to be traversed backwards
5554 : :
5555 [ # # ]: 0 : for( r=0; r<nr; r++ )
5556 : : {
5557 : : // Rows go up B and D (note these contain the corner coords)
5558 : 0 : coords[r][0] = get_uv_point( ref_face_ptr, tdss->coord_list_get_and_back_d() );
5559 : 0 : coords[r][nc-1] = get_uv_point( ref_face_ptr, tdss->coord_list_get_and_step_b() );
5560 : : }
5561 : :
5562 [ # # ]: 0 : for( c=1; c<nc-1; c++ )
5563 : : {
5564 : : // Columns go up A and C (note these DO NOT contain the corner coords)
5565 : 0 : coords[0][c] = get_uv_point( ref_face_ptr, tdss->coord_list_get_and_step_a() );
5566 : 0 : coords[nr-1][c] = get_uv_point( ref_face_ptr, tdss->coord_list_get_and_back_c() );
5567 : : }
5568 : :
5569 : 0 : return CUBIT_SUCCESS;
5570 : : }
5571 : :
5572 : : Cubit2DPoint *
5573 : 0 : SplitSurfaceTool::get_uv_point( RefFace *ref_face_ptr, CubitVector *vec_ptr )
5574 : : {
5575 : : double u, v;
5576 [ # # ]: 0 : ref_face_ptr->u_v_from_position( *vec_ptr, u, v );
5577 [ # # ][ # # ]: 0 : return( new Cubit2DPoint( u, v ) );
5578 : : }
5579 : :
5580 : : // Cloned from MapToolSupport, except MapToolSupport does not accurately
5581 : : // calculate ada and tse
5582 : : CubitStatus
5583 : 0 : SplitSurfaceTool::fill_interior_coords( TDSplitSurface *tdss,
5584 : : int nr, int nc, Cubit2DPoint ***coords )
5585 : : {
5586 : : int r, c;
5587 : :
5588 : 0 : int ada_ints = nr-1;
5589 : 0 : int tse_ints = nc-1;
5590 : :
5591 : : double ada, tse;
5592 : :
5593 [ # # ]: 0 : DLIList<double> tse_array;
5594 [ # # ][ # # ]: 0 : if( get_tse_array( tdss, tse_ints, tse_array ) == CUBIT_FAILURE )
5595 : 0 : return CUBIT_FAILURE;
5596 : :
5597 : : // Create all the new coords in the interior of the array
5598 [ # # ]: 0 : if( tdss )
5599 : : {
5600 : : // Initialize list position
5601 : :
5602 : : // Must use side that is not collapsed
5603 [ # # ][ # # ]: 0 : if( tdss->is_b_collapsed() && tdss->is_d_collapsed() )
[ # # ][ # # ]
[ # # ]
5604 : : ; // Nothing to do
5605 [ # # ][ # # ]: 0 : else if( tdss->is_b_collapsed() == CUBIT_FALSE )
5606 : : {
5607 [ # # ]: 0 : tdss->param_list_reset_b();
5608 [ # # ]: 0 : ada = tdss->param_list_get_and_step_b();
5609 : : }
5610 : : else
5611 : : {
5612 : : // Must go backwards on this list
5613 [ # # ]: 0 : tdss->param_list_last_d();
5614 [ # # ]: 0 : ada = tdss->param_list_get_and_back_d();
5615 : : }
5616 : : }
5617 [ # # ]: 0 : for( r=1; r<ada_ints; r++ )
5618 : : {
5619 [ # # ]: 0 : if( tdss )
5620 : : {
5621 [ # # ][ # # ]: 0 : if( tdss->is_b_collapsed() && tdss->is_d_collapsed() )
[ # # ][ # # ]
[ # # ]
5622 : 0 : ada = (double)r/(double)ada_ints;
5623 [ # # ][ # # ]: 0 : else if( tdss->is_b_collapsed() )
5624 [ # # ][ # # ]: 0 : ada = tdss->param_list_get_and_back_d()/tdss->length_d();
5625 : : else
5626 [ # # ][ # # ]: 0 : ada = tdss->param_list_get_and_step_b()/tdss->length_b();
5627 : : }
5628 : : else
5629 : : {
5630 : 0 : ada = (double)r/(double)ada_ints;
5631 : : }
5632 : :
5633 [ # # ]: 0 : tse_array.reset();
5634 [ # # ]: 0 : for( c=1; c<tse_ints; c++ )
5635 : : {
5636 [ # # ]: 0 : tse = tse_array.get_and_step();
5637 : :
5638 : : // Create a new coord at the mapped location on the face
5639 [ # # ]: 0 : coords[r][c] = make_interior_coord( coords, nr, nc, ada, tse, r, c );
5640 : : }
5641 : : }
5642 : :
5643 [ # # ]: 0 : return CUBIT_SUCCESS;
5644 : : }
5645 : :
5646 : : CubitStatus
5647 : 0 : SplitSurfaceTool::get_tse_array( TDSplitSurface *tdss, int tse_ints,
5648 : : DLIList<double> &tse_array )
5649 : : {
5650 : : int c;
5651 : : double tse;
5652 : :
5653 [ # # ]: 0 : tdss->param_list_reset_a();
5654 [ # # ]: 0 : tdss->param_list_last_c();
5655 : :
5656 [ # # ]: 0 : for( c = 1; c < tse_ints; c++ )
5657 : : {
5658 [ # # ]: 0 : if( tdss )
5659 : : {
5660 [ # # ][ # # ]: 0 : if( tdss->is_a_collapsed() && tdss->is_c_collapsed() )
[ # # ][ # # ]
[ # # ]
5661 : : {
5662 : 0 : tse = (double)c/(double)tse_ints;
5663 : : }
5664 [ # # ][ # # ]: 0 : else if( tdss->is_a_collapsed() )
5665 : : {
5666 : : // Just use C (go backwards on side C)
5667 [ # # ][ # # ]: 0 : tse = tdss->param_list_get_and_back_c()/tdss->length_c();
5668 : : }
5669 [ # # ][ # # ]: 0 : else if( tdss->is_c_collapsed() )
5670 : : {
5671 : : // Just use A
5672 [ # # ][ # # ]: 0 : tse = tdss->param_list_get_and_step_a()/tdss->length_a();
5673 : : }
5674 : : else
5675 : : {
5676 : : // Take average fractional location across the surface
5677 [ # # ][ # # ]: 0 : tse = (tdss->param_list_get_and_step_a()/tdss->length_a() + 1.0 -
5678 [ # # ][ # # ]: 0 : tdss->param_list_get_and_back_c()/tdss->length_c())/2.0;
5679 : : }
5680 : : }
5681 : : else
5682 : : {
5683 : 0 : tse = (double)c/(double)tse_ints;
5684 : : }
5685 : :
5686 [ # # ]: 0 : tse_array.append( tse );
5687 : :
5688 : : }
5689 : :
5690 : 0 : return CUBIT_SUCCESS;
5691 : : }
5692 : :
5693 : : Cubit2DPoint*
5694 : 0 : SplitSurfaceTool::make_interior_coord( Cubit2DPoint ***coords,
5695 : : int nr, int nc,
5696 : : double ada, double tse,
5697 : : int r, int c )
5698 : : {
5699 : : double temp_x, temp_y;
5700 : : Cubit2DPoint *pnt;
5701 : 0 : int ada_ints = nr-1;
5702 : 0 : int tse_ints = nc-1;
5703 : :
5704 : 0 : temp_x = (1.0 - ada)*coords[0][c]->x()
5705 : 0 : + ada*coords[ada_ints][c]->x()
5706 : 0 : + (1.0 - tse)*coords[r][0]->x()
5707 : 0 : + tse*coords[r][tse_ints]->x()
5708 : 0 : - (1.0 - tse)*(1.0 - ada)*coords[0][0]->x()
5709 : 0 : - (1.0 - tse)*ada*coords[ada_ints][0]->x()
5710 : 0 : - tse*(1.0 - ada)*coords[0][tse_ints]->x()
5711 : 0 : - tse*ada*coords[ada_ints][tse_ints]->x();
5712 : :
5713 : 0 : temp_y = (1.0 - ada)*coords[0][c]->y()
5714 : 0 : + ada*coords[ada_ints][c]->y()
5715 : 0 : + (1.0 - tse)*coords[r][0]->y()
5716 : 0 : + tse*coords[r][tse_ints]->y()
5717 : 0 : - (1.0 - tse)*(1.0 - ada)*coords[0][0]->y()
5718 : 0 : - (1.0 - tse)*ada*coords[ada_ints][0]->y()
5719 : 0 : - tse*(1.0 - ada)*coords[0][tse_ints]->y()
5720 : 0 : - tse*ada*coords[ada_ints][tse_ints]->y();
5721 : :
5722 [ # # ]: 0 : pnt = new Cubit2DPoint( temp_x, temp_y );
5723 : :
5724 : 0 : return pnt;
5725 : : }
5726 : :
5727 : : CubitStatus
5728 : 0 : SplitSurfaceTool::draw_preview( DLIList<Curve*> &curve_list, int color )
5729 : : {
5730 : : int i;
5731 : : Curve *curve_ptr;
5732 : 0 : curve_list.reset();
5733 : :
5734 [ # # ]: 0 : for( i=curve_list.size(); i--; )
5735 : : {
5736 : 0 : curve_ptr = curve_list.get_and_step();
5737 : 0 : draw_preview( curve_ptr, CUBIT_FALSE, color );
5738 : : }
5739 : :
5740 : 0 : GfxPreview::flush();
5741 : :
5742 : 0 : return CUBIT_SUCCESS;
5743 : : }
5744 : :
5745 : : CubitStatus
5746 : 0 : SplitSurfaceTool::draw_preview( Curve *curve_ptr, CubitBoolean flush,
5747 : : int color )
5748 : : {
5749 : : CubitStatus result;
5750 [ # # ]: 0 : GMem g_mem;
5751 : :
5752 : : // get the graphics
5753 [ # # ]: 0 : result = curve_ptr->get_geometry_query_engine()->
5754 [ # # ]: 0 : get_graphics( curve_ptr, &g_mem );
5755 : :
5756 [ # # ][ # # ]: 0 : if (result==CUBIT_FAILURE || g_mem.pointListCount == 0)
5757 : : {
5758 [ # # ][ # # ]: 0 : PRINT_WARNING("Unable to preview a curve\n" );
[ # # ][ # # ]
5759 : : }
5760 : :
5761 : : // Draw the polyline
5762 [ # # ][ # # ]: 0 : GfxPreview::draw_polyline( g_mem.point_list(), g_mem.pointListCount, color );
5763 [ # # ]: 0 : if( flush )
5764 [ # # ]: 0 : GfxPreview::flush();
5765 : :
5766 [ # # ]: 0 : return CUBIT_SUCCESS;
5767 : : }
5768 : :
5769 : : CubitStatus
5770 : 0 : SplitSurfaceTool::create_ref_edges( DLIList<Curve*> &curve_list,
5771 : : DLIList<RefEdge*> &ref_edge_list )
5772 : : {
5773 : : int i;
5774 : : Curve *curve_ptr;
5775 : : RefEdge *ref_edge_ptr;
5776 [ # # ]: 0 : curve_list.reset();
5777 [ # # ][ # # ]: 0 : for( i=curve_list.size(); i--; )
5778 : : {
5779 [ # # ]: 0 : curve_ptr = curve_list.get_and_step();
5780 [ # # ][ # # ]: 0 : ref_edge_ptr = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
5781 [ # # ][ # # ]: 0 : if( ref_edge_ptr ) ref_edge_list.append( ref_edge_ptr );
5782 : : }
5783 : 0 : return CUBIT_SUCCESS;
5784 : : }
5785 : :
5786 : : int
5787 : 0 : SplitSurfaceTool::number_coedges( RefEdge *ref_edge_ptr, RefFace *ref_face_ptr )
5788 : : {
5789 [ # # ]: 0 : DLIList<CoEdge*> co_edge_list;
5790 [ # # ]: 0 : ref_edge_ptr->get_co_edges( co_edge_list, ref_face_ptr );
5791 [ # # ][ # # ]: 0 : return co_edge_list.size();
5792 : : }
5793 : :
5794 : : Curve *
5795 : 0 : SplitSurfaceTool::create_curve( DLIList<CubitVector*> &vec_list,
5796 : : Surface *surf_ptr,
5797 : : double tolerance,
5798 : : CubitBoolean iterate,
5799 : : CubitBoolean draw_pnts,
5800 : : CubitBoolean project_curve )
5801 : : {
5802 : 0 : Curve *curve_ptr = NULL;
5803 : :
5804 [ # # ][ # # ]: 0 : if( vec_list.size() < 2 )
5805 : : {
5806 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to create a curve from less than two locations.\n" );
[ # # ][ # # ]
5807 : 0 : return NULL;
5808 : : }
5809 : :
5810 : : GeometryModifyEngine* gme =
5811 [ # # ][ # # ]: 0 : GeometryModifyTool::instance()->get_engine( surf_ptr );
5812 : :
5813 [ # # ]: 0 : if (NULL == gme)
5814 : : {
5815 [ # # ][ # # ]: 0 : PRINT_ERROR("No geometry modify engine available. Unable to create split curve.\n");
[ # # ][ # # ]
5816 : 0 : return NULL;
5817 : : }
5818 : :
5819 [ # # ]: 0 : GeometryQueryEngine* gqe = surf_ptr->get_geometry_query_engine();
5820 : : // Note the user can set the following value through
5821 : : // set geometry accuracy <val>
5822 [ # # ]: 0 : double resabs = gqe->get_sme_resabs_tolerance();
5823 : :
5824 : : // Find start and end locations
5825 [ # # ]: 0 : vec_list.reset();
5826 [ # # ]: 0 : CubitVector *start_pnt = vec_list.get_and_back();
5827 [ # # ]: 0 : CubitVector *end_pnt = vec_list.get();
5828 : :
5829 : : // Check to see if a simple straight line should be created. Use 1/2 the
5830 : : // tolerance because points can deviate on either side of the straight line
5831 : : // (unless tolerance is resabs - then just use it).
5832 [ # # ][ # # ]: 0 : if( check_points_straight( surf_ptr, vec_list,
5833 [ # # ]: 0 : tolerance==resabs ? resabs : 0.5*tolerance ) )
5834 : : {
5835 : : // Create a straight line on the surface
5836 [ # # ]: 0 : TBPoint *start_Point = gme->make_Point( *start_pnt );
5837 [ # # ]: 0 : TBPoint *end_Point = gme->make_Point( *end_pnt );
5838 [ # # ][ # # ]: 0 : if( start_Point == NULL || end_Point == NULL )
5839 : : {
5840 [ # # ][ # # ]: 0 : if( start_Point ) start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
[ # # ]
5841 [ # # ][ # # ]: 0 : if( end_Point ) end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
[ # # ]
5842 : 0 : return NULL;
5843 : : }
5844 [ # # ]: 0 : curve_ptr = gme->make_Curve( start_Point, end_Point, surf_ptr );
5845 [ # # ]: 0 : if( draw_pnts == CUBIT_TRUE )
5846 : : {
5847 : : // Drawing here is a bit of a hack but it saves storing the point
5848 : : // list
5849 [ # # ]: 0 : draw_point( *start_pnt, CUBIT_BLUE_INDEX );
5850 [ # # ]: 0 : draw_point( *end_pnt, CUBIT_BLUE_INDEX );
5851 : : }
5852 : :
5853 : : // Free memory
5854 : : // start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point );
5855 : : // end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point );
5856 : :
5857 : 0 : return curve_ptr;
5858 : : }
5859 : :
5860 : : // Check to see if an arc should be created. Use 1/2 the tolerance because
5861 : : // points can deviate on either side of the arc (unless tolerance is resabs -
5862 : : // then just use resabs).
5863 [ # # ]: 0 : if( (curve_ptr = check_points_arc( surf_ptr, gme, vec_list, resabs,
5864 [ # # ][ # # ]: 0 : tolerance==resabs ? resabs : 0.5*tolerance ) ) != NULL )
5865 : : {
5866 [ # # ]: 0 : if( draw_pnts == CUBIT_TRUE )
5867 : : {
5868 : : // Drawing here is a bit of a hack but it saves storing the point
5869 : : // lists
5870 [ # # ]: 0 : draw_point( *start_pnt, CUBIT_BLUE_INDEX );
5871 [ # # ]: 0 : draw_point( *end_pnt, CUBIT_BLUE_INDEX );
5872 : : }
5873 : 0 : return curve_ptr;
5874 : : }
5875 : :
5876 : : // Ok - its not a straight line or arc, so create a spline
5877 : :
5878 : : // Copy the vectors since we are going to add to the list
5879 [ # # ]: 0 : DLIList<CubitVector*> spline_points;
5880 : : int i;
5881 [ # # ]: 0 : vec_list.reset();
5882 [ # # ][ # # ]: 0 : for( i=vec_list.size(); i--; )
5883 [ # # ][ # # ]: 0 : spline_points.append( new CubitVector(*vec_list.get_and_step()) );
[ # # ][ # # ]
5884 : :
5885 : 0 : int times_through_loop = 0;
5886 : 0 : int done = 0;
5887 [ # # ]: 0 : while( !done )
5888 : : {
5889 : 0 : times_through_loop++;
5890 : :
5891 : : // Create a spline. Do not create on the surface since that can be
5892 : : // computationally expensive and we are going to iterate. Later we
5893 : : // will project the final result to the surface. Note: the preceeding
5894 : : // statement is not true - the gme->make_Curve function would not
5895 : : // actually create the curve on the surface - it only projects the
5896 : : // points to the surface then makes a free spline - this is puzzling.
5897 [ # # ]: 0 : TBPoint *start_Point = gme->make_Point( *start_pnt );
5898 [ # # ]: 0 : TBPoint *end_Point = gme->make_Point( *end_pnt );
5899 [ # # ][ # # ]: 0 : if( start_Point == NULL || end_Point == NULL )
5900 : : {
5901 [ # # ][ # # ]: 0 : while( spline_points.size() ) delete spline_points.pop();
[ # # ]
5902 [ # # ][ # # ]: 0 : if( start_Point ) start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
[ # # ]
5903 [ # # ][ # # ]: 0 : if( end_Point ) end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
[ # # ]
5904 : 0 : return NULL;
5905 : : }
5906 : :
5907 [ # # ][ # # ]: 0 : if( spline_points.size() == 2 )
5908 [ # # ]: 0 : curve_ptr = gme->make_Curve( STRAIGHT_CURVE_TYPE, start_Point, end_Point, NULL );
5909 : : else
5910 : : curve_ptr = gme->make_Curve( SPLINE_CURVE_TYPE, start_Point, end_Point,
5911 [ # # ]: 0 : spline_points );
5912 : :
5913 [ # # ]: 0 : if( curve_ptr == NULL )
5914 : : {
5915 [ # # ][ # # ]: 0 : while( spline_points.size() ) delete spline_points.pop();
[ # # ]
5916 [ # # ][ # # ]: 0 : start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
5917 [ # # ][ # # ]: 0 : end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
5918 : 0 : return NULL;
5919 : : }
5920 : :
5921 [ # # ]: 0 : if( iterate == CUBIT_FALSE )
5922 : 0 : break;
5923 : :
5924 : : // Check to see if spline is close enough
5925 : : CubitVector *start_vec_ptr, *end_vec_ptr;
5926 [ # # ]: 0 : spline_points.reset();
5927 [ # # ]: 0 : CubitVector mid_vec;
5928 : : double dist;
5929 : 0 : int insert_num = 0;
5930 [ # # ][ # # ]: 0 : for( i=spline_points.size()-1; i--; )
5931 : : {
5932 [ # # ]: 0 : start_vec_ptr = spline_points.get_and_step();
5933 [ # # ]: 0 : end_vec_ptr = spline_points.get();
5934 [ # # ][ # # ]: 0 : mid_vec = (*start_vec_ptr + *end_vec_ptr)/2.0;
[ # # ]
5935 : :
5936 : : // Check distance from mid_vec to Curve
5937 [ # # ]: 0 : CubitVector mid_vec_crv;
5938 [ # # ]: 0 : curve_ptr->closest_point( mid_vec, mid_vec_crv );
5939 : :
5940 [ # # ][ # # ]: 0 : double x2 = mid_vec.x()-mid_vec_crv.x();
5941 : 0 : x2 = x2*x2;
5942 [ # # ][ # # ]: 0 : double y2 = mid_vec.y()-mid_vec_crv.y();
5943 : 0 : y2 = y2*y2;
5944 [ # # ][ # # ]: 0 : double z2 = mid_vec.z()-mid_vec_crv.z();
5945 : 0 : z2 = z2*z2;
5946 : :
5947 : 0 : dist = sqrt( x2+y2+z2 );
5948 : :
5949 [ # # ]: 0 : if( dist > tolerance )
5950 : : {
5951 : : // Insert the midpoint location into the list
5952 [ # # ]: 0 : spline_points.back();
5953 [ # # ][ # # ]: 0 : spline_points.insert( new CubitVector( mid_vec ) );
[ # # ]
5954 : 0 : insert_num++;
5955 : : }
5956 : :
5957 : : }
5958 : :
5959 [ # # ]: 0 : if( insert_num == 0 )
5960 : 0 : done++;
5961 : :
5962 [ # # ]: 0 : if( times_through_loop > 100 )
5963 : : {
5964 [ # # ][ # # ]: 0 : PRINT_WARNING( "Unable to closely approximate spline\n" );
[ # # ][ # # ]
5965 : 0 : done++;
5966 : : }
5967 : :
5968 [ # # ]: 0 : if( !done )
5969 : : {
5970 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
5971 : : }
5972 : :
5973 [ # # ]: 0 : if( insert_num > 0 ) {
5974 [ # # ][ # # ]: 0 : PRINT_DEBUG_154( "Inserted %d points when creating spline\n", insert_num );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5975 : : }
5976 : : }
5977 : :
5978 : : // Project the spline to the surface (if the surface is not planar)
5979 [ # # ][ # # ]: 0 : DLIList<Surface*> surf_list;
5980 [ # # ]: 0 : surf_list.append( surf_ptr );
5981 [ # # ][ # # ]: 0 : DLIList<Curve*> curve_list;
5982 [ # # ]: 0 : curve_list.append( curve_ptr );
5983 [ # # ][ # # ]: 0 : DLIList<Curve*> curve_list_new;
5984 : :
5985 [ # # ][ # # ]: 0 : if( gme->project_edges( surf_list, curve_list, curve_list_new ) == CUBIT_FAILURE )
5986 : : {
5987 [ # # ][ # # ]: 0 : PRINT_WARNING( "Unable to project curve to surface - split may fail\n" );
[ # # ][ # # ]
5988 : : }
5989 : : else
5990 : : {
5991 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
5992 [ # # ]: 0 : curve_ptr = curve_list_new.get();
5993 : : }
5994 : :
5995 [ # # ][ # # ]: 0 : if( curve_ptr && draw_pnts == CUBIT_TRUE )
5996 : : {
5997 : : // Drawing here is a bit of a hack but it saves storing the point
5998 : : // lists
5999 [ # # ]: 0 : draw_points( spline_points, CUBIT_BLUE_INDEX, CUBIT_FALSE );
6000 : : }
6001 : :
6002 : : // Free memory
6003 [ # # ][ # # ]: 0 : while( spline_points.size() ) delete spline_points.pop();
[ # # ]
6004 : :
6005 [ # # ]: 0 : return curve_ptr;
6006 : : }
6007 : :
6008 : : CubitBoolean
6009 : 0 : SplitSurfaceTool::check_points_straight( Surface *surf_ptr,
6010 : : DLIList<CubitVector*> &point_list,
6011 : : double tolerance )
6012 : : {
6013 [ # # ]: 0 : GeometryType geom_type = surf_ptr->geometry_type();
6014 : :
6015 : : // Get start and end point
6016 [ # # ]: 0 : point_list.reset();
6017 [ # # ][ # # ]: 0 : CubitVector start_pnt( *point_list.get_and_back() );
6018 [ # # ][ # # ]: 0 : CubitVector end_pnt( *point_list.get() );
6019 : :
6020 : : // If 2 or 3 points, check points along a straight line to make sure they
6021 : : // lie on the surface. If we only have 2 points and we meet this criteria
6022 : : // we are done.
6023 [ # # ][ # # ]: 0 : if( point_list.size() < 4 )
6024 : : {
6025 [ # # ][ # # ]: 0 : if( point_list.size()==2 && geom_type == PLANE_SURFACE_TYPE )
[ # # ][ # # ]
6026 : 0 : return CUBIT_TRUE;
6027 : :
6028 : : // Check several points on the straight line - see if on surface
6029 : :
6030 [ # # ]: 0 : CubitVector check_pnt;
6031 [ # # ][ # # ]: 0 : check_pnt.set( start_pnt.x() + .25 * (end_pnt.x() - start_pnt.x()),
[ # # ]
6032 [ # # ][ # # ]: 0 : start_pnt.y() + .25 * (end_pnt.y() - start_pnt.y()),
[ # # ]
6033 [ # # ][ # # ]: 0 : start_pnt.z() + .25 * (end_pnt.z() - start_pnt.z()) );
[ # # ][ # # ]
6034 [ # # ][ # # ]: 0 : if( is_point_on_surface( surf_ptr, check_pnt, GEOMETRY_RESABS ) == CUBIT_FALSE )
6035 : 0 : return CUBIT_FALSE;
6036 : :
6037 [ # # ][ # # ]: 0 : check_pnt.set( start_pnt.x() + .5 * (end_pnt.x() - start_pnt.x()),
[ # # ]
6038 [ # # ][ # # ]: 0 : start_pnt.y() + .5 * (end_pnt.y() - start_pnt.y()),
[ # # ]
6039 [ # # ][ # # ]: 0 : start_pnt.z() + .5 * (end_pnt.z() - start_pnt.z()) );
[ # # ][ # # ]
6040 [ # # ][ # # ]: 0 : if( is_point_on_surface( surf_ptr, check_pnt, GEOMETRY_RESABS ) == CUBIT_FALSE )
6041 : 0 : return CUBIT_FALSE;
6042 : :
6043 [ # # ][ # # ]: 0 : check_pnt.set( start_pnt.x() + .75 * (end_pnt.x() - start_pnt.x()),
[ # # ]
6044 [ # # ][ # # ]: 0 : start_pnt.y() + .75 * (end_pnt.y() - start_pnt.y()),
[ # # ]
6045 [ # # ][ # # ]: 0 : start_pnt.z() + .75 * (end_pnt.z() - start_pnt.z()) );
[ # # ][ # # ]
6046 [ # # ][ # # ]: 0 : if( is_point_on_surface( surf_ptr, check_pnt, GEOMETRY_RESABS ) == CUBIT_FALSE )
6047 : 0 : return CUBIT_FALSE;
6048 : :
6049 [ # # ][ # # ]: 0 : if( point_list.size() == 2 )
6050 : 0 : return CUBIT_TRUE;
6051 : : }
6052 : :
6053 : : // Get vector along the line
6054 [ # # ]: 0 : CubitVector ln_vec = end_pnt - start_pnt;
6055 [ # # ]: 0 : ln_vec.normalize();
6056 : :
6057 : : int i;
6058 [ # # ]: 0 : point_list.reset();
6059 [ # # ]: 0 : point_list.step();
6060 [ # # ][ # # ]: 0 : for( i=point_list.size()-2; i--; )
6061 : : {
6062 [ # # ]: 0 : CubitVector *pnt = point_list.get_and_step();
6063 : :
6064 : : // Get vector from point to line origin
6065 [ # # ]: 0 : CubitVector vec = *pnt - start_pnt;
6066 : :
6067 : : // Calculate distance from point to origin
6068 [ # # ]: 0 : double distpnt_orig = vec.length();
6069 : :
6070 : : // Take dot product of vec & unit vector to get distance to intersection
6071 : : // along the line
6072 [ # # ]: 0 : double dot = fabs( vec % ln_vec );
6073 : :
6074 : : // Calculate distance from point to line w/sqrt (use fabs to account for
6075 : : // tiny roundoff error that could result in a negative number)
6076 : 0 : double distance = sqrt(fabs(distpnt_orig*distpnt_orig - dot*dot));
6077 : :
6078 [ # # ]: 0 : if( distance > tolerance )
6079 : 0 : return CUBIT_FALSE;
6080 : :
6081 [ # # ]: 0 : if( geom_type != PLANE_SURFACE_TYPE )
6082 : : {
6083 : : // Find the actual intersection point and determine if it is within
6084 : : // GEOMETRY_RESABS of the surface
6085 : :
6086 : : // Travel along the line to get the intersection point
6087 [ # # ]: 0 : CubitVector int_pnt;
6088 [ # # ]: 0 : start_pnt.next_point( ln_vec, dot, int_pnt );
6089 : :
6090 : : // Find the closest point on the surface
6091 [ # # ]: 0 : CubitVector closest_loc_on_surf;
6092 [ # # ][ # # ]: 0 : if( surf_ptr->closest_point( int_pnt, &closest_loc_on_surf ) == CUBIT_FAILURE )
6093 : : {
6094 : 0 : return CUBIT_FALSE;
6095 : : }
6096 : :
6097 : : // Find the distance between these two points
6098 [ # # ]: 0 : double dist = int_pnt.distance_between( closest_loc_on_surf );
6099 [ # # ]: 0 : if( dist > GEOMETRY_RESABS )
6100 : 0 : return CUBIT_FALSE;
6101 : : }
6102 : : }
6103 : :
6104 : 0 : return CUBIT_TRUE;
6105 : : }
6106 : :
6107 : : Curve *
6108 : 0 : SplitSurfaceTool:: check_points_arc( Surface *surf_ptr,
6109 : : GeometryModifyEngine *gme,
6110 : : DLIList<CubitVector*> &point_list,
6111 : : double resabs,
6112 : : double tolerance )
6113 : : {
6114 [ # # ][ # # ]: 0 : if( point_list.size() < 2 )
6115 : 0 : return 0;
6116 : :
6117 [ # # ]: 0 : point_list.reset();
6118 [ # # ][ # # ]: 0 : CubitVector start_pnt( *point_list.get_and_back() );
6119 [ # # ][ # # ]: 0 : CubitVector end_pnt( *point_list.get() );
6120 : :
6121 [ # # ][ # # ]: 0 : if( point_list.size() == 2 )
6122 : : return create_arc_two( gme, surf_ptr, start_pnt, end_pnt, resabs,
6123 [ # # ]: 0 : tolerance );
6124 : :
6125 : : // Get a mid point location
6126 [ # # ]: 0 : CubitVector mid_pnt;
6127 [ # # ]: 0 : int mid = point_list.size()/2;
6128 [ # # ]: 0 : point_list.reset();
6129 [ # # ]: 0 : point_list.step( mid );
6130 [ # # ][ # # ]: 0 : mid_pnt = *point_list.get();
6131 : :
6132 : : // Check if 3 points are colinear
6133 [ # # ][ # # ]: 0 : double a = (start_pnt-mid_pnt).length();
6134 [ # # ][ # # ]: 0 : double b = (mid_pnt-end_pnt).length();
6135 [ # # ][ # # ]: 0 : double c = (end_pnt-start_pnt).length();
6136 : :
6137 : 0 : double denom = sqrt((a+b+c)*(b+c-a)*(c+a-b)*(a+b-c));
6138 [ # # ]: 0 : if( denom < GEOMETRY_RESABS )
6139 : 0 : return 0;
6140 : :
6141 : : // Special case if 3 points
6142 [ # # ][ # # ]: 0 : if( point_list.size() == 3 )
6143 [ # # ]: 0 : return create_arc_three( gme, surf_ptr, start_pnt, mid_pnt, end_pnt, resabs );
6144 : :
6145 : : // Get a potentially more accurate arc mid_pnt
6146 [ # # ]: 0 : get_arc_mid_pnt( surf_ptr, start_pnt, end_pnt, mid_pnt, tolerance );
6147 : :
6148 : : // Create an actual arc and do some comparisons
6149 : : double deviation;
6150 : : Curve *curve_ptr = check_if_arc( gme, surf_ptr, point_list, start_pnt,
6151 [ # # ]: 0 : mid_pnt, end_pnt, resabs, tolerance, deviation );
6152 : :
6153 [ # # ]: 0 : if( curve_ptr )
6154 : 0 : return curve_ptr;
6155 : :
6156 : : // Try harder to find an arc - use each point as the center point
6157 : : int i;
6158 [ # # ]: 0 : point_list.reset();
6159 [ # # ]: 0 : point_list.step();
6160 : : CubitVector *mid_pnt_ptr;
6161 [ # # ][ # # ]: 0 : for( i=point_list.size()-2; i--; )
6162 : : {
6163 [ # # ]: 0 : mid_pnt_ptr = point_list.get_and_step();
6164 : :
6165 : : curve_ptr = check_if_arc( gme, surf_ptr, point_list, start_pnt,
6166 : : *mid_pnt_ptr, end_pnt, resabs, tolerance,
6167 [ # # ]: 0 : deviation );
6168 : :
6169 [ # # ]: 0 : if( curve_ptr )
6170 : 0 : return curve_ptr;
6171 : :
6172 [ # # ]: 0 : if( deviation > tolerance )
6173 : : {
6174 : 0 : return 0;
6175 : : }
6176 : : }
6177 : :
6178 : 0 : return 0;
6179 : : }
6180 : :
6181 : : CubitStatus
6182 : 0 : SplitSurfaceTool::get_arc_mid_pnt( Surface *surf_ptr,
6183 : : CubitVector &start_pnt,
6184 : : CubitVector &end_pnt,
6185 : : CubitVector &mid_pnt,
6186 : : double tolerance )
6187 : : {
6188 : : // Possible Surface types.
6189 : : // CONE_SURFACE_TYPE
6190 : : // PLANE_SURFACE_TYPE
6191 : : // SPHERE_SURFACE_TYPE
6192 : : // SPLINE_SURFACE_TYPE
6193 : : // TORUS_SURFACE_TYPE
6194 : : // BEST_FIT_SURFACE_TYPE
6195 : : // FACET_SURFACE_TYPE
6196 : : // UNDEFINED_SURFACE_TYPE
6197 : 0 : GeometryType geom_type = surf_ptr->geometry_type();
6198 : :
6199 : : // If surface is a cone, sphere or torus, we will *try* to get a more accurate
6200 : : // mid point location. This can often result in a better arc.
6201 [ # # ][ # # ]: 0 : if( (geom_type == CONE_SURFACE_TYPE ||
6202 [ # # ]: 0 : geom_type == SPHERE_SURFACE_TYPE ||
6203 [ # # # # ]: 0 : geom_type == TORUS_SURFACE_TYPE) &&
6204 : 0 : surf_ptr->is_parametric() )
6205 : : {
6206 : : // Determine if arc traverses approximately along the uv space of the surface
6207 : : // Using the surface uv space to create the arc should be the most accurate
6208 : : // method of creating the arc.
6209 : :
6210 : : double start_u, start_v;
6211 [ # # ][ # # ]: 0 : if( surf_ptr->u_v_from_position ( start_pnt, start_u, start_v )
6212 : : == CUBIT_FAILURE )
6213 : 0 : return CUBIT_FAILURE;
6214 : :
6215 : : double end_u, end_v;
6216 [ # # ][ # # ]: 0 : if( surf_ptr->u_v_from_position ( end_pnt, end_u, end_v )
6217 : : == CUBIT_FAILURE )
6218 : 0 : return CUBIT_FAILURE;
6219 : :
6220 : : // Use average. Note this could go to the opposite side of the surface
6221 : : // - I'm not sure how to handle this other than checking the resultant
6222 : : // point and flipping to the other side if it is off.
6223 : : double mid_u, mid_v;
6224 : 0 : mid_u = (start_u+end_u)/2.0;
6225 : 0 : mid_v = (start_v+end_v)/2.0;
6226 : :
6227 [ # # ]: 0 : CubitVector new_mid_pnt = surf_ptr->position_from_u_v( mid_u, mid_v );
6228 : :
6229 : : CubitPointContainment pnt_on_flg;
6230 [ # # ]: 0 : pnt_on_flg = surf_ptr->point_containment( mid_u, mid_v );
6231 [ # # ][ # # ]: 0 : if( pnt_on_flg == CUBIT_PNT_OUTSIDE ||
6232 : : pnt_on_flg == CUBIT_PNT_UNKNOWN )
6233 : : {
6234 [ # # ]: 0 : CubitVector mid_pnt_ref;
6235 : :
6236 [ # # ][ # # ]: 0 : if( reflect_arc_pnt( start_pnt, new_mid_pnt, end_pnt, new_mid_pnt, mid_pnt_ref ) ==
6237 : : CUBIT_SUCCESS )
6238 : : {
6239 : : // Make sure the point is on the surface
6240 [ # # ]: 0 : CubitVector mid_pnt_ref_on;
6241 [ # # ]: 0 : surf_ptr->closest_point( mid_pnt_ref, &mid_pnt_ref_on );
6242 [ # # ][ # # ]: 0 : if( mid_pnt_ref.distance_between( mid_pnt_ref_on ) < tolerance )
6243 : : {
6244 [ # # ]: 0 : pnt_on_flg = surf_ptr->point_containment( mid_pnt_ref );
6245 [ # # ][ # # ]: 0 : if( pnt_on_flg == CUBIT_PNT_INSIDE ||
6246 : : pnt_on_flg == CUBIT_PNT_BOUNDARY )
6247 : : {
6248 [ # # ]: 0 : mid_pnt = mid_pnt_ref_on;
6249 : 0 : return CUBIT_SUCCESS;
6250 : : }
6251 : : }
6252 : 0 : }
6253 : : }
6254 : : else
6255 : : {
6256 [ # # ]: 0 : mid_pnt = new_mid_pnt;
6257 : 0 : return CUBIT_SUCCESS;
6258 : : }
6259 : : }
6260 : :
6261 : 0 : return CUBIT_FAILURE;
6262 : : }
6263 : :
6264 : : Curve*
6265 : 0 : SplitSurfaceTool::create_arc_two( GeometryModifyEngine *gme,
6266 : : Surface *surf_ptr,
6267 : : CubitVector &start_pnt,
6268 : : CubitVector &end_pnt,
6269 : : double resabs,
6270 : : double tolerance )
6271 : : {
6272 [ # # ]: 0 : CubitVector mid_pnt;
6273 [ # # ][ # # ]: 0 : if( get_arc_mid_pnt( surf_ptr, start_pnt, end_pnt, mid_pnt, tolerance )
6274 : : == CUBIT_FAILURE )
6275 : 0 : return 0;
6276 : :
6277 : : // Check if 3 points are colinear
6278 [ # # ][ # # ]: 0 : double a = (start_pnt-mid_pnt).length();
6279 [ # # ][ # # ]: 0 : double b = (mid_pnt-end_pnt).length();
6280 [ # # ][ # # ]: 0 : double c = (end_pnt-start_pnt).length();
6281 : :
6282 : 0 : double denom = sqrt((a+b+c)*(b+c-a)*(c+a-b)*(a+b-c));
6283 [ # # ]: 0 : if( denom < GEOMETRY_RESABS )
6284 : 0 : return 0;
6285 : :
6286 [ # # ]: 0 : TBPoint *start_Point = gme->make_Point( start_pnt );
6287 [ # # ]: 0 : TBPoint *end_Point = gme->make_Point( end_pnt );
6288 [ # # ]: 0 : TBPoint *mid_Point = gme->make_Point( mid_pnt );
6289 [ # # ][ # # ]: 0 : if( start_Point == NULL || mid_Point == NULL || end_Point == NULL )
[ # # ]
6290 : : {
6291 [ # # ][ # # ]: 0 : if( start_Point ) start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
[ # # ]
6292 [ # # ][ # # ]: 0 : if( mid_Point ) mid_Point->get_geometry_query_engine()->delete_solid_model_entities(mid_Point);
[ # # ]
6293 [ # # ][ # # ]: 0 : if( end_Point ) end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
[ # # ]
6294 : 0 : return 0;
6295 : : }
6296 : :
6297 : : // Create a 3-pt arc with the GeometryModifyEngine
6298 : : Curve *curve_ptr = gme->create_arc_three( start_Point,
6299 : : mid_Point,
6300 [ # # ]: 0 : end_Point );
6301 : :
6302 [ # # ][ # # ]: 0 : if( mid_Point ) mid_Point->get_geometry_query_engine()->delete_solid_model_entities(mid_Point);
[ # # ]
6303 : :
6304 [ # # ]: 0 : if( !curve_ptr )
6305 : : {
6306 [ # # ][ # # ]: 0 : if( start_Point ) start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
[ # # ]
6307 [ # # ][ # # ]: 0 : if( end_Point ) end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
[ # # ]
6308 : 0 : return 0;
6309 : : }
6310 : :
6311 : : // Check 1/4 and 3/4 location - make sure on surface
6312 [ # # ]: 0 : CubitVector check_loc;
6313 [ # # ][ # # ]: 0 : if( curve_ptr->position_from_fraction( .25, check_loc ) == CUBIT_FAILURE )
6314 : : {
6315 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6316 : 0 : return 0;
6317 : : }
6318 : :
6319 : : // Now make sure within GEOMETRY_RESABS to the surface
6320 [ # # ][ # # ]: 0 : if( is_point_on_surface( surf_ptr, check_loc, resabs ) == CUBIT_FALSE )
6321 : : {
6322 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6323 : 0 : return 0;
6324 : : }
6325 : :
6326 [ # # ][ # # ]: 0 : if( curve_ptr->position_from_fraction( .75, check_loc ) == CUBIT_FAILURE )
6327 : : {
6328 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6329 : 0 : return 0;
6330 : : }
6331 : :
6332 : : // Now make sure within GEOMETRY_RESABS to the surface
6333 [ # # ][ # # ]: 0 : if( is_point_on_surface( surf_ptr, check_loc, resabs ) == CUBIT_FALSE )
6334 : : {
6335 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6336 : 0 : return 0;
6337 : : }
6338 : :
6339 : 0 : return curve_ptr;
6340 : : }
6341 : :
6342 : : Curve*
6343 : 0 : SplitSurfaceTool::create_arc_three( GeometryModifyEngine *gme,
6344 : : Surface *surf_ptr,
6345 : : CubitVector &start_pnt,
6346 : : CubitVector &mid_pnt,
6347 : : CubitVector &end_pnt,
6348 : : double resabs )
6349 : : {
6350 [ # # ]: 0 : TBPoint *start_Point = gme->make_Point( start_pnt );
6351 [ # # ]: 0 : TBPoint *end_Point = gme->make_Point( end_pnt );
6352 [ # # ]: 0 : TBPoint *mid_Point = gme->make_Point( mid_pnt );
6353 [ # # ][ # # ]: 0 : if( start_Point == NULL || mid_Point == NULL || end_Point == NULL )
[ # # ]
6354 : : {
6355 [ # # ][ # # ]: 0 : if( start_Point ) start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
[ # # ]
6356 [ # # ][ # # ]: 0 : if( mid_Point ) mid_Point->get_geometry_query_engine()->delete_solid_model_entities(mid_Point);
[ # # ]
6357 [ # # ][ # # ]: 0 : if( end_Point ) end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
[ # # ]
6358 : 0 : return 0;
6359 : : }
6360 : :
6361 : : // Create a 3-pt arc with the GeometryModifyEngine
6362 : : Curve *curve_ptr = gme->create_arc_three( start_Point,
6363 : : mid_Point,
6364 [ # # ]: 0 : end_Point );
6365 : :
6366 [ # # ][ # # ]: 0 : if( mid_Point ) mid_Point->get_geometry_query_engine()->delete_solid_model_entities(mid_Point);
[ # # ]
6367 : :
6368 [ # # ]: 0 : if( !curve_ptr )
6369 : : {
6370 [ # # ][ # # ]: 0 : if( start_Point ) start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
[ # # ]
6371 [ # # ][ # # ]: 0 : if( end_Point ) end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
[ # # ]
6372 : 0 : return 0;
6373 : : }
6374 : :
6375 : : // Check 1/4 and 3/4 location - make sure on surface
6376 [ # # ]: 0 : CubitVector check_loc;
6377 [ # # ][ # # ]: 0 : if( curve_ptr->position_from_fraction( .25, check_loc ) == CUBIT_FAILURE )
6378 : : {
6379 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6380 : 0 : return 0;
6381 : : }
6382 : :
6383 : : // Now make sure within GEOMETRY_RESABS to the surface
6384 [ # # ][ # # ]: 0 : if( is_point_on_surface( surf_ptr, check_loc, resabs ) == CUBIT_FALSE )
6385 : : {
6386 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6387 : 0 : return 0;
6388 : : }
6389 : :
6390 [ # # ][ # # ]: 0 : if( curve_ptr->position_from_fraction( .75, check_loc ) == CUBIT_FAILURE )
6391 : : {
6392 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6393 : 0 : return 0;
6394 : : }
6395 : :
6396 : : // Now make sure within GEOMETRY_RESABS to the surface
6397 [ # # ][ # # ]: 0 : if( is_point_on_surface( surf_ptr, check_loc, resabs ) == CUBIT_FALSE )
6398 : : {
6399 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6400 : 0 : return 0;
6401 : : }
6402 : :
6403 : 0 : return curve_ptr;
6404 : : }
6405 : :
6406 : : Curve *
6407 : 0 : SplitSurfaceTool::check_if_arc( GeometryModifyEngine *gme,
6408 : : Surface *surf_ptr,
6409 : : DLIList<CubitVector*> &point_list,
6410 : : CubitVector &start_pnt,
6411 : : CubitVector &mid_pnt,
6412 : : CubitVector &end_pnt,
6413 : : double resabs,
6414 : : double tolerance,
6415 : : double &deviation )
6416 : : {
6417 : : // Check if 3 points are colinear
6418 [ # # ][ # # ]: 0 : double a = (start_pnt-mid_pnt).length();
6419 [ # # ][ # # ]: 0 : double b = (mid_pnt-end_pnt).length();
6420 [ # # ][ # # ]: 0 : double c = (end_pnt-start_pnt).length();
6421 : :
6422 : 0 : double denom = sqrt((a+b+c)*(b+c-a)*(c+a-b)*(a+b-c));
6423 [ # # ]: 0 : if( denom < GEOMETRY_RESABS )
6424 : : {
6425 : 0 : deviation = 99999.0;
6426 : 0 : return 0;
6427 : : }
6428 : :
6429 : : // Create an actual arc and do some comparisons
6430 : :
6431 [ # # ]: 0 : TBPoint *start_Point = gme->make_Point( start_pnt );
6432 [ # # ]: 0 : TBPoint *end_Point = gme->make_Point( end_pnt );
6433 [ # # ]: 0 : TBPoint *mid_Point = gme->make_Point( mid_pnt );
6434 [ # # ][ # # ]: 0 : if( start_Point == NULL || mid_Point == NULL || end_Point == NULL )
[ # # ]
6435 : : {
6436 [ # # ][ # # ]: 0 : if( start_Point ) start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
[ # # ]
6437 [ # # ][ # # ]: 0 : if( mid_Point ) mid_Point->get_geometry_query_engine()->delete_solid_model_entities(mid_Point);
[ # # ]
6438 [ # # ][ # # ]: 0 : if( end_Point ) end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
[ # # ]
6439 : 0 : return 0;
6440 : : }
6441 : :
6442 : : // Create a 3-pt arc with the GeometryModifyEngine
6443 : : Curve *curve_ptr = gme->create_arc_three( start_Point,
6444 : : mid_Point,
6445 [ # # ]: 0 : end_Point );
6446 : :
6447 [ # # ][ # # ]: 0 : if( mid_Point ) mid_Point->get_geometry_query_engine()->delete_solid_model_entities(mid_Point);
[ # # ]
6448 : :
6449 [ # # ]: 0 : if( curve_ptr == NULL )
6450 : : {
6451 [ # # ][ # # ]: 0 : if( start_Point ) start_Point->get_geometry_query_engine()->delete_solid_model_entities(start_Point);
[ # # ]
6452 [ # # ][ # # ]: 0 : if( end_Point ) end_Point->get_geometry_query_engine()->delete_solid_model_entities(end_Point);
[ # # ]
6453 : 0 : return 0;
6454 : : }
6455 : :
6456 : : // Now check all points to see if they are within tolerance to the arc
6457 : : // At the same time, check to make sure that each point on the arc is
6458 : : // within GEOMETRY_RESABS of the surface (otherwise an imprint will likely
6459 : : // not occur).
6460 : : int i;
6461 [ # # ]: 0 : CubitVector closest_loc;
6462 [ # # ]: 0 : point_list.reset();
6463 : 0 : double max_deviation = -1.0;
6464 [ # # ][ # # ]: 0 : for( i=point_list.size(); i--; )
6465 : : {
6466 [ # # ]: 0 : CubitVector *vec_ptr = point_list.get_and_step();
6467 [ # # ][ # # ]: 0 : if( curve_ptr->closest_point( *vec_ptr, closest_loc ) == CUBIT_FAILURE )
6468 : : {
6469 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6470 : 0 : return 0;
6471 : : }
6472 : :
6473 [ # # ]: 0 : deviation = vec_ptr->distance_between( closest_loc );
6474 [ # # ]: 0 : if( deviation > max_deviation )
6475 : 0 : max_deviation = deviation;
6476 : :
6477 [ # # ]: 0 : if( deviation > tolerance )
6478 : : {
6479 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6480 : 0 : return 0;
6481 : : }
6482 : :
6483 : : // Now make sure within GEOMETRY_RESABS (actually resbas) to the surface
6484 [ # # ][ # # ]: 0 : if( is_point_on_surface( surf_ptr, closest_loc, resabs ) == CUBIT_FALSE )
6485 : : {
6486 [ # # ][ # # ]: 0 : curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
6487 : 0 : return 0;
6488 : : }
6489 : : }
6490 : :
6491 : 0 : deviation = max_deviation;
6492 : 0 : return curve_ptr;
6493 : : }
6494 : :
6495 : : CubitStatus
6496 : 0 : SplitSurfaceTool::reflect_arc_pnt( CubitVector &vec1,
6497 : : CubitVector &vec2,
6498 : : CubitVector &vec3,
6499 : : CubitVector &pnt_to_reflect,
6500 : : CubitVector &out_pnt )
6501 : :
6502 : : {
6503 [ # # ][ # # ]: 0 : double a = (vec1-vec2).length();
6504 [ # # ][ # # ]: 0 : double b = (vec2-vec3).length();
6505 [ # # ][ # # ]: 0 : double c = (vec3-vec1).length();
6506 : :
6507 : 0 : double denom = sqrt((a+b+c)*(b+c-a)*(c+a-b)*(a+b-c));
6508 [ # # ]: 0 : if(denom < GEOMETRY_RESABS )
6509 : 0 : return CUBIT_FAILURE;
6510 : :
6511 [ # # ]: 0 : AnalyticGeometryTool *agt = AnalyticGeometryTool::instance();
6512 : :
6513 : : // Find the circle radius
6514 : 0 : double rad = (a*b*c)/denom;
6515 : :
6516 : : // Find a coordinate system in the plane of the arc
6517 : : // Start by getting normal to arc
6518 [ # # ][ # # ]: 0 : CubitVector z = (vec1-vec2)*(vec2-vec3);
[ # # ]
6519 [ # # ]: 0 : z.normalize();
6520 [ # # ]: 0 : CubitVector x;
6521 [ # # ]: 0 : CubitVector y;
6522 [ # # ]: 0 : z.orthogonal_vectors( x,y );
6523 : :
6524 : : // Now we are going to transform the points to a local coordinate
6525 : : // system in the plane of the arc - thats where we can work to
6526 : : // determine the equation of the circle (in 2D).
6527 : : double mtx_global_to_local[4][4];
6528 : : double mtx_local_to_global[4][4];
6529 : :
6530 : : double xt[3], yt[3], zt[3], origint[3];
6531 [ # # ]: 0 : agt->copy_pnt( x, xt );
6532 [ # # ]: 0 : agt->copy_pnt( y, yt );
6533 [ # # ]: 0 : agt->copy_pnt( z, zt );
6534 [ # # ]: 0 : agt->copy_pnt( vec1, origint );
6535 : :
6536 [ # # ]: 0 : agt->vecs_to_mtx( xt, yt, zt, origint, mtx_local_to_global );
6537 [ # # ]: 0 : agt->inv_trans_mtx( mtx_local_to_global, mtx_global_to_local );
6538 : :
6539 : : double vec1_loc[3], vec2_loc[3], vec3_loc[3];
6540 [ # # ]: 0 : agt->copy_pnt( vec1, vec1_loc );
6541 [ # # ]: 0 : agt->copy_pnt( vec2, vec2_loc );
6542 [ # # ]: 0 : agt->copy_pnt( vec3, vec3_loc );
6543 : :
6544 [ # # ]: 0 : agt->transform_pnt( mtx_global_to_local, vec1_loc, vec1_loc );
6545 [ # # ]: 0 : agt->transform_pnt( mtx_global_to_local, vec2_loc, vec2_loc );
6546 [ # # ]: 0 : agt->transform_pnt( mtx_global_to_local, vec3_loc, vec3_loc );
6547 : :
6548 : : // PRINT_INFO( "vec1_loc = %f, %f, %f\n", vec1_loc[0], vec1_loc[1], vec1_loc[2] );
6549 : : // PRINT_INFO( "vec2_loc = %f, %f, %f\n", vec2_loc[0], vec2_loc[1], vec2_loc[2] );
6550 : : // PRINT_INFO( "vec3_loc = %f, %f, %f\n", vec3_loc[0], vec3_loc[1], vec3_loc[2] );
6551 : :
6552 : 0 : double x_1 = vec1_loc[0];
6553 : 0 : double y_1 = vec1_loc[1];
6554 : 0 : double x_2 = vec2_loc[0];
6555 : 0 : double y_2 = vec2_loc[1];
6556 : 0 : double x_3 = vec3_loc[0];
6557 : 0 : double y_3 = vec3_loc[1];
6558 : :
6559 : : double N_1_mat[2][2];
6560 : 0 : N_1_mat[0][0] = (x_2*x_2 + y_2*y_2-(x_1*x_1 + y_1*y_1));
6561 : 0 : N_1_mat[0][1] = y_2-y_1;
6562 : 0 : N_1_mat[1][0] = (x_3*x_3 + y_3*y_3-(x_1*x_1 + y_1*y_1));
6563 : 0 : N_1_mat[1][1] = y_3-y_1;
6564 : : double N_2_mat[2][2];
6565 : 0 : N_2_mat[0][0] = x_2-x_1;
6566 : 0 : N_2_mat[0][1] = (x_2*x_2 + y_2*y_2-(x_1*x_1 + y_1*y_1));
6567 : 0 : N_2_mat[1][0] = x_3-x_1;
6568 : 0 : N_2_mat[1][1] = (x_3*x_3 + y_3*y_3-(x_1*x_1 + y_1*y_1));
6569 : : double D_mat[2][2];
6570 : 0 : D_mat[0][0] = x_2-x_1;
6571 : 0 : D_mat[0][1] = y_2-y_1;
6572 : 0 : D_mat[1][0] = x_3-x_1;
6573 : 0 : D_mat[1][1] = y_3-y_1;
6574 : :
6575 : 0 : double N_1 = N_1_mat[0][0]*N_1_mat[1][1] - N_1_mat[0][1]*N_1_mat[1][0];
6576 : 0 : double N_2 = N_2_mat[0][0]*N_2_mat[1][1] - N_2_mat[0][1]*N_2_mat[1][0];
6577 : 0 : double D = D_mat[0][0]*D_mat[1][1] - D_mat[0][1]*D_mat[1][0];
6578 : :
6579 : : double center_loc[3];
6580 : 0 : center_loc[0] = N_1/(2.0*D);
6581 : 0 : center_loc[1] = N_2/(2.0*D);
6582 : 0 : center_loc[2] = 0.0;
6583 : :
6584 : : // double centert[3];
6585 : : // agt->transform_pnt( mtx_local_to_global, center_loc, centert );
6586 : : //
6587 : : // CubitVector center( centert );
6588 : : // PRINT_INFO( "Arc Center = %f, %f, %f\n", center.x(), center.y(), center.z() );
6589 : : //
6590 : : // GfxDebug::draw_point( center, CUBIT_BLUE_INDEX );
6591 : :
6592 : : // Now that we have the center, it is simple matter to find the reflected
6593 : : // point from pnt_to_reflect by traversing 2*rad along a vector from
6594 : : // pnt_to_reflect to center.
6595 : : double pnt_to_reflectt[3];
6596 [ # # ]: 0 : agt->copy_pnt( pnt_to_reflect, pnt_to_reflectt );
6597 : : double pnt_to_reflect_loc[3];
6598 [ # # ]: 0 : agt->transform_pnt( mtx_global_to_local, pnt_to_reflectt, pnt_to_reflect_loc );
6599 : : double trav_vec[3];
6600 [ # # ][ # # ]: 0 : if( agt->get_vec( pnt_to_reflect_loc, center_loc, trav_vec ) == CUBIT_FAILURE )
6601 : 0 : return CUBIT_FAILURE;
6602 : :
6603 [ # # ]: 0 : agt->unit_vec( trav_vec, trav_vec );
6604 : :
6605 : : double ref_pnt_loc[3];
6606 [ # # ]: 0 : agt->next_pnt( pnt_to_reflect_loc, trav_vec, 2.0*rad, ref_pnt_loc );
6607 : :
6608 : : // Now transform this point to the global csys
6609 : : double ref_pntt[3];
6610 [ # # ]: 0 : agt->transform_pnt( mtx_local_to_global, ref_pnt_loc, ref_pntt );
6611 : :
6612 [ # # ]: 0 : out_pnt.set( ref_pntt[0], ref_pntt[1], ref_pntt[2] );
6613 : :
6614 : 0 : return CUBIT_SUCCESS;
6615 : : }
6616 : :
6617 : : CubitBoolean
6618 : 0 : SplitSurfaceTool::is_point_on_surface( Surface *surf_ptr, CubitVector &pnt,
6619 : : double resabs )
6620 : : {
6621 : : // Make sure within GEOMETRY_RESABS to the surface
6622 [ # # ]: 0 : CubitVector closest_loc_on_surf;
6623 [ # # ][ # # ]: 0 : if( surf_ptr->closest_point( pnt, &closest_loc_on_surf ) == CUBIT_FAILURE )
6624 : 0 : return CUBIT_FALSE;
6625 : :
6626 [ # # ]: 0 : double dist = pnt.distance_between( closest_loc_on_surf );
6627 [ # # ]: 0 : if( dist > resabs ) // Was GEOMETRY_RESABS
6628 : 0 : return CUBIT_FALSE;
6629 : :
6630 : 0 : return CUBIT_TRUE;
6631 : : }
6632 : :
6633 : : int
6634 : 0 : SplitSurfaceTool::count_surfaces_in_owning_body( RefFace *ref_face_ptr,
6635 : : Body *&body_ptr )
6636 : : {
6637 : : // Returns: Number of surfaces in the owning body of the RefFace
6638 : : // -1 - RefFace is free (no owning body)
6639 : : // -2 - RefFace is owned by more than one body
6640 : 0 : body_ptr = 0;
6641 [ # # ]: 0 : DLIList<Body*> body_list;
6642 : :
6643 [ # # ]: 0 : ref_face_ptr->bodies( body_list );
6644 [ # # ][ # # ]: 0 : if( body_list.size() == 0 )
6645 : 0 : return -1;
6646 [ # # ][ # # ]: 0 : else if( body_list.size() > 1 )
6647 : 0 : return -2;
6648 : :
6649 [ # # ]: 0 : body_ptr = body_list.get();
6650 [ # # ][ # # ]: 0 : DLIList<RefFace*> ref_face_list;
6651 [ # # ]: 0 : body_ptr->ref_faces( ref_face_list );
6652 [ # # ][ # # ]: 0 : return ref_face_list.size();
6653 : : }
6654 : :
6655 : : int
6656 : 0 : SplitSurfaceTool::count_surfaces_in_body( Body *body_ptr )
6657 : : {
6658 : : // Return number of surfaces in the body
6659 [ # # ]: 0 : DLIList<RefFace*> ref_face_list;
6660 [ # # ]: 0 : body_ptr->ref_faces( ref_face_list );
6661 [ # # ][ # # ]: 0 : return ref_face_list.size();
6662 : : }
6663 : :
6664 : : int
6665 : 0 : SplitSurfaceTool::count_curves_in_body( Body *body_ptr )
6666 : : {
6667 : : // Return number of edges in the body
6668 [ # # ]: 0 : DLIList<RefEdge*> ref_edge_list;
6669 [ # # ]: 0 : body_ptr->ref_edges( ref_edge_list );
6670 [ # # ][ # # ]: 0 : return ref_edge_list.size();
6671 : : }
6672 : :
6673 : : CubitStatus
6674 : 0 : SplitSurfaceTool::split_surfaces_extend( DLIList<RefFace*> &ref_face_list,
6675 : : DLIList<RefVertex*> &ref_vertex_list,
6676 : : CubitBoolean preview_flg,
6677 : : CubitBoolean create_ref_edges_flg )
6678 : : {
6679 : : // In the below code, "manual" mode refers to when vertices are passed in. In
6680 : : // this mode, an extension must occur from each given vertex for success.
6681 : : // "Auto" mode refers to when no vertices are passed in. In this mode the
6682 : : // vertices (curves to extend) are found automatically - the ends of
6683 : : // hardlines. Only in auto mode are the gap threshold and normal settings
6684 : : // valid.
6685 : : int i, j;
6686 : 0 : RefFace *ref_face_ptr = NULL;
6687 : 0 : RefVertex *ref_vertex_ptr = NULL;
6688 : 0 : GeometryModifyEngine *gme = NULL;
6689 : 0 : TDSplitSurfaceExtend *tdsse = NULL;
6690 : :
6691 : : // Clear previous graphics previews
6692 [ # # ]: 0 : GfxPreview::clear();
6693 : :
6694 : 0 : CubitBoolean auto_flg = CUBIT_TRUE;
6695 [ # # ][ # # ]: 0 : if( ref_vertex_list.size() )
6696 : 0 : auto_flg = CUBIT_FALSE;
6697 : :
6698 : : // Copy input face list since we don't want to modify it
6699 [ # # ]: 0 : DLIList<RefFace*> copied_ref_face_list = ref_face_list;
6700 : :
6701 : : // Check for errors
6702 [ # # ]: 0 : copied_ref_face_list.reset();
6703 [ # # ][ # # ]: 0 : for( i=copied_ref_face_list.size(); i--; )
6704 : : {
6705 [ # # ]: 0 : ref_face_ptr = copied_ref_face_list.get();
6706 : :
6707 : : // Check for free and merged surfaces... for both manual and auto cases.
6708 : : // (we make this fatal for the auto case too since the user can correct
6709 : : // these and may not even know about them)
6710 [ # # ]: 0 : DLIList<Body*> body_list;
6711 [ # # ]: 0 : ref_face_ptr->bodies( body_list );
6712 [ # # ][ # # ]: 0 : if( body_list.size()==0 )
6713 : : {
6714 [ # # ][ # # ]: 0 : PRINT_ERROR( "Surface %d is not contained within a parent body.\n"
[ # # ][ # # ]
6715 [ # # ]: 0 : " It cannot be split.\n", ref_face_ptr->id() );
6716 : 0 : return CUBIT_FAILURE;
6717 : : }
6718 [ # # ][ # # ]: 0 : else if( body_list.size() > 1 )
6719 : : {
6720 [ # # ][ # # ]: 0 : PRINT_ERROR( "Surface %d is merged and cannot be split.\n",
[ # # ][ # # ]
6721 [ # # ]: 0 : ref_face_ptr->id() );
6722 : 0 : return CUBIT_FAILURE;
6723 : : }
6724 : :
6725 : : // Check for nonplanar surface. For auto case, just remove these, but
6726 : : // for manual case, give a fatal error.
6727 [ # # ][ # # ]: 0 : if( ref_face_ptr->is_planar() == CUBIT_FALSE )
6728 : : {
6729 [ # # ]: 0 : if( auto_flg == CUBIT_TRUE )
6730 : : {
6731 [ # # ]: 0 : copied_ref_face_list.change_to( NULL );
6732 [ # # ]: 0 : copied_ref_face_list.step();
6733 : 0 : continue;
6734 : : }
6735 : : else
6736 : : {
6737 : : // Error out
6738 [ # # ][ # # ]: 0 : PRINT_ERROR( "The 'split across extend' command only works on planar surfaces.\n"
[ # # ][ # # ]
6739 [ # # ]: 0 : " Surface %d is nonplanar\n", ref_face_ptr->id() );
6740 : 0 : return CUBIT_FAILURE;
6741 : : }
6742 : : }
6743 [ # # ][ # # ]: 0 : copied_ref_face_list.step();
[ # # # ]
6744 : 0 : }
6745 : :
6746 [ # # ]: 0 : copied_ref_face_list.remove_all_with_value( NULL );
6747 : :
6748 : : // If we don't have any faces left, we exit (could only occur for auto case...
6749 : : // make this a warning instead of an error).
6750 [ # # ][ # # ]: 0 : if( !copied_ref_face_list.size() )
6751 : : {
6752 [ # # ][ # # ]: 0 : PRINT_WARNING( "No valid surfaces found to be split. Note to be split, they\n"
[ # # ]
6753 [ # # ]: 0 : " must be nonplanar, contained in a body, and not merged.\n" );
6754 : 0 : return CUBIT_SUCCESS;
6755 : : }
6756 : :
6757 : : // Mark each of the input vertices with a tooldata
6758 [ # # ]: 0 : ref_vertex_list.reset();
6759 [ # # ][ # # ]: 0 : for( i=ref_vertex_list.size(); i--; )
6760 : : {
6761 [ # # ]: 0 : ref_vertex_ptr = ref_vertex_list.get_and_step();
6762 [ # # ][ # # ]: 0 : ref_vertex_ptr->add_TD( new TDSplitSurfaceExtend() );
[ # # ]
6763 : : }
6764 : :
6765 : : // Store list of faces and new curves sorted by body and face
6766 [ # # ][ # # ]: 0 : DLIList<DLIList<Surface*>*> body_surf_list_list;
6767 [ # # ][ # # ]: 0 : DLIList<DLIList<DLIList<Curve*>*>*> curve_lists_lists_list;
6768 : :
6769 : : // Store ids of Curves that are extended
6770 [ # # ][ # # ]: 0 : DLIList<int> ext_curve_ids;
6771 : :
6772 : : // Operate by common body - pull faces out of the input face list that are
6773 : : // from a common Body and place them in a separate list (split_face_list).
6774 : : Body *curr_Body_ptr;
6775 [ # # ][ # # ]: 0 : while( copied_ref_face_list.size() )
6776 : : {
6777 [ # # ]: 0 : DLIList<RefFace*> split_face_list; // Holds faces from common body
6778 : :
6779 : : // Store new curves for this body, sorted by face
6780 : : DLIList<DLIList<Curve*>*> *curve_lists_list_ptr;
6781 [ # # ][ # # ]: 0 : curve_lists_list_ptr = new DLIList<DLIList<Curve*>*>;
6782 [ # # ]: 0 : curve_lists_lists_list.append( curve_lists_list_ptr );
6783 : :
6784 : 0 : curr_Body_ptr = NULL;
6785 : :
6786 [ # # ]: 0 : copied_ref_face_list.reset();
6787 [ # # ][ # # ]: 0 : for( i=copied_ref_face_list.size(); i--; )
6788 : : {
6789 [ # # ]: 0 : ref_face_ptr = copied_ref_face_list.get();
6790 : :
6791 [ # # ]: 0 : DLIList<Body*> body_list;
6792 [ # # ]: 0 : ref_face_ptr->bodies( body_list );
6793 : :
6794 [ # # ]: 0 : if( curr_Body_ptr == NULL )
6795 [ # # ]: 0 : curr_Body_ptr = body_list.get();
6796 : :
6797 [ # # ][ # # ]: 0 : if( curr_Body_ptr == body_list.get() )
6798 : : {
6799 [ # # ]: 0 : split_face_list.append( ref_face_ptr );
6800 [ # # ]: 0 : copied_ref_face_list.change_to( NULL );
6801 : : }
6802 : :
6803 [ # # ]: 0 : copied_ref_face_list.step();
6804 [ # # ]: 0 : }
6805 : :
6806 [ # # ]: 0 : copied_ref_face_list.remove_all_with_value( NULL );
6807 : :
6808 : : DLIList<Surface*> *body_surf_list_ptr;
6809 [ # # ][ # # ]: 0 : body_surf_list_ptr = new DLIList<Surface*>;
6810 [ # # ]: 0 : body_surf_list_list.append( body_surf_list_ptr );
6811 : :
6812 : : // Loop through each face on the common body
6813 : : RefFace *split_face_ptr;
6814 : : DLIList<Curve*> *curve_list_ptr;
6815 [ # # ]: 0 : split_face_list.reset();
6816 [ # # ][ # # ]: 0 : for( i=split_face_list.size(); i--; )
6817 : : {
6818 [ # # ]: 0 : split_face_ptr = split_face_list.get_and_step();
6819 [ # # ][ # # ]: 0 : body_surf_list_ptr->append( split_face_ptr->get_surface_ptr() );
6820 : :
6821 [ # # ][ # # ]: 0 : curve_list_ptr = new DLIList<Curve*>;
6822 [ # # ]: 0 : curve_lists_list_ptr->append( curve_list_ptr );
6823 : :
6824 : : // Get the RefEdges to fire a ray at (from surface)
6825 [ # # ]: 0 : DLIList<RefEdge*> ref_edge_list;
6826 [ # # ]: 0 : split_face_ptr->ref_edges( ref_edge_list );
6827 [ # # ][ # # ]: 0 : DLIList<RefEntity*> at_entity_list;
[ # # ]
6828 [ # # ][ # # ]: 0 : CAST_LIST( ref_edge_list, at_entity_list, RefEntity );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
6829 : :
6830 : : // Fire a ray from each vertex in an outward direction from the tangent
6831 : : // of the owning curve at the at_entity_list
6832 [ # # ][ # # ]: 0 : DLIList<RefVertex*> tmp_vertex_list;
[ # # ]
6833 [ # # ]: 0 : split_face_ptr->ref_vertices( tmp_vertex_list );
6834 : :
6835 [ # # ]: 0 : tmp_vertex_list.reset();
6836 [ # # ][ # # ]: 0 : for( j=tmp_vertex_list.size(); j--; )
[ # # ][ # # ]
6837 : : {
6838 [ # # ]: 0 : ref_vertex_ptr = tmp_vertex_list.get_and_step();
6839 : :
6840 : : // The vertex must be part of the surface being considered, plus
6841 : : // the attached curve must be on the surface. We must have one and
6842 : : // only one attached curve. This curve must be linear.
6843 : :
6844 : : // For manual case, only consider vertices that are in the input list
6845 [ # # ]: 0 : if( auto_flg == CUBIT_FALSE )
6846 : : {
6847 : : tdsse = (TDSplitSurfaceExtend *)ref_vertex_ptr->
6848 [ # # ]: 0 : get_TD(&TDSplitSurfaceExtend::is_split_surface_extend);
6849 [ # # ]: 0 : if( !tdsse ) continue;
6850 : : }
6851 : :
6852 : : // Get attached RefEdges to this vertex
6853 [ # # ]: 0 : DLIList<RefEdge*> att_ref_edge_list;
6854 [ # # ]: 0 : ref_vertex_ptr->ref_edges( att_ref_edge_list );
6855 : :
6856 : 0 : RefEdge *extend_edge_ptr = 0;
6857 : : RefEdge *ref_edge_ptr;
6858 : : int k;
6859 [ # # ][ # # ]: 0 : for( k=att_ref_edge_list.size(); k--; )
6860 : : {
6861 [ # # ]: 0 : ref_edge_ptr = att_ref_edge_list.get_and_step();
6862 [ # # ][ # # ]: 0 : if( ref_edge_ptr->is_directly_related( split_face_ptr ) )
6863 : : {
6864 [ # # ]: 0 : if( !extend_edge_ptr )
6865 : 0 : extend_edge_ptr = ref_edge_ptr;
6866 : : else
6867 : : {
6868 : 0 : extend_edge_ptr = 0;
6869 : 0 : break;
6870 : : }
6871 : : }
6872 : : }
6873 : :
6874 [ # # ]: 0 : if( !extend_edge_ptr )
6875 : 0 : continue;
6876 : :
6877 : : // For now, limit this to linear curves. Technically, we should be able
6878 : : // to extend non-linear curves though.
6879 [ # # ]: 0 : Curve *curve_ptr = extend_edge_ptr->get_curve_ptr();
6880 [ # # ][ # # ]: 0 : if( curve_ptr->geometry_type() != STRAIGHT_CURVE_TYPE )
6881 : 0 : continue;
6882 : :
6883 : : RefVertex *start_vertex_ptr, *end_vertex_ptr;
6884 : :
6885 [ # # ]: 0 : start_vertex_ptr = extend_edge_ptr->start_vertex();
6886 [ # # ]: 0 : end_vertex_ptr = extend_edge_ptr->end_vertex();
6887 : :
6888 [ # # ][ # # ]: 0 : DLIList<double> ray_params;
[ # # # ]
6889 [ # # ]: 0 : CubitVector start_loc = ref_vertex_ptr->coordinates();
6890 : :
6891 : : // Find direction to fire ray
6892 [ # # ]: 0 : CubitVector ray_dir;
6893 : :
6894 [ # # ]: 0 : if( ref_vertex_ptr == start_vertex_ptr )
6895 [ # # ][ # # ]: 0 : ray_dir = start_vertex_ptr->coordinates() -
[ # # ]
6896 [ # # ]: 0 : end_vertex_ptr->coordinates();
6897 : : else
6898 [ # # ][ # # ]: 0 : ray_dir = end_vertex_ptr->coordinates() -
[ # # ]
6899 [ # # ]: 0 : start_vertex_ptr->coordinates();
6900 : :
6901 [ # # ]: 0 : ray_dir.normalize();
6902 : :
6903 : : // Remove the curve being extended from the at_entity_list
6904 [ # # ][ # # ]: 0 : DLIList<RefEntity*> tmp_at_entity_list = at_entity_list;
[ # # # ]
6905 [ # # ][ # # ]: 0 : tmp_at_entity_list.remove_all_with_value( extend_edge_ptr );
6906 : :
6907 : : // Fire the ray, asking for only one hit
6908 [ # # ][ # # ]: 0 : DLIList<RefEntity*> hit_entity_list;
[ # # # ]
6909 [ # # ]: 0 : if( GeometryQueryTool::instance()->fire_ray( start_loc, ray_dir,
6910 [ # # ][ # # ]: 0 : tmp_at_entity_list, ray_params, 1, 0.0, &hit_entity_list )
6911 [ # # ]: 0 : == CUBIT_FAILURE ||
6912 [ # # ][ # # ]: 0 : ray_params.size() == 0 || ray_params.get() == 0.0 )
[ # # ][ # # ]
6913 : 0 : continue;
6914 : :
6915 : : //PRINT_INFO( "Got hit from vertex %d on surface %d at distance %lf\n",
6916 : : // ref_vertex_ptr->id(), split_face_ptr->id(), ray_params.get() )
6917 : :
6918 [ # # ]: 0 : CubitVector end_loc;
6919 [ # # ]: 0 : double ray_param = ray_params.get();
6920 : :
6921 : : // Note the hit entity could be a curve or a vertex
6922 : 0 : RefEntity *hit_entity_ptr = 0;
6923 : 0 : RefEdge *hit_edge_ptr = 0;
6924 [ # # ][ # # ]: 0 : if( hit_entity_list.size() ) // In case fire_ray didn't return hit ents
6925 : : {
6926 [ # # ]: 0 : hit_entity_ptr = hit_entity_list.get();
6927 [ # # ]: 0 : hit_edge_ptr = CAST_TO( hit_entity_ptr, RefEdge );
6928 : : }
6929 : :
6930 [ # # ]: 0 : if( extendNormalFlg == CUBIT_TRUE )
6931 : : {
6932 : : // Try going normal to the curve hit.
6933 : 0 : double norm_dist = CUBIT_DBL_MAX;
6934 : :
6935 [ # # ]: 0 : if( hit_edge_ptr )
6936 : : {
6937 [ # # ]: 0 : hit_edge_ptr->closest_point( start_loc, end_loc );
6938 : :
6939 : : // Only valid if end_loc is ON the curve
6940 : : CubitPointContainment contain = hit_edge_ptr->
6941 [ # # ]: 0 : point_containment( end_loc );
6942 : :
6943 [ # # ]: 0 : if( contain != CUBIT_PNT_ON )
6944 : : {
6945 : : // find the nearest curve which the vertex can be extended to and normal
6946 : 0 : RefEdge* new_edge_ptr = NULL;
6947 [ # # ]: 0 : CubitVector new_end_loc;
6948 : : find_nearest_curve_for_normal_projection(
6949 [ # # ]: 0 : hit_edge_ptr, start_loc, split_face_ptr, ray_dir, new_edge_ptr, new_end_loc);
6950 : :
6951 [ # # ]: 0 : if (new_edge_ptr)
6952 : : {
6953 : 0 : hit_edge_ptr = new_edge_ptr;
6954 [ # # ]: 0 : end_loc = new_end_loc;
6955 : : }
6956 : : }
6957 : :
6958 [ # # ]: 0 : norm_dist = start_loc.distance_between( end_loc );
6959 : : }
6960 : :
6961 : : // Use shortest distance between closest normal and ray_param
6962 [ # # ]: 0 : if( ray_param < norm_dist )
6963 [ # # ]: 0 : start_loc.next_point( ray_dir, ray_param, end_loc );
6964 : : }
6965 : : else
6966 : : // Use ray_dir along ray
6967 [ # # ]: 0 : start_loc.next_point( ray_dir, ray_param, end_loc );
6968 : :
6969 : : // For auto mode, check to see if we are out of the extendGapThreshold
6970 [ # # ][ # # ]: 0 : if( auto_flg &&
[ # # ]
6971 [ # # ]: 0 : ( start_loc.distance_between( end_loc ) > extendGapThreshold ) )
6972 : 0 : continue;
6973 : :
6974 : : // Check for close vertex
6975 [ # # ]: 0 : if( hit_edge_ptr )
6976 : : {
6977 : : double arc_length;
6978 : :
6979 : : // Check distance to start of curve
6980 [ # # ]: 0 : arc_length = hit_edge_ptr->get_arc_length( end_loc, 0 );
6981 : :
6982 [ # # ]: 0 : if( arc_length <= extendTolerance )
6983 : : {
6984 [ # # ][ # # ]: 0 : end_loc = hit_edge_ptr->start_coordinates();
6985 [ # # ][ # # ]: 0 : PRINT_INFO( "Snapping to close vertex for curve %d extended from vertex %d\n",
[ # # ][ # # ]
[ # # ]
6986 [ # # ]: 0 : extend_edge_ptr->id(), ref_vertex_ptr->id() );
6987 : : }
6988 : : else
6989 : : {
6990 : : // Check distance to end of curve
6991 [ # # ]: 0 : arc_length = hit_edge_ptr->get_arc_length( end_loc, 1 );
6992 : :
6993 [ # # ]: 0 : if( arc_length <= extendTolerance )
6994 : : {
6995 [ # # ][ # # ]: 0 : end_loc = hit_edge_ptr->end_coordinates();
6996 [ # # ][ # # ]: 0 : PRINT_INFO( "Snapping to close vertex for curve %d extended from vertex %d\n",
[ # # ][ # # ]
[ # # ]
6997 [ # # ]: 0 : extend_edge_ptr->id(), ref_vertex_ptr->id() );
6998 : : }
6999 : : }
7000 : : }
7001 : :
7002 : 0 : curve_ptr = NULL;
7003 : :
7004 : : // Create curve (from start_vec to end_vec)
7005 [ # # ]: 0 : Surface *surf_ptr = split_face_ptr->get_surface_ptr();
7006 : :
7007 [ # # ][ # # ]: 0 : gme = GeometryModifyTool::instance()->get_engine( surf_ptr );
7008 [ # # ]: 0 : if( gme == NULL )
7009 : : {
7010 [ # # ][ # # ]: 0 : PRINT_ERROR("No geometry modify engine available for surface %d\n"
[ # # ][ # # ]
7011 [ # # ]: 0 : " Unable to create split curve.\n", split_face_ptr->id());
7012 : : // Remove tooldatas and free memory
7013 : : cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
7014 [ # # ]: 0 : curve_lists_lists_list );
7015 : 0 : return CUBIT_FAILURE;
7016 : : }
7017 : :
7018 : : // Create a straight line on the surface
7019 [ # # ]: 0 : TBPoint *start_Point = gme->make_Point( start_loc );
7020 [ # # ]: 0 : TBPoint *end_Point = gme->make_Point( end_loc );
7021 [ # # ][ # # ]: 0 : if( start_Point == NULL || end_Point == NULL )
7022 : : {
7023 [ # # ][ # # ]: 0 : PRINT_ERROR("Unable to create points for curve on surface %d\n",
[ # # ][ # # ]
7024 [ # # ]: 0 : split_face_ptr->id() );
7025 : : // Remove tooldatas and free memory
7026 : : cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
7027 [ # # ]: 0 : curve_lists_lists_list );
7028 : 0 : return CUBIT_FAILURE;
7029 : : }
7030 [ # # ]: 0 : curve_ptr = gme->make_Curve( start_Point, end_Point, surf_ptr );
7031 [ # # ]: 0 : if( !curve_ptr )
7032 : : {
7033 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to create split curve from vertex %d on surface %d\n",
[ # # ][ # # ]
[ # # ]
7034 [ # # ]: 0 : ref_vertex_ptr->id(), split_face_ptr->id() );
7035 : : // Remove tooldatas and free memory
7036 : : cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
7037 [ # # ]: 0 : curve_lists_lists_list );
7038 : 0 : return CUBIT_FAILURE;
7039 : : }
7040 : :
7041 [ # # ]: 0 : curve_list_ptr->append( curve_ptr );
7042 : :
7043 : : // Keep track of which curves are extended
7044 [ # # ][ # # ]: 0 : ext_curve_ids.append( extend_edge_ptr->id() );
7045 : :
7046 [ # # ]: 0 : if( tdsse )
7047 [ # # ][ # # ]: 0 : tdsse->set_success();
[ # # # ]
7048 : 0 : }
7049 : :
7050 : 0 : }
7051 : :
7052 [ # # ][ # # ]: 0 : curr_Body_ptr = 0;
7053 : 0 : }
7054 : :
7055 : : // For manual mode, check to make sure that all vertices had success,
7056 : : // otherwise, this is an error. Note... vertices seem to live through
7057 : : // these operations.
7058 [ # # ][ # # ]: 0 : DLIList<int> vertex_id_list;
7059 [ # # ][ # # ]: 0 : for( i=ref_vertex_list.size(); i--; )
7060 : : {
7061 [ # # ]: 0 : ref_vertex_ptr = ref_vertex_list.get_and_step();
7062 : :
7063 : : tdsse = (TDSplitSurfaceExtend *)ref_vertex_ptr->
7064 [ # # ]: 0 : get_TD(&TDSplitSurfaceExtend::is_split_surface_extend);
7065 : :
7066 [ # # ]: 0 : if( !tdsse ) continue;
7067 : :
7068 [ # # ][ # # ]: 0 : if( !tdsse->is_success() )
7069 [ # # ][ # # ]: 0 : vertex_id_list.append( ref_vertex_ptr->id() );
7070 : : }
7071 [ # # ][ # # ]: 0 : if( vertex_id_list.size() )
7072 : : {
7073 [ # # ][ # # ]: 0 : if( vertex_id_list.size() == 1 )
7074 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to extend from vertex %d\n", ref_vertex_ptr->id() );
[ # # ][ # # ]
[ # # ]
7075 : : else
7076 : : {
7077 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to extend from vertices\n" );
[ # # ][ # # ]
7078 [ # # ]: 0 : CubitUtil::list_entity_ids( " Problem vertices: ", vertex_id_list );
7079 : : }
7080 [ # # ][ # # ]: 0 : PRINT_INFO( " Vertices must be at the end of only one curve on the surface to split,\n"
[ # # ]
7081 [ # # ]: 0 : " extended curves must be linear, and surfaces to split must be planar.\n" );
7082 : :
7083 : : // Remove tooldatas and free memory
7084 : : cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
7085 [ # # ]: 0 : curve_lists_lists_list );
7086 : 0 : return CUBIT_FAILURE;
7087 : : }
7088 : :
7089 : : // Give message as to which curves were extended
7090 : : char msg[50];
7091 [ # # ][ # # ]: 0 : if( ext_curve_ids.size() )
7092 : : {
7093 : : // Remove duplicates (curves extended from both ends)
7094 [ # # ]: 0 : ext_curve_ids.uniquify_ordered();
7095 : :
7096 : : // Give a nice message
7097 [ # # ][ # # ]: 0 : if( ext_curve_ids.size() == 1 )
7098 [ # # ]: 0 : CubitUtil::list_entity_ids( "1 curve extended: ", ext_curve_ids );
7099 : : else
7100 : : {
7101 [ # # ]: 0 : sprintf( msg, "%d curves extended: ", ext_curve_ids.size() );
7102 [ # # ]: 0 : CubitUtil::list_entity_ids( msg, ext_curve_ids );
7103 : : }
7104 : : }
7105 : : else
7106 : : {
7107 : : // Might as well exit
7108 [ # # ][ # # ]: 0 : PRINT_INFO( "No curves found to extend\n" );
[ # # ][ # # ]
7109 : : // Remove tooldatas and free memory
7110 : : cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
7111 [ # # ]: 0 : curve_lists_lists_list );
7112 : 0 : return CUBIT_SUCCESS;
7113 : : }
7114 : :
7115 : : // Do the splitting
7116 : : DLIList<Surface*> *surf_list_ptr;
7117 : : DLIList<DLIList<Curve*>*> *curve_lists_list_ptr;
7118 [ # # ]: 0 : body_surf_list_list.reset();
7119 [ # # ]: 0 : curve_lists_lists_list.reset();
7120 [ # # ][ # # ]: 0 : if( preview_flg==CUBIT_FALSE && create_ref_edges_flg==CUBIT_FALSE )
7121 : : {
7122 [ # # ][ # # ]: 0 : for( i=body_surf_list_list.size(); i--; )
7123 : : {
7124 [ # # ]: 0 : surf_list_ptr = body_surf_list_list.get_and_step();
7125 [ # # ]: 0 : curve_lists_list_ptr = curve_lists_lists_list.get_and_step();
7126 : :
7127 : : Body *new_body_ptr;
7128 [ # # ]: 0 : if( GeometryModifyTool::instance()->imprint( *surf_list_ptr,
7129 [ # # ][ # # ]: 0 : *curve_lists_list_ptr, new_body_ptr ) == CUBIT_FAILURE )
7130 : : {
7131 : : // Remove tooldatas and free memory
7132 : : cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
7133 [ # # ]: 0 : curve_lists_lists_list );
7134 : 0 : return CUBIT_FAILURE;
7135 : : }
7136 : 0 : }
7137 : : }
7138 [ # # ][ # # ]: 0 : else if( preview_flg==CUBIT_TRUE && create_ref_edges_flg==CUBIT_TRUE )
7139 : : {
7140 : : // Just create the RefEdges
7141 [ # # ]: 0 : DLIList<RefEdge*> new_ref_edge_list;
7142 [ # # ]: 0 : curve_lists_lists_list.reset();
7143 : :
7144 [ # # ][ # # ]: 0 : for( i=curve_lists_lists_list.size(); i--; )
7145 : : {
7146 [ # # ]: 0 : curve_lists_list_ptr = curve_lists_lists_list.get_and_step();
7147 : :
7148 [ # # ]: 0 : curve_lists_list_ptr->reset();
7149 [ # # ][ # # ]: 0 : for( j=curve_lists_list_ptr->size(); j--; )
7150 : : {
7151 [ # # ]: 0 : DLIList<Curve*> *curve_list_ptr = curve_lists_list_ptr->get_and_step();
7152 [ # # ]: 0 : curve_list_ptr->reset();
7153 : :
7154 [ # # ]: 0 : create_ref_edges( *curve_list_ptr, new_ref_edge_list );
7155 : : }
7156 : : }
7157 : : // Let the user know about the new curves created
7158 [ # # ][ # # ]: 0 : if( new_ref_edge_list.size() )
7159 : : {
7160 [ # # ]: 0 : DLIList<CubitEntity*> cubit_entity_list;
7161 [ # # ][ # # ]: 0 : CAST_LIST( new_ref_edge_list, cubit_entity_list, CubitEntity );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
7162 [ # # ][ # # ]: 0 : CubitUtil::list_entity_ids( "Created new curves: ", cubit_entity_list );
7163 [ # # ]: 0 : }
7164 : : }
7165 : : else
7166 : : {
7167 : : // Just preview
7168 [ # # ][ # # ]: 0 : for( i=body_surf_list_list.size(); i--; )
7169 : : {
7170 [ # # ]: 0 : curve_lists_list_ptr = curve_lists_lists_list.get_and_step();
7171 : :
7172 [ # # ]: 0 : curve_lists_list_ptr->reset();
7173 [ # # ][ # # ]: 0 : for( j=curve_lists_list_ptr->size(); j--; )
7174 : : {
7175 [ # # ]: 0 : DLIList<Curve*> *curve_list_ptr = curve_lists_list_ptr->get_and_step();
7176 : :
7177 : : // Draw the curves
7178 [ # # ]: 0 : draw_preview( *curve_list_ptr );
7179 : : }
7180 : : }
7181 : : }
7182 : :
7183 : : // Flush the graphics
7184 [ # # ]: 0 : GfxPreview::flush();
7185 : :
7186 : : // Remove tooldatas and free memory
7187 : : cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
7188 [ # # ]: 0 : curve_lists_lists_list );
7189 : :
7190 [ # # ]: 0 : return CUBIT_SUCCESS;
7191 : : }
7192 : :
7193 : : void
7194 : 0 : SplitSurfaceTool::cleanup_for_extend_op( DLIList<RefVertex*> &ref_vertex_list,
7195 : : DLIList<DLIList<Surface*>*> &body_surf_list_list,
7196 : : DLIList<DLIList<DLIList<Curve*>*>*> &curve_lists_lists_list,
7197 : : CubitBoolean free_curves_flg )
7198 : : {
7199 : : int i;
7200 : : RefVertex *ref_vertex_ptr;
7201 : :
7202 : : // Remove tooldatas from vertices
7203 : 0 : ref_vertex_list.reset();
7204 [ # # ]: 0 : for( i=ref_vertex_list.size(); i--; )
7205 : : {
7206 : 0 : ref_vertex_ptr = ref_vertex_list.get_and_step();
7207 : 0 : ref_vertex_ptr->delete_TD( &TDSplitSurfaceExtend::is_split_surface_extend );
7208 : : }
7209 : :
7210 : : // Free allocated lists in body_surf_list_list
7211 [ # # ][ # # ]: 0 : while( body_surf_list_list.size() ) delete body_surf_list_list.pop();
7212 : :
7213 : : // Free allocated lists in curve_list_lists_list, as well as Curves (if not
7214 : : // attached to RefEdges).
7215 : : DLIList<DLIList<Curve*>*> *curve_list_lists_ptr;
7216 [ # # ]: 0 : for( i=curve_lists_lists_list.size(); i--; )
7217 : : {
7218 : 0 : curve_list_lists_ptr = curve_lists_lists_list.get();
7219 : :
7220 : 0 : free_curves_lists( *curve_list_lists_ptr );
7221 [ # # ]: 0 : delete curve_list_lists_ptr;
7222 : :
7223 : 0 : curve_lists_lists_list.step();
7224 : : }
7225 : :
7226 : 0 : return;
7227 : : }
7228 : :
7229 : 0 : void SplitSurfaceTool::find_nearest_curve_for_normal_projection(
7230 : : RefEdge* hit_edge_ptr, CubitVector& start_loc,
7231 : : RefFace* face, CubitVector& ray_dir, RefEdge*& new_edge_ptr,
7232 : : CubitVector& new_end_loc)
7233 : : {
7234 : : // traverse the curves in the surface and find the closest curve to the hardline
7235 : : // which the hardline can extend normal to
7236 : :
7237 [ # # ]: 0 : DLIList<RefEdge*> edge_list;
7238 [ # # ]: 0 : face->ref_edges(edge_list);
7239 : :
7240 [ # # ][ # # ]: 0 : std::map<double, std::pair<RefEdge*, CubitVector> > potential_curves_map;
7241 : :
7242 : : // maybe traverse all curves all of the time, and use the one closest to the point
7243 : : int i;
7244 [ # # ][ # # ]: 0 : for (i=edge_list.size(); i--;)
7245 : : {
7246 [ # # ]: 0 : RefEdge* edge = edge_list.get_and_step();
7247 : :
7248 [ # # ]: 0 : if (edge == hit_edge_ptr)
7249 : 0 : continue;
7250 : :
7251 [ # # ]: 0 : CubitVector closest_point;
7252 [ # # ]: 0 : edge->closest_point(start_loc, closest_point);
7253 : :
7254 : : // Only valid if location is ON the curve
7255 [ # # ]: 0 : CubitPointContainment contain = edge->point_containment( closest_point );
7256 [ # # ]: 0 : if( contain == CUBIT_PNT_ON )
7257 : : {
7258 : : // check to make sure angle isn't too bad
7259 : : // have a user setting for this in the future
7260 : : // but for now, use 90 degrees
7261 [ # # ]: 0 : CubitVector split_direction = closest_point - start_loc;
7262 [ # # ][ # # ]: 0 : if (split_direction.length_squared() <= GEOMETRY_RESABS) //ignore self
7263 : 0 : continue;
7264 : :
7265 [ # # ]: 0 : double angle = ray_dir.interior_angle(split_direction);
7266 [ # # ]: 0 : if (fabs(angle) <= 90.0)
7267 : : {
7268 [ # # ]: 0 : double dist = start_loc.distance_between(closest_point);
7269 : : potential_curves_map.insert(std::map<double, std::pair<RefEdge*, CubitVector> >::value_type(
7270 [ # # ][ # # ]: 0 : dist, std::make_pair(edge, closest_point)));
[ # # ][ # # ]
7271 : : }
7272 : : }
7273 : : }
7274 : :
7275 [ # # ][ # # ]: 0 : if (potential_curves_map.size())
7276 : : {
7277 [ # # ]: 0 : std::map<double, std::pair<RefEdge*, CubitVector> >::iterator iter = potential_curves_map.begin();
7278 [ # # ]: 0 : new_edge_ptr = (iter->second).first;
7279 [ # # ][ # # ]: 0 : new_end_loc = (iter->second).second;
7280 : : }
7281 : :
7282 [ # # ]: 0 : return;
7283 [ + - ][ + - ]: 6540 : }
|