Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DO NOT MERGE ME (Solutions ask ) (ABC-343) #517

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Source/abci/Importer/AlembicImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ abciAPI void aiPolyMeshFillVertexBuffer(aiPolyMeshSample* sample, aiPolyMeshData
sample->fillVertexBuffer(vbs, ibs);
}

abciAPI char* aiPolyMeshReadPropertyName(aiPolyMeshSample* sample, int idx)
{
if (sample)
return sample->readPropertyName(idx);
return "\0";
}

abciAPI void aiSubDGetSummary(aiSubD* schema, aiMeshSummary* dst)
{
if (schema)
Expand Down
7 changes: 7 additions & 0 deletions Source/abci/Importer/AlembicImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class aiPolyMeshSample; // : aiSample
class aiSubDSample; // : aiSample
class aiPointsSample; // : aiSample
class aiCurves;
struct FixedString128;
#else
// force make castable
using aiSchema = void;
Expand Down Expand Up @@ -148,6 +149,7 @@ struct aiMeshSummary
bool constant_uv1 = false;
bool constant_rgba = false;
bool constant_rgb = false;
int numV2FVertexProperties = 0;
};

struct aiMeshSampleSummary
Expand Down Expand Up @@ -189,13 +191,17 @@ struct aiPolyMeshData
abcV2 *uv1 = nullptr;
abcV4 *rgba = nullptr;
abcV4 *rgb = nullptr;
abcV2 **v2fParams = nullptr;
// FixedString128* v2fParamNames = nullptr;
int *indices = nullptr;

int vertex_count = 0;
int index_count = 0;

abcV3 center = { 0.0f, 0.0f, 0.0f };
abcV3 extents = { 0.0f, 0.0f, 0.0f };

// need the data for c#
};

struct aiSubmeshData
Expand Down Expand Up @@ -322,6 +328,7 @@ abciAPI void aiPolyMeshGetSampleSummary(aiPolyMeshSample* sample, aiM
abciAPI void aiPolyMeshGetSplitSummaries(aiPolyMeshSample* sample, aiMeshSplitSummary *dst);
abciAPI void aiPolyMeshGetSubmeshSummaries(aiPolyMeshSample* sample, aiSubmeshSummary* dst);
abciAPI void aiPolyMeshFillVertexBuffer(aiPolyMeshSample* sample, aiPolyMeshData* vbs, aiSubmeshData* ibs);
abciAPI char* aiPolyMeshReadPropertyName(aiPolyMeshSample* sample, int idx);

abciAPI void aiSubDGetSummary(aiSubD* schema, aiMeshSummary* dst);
abciAPI void aiSubDGetSampleSummary(aiSubDSample* sample, aiMeshSampleSummary* dst);
Expand Down
2 changes: 2 additions & 0 deletions Source/abci/Importer/aiMeshSchema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "aiMeshSchema.h"
#include "aiSubD.h"

constexpr size_t FixedString128::MaxLength;

aiMeshTopology::aiMeshTopology()
{
}
Expand Down
119 changes: 116 additions & 3 deletions Source/abci/Importer/aiMeshSchema.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <algorithm>
#include "aiMeshOps.h"

namespace
Expand All @@ -13,6 +14,15 @@ namespace
}
}
}

struct FixedString128
{
static constexpr size_t MaxLength = 126;
unsigned short Length;
char String[MaxLength];
};


using abcFaceSetSchemas = std::vector<AbcGeom::IFaceSetSchema>;
using abcFaceSetSamples = std::vector<AbcGeom::IFaceSetSchema::Sample>;

Expand Down Expand Up @@ -64,6 +74,8 @@ class aiMeshTopology
RawVector<int> m_remap_rgba;
RawVector<int> m_remap_rgb;

std::vector<RawVector<int> > m_remap_m_IV2fGeomParam;

int m_vertex_count = 0;
int m_index_count = 0; // triangulated
};
Expand All @@ -84,6 +96,7 @@ class aiMeshSample : public aiSample
void fillSplitVertices(int split_index, aiPolyMeshData &data) const;
void fillSubmeshIndices(int submesh_index, aiSubmeshData &data) const;
void fillVertexBuffer(aiPolyMeshData* vbs, aiSubmeshData* ibs);
char* readPropertyName(int index);

public:
Abc::P3fArraySamplePtr m_points_sp, m_points_sp2;
Expand All @@ -95,6 +108,10 @@ class aiMeshSample : public aiSample
AbcGeom::IC3fGeomParam::Sample m_rgb_sp, m_rgb_sp2;
Abc::Box3d m_bounds;

std::vector<AbcGeom::IV2fGeomParam::Sample> m_IV2fGeomParam_sp;
std::vector<FixedString128> m_IV2fGeomParamName;
std::vector<RawVector<abcV2> > m_IV2fGeomParam;

IArray<abcV3> m_points_ref;
IArray<abcV3> m_velocities_ref;
IArray<abcV2> m_uv0_ref, m_uv1_ref;
Expand All @@ -112,6 +129,8 @@ class aiMeshSample : public aiSample
RawVector<abcC4> m_rgba, m_rgba2, m_rgba_int;
RawVector<abcC3> m_rgb, m_rgb2, m_rgb_int;

//// props

TopologyPtr m_topology;
bool m_topology_changed = false;

Expand Down Expand Up @@ -147,13 +166,15 @@ class aiMeshSchema : public aiTSchema<T>
protected:
virtual AbcGeom::IN3fGeomParam readNormalsParam();
aiMeshSummaryInternal m_summary;
AbcGeom::IV2fGeomParam m_uv1_param;
AbcGeom::IV2fGeomParam m_uv1_param; // obsolete
AbcGeom::IC4fGeomParam m_rgba_param;
AbcGeom::IC3fGeomParam m_rgb_param;

TopologyPtr m_shared_topology;
abcFaceSetSchemas m_facesets;
bool m_varying_topology = false;

std::vector<AbcGeom::IV2fGeomParam> m_IV2fGeomParam;
};

template<typename T, typename U>
Expand Down Expand Up @@ -190,7 +211,12 @@ inline aiMeshSchema<T, U>::aiMeshSchema(aiObject * parent, const abcObject & abc
// uv
if (AbcGeom::IV2fGeomParam::matches(header))
{
m_uv1_param = AbcGeom::IV2fGeomParam(geom_params, header.getName());
m_uv1_param = AbcGeom::IV2fGeomParam(geom_params, header.getName()); // obsolete
}

if (AbcGeom::IV2fGeomParam::matches(header))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this 2d Vector indexed properties.
We should probably include: Vector3 and Vector4 and Un-indexed flavours.

{
m_IV2fGeomParam.push_back(AbcGeom::IV2fGeomParam(geom_params, header.getName())); // obsolete
}
}
}
Expand Down Expand Up @@ -224,6 +250,18 @@ static inline void copy_or_clear(T* dst, const IArray<T>& src, const MeshRefiner
}
}

template<class T>
static inline void copy_or_clear(T* dst, const RawVector<T>& src, const MeshRefiner::Split& split)
{
if (dst)
{
if (!src.empty())
memcpy(dst, src.data() + split.vertex_offset, sizeof(T) * split.vertex_count);
else
memset(dst, 0, split.vertex_count * sizeof(T));
}
}

template<class T1, class T2>
static inline void copy_or_clear_3_to_4(T1* dst, const IArray<T2>& src, const MeshRefiner::Split& split)
{
Expand Down Expand Up @@ -422,6 +460,8 @@ void aiMeshSchema<T, U>::updateSummary()
if (summary.has_rgb_prop && !summary.constant_rgb)
summary.interpolate_rgb = true;
}

summary.numV2FVertexProperties = m_IV2fGeomParam.size();
}

template<typename T, typename U>
Expand Down Expand Up @@ -539,6 +579,25 @@ void aiMeshSchema<T, U>::readSampleBody(U& sample, uint64_t idx)
}
}

if (sample.m_IV2fGeomParam_sp.size() != m_IV2fGeomParam.size())
{
sample.m_IV2fGeomParam_sp = std::vector<AbcGeom::IV2fGeomParam::Sample>(m_IV2fGeomParam.size());
}

if (sample.m_IV2fGeomParamName.size() != m_IV2fGeomParam.size())
{
sample.m_IV2fGeomParamName = std::vector<FixedString128>(m_IV2fGeomParam.size());
}

for (int i = 0; i < m_IV2fGeomParam.size(); ++i)
{
auto param = m_IV2fGeomParam[i];
// sample.m_IV2fGeomParamName[i]. = param.getName();
strncpy(sample.m_IV2fGeomParamName[i].String, param.getName().c_str(), std::min(FixedString128::MaxLength, param.getName().size()));
param.getIndexed(sample.m_IV2fGeomParam_sp[i], ss);
/// deal with interpolation
}

auto bounds_param = this->m_schema.getSelfBoundsProperty();
if (bounds_param && bounds_param.getNumSamples() > 0)
bounds_param.get(sample.m_bounds, ss);
Expand All @@ -562,7 +621,7 @@ void aiMeshSchema<T, U>::cookSampleBody(U& sample)
{
onTopologyChange(sample);
}
else if (this->m_sample_index_changed)
else if (this->m_sample_index_changed) // Not happening in solutions
{
onTopologyDetermined();

Expand Down Expand Up @@ -966,6 +1025,42 @@ void aiMeshSchema<T, U>::onTopologyChange(U& sample)
}


/// Arbitrary V2f attributes
if (sample.m_IV2fGeomParam.size() != sample.m_IV2fGeomParam_sp.size())
{
sample.m_IV2fGeomParam = std::vector<RawVector<abcV2> >(sample.m_IV2fGeomParam_sp.size());
}

if (topology.m_remap_m_IV2fGeomParam.size() != sample.m_IV2fGeomParam_sp.size())
{
topology.m_remap_m_IV2fGeomParam = std::vector<RawVector<int> >(sample.m_IV2fGeomParam_sp.size());
}

for (int i = 0; i < sample.m_IV2fGeomParam_sp.size(); ++i)
{
auto sp = sample.m_IV2fGeomParam_sp[i];
if (sp.valid())
{
IArray<abcV2> src{sp.getVals()->get(), sp.getVals()->size()};
auto &dst = sample.m_IV2fGeomParam[i];

if (sp.isIndexed() && sp.getIndices()->size() == refiner.indices.size())
{
IArray<int> indices{(int *)sp.getIndices()->get(), sp.getIndices()->size()};
refiner.template addIndexedAttribute<abcV2>(src, indices, dst, topology.m_remap_m_IV2fGeomParam[i]);
}
else if (src.size() == refiner.indices.size())
{
refiner.template addExpandedAttribute<abcV2>(src, dst, topology.m_remap_m_IV2fGeomParam[i]);
}
else if (src.size() == refiner.points.size())
{
refiner.template addIndexedAttribute<abcV2>(src, refiner.indices, dst, topology.m_remap_m_IV2fGeomParam[i]);
}
}
}
///

refiner.refine();
refiner.retopology(config.swap_face_winding);

Expand Down Expand Up @@ -1180,6 +1275,18 @@ void aiMeshSample<T>::fillSplitVertices(int split_index, aiPolyMeshData &data) c
copy_or_clear(data.uv1, m_uv1_ref, split);
copy_or_clear((abcC4*)data.rgba, m_rgba_ref, split);
copy_or_clear_3_to_4<abcC4, abcC3>((abcC4*)data.rgb, m_rgb_ref, split);

if (data.v2fParams != nullptr)
{
for (int i = 0; i < m_IV2fGeomParam.size(); ++i)
{
abcV2 *dst = data.v2fParams[i];
copy_or_clear(dst, m_IV2fGeomParam[i], split);

// data.v2fParamNames[i] = m_IV2fGeomParamName[i];
// strncpy(data.v2fParamNames[i].String, m_IV2fGeomParamName[i].String, FixedString128::MaxLength);
}
}
}

template<typename T>
Expand All @@ -1203,3 +1310,9 @@ void aiMeshSample<T>::fillVertexBuffer(aiPolyMeshData * vbs, aiSubmeshData * ibs
for (int smi = 0; smi < (int)refiner.submeshes.size(); ++smi)
fillSubmeshIndices(smi, ibs[smi]);
}

template<typename T>
char* aiMeshSample<T>::readPropertyName(int idx)
{
return &(m_IV2fGeomParamName[idx].String[0]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.Collections;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script is a example on how to map the custom vertex attributes to Mesh UV2-3-4 (Solution Ask)

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Formats.Alembic.Importer;

[ExecuteInEditMode]
public class AlembicMeshCustomDataMapper : MonoBehaviour
{
AlembicCustomData customData;

Mesh mesh;
// Start is called before the first frame update

// Update is called once per frame
void LateUpdate()
{
customData = GetComponent<AlembicCustomData>();
var mf = GetComponent<MeshFilter>();
if (mf != null)
{
mesh = mf.sharedMesh;
}

if (customData == null || mesh == null)
{
return;
}

// Make sure the Alembic is up to date;
var asp = GetComponentInParent<AlembicStreamPlayer>();
asp.UpdateImmediately(asp.CurrentTime);

foreach (var attribute in customData.VertexAttributes)
{

if (attribute.Name == "furUVs")
{
mesh.SetUVs(1, attribute.Data);
}
else if (attribute.Name == "rigUVs")
{
mesh.SetUVs(3, attribute.Data);
}
else if (attribute.Name == "transferUVs")
{
mesh.SetUVs(2, attribute.Data);
}
else
{
Debug.LogWarning($"Unhandled Attribute: {attribute.Name.Value}");
}


}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions com.unity.formats.alembic/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.4.0-pre.1] - 2022-12-05
### Added
- Added support for custom Vector2 Mesh vertex attributes.
### Changed
### Fixed

## [2.3.1] - 2022-12-06
### Added
### Changed
Expand Down
Loading