mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-18 08:25:52 +08:00
Increase performance and decrease memory usage by using numpy library for 3D models. Saves more then 50% memory, and is about 30% faster when loading models. I think more performance can be gained with this library.
This commit is contained in:
parent
e698fb067d
commit
8069d0633f
@ -180,44 +180,44 @@ def ResetMatrixRotationAndScale():
|
||||
|
||||
def DrawBox(vMin, vMax):
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(vMin.x, vMin.y, vMin.z)
|
||||
glVertex3f(vMax.x, vMin.y, vMin.z)
|
||||
glVertex3f(vMax.x, vMax.y, vMin.z)
|
||||
glVertex3f(vMin.x, vMax.y, vMin.z)
|
||||
glVertex3f(vMin[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMin[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMin[2])
|
||||
glEnd()
|
||||
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(vMin.x, vMin.y, vMax.z)
|
||||
glVertex3f(vMax.x, vMin.y, vMax.z)
|
||||
glVertex3f(vMax.x, vMax.y, vMax.z)
|
||||
glVertex3f(vMin.x, vMax.y, vMax.z)
|
||||
glVertex3f(vMin[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMax[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMax[2])
|
||||
glEnd()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(vMin.x, vMin.y, vMin.z)
|
||||
glVertex3f(vMin.x, vMin.y, vMax.z)
|
||||
glVertex3f(vMax.x, vMin.y, vMin.z)
|
||||
glVertex3f(vMax.x, vMin.y, vMax.z)
|
||||
glVertex3f(vMax.x, vMax.y, vMin.z)
|
||||
glVertex3f(vMax.x, vMax.y, vMax.z)
|
||||
glVertex3f(vMin.x, vMax.y, vMin.z)
|
||||
glVertex3f(vMin.x, vMax.y, vMax.z)
|
||||
glVertex3f(vMin[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMin[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMax[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMin[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMax[2])
|
||||
glEnd()
|
||||
|
||||
def DrawSTL(mesh):
|
||||
glEnable(GL_CULL_FACE)
|
||||
for face in mesh.faces:
|
||||
for i in xrange(0, mesh.vertexCount, 3):
|
||||
glBegin(GL_TRIANGLES)
|
||||
v1 = face.v[0]
|
||||
v2 = face.v[1]
|
||||
v3 = face.v[2]
|
||||
glNormal3f(face.normal.x, face.normal.y, face.normal.z)
|
||||
glVertex3f(v1.x, v1.y, v1.z)
|
||||
glVertex3f(v2.x, v2.y, v2.z)
|
||||
glVertex3f(v3.x, v3.y, v3.z)
|
||||
glNormal3f(-face.normal.x, -face.normal.y, -face.normal.z)
|
||||
glVertex3f(v1.x, v1.y, v1.z)
|
||||
glVertex3f(v3.x, v3.y, v3.z)
|
||||
glVertex3f(v2.x, v2.y, v2.z)
|
||||
v1 = mesh.vertexes[i]
|
||||
v2 = mesh.vertexes[i+1]
|
||||
v3 = mesh.vertexes[i+2]
|
||||
glNormal3f(mesh.normal[i/3][0], mesh.normal[i/3][1], mesh.normal[i/3][2])
|
||||
glVertex3f(v1[0], v1[1], v1[2])
|
||||
glVertex3f(v2[0], v2[1], v2[2])
|
||||
glVertex3f(v3[0], v3[1], v3[2])
|
||||
glNormal3f(-mesh.normal[i/3][0], -mesh.normal[i/3][1], -mesh.normal[i/3][2])
|
||||
glVertex3f(v1[0], v1[1], v1[2])
|
||||
glVertex3f(v2[0], v2[1], v2[2])
|
||||
glVertex3f(v3[0], v3[1], v3[2])
|
||||
glEnd()
|
||||
|
||||
def DrawGCodeLayer(layer):
|
||||
|
@ -1,6 +1,7 @@
|
||||
from __future__ import division
|
||||
|
||||
import sys, math, threading, re, time, os
|
||||
import numpy
|
||||
|
||||
from wx import glcanvas
|
||||
import wx
|
||||
@ -170,11 +171,11 @@ class previewPanel(wx.Panel):
|
||||
return
|
||||
vMin = self.objectsMinV
|
||||
vMax = self.objectsMaxV
|
||||
scaleX1 = (self.machineSize.x - self.machineCenter.x) / ((vMax.x - vMin.x) / 2)
|
||||
scaleY1 = (self.machineSize.y - self.machineCenter.y) / ((vMax.y - vMin.y) / 2)
|
||||
scaleX2 = (self.machineCenter.x) / ((vMax.x - vMin.x) / 2)
|
||||
scaleY2 = (self.machineCenter.y) / ((vMax.y - vMin.y) / 2)
|
||||
scaleZ = self.machineSize.z / (vMax.z - vMin.z)
|
||||
scaleX1 = (self.machineSize.x - self.machineCenter.x) / ((vMax[0] - vMin[0]) / 2)
|
||||
scaleY1 = (self.machineSize.y - self.machineCenter.y) / ((vMax[1] - vMin[1]) / 2)
|
||||
scaleX2 = (self.machineCenter.x) / ((vMax[0] - vMin[1]) / 2)
|
||||
scaleY2 = (self.machineCenter.y) / ((vMax[1] - vMin[1]) / 2)
|
||||
scaleZ = self.machineSize.z / (vMax[2] - vMin[2])
|
||||
scale = min(scaleX1, scaleY1, scaleX2, scaleY2, scaleZ)
|
||||
self.scale.SetValue(str(scale))
|
||||
profile.putProfileSetting('model_scale', self.scale.GetValue())
|
||||
@ -356,8 +357,8 @@ class previewPanel(wx.Panel):
|
||||
continue
|
||||
|
||||
obj.mesh.getMinimumZ()
|
||||
minV = minV.min(obj.mesh.getMinimum())
|
||||
maxV = maxV.max(obj.mesh.getMaximum())
|
||||
minV = numpy.minimum(minV, obj.mesh.getMinimum())
|
||||
maxV = numpy.maximum(maxV, obj.mesh.getMaximum())
|
||||
|
||||
self.objectsMaxV = maxV
|
||||
self.objectsMinV = minV
|
||||
@ -365,10 +366,11 @@ class previewPanel(wx.Panel):
|
||||
if obj.mesh == None:
|
||||
continue
|
||||
|
||||
for v in obj.mesh.vertexes:
|
||||
v.z -= minV.z
|
||||
v.x -= minV.x + (maxV.x - minV.x) / 2
|
||||
v.y -= minV.y + (maxV.y - minV.y) / 2
|
||||
obj.mesh.vertexes -= numpy.array([minV[0] + (maxV[0] - minV[0]) / 2, minV[1] + (maxV[1] - minV[1]) / 2, minV[2]])
|
||||
#for v in obj.mesh.vertexes:
|
||||
# v[2] -= minV[2]
|
||||
# v[0] -= minV[0] + (maxV[0] - minV[0]) / 2
|
||||
# v[1] -= minV[1] + (maxV[1] - minV[1]) / 2
|
||||
obj.mesh.getMinimumZ()
|
||||
obj.dirty = True
|
||||
self.glCanvas.Refresh()
|
||||
@ -461,7 +463,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
glTranslate(0,0,-self.parent.gcode.layerList[self.parent.layerSpin.GetValue()][0].list[-1].z)
|
||||
else:
|
||||
if self.parent.objectsMaxV != None:
|
||||
glTranslate(0,0,-self.parent.objectsMaxV.z * profile.getProfileSettingFloat('model_scale') / 2)
|
||||
glTranslate(0,0,-self.parent.objectsMaxV[2] * profile.getProfileSettingFloat('model_scale') / 2)
|
||||
else:
|
||||
glScale(1.0/self.zoom, 1.0/self.zoom, 1.0)
|
||||
glTranslate(self.offsetX, self.offsetY, 0.0)
|
||||
@ -610,11 +612,11 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
modelScale = profile.getProfileSettingFloat('model_scale')
|
||||
modelSize = (obj.mesh.getMaximum() - obj.mesh.getMinimum()) * modelScale
|
||||
glPushMatrix()
|
||||
glTranslate(-(modelSize.x+10)*(multiX-1)/2,-(modelSize.y+10)*(multiY-1)/2, 0)
|
||||
glTranslate(-(modelSize[0]+10)*(multiX-1)/2,-(modelSize[1]+10)*(multiY-1)/2, 0)
|
||||
for mx in xrange(0, multiX):
|
||||
for my in xrange(0, multiY):
|
||||
glPushMatrix()
|
||||
glTranslate((modelSize.x+10)*mx,(modelSize.y+10)*my, 0)
|
||||
glTranslate((modelSize[0]+10)*mx,(modelSize[1]+10)*my, 0)
|
||||
glScalef(modelScale, modelScale, modelScale)
|
||||
glCallList(obj.displayList)
|
||||
glPopMatrix()
|
||||
|
@ -3,9 +3,9 @@ import __init__
|
||||
|
||||
import wx, os, platform, types, webbrowser, math, subprocess, threading, time, re
|
||||
import ConfigParser
|
||||
import numpy
|
||||
|
||||
from wx import glcanvas
|
||||
import wx
|
||||
try:
|
||||
import OpenGL
|
||||
OpenGL.ERROR_CHECKING = False
|
||||
@ -55,18 +55,15 @@ class ProjectObject(stl.stlModel):
|
||||
self.modelDisplayList = None
|
||||
self.modelDirty = False
|
||||
|
||||
self.origonalVertexes = list(self.vertexes)
|
||||
for i in xrange(0, len(self.origonalVertexes)):
|
||||
self.origonalVertexes[i] = self.origonalVertexes[i].copy()
|
||||
self.getMinimumZ()
|
||||
|
||||
self.centerX = -self.getMinimum().x + 5
|
||||
self.centerY = -self.getMinimum().y + 5
|
||||
self.centerX = -self.getMinimum()[0] + 5
|
||||
self.centerY = -self.getMinimum()[1] + 5
|
||||
|
||||
self.updateModelTransform()
|
||||
|
||||
self.centerX = -self.getMinimum().x + 5
|
||||
self.centerY = -self.getMinimum().y + 5
|
||||
self.centerX = -self.getMinimum()[0] + 5
|
||||
self.centerY = -self.getMinimum()[1] + 5
|
||||
|
||||
def isSameExceptForPosition(self, other):
|
||||
if self.filename != other.filename:
|
||||
@ -96,10 +93,7 @@ class ProjectObject(stl.stlModel):
|
||||
minZ = self.getMinimumZ()
|
||||
minV = self.getMinimum()
|
||||
maxV = self.getMaximum()
|
||||
for v in self.vertexes:
|
||||
v.z -= minZ
|
||||
v.x -= minV.x + (maxV.x - minV.x) / 2
|
||||
v.y -= minV.y + (maxV.y - minV.y) / 2
|
||||
self.vertexes -= numpy.array([minV[0] + (maxV[0] - minV[0]) / 2, minV[1] + (maxV[1] - minV[1]) / 2, minZ])
|
||||
minZ = self.getMinimumZ()
|
||||
self.modelDirty = True
|
||||
|
||||
@ -125,14 +119,14 @@ class ProjectObject(stl.stlModel):
|
||||
return p
|
||||
|
||||
def clampXY(self):
|
||||
if self.centerX < -self.getMinimum().x * self.scale + self.parent.extruderOffset[self.extruder].x:
|
||||
self.centerX = -self.getMinimum().x * self.scale + self.parent.extruderOffset[self.extruder].x
|
||||
if self.centerY < -self.getMinimum().y * self.scale + self.parent.extruderOffset[self.extruder].y:
|
||||
self.centerY = -self.getMinimum().y * self.scale + self.parent.extruderOffset[self.extruder].y
|
||||
if self.centerX > self.parent.machineSize.x + self.parent.extruderOffset[self.extruder].x - self.getMaximum().x * self.scale:
|
||||
self.centerX = self.parent.machineSize.x + self.parent.extruderOffset[self.extruder].x - self.getMaximum().x * self.scale
|
||||
if self.centerY > self.parent.machineSize.y + self.parent.extruderOffset[self.extruder].y - self.getMaximum().y * self.scale:
|
||||
self.centerY = self.parent.machineSize.y + self.parent.extruderOffset[self.extruder].y - self.getMaximum().y * self.scale
|
||||
if self.centerX < -self.getMinimum()[0] * self.scale + self.parent.extruderOffset[self.extruder][0]:
|
||||
self.centerX = -self.getMinimum()[0] * self.scale + self.parent.extruderOffset[self.extruder][0]
|
||||
if self.centerY < -self.getMinimum()[1] * self.scale + self.parent.extruderOffset[self.extruder][1]:
|
||||
self.centerY = -self.getMinimum()[1] * self.scale + self.parent.extruderOffset[self.extruder][1]
|
||||
if self.centerX > self.parent.machineSize[0] + self.parent.extruderOffset[self.extruder][0] - self.getMaximum()[0] * self.scale:
|
||||
self.centerX = self.parent.machineSize[0] + self.parent.extruderOffset[self.extruder][0] - self.getMaximum()[0] * self.scale
|
||||
if self.centerY > self.parent.machineSize[1] + self.parent.extruderOffset[self.extruder][1] - self.getMaximum()[1] * self.scale:
|
||||
self.centerY = self.parent.machineSize[1] + self.parent.extruderOffset[self.extruder][1] - self.getMaximum()[1] * self.scale
|
||||
|
||||
class projectPlanner(wx.Frame):
|
||||
"Main user interface window"
|
||||
@ -151,15 +145,15 @@ class projectPlanner(wx.Frame):
|
||||
self.selection = None
|
||||
self.printMode = 0
|
||||
|
||||
self.machineSize = util3d.Vector3(profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height'))
|
||||
self.headSizeMin = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0)
|
||||
self.headSizeMax = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0)
|
||||
self.machineSize = numpy.array([profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')])
|
||||
self.headSizeMin = numpy.array([profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0])
|
||||
self.headSizeMax = numpy.array([profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0])
|
||||
|
||||
self.extruderOffset = [
|
||||
util3d.Vector3(0,0,0),
|
||||
util3d.Vector3(profile.getPreferenceFloat('extruder_offset_x1'), profile.getPreferenceFloat('extruder_offset_y1'), 0),
|
||||
util3d.Vector3(profile.getPreferenceFloat('extruder_offset_x2'), profile.getPreferenceFloat('extruder_offset_y2'), 0),
|
||||
util3d.Vector3(profile.getPreferenceFloat('extruder_offset_x3'), profile.getPreferenceFloat('extruder_offset_y3'), 0)]
|
||||
numpy.array([0,0,0]),
|
||||
numpy.array([profile.getPreferenceFloat('extruder_offset_x1'), profile.getPreferenceFloat('extruder_offset_y1'), 0]),
|
||||
numpy.array([profile.getPreferenceFloat('extruder_offset_x2'), profile.getPreferenceFloat('extruder_offset_y2'), 0]),
|
||||
numpy.array([profile.getPreferenceFloat('extruder_offset_x3'), profile.getPreferenceFloat('extruder_offset_y3'), 0])]
|
||||
|
||||
self.toolbar = toolbarUtil.Toolbar(self.panel)
|
||||
|
||||
@ -392,7 +386,7 @@ class projectPlanner(wx.Frame):
|
||||
|
||||
def OnTopClick(self):
|
||||
self.preview.view3D = False
|
||||
self.preview.zoom = self.machineSize.x / 2 + 10
|
||||
self.preview.zoom = self.machineSize[0] / 2 + 10
|
||||
self.preview.offsetX = 0
|
||||
self.preview.offsetY = 0
|
||||
self.preview.Refresh()
|
||||
@ -499,9 +493,9 @@ class projectPlanner(wx.Frame):
|
||||
self.listbox.SetSelection(-1)
|
||||
|
||||
def OnAutoPlace(self, e):
|
||||
bestAllowedSize = int(self.machineSize.y)
|
||||
bestAllowedSize = int(self.machineSize[1])
|
||||
bestArea = self._doAutoPlace(bestAllowedSize)
|
||||
for i in xrange(10, int(self.machineSize.y), 10):
|
||||
for i in xrange(10, int(self.machineSize[1]), 10):
|
||||
area = self._doAutoPlace(i)
|
||||
if area < bestArea:
|
||||
bestAllowedSize = i
|
||||
@ -516,18 +510,18 @@ class projectPlanner(wx.Frame):
|
||||
extraSizeMax = self.headSizeMax
|
||||
if profile.getProfileSettingFloat('skirt_line_count') > 0:
|
||||
skirtSize = profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')
|
||||
extraSizeMin = extraSizeMin + util3d.Vector3(skirtSize, skirtSize, 0)
|
||||
extraSizeMax = extraSizeMax + util3d.Vector3(skirtSize, skirtSize, 0)
|
||||
extraSizeMin = extraSizeMin + numpy.array([skirtSize, skirtSize, 0])
|
||||
extraSizeMax = extraSizeMax + numpy.array([skirtSize, skirtSize, 0])
|
||||
if profile.getProfileSetting('support') != 'None':
|
||||
extraSizeMin = extraSizeMin + util3d.Vector3(3.0, 0, 0)
|
||||
extraSizeMax = extraSizeMax + util3d.Vector3(3.0, 0, 0)
|
||||
extraSizeMin = extraSizeMin + numpy.array([3.0, 0, 0])
|
||||
extraSizeMax = extraSizeMax + numpy.array([3.0, 0, 0])
|
||||
|
||||
if self.printMode == 1:
|
||||
extraSizeMin = util3d.Vector3(6.0, 6.0, 0)
|
||||
extraSizeMax = util3d.Vector3(6.0, 6.0, 0)
|
||||
extraSizeMin = numpy.array([6.0, 6.0, 0])
|
||||
extraSizeMax = numpy.array([6.0, 6.0, 0])
|
||||
|
||||
if extraSizeMin.x > extraSizeMax.x:
|
||||
posX = self.machineSize.x
|
||||
if extraSizeMin[0] > extraSizeMax[0]:
|
||||
posX = self.machineSize[0]
|
||||
dirX = -1
|
||||
else:
|
||||
posX = 0
|
||||
@ -535,35 +529,35 @@ class projectPlanner(wx.Frame):
|
||||
posY = 0
|
||||
dirY = 1
|
||||
|
||||
minX = self.machineSize.x
|
||||
minY = self.machineSize.y
|
||||
minX = self.machineSize[0]
|
||||
minY = self.machineSize[1]
|
||||
maxX = 0
|
||||
maxY = 0
|
||||
for item in self.list:
|
||||
item.centerX = posX + item.getMaximum().x * item.scale * dirX
|
||||
item.centerY = posY + item.getMaximum().y * item.scale * dirY
|
||||
if item.centerY + item.getSize().y >= allowedSizeY:
|
||||
item.centerX = posX + item.getMaximum()[0] * item.scale * dirX
|
||||
item.centerY = posY + item.getMaximum()[1] * item.scale * dirY
|
||||
if item.centerY + item.getSize()[1] >= allowedSizeY:
|
||||
if dirX < 0:
|
||||
posX = minX - extraSizeMax.x - 1
|
||||
posX = minX - extraSizeMax[0] - 1
|
||||
else:
|
||||
posX = maxX + extraSizeMin.x + 1
|
||||
posX = maxX + extraSizeMin[0] + 1
|
||||
posY = 0
|
||||
item.centerX = posX + item.getMaximum().x * item.scale * dirX
|
||||
item.centerY = posY + item.getMaximum().y * item.scale * dirY
|
||||
posY += item.getSize().y * item.scale * dirY + extraSizeMin.y + 1
|
||||
minX = min(minX, item.centerX - item.getSize().x * item.scale / 2)
|
||||
minY = min(minY, item.centerY - item.getSize().y * item.scale / 2)
|
||||
maxX = max(maxX, item.centerX + item.getSize().x * item.scale / 2)
|
||||
maxY = max(maxY, item.centerY + item.getSize().y * item.scale / 2)
|
||||
item.centerX = posX + item.getMaximum()[0] * item.scale * dirX
|
||||
item.centerY = posY + item.getMaximum()[1] * item.scale * dirY
|
||||
posY += item.getSize()[1] * item.scale * dirY + extraSizeMin[1] + 1
|
||||
minX = min(minX, item.centerX - item.getSize()[0] * item.scale / 2)
|
||||
minY = min(minY, item.centerY - item.getSize()[1] * item.scale / 2)
|
||||
maxX = max(maxX, item.centerX + item.getSize()[0] * item.scale / 2)
|
||||
maxY = max(maxY, item.centerY + item.getSize()[1] * item.scale / 2)
|
||||
|
||||
for item in self.list:
|
||||
if dirX < 0:
|
||||
item.centerX -= minX / 2
|
||||
else:
|
||||
item.centerX += (self.machineSize.x - maxX) / 2
|
||||
item.centerY += (self.machineSize.y - maxY) / 2
|
||||
item.centerX += (self.machineSize[0] - maxX) / 2
|
||||
item.centerY += (self.machineSize[1] - maxY) / 2
|
||||
|
||||
if minX < 0 or maxX > self.machineSize.x:
|
||||
if minX < 0 or maxX > self.machineSize[0]:
|
||||
return ((maxX - minX) + (maxY - minY)) * 100
|
||||
|
||||
return (maxX - minX) + (maxY - minY)
|
||||
@ -590,8 +584,8 @@ class projectPlanner(wx.Frame):
|
||||
for item in self.list:
|
||||
if item.profile != None and os.path.isfile(item.profile):
|
||||
profile.loadGlobalProfile(item.profile)
|
||||
put('machine_center_x', item.centerX - self.extruderOffset[item.extruder].x)
|
||||
put('machine_center_y', item.centerY - self.extruderOffset[item.extruder].y)
|
||||
put('machine_center_x', item.centerX - self.extruderOffset[item.extruder][0])
|
||||
put('machine_center_y', item.centerY - self.extruderOffset[item.extruder][1])
|
||||
put('model_scale', item.scale)
|
||||
put('flip_x', item.flipX)
|
||||
put('flip_y', item.flipY)
|
||||
@ -607,7 +601,7 @@ class projectPlanner(wx.Frame):
|
||||
action.temperature = profile.getProfileSettingFloat('print_temperature')
|
||||
action.extruder = item.extruder
|
||||
action.filename = item.filename
|
||||
clearZ = max(clearZ, item.getMaximum().z * item.scale + 5.0)
|
||||
clearZ = max(clearZ, item.getMaximum()[2] * item.scale + 5.0)
|
||||
action.clearZ = clearZ
|
||||
action.leaveResultForNextSlice = False
|
||||
action.usePreviousSlice = False
|
||||
@ -698,7 +692,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
wx.EVT_MOUSEWHEEL(self, self.OnMouseWheel)
|
||||
self.yaw = 30
|
||||
self.pitch = 60
|
||||
self.zoom = self.parent.machineSize.x / 2 + 10
|
||||
self.zoom = self.parent.machineSize[0] / 2 + 10
|
||||
self.offsetX = 0
|
||||
self.offsetY = 0
|
||||
self.view3D = False
|
||||
@ -760,32 +754,30 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
glTranslate(0,0,-self.zoom)
|
||||
glRotate(-self.pitch, 1,0,0)
|
||||
glRotate(self.yaw, 0,0,1)
|
||||
if False: #self.parent.triangleMesh != None:
|
||||
glTranslate(0,0,-self.parent.triangleMesh.getMaximum().z / 2)
|
||||
else:
|
||||
glScale(1.0/self.zoom, 1.0/self.zoom, 1.0)
|
||||
glTranslate(self.offsetX, self.offsetY, 0.0)
|
||||
glTranslate(-self.parent.machineSize.x/2, -self.parent.machineSize.y/2, 0)
|
||||
glTranslate(-self.parent.machineSize[0]/2, -self.parent.machineSize[1]/2, 0)
|
||||
|
||||
self.OnDraw()
|
||||
self.SwapBuffers()
|
||||
|
||||
def OnDraw(self):
|
||||
machineSize = self.parent.machineSize
|
||||
opengl.DrawMachine(machineSize)
|
||||
opengl.DrawMachine(util3d.Vector3(machineSize[0], machineSize[1], machineSize[2]))
|
||||
extraSizeMin = self.parent.headSizeMin
|
||||
extraSizeMax = self.parent.headSizeMax
|
||||
if profile.getProfileSettingFloat('skirt_line_count') > 0:
|
||||
skirtSize = profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')
|
||||
extraSizeMin = extraSizeMin + util3d.Vector3(skirtSize, skirtSize, 0)
|
||||
extraSizeMax = extraSizeMax + util3d.Vector3(skirtSize, skirtSize, 0)
|
||||
extraSizeMin = extraSizeMin + numpy.array([skirtSize, skirtSize, 0])
|
||||
extraSizeMax = extraSizeMax + numpy.array([skirtSize, skirtSize, 0])
|
||||
if profile.getProfileSetting('support') != 'None':
|
||||
extraSizeMin = extraSizeMin + util3d.Vector3(3.0, 0, 0)
|
||||
extraSizeMax = extraSizeMax + util3d.Vector3(3.0, 0, 0)
|
||||
extraSizeMin = extraSizeMin + numpy.array([3.0, 0, 0])
|
||||
extraSizeMax = extraSizeMax + numpy.array([3.0, 0, 0])
|
||||
|
||||
if self.parent.printMode == 1:
|
||||
extraSizeMin = util3d.Vector3(6.0, 6.0, 0)
|
||||
extraSizeMax = util3d.Vector3(6.0, 6.0, 0)
|
||||
extraSizeMin = numpy.array([6.0, 6.0, 0])
|
||||
extraSizeMax = numpy.array([6.0, 6.0, 0])
|
||||
|
||||
for item in self.parent.list:
|
||||
item.validPlacement = True
|
||||
@ -793,13 +785,13 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
|
||||
for idx1 in xrange(0, len(self.parent.list)):
|
||||
item = self.parent.list[idx1]
|
||||
iMin1 = item.getMinimum() * item.scale + util3d.Vector3(item.centerX, item.centerY, 0) - extraSizeMin - self.parent.extruderOffset[item.extruder]
|
||||
iMax1 = item.getMaximum() * item.scale + util3d.Vector3(item.centerX, item.centerY, 0) + extraSizeMax - self.parent.extruderOffset[item.extruder]
|
||||
iMin1 = (item.getMinimum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) - extraSizeMin - self.parent.extruderOffset[item.extruder]
|
||||
iMax1 = (item.getMaximum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) + extraSizeMax - self.parent.extruderOffset[item.extruder]
|
||||
for idx2 in xrange(0, idx1):
|
||||
item2 = self.parent.list[idx2]
|
||||
iMin2 = item2.getMinimum() * item2.scale + util3d.Vector3(item2.centerX, item2.centerY, 0)
|
||||
iMax2 = item2.getMaximum() * item2.scale + util3d.Vector3(item2.centerX, item2.centerY, 0)
|
||||
if item != item2 and iMax1.x >= iMin2.x and iMin1.x <= iMax2.x and iMax1.y >= iMin2.y and iMin1.y <= iMax2.y:
|
||||
iMin2 = (item2.getMinimum() * item2.scale) + numpy.array([item2.centerX, item2.centerY, 0])
|
||||
iMax2 = (item2.getMaximum() * item2.scale) + numpy.array([item2.centerX, item2.centerY, 0])
|
||||
if item != item2 and iMax1[0] >= iMin2[0] and iMin1[0] <= iMax2[0] and iMax1[1] >= iMin2[1] and iMin1[1] <= iMax2[1]:
|
||||
item.validPlacement = False
|
||||
item2.gotHit = True
|
||||
|
||||
@ -959,8 +951,8 @@ class ProjectSliceProgressWindow(wx.Frame):
|
||||
line = p.stdout.readline()
|
||||
self.returnCode = p.wait()
|
||||
|
||||
put('machine_center_x', action.centerX - self.extruderOffset[action.extruder].x)
|
||||
put('machine_center_y', action.centerY - self.extruderOffset[action.extruder].y)
|
||||
put('machine_center_x', action.centerX - self.extruderOffset[action.extruder][0])
|
||||
put('machine_center_y', action.centerY - self.extruderOffset[action.extruder][1])
|
||||
put('clear_z', action.clearZ)
|
||||
put('extruder', action.extruder)
|
||||
put('print_temperature', action.temperature)
|
||||
@ -1089,8 +1081,8 @@ class preferencesDialog(configBase.configWindowBase):
|
||||
self.Fit()
|
||||
|
||||
def OnClose(self, e):
|
||||
self.parent.headSizeMin = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0)
|
||||
self.parent.headSizeMax = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0)
|
||||
self.parent.headSizeMin = numpy.array([profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0])
|
||||
self.parent.headSizeMax = numpy.array([profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0])
|
||||
self.parent.Refresh()
|
||||
|
||||
self.MakeModal(False)
|
||||
|
@ -2,41 +2,36 @@ import sys, math, re, os, struct, time
|
||||
|
||||
import util3d
|
||||
|
||||
class meshFace(object):
|
||||
def __init__(self, v0, v1, v2):
|
||||
self.v = [v0, v1, v2]
|
||||
import numpy
|
||||
|
||||
class mesh(object):
|
||||
def __init__(self):
|
||||
self.faces = []
|
||||
self.vertexes = []
|
||||
self.vertexes = None
|
||||
self.origonalVertexes = None
|
||||
self.vertexCount = 0
|
||||
|
||||
def addFace(self, v0, v1, v2):
|
||||
self.vertexes.append(v0)
|
||||
self.vertexes.append(v1)
|
||||
self.vertexes.append(v2)
|
||||
self.faces.append(meshFace(v0, v1, v2))
|
||||
def addVertex(self, x, y, z):
|
||||
n = self.vertexCount
|
||||
self.origonalVertexes[n][0] = x
|
||||
self.origonalVertexes[n][1] = y
|
||||
self.origonalVertexes[n][2] = z
|
||||
self.vertexCount += 1
|
||||
|
||||
def _prepareVertexCount(self, vertexNumber):
|
||||
#Set the amount of faces before loading data in them. This way we can create the numpy arrays before we fill them.
|
||||
self.origonalVertexes = numpy.zeros((vertexNumber, 3), float)
|
||||
self.normal = numpy.zeros((vertexNumber / 3, 3))
|
||||
self.vertexCount = 0
|
||||
|
||||
def _postProcessAfterLoad(self):
|
||||
self.origonalVertexes = list(self.vertexes)
|
||||
for i in xrange(0, len(self.origonalVertexes)):
|
||||
self.origonalVertexes[i] = self.origonalVertexes[i].copy()
|
||||
self.vertexes = self.origonalVertexes.copy()
|
||||
self.getMinimumZ()
|
||||
|
||||
def getMinimumZ(self):
|
||||
minv = self.vertexes[0].copy()
|
||||
maxv = self.vertexes[0].copy()
|
||||
for v in self.vertexes:
|
||||
minv.x = min(minv.x, v.x)
|
||||
minv.y = min(minv.y, v.y)
|
||||
minv.z = min(minv.z, v.z)
|
||||
maxv.x = max(maxv.x, v.x)
|
||||
maxv.y = max(maxv.y, v.y)
|
||||
maxv.z = max(maxv.z, v.z)
|
||||
self.min = minv
|
||||
self.max = maxv
|
||||
self.size = maxv - minv
|
||||
return self.min.z
|
||||
self.min = self.vertexes.min(0)
|
||||
self.max = self.vertexes.max(0)
|
||||
self.size = self.max - self.min
|
||||
return self.min[2]
|
||||
|
||||
def getMaximum(self):
|
||||
return self.max
|
||||
@ -62,23 +57,23 @@ class mesh(object):
|
||||
mat11 = math.cos(rotate) * scaleY
|
||||
|
||||
for i in xrange(0, len(self.origonalVertexes)):
|
||||
x = self.origonalVertexes[i].x
|
||||
y = self.origonalVertexes[i].y
|
||||
z = self.origonalVertexes[i].z
|
||||
x = self.origonalVertexes[i][0]
|
||||
y = self.origonalVertexes[i][1]
|
||||
z = self.origonalVertexes[i][2]
|
||||
if swapXZ:
|
||||
x, z = z, x
|
||||
if swapYZ:
|
||||
y, z = z, y
|
||||
self.vertexes[i].x = x * mat00 + y * mat01
|
||||
self.vertexes[i].y = x * mat10 + y * mat11
|
||||
self.vertexes[i].z = z * scaleZ
|
||||
self.vertexes[i][0] = x * mat00 + y * mat01
|
||||
self.vertexes[i][1] = x * mat10 + y * mat11
|
||||
self.vertexes[i][2] = z * scaleZ
|
||||
|
||||
for face in self.faces:
|
||||
v1 = face.v[0]
|
||||
v2 = face.v[1]
|
||||
v3 = face.v[2]
|
||||
face.normal = (v2 - v1).cross(v3 - v1)
|
||||
face.normal.normalize()
|
||||
for i in xrange(0, len(self.origonalVertexes), 3):
|
||||
v1 = self.vertexes[i]
|
||||
v2 = self.vertexes[i+1]
|
||||
v3 = self.vertexes[i+2]
|
||||
self.normal[i/3] = numpy.cross((v2 - v1), (v3 - v1))
|
||||
self.normal[i/3] /= (self.normal[i/3] * self.normal[i/3]).sum()
|
||||
|
||||
self.getMinimumZ()
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import sys, math, re, os, struct, time
|
||||
|
||||
import util3d
|
||||
import mesh
|
||||
|
||||
class stlModel(mesh.mesh):
|
||||
@ -11,7 +10,7 @@ class stlModel(mesh.mesh):
|
||||
f = open(filename, "rb")
|
||||
if f.read(5).lower() == "solid":
|
||||
self._loadAscii(f)
|
||||
if not self.faces:
|
||||
if self.vertexCount < 3:
|
||||
f.seek(5, os.SEEK_SET)
|
||||
self._loadBinary(f)
|
||||
else:
|
||||
@ -22,31 +21,28 @@ class stlModel(mesh.mesh):
|
||||
return self
|
||||
|
||||
def _loadAscii(self, f):
|
||||
cnt = 0
|
||||
for line in f:
|
||||
if 'vertex' in line:
|
||||
cnt += 1
|
||||
self._prepareVertexCount(int(cnt))
|
||||
f.seek(5, os.SEEK_SET)
|
||||
cnt = 0
|
||||
for line in f:
|
||||
if 'vertex' in line:
|
||||
data = line.split()
|
||||
if cnt == 0:
|
||||
v0 = util3d.Vector3(float(data[1]), float(data[2]), float(data[3]))
|
||||
cnt = 1
|
||||
elif cnt == 1:
|
||||
v1 = util3d.Vector3(float(data[1]), float(data[2]), float(data[3]))
|
||||
cnt = 2
|
||||
elif cnt == 2:
|
||||
v2 = util3d.Vector3(float(data[1]), float(data[2]), float(data[3]))
|
||||
self.addFace(v0, v1, v2)
|
||||
cnt = 0
|
||||
self.addVertex(float(data[1]), float(data[2]), float(data[3]))
|
||||
|
||||
def _loadBinary(self, f):
|
||||
#Skip the header
|
||||
f.read(80-5)
|
||||
faceCount = struct.unpack('<I', f.read(4))[0]
|
||||
self._prepareVertexCount(faceCount * 3)
|
||||
for idx in xrange(0, faceCount):
|
||||
data = struct.unpack("<ffffffffffffH", f.read(50))
|
||||
v0 = util3d.Vector3(data[3], data[4], data[5])
|
||||
v1 = util3d.Vector3(data[6], data[7], data[8])
|
||||
v2 = util3d.Vector3(data[9], data[10], data[11])
|
||||
self.addFace(v0, v1, v2)
|
||||
self.addVertex(data[3], data[4], data[5])
|
||||
self.addVertex(data[6], data[7], data[8])
|
||||
self.addVertex(data[9], data[10], data[11])
|
||||
|
||||
def saveAsSTL(mesh, filename):
|
||||
f = open(filename, 'wb')
|
||||
@ -70,8 +66,8 @@ def saveAsSTL(mesh, filename):
|
||||
if __name__ == '__main__':
|
||||
for filename in sys.argv[1:]:
|
||||
m = stlModel().load(filename)
|
||||
print("Loaded %d faces" % (len(m.faces)))
|
||||
parts = m.splitToParts()
|
||||
for p in parts:
|
||||
saveAsSTL(p, "export_%i.stl" % parts.index(p))
|
||||
print("Loaded %d faces" % (m.vertexCount / 3))
|
||||
# parts = m.splitToParts()
|
||||
# for p in parts:
|
||||
# saveAsSTL(p, "export_%i.stl" % parts.index(p))
|
||||
|
||||
|
@ -13,7 +13,7 @@ class Vector3(object):
|
||||
return Vector3(self.x, self.y, self.z)
|
||||
|
||||
def __repr__(self):
|
||||
return '[%s, %s, %s]' % ( self.x, self.y, self.z )
|
||||
return 'V[%s, %s, %s]' % ( self.x, self.y, self.z )
|
||||
|
||||
def __add__(self, v):
|
||||
return Vector3( self.x + v.x, self.y + v.y, self.z + v.z )
|
||||
|
Loading…
x
Reference in New Issue
Block a user