forked from blender/blender
Export curves #46
@ -74,6 +74,8 @@ set(SRC
|
|||||||
scene_delegate/material.cc
|
scene_delegate/material.cc
|
||||||
scene_delegate/mesh.h
|
scene_delegate/mesh.h
|
||||||
scene_delegate/mesh.cc
|
scene_delegate/mesh.cc
|
||||||
|
scene_delegate/curves.h
|
||||||
|
scene_delegate/curves.cc
|
||||||
scene_delegate/mtlx_hydra_adapter.h
|
scene_delegate/mtlx_hydra_adapter.h
|
||||||
scene_delegate/mtlx_hydra_adapter.cc
|
scene_delegate/mtlx_hydra_adapter.cc
|
||||||
scene_delegate/light.h
|
scene_delegate/light.h
|
||||||
|
@ -27,6 +27,13 @@ pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id
|
|||||||
return m_data->mesh_topology(id);
|
return m_data->mesh_topology(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pxr::HdBasisCurvesTopology BlenderSceneDelegate::GetBasisCurvesTopology(pxr::SdfPath const &id)
|
||||||
|
{
|
||||||
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||||
|
CurvesData *c_data = curves_data(id);
|
||||||
|
return c_data->curves_topology(id);
|
||||||
|
};
|
||||||
|
|
||||||
pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
|
pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||||
@ -51,6 +58,10 @@ pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken cons
|
|||||||
if (m_data) {
|
if (m_data) {
|
||||||
return m_data->get_data(id, key);
|
return m_data->get_data(id, key);
|
||||||
}
|
}
|
||||||
|
CurvesData *c_data = curves_data(id);
|
||||||
|
if (c_data) {
|
||||||
|
return c_data->get_data(id, key);
|
||||||
|
}
|
||||||
ObjectData *obj_data = object_data(id);
|
ObjectData *obj_data = object_data(id);
|
||||||
if (obj_data) {
|
if (obj_data) {
|
||||||
return obj_data->get_data(key);
|
return obj_data->get_data(key);
|
||||||
@ -88,6 +99,10 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(
|
|||||||
if (m_data) {
|
if (m_data) {
|
||||||
return m_data->primvar_descriptors(interpolation);
|
return m_data->primvar_descriptors(interpolation);
|
||||||
}
|
}
|
||||||
|
CurvesData *c_data = curves_data(id);
|
||||||
|
if (c_data) {
|
||||||
|
return c_data->primvar_descriptors(interpolation);
|
||||||
|
}
|
||||||
InstancerData *i_data = instancer_data(id);
|
InstancerData *i_data = instancer_data(id);
|
||||||
if (i_data) {
|
if (i_data) {
|
||||||
return i_data->primvar_descriptors(interpolation);
|
return i_data->primvar_descriptors(interpolation);
|
||||||
@ -98,7 +113,15 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(
|
|||||||
pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
|
pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", rprim_id.GetText());
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", rprim_id.GetText());
|
||||||
return mesh_data(rprim_id)->material_id(rprim_id);
|
MeshData *m_data = mesh_data(rprim_id);
|
||||||
|
if (m_data) {
|
||||||
|
return m_data->material_id(rprim_id);
|
||||||
|
}
|
||||||
|
CurvesData *c_data = curves_data(rprim_id);
|
||||||
|
if (c_data) {
|
||||||
|
return c_data->material_id();
|
||||||
|
}
|
||||||
|
return pxr::SdfPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
|
pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
|
||||||
@ -262,6 +285,11 @@ MeshData *BlenderSceneDelegate::mesh_data(pxr::SdfPath const &id) const
|
|||||||
return dynamic_cast<MeshData *>(object_data(id));
|
return dynamic_cast<MeshData *>(object_data(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurvesData *BlenderSceneDelegate::curves_data(pxr::SdfPath const &id) const
|
||||||
|
{
|
||||||
|
return dynamic_cast<CurvesData *>(object_data(id));
|
||||||
|
}
|
||||||
|
|
||||||
LightData *BlenderSceneDelegate::light_data(pxr::SdfPath const &id) const
|
LightData *BlenderSceneDelegate::light_data(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
return dynamic_cast<LightData *>(object_data(id));
|
return dynamic_cast<LightData *>(object_data(id));
|
||||||
@ -549,6 +577,10 @@ void BlenderSceneDelegate::remove_unused_objects()
|
|||||||
if (m_data) {
|
if (m_data) {
|
||||||
m_data->available_materials(available_materials);
|
m_data->available_materials(available_materials);
|
||||||
}
|
}
|
||||||
|
CurvesData *c_data = dynamic_cast<CurvesData *>(it.second.get());
|
||||||
|
if (c_data) {
|
||||||
|
c_data->available_materials(available_materials);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (auto &it : instancers_) {
|
for (auto &it : instancers_) {
|
||||||
it.second->available_materials(available_materials);
|
it.second->available_materials(available_materials);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "CLG_log.h"
|
#include "CLG_log.h"
|
||||||
|
|
||||||
|
#include "curves.h"
|
||||||
#include "instancer.h"
|
#include "instancer.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
@ -25,6 +26,7 @@ class Engine;
|
|||||||
|
|
||||||
class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
||||||
friend ObjectData; /* has access to instances */
|
friend ObjectData; /* has access to instances */
|
||||||
|
friend CurvesData; /* has access to materials */
|
||||||
friend MeshData; /* has access to materials */
|
friend MeshData; /* has access to materials */
|
||||||
friend MaterialData; /* has access to objects and instancers */
|
friend MaterialData; /* has access to objects and instancers */
|
||||||
|
|
||||||
@ -40,6 +42,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
|||||||
|
|
||||||
/* Delegate methods */
|
/* Delegate methods */
|
||||||
pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override;
|
pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override;
|
||||||
|
pxr::HdBasisCurvesTopology GetBasisCurvesTopology(pxr::SdfPath const &id) override;
|
||||||
pxr::GfMatrix4d GetTransform(pxr::SdfPath const &id) override;
|
pxr::GfMatrix4d GetTransform(pxr::SdfPath const &id) override;
|
||||||
pxr::VtValue Get(pxr::SdfPath const &id, pxr::TfToken const &key) override;
|
pxr::VtValue Get(pxr::SdfPath const &id, pxr::TfToken const &key) override;
|
||||||
pxr::VtValue GetLightParamValue(pxr::SdfPath const &id, pxr::TfToken const &key) override;
|
pxr::VtValue GetLightParamValue(pxr::SdfPath const &id, pxr::TfToken const &key) override;
|
||||||
@ -76,6 +79,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
|||||||
|
|
||||||
ObjectData *object_data(pxr::SdfPath const &id) const;
|
ObjectData *object_data(pxr::SdfPath const &id) const;
|
||||||
MeshData *mesh_data(pxr::SdfPath const &id) const;
|
MeshData *mesh_data(pxr::SdfPath const &id) const;
|
||||||
|
CurvesData *curves_data(pxr::SdfPath const &id) const;
|
||||||
LightData *light_data(pxr::SdfPath const &id) const;
|
LightData *light_data(pxr::SdfPath const &id) const;
|
||||||
MaterialData *material_data(pxr::SdfPath const &id) const;
|
MaterialData *material_data(pxr::SdfPath const &id) const;
|
||||||
InstancerData *instancer_data(pxr::SdfPath const &id, bool child_id = false) const;
|
InstancerData *instancer_data(pxr::SdfPath const &id, bool child_id = false) const;
|
||||||
|
209
source/blender/render/hydra/scene_delegate/curves.cc
Normal file
209
source/blender/render/hydra/scene_delegate/curves.cc
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0
|
||||||
|
* Copyright 2011-2022 Blender Foundation */
|
||||||
|
|
||||||
|
#include <pxr/base/gf/vec2f.h>
|
||||||
|
#include <pxr/imaging/hd/tokens.h>
|
||||||
|
|
||||||
|
#include "BKE_customdata.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
|
||||||
|
#include "blender_scene_delegate.h"
|
||||||
|
|
||||||
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
|
CurvesData::CurvesData(BlenderSceneDelegate *scene_delegate,
|
||||||
|
Object *object,
|
||||||
|
pxr::SdfPath const &prim_id)
|
||||||
|
: ObjectData(scene_delegate, object, prim_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurvesData::init()
|
||||||
|
{
|
||||||
|
ID_LOG(2, "");
|
||||||
|
|
||||||
|
Object *object = (Object *)id;
|
||||||
|
write_curves((Curves *)object->data);
|
||||||
|
write_transform();
|
||||||
|
write_material();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurvesData::insert()
|
||||||
|
{
|
||||||
|
ID_LOG(2, "");
|
||||||
|
scene_delegate_->GetRenderIndex().InsertRprim(
|
||||||
|
pxr::HdPrimTypeTokens->basisCurves, scene_delegate_, prim_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurvesData::remove()
|
||||||
|
{
|
||||||
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
|
||||||
|
scene_delegate_->GetRenderIndex().RemoveRprim(prim_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurvesData::update()
|
||||||
|
{
|
||||||
|
Object *object = (Object *)id;
|
||||||
|
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
|
||||||
|
if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) {
|
||||||
|
init();
|
||||||
|
bits = pxr::HdChangeTracker::AllDirty;
|
||||||
|
}
|
||||||
|
if (id->recalc & ID_RECALC_SHADING) {
|
||||||
|
write_material();
|
||||||
|
bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided;
|
||||||
|
}
|
||||||
|
if (id->recalc & ID_RECALC_TRANSFORM) {
|
||||||
|
write_transform();
|
||||||
|
bits |= pxr::HdChangeTracker::DirtyTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bits == pxr::HdChangeTracker::Clean) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(prim_id, bits);
|
||||||
|
ID_LOG(2, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
pxr::VtValue CurvesData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const
|
||||||
|
{
|
||||||
|
pxr::VtValue ret;
|
||||||
|
if (key == pxr::HdTokens->points) {
|
||||||
|
ret = vertices_;
|
||||||
|
}
|
||||||
|
else if (key == pxr::HdPrimvarRoleTokens->textureCoordinate) {
|
||||||
|
ret = uvs_;
|
||||||
|
}
|
||||||
|
else if (key == pxr::HdTokens->widths) {
|
||||||
|
ret = widths_;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CurvesData::update_visibility()
|
||||||
|
{
|
||||||
|
bool ret = ObjectData::update_visibility();
|
||||||
|
if (ret) {
|
||||||
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
|
||||||
|
prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||||
|
ID_LOG(2, "");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxr::HdBasisCurvesTopology CurvesData::curves_topology(pxr::SdfPath const &id) const
|
||||||
|
{
|
||||||
|
return pxr::HdBasisCurvesTopology(pxr::HdTokens->linear,
|
||||||
|
pxr::TfToken(),
|
||||||
|
pxr::HdTokens->nonperiodic,
|
||||||
|
curve_vertex_counts_,
|
||||||
|
pxr::VtIntArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
pxr::HdPrimvarDescriptorVector CurvesData::primvar_descriptors(
|
||||||
|
pxr::HdInterpolation interpolation) const
|
||||||
|
{
|
||||||
|
pxr::HdPrimvarDescriptorVector primvars;
|
||||||
|
if (interpolation == pxr::HdInterpolationVertex) {
|
||||||
|
if (!vertices_.empty()) {
|
||||||
|
primvars.emplace_back(pxr::HdTokens->points, interpolation, pxr::HdPrimvarRoleTokens->point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (interpolation == pxr::HdInterpolationFaceVarying) {
|
||||||
|
if (!uvs_.empty()) {
|
||||||
|
primvars.emplace_back(pxr::HdPrimvarRoleTokens->textureCoordinate,
|
||||||
|
interpolation,
|
||||||
|
pxr::HdPrimvarRoleTokens->textureCoordinate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (interpolation == pxr::HdInterpolationConstant) {
|
||||||
|
if (!widths_.empty()) {
|
||||||
|
primvars.emplace_back(pxr::HdTokens->widths, interpolation, pxr::HdPrimvarRoleTokens->none);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return primvars;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxr::SdfPath CurvesData::material_id() const
|
||||||
|
{
|
||||||
|
if (!mat_data_) {
|
||||||
|
return pxr::SdfPath();
|
||||||
|
}
|
||||||
|
return mat_data_->prim_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurvesData::available_materials(std::set<pxr::SdfPath> &paths) const
|
||||||
|
{
|
||||||
|
if (mat_data_ && !mat_data_->prim_id.IsEmpty()) {
|
||||||
|
paths.insert(mat_data_->prim_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurvesData::write_curves(Curves *curves)
|
||||||
|
{
|
||||||
|
curve_vertex_counts_.clear();
|
||||||
|
widths_.clear();
|
||||||
|
vertices_.clear();
|
||||||
|
|
||||||
|
const float *radii = (const float *)CustomData_get_layer_named(
|
||||||
|
&curves->geometry.point_data, CD_PROP_FLOAT, "radius");
|
||||||
|
const float(*positions)[3] = (const float(*)[3])CustomData_get_layer_named(
|
||||||
|
&curves->geometry.point_data, CD_PROP_FLOAT3, "position");
|
||||||
|
|
||||||
|
vertices_.reserve(curves->geometry.curve_num);
|
||||||
|
|
||||||
|
for (int i = 0; i < curves->geometry.curve_num; i++) {
|
||||||
|
int first_point_index = *(curves->geometry.curve_offsets + i);
|
||||||
|
int num_points = *(curves->geometry.curve_offsets + i + 1) - first_point_index;
|
||||||
|
curve_vertex_counts_.push_back(num_points);
|
||||||
|
|
||||||
|
/* Set radius similar to Cycles if isn't set */
|
||||||
|
widths_.push_back(radii ? radii[i] : 0.01f);
|
||||||
|
|
||||||
|
for (int j = 0; j < num_points; j++) {
|
||||||
|
int ind = first_point_index + j;
|
||||||
|
vertices_.push_back(pxr::GfVec3f(positions[ind][0], positions[ind][1], positions[ind][2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write_uv_maps(curves);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurvesData::write_uv_maps(Curves *curves)
|
||||||
|
{
|
||||||
|
uvs_.clear();
|
||||||
|
|
||||||
|
const float(*uvs)[2] = (const float(*)[2])CustomData_get_layer_named(
|
||||||
|
&curves->geometry.curve_data, CD_PROP_FLOAT2, "surface_uv_coordinate");
|
||||||
|
if (uvs) {
|
||||||
|
for (int i = 0; i < curves->geometry.curve_num; i++) {
|
||||||
|
uvs_.push_back(pxr::GfVec2f(uvs[i][0], uvs[i][1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurvesData::write_material()
|
||||||
|
{
|
||||||
|
Object *object = (Object *)id;
|
||||||
|
Material *mat = nullptr;
|
||||||
|
if (BKE_object_material_count_eval(object) > 0) {
|
||||||
|
mat = BKE_object_material_get_eval(object, object->actcol);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mat) {
|
||||||
|
mat_data_ = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
|
||||||
|
mat_data_ = scene_delegate_->material_data(p_id);
|
||||||
|
if (!mat_data_) {
|
||||||
|
scene_delegate_->materials_[p_id] = std::make_unique<MaterialData>(scene_delegate_, mat, p_id);
|
||||||
|
mat_data_ = scene_delegate_->material_data(p_id);
|
||||||
|
mat_data_->init();
|
||||||
|
mat_data_->insert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::render::hydra
|
47
source/blender/render/hydra/scene_delegate/curves.h
Normal file
47
source/blender/render/hydra/scene_delegate/curves.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0
|
||||||
|
* Copyright 2011-2022 Blender Foundation */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pxr/base/vt/array.h>
|
||||||
|
#include <pxr/imaging/hd/sceneDelegate.h>
|
||||||
|
|
||||||
|
#include "BKE_duplilist.h"
|
||||||
|
#include "DNA_Curves_types.h"
|
||||||
|
|
||||||
|
#include "material.h"
|
||||||
|
#include "object.h"
|
||||||
|
|
||||||
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
|
class CurvesData : public ObjectData {
|
||||||
|
public:
|
||||||
|
CurvesData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||||
|
|
||||||
|
void init() override;
|
||||||
|
void insert() override;
|
||||||
|
void remove() override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
pxr::VtValue get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const;
|
||||||
|
bool update_visibility() override;
|
||||||
|
|
||||||
|
pxr::HdBasisCurvesTopology curves_topology(pxr::SdfPath const &id) const;
|
||||||
|
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
|
||||||
|
pxr::SdfPath material_id() const;
|
||||||
|
void available_materials(std::set<pxr::SdfPath> &paths) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void write_curves(Curves *curves);
|
||||||
|
void write_uv_maps(Curves *curves);
|
||||||
|
void write_material();
|
||||||
|
|
||||||
|
pxr::VtIntArray curve_vertex_counts_;
|
||||||
|
pxr::VtVec3fArray vertices_;
|
||||||
|
pxr::VtVec2fArray uvs_;
|
||||||
|
pxr::VtFloatArray widths_;
|
||||||
|
|
||||||
|
MaterialData *mat_data_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blender::render::hydra
|
@ -5,6 +5,7 @@
|
|||||||
#include "DEG_depsgraph_query.h"
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
#include "blender_scene_delegate.h"
|
#include "blender_scene_delegate.h"
|
||||||
|
#include "curves.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
@ -32,7 +33,9 @@ std::unique_ptr<ObjectData> ObjectData::create(BlenderSceneDelegate *scene_deleg
|
|||||||
case OB_MBALL:
|
case OB_MBALL:
|
||||||
data = std::make_unique<MeshData>(scene_delegate, object, prim_id);
|
data = std::make_unique<MeshData>(scene_delegate, object, prim_id);
|
||||||
break;
|
break;
|
||||||
|
case OB_CURVES:
|
||||||
|
data = std::make_unique<CurvesData>(scene_delegate, object, prim_id);
|
||||||
|
break;
|
||||||
case OB_LAMP:
|
case OB_LAMP:
|
||||||
data = std::make_unique<LightData>(scene_delegate, object, prim_id);
|
data = std::make_unique<LightData>(scene_delegate, object, prim_id);
|
||||||
break;
|
break;
|
||||||
@ -49,6 +52,7 @@ bool ObjectData::is_supported(Object *object)
|
|||||||
case OB_MESH:
|
case OB_MESH:
|
||||||
case OB_SURF:
|
case OB_SURF:
|
||||||
case OB_FONT:
|
case OB_FONT:
|
||||||
|
case OB_CURVES:
|
||||||
case OB_CURVES_LEGACY:
|
case OB_CURVES_LEGACY:
|
||||||
case OB_MBALL:
|
case OB_MBALL:
|
||||||
case OB_LAMP:
|
case OB_LAMP:
|
||||||
|
Loading…
Reference in New Issue
Block a user