Skip to content

Commit

Permalink
Add support for color and curve ramps.
Browse files Browse the repository at this point in the history
  • Loading branch information
est77 committed May 8, 2018
1 parent 4543278 commit a6daee2
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/appleseedmaya/CMakeLists.txt
Expand Up @@ -65,6 +65,7 @@ set (appleseed_maya_sources
pluginmain.cpp
pythonbridge.cpp
pythonbridge.h
ramputils.h
rendercommands.cpp
rendercommands.h
renderercontroller.h
Expand Down
44 changes: 9 additions & 35 deletions src/appleseedmaya/exporters/rampexporter.cpp
Expand Up @@ -32,6 +32,7 @@
// appleseed-maya headers.
#include "appleseedmaya/attributeutils.h"
#include "appleseedmaya/exporters/exporterfactory.h"
#include "appleseedmaya/ramputils.h"
#include "appleseedmaya/shadingnodemetadata.h"

// appleseed.renderer headers.
Expand All @@ -50,26 +51,6 @@
namespace asf = foundation;
namespace asr = renderer;

namespace
{
struct RampEntry
{
RampEntry(float pos, const MColor& col)
: m_pos(pos)
, m_col(col)
{
}

bool operator<(const RampEntry& other) const
{
return m_pos < other.m_pos;
}

float m_pos;
MColor m_col;
};
}

void RampExporter::registerExporter()
{
NodeExporterFactory::registerShadingNodeExporter(
Expand Down Expand Up @@ -103,7 +84,7 @@ void RampExporter::exportParameterValue(
{
MPlug plug = depNodeFn.findPlug("colorEntryList", false, &status);

std::vector<RampEntry> rampColors;
std::vector<RampEntry<MColor>> rampColors;
rampColors.reserve(plug.numElements());

for (unsigned int i = 0, e = plug.numElements(); i < e; ++i)
Expand All @@ -118,7 +99,7 @@ void RampExporter::exportParameterValue(
MColor c;
AttributeUtils::get(color, c);

rampColors.push_back(RampEntry(p, c));
rampColors.push_back(RampEntry<MColor>(i, p, c));
}

plug = depNodeFn.findPlug("type", false, &status);
Expand All @@ -130,27 +111,20 @@ void RampExporter::exportParameterValue(
{
// Fill with black if we have less than 4 elements.
while (rampColors.size() < 4)
rampColors.push_back(RampEntry(1.0f, MColor(0.0f, 0.0f, 0.0f)));
rampColors.push_back(RampEntry<MColor>(rampColors.size(), 1.0f, MColor(0.0f, 0.0f, 0.0f)));
}
else
{
// Sort the ramp entries.
std::sort(rampColors.begin(), rampColors.end());
}

std::stringstream ssp;
ssp << "float[] ";

std::stringstream ssc;
ssc << "color[] ";
for (size_t i = 0, e = rampColors.size(); i < e; ++i)
{
ssp << rampColors[i].m_pos << " ";
ssc << rampColors[i].m_col.r << " " << rampColors[i].m_col.g << " " << rampColors[i].m_col.b << " ";
}
std::string values;
std::string positions;
serializeRamp(rampColors, values, positions);

shaderParams.insert("in_position", ssp.str().c_str());
shaderParams.insert("in_color" , ssc.str().c_str());
shaderParams.insert("in_position", positions.c_str());
shaderParams.insert("in_color" , values.c_str());
}
else if (paramInfo.paramName == "in_color")
{
Expand Down
91 changes: 88 additions & 3 deletions src/appleseedmaya/exporters/shadingnodeexporter.cpp
Expand Up @@ -33,6 +33,7 @@
#include "appleseedmaya/attributeutils.h"
#include "appleseedmaya/exporters/exporterfactory.h"
#include "appleseedmaya/logger.h"
#include "appleseedmaya/ramputils.h"
#include "appleseedmaya/shadingnodemetadata.h"
#include "appleseedmaya/shadingnoderegistry.h"

Expand All @@ -48,11 +49,14 @@
#include <maya/MFnDependencyNode.h>
#include <maya/MFnEnumAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MRampAttribute.h>
#include <maya/MStringArray.h>
#include "appleseedmaya/_endmayaheaders.h"

// Standard headers.
#include <algorithm>
#include <sstream>
#include <vector>

namespace asf = foundation;
namespace asr = renderer;
Expand Down Expand Up @@ -447,10 +451,25 @@ void ShadingNodeExporter::exportParameterValue(
const OSLParamInfo& paramInfo,
renderer::ParamArray& shaderParams) const
{
if (paramInfo.isArray)
exportArrayValue(plug, paramInfo, shaderParams);
if (paramInfo.asWidget == "ramp")
exportRampValue(plug, paramInfo, shaderParams);
else if (paramInfo.asWidget == "ramp_positions")
{
// Ramp positions are saved as part of the ramp.
return;
}
else if (paramInfo.asWidget == "ramp_basis")
{
// Ramp basis is saved as part of the ramp.
return;
}
else
exportValue(plug, paramInfo, shaderParams);
{
if (paramInfo.isArray)
exportArrayValue(plug, paramInfo, shaderParams);
else
exportValue(plug, paramInfo, shaderParams);
}
}

void ShadingNodeExporter::exportValue(
Expand Down Expand Up @@ -634,6 +653,72 @@ void ShadingNodeExporter::exportArrayValue(
}
}

namespace
{
template <typename T>
void getRampValues(
MRampAttribute& ramp,
std::vector<RampEntry<T>>& entries)
{
entries.clear();
entries.reserve(ramp.getNumEntries());

MIntArray indices;
MFloatArray positions;
MIntArray interps;

typename RampEntryTraits<T>::ArrayType values;

ramp.getEntries(indices, positions, values, interps);

for (size_t i = 0 , e = ramp.getNumEntries() ; i < e ; ++i )
entries.push_back(RampEntry<T>(indices[i], positions[i], values[i]));
}
}

void ShadingNodeExporter::exportRampValue(
const MPlug& plug,
const OSLParamInfo& paramInfo,
renderer::ParamArray& shaderParams) const
{
MRampAttribute ramp(plug);
std::string values;
std::string positions;
// std::string basis;

if (paramInfo.paramType == "color")
{
std::vector<RampEntry<MColor>> entries;
getRampValues(ramp, entries);
getRampValues(ramp, entries);
serializeRamp(entries, values, positions);
}
else if (paramInfo.paramType == "float")
{
std::vector<RampEntry<float>> entries;
getRampValues(ramp, entries);
serializeRamp(entries, values, positions);
}
else
{
RENDERER_LOG_WARNING(
"Skipping shading node attr %s of unknown type %s ramp.",
paramInfo.mayaAttributeName.asChar(),
paramInfo.paramType.asChar());
return;
}

shaderParams.insert(paramInfo.paramName.asChar(), values.c_str());

std::string positionsParamName = asf::replace(
paramInfo.paramName.asChar(),
"_values",
"_positions");
shaderParams.insert(positionsParamName.c_str(), positions.c_str());

// todo: save basis here...
}

MObject ShadingNodeExporter::node() const
{
return m_object;
Expand Down
5 changes: 5 additions & 0 deletions src/appleseedmaya/exporters/shadingnodeexporter.h
Expand Up @@ -95,6 +95,11 @@ class ShadingNodeExporter
const OSLParamInfo& paramInfo,
renderer::ParamArray& shaderParams) const;

void exportRampValue(
const MPlug& plug,
const OSLParamInfo& paramInfo,
renderer::ParamArray& shaderParams) const;

virtual bool layerAndParamNameFromPlug(
const MPlug& plug,
MString& layerName,
Expand Down
118 changes: 118 additions & 0 deletions src/appleseedmaya/ramputils.h
@@ -0,0 +1,118 @@

//
// This source file is part of appleseed.
// Visit https://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2018 Esteban Tovagliari, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#ifndef APPLESEED_MAYA_RAMP_UTILS_H
#define APPLESEED_MAYA_RAMP_UTILS_H

// Maya headers.
#include "appleseedmaya/_beginmayaheaders.h"
#include <maya/MColor.h>
#include <maya/MColorArray.h>
#include <maya/MFloatArray.h>
#include "appleseedmaya/_endmayaheaders.h"

// Standard headers.
#include <sstream>
#include <string>
#include <vector>

template <typename T>
struct RampEntry
{
RampEntry(int index, float pos, const T& value)
: m_index(index)
, m_pos(pos)
, m_value(value)
{
}

bool operator<(const RampEntry<T>& other) const
{
return m_pos < other.m_pos;
}

int m_index;
float m_pos;
T m_value;
};

template <typename T> struct RampEntryTraits {};

template <> struct RampEntryTraits<MColor>
{
typedef MColorArray ArrayType;

static const char* paramValueTypeName()
{
return "color[]";
}

static void outputValue(std::stringstream& ss, const MColor& value)
{
ss << value.r << " " << value.g << " " << value.b << " ";
}
};

template <> struct RampEntryTraits<float>
{
typedef MFloatArray ArrayType;

static const char* paramValueTypeName()
{
return "float[]";
}

static void outputValue(std::stringstream& ss, const float& value)
{
ss << value << " ";
}
};

template <typename T>
void serializeRamp(
const std::vector<RampEntry<T>>& entries,
std::string& outValues,
std::string& outPositions)
{
std::stringstream ssp;
ssp << "float[] ";

std::stringstream ssv;
ssv << RampEntryTraits<T>::paramValueTypeName() << " ";

for (size_t i = 0, e = entries.size(); i < e; ++i)
{
ssp << entries[i].m_pos << " ";
RampEntryTraits<T>::outputValue(ssv, entries[i].m_value);
}

outValues = ssv.str();
outPositions = ssp.str();
}

#endif // !APPLESEED_MAYA_RAMP_UTILS_H

0 comments on commit a6daee2

Please sign in to comment.