Branch data Line data Source code
1 : : //-------------------------------------------------------------------------
2 : : // Copyright Notice
3 : : //
4 : : // Copyright (c) 1996
5 : : // by Malcolm J. Panthaki, DBA, and the University of New Mexico.
6 : : //-------------------------------------------------------------------------
7 : : //
8 : : //-------------------------------------------------------------------------
9 : : // Filename : Loop.C
10 : : //
11 : : // Purpose : This file contains the implementation of the class
12 : : // Loop.
13 : : //
14 : : // Special Notes :
15 : : //
16 : : // Creator : Xuechen Liu
17 : : //
18 : : // Creation Date : 08/02/96
19 : : //
20 : : // Owner : Malcolm J. Panthaki
21 : : //-------------------------------------------------------------------------
22 : :
23 : : // ********** BEGIN STANDARD INCLUDES **********
24 : : // ********** END STANDARD INCLUDES **********
25 : :
26 : : // ********** BEGIN MOTIF INCLUDES **********
27 : : // ********** END MOTIF INCLUDES **********
28 : :
29 : : // ********** BEGIN OPEN INVENTOR INCLUDES **********
30 : : // ********** END OPEN INVENTOR INCLUDES **********
31 : :
32 : : // ********** BEGIN CUBIT INCLUDES **********
33 : :
34 : : #include "Loop.hpp"
35 : :
36 : : #include "CoEdge.hpp"
37 : : #include "SenseEntity.hpp"
38 : : #include "RefEdge.hpp"
39 : : #include "RefFace.hpp"
40 : : #include "RefVertex.hpp"
41 : : #include "CubitUtil.hpp"
42 : :
43 : : #include "GeometryQueryEngine.hpp"
44 : :
45 : : #include "DLIList.hpp"
46 : : #include "CastTo.hpp"
47 : :
48 : : #include "Curve.hpp"
49 : : #include "LoopSM.hpp"
50 : :
51 : : // ********** END CUBIT INCLUDES **********
52 : :
53 : : // ********** BEGIN STATIC DECLARATIONS **********
54 : : // ********** END STATIC DECLARATIONS **********
55 : :
56 : : // ********** BEGIN PUBLIC FUNCTIONS **********
57 : :
58 : : //-------------------------------------------------------------------------
59 : : // Purpose : Default constructor.
60 : : //
61 : : // Special Notes :
62 : : //
63 : : // Creator : Xuechen Liu
64 : : //
65 : : // Creation Date : 08/06/96
66 : : //-------------------------------------------------------------------------
67 : 0 : Loop::Loop()
68 : : {
69 : 0 : }
70 : :
71 : : //-------------------------------------------------------------------------
72 : : // Purpose : A constructor woth a pointer to an other solid
73 : : // model entity.
74 : : //
75 : : // Special Notes :
76 : : //
77 : : // Creator : Xuechen Liu
78 : : //
79 : : // Creation Date : 08/06/96
80 : : //-------------------------------------------------------------------------
81 : 34684 : Loop::Loop(LoopSM* OSMEPtr)
82 : : {
83 [ + - ]: 17342 : set_topology_bridge(OSMEPtr) ;
84 : 17342 : }
85 : :
86 : 0 : LoopType Loop::loop_type() const
87 : : {
88 : 0 : LoopSM* loop_sm = get_loop_sm_ptr();
89 [ # # ]: 0 : if (loop_sm)
90 : : {
91 : 0 : return loop_sm->loop_type();
92 : : }
93 : 0 : assert(0);
94 : : return LOOP_TYPE_UNKNOWN;
95 : : }
96 : :
97 : : //-------------------------------------------------------------------------
98 : : // Purpose : Gets the angle metric for this Loop.
99 : : //
100 : : // Special Notes : The actual computation is done by the underlying geometric
101 : : // modeling engine as this is a geometric computation.
102 : : //
103 : : // Creator : Malcolm J. Panthaki
104 : : //
105 : : // Creation Date : 1/10/97
106 : : //-------------------------------------------------------------------------
107 : 0 : CubitStatus Loop::get_angle_metric(double& angle_metric)
108 : : {
109 : : // If the OSME knows its angle metric (some modelers cache
110 : : // some data along these lines), return that value
111 [ # # ]: 0 : LoopSM* loop_sm = get_loop_sm_ptr();
112 [ # # ][ # # ]: 0 : if (loop_sm && loop_sm->get_angle_metric(angle_metric))
[ # # ][ # # ]
113 : 0 : return CUBIT_SUCCESS;
114 : :
115 : : // First, get the list of coedges
116 [ # # ]: 0 : DLIList<CoEdge*> coedges;
117 [ # # ]: 0 : ordered_co_edges(coedges);
118 : :
119 : : // Now build a polygon approximation of the curves in the loop.
120 : : // The polygon is a straight-line approximation to and is
121 : : // topologically equivalent to the loop. At any given point,
122 : : // the polygon may be far from the actual loop, however.
123 : : // - samitch
124 : :
125 : : // If there are no coedges, this is an empty loop
126 [ # # ][ # # ]: 0 : if (coedges.size() == 0)
127 : : {
128 : 0 : angle_metric = 0;
129 : 0 : return CUBIT_FAILURE;
130 : : }
131 : :
132 : : //catch hardpoint case
133 [ # # ][ # # ]: 0 : if( coedges.size() == 1 && coedges[0]->ref_edge()->geometry_type() == POINT_CURVE_TYPE )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
134 : : {
135 : 0 : angle_metric = 2.0;
136 : 0 : return CUBIT_SUCCESS;
137 : : }
138 : :
139 : : // Loop through each coedge
140 : : int i, j;
141 [ # # ][ # # ]: 0 : DLIList<CubitVector*> polygon_points;
142 [ # # ][ # # ]: 0 : DLIList<CubitVector*> interior_points;
143 : 0 : CoEdge* cur_coedge = NULL;
144 [ # # ]: 0 : coedges.reset();
145 [ # # ][ # # ]: 0 : for (i = coedges.size(); i--; )
146 : : {
147 : : // Get the first point on this curve
148 [ # # ]: 0 : cur_coedge = coedges.get_and_step();
149 [ # # ]: 0 : RefEdge* cur_refedge = cur_coedge->get_ref_edge_ptr();
150 : : polygon_points.append(new CubitVector
151 [ # # ]: 0 : (cur_coedge->get_sense() == CUBIT_FORWARD ?
152 : : cur_refedge->start_vertex()->coordinates() :
153 [ # # ][ # # ]: 0 : cur_refedge->end_vertex()->coordinates()));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
154 : :
155 : : // Get the interior points for approximation
156 [ # # ]: 0 : CubitSense return_sense = cur_coedge->get_sense();
157 [ # # ]: 0 : interior_points.clean_out();
158 [ # # ]: 0 : cur_refedge->get_interior_extrema(interior_points, return_sense);
159 : : // Now put the points into the polygon.
160 : : // We don't need to re-allocate any CubitVectors because we are just
161 : : // copying pointers to dynamically allocated CubitVectors.
162 [ # # ][ # # ]: 0 : if (cur_coedge->get_sense() == return_sense)
163 : : {
164 [ # # ]: 0 : interior_points.reset();
165 [ # # ][ # # ]: 0 : for (j = interior_points.size(); j--; )
166 [ # # ][ # # ]: 0 : polygon_points.append(interior_points.get_and_step());
167 : : }
168 : : else
169 : : {
170 [ # # ]: 0 : interior_points.last();
171 [ # # ][ # # ]: 0 : for (j = interior_points.size(); j--; )
172 [ # # ][ # # ]: 0 : polygon_points.append(interior_points.get_and_back());
173 : : }
174 : : }
175 : :
176 : : // Now that we have all of the points, compute and sum up
177 : : // the internal angles on the polygon approximation.
178 : 0 : double angle, angle_sum = 0;
179 [ # # ]: 0 : RefFace* surface = cur_coedge->get_ref_face();
180 [ # # ][ # # ]: 0 : CubitVector *point[3], t[2], normal;
[ # # ]
181 [ # # ]: 0 : point[0] = polygon_points.get_and_step();
182 [ # # ]: 0 : point[1] = polygon_points.get_and_step();
183 [ # # ][ # # ]: 0 : t[0] = *point[1] - *point[0];
184 [ # # ][ # # ]: 0 : for (i = polygon_points.size(); i--; )
185 : : {
186 : : // Determine proper internal surface angle at point[1]
187 [ # # ]: 0 : point[2] = polygon_points.get_and_step();
188 [ # # ][ # # ]: 0 : normal = surface->normal_at(*point[1]);
189 [ # # ][ # # ]: 0 : t[1] = *point[1] - *point[2] ;
190 [ # # ]: 0 : angle = normal.vector_angle(t[1], t[0]);
191 : :
192 : : // Add up the total
193 : 0 : angle_sum += angle;
194 : :
195 : : // Iterate
196 : 0 : point[1] = point[2];
197 [ # # ][ # # ]: 0 : t[0] = -t[1];
198 : : }
199 [ # # ]: 0 : angle_metric = angle_sum / CUBIT_PI - polygon_points.size();
200 : :
201 : : // Clean up dynamically allocated vectors
202 [ # # ][ # # ]: 0 : for (i = polygon_points.size(); i>0; i--)
203 [ # # ]: 0 : delete polygon_points.get_and_step();
204 : :
205 [ # # ]: 0 : return CUBIT_SUCCESS;
206 : : }
207 : :
208 : : //-------------------------------------------------------------------------
209 : : // Purpose : gets the ref edges in order with respect to this Loop.
210 : : //
211 : : // Special Notes : appends the edges to the list, with respect to coedges.
212 : : //
213 : : // Creator : David White
214 : : //
215 : : // Creation Date : 03/25/97
216 : : //-------------------------------------------------------------------------
217 : 132 : CubitStatus Loop::ordered_ref_edges(DLIList<RefEdge*>& ordered_edge_list )
218 : : {
219 : 132 : CubitStatus status = CUBIT_SUCCESS;
220 : :
221 [ + - ]: 132 : DLIList<SenseEntity*> sense_entity_list;
222 : :
223 [ + - ]: 132 : status = this->get_sense_entity_list(sense_entity_list);
224 [ - + ]: 132 : if ( status == CUBIT_FAILURE )
225 : : {
226 [ # # ][ # # ]: 0 : PRINT_ERROR("In Loop::ordered_ref_edges\n");
[ # # ][ # # ]
227 [ # # ][ # # ]: 0 : PRINT_ERROR(" Problem getting the CoEdges of this Loop.\n");
[ # # ][ # # ]
228 : 0 : return CUBIT_FAILURE;
229 : : }
230 : :
231 : : //Get the ref_edges associated with each co_edge.
232 [ + - ][ + + ]: 660 : for ( int ii = sense_entity_list.size(); ii > 0; ii-- )
233 : : {
234 [ + - ]: 528 : SenseEntity* se_ptr = sense_entity_list.get_and_step();
235 [ + - ]: 528 : BasicTopologyEntity* bte_ptr = se_ptr->get_basic_topology_entity_ptr();
236 [ - + ][ + - ]: 528 : ordered_edge_list.append( dynamic_cast<RefEdge*>(bte_ptr) );
237 : : }
238 : :
239 [ + - ]: 132 : return CUBIT_SUCCESS;
240 : : }
241 : : //-------------------------------------------------------------------------
242 : : // Purpose : gets the ref edges in order with respect to this Loop.
243 : : //
244 : : // Special Notes : appends the edges to the list, with respect to coedges.
245 : : //
246 : : // Creator : David White
247 : : //
248 : : // Creation Date : 03/25/97
249 : : //-------------------------------------------------------------------------
250 : 4992 : CubitStatus Loop::ordered_co_edges(DLIList<CoEdge*>& ordered_coedge_list )
251 : : {
252 : 4992 : CubitStatus status = CUBIT_SUCCESS;
253 : :
254 [ + - ]: 4992 : DLIList<SenseEntity*> sense_entity_list;
255 : :
256 [ + - ]: 4992 : status = this->get_sense_entity_list(sense_entity_list);
257 [ - + ]: 4992 : if ( status == CUBIT_FAILURE )
258 : : {
259 [ # # ][ # # ]: 0 : PRINT_ERROR("In Loop::ordered_co_edges\n"
[ # # ]
260 [ # # ]: 0 : " Problem getting the CoEdges of this Loop.\n");
261 : 0 : return CUBIT_FAILURE;
262 : : }
263 : :
264 : : // Cast the SenseEntity list to a CoEdge list
265 [ + - ][ + - ]: 9984 : DLIList<CoEdge*> co_edge_list(sense_entity_list.size());
[ + - ]
266 [ + - ][ + - ]: 24960 : CAST_LIST( sense_entity_list, co_edge_list , CoEdge);
[ + - ][ - + ]
[ + - ][ + - ]
[ + + ]
267 : :
268 [ + - ]: 4992 : ordered_coedge_list += co_edge_list;
269 [ + - ]: 4992 : return CUBIT_SUCCESS;
270 : : }
271 : :
272 : :
273 : :
274 : 20052 : RefFace* Loop::get_ref_face_ptr()
275 : : {
276 [ + + ]: 20052 : return CAST_TO( get_basic_topology_entity_ptr(), RefFace );
277 : : }
278 : :
279 : : //-------------------------------------------------------------------------
280 : : // Purpose : Get LoopSM
281 : : //
282 : : // Special Notes :
283 : : //
284 : : // Creator : Jason Kraftcheck
285 : : //
286 : : // Creation Date : 07/23/03
287 : : //-------------------------------------------------------------------------
288 : 0 : LoopSM* Loop::get_loop_sm_ptr() const
289 : : {
290 [ # # ]: 0 : return dynamic_cast<LoopSM*>(bridge_manager()->topology_bridge());
291 : : }
292 : :
293 : : //-------------------------------------------------------------------------
294 : : // Purpose : Check if loops are spatially equal.
295 : : //
296 : : // Special Notes :
297 : : //
298 : : // Creator : Jason Kraftcheck
299 : : //
300 : : // Creation Date : 04/01/04
301 : : //-------------------------------------------------------------------------
302 : 2397 : CubitBoolean Loop::about_spatially_equal( DLIList<CoEdge*>& other_coedges,
303 : : CubitSense relative_sense,
304 : : double tolerance_factor,
305 : : CubitBoolean notify_refEntity )
306 : : {
307 [ + - ][ + - ]: 2397 : DLIList<CoEdge*> this_coedges(other_coedges.size());
308 : :
309 : : // Loops must have same number of coedges to match.
310 [ + - ]: 2397 : this->ordered_co_edges( this_coedges );
311 [ + - ][ + - ]: 2397 : if (this_coedges.size() != other_coedges.size())
[ - + ]
312 : 0 : return CUBIT_FALSE;
313 : :
314 : : // Want to compare coedges in order, so make sure we have
315 : : // them in the correct order.
316 [ + + ]: 2397 : if (relative_sense == CUBIT_REVERSED)
317 [ + - ]: 43 : this_coedges.reverse();
318 : :
319 : : // Try to match all coedges. Begin with the first coedge
320 : : // in this loop. For each coedge in the other loop that
321 : : // it matches, check if all the other coedges match in the
322 : : // correct order.
323 : 2397 : int other_loop_index = 0;
324 [ + - ]: 2397 : this_coedges.reset();
325 [ + - ]: 2397 : other_coedges.reset();
326 [ + - ]: 2397 : CoEdge* this_coedge = this_coedges.get_and_step();
327 [ + - ][ + + ]: 11630 : for (int i = other_coedges.size(); i--; )
328 : : {
329 : : // Loop until we find a matching CoEdge
330 [ + - ]: 9347 : CoEdge* other_coedge = other_coedges.get_and_step();
331 [ + + ]: 9347 : if (!this_coedge->about_spatially_equal( other_coedge,
332 : : relative_sense,
333 : : tolerance_factor,
334 [ + - ]: 9347 : notify_refEntity ))
335 : 9073 : continue;
336 : :
337 : : // Found a matching coedge. Now try to match all the
338 : : // others in the correct order.
339 : 274 : bool match = true;
340 [ + - ]: 274 : other_loop_index = other_coedges.get_index();
341 [ + - ][ + + ]: 776 : for (int j = other_coedges.size() - 1; j-- && match; )
[ + + ][ + + ]
342 : : {
343 [ + - ]: 502 : this_coedge = this_coedges.get_and_step();
344 [ + - ]: 502 : other_coedge = other_coedges.get_and_step();
345 : : match = this_coedge->about_spatially_equal( other_coedge,
346 : : relative_sense,
347 : : tolerance_factor,
348 [ + - ]: 502 : notify_refEntity );
349 : : }
350 : :
351 : : // Matched all coedges, in order. Done.
352 [ + + ]: 274 : if (match)
353 : 114 : return CUBIT_TRUE;
354 : :
355 : : // Try again, as perhaps the first coedge of this loop
356 : : // also matches some other one in the second loop and
357 : : // if we start with that one, the remaining coedges will
358 : : // also match.
359 [ + - ]: 160 : this_coedges.reset();
360 [ + - ]: 160 : this_coedge = this_coedges.get_and_step();
361 [ + - ]: 160 : other_coedges.reset();
362 [ + - ]: 160 : other_coedges.step( other_loop_index );
363 : : }
364 : :
365 : : // If here, loops didn't match.
366 [ + - ]: 2397 : return CUBIT_FALSE;
367 [ + - ][ + - ]: 6540 : }
368 : :
369 : :
370 : :
371 : : // ********** END PUBLIC FUNCTIONS **********
372 : :
373 : : // ********** BEGIN PROTECTED FUNCTIONS **********
374 : : // ********** END PROTECTED FUNCTIONS **********
375 : :
376 : : // ********** BEGIN PRIVATE FUNCTIONS **********
377 : : // ********** END PRIVATE FUNCTIONS **********
378 : :
379 : : // ********** BEGIN HELPER CLASSES **********
380 : : // ********** END HELPER CLASSES **********
381 : :
382 : : // ********** BEGIN EXTERN FUNCTIONS **********
383 : : // ********** END EXTERN FUNCTIONS **********
384 : :
385 : : // ********** BEGIN STATIC FUNCTIONS **********
386 : : // ********** END STATIC FUNCTIONS **********
387 : :
388 : :
|