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/mesh/triangle_soup_mesh_builder.h"
16 
17 namespace draco {
18 
Start(int num_faces)19 void TriangleSoupMeshBuilder::Start(int num_faces) {
20   mesh_ = std::unique_ptr<Mesh>(new Mesh());
21   mesh_->SetNumFaces(num_faces);
22   mesh_->set_num_points(num_faces * 3);
23   attribute_element_types_.clear();
24 }
25 
AddAttribute(GeometryAttribute::Type attribute_type,int8_t num_components,DataType data_type)26 int TriangleSoupMeshBuilder::AddAttribute(
27     GeometryAttribute::Type attribute_type, int8_t num_components,
28     DataType data_type) {
29   GeometryAttribute va;
30   va.Init(attribute_type, nullptr, num_components, data_type, false,
31           DataTypeLength(data_type) * num_components, 0);
32   attribute_element_types_.push_back(-1);
33   return mesh_->AddAttribute(va, true, mesh_->num_points());
34 }
35 
SetAttributeValuesForFace(int att_id,FaceIndex face_id,const void * corner_value_0,const void * corner_value_1,const void * corner_value_2)36 void TriangleSoupMeshBuilder::SetAttributeValuesForFace(
37     int att_id, FaceIndex face_id, const void *corner_value_0,
38     const void *corner_value_1, const void *corner_value_2) {
39   const int start_index = 3 * face_id.value();
40   PointAttribute *const att = mesh_->attribute(att_id);
41   att->SetAttributeValue(AttributeValueIndex(start_index), corner_value_0);
42   att->SetAttributeValue(AttributeValueIndex(start_index + 1), corner_value_1);
43   att->SetAttributeValue(AttributeValueIndex(start_index + 2), corner_value_2);
44   mesh_->SetFace(face_id,
45                  {{PointIndex(start_index), PointIndex(start_index + 1),
46                    PointIndex(start_index + 2)}});
47   attribute_element_types_[att_id] = MESH_CORNER_ATTRIBUTE;
48 }
49 
SetPerFaceAttributeValueForFace(int att_id,FaceIndex face_id,const void * value)50 void TriangleSoupMeshBuilder::SetPerFaceAttributeValueForFace(
51     int att_id, FaceIndex face_id, const void *value) {
52   const int start_index = 3 * face_id.value();
53   PointAttribute *const att = mesh_->attribute(att_id);
54   att->SetAttributeValue(AttributeValueIndex(start_index), value);
55   att->SetAttributeValue(AttributeValueIndex(start_index + 1), value);
56   att->SetAttributeValue(AttributeValueIndex(start_index + 2), value);
57   mesh_->SetFace(face_id,
58                  {{PointIndex(start_index), PointIndex(start_index + 1),
59                    PointIndex(start_index + 2)}});
60   int8_t &element_type = attribute_element_types_[att_id];
61   if (element_type < 0) {
62     element_type = MESH_FACE_ATTRIBUTE;
63   }
64 }
65 
Finalize()66 std::unique_ptr<Mesh> TriangleSoupMeshBuilder::Finalize() {
67 #ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
68   // First deduplicate attribute values.
69   if (!mesh_->DeduplicateAttributeValues()) {
70     return nullptr;
71   }
72 #endif
73 #ifdef DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
74   // Also deduplicate vertex indices.
75   mesh_->DeduplicatePointIds();
76 #endif
77   for (size_t i = 0; i < attribute_element_types_.size(); ++i) {
78     if (attribute_element_types_[i] >= 0) {
79       mesh_->SetAttributeElementType(
80           static_cast<int>(i),
81           static_cast<MeshAttributeElementType>(attribute_element_types_[i]));
82     }
83   }
84   return std::move(mesh_);
85 }
86 
87 }  // namespace draco
88