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 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
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 | |
59ec40f8 |
15 | #include <Graphic3d_ArrayOfPrimitives.hxx> |
42cf5bc1 |
16 | |
8e0a2b19 |
17 | #include <Graphic3d_ArrayOfPoints.hxx> |
18 | #include <Graphic3d_ArrayOfSegments.hxx> |
19 | #include <Graphic3d_ArrayOfPolylines.hxx> |
20 | #include <Graphic3d_ArrayOfTriangles.hxx> |
21 | #include <Graphic3d_ArrayOfTriangleStrips.hxx> |
22 | #include <Graphic3d_ArrayOfTriangleFans.hxx> |
23 | #include <Graphic3d_ArrayOfQuadrangles.hxx> |
24 | #include <Graphic3d_ArrayOfQuadrangleStrips.hxx> |
25 | #include <Graphic3d_ArrayOfPolygons.hxx> |
26 | |
42cf5bc1 |
27 | #include <NCollection_AlignedAllocator.hxx> |
7fd59977 |
28 | #include <TCollection_AsciiString.hxx> |
7fd59977 |
29 | |
30 | #include <stdio.h> |
31 | #include <stdlib.h> |
92efcf78 |
32 | |
7379f442 |
33 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPrimitives, Standard_Transient) |
34 | |
8e0a2b19 |
35 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPoints, Graphic3d_ArrayOfPrimitives) |
36 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfSegments, Graphic3d_ArrayOfPrimitives) |
37 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPolylines, Graphic3d_ArrayOfPrimitives) |
38 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfTriangles, Graphic3d_ArrayOfPrimitives) |
39 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfTriangleStrips, Graphic3d_ArrayOfPrimitives) |
40 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfTriangleFans, Graphic3d_ArrayOfPrimitives) |
41 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfQuadrangles, Graphic3d_ArrayOfPrimitives) |
42 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfQuadrangleStrips, Graphic3d_ArrayOfPrimitives) |
43 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPolygons, Graphic3d_ArrayOfPrimitives) |
44 | |
7379f442 |
45 | // ======================================================================= |
34253146 |
46 | // function : init |
7379f442 |
47 | // purpose : |
48 | // ======================================================================= |
34253146 |
49 | void Graphic3d_ArrayOfPrimitives::init (Graphic3d_TypeOfPrimitiveArray theType, |
50 | Standard_Integer theMaxVertexs, |
51 | Standard_Integer theMaxBounds, |
52 | Standard_Integer theMaxEdges, |
53 | Graphic3d_ArrayFlags theArrayOptions) |
871fa103 |
54 | { |
34253146 |
55 | myType = theType; |
56 | myVNor = 0; |
57 | myVTex = 0; |
58 | myVCol = 0; |
59 | myAttribs.Nullify(); |
60 | myIndices.Nullify(); |
61 | myBounds.Nullify(); |
62 | |
871fa103 |
63 | Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16); |
64 | myAttribs = new Graphic3d_Buffer (anAlloc); |
65 | if (theMaxVertexs < 1) |
66 | { |
67 | return; |
7fd59977 |
68 | } |
69 | |
871fa103 |
70 | if (theMaxEdges > 0) |
71 | { |
72 | myIndices = new Graphic3d_IndexBuffer (anAlloc); |
09f30297 |
73 | if (theMaxVertexs < Standard_Integer(USHRT_MAX)) |
871fa103 |
74 | { |
75 | if (!myIndices->Init<unsigned short> (theMaxEdges)) |
76 | { |
77 | myIndices.Nullify(); |
78 | return; |
79 | } |
80 | } |
81 | else |
82 | { |
83 | if (!myIndices->Init<unsigned int> (theMaxEdges)) |
84 | { |
85 | myIndices.Nullify(); |
86 | return; |
87 | } |
88 | } |
89 | myIndices->NbElements = 0; |
7fd59977 |
90 | } |
91 | |
871fa103 |
92 | Graphic3d_Attribute anAttribs[4]; |
93 | Standard_Integer aNbAttribs = 0; |
94 | anAttribs[aNbAttribs].Id = Graphic3d_TOA_POS; |
95 | anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3; |
96 | ++aNbAttribs; |
34253146 |
97 | if ((theArrayOptions & Graphic3d_ArrayFlags_VertexNormal) != 0) |
871fa103 |
98 | { |
99 | anAttribs[aNbAttribs].Id = Graphic3d_TOA_NORM; |
100 | anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3; |
101 | ++aNbAttribs; |
7fd59977 |
102 | } |
34253146 |
103 | if ((theArrayOptions & Graphic3d_ArrayFlags_VertexTexel) != 0) |
871fa103 |
104 | { |
105 | anAttribs[aNbAttribs].Id = Graphic3d_TOA_UV; |
106 | anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC2; |
107 | ++aNbAttribs; |
7fd59977 |
108 | } |
34253146 |
109 | if ((theArrayOptions & Graphic3d_ArrayFlags_VertexColor) != 0) |
871fa103 |
110 | { |
111 | anAttribs[aNbAttribs].Id = Graphic3d_TOA_COLOR; |
112 | anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC4UB; |
113 | ++aNbAttribs; |
7fd59977 |
114 | } |
115 | |
871fa103 |
116 | if (!myAttribs->Init (theMaxVertexs, anAttribs, aNbAttribs)) |
117 | { |
118 | myAttribs.Nullify(); |
119 | myIndices.Nullify(); |
120 | return; |
7fd59977 |
121 | } |
34253146 |
122 | myAttribs->NbElements = 0; |
123 | memset (myAttribs->ChangeData (0), 0, size_t(myAttribs->Stride) * size_t(myAttribs->NbMaxElements())); |
871fa103 |
124 | |
125 | if (theMaxBounds > 0) |
126 | { |
127 | myBounds = new Graphic3d_BoundBuffer (anAlloc); |
34253146 |
128 | if (!myBounds->Init (theMaxBounds, (theArrayOptions & Graphic3d_ArrayFlags_BoundColor) != 0)) |
871fa103 |
129 | { |
130 | myAttribs.Nullify(); |
131 | myIndices.Nullify(); |
132 | myBounds .Nullify(); |
133 | return; |
7fd59977 |
134 | } |
871fa103 |
135 | myBounds->NbBounds = 0; |
136 | } |
7fd59977 |
137 | |
871fa103 |
138 | for (Standard_Integer anAttribIter = 0; anAttribIter < aNbAttribs; ++anAttribIter) |
139 | { |
140 | const Graphic3d_Attribute& anAttrib = anAttribs[anAttribIter]; |
141 | switch (anAttrib.Id) |
142 | { |
143 | case Graphic3d_TOA_POS: |
144 | case Graphic3d_TOA_CUSTOM: |
145 | break; |
146 | case Graphic3d_TOA_NORM: |
147 | { |
148 | myVNor = static_cast<Standard_Byte>(myAttribs->AttributeOffset (anAttribIter)); |
149 | break; |
150 | } |
151 | case Graphic3d_TOA_UV: |
152 | { |
153 | myVTex = static_cast<Standard_Byte>(myAttribs->AttributeOffset (anAttribIter)); |
154 | break; |
155 | } |
156 | case Graphic3d_TOA_COLOR: |
157 | { |
158 | myVCol = static_cast<Standard_Byte>(myAttribs->AttributeOffset (anAttribIter)); |
159 | break; |
160 | } |
7fd59977 |
161 | } |
7fd59977 |
162 | } |
7fd59977 |
163 | } |
164 | |
7379f442 |
165 | // ======================================================================= |
166 | // function : ~Graphic3d_ArrayOfPrimitives |
167 | // purpose : |
168 | // ======================================================================= |
169 | Graphic3d_ArrayOfPrimitives::~Graphic3d_ArrayOfPrimitives() |
b8ddfc2f |
170 | { |
871fa103 |
171 | myVNor = 0; |
172 | myVTex = 0; |
173 | myVCol = 0; |
174 | myIndices.Nullify(); |
175 | myAttribs.Nullify(); |
176 | myBounds .Nullify(); |
7fd59977 |
177 | } |
b8ddfc2f |
178 | |
7379f442 |
179 | // ======================================================================= |
180 | // function : AddBound |
181 | // purpose : |
182 | // ======================================================================= |
871fa103 |
183 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber) |
b8ddfc2f |
184 | { |
34253146 |
185 | Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->NbBounds >= myBounds->NbMaxBounds, "TOO many BOUND"); |
186 | myBounds->Bounds[myBounds->NbBounds] = theEdgeNumber; |
187 | return ++myBounds->NbBounds; |
7fd59977 |
188 | } |
189 | |
7379f442 |
190 | // ======================================================================= |
191 | // function : AddBound |
192 | // purpose : |
193 | // ======================================================================= |
871fa103 |
194 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber, |
195 | const Standard_Real theR, |
196 | const Standard_Real theG, |
197 | const Standard_Real theB) |
b8ddfc2f |
198 | { |
34253146 |
199 | Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->NbBounds >= myBounds->NbMaxBounds, "TOO many BOUND"); |
200 | myBounds->Bounds[myBounds->NbBounds] = theEdgeNumber; |
201 | ++myBounds->NbBounds; |
202 | SetBoundColor (myBounds->NbBounds, theR, theG, theB); |
203 | return myBounds->NbBounds; |
7fd59977 |
204 | } |
205 | |
7379f442 |
206 | // ======================================================================= |
207 | // function : AddEdge |
208 | // purpose : |
209 | // ======================================================================= |
871fa103 |
210 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddEdge (const Standard_Integer theVertexIndex) |
b8ddfc2f |
211 | { |
34253146 |
212 | Standard_OutOfRange_Raise_if (myIndices.IsNull() || myIndices->NbElements >= myIndices->NbMaxElements(), "TOO many EDGE"); |
213 | Standard_OutOfRange_Raise_if (theVertexIndex < 1 || theVertexIndex > myAttribs->NbElements, "BAD VERTEX index"); |
214 | const Standard_Integer aVertIndex = theVertexIndex - 1; |
215 | myIndices->SetIndex (myIndices->NbElements, aVertIndex); |
216 | return ++myIndices->NbElements; |
7fd59977 |
217 | } |
218 | |
7379f442 |
219 | // ======================================================================= |
220 | // function : StringType |
221 | // purpose : |
222 | // ======================================================================= |
b8ddfc2f |
223 | Standard_CString Graphic3d_ArrayOfPrimitives::StringType() const |
224 | { |
871fa103 |
225 | switch (myType) |
226 | { |
227 | case Graphic3d_TOPA_POINTS: return "ArrayOfPoints"; |
871fa103 |
228 | case Graphic3d_TOPA_SEGMENTS: return "ArrayOfSegments"; |
8e0a2b19 |
229 | case Graphic3d_TOPA_POLYLINES: return "ArrayOfPolylines"; |
871fa103 |
230 | case Graphic3d_TOPA_TRIANGLES: return "ArrayOfTriangles"; |
871fa103 |
231 | case Graphic3d_TOPA_TRIANGLESTRIPS: return "ArrayOfTriangleStrips"; |
871fa103 |
232 | case Graphic3d_TOPA_TRIANGLEFANS: return "ArrayOfTriangleFans"; |
8e0a2b19 |
233 | case Graphic3d_TOPA_LINES_ADJACENCY: return "ArrayOfLinesAdjacency"; |
234 | case Graphic3d_TOPA_LINE_STRIP_ADJACENCY: return "ArrayOfLineStripAdjacency"; |
235 | case Graphic3d_TOPA_TRIANGLES_ADJACENCY: return "ArrayOfTrianglesAdjacency"; |
236 | case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY: return "ArrayOfTriangleStripAdjacency"; |
237 | case Graphic3d_TOPA_QUADRANGLES: return "ArrayOfQuadrangles"; |
238 | case Graphic3d_TOPA_QUADRANGLESTRIPS: return "ArrayOfQuadrangleStrips"; |
239 | case Graphic3d_TOPA_POLYGONS: return "ArrayOfPolygons"; |
871fa103 |
240 | case Graphic3d_TOPA_UNDEFINED: return "UndefinedArray"; |
7fd59977 |
241 | } |
871fa103 |
242 | return "UndefinedArray"; |
7fd59977 |
243 | } |
244 | |
7379f442 |
245 | // ======================================================================= |
246 | // function : ItemNumber |
247 | // purpose : |
248 | // ======================================================================= |
b8ddfc2f |
249 | Standard_Integer Graphic3d_ArrayOfPrimitives::ItemNumber() const |
250 | { |
871fa103 |
251 | if (myAttribs.IsNull()) |
252 | { |
253 | return -1; |
7fd59977 |
254 | } |
255 | |
871fa103 |
256 | switch (myType) |
257 | { |
258 | case Graphic3d_TOPA_POINTS: return myAttribs->NbElements; |
259 | case Graphic3d_TOPA_POLYLINES: |
260 | case Graphic3d_TOPA_POLYGONS: return !myBounds.IsNull() ? myBounds->NbBounds : 1; |
261 | case Graphic3d_TOPA_SEGMENTS: return myIndices.IsNull() || myIndices->NbElements < 1 |
262 | ? myAttribs->NbElements / 2 |
263 | : myIndices->NbElements / 2; |
264 | case Graphic3d_TOPA_TRIANGLES: return myIndices.IsNull() || myIndices->NbElements < 1 |
265 | ? myAttribs->NbElements / 3 |
266 | : myIndices->NbElements / 3; |
267 | case Graphic3d_TOPA_QUADRANGLES: return myIndices.IsNull() || myIndices->NbElements < 1 |
268 | ? myAttribs->NbElements / 4 |
269 | : myIndices->NbElements / 4; |
270 | case Graphic3d_TOPA_TRIANGLESTRIPS: return !myBounds.IsNull() |
271 | ? myAttribs->NbElements - 2 * myBounds->NbBounds |
272 | : myAttribs->NbElements - 2; |
273 | case Graphic3d_TOPA_QUADRANGLESTRIPS: return !myBounds.IsNull() |
274 | ? myAttribs->NbElements / 2 - myBounds->NbBounds |
275 | : myAttribs->NbElements / 2 - 1; |
276 | case Graphic3d_TOPA_TRIANGLEFANS: return !myBounds.IsNull() |
277 | ? myAttribs->NbElements - 2 * myBounds->NbBounds |
278 | : myAttribs->NbElements - 2; |
8e0a2b19 |
279 | case Graphic3d_TOPA_LINES_ADJACENCY: return myIndices.IsNull() || myIndices->NbElements < 1 |
280 | ? myAttribs->NbElements / 4 |
281 | : myIndices->NbElements / 4; |
282 | case Graphic3d_TOPA_LINE_STRIP_ADJACENCY: return !myBounds.IsNull() |
283 | ? myAttribs->NbElements - 4 * myBounds->NbBounds |
284 | : myAttribs->NbElements - 4; |
285 | case Graphic3d_TOPA_TRIANGLES_ADJACENCY: return myIndices.IsNull() || myIndices->NbElements < 1 |
286 | ? myAttribs->NbElements / 6 |
287 | : myIndices->NbElements / 6; |
288 | case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY: return !myBounds.IsNull() |
289 | ? myAttribs->NbElements - 4 * myBounds->NbBounds |
290 | : myAttribs->NbElements - 4; |
871fa103 |
291 | case Graphic3d_TOPA_UNDEFINED: return -1; |
292 | } |
293 | return -1; |
7fd59977 |
294 | } |
295 | |
7379f442 |
296 | // ======================================================================= |
297 | // function : IsValid |
298 | // purpose : |
299 | // ======================================================================= |
b8ddfc2f |
300 | Standard_Boolean Graphic3d_ArrayOfPrimitives::IsValid() |
301 | { |
871fa103 |
302 | if (myAttribs.IsNull()) |
303 | { |
304 | return Standard_False; |
305 | } |
306 | |
307 | Standard_Integer nvertexs = myAttribs->NbElements; |
308 | Standard_Integer nbounds = myBounds.IsNull() ? 0 : myBounds->NbBounds; |
309 | Standard_Integer nedges = myIndices.IsNull() ? 0 : myIndices->NbElements; |
310 | switch (myType) |
311 | { |
312 | case Graphic3d_TOPA_POINTS: |
313 | if (nvertexs < 1) |
314 | { |
7fd59977 |
315 | return Standard_False; |
316 | } |
317 | break; |
871fa103 |
318 | case Graphic3d_TOPA_POLYLINES: |
319 | if (nedges > 0 |
320 | && nedges < 2) |
321 | { |
7fd59977 |
322 | return Standard_False; |
323 | } |
871fa103 |
324 | if (nvertexs < 2) |
325 | { |
7fd59977 |
326 | return Standard_False; |
327 | } |
328 | break; |
871fa103 |
329 | case Graphic3d_TOPA_SEGMENTS: |
330 | if (nvertexs < 2) |
331 | { |
7fd59977 |
332 | return Standard_False; |
333 | } |
334 | break; |
871fa103 |
335 | case Graphic3d_TOPA_POLYGONS: |
336 | if (nedges > 0 |
337 | && nedges < 3) |
338 | { |
7fd59977 |
339 | return Standard_False; |
340 | } |
871fa103 |
341 | if (nvertexs < 3) |
342 | { |
7fd59977 |
343 | return Standard_False; |
344 | } |
345 | break; |
871fa103 |
346 | case Graphic3d_TOPA_TRIANGLES: |
347 | if (nedges > 0) |
348 | { |
349 | if (nedges < 3 |
350 | || nedges % 3 != 0) |
351 | { |
352 | if (nedges <= 3) |
353 | { |
354 | return Standard_False; |
355 | } |
356 | myIndices->NbElements = 3 * (nedges / 3); |
357 | } |
358 | } |
359 | else if (nvertexs < 3 |
360 | || nvertexs % 3 != 0 ) |
361 | { |
362 | if (nvertexs <= 3) |
363 | { |
364 | return Standard_False; |
7fd59977 |
365 | } |
871fa103 |
366 | myAttribs->NbElements = 3 * (nvertexs / 3); |
7fd59977 |
367 | } |
368 | break; |
871fa103 |
369 | case Graphic3d_TOPA_QUADRANGLES: |
370 | if (nedges > 0) |
371 | { |
372 | if (nedges < 4 |
373 | || nedges % 4 != 0) |
374 | { |
375 | if (nedges <= 4) |
376 | { |
377 | return Standard_False; |
378 | } |
379 | myIndices->NbElements = 4 * (nedges / 4); |
380 | } |
381 | } |
382 | else if (nvertexs < 4 |
383 | || nvertexs % 4 != 0) |
384 | { |
385 | if (nvertexs <= 4) |
386 | { |
387 | return Standard_False; |
7fd59977 |
388 | } |
871fa103 |
389 | myAttribs->NbElements = 4 * (nvertexs / 4); |
7fd59977 |
390 | } |
391 | break; |
871fa103 |
392 | case Graphic3d_TOPA_TRIANGLEFANS: |
393 | case Graphic3d_TOPA_TRIANGLESTRIPS: |
394 | if (nvertexs < 3) |
395 | { |
7fd59977 |
396 | return Standard_False; |
397 | } |
398 | break; |
871fa103 |
399 | case Graphic3d_TOPA_QUADRANGLESTRIPS: |
400 | if (nvertexs < 4) |
401 | { |
7fd59977 |
402 | return Standard_False; |
403 | } |
404 | break; |
8e0a2b19 |
405 | case Graphic3d_TOPA_LINES_ADJACENCY: |
406 | case Graphic3d_TOPA_LINE_STRIP_ADJACENCY: |
407 | if (nvertexs < 4) |
408 | { |
409 | return Standard_False; |
410 | } |
411 | break; |
412 | case Graphic3d_TOPA_TRIANGLES_ADJACENCY: |
413 | case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY: |
414 | if (nvertexs < 6) |
415 | { |
416 | return Standard_False; |
417 | } |
418 | break; |
871fa103 |
419 | case Graphic3d_TOPA_UNDEFINED: |
7fd59977 |
420 | default: |
7fd59977 |
421 | return Standard_False; |
422 | } |
423 | |
871fa103 |
424 | // total number of edges(vertices) in bounds should be the same as variable |
425 | // of total number of defined edges(vertices); if no edges - only vertices |
9558a876 |
426 | // could be in bounds. |
871fa103 |
427 | if (nbounds > 0) |
428 | { |
429 | Standard_Integer n = 0; |
430 | for (Standard_Integer aBoundIter = 0; aBoundIter < nbounds; ++aBoundIter) |
431 | { |
432 | n += myBounds->Bounds[aBoundIter]; |
7fd59977 |
433 | } |
871fa103 |
434 | if (nedges > 0 |
435 | && n != nedges) |
436 | { |
437 | if (nedges <= n) |
438 | { |
439 | return Standard_False; |
440 | } |
441 | myIndices->NbElements = n; |
442 | } |
443 | else if (nedges == 0 |
444 | && n != nvertexs) |
445 | { |
446 | if (nvertexs <= n) |
447 | { |
448 | return Standard_False; |
449 | } |
450 | myAttribs->NbElements = n; |
7fd59977 |
451 | } |
452 | } |
453 | |
871fa103 |
454 | // check that edges (indexes to an array of vertices) are in range. |
455 | if (nedges > 0) |
456 | { |
457 | for (Standard_Integer anEdgeIter = 0; anEdgeIter < nedges; ++anEdgeIter) |
458 | { |
459 | if (myIndices->Index (anEdgeIter) >= myAttribs->NbElements) |
460 | { |
461 | return Standard_False; |
7fd59977 |
462 | } |
463 | } |
464 | } |
7fd59977 |
465 | return Standard_True; |
466 | } |