Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Converting ArtRage XML into Blender 3D using Sverchok Add-On and Python #1

Open
enzyme69 opened this issue Apr 28, 2017 · 11 comments

Comments

@enzyme69
Copy link
Owner

commented Apr 28, 2017

I wanted to export STROKE DRAWING DATA from an iPad App called ArtRage into Blender 3D Open Source. This app understands Apple iPad Pro and Pencil pressure and tilt, so I think this is a great opportunity to practice my Python and workflow to parse the XML to something that Blender can understand.

I am using Sverchok Add-On to assist me to keep the node.

My code will be very rough but will try to improve it overtime.

@enzyme69 enzyme69 self-assigned this Apr 28, 2017

@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Apr 28, 2017

import xml.etree.ElementTree as etree
tree = etree.parse('test.xml')

root = tree.getroot()

mylist = []

# Get the string tail from XML tag
for child in root:
    #print(child)
    for i in child:
        #print(i)
        print(i.tail)
        mylist.append(i.tail)
        #for e in i:
            #if e.tag == 'Recorded':
            #    print(e.text)
            
# clean up

mypointlist = []

for item in mylist:
    mypointlist.append( item.lstrip().rstrip('\n\n').split('\n\t'))


# Get Pressure Strength

pressureListAll = []

for i in range(18):

    pressureList = []

    for item in mypointlist[i]:
        blah = item.split('\t')
        #print(blah)
        pressure = blah[2].split(': ')[1]

        pressureList.append(float(pressure))

        #coor = coordinate.lstrip('(').rstrip(')').split(',')

        #print(coor[0], coor[1])
        
    pressureListAll.append(pressureList)

print(pressureListAll)

# Get XY Coordinate and pass it out as Vector

coordinateAll = []

for i in range(18):

    listCoordinate = []

    for item in mypointlist[i]:
        blah = item.split('\t')

        coordinate = blah[1].split(': ')[1]

        coor = coordinate.lstrip('(').rstrip(')').split(',')

        listCoordinate.append([float(coor[0]), float(coor[1]), 0.0])
        
    coordinateAll.append(listCoordinate)

print(coordinateAll)
@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Apr 28, 2017

The XML arscript needs additional tag to start with. I ignore a lot of other data and focusing only on the STROKE POINTS and PRESSURE. There are some other useful data for timing and animation like how long a pen stay in that point. Anyhow, for simplicity I just care about the strokes drawing and thickness which will translate into Grease Pencil in Blender via Sverchok Add-On.

<ArtRage>
   <StrokeEvent>
      <StrokeHeader>
      </StrokeHeader>
      .... data here ....
   </StrokeEvent>

   <StrokeEvent>
      <StrokeHeader>
      </StrokeHeader>
      .... data here ....
   </StrokeEvent>

</ArtRage>
@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Apr 28, 2017

Using above setup and Sverchok Add-On to read Text In, I manage to bring the strokes I made using iPad and Apple Pencil into Blender!

screen shot 2017-04-28 at 20 56 20

@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Apr 28, 2017

What would be interesting is to also do the opposite: to make strokes in Blender using GREASE PENCIL and then pass it to ArtRage to process the data. Below is the original artwork that I draw on iPad using Apple Pencil, redrawn via ArtRage Script on ArtRage app on Mac:
screen shot 2017-04-28 at 20 57 31

Imagine the same thing, but the opposite ways from BLENDER to ARTRAGE:
Stroke drawings made in Blender, can be from 3D rendering and then redraw frame by frame on ArtRage? Can be pretty cool, especially with ArtRage brushes.

The Python script needs to be remade to work the opposite way to generate XML, etc.

Future homework.....

@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Apr 28, 2017

Below is the Sverchok node tree inside Blender.
screen shot 2017-04-28 at 21 00 34

@enzyme69 enzyme69 changed the title WIP Converting ArtRage XML into Sverchok using Python and Script Node WIP Converting ArtRage XML into Blender 3D using Sverchok Add-On and Python Apr 28, 2017

@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Apr 28, 2017

I learned a couple of things while parsing the XML. It is not always straight forward and my code is pretty lousy, it can always be improved. But it was pretty fun too.

@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Apr 30, 2017

Below is Sverchok Script Node Lite script to convert ArtRage XML into point and pressure strokes data to use in Blender: (very rough ugly code, can be improved)

"""
in matrices         m   d=[[]]   n=0
out points   v
out pressures s
"""

import os
import xml.etree.ElementTree as etree
import bpy

# source the file

base_dir = '/Users/jimmygunawan/Desktop/_PINEAPPLE_FILES'
filename = 'blend.xml'

tree = etree.parse( os.path.join(base_dir, filename ))

# root and tag
root = tree.getroot()

mylist = []

for child in root:
    #print(child)
    for i in child:
        #print(i)
        #print(i.tail)
        mylist.append(i.tail)
        #for e in i:
            #if e.tag == 'Recorded':
            #    print(e.text)
    
    
# clean up tail
mypointlist = []

for item in mylist:
    mypointlist.append( item.lstrip().rstrip('\n\n').split('\n\t'))
    
    
# Get Pressure Strength

pressureListAll = []

for i in range(len(mypointlist)):

    pressureList = []

    for item in mypointlist[i]:
        blah = item.split('\t')
        #print(blah)
        pressure = blah[2].split(': ')[1]

        pressureList.append(float(pressure))

        #coor = coordinate.lstrip('(').rstrip(')').split(',')

        #print(coor[0], coor[1])
        
    pressureListAll.append(pressureList)

pressures = pressureListAll

# Get XY Coordinate and pass it out as Vector

coordinateAll = []

for i in range(len(mypointlist)):

    listCoordinate = []

    for item in mypointlist[i]:
        blah = item.split('\t')

        coordinate = blah[1].split(': ')[1]

        coor = coordinate.lstrip('(').rstrip(')').split(',')

        listCoordinate.append([float(coor[0]), float(coor[1]), 0.0])
        
    coordinateAll.append(listCoordinate)
    
points = coordinateAll
@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Jan 15, 2018

BLEND ZIP example with XML, SNL and Python to test
SV_ArtRage_Script_Parsing_008_2018_01_15_03_03.zip

@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Jan 15, 2018

PYTHON Parsing example, sometimes XML format may change, and need to update parser accordingly!

import os
import xml.etree.ElementTree as etree
import bpy

# source the file

base_dir = '/Users/jimmygunawan/Downloads'
filename = 'blend.xml'

tree = etree.parse( os.path.join(base_dir, filename ))

# root and tag
root = tree.getroot()

mylist = []

for child in root:
    #print(child)
    for i in child:
        #print(i)
        #print(i.tail)
        mylist.append(i.tail)
        #for e in i:
            #if e.tag == 'Recorded':
            #    print(e.text)
    
    
# clean up tail
mypointlist = []

for num,item in enumerate(mylist):
    #mypointlist.append( item.lstrip().rstrip('\n\n').split('\n\t'))
    #print(num, item.rstrip('\n\n'))
    mypointlist.append( item.rstrip('\n\n').split('\n\t') )
    
#print(mypointlist[0][-1])



####print(len(mypointlist)) # there are 8 strokes
    
# Get Pressure Strength

pressureListAll = []

for i in range(len(mypointlist)):


    print("#### Getting Pressure List")
    pressureList = []
    
    # For every data in every strokes
    for num,item in enumerate(mypointlist[i][1:-1]):
        blah = item.split('\t')
        print(num,blah[3])
        pressure = blah[3].split(': ')[1]
        pressureList.append(float(pressure))

        
    pressureListAll.append(pressureList)

pressures = pressureListAll


# Get XY Coordinate and pass it out as Vector

coordinateAll = []

for i in range(len(mypointlist)):
    
    print("#### Getting XY Coordinate List")

    listCoordinate = []

    for num,item in enumerate(mypointlist[i][1:-1]):
        blah = item.split('\t')
        print(num,blah[2])

        coordinate = blah[2].split(': ')[1]

        coor = coordinate.lstrip('(').rstrip(')').split(',')

        listCoordinate.append([float(coor[0]), float(coor[1]), 0.0])
        
    coordinateAll.append(listCoordinate)
    
points = coordinateAll

print(points)

@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Jan 15, 2018

"""
in matrices         m   d=[[]]   n=0
out points   v
out pressures s
"""

import os
import xml.etree.ElementTree as etree
import bpy

# source the file

base_dir = '/Users/jimmygunawan/Downloads'
filename = 'blend.xml'

tree = etree.parse( os.path.join(base_dir, filename ))

# root and tag
root = tree.getroot()

mylist = []

for child in root:
    #print(child)
    for i in child:
        #print(i)
        #print(i.tail)
        mylist.append(i.tail)
        #for e in i:
            #if e.tag == 'Recorded':
            #    print(e.text)
    
    
# clean up tail
mypointlist = []

for num,item in enumerate(mylist):
    #mypointlist.append( item.lstrip().rstrip('\n\n').split('\n\t'))
    #print(num, item.rstrip('\n\n'))
    mypointlist.append( item.rstrip('\n\n').split('\n\t') )
    
#print(mypointlist[0][-1])



####print(len(mypointlist)) # there are 8 strokes
    
# Get Pressure Strength

pressureListAll = []

for i in range(len(mypointlist)):


    print("#### Getting Pressure List")
    pressureList = []
    
    # For every data in every strokes
    for num,item in enumerate(mypointlist[i][1:-1]):
        blah = item.split('\t')
        print(num,blah[3])
        pressure = blah[3].split(': ')[1]
        pressureList.append(float(pressure))

        
    pressureListAll.append(pressureList)

pressures = pressureListAll


# Get XY Coordinate and pass it out as Vector

coordinateAll = []

for i in range(len(mypointlist)):
    
    print("#### Getting XY Coordinate List")

    listCoordinate = []

    for num,item in enumerate(mypointlist[i][1:-1]):
        blah = item.split('\t')
        print(num,blah[2])

        coordinate = blah[2].split(': ')[1]

        coor = coordinate.lstrip('(').rstrip(')').split(',')

        listCoordinate.append([float(coor[0]), float(coor[1]), 0.0])
        
    coordinateAll.append(listCoordinate)
    
points = coordinateAll
@enzyme69

This comment has been minimized.

Copy link
Owner Author

commented Jan 15, 2018

screen shot 2018-01-15 at 2 05 43 pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.