File size: 6,797 Bytes
8c52bbf
 
cfe4dff
8c52bbf
 
e1dd757
be4e070
d8707ce
8c52bbf
d8707ce
0d9e5b3
be4e070
0d9e5b3
8c52bbf
 
0d9e5b3
8c52bbf
 
 
be4e070
 
 
4a33878
be4e070
0d9e5b3
8c52bbf
be4e070
8c52bbf
0d9e5b3
 
 
e1dd757
0d9e5b3
 
 
 
 
 
 
 
 
 
 
 
 
 
be4e070
0d9e5b3
 
 
be4e070
0d9e5b3
 
e1dd757
 
0d9e5b3
be4e070
 
e1dd757
 
be4e070
e1dd757
be4e070
0d9e5b3
a8aa6e6
 
 
 
 
0d9e5b3
be4e070
a8aa6e6
be4e070
 
0d9e5b3
be4e070
a8aa6e6
be4e070
0d9e5b3
 
 
be4e070
 
 
a8aa6e6
be4e070
a8aa6e6
be4e070
 
a8aa6e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
be4e070
 
 
 
 
 
 
a8aa6e6
be4e070
8f4ea34
 
be4e070
8f4ea34
be4e070
 
 
 
 
 
 
 
 
 
 
8f4ea34
be4e070
8f4ea34
be4e070
8f4ea34
 
0d9e5b3
 
 
8f4ea34
be4e070
 
d8707ce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f4ea34
be4e070
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import streamlit as st
import ast
import base64
import streamlit.components.v1 as components
from transformers import pipeline
from gtts import gTTS
import os
import qrcode  # QR code generation

# Set up the Streamlit page
st.set_page_config(page_title="AR/VR Code Visualizer", layout="wide")
st.title("πŸ‘“ AR/VR Code Visualizer with Editing, Interaction, and Export")

@st.cache_resource
def load_model():
    return pipeline("summarization", model="philschmid/bart-large-cnn-samsum")

summarizer = load_model()

# In-browser code editor
st.subheader("πŸ“ Write or Paste Your Python Code")
code = st.text_area("Enter your Python code here", height=300)

if code.strip():
    st.code(code, language="python")

    # Parse AST for functions and calls
    tree = ast.parse(code)

    class FunctionCallVisitor(ast.NodeVisitor):
        def __init__(self):
            self.calls = {}

        def visit_FunctionDef(self, node):
            caller = node.name
            self.calls[caller] = []
            for child in ast.walk(node):
                if isinstance(child, ast.Call) and isinstance(child.func, ast.Name):
                    self.calls[caller].append(child.func.id)
            self.generic_visit(node)

    visitor = FunctionCallVisitor()
    visitor.visit(tree)
    call_graph = visitor.calls
    all_functions = list(call_graph.keys())

    st.subheader("πŸ“Š Function Calls")
    for fn, callees in call_graph.items():
        st.write(f"πŸ”Ή `{fn}` calls: {', '.join(callees) if callees else 'None'}")

    # Generate AI summary
    prompt = f"Explain the structure and purpose of the following functions and how they call each other: {call_graph}"
    summary = summarizer(prompt, max_length=60, min_length=15, do_sample=False)
    summary_text = summary[0]['summary_text']
    st.success(summary_text)

    # Generate voice narration
    st.subheader("πŸ”Š Voice Narration")
    tts = gTTS(text=summary_text)
    tts.save("summary.mp3")
    st.audio("summary.mp3", format="audio/mp3")

    # A-Frame VR scene with interactivity and export
    def generate_aframe(call_graph):
        # Serialize function data to JSON format
        function_data = {
            "functions": [],
            "relationships": []
        }

        function_positions = {}
        spacing = 3
        i = 0
        for fn in call_graph:
            x = i * spacing
            function_positions[fn] = (x, 1, -3)
            function_data["functions"].append({"name": fn, "position": [x, 1, -3]})
            i += 1

        for caller, callees in call_graph.items():
            for callee in callees:
                if callee in function_positions:
                    x1, y1, z1 = function_positions[caller]
                    x2, y2, z2 = function_positions[callee]
                    function_data["relationships"].append({"start": [x1, y1, z1], "end": [x2, y2, z2]})

        # JavaScript to render the function data dynamically using JSON
        js = """
        <script>
        // The JSON data will be passed as a global variable
        const functionData = """ + str(function_data).replace("'", '"') + """;
        
        // Render boxes dynamically based on function data
        functionData.functions.forEach(function(fn) {
            const el = document.createElement('a-box');
            el.setAttribute('id', fn.name);
            el.setAttribute('position', fn.position.join(' '));
            el.setAttribute('depth', '0.5');
            el.setAttribute('height', '0.5');
            el.setAttribute('width', '2');
            el.setAttribute('color', '#FFC65D');
            el.setAttribute('class', 'clickable');
            el.setAttribute('event-set__enter', '_event: mouseenter; color: #00CED1');
            el.setAttribute('event-set__leave', '_event: mouseleave; color: #FFC65D');
            el.setAttribute('onclick', `say('${fn.name}')`);
            document.querySelector('a-scene').appendChild(el);

            // Add text for the function
            const text = document.createElement('a-text');
            text.setAttribute('value', fn.name);
            text.setAttribute('position', `${fn.position[0]} ${fn.position[1] + 1} ${fn.position[2]}`);
            text.setAttribute('align', 'center');
            text.setAttribute('color', '#000');
            document.querySelector('a-scene').appendChild(text);
        });

        // Render relationship lines dynamically based on function data
        functionData.relationships.forEach(function(rel) {
            const el = document.createElement('a-entity');
            el.setAttribute('line', `start: ${rel.start.join(' ')}; end: ${rel.end.join(' ')}; color: red`);
            document.querySelector('a-scene').appendChild(el);
        });
        
        // Text-to-speech function for box click
        function say(text) {
            const utter = new SpeechSynthesisUtterance(text);
            speechSynthesis.speak(utter);
        }
        </script>
        """

        # HTML structure for A-Frame scene
        html = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
            <script src="https://cdn.jsdelivr.net/gh/donmccurdy/[email protected]/dist/aframe-extras.min.js"></script>
            <script src="https://unpkg.com/[email protected]/dist/aframe-screenshot-component.min.js"></script>
            {js}
        </head>
        <body>
            <a-scene screenshot>
                <a-entity position="0 1.6 3">
                    <a-camera wasd-controls-enabled="true" look-controls-enabled="true"></a-camera>
                </a-entity>
                <a-light type="ambient" color="#FFF"></a-light>
                <a-plane rotation="-90 0 0" width="40" height="40" color="#7BC8A4"></a-plane>
            </a-scene>
        </body>
        </html>
        """
        return html

    aframe_html = generate_aframe(call_graph)
    b64 = base64.b64encode(aframe_html.encode()).decode()
    data_url = f"data:text/html;base64,{b64}"

    st.subheader("🌐 Interactive 3D Function Visualizer")
    components.iframe(data_url, height=600)

    # QR Code for AR View on Mobile
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=4,
    )
    url = "https://huggingface.co/spaces/your-space-url"  # Replace with your Hugging Face Space URL
    qr.add_data(url)
    qr.make(fit=True)

    # Create and display the QR Code
    img = qr.make_image(fill='black', back_color='white')
    st.image(img, caption="Scan this QR code to view the VR scene in AR on your mobile!")
else:
    st.info("Write some Python code above to visualize, narrate, and explore it in VR.")