1 // Created on: 2000-06-16
2 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <Graphic3d_ArrayOfPrimitives.hxx>
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 #include <Graphic3d_AttribBuffer.hxx>
27 #include <Graphic3d_MutableIndexBuffer.hxx>
29 #include <NCollection_AlignedAllocator.hxx>
30 #include <TCollection_AsciiString.hxx>
35 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPrimitives, Standard_Transient)
37 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPoints, Graphic3d_ArrayOfPrimitives)
38 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfSegments, Graphic3d_ArrayOfPrimitives)
39 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPolylines, Graphic3d_ArrayOfPrimitives)
40 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfTriangles, Graphic3d_ArrayOfPrimitives)
41 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfTriangleStrips, Graphic3d_ArrayOfPrimitives)
42 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfTriangleFans, Graphic3d_ArrayOfPrimitives)
43 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfQuadrangles, Graphic3d_ArrayOfPrimitives)
44 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfQuadrangleStrips, Graphic3d_ArrayOfPrimitives)
45 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPolygons, Graphic3d_ArrayOfPrimitives)
47 // =======================================================================
48 // function : CreateArray
50 // =======================================================================
51 Handle(Graphic3d_ArrayOfPrimitives) Graphic3d_ArrayOfPrimitives::CreateArray (Graphic3d_TypeOfPrimitiveArray theType,
52 Standard_Integer theMaxVertexs,
53 Standard_Integer theMaxBounds,
54 Standard_Integer theMaxEdges,
55 Graphic3d_ArrayFlags theArrayFlags)
59 case Graphic3d_TOPA_UNDEFINED:
60 return Handle(Graphic3d_ArrayOfPrimitives)();
61 case Graphic3d_TOPA_POINTS:
62 return new Graphic3d_ArrayOfPoints (theMaxVertexs, theArrayFlags);
63 case Graphic3d_TOPA_SEGMENTS:
64 return new Graphic3d_ArrayOfSegments (theMaxVertexs, theMaxEdges, theArrayFlags);
65 case Graphic3d_TOPA_POLYLINES:
66 return new Graphic3d_ArrayOfPolylines (theMaxVertexs, theMaxBounds, theMaxEdges, theArrayFlags);
67 case Graphic3d_TOPA_TRIANGLES:
68 return new Graphic3d_ArrayOfTriangles (theMaxVertexs, theMaxEdges, theArrayFlags);
69 case Graphic3d_TOPA_TRIANGLESTRIPS:
70 return new Graphic3d_ArrayOfTriangleStrips (theMaxVertexs, theMaxBounds, theArrayFlags);
71 case Graphic3d_TOPA_TRIANGLEFANS:
72 return new Graphic3d_ArrayOfTriangleFans (theMaxVertexs, theMaxBounds, theArrayFlags);
73 case Graphic3d_TOPA_LINES_ADJACENCY:
74 case Graphic3d_TOPA_LINE_STRIP_ADJACENCY:
75 case Graphic3d_TOPA_TRIANGLES_ADJACENCY:
76 case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY:
77 return new Graphic3d_ArrayOfPrimitives (theType, theMaxVertexs, theMaxBounds, theMaxEdges, theArrayFlags);
78 case Graphic3d_TOPA_QUADRANGLES:
79 return new Graphic3d_ArrayOfQuadrangles (theMaxVertexs, theMaxEdges, theArrayFlags);
80 case Graphic3d_TOPA_QUADRANGLESTRIPS:
81 return new Graphic3d_ArrayOfQuadrangleStrips (theMaxVertexs, theMaxBounds, theArrayFlags);
82 case Graphic3d_TOPA_POLYGONS:
83 return new Graphic3d_ArrayOfPolygons (theMaxVertexs, theMaxBounds, theMaxEdges, theArrayFlags);
85 return Handle(Graphic3d_ArrayOfPrimitives)();
88 // =======================================================================
91 // =======================================================================
92 void Graphic3d_ArrayOfPrimitives::init (Graphic3d_TypeOfPrimitiveArray theType,
93 Standard_Integer theMaxVertexs,
94 Standard_Integer theMaxBounds,
95 Standard_Integer theMaxEdges,
96 Graphic3d_ArrayFlags theArrayOptions)
106 Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
107 if ((theArrayOptions & Graphic3d_ArrayFlags_AttribsMutable) != 0
108 || (theArrayOptions & Graphic3d_ArrayFlags_AttribsDeinterleaved) != 0)
110 Graphic3d_AttribBuffer* anAttribs = new Graphic3d_AttribBuffer (anAlloc);
111 anAttribs->SetMutable ((theArrayOptions & Graphic3d_ArrayFlags_AttribsMutable) != 0);
112 anAttribs->SetInterleaved ((theArrayOptions & Graphic3d_ArrayFlags_AttribsDeinterleaved) == 0);
113 myAttribs = anAttribs;
117 myAttribs = new Graphic3d_Buffer (anAlloc);
119 if (theMaxVertexs < 1)
126 if ((theArrayOptions & Graphic3d_ArrayFlags_IndexesMutable) != 0)
128 myIndices = new Graphic3d_MutableIndexBuffer (anAlloc);
132 myIndices = new Graphic3d_IndexBuffer (anAlloc);
134 if (theMaxVertexs < Standard_Integer(USHRT_MAX))
136 if (!myIndices->Init<unsigned short> (theMaxEdges))
144 if (!myIndices->Init<unsigned int> (theMaxEdges))
150 myIndices->NbElements = 0;
153 Graphic3d_Attribute anAttribs[4];
154 Standard_Integer aNbAttribs = 0;
155 anAttribs[aNbAttribs].Id = Graphic3d_TOA_POS;
156 anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3;
158 if ((theArrayOptions & Graphic3d_ArrayFlags_VertexNormal) != 0)
160 anAttribs[aNbAttribs].Id = Graphic3d_TOA_NORM;
161 anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3;
164 if ((theArrayOptions & Graphic3d_ArrayFlags_VertexTexel) != 0)
166 anAttribs[aNbAttribs].Id = Graphic3d_TOA_UV;
167 anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC2;
170 if ((theArrayOptions & Graphic3d_ArrayFlags_VertexColor) != 0)
172 anAttribs[aNbAttribs].Id = Graphic3d_TOA_COLOR;
173 anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC4UB;
177 if (!myAttribs->Init (theMaxVertexs, anAttribs, aNbAttribs))
184 Standard_Integer anAttribDummy = 0;
185 myAttribs->ChangeAttributeData (Graphic3d_TOA_POS, anAttribDummy, myPosStride);
186 myNormData = myAttribs->ChangeAttributeData (Graphic3d_TOA_NORM, anAttribDummy, myNormStride);
187 myTexData = myAttribs->ChangeAttributeData (Graphic3d_TOA_UV, anAttribDummy, myTexStride);
188 myColData = myAttribs->ChangeAttributeData (Graphic3d_TOA_COLOR, anAttribDummy, myColStride);
190 memset (myAttribs->ChangeData(), 0, size_t(myAttribs->Stride) * size_t(myAttribs->NbMaxElements()));
191 if ((theArrayOptions & Graphic3d_ArrayFlags_AttribsMutable) == 0
192 && (theArrayOptions & Graphic3d_ArrayFlags_AttribsDeinterleaved) == 0)
194 myAttribs->NbElements = 0;
197 if (theMaxBounds > 0)
199 myBounds = new Graphic3d_BoundBuffer (anAlloc);
200 if (!myBounds->Init (theMaxBounds, (theArrayOptions & Graphic3d_ArrayFlags_BoundColor) != 0))
207 myBounds->NbBounds = 0;
211 // =======================================================================
212 // function : ~Graphic3d_ArrayOfPrimitives
214 // =======================================================================
215 Graphic3d_ArrayOfPrimitives::~Graphic3d_ArrayOfPrimitives()
222 // =======================================================================
223 // function : AddBound
225 // =======================================================================
226 Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber)
228 Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->NbBounds >= myBounds->NbMaxBounds, "TOO many BOUND");
229 myBounds->Bounds[myBounds->NbBounds] = theEdgeNumber;
230 return ++myBounds->NbBounds;
233 // =======================================================================
234 // function : AddBound
236 // =======================================================================
237 Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber,
238 const Standard_Real theR,
239 const Standard_Real theG,
240 const Standard_Real theB)
242 Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->NbBounds >= myBounds->NbMaxBounds, "TOO many BOUND");
243 myBounds->Bounds[myBounds->NbBounds] = theEdgeNumber;
244 ++myBounds->NbBounds;
245 SetBoundColor (myBounds->NbBounds, theR, theG, theB);
246 return myBounds->NbBounds;
249 // =======================================================================
250 // function : AddEdge
252 // =======================================================================
253 Standard_Integer Graphic3d_ArrayOfPrimitives::AddEdge (const Standard_Integer theVertexIndex)
255 Standard_OutOfRange_Raise_if (myIndices.IsNull() || myIndices->NbElements >= myIndices->NbMaxElements(), "TOO many EDGE");
256 Standard_OutOfRange_Raise_if (theVertexIndex < 1 || theVertexIndex > myAttribs->NbElements, "BAD VERTEX index");
257 const Standard_Integer aVertIndex = theVertexIndex - 1;
258 myIndices->SetIndex (myIndices->NbElements, aVertIndex);
259 return ++myIndices->NbElements;
262 // =======================================================================
263 // function : StringType
265 // =======================================================================
266 Standard_CString Graphic3d_ArrayOfPrimitives::StringType() const
270 case Graphic3d_TOPA_POINTS: return "ArrayOfPoints";
271 case Graphic3d_TOPA_SEGMENTS: return "ArrayOfSegments";
272 case Graphic3d_TOPA_POLYLINES: return "ArrayOfPolylines";
273 case Graphic3d_TOPA_TRIANGLES: return "ArrayOfTriangles";
274 case Graphic3d_TOPA_TRIANGLESTRIPS: return "ArrayOfTriangleStrips";
275 case Graphic3d_TOPA_TRIANGLEFANS: return "ArrayOfTriangleFans";
276 case Graphic3d_TOPA_LINES_ADJACENCY: return "ArrayOfLinesAdjacency";
277 case Graphic3d_TOPA_LINE_STRIP_ADJACENCY: return "ArrayOfLineStripAdjacency";
278 case Graphic3d_TOPA_TRIANGLES_ADJACENCY: return "ArrayOfTrianglesAdjacency";
279 case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY: return "ArrayOfTriangleStripAdjacency";
280 case Graphic3d_TOPA_QUADRANGLES: return "ArrayOfQuadrangles";
281 case Graphic3d_TOPA_QUADRANGLESTRIPS: return "ArrayOfQuadrangleStrips";
282 case Graphic3d_TOPA_POLYGONS: return "ArrayOfPolygons";
283 case Graphic3d_TOPA_UNDEFINED: return "UndefinedArray";
285 return "UndefinedArray";
288 // =======================================================================
289 // function : ItemNumber
291 // =======================================================================
292 Standard_Integer Graphic3d_ArrayOfPrimitives::ItemNumber() const
294 if (myAttribs.IsNull())
301 case Graphic3d_TOPA_POINTS: return myAttribs->NbElements;
302 case Graphic3d_TOPA_POLYLINES:
303 case Graphic3d_TOPA_POLYGONS: return !myBounds.IsNull() ? myBounds->NbBounds : 1;
304 case Graphic3d_TOPA_SEGMENTS: return myIndices.IsNull() || myIndices->NbElements < 1
305 ? myAttribs->NbElements / 2
306 : myIndices->NbElements / 2;
307 case Graphic3d_TOPA_TRIANGLES: return myIndices.IsNull() || myIndices->NbElements < 1
308 ? myAttribs->NbElements / 3
309 : myIndices->NbElements / 3;
310 case Graphic3d_TOPA_QUADRANGLES: return myIndices.IsNull() || myIndices->NbElements < 1
311 ? myAttribs->NbElements / 4
312 : myIndices->NbElements / 4;
313 case Graphic3d_TOPA_TRIANGLESTRIPS: return !myBounds.IsNull()
314 ? myAttribs->NbElements - 2 * myBounds->NbBounds
315 : myAttribs->NbElements - 2;
316 case Graphic3d_TOPA_QUADRANGLESTRIPS: return !myBounds.IsNull()
317 ? myAttribs->NbElements / 2 - myBounds->NbBounds
318 : myAttribs->NbElements / 2 - 1;
319 case Graphic3d_TOPA_TRIANGLEFANS: return !myBounds.IsNull()
320 ? myAttribs->NbElements - 2 * myBounds->NbBounds
321 : myAttribs->NbElements - 2;
322 case Graphic3d_TOPA_LINES_ADJACENCY: return myIndices.IsNull() || myIndices->NbElements < 1
323 ? myAttribs->NbElements / 4
324 : myIndices->NbElements / 4;
325 case Graphic3d_TOPA_LINE_STRIP_ADJACENCY: return !myBounds.IsNull()
326 ? myAttribs->NbElements - 4 * myBounds->NbBounds
327 : myAttribs->NbElements - 4;
328 case Graphic3d_TOPA_TRIANGLES_ADJACENCY: return myIndices.IsNull() || myIndices->NbElements < 1
329 ? myAttribs->NbElements / 6
330 : myIndices->NbElements / 6;
331 case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY: return !myBounds.IsNull()
332 ? myAttribs->NbElements - 4 * myBounds->NbBounds
333 : myAttribs->NbElements - 4;
334 case Graphic3d_TOPA_UNDEFINED: return -1;
339 // =======================================================================
340 // function : IsValid
342 // =======================================================================
343 Standard_Boolean Graphic3d_ArrayOfPrimitives::IsValid()
345 if (myAttribs.IsNull())
347 return Standard_False;
350 Standard_Integer nvertexs = myAttribs->NbElements;
351 Standard_Integer nbounds = myBounds.IsNull() ? 0 : myBounds->NbBounds;
352 Standard_Integer nedges = myIndices.IsNull() ? 0 : myIndices->NbElements;
355 case Graphic3d_TOPA_POINTS:
358 return Standard_False;
361 case Graphic3d_TOPA_POLYLINES:
365 return Standard_False;
369 return Standard_False;
372 case Graphic3d_TOPA_SEGMENTS:
375 return Standard_False;
378 case Graphic3d_TOPA_POLYGONS:
382 return Standard_False;
386 return Standard_False;
389 case Graphic3d_TOPA_TRIANGLES:
397 return Standard_False;
399 myIndices->NbElements = 3 * (nedges / 3);
402 else if (nvertexs < 3
403 || nvertexs % 3 != 0 )
407 return Standard_False;
409 myAttribs->NbElements = 3 * (nvertexs / 3);
412 case Graphic3d_TOPA_QUADRANGLES:
420 return Standard_False;
422 myIndices->NbElements = 4 * (nedges / 4);
425 else if (nvertexs < 4
426 || nvertexs % 4 != 0)
430 return Standard_False;
432 myAttribs->NbElements = 4 * (nvertexs / 4);
435 case Graphic3d_TOPA_TRIANGLEFANS:
436 case Graphic3d_TOPA_TRIANGLESTRIPS:
439 return Standard_False;
442 case Graphic3d_TOPA_QUADRANGLESTRIPS:
445 return Standard_False;
448 case Graphic3d_TOPA_LINES_ADJACENCY:
449 case Graphic3d_TOPA_LINE_STRIP_ADJACENCY:
452 return Standard_False;
455 case Graphic3d_TOPA_TRIANGLES_ADJACENCY:
456 case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY:
459 return Standard_False;
462 case Graphic3d_TOPA_UNDEFINED:
464 return Standard_False;
467 // total number of edges(vertices) in bounds should be the same as variable
468 // of total number of defined edges(vertices); if no edges - only vertices
469 // could be in bounds.
472 Standard_Integer n = 0;
473 for (Standard_Integer aBoundIter = 0; aBoundIter < nbounds; ++aBoundIter)
475 n += myBounds->Bounds[aBoundIter];
482 return Standard_False;
484 myIndices->NbElements = n;
491 return Standard_False;
493 myAttribs->NbElements = n;
497 // check that edges (indexes to an array of vertices) are in range.
500 for (Standard_Integer anEdgeIter = 0; anEdgeIter < nedges; ++anEdgeIter)
502 if (myIndices->Index (anEdgeIter) >= myAttribs->NbElements)
504 return Standard_False;
508 return Standard_True;