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