mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-06 22:47:29 -06:00
Fix for the Extrusion node, the trickiest geometry of them all
This commit is contained in:
parent
43de0e1c06
commit
db5d238898
1 changed files with 13 additions and 13 deletions
|
@ -26,10 +26,12 @@ class X3DReader(MeshReader):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._supported_extensions = [".x3d"]
|
self._supported_extensions = [".x3d"]
|
||||||
self._namespaces = {}
|
self._namespaces = {}
|
||||||
self.defs = {}
|
|
||||||
|
# Main entry point
|
||||||
|
# Reads the file, returns a SceneNode (possibly with nested ones), or None
|
||||||
def read(self, file_name):
|
def read(self, file_name):
|
||||||
try:
|
try:
|
||||||
|
self.defs = {}
|
||||||
self.sceneNodes = []
|
self.sceneNodes = []
|
||||||
self.fileName = file_name
|
self.fileName = file_name
|
||||||
|
|
||||||
|
@ -39,7 +41,7 @@ class X3DReader(MeshReader):
|
||||||
if root.tag != "X3D":
|
if root.tag != "X3D":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
scale = 1000 # Default X3D unit it one meter, while Cura's is one mm
|
scale = 1000 # Default X3D unit it one meter, while Cura's is one millimeters
|
||||||
if root[0].tag == "head":
|
if root[0].tag == "head":
|
||||||
for headNode in root[0]:
|
for headNode in root[0]:
|
||||||
if headNode.tag == "unit" and headNode.attrib.get("category") == "length":
|
if headNode.tag == "unit" and headNode.attrib.get("category") == "length":
|
||||||
|
@ -53,9 +55,9 @@ class X3DReader(MeshReader):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
self.transform = Matrix()
|
self.transform = Matrix()
|
||||||
self.transform.setByScaleVector(Vector(scale, scale, scale))
|
self.transform.setByScaleFactor(scale)
|
||||||
|
|
||||||
# This will populate the sceneNodes array
|
# Traverse the scene tree, populate the sceneNodes array
|
||||||
self.processChildNodes(scene)
|
self.processChildNodes(scene)
|
||||||
|
|
||||||
if len(self.sceneNodes) > 1:
|
if len(self.sceneNodes) > 1:
|
||||||
|
@ -132,7 +134,8 @@ class X3DReader(MeshReader):
|
||||||
# Returns the referenced node if the node has USE, the same node otherwise.
|
# Returns the referenced node if the node has USE, the same node otherwise.
|
||||||
# May return None is USE points at a nonexistent node
|
# May return None is USE points at a nonexistent node
|
||||||
# In X3DOM, when both DEF and USE are in the same node, DEF is ignored.
|
# In X3DOM, when both DEF and USE are in the same node, DEF is ignored.
|
||||||
# Big caveat: XML node objects may evaluate to boolean False!!!
|
# Big caveat: XML element objects may evaluate to boolean False!!!
|
||||||
|
# Don't ever use "if node:", use "if not node is None:" instead
|
||||||
def resolveDefUse(self, node):
|
def resolveDefUse(self, node):
|
||||||
USE = node.attrib.get("USE")
|
USE = node.attrib.get("USE")
|
||||||
if USE:
|
if USE:
|
||||||
|
@ -210,12 +213,10 @@ class X3DReader(MeshReader):
|
||||||
else:
|
else:
|
||||||
nr = ns = DEFAULT_SUBDIV
|
nr = ns = DEFAULT_SUBDIV
|
||||||
|
|
||||||
|
|
||||||
lau = pi / nr # Unit angle of latitude (rings) for the given tesselation
|
lau = pi / nr # Unit angle of latitude (rings) for the given tesselation
|
||||||
lou = 2 * pi / ns # Unit angle of longitude (segments)
|
lou = 2 * pi / ns # Unit angle of longitude (segments)
|
||||||
|
|
||||||
bui.reserveFaceAndVertexCount(ns*(nr*2 - 2), 2 + (nr + 1)*ns)
|
bui.reserveFaceAndVertexCount(ns*(nr*2 - 2), 2 + (nr + 1)*ns)
|
||||||
|
|
||||||
|
|
||||||
# +y and -y poles
|
# +y and -y poles
|
||||||
bui.addVertex(0, r, 0)
|
bui.addVertex(0, r, 0)
|
||||||
|
@ -434,13 +435,13 @@ class X3DReader(MeshReader):
|
||||||
z = z.normalized()
|
z = z.normalized()
|
||||||
y = y.normalized()
|
y = y.normalized()
|
||||||
x = y.cross(z) # Already normalized
|
x = y.cross(z) # Already normalized
|
||||||
m = numpy.array((x.getData(), y.getData(), z.getData()))
|
m = numpy.array(((x.x, y.x, z.x), (x.y, y.y, z.y), (x.z, y.z, z.z)))
|
||||||
|
|
||||||
# Columns are the unit vectors for the xz plane for the cross-section
|
# Columns are the unit vectors for the xz plane for the cross-section
|
||||||
if orient:
|
if orient:
|
||||||
mrot = orient[i] if len(orient) > 1 else orient[0]
|
mrot = orient[i] if len(orient) > 1 else orient[0]
|
||||||
if not mrot is None:
|
if not mrot is None:
|
||||||
m = m.dot(mrot) # Not sure about this. Counterexample???
|
m = m.dot(mrot) # Tested against X3DOM, the result matches, still not sure :(
|
||||||
|
|
||||||
if scale:
|
if scale:
|
||||||
mscale = scale[i] if len(scale) > 1 else scale[0]
|
mscale = scale[i] if len(scale) > 1 else scale[0]
|
||||||
|
@ -451,10 +452,10 @@ class X3DReader(MeshReader):
|
||||||
# then rotated (which may make it a 3-vector),
|
# then rotated (which may make it a 3-vector),
|
||||||
# then applied to the xz plane unit vectors
|
# then applied to the xz plane unit vectors
|
||||||
|
|
||||||
|
sptv3 = numpy.array(spt.getData()[:3])
|
||||||
for cpt in cross:
|
for cpt in cross:
|
||||||
v = numpy.array(spt.getData()[:3]) + m.dot(cpt)
|
v = sptv3 + m.dot(cpt)
|
||||||
bui.addVertex(*v)
|
bui.addVertex(*v)
|
||||||
# Could've done this with a single 4x4 matrix... Oh well
|
|
||||||
|
|
||||||
if beginCap:
|
if beginCap:
|
||||||
addFace(bui, [x for x in range(nc - 1, -1, -1)], ccw)
|
addFace(bui, [x for x in range(nc - 1, -1, -1)], ccw)
|
||||||
|
@ -521,7 +522,6 @@ class X3DReader(MeshReader):
|
||||||
for fan in fans:
|
for fan in fans:
|
||||||
for i in range(1, len(fan) - 1):
|
for i in range(1, len(fan) - 1):
|
||||||
addTriFlip(bui, fan[0], fan[i], fan[i+1], ccw)
|
addTriFlip(bui, fan[0], fan[i], fan[i+1], ccw)
|
||||||
|
|
||||||
|
|
||||||
def geomTriangleSet(self, node, bui):
|
def geomTriangleSet(self, node, bui):
|
||||||
ccw = self.startCoordMesh(node, bui, lambda coord: len(coord) // 3)
|
ccw = self.startCoordMesh(node, bui, lambda coord: len(coord) // 3)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue