1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
// Copyright 2016 The Draco Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "draco/mesh/triangle_soup_mesh_builder.h"
namespace draco {
void TriangleSoupMeshBuilder::Start(int num_faces) {
mesh_ = std::unique_ptr<Mesh>(new Mesh());
mesh_->SetNumFaces(num_faces);
mesh_->set_num_points(num_faces * 3);
attribute_element_types_.clear();
}
int TriangleSoupMeshBuilder::AddAttribute(
GeometryAttribute::Type attribute_type, int8_t num_components,
DataType data_type) {
GeometryAttribute va;
va.Init(attribute_type, nullptr, num_components, data_type, false,
DataTypeLength(data_type) * num_components, 0);
attribute_element_types_.push_back(-1);
return mesh_->AddAttribute(va, true, mesh_->num_points());
}
void TriangleSoupMeshBuilder::SetAttributeValuesForFace(
int att_id, FaceIndex face_id, const void *corner_value_0,
const void *corner_value_1, const void *corner_value_2) {
const int start_index = 3 * face_id.value();
PointAttribute *const att = mesh_->attribute(att_id);
att->SetAttributeValue(AttributeValueIndex(start_index), corner_value_0);
att->SetAttributeValue(AttributeValueIndex(start_index + 1), corner_value_1);
att->SetAttributeValue(AttributeValueIndex(start_index + 2), corner_value_2);
// TODO(ostava): The below code should be called only for one attribute.
// It will work OK even for multiple attributes, but it's redundant.
mesh_->SetFace(face_id,
{{PointIndex(start_index), PointIndex(start_index + 1),
PointIndex(start_index + 2)}});
attribute_element_types_[att_id] = MESH_CORNER_ATTRIBUTE;
}
void TriangleSoupMeshBuilder::SetPerFaceAttributeValueForFace(
int att_id, FaceIndex face_id, const void *value) {
const int start_index = 3 * face_id.value();
PointAttribute *const att = mesh_->attribute(att_id);
att->SetAttributeValue(AttributeValueIndex(start_index), value);
att->SetAttributeValue(AttributeValueIndex(start_index + 1), value);
att->SetAttributeValue(AttributeValueIndex(start_index + 2), value);
mesh_->SetFace(face_id,
{{PointIndex(start_index), PointIndex(start_index + 1),
PointIndex(start_index + 2)}});
int8_t &element_type = attribute_element_types_[att_id];
if (element_type < 0) {
element_type = MESH_FACE_ATTRIBUTE;
}
}
std::unique_ptr<Mesh> TriangleSoupMeshBuilder::Finalize() {
#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
// First deduplicate attribute values.
if (!mesh_->DeduplicateAttributeValues()) {
return nullptr;
}
#endif
#ifdef DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
// Also deduplicate vertex indices.
mesh_->DeduplicatePointIds();
#endif
for (size_t i = 0; i < attribute_element_types_.size(); ++i) {
if (attribute_element_types_[i] >= 0) {
mesh_->SetAttributeElementType(
static_cast<int>(i),
static_cast<MeshAttributeElementType>(attribute_element_types_[i]));
}
}
return std::move(mesh_);
}
} // namespace draco
|