// 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(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 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(i), static_cast(attribute_element_types_[i])); } } return std::move(mesh_); } } // namespace draco