1 // Copyright 2016 The Draco Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 #include "draco/point_cloud/point_cloud_builder.h"
16 
17 namespace draco {
18 
PointCloudBuilder()19 PointCloudBuilder::PointCloudBuilder() {}
20 
Start(PointIndex::ValueType num_points)21 void PointCloudBuilder::Start(PointIndex::ValueType num_points) {
22   point_cloud_ = std::unique_ptr<PointCloud>(new PointCloud());
23   point_cloud_->set_num_points(num_points);
24 }
25 
AddAttribute(GeometryAttribute::Type attribute_type,int8_t num_components,DataType data_type)26 int PointCloudBuilder::AddAttribute(GeometryAttribute::Type attribute_type,
27                                     int8_t num_components, DataType data_type) {
28   GeometryAttribute ga;
29   ga.Init(attribute_type, nullptr, num_components, data_type, false,
30           DataTypeLength(data_type) * num_components, 0);
31   return point_cloud_->AddAttribute(ga, true, point_cloud_->num_points());
32 }
33 
SetAttributeValueForPoint(int att_id,PointIndex point_index,const void * attribute_value)34 void PointCloudBuilder::SetAttributeValueForPoint(int att_id,
35                                                   PointIndex point_index,
36                                                   const void *attribute_value) {
37   PointAttribute *const att = point_cloud_->attribute(att_id);
38   att->SetAttributeValue(att->mapped_index(point_index), attribute_value);
39 }
40 
SetAttributeValuesForAllPoints(int att_id,const void * attribute_values,int stride)41 void PointCloudBuilder::SetAttributeValuesForAllPoints(
42     int att_id, const void *attribute_values, int stride) {
43   PointAttribute *const att = point_cloud_->attribute(att_id);
44   const int data_stride =
45       DataTypeLength(att->data_type()) * att->num_components();
46   if (stride == 0) {
47     stride = data_stride;
48   }
49   if (stride == data_stride) {
50     // Fast copy path.
51     att->buffer()->Write(0, attribute_values,
52                          point_cloud_->num_points() * data_stride);
53   } else {
54     // Copy attribute entries one by one.
55     for (PointIndex i(0); i < point_cloud_->num_points(); ++i) {
56       att->SetAttributeValue(
57           att->mapped_index(i),
58           static_cast<const uint8_t *>(attribute_values) + stride * i.value());
59     }
60   }
61 }
62 
Finalize(bool deduplicate_points)63 std::unique_ptr<PointCloud> PointCloudBuilder::Finalize(
64     bool deduplicate_points) {
65   if (deduplicate_points) {
66 #ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
67     point_cloud_->DeduplicateAttributeValues();
68 #endif
69 #ifdef DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
70     point_cloud_->DeduplicatePointIds();
71 #endif
72   }
73   return std::move(point_cloud_);
74 }
75 
76 }  // namespace draco
77