Skip to content

Commit

Permalink
Merge pull request #5588 from danieldresser-ie/deepSlice
Browse files Browse the repository at this point in the history
Deep Slice
  • Loading branch information
danieldresser-ie authored Dec 18, 2023
2 parents 187c800 + 9cc5193 commit c880dd7
Show file tree
Hide file tree
Showing 19 changed files with 2,013 additions and 2 deletions.
6 changes: 6 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
1.x.x.x (relative to 1.3.x.x)
=======

Features
--------

- GafferImage : Added DeepSlice node for clipping out part of an image based on depth.

Improvements
------------

Expand Down Expand Up @@ -63,6 +68,7 @@ API
- Added `ignoreMissingSource` argument to `shuffle()`.
- Added `shuffleWithExtraSources()` method.
- ShufflePlugValueWidget : Widgets for the `source` and `destination` plugs can now be customised using standard `plugValueWidget:type` metadata.
- ImageTestCase : in `assertImageEqual` function, maxDifference may now be a tuple, to specify an asymmetric range.

Breaking Changes
----------------
Expand Down
195 changes: 195 additions & 0 deletions contrib/dd/buildDeepTestData.gfr

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions include/GafferImage/DeepSampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,6 @@ class GAFFERIMAGE_API DeepSampler : public Gaffer::ComputeNode

};

IE_CORE_DECLAREPTR( DeepSampler )

} // namespace GafferImage
102 changes: 102 additions & 0 deletions include/GafferImage/DeepSlice.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2023, Image Engine Design Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above
// copyright notice, this list of conditions and the following
// disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided with
// the distribution.
//
// * Neither the name of John Haddon nor the names of
// any other contributors to this software may be used to endorse or
// promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#pragma once

#include "GafferImage/ImageProcessor.h"

#include "Gaffer/OptionalValuePlug.h"
#include "Gaffer/NumericPlug.h"

namespace Gaffer
{

IE_CORE_FORWARDDECLARE( StringPlug )

} // namespace Gaffer

namespace GafferImage
{

class GAFFERIMAGE_API DeepSlice : public ImageProcessor
{
public :

explicit DeepSlice( const std::string &name=defaultName<DeepSlice>() );
~DeepSlice() override;

GAFFER_NODE_DECLARE_TYPE( GafferImage::DeepSlice, DeepSliceTypeId, ImageProcessor );

Gaffer::OptionalValuePlug *nearClipPlug();
const Gaffer::OptionalValuePlug *nearClipPlug() const;

Gaffer::OptionalValuePlug *farClipPlug();
const Gaffer::OptionalValuePlug *farClipPlug() const;

Gaffer::BoolPlug *flattenPlug();
const Gaffer::BoolPlug *flattenPlug() const;

void affects( const Gaffer::Plug *input, AffectedPlugsContainer &outputs ) const override;

protected :

void hash( const Gaffer::ValuePlug *output, const Gaffer::Context *context, IECore::MurmurHash &h ) const override;
void compute( Gaffer::ValuePlug *output, const Gaffer::Context *context ) const override;

void hashChannelData( const GafferImage::ImagePlug *parent, const Gaffer::Context *context, IECore::MurmurHash &h ) const override;
IECore::ConstFloatVectorDataPtr computeChannelData( const std::string &channelName, const Imath::V2i &tileOrigin, const Gaffer::Context *context, const ImagePlug *parent ) const override;

void hashSampleOffsets( const GafferImage::ImagePlug *parent, const Gaffer::Context *context, IECore::MurmurHash &h ) const override;
IECore::ConstIntVectorDataPtr computeSampleOffsets( const Imath::V2i &tileOrigin, const Gaffer::Context *context, const ImagePlug *parent ) const override;

void hashDeep( const GafferImage::ImagePlug *parent, const Gaffer::Context *context, IECore::MurmurHash &h ) const override;
bool computeDeep( const Gaffer::Context *context, const ImagePlug *parent ) const override;

private :

ImagePlug *tidyInPlug();
const ImagePlug *tidyInPlug() const;

Gaffer::CompoundObjectPlug *sliceDataPlug();
const Gaffer::CompoundObjectPlug *sliceDataPlug() const;

static size_t g_firstPlugIndex;

};

IE_CORE_DECLAREPTR( DeepSlice )

} // namespace GafferImage
1 change: 1 addition & 0 deletions include/GafferImage/TypeIds.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ enum TypeId
DeepHoldoutTypeId = 110833,
DeepRecolorTypeId = 110834,
SaturationTypeId = 110835,
DeepSliceTypeId = 110836,

LastTypeId = 110849
};
Expand Down
28 changes: 28 additions & 0 deletions python/GafferImageTest/ConstantTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,5 +208,33 @@ def testLayerAffectsChannelNames( self ) :

self.assertTrue( c["out"]["channelNames"] in set( [ x[0] for x in cs ] ) )

def testAssertImagesEqual( self ) :

a = GafferImage.Constant()
a["color"].setValue( imath.Color4f( 0.5 ) )

b = GafferImage.Constant()
b["color"].setValue( imath.Color4f( 0.5 ) )

self.assertImagesEqual( a["out"], b["out"] )

a["color"].setValue( imath.Color4f( 0.75 ) )

with self.assertRaisesRegex( AssertionError, "0.25 not less than or equal to 0.0 : Channel R" ) :
self.assertImagesEqual( a["out"], b["out"] )

self.assertImagesEqual( a["out"], b["out"], maxDifference = 0.25 )

self.assertImagesEqual( a["out"], b["out"], maxDifference = ( -0.25, 0.0 ) )
with self.assertRaisesRegex( AssertionError, "-0.25 not greater than or equal to 0.0 : Channel R" ) :
self.assertImagesEqual( a["out"], b["out"], maxDifference = ( 0.0, 0.25 ) )

b["color"].setValue( imath.Color4f( 1.0 ) )

self.assertImagesEqual( a["out"], b["out"], maxDifference = ( 0.0, 0.25 ) )
with self.assertRaisesRegex( AssertionError, "0.25 not less than or equal to 0.0 : Channel R" ) :
self.assertImagesEqual( a["out"], b["out"], maxDifference = ( -0.25, 0.0 ) )


if __name__ == "__main__":
unittest.main()
Loading

0 comments on commit c880dd7

Please sign in to comment.