OCC22199 OpenGL memory leaks in TKOpenGl
[occt.git] / src / Graphic3d / Graphic3d_ArrayOfPrimitives.cxx
CommitLineData
7fd59977 1// File Graphic3d_ArrayOfPrimitives.cxx
2// Created 16/06/2000 : ATS/GG : G005
3
4#define TRACE 0
5
6#include <Graphic3d_ArrayOfPrimitives.ixx>
7#include <Standard.hxx>
8#include <TCollection_AsciiString.hxx>
9#include <OSD_Environment.hxx>
10
11#include <stdio.h>
12#include <stdlib.h>
13
14static Standard_Integer enableArray = 1;
15static Standard_Boolean interleavedArray = Standard_False;
16
17Graphic3d_ArrayOfPrimitives :: Graphic3d_ArrayOfPrimitives (
18 const Graphic3d_TypeOfPrimitiveArray aType,
19 const Standard_Integer maxVertexs,
20 const Standard_Integer maxBounds,
21 const Standard_Integer maxEdges,
22 const Standard_Boolean hasVNormals,
23 const Standard_Boolean hasVColors,
24 const Standard_Boolean hasFColors,
25 const Standard_Boolean hasVTexels,
26 const Standard_Boolean hasEdgeInfos
27) : myMaxBounds(0),myMaxVertexs(0),myMaxEdges(0) {
28 Standard_Integer size = sizeof(CALL_DEF_PARRAY);
29 Standard_Integer format = MVERTICE;
30 if( hasVNormals ) format |= MVNORMAL;
31 if( hasVColors ) format |= MVCOLOR;
32 if( hasVTexels ) format |= MVTEXEL;
33
34 myPrimitiveArray = (Graphic3d_PrimitiveArray) Standard::Allocate(size);
35 memset ( myPrimitiveArray, 0, size );
36
37 if( maxVertexs > 0){
38 myPrimitiveArray->vertices = (TEL_POINT*) Standard::Allocate(maxVertexs *sizeof(TEL_POINT));
39 memset ( myPrimitiveArray->vertices, 0, maxVertexs *sizeof(TEL_POINT));
40 }
41
42 if( hasVNormals ){
43 myPrimitiveArray->vnormals = (TEL_POINT*) Standard::Allocate(sizeof(TEL_POINT) * maxVertexs);
44 memset ( myPrimitiveArray->vnormals, 0, sizeof(TEL_POINT) * maxVertexs);
45 }
46
47 if( hasVColors ){
48 myPrimitiveArray->vcolours = (Tint*) Standard::Allocate(maxVertexs *sizeof(Tint));
49 memset ( myPrimitiveArray->vcolours, 0, sizeof(Tint) * maxVertexs);
50 }
51
52 if( hasVTexels ){
53 myPrimitiveArray->vtexels = (TEL_TEXTURE_COORD*) Standard::Allocate(maxVertexs *sizeof(TEL_TEXTURE_COORD));
54 memset ( myPrimitiveArray->vtexels, 0, sizeof(TEL_TEXTURE_COORD) * maxVertexs);
55 }
56
57 if( hasFColors && (maxBounds > 0) ){
58 myPrimitiveArray->fcolours = (TEL_COLOUR*) Standard::Allocate(maxBounds *sizeof(TEL_COLOUR));
59 memset ( myPrimitiveArray->fcolours, 0, sizeof(TEL_COLOUR) * maxBounds);
60 }
61
62 if( maxBounds > 0 ){
63 myPrimitiveArray->bounds = (Tint*) Standard::Allocate(maxBounds *sizeof(Tint));
64 memset ( myPrimitiveArray->bounds, 0, maxBounds *sizeof(Tint));
65 }
66
67 if( maxEdges > 0 ){
68 myPrimitiveArray->edges = (Tint*) Standard::Allocate(maxEdges *sizeof(Tint));
69 memset ( myPrimitiveArray->edges, 0, maxEdges *sizeof(Tint));
70 }
71
72 if( hasEdgeInfos && (maxEdges > 0) ){
73 myPrimitiveArray->edge_vis = (Tchar*)Standard::Allocate(maxEdges *sizeof(Tchar));
74 memset ( myPrimitiveArray->edge_vis, 0, maxEdges *sizeof(Tchar));
75 }
76
77 myPrimitiveArray->keys = NULL;
78 myMaxVertexs = maxVertexs;
79 myMaxBounds = maxBounds;
80 myMaxEdges = maxEdges;
81 myPrimitiveArray->type = (TelPrimitivesArrayType) aType;
82 myPrimitiveArray->format = format;
83 myPrimitiveArray->num_bounds = 0;
84 myPrimitiveArray->num_vertexs = 0;
85 myPrimitiveArray->num_edges = 0;
86 myPrimitiveArray->VBOEnabled = -1;
87 myPrimitiveArray->flagBufferVBO = -1;
161c4476 88 myPrimitiveArray->contextId = 0;
7fd59977 89
90 for( int i =0 ; i < VBOMaxType ; i++){
91 myPrimitiveArray->bufferVBO[i] = 0;
92 }
93
94}
95
96void Graphic3d_ArrayOfPrimitives::Destroy ( ){
97 if( myPrimitiveArray ) {
98 if( myPrimitiveArray->vertices ){
99 Standard::Free( (Standard_Address&)myPrimitiveArray->vertices );
100 myPrimitiveArray->vertices = 0;
101 }
102
103 if( myPrimitiveArray->vnormals ){
104 Standard::Free( (Standard_Address&)myPrimitiveArray->vnormals );
105 myPrimitiveArray->vnormals = 0;
106 }
107
108 if( myPrimitiveArray->vcolours ){
109 Standard::Free( (Standard_Address&)myPrimitiveArray->vcolours );
110 myPrimitiveArray->vcolours = 0;
111 }
112
113 if( myPrimitiveArray->vtexels ){
114 Standard::Free( (Standard_Address&)myPrimitiveArray->vtexels );
115 myPrimitiveArray->vtexels = 0;
116 }
117
118 if( myPrimitiveArray->fcolours ){
119 Standard::Free( (Standard_Address&)myPrimitiveArray->fcolours );
120 myPrimitiveArray->fcolours = 0;
121 }
122
123 if( myPrimitiveArray->bounds ){
124 Standard::Free( (Standard_Address&)myPrimitiveArray->bounds );
125 myPrimitiveArray->bounds = 0;
126 }
127
128 if( myPrimitiveArray->edges ){
129 Standard::Free( (Standard_Address&)myPrimitiveArray->edges );
130 myPrimitiveArray->edges = 0;
131 }
132
133 if( myPrimitiveArray->edge_vis ){
134 Standard::Free( (Standard_Address&)myPrimitiveArray->edge_vis );
135 myPrimitiveArray->edge_vis = 0;
136 }
137
138 Standard::Free( (Standard_Address&)myPrimitiveArray );
139#if TRACE > 0
140 cout << " Graphic3d_ArrayOfPrimitives::Destroy()" << endl;
141#endif
142 }
143}
144
145void Graphic3d_ArrayOfPrimitives::Enable() {
146 enableArray = 1;
147}
148
149void Graphic3d_ArrayOfPrimitives::Disable() {
150 enableArray = -1;
151}
152
153Standard_Boolean Graphic3d_ArrayOfPrimitives::IsEnable() {
154
155 if( enableArray == 0 ) {
156 OSD_Environment csf(TCollection_AsciiString("CSF_USE_ARRAY_OF_PRIMITIVES"));
157 TCollection_AsciiString value = csf.Value();
158 enableArray = -1;
159 if( value.Length() > 0 ) {
160 if( value.IsIntegerValue() ) {
161 enableArray = value.IntegerValue();
162 if( enableArray > 1 ) {
163 enableArray = 1;
164 } else interleavedArray = Standard_False;
165 }
166 }
167#if TRACE > 0
168 if( enableArray > 0 ) {
169 if( interleavedArray )
170 cout << " ! ENABLE to use Interleaved arrays of primitives" << endl;
171 else
172 cout << " ! ENABLE to use Single arrays of primitives" << endl;
173 } else
174 cout << " ! DISABLE to use arrays of primitives" << endl;
175#endif
176 }
177 if( enableArray > 0 ) return Standard_True;
178
179 return Standard_False;
180}
181
182Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
183 const gp_Pnt& aVertice) {
184 Standard_Real x,y,z;
185 aVertice.Coord(x,y,z);
186 return AddVertex(x,y,z);
187}
188
189Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
190 const Standard_Real X, const Standard_Real Y, const Standard_Real Z) {
191
192 if( !myPrimitiveArray ) return 0;
193
194 Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
195 if( index > myMaxVertexs ) {
196 Standard_OutOfRange::Raise(" TOO many VERTEX");
197 }
198 SetVertice(index,X,Y,Z);
199 return index;
200}
201
202Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
203 const gp_Pnt& aVertice,
204 const Quantity_Color& aColor) {
205 Standard_Real x,y,z;
206 aVertice.Coord(x,y,z);
207 Standard_Integer index = AddVertex(x,y,z);
208 Standard_Real r,g,b;
209 aColor.Values(r,g,b,Quantity_TOC_RGB);
210 SetVertexColor(index,r,g,b);
211 return index;
212}
213Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
214 const gp_Pnt& aVertice,
215 const Standard_Integer aColor) {
216 Standard_Real x,y,z;
217 aVertice.Coord(x,y,z);
218 Standard_Integer index = AddVertex(x,y,z);
219 SetVertexColor(index,aColor);
220 return index;
221}
222
223
224Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
225 const gp_Pnt& aVertice,
226 const gp_Dir& aNormal) {
227 Standard_Real x,y,z;
228 aVertice.Coord(x,y,z);
229 Standard_Real nx,ny,nz;
230 aNormal.Coord(nx,ny,nz);
231 return AddVertex(x,y,z,nx,ny,nz);
232}
233
234Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
235 const Standard_Real X, const Standard_Real Y, const Standard_Real Z,
236 const Standard_Real NX, const Standard_Real NY, const Standard_Real NZ) {
237 if( !myPrimitiveArray ) return 0;
238
239 Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
240 if( index > myMaxVertexs ) {
241 Standard_OutOfRange::Raise(" TOO many VERTEX");
242 }
243 SetVertice(index,X,Y,Z);
244 SetVertexNormal(index,NX,NY,NZ);
245 return index;
246}
247
248
249Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
250 const gp_Pnt& aVertice,
251 const gp_Dir& aNormal,
252 const Quantity_Color& aColor) {
253 Standard_Real x,y,z;
254 aVertice.Coord(x,y,z);
255 Standard_Real nx,ny,nz;
256 aNormal.Coord(nx,ny,nz);
257 Standard_Integer index = AddVertex(x,y,z,nx,ny,nz);
258 Standard_Real r,g,b;
259 aColor.Values(r,g,b,Quantity_TOC_RGB);
260 SetVertexColor(index,r,g,b);
261 return index;
262}
263
264Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
265 const gp_Pnt& aVertice,
266 const gp_Dir& aNormal,
267 const Standard_Integer aColor) {
268 Standard_Real x,y,z;
269 aVertice.Coord(x,y,z);
270 Standard_Real nx,ny,nz;
271 aNormal.Coord(nx,ny,nz);
272 Standard_Integer index = AddVertex(x,y,z,nx,ny,nz);
273 SetVertexColor(index,aColor);
274 return index;
275}
276
277Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
278 const gp_Pnt& aVertice,
279 const gp_Pnt2d& aTexel) {
280 Standard_Real x,y,z;
281 aVertice.Coord(x,y,z);
282 Standard_Real tx,ty;
283 aTexel.Coord(tx,ty);
284 return AddVertex(x,y,z,tx,ty);
285}
286
287Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
288 const Standard_Real X, const Standard_Real Y, const Standard_Real Z,
289 const Standard_Real TX, const Standard_Real TY) {
290 if( !myPrimitiveArray ) return 0;
291
292 Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
293 if( index > myMaxVertexs ) {
294 Standard_OutOfRange::Raise(" TOO many VERTEX");
295 }
296 SetVertice(index,X,Y,Z);
297 SetVertexTexel(index,TX,TY);
298 return index;
299}
300
301Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
302 const gp_Pnt& aVertice,
303 const gp_Dir& aNormal,
304 const gp_Pnt2d& aTexel) {
305 Standard_Real x,y,z;
306 aVertice.Coord(x,y,z);
307 Standard_Real nx,ny,nz;
308 aNormal.Coord(nx,ny,nz);
309 Standard_Real tx,ty;
310 aTexel.Coord(tx,ty);
311 return AddVertex(x,y,z,nx,ny,nz,tx,ty);
312}
313
314Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
315 const Standard_Real X, const Standard_Real Y, const Standard_Real Z,
316 const Standard_Real NX, const Standard_Real NY, const Standard_Real NZ,
317 const Standard_Real TX, const Standard_Real TY) {
318 if( !myPrimitiveArray ) return 0;
319
320 Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
321 if( index > myMaxVertexs ) {
322 Standard_OutOfRange::Raise(" TOO many VERTEX");
323 }
324 SetVertice(index,X,Y,Z);
325 SetVertexNormal(index,NX,NY,NZ);
326 SetVertexTexel(index,TX,TY);
327 return index;
328}
329
330Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber) {
331 Standard_Integer index = 0;
332 if( myPrimitiveArray && myPrimitiveArray->bounds ) {
333 index = myPrimitiveArray->num_bounds;
334 if( index < myMaxBounds ) {
335 myPrimitiveArray->bounds[index] = edgeNumber;
336 myPrimitiveArray->num_bounds = ++index;
337 } else {
338 Standard_OutOfRange::Raise(" TOO many BOUNDS");
339 }
340 }
341
342 return index;
343}
344
345Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound(
346 const Standard_Integer edgeNumber,
347 const Quantity_Color& aFColor
348) {
349 Standard_Real r,g,b;
350 aFColor.Values(r,g,b,Quantity_TOC_RGB);
351 return AddBound(edgeNumber,r,g,b);
352}
353
354Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound(
355 const Standard_Integer edgeNumber,
356 const Standard_Real R,
357 const Standard_Real G,
358 const Standard_Real B) {
359 if( !myPrimitiveArray ) return 0;
360
361 Standard_Integer index = myPrimitiveArray->num_bounds;
362 if( index >= myMaxBounds ) {
363 Standard_OutOfRange::Raise(" TOO many BOUND");
364 }
365 myPrimitiveArray->bounds[index] = edgeNumber;
366 myPrimitiveArray->num_bounds = ++index;
367 SetBoundColor(index,R,G,B);
368 return index;
369}
370
371Standard_Integer Graphic3d_ArrayOfPrimitives::AddEdge(
372 const Standard_Integer vertexIndex,
373 const Standard_Boolean isVisible) {
374 if( !myPrimitiveArray ) return 0;
375
376 Standard_Integer index = myPrimitiveArray->num_edges;
377 if( index >= myMaxEdges ) {
378 Standard_OutOfRange::Raise(" TOO many EDGE");
379 }
380 Standard_Integer vindex = vertexIndex-1;
381 if( vertexIndex > 0 && vindex < myMaxVertexs ) {
382 myPrimitiveArray->edges[index] = vindex;
383 if( myPrimitiveArray->edge_vis ) {
384 myPrimitiveArray->edge_vis[index] = (Tchar) (isVisible ? 1 : 0);
385 }
386 myPrimitiveArray->num_edges = ++index;
387 } else {
388 Standard_OutOfRange::Raise(" BAD EDGE vertex index");
389 }
390
391 return index;
392}
393
394Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(
395 const gp_Dir& aNormal) {
396 return Orientate(1,Max(VertexNumber(),EdgeNumber()),aNormal);
397}
398
399Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(
400 const Standard_Integer aVertexIndex,
401 const Standard_Integer aVertexNumber,
402 const gp_Dir& aNormal) {
403 Standard_Boolean somethingHasChange = Standard_False;
404 if( myPrimitiveArray && (myPrimitiveArray->num_vertexs > 2) ) {
405 Standard_Integer i,j,k=aVertexNumber,n=aVertexIndex-1;
406 Standard_ShortReal x,y,z;
407 if( myPrimitiveArray->edges ) {
408 if( n >= 0 && (n+k) <= myPrimitiveArray->num_edges ) {
409 Standard_Integer i1 = myPrimitiveArray->edges[n];
410 Standard_Integer i2 = myPrimitiveArray->edges[n+1];
411 Standard_Integer i3 = myPrimitiveArray->edges[n+2];
412 gp_Pnt p1(myPrimitiveArray->vertices[i1].xyz[0],
413 myPrimitiveArray->vertices[i1].xyz[1],
414 myPrimitiveArray->vertices[i1].xyz[2]);
415 gp_Pnt p2(myPrimitiveArray->vertices[i2].xyz[0],
416 myPrimitiveArray->vertices[i2].xyz[1],
417 myPrimitiveArray->vertices[i2].xyz[2]);
418 gp_Pnt p3(myPrimitiveArray->vertices[i3].xyz[0],
419 myPrimitiveArray->vertices[i3].xyz[1],
420 myPrimitiveArray->vertices[i3].xyz[2]);
421 gp_Vec v21(p1,p2),v31(p1,p3),fn = v21.Crossed(v31);
422 if( aNormal.IsOpposite(fn,Standard_PI/4.) ) {
423 Standard_Integer e; char v;
424 for( i=0,j=k-1 ; i<k/2 ; i++,j-- ) {
425 e = myPrimitiveArray->edges[n+i];
426 myPrimitiveArray->edges[n+i] = myPrimitiveArray->edges[n+j];
427 myPrimitiveArray->edges[n+j] = e;
428 if( myPrimitiveArray->edge_vis ) {
429 v = myPrimitiveArray->edge_vis[n+i];
430 myPrimitiveArray->edge_vis[n+i] = myPrimitiveArray->edge_vis[n+j];
431 myPrimitiveArray->edge_vis[n+j] = v;
432 }
433 if( myPrimitiveArray->vnormals ) {
434 e = myPrimitiveArray->edges[n+i];
435 x = myPrimitiveArray->vnormals[e].xyz[0];
436 y = myPrimitiveArray->vnormals[e].xyz[1];
437 z = myPrimitiveArray->vnormals[e].xyz[2];
438 gp_Vec vn(x,y,z);
439 if( aNormal.IsOpposite(vn,Standard_PI/4.) ) {
440 myPrimitiveArray->vnormals[e].xyz[0] = -x;
441 myPrimitiveArray->vnormals[e].xyz[1] = -y;
442 myPrimitiveArray->vnormals[e].xyz[2] = -z;
443 }
444 }
445 }
446 somethingHasChange = Standard_True;
447 }
448 } else {
449 Standard_OutOfRange::Raise(" BAD EDGE index or number");
450 }
451 return somethingHasChange;
452 }
453
454 if( n >= 0 && (n+k) <= myPrimitiveArray->num_vertexs ) {
455 gp_Pnt p1(myPrimitiveArray->vertices[n].xyz[0],
456 myPrimitiveArray->vertices[n].xyz[1],
457 myPrimitiveArray->vertices[n].xyz[2]);
458 gp_Pnt p2(myPrimitiveArray->vertices[n+1].xyz[0],
459 myPrimitiveArray->vertices[n+1].xyz[1],
460 myPrimitiveArray->vertices[n+1].xyz[2]);
461 gp_Pnt p3(myPrimitiveArray->vertices[n+2].xyz[0],
462 myPrimitiveArray->vertices[n+2].xyz[1],
463 myPrimitiveArray->vertices[n+2].xyz[2]);
464 gp_Vec v21(p1,p2),v31(p1,p3),fn = v21.Crossed(v31);
465 if( aNormal.IsOpposite(fn,Standard_PI/4.) ) {
466 for( i=0,j=k-1 ; i<k/2 ; i++,j-- ) {
467 x = myPrimitiveArray->vertices[n+i].xyz[0];
468 y = myPrimitiveArray->vertices[n+i].xyz[1];
469 z = myPrimitiveArray->vertices[n+i].xyz[2];
470 myPrimitiveArray->vertices[n+i].xyz[0] = myPrimitiveArray->vertices[n+j].xyz[0];
471 myPrimitiveArray->vertices[n+i].xyz[1] = myPrimitiveArray->vertices[n+j].xyz[1];
472 myPrimitiveArray->vertices[n+i].xyz[2] = myPrimitiveArray->vertices[n+j].xyz[2];
473 myPrimitiveArray->vertices[n+j].xyz[0] = x;
474 myPrimitiveArray->vertices[n+j].xyz[1] = y;
475 myPrimitiveArray->vertices[n+j].xyz[2] = z;
476 if( myPrimitiveArray->vnormals ) {
477 x = myPrimitiveArray->vnormals[n+i].xyz[0];
478 y = myPrimitiveArray->vnormals[n+i].xyz[1];
479 z = myPrimitiveArray->vnormals[n+i].xyz[2];
480 myPrimitiveArray->vnormals[n+i].xyz[0] = myPrimitiveArray->vnormals[n+j].xyz[0];
481 myPrimitiveArray->vnormals[n+i].xyz[1] = myPrimitiveArray->vnormals[n+j].xyz[1];
482 myPrimitiveArray->vnormals[n+i].xyz[2] = myPrimitiveArray->vnormals[n+j].xyz[2];
483 myPrimitiveArray->vnormals[n+j].xyz[0] = x;
484 myPrimitiveArray->vnormals[n+j].xyz[1] = y;
485 myPrimitiveArray->vnormals[n+j].xyz[2] = z;
486
487 x = myPrimitiveArray->vnormals[n+i].xyz[0];
488 y = myPrimitiveArray->vnormals[n+i].xyz[1];
489 z = myPrimitiveArray->vnormals[n+i].xyz[2];
490 gp_Vec vn(x,y,z);
491 if( aNormal.IsOpposite(vn,Standard_PI/4.) ) {
492 myPrimitiveArray->vnormals[n+i].xyz[0] = -x;
493 myPrimitiveArray->vnormals[n+i].xyz[1] = -y;
494 myPrimitiveArray->vnormals[n+i].xyz[2] = -z;
495 }
496 }
497 if( myPrimitiveArray->vcolours ) {
498 x = (Standard_ShortReal)myPrimitiveArray->vcolours[n+i];
499 myPrimitiveArray->vcolours[n+i] = myPrimitiveArray->vcolours[n+j];
500 myPrimitiveArray->vcolours[n+j] = (Tint)x;
501 }
502 if( myPrimitiveArray->vtexels ) {
503 x = myPrimitiveArray->vtexels[n+i].xy[0];
504 y = myPrimitiveArray->vtexels[n+i].xy[1];
505 myPrimitiveArray->vtexels[n+i].xy[0] = myPrimitiveArray->vtexels[n+j].xy[0];
506 myPrimitiveArray->vtexels[n+i].xy[1] = myPrimitiveArray->vtexels[n+j].xy[1];
507 myPrimitiveArray->vtexels[n+j].xy[0] = x;
508 myPrimitiveArray->vtexels[n+j].xy[1] = y;
509 }
510 }
511 somethingHasChange = Standard_True;
512 }
513 }
514 }
515 return somethingHasChange;
516}
517
518Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(
519 const Standard_Integer aBoundIndex,
520 const gp_Dir& aNormal) {
521 Standard_Boolean somethingHasChange = Standard_False;
522 if( myPrimitiveArray && myPrimitiveArray->vertices ) {
523 if( myPrimitiveArray->bounds &&
524 (aBoundIndex > 0) && (aBoundIndex <= myPrimitiveArray->num_bounds) ) {
525 Standard_Integer k,n;
526 for( k=n=1 ; k<aBoundIndex ; k++ )
527 n += myPrimitiveArray->bounds[k];
528 k = myPrimitiveArray->bounds[aBoundIndex-1];
529 somethingHasChange = Orientate(n,k,aNormal);
530 } else if( myPrimitiveArray->bounds ) {
531 Standard_OutOfRange::Raise(" BAD BOUND index");
532 } else if( (aBoundIndex > 0) && (aBoundIndex <= ItemNumber()) ) {
533 switch( myPrimitiveArray->type ) {
534 case TelPointsArrayType:
535 case TelPolylinesArrayType:
536 case TelSegmentsArrayType:
537 break;
538 case TelPolygonsArrayType:
539 case TelTriangleStripsArrayType:
540 case TelTriangleFansArrayType:
541 case TelQuadrangleStripsArrayType:
542 somethingHasChange = Orientate(1,VertexNumber(),aNormal);
543 break;
544 case TelTrianglesArrayType:
545 somethingHasChange = Orientate(aBoundIndex*3-2,3,aNormal);
546 break;
547 case TelQuadranglesArrayType:
548 somethingHasChange = Orientate(aBoundIndex*4-3,4,aNormal);
549 break;
550 default:
551 break;
552 }
553 } else {
554 Standard_OutOfRange::Raise(" BAD ITEM index");
555 }
556 }
557 return somethingHasChange;
558}
559
560void Graphic3d_ArrayOfPrimitives::SetVertice(
561 const Standard_Integer anIndex,
562 const gp_Pnt& aVertice) {
563 Standard_Real x,y,z;
564 aVertice.Coord(x,y,z);
565 SetVertice(anIndex,x,y,z);
566}
567
568void Graphic3d_ArrayOfPrimitives::SetVertexColor(
569 const Standard_Integer anIndex,
570 const Quantity_Color& aColor) {
571 Standard_Real r,g,b;
572 aColor.Values(r,g,b,Quantity_TOC_RGB);
573 SetVertexColor(anIndex,r,g,b);
574}
575
576void Graphic3d_ArrayOfPrimitives::SetVertexColor(
577 const Standard_Integer anIndex,
578 const Standard_Integer aColor) {
579
580 if( !myPrimitiveArray ) return;
581 if( anIndex < 1 || anIndex > myMaxVertexs ) {
582 Standard_OutOfRange::Raise(" BAD VERTEX index");
583 }
584 Standard_Integer index = anIndex - 1;
585 if( myPrimitiveArray->vcolours ) {
586#if defined (sparc) || defined (__sparc__) || defined (__sparc)
587 /*
588 Well known processor(x86) architectures that use the little-endian format.
589 Processors use big-endian format is SPARC. In this case use platform with
590 SPARC architecture(SUNOS). Byte order could have little-endian format.
591 */
592 const char* p_ch = (const char*)&aColor;
593 myPrimitiveArray->vcolours[index] += p_ch[0];
594 myPrimitiveArray->vcolours[index] += p_ch[1] << 8 ;
595 myPrimitiveArray->vcolours[index] += p_ch[2] << 16;
596 myPrimitiveArray->vcolours[index] += p_ch[3] << 24;
597#else
598 myPrimitiveArray->vcolours[index] = aColor;
599#endif
600
601 }
602}
603void Graphic3d_ArrayOfPrimitives::SetVertexNormal(
604 const Standard_Integer anIndex,
605 const gp_Dir& aNormal) {
606 Standard_Real x,y,z;
607 aNormal.Coord(x,y,z);
608 SetVertexNormal(anIndex,x,y,z);
609}
610
611void Graphic3d_ArrayOfPrimitives::SetVertexTexel(
612 const Standard_Integer anIndex,
613 const gp_Pnt2d& aTexel) {
614 Standard_Real x,y;
615 aTexel.Coord(x,y);
616 SetVertexTexel(anIndex,x,y);
617}
618
619void Graphic3d_ArrayOfPrimitives::SetBoundColor(
620 const Standard_Integer anIndex,
621 const Quantity_Color& aColor) {
622 Standard_Real r,g,b;
623 aColor.Values(r,g,b,Quantity_TOC_RGB);
624 SetBoundColor(anIndex,r,g,b);
625}
626
627Standard_CString Graphic3d_ArrayOfPrimitives::StringType() const {
628 TCollection_AsciiString name("UndefinedArray");
629 switch( myPrimitiveArray->type ) {
630 case TelPointsArrayType:
631 name = "ArrayOfPoints";
632 break;
633 case TelPolylinesArrayType:
634 name = "ArrayOfPolylines";
635 break;
636 case TelSegmentsArrayType:
637 name = "ArrayOfSegments";
638 break;
639 case TelPolygonsArrayType:
640 name = "ArrayOfPolygons";
641 break;
642 case TelTrianglesArrayType:
643 name = "ArrayOfTriangles";
644 break;
645 case TelQuadranglesArrayType:
646 name = "ArrayOfQuadrangles";
647 break;
648 case TelTriangleStripsArrayType:
649 name = "ArrayOfTriangleStrips";
650 break;
651 case TelQuadrangleStripsArrayType:
652 name = "ArrayOfQuadrangleStrips";
653 break;
654 case TelTriangleFansArrayType:
655 name = "ArrayOfTriangleFans";
656 break;
657 default:
658 break;
659 }
660
661 return name.ToCString();
662}
663
664gp_Pnt Graphic3d_ArrayOfPrimitives::Vertice(const Standard_Integer aRank) const {
665 Standard_Real x,y,z;
666 Vertice(aRank,x,y,z);
667 return gp_Pnt(x,y,z);
668}
669
670Quantity_Color Graphic3d_ArrayOfPrimitives::VertexColor(const Standard_Integer aRank) const {
671 Standard_Real r,g,b;
672 VertexColor(aRank,r,g,b);
673 return Quantity_Color(r,g,b,Quantity_TOC_RGB);
674}
675
676gp_Dir Graphic3d_ArrayOfPrimitives::VertexNormal(const Standard_Integer aRank) const {
677 Standard_Real x,y,z;
678 VertexNormal(aRank,x,y,z);
679 return gp_Dir(x,y,z);
680}
681
682gp_Pnt2d Graphic3d_ArrayOfPrimitives::VertexTexel(const Standard_Integer aRank) const {
683 Standard_Real x,y;
684 VertexTexel(aRank,x,y);
685 return gp_Pnt2d(x,y);
686}
687
688Quantity_Color Graphic3d_ArrayOfPrimitives::BoundColor(const Standard_Integer aRank) const {
689 Standard_Real r,g,b;
690 BoundColor(aRank,r,g,b);
691 return Quantity_Color(r,g,b,Quantity_TOC_RGB);
692}
693
694Standard_Integer Graphic3d_ArrayOfPrimitives::ItemNumber() const {
695 Standard_Integer number=-1;
696 if( myPrimitiveArray ) switch( myPrimitiveArray->type ) {
697 case TelPointsArrayType:
698 number = myPrimitiveArray->num_vertexs;
699 break;
700 case TelPolylinesArrayType:
701 case TelPolygonsArrayType:
702 if( myPrimitiveArray->num_bounds > 0 )
703 number = myPrimitiveArray->num_bounds;
704 else number = 1;
705 break;
706 case TelSegmentsArrayType:
707 if( myPrimitiveArray->num_edges > 0 )
708 number = myPrimitiveArray->num_edges/2;
709 else number = myPrimitiveArray->num_vertexs/2;
710 break;
711 case TelTrianglesArrayType:
712 if( myPrimitiveArray->num_edges > 0 )
713 number = myPrimitiveArray->num_edges/3;
714 else number = myPrimitiveArray->num_vertexs/3;
715 break;
716 case TelQuadranglesArrayType:
717 if( myPrimitiveArray->num_edges > 0 )
718 number = myPrimitiveArray->num_edges/4;
719 else number = myPrimitiveArray->num_vertexs/4;
720 break;
721 case TelTriangleStripsArrayType:
722 if( myPrimitiveArray->num_bounds > 0 )
723 number = myPrimitiveArray->num_vertexs-2*myPrimitiveArray->num_bounds;
724 else number = myPrimitiveArray->num_vertexs-2;
725 break;
726 case TelQuadrangleStripsArrayType:
727 if( myPrimitiveArray->num_bounds > 0 )
728 number = myPrimitiveArray->num_vertexs/2-myPrimitiveArray->num_bounds;
729 else number = myPrimitiveArray->num_vertexs/2-1;
730 break;
731 case TelTriangleFansArrayType:
732 if( myPrimitiveArray->num_bounds > 0 )
733 number = myPrimitiveArray->num_vertexs-2*myPrimitiveArray->num_bounds;
734 else number = myPrimitiveArray->num_vertexs-2;
735 break;
736 default:
737 break;
738 }
739
740 return number;
741}
742
743void Graphic3d_ArrayOfPrimitives::ComputeVNormals(
744 const Standard_Integer from,
745 const Standard_Integer to) {
746 Standard_Integer next = from+1;
747 Standard_Integer last = to+1;
748 gp_Pnt p1,p2,p3;
749
750 if( myMaxEdges > 0 ) {
751 p1 = Vertice(Edge(next++));
752 p2 = Vertice(Edge(next++));
753 } else {
754 p1 = Vertice(next++);
755 p2 = Vertice(next++);
756 }
757
758 gp_Vec vn;
759
760 while ( next <= last ) {
761 if( myMaxEdges > 0 ) {
762 p3 = Vertice(Edge(next));
763 } else {
764 p3 = Vertice(next);
765 }
766 gp_Vec v21(p2,p1);
767 gp_Vec v31(p3,p1);
768 vn = v21 ^ v31;
769 if( vn.SquareMagnitude() > 0. ) break;
770 next++;
771 }
772
773 if( next > last ) {
774#if TRACE > 0
775 cout << " An item has a NULL computed facet normal" << endl;
776#endif
777 return;
778 }
779
780 vn.Normalize();
781 if( myMaxEdges > 0 ) {
782 for( int i=from+1 ; i<=to+1 ; i++ ) {
783 SetVertexNormal(Edge(i),vn);
784 }
785 } else {
786 for( int i=from+1 ; i<=to+1 ; i++ ) {
787 SetVertexNormal(i,vn);
788 }
789 }
790}
791
792Standard_Boolean Graphic3d_ArrayOfPrimitives::IsValid() {
793
794 if( !myPrimitiveArray ) return Standard_False;
795
796 Standard_Integer nvertexs = myPrimitiveArray->num_vertexs;
797 Standard_Integer nbounds = myPrimitiveArray->num_bounds;
798 Standard_Integer nedges = myPrimitiveArray->num_edges;
799 Standard_Integer i,j,k,n;
800
801#if TRACE > 0
802 Standard_CString name = StringType();
803 cout << " !!! An " << name << " has " << ItemNumber() << " items" << endl;
804#endif
805
806 switch( myPrimitiveArray->type ) {
807 case TelPointsArrayType:
808 if( nvertexs < 1 ) {
809#if TRACE > 0
810 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
811#endif
812 return Standard_False;
813 }
814 break;
815 case TelPolylinesArrayType:
816 if( nedges > 0 && nedges < 2 ) {
817#if TRACE > 0
818 cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
819#endif
820 return Standard_False;
821 }
822 if( nvertexs < 2 ) {
823#if TRACE > 0
824 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
825#endif
826 return Standard_False;
827 }
828 break;
829 case TelSegmentsArrayType:
830 if( nvertexs < 2 ) {
831#if TRACE > 0
832 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
833#endif
834 return Standard_False;
835 }
836 break;
837 case TelPolygonsArrayType:
838 if( nedges > 0 && nedges < 3 ) {
839#if TRACE > 0
840 cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
841#endif
842 return Standard_False;
843 }
844 if( nvertexs < 3 ) {
845#if TRACE > 0
846 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
847#endif
848 return Standard_False;
849 }
850 break;
851 case TelTrianglesArrayType:
852 if( nedges > 0 ) {
853 if( nedges < 3 || nedges % 3 != 0 ) {
854#if TRACE > 0
855 cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
856#endif
857 if( nedges > 3 ) myPrimitiveArray->num_edges = 3 * (nedges / 3);
858 else return Standard_False;
859 }
860 } else if( nvertexs < 3 || nvertexs % 3 != 0 ) {
861#if TRACE > 0
862 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
863#endif
864 if( nvertexs > 3 ) myPrimitiveArray->num_vertexs = 3 * (nvertexs / 3);
865 else return Standard_False;
866 }
867 break;
868 case TelQuadranglesArrayType:
869 if( nedges > 0 ) {
870 if( nedges < 4 || nedges % 4 != 0 ) {
871#if TRACE > 0
872 cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
873#endif
874 if( nedges > 4 ) myPrimitiveArray->num_edges = 4 * (nedges / 4);
875 else return Standard_False;
876 }
877 } else if( nvertexs < 4 || nvertexs % 4 != 0 ) {
878#if TRACE > 0
879 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
880#endif
881 if( nvertexs > 4 ) myPrimitiveArray->num_vertexs = 4 * (nvertexs / 4);
882 else return Standard_False;
883 }
884 break;
885 case TelTriangleFansArrayType:
886 case TelTriangleStripsArrayType:
887 if( nvertexs < 3 ) {
888#if TRACE > 0
889 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
890#endif
891 return Standard_False;
892 }
893 break;
894 case TelQuadrangleStripsArrayType:
895 if( nvertexs < 4 ) {
896#if TRACE > 0
897 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
898#endif
899 return Standard_False;
900 }
901 break;
902 default:
903#if TRACE > 0
904 cout << " *** UNKNOWN Array of primitives type found" << endl;
905#endif
906 return Standard_False;
907 }
908
909 if( nbounds > 0 ) {
910 for( i=n=0 ; i<nbounds ; i++ ) {
911 n += myPrimitiveArray->bounds[i];
912 }
913 if( nedges > 0 && n != nedges ) {
914#if TRACE > 0
915 cout << " *** An " << name << " has an incoherent number of edges " << nedges << endl;
916#endif
917 if( nedges > n ) myPrimitiveArray->num_edges = n;
918 else return Standard_False;
919 } else if( n != nvertexs ) {
920#if TRACE > 0
921 cout << " *** An " << name << " has an incoherent number of vertexs " << nvertexs << endl;
922#endif
923 if( nvertexs > n ) myPrimitiveArray->num_vertexs = n;
924 else return Standard_False;
925 }
926 }
927
928 if( nedges > 0 ) {
929 for( i=0 ; i<nedges ; i++ ) {
930 if( myPrimitiveArray->edges[i] >= myPrimitiveArray->num_vertexs ) {
931#if TRACE > 0
932 cout << " *** An " << name << " has a vertex index " << myPrimitiveArray->edges[i] << " greater than the number of defined vertexs " << myPrimitiveArray->num_vertexs << endl;
933#endif
934 myPrimitiveArray->edges[i] = myPrimitiveArray->num_vertexs-1;
935 }
936 }
937 }
938
939 Standard_Integer format;
940 Standard_Boolean valid = Standard_True;
941 for( i=0 ; i<nvertexs ; i++ ) {
942 format = myPrimitiveArray->format;
943 if( format != myPrimitiveArray->format ) {
944 valid = Standard_False;
945#if TRACE > 0
946 cout << " *** An " << name << " has an incoherent kind of vertexs "
947 << i+1 << " of type " << myPrimitiveArray->format << "/" << format << endl;
948#endif
949 break;
950 }
951 }
952
953 if( valid ) return Standard_True;
954
955 if( nbounds > 0 )
956 {
957 for( j=n=0 ; j<nbounds ; j++ )
958 {
959 k = myPrimitiveArray->bounds[j];
960 for( i=0 ; i<k ; i++ )
961 {
962 format = myPrimitiveArray->format;
963 if( format != myPrimitiveArray->format )
964 {
965 if( myPrimitiveArray->format & MVNORMAL ) switch( myPrimitiveArray->type )
966 {
967 case TelPolygonsArrayType:
968 if( i == 0 ) ComputeVNormals(n+i,n+k-1);
969 break;
970 case TelTrianglesArrayType:
971 if( !(i % 3) ) ComputeVNormals(n+i,n+i+2);
972 break;
973 case TelQuadranglesArrayType:
974 if( !(i % 4) ) ComputeVNormals(n+i,n+i+3);
975 break;
976 case TelTriangleFansArrayType:
977 case TelTriangleStripsArrayType:
978 if( i < k-2 ) ComputeVNormals(n+i,n+i+2);
979 else
980 break;
981 case TelQuadrangleStripsArrayType:
982 if( !(i %2) && (i < k-3) ) ComputeVNormals(n+i,n+i+3);
983 break;
984 default:
985 break;
986 }
987 }
988 }
989 n += myPrimitiveArray->bounds[j];
990 }
991 } else if( nedges > 0 ) {
992 for( i=0 ; i<nedges ; i++ ) {
993 k = myPrimitiveArray->edges[i];
994 format = myPrimitiveArray->format;
995 if( format != myPrimitiveArray->format ) {
996 if( myPrimitiveArray->format & MVNORMAL ) switch( myPrimitiveArray->type ) {
997 case TelPolygonsArrayType:
998 if( i == 0 ) ComputeVNormals(i,nedges-1);
999 break;
1000 case TelTrianglesArrayType:
1001 k = i/3*3;
1002 ComputeVNormals(k,k+2);
1003 break;
1004 case TelQuadranglesArrayType:
1005 k = i/4*4;
1006 ComputeVNormals(k,k+3);
1007 break;
1008 case TelTriangleFansArrayType:
1009 case TelTriangleStripsArrayType:
1010 if( i < nedges-2 ) ComputeVNormals(i,i+2);
1011 else
1012 break;
1013 case TelQuadrangleStripsArrayType:
1014 if( !(i %2) && (i < nedges-3) ) ComputeVNormals(i,i+3);
1015 break;
1016 default:
1017 break;
1018 }
1019 }
1020 }
1021 } else if( nvertexs > 0 ) {
1022 for( i=0 ; i<nvertexs ; i++ ) {
1023 format = myPrimitiveArray->format;
1024 if( format != myPrimitiveArray->format ) {
1025 if( myPrimitiveArray->format & MVNORMAL ) switch( myPrimitiveArray->type ) {
1026 case TelPolygonsArrayType:
1027 if( i == 0 ) ComputeVNormals(i,nvertexs-1);
1028 break;
1029 case TelTrianglesArrayType:
1030 if( !(i % 3) ) ComputeVNormals(i,i+2);
1031 break;
1032 case TelQuadranglesArrayType:
1033 if( !(i % 4) ) ComputeVNormals(i,i+3);
1034 break;
1035 case TelTriangleFansArrayType:
1036 case TelTriangleStripsArrayType:
1037 if( i < nvertexs-2 ) ComputeVNormals(i,i+2);
1038 else
1039 break;
1040 case TelQuadrangleStripsArrayType:
1041 if( !(i %2) && (i < nvertexs-3) ) ComputeVNormals(i,i+3);
1042 break;
1043 default:
1044 break;
1045 }
1046 }
1047 }
1048 }
1049
1050 return Standard_True;
1051}