mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-08-12 07:19:01 +08:00
parent
c8b6219ff9
commit
b267d04c49
@ -58,8 +58,8 @@ bool SequentialAttributeDecoder::TransformAttributeToOriginalFormat(
|
||||
const PointAttribute *SequentialAttributeDecoder::GetPortableAttribute() {
|
||||
// If needed, copy point to attribute value index mapping from the final
|
||||
// attribute to the portable attribute.
|
||||
if (!attribute_->is_mapping_identity() &&
|
||||
portable_attribute_ && portable_attribute_->is_mapping_identity()) {
|
||||
if (!attribute_->is_mapping_identity() && portable_attribute_ &&
|
||||
portable_attribute_->is_mapping_identity()) {
|
||||
portable_attribute_->SetExplicitMapping(attribute_->indices_map_size());
|
||||
for (PointIndex i(0); i < attribute_->indices_map_size(); ++i) {
|
||||
portable_attribute_->SetPointMapEntry(i, attribute_->mapped_index(i));
|
||||
|
@ -30,9 +30,9 @@ std::unique_ptr<Mesh> ReadMeshFromFile(const std::string &file_name,
|
||||
bool use_metadata) {
|
||||
std::unique_ptr<Mesh> mesh(new Mesh());
|
||||
// Analyze file extension.
|
||||
const std::string extension =
|
||||
parser::ToLower(file_name.size() >= 4 ?
|
||||
file_name.substr(file_name.size() - 4) : file_name);
|
||||
const std::string extension = parser::ToLower(
|
||||
file_name.size() >= 4 ? file_name.substr(file_name.size() - 4)
|
||||
: file_name);
|
||||
if (extension == ".obj") {
|
||||
// Wavefront OBJ file format.
|
||||
ObjDecoder obj_decoder;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <fstream>
|
||||
|
||||
#include "draco/io/obj_decoder.h"
|
||||
#include "draco/io/parser_utils.h"
|
||||
#include "draco/io/ply_decoder.h"
|
||||
|
||||
namespace draco {
|
||||
@ -25,8 +26,9 @@ std::unique_ptr<PointCloud> ReadPointCloudFromFile(
|
||||
const std::string &file_name) {
|
||||
std::unique_ptr<PointCloud> pc(new PointCloud());
|
||||
// Analyze file extension.
|
||||
const std::string extension = file_name.size() >= 4 ?
|
||||
file_name.substr(file_name.size() - 4) : file_name;
|
||||
const std::string extension = parser::ToLower(
|
||||
file_name.size() >= 4 ? file_name.substr(file_name.size() - 4)
|
||||
: file_name);
|
||||
if (extension == ".obj") {
|
||||
// Wavefront OBJ file format.
|
||||
ObjDecoder obj_decoder;
|
||||
|
217
src/draco/javascript/emscripten/decoder_webidl_wrapper.cc
Normal file
217
src/draco/javascript/emscripten/decoder_webidl_wrapper.cc
Normal file
@ -0,0 +1,217 @@
|
||||
// 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/javascript/emscripten/decoder_webidl_wrapper.h"
|
||||
|
||||
#include "draco/compression/decode.h"
|
||||
#include "draco/mesh/mesh.h"
|
||||
#include "draco/mesh/mesh_stripifier.h"
|
||||
|
||||
using draco::DecoderBuffer;
|
||||
using draco::Mesh;
|
||||
using draco::Metadata;
|
||||
using draco::PointAttribute;
|
||||
using draco::PointCloud;
|
||||
using draco::Status;
|
||||
|
||||
MetadataQuerier::MetadataQuerier() {}
|
||||
|
||||
bool MetadataQuerier::HasIntEntry(const Metadata &metadata,
|
||||
const char *entry_name) const {
|
||||
int32_t value = 0;
|
||||
const std::string name(entry_name);
|
||||
if (!metadata.GetEntryInt(name, &value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
long MetadataQuerier::GetIntEntry(const Metadata &metadata,
|
||||
const char *entry_name) const {
|
||||
int32_t value = 0;
|
||||
const std::string name(entry_name);
|
||||
metadata.GetEntryInt(name, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool MetadataQuerier::HasDoubleEntry(const Metadata &metadata,
|
||||
const char *entry_name) const {
|
||||
double value = 0;
|
||||
const std::string name(entry_name);
|
||||
if (!metadata.GetEntryDouble(name, &value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
double MetadataQuerier::GetDoubleEntry(const Metadata &metadata,
|
||||
const char *entry_name) const {
|
||||
double value = 0;
|
||||
const std::string name(entry_name);
|
||||
metadata.GetEntryDouble(name, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool MetadataQuerier::HasStringEntry(const Metadata &metadata,
|
||||
const char *entry_name) const {
|
||||
std::string return_value;
|
||||
const std::string name(entry_name);
|
||||
if (!metadata.GetEntryString(name, &return_value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *MetadataQuerier::GetStringEntry(const Metadata &metadata,
|
||||
const char *entry_name) const {
|
||||
std::string return_value;
|
||||
const std::string name(entry_name);
|
||||
metadata.GetEntryString(name, &return_value);
|
||||
const char *value = return_value.c_str();
|
||||
return value;
|
||||
}
|
||||
|
||||
DracoFloat32Array::DracoFloat32Array() {}
|
||||
|
||||
float DracoFloat32Array::GetValue(int index) const { return values_[index]; }
|
||||
|
||||
bool DracoFloat32Array::SetValues(const float *values, int count) {
|
||||
if (values) {
|
||||
values_.assign(values, values + count);
|
||||
} else {
|
||||
values_.resize(count);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DracoInt32Array::DracoInt32Array() {}
|
||||
|
||||
int DracoInt32Array::GetValue(int index) const { return values_[index]; }
|
||||
|
||||
bool DracoInt32Array::SetValues(const int *values, int count) {
|
||||
values_.assign(values, values + count);
|
||||
return true;
|
||||
}
|
||||
|
||||
Decoder::Decoder() {}
|
||||
|
||||
draco_EncodedGeometryType Decoder::GetEncodedGeometryType(
|
||||
DecoderBuffer *in_buffer) {
|
||||
return draco::Decoder::GetEncodedGeometryType(in_buffer).value();
|
||||
}
|
||||
|
||||
const Status *Decoder::DecodeBufferToPointCloud(DecoderBuffer *in_buffer,
|
||||
PointCloud *out_point_cloud) {
|
||||
last_status_ = decoder_.DecodeBufferToGeometry(in_buffer, out_point_cloud);
|
||||
return &last_status_;
|
||||
}
|
||||
|
||||
const Status *Decoder::DecodeBufferToMesh(DecoderBuffer *in_buffer,
|
||||
Mesh *out_mesh) {
|
||||
last_status_ = decoder_.DecodeBufferToGeometry(in_buffer, out_mesh);
|
||||
return &last_status_;
|
||||
}
|
||||
|
||||
long Decoder::GetAttributeId(const PointCloud &pc,
|
||||
draco_GeometryAttribute_Type type) const {
|
||||
return pc.GetNamedAttributeId(type);
|
||||
}
|
||||
|
||||
const PointAttribute *Decoder::GetAttribute(const PointCloud &pc, long att_id) {
|
||||
return pc.attribute(att_id);
|
||||
}
|
||||
|
||||
long Decoder::GetAttributeIdByName(const PointCloud &pc,
|
||||
const char *attribute_name) {
|
||||
const std::string entry_value(attribute_name);
|
||||
return pc.GetAttributeIdByMetadataEntry("name", entry_value);
|
||||
}
|
||||
|
||||
long Decoder::GetAttributeIdByMetadataEntry(const PointCloud &pc,
|
||||
const char *metadata_name,
|
||||
const char *metadata_value) {
|
||||
const std::string entry_name(metadata_name);
|
||||
const std::string entry_value(metadata_value);
|
||||
return pc.GetAttributeIdByMetadataEntry(entry_name, entry_value);
|
||||
}
|
||||
|
||||
bool Decoder::GetFaceFromMesh(const Mesh &m,
|
||||
draco::FaceIndex::ValueType face_id,
|
||||
DracoInt32Array *out_values) {
|
||||
const Mesh::Face &face = m.face(draco::FaceIndex(face_id));
|
||||
return out_values->SetValues(reinterpret_cast<const int *>(face.data()),
|
||||
face.size());
|
||||
}
|
||||
|
||||
long Decoder::GetTriangleStripsFromMesh(const Mesh &m,
|
||||
DracoInt32Array *strip_values) {
|
||||
draco::MeshStripifier stripifier;
|
||||
std::vector<int32_t> strip_indices;
|
||||
if (!stripifier.GenerateTriangleStripsWithDegenerateTriangles(
|
||||
m, std::back_inserter(strip_indices))) {
|
||||
return 0;
|
||||
}
|
||||
if (!strip_values->SetValues(strip_indices.data(), strip_indices.size()))
|
||||
return 0;
|
||||
return stripifier.num_strips();
|
||||
}
|
||||
|
||||
bool Decoder::GetAttributeFloat(const PointAttribute &pa,
|
||||
draco::AttributeValueIndex::ValueType val_index,
|
||||
DracoFloat32Array *out_values) {
|
||||
const int kMaxAttributeFloatValues = 4;
|
||||
const int components = pa.num_components();
|
||||
float values[kMaxAttributeFloatValues] = {-2.0, -2.0, -2.0, -2.0};
|
||||
if (!pa.ConvertValue<float>(draco::AttributeValueIndex(val_index), values))
|
||||
return false;
|
||||
return out_values->SetValues(values, components);
|
||||
}
|
||||
|
||||
bool Decoder::GetAttributeFloatForAllPoints(const PointCloud &pc,
|
||||
const PointAttribute &pa,
|
||||
DracoFloat32Array *out_values) {
|
||||
const int components = pa.num_components();
|
||||
const int num_points = pc.num_points();
|
||||
const int num_entries = num_points * components;
|
||||
const int kMaxAttributeFloatValues = 4;
|
||||
float values[kMaxAttributeFloatValues] = {-2.0, -2.0, -2.0, -2.0};
|
||||
int entry_id = 0;
|
||||
|
||||
out_values->SetValues(nullptr, num_entries);
|
||||
for (draco::PointIndex i(0); i < num_points; ++i) {
|
||||
const draco::AttributeValueIndex val_index = pa.mapped_index(i);
|
||||
if (!pa.ConvertValue<float>(val_index, values))
|
||||
return false;
|
||||
for (int j = 0; j < components; ++j) {
|
||||
out_values->SetValue(entry_id++, values[j]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Decoder::SkipAttributeTransform(draco_GeometryAttribute_Type att_type) {
|
||||
decoder_.SetSkipAttributeTransform(att_type);
|
||||
}
|
||||
|
||||
const Metadata *Decoder::GetMetadata(const PointCloud &pc) const {
|
||||
if (!pc.GetMetadata()) {
|
||||
return nullptr;
|
||||
}
|
||||
return pc.GetMetadata();
|
||||
}
|
||||
|
||||
const Metadata *Decoder::GetAttributeMetadata(const PointCloud &pc,
|
||||
long att_id) const {
|
||||
if (!pc.GetMetadata()) {
|
||||
return nullptr;
|
||||
}
|
||||
return pc.GetMetadata()->GetAttributeMetadata(att_id);
|
||||
}
|
158
src/draco/javascript/emscripten/decoder_webidl_wrapper.h
Normal file
158
src/draco/javascript/emscripten/decoder_webidl_wrapper.h
Normal file
@ -0,0 +1,158 @@
|
||||
// Copyright 2017 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.
|
||||
//
|
||||
#ifndef DRACO_JAVASCRIPT_EMSCRITPEN_DECODER_WEBIDL_WRAPPER_H_
|
||||
#define DRACO_JAVASCRIPT_EMSCRITPEN_DECODER_WEBIDL_WRAPPER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "draco/attributes/attribute_transform_type.h"
|
||||
#include "draco/attributes/point_attribute.h"
|
||||
#include "draco/compression/config/compression_shared.h"
|
||||
#include "draco/compression/decode.h"
|
||||
#include "draco/core/decoder_buffer.h"
|
||||
#include "draco/mesh/mesh.h"
|
||||
|
||||
typedef draco::AttributeTransformType draco_AttributeTransformType;
|
||||
typedef draco::GeometryAttribute draco_GeometryAttribute;
|
||||
typedef draco_GeometryAttribute::Type draco_GeometryAttribute_Type;
|
||||
typedef draco::EncodedGeometryType draco_EncodedGeometryType;
|
||||
typedef draco::Status draco_Status;
|
||||
typedef draco::Status::Code draco_StatusCode;
|
||||
|
||||
// To generate Draco JabvaScript bindings you must have emscripten installed.
|
||||
// Then run make -f Makefile.emcc jslib.
|
||||
|
||||
class MetadataQuerier {
|
||||
public:
|
||||
MetadataQuerier();
|
||||
|
||||
bool HasIntEntry(const draco::Metadata &metadata,
|
||||
const char *entry_name) const;
|
||||
long GetIntEntry(const draco::Metadata &metadata,
|
||||
const char *entry_name) const;
|
||||
bool HasDoubleEntry(const draco::Metadata &metadata,
|
||||
const char *entry_name) const;
|
||||
double GetDoubleEntry(const draco::Metadata &metadata,
|
||||
const char *entry_name) const;
|
||||
bool HasStringEntry(const draco::Metadata &metadata,
|
||||
const char *entry_name) const;
|
||||
const char *GetStringEntry(const draco::Metadata &metadata,
|
||||
const char *entry_name) const;
|
||||
};
|
||||
|
||||
class DracoFloat32Array {
|
||||
public:
|
||||
DracoFloat32Array();
|
||||
float GetValue(int index) const;
|
||||
|
||||
// In case |values| is nullptr, the data is allocated but not initialized.
|
||||
bool SetValues(const float *values, int count);
|
||||
|
||||
// Directly sets a value for a specific index. The array has to be already
|
||||
// allocated at this point (using SetValues() method).
|
||||
void SetValue(int index, float val) { values_[index] = val; }
|
||||
|
||||
int size() const { return values_.size(); }
|
||||
|
||||
private:
|
||||
std::vector<float> values_;
|
||||
};
|
||||
|
||||
class DracoInt32Array {
|
||||
public:
|
||||
DracoInt32Array();
|
||||
int GetValue(int index) const;
|
||||
bool SetValues(const int *values, int count);
|
||||
int size() const { return values_.size(); }
|
||||
|
||||
private:
|
||||
std::vector<int> values_;
|
||||
};
|
||||
|
||||
// Class used by emscripten WebIDL Binder [1] to wrap calls to decode Draco
|
||||
// data.
|
||||
// [1]http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.html
|
||||
class Decoder {
|
||||
public:
|
||||
Decoder();
|
||||
|
||||
// Returns the geometry type stored in the |in_buffer|. Return values can be
|
||||
// INVALID_GEOMETRY_TYPE, POINT_CLOUD, or MESH.
|
||||
draco_EncodedGeometryType GetEncodedGeometryType(
|
||||
draco::DecoderBuffer *in_buffer);
|
||||
|
||||
// Decodes a point cloud from the provided buffer.
|
||||
const draco::Status *DecodeBufferToPointCloud(
|
||||
draco::DecoderBuffer *in_buffer, draco::PointCloud *out_point_cloud);
|
||||
|
||||
// Decodes a triangular mesh from the provided buffer.
|
||||
const draco::Status *DecodeBufferToMesh(draco::DecoderBuffer *in_buffer,
|
||||
draco::Mesh *out_mesh);
|
||||
|
||||
// Returns an attribute id for the first attribute of a given type.
|
||||
long GetAttributeId(const draco::PointCloud &pc,
|
||||
draco_GeometryAttribute_Type type) const;
|
||||
|
||||
// Returns an attribute id of an attribute that contains a valid metadata
|
||||
// entry "name" with value |attribute_name|.
|
||||
static long GetAttributeIdByName(const draco::PointCloud &pc,
|
||||
const char *attribute_name);
|
||||
|
||||
// Returns an attribute id of an attribute with a specified metadata pair
|
||||
// <|metadata_name|, |metadata_value|>.
|
||||
static long GetAttributeIdByMetadataEntry(const draco::PointCloud &pc,
|
||||
const char *metadata_name,
|
||||
const char *metadata_value);
|
||||
|
||||
// Returns a PointAttribute pointer from |att_id| index.
|
||||
static const draco::PointAttribute *GetAttribute(const draco::PointCloud &pc,
|
||||
long att_id);
|
||||
|
||||
// Returns Mesh::Face values in |out_values| from |face_id| index.
|
||||
static bool GetFaceFromMesh(const draco::Mesh &m,
|
||||
draco::FaceIndex::ValueType face_id,
|
||||
DracoInt32Array *out_values);
|
||||
|
||||
// Returns triangle strips for mesh |m|. If there's multiple strips,
|
||||
// the strips will be separated by degenerate faces.
|
||||
static long GetTriangleStripsFromMesh(const draco::Mesh &m,
|
||||
DracoInt32Array *strip_values);
|
||||
|
||||
// Returns float attribute values in |out_values| from |entry_index| index.
|
||||
static bool GetAttributeFloat(
|
||||
const draco::PointAttribute &pa,
|
||||
draco::AttributeValueIndex::ValueType entry_index,
|
||||
DracoFloat32Array *out_values);
|
||||
|
||||
// Returns float attribute values for all point ids of the point cloud.
|
||||
// I.e., the |out_values| is going to contain m.num_points() entries.
|
||||
static bool GetAttributeFloatForAllPoints(const draco::PointCloud &pc,
|
||||
const draco::PointAttribute &pa,
|
||||
DracoFloat32Array *out_values);
|
||||
|
||||
// Tells the decoder to skip an attribute transform (e.g. dequantization) for
|
||||
// an attribute of a given type.
|
||||
void SkipAttributeTransform(draco_GeometryAttribute_Type att_type);
|
||||
|
||||
const draco::Metadata *GetMetadata(const draco::PointCloud &pc) const;
|
||||
const draco::Metadata *GetAttributeMetadata(const draco::PointCloud &pc,
|
||||
long att_id) const;
|
||||
|
||||
private:
|
||||
draco::Decoder decoder_;
|
||||
draco::Status last_status_;
|
||||
};
|
||||
|
||||
#endif // DRACO_JAVASCRIPT_EMSCRITPEN_DECODER_WEBIDL_WRAPPER_H_
|
@ -18,6 +18,7 @@
|
||||
#include "draco/compression/decode.h"
|
||||
#include "draco/core/cycle_timer.h"
|
||||
#include "draco/io/obj_encoder.h"
|
||||
#include "draco/io/parser_utils.h"
|
||||
#include "draco/io/ply_encoder.h"
|
||||
|
||||
namespace {
|
||||
@ -134,8 +135,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Save the decoded geometry into a file.
|
||||
// TODO(ostava): Currently only .ply and .obj are supported.
|
||||
const std::string extension = options.output.size() >= 4 ?
|
||||
options.output.substr(options.output.size() - 4) : options.output;
|
||||
const std::string extension = draco::parser::ToLower(
|
||||
options.output.size() >= 4
|
||||
? options.output.substr(options.output.size() - 4)
|
||||
: options.output);
|
||||
|
||||
if (extension == ".obj") {
|
||||
draco::ObjEncoder obj_encoder;
|
||||
if (mesh) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user