Beispiel #1
0
ValueNode_Bone::BoneSet
ValueNode_Bone::get_possible_parent_bones(ValueNode::Handle value_node)
{
	BoneSet ret;
	bool debug(false);

	if (getenv("SYNFIG_DEBUG_SUITABLE_PARENTS"))
		debug = true;

	if (debug) printf("%s:%d which bones can be parents of %lx (%s)\n", __FILE__, __LINE__, uintptr_t(value_node.get()), value_node->get_string().c_str());

	// which bones are we currently editing the parent of - it can be more than one due to linking
	ValueNode_Bone::BoneSet affected_bones(ValueNode_Bone::get_bones_affected_by(value_node));
	if (debug) printf("%s:%d got %zd affected bones\n", __FILE__, __LINE__, affected_bones.size());
	Canvas::LooseHandle canvas(value_node->get_root_canvas());
	if (debug) printf("%s:%d canvas %lx\n", __FILE__, __LINE__, uintptr_t(canvas.get()));
	for (ValueNode_Bone::BoneSet::iterator iter = affected_bones.begin(); iter != affected_bones.end(); iter++)
	{
		if (!canvas)
		{
			canvas = (*iter)->get_root_canvas();
			printf("%s:%d root canvas %lx\n", __FILE__, __LINE__, uintptr_t((*iter)->get_root_canvas().get()));
			printf("%s:%d parent canvas %lx\n", __FILE__, __LINE__, uintptr_t((*iter)->get_parent_canvas().get()));
			printf("%s:%d ancestor canvas %lx\n", __FILE__, __LINE__, uintptr_t((*iter)->get_non_inline_ancestor_canvas().get()));

		}
		if (canvas != (*iter)->get_root_canvas())
			warning("%s:%d multiple root canvases in affected bones: %lx and %lx", __FILE__, __LINE__,
					uintptr_t(canvas.get()), uintptr_t((*iter)->get_root_canvas().get()));
	}

	BoneMap bone_map(canvas_map[canvas]);

	// loop through all the bones that exist
	for (ValueNode_Bone::BoneMap::const_iterator iter=bone_map.begin(); iter!=bone_map.end(); iter++)
	{
		ValueNode_Bone::Handle bone_value_node(iter->second);

		// if the bone would be affected by our editing, skip it - it would cause a loop if the user selected it
		if (affected_bones.count(bone_value_node.get()))
			continue;

		// loop through the list of bones referenced by this bone's parent link;
		// if any of them would be affected by editing the cell, don't offer this bone in the menu
		{
			ValueNode_Bone::BoneSet parents(ValueNode_Bone::get_bones_referenced_by(bone_value_node->get_link("parent")));

			ValueNode_Bone::BoneSet::iterator iter;
			for (iter = parents.begin(); iter != parents.end(); iter++)
				if (affected_bones.count(iter->get()))
					break;
			if (iter == parents.end())
				ret.insert(bone_value_node);
		}
	}

	if (debug) printf("%s:%d returning %zd possible parents\n", __FILE__, __LINE__, ret.size());
	return ret;
}
ValueNode_Switch::ValueNode_Switch(const ValueNode::Handle &x):
	LinkableValueNode(x->get_type())
{
	Vocab ret(get_children_vocab());
	set_children_vocab(ret);
	set_link("link_off",x);
	set_link("link_on",x);
	set_link("switch",ValueNode_Const::create(bool(false)));
}
ValueNode_TimeLoop::ValueNode_TimeLoop(const ValueNode::Handle &x):
	LinkableValueNode(x->get_type())
{
	Vocab ret(get_children_vocab());
	set_children_vocab(ret);
	set_link("link", x);
	set_link("link_time",  ValueNode_Const::create(Time(0)));
	set_link("local_time", ValueNode_Const::create(Time(0)));
	set_link("duration",   ValueNode_Const::create(Time(1)));
}
bool
ValueNode_DynamicList::set_link_vfunc(int i,ValueNode::Handle x)
{
	assert(i>=0);

	if((unsigned)i>=list.size())
		return false;
	if(x->get_type()!=*container_type)
		return false;
	list[i].value_node=x;
	return true;
}
Beispiel #5
0
bool
ValueNode_StaticList::set_link_vfunc(int i,ValueNode::Handle x) // line 628
{
	assert(i>=0);

	if((unsigned)i>=list.size())
		return false;
	if(x->get_type()!=*container_type)
		return false;
	list[i]=x;
	return true;
}
Beispiel #6
0
ValueNode_BoneInfluence::ValueNode_BoneInfluence(const ValueNode::Handle &x, Canvas::LooseHandle canvas):
	LinkableValueNode(x->get_type()),
	checked_inverse_(),
	has_inverse_()
{
	Type &type(x->get_type());
	if (type == type_vector || type == type_bline_point)
	{
		ValueNode_StaticList::Handle bone_weight_list(ValueNode_StaticList::create(type_bone_weight_pair, canvas));
		bone_weight_list->add(ValueNode_BoneWeightPair::create(BoneWeightPair(Bone(), 1), canvas));
		set_link("bone_weight_list",	bone_weight_list);
		set_link("link",				x);

		if (getenv("SYNFIG_DEBUG_SET_PARENT_CANVAS"))
			printf("%s:%d set parent canvas for bone influence to %lx\n", __FILE__, __LINE__, uintptr_t(canvas.get()));
		set_parent_canvas(canvas);
	}
	else
	{
		throw Exception::BadType(type.description.local_name);
	}
}
Beispiel #7
0
bool
Layer::connect_dynamic_param(const String& param, etl::loose_handle<ValueNode> value_node)
{
	if (!value_node) return disconnect_dynamic_param(param);

	ValueNode::Handle previous;
	DynamicParamList::iterator i = dynamic_param_list_.find(param);
	if (i != dynamic_param_list_.end()) previous = i->second;

	if (previous == value_node)
		return true;

	String param_noref = param;
	dynamic_param_list_[param]=ValueNode::Handle(value_node);

	if (previous)
	{
		// fix 2353284: if two parameters in the same layer are
		// connected to the same valuenode and we disconnect one of
		// them, the parent-child relationship for the remaining
		// connection was being deleted.  now we search the parameter
		// list to see if another parameter uses the same valuenode
		DynamicParamList::const_iterator iter;
		for (iter = dynamic_param_list().begin(); iter != dynamic_param_list().end(); iter++)
			if (iter->second == previous)
				break;
		if (iter == dynamic_param_list().end())
			remove_child(previous.get());
	}

	add_child(value_node.get());
	if(!value_node->is_exported() && get_canvas())
		value_node->set_parent_canvas(get_canvas());

	dynamic_param_changed(param);
	changed();
	return true;
}
ValueNode_BoneInfluence::ValueNode_BoneInfluence(const ValueNode::Handle &x, Canvas::LooseHandle canvas):
	LinkableValueNode(x->get_type())
{
	switch(x->get_type())
	{
	case ValueBase::TYPE_VECTOR:
	case ValueBase::TYPE_BLINEPOINT:
	//case ValueBase::TYPE_BLINE:
	{
		ValueNode_StaticList::Handle bone_weight_list(ValueNode_StaticList::create(ValueBase::TYPE_BONE_WEIGHT_PAIR, canvas));
		bone_weight_list->add(ValueNode_BoneWeightPair::create(BoneWeightPair(Bone(), 1), canvas));
		set_link("bone_weight_list",	bone_weight_list);
		set_link("link",				x);

		if (getenv("SYNFIG_DEBUG_SET_PARENT_CANVAS"))
			printf("%s:%d set parent canvas for bone influence to %lx\n", __FILE__, __LINE__, uintptr_t(canvas.get()));
		set_parent_canvas(canvas);

		break;
	}
	default:
		throw Exception::BadType(ValueBase::type_local_name(x->get_type()));
	}
}
void swap_guid(const ValueNode::Handle& a,const ValueNode::Handle& b)
{
    synfig::GUID old_a(a->get_guid());
    a->set_guid(synfig::GUID());

    synfig::GUID old_b(b->get_guid());
    b->set_guid(synfig::GUID());

    a->set_guid(old_b);
    b->set_guid(old_a);
}
Beispiel #10
0
bool
ValueNodeList::erase(ValueNode::Handle value_node)
{
	assert(value_node);

	iterator iter;

	for(iter=begin();iter!=end();++iter)
		if(value_node.get()==iter->get())
		{
			std::list<ValueNode::RHandle>::erase(iter);
			if(PlaceholderValueNode::Handle::cast_dynamic(value_node))
				placeholder_count_--;
			return true;
		}
	return false;
}
void
ValueNode_DynamicList::add(const ValueNode::Handle &value_node, int index)
{
	ListEntry list_entry(value_node);
	list_entry.timing_info.size();

	if(index<0 || index>=(int)list.size())
	{
		list.push_back(list_entry);
	}
	else
	{
		list.insert(list.begin()+index,list_entry);
	}

	add_child(value_node.get());
	reindex();
	//changed();

	if(get_parent_canvas())
		get_parent_canvas()->signal_value_node_child_added()(this,value_node);
	else if(get_root_canvas() && get_parent_canvas())
		get_root_canvas()->signal_value_node_child_added()(this,value_node);
}
Beispiel #12
0
ValueNode_Bone::BoneSet
ValueNode_Bone::get_bones_referenced_by(ValueNode::Handle value_node, bool recursive)
{
	// printf("%s:%d rec = %d\n", __FILE__, __LINE__,recursive);
	BoneSet ret;
	if (!value_node)
	{
		printf("%s:%d failed?\n", __FILE__, __LINE__);
		assert(0);
		return ret;
	}

	// if it's a ValueNode_Const
	if (ValueNode_Const::Handle value_node_const = ValueNode_Const::Handle::cast_dynamic(value_node))
	{
		ValueBase value_node(value_node_const->get_value());
		if (value_node.get_type() == type_bone_valuenode)
			if (ValueNode_Bone::Handle bone = value_node.get(ValueNode_Bone::Handle()))
			{
				// do we want to check for bone references in other bone fields or just 'parent'?
				if (recursive)
				{
					// printf("%s:%d rec\n", __FILE__, __LINE__);
					ret = get_bones_referenced_by(bone, recursive);
					// ret = get_bones_referenced_by(bone->get_link("parent"), recursive);
				}
				if (!bone->is_root())
					ret.insert(bone);
			}
		return ret;
	}

	// if it's a ValueNode_Animated
	if (ValueNode_Animated::Handle value_node_animated = ValueNode_Animated::Handle::cast_dynamic(value_node))
	{
		// ValueNode_Animated::Handle ret = ValueNode_Animated::create(type_bone_object);
		ValueNode_Animated::WaypointList list(value_node_animated->waypoint_list());
		for (ValueNode_Animated::WaypointList::iterator iter = list.begin(); iter != list.end(); iter++)
		{
//			printf("%s:%d getting bones from waypoint\n", __FILE__, __LINE__);
			BoneSet ret2(get_bones_referenced_by(iter->get_value_node(), recursive));
			ret.insert(ret2.begin(), ret2.end());
//			printf("added %d bones from waypoint to get %d\n", int(ret2.size()), int(ret.size()));
		}
//		printf("returning %d bones\n", int(ret.size()));
		return ret;
	}

	// if it's a LinkableValueNode
	if (LinkableValueNode::Handle linkable_value_node = LinkableValueNode::Handle::cast_dynamic(value_node))
	{
		for (int i = 0; i < linkable_value_node->link_count(); i++)
		{
			BoneSet ret2(get_bones_referenced_by(linkable_value_node->get_link(i), recursive));
			ret.insert(ret2.begin(), ret2.end());
		}
		return ret;
	}

	if (PlaceholderValueNode::Handle linkable_value_node = PlaceholderValueNode::Handle::cast_dynamic(value_node))
	{
		// todo: while loading we might be setting up an ancestry loop by ignoring the placeholder valuenode here
		// can we check for loops in badly formatted .sifz files somehow?
		if (getenv("SYNFIG_DEBUG_PLACEHOLDER_VALUENODE"))
			printf("%s:%d found a placeholder - skipping loop check\n", __FILE__, __LINE__);
		return ret;
	}

	error("%s:%d BUG: bad type in valuenode '%s'", __FILE__, __LINE__, value_node->get_string().c_str());
	assert(0);
	return ret;
}
Beispiel #13
0
bool
ValueNode_Composite::set_link_vfunc(int i,ValueNode::Handle x)
{
    assert(i>=0 && i<link_count());

    if(PlaceholderValueNode::Handle::cast_dynamic(x))
    {
        components[i]=x;
        return true;
    }

    Type &type(get_type());
    if (type == type_vector)
    {
        if(x->get_type()==ValueBase(Real()).get_type() || PlaceholderValueNode::Handle::cast_dynamic(x))
        {
            components[i]=x;
            return true;
        }
    }
    else if (type == type_color)
    {
        if(x->get_type()==ValueBase(Real()).get_type() || PlaceholderValueNode::Handle::cast_dynamic(x))
        {
            components[i]=x;
            return true;
        }
    }
    else if (type == type_segment)
    {
        if(x->get_type()==ValueBase(Point()).get_type() || PlaceholderValueNode::Handle::cast_dynamic(x))
        {
            components[i]=x;
            return true;
        }
    }
    else if (type == type_bline_point)
    {
        if((i==0 || i==4 || i==5) && x->get_type()==ValueBase(Point()).get_type())
        {
            components[i]=x;
            return true;
        }
        if((i==1 || i==2) && x->get_type()==ValueBase(Real()).get_type())
        {
            components[i]=x;
            return true;
        }
        if((i==3 || i==6 || i==7) && x->get_type()==ValueBase(bool()).get_type())
        {
            components[i]=x;
            return true;
        }
    }
    else if (type == type_dash_item
             || type == type_width_point)
    {
        if((i==0 || i==1) && x->get_type()==ValueBase(Real()).get_type())
        {
            components[i]=x;
            return true;
        }
        if((i==2 || i==3) && x->get_type()==ValueBase(int()).get_type())
        {
            components[i]=x;
            return true;
        }
        if((i==4 || i==5) && x->get_type()==ValueBase(Real()).get_type())
        {
            if(ValueNode_Const::Handle::cast_dynamic(x))
            {
                if(i==4 && components[5])
                {
                    if(i==4 && (*x)(0).get(Real()) < (*components[5])(0).get(Real()))
                    {
                        components[i]=x;
                        return true;
                    }
                    else
                        return false;
                }
                if(i==5 && components[4])
                {
                    if((i==5 && (*x)(0).get(Real()) > (*components[4])(0).get(Real())))
                    {
                        components[i]=x;
                        return true;
                    }
                    else
                        return false;
                }
                components[i]=x;
                return true;
            }
            return false;
        }
    }
    else if (type == type_transformation)
    {
        if( PlaceholderValueNode::Handle::cast_dynamic(x)
                || (i == 0 && x->get_type()==ValueBase(Vector()).get_type())
                || (i == 1 && x->get_type()==ValueBase(Angle()).get_type())
                || (i == 2 && x->get_type()==ValueBase(Angle()).get_type())
                || (i == 3 && x->get_type()==ValueBase(Vector()).get_type())
          ) {
            components[i]=x;
            return true;
        }
    }
    else if (dynamic_cast<types_namespace::TypeWeightedValueBase*>(&type) != NULL)
    {
        types_namespace::TypeWeightedValueBase *tp =
            dynamic_cast<types_namespace::TypeWeightedValueBase*>(&type);
        if( PlaceholderValueNode::Handle::cast_dynamic(x)
                || (i == 0 && x->get_type()==ValueBase(Real()).get_type())
                || (i == 1 && x->get_type()==tp->get_contained_type())
          ) {
            components[i]=x;
            return true;
        }
    }
    else if (dynamic_cast<types_namespace::TypePairBase*>(&type) != NULL)
    {
        types_namespace::TypePairBase *tp =
            dynamic_cast<types_namespace::TypePairBase*>(&type);
        if( PlaceholderValueNode::Handle::cast_dynamic(x)
                || (i == 0 && x->get_type()==tp->get_first_type())
                || (i == 1 && x->get_type()==tp->get_second_type())
          ) {
            components[i]=x;
            return true;
        }
    }

    return false;
}
void synfigapp::recurse_valuedesc(synfigapp::ValueDesc h, const std::set<Time> &tlist,
								timepoints_ref &vals, synfig::Time time_offset, synfig::Real time_dilation)
{
	//special cases for Animated, DynamicList, and Linkable

	//synfig::info("ValueBasenode... %p, %s", h.get_value_node().get(),typeid(*h.get_value_node()).name());


	//animated case
	{
		synfig::ValueNode_Animated::Handle p = synfig::ValueNode_Animated::Handle::cast_dynamic(h.get_value_node());

		if(p)
		{
			//loop through and determine which waypoint we will need to reference
			const synfig::WaypointList &w = p->waypoint_list();

			synfig::WaypointList::const_iterator i = w.begin(),
												end = w.end();

			std::set<Time>::const_iterator		j = tlist.begin(),
												jend = tlist.end();
			for(; i != end && j != jend;)
			{
				//synfig::info("tpair t(%.3f) = %.3f", (float)*j, (float)(i->get_time()));

				if((*j*time_dilation+time_offset).is_equal(i->get_time()))
				{
					vals.insert(p,*i,time_dilation);
					++i,++j;
				}else if(*i < *j*time_dilation+time_offset)
				{
					++i;
				}else ++j;
			}
			return;
		}
	}

	//parent dynamiclist case - just for active points for that object...
	if(h.parent_is_value_node())
	{
		synfig::ValueNode_DynamicList::Handle p = synfig::ValueNode_DynamicList::Handle::cast_dynamic(h.get_parent_value_node());

		if(p)
		{
			int index = h.get_index();

			//check all the active points in each list...
			const synfig::ActivepointList &a = p->list[index].timing_info;

			//synfig::info("Our parent = dynamic list, searching in %d activepts",a.size());

			std::set<Time>::const_iterator			i = tlist.begin(),
													end = tlist.end();

			synfig::ActivepointList::const_iterator 	j = a.begin(),
													jend = a.end();

			for(; j != jend && i != end;)
			{
				double it = *i*time_dilation+time_offset;
				double jt = j->get_time();
				double diff = (double)(it - jt);

				//synfig::info("\ttpair match(%.4lg) - %.4lg (diff = %lg",it,jt,diff);

				//
				if(abs(diff) < (double)Time::epsilon())
				{
					//synfig::info("\tActivepoint to add being referenced (%x,%s,%.4lg)",
					//				(int)j->get_uid(),j->state?"true":"false", (double)j->time);
					vals.insert(ValueDesc(p,index),*j,time_dilation);
					++i,++j;
				}else if(it < jt)
				{
					++i;
					//synfig::info("\tIncrementing time");
				}
				else
				{
					++j;
					//synfig::info("\tIncrementing actpt");
				}
			}
		}
	}

	//dynamiclist case - we must still make sure that we read from the list entries the time values
	//						because just the linked valuenodes will not do that
	{
		synfig::ValueNode_DynamicList::Handle p = synfig::ValueNode_DynamicList::Handle::cast_dynamic(h.get_value_node());

		if(p)
		{
			//synfig::info("Process dynamic list valuenode");
			int index = 0;

			std::vector<synfig::ValueNode_DynamicList::ListEntry>::const_iterator
							i = p->list.begin(),
							end = p->list.end();

			for(; i != end; ++i, ++index)
			{
				const Node::time_set &tset = i->get_times();

				if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset,time_dilation))
				{
					recurse_valuedesc(ValueDesc(p,index),tlist,vals,time_offset,time_dilation);
				}
			}
			return;
		}
	}

	//the linkable case...
	{
		etl::handle<synfig::LinkableValueNode> p = etl::handle<synfig::LinkableValueNode>::cast_dynamic(h.get_value_node());

		if(p)
		{
			//synfig::info("Process Linkable ValueBasenode");
			int i = 0, size = p->link_count();

			for(; i < size; ++i)
			{
				ValueNode::Handle v = p->get_link(i);
				const Node::time_set &tset = v->get_times();

				if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset,time_dilation))
				{
					recurse_valuedesc(ValueDesc(p,i),tlist,vals,time_offset,time_dilation);
				}
			}
		}
	}
}