Beispiel #1
0
    def add_skin_attachments_to_slot(graph: DAGraph,
                                     slot_parent: SpineNodeData,
                                     skin_attachment: List) -> None:
        for _id in skin_attachment:
            _data = skin_attachment[_id]
            attachment_data = SpineNodeData(
                node_data=_data,
                node_type=NodeType.ATTACHMENT,
                node_base_id=_id,
            )

            if graph.get_node(attachment_data.node_id) is None:
                graph.add_node(
                    node_type=attachment_data.node_type,
                    node_id=attachment_data.node_id,
                    node_data=attachment_data.node_data,
                )

            image_id = _data.get("path") or _data.get("name") or _id
            image_node_data = SpineNodeData(node_data={},
                                            node_type=NodeType.IMAGE,
                                            node_base_id=image_id)

            if graph.get_node(image_node_data.node_id) is None:
                graph.add_node(
                    node_type=image_node_data.node_type,
                    node_id=image_node_data.node_id,
                    node_data=image_node_data.node_data,
                )

            graph.add_edge(attachment_data.node_id, image_node_data.node_id)
            graph.add_edge(slot_parent.node_id, attachment_data.node_id)
Beispiel #2
0
    def test_graph_create_from_json_data_not_implemented(self, node_factory):
        graph_parser = IGraphParser()
        with pytest.raises(NotImplementedError):
            graph_parser.create_from_json_data(None, node_factory)

        with pytest.raises(NotImplementedError):
            DAGraph.create_from_json_data(IGraphParser, {}, node_factory)

        with pytest.raises(TypeError):
            DAGraph.create_from_json_data(object, {}, node_factory)
Beispiel #3
0
    def test_graph_create_from_json_file(self, node_factory):
        graph_parser = IGraphParser()
        with pytest.raises(NotImplementedError):
            DAGraph.create_from_json_file(IGraphParser, "PATH", node_factory)

        with pytest.raises(NotImplementedError):
            graph_parser.create_from_json_file(None, node_factory)

        with pytest.raises(TypeError):
            DAGraph.create_from_json_file(object, "PATH", node_factory)
Beispiel #4
0
def test_graph(graph_data: Dict[str, Any]) -> DAGraph:
    graph = DAGraph()

    node_types = graph_data.get("types", {})

    for node_id in graph_data["nodes"]:
        graph.add_node(node_id=node_id, node_type=node_types.get(node_id))
    [
        graph.add_edge(parent_id=edge[0], child_id=edge[1])
        for edge in graph_data["edges"]
    ]

    return graph
Beispiel #5
0
    def test_graph_edges(self):
        graph = DAGraph()
        graph.add_node(node_id="0")
        graph.add_node(node_id="1")
        graph.add_edge(parent_id="0", child_id="1")

        with pytest.raises(TypeError) as excinfo:
            graph.add_edge(parent_id="0", child_id="wrong_id")
        assert PARENTSHIP_TO_NO_NODE.format("child") in str(excinfo.value)

        with pytest.raises(TypeError) as excinfo:
            graph.add_edge(parent_id="wrong_id", child_id="1")
        assert PARENTSHIP_TO_NO_NODE.format("parent") in str(excinfo.value)
Beispiel #6
0
    def add_ik_to_graph(graph: DAGraph, ik_data: Dict[str, Any],
                        idx: int) -> SpineNodeData:
        spine_ik_data = SpineNodeData(
            node_data=ik_data,
            node_type=NodeType.IK,
            node_base_id=ik_data["name"],
            idx=idx,
        )
        graph.add_node(
            node_type=spine_ik_data.node_type,
            node_id=spine_ik_data.node_id,
            node_data=spine_ik_data.node_data,
        )

        # Getting optional parents for ik
        for child_bone_id in ik_data["bones"]:
            child_id = SpineGraphParser._to_graph_id(
                node_type_name=NodeType.BONE.name, node_base_id=child_bone_id)
            child = graph.get_node(child_id)
            if child:
                graph.add_edge(spine_ik_data.node_id, child.id)

        target_bone = ik_data.get("target")
        if target_bone:
            parent_bone_id = SpineGraphParser._to_graph_id(
                node_type_name=NodeType.BONE.name, node_base_id=target_bone)
            parent_bone = graph.get_node(parent_bone_id)
            if parent_bone:
                graph.add_edge(parent_bone.id, spine_ik_data.node_id)

        return spine_ik_data
Beispiel #7
0
    def create_from_json_data(cls, json_data: Dict[str, Any],
                              node_factory: SpineNodeFactory) -> DAGraph:
        graph = DAGraph(node_factory)

        for idx, bone_data in enumerate(json_data["bones"]):
            cls.add_bone_to_graph(graph=graph, bone_data=bone_data, idx=idx)

        for idx, _slot_data in enumerate(json_data.get("slots", [])):
            node_slot = cls.add_slot_to_graph(graph=graph,
                                              slot_data=_slot_data,
                                              idx=idx)

            # Adding attachments as child to slots differentiating between versions:
            for data in json_data["skins"]:
                skin_data = data.get("attachments")
                if skin_data:
                    slot_skinned = skin_data.get(_slot_data["name"], [])

                    SpineGraphParser.add_skin_attachments_to_slot(
                        graph=graph,
                        slot_parent=node_slot,
                        skin_attachment=slot_skinned,
                    )

        iks = json_data.get("ik", [])
        for idx, ik_data in enumerate(iks):
            cls.add_ik_to_graph(graph=graph, ik_data=ik_data, idx=idx)

        return graph
Beispiel #8
0
    def test_graph_remove_node(self):
        graph = DAGraph()
        graph.add_node(node_id=DEFAULT_ID)
        graph.remove_node_by_id(node_id=DEFAULT_ID)

        # Trying to remove already removed
        with pytest.raises(ValueError) as excinfo:
            graph.remove_node_by_id(node_id=DEFAULT_ID)
        assert ID_NODE_NOT_FOUND.format(DEFAULT_ID) in str(excinfo.value)
Beispiel #9
0
    def add_slot_to_graph(graph: DAGraph, slot_data: Dict[str, Any], idx: int):
        spine_slot_data = SpineNodeData(
            node_data=slot_data,
            node_type=NodeType.SLOT,
            node_base_id=slot_data["name"],
            idx=idx,
        )

        graph.add_node(
            node_type=spine_slot_data.node_type,
            node_id=spine_slot_data.node_id,
            node_data=spine_slot_data.node_data,
        )

        # Getting optional parents from slot
        parent_id = SpineGraphParser._to_graph_id(
            node_type_name=NodeType.BONE.name,
            node_base_id=slot_data.get("bone"))
        parent = graph.get_node(parent_id)
        if parent:
            graph.add_edge(parent.id, spine_slot_data.node_id)

        return spine_slot_data
Beispiel #10
0
    def create_from_json_data(cls, json_data: Dict[str, Any],
                              node_factory: SpineNodeFactory) -> DAGraph:
        graph = DAGraph(node_factory)

        for idx, bone_data in enumerate(json_data["bones"]):
            node_data = SpineNodeData(
                node_data=bone_data,
                node_type=NodeType.BONE,
                node_base_id=bone_data["name"],
                idx=idx,
            )
            graph.add_node(
                node_type=node_data.node_type,
                node_id=node_data.node_id,
                node_data=node_data.node_data,
            )

            # Getting optional parent from bone
            parent_id = SpineGraphParser._to_graph_id(
                node_type_name=NodeType.BONE.name,
                node_base_id=bone_data.get("parent"))
            parent = graph.get_node(parent_id)
            if parent:
                graph.add_edge(parent.id, node_data.node_id)

        slots_json_data = json_data.get("slots", [])
        for idx, _slot_data in enumerate(slots_json_data):
            spine_slot_data = SpineNodeData(
                node_data=_slot_data,
                node_type=NodeType.SLOT,
                node_base_id=_slot_data["name"],
                idx=idx,
            )

            graph.add_node(
                node_type=spine_slot_data.node_type,
                node_id=spine_slot_data.node_id,
                node_data=spine_slot_data.node_data,
            )

            def add_slot_skinned_to_graph(graph, slot_skinned):
                for _id in slot_skinned:
                    _data = slot_skinned[_id]
                    attachment_data = SpineNodeData(
                        node_data=_data,
                        node_type=NodeType.ATTACHMENT,
                        node_base_id=_data.get("path") or _data.get("name")
                        or _id,
                    )

                    if graph.get_node(attachment_data.node_id) is None:
                        graph.add_node(
                            node_type=attachment_data.node_type,
                            node_id=attachment_data.node_id,
                            node_data=attachment_data.node_data,
                        )
                    graph.add_edge(spine_slot_data.node_id,
                                   attachment_data.node_id)

            # Adding attachments as child to slots differentiating between versions:
            for data in json_data["skins"]:
                skin_data = data.get("attachments")
                if skin_data:
                    slot_skinned = skin_data.get(_slot_data["name"], [])

                    add_slot_skinned_to_graph(graph=graph,
                                              slot_skinned=slot_skinned)

            # Getting optional parents from slot
            parent_id = SpineGraphParser._to_graph_id(
                node_type_name=NodeType.BONE.name,
                node_base_id=_slot_data.get("bone"))
            parent = graph.get_node(parent_id)
            if parent:
                graph.add_edge(parent.id, spine_slot_data.node_id)

        iks = json_data.get("ik", [])
        for idx, ik_data in enumerate(iks):
            spine_ik_data = SpineNodeData(
                node_data=ik_data,
                node_type=NodeType.IK,
                node_base_id=ik_data["name"],
                idx=idx,
            )
            graph.add_node(
                node_type=spine_ik_data.node_type,
                node_id=spine_ik_data.node_id,
                node_data=spine_ik_data.node_data,
            )

            # Getting optional parents for ik
            for child_bone_id in ik_data["bones"]:
                child_id = SpineGraphParser._to_graph_id(
                    node_type_name=NodeType.BONE.name,
                    node_base_id=child_bone_id)
                child = graph.get_node(child_id)
                if child:
                    graph.add_edge(spine_ik_data.node_id, child.id)

            target_bone = ik_data.get("target")
            if target_bone:
                parent_bone_id = SpineGraphParser._to_graph_id(
                    node_type_name=NodeType.BONE.name,
                    node_base_id=target_bone)
                parent_bone = graph.get_node(parent_bone_id)
                if parent_bone:
                    graph.add_edge(parent_bone.id, spine_ik_data.node_id)

        return graph
Beispiel #11
0
    def test_graph_nodes_creation(self, node_factory):
        graph = DAGraph(node_factory)

        node1 = graph.add_node(node_id=DEFAULT_ID)
        assert node1 is not None
        assert graph.get_node(node_id=DEFAULT_ID) is node1

        with pytest.raises(ValueError) as excinfo:
            graph.add_node(node_id=DEFAULT_ID, node_data=None)
        assert UNIQUE_ID_ERROR_MESSAGE in str(excinfo.value)

        graph.add_node(node_id="1", node_data=None)
        NUM_NODES = 1000
        for _ in range(0, NUM_NODES):
            id_ = graph.generate_unique_id()
            tmp_node = graph.add_node(node_id=id_)
            assert id_ is not DEFAULT_ID
            assert tmp_node is not None
            assert graph.get_node(node_id=id_) is tmp_node

            with pytest.raises(ValueError) as excinfo:
                graph.add_node(node_id=id_, node_data=None)
            assert UNIQUE_ID_ERROR_MESSAGE in str(excinfo.value)

            with pytest.raises(TypeError) as excinfo:
                graph.add_node(node_id=0)
            assert WRONG_NODE_ID_TYPE in str(excinfo.value)

            with pytest.raises(TypeError) as excinfo:
                graph.get_node(node_id=0)
            assert WRONG_NODE_ID_TYPE in str(excinfo.value)
Beispiel #12
0
    def test_graph_multi_graphs(self, node_factory):
        graph1 = DAGraph(node_factory)
        graph2 = DAGraph(node_factory)

        id_ = graph1.generate_unique_id()
        node1 = graph1.add_node(node_id=id_)
        assert node1 is not None
        assert graph1.get_node(node_id=id_) is node1

        # Checking if also in graph2
        assert graph2.get_node(node_id=id_) is None

        # Creating two nodes with the same id in different graphs
        node2 = graph2.add_node(node_id=id_)
        assert node2 is not node1

        with pytest.raises(ValueError) as excinfo:
            graph1.add_edge(parent_id=id_, child_id=id_)
        assert CIRCULAR_PARENTSHIP_NODE_ERROR.format("child") in str(excinfo.value)
Beispiel #13
0
    def test_graph_forbidden_child_types(self, node_factory):
        graph = DAGraph(node_factory)
        graph.add_node(node_id=NODE_TYPE_BLOND, node_type=NODE_TYPE_BLOND)
        graph.add_node(node_id=NODE_TYPE_BROWN, node_type=NODE_TYPE_BROWN)
        graph.add_node(node_id=NODE_TYPE_BLACK, node_type=NODE_TYPE_BLACK)
        graph.add_edge(parent_id=NODE_TYPE_BLOND, child_id=NODE_TYPE_BROWN)
        graph.add_edge(parent_id=NODE_TYPE_BLACK, child_id=NODE_TYPE_BROWN)

        with pytest.raises(TypeError) as excinfo:
            graph.add_edge(parent_id=NODE_TYPE_BLACK, child_id=NODE_TYPE_BLOND)
        assert CHILD_TYPE_FORBIDDEN in str(excinfo.value)

        with pytest.raises(TypeError) as excinfo:
            graph.add_edge(parent_id=NODE_TYPE_BLOND, child_id=NODE_TYPE_BLACK)
        assert CHILD_TYPE_FORBIDDEN in str(excinfo.value)