File indexing completed on 2025-02-02 04:11:07

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "path_modifier.hpp"
0008 
0009 #include "model/shapes/group.hpp"
0010 #include "model/shapes/path.hpp"
0011 
0012 #include "model/animation/join_animatables.hpp"
0013 
0014 
0015 static void to_path_value(
0016     const glaxnimate::math::bezier::MultiBezier& mbez,
0017     std::vector<glaxnimate::model::Path*>& paths,
0018     glaxnimate::model::Group* group,
0019     glaxnimate::model::Document* document
0020 )
0021 {
0022     for ( int i = 0; i < mbez.size(); i++ )
0023     {
0024         if ( i >= int(paths.size()) )
0025         {
0026             auto new_path = std::make_unique<glaxnimate::model::Path>(document);
0027             paths.push_back(new_path.get());
0028             group->shapes.insert(std::move(new_path));
0029         }
0030 
0031         auto path = paths[i];
0032         path->shape.set(mbez.beziers()[i]);
0033     }
0034 }
0035 
0036 static void to_path_frame(
0037     const glaxnimate::math::bezier::MultiBezier& mbez,
0038     std::vector<glaxnimate::model::Path*>& paths,
0039     glaxnimate::model::FrameTime t,
0040     const glaxnimate::model::KeyframeTransition& transition,
0041     glaxnimate::model::Group* group,
0042     glaxnimate::model::Document* document
0043 )
0044 {
0045     for ( int i = 0; i < mbez.size(); i++ )
0046     {
0047         if ( i >= int(paths.size()) )
0048         {
0049             auto new_path = std::make_unique<glaxnimate::model::Path>(document);
0050             if ( t > 0 )
0051             {
0052                 glaxnimate::model::KeyframeTransition trans;
0053                 trans.set_hold(true);
0054                 new_path->shape.set_keyframe(0, glaxnimate::math::bezier::Bezier{})->set_transition({trans});
0055             }
0056             paths.push_back(new_path.get());
0057             group->shapes.insert(std::move(new_path));
0058         }
0059 
0060         auto path = paths[i];
0061         path->shape.set_keyframe(t, mbez.beziers()[i])->set_transition(transition);
0062     }
0063 }
0064 
0065 std::unique_ptr<glaxnimate::model::ShapeElement> glaxnimate::model::PathModifier::to_path() const
0066 {
0067     auto group = std::make_unique<glaxnimate::model::Group>(document());
0068     group->name.set(name.get());
0069     group->group_color.set(group_color.get());
0070     group->visible.set(visible.get());
0071 
0072 
0073     std::vector<const AnimatableBase*> properties;
0074     auto flags = PropertyTraits::Visual|PropertyTraits::Animated;
0075     for ( auto prop : this->properties() )
0076     {
0077         if ( (prop->traits().flags & flags) == flags )
0078             properties.push_back(static_cast<AnimatableBase*>(prop));
0079     }
0080 
0081     JoinAnimatables ja(std::move(properties), JoinAnimatables::NoValues);
0082     FrameTime cur_time = ja.properties()[0]->time();
0083 
0084     std::vector<glaxnimate::model::Path*> paths;
0085 
0086     if ( ja.animated() )
0087     {
0088         for ( const auto & kf : ja )
0089         {
0090             auto bez = collect_shapes(kf.time, {});
0091             to_path_frame(bez, paths, kf.time, kf.transition(), group.get(), document());
0092         }
0093     }
0094     else
0095     {
0096         auto bez = collect_shapes(time(), {});
0097         to_path_value(bez, paths, group.get(), document());
0098     }
0099 
0100     group->set_time(cur_time);
0101     return group;
0102 
0103 }
0104 
0105 void glaxnimate::model::PathModifier::on_paint(QPainter* painter, glaxnimate::model::FrameTime t, glaxnimate::model::VisualNode::PaintMode mode, glaxnimate::model::Modifier*) const
0106 {
0107     for ( auto sib : affected() )
0108         sib->paint(painter, t, mode, const_cast<glaxnimate::model::PathModifier*>(this));
0109 }
0110 
0111