Commit | Line | Data |
---|---|---|
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 | 25 | Graphic3d_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 | 97 | void 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 | 147 | Standard_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 | 155 | Standard_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 | |
164 | Standard_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 | 171 | Standard_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 | 181 | Standard_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 | 192 | Standard_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 | ||
201 | Standard_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 | ||
212 | Standard_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 | 225 | Standard_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 | 241 | Standard_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 | 249 | Standard_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 | 265 | Standard_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 | 288 | Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const gp_Dir& aNormal) |
289 | { | |
7fd59977 | 290 | return Orientate(1,Max(VertexNumber(),EdgeNumber()),aNormal); |
291 | } | |
292 | ||
b8ddfc2f | 293 | Standard_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 | 412 | Standard_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 | 454 | void 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 | 462 | void 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 | 470 | void 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 | |
497 | void 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 | 505 | void 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 | 513 | void 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 | 521 | Standard_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 | 559 | gp_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 | 566 | Quantity_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 | 573 | gp_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 | 580 | gp_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 | 587 | Quantity_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 | 594 | Standard_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 | 644 | void 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 | 693 | Standard_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 | } |