Skip to content

Commit

Permalink
Merge pull request #1151 from rolanddenis/fix_779
Browse files Browse the repository at this point in the history
Fixing issue #779
  • Loading branch information
JacquesOlivierLachaud committed May 12, 2016
2 parents 2e5fa0f + 7599992 commit 7865ca3
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 110 deletions.
9 changes: 7 additions & 2 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,17 @@
some improvements on bounding box computation with orientation check.
(B. Kerautret, [#1123](https:/DGtal-team/DGtal/pull/1123))

- *Image Package*
- Fixing issue [#779](https:/DGtal-team/DGtal/issues/779) by
storing domain with smart pointer in ImageContainerBySTLMap.
(Roland Denis [#1151](https:/DGtal-team/DGtal/pull/1151))

- *IO Package*
- Display3D: Fix embedder usage when using default constructor in Debug mode.
(Roland Denis [##1143](https:/DGtal-team/DGtal/pull/1143))
(Roland Denis [#1143](https:/DGtal-team/DGtal/pull/1143))
- Viewer3D: Fix a problem when the show() method was called at the end of the
main program (the list creation was not called).
(Bertrand Kerautret [##1138](https:/DGtal-team/DGtal/pull/1138))
(Bertrand Kerautret [#1138](https:/DGtal-team/DGtal/pull/1138))
- Viewer3D: add three new modes for shape rendering (default, metallic and
plastic). The rendering can be changed by using the key M. The user can
also choose its own rendering with some setter/getter on the opengl
Expand Down
31 changes: 28 additions & 3 deletions src/DGtal/base/CowPtr.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
//////////////////////////////////////////////////////////////////////////////
// Inclusions
#include <iostream>
#include <type_traits>
#include "DGtal/base/Common.h"
#include "DGtal/base/CountedPtr.h"
//////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -88,14 +89,38 @@ namespace DGtal
const T& operator*() const throw() {return *myPtr;}
const T* operator->() const throw() {return myPtr.get();}
const T* get() const throw() {return myPtr.get();}


/* The following non-const methods are deactivated if T is a const type.
* The goal here is to avoid unecessary copies when it is known that
* the T object will not be modified.
*
* The problem is that C++ uses the non-const methods whenever it's possible
* (ie when CowPtr<T> is non-const), even if the full expression doesn't
* modify the object. A solution is to const_cast the CowPtr<T> before
* using one of these methods to force the usage of the const versions above.
*
* However, in the trivial case when T is a const type, we can simplify this
* by deactivating those methods.
*
* To do that, we use std::enable_if (see http://en.cppreference.com/w/cpp/types/enable_if )
* in the template parameters (it is also possible in the return type or
* as a parameter but it will change the signature). It depends on
* the constness of T returned by the type trait std::is_const.
* The `typename U = T` is necessary in order that the SFINAE rule works at the overload
* resolution step.
*/
template < typename U = T, typename std::enable_if< ! std::is_const<U>::value >::type* = nullptr >
T& operator*() {copy(); return *myPtr;}

template < typename U = T, typename std::enable_if< ! std::is_const<U>::value >::type* = nullptr >
T* operator->() {copy(); return myPtr.get();}

template < typename U = T, typename std::enable_if< ! std::is_const<U>::value >::type* = nullptr >
T* get() {copy(); return myPtr.get();}

/**
Equality operator ==
@param other any other pointer.
@return 'true' if pointed address is equal to \a other.
*/
Expand All @@ -106,7 +131,7 @@ namespace DGtal

/**
Inequality operator !=
@param other any other pointer.
@return 'true' if pointed address is different from \a other.
*/
Expand Down
77 changes: 39 additions & 38 deletions src/DGtal/images/ImageContainerBySTLMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
#include <map>

#include "DGtal/base/Common.h"
#include "DGtal/base/ConstAlias.h"
#include "DGtal/base/CountedPtr.h"
#include "DGtal/base/BasicFunctors.h"
#include "DGtal/base/CowPtr.h"
#include "DGtal/base/Clone.h"
#include "DGtal/images/DefaultConstImageRange.h"
#include "DGtal/images/DefaultImageRange.h"
#include "DGtal/images/SetValueIterator.h"
Expand All @@ -78,33 +78,33 @@ namespace DGtal
* Once constructed, the image is valid, i.e. every point of the
* image domain has a value, which can be read and overwritten.
* Note that the default value (returned for points that are not
* stored in the underlying STL map) can be chosen by the user.
* stored in the underlying STL map) can be chosen by the user.
*
* As a model of concepts::CImage, this class provides two ways of accessing values:
* - through the range of points returned by the domain() method
* combined with the operator() that takes a point and returns its associated value.
* - through the range of values returned by the range() method,
* As a model of concepts::CImage, this class provides two ways of accessing values:
* - through the range of points returned by the domain() method
* combined with the operator() that takes a point and returns its associated value.
* - through the range of values returned by the range() method,
* which can be used to directly iterate over the values of the image
*
* This class also provides a setValue() method and an output iterator,
* which is returned by the outputIterator() method for writting purposes.
* This class also provides a setValue() method and an output iterator,
* which is returned by the outputIterator() method for writting purposes.
*
* @see testImage.cpp
*/

template <typename TDomain, typename TValue>
class ImageContainerBySTLMap:
class ImageContainerBySTLMap:
public std::map<typename TDomain::Point, TValue >
{

public:

typedef ImageContainerBySTLMap<TDomain,TValue> Self;
typedef std::map<typename TDomain::Point, TValue > Parent;
typedef ImageContainerBySTLMap<TDomain,TValue> Self;
typedef std::map<typename TDomain::Point, TValue > Parent;

/// domain
BOOST_CONCEPT_ASSERT(( concepts::CDomain<TDomain> ));
typedef TDomain Domain;
typedef TDomain Domain;
typedef typename Domain::Point Point;
typedef typename Domain::Vector Vector;
typedef typename Domain::Integer Integer;
Expand All @@ -113,25 +113,24 @@ namespace DGtal
typedef Point Vertex;

// Pointer to the (const) Domain given at construction.
typedef const Domain * DomainPtr;

typedef CowPtr< const Domain > DomainPtr;

/// static constants
static const typename Domain::Dimension dimension;

/// range of values
BOOST_CONCEPT_ASSERT(( concepts::CLabel<TValue> ));
typedef TValue Value;
typedef DefaultConstImageRange<Self> ConstRange;
typedef DefaultImageRange<Self> Range;
typedef DefaultConstImageRange<Self> ConstRange;
typedef DefaultImageRange<Self> Range;

/// output iterator
typedef SetValueIterator<Self> OutputIterator;
typedef SetValueIterator<Self> OutputIterator;

/////////////////// Data members //////////////////
private:
private:

/// Counted pointer on the image domain,
/// Shared pointer on the image domain,
/// Since the domain is not mutable, not assignable,
/// it is shared by all the copies of *this
DomainPtr myDomainPtr;
Expand All @@ -141,39 +140,41 @@ namespace DGtal

/////////////////// standard services //////////////////

public:
public:

/**
* Constructor from a Domain
*
/**
* Constructor from a pointer to a domain.
*
* If Domain is a heavy type, consider giving instead a smart pointer on the domain (like CountedPtr).
*
* @param aDomain the image domain.
* @param aValue a default value associated to the domain points
* that are not contained in the underlying map.
*/
ImageContainerBySTLMap( ConstAlias<Domain> aDomain, const Value& aValue = 0);
ImageContainerBySTLMap( Clone<const Domain> aDomain, const Value& aValue = 0);

/**
/**
* Copy operator
*
*
* @param other the object to copy.
*/
ImageContainerBySTLMap(const ImageContainerBySTLMap& other);

/**
/**
* Assignement operator
*
*
* @param other the object to copy.
* @return this
*/
ImageContainerBySTLMap& operator=(const ImageContainerBySTLMap& other);

/**
/**
* Destructor.
*
*/
~ImageContainerBySTLMap();


/////////////////// Interface //////////////////

/**
Expand All @@ -196,12 +197,12 @@ namespace DGtal
* @param aValue the value.
*/
void setValue(const Point &aPoint, const Value &aValue);


/**
* @return the domain associated to the image.
*/
const Domain &domain() const;
const Domain &domain() const;

/**
* @return the const range providing constant
Expand Down Expand Up @@ -238,15 +239,15 @@ namespace DGtal
typedef typename std::map<Point,Value>::const_iterator ConstIterator;
typedef typename std::map<Point,Value>::reverse_iterator ReverseIterator;
typedef typename std::map<Point,Value>::const_reverse_iterator ConstReverseIterator;

/**
* Construct a Iterator on the image
* Construct a Iterator on the image
*
*
*
* @return a Iterator */
OutputIterator outputIterator();


};

/**
Expand All @@ -258,7 +259,7 @@ namespace DGtal
template <typename TDomain, typename TValue>
inline
std::ostream&
operator<< ( std::ostream & out,
operator<< ( std::ostream & out,
const ImageContainerBySTLMap<TDomain,TValue> & object )
{
object.selfDisplay ( out );
Expand Down
29 changes: 15 additions & 14 deletions src/DGtal/images/ImageContainerBySTLMap.ih
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,13 @@ template <typename TDomain, typename TValue>
const typename TDomain::Dimension DGtal::ImageContainerBySTLMap<TDomain,
TValue>::dimension = TDomain::Space::dimension;

//------------------------------------------------------------------------------

template <typename TDomain, typename TValue>
inline
DGtal::ImageContainerBySTLMap<TDomain,TValue>
::ImageContainerBySTLMap( ConstAlias<Domain> aDomain, const Value& aValue)
: myDomainPtr( &aDomain ), myDefaultValue( aValue )
::ImageContainerBySTLMap( Clone<const Domain> aDomain, const Value& aValue)
: myDomainPtr( aDomain ), myDefaultValue( aValue )
{
}

Expand All @@ -57,7 +58,7 @@ template <typename TDomain, typename TValue>
inline
DGtal::ImageContainerBySTLMap<TDomain,TValue>
::ImageContainerBySTLMap(const ImageContainerBySTLMap& other)
: Parent(other),
: Parent(other),
myDomainPtr(other.myDomainPtr), myDefaultValue(other.myDefaultValue)
{
}
Expand All @@ -70,11 +71,11 @@ DGtal::ImageContainerBySTLMap<TDomain,TValue>
{
if (this != &other)
{
Parent::operator=(other);
myDomainPtr = other.myDomainPtr;
myDefaultValue = other.myDefaultValue;
Parent::operator=(other);
myDomainPtr = other.myDomainPtr;
myDefaultValue = other.myDefaultValue;
}
return *this;
return *this;
}
//------------------------------------------------------------------------------
template <typename TDomain, typename TValue>
Expand All @@ -87,9 +88,9 @@ DGtal::ImageContainerBySTLMap<TDomain,TValue>::~ImageContainerBySTLMap( )
template <typename TDomain, typename TValue>
inline
typename DGtal::ImageContainerBySTLMap<TDomain,TValue>::Value
DGtal::ImageContainerBySTLMap<TDomain,TValue>::operator()(const Point &aPoint) const
DGtal::ImageContainerBySTLMap<TDomain,TValue>::operator()(const Point &aPoint) const
{
ASSERT( this->domain().isInside( aPoint ) );
ASSERT( this->domain().isInside( aPoint ) );
ConstIterator it = this->find( aPoint );
if ( it == this->end() )
return myDefaultValue;
Expand All @@ -103,11 +104,11 @@ inline
void
DGtal::ImageContainerBySTLMap<TDomain,TValue>::setValue(const Point &aPoint, const Value &aValue)
{
ASSERT( this->domain().isInside( aPoint ) );
std::pair<typename std::map<Point,Value>::iterator, bool>
res = this->insert( std::pair<Point,Value>(aPoint, aValue) );
ASSERT( this->domain().isInside( aPoint ) );
std::pair<typename std::map<Point,Value>::iterator, bool>
res = this->insert( std::pair<Point,Value>(aPoint, aValue) );
if (res.second == false)
res.first->second = aValue;
res.first->second = aValue;
}

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -161,7 +162,7 @@ inline
void
DGtal::ImageContainerBySTLMap<TDomain,TValue>::selfDisplay ( std::ostream & out ) const
{
out << "[Image - STLMap] size=" << this->size() << " valuetype="
out << "[Image - STLMap] size=" << this->size() << " valuetype="
<< sizeof(TValue) << "bytes Domain=" << *myDomainPtr;
}

Expand Down
Loading

0 comments on commit 7865ca3

Please sign in to comment.