Updated CadQuery library with mirrorX fix for issue #51
This commit is contained in:
parent
e7309e37ed
commit
d299a74b86
|
@ -1261,7 +1261,7 @@ class Workplane(CQ):
|
|||
#attempt to consolidate wires together.
|
||||
consolidated = n.consolidateWires()
|
||||
|
||||
rotatedWires = self.plane.rotateShapes(consolidated.wires().vals(),matrix)
|
||||
rotatedWires = self.plane.rotateShapes(consolidated.wires().vals(), matrix)
|
||||
|
||||
for w in rotatedWires:
|
||||
consolidated.objects.append(w)
|
||||
|
@ -1269,6 +1269,7 @@ class Workplane(CQ):
|
|||
|
||||
#attempt again to consolidate all of the wires
|
||||
c = consolidated.consolidateWires()
|
||||
|
||||
return c
|
||||
|
||||
def mirrorY(self):
|
||||
|
@ -1288,7 +1289,6 @@ class Workplane(CQ):
|
|||
|
||||
Future Enhancements:
|
||||
mirrorX().mirrorY() should work but doesnt, due to some FreeCAD weirdness
|
||||
|
||||
"""
|
||||
tm = Matrix()
|
||||
tm.rotateY(math.pi)
|
||||
|
@ -1307,7 +1307,6 @@ class Workplane(CQ):
|
|||
|
||||
Future Enhancements:
|
||||
mirrorX().mirrorY() should work but doesnt, due to some FreeCAD weirdness
|
||||
|
||||
"""
|
||||
tm = Matrix()
|
||||
tm.rotateX(math.pi)
|
||||
|
@ -1349,11 +1348,9 @@ class Workplane(CQ):
|
|||
If possible, a new object with the results are returned.
|
||||
if not possible, the wires remain separated
|
||||
|
||||
FreeCAD has a bug in Part.Wire([]) which does not create wires/edges properly somtimes
|
||||
Additionally, it has a bug where a profile compose of two wires ( rathre than one )
|
||||
also does not work properly
|
||||
|
||||
together these are a real problem.
|
||||
FreeCAD has a bug in Part.Wire([]) which does not create wires/edges properly sometimes
|
||||
Additionally, it has a bug where a profile compose of two wires ( rather than one )
|
||||
also does not work properly. Together these are a real problem.
|
||||
"""
|
||||
wires = self.wires().vals()
|
||||
if len(wires) < 2:
|
||||
|
@ -2272,11 +2269,48 @@ class Workplane(CQ):
|
|||
return self.union(boxes)
|
||||
|
||||
def sphere(self, radius, direct=(0, 0, 1), angle1=-90, angle2=90, angle3=360, centered=(True, True, True), combine=True):
|
||||
"""
|
||||
Returns a 3D sphere with the specified radius for each point on the stack
|
||||
|
||||
:param radius: The radius of the sphere
|
||||
:type radius: float > 0
|
||||
:param direct: The direction axis for the creation of the sphere
|
||||
:type direct: A three-tuple
|
||||
:param angle1: The first angle to sweep the sphere arc through
|
||||
:type angle1: float > 0
|
||||
:param angle2: The second angle to sweep the sphere arc through
|
||||
:type angle2: float > 0
|
||||
:param angle3: The third angle to sweep the sphere arc through
|
||||
:type angle3: float > 0
|
||||
:param centered: A three-tuple of booleans that determines whether the sphere is centered on each axis origin
|
||||
:param combine: Whether the results should be combined with other solids on the stack (and each other)
|
||||
:type combine: true to combine shapes, false otherwise
|
||||
:return: A sphere object for each point on the stack
|
||||
|
||||
Centered is a tuple that describes whether the sphere should be centered on the x,y, and z axes. If true,
|
||||
the sphere is centered on the respective axis relative to the workplane origin, if false, the workplane center
|
||||
will represent the lower bound of the resulting sphere
|
||||
|
||||
One sphere is created for each item on the current stack. If no items are on the stack, one box using
|
||||
the current workplane center is created.
|
||||
|
||||
If combine is true, the result will be a single object on the stack:
|
||||
If a solid was found in the chain, the result is that solid with all spheres produced fused onto it
|
||||
otherwise, the result is the combination of all the produced boxes
|
||||
|
||||
If combine is false, the result will be a list of the spheres produced
|
||||
"""
|
||||
|
||||
# Convert the direction tuple to a vector, if needed
|
||||
if isinstance(direct, tuple):
|
||||
direct = Vector(direct)
|
||||
|
||||
def _makesphere(pnt):
|
||||
"""
|
||||
Inner function that is used to create a sphere for each point/object on the workplane
|
||||
:param pnt: The center point for the sphere
|
||||
:return: A CQ Solid object representing a sphere
|
||||
"""
|
||||
(xp, yp, zp) = pnt.toTuple()
|
||||
|
||||
if centered[0]:
|
||||
|
@ -2288,6 +2322,7 @@ class Workplane(CQ):
|
|||
|
||||
return Solid.makeSphere(radius, Vector(xp, yp, zp), direct, angle1, angle2, angle3)
|
||||
|
||||
# We want a sphere for each point on the workplane
|
||||
spheres = self.eachpoint(_makesphere, True)
|
||||
|
||||
# If we don't need to combine everything, just return the created spheres
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
License along with this library; If not, see <http://www.gnu.org/licenses/>
|
||||
"""
|
||||
|
||||
import math,sys
|
||||
import math
|
||||
import cadquery
|
||||
import FreeCAD
|
||||
#Turns out we don't need the Part module here.
|
||||
import Part as FreeCADPart
|
||||
|
||||
def sortWiresByBuildOrder(wireList,plane,result=[]):
|
||||
"""
|
||||
|
@ -403,9 +404,9 @@ class Plane:
|
|||
correctly.
|
||||
|
||||
"""
|
||||
if isinstance(obj,Vector):
|
||||
if isinstance(obj, Vector):
|
||||
return Vector(self.fG.multiply(obj.wrapped))
|
||||
elif isinstance(obj,Shape):
|
||||
elif isinstance(obj, cadquery.Shape):
|
||||
return obj.transformShape(self.rG)
|
||||
else:
|
||||
raise ValueError("Dont know how to convert type %s to local coordinates" % str(type(obj)))
|
||||
|
@ -464,7 +465,7 @@ class Plane:
|
|||
newP= Plane(self.origin,newXdir,newZdir)
|
||||
return newP
|
||||
|
||||
def rotateShapes(self,listOfShapes,rotationMatrix):
|
||||
def rotateShapes(self, listOfShapes, rotationMatrix):
|
||||
"""
|
||||
rotate the listOfShapes by the rotationMatrix supplied.
|
||||
@param listOfShapes is a list of shape objects
|
||||
|
@ -480,24 +481,42 @@ class Plane:
|
|||
#There might be a better way, but to do this rotation takes 3 steps
|
||||
#transform geometry to local coordinates
|
||||
#then rotate about x
|
||||
#then transform back to global coordiante
|
||||
#then transform back to global coordinates
|
||||
|
||||
resultWires = []
|
||||
for w in listOfShapes:
|
||||
mirrored = w.transformGeometry(rotationMatrix.wrapped)
|
||||
resultWires.append(mirrored)
|
||||
|
||||
# If the first vertex of the second wire is not coincident with the first or last vertices of the first wire
|
||||
# we have to fix the wire so that it will mirror correctly
|
||||
if (mirrored.wrapped.Vertexes[0].X == w.wrapped.Vertexes[0].X and
|
||||
mirrored.wrapped.Vertexes[0].Y == w.wrapped.Vertexes[0].Y and
|
||||
mirrored.wrapped.Vertexes[0].Z == w.wrapped.Vertexes[0].Z) or \
|
||||
(mirrored.wrapped.Vertexes[0].X == w.wrapped.Vertexes[-1].X and
|
||||
mirrored.wrapped.Vertexes[0].Y == w.wrapped.Vertexes[-1].Y and
|
||||
mirrored.wrapped.Vertexes[0].Z == w.wrapped.Vertexes[-1].Z):
|
||||
|
||||
resultWires.append(mirrored)
|
||||
else:
|
||||
# Make sure that our mirrored edges meet up and are ordered properly
|
||||
aEdges = w.wrapped.Edges
|
||||
aEdges.extend(mirrored.wrapped.Edges)
|
||||
comp = FreeCADPart.Compound(aEdges)
|
||||
mirroredWire = comp.connectEdgesToWires(False).Wires[0]
|
||||
|
||||
resultWires.append(cadquery.Shape.cast(mirroredWire))
|
||||
|
||||
return resultWires
|
||||
|
||||
|
||||
def _calcTransforms(self):
|
||||
"""
|
||||
Computes transformation martrices to convert betwene local and global coordinates
|
||||
Computes transformation martrices to convert between local and global coordinates
|
||||
"""
|
||||
#r is the forward transformation matrix from world to local coordinates
|
||||
#ok i will be really honest-- i cannot understand exactly why this works
|
||||
#something bout the order of the transaltion and the rotation.
|
||||
# the double-inverting is strange, and i dont understand it.
|
||||
#something bout the order of the translation and the rotation.
|
||||
# the double-inverting is strange, and I don't understand it.
|
||||
r = FreeCAD.Base.Matrix()
|
||||
|
||||
#forward transform must rotate and adjust for origin
|
||||
|
|
Loading…
Reference in New Issue
Block a user