0023830: BRepExtrema_DistShapeShape does not find intersection of face with edge
[occt.git] / src / Xw / Xw_draw_line.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 #define S3593           /*GG_130398
19 OPTIMISATION MFT
20                         Activer le clipping de maniere optionnelle
21 */
22
23 #include <Xw_Extension.h>
24
25         /* ifdef then trace on */
26 #ifdef TRACE
27 #define TRACE_DRAW_LINE
28 #endif
29
30 /*
31    STATUS Xw_draw_line (awindow,npoint,x,y):
32    XW_EXT_WINDOW *awindow
33    int npoint           Polyline point number
34    float *x,*y          Points Arrays
35
36
37         Display continuous line in current QG set by set_line_attrib .
38         Note that lines can be buffered depending of the DisplayMode context
39         and Flush at Xw_flush time .
40
41         returns ERROR if npoint > MAXPOINTS
42         returns SUCCESS always 
43
44 */
45
46 static int BeginLine = -1 ;
47 static XW_EXT_LINE *plinelist ;
48 static XW_EXT_POINT *plinedesc ;
49 static XSegment segment;
50
51 #ifdef XW_PROTOTYPE
52 XW_STATUS Xw_draw_line (void* awindow,int npoint,float* px,float* py) 
53 #else
54 XW_STATUS Xw_draw_line (awindow,npoint,px,py) 
55 void *awindow;
56 int npoint ;
57 float *px,*py ;
58 #endif /*XW_PROTOTYPE*/
59 {
60 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*) awindow ;
61 XW_EXT_BUFFER *pbuffer ;
62 int i,nline,ldesc,bindex;
63 int x,y,lx=0,ly=0 ;
64
65         if( !Xw_isdefine_window(pwindow) ) {
66             /*ERROR*Bad EXT_WINDOW Address*/
67             Xw_set_error(24,"Xw_draw_line",pwindow) ;
68             return (XW_ERROR) ;
69         }
70
71         if( npoint > MAXPOINTS ) {
72             npoint = MAXPOINTS;
73             /*ERROR*Too many points in LINE*/
74             Xw_set_error(28,"Xw_draw_line",&npoint) ;
75             return (XW_ERROR) ;
76         }
77
78         bindex = _BINDEX ;
79         pbuffer = &_BUFFER(bindex) ;
80         for( plinelist = pbuffer->plinelist ; plinelist ;
81                         plinelist = (XW_EXT_LINE*)plinelist->link ) {
82             if( plinelist->nline < MAXLINES ) break ;
83         }
84
85         if( !plinelist ) {
86             plinelist = Xw_add_polyline_structure(pbuffer) ;
87         }
88
89         if( !plinelist ) return XW_ERROR ;
90
91         for( plinedesc = pbuffer->plinedesc ; plinedesc ;
92                         plinedesc = (XW_EXT_POINT*)plinedesc->link ) {
93             if( plinedesc->npoint + npoint <= MAXPOINTS ) break ;
94         }
95
96         if( !plinedesc ) {
97             plinedesc = Xw_add_line_desc_structure(pbuffer) ;
98         }
99
100         if( !plinedesc ) return XW_ERROR ;
101
102         nline = plinelist->nline ;
103         ldesc = plinedesc->npoint ;
104         plinelist->plines[nline] = &plinedesc->rpoints[ldesc] ;
105         for( i=0 ; i<npoint ; i++ ) {
106 //OCC186
107           x = PXPOINT(px[i], pwindow->xratio) ;
108           y = PYPOINT(py[i], pwindow->attributes.height, pwindow->yratio) ;
109 //OCC186
110 #ifdef S3593
111           if( pwindow->clipflag ) {  
112 #endif
113             if( i > 0 ) {
114               int status;
115               status = Xw_clip_segment(pwindow,lx,ly,x,y,&segment);
116               if( status >= 0 ) { 
117                 if( (i < 2) || (status & 0xF ) ) {
118                   plinedesc->rpoints[ldesc].x = segment.x1 ;
119                   plinedesc->rpoints[ldesc].y = segment.y1 ;
120                   ldesc++;
121                   if( bindex > 0 ) {
122                     int xx = segment.x1,yy = segment.y1;
123                     pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
124                     pbuffer->rymin = min(pbuffer->rymin,yy) ;
125                     pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
126                     pbuffer->rymax = max(pbuffer->rymax,yy) ;
127                   }
128                 }
129                 plinedesc->rpoints[ldesc].x = segment.x2 ;
130                 plinedesc->rpoints[ldesc].y = segment.y2 ;
131                 ldesc++;
132                 if( bindex > 0 ) {
133                   int xx = segment.x2,yy = segment.y2;
134                   pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
135                   pbuffer->rymin = min(pbuffer->rymin,yy) ;
136                   pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
137                   pbuffer->rymax = max(pbuffer->rymax,yy) ;
138                 }
139               }
140             }
141             lx = x; ly = y;
142 #ifdef S3593
143           } else {
144             plinedesc->rpoints[ldesc].x = x ;
145             plinedesc->rpoints[ldesc].y = y ;
146             ldesc++ ;
147             if( bindex > 0 ) {
148               pbuffer->rxmin = min(pbuffer->rxmin,x) ;
149               pbuffer->rymin = min(pbuffer->rymin,y) ;
150               pbuffer->rxmax = max(pbuffer->rxmax,x) ;
151               pbuffer->rymax = max(pbuffer->rymax,y) ;
152             }
153           }
154 #endif
155         }
156         plinelist->lines[nline] = ldesc - plinedesc->npoint ;
157         if( plinelist->lines[nline] > 1 ) {
158           plinedesc->npoint = ldesc ;
159           plinelist->nline++ ;
160           if( bindex > 0 ) {
161             pbuffer->isempty = False ;
162           } else if( BeginLine < 0 ) {
163             int index = pwindow->lineindex ;
164             Xw_draw_pixel_lines(pwindow,plinelist,pwindow->qgline[index].gc);
165             plinelist->nline = 0 ;
166             plinedesc->npoint = 0 ;
167           }
168         }
169
170 #ifdef  TRACE_DRAW_LINE
171 if( Xw_get_trace() > 2 ) {
172     printf(" Xw_draw_line(%lx,%d)\n",(long ) pwindow,npoint) ;
173     for( i=0 ; i<npoint ; i++ ) {
174         printf("        Point(%d) = {%f,%f}\n",i,px[i],py[i]) ;
175     }
176 }
177 #endif
178
179         return (XW_SUCCESS);
180 }
181
182 #ifdef XW_PROTOTYPE
183 void Xw_draw_pixel_lines (XW_EXT_WINDOW* pwindow,XW_EXT_LINE *plinelist,GC gc) 
184 #else
185 void Xw_draw_pixel_lines (pwindow,plinelist,gc) 
186 XW_EXT_WINDOW *pwindow;
187 XW_EXT_LINE *plinelist;
188 GC gc ;
189 #endif /*XW_PROTOTYPE*/
190 {
191 int i,npoint;
192 XPoint *ppoint ;
193
194     for( i=0 ; i<plinelist->nline ; i++ ) {
195         npoint = plinelist->lines[i] ;
196         ppoint = plinelist->plines[i] ;
197         if( plinelist->isupdated ) {
198           ppoint += MAXPOINTS ;
199         }
200         if( ppoint && npoint > 1 ) {
201           XDrawLines(_DISPLAY,_DRAWABLE,gc,ppoint,npoint,CoordModeOrigin) ;
202         }
203     }
204 }
205
206 /*
207    STATUS Xw_begin_line (awindow,npoint):
208    XW_EXT_WINDOW *awindow
209    int npoint           Polyline point number
210
211
212         Begin Polyline which must be filled by Xw_line_point and
213                                      closed by Xw_close_line
214
215         returns ERROR if npoint > MAXPOINTS
216         returns SUCCESS if successful
217
218 */
219
220 static int Npoint = 0;
221 static int Lx,Ly;
222 #ifdef XW_PROTOTYPE
223 XW_STATUS Xw_begin_line(void* awindow,int npoint)
224 #else
225 XW_STATUS Xw_begin_line(awindow,npoint)
226 void *awindow ;
227 int npoint ;
228 #endif /*XW_PROTOTYPE*/
229 {
230 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
231 XW_EXT_BUFFER *pbuffer ;
232 int nline,ldesc,bindex ;
233
234         if( !Xw_isdefine_window(pwindow) ) {
235             /*ERROR*Bad EXT_WINDOW Address*/
236             Xw_set_error(24,"Xw_begin_line",pwindow) ;
237             return (XW_ERROR) ;
238         }
239
240         if( npoint > MAXPOINTS ) {
241             npoint = MAXPOINTS ;
242             /*ERROR*Too many points in LINE*/
243             Xw_set_error(28,"Xw_begin_line",&npoint) ;
244             return (XW_ERROR) ;
245         }
246
247         if( BeginLine >= 0 ) Xw_close_line(pwindow);
248
249         bindex = _BINDEX ;
250         pbuffer = &_BUFFER(bindex) ;
251         for( plinelist = pbuffer->plinelist ; plinelist ;
252                         plinelist = (XW_EXT_LINE*)plinelist->link ) {
253             if( plinelist->nline < MAXLINES ) break ;
254         }
255
256         if( !plinelist ) {
257             plinelist = Xw_add_polyline_structure(pbuffer) ;
258         }
259
260         if( !plinelist ) return XW_ERROR ;
261
262         for( plinedesc = pbuffer->plinedesc ; plinedesc ;
263                         plinedesc = (XW_EXT_POINT*)plinedesc->link ) {
264             if( plinedesc->npoint + npoint <= MAXPOINTS ) break ;
265         }
266
267         if( !plinedesc ) {
268             plinedesc = Xw_add_line_desc_structure(pbuffer) ;
269         }
270
271         if( !plinedesc ) return XW_ERROR ;
272
273         nline = plinelist->nline ;
274         ldesc = plinedesc->npoint ;
275         plinelist->lines[nline] = Npoint = 0 ;
276         plinelist->plines[nline] = &plinedesc->rpoints[ldesc] ;
277         BeginLine = ldesc ;
278
279 #ifdef  TRACE_DRAW_LINE
280 if( Xw_get_trace() > 2 ) {
281     printf(" Xw_begin_line(%lx,%d)\n",(long ) pwindow,npoint) ;
282 }
283 #endif
284         return (XW_SUCCESS) ;
285 }
286
287 /*
288    STATUS Xw_line_point (awindow,x,y):
289    XW_EXT_WINDOW *awindow
290    float x,y    New point to add in polyline in user-space coordinates
291
292         Fill Polyline with one point more
293
294         returns ERROR if Too Many Points in polylines
295         returns SUCCESS if successful
296
297 */
298
299 #ifdef XW_PROTOTYPE
300 XW_STATUS Xw_line_point(void* awindow,float x,float y)
301 #else
302 XW_STATUS Xw_line_point(awindow,x,y)
303 void *awindow ;
304 float x,y ;
305 #endif /*XW_PROTOTYPE*/
306 {
307 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
308 XW_EXT_BUFFER *pbuffer ;
309 int bindex,xi,yi ;
310
311       if( BeginLine >= 0 ) {
312         int ldesc = plinedesc->npoint ;
313         if( ldesc >= MAXPOINTS ) {
314           /*ERROR*Too many points in LINE*/
315           Xw_set_error(28,"Xw_line_point",&ldesc) ;
316           Xw_close_line(pwindow) ;
317           return (XW_ERROR) ;
318         }
319
320         bindex = _BINDEX ;
321         pbuffer = &_BUFFER(bindex) ;
322 //OCC186
323         xi = PXPOINT(x, pwindow->xratio) ;
324         yi = PYPOINT(y, pwindow->attributes.height, pwindow->yratio) ;
325 //OCC186
326 #ifdef S3593
327         if( pwindow->clipflag ) {  
328 #endif
329           if( Npoint > 0 ) {
330             int status;
331             status = Xw_clip_segment(pwindow,Lx,Ly,xi,yi,&segment);
332             if( status >= 0 ) { 
333               if( (Npoint < 2) || (status & 0xF ) ) {
334                 plinedesc->rpoints[ldesc].x = segment.x1 ;
335                 plinedesc->rpoints[ldesc].y = segment.y1 ;
336                 ldesc++;
337                 if( bindex > 0 ) {
338                   int xx = segment.x1,yy = segment.y1;
339                   pbuffer->isempty = False ;
340                   pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
341                   pbuffer->rymin = min(pbuffer->rymin,yy) ;
342                   pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
343                   pbuffer->rymax = max(pbuffer->rymax,yy) ;
344                 }
345               }
346               plinedesc->rpoints[ldesc].x = segment.x2 ;
347               plinedesc->rpoints[ldesc].y = segment.y2 ;
348               ldesc++;
349               if( bindex > 0 ) {
350                 int xx = segment.x2,yy = segment.y2;
351                 pbuffer->isempty = False ;
352                 pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
353                 pbuffer->rymin = min(pbuffer->rymin,yy) ;
354                 pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
355                 pbuffer->rymax = max(pbuffer->rymax,yy) ;
356               }
357             }
358           }
359           Lx = xi; Ly = yi;
360 #ifdef S3593
361         } else {
362           plinedesc->rpoints[ldesc].x = xi ;
363           plinedesc->rpoints[ldesc].y = yi ;
364           ldesc++;
365           if( bindex > 0 ) {
366             pbuffer->isempty = False ;
367             pbuffer->rxmin = min(pbuffer->rxmin,xi) ;
368             pbuffer->rymin = min(pbuffer->rymin,yi) ;
369             pbuffer->rxmax = max(pbuffer->rxmax,xi) ;
370             pbuffer->rymax = max(pbuffer->rymax,yi) ;
371           }
372         }
373 #endif
374         Npoint++;
375         plinedesc->npoint = ldesc ;
376       }
377
378 #ifdef  TRACE_DRAW_LINE
379 if( Xw_get_trace() > 3 ) {
380     printf(" Xw_line_point(%lx,%f,%f)\n",(long ) pwindow,x,y) ;
381 }
382 #endif
383         return (XW_SUCCESS) ;
384 }
385
386 /*
387    STATUS Xw_close_line (awindow):
388    XW_EXT_WINDOW *awindow
389
390         Close the Polyline
391
392         returns ERROR if Polyline is empty
393         returns SUCCESS if successful
394
395 */
396
397 #ifdef XW_PROTOTYPE
398 XW_STATUS Xw_close_line(void* awindow)
399 #else
400 XW_STATUS Xw_close_line(awindow)
401 void *awindow ;
402 #endif /*XW_PROTOTYPE*/
403 {
404 XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
405
406         if( BeginLine >= 0 ) {
407           int nline = plinelist->nline ;
408           int ldesc = plinedesc->npoint ;
409           int bindex = _BINDEX ;
410           plinelist->lines[nline] = ldesc - BeginLine ;
411           plinelist->nline++ ;
412
413           if( !bindex ) {       
414             int index = pwindow->lineindex ;
415             Xw_draw_pixel_lines(pwindow,plinelist,pwindow->qgline[index].gc) ;
416             plinelist->nline = 0 ;
417             plinedesc->npoint = 0 ;
418           }
419           BeginLine = -1 ;
420         }
421
422 #ifdef  TRACE_DRAW_LINE
423 if( Xw_get_trace() > 2 ) {
424     printf(" Xw_close_line(%lx)\n",(long ) pwindow) ;
425 }
426 #endif
427         return (XW_SUCCESS) ;
428 }
429
430 #ifdef XW_PROTOTYPE
431 XW_EXT_LINE* Xw_add_polyline_structure(XW_EXT_BUFFER* pbuflist )
432 #else
433 XW_EXT_LINE* Xw_add_polyline_structure(pbuflist )
434 XW_EXT_BUFFER *pbuflist ;
435 #endif /*XW_PROTOTYPE*/
436 /*
437         Create and Insert at end one Extended polyline structure in the
438         polyline List
439
440         returns Extended polyline address if successful
441                 or NULL if Bad Allocation
442 */
443 {
444 XW_EXT_LINE *pline ;
445
446         pline = (XW_EXT_LINE*) Xw_malloc(sizeof(XW_EXT_LINE)) ;
447         if( pline ) {
448             pline->link = pbuflist->plinelist ;
449             pline->isupdated = False ;
450             pline->nline = 0 ;
451             pbuflist->plinelist = pline ;
452         } else {
453             /*ERROR*EXT_LINE allocation failed*/
454             Xw_set_error(30,"Xw_add_polyline_structure",NULL) ;
455         }
456
457         return (pline) ;
458 }
459
460 #ifdef XW_PROTOTYPE
461 XW_STATUS Xw_del_polyline_structure(XW_EXT_BUFFER* pbuflist)
462 #else
463 XW_STATUS Xw_del_polyline_structure(pbuflist)
464 XW_EXT_BUFFER *pbuflist ;
465 #endif /*XW_PROTOTYPE*/
466 /*
467         Remove ALL Extended polyline structure in the
468         polyline List
469
470         SUCCESS always
471 */
472 {
473 XW_EXT_LINE *pline,*qline ;
474
475         for( pline = pbuflist->plinelist ; pline ; pline = qline ) {
476             qline = (XW_EXT_LINE*)pline->link ;
477             Xw_free(pline) ;
478         }
479         pbuflist->plinelist = NULL ;
480
481         return (XW_SUCCESS) ;
482 }
483
484 #ifdef XW_PROTOTYPE
485 XW_EXT_POINT* Xw_add_line_desc_structure(XW_EXT_BUFFER* pbuflist )
486 #else
487 XW_EXT_POINT* Xw_add_line_desc_structure(pbuflist )
488 XW_EXT_BUFFER *pbuflist ;
489 #endif /*XW_PROTOTYPE*/
490 /*
491         Create and Insert at end one Extended line_desc structure in the
492         line_desc List
493
494         returns Extended line_desc address if successful
495                 or NULL if Bad Allocation
496 */
497 {
498 XW_EXT_POINT *pdesc ;
499
500         pdesc = (XW_EXT_POINT*) Xw_malloc(sizeof(XW_EXT_POINT)) ;
501         if( pdesc ) {
502             pdesc->link = pbuflist->plinedesc ;
503             pdesc->npoint = 0 ;
504             pbuflist->plinedesc = pdesc ;
505         } else {
506             /*ERROR*EXT_POINT allocation failed*/
507             Xw_set_error(117,"Xw_add_line_desc_structure",NULL) ;
508         }
509
510         return (pdesc) ;
511 }
512
513 #ifdef XW_PROTOTYPE
514 XW_STATUS Xw_del_line_desc_structure(XW_EXT_BUFFER* pbuflist)
515 #else
516 XW_STATUS Xw_del_line_desc_structure(pbuflist)
517 XW_EXT_BUFFER *pbuflist ;
518 #endif /*XW_PROTOTYPE*/
519 /*
520         Remove ALL Extended line_desc structure in the
521         line_desc List
522
523         SUCCESS always
524 */
525 {
526 XW_EXT_POINT *pdesc,*qdesc ;
527
528         for( pdesc = pbuflist->plinedesc ; pdesc ; pdesc = qdesc ) {
529             qdesc = (XW_EXT_POINT*)pdesc->link ;
530             Xw_free(pdesc) ;
531         }
532         pbuflist->plinedesc = NULL ;
533
534         return (XW_SUCCESS) ;
535 }