Commit | Line | Data |
---|---|---|
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 | ||
14 | static Standard_Integer enableArray = 1; | |
15 | static Standard_Boolean interleavedArray = Standard_False; | |
16 | ||
17 | Graphic3d_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 | ||
96 | void 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 | ||
145 | void Graphic3d_ArrayOfPrimitives::Enable() { | |
146 | enableArray = 1; | |
147 | } | |
148 | ||
149 | void Graphic3d_ArrayOfPrimitives::Disable() { | |
150 | enableArray = -1; | |
151 | } | |
152 | ||
153 | Standard_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 | ||
182 | Standard_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 | ||
189 | Standard_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 | ||
202 | Standard_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 | } | |
213 | Standard_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 | ||
224 | Standard_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 | ||
234 | Standard_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 | ||
249 | Standard_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 | ||
264 | Standard_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 | ||
277 | Standard_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 | ||
287 | Standard_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 | ||
301 | Standard_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 | ||
314 | Standard_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 | ||
330 | Standard_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 | ||
345 | Standard_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 | ||
354 | Standard_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 | ||
371 | Standard_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 | ||
394 | Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate( | |
395 | const gp_Dir& aNormal) { | |
396 | return Orientate(1,Max(VertexNumber(),EdgeNumber()),aNormal); | |
397 | } | |
398 | ||
399 | Standard_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 | ||
518 | Standard_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 | ||
560 | void 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 | ||
568 | void 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 | ||
576 | void 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 | } | |
603 | void 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 | ||
611 | void 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 | ||
619 | void 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 | ||
627 | Standard_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 | ||
664 | gp_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 | ||
670 | Quantity_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 | ||
676 | gp_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 | ||
682 | gp_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 | ||
688 | Quantity_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 | ||
694 | Standard_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 | ||
743 | void 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 | ||
792 | Standard_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 | ||
9558a876 A |
909 | // total number of edges(verticies) in bounds should be the same as variable |
910 | // of total number of defined edges(verticies); if no edges - only verticies | |
911 | // could be in bounds. | |
7fd59977 | 912 | if( nbounds > 0 ) { |
913 | for( i=n=0 ; i<nbounds ; i++ ) { | |
914 | n += myPrimitiveArray->bounds[i]; | |
915 | } | |
916 | if( nedges > 0 && n != nedges ) { | |
917 | #if TRACE > 0 | |
918 | cout << " *** An " << name << " has an incoherent number of edges " << nedges << endl; | |
919 | #endif | |
920 | if( nedges > n ) myPrimitiveArray->num_edges = n; | |
921 | else return Standard_False; | |
9558a876 | 922 | } else if ( nedges == 0 && n != nvertexs ) { |
7fd59977 | 923 | #if TRACE > 0 |
924 | cout << " *** An " << name << " has an incoherent number of vertexs " << nvertexs << endl; | |
925 | #endif | |
926 | if( nvertexs > n ) myPrimitiveArray->num_vertexs = n; | |
927 | else return Standard_False; | |
928 | } | |
929 | } | |
930 | ||
9558a876 | 931 | // check that edges (indexes to an array of verticies) are in range. |
7fd59977 | 932 | if( nedges > 0 ) { |
933 | for( i=0 ; i<nedges ; i++ ) { | |
934 | if( myPrimitiveArray->edges[i] >= myPrimitiveArray->num_vertexs ) { | |
935 | #if TRACE > 0 | |
936 | cout << " *** An " << name << " has a vertex index " << myPrimitiveArray->edges[i] << " greater than the number of defined vertexs " << myPrimitiveArray->num_vertexs << endl; | |
937 | #endif | |
938 | myPrimitiveArray->edges[i] = myPrimitiveArray->num_vertexs-1; | |
939 | } | |
940 | } | |
941 | } | |
942 | ||
7fd59977 | 943 | return Standard_True; |
944 | } |