1 // Copyright 2009-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #include "scene_points.h"
5 #include "scene.h"
6 
7 namespace embree
8 {
9 #if defined(EMBREE_LOWEST_ISA)
10 
Points(Device * device,Geometry::GType gtype)11   Points::Points(Device* device, Geometry::GType gtype) : Geometry(device, gtype, 0, 1)
12   {
13     vertices.resize(numTimeSteps);
14     if (getType() == GTY_ORIENTED_DISC_POINT)
15       normals.resize(numTimeSteps);
16   }
17 
setMask(unsigned mask)18   void Points::setMask(unsigned mask)
19   {
20     this->mask = mask;
21     Geometry::update();
22   }
23 
setNumTimeSteps(unsigned int numTimeSteps)24   void Points::setNumTimeSteps(unsigned int numTimeSteps)
25   {
26     vertices.resize(numTimeSteps);
27     if (getType() == GTY_ORIENTED_DISC_POINT)
28       normals.resize(numTimeSteps);
29     Geometry::setNumTimeSteps(numTimeSteps);
30   }
31 
setVertexAttributeCount(unsigned int N)32   void Points::setVertexAttributeCount(unsigned int N)
33   {
34     vertexAttribs.resize(N);
35     Geometry::update();
36   }
37 
setBuffer(RTCBufferType type,unsigned int slot,RTCFormat format,const Ref<Buffer> & buffer,size_t offset,size_t stride,unsigned int num)38   void Points::setBuffer(RTCBufferType type,
39                          unsigned int slot,
40                          RTCFormat format,
41                          const Ref<Buffer>& buffer,
42                          size_t offset,
43                          size_t stride,
44                          unsigned int num)
45   {
46     /* verify that all accesses are 4 bytes aligned */
47     if ((type != RTC_BUFFER_TYPE_FLAGS) && (((size_t(buffer->getPtr()) + offset) & 0x3) || (stride & 0x3)))
48       throw_RTCError(RTC_ERROR_INVALID_OPERATION, "data must be 4 bytes aligned");
49 
50     if (type == RTC_BUFFER_TYPE_VERTEX) {
51       if (format != RTC_FORMAT_FLOAT4)
52         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex buffer format");
53 
54       if (slot >= vertices.size())
55         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid vertex buffer slot");
56 
57       vertices[slot].set(buffer, offset, stride, num, format);
58       vertices[slot].checkPadding16();
59       setNumPrimitives(num);
60     } else if (type == RTC_BUFFER_TYPE_NORMAL) {
61       if (getType() != GTY_ORIENTED_DISC_POINT)
62         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");
63 
64       if (format != RTC_FORMAT_FLOAT3)
65         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid normal buffer format");
66 
67       if (slot >= normals.size())
68         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid normal buffer slot");
69 
70       normals[slot].set(buffer, offset, stride, num, format);
71       normals[slot].checkPadding16();
72     } else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) {
73       if (format < RTC_FORMAT_FLOAT || format > RTC_FORMAT_FLOAT16)
74         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex attribute buffer format");
75 
76       if (slot >= vertexAttribs.size())
77         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex attribute buffer slot");
78 
79       vertexAttribs[slot].set(buffer, offset, stride, num, format);
80       vertexAttribs[slot].checkPadding16();
81     } else
82       throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");
83   }
84 
getBuffer(RTCBufferType type,unsigned int slot)85   void* Points::getBuffer(RTCBufferType type, unsigned int slot)
86   {
87     if (type == RTC_BUFFER_TYPE_VERTEX) {
88       if (slot >= vertices.size())
89         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
90       return vertices[slot].getPtr();
91     } else if (type == RTC_BUFFER_TYPE_NORMAL) {
92       if (slot >= normals.size())
93         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
94       return normals[slot].getPtr();
95     } else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) {
96       if (slot >= vertexAttribs.size())
97         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
98       return vertexAttribs[slot].getPtr();
99     } else {
100       throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");
101       return nullptr;
102     }
103   }
104 
updateBuffer(RTCBufferType type,unsigned int slot)105   void Points::updateBuffer(RTCBufferType type, unsigned int slot)
106   {
107     if (type == RTC_BUFFER_TYPE_VERTEX) {
108       if (slot >= vertices.size())
109         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
110       vertices[slot].setModified();
111     } else if (type == RTC_BUFFER_TYPE_NORMAL) {
112       if (slot >= normals.size())
113         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
114       normals[slot].setModified();
115     } else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) {
116       if (slot >= vertexAttribs.size())
117         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");
118       vertexAttribs[slot].setModified();
119     } else {
120       throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");
121     }
122 
123     Geometry::update();
124   }
125 
setMaxRadiusScale(float s)126   void Points::setMaxRadiusScale(float s) {
127     maxRadiusScale = s;
128   }
129 
commit()130   void Points::commit()
131   {
132     /* verify that stride of all time steps are identical */
133     for (unsigned int t = 0; t < numTimeSteps; t++)
134       if (vertices[t].getStride() != vertices[0].getStride())
135         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "stride of vertex buffers have to be identical for each time step");
136 
137     for (const auto& buffer : normals)
138       if (buffer.getStride() != normals[0].getStride())
139         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "stride of normal buffers have to be identical for each time step");
140 
141     vertices0 = vertices[0];
142     if (getType() == GTY_ORIENTED_DISC_POINT)
143       normals0 = normals[0];
144 
145     Geometry::commit();
146   }
147 
addElementsToCount(GeometryCounts & counts) const148   void Points::addElementsToCount (GeometryCounts & counts) const
149   {
150     if (numTimeSteps == 1)
151       counts.numPoints += numPrimitives;
152     else
153       counts.numMBPoints += numPrimitives;
154   }
155 
verify()156   bool Points::verify()
157   {
158     /*! verify consistent size of vertex arrays */
159     if (vertices.size() == 0)
160       return false;
161 
162     for (const auto& buffer : vertices)
163       if (buffer.size() != numVertices())
164         return false;
165 
166     if (getType() == GTY_ORIENTED_DISC_POINT) {
167       if (normals.size() == 0)
168         return false;
169 
170       for (const auto& buffer : normals)
171         if (vertices[0].size() != buffer.size())
172           return false;
173     } else {
174       if (normals.size())
175         return false;
176     }
177 
178     /*! verify vertices */
179     for (const auto& buffer : vertices) {
180       for (size_t i = 0; i < buffer.size(); i++) {
181         if (!isvalid(buffer[i].x))
182           return false;
183         if (!isvalid(buffer[i].y))
184           return false;
185         if (!isvalid(buffer[i].z))
186           return false;
187         if (!isvalid(buffer[i].w))
188           return false;
189       }
190     }
191     return true;
192   }
193 #endif
194 
195   namespace isa
196   {
createPoints(Device * device,Geometry::GType gtype)197     Points* createPoints(Device* device, Geometry::GType gtype)
198     {
199       return new PointsISA(device, gtype);
200     }
201   }  // namespace isa
202 }  // namespace embree
203