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

#include <iostream>
#include <vector>
#include <string>

#include "boost/multi_array.hpp"

#include "IECore/CompoundParameter.h"
#include "IECore/ImagePrimitive.h"
#include "IECore/DespatchTypedData.h"
#include "IECore/DataConvert.h"
#include "IECore/ScaledDataConversion.h"
#include "IECore/TypedData.h"
#include "IECore/VectorTypedData.h"

#include "IECoreMaya/ToMayaImageConverter.h"
#include "IECoreMaya/MImageAccessor.h"

using namespace IECoreMaya;
using namespace IECore;

using std::string;
using std::vector;

ToMayaImageConverter::ToMayaImageConverter( ConstObjectPtr object )
	:	ToMayaConverter( "ToMayaImageConverter", "Converts image types.", IECore::ImagePrimitiveTypeId )
{
	srcParameter()->setValue( boost::const_pointer_cast<Object>( object ) );

	IntParameter::PresetsMap typePresets;
	typePresets["Float"] = Float;
	typePresets["Byte"] = Byte;

	m_typeParameter = new IntParameter(
		"type",
		"Type of image to convert to",
		Byte,
		typePresets );

	parameters()->addParameter( m_typeParameter );
}

ToMayaImageConverterPtr ToMayaImageConverter::create( const IECore::ObjectPtr src )
{
	return new ToMayaImageConverter( src );
}

IntParameterPtr ToMayaImageConverter::typeParameter()
{
	return m_typeParameter;
}

ConstIntParameterPtr ToMayaImageConverter::typeParameter() const
{
	return m_typeParameter;
}

template<typename C>
struct ToMayaImageConverter::ChannelConverter
{
	typedef typename TypedData< std::vector<C> >::Ptr  ReturnType;

	const std::string &m_channelName;

	ChannelConverter( const std::string &channelName ) : m_channelName( channelName )
	{
	}

	template<typename T>
	ReturnType operator()( typename T::Ptr data )
	{
		assert( data );

		return DataConvert < T, TypedData< std::vector<C> >, ScaledDataConversion< typename T::ValueType::value_type, C> >()
		(
			boost::static_pointer_cast<const T>( data )
		);
	};

	struct ErrorHandler
	{
		template<typename T, typename F>
		void operator()( typename T::ConstPtr data, const F& functor )
		{
			assert( data );

			throw InvalidArgumentException( ( boost::format( "ToMayaImageConverter: Invalid data type \"%s\" for channel \"%s\"." ) % Object::typeNameFromTypeId( data->typeId() ) % functor.m_channelName ).str() );
		}
	};
};

template<typename T>
void ToMayaImageConverter::writeChannel( MImage &image, typename TypedData< std::vector<T> >::Ptr channelData, unsigned channelOffset, unsigned numChannels ) const
{
	assert( channelOffset < numChannels );

	ConstImagePrimitivePtr toConvert = runTimeCast<const ImagePrimitive>( srcParameter()->getValidatedValue() );
	assert( toConvert );

	unsigned width, height;
	image.getSize( width, height );

	const Imath::Box2i &dataWindow = toConvert->getDataWindow();
	const Imath::Box2i &displayWindow = toConvert->getDisplayWindow();

	unsigned int dataWidth = dataWindow.size().x + 1;
	unsigned int dataHeight = dataWindow.size().y + 1;

	Imath::V2i dataOffset = dataWindow.min - displayWindow.min ;

	boost::multi_array_ref< const T, 2 > src( &channelData->readable()[0], boost::extents[dataHeight][dataWidth] );
	boost::multi_array_ref< T, 3 > dst( MImageAccessor<T>::getPixels( image ), boost::extents[ height ][ width ][ numChannels ] );

	for ( unsigned x = 0; x < dataWidth; x++ )
	{
		for ( unsigned y = 0; y < dataHeight; y++ )
		{
			/// Vertical flip, to match Maya
			dst[ ( height - 1 ) - ( y + dataOffset.y ) ][ x + dataOffset.x ][channelOffset] = src[y][x];
		}
	}
}

template<typename T>
void ToMayaImageConverter::writeAlpha( MImage &image, const T &alpha ) const
{
	const int numChannels = 4;
	const int channelOffset = 3;

	unsigned width, height;
	image.getSize( width, height );

	boost::multi_array_ref< T, 3 > dst( MImageAccessor<T>::getPixels( image ), boost::extents[ height ][ width ][ numChannels ] );

	for ( unsigned x = 0; x < width; x++ )
	{
		for ( unsigned y = 0; y < height; y++ )
		{
			dst[y][x][channelOffset] = alpha;
		}
	}
}

MStatus ToMayaImageConverter::convert( MImage &image ) const
{
	MStatus s;
	ConstImagePrimitivePtr toConvert = runTimeCast<const ImagePrimitive>( srcParameter()->getValidatedValue() );
	assert( toConvert );

	unsigned int width = toConvert->getDisplayWindow().size().x + 1;
	unsigned int height = toConvert->getDisplayWindow().size().y + 1;

	MImage::MPixelType pixelType = MImage::kUnknown;
	switch( typeParameter()->getNumericValue() )
	{
		case Float :
			pixelType = MImage::kFloat;
			break;
		case Byte:
			pixelType = MImage::kByte;
			break;
		default :

			assert( false );
	}

	/// Get the channels RGBA at the front, in that order, if they exist
	vector<string> desiredChannelOrder;
	desiredChannelOrder.push_back( "R" );
	desiredChannelOrder.push_back( "G" );
	desiredChannelOrder.push_back( "B" );
	desiredChannelOrder.push_back( "A" );

	vector<string> channelNames;
	for  ( PrimitiveVariableMap::const_iterator it = toConvert->variables.begin(); it != toConvert->variables.end(); ++it )
	{
		channelNames.push_back( it->first );
	}

	vector<string> filteredNames;

	int rgbChannelsFound = 0;
	bool haveAlpha = false;
	for ( vector<string>::const_iterator it = desiredChannelOrder.begin(); it != desiredChannelOrder.end(); ++it )
	{
		vector<string>::iterator res = find( channelNames.begin(), channelNames.end(), *it );
		if ( res != channelNames.end() )
		{
			if ( *it == "A" )
			{
				haveAlpha = true;
			}
			else
			{
				rgbChannelsFound ++;
			}
			channelNames.erase( res );
			filteredNames.push_back( *it );
		}
	}
	channelNames = filteredNames;

	if ( rgbChannelsFound != 3 )
	{
		return MS::kFailure;
	}

	unsigned numChannels = 4; // We always add an alpha if one is not present.

	s = image.create( width, height, numChannels, pixelType );
	if ( !s )
	{
		return s;
	}

	image.setRGBA( true );

	unsigned channelOffset = 0;
	for ( vector<string>::const_iterator it = channelNames.begin(); it != channelNames.end(); ++it, ++channelOffset )
	{
		DataPtr dataContainer = toConvert->variables.find( *it )->second.data;
		assert( dataContainer );

		switch( pixelType )
		{
			case MImage::kFloat :
			{
				ChannelConverter<float> converter( *it );
				FloatVectorDataPtr channelData = despatchTypedData<
					ChannelConverter<float>,
					TypeTraits::IsNumericVectorTypedData,
					ChannelConverter<float>::ErrorHandler
				>( dataContainer, converter );

				writeChannel<float>( image, channelData, channelOffset, numChannels );
			}

				break;
			case MImage::kByte:
			{
				ChannelConverter<unsigned char> converter( *it );
				UCharVectorDataPtr channelData = despatchTypedData<
					ChannelConverter<unsigned char>,
					TypeTraits::IsNumericVectorTypedData,
					ChannelConverter<unsigned char>::ErrorHandler
				>( dataContainer, converter );

				writeChannel<unsigned char>( image, channelData, channelOffset, numChannels );
			}

				break;
			default :

				assert( false );
		}
	}

	if ( !haveAlpha )
	{
		switch( pixelType )
		{
			case MImage::kFloat :
			{
				writeAlpha<float>( image, 1.0 );
			}
			break;
			case MImage::kByte :
			{
				writeAlpha<unsigned char>( image, 255 );
			}
			break;
			default :

				assert( false );
		}
	}

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

#include <iostream>
#include <vector>
#include <string>

#include "boost/multi_array.hpp"

#include "IECore/CompoundParameter.h"
#include "IECore/ImagePrimitive.h"
#include "IECore/DespatchTypedData.h"
#include "IECore/DataConvert.h"
#include "IECore/ScaledDataConversion.h"
#include "IECore/TypedData.h"
#include "IECore/VectorTypedData.h"

#include "IECoreMaya/ToMayaImageConverter.h"
#include "IECoreMaya/MImageAccessor.h"

using namespace IECoreMaya;
using namespace IECore;

using std::string;
using std::vector;

ToMayaImageConverter::ToMayaImageConverter( ConstObjectPtr object )
	:	ToMayaConverter( "ToMayaImageConverter", "Converts image types.", IECore::ImagePrimitiveTypeId )
{
	srcParameter()->setValue( boost::const_pointer_cast<Object>( object ) );

	IntParameter::PresetsMap typePresets;
	typePresets["Float"] = Float;
	typePresets["Byte"] = Byte;

	m_typeParameter = new IntParameter(
		"type",
		"Type of image to convert to",
		Byte,
		typePresets );

	parameters()->addParameter( m_typeParameter );
}

ToMayaImageConverterPtr ToMayaImageConverter::create( const IECore::ObjectPtr src )
{
	return new ToMayaImageConverter( src );
}

IntParameterPtr ToMayaImageConverter::typeParameter()
{
	return m_typeParameter;
}

ConstIntParameterPtr ToMayaImageConverter::typeParameter() const
{
	return m_typeParameter;
}

template<typename C>
struct ToMayaImageConverter::ChannelConverter
{
	typedef typename TypedData< std::vector<C> >::Ptr  ReturnType;

	const std::string &m_channelName;

	ChannelConverter( const std::string &channelName ) : m_channelName( channelName )
	{
	}

	template<typename T>
	ReturnType operator()( typename T::Ptr data )
	{
		assert( data );

		return DataConvert < T, TypedData< std::vector<C> >, ScaledDataConversion< typename T::ValueType::value_type, C> >()
		(
			boost::static_pointer_cast<const T>( data )
		);
	};

	struct ErrorHandler
	{
		template<typename T, typename F>
		void operator()( typename T::ConstPtr data, const F& functor )
		{
			assert( data );

			throw InvalidArgumentException( ( boost::format( "ToMayaImageConverter: Invalid data type \"%s\" for channel \"%s\"." ) % Object::typeNameFromTypeId( data->typeId() ) % functor.m_channelName ).str() );
		}
	};
};

template<typename T>
void ToMayaImageConverter::writeChannel( MImage &image, typename TypedData< std::vector<T> >::Ptr channelData, unsigned channelOffset, unsigned numChannels ) const
{
	assert( channelOffset < numChannels );

	ConstImagePrimitivePtr toConvert = runTimeCast<const ImagePrimitive>( srcParameter()->getValidatedValue() );
	assert( toConvert );

	unsigned width, height;
	image.getSize( width, height );

	const Imath::Box2i &dataWindow = toConvert->getDataWindow();
	const Imath::Box2i &displayWindow = toConvert->getDisplayWindow();

	unsigned int dataWidth = dataWindow.size().x + 1;
	unsigned int dataHeight = dataWindow.size().y + 1;

	Imath::V2i dataOffset = dataWindow.min - displayWindow.min ;

	boost::multi_array_ref< const T, 2 > src( &channelData->readable()[0], boost::extents[dataHeight][dataWidth] );
	boost::multi_array_ref< T, 3 > dst( MImageAccessor<T>::getPixels( image ), boost::extents[ height ][ width ][ numChannels ] );

	for ( unsigned x = 0; x < dataWidth; x++ )
	{
		for ( unsigned y = 0; y < dataHeight; y++ )
		{
			/// Vertical flip, to match Maya
			dst[ ( height - 1 ) - ( y + dataOffset.y ) ][ x + dataOffset.x ][channelOffset] = src[y][x];
		}
	}
}

template<typename T>
void ToMayaImageConverter::writeAlpha( MImage &image, const T &alpha ) const
{
	const int numChannels = 4;
	const int channelOffset = 3;

	unsigned width, height;
	image.getSize( width, height );

	boost::multi_array_ref< T, 3 > dst( MImageAccessor<T>::getPixels( image ), boost::extents[ height ][ width ][ numChannels ] );

	for ( unsigned x = 0; x < width; x++ )
	{
		for ( unsigned y = 0; y < height; y++ )
		{
			dst[y][x][channelOffset] = alpha;
		}
	}
}

MStatus ToMayaImageConverter::convert( MImage &image ) const
{
	MStatus s;
	ConstImagePrimitivePtr toConvert = runTimeCast<const ImagePrimitive>( srcParameter()->getValidatedValue() );
	assert( toConvert );

	unsigned int width = toConvert->getDisplayWindow().size().x + 1;
	unsigned int height = toConvert->getDisplayWindow().size().y + 1;

	MImage::MPixelType pixelType = MImage::kUnknown;
	switch( typeParameter()->getNumericValue() )
	{
		case Float :
			pixelType = MImage::kFloat;
			break;
		case Byte:
			pixelType = MImage::kByte;
			break;
		default :

			assert( false );
	}

	/// Get the channels RGBA at the front, in that order, if they exist
	vector<string> desiredChannelOrder;
	desiredChannelOrder.push_back( "R" );
	desiredChannelOrder.push_back( "G" );
	desiredChannelOrder.push_back( "B" );
	desiredChannelOrder.push_back( "A" );

	vector<string> channelNames;
	for  ( PrimitiveVariableMap::const_iterator it = toConvert->variables.begin(); it != toConvert->variables.end(); ++it )
	{
		channelNames.push_back( it->first );
	}

	vector<string> filteredNames;

	int rgbChannelsFound = 0;
	bool haveAlpha = false;
	for ( vector<string>::const_iterator it = desiredChannelOrder.begin(); it != desiredChannelOrder.end(); ++it )
	{
		vector<string>::iterator res = find( channelNames.begin(), channelNames.end(), *it );
		if ( res != channelNames.end() )
		{
			if ( *it == "A" )
			{
				haveAlpha = true;
			}
			else
			{
				rgbChannelsFound ++;
			}
			channelNames.erase( res );
			filteredNames.push_back( *it );
		}
	}
	channelNames = filteredNames;

	if ( rgbChannelsFound != 3 )
	{
		return MS::kFailure;
	}

	unsigned numChannels = 4; // We always add an alpha if one is not present.

	/// \todo We could optimise here by not recreating the image if the existing one matches our exact requirements
	s = image.create( width, height, numChannels, pixelType );
	if ( !s )
	{
		return s;
	}

	image.setRGBA( true );

	unsigned channelOffset = 0;
	for ( vector<string>::const_iterator it = channelNames.begin(); it != channelNames.end(); ++it, ++channelOffset )
	{
		DataPtr dataContainer = toConvert->variables.find( *it )->second.data;
		assert( dataContainer );

		switch( pixelType )
		{
			case MImage::kFloat :
			{
				ChannelConverter<float> converter( *it );
				FloatVectorDataPtr channelData = despatchTypedData<
					ChannelConverter<float>,
					TypeTraits::IsNumericVectorTypedData,
					ChannelConverter<float>::ErrorHandler
				>( dataContainer, converter );

				writeChannel<float>( image, channelData, channelOffset, numChannels );
			}

				break;
			case MImage::kByte:
			{
				ChannelConverter<unsigned char> converter( *it );
				UCharVectorDataPtr channelData = despatchTypedData<
					ChannelConverter<unsigned char>,
					TypeTraits::IsNumericVectorTypedData,
					ChannelConverter<unsigned char>::ErrorHandler
				>( dataContainer, converter );

				writeChannel<unsigned char>( image, channelData, channelOffset, numChannels );
			}

				break;
			default :

				assert( false );
		}
	}

	if ( !haveAlpha )
	{
		switch( pixelType )
		{
			case MImage::kFloat :
			{
				writeAlpha<float>( image, 1.0 );
			}
			break;
			case MImage::kByte :
			{
				writeAlpha<unsigned char>( image, 255 );
			}
			break;
			default :

				assert( false );
		}
	}

	return MS::kSuccess;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: options.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 18:05:11 $
 *
 *  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 _IDLC_OPTIONS_HXX_
#define _IDLC_OPTIONS_HXX_

#ifndef _IDLC_IDLCTYPEs_HXX_
#include <idlc/idlctypes.hxx>
#endif

typedef ::std::hash_map< ::rtl::OString,
                         ::rtl::OString,
                         HashString,
                         EqualString > OptionMap;

class IllegalArgument
{
public:
    IllegalArgument(const ::rtl::OString& msg)
        : m_message(msg) {}

    ::rtl::OString  m_message;
};

class Options
{
public:
    Options();
    ~Options();

    sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False)
        throw( IllegalArgument );

    ::rtl::OString prepareHelp();
    ::rtl::OString prepareVersion();

    const ::rtl::OString&   getProgramName() const;
    sal_uInt16              getNumberOfOptions() const;
    sal_Bool                isValid(const ::rtl::OString& option);
    const ::rtl::OString    getOption(const ::rtl::OString& option)
        throw( IllegalArgument );
    const OptionMap&        getOptions();

    const StringVector& getInputFiles() const { return m_inputFiles; }
    bool readStdin() const { return m_stdin; }

protected:
    ::rtl::OString  m_program;
    StringVector    m_inputFiles;
    bool            m_stdin;
    OptionMap       m_options;
};

#endif // _IDLC_OPTIONS_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.3.88); FILE MERGED 2008/03/31 07:23:50 rt 1.3.88.1: #i87441# Change license header to LPGL v3.<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: options.hxx,v $
 * $Revision: 1.4 $
 *
 * 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.
 *
 ************************************************************************/

#ifndef _IDLC_OPTIONS_HXX_
#define _IDLC_OPTIONS_HXX_

#ifndef _IDLC_IDLCTYPEs_HXX_
#include <idlc/idlctypes.hxx>
#endif

typedef ::std::hash_map< ::rtl::OString,
                         ::rtl::OString,
                         HashString,
                         EqualString > OptionMap;

class IllegalArgument
{
public:
    IllegalArgument(const ::rtl::OString& msg)
        : m_message(msg) {}

    ::rtl::OString  m_message;
};

class Options
{
public:
    Options();
    ~Options();

    sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False)
        throw( IllegalArgument );

    ::rtl::OString prepareHelp();
    ::rtl::OString prepareVersion();

    const ::rtl::OString&   getProgramName() const;
    sal_uInt16              getNumberOfOptions() const;
    sal_Bool                isValid(const ::rtl::OString& option);
    const ::rtl::OString    getOption(const ::rtl::OString& option)
        throw( IllegalArgument );
    const OptionMap&        getOptions();

    const StringVector& getInputFiles() const { return m_inputFiles; }
    bool readStdin() const { return m_stdin; }

protected:
    ::rtl::OString  m_program;
    StringVector    m_inputFiles;
    bool            m_stdin;
    OptionMap       m_options;
};

#endif // _IDLC_OPTIONS_HXX_

<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   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., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepAlgoAPI_BooleanOperation.hxx>
# include <BRepCheck_Analyzer.hxx>
# include <Standard_Failure.hxx>
# include <memory>
#endif

#include "FeaturePartBoolean.h"
#include "modelRefine.h"
#include <App/Application.h>
#include <Base/Parameter.h>

using namespace Part;

PROPERTY_SOURCE_ABSTRACT(Part::Boolean, Part::Feature)

Boolean::Boolean(void)
{
    ADD_PROPERTY(Base,(0));
    ADD_PROPERTY(Tool,(0));
    ADD_PROPERTY_TYPE(History,(ShapeHistory()), "Boolean", (App::PropertyType)
        (App::Prop_Output|App::Prop_Transient|App::Prop_Hidden), "Shape history");
    History.setSize(0);

    ADD_PROPERTY_TYPE(Refine,(0),"Boolean",(App::PropertyType)(App::Prop_None),"Refine shape (clean up redundant edges) after this boolean operation");

    //init Refine property
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
        .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part/Boolean");
    this->Refine.setValue(hGrp->GetBool("RefineModel", false));
}

short Boolean::mustExecute() const
{
    if (Base.getValue() && Tool.getValue()) {
        if (Base.isTouched())
            return 1;
        if (Tool.isTouched())
            return 1;
    }
    return 0;
}

App::DocumentObjectExecReturn *Boolean::execute(void)
{
    try {
#if defined(__GNUC__) && defined (FC_OS_LINUX)
        Base::SignalException se;
#endif
        Part::Feature *base = dynamic_cast<Part::Feature*>(Base.getValue());
        Part::Feature *tool = dynamic_cast<Part::Feature*>(Tool.getValue());

        if (!base || !tool)
            return new App::DocumentObjectExecReturn("Linked object is not a Part object");

        // Now, let's get the TopoDS_Shape
        TopoDS_Shape BaseShape = base->Shape.getValue();
        if (BaseShape.IsNull())
            throw NullShapeException("Base shape is null");
        TopoDS_Shape ToolShape = tool->Shape.getValue();
        if (ToolShape.IsNull())
            throw NullShapeException("Tool shape is null");

        std::unique_ptr<BRepAlgoAPI_BooleanOperation> mkBool(makeOperation(BaseShape, ToolShape));
        if (!mkBool->IsDone()) {
            return new App::DocumentObjectExecReturn("Boolean operation failed");
        }
        TopoDS_Shape resShape = mkBool->Shape();
        if (resShape.IsNull()) {
            return new App::DocumentObjectExecReturn("Resulting shape is null");
        }
        Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
            .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part/Boolean");

        if (hGrp->GetBool("CheckModel", false)) {
            BRepCheck_Analyzer aChecker(resShape);
            if (! aChecker.IsValid() ) {
                return new App::DocumentObjectExecReturn("Resulting shape is invalid");
            }
        }

        std::vector<ShapeHistory> history;
        history.push_back(buildHistory(*mkBool.get(), TopAbs_FACE, resShape, BaseShape));
        history.push_back(buildHistory(*mkBool.get(), TopAbs_FACE, resShape, ToolShape));

        if (this->Refine.getValue()) {
            try {
                TopoDS_Shape oldShape = resShape;
                BRepBuilderAPI_RefineModel mkRefine(oldShape);
                resShape = mkRefine.Shape();
                ShapeHistory hist = buildHistory(mkRefine, TopAbs_FACE, resShape, oldShape);
                history[0] = joinHistory(history[0], hist);
                history[1] = joinHistory(history[1], hist);
            }
            catch (Standard_Failure&) {
                // do nothing
            }
        }

        this->Shape.setValue(resShape);
        this->History.setValues(history);
        return App::DocumentObject::StdReturn;
    }
    catch (...) {
        return new App::DocumentObjectExecReturn("A fatal error occurred when running boolean operation");
    }
}
<commit_msg>fixes 0003694: Part->Boolean->Cut should show error message if a non-solid (Shell, etc.) is selected<commit_after>/***************************************************************************
 *   Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   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., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepAlgoAPI_BooleanOperation.hxx>
# include <BRepCheck_Analyzer.hxx>
# include <Standard_Failure.hxx>
# include <memory>
#endif

#include "FeaturePartBoolean.h"
#include "modelRefine.h"
#include <App/Application.h>
#include <Base/Parameter.h>

using namespace Part;

PROPERTY_SOURCE_ABSTRACT(Part::Boolean, Part::Feature)

Boolean::Boolean(void)
{
    ADD_PROPERTY(Base,(0));
    ADD_PROPERTY(Tool,(0));
    ADD_PROPERTY_TYPE(History,(ShapeHistory()), "Boolean", (App::PropertyType)
        (App::Prop_Output|App::Prop_Transient|App::Prop_Hidden), "Shape history");
    History.setSize(0);

    ADD_PROPERTY_TYPE(Refine,(0),"Boolean",(App::PropertyType)(App::Prop_None),"Refine shape (clean up redundant edges) after this boolean operation");

    //init Refine property
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
        .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part/Boolean");
    this->Refine.setValue(hGrp->GetBool("RefineModel", false));
}

short Boolean::mustExecute() const
{
    if (Base.getValue() && Tool.getValue()) {
        if (Base.isTouched())
            return 1;
        if (Tool.isTouched())
            return 1;
    }
    return 0;
}

App::DocumentObjectExecReturn *Boolean::execute(void)
{
    try {
#if defined(__GNUC__) && defined (FC_OS_LINUX)
        Base::SignalException se;
#endif
        Part::Feature *base = dynamic_cast<Part::Feature*>(Base.getValue());
        Part::Feature *tool = dynamic_cast<Part::Feature*>(Tool.getValue());

        if (!base || !tool)
            return new App::DocumentObjectExecReturn("Linked object is not a Part object");

        // Now, let's get the TopoDS_Shape
        TopoDS_Shape BaseShape = base->Shape.getValue();
        if (BaseShape.IsNull())
            throw NullShapeException("Base shape is null");
        TopoDS_Shape ToolShape = tool->Shape.getValue();
        if (ToolShape.IsNull())
            throw NullShapeException("Tool shape is null");

        std::unique_ptr<BRepAlgoAPI_BooleanOperation> mkBool(makeOperation(BaseShape, ToolShape));
        if (!mkBool->IsDone()) {
            std::stringstream error;
            error << "Boolean operation failed";
            if (BaseShape.ShapeType() != TopAbs_SOLID) {
                error << std::endl << base->Label.getValue() << " is not a solid";
            }
            if (ToolShape.ShapeType() != TopAbs_SOLID) {
                error << std::endl << tool->Label.getValue() << " is not a solid";
            }
            return new App::DocumentObjectExecReturn(error.str());
        }
        TopoDS_Shape resShape = mkBool->Shape();
        if (resShape.IsNull()) {
            return new App::DocumentObjectExecReturn("Resulting shape is null");
        }
        Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
            .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part/Boolean");

        if (hGrp->GetBool("CheckModel", false)) {
            BRepCheck_Analyzer aChecker(resShape);
            if (! aChecker.IsValid() ) {
                return new App::DocumentObjectExecReturn("Resulting shape is invalid");
            }
        }

        std::vector<ShapeHistory> history;
        history.push_back(buildHistory(*mkBool.get(), TopAbs_FACE, resShape, BaseShape));
        history.push_back(buildHistory(*mkBool.get(), TopAbs_FACE, resShape, ToolShape));

        if (this->Refine.getValue()) {
            try {
                TopoDS_Shape oldShape = resShape;
                BRepBuilderAPI_RefineModel mkRefine(oldShape);
                resShape = mkRefine.Shape();
                ShapeHistory hist = buildHistory(mkRefine, TopAbs_FACE, resShape, oldShape);
                history[0] = joinHistory(history[0], hist);
                history[1] = joinHistory(history[1], hist);
            }
            catch (Standard_Failure&) {
                // do nothing
            }
        }

        this->Shape.setValue(resShape);
        this->History.setValues(history);
        return App::DocumentObject::StdReturn;
    }
    catch (...) {
        return new App::DocumentObjectExecReturn("A fatal error occurred when running boolean operation");
    }
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2009 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   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., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepBuilderAPI_MakeEdge.hxx>
# include <gp_Dir.hxx>
# include <gp_Vec.hxx>
# include <gp_Pln.hxx>
# include <GCPnts_UniformAbscissa.hxx>
# include <GCPnts_AbscissaPoint.hxx>
# include <Geom2dAPI_InterCurveCurve.hxx>
# include <GeomAPI.hxx>
# include <Geom_Geometry.hxx>
# include <Geom_Curve.hxx>
# include <Geom_Plane.hxx>
# include <Geom_Surface.hxx>
# include <GeomAdaptor_Curve.hxx>
# include <GeomFill.hxx>
# include <GeomLProp_CLProps.hxx>
# include <Handle_Geom_RectangularTrimmedSurface.hxx>
# include <Handle_Geom_BSplineSurface.hxx>
# include <Precision.hxx>
# include <GeomAPI_ProjectPointOnCurve.hxx>
# include <Standard_Failure.hxx>
#endif

#include <Base/GeometryPyCXX.h>
#include <Base/VectorPy.h>

#include "Geometry.h"
#include "GeometryCurvePy.h"
#include "GeometryCurvePy.cpp"
#include "RectangularTrimmedSurfacePy.h"
#include "BSplineSurfacePy.h"
#include "PlanePy.h"

#include "TopoShape.h"
#include "TopoShapePy.h"
#include "TopoShapeEdgePy.h"

using namespace Part;

// returns a string which represents the object e.g. when printed in python
std::string GeometryCurvePy::representation(void) const
{
    return "<Curve object>";
}

PyObject *GeometryCurvePy::PyMake(struct _typeobject *, PyObject *, PyObject *)  // Python wrapper
{
    // never create such objects with the constructor
    PyErr_SetString(PyExc_RuntimeError,
        "You cannot create an instance of the abstract class 'GeometryCurve'.");
    return 0;
}

// constructor method
int GeometryCurvePy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
{
    return 0;
}

PyObject* GeometryCurvePy::toShape(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u,v;
            u=c->FirstParameter();
            v=c->LastParameter();
            if (!PyArg_ParseTuple(args, "|dd", &u,&v))
                return 0;
            BRepBuilderAPI_MakeEdge mkBuilder(c, u, v);
            TopoDS_Shape sh = mkBuilder.Shape();
            return new TopoShapeEdgePy(new TopoShape(sh));
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::discretize(PyObject *args)
{
    PyObject* defl_or_num;
    if (!PyArg_ParseTuple(args, "O", &defl_or_num))
        return 0;

    try {
        Handle_Geom_Geometry g = getGeometryPtr()->handle();
        Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
        if (!c.IsNull()) {
            GeomAdaptor_Curve adapt(c);
            GCPnts_UniformAbscissa discretizer;
            if (PyInt_Check(defl_or_num)) {
                int num = PyInt_AsLong(defl_or_num);
                discretizer.Initialize (adapt, num);
            }
            else if (PyFloat_Check(defl_or_num)) {
                double defl = PyFloat_AsDouble(defl_or_num);
                discretizer.Initialize (adapt, defl);
            }
            else {
                PyErr_SetString(PyExc_TypeError, "Either int or float expected");
                return 0;
            }
            if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
                Py::List points;
                int nbPoints = discretizer.NbPoints ();
                for (int i=1; i<=nbPoints; i++) {
                    gp_Pnt p = adapt.Value (discretizer.Parameter (i));
                    points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
                }

                return Py::new_reference_to(points);
            }
            else {
                PyErr_SetString(PyExc_Exception, "Descretization of curve failed");
                return 0;
            }
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::length(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u=c->FirstParameter();
            double v=c->LastParameter();
            double t=Precision::Confusion();
            if (!PyArg_ParseTuple(args, "|ddd", &u,&v,&t))
                return 0;
            double len = GCPnts_AbscissaPoint::Length(GeomAdaptor_Curve(c),u,v,t);
            return PyFloat_FromDouble(len);
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::value(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u;
            if (!PyArg_ParseTuple(args, "d", &u))
                return 0;
            gp_Pnt p = c->Value(u);
            return new Base::VectorPy(Base::Vector3d(p.X(),p.Y(),p.Z()));
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::tangent(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u;
            if (!PyArg_ParseTuple(args, "d", &u))
                return 0;
            gp_Dir dir;
            Py::Tuple tuple(1);
            GeomLProp_CLProps prop(c,u,1,Precision::Confusion());
            if (prop.IsTangentDefined()) {
                prop.Tangent(dir);
                tuple.setItem(0, Py::Vector(Base::Vector3d(dir.X(),dir.Y(),dir.Z())));
            }

            return Py::new_reference_to(tuple);
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::parameter(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            PyObject *p;
            if (!PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &p))
                return 0;
            Base::Vector3d v = Py::Vector(p, false).toVector();
            gp_Pnt pnt(v.x,v.y,v.z);
            GeomAPI_ProjectPointOnCurve ppc(pnt, c);
            double val = ppc.LowerDistanceParameter();
            return Py::new_reference_to(Py::Float(val));
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::makeRuledSurface(PyObject *args)
{
    PyObject* curve;
    if (!PyArg_ParseTuple(args, "O!", &(Part::GeometryCurvePy::Type), &curve))
        return 0;

    try {
        Handle_Geom_Curve aCrv1 = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle());
        GeometryCurvePy* c = static_cast<GeometryCurvePy*>(curve);
        Handle_Geom_Curve aCrv2 = Handle_Geom_Curve::DownCast(c->getGeometryPtr()->handle());
        Handle_Geom_Surface aSurf = GeomFill::Surface (aCrv1, aCrv2);
        if (aSurf.IsNull()) {
            PyErr_SetString(PyExc_Exception, "Failed to create ruled surface");
            return 0;
        }
        // check the result surface type
        if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
            Handle_Geom_RectangularTrimmedSurface aTSurf =
                Handle_Geom_RectangularTrimmedSurface::DownCast(aSurf);
            return new RectangularTrimmedSurfacePy(new GeomTrimmedSurface(aTSurf));
        }
        else if (aSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
            Handle_Geom_BSplineSurface aBSurf =
                Handle_Geom_BSplineSurface::DownCast(aSurf);
            return new BSplineSurfacePy(new GeomBSplineSurface(aBSurf));
        }
        else {
            PyErr_Format(PyExc_NotImplementedError, "Ruled surface is of type '%s'",
                aSurf->DynamicType()->Name());
            return 0;
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::intersect2d(PyObject *args)
{
    PyObject *c,*p;
    if (!PyArg_ParseTuple(args, "O!O!", &(Part::GeometryCurvePy::Type), &c,
                                        &(Part::PlanePy::Type), &p))
        return 0;

    try {
        Handle_Geom_Curve self = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle());
        Handle_Geom_Curve curv = Handle_Geom_Curve::DownCast(static_cast<GeometryPy*>(c)->
            getGeometryPtr()->handle());
        Handle_Geom_Plane plane = Handle_Geom_Plane::DownCast(static_cast<GeometryPy*>(p)->
            getGeometryPtr()->handle());

        Handle_Geom2d_Curve curv1 = GeomAPI::To2d(self, plane->Pln());
        Handle_Geom2d_Curve curv2 = GeomAPI::To2d(curv, plane->Pln());
        Geom2dAPI_InterCurveCurve intCC(curv1, curv2);
        int nbPoints = intCC.NbPoints();
        Py::List list;
        for (int i=1; i<= nbPoints; i++) {
            gp_Pnt2d pt = intCC.Point(i);
            Py::Tuple tuple(2);
            tuple.setItem(0, Py::Float(pt.X()));
            tuple.setItem(1, Py::Float(pt.Y()));
            list.append(tuple);
        }
        return Py::new_reference_to(list);
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }
}

Py::Float GeometryCurvePy::getFirstParameter(void) const
{
    return Py::Float(Handle_Geom_Curve::DownCast
        (getGeometryPtr()->handle())->FirstParameter());
}

Py::Float GeometryCurvePy::getLastParameter(void) const
{
    return Py::Float(Handle_Geom_Curve::DownCast
        (getGeometryPtr()->handle())->LastParameter());
}

PyObject *GeometryCurvePy::getCustomAttributes(const char* /*attr*/) const
{
    return 0;
}

int GeometryCurvePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
    return 0;
}
<commit_msg>Fix build failure<commit_after>/***************************************************************************
 *   Copyright (c) 2009 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   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., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepBuilderAPI_MakeEdge.hxx>
# include <gp_Dir.hxx>
# include <gp_Vec.hxx>
# include <gp_Pln.hxx>
# include <GCPnts_UniformAbscissa.hxx>
# include <GCPnts_AbscissaPoint.hxx>
# include <Geom2dAPI_InterCurveCurve.hxx>
# include <GeomAPI.hxx>
# include <Geom_Geometry.hxx>
# include <Geom_Curve.hxx>
# include <Geom_Plane.hxx>
# include <Geom_Surface.hxx>
# include <GeomAdaptor_Curve.hxx>
# include <GeomFill.hxx>
# include <GeomLProp_CLProps.hxx>
# include <Handle_Geom_RectangularTrimmedSurface.hxx>
# include <Handle_Geom_BSplineSurface.hxx>
# include <Precision.hxx>
# include <GeomAPI_ProjectPointOnCurve.hxx>
# include <Standard_Failure.hxx>
#endif

#include <Base/GeometryPyCXX.h>
#include <Base/VectorPy.h>

#include "Geometry.h"
#include "GeometryCurvePy.h"
#include "GeometryCurvePy.cpp"
#include "RectangularTrimmedSurfacePy.h"
#include "BSplineSurfacePy.h"
#include "PlanePy.h"

#include "TopoShape.h"
#include "TopoShapePy.h"
#include "TopoShapeEdgePy.h"

using namespace Part;

// returns a string which represents the object e.g. when printed in python
std::string GeometryCurvePy::representation(void) const
{
    return "<Curve object>";
}

PyObject *GeometryCurvePy::PyMake(struct _typeobject *, PyObject *, PyObject *)  // Python wrapper
{
    // never create such objects with the constructor
    PyErr_SetString(PyExc_RuntimeError,
        "You cannot create an instance of the abstract class 'GeometryCurve'.");
    return 0;
}

// constructor method
int GeometryCurvePy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
{
    return 0;
}

PyObject* GeometryCurvePy::toShape(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u,v;
            u=c->FirstParameter();
            v=c->LastParameter();
            if (!PyArg_ParseTuple(args, "|dd", &u,&v))
                return 0;
            BRepBuilderAPI_MakeEdge mkBuilder(c, u, v);
            TopoDS_Shape sh = mkBuilder.Shape();
            return new TopoShapeEdgePy(new TopoShape(sh));
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::discretize(PyObject *args)
{
    PyObject* defl_or_num;
    if (!PyArg_ParseTuple(args, "O", &defl_or_num))
        return 0;

    try {
        Handle_Geom_Geometry g = getGeometryPtr()->handle();
        Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
        if (!c.IsNull()) {
            GeomAdaptor_Curve adapt(c);
            GCPnts_UniformAbscissa discretizer;
            if (PyInt_Check(defl_or_num)) {
                int num = PyInt_AsLong(defl_or_num);
                discretizer.Initialize (adapt, num);
            }
            else if (PyFloat_Check(defl_or_num)) {
                double defl = PyFloat_AsDouble(defl_or_num);
                discretizer.Initialize (adapt, defl);
            }
            else {
                PyErr_SetString(PyExc_TypeError, "Either int or float expected");
                return 0;
            }
            if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
                Py::List points;
                int nbPoints = discretizer.NbPoints ();
                for (int i=1; i<=nbPoints; i++) {
                    gp_Pnt p = adapt.Value (discretizer.Parameter (i));
                    points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
                }

                return Py::new_reference_to(points);
            }
            else {
                PyErr_SetString(PyExc_Exception, "Descretization of curve failed");
                return 0;
            }
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::length(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u=c->FirstParameter();
            double v=c->LastParameter();
            double t=Precision::Confusion();
            if (!PyArg_ParseTuple(args, "|ddd", &u,&v,&t))
                return 0;
            GeomAdaptor_Curve adapt(c);
            double len = GCPnts_AbscissaPoint::Length(adapt,u,v,t);
            return PyFloat_FromDouble(len);
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::value(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u;
            if (!PyArg_ParseTuple(args, "d", &u))
                return 0;
            gp_Pnt p = c->Value(u);
            return new Base::VectorPy(Base::Vector3d(p.X(),p.Y(),p.Z()));
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::tangent(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u;
            if (!PyArg_ParseTuple(args, "d", &u))
                return 0;
            gp_Dir dir;
            Py::Tuple tuple(1);
            GeomLProp_CLProps prop(c,u,1,Precision::Confusion());
            if (prop.IsTangentDefined()) {
                prop.Tangent(dir);
                tuple.setItem(0, Py::Vector(Base::Vector3d(dir.X(),dir.Y(),dir.Z())));
            }

            return Py::new_reference_to(tuple);
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::parameter(PyObject *args)
{
    Handle_Geom_Geometry g = getGeometryPtr()->handle();
    Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
    try {
        if (!c.IsNull()) {
            PyObject *p;
            if (!PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &p))
                return 0;
            Base::Vector3d v = Py::Vector(p, false).toVector();
            gp_Pnt pnt(v.x,v.y,v.z);
            GeomAPI_ProjectPointOnCurve ppc(pnt, c);
            double val = ppc.LowerDistanceParameter();
            return Py::new_reference_to(Py::Float(val));
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::makeRuledSurface(PyObject *args)
{
    PyObject* curve;
    if (!PyArg_ParseTuple(args, "O!", &(Part::GeometryCurvePy::Type), &curve))
        return 0;

    try {
        Handle_Geom_Curve aCrv1 = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle());
        GeometryCurvePy* c = static_cast<GeometryCurvePy*>(curve);
        Handle_Geom_Curve aCrv2 = Handle_Geom_Curve::DownCast(c->getGeometryPtr()->handle());
        Handle_Geom_Surface aSurf = GeomFill::Surface (aCrv1, aCrv2);
        if (aSurf.IsNull()) {
            PyErr_SetString(PyExc_Exception, "Failed to create ruled surface");
            return 0;
        }
        // check the result surface type
        if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
            Handle_Geom_RectangularTrimmedSurface aTSurf =
                Handle_Geom_RectangularTrimmedSurface::DownCast(aSurf);
            return new RectangularTrimmedSurfacePy(new GeomTrimmedSurface(aTSurf));
        }
        else if (aSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
            Handle_Geom_BSplineSurface aBSurf =
                Handle_Geom_BSplineSurface::DownCast(aSurf);
            return new BSplineSurfacePy(new GeomBSplineSurface(aBSurf));
        }
        else {
            PyErr_Format(PyExc_NotImplementedError, "Ruled surface is of type '%s'",
                aSurf->DynamicType()->Name());
            return 0;
        }
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }

    PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
    return 0;
}

PyObject* GeometryCurvePy::intersect2d(PyObject *args)
{
    PyObject *c,*p;
    if (!PyArg_ParseTuple(args, "O!O!", &(Part::GeometryCurvePy::Type), &c,
                                        &(Part::PlanePy::Type), &p))
        return 0;

    try {
        Handle_Geom_Curve self = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle());
        Handle_Geom_Curve curv = Handle_Geom_Curve::DownCast(static_cast<GeometryPy*>(c)->
            getGeometryPtr()->handle());
        Handle_Geom_Plane plane = Handle_Geom_Plane::DownCast(static_cast<GeometryPy*>(p)->
            getGeometryPtr()->handle());

        Handle_Geom2d_Curve curv1 = GeomAPI::To2d(self, plane->Pln());
        Handle_Geom2d_Curve curv2 = GeomAPI::To2d(curv, plane->Pln());
        Geom2dAPI_InterCurveCurve intCC(curv1, curv2);
        int nbPoints = intCC.NbPoints();
        Py::List list;
        for (int i=1; i<= nbPoints; i++) {
            gp_Pnt2d pt = intCC.Point(i);
            Py::Tuple tuple(2);
            tuple.setItem(0, Py::Float(pt.X()));
            tuple.setItem(1, Py::Float(pt.Y()));
            list.append(tuple);
        }
        return Py::new_reference_to(list);
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }
}

Py::Float GeometryCurvePy::getFirstParameter(void) const
{
    return Py::Float(Handle_Geom_Curve::DownCast
        (getGeometryPtr()->handle())->FirstParameter());
}

Py::Float GeometryCurvePy::getLastParameter(void) const
{
    return Py::Float(Handle_Geom_Curve::DownCast
        (getGeometryPtr()->handle())->LastParameter());
}

PyObject *GeometryCurvePy::getCustomAttributes(const char* /*attr*/) const
{
    return 0;
}

int GeometryCurvePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
    return 0;
}
<|endoftext|>


<commit_before>// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//

#include "SalomeApp_VisualState.h"

#include "SalomeApp_Module.h"
#include "SalomeApp_Study.h"
#include "SalomeApp_Application.h"

//#include <SUIT_ResourceMgr.h>
#include <SUIT_ViewManager.h>
#include <SUIT_ViewWindow.h>
#include <QtxWorkstack.h>

#include <STD_TabDesktop.h>

#include <QList>
#include <QApplication>
#include <QMultiHash>

#include <SALOMEDSClient_ClientFactory.hxx>//?
#include <SALOMEDSClient_IParameters.hxx>//?

#include <vector>//?
#include <string>//?
#include <cstdio>

/*!
  Constructor.
*/
SalomeApp_VisualState::SalomeApp_VisualState( SalomeApp_Application* app )
  : QObject(),
    myApp( app )
{
}

/*!
  Destructor.
*/
SalomeApp_VisualState::~SalomeApp_VisualState()
{
}

/*!
  Sets names of all view windows in given list.  This is used
  in order to apply the same naming algorithm when saving and restoring
  view windows.  Names of view windows must be the same before saving
  workstack (splitters) information, and before its restoring!
  Naming rule: ViewerType_IndexOfViewerOfThisType_IndexOfViewInThisViewer
               VTKViewer_0_0
               OCCViewer_0_0  OCCViewer_0_1  OCCViewer_0_2
               VTKViewer_1_0
*/
void nameViewWindows( const ViewManagerList& lst )
{
  QMap<QString, int> viewersCounter;
  for ( QList<SUIT_ViewManager*>::const_iterator it = lst.begin(); it != lst.end(); ++it )
  {
    SUIT_ViewManager* aVM = *it;
    if ( !aVM )
      continue;

    int view_count = aVM->getViewsCount();
    QString vType = aVM->getType();
    if ( !view_count )
      continue; //No views is opened in the viewer

    if ( !viewersCounter.contains( vType ) )
      viewersCounter.insert( vType, 0 );

    int& viewerID = viewersCounter[vType];

    QVector<SUIT_ViewWindow*> views = aVM->getViews();
    for ( int i = 0; i < view_count; i++ )
    {
      QString vName = QString( "%1_%2_%3" ).arg( vType ).arg( viewerID ).arg( i );
      views[i]->setObjectName( vName );
    }
    viewerID++;
  }
}

/*!
  Stores the visual parameters of the viewers
*/
int SalomeApp_VisualState::storeState()
{
  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
  if ( !study )
    return -1;

  // unlock study if it is locked
  bool aLocked = study->studyDS()->GetProperties()->IsLocked();
  if (aLocked) study->studyDS()->GetProperties()->SetLocked(false);

  int savePoint = 1;
  std::vector<int> savePoints = study->getSavePoints();
  //Calculate a new savePoint number = the last save point number + 1
  if ( savePoints.size() > 0)
    savePoint = savePoints[savePoints.size()-1] + 1;

  _PTR(AttributeParameter) ap = study->studyDS()->GetCommonParameters( study->getVisualComponentName().toLatin1().constData(),
								       savePoint );
  _PTR(IParameters) ip = ClientFactory::getIParameters( ap );

  ViewManagerList lst;
  myApp->viewManagers( lst );

  // setting unique names for view windows in order to save this view inside
  // workstack's structure (see below).  On restore the views with the same names will
  // be placed to the same place inside the workstack's splitters.
  nameViewWindows( lst );

  // store active window's name
  SUIT_ViewWindow* win = myApp->desktop()->activeWindow();
  if ( win )
    ip->setProperty("AP_ACTIVE_VIEW", win->objectName().toStdString() );

  int viewerID = 0;
  SUIT_ViewManager* vm = 0;
  QListIterator<SUIT_ViewManager*> it( lst );
  while ( it.hasNext() ) {
    vm = it.next();
    if ( !vm ) continue;

    int view_count = vm->getViewsCount();
    if ( !view_count )
      continue; //No views is opened in the viewer

    std::string viewerEntry = QString( "%1_%2" ).arg( vm->getType() ).arg( ++viewerID ).toStdString();
    ip->append("AP_VIEWERS_LIST", viewerEntry);

    QVector<SUIT_ViewWindow*> views = vm->getViews();
    for(int i = 0; i<view_count; i++) {
      ip->append( viewerEntry, views[i]->windowTitle().toStdString() );
      ip->append( viewerEntry, views[i]->getVisualParameters().toStdString() );
    }
  }

  //Save information about split areas
  if ( myApp->desktop()->inherits( "STD_TabDesktop" ) )
  {
    QString workstackInfo;
    QtxWorkstack* workstack = ((STD_TabDesktop*)myApp->desktop())->workstack();
    QByteArray geomState = workstack->saveState( 0 );
    ip->setProperty( "AP_WORKSTACK_INFO", QString( geomState.toHex() ).toStdString() );
  }

  //Save a name of the active module
  if ( CAM_Module* activeModule = myApp->activeModule() )
    ip->setProperty( "AP_ACTIVE_MODULE", activeModule->moduleName().toStdString() );

  //Store visual parameters of the modules
  QList<CAM_Module*> mlist;
  myApp->modules( mlist );
  QListIterator<CAM_Module*> itM( mlist );
  CAM_Module* module = 0;
  while ( itM.hasNext() ) {
    module = itM.next();
    //DEBTRACE("---");
    if ( !module ) continue;
    //DEBTRACE("--- " << module->name().toStdString());

    if ( LightApp_Module* lModule = dynamic_cast<LightApp_Module*>( module ) ) {
      //DEBTRACE("AP_MODULES_LIST append " << lModule->moduleName().toStdString());
      ip->append( "AP_MODULES_LIST", lModule->moduleName().toStdString() );
      if ( SalomeApp_Module* sModule = dynamic_cast<SalomeApp_Module*>( module ) )
        sModule->storeVisualParameters( savePoint );
    }
  }

  // set default name of new savePoint
  study->setNameOfSavePoint( savePoint, QObject::tr( "SAVE_POINT_DEF_NAME" ) + QString::number( savePoint ) );

  if (aLocked) study->studyDS()->GetProperties()->SetLocked(true);

  return savePoint;
}

/*!
  Restores the visual parameters of the viewers
*/
void SalomeApp_VisualState::restoreState(int savePoint)
{
  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
  if ( !study )
    return;

  _PTR(AttributeParameter) ap = study->studyDS()->GetCommonParameters( study->getVisualComponentName().toLatin1().constData(),
								       savePoint );
  _PTR(IParameters) ip = ClientFactory::getIParameters(ap);

  qApp->installEventFilter( this );

  //Remove all already existent veiwers and their views
  //myApp->clearViewManagers();
  myApp->clearKnownViewManagers();

  //Restore the viewers and view windows
  int nbViewers = ip->nbValues( "AP_VIEWERS_LIST" );
  SUIT_ViewWindow* viewWin = 0;

  // parameters of view windows are stored in a map for restoring after restoring of the workstack
  QMap<SUIT_ViewWindow*, QString> viewersParameters;

  for ( int i = 0; i < nbViewers; i++ )
  {
    std::string viewerEntry = ip->getValue( "AP_VIEWERS_LIST", i );
    std::vector<std::string> veiewerParams = ip->parseValue(viewerEntry,'_');
    std::string type = veiewerParams[0];
    std::string viewerID = veiewerParams[1];
    SUIT_ViewManager* vm = myApp->newViewManager( type.c_str() );
    if ( !vm )
      continue; //Unknown viewer

    int nbViews = (ip->nbValues(viewerEntry))/2;

    //Create nbViews-1 view (-1 because 1 view is created by createViewManager)
    for ( int i = 1; i< nbViews; i++ )
    {
      SUIT_ViewWindow* aView = vm->createViewWindow();
      aView->show();
    }

    int viewCount = vm->getViewsCount();
    if ( viewCount != nbViews )
    {
      printf( "\nRestore visual state: Unknow error, Can't create a view!\n" );
      continue;
    }

    //Resize the views, set their captions and apply visual parameters.
    QVector<SUIT_ViewWindow*> views = vm->getViews();
    for ( int i = 0, j = 0; i<viewCount; i++, j+=2 )
    {
      viewWin = views[i];
      if ( !viewWin )
        continue;

      // wait untill the window is really shown.  This step fixes MANY bugs..
      //      while ( !vm->isVisible() )
      //        qApp->processEvents();

      viewWin->setWindowTitle( ip->getValue( viewerEntry, j ).c_str() );

      //      printf ( "VP for viewWin \"%s\": %s\n", viewerEntry.c_str(), ip->getValue(viewerEntry, j+1).c_str() );
      viewersParameters[ viewWin ] = ip->getValue( viewerEntry, j + 1 ).c_str();
      //viewWin->setVisualParameters(ip->getValue(viewerEntry, j+1).c_str());
    }
  }

  qApp->processEvents( QEventLoop::ExcludeUserInputEvents, 5000 );

  // restore modules' visual parameters
  std::vector<std::string> v = ip->getValues( "AP_MODULES_LIST" );
  for ( int i = 0; i < v.size(); i++ )
  {
    myApp->activateModule( v[i].c_str() );
    if ( SalomeApp_Module* module = dynamic_cast<SalomeApp_Module*>( myApp->activeModule() ) )
      module->restoreVisualParameters( savePoint );
  }

  // new view windows may have been created in  module->restoreVisualParameters() [GAUSS]
  // so here we store their visual parameters for later restoring..
  QList<SUIT_ViewManager*> lst;
  myApp->viewManagers( lst );
  for ( QList<SUIT_ViewManager*>::iterator itVM = lst.begin(); itVM != lst.end(); ++itVM )
  {
    SUIT_ViewManager* aVM = *itVM;
    if ( !aVM )
      continue;

    int view_count = aVM->getViewsCount();
    QVector<SUIT_ViewWindow*> views = aVM->getViews();
    for ( int i = 0; i < view_count; i++ )
    {
      if ( !viewersParameters.contains( views[i] ) )
      {
        viewersParameters[ views[i] ] = views[i]->getVisualParameters();
        //      printf ( "store VP for viewWin \"%s\": %s\n", views[i]->name(), views[i]->getVisualParameters().toLatin1().constData() );
      }
    }
  }

  // activate module that was active on save
  QString activeModuleName( ip->getProperty("AP_ACTIVE_MODULE" ).c_str() );
  if ( !activeModuleName.isEmpty() )
    myApp->activateModule( activeModuleName );

  // setting unique names for view windows in order to restore positions of view windows inside
  // workstack's structure (see below).  During save the same naming algorithm was used,
  // so the same views will get the same names.
  nameViewWindows( lst );

  qApp->processEvents( QEventLoop::ExcludeUserInputEvents, 5000 );

  // restore workstack parameters.  should be done after module's restoreVisualParameters(), because
  // some modules can create their own viewers (like VISU creates GaussViewers)
  if ( myApp->desktop()->inherits( "STD_TabDesktop" ) )
  {
    QtxWorkstack* workstack = ((STD_TabDesktop*)myApp->desktop())->workstack();
    workstack->restoreState( QByteArray::fromHex( QByteArray( ip->getProperty( "AP_WORKSTACK_INFO" ).c_str() ) ), 0 );
  }

  // restore visual parameters of view windows.  it must be done AFTER restoring workstack.
  // also set active view
  std::string activeViewName = ip->getProperty("AP_ACTIVE_VIEW");
  QMap<SUIT_ViewWindow*, QString>::Iterator mapIt;
  for ( mapIt = viewersParameters.begin(); mapIt != viewersParameters.end(); ++mapIt ) {
    mapIt.key()->setVisualParameters( mapIt.value() );
    if ( activeViewName == mapIt.key()->objectName().toStdString() )
      mapIt.key()->setFocus();
  }

  qApp->removeEventFilter( this );

  //  for ( it.toFirst(); it.current(); ++it ) {
  //    int view_count = it.current()->getViewsCount();
  //    QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
  //    for ( int i = 0; i < view_count; i++ )
  //      views[i]->setVisualParameters( viewersParameters[ views[i]->name() ] );
  //  }

  // set focus to previously saved active view window
  //  std::string activeViewName = ip->getProperty("AP_ACTIVE_VIEW");
  //  for ( it.toFirst(); it.current(); ++it ) {
  //    int view_count = it.current()->getViewsCount();
  //    QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
  //    for ( int i = 0; i < view_count; i++ )  {
  //      if ( activeViewName == views[i]->name() )
  //    views[i]->setFocus();
  //    }
  //  }
}

/*!
  Custom event filter
*/
bool SalomeApp_VisualState::eventFilter( QObject* o, QEvent* e )
{
  // eat keyboard and mouse events
  QEvent::Type aType = e->type();
  if ( aType == QEvent::MouseButtonDblClick ||
       aType == QEvent::MouseButtonPress ||
       aType == QEvent::MouseButtonRelease ||
       aType == QEvent::MouseMove ||
       aType == QEvent::KeyPress ||
       aType == QEvent::KeyRelease )
    return true;

  return QObject::eventFilter( o, e );
}
<commit_msg>remove traces<commit_after>// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//

#include "SalomeApp_VisualState.h"

#include "SalomeApp_Module.h"
#include "SalomeApp_Study.h"
#include "SalomeApp_Application.h"

//#include <SUIT_ResourceMgr.h>
#include <SUIT_ViewManager.h>
#include <SUIT_ViewWindow.h>
#include <QtxWorkstack.h>

#include <STD_TabDesktop.h>

#include <QList>
#include <QApplication>
#include <QMultiHash>

#include <SALOMEDSClient_ClientFactory.hxx>//?
#include <SALOMEDSClient_IParameters.hxx>//?

#include <vector>//?
#include <string>//?
#include <cstdio>

/*!
  Constructor.
*/
SalomeApp_VisualState::SalomeApp_VisualState( SalomeApp_Application* app )
  : QObject(),
    myApp( app )
{
}

/*!
  Destructor.
*/
SalomeApp_VisualState::~SalomeApp_VisualState()
{
}

/*!
  Sets names of all view windows in given list.  This is used
  in order to apply the same naming algorithm when saving and restoring
  view windows.  Names of view windows must be the same before saving
  workstack (splitters) information, and before its restoring!
  Naming rule: ViewerType_IndexOfViewerOfThisType_IndexOfViewInThisViewer
               VTKViewer_0_0
               OCCViewer_0_0  OCCViewer_0_1  OCCViewer_0_2
               VTKViewer_1_0
*/
void nameViewWindows( const ViewManagerList& lst )
{
  QMap<QString, int> viewersCounter;
  for ( QList<SUIT_ViewManager*>::const_iterator it = lst.begin(); it != lst.end(); ++it )
  {
    SUIT_ViewManager* aVM = *it;
    if ( !aVM )
      continue;

    int view_count = aVM->getViewsCount();
    QString vType = aVM->getType();
    if ( !view_count )
      continue; //No views is opened in the viewer

    if ( !viewersCounter.contains( vType ) )
      viewersCounter.insert( vType, 0 );

    int& viewerID = viewersCounter[vType];

    QVector<SUIT_ViewWindow*> views = aVM->getViews();
    for ( int i = 0; i < view_count; i++ )
    {
      QString vName = QString( "%1_%2_%3" ).arg( vType ).arg( viewerID ).arg( i );
      views[i]->setObjectName( vName );
    }
    viewerID++;
  }
}

/*!
  Stores the visual parameters of the viewers
*/
int SalomeApp_VisualState::storeState()
{
  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
  if ( !study )
    return -1;

  // unlock study if it is locked
  bool aLocked = study->studyDS()->GetProperties()->IsLocked();
  if (aLocked) study->studyDS()->GetProperties()->SetLocked(false);

  int savePoint = 1;
  std::vector<int> savePoints = study->getSavePoints();
  //Calculate a new savePoint number = the last save point number + 1
  if ( savePoints.size() > 0)
    savePoint = savePoints[savePoints.size()-1] + 1;

  _PTR(AttributeParameter) ap = study->studyDS()->GetCommonParameters( study->getVisualComponentName().toLatin1().constData(),
								       savePoint );
  _PTR(IParameters) ip = ClientFactory::getIParameters( ap );

  ViewManagerList lst;
  myApp->viewManagers( lst );

  // setting unique names for view windows in order to save this view inside
  // workstack's structure (see below).  On restore the views with the same names will
  // be placed to the same place inside the workstack's splitters.
  nameViewWindows( lst );

  // store active window's name
  SUIT_ViewWindow* win = myApp->desktop()->activeWindow();
  if ( win )
    ip->setProperty("AP_ACTIVE_VIEW", win->objectName().toStdString() );

  int viewerID = 0;
  SUIT_ViewManager* vm = 0;
  QListIterator<SUIT_ViewManager*> it( lst );
  while ( it.hasNext() ) {
    vm = it.next();
    if ( !vm ) continue;

    int view_count = vm->getViewsCount();
    if ( !view_count )
      continue; //No views is opened in the viewer

    std::string viewerEntry = QString( "%1_%2" ).arg( vm->getType() ).arg( ++viewerID ).toStdString();
    ip->append("AP_VIEWERS_LIST", viewerEntry);

    QVector<SUIT_ViewWindow*> views = vm->getViews();
    for(int i = 0; i<view_count; i++) {
      ip->append( viewerEntry, views[i]->windowTitle().toStdString() );
      ip->append( viewerEntry, views[i]->getVisualParameters().toStdString() );
    }
  }

  //Save information about split areas
  if ( myApp->desktop()->inherits( "STD_TabDesktop" ) )
  {
    QString workstackInfo;
    QtxWorkstack* workstack = ((STD_TabDesktop*)myApp->desktop())->workstack();
    QByteArray geomState = workstack->saveState( 0 );
    ip->setProperty( "AP_WORKSTACK_INFO", QString( geomState.toHex() ).toStdString() );
  }

  //Save a name of the active module
  if ( CAM_Module* activeModule = myApp->activeModule() )
    ip->setProperty( "AP_ACTIVE_MODULE", activeModule->moduleName().toStdString() );

  //Store visual parameters of the modules
  QList<CAM_Module*> mlist;
  myApp->modules( mlist );
  QListIterator<CAM_Module*> itM( mlist );
  CAM_Module* module = 0;
  while ( itM.hasNext() ) {
    module = itM.next();
    if ( !module ) continue;

    if ( LightApp_Module* lModule = dynamic_cast<LightApp_Module*>( module ) ) {
      ip->append( "AP_MODULES_LIST", lModule->moduleName().toStdString() );
      if ( SalomeApp_Module* sModule = dynamic_cast<SalomeApp_Module*>( module ) )
        sModule->storeVisualParameters( savePoint );
    }
  }

  // set default name of new savePoint
  study->setNameOfSavePoint( savePoint, QObject::tr( "SAVE_POINT_DEF_NAME" ) + QString::number( savePoint ) );

  if (aLocked) study->studyDS()->GetProperties()->SetLocked(true);

  return savePoint;
}

/*!
  Restores the visual parameters of the viewers
*/
void SalomeApp_VisualState::restoreState(int savePoint)
{
  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
  if ( !study )
    return;

  _PTR(AttributeParameter) ap = study->studyDS()->GetCommonParameters( study->getVisualComponentName().toLatin1().constData(),
								       savePoint );
  _PTR(IParameters) ip = ClientFactory::getIParameters(ap);

  qApp->installEventFilter( this );

  //Remove all already existent veiwers and their views
  //myApp->clearViewManagers();
  myApp->clearKnownViewManagers();

  //Restore the viewers and view windows
  int nbViewers = ip->nbValues( "AP_VIEWERS_LIST" );
  SUIT_ViewWindow* viewWin = 0;

  // parameters of view windows are stored in a map for restoring after restoring of the workstack
  QMap<SUIT_ViewWindow*, QString> viewersParameters;

  for ( int i = 0; i < nbViewers; i++ )
  {
    std::string viewerEntry = ip->getValue( "AP_VIEWERS_LIST", i );
    std::vector<std::string> veiewerParams = ip->parseValue(viewerEntry,'_');
    std::string type = veiewerParams[0];
    std::string viewerID = veiewerParams[1];
    SUIT_ViewManager* vm = myApp->newViewManager( type.c_str() );
    if ( !vm )
      continue; //Unknown viewer

    int nbViews = (ip->nbValues(viewerEntry))/2;

    //Create nbViews-1 view (-1 because 1 view is created by createViewManager)
    for ( int i = 1; i< nbViews; i++ )
    {
      SUIT_ViewWindow* aView = vm->createViewWindow();
      aView->show();
    }

    int viewCount = vm->getViewsCount();
    if ( viewCount != nbViews )
    {
      printf( "\nRestore visual state: Unknow error, Can't create a view!\n" );
      continue;
    }

    //Resize the views, set their captions and apply visual parameters.
    QVector<SUIT_ViewWindow*> views = vm->getViews();
    for ( int i = 0, j = 0; i<viewCount; i++, j+=2 )
    {
      viewWin = views[i];
      if ( !viewWin )
        continue;

      // wait untill the window is really shown.  This step fixes MANY bugs..
      //      while ( !vm->isVisible() )
      //        qApp->processEvents();

      viewWin->setWindowTitle( ip->getValue( viewerEntry, j ).c_str() );

      //      printf ( "VP for viewWin \"%s\": %s\n", viewerEntry.c_str(), ip->getValue(viewerEntry, j+1).c_str() );
      viewersParameters[ viewWin ] = ip->getValue( viewerEntry, j + 1 ).c_str();
      //viewWin->setVisualParameters(ip->getValue(viewerEntry, j+1).c_str());
    }
  }

  qApp->processEvents( QEventLoop::ExcludeUserInputEvents, 5000 );

  // restore modules' visual parameters
  std::vector<std::string> v = ip->getValues( "AP_MODULES_LIST" );
  for ( int i = 0; i < v.size(); i++ )
  {
    myApp->activateModule( v[i].c_str() );
    if ( SalomeApp_Module* module = dynamic_cast<SalomeApp_Module*>( myApp->activeModule() ) )
      module->restoreVisualParameters( savePoint );
  }

  // new view windows may have been created in  module->restoreVisualParameters() [GAUSS]
  // so here we store their visual parameters for later restoring..
  QList<SUIT_ViewManager*> lst;
  myApp->viewManagers( lst );
  for ( QList<SUIT_ViewManager*>::iterator itVM = lst.begin(); itVM != lst.end(); ++itVM )
  {
    SUIT_ViewManager* aVM = *itVM;
    if ( !aVM )
      continue;

    int view_count = aVM->getViewsCount();
    QVector<SUIT_ViewWindow*> views = aVM->getViews();
    for ( int i = 0; i < view_count; i++ )
    {
      if ( !viewersParameters.contains( views[i] ) )
      {
        viewersParameters[ views[i] ] = views[i]->getVisualParameters();
        //      printf ( "store VP for viewWin \"%s\": %s\n", views[i]->name(), views[i]->getVisualParameters().toLatin1().constData() );
      }
    }
  }

  // activate module that was active on save
  QString activeModuleName( ip->getProperty("AP_ACTIVE_MODULE" ).c_str() );
  if ( !activeModuleName.isEmpty() )
    myApp->activateModule( activeModuleName );

  // setting unique names for view windows in order to restore positions of view windows inside
  // workstack's structure (see below).  During save the same naming algorithm was used,
  // so the same views will get the same names.
  nameViewWindows( lst );

  qApp->processEvents( QEventLoop::ExcludeUserInputEvents, 5000 );

  // restore workstack parameters.  should be done after module's restoreVisualParameters(), because
  // some modules can create their own viewers (like VISU creates GaussViewers)
  if ( myApp->desktop()->inherits( "STD_TabDesktop" ) )
  {
    QtxWorkstack* workstack = ((STD_TabDesktop*)myApp->desktop())->workstack();
    workstack->restoreState( QByteArray::fromHex( QByteArray( ip->getProperty( "AP_WORKSTACK_INFO" ).c_str() ) ), 0 );
  }

  // restore visual parameters of view windows.  it must be done AFTER restoring workstack.
  // also set active view
  std::string activeViewName = ip->getProperty("AP_ACTIVE_VIEW");
  QMap<SUIT_ViewWindow*, QString>::Iterator mapIt;
  for ( mapIt = viewersParameters.begin(); mapIt != viewersParameters.end(); ++mapIt ) {
    mapIt.key()->setVisualParameters( mapIt.value() );
    if ( activeViewName == mapIt.key()->objectName().toStdString() )
      mapIt.key()->setFocus();
  }

  qApp->removeEventFilter( this );

  //  for ( it.toFirst(); it.current(); ++it ) {
  //    int view_count = it.current()->getViewsCount();
  //    QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
  //    for ( int i = 0; i < view_count; i++ )
  //      views[i]->setVisualParameters( viewersParameters[ views[i]->name() ] );
  //  }

  // set focus to previously saved active view window
  //  std::string activeViewName = ip->getProperty("AP_ACTIVE_VIEW");
  //  for ( it.toFirst(); it.current(); ++it ) {
  //    int view_count = it.current()->getViewsCount();
  //    QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
  //    for ( int i = 0; i < view_count; i++ )  {
  //      if ( activeViewName == views[i]->name() )
  //    views[i]->setFocus();
  //    }
  //  }
}

/*!
  Custom event filter
*/
bool SalomeApp_VisualState::eventFilter( QObject* o, QEvent* e )
{
  // eat keyboard and mouse events
  QEvent::Type aType = e->type();
  if ( aType == QEvent::MouseButtonDblClick ||
       aType == QEvent::MouseButtonPress ||
       aType == QEvent::MouseButtonRelease ||
       aType == QEvent::MouseMove ||
       aType == QEvent::KeyPress ||
       aType == QEvent::KeyRelease )
    return true;

  return QObject::eventFilter( o, e );
}
<|endoftext|>