|
|
78db8b |
/* === S Y N F I G ========================================================= */
|
|
|
78db8b |
/*! \file synfig/rendering/common/optimizer/optimizertransformation.cpp
|
|
|
78db8b |
** \brief OptimizerTransformation
|
|
|
78db8b |
**
|
|
|
78db8b |
** $Id$
|
|
|
78db8b |
**
|
|
|
78db8b |
** \legal
|
|
|
81df8d |
** ......... ... 2015-2018 Ivan Mahonin
|
|
|
78db8b |
**
|
|
|
78db8b |
** This package is free software; you can redistribute it and/or
|
|
|
78db8b |
** modify it under the terms of the GNU General Public License as
|
|
|
78db8b |
** published by the Free Software Foundation; either version 2 of
|
|
|
78db8b |
** the License, or (at your option) any later version.
|
|
|
78db8b |
**
|
|
|
78db8b |
** This package is distributed in the hope that it will be useful,
|
|
|
78db8b |
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
78db8b |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
78db8b |
** General Public License for more details.
|
|
|
78db8b |
** \endlegal
|
|
|
78db8b |
*/
|
|
|
78db8b |
/* ========================================================================= */
|
|
|
78db8b |
|
|
|
78db8b |
/* === H E A D E R S ======================================================= */
|
|
|
78db8b |
|
|
|
78db8b |
#ifdef USING_PCH
|
|
|
78db8b |
# include "pch.h"
|
|
|
78db8b |
#else
|
|
|
78db8b |
#ifdef HAVE_CONFIG_H
|
|
|
78db8b |
# include <config.h></config.h>
|
|
|
78db8b |
#endif
|
|
|
78db8b |
|
|
|
78db8b |
#include "optimizertransformation.h"
|
|
|
78db8b |
|
|
|
5b889e |
#include "../task/tasktransformation.h"
|
|
|
81df8d |
#include "../../primitive/transformationaffine.h"
|
|
|
5b889e |
|
|
|
78db8b |
#endif
|
|
|
78db8b |
|
|
|
78db8b |
using namespace synfig;
|
|
|
78db8b |
using namespace rendering;
|
|
|
78db8b |
|
|
|
78db8b |
/* === M A C R O S ========================================================= */
|
|
|
78db8b |
|
|
|
78db8b |
/* === G L O B A L S ======================================================= */
|
|
|
78db8b |
|
|
|
78db8b |
/* === P R O C E D U R E S ================================================= */
|
|
|
78db8b |
|
|
|
78db8b |
/* === M E T H O D S ======================================================= */
|
|
|
78db8b |
|
|
|
81df8d |
|
|
|
81df8d |
OptimizerTransformation::OptimizerTransformation()
|
|
|
943a07 |
{
|
|
|
81df8d |
category_id = CATEGORY_ID_BEGIN;
|
|
|
81df8d |
mode = MODE_REPEAT_LAST | MODE_RECURSIVE;
|
|
|
81df8d |
for_task = true;
|
|
|
943a07 |
}
|
|
|
943a07 |
|
|
|
81df8d |
|
|
|
943a07 |
void
|
|
|
81df8d |
OptimizerTransformation::run(const RunParams& params) const
|
|
|
943a07 |
{
|
|
|
81df8d |
TaskTransformation::Handle transformation = TaskTransformation::Handle::cast_dynamic(params.ref_task);
|
|
|
81df8d |
if (!transformation || !transformation->is_simple()) return;
|
|
|
81df8d |
|
|
|
81df8d |
// transformation of none in none
|
|
|
81df8d |
Task::Handle sub_task = transformation->sub_task();
|
|
|
61ff9b |
if (!sub_task || !transformation->get_transformation())
|
|
|
dda72a |
{ apply(params, Task::Handle()); return; }
|
|
|
81df8d |
|
|
|
81df8d |
// transformation of solid is solid
|
|
|
81df8d |
if (TaskInterfaceConstant *constant = sub_task.type_pointer<taskinterfaceconstant>())</taskinterfaceconstant>
|
|
|
943a07 |
{
|
|
|
81df8d |
if (constant->is_constant())
|
|
|
81df8d |
{
|
|
|
81df8d |
sub_task = sub_task->clone();
|
|
|
81df8d |
sub_task->assign_target(*transformation);
|
|
|
81df8d |
apply(params, sub_task);
|
|
|
81df8d |
return;
|
|
|
81df8d |
}
|
|
|
943a07 |
}
|
|
|
61ff9b |
|
|
|
61ff9b |
// merge into sub-task
|
|
|
81df8d |
if (TaskInterfaceTransformation *interface = sub_task.type_pointer<taskinterfacetransformation>())</taskinterfacetransformation>
|
|
|
5b889e |
{
|
|
|
81df8d |
if ( interface->get_transformation()
|
|
|
81df8d |
&& interface->get_transformation()->can_merge_outer( transformation->get_transformation() ) )
|
|
|
943a07 |
{
|
|
|
81df8d |
sub_task = sub_task->clone();
|
|
|
81df8d |
sub_task->assign_target(*transformation);
|
|
|
81df8d |
|
|
|
81df8d |
interface = sub_task.type_pointer<taskinterfacetransformation>();</taskinterfacetransformation>
|
|
|
81df8d |
assert( interface
|
|
|
81df8d |
&& interface->get_transformation()->can_merge_outer( transformation->get_transformation()) );
|
|
|
81df8d |
interface->get_transformation()->merge_outer( transformation->get_transformation() );
|
|
|
81df8d |
|
|
|
81df8d |
apply(params, sub_task);
|
|
|
e76351 |
return;
|
|
|
943a07 |
}
|
|
|
81df8d |
}
|
|
|
943a07 |
|
|
|
61ff9b |
// merge sub-task into current task
|
|
|
61ff9b |
if (TaskTransformation::Handle sub_transformation = TaskTransformation::Handle::cast_dynamic(sub_task))
|
|
|
61ff9b |
{
|
|
|
61ff9b |
if ( sub_transformation->is_simple()
|
|
|
61ff9b |
&& sub_transformation->sub_task()
|
|
|
61ff9b |
&& !sub_transformation->target_surface // exclude tasks with prerendered source
|
|
|
61ff9b |
&& transformation->get_transformation()->can_merge_inner(sub_transformation->get_transformation()) )
|
|
|
61ff9b |
{
|
|
|
61ff9b |
transformation = TaskTransformation::Handle::cast_dynamic(transformation->clone());
|
|
|
61ff9b |
// recheck ability to merge after clone
|
|
|
61ff9b |
assert( transformation->get_transformation()->can_merge_inner( transformation->get_transformation()) );
|
|
|
61ff9b |
transformation->get_transformation()->merge_inner( sub_transformation->get_transformation() );
|
|
|
61ff9b |
transformation->sub_task() = sub_transformation->sub_task();
|
|
|
61ff9b |
apply(params, transformation);
|
|
|
61ff9b |
return;
|
|
|
61ff9b |
}
|
|
|
61ff9b |
}
|
|
|
61ff9b |
|
|
|
81df8d |
// fall deeper in tree to make a chance to merge with others (for affine only)
|
|
|
81df8d |
if ( transformation->get_transformation().type_is<transformationaffine>() )</transformationaffine>
|
|
|
81df8d |
{
|
|
|
81df8d |
if ( sub_task.type_is<taskinterfacetransformationpass>() )</taskinterfacetransformationpass>
|
|
|
943a07 |
{
|
|
|
81df8d |
sub_task = sub_task->clone();
|
|
|
81df8d |
sub_task->assign_target(*transformation);
|
|
|
81df8d |
for(Task::List::iterator i = sub_task->sub_tasks.begin(); i != sub_task->sub_tasks.end(); ++i)
|
|
|
81df8d |
if (*i) {
|
|
|
81df8d |
Task::Handle t = transformation->clone();
|
|
|
81df8d |
t->assign_target(**i);
|
|
|
81df8d |
t->sub_task(0) = *i;
|
|
|
81df8d |
*i = t;
|
|
|
943a07 |
}
|
|
|
81df8d |
apply(params, sub_task);
|
|
|
81df8d |
return;
|
|
|
943a07 |
}
|
|
|
5b889e |
}
|
|
|
78db8b |
}
|
|
|
78db8b |
|
|
|
81df8d |
|
|
|
78db8b |
/* === E N T R Y P O I N T ================================================= */
|