Reputation: 800
using Excel interface, how can I plot a 3D wireframe? I have no clue how to do this ! but wanted to do by giving the coordinates of the joints where there are frames between them.
for simplicity of the Example, just immagine a 3D wireframe in the form of a cube.
Upvotes: 1
Views: 537
Reputation: 8270
Ok, so I previously gave advice as to switch on the macro recorder but this would not give you the 3D mathematics required to draw wireframes. For that you need a library, Philip Rideout's SVG wireframes Python library which is written up here on his blog.
On my blog I have added some code which parses the SVG file generated by Philip Rideout's code and then converts the Polygon directives to Excel free from shapes on the worksheet. This is a screenshot of the output.
I have added the code here as well
class ScreenUpdatingRAII(object):
def __init__(self, app, visible:bool=False):
self.app = app
self.saved = app.ScreenUpdating
app.ScreenUpdating = visible
def restore(self):
self.app.ScreenUpdating = self.saved
self.app = None
def convertSvgToExcelShapes(filename):
import xml.etree.ElementTree as ET
from win32com.client import GetObject,Dispatch
# code below is highly dependent on the child
# structure because xpath was not working for me (my bad)
dom = ET.parse(filename)
rootxml = dom.getroot()
g = rootxml[1] # second child
wb = Dispatch(GetObject(r"C:\Users\Simon\source\repos\WireframeExcelShapes\WireframeExcelShapes\WireframeExcelShapes.xlsx"))
app = Dispatch(wb.Parent)
ws = Dispatch(wb.Worksheets.Item("WireFrame"))
shps = Dispatch(ws.Shapes)
for x in shps:
Dispatch(x).Delete()
idx =0
scale, xoffset, yoffset = 500, 300,300
screenUpdates = ScreenUpdatingRAII(app)
for polygon in g:
# triple nested list comprehension parsing the points by splitting
# first by space then by comma then converting to float
points = [[float(z[0])*scale+xoffset, float(z[1])*scale+yoffset] for z in [y.split(',') for y in [x for x in polygon.attrib['points'].split()]]]
#print(points)
msoEditingAuto,msoSegmentLine, msoFalse, msoTrue = 0,0,0, -1
freeformbuilder=shps.BuildFreeform(msoEditingAuto, points[0][0] , points[0][1])
freeformbuilder.AddNodes(msoSegmentLine, msoEditingAuto, points[1][0] , points[1][1])
freeformbuilder.AddNodes(msoSegmentLine, msoEditingAuto, points[2][0] , points[2][1])
freeformbuilder.AddNodes(msoSegmentLine, msoEditingAuto, points[0][0], points[0][1])
newShp = Dispatch(freeformbuilder.ConvertToShape())
shpFill = Dispatch(newShp.Fill)
shpFill.Visible = msoTrue
shpFill.Transparency = 0.25
shpFill.Solid
shpFill.ForeColor.RGB = 0xFFFFFF
idx=+1
screenUpdates.restore()
pass
filename = "octahedron.svg"
generate_svg(filename)
convertSvgToExcelShapes(filename)
You still have a little work to do to generate your own shape as the sample shape is an octahedron.
Upvotes: 2