0024489: Avoid type casts in call to Standard::Free()
[occt.git] / src / Graphic3d / Graphic3d_ArrayOfPrimitives.cxx
CommitLineData
b311480e 1// Created on: 2000-06-16
973c2be1 2// Copyright (c) 2000-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
973c2be1 6// This library is free software; you can redistribute it and / or modify it
7// under the terms of the GNU Lesser General Public version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
15#define TRACE 0
16
17#include <Graphic3d_ArrayOfPrimitives.ixx>
18#include <Standard.hxx>
19#include <TCollection_AsciiString.hxx>
20#include <OSD_Environment.hxx>
21
22#include <stdio.h>
23#include <stdlib.h>
24
7fd59977 25Graphic3d_ArrayOfPrimitives :: Graphic3d_ArrayOfPrimitives (
26 const Graphic3d_TypeOfPrimitiveArray aType,
27 const Standard_Integer maxVertexs,
28 const Standard_Integer maxBounds,
29 const Standard_Integer maxEdges,
30 const Standard_Boolean hasVNormals,
31 const Standard_Boolean hasVColors,
32 const Standard_Boolean hasFColors,
33 const Standard_Boolean hasVTexels,
b8ddfc2f 34 const Standard_Boolean hasEdgeInfos )
35: myMaxBounds(0),myMaxVertexs(0),myMaxEdges(0)
36{
37 const Standard_Integer size = sizeof(CALL_DEF_PARRAY);
7fd59977 38 Standard_Integer format = MVERTICE;
39 if( hasVNormals ) format |= MVNORMAL;
40 if( hasVColors ) format |= MVCOLOR;
41 if( hasVTexels ) format |= MVTEXEL;
42
43 myPrimitiveArray = (Graphic3d_PrimitiveArray) Standard::Allocate(size);
44 memset ( myPrimitiveArray, 0, size );
45
46 if( maxVertexs > 0){
47 myPrimitiveArray->vertices = (TEL_POINT*) Standard::Allocate(maxVertexs *sizeof(TEL_POINT));
48 memset ( myPrimitiveArray->vertices, 0, maxVertexs *sizeof(TEL_POINT));
49 }
50
51 if( hasVNormals ){
52 myPrimitiveArray->vnormals = (TEL_POINT*) Standard::Allocate(sizeof(TEL_POINT) * maxVertexs);
53 memset ( myPrimitiveArray->vnormals, 0, sizeof(TEL_POINT) * maxVertexs);
54 }
55
56 if( hasVColors ){
57 myPrimitiveArray->vcolours = (Tint*) Standard::Allocate(maxVertexs *sizeof(Tint));
58 memset ( myPrimitiveArray->vcolours, 0, sizeof(Tint) * maxVertexs);
59 }
60
61 if( hasVTexels ){
62 myPrimitiveArray->vtexels = (TEL_TEXTURE_COORD*) Standard::Allocate(maxVertexs *sizeof(TEL_TEXTURE_COORD));
63 memset ( myPrimitiveArray->vtexels, 0, sizeof(TEL_TEXTURE_COORD) * maxVertexs);
64 }
65
66 if( hasFColors && (maxBounds > 0) ){
67 myPrimitiveArray->fcolours = (TEL_COLOUR*) Standard::Allocate(maxBounds *sizeof(TEL_COLOUR));
68 memset ( myPrimitiveArray->fcolours, 0, sizeof(TEL_COLOUR) * maxBounds);
69 }
70
71 if( maxBounds > 0 ){
72 myPrimitiveArray->bounds = (Tint*) Standard::Allocate(maxBounds *sizeof(Tint));
73 memset ( myPrimitiveArray->bounds, 0, maxBounds *sizeof(Tint));
74 }
75
76 if( maxEdges > 0 ){
77 myPrimitiveArray->edges = (Tint*) Standard::Allocate(maxEdges *sizeof(Tint));
78 memset ( myPrimitiveArray->edges, 0, maxEdges *sizeof(Tint));
79 }
80
81 if( hasEdgeInfos && (maxEdges > 0) ){
82 myPrimitiveArray->edge_vis = (Tchar*)Standard::Allocate(maxEdges *sizeof(Tchar));
83 memset ( myPrimitiveArray->edge_vis, 0, maxEdges *sizeof(Tchar));
84 }
85
86 myPrimitiveArray->keys = NULL;
87 myMaxVertexs = maxVertexs;
88 myMaxBounds = maxBounds;
89 myMaxEdges = maxEdges;
90 myPrimitiveArray->type = (TelPrimitivesArrayType) aType;
91 myPrimitiveArray->format = format;
92 myPrimitiveArray->num_bounds = 0;
93 myPrimitiveArray->num_vertexs = 0;
94 myPrimitiveArray->num_edges = 0;
7fd59977 95}
96
b8ddfc2f 97void Graphic3d_ArrayOfPrimitives::Destroy ()
98{
7fd59977 99 if( myPrimitiveArray ) {
100 if( myPrimitiveArray->vertices ){
547702a1 101 Standard::Free (myPrimitiveArray->vertices);
7fd59977 102 myPrimitiveArray->vertices = 0;
103 }
104
105 if( myPrimitiveArray->vnormals ){
547702a1 106 Standard::Free (myPrimitiveArray->vnormals);
7fd59977 107 myPrimitiveArray->vnormals = 0;
108 }
109
110 if( myPrimitiveArray->vcolours ){
547702a1 111 Standard::Free (myPrimitiveArray->vcolours);
7fd59977 112 myPrimitiveArray->vcolours = 0;
113 }
114
115 if( myPrimitiveArray->vtexels ){
547702a1 116 Standard::Free (myPrimitiveArray->vtexels);
7fd59977 117 myPrimitiveArray->vtexels = 0;
118 }
119
120 if( myPrimitiveArray->fcolours ){
547702a1 121 Standard::Free (myPrimitiveArray->fcolours);
7fd59977 122 myPrimitiveArray->fcolours = 0;
123 }
124
125 if( myPrimitiveArray->bounds ){
547702a1 126 Standard::Free (myPrimitiveArray->bounds);
7fd59977 127 myPrimitiveArray->bounds = 0;
128 }
129
130 if( myPrimitiveArray->edges ){
547702a1 131 Standard::Free (myPrimitiveArray->edges);
7fd59977 132 myPrimitiveArray->edges = 0;
133 }
134
135 if( myPrimitiveArray->edge_vis ){
547702a1 136 Standard::Free (myPrimitiveArray->edge_vis);
7fd59977 137 myPrimitiveArray->edge_vis = 0;
138 }
139
547702a1 140 Standard::Free (myPrimitiveArray);
7fd59977 141#if TRACE > 0
142 cout << " Graphic3d_ArrayOfPrimitives::Destroy()" << endl;
143#endif
144 }
145}
146
b8ddfc2f 147Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z)
148{
7fd59977 149 if( !myPrimitiveArray ) return 0;
b8ddfc2f 150 const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
7fd59977 151 SetVertice(index,X,Y,Z);
152 return index;
153}
154
b8ddfc2f 155Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice, const Quantity_Color& aColor)
156{
157 const Standard_Integer index = AddVertex(aVertice);
7fd59977 158 Standard_Real r,g,b;
159 aColor.Values(r,g,b,Quantity_TOC_RGB);
160 SetVertexColor(index,r,g,b);
161 return index;
162}
b8ddfc2f 163
164Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice, const Standard_Integer aColor)
165{
166 const Standard_Integer index = AddVertex(aVertice);
7fd59977 167 SetVertexColor(index,aColor);
168 return index;
169}
170
b8ddfc2f 171Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z,
172 const Standard_ShortReal NX, const Standard_ShortReal NY, const Standard_ShortReal NZ)
173{
7fd59977 174 if( !myPrimitiveArray ) return 0;
b8ddfc2f 175 const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
7fd59977 176 SetVertice(index,X,Y,Z);
177 SetVertexNormal(index,NX,NY,NZ);
178 return index;
179}
180
b8ddfc2f 181Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice,
7fd59977 182 const gp_Dir& aNormal,
b8ddfc2f 183 const Quantity_Color& aColor)
184{
185 const Standard_Integer index = AddVertex(aVertice,aNormal);
7fd59977 186 Standard_Real r,g,b;
187 aColor.Values(r,g,b,Quantity_TOC_RGB);
188 SetVertexColor(index,r,g,b);
189 return index;
190}
191
b8ddfc2f 192Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice,
7fd59977 193 const gp_Dir& aNormal,
b8ddfc2f 194 const Standard_Integer aColor)
195{
196 const Standard_Integer index = AddVertex(aVertice,aNormal);
7fd59977 197 SetVertexColor(index,aColor);
198 return index;
199}
200
201Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
b8ddfc2f 202 const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z,
203 const Standard_ShortReal TX, const Standard_ShortReal TY)
204{
7fd59977 205 if( !myPrimitiveArray ) return 0;
b8ddfc2f 206 const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
7fd59977 207 SetVertice(index,X,Y,Z);
208 SetVertexTexel(index,TX,TY);
209 return index;
210}
211
212Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
b8ddfc2f 213 const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z,
214 const Standard_ShortReal NX, const Standard_ShortReal NY, const Standard_ShortReal NZ,
215 const Standard_ShortReal TX, const Standard_ShortReal TY)
216{
7fd59977 217 if( !myPrimitiveArray ) return 0;
b8ddfc2f 218 const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
7fd59977 219 SetVertice(index,X,Y,Z);
220 SetVertexNormal(index,NX,NY,NZ);
221 SetVertexTexel(index,TX,TY);
222 return index;
223}
224
b8ddfc2f 225Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber)
226{
7fd59977 227 Standard_Integer index = 0;
228 if( myPrimitiveArray && myPrimitiveArray->bounds ) {
229 index = myPrimitiveArray->num_bounds;
230 if( index < myMaxBounds ) {
231 myPrimitiveArray->bounds[index] = edgeNumber;
232 myPrimitiveArray->num_bounds = ++index;
233 } else {
234 Standard_OutOfRange::Raise(" TOO many BOUNDS");
235 }
236 }
237
238 return index;
239}
240
b8ddfc2f 241Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber,
242 const Quantity_Color& aFColor)
243{
7fd59977 244 Standard_Real r,g,b;
245 aFColor.Values(r,g,b,Quantity_TOC_RGB);
246 return AddBound(edgeNumber,r,g,b);
247}
248
b8ddfc2f 249Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber,
7fd59977 250 const Standard_Real R,
251 const Standard_Real G,
b8ddfc2f 252 const Standard_Real B)
253{
7fd59977 254 if( !myPrimitiveArray ) return 0;
7fd59977 255 Standard_Integer index = myPrimitiveArray->num_bounds;
256 if( index >= myMaxBounds ) {
257 Standard_OutOfRange::Raise(" TOO many BOUND");
258 }
259 myPrimitiveArray->bounds[index] = edgeNumber;
260 myPrimitiveArray->num_bounds = ++index;
261 SetBoundColor(index,R,G,B);
262 return index;
263}
264
b8ddfc2f 265Standard_Integer Graphic3d_ArrayOfPrimitives::AddEdge(const Standard_Integer vertexIndex,
266 const Standard_Boolean isVisible)
267{
7fd59977 268 if( !myPrimitiveArray ) return 0;
269
270 Standard_Integer index = myPrimitiveArray->num_edges;
271 if( index >= myMaxEdges ) {
272 Standard_OutOfRange::Raise(" TOO many EDGE");
273 }
274 Standard_Integer vindex = vertexIndex-1;
275 if( vertexIndex > 0 && vindex < myMaxVertexs ) {
276 myPrimitiveArray->edges[index] = vindex;
277 if( myPrimitiveArray->edge_vis ) {
278 myPrimitiveArray->edge_vis[index] = (Tchar) (isVisible ? 1 : 0);
279 }
280 myPrimitiveArray->num_edges = ++index;
281 } else {
282 Standard_OutOfRange::Raise(" BAD EDGE vertex index");
283 }
284
285 return index;
286}
287
b8ddfc2f 288Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const gp_Dir& aNormal)
289{
7fd59977 290 return Orientate(1,Max(VertexNumber(),EdgeNumber()),aNormal);
291}
292
b8ddfc2f 293Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const Standard_Integer aVertexIndex,
7fd59977 294 const Standard_Integer aVertexNumber,
b8ddfc2f 295 const gp_Dir& aNormal)
296{
7fd59977 297 Standard_Boolean somethingHasChange = Standard_False;
298 if( myPrimitiveArray && (myPrimitiveArray->num_vertexs > 2) ) {
299 Standard_Integer i,j,k=aVertexNumber,n=aVertexIndex-1;
300 Standard_ShortReal x,y,z;
301 if( myPrimitiveArray->edges ) {
302 if( n >= 0 && (n+k) <= myPrimitiveArray->num_edges ) {
303 Standard_Integer i1 = myPrimitiveArray->edges[n];
304 Standard_Integer i2 = myPrimitiveArray->edges[n+1];
305 Standard_Integer i3 = myPrimitiveArray->edges[n+2];
306 gp_Pnt p1(myPrimitiveArray->vertices[i1].xyz[0],
307 myPrimitiveArray->vertices[i1].xyz[1],
308 myPrimitiveArray->vertices[i1].xyz[2]);
309 gp_Pnt p2(myPrimitiveArray->vertices[i2].xyz[0],
310 myPrimitiveArray->vertices[i2].xyz[1],
311 myPrimitiveArray->vertices[i2].xyz[2]);
312 gp_Pnt p3(myPrimitiveArray->vertices[i3].xyz[0],
313 myPrimitiveArray->vertices[i3].xyz[1],
314 myPrimitiveArray->vertices[i3].xyz[2]);
315 gp_Vec v21(p1,p2),v31(p1,p3),fn = v21.Crossed(v31);
c6541a0c 316 if( aNormal.IsOpposite(fn, M_PI / 4.) ) {
7fd59977 317 Standard_Integer e; char v;
318 for( i=0,j=k-1 ; i<k/2 ; i++,j-- ) {
319 e = myPrimitiveArray->edges[n+i];
320 myPrimitiveArray->edges[n+i] = myPrimitiveArray->edges[n+j];
321 myPrimitiveArray->edges[n+j] = e;
322 if( myPrimitiveArray->edge_vis ) {
323 v = myPrimitiveArray->edge_vis[n+i];
324 myPrimitiveArray->edge_vis[n+i] = myPrimitiveArray->edge_vis[n+j];
325 myPrimitiveArray->edge_vis[n+j] = v;
326 }
327 if( myPrimitiveArray->vnormals ) {
328 e = myPrimitiveArray->edges[n+i];
329 x = myPrimitiveArray->vnormals[e].xyz[0];
330 y = myPrimitiveArray->vnormals[e].xyz[1];
331 z = myPrimitiveArray->vnormals[e].xyz[2];
332 gp_Vec vn(x,y,z);
c6541a0c 333 if( aNormal.IsOpposite(vn, M_PI / 4.) ) {
7fd59977 334 myPrimitiveArray->vnormals[e].xyz[0] = -x;
335 myPrimitiveArray->vnormals[e].xyz[1] = -y;
336 myPrimitiveArray->vnormals[e].xyz[2] = -z;
337 }
338 }
339 }
340 somethingHasChange = Standard_True;
341 }
342 } else {
343 Standard_OutOfRange::Raise(" BAD EDGE index or number");
344 }
345 return somethingHasChange;
346 }
347
348 if( n >= 0 && (n+k) <= myPrimitiveArray->num_vertexs ) {
349 gp_Pnt p1(myPrimitiveArray->vertices[n].xyz[0],
350 myPrimitiveArray->vertices[n].xyz[1],
351 myPrimitiveArray->vertices[n].xyz[2]);
352 gp_Pnt p2(myPrimitiveArray->vertices[n+1].xyz[0],
353 myPrimitiveArray->vertices[n+1].xyz[1],
354 myPrimitiveArray->vertices[n+1].xyz[2]);
355 gp_Pnt p3(myPrimitiveArray->vertices[n+2].xyz[0],
356 myPrimitiveArray->vertices[n+2].xyz[1],
357 myPrimitiveArray->vertices[n+2].xyz[2]);
358 gp_Vec v21(p1,p2),v31(p1,p3),fn = v21.Crossed(v31);
c6541a0c 359 if( aNormal.IsOpposite(fn, M_PI / 4.) ) {
7fd59977 360 for( i=0,j=k-1 ; i<k/2 ; i++,j-- ) {
361 x = myPrimitiveArray->vertices[n+i].xyz[0];
362 y = myPrimitiveArray->vertices[n+i].xyz[1];
363 z = myPrimitiveArray->vertices[n+i].xyz[2];
364 myPrimitiveArray->vertices[n+i].xyz[0] = myPrimitiveArray->vertices[n+j].xyz[0];
365 myPrimitiveArray->vertices[n+i].xyz[1] = myPrimitiveArray->vertices[n+j].xyz[1];
366 myPrimitiveArray->vertices[n+i].xyz[2] = myPrimitiveArray->vertices[n+j].xyz[2];
367 myPrimitiveArray->vertices[n+j].xyz[0] = x;
368 myPrimitiveArray->vertices[n+j].xyz[1] = y;
369 myPrimitiveArray->vertices[n+j].xyz[2] = z;
370 if( myPrimitiveArray->vnormals ) {
371 x = myPrimitiveArray->vnormals[n+i].xyz[0];
372 y = myPrimitiveArray->vnormals[n+i].xyz[1];
373 z = myPrimitiveArray->vnormals[n+i].xyz[2];
374 myPrimitiveArray->vnormals[n+i].xyz[0] = myPrimitiveArray->vnormals[n+j].xyz[0];
375 myPrimitiveArray->vnormals[n+i].xyz[1] = myPrimitiveArray->vnormals[n+j].xyz[1];
376 myPrimitiveArray->vnormals[n+i].xyz[2] = myPrimitiveArray->vnormals[n+j].xyz[2];
377 myPrimitiveArray->vnormals[n+j].xyz[0] = x;
378 myPrimitiveArray->vnormals[n+j].xyz[1] = y;
379 myPrimitiveArray->vnormals[n+j].xyz[2] = z;
380
381 x = myPrimitiveArray->vnormals[n+i].xyz[0];
382 y = myPrimitiveArray->vnormals[n+i].xyz[1];
383 z = myPrimitiveArray->vnormals[n+i].xyz[2];
384 gp_Vec vn(x,y,z);
c6541a0c 385 if( aNormal.IsOpposite(vn, M_PI / 4.) ) {
7fd59977 386 myPrimitiveArray->vnormals[n+i].xyz[0] = -x;
387 myPrimitiveArray->vnormals[n+i].xyz[1] = -y;
388 myPrimitiveArray->vnormals[n+i].xyz[2] = -z;
389 }
390 }
391 if( myPrimitiveArray->vcolours ) {
392 x = (Standard_ShortReal)myPrimitiveArray->vcolours[n+i];
393 myPrimitiveArray->vcolours[n+i] = myPrimitiveArray->vcolours[n+j];
394 myPrimitiveArray->vcolours[n+j] = (Tint)x;
395 }
396 if( myPrimitiveArray->vtexels ) {
397 x = myPrimitiveArray->vtexels[n+i].xy[0];
398 y = myPrimitiveArray->vtexels[n+i].xy[1];
399 myPrimitiveArray->vtexels[n+i].xy[0] = myPrimitiveArray->vtexels[n+j].xy[0];
400 myPrimitiveArray->vtexels[n+i].xy[1] = myPrimitiveArray->vtexels[n+j].xy[1];
401 myPrimitiveArray->vtexels[n+j].xy[0] = x;
402 myPrimitiveArray->vtexels[n+j].xy[1] = y;
403 }
404 }
405 somethingHasChange = Standard_True;
406 }
407 }
408 }
409 return somethingHasChange;
410}
411
b8ddfc2f 412Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const Standard_Integer aBoundIndex,
413 const gp_Dir& aNormal)
414{
7fd59977 415 Standard_Boolean somethingHasChange = Standard_False;
416 if( myPrimitiveArray && myPrimitiveArray->vertices ) {
417 if( myPrimitiveArray->bounds &&
418 (aBoundIndex > 0) && (aBoundIndex <= myPrimitiveArray->num_bounds) ) {
419 Standard_Integer k,n;
420 for( k=n=1 ; k<aBoundIndex ; k++ )
421 n += myPrimitiveArray->bounds[k];
422 k = myPrimitiveArray->bounds[aBoundIndex-1];
423 somethingHasChange = Orientate(n,k,aNormal);
424 } else if( myPrimitiveArray->bounds ) {
425 Standard_OutOfRange::Raise(" BAD BOUND index");
426 } else if( (aBoundIndex > 0) && (aBoundIndex <= ItemNumber()) ) {
427 switch( myPrimitiveArray->type ) {
428 case TelPointsArrayType:
429 case TelPolylinesArrayType:
430 case TelSegmentsArrayType:
431 break;
432 case TelPolygonsArrayType:
433 case TelTriangleStripsArrayType:
434 case TelTriangleFansArrayType:
435 case TelQuadrangleStripsArrayType:
436 somethingHasChange = Orientate(1,VertexNumber(),aNormal);
437 break;
438 case TelTrianglesArrayType:
439 somethingHasChange = Orientate(aBoundIndex*3-2,3,aNormal);
440 break;
441 case TelQuadranglesArrayType:
442 somethingHasChange = Orientate(aBoundIndex*4-3,4,aNormal);
443 break;
444 default:
445 break;
446 }
447 } else {
448 Standard_OutOfRange::Raise(" BAD ITEM index");
449 }
450 }
451 return somethingHasChange;
452}
453
b8ddfc2f 454void Graphic3d_ArrayOfPrimitives::SetVertice( const Standard_Integer anIndex,
455 const gp_Pnt& aVertice)
456{
7fd59977 457 Standard_Real x,y,z;
458 aVertice.Coord(x,y,z);
b8ddfc2f 459 SetVertice(anIndex,Standard_ShortReal(x),Standard_ShortReal(y),Standard_ShortReal(z));
7fd59977 460}
461
b8ddfc2f 462void Graphic3d_ArrayOfPrimitives::SetVertexColor( const Standard_Integer anIndex,
463 const Quantity_Color& aColor)
464{
7fd59977 465 Standard_Real r,g,b;
466 aColor.Values(r,g,b,Quantity_TOC_RGB);
467 SetVertexColor(anIndex,r,g,b);
468}
469
b8ddfc2f 470void Graphic3d_ArrayOfPrimitives::SetVertexColor( const Standard_Integer anIndex,
471 const Standard_Integer aColor)
472{
7fd59977 473 if( !myPrimitiveArray ) return;
474 if( anIndex < 1 || anIndex > myMaxVertexs ) {
475 Standard_OutOfRange::Raise(" BAD VERTEX index");
476 }
477 Standard_Integer index = anIndex - 1;
478 if( myPrimitiveArray->vcolours ) {
479#if defined (sparc) || defined (__sparc__) || defined (__sparc)
480 /*
481 Well known processor(x86) architectures that use the little-endian format.
482 Processors use big-endian format is SPARC. In this case use platform with
483 SPARC architecture(SUNOS). Byte order could have little-endian format.
484 */
485 const char* p_ch = (const char*)&aColor;
486 myPrimitiveArray->vcolours[index] += p_ch[0];
487 myPrimitiveArray->vcolours[index] += p_ch[1] << 8 ;
488 myPrimitiveArray->vcolours[index] += p_ch[2] << 16;
489 myPrimitiveArray->vcolours[index] += p_ch[3] << 24;
490#else
491 myPrimitiveArray->vcolours[index] = aColor;
492#endif
493
494 }
495}
b8ddfc2f 496
497void Graphic3d_ArrayOfPrimitives::SetVertexNormal(const Standard_Integer anIndex,
498 const gp_Dir& aNormal)
499{
7fd59977 500 Standard_Real x,y,z;
501 aNormal.Coord(x,y,z);
502 SetVertexNormal(anIndex,x,y,z);
503}
504
b8ddfc2f 505void Graphic3d_ArrayOfPrimitives::SetVertexTexel( const Standard_Integer anIndex,
506 const gp_Pnt2d& aTexel)
507{
7fd59977 508 Standard_Real x,y;
509 aTexel.Coord(x,y);
510 SetVertexTexel(anIndex,x,y);
511}
512
b8ddfc2f 513void Graphic3d_ArrayOfPrimitives::SetBoundColor(const Standard_Integer anIndex,
514 const Quantity_Color& aColor)
515{
7fd59977 516 Standard_Real r,g,b;
517 aColor.Values(r,g,b,Quantity_TOC_RGB);
518 SetBoundColor(anIndex,r,g,b);
519}
520
b8ddfc2f 521Standard_CString Graphic3d_ArrayOfPrimitives::StringType() const
522{
7fd59977 523 TCollection_AsciiString name("UndefinedArray");
524 switch( myPrimitiveArray->type ) {
525 case TelPointsArrayType:
526 name = "ArrayOfPoints";
527 break;
528 case TelPolylinesArrayType:
529 name = "ArrayOfPolylines";
530 break;
531 case TelSegmentsArrayType:
532 name = "ArrayOfSegments";
533 break;
534 case TelPolygonsArrayType:
535 name = "ArrayOfPolygons";
536 break;
537 case TelTrianglesArrayType:
538 name = "ArrayOfTriangles";
539 break;
540 case TelQuadranglesArrayType:
541 name = "ArrayOfQuadrangles";
542 break;
543 case TelTriangleStripsArrayType:
544 name = "ArrayOfTriangleStrips";
545 break;
546 case TelQuadrangleStripsArrayType:
547 name = "ArrayOfQuadrangleStrips";
548 break;
549 case TelTriangleFansArrayType:
550 name = "ArrayOfTriangleFans";
551 break;
552 default:
553 break;
554 }
555
556 return name.ToCString();
557}
558
b8ddfc2f 559gp_Pnt Graphic3d_ArrayOfPrimitives::Vertice(const Standard_Integer aRank) const
560{
7fd59977 561 Standard_Real x,y,z;
562 Vertice(aRank,x,y,z);
563 return gp_Pnt(x,y,z);
564}
565
b8ddfc2f 566Quantity_Color Graphic3d_ArrayOfPrimitives::VertexColor(const Standard_Integer aRank) const
567{
7fd59977 568 Standard_Real r,g,b;
569 VertexColor(aRank,r,g,b);
570 return Quantity_Color(r,g,b,Quantity_TOC_RGB);
571}
572
b8ddfc2f 573gp_Dir Graphic3d_ArrayOfPrimitives::VertexNormal(const Standard_Integer aRank) const
574{
7fd59977 575 Standard_Real x,y,z;
576 VertexNormal(aRank,x,y,z);
577 return gp_Dir(x,y,z);
578}
579
b8ddfc2f 580gp_Pnt2d Graphic3d_ArrayOfPrimitives::VertexTexel(const Standard_Integer aRank) const
581{
7fd59977 582 Standard_Real x,y;
583 VertexTexel(aRank,x,y);
584 return gp_Pnt2d(x,y);
585}
586
b8ddfc2f 587Quantity_Color Graphic3d_ArrayOfPrimitives::BoundColor(const Standard_Integer aRank) const
588{
d20d815b 589 Standard_Real r = 0.0, g = 0.0, b = 0.0;
7fd59977 590 BoundColor(aRank,r,g,b);
591 return Quantity_Color(r,g,b,Quantity_TOC_RGB);
592}
593
b8ddfc2f 594Standard_Integer Graphic3d_ArrayOfPrimitives::ItemNumber() const
595{
7fd59977 596 Standard_Integer number=-1;
597 if( myPrimitiveArray ) switch( myPrimitiveArray->type ) {
598 case TelPointsArrayType:
599 number = myPrimitiveArray->num_vertexs;
600 break;
601 case TelPolylinesArrayType:
602 case TelPolygonsArrayType:
603 if( myPrimitiveArray->num_bounds > 0 )
604 number = myPrimitiveArray->num_bounds;
605 else number = 1;
606 break;
607 case TelSegmentsArrayType:
608 if( myPrimitiveArray->num_edges > 0 )
609 number = myPrimitiveArray->num_edges/2;
610 else number = myPrimitiveArray->num_vertexs/2;
611 break;
612 case TelTrianglesArrayType:
613 if( myPrimitiveArray->num_edges > 0 )
614 number = myPrimitiveArray->num_edges/3;
615 else number = myPrimitiveArray->num_vertexs/3;
616 break;
617 case TelQuadranglesArrayType:
618 if( myPrimitiveArray->num_edges > 0 )
619 number = myPrimitiveArray->num_edges/4;
620 else number = myPrimitiveArray->num_vertexs/4;
621 break;
622 case TelTriangleStripsArrayType:
623 if( myPrimitiveArray->num_bounds > 0 )
624 number = myPrimitiveArray->num_vertexs-2*myPrimitiveArray->num_bounds;
625 else number = myPrimitiveArray->num_vertexs-2;
626 break;
627 case TelQuadrangleStripsArrayType:
628 if( myPrimitiveArray->num_bounds > 0 )
629 number = myPrimitiveArray->num_vertexs/2-myPrimitiveArray->num_bounds;
630 else number = myPrimitiveArray->num_vertexs/2-1;
631 break;
632 case TelTriangleFansArrayType:
633 if( myPrimitiveArray->num_bounds > 0 )
634 number = myPrimitiveArray->num_vertexs-2*myPrimitiveArray->num_bounds;
635 else number = myPrimitiveArray->num_vertexs-2;
636 break;
637 default:
638 break;
639 }
640
641 return number;
642}
643
b8ddfc2f 644void Graphic3d_ArrayOfPrimitives::ComputeVNormals(const Standard_Integer from,
645 const Standard_Integer to)
646{
7fd59977 647 Standard_Integer next = from+1;
648 Standard_Integer last = to+1;
649 gp_Pnt p1,p2,p3;
650
651 if( myMaxEdges > 0 ) {
652 p1 = Vertice(Edge(next++));
653 p2 = Vertice(Edge(next++));
654 } else {
655 p1 = Vertice(next++);
656 p2 = Vertice(next++);
657 }
658
659 gp_Vec vn;
660
661 while ( next <= last ) {
662 if( myMaxEdges > 0 ) {
663 p3 = Vertice(Edge(next));
664 } else {
665 p3 = Vertice(next);
666 }
667 gp_Vec v21(p2,p1);
668 gp_Vec v31(p3,p1);
669 vn = v21 ^ v31;
670 if( vn.SquareMagnitude() > 0. ) break;
671 next++;
672 }
673
674 if( next > last ) {
675#if TRACE > 0
676 cout << " An item has a NULL computed facet normal" << endl;
677#endif
678 return;
679 }
680
681 vn.Normalize();
682 if( myMaxEdges > 0 ) {
683 for( int i=from+1 ; i<=to+1 ; i++ ) {
684 SetVertexNormal(Edge(i),vn);
685 }
686 } else {
687 for( int i=from+1 ; i<=to+1 ; i++ ) {
688 SetVertexNormal(i,vn);
689 }
690 }
691}
692
b8ddfc2f 693Standard_Boolean Graphic3d_ArrayOfPrimitives::IsValid()
694{
7fd59977 695 if( !myPrimitiveArray ) return Standard_False;
696
697 Standard_Integer nvertexs = myPrimitiveArray->num_vertexs;
698 Standard_Integer nbounds = myPrimitiveArray->num_bounds;
699 Standard_Integer nedges = myPrimitiveArray->num_edges;
6e6cd5d9 700 Standard_Integer i,n;
7fd59977 701
702#if TRACE > 0
703 Standard_CString name = StringType();
704 cout << " !!! An " << name << " has " << ItemNumber() << " items" << endl;
705#endif
706
707 switch( myPrimitiveArray->type ) {
708 case TelPointsArrayType:
709 if( nvertexs < 1 ) {
710#if TRACE > 0
711 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
712#endif
713 return Standard_False;
714 }
715 break;
716 case TelPolylinesArrayType:
717 if( nedges > 0 && nedges < 2 ) {
718#if TRACE > 0
719 cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
720#endif
721 return Standard_False;
722 }
723 if( nvertexs < 2 ) {
724#if TRACE > 0
725 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
726#endif
727 return Standard_False;
728 }
729 break;
730 case TelSegmentsArrayType:
731 if( nvertexs < 2 ) {
732#if TRACE > 0
733 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
734#endif
735 return Standard_False;
736 }
737 break;
738 case TelPolygonsArrayType:
739 if( nedges > 0 && nedges < 3 ) {
740#if TRACE > 0
741 cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
742#endif
743 return Standard_False;
744 }
745 if( nvertexs < 3 ) {
746#if TRACE > 0
747 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
748#endif
749 return Standard_False;
750 }
751 break;
752 case TelTrianglesArrayType:
753 if( nedges > 0 ) {
754 if( nedges < 3 || nedges % 3 != 0 ) {
755#if TRACE > 0
756 cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
757#endif
758 if( nedges > 3 ) myPrimitiveArray->num_edges = 3 * (nedges / 3);
759 else return Standard_False;
760 }
761 } else if( nvertexs < 3 || nvertexs % 3 != 0 ) {
762#if TRACE > 0
763 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
764#endif
765 if( nvertexs > 3 ) myPrimitiveArray->num_vertexs = 3 * (nvertexs / 3);
766 else return Standard_False;
767 }
768 break;
769 case TelQuadranglesArrayType:
770 if( nedges > 0 ) {
771 if( nedges < 4 || nedges % 4 != 0 ) {
772#if TRACE > 0
773 cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
774#endif
775 if( nedges > 4 ) myPrimitiveArray->num_edges = 4 * (nedges / 4);
776 else return Standard_False;
777 }
778 } else if( nvertexs < 4 || nvertexs % 4 != 0 ) {
779#if TRACE > 0
780 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
781#endif
782 if( nvertexs > 4 ) myPrimitiveArray->num_vertexs = 4 * (nvertexs / 4);
783 else return Standard_False;
784 }
785 break;
786 case TelTriangleFansArrayType:
787 case TelTriangleStripsArrayType:
788 if( nvertexs < 3 ) {
789#if TRACE > 0
790 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
791#endif
792 return Standard_False;
793 }
794 break;
795 case TelQuadrangleStripsArrayType:
796 if( nvertexs < 4 ) {
797#if TRACE > 0
798 cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
799#endif
800 return Standard_False;
801 }
802 break;
803 default:
804#if TRACE > 0
805 cout << " *** UNKNOWN Array of primitives type found" << endl;
806#endif
807 return Standard_False;
808 }
809
9558a876
A
810 // total number of edges(verticies) in bounds should be the same as variable
811 // of total number of defined edges(verticies); if no edges - only verticies
812 // could be in bounds.
7fd59977 813 if( nbounds > 0 ) {
814 for( i=n=0 ; i<nbounds ; i++ ) {
815 n += myPrimitiveArray->bounds[i];
816 }
817 if( nedges > 0 && n != nedges ) {
818#if TRACE > 0
819 cout << " *** An " << name << " has an incoherent number of edges " << nedges << endl;
820#endif
821 if( nedges > n ) myPrimitiveArray->num_edges = n;
822 else return Standard_False;
9558a876 823 } else if ( nedges == 0 && n != nvertexs ) {
7fd59977 824#if TRACE > 0
825 cout << " *** An " << name << " has an incoherent number of vertexs " << nvertexs << endl;
826#endif
827 if( nvertexs > n ) myPrimitiveArray->num_vertexs = n;
828 else return Standard_False;
829 }
830 }
831
9558a876 832 // check that edges (indexes to an array of verticies) are in range.
7fd59977 833 if( nedges > 0 ) {
834 for( i=0 ; i<nedges ; i++ ) {
835 if( myPrimitiveArray->edges[i] >= myPrimitiveArray->num_vertexs ) {
836#if TRACE > 0
837 cout << " *** An " << name << " has a vertex index " << myPrimitiveArray->edges[i] << " greater than the number of defined vertexs " << myPrimitiveArray->num_vertexs << endl;
838#endif
839 myPrimitiveArray->edges[i] = myPrimitiveArray->num_vertexs-1;
840 }
841 }
842 }
843
7fd59977 844 return Standard_True;
845}