<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlsQueueProcessor.hxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: vg $ $Date: 2008-02-12 16:27:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_QUEUE_PROCESSOR_HXX
#define SD_SLIDESORTER_QUEUE_PROCESSOR_HXX

#include "SlsRequestPriorityClass.hxx"
#include "view/SlsPageObject.hxx"
#include "view/SlideSorterView.hxx"
#include "tools/IdleDetection.hxx"
#include "SlsBitmapCache.hxx"
#include "taskpane/SlideSorterCacheDisplay.hxx"
#include "sdpage.hxx"
#include "Window.hxx"

#include <svx/svdpagv.hxx>
#include <vcl/svapp.hxx>
#include <vcl/timer.hxx>

#include <view/SlsPageObjectViewObjectContact.hxx>

// Uncomment the define below to have some more OSL_TRACE messages.
#ifdef DEBUG
//#define VERBOSE
#endif

namespace sd { namespace slidesorter { namespace view {
class SlideSorterView;
} } }

namespace sd { namespace slidesorter { namespace cache {

/** This non-template base class exists primarily as a place for
    implementing the timer callback.
*/
class QueueProcessorBase
{
public:
    QueueProcessorBase (void);
    virtual ~QueueProcessorBase();

    /** Start the processor.  This implementation is timer based and waits
        an defined amount of time that depends on the given argument before
        the next entry in the queue is processed.
        @param nPriorityClass
            A priority class of 0 tells the processor that a high priority
            request is waiting in the queue.  The time to wait is thus
            shorter then that for a low priority request (denoted by a value
            of 1.)  When the timer is already running it is not modified.
    */
    void Start (int nPriorityClass = 0);
    void Stop (void);

protected:
    virtual void ProcessRequest (void) = 0;

    sal_uInt32 mnTimeBetweenHighPriorityRequests;
    sal_uInt32 mnTimeBetweenLowPriorityRequests;
    sal_uInt32 mnTimeBetweenRequestsWhenNotIdle;

private:
    /// This time controls when to process the next element from the queue.
    Timer maTimer;
    DECL_LINK(ProcessRequestHdl, Timer*);
};

/** This queue processor is timer based, i.e. when an entry is added to the
    queue and the processor is started with Start() in the base class a
    timer is started that eventually calls ProcessRequest().  This is
    repeated until the queue is empty or Stop() is called.
*/
template <class Queue,
          class RequestData,
          class BitmapFactory>
    class QueueProcessor
    : public QueueProcessorBase
{
public:
    QueueProcessor (
        view::SlideSorterView& rView,
        Queue& rQueue,
        const ::boost::shared_ptr<BitmapCache>& rpCache);
    virtual ~QueueProcessor();

    void Terminate (void);

    /** As we can not really terminate the rendering of a preview bitmap for
        a request in midair this method acts more like a semaphor.  It
        returns only when it is save for the caller to delete the request.
        For this to work it is important to remove the request from the
        queue before calling this method.
    */
    void RemoveRequest (RequestData& rRequest);

    /** Use this method when the page cache is (maybe) using a different
        BitmapCache.  This is usually necessary after calling
        PageCacheManager::ChangeSize().
    */
    void SetBitmapCache (const ::boost::shared_ptr<BitmapCache>& rpCache);

private:
    /** This mutex is used to guard the queue processor.  Be carefull not to
        mix its use with that of the solar mutex.
    */
    ::osl::Mutex maMutex;

    view::SlideSorterView& mrView;
    Queue& mrQueue;
    ::boost::shared_ptr<BitmapCache> mpCache;
    BitmapFactory maBitmapFactory;

    virtual void ProcessRequest (void);
};

//=====  QueueProcessor  ======================================================

template <class Queue, class RequestData, class BitmapFactory>
    QueueProcessor<Queue, RequestData, BitmapFactory>::QueueProcessor (
        view::SlideSorterView& rView,
        Queue& rQueue,
        const ::boost::shared_ptr<BitmapCache>& rpCache)
        : maMutex(),
          mrView (rView),
          mrQueue (rQueue),
          mpCache (rpCache),
          maBitmapFactory(rView)
{
}

template <class Queue, class RequestData, class BitmapFactory>
QueueProcessor<Queue, RequestData, BitmapFactory>::~QueueProcessor()
{
}

template <class Queue, class RequestData, class BitmapFactory>
    void QueueProcessor<Queue, RequestData, BitmapFactory>::ProcessRequest (void)
{
    bool bIsShowingFullScreenShow (false);

    while ( ! mrQueue.IsEmpty())
    {
        // Determine whether the system is idle.
        sal_Int32 nIdleState (tools::IdleDetection::GetIdleState(static_cast< ::Window* >(mrView.GetWindow())));
        if (nIdleState != tools::IdleDetection::IDET_IDLE)
        {
            if ((nIdleState&tools::IdleDetection::IDET_FULL_SCREEN_SHOW_ACTIVE) != 0)
                bIsShowingFullScreenShow = true;
            break;
        }

        RequestData* pRequest = NULL;
        RequestPriorityClass ePriorityClass (NOT_VISIBLE);
        bool bRequestIsValid = false;
        Rectangle aDirtyRectangle;
        Size aPreviewPixelSize;
        const SdrPage* pPage = NULL;
        {
            ::osl::MutexGuard aGuard (mrQueue.GetMutex());

            if ( ! mrQueue.IsEmpty())
            {
                // Get the requeuest with the highest priority from the
                // queue.
                ePriorityClass = mrQueue.GetFrontPriorityClass();
                pRequest = &mrQueue.GetFront();
                mrQueue.PopFront();
                if (pRequest != NULL)
                {
                    // Save some values while we hold the mutex of the queue.
                    pPage = pRequest->GetPage();
                    aDirtyRectangle = pRequest->GetViewContact().GetPaintRectangle();
                    aPreviewPixelSize = pRequest->GetBoundingBox(
                        *mrView.GetWindow(),
                        view::PageObjectViewObjectContact::PreviewBoundingBox,
                        view::PageObjectViewObjectContact::PixelCoordinateSystem).GetSize();
                    bRequestIsValid = true;
                    SSCD_SET_STATUS(pPage,RENDERING);
                }
            }
        }
        if (bRequestIsValid)
        {
#ifdef VERBOSE
            OSL_TRACE ("processing request for page %d with priority class %d",
                (pPage->GetPageNum()-1)/2,
                ePriorityClass);
#endif
            try
            {

                ::osl::MutexGuard aGuard (maMutex);
                // Create a new preview bitmap and store it in the cache.
                if (mpCache.get() != NULL)
                {
                    const SdPage* pSdPage = dynamic_cast<const SdPage*>(pPage);
                    if (pSdPage != NULL)
                    {
                        mpCache->SetBitmap (
                            pPage,
                            maBitmapFactory.CreateBitmap(*pSdPage, aPreviewPixelSize),
                            ePriorityClass!=NOT_VISIBLE);

                        // Initiate a repaint of the new preview.
                        if (ePriorityClass != NOT_VISIBLE)
                            mrView.InvalidateAllWin(aDirtyRectangle);

                        SSCD_SET_STATUS(pPage,NONE);
                    }
                }
            }
            catch (::com::sun::star::uno::RuntimeException aException)
            {
                OSL_ASSERT("RuntimeException caught in QueueProcessor");
                (void) aException;
            }
            catch (::com::sun::star::uno::Exception aException)
            {
                OSL_ASSERT("Exception caught in QueueProcessor");
                (void) aException;
            }

            // Requests of lower priority are processed one at a time.
            {
                ::osl::MutexGuard aGuard (mrQueue.GetMutex());
                if ( ! mrQueue.IsEmpty())
                    if (mrQueue.GetFrontPriorityClass() > 0)
                        break;
            }
        }
    }

    if ( ! mrQueue.IsEmpty())
        if (bIsShowingFullScreenShow)
            Start(mnTimeBetweenRequestsWhenNotIdle);
        else
            Start(mrQueue.GetFrontPriorityClass());
}

template <class Queue, class RequestData, class BitmapFactory>
    void QueueProcessor<Queue, RequestData, BitmapFactory>::Terminate (void)
{
}

template <class Queue, class RequestData, class BitmapFactory>
    void QueueProcessor<Queue, RequestData, BitmapFactory>::RemoveRequest (RequestData& )
{
    // See the method declaration above for an explanation why this makes sense.
    ::osl::MutexGuard aGuard (maMutex);
}

template <class Queue, class RequestData, class BitmapFactory>
    void QueueProcessor<Queue, RequestData, BitmapFactory>::SetBitmapCache (
        const ::boost::shared_ptr<BitmapCache>& rpCache)
{
    mpCache = rpCache;
}

} } } // end of namespace ::sd::slidesorter::cache

#endif
<commit_msg>INTEGRATION: CWS presenterview (1.15.54); FILE MERGED 2008/02/26 12:23:35 af 1.15.54.4: #i18486# Dropped the use of templates for implementing cache classes. 2008/02/26 09:03:06 af 1.15.54.3: RESYNC: (1.16-1.17); FILE MERGED 2007/07/11 09:08:04 af 1.15.54.2: RESYNC: (1.15-1.16); FILE MERGED 2007/04/26 15:41:21 af 1.15.54.1: #i75317# Separation of SlideSorter from ViewShell.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlsQueueProcessor.hxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: kz $ $Date: 2008-04-03 14:20:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_QUEUE_PROCESSOR_HXX
#define SD_SLIDESORTER_QUEUE_PROCESSOR_HXX

#include "cache/SlsPageCache.hxx"
#include "SlsRequestPriorityClass.hxx"
#include "SlsBitmapFactory.hxx"
#include "view/SlsPageObject.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsPageObjectViewObjectContact.hxx"
#include "tools/IdleDetection.hxx"
#include "SlsBitmapCache.hxx"
#include "taskpane/SlideSorterCacheDisplay.hxx"
#include "sdpage.hxx"
#include "Window.hxx"

#include <svx/svdpagv.hxx>
#include <vcl/svapp.hxx>
#include <vcl/timer.hxx>
#include <boost/function.hpp>

// Uncomment the define below to have some more OSL_TRACE messages.
#ifdef DEBUG
//#define VERBOSE
#endif

namespace sd { namespace slidesorter { namespace view {
class SlideSorterView;
} } }

namespace sd { namespace slidesorter { namespace cache {

class BitmapCache;
class RequestQueue;

/** This queue processor is timer based, i.e. when an entry is added to the
    queue and the processor is started with Start() in the base class a
    timer is started that eventually calls ProcessRequest().  This is
    repeated until the queue is empty or Stop() is called.
*/
class QueueProcessor
{
public:
    typedef ::boost::function<bool()> IdleDetectionCallback;
    QueueProcessor (
        RequestQueue& rQueue,
        const ::boost::shared_ptr<BitmapCache>& rpCache,
        const Size& rPreviewSize,
        const SharedCacheContext& rpCacheContext);
    virtual ~QueueProcessor();

    /** Start the processor.  This implementation is timer based and waits
        an defined amount of time that depends on the given argument before
        the next entry in the queue is processed.
        @param nPriorityClass
            A priority class of 0 tells the processor that a high priority
            request is waiting in the queue.  The time to wait is thus
            shorter then that for a low priority request (denoted by a value
            of 1.)  When the timer is already running it is not modified.
    */
    void Start (int nPriorityClass = 0);
    void Stop (void);
    void Pause (void);
    void Resume (void);

    void Terminate (void);

    void SetPreviewSize (const Size& rSize);

    /** As we can not really terminate the rendering of a preview bitmap for
        a request in midair this method acts more like a semaphor.  It
        returns only when it is save for the caller to delete the request.
        For this to work it is important to remove the request from the
        queue before calling this method.
    */
    void RemoveRequest (CacheKey aKey);

    /** Use this method when the page cache is (maybe) using a different
        BitmapCache.  This is usually necessary after calling
        PageCacheManager::ChangeSize().
    */
    void SetBitmapCache (const ::boost::shared_ptr<BitmapCache>& rpCache);

private:
    /** This mutex is used to guard the queue processor.  Be carefull not to
        mix its use with that of the solar mutex.
    */
    ::osl::Mutex maMutex;

    Timer maTimer;
    DECL_LINK(ProcessRequestHdl, Timer*);
    sal_uInt32 mnTimeBetweenHighPriorityRequests;
    sal_uInt32 mnTimeBetweenLowPriorityRequests;
    sal_uInt32 mnTimeBetweenRequestsWhenNotIdle;
    Size maPreviewSize;
    SharedCacheContext mpCacheContext;
    RequestQueue& mrQueue;
    ::boost::shared_ptr<BitmapCache> mpCache;
    BitmapFactory maBitmapFactory;
    bool mbIsPaused;

    void ProcessRequests (void);
    void ProcessOneRequest (
        CacheKey aKey,
        const RequestPriorityClass ePriorityClass);
};

} } } // end of namespace ::sd::slidesorter::cache

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: SlsPageDescriptor.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "model/SlsPageDescriptor.hxx"
#include "view/SlsPageObject.hxx"
#include "view/SlsPageObjectViewObjectContact.hxx"
#include "controller/SlsPageObjectFactory.hxx"

#include "sdpage.hxx"
#include "drawdoc.hxx"

#include <svx/svdopage.hxx>
#include <svx/svdpagv.hxx>
#include <svx/sdr/contact/viewcontact.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;

namespace sd {  namespace slidesorter { namespace model {

PageDescriptor::PageDescriptor (
    const Reference<drawing::XDrawPage>& rxPage,
    SdPage* pPage,
    const sal_Int32 nIndex,
    const controller::PageObjectFactory& rPageObjectFactory)
    : mpPage(pPage),
      mxPage(rxPage),
      mnIndex(nIndex),
      mpPageObjectFactory(&rPageObjectFactory),
      mpPageObject(NULL),
      mbIsSelected(false),
      mbIsVisible(false),
      mbIsFocused(false),
      mbIsCurrent(false),
      mpViewObjectContact(NULL),
      maModelBorder(0,0,0,0),
      maPageNumberAreaModelSize(0,0)
{
    OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage));
}

PageDescriptor::~PageDescriptor (void)
{
}

SdPage* PageDescriptor::GetPage (void) const
{
    return mpPage;
}

Reference<drawing::XDrawPage> PageDescriptor::GetXDrawPage (void) const
{
    return mxPage;
}

sal_Int32 PageDescriptor::GetPageIndex (void) const
{
    return mnIndex;
}

view::PageObject* PageDescriptor::GetPageObject (void)
{
    if (mpPageObject==NULL && mpPageObjectFactory!=NULL)
    {
        mpPageObject = mpPageObjectFactory->CreatePageObject(mpPage, shared_from_this());
    }

    return mpPageObject;
}

void PageDescriptor::ReleasePageObject (void)
{
    mpPageObject = NULL;
}

bool PageDescriptor::IsVisible (void) const
{
    return mbIsVisible;
}

void PageDescriptor::SetVisible (bool bIsVisible)
{
    mbIsVisible = bIsVisible;
}

bool PageDescriptor::Select (void)
{
    if ( ! IsSelected())
    {
        mbIsSelected = true;
        return true;
    }
    else
        return false;
}

bool PageDescriptor::Deselect (void)
{
    if (IsSelected())
    {
        mbIsSelected = false;
        return true;
    }
    else
        return false;
}

bool PageDescriptor::IsSelected (void) const
{
    return mbIsSelected;
}

bool PageDescriptor::UpdateSelection (void)
{
    if (mpPage!=NULL && (mpPage->IsSelected()==TRUE) != mbIsSelected)
    {
        mbIsSelected = ! mbIsSelected;
        return true;
    }
    else
        return false;
}

bool PageDescriptor::IsFocused (void) const
{
    return mbIsFocused;
}

void PageDescriptor::SetFocus (void)
{
    mbIsFocused = true;
}

void PageDescriptor::RemoveFocus (void)
{
    mbIsFocused = false;
}

view::PageObjectViewObjectContact*
    PageDescriptor::GetViewObjectContact (void) const
{
    return mpViewObjectContact;
}

void PageDescriptor::SetViewObjectContact (
    view::PageObjectViewObjectContact* pViewObjectContact)
{
    mpViewObjectContact = pViewObjectContact;
}

const controller::PageObjectFactory&
    PageDescriptor::GetPageObjectFactory (void) const
{
    return *mpPageObjectFactory;
}

void PageDescriptor::SetPageObjectFactory (
    const controller::PageObjectFactory& rFactory)
{
    mpPageObjectFactory = &rFactory;
}

void PageDescriptor::SetModelBorder (const SvBorder& rBorder)
{
    maModelBorder = rBorder;
}

SvBorder PageDescriptor::GetModelBorder (void) const
{
    return maModelBorder;
}

void PageDescriptor::SetPageNumberAreaModelSize (const Size& rSize)
{
    maPageNumberAreaModelSize = rSize;
}

Size PageDescriptor::GetPageNumberAreaModelSize (void) const
{
    return maPageNumberAreaModelSize;
}

bool PageDescriptor::IsCurrentPage (void) const
{
    return mbIsCurrent;
}

void PageDescriptor::SetIsCurrentPage (const bool bIsCurrent)
{
    mbIsCurrent = bIsCurrent;
}

} } } // end of namespace ::sd::slidesorter::model
<commit_msg>INTEGRATION: CWS impress141 (1.7.6); FILE MERGED 2008/04/29 15:03:21 cl 1.7.6.1: #i88007# check for null pointer<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: SlsPageDescriptor.cxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "model/SlsPageDescriptor.hxx"
#include "view/SlsPageObject.hxx"
#include "view/SlsPageObjectViewObjectContact.hxx"
#include "controller/SlsPageObjectFactory.hxx"

#include "sdpage.hxx"
#include "drawdoc.hxx"

#include <svx/svdopage.hxx>
#include <svx/svdpagv.hxx>
#include <svx/sdr/contact/viewcontact.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;

namespace sd {  namespace slidesorter { namespace model {

PageDescriptor::PageDescriptor (
    const Reference<drawing::XDrawPage>& rxPage,
    SdPage* pPage,
    const sal_Int32 nIndex,
    const controller::PageObjectFactory& rPageObjectFactory)
    : mpPage(pPage),
      mxPage(rxPage),
      mnIndex(nIndex),
      mpPageObjectFactory(&rPageObjectFactory),
      mpPageObject(NULL),
      mbIsSelected(false),
      mbIsVisible(false),
      mbIsFocused(false),
      mbIsCurrent(false),
      mpViewObjectContact(NULL),
      maModelBorder(0,0,0,0),
      maPageNumberAreaModelSize(0,0)
{
    OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage));
}

PageDescriptor::~PageDescriptor (void)
{
}

SdPage* PageDescriptor::GetPage (void) const
{
    return mpPage;
}

Reference<drawing::XDrawPage> PageDescriptor::GetXDrawPage (void) const
{
    return mxPage;
}

sal_Int32 PageDescriptor::GetPageIndex (void) const
{
    return mnIndex;
}

view::PageObject* PageDescriptor::GetPageObject (void)
{
    if (mpPageObject==NULL && mpPageObjectFactory!=NULL && mpPage != NULL)
    {
        mpPageObject = mpPageObjectFactory->CreatePageObject(mpPage, shared_from_this());
    }

    return mpPageObject;
}

void PageDescriptor::ReleasePageObject (void)
{
    mpPageObject = NULL;
}

bool PageDescriptor::IsVisible (void) const
{
    return mbIsVisible;
}

void PageDescriptor::SetVisible (bool bIsVisible)
{
    mbIsVisible = bIsVisible;
}

bool PageDescriptor::Select (void)
{
    if ( ! IsSelected())
    {
        mbIsSelected = true;
        return true;
    }
    else
        return false;
}

bool PageDescriptor::Deselect (void)
{
    if (IsSelected())
    {
        mbIsSelected = false;
        return true;
    }
    else
        return false;
}

bool PageDescriptor::IsSelected (void) const
{
    return mbIsSelected;
}

bool PageDescriptor::UpdateSelection (void)
{
    if (mpPage!=NULL && (mpPage->IsSelected()==TRUE) != mbIsSelected)
    {
        mbIsSelected = ! mbIsSelected;
        return true;
    }
    else
        return false;
}

bool PageDescriptor::IsFocused (void) const
{
    return mbIsFocused;
}

void PageDescriptor::SetFocus (void)
{
    mbIsFocused = true;
}

void PageDescriptor::RemoveFocus (void)
{
    mbIsFocused = false;
}

view::PageObjectViewObjectContact*
    PageDescriptor::GetViewObjectContact (void) const
{
    return mpViewObjectContact;
}

void PageDescriptor::SetViewObjectContact (
    view::PageObjectViewObjectContact* pViewObjectContact)
{
    mpViewObjectContact = pViewObjectContact;
}

const controller::PageObjectFactory&
    PageDescriptor::GetPageObjectFactory (void) const
{
    return *mpPageObjectFactory;
}

void PageDescriptor::SetPageObjectFactory (
    const controller::PageObjectFactory& rFactory)
{
    mpPageObjectFactory = &rFactory;
}

void PageDescriptor::SetModelBorder (const SvBorder& rBorder)
{
    maModelBorder = rBorder;
}

SvBorder PageDescriptor::GetModelBorder (void) const
{
    return maModelBorder;
}

void PageDescriptor::SetPageNumberAreaModelSize (const Size& rSize)
{
    maPageNumberAreaModelSize = rSize;
}

Size PageDescriptor::GetPageNumberAreaModelSize (void) const
{
    return maPageNumberAreaModelSize;
}

bool PageDescriptor::IsCurrentPage (void) const
{
    return mbIsCurrent;
}

void PageDescriptor::SetIsCurrentPage (const bool bIsCurrent)
{
    mbIsCurrent = bIsCurrent;
}

} } } // end of namespace ::sd::slidesorter::model
<|endoftext|>


<commit_before>#include "search/search_quality/assessment_tool/main_model.hpp"

#include "search/feature_loader.hpp"
#include "search/search_quality/assessment_tool/view.hpp"
#include "search/search_quality/matcher.hpp"

#include "map/framework.hpp"

#include "search/search_params.hpp"

#include "geometry/algorithm.hpp"
#include "geometry/mercator.hpp"

#include "coding/multilang_utf8_string.hpp"

#include "platform/platform.hpp"

#include "base/assert.hpp"
#include "base/logging.hpp"

#include <algorithm>
#include <fstream>
#include <functional>
#include <iterator>

using Relevance = search::Sample::Result::Relevance;
using namespace std;

// MainModel::SampleContext ------------------------------------------------------------------------

// MainModel ---------------------------------------------------------------------------------------
MainModel::MainModel(Framework & framework)
  : m_framework(framework)
  , m_index(m_framework.GetIndex())
  , m_loader(m_index)
  , m_contexts(
        [this](size_t sampleIndex, Edits::Update const & update) {
          OnUpdate(View::ResultType::Found, sampleIndex, update);
        },
        [this](size_t sampleIndex, Edits::Update const & update) {
          OnUpdate(View::ResultType::NonFound, sampleIndex, update);
        })
{
}

void MainModel::Open(string const & path)
{
  CHECK(m_view, ());

  string contents;

  {
    ifstream ifs(path);
    if (!ifs)
    {
      m_view->ShowError("Can't open file: " + path);
      return;
    }
    contents.assign(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>());
  }

  vector<search::Sample> samples;
  if (!search::Sample::DeserializeFromJSONLines(contents, samples))
  {
    m_view->ShowError("Can't parse samples: " + path);
    return;
  }

  ResetSearch();

  m_view->Clear();

  m_contexts.Resize(samples.size());
  for (size_t i = 0; i < samples.size(); ++i)
  {
    auto & context = m_contexts[i];
    context.Clear();
    context.m_sample = samples[i];
  }
  m_path = path;

  m_view->SetSamples(ContextList::SamplesSlice(m_contexts));
  m_selectedSample = kInvalidIndex;
}

void MainModel::Save()
{
  CHECK(HasChanges(), ());
  SaveAs(m_path);
}

void MainModel::SaveAs(string const & path)
{
  CHECK(HasChanges(), ());
  CHECK(!path.empty(), ());

  string contents;
  search::Sample::SerializeToJSONLines(m_contexts.MakeSamples(m_loader), contents);

  {
    ofstream ofs(path);
    if (!ofs)
    {
      m_view->ShowError("Can't open file: " + path);
      return;
    }
    copy(contents.begin(), contents.end(), ostreambuf_iterator<char>(ofs));
  }

  m_contexts.ApplyEdits();
  m_path = path;
}

void MainModel::OnSampleSelected(int index)
{
  CHECK(m_threadChecker.CalledOnOriginalThread(), ());

  CHECK_GREATER_OR_EQUAL(index, 0, ());
  CHECK_LESS(index, m_contexts.Size(), ());
  CHECK(m_view, ());

  m_selectedSample = index;

  auto & context = m_contexts[index];
  auto const & sample = context.m_sample;
  m_view->ShowSample(index, sample, sample.m_posAvailable, sample.m_pos, context.HasChanges());

  ResetSearch();
  auto const timestamp = m_queryTimestamp;
  m_numShownResults = 0;

  if (context.m_initialized)
  {
    OnResults(timestamp, index, context.m_foundResults, context.m_foundResultsEdits.GetRelevances(),
              context.m_goldenMatching, context.m_actualMatching);
    return;
  }

  auto & engine = m_framework.GetSearchEngine();
  {
    search::SearchParams params;
    sample.FillSearchParams(params);
    params.m_onResults = [this, index, sample, timestamp](search::Results const & results) {
      vector<Relevance> relevances;
      vector<size_t> goldenMatching;
      vector<size_t> actualMatching;

      if (results.IsEndedNormal())
      {
        // Can't use m_loader here due to thread-safety issues.
        search::FeatureLoader loader(m_index);
        search::Matcher matcher(loader);

        vector<search::Result> const actual(results.begin(), results.end());
        matcher.Match(sample.m_results, actual, goldenMatching, actualMatching);
        relevances.assign(actual.size(), Relevance::Irrelevant);
        for (size_t i = 0; i < goldenMatching.size(); ++i)
        {
          auto const j = goldenMatching[i];
          if (j != search::Matcher::kInvalidId)
          {
            CHECK_LESS(j, relevances.size(), ());
            relevances[j] = sample.m_results[i].m_relevance;
          }
        }
      }

      GetPlatform().RunOnGuiThread(bind(&MainModel::OnResults, this, timestamp, index, results,
                                        relevances, goldenMatching, actualMatching));
    };

    m_queryHandle = engine.Search(params, sample.m_viewport);
    m_view->OnSearchStarted();
  }
}

void MainModel::OnResultSelected(int index)
{
  CHECK_GREATER_OR_EQUAL(m_selectedSample, 0, ());
  CHECK_LESS(m_selectedSample, m_contexts.Size(), ());
  auto const & context = m_contexts[m_selectedSample];
  auto const & foundResults = context.m_foundResults;

  CHECK_GREATER_OR_EQUAL(index, 0, ());
  CHECK_LESS(index, foundResults.GetCount(), ());
  m_view->MoveViewportToResult(foundResults[index]);
}

void MainModel::OnNonFoundResultSelected(int index)
{
  CHECK_GREATER_OR_EQUAL(m_selectedSample, 0, ());
  CHECK_LESS(m_selectedSample, m_contexts.Size(), ());
  auto const & context = m_contexts[m_selectedSample];
  auto const & results = context.m_nonFoundResults;

  CHECK_GREATER_OR_EQUAL(index, 0, ());
  CHECK_LESS(index, results.size(), ());
  m_view->MoveViewportToResult(results[index]);
}

void MainModel::OnShowViewportClicked()
{
  CHECK(m_selectedSample != kInvalidIndex, ());
  CHECK(m_selectedSample < m_contexts.Size(), ());

  auto const & context = m_contexts[m_selectedSample];
  m_view->MoveViewportToRect(context.m_sample.m_viewport);
}

void MainModel::OnShowPositionClicked()
{
  CHECK(m_selectedSample != kInvalidIndex, ());
  CHECK(m_selectedSample < m_contexts.Size(), ());

  static int constexpr kViewportAroundPositionSizeM = 100;
  static double constexpr kScale = 1.2;
  static size_t constexpr kMaxTopResults = 3;

  auto const & context = m_contexts[m_selectedSample];

  vector<m2::PointD> points;
  if (context.m_sample.m_posAvailable)
    points.push_back(context.m_sample.m_pos);

  size_t resultsAdded = 0;
  for (auto const & result : context.m_foundResults)
  {
    if (!result.HasPoint())
      continue;

    if (resultsAdded == kMaxTopResults)
      break;

    points.push_back(result.GetFeatureCenter());
    ++resultsAdded;
  }

  CHECK(!points.empty(), ());
  auto boundingBox = m2::ApplyCalculator(points, m2::CalculateBoundingBox());
  boundingBox.Scale(kScale);

  auto const minRect = MercatorBounds::RectByCenterXYAndSizeInMeters(boundingBox.Center(),
                                                                     kViewportAroundPositionSizeM);
  m_view->MoveViewportToRect(m2::Add(boundingBox, minRect));
}

bool MainModel::HasChanges() { return m_contexts.HasChanges(); }

bool MainModel::AlreadyInSamples(FeatureID const & id)
{
  CHECK(m_selectedSample != kInvalidIndex, ());
  CHECK(m_selectedSample < m_contexts.Size(), ());

  bool found = false;
  ForAnyMatchingEntry(m_contexts[m_selectedSample], id, [&](Edits & edits, size_t index) {
    auto const & entry = edits.GetEntry(index);
    if (!entry.m_deleted)
      found = true;
  });
  return found;
}

void MainModel::AddNonFoundResult(FeatureID const & id)
{
  CHECK(m_selectedSample != kInvalidIndex, ());
  CHECK(m_selectedSample < m_contexts.Size(), ());

  auto & context = m_contexts[m_selectedSample];

  bool resurrected = false;
  ForAnyMatchingEntry(context, id, [&](Edits & edits, size_t index) {
    auto const & entry = edits.GetEntry(index);
    CHECK(entry.m_deleted, ());
    edits.Resurrect(index);
    resurrected = true;
  });
  if (resurrected)
    return;

  FeatureType ft;
  CHECK(m_loader.Load(id, ft), ("Can't load feature:", id));
  auto const result = search::Sample::Result::Build(ft, search::Sample::Result::Relevance::Vital);
  context.AddNonFoundResult(result);
}

void MainModel::OnUpdate(View::ResultType type, size_t sampleIndex, Edits::Update const & update)
{
  using Type = Edits::Update::Type;

  CHECK_LESS(sampleIndex, m_contexts.Size(), ());
  auto & context = m_contexts[sampleIndex];

  if (update.m_type == Type::Add)
  {
    CHECK_EQUAL(type, View::ResultType::NonFound, ());
    m_view->ShowNonFoundResults(context.m_nonFoundResults,
                                context.m_nonFoundResultsEdits.GetEntries());
    m_view->SetEdits(m_selectedSample, context.m_foundResultsEdits, context.m_nonFoundResultsEdits);
  }

  m_view->OnResultChanged(sampleIndex, type, update);
  m_view->OnSampleChanged(sampleIndex, context.HasChanges());
  m_view->OnSamplesChanged(m_contexts.HasChanges());

  if (update.m_type == Type::Add || update.m_type == Type::Resurrect ||
      update.m_type == Type::Delete)
  {
    CHECK(context.m_initialized, ());
    CHECK_EQUAL(type, View::ResultType::NonFound, ());
    ShowMarks(context);
  }
}

void MainModel::OnResults(uint64_t timestamp, size_t sampleIndex, search::Results const & results,
                          vector<Relevance> const & relevances,
                          vector<size_t> const & goldenMatching,
                          vector<size_t> const & actualMatching)
{
  CHECK(m_threadChecker.CalledOnOriginalThread(), ());

  if (timestamp != m_queryTimestamp)
    return;

  CHECK_LESS_OR_EQUAL(m_numShownResults, results.GetCount(), ());
  m_view->AddFoundResults(results.begin() + m_numShownResults, results.end());
  m_numShownResults = results.GetCount();

  auto & context = m_contexts[sampleIndex];
  context.m_foundResults = results;

  if (!results.IsEndedNormal())
    return;

  if (!context.m_initialized)
  {
    context.m_foundResultsEdits.Reset(relevances);
    context.m_goldenMatching = goldenMatching;
    context.m_actualMatching = actualMatching;

    {
      vector<Relevance> relevances;

      auto & nonFound = context.m_nonFoundResults;
      CHECK(nonFound.empty(), ());
      for (size_t i = 0; i < context.m_goldenMatching.size(); ++i)
      {
        auto const j = context.m_goldenMatching[i];
        if (j != search::Matcher::kInvalidId)
          continue;
        nonFound.push_back(context.m_sample.m_results[i]);
        relevances.push_back(nonFound.back().m_relevance);
      }
      context.m_nonFoundResultsEdits.Reset(relevances);
    }

    context.m_initialized = true;
  }

  m_view->ShowNonFoundResults(context.m_nonFoundResults,
                              context.m_nonFoundResultsEdits.GetEntries());
  ShowMarks(context);
  m_view->OnResultChanged(sampleIndex, View::ResultType::Found,
                          Edits::Update::MakeAll());
  m_view->OnResultChanged(sampleIndex, View::ResultType::NonFound,
                          Edits::Update::MakeAll());
  m_view->OnSampleChanged(sampleIndex, context.HasChanges());
  m_view->SetEdits(sampleIndex, context.m_foundResultsEdits, context.m_nonFoundResultsEdits);
  m_view->OnSearchCompleted();
}

void MainModel::ResetSearch()
{
  ++m_queryTimestamp;
  if (auto handle = m_queryHandle.lock())
    handle->Cancel();
}

void MainModel::ShowMarks(Context const & context)
{
  m_view->ClearSearchResultMarks();
  m_view->ShowFoundResultsMarks(context.m_foundResults.begin(), context.m_foundResults.end());
  m_view->ShowNonFoundResultsMarks(context.m_nonFoundResults,
                                   context.m_nonFoundResultsEdits.GetEntries());
}

template <typename Fn>
void MainModel::ForAnyMatchingEntry(Context & context, FeatureID const & id, Fn && fn)
{
  CHECK(context.m_initialized, ());

  auto const & foundResults = context.m_foundResults;
  CHECK_EQUAL(foundResults.GetCount(), context.m_foundResultsEdits.NumEntries(), ());
  for (size_t i = 0; i < foundResults.GetCount(); ++i)
  {
    auto const & result = foundResults[i];
    if (result.GetResultType() != search::Result::RESULT_FEATURE)
      continue;
    if (result.GetFeatureID() == id)
      return fn(context.m_foundResultsEdits, i);
  }

  FeatureType ft;
  CHECK(m_loader.Load(id, ft), ("Can't load feature:", id));
  search::Matcher matcher(m_loader);

  auto const & nonFoundResults = context.m_nonFoundResults;
  CHECK_EQUAL(nonFoundResults.size(), context.m_nonFoundResultsEdits.NumEntries(), ());
  for (size_t i = 0; i < nonFoundResults.size(); ++i)
  {
    auto const & result = context.m_nonFoundResults[i];
    if (matcher.Matches(result, ft))
      return fn(context.m_nonFoundResultsEdits, i);
  }
}
<commit_msg>Reviews fixes.<commit_after>#include "search/search_quality/assessment_tool/main_model.hpp"

#include "search/feature_loader.hpp"
#include "search/search_quality/assessment_tool/view.hpp"
#include "search/search_quality/matcher.hpp"

#include "map/framework.hpp"

#include "search/search_params.hpp"

#include "geometry/algorithm.hpp"
#include "geometry/mercator.hpp"

#include "coding/multilang_utf8_string.hpp"

#include "platform/platform.hpp"

#include "base/assert.hpp"
#include "base/logging.hpp"

#include <algorithm>
#include <fstream>
#include <functional>
#include <iterator>

using Relevance = search::Sample::Result::Relevance;
using namespace std;

// MainModel::SampleContext ------------------------------------------------------------------------

// MainModel ---------------------------------------------------------------------------------------
MainModel::MainModel(Framework & framework)
  : m_framework(framework)
  , m_index(m_framework.GetIndex())
  , m_loader(m_index)
  , m_contexts(
        [this](size_t sampleIndex, Edits::Update const & update) {
          OnUpdate(View::ResultType::Found, sampleIndex, update);
        },
        [this](size_t sampleIndex, Edits::Update const & update) {
          OnUpdate(View::ResultType::NonFound, sampleIndex, update);
        })
{
}

void MainModel::Open(string const & path)
{
  CHECK(m_view, ());

  string contents;

  {
    ifstream ifs(path);
    if (!ifs)
    {
      m_view->ShowError("Can't open file: " + path);
      return;
    }
    contents.assign(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>());
  }

  vector<search::Sample> samples;
  if (!search::Sample::DeserializeFromJSONLines(contents, samples))
  {
    m_view->ShowError("Can't parse samples: " + path);
    return;
  }

  ResetSearch();

  m_view->Clear();

  m_contexts.Resize(samples.size());
  for (size_t i = 0; i < samples.size(); ++i)
  {
    auto & context = m_contexts[i];
    context.Clear();
    context.m_sample = samples[i];
  }
  m_path = path;

  m_view->SetSamples(ContextList::SamplesSlice(m_contexts));
  m_selectedSample = kInvalidIndex;
}

void MainModel::Save()
{
  CHECK(HasChanges(), ());
  SaveAs(m_path);
}

void MainModel::SaveAs(string const & path)
{
  CHECK(HasChanges(), ());
  CHECK(!path.empty(), ());

  string contents;
  search::Sample::SerializeToJSONLines(m_contexts.MakeSamples(m_loader), contents);

  {
    ofstream ofs(path);
    if (!ofs)
    {
      m_view->ShowError("Can't open file: " + path);
      return;
    }
    copy(contents.begin(), contents.end(), ostreambuf_iterator<char>(ofs));
  }

  m_contexts.ApplyEdits();
  m_path = path;
}

void MainModel::OnSampleSelected(int index)
{
  CHECK(m_threadChecker.CalledOnOriginalThread(), ());

  CHECK_GREATER_OR_EQUAL(index, 0, ());
  CHECK_LESS(index, m_contexts.Size(), ());
  CHECK(m_view, ());

  m_selectedSample = index;

  auto & context = m_contexts[index];
  auto const & sample = context.m_sample;
  m_view->ShowSample(index, sample, sample.m_posAvailable, sample.m_pos, context.HasChanges());

  ResetSearch();
  auto const timestamp = m_queryTimestamp;
  m_numShownResults = 0;

  if (context.m_initialized)
  {
    OnResults(timestamp, index, context.m_foundResults, context.m_foundResultsEdits.GetRelevances(),
              context.m_goldenMatching, context.m_actualMatching);
    return;
  }

  auto & engine = m_framework.GetSearchEngine();
  {
    search::SearchParams params;
    sample.FillSearchParams(params);
    params.m_onResults = [this, index, sample, timestamp](search::Results const & results) {
      vector<Relevance> relevances;
      vector<size_t> goldenMatching;
      vector<size_t> actualMatching;

      if (results.IsEndedNormal())
      {
        // Can't use m_loader here due to thread-safety issues.
        search::FeatureLoader loader(m_index);
        search::Matcher matcher(loader);

        vector<search::Result> const actual(results.begin(), results.end());
        matcher.Match(sample.m_results, actual, goldenMatching, actualMatching);
        relevances.assign(actual.size(), Relevance::Irrelevant);
        for (size_t i = 0; i < goldenMatching.size(); ++i)
        {
          auto const j = goldenMatching[i];
          if (j != search::Matcher::kInvalidId)
          {
            CHECK_LESS(j, relevances.size(), ());
            relevances[j] = sample.m_results[i].m_relevance;
          }
        }
      }

      GetPlatform().RunOnGuiThread(bind(&MainModel::OnResults, this, timestamp, index, results,
                                        relevances, goldenMatching, actualMatching));
    };

    m_queryHandle = engine.Search(params, sample.m_viewport);
    m_view->OnSearchStarted();
  }
}

void MainModel::OnResultSelected(int index)
{
  CHECK_GREATER_OR_EQUAL(m_selectedSample, 0, ());
  CHECK_LESS(m_selectedSample, m_contexts.Size(), ());
  auto const & context = m_contexts[m_selectedSample];
  auto const & foundResults = context.m_foundResults;

  CHECK_GREATER_OR_EQUAL(index, 0, ());
  CHECK_LESS(index, foundResults.GetCount(), ());
  m_view->MoveViewportToResult(foundResults[index]);
}

void MainModel::OnNonFoundResultSelected(int index)
{
  CHECK_GREATER_OR_EQUAL(m_selectedSample, 0, ());
  CHECK_LESS(m_selectedSample, m_contexts.Size(), ());
  auto const & context = m_contexts[m_selectedSample];
  auto const & results = context.m_nonFoundResults;

  CHECK_GREATER_OR_EQUAL(index, 0, ());
  CHECK_LESS(index, results.size(), ());
  m_view->MoveViewportToResult(results[index]);
}

void MainModel::OnShowViewportClicked()
{
  CHECK(m_selectedSample != kInvalidIndex, ());
  CHECK(m_selectedSample < m_contexts.Size(), ());

  auto const & context = m_contexts[m_selectedSample];
  m_view->MoveViewportToRect(context.m_sample.m_viewport);
}

void MainModel::OnShowPositionClicked()
{
  CHECK(m_selectedSample != kInvalidIndex, ());
  CHECK(m_selectedSample < m_contexts.Size(), ());

  static int constexpr kViewportAroundTopResultsSizeM = 100;
  static double constexpr kViewportAroundTopResultsScale = 1.2;
  static size_t constexpr kMaxTopResults = 3;

  auto const & context = m_contexts[m_selectedSample];

  vector<m2::PointD> points;
  if (context.m_sample.m_posAvailable)
    points.push_back(context.m_sample.m_pos);

  size_t resultsAdded = 0;
  for (auto const & result : context.m_foundResults)
  {
    if (!result.HasPoint())
      continue;

    if (resultsAdded == kMaxTopResults)
      break;

    points.push_back(result.GetFeatureCenter());
    ++resultsAdded;
  }

  CHECK(!points.empty(), ());
  auto boundingBox = m2::ApplyCalculator(points, m2::CalculateBoundingBox());
  boundingBox.Scale(kViewportAroundTopResultsScale);

  auto const minRect = MercatorBounds::RectByCenterXYAndSizeInMeters(
      boundingBox.Center(), kViewportAroundTopResultsSizeM);
  m_view->MoveViewportToRect(m2::Add(boundingBox, minRect));
}

bool MainModel::HasChanges() { return m_contexts.HasChanges(); }

bool MainModel::AlreadyInSamples(FeatureID const & id)
{
  CHECK(m_selectedSample != kInvalidIndex, ());
  CHECK(m_selectedSample < m_contexts.Size(), ());

  bool found = false;
  ForAnyMatchingEntry(m_contexts[m_selectedSample], id, [&](Edits & edits, size_t index) {
    auto const & entry = edits.GetEntry(index);
    if (!entry.m_deleted)
      found = true;
  });
  return found;
}

void MainModel::AddNonFoundResult(FeatureID const & id)
{
  CHECK(m_selectedSample != kInvalidIndex, ());
  CHECK(m_selectedSample < m_contexts.Size(), ());

  auto & context = m_contexts[m_selectedSample];

  bool resurrected = false;
  ForAnyMatchingEntry(context, id, [&](Edits & edits, size_t index) {
    auto const & entry = edits.GetEntry(index);
    CHECK(entry.m_deleted, ());
    edits.Resurrect(index);
    resurrected = true;
  });
  if (resurrected)
    return;

  FeatureType ft;
  CHECK(m_loader.Load(id, ft), ("Can't load feature:", id));
  auto const result = search::Sample::Result::Build(ft, search::Sample::Result::Relevance::Vital);
  context.AddNonFoundResult(result);
}

void MainModel::OnUpdate(View::ResultType type, size_t sampleIndex, Edits::Update const & update)
{
  using Type = Edits::Update::Type;

  CHECK_LESS(sampleIndex, m_contexts.Size(), ());
  auto & context = m_contexts[sampleIndex];

  if (update.m_type == Type::Add)
  {
    CHECK_EQUAL(type, View::ResultType::NonFound, ());
    m_view->ShowNonFoundResults(context.m_nonFoundResults,
                                context.m_nonFoundResultsEdits.GetEntries());
    m_view->SetEdits(m_selectedSample, context.m_foundResultsEdits, context.m_nonFoundResultsEdits);
  }

  m_view->OnResultChanged(sampleIndex, type, update);
  m_view->OnSampleChanged(sampleIndex, context.HasChanges());
  m_view->OnSamplesChanged(m_contexts.HasChanges());

  if (update.m_type == Type::Add || update.m_type == Type::Resurrect ||
      update.m_type == Type::Delete)
  {
    CHECK(context.m_initialized, ());
    CHECK_EQUAL(type, View::ResultType::NonFound, ());
    ShowMarks(context);
  }
}

void MainModel::OnResults(uint64_t timestamp, size_t sampleIndex, search::Results const & results,
                          vector<Relevance> const & relevances,
                          vector<size_t> const & goldenMatching,
                          vector<size_t> const & actualMatching)
{
  CHECK(m_threadChecker.CalledOnOriginalThread(), ());

  if (timestamp != m_queryTimestamp)
    return;

  CHECK_LESS_OR_EQUAL(m_numShownResults, results.GetCount(), ());
  m_view->AddFoundResults(results.begin() + m_numShownResults, results.end());
  m_numShownResults = results.GetCount();

  auto & context = m_contexts[sampleIndex];
  context.m_foundResults = results;

  if (!results.IsEndedNormal())
    return;

  if (!context.m_initialized)
  {
    context.m_foundResultsEdits.Reset(relevances);
    context.m_goldenMatching = goldenMatching;
    context.m_actualMatching = actualMatching;

    {
      vector<Relevance> relevances;

      auto & nonFound = context.m_nonFoundResults;
      CHECK(nonFound.empty(), ());
      for (size_t i = 0; i < context.m_goldenMatching.size(); ++i)
      {
        auto const j = context.m_goldenMatching[i];
        if (j != search::Matcher::kInvalidId)
          continue;
        nonFound.push_back(context.m_sample.m_results[i]);
        relevances.push_back(nonFound.back().m_relevance);
      }
      context.m_nonFoundResultsEdits.Reset(relevances);
    }

    context.m_initialized = true;
  }

  m_view->ShowNonFoundResults(context.m_nonFoundResults,
                              context.m_nonFoundResultsEdits.GetEntries());
  ShowMarks(context);
  m_view->OnResultChanged(sampleIndex, View::ResultType::Found,
                          Edits::Update::MakeAll());
  m_view->OnResultChanged(sampleIndex, View::ResultType::NonFound,
                          Edits::Update::MakeAll());
  m_view->OnSampleChanged(sampleIndex, context.HasChanges());
  m_view->SetEdits(sampleIndex, context.m_foundResultsEdits, context.m_nonFoundResultsEdits);
  m_view->OnSearchCompleted();
}

void MainModel::ResetSearch()
{
  ++m_queryTimestamp;
  if (auto handle = m_queryHandle.lock())
    handle->Cancel();
}

void MainModel::ShowMarks(Context const & context)
{
  m_view->ClearSearchResultMarks();
  m_view->ShowFoundResultsMarks(context.m_foundResults.begin(), context.m_foundResults.end());
  m_view->ShowNonFoundResultsMarks(context.m_nonFoundResults,
                                   context.m_nonFoundResultsEdits.GetEntries());
}

template <typename Fn>
void MainModel::ForAnyMatchingEntry(Context & context, FeatureID const & id, Fn && fn)
{
  CHECK(context.m_initialized, ());

  auto const & foundResults = context.m_foundResults;
  CHECK_EQUAL(foundResults.GetCount(), context.m_foundResultsEdits.NumEntries(), ());
  for (size_t i = 0; i < foundResults.GetCount(); ++i)
  {
    auto const & result = foundResults[i];
    if (result.GetResultType() != search::Result::RESULT_FEATURE)
      continue;
    if (result.GetFeatureID() == id)
      return fn(context.m_foundResultsEdits, i);
  }

  FeatureType ft;
  CHECK(m_loader.Load(id, ft), ("Can't load feature:", id));
  search::Matcher matcher(m_loader);

  auto const & nonFoundResults = context.m_nonFoundResults;
  CHECK_EQUAL(nonFoundResults.size(), context.m_nonFoundResultsEdits.NumEntries(), ());
  for (size_t i = 0; i < nonFoundResults.size(); ++i)
  {
    auto const & result = context.m_nonFoundResults[i];
    if (matcher.Matches(result, ft))
      return fn(context.m_nonFoundResultsEdits, i);
  }
}
<|endoftext|>


<commit_before>#include <string.h>

#include <bot_core/bot_core.h>
#include <bot_vis/bot_vis.h>
#include <gtk/gtk.h>
#include <lcm/lcm.h>
#include <bot_lcmgl_render/lcmgl_bot_renderer.h>

/*#include <bot_vis/viewer.h>
#include <bot_vis/bot_vis.h>
#include <bot_vis/param_widget.h>
#include <bot_vis/glm.h>
#include <bot_frames/bot_frames.h>
#include <bot_param/param_client.h>
#include <bot_param/param_util.h>
*/

#include "UIProcessing.h"
#include "LinearAlgebra.h"
#include "perception/PclSurrogateUtils.h"
#include <renderer_robot_plan/renderer_robot_plan.hpp>

//#include <otdf_renderer/renderer_otdf.hpp>
#include <renderer_affordances/renderer_affordances.hpp>
#include <ConciseArgs>

using namespace surrogate_gui;

typedef struct {
    BotViewer *viewer;
    lcm_t *lcm;
} state_t;

/////////////////////////////////////////////////////////////

int main(int argc, char *argv[])
{

  string role = "robot";
  ConciseArgs opt(argc, (char**)argv);
  opt.add(role, "r", "role","Role - robot or base");
  opt.parse();
  std::cout << "role: " << role << "\n";

  string lcm_url="";
  std::string role_upper;
  for(short i = 0; i < role.size(); ++i)
     role_upper+= (std::toupper(role[i]));
  if((role.compare("robot") == 0) || (role.compare("base") == 0) ){
    for(short i = 0; i < role_upper.size(); ++i)
       role_upper[i] = (std::toupper(role_upper[i]));
    string env_variable_name = string("LCM_URL_DRC_" + role_upper);
    char* env_variable;
    env_variable = getenv (env_variable_name.c_str());
    if (env_variable!=NULL){
      //printf ("The env_variable is: %s\n",env_variable);
      lcm_url = string(env_variable);
    }else{
      std::cout << env_variable_name << " environment variable has not been set ["<< lcm_url <<"]\n";
      exit(-1);
    }
  }else{
    std::cout << "Role not understood, choose: robot or base\n";
    return 1;
  }

  string vis_config_file="";
  if(role.compare("robot") == 0){
     vis_config_file = ".bot-plugin-robot-segmentation-viewer";
  }else if(role.compare("base") == 0){
     vis_config_file = ".bot-plugin-base-segmentation-viewer";
  }else{
    std::cout << "DRC Viewer role not understood, choose: robot or base\n";
    return 1;
  }

	//LinearAlgebra::runTests();
	//PclSurrogateUtils::runTests();
	//if (true) return 1;

	/*for (int i = 0; i < Color::HIGHLIGHT; i++)
	{
		cout << " i = " << i << " getColor(i) = " <<
				Color::getColor(i) << " | as int = " <<
				((int) Color::getColor(i)) << endl;
	}

	vector<Color::StockColor> colors = Color::getDifferentColors(Color::BLUE, 5);
	cout << endl << "===different colors w/ initial = " << Color::BLUE << "====" << endl;
	for (uint i = 0; i < colors.size(); i++)
	{
		cout << "\nnext color = " << colors[i] << endl;
	}

	return 0;
*/
    gtk_init(&argc, &argv);
    glutInit(&argc, argv);
    g_thread_init(NULL);

    setlinebuf(stdout);

    state_t app;
    memset(&app, 0, sizeof(app));

    BotViewer *viewer = bot_viewer_new("Segmentation");
    app.viewer = viewer;
    app.lcm = lcm_create( lcm_url.c_str() );
    boost::shared_ptr<lcm::LCM> lcmCpp = boost::shared_ptr<lcm::LCM>(new lcm::LCM(app.lcm));

    bot_glib_mainloop_attach_lcm(app.lcm);

    //otdf
    // older: setup_renderer_otdf(viewer, 0, lcmCpp);
    setup_renderer_affordances(viewer, 0, lcmCpp->getUnderlyingLCM());

    // setup renderers
    bot_viewer_add_stock_renderer(viewer, BOT_VIEWER_STOCK_RENDERER_GRID, 1);
    //KinectRendererXYZRGB *krxyzrgb = kinect_add_renderer_xyzrgb_to_viewer(viewer, 0,NULL,NULL);

    // lcmgl
    bot_lcmgl_add_renderer_to_viewer(viewer, lcmCpp->getUnderlyingLCM(), 1);

	// create segmentation handler
    std::string channel_name = "LOCAL_MAP_POINTS";
    UIProcessing uip(viewer, lcmCpp, channel_name.c_str()); //"KINECT_XYZRGB_ROS");

    std::cout << "Listening to data from channel: " << channel_name << "\n";

    // load saved preferences
    char *fname = g_build_filename(g_get_user_config_dir(), vis_config_file.c_str() , NULL);
    bot_viewer_load_preferences(viewer, fname);

    printf("\n\n\n========USAGE:\n");
    printf("'a' = display axes for currently force or rotation-axis vector [track mode]\n");
    printf("'c' = camera move\n");
    printf("'g' = display trajector determined by force vector + rotation axis\n");
    printf("'r' = rectangle select (valid in selection mode)\n");
    printf("'s' = turn segment coloring on/off (valid in selection mode)\n");
    printf("'t' = turn tracking info on/off\n");
    printf("'u' = turn model fit display on/off in segmenting mode\n");
    printf("'<--' and '-->' switch between sub-components of an object [segment mode]");
    printf("'<--', '-->', [up|down] arrows +- [shift_l and/or shift_r]: rotate vector [track mode]");
    printf("'tab', switch between rotation axis vector and force vector [track mode]");

    printf("\n==============\n\n\n");

    // run the main loop
    gtk_main();

    // save any changed preferences
    bot_viewer_save_preferences(viewer, fname);
    free(fname);

    // cleanup
    bot_viewer_unref(viewer);

    return 0;
}
<commit_msg>fixed broken build due to change in renderer_affordances api<commit_after>#include <string.h>

#include <bot_core/bot_core.h>
#include <bot_vis/bot_vis.h>
#include <gtk/gtk.h>
#include <lcm/lcm.h>
#include <bot_lcmgl_render/lcmgl_bot_renderer.h>

/*#include <bot_vis/viewer.h>
#include <bot_vis/bot_vis.h>
#include <bot_vis/param_widget.h>
#include <bot_vis/glm.h>
#include <bot_frames/bot_frames.h>
#include <bot_param/param_client.h>
#include <bot_param/param_util.h>
*/

#include "UIProcessing.h"
#include "LinearAlgebra.h"
#include "perception/PclSurrogateUtils.h"
#include <renderer_robot_plan/renderer_robot_plan.hpp>

//#include <otdf_renderer/renderer_otdf.hpp>
#include <renderer_affordances/renderer_affordances.hpp>
#include <ConciseArgs>

using namespace surrogate_gui;

typedef struct {
    BotViewer *viewer;
    lcm_t *lcm;
} state_t;

/////////////////////////////////////////////////////////////

int main(int argc, char *argv[])
{

  string role = "robot";
  ConciseArgs opt(argc, (char**)argv);
  opt.add(role, "r", "role","Role - robot or base");
  opt.parse();
  std::cout << "role: " << role << "\n";

  string lcm_url="";
  std::string role_upper;
  for(short i = 0; i < role.size(); ++i)
     role_upper+= (std::toupper(role[i]));
  if((role.compare("robot") == 0) || (role.compare("base") == 0) ){
    for(short i = 0; i < role_upper.size(); ++i)
       role_upper[i] = (std::toupper(role_upper[i]));
    string env_variable_name = string("LCM_URL_DRC_" + role_upper);
    char* env_variable;
    env_variable = getenv (env_variable_name.c_str());
    if (env_variable!=NULL){
      //printf ("The env_variable is: %s\n",env_variable);
      lcm_url = string(env_variable);
    }else{
      std::cout << env_variable_name << " environment variable has not been set ["<< lcm_url <<"]\n";
      exit(-1);
    }
  }else{
    std::cout << "Role not understood, choose: robot or base\n";
    return 1;
  }

  string vis_config_file="";
  if(role.compare("robot") == 0){
     vis_config_file = ".bot-plugin-robot-segmentation-viewer";
  }else if(role.compare("base") == 0){
     vis_config_file = ".bot-plugin-base-segmentation-viewer";
  }else{
    std::cout << "DRC Viewer role not understood, choose: robot or base\n";
    return 1;
  }

	//LinearAlgebra::runTests();
	//PclSurrogateUtils::runTests();
	//if (true) return 1;

	/*for (int i = 0; i < Color::HIGHLIGHT; i++)
	{
		cout << " i = " << i << " getColor(i) = " <<
				Color::getColor(i) << " | as int = " <<
				((int) Color::getColor(i)) << endl;
	}

	vector<Color::StockColor> colors = Color::getDifferentColors(Color::BLUE, 5);
	cout << endl << "===different colors w/ initial = " << Color::BLUE << "====" << endl;
	for (uint i = 0; i < colors.size(); i++)
	{
		cout << "\nnext color = " << colors[i] << endl;
	}

	return 0;
*/
    gtk_init(&argc, &argv);
    glutInit(&argc, argv);
    g_thread_init(NULL);

    setlinebuf(stdout);

    state_t app;
    memset(&app, 0, sizeof(app));

    BotViewer *viewer = bot_viewer_new("Segmentation");
    app.viewer = viewer;
    app.lcm = lcm_create( lcm_url.c_str() );
    BotParam* bot_param = bot_param_new_from_server(app.lcm, 0);
    if (bot_param == NULL) {
      fprintf(stderr, "Couldn't get bot param from server.\n");
      return 1;
    }
    BotFrames* bot_frames = bot_frames_new(app.lcm, bot_param);
    boost::shared_ptr<lcm::LCM> lcmCpp = boost::shared_ptr<lcm::LCM>(new lcm::LCM(app.lcm));

    bot_glib_mainloop_attach_lcm(app.lcm);

    //otdf
    // older: setup_renderer_otdf(viewer, 0, lcmCpp);
    setup_renderer_affordances(viewer, 0, lcmCpp->getUnderlyingLCM(), bot_frames);

    // setup renderers
    bot_viewer_add_stock_renderer(viewer, BOT_VIEWER_STOCK_RENDERER_GRID, 1);
    //KinectRendererXYZRGB *krxyzrgb = kinect_add_renderer_xyzrgb_to_viewer(viewer, 0,NULL,NULL);

    // lcmgl
    bot_lcmgl_add_renderer_to_viewer(viewer, lcmCpp->getUnderlyingLCM(), 1);

	// create segmentation handler
    std::string channel_name = "LOCAL_MAP_POINTS";
    UIProcessing uip(viewer, lcmCpp, channel_name.c_str()); //"KINECT_XYZRGB_ROS");

    std::cout << "Listening to data from channel: " << channel_name << "\n";

    // load saved preferences
    char *fname = g_build_filename(g_get_user_config_dir(), vis_config_file.c_str() , NULL);
    bot_viewer_load_preferences(viewer, fname);

    printf("\n\n\n========USAGE:\n");
    printf("'a' = display axes for currently force or rotation-axis vector [track mode]\n");
    printf("'c' = camera move\n");
    printf("'g' = display trajector determined by force vector + rotation axis\n");
    printf("'r' = rectangle select (valid in selection mode)\n");
    printf("'s' = turn segment coloring on/off (valid in selection mode)\n");
    printf("'t' = turn tracking info on/off\n");
    printf("'u' = turn model fit display on/off in segmenting mode\n");
    printf("'<--' and '-->' switch between sub-components of an object [segment mode]");
    printf("'<--', '-->', [up|down] arrows +- [shift_l and/or shift_r]: rotate vector [track mode]");
    printf("'tab', switch between rotation axis vector and force vector [track mode]");

    printf("\n==============\n\n\n");

    // run the main loop
    gtk_main();

    // save any changed preferences
    bot_viewer_save_preferences(viewer, fname);
    free(fname);

    // cleanup
    bot_viewer_unref(viewer);

    return 0;
}
<|endoftext|>


<commit_before>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2007 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "variant.h"

using namespace std;
using namespace Strigi;

class Strigi::VariantPrivate {
public:
    int32_t i_value;
    uint32_t u_value;
    string s_value;
    vector<string> as_value;
    vector<vector<string> > aas_value;
    Variant::Type vartype;
    bool valid;

    VariantPrivate() :i_value(0), u_value(0), vartype(Variant::b_val), valid(false) {}
    VariantPrivate(const Variant& v) { *this = v; }
    void operator=(const VariantPrivate& v);
    bool b() const;
    int32_t i() const;
    uint32_t u() const;
    string s() const;
    vector<string> as() const;
    vector<vector<string> > aas() const;

    static string itos(int32_t i);
};
Variant::Variant() :p(new VariantPrivate()) {}
Variant::Variant(bool v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(int32_t v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(uint32_t v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const char* v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const string& v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const vector<string>& v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const vector<vector<string> >& v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const Variant& v) :p(new VariantPrivate(*v.p)) {
}
Variant::~Variant() {
  delete p;
}

Variant::Type
Variant::type() const { return p->vartype; }
const Variant&
Variant::operator=(bool v) {
    p->valid = true;
    p->i_value = v;
    p->vartype = b_val;
    return *this;
}
const Variant&
Variant::operator=(int32_t v) {
    p->valid=true;
    p->i_value = v;
    p->u_value = v;
    p->vartype = i_val;
    return *this;
}
const Variant&
Variant::operator=(uint32_t v) {
    p->valid=true;
    p->i_value = v;
    p->u_value = v;
    p->vartype = u_val;
    return *this;
}
const Variant&
Variant::operator=(const char* v) {
    p->valid=true;
    p->s_value.assign(v);
    p->vartype = s_val;
    return *this;
}
const Variant&
Variant::operator=(const string& v) {
    p->valid=true;
    p->s_value.assign(v);
    p->vartype = s_val;
    return *this;
}
const Variant&
Variant::operator=(const vector<string>& v) {
    p->valid=true;
    p->as_value = v;
    p->vartype = as_val;
    return *this;
}
const Variant&
Variant::operator=(const vector<vector<string> >& v) {
    p->valid=true;
    p->aas_value = v;
    p->vartype = aas_val;
    return *this;
}
const Variant&
Variant::operator=(const Variant& v) {
    *p = *v.p;
    return v;
}
void
VariantPrivate::operator=(const VariantPrivate& v) {
    i_value = v.i_value;
    s_value = v.s_value;
    as_value = v.as_value;
    vartype = v.vartype;
    valid = v.valid;
}
bool
Variant::b() const {
    return p->b();
}
bool
VariantPrivate::b() const {
    switch (vartype) {
    case Variant::b_val:
    case Variant::i_val:
         return i_value;
    case Variant::s_val:
         return s_value == "1" || s_value == "true" || s_value == "True"
             || s_value == "TRUE";
    case Variant::as_val:
         return as_value.size();
    default:
         return false;
    }
}
int32_t
Variant::i() const {
    return p->i();
}
int32_t
VariantPrivate::i() const {
    switch (vartype) {
    case Variant::b_val:
    case Variant::i_val:
         return i_value;
    case Variant::s_val:
         return atoi(s_value.c_str());
    case Variant::as_val:
         return as_value.size();
    default:
         return -1;
    }
}
int32_t
Variant::u() const {
    return p->u();
}
uint32_t
VariantPrivate::u() const {
    switch (vartype) {
    case Variant::b_val:
    case Variant::i_val:
    case Variant::u_val:
         return u_value;
    case Variant::s_val:
         return atoi(s_value.c_str());
    case Variant::as_val:
         return as_value.size();
    default:
         return -1;
    }
}
string
VariantPrivate::itos(int32_t i) {
    ostringstream o;
    o << i;
    return o.str();
}
string
Variant::s() const {
    return p->s();
}
string
VariantPrivate::s() const {
    switch (vartype) {
    case Variant::b_val:
         return i_value ?"true" :"false";
    case Variant::i_val:
         return itos(i_value);
    case Variant::s_val:
         return s_value;
    case Variant::as_val:
         return as_value.size() ?as_value[0] :"";
    default:
         return "";
    }
}
vector<string>
Variant::as() const {
    return p->as();
}
vector<string>
VariantPrivate::as() const {
    if (vartype == Variant::as_val) {
        return as_value;
    }
    vector<string> v;
    if (b()) {
        v.push_back(s());
    }
    return v;
}
vector<vector<string> >
Variant::aas() const {
    return p->aas();
}
vector<vector<string> >
VariantPrivate::aas() const {
    if (vartype == Variant::aas_val) {
        return aas_value;
    }
    vector<vector<string> > v;
    if (b()) {
        v.push_back(as());
    }
    return v;
}
bool
Variant::isValid() const {
    return p->valid;
}
<commit_msg>fix return type<commit_after>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2007 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "variant.h"

using namespace std;
using namespace Strigi;

class Strigi::VariantPrivate {
public:
    int32_t i_value;
    uint32_t u_value;
    string s_value;
    vector<string> as_value;
    vector<vector<string> > aas_value;
    Variant::Type vartype;
    bool valid;

    VariantPrivate() :i_value(0), u_value(0), vartype(Variant::b_val), valid(false) {}
    VariantPrivate(const Variant& v) { *this = v; }
    void operator=(const VariantPrivate& v);
    bool b() const;
    int32_t i() const;
    uint32_t u() const;
    string s() const;
    vector<string> as() const;
    vector<vector<string> > aas() const;

    static string itos(int32_t i);
};
Variant::Variant() :p(new VariantPrivate()) {}
Variant::Variant(bool v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(int32_t v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(uint32_t v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const char* v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const string& v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const vector<string>& v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const vector<vector<string> >& v) :p(new VariantPrivate()) {
    *this=v;
}
Variant::Variant(const Variant& v) :p(new VariantPrivate(*v.p)) {
}
Variant::~Variant() {
  delete p;
}

Variant::Type
Variant::type() const { return p->vartype; }
const Variant&
Variant::operator=(bool v) {
    p->valid = true;
    p->i_value = v;
    p->vartype = b_val;
    return *this;
}
const Variant&
Variant::operator=(int32_t v) {
    p->valid=true;
    p->i_value = v;
    p->u_value = v;
    p->vartype = i_val;
    return *this;
}
const Variant&
Variant::operator=(uint32_t v) {
    p->valid=true;
    p->i_value = v;
    p->u_value = v;
    p->vartype = u_val;
    return *this;
}
const Variant&
Variant::operator=(const char* v) {
    p->valid=true;
    p->s_value.assign(v);
    p->vartype = s_val;
    return *this;
}
const Variant&
Variant::operator=(const string& v) {
    p->valid=true;
    p->s_value.assign(v);
    p->vartype = s_val;
    return *this;
}
const Variant&
Variant::operator=(const vector<string>& v) {
    p->valid=true;
    p->as_value = v;
    p->vartype = as_val;
    return *this;
}
const Variant&
Variant::operator=(const vector<vector<string> >& v) {
    p->valid=true;
    p->aas_value = v;
    p->vartype = aas_val;
    return *this;
}
const Variant&
Variant::operator=(const Variant& v) {
    *p = *v.p;
    return v;
}
void
VariantPrivate::operator=(const VariantPrivate& v) {
    i_value = v.i_value;
    s_value = v.s_value;
    as_value = v.as_value;
    vartype = v.vartype;
    valid = v.valid;
}
bool
Variant::b() const {
    return p->b();
}
bool
VariantPrivate::b() const {
    switch (vartype) {
    case Variant::b_val:
    case Variant::i_val:
         return i_value;
    case Variant::s_val:
         return s_value == "1" || s_value == "true" || s_value == "True"
             || s_value == "TRUE";
    case Variant::as_val:
         return as_value.size();
    default:
         return false;
    }
}
int32_t
Variant::i() const {
    return p->i();
}
int32_t
VariantPrivate::i() const {
    switch (vartype) {
    case Variant::b_val:
    case Variant::i_val:
         return i_value;
    case Variant::s_val:
         return atoi(s_value.c_str());
    case Variant::as_val:
         return as_value.size();
    default:
         return -1;
    }
}
uint32_t
Variant::u() const {
    return p->u();
}
uint32_t
VariantPrivate::u() const {
    switch (vartype) {
    case Variant::b_val:
    case Variant::i_val:
    case Variant::u_val:
         return u_value;
    case Variant::s_val:
         return atoi(s_value.c_str());
    case Variant::as_val:
         return as_value.size();
    default:
         return -1;
    }
}
string
VariantPrivate::itos(int32_t i) {
    ostringstream o;
    o << i;
    return o.str();
}
string
Variant::s() const {
    return p->s();
}
string
VariantPrivate::s() const {
    switch (vartype) {
    case Variant::b_val:
         return i_value ?"true" :"false";
    case Variant::i_val:
         return itos(i_value);
    case Variant::s_val:
         return s_value;
    case Variant::as_val:
         return as_value.size() ?as_value[0] :"";
    default:
         return "";
    }
}
vector<string>
Variant::as() const {
    return p->as();
}
vector<string>
VariantPrivate::as() const {
    if (vartype == Variant::as_val) {
        return as_value;
    }
    vector<string> v;
    if (b()) {
        v.push_back(s());
    }
    return v;
}
vector<vector<string> >
Variant::aas() const {
    return p->aas();
}
vector<vector<string> >
VariantPrivate::aas() const {
    if (vartype == Variant::aas_val) {
        return aas_value;
    }
    vector<vector<string> > v;
    if (b()) {
        v.push_back(as());
    }
    return v;
}
bool
Variant::isValid() const {
    return p->valid;
}
<|endoftext|>


<commit_before>
#include "geometry.h"
#include <tuple>

namespace
{
	template<int n, typename T>
	inline const base::point &pt( const T &t )
	{
		return std::get<n>( t );
	}

	constexpr double PI = 3.14159265358979323846;
}

namespace draw
{

////////////////////////////////////////

size_t circle_precision( double r )
{
	size_t n = 3;
	double error = 0.0;
	do
	{
		n = n * 2;
		error = r * ( 1 - std::cos( PI / n ) );
	} while ( error > 0.5 );

	return n;
}

////////////////////////////////////////

void add_quadratic( const base::point &p1, const base::point &p2, const base::point &p3, polyline &line )
{
	using base::point;
	typedef std::tuple<point,point,point> curve;
	std::vector<curve> stack;
	stack.reserve( 16 );
	stack.emplace_back( p1, p2, p3 );
	point c0, c1, c2, c3;

	while ( !stack.empty() )
	{
		curve &c = stack.back();
		point mid = ( pt<0>( c ) + pt<2>( c ) ) * 0.5;

		if ( point::distance_squared( mid, pt<1>( c ) ) <= 0.01 )
		{
			line.push_back( pt<2>( c ) );
			stack.pop_back();
		}
		else
		{
			c0 = pt<0>( c );
			c1 = ( c0 + pt<1>( c ) ) * 0.5;
			c3 = ( pt<1>( c ) + pt<2>( c ) ) * 0.5;
			c2 = ( c1 + c3 ) * 0.5;

			c = std::make_tuple( c2, c3, pt<2>( c ) ); // right side
			stack.emplace_back( c0, c1, c2 );
		}
	}
}

////////////////////////////////////////

void add_cubic( const base::point &p1, const base::point &p2, const base::point &p3, const base::point &p4, polyline &line )
{
	using base::point;
	typedef std::tuple<point,point,point,point> curve;
	std::vector<curve> stack;
	stack.reserve( 16 );
	stack.emplace_back( p1, p2, p3, p4 );
	point p0, p01, p12, p23, p012, p123, p0123, d, d13, d23;
	bool first = true;

	while ( !stack.empty() )
	{
		curve &c = stack.back();
		p01 = ( pt<0>( c ) + pt<1>( c ) ) * 0.5;
		p12 = ( pt<1>( c ) + pt<2>( c ) ) * 0.5;
		p23 = ( pt<2>( c ) + pt<3>( c ) ) * 0.5;
		p012 = ( p01 + p12 ) * 0.5;
		p123 = ( p12 + p23 ) * 0.5;
		p0123 = ( p012 + p123 ) * 0.5;

		d = pt<0>( c ) - pt<3>( c );
		d13 = pt<1>( c ) - pt<3>( c );
		d23 = pt<2>( c ) - pt<3>( c );

		double d2 = d13.x() * d.y() - d13.y() * d.x();
		double d3 = d23.x() * d.y() - d23.y() * d.x();

		if ( ( d2 + d3 ) * ( d2 + d3 ) < 0.1 * ( d.x() * d.x() + d.y() * d.y() ) && !first )
		{
			line.push_back( pt<3>( c ) );
			stack.pop_back();
		}
		else
		{
			p0 = pt<0>( c );
			c = std::make_tuple( p0123, p123, p23, pt<3>( c ) ); // right side
			stack.emplace_back( p0, p01, p012, p0123 );
		}
		first = false;
	}
}

////////////////////////////////////////

void add_arc( const base::point &center, double radius, double a1, double a2, polyline &line )
{
	using base::point;

	size_t n = circle_precision( radius );

	double span = std::abs( std::fmod( ( a1 - a2 + PI ), 2.0 * PI ) - PI );
	n = size_t( std::ceil( n * span / ( 2.0 * PI ) ) );

	point p = point::polar( radius, a1 ) + center;
	if ( line.empty() || point::distance_squared( p, line.back() ) > 0.1 )
		line.push_back( p );

	for ( size_t i = 1; i <= n; ++i )
	{
		double m = double(i) / double(n);
		double a = a1 * ( 1.0 - m ) + a2 * m;
		line.push_back( point::polar( radius, a ) + center );
	}
}

////////////////////////////////////////

}

<commit_msg>Increased precision of circle.<commit_after>
#include "geometry.h"
#include <tuple>

namespace
{
	template<int n, typename T>
	inline const base::point &pt( const T &t )
	{
		return std::get<n>( t );
	}

	constexpr double PI = 3.14159265358979323846;
}

namespace draw
{

////////////////////////////////////////

size_t circle_precision( double r )
{
	size_t n = 3;
	double error = 0.0;
	do
	{
		n = n * 2;
		error = r * ( 1 - std::cos( PI / n ) );
	} while ( error > 0.01 );

	return n;
}

////////////////////////////////////////

void add_quadratic( const base::point &p1, const base::point &p2, const base::point &p3, polyline &line )
{
	using base::point;
	typedef std::tuple<point,point,point> curve;
	std::vector<curve> stack;
	stack.reserve( 16 );
	stack.emplace_back( p1, p2, p3 );
	point c0, c1, c2, c3;

	while ( !stack.empty() )
	{
		curve &c = stack.back();
		point mid = ( pt<0>( c ) + pt<2>( c ) ) * 0.5;

		if ( point::distance_squared( mid, pt<1>( c ) ) <= 0.01 )
		{
			line.push_back( pt<2>( c ) );
			stack.pop_back();
		}
		else
		{
			c0 = pt<0>( c );
			c1 = ( c0 + pt<1>( c ) ) * 0.5;
			c3 = ( pt<1>( c ) + pt<2>( c ) ) * 0.5;
			c2 = ( c1 + c3 ) * 0.5;

			c = std::make_tuple( c2, c3, pt<2>( c ) ); // right side
			stack.emplace_back( c0, c1, c2 );
		}
	}
}

////////////////////////////////////////

void add_cubic( const base::point &p1, const base::point &p2, const base::point &p3, const base::point &p4, polyline &line )
{
	using base::point;
	typedef std::tuple<point,point,point,point> curve;
	std::vector<curve> stack;
	stack.reserve( 16 );
	stack.emplace_back( p1, p2, p3, p4 );
	point p0, p01, p12, p23, p012, p123, p0123, d, d13, d23;
	bool first = true;

	while ( !stack.empty() )
	{
		curve &c = stack.back();
		p01 = ( pt<0>( c ) + pt<1>( c ) ) * 0.5;
		p12 = ( pt<1>( c ) + pt<2>( c ) ) * 0.5;
		p23 = ( pt<2>( c ) + pt<3>( c ) ) * 0.5;
		p012 = ( p01 + p12 ) * 0.5;
		p123 = ( p12 + p23 ) * 0.5;
		p0123 = ( p012 + p123 ) * 0.5;

		d = pt<0>( c ) - pt<3>( c );
		d13 = pt<1>( c ) - pt<3>( c );
		d23 = pt<2>( c ) - pt<3>( c );

		double d2 = d13.x() * d.y() - d13.y() * d.x();
		double d3 = d23.x() * d.y() - d23.y() * d.x();

		if ( ( d2 + d3 ) * ( d2 + d3 ) < 0.1 * ( d.x() * d.x() + d.y() * d.y() ) && !first )
		{
			line.push_back( pt<3>( c ) );
			stack.pop_back();
		}
		else
		{
			p0 = pt<0>( c );
			c = std::make_tuple( p0123, p123, p23, pt<3>( c ) ); // right side
			stack.emplace_back( p0, p01, p012, p0123 );
		}
		first = false;
	}
}

////////////////////////////////////////

void add_arc( const base::point &center, double radius, double a1, double a2, polyline &line )
{
	using base::point;

	size_t n = circle_precision( radius );

	double span = std::abs( std::fmod( ( a1 - a2 + PI ), 2.0 * PI ) - PI );
	n = size_t( std::ceil( n * span / ( 2.0 * PI ) ) );

	point p = point::polar( radius, a1 ) + center;
	if ( line.empty() || point::distance_squared( p, line.back() ) > 0.1 )
		line.push_back( p );

	for ( size_t i = 1; i <= n; ++i )
	{
		double m = double(i) / double(n);
		double a = a1 * ( 1.0 - m ) + a2 * m;
		line.push_back( point::polar( radius, a ) + center );
	}
}

////////////////////////////////////////

}

<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include <SFML/Graphics.hpp>

using namespace std;
using namespace sf;

void load_csv(string & filename, vector<float> & data)
{
    ifstream infile(filename.c_str());
    string s_number, line;
    getline(infile, line);
    stringstream linestream(line);
    while(getline(linestream, s_number, ','))
    {
        //data.push_back((atof(s_number.c_str()) + 2) * 50);
        data.push_back(atof(s_number.c_str()));
    }
    infile.close();
}

class TimeCourse : public Drawable
{
public:
    vector<float> data;
    TimeCourse(vector<float> & data)
    : data(data) {}
private:
    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        VertexArray polyline(sf::LinesStrip, data.size());
        for (int i = 0; i < data.size(); i++)
        {
            Vector2f p = Vector2f((float)i, data.at(i));
            polyline[i] = p;
        }
        target.draw(polyline, states);
    }
};

Transform getTransform(Vector2f center, Vector2f zoom) {
    Transform transform = Transform::Identity;
    transform = transform.translate(center.x, center.y);
    cout << center.x << " " << center.y << endl;
    transform = transform.scale(zoom.x, zoom.y);
    return transform.translate(-center.x, -center.y);
}

int main(int argc, char ** argv)
{

    if (argc < 2)
    {
        cout << "Usage: viewer [SIGNAL_FILENAME]" << endl;
        cout << "Exiting." << endl;
        exit(-1);
    }

    string filename(argv[1]);
    vector<float> data;
    load_csv(filename, data);
    TimeCourse tc(data);

    RenderWindow window(sf::VideoMode(1000, 500), "Mega Chaos");
    View upper_view;
    upper_view.reset(sf::FloatRect(0, -2, 10000, 4));

    //upper_view.setSize(800, 200);
    upper_view.setViewport(sf::FloatRect(0.f, 0.f, 1.f, 1.f));

    int current_view_level = 0;
    int level_cnt = 3;
    View current_view = upper_view;

    float x0p, x1p, x0p_, x1p_, pxm, pxs, l, l_;
    x0p = 0.; x1p = 10000.;
    x0p_ = x0p; x1p_ = x1p;
    l = x1p - x0p; l_ = l;

    float y0p, y1p, y0p_, y1p_, pym, pys, h, h_;
    y0p = -2.; y1p = 2.;
    y0p_ = y0p; y1p_ = y1p;
    h = y1p - y0p; h_ = h;
    float z = 0.95f;

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            if (event.type == sf::Event::MouseWheelMoved)
            {
                if (!Keyboard::isKeyPressed(Keyboard::LControl))
                {
                    if ((event.mouseWheel.delta > 0) && (x1p_ - x0p_) < 0.01)
                    {
                        continue;
                    }
                    std::cout << "X0P_, X1P_: " << x0p_ << ", " << x1p_ << std::endl;
                    std::cout << "Len: " << l_ << "," << l << std::endl;
                    pxm = event.mouseWheel.x;
                    pxs = pxm / window.getSize().x * l + x0p_;
                    std::cout << "PXM, PXS:  " << pxm << "," << pxs << std::endl;
                    z = 1 - event.mouseWheel.delta * 0.05;
                    x0p = ((pxs) * (1. - z) + z*x0p_);
                    x1p = z*l_ + x0p;
                    l = x1p - x0p;
                    std::cout << "X0P, X1P: " << x0p << ", " << x1p << std::endl;
                    std::cout << "Len: " << l_ << std::endl;
                    upper_view.reset(sf::FloatRect(x0p, y0p, l, h));

                    x0p_ = x0p;
                    x1p_ = x1p;
                    l_ = l;

                }
                else
                {
                    if ((event.mouseWheel.delta > 0) && (y1p_ - y0p_) < 0.01)
                    {
                        continue;
                    }
                    pym = event.mouseWheel.y;
                    pys = pym / window.getSize().y * h + y0p_;
                    z = 1 - event.mouseWheel.delta * 0.05;
                    y0p = ((pys) * (1. - z) + z*y0p_);
                    y1p = z*h_ + y0p;
                    h = y1p - y0p;
                    upper_view.reset(sf::FloatRect(x0p, y0p, l, h));

                    y0p_ = y0p;
                    y1p_ = y1p;
                    h_ = h;
                }
            }
        }
        window.clear(sf::Color::Black);
        //window.draw(line, 2, sf::Lines);

        window.setView(upper_view);
        window.draw(tc);

        window.display();
    }
}<commit_msg>Enabled rectangular zoom<commit_after>#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include <SFML/Graphics.hpp>

using namespace std;
using namespace sf;

void load_csv(string & filename, vector<float> & data)
{
    ifstream infile(filename.c_str());
    string s_number, line;
    getline(infile, line);
    stringstream linestream(line);
    while(getline(linestream, s_number, ','))
    {
        //data.push_back((atof(s_number.c_str()) + 2) * 50);
        data.push_back(atof(s_number.c_str()));
    }
    infile.close();
}

class TimeCourse : public Drawable
{
public:
    vector<float> data;
    TimeCourse(vector<float> & data)
    : data(data) {}
private:
    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        VertexArray polyline(sf::LinesStrip, data.size());
        for (int i = 0; i < data.size(); i++)
        {
            Vector2f p = Vector2f((float)i, data.at(i));
            polyline[i] = p;
        }
        target.draw(polyline, states);
    }
};

Transform getTransform(Vector2f center, Vector2f zoom) {
    Transform transform = Transform::Identity;
    transform = transform.translate(center.x, center.y);
    cout << center.x << " " << center.y << endl;
    transform = transform.scale(zoom.x, zoom.y);
    return transform.translate(-center.x, -center.y);
}

int main(int argc, char ** argv)
{

    if (argc < 2)
    {
        cout << "Usage: viewer [SIGNAL_FILENAME]" << endl;
        cout << "Exiting." << endl;
        exit(-1);
    }

    string filename(argv[1]);
    vector<float> data;
    load_csv(filename, data);
    TimeCourse tc(data);

    RenderWindow window(sf::VideoMode(1000, 500), "Mega Chaos");
    View upper_view;
    upper_view.reset(sf::FloatRect(0, -2, 10000, 4));

    //upper_view.setSize(800, 200);
    upper_view.setViewport(sf::FloatRect(0.f, 0.f, 1.f, 1.f));

    int current_view_level = 0;
    int level_cnt = 3;
    View current_view = upper_view;

    float x0p, x1p, x0p_, x1p_, pxm, pxs, l, l_;
    x0p = 0.; x1p = 10000.;
    x0p_ = x0p; x1p_ = x1p;
    l = x1p - x0p; l_ = l;

    float y0p, y1p, y0p_, y1p_, pym, pys, h, h_;
    y0p = -2.; y1p = 2.;
    y0p_ = y0p; y1p_ = y1p;
    h = y1p - y0p; h_ = h;
    float z = 0.95f;

    RectangleShape zoomRect;
    Vector2i initialPosition = Vector2i(0, 0);
    zoomRect.setFillColor(Color(76, 165, 0, 100));
    View zoomView;
    zoomView.reset(sf::FloatRect(0, 0, 1000, 500));

    //zoomView.setSize(800, 200);
    zoomView.setViewport(sf::FloatRect(0.f, 0.f, 1.f, 1.f));

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            if (event.type == sf::Event::MouseWheelMoved)
            {
                if (!Keyboard::isKeyPressed(Keyboard::LControl))
                {
                    if ((event.mouseWheel.delta > 0) && (x1p_ - x0p_) < 0.01)
                    {
                        continue;
                    }
                    std::cout << "X0P_, X1P_: " << x0p_ << ", " << x1p_ << std::endl;
                    std::cout << "Len: " << l_ << "," << l << std::endl;
                    pxm = event.mouseWheel.x;
                    pxs = pxm / window.getSize().x * l + x0p_;
                    std::cout << "PXM, PXS:  " << pxm << "," << pxs << std::endl;
                    z = 1 - event.mouseWheel.delta * 0.05;
                    x0p = ((pxs) * (1. - z) + z*x0p_);
                    x1p = z*l_ + x0p;
                    l = x1p - x0p;
                    std::cout << "X0P, X1P: " << x0p << ", " << x1p << std::endl;
                    std::cout << "Len: " << l_ << std::endl;
                    upper_view.reset(sf::FloatRect(x0p, y0p, l, h));

                    x0p_ = x0p;
                    x1p_ = x1p;
                    l_ = l;

                }
                else
                {
                    if ((event.mouseWheel.delta > 0) && (y1p_ - y0p_) < 0.01)
                    {
                        continue;
                    }
                    pym = event.mouseWheel.y;
                    pys = pym / window.getSize().y * h + y0p_;
                    z = 1 - event.mouseWheel.delta * 0.05;
                    y0p = ((pys) * (1. - z) + z*y0p_);
                    y1p = z*h_ + y0p;
                    h = y1p - y0p;
                    upper_view.reset(sf::FloatRect(x0p, y0p, l, h));

                    y0p_ = y0p;
                    y1p_ = y1p;
                    h_ = h;
                }
            }
            if (event.type == Event::MouseButtonPressed &&
                Keyboard::isKeyPressed(Keyboard::R))
            {
                initialPosition = Mouse::getPosition(window);
                zoomRect.setPosition(initialPosition.x, initialPosition.y);
                cout << "initial pos: " << initialPosition.x << ", " << initialPosition.y << endl;
            }
            if (Keyboard::isKeyPressed(Keyboard::R) && Mouse::isButtonPressed(Mouse::Left))
            {
                zoomRect.setPosition(initialPosition.x, initialPosition.y);

                Vector2i newPos = Mouse::getPosition(window);
                float len = newPos.x - initialPosition.x;
                float wid = newPos.y - initialPosition.y;
                zoomRect.setSize(Vector2f(len, wid));
                cout << "Drawing..." << endl;
                cout << "X, Y: " << zoomRect.getPosition().x << ", " << zoomRect.getPosition().y <<
                ", W, H: " << zoomRect.getSize().x << ", " << zoomRect.getSize().y << endl;
            }
            if (event.type == Event::MouseButtonReleased && zoomRect.getSize().x > 0)
            {
                float x0 = initialPosition.x;
                float x1 = Mouse::getPosition(window).x;
                x0 = x0 / window.getSize().x * l_ + x0p_;
                x1 = x1 / window.getSize().x * l_ + x0p_;
                float y0 = initialPosition.y;
                float y1 = Mouse::getPosition(window).y;
                y0 = y0 / window.getSize().y * h_ + y0p_;
                y1 = y1 / window.getSize().y * h_ + y0p_;

                upper_view.reset(FloatRect(x0, y0, x1 - x0, y1 - y0));

                x0p_ = x0p = x0;
                x1p_ = x1p = x1;
                y0p_ = y0p = y0;
                y1p_ = y1p = y1;
                l_ = l = x1 - x0;
                h_ = h = y1 - y0;

                zoomRect.setSize(Vector2f(0, 0));
            }
        }
        window.clear(sf::Color::Black);
        //window.draw(line, 2, sf::Lines);

        window.setView(upper_view);
        window.draw(tc);

        window.setView(zoomView);
        window.draw(zoomRect);

        window.display();
    }
}<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Library
  Module:    Cell.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Description:
---------------------------------------------------------------------------
This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
//
// Abstract specification of computational cells.
//
#ifndef __vlCell_h
#define __vlCell_h

#define MAX_CELL_SIZE 128
#define TOL 1.e-05 // Tolerance for geometric calculation

#include "Object.hh"
#include "FPoints.hh"
#include "FScalars.hh"
#include "IdList.hh"
#include "CellType.hh"

class vlCellArray;

class vlCell : public vlObject
{
public:
  vlCell(): Points(MAX_CELL_SIZE), PointIds(MAX_CELL_SIZE) {};
  void Initialize(int npts, int *pts, vlPoints *p);
  char *GetClassName() {return "vlCell";};

  // Because these objects (cells and derived classes) are computational
  // objects, and because they are used internally, do not use memory
  // reference counting.

  // Type of cell
  virtual int GetCellType() = 0;

  // Dimensionality of cell (0,1,2, or 3)
  virtual int GetCellDimension() = 0;

  // Point coordinates for cell.
  vlFloatPoints *GetPoints() {return &this->Points;};

  // Number of points (and other topological entities) in cell
  int GetNumberOfPoints() {return this->PointIds.GetNumberOfIds();};
  virtual int GetNumberOfEdges() = 0;
  virtual int GetNumberOfFaces() = 0;

  // Get topological entities
  vlIdList *GetPointIds() {return &this->PointIds;};
  int GetPointId(int ptId) {return this->PointIds.GetId(ptId);};
  virtual vlCell *GetEdge(int edgeId) = 0;
  virtual vlCell *GetFace(int faceId) = 0;

  // given a point x[3] return inside(=1) or outside(=0) cell; evaluate
  // parametric coordinates, sub-cell id (!=0 only if cell is composite),
  // distance squared  of point x[3] to cell (in particular, the sub-cell
  // indicated), and interpolation weights in cell.
  virtual int EvaluatePosition(float x[3], float closestPoint[3],
                               int& subId, float pcoords[3],
                               float& dist2, float weights[MAX_CELL_SIZE]) = 0;

  // Determine global coordinate from subId and parametric coordinates
  virtual void EvaluateLocation(int& subId, float pcoords[3],
                                float x[3], float weights[MAX_CELL_SIZE]) = 0;

  // Generate contouring primitives
  virtual void Contour(float value, vlFloatScalars *cellScalars,
                       vlFloatPoints *points, vlCellArray *verts,
                       vlCellArray *lines, vlCellArray *polys,
                       vlFloatScalars *scalars) = 0;

  // Compute cell bounding box (xmin,xmax,ymin,ymax,zmin,zmax)
  float *GetBounds();

  // Quick intersection of cell bounding box.  Returns != 0 for hit.
  char HitBBox(float bounds[6], float origin[3], float dir[3], float coord[3]);

  // left public for quick computational access
  vlFloatPoints Points;
  vlIdList PointIds;

};

#endif

<commit_msg>ENH: Added length2 method.<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    Cell.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Description:
---------------------------------------------------------------------------
This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
//
// Abstract specification of computational cells.
//
#ifndef __vlCell_h
#define __vlCell_h

#define MAX_CELL_SIZE 128
#define TOL 1.e-05 // Tolerance for geometric calculation

#include "Object.hh"
#include "FPoints.hh"
#include "FScalars.hh"
#include "IdList.hh"
#include "CellType.hh"

class vlCellArray;

class vlCell : public vlObject
{
public:
  vlCell(): Points(MAX_CELL_SIZE), PointIds(MAX_CELL_SIZE) {};
  void Initialize(int npts, int *pts, vlPoints *p);
  char *GetClassName() {return "vlCell";};

  // Because these objects (cells and derived classes) are computational
  // objects, and because they are used internally, do not use memory
  // reference counting.

  // Type of cell
  virtual int GetCellType() = 0;

  // Dimensionality of cell (0,1,2, or 3)
  virtual int GetCellDimension() = 0;

  // Point coordinates for cell.
  vlFloatPoints *GetPoints() {return &this->Points;};

  // Number of points (and other topological entities) in cell
  int GetNumberOfPoints() {return this->PointIds.GetNumberOfIds();};
  virtual int GetNumberOfEdges() = 0;
  virtual int GetNumberOfFaces() = 0;

  // Get topological entities
  vlIdList *GetPointIds() {return &this->PointIds;};
  int GetPointId(int ptId) {return this->PointIds.GetId(ptId);};
  virtual vlCell *GetEdge(int edgeId) = 0;
  virtual vlCell *GetFace(int faceId) = 0;

  // given a point x[3] return inside(=1) or outside(=0) cell; evaluate
  // parametric coordinates, sub-cell id (!=0 only if cell is composite),
  // distance squared  of point x[3] to cell (in particular, the sub-cell
  // indicated), and interpolation weights in cell.
  virtual int EvaluatePosition(float x[3], float closestPoint[3],
                               int& subId, float pcoords[3],
                               float& dist2, float weights[MAX_CELL_SIZE]) = 0;

  // Determine global coordinate from subId and parametric coordinates
  virtual void EvaluateLocation(int& subId, float pcoords[3],
                                float x[3], float weights[MAX_CELL_SIZE]) = 0;

  // Generate contouring primitives
  virtual void Contour(float value, vlFloatScalars *cellScalars,
                       vlFloatPoints *points, vlCellArray *verts,
                       vlCellArray *lines, vlCellArray *polys,
                       vlFloatScalars *scalars) = 0;

  // Compute cell bounding box (xmin,xmax,ymin,ymax,zmin,zmax)
  float *GetBounds();

  // Compute Length squared of cell (i.e., bounding box diagonal squared)
  float GetLength2();

  // Quick intersection of cell bounding box.  Returns != 0 for hit.
  char HitBBox(float bounds[6], float origin[3], float dir[3], float coord[3]);

  // left public for quick computational access
  vlFloatPoints Points;
  vlIdList PointIds;

};

#endif

<|endoftext|>