commit
43c593e76f
|
@ -19,7 +19,6 @@ p_boreDiameter = 8.0 # Diameter of the counterbore hole, if any
|
||||||
p_boreDepth = 1.0 # Depth of the counterbore hole, if
|
p_boreDepth = 1.0 # Depth of the counterbore hole, if
|
||||||
p_countersinkDiameter = 0.0 # Outer diameter of countersink. Should roughly match the outer diameter of the screw head
|
p_countersinkDiameter = 0.0 # Outer diameter of countersink. Should roughly match the outer diameter of the screw head
|
||||||
p_countersinkAngle = 90.0 # Countersink angle (complete angle between opposite sides, not from center to one side)
|
p_countersinkAngle = 90.0 # Countersink angle (complete angle between opposite sides, not from center to one side)
|
||||||
p_flipLid = True # Whether to place the lid with the top facing down or not.
|
|
||||||
p_lipHeight = 1.0 # Height of lip on the underside of the lid. Sits inside the box body for a snug fit.
|
p_lipHeight = 1.0 # Height of lip on the underside of the lid. Sits inside the box body for a snug fit.
|
||||||
|
|
||||||
# Outer shell
|
# Outer shell
|
||||||
|
@ -73,10 +72,6 @@ elif p_countersinkDiameter > 0 and p_countersinkAngle > 0:
|
||||||
else:
|
else:
|
||||||
topOfLid= topOfLidCenters.hole(p_screwpostID, 2.0 * p_thickness)
|
topOfLid= topOfLidCenters.hole(p_screwpostID, 2.0 * p_thickness)
|
||||||
|
|
||||||
# Flip lid upside down if desired
|
|
||||||
if p_flipLid:
|
|
||||||
topOfLid.rotateAboutCenter((1, 0, 0), 180)
|
|
||||||
|
|
||||||
# Return the combined result
|
# Return the combined result
|
||||||
result = topOfLid.combineSolids(bottom)
|
result = topOfLid.combineSolids(bottom)
|
||||||
|
|
||||||
|
|
26
CadQuery/Examples/Ex028_Numpy.py
Normal file
26
CadQuery/Examples/Ex028_Numpy.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# This example is meant to be used from within the CadQuery module of FreeCAD.
|
||||||
|
import numpy as np
|
||||||
|
import cadquery
|
||||||
|
from Helpers import show
|
||||||
|
|
||||||
|
# Square side and offset in x and y.
|
||||||
|
side = 10
|
||||||
|
offset = 5
|
||||||
|
|
||||||
|
# Define the locations that the polyline will be drawn to/thru.
|
||||||
|
# The polyline is defined as numpy.array so that operations like translation
|
||||||
|
# of all points are simplified.
|
||||||
|
pts = np.array([
|
||||||
|
(0, 0),
|
||||||
|
(side, 0),
|
||||||
|
(side, side),
|
||||||
|
(0, side),
|
||||||
|
(0, 0),
|
||||||
|
]) + [offset, offset]
|
||||||
|
|
||||||
|
result = cadquery.Workplane('XY') \
|
||||||
|
.polyline(pts).extrude(2) \
|
||||||
|
.faces('+Z').workplane().circle(side / 2).extrude(1)
|
||||||
|
|
||||||
|
# Render the solid
|
||||||
|
show(result)
|
183
CadQuery/Examples/Ex029_Braille.py
Normal file
183
CadQuery/Examples/Ex029_Braille.py
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import unicode_literals, division
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
import cadquery as cq
|
||||||
|
from Helpers import show
|
||||||
|
|
||||||
|
# text_lines is a list of text lines.
|
||||||
|
# FreeCAD in braille (converted with braille-converter:
|
||||||
|
# https://github.com/jpaugh/braille-converter.git).
|
||||||
|
text_lines = ['⠠ ⠋ ⠗ ⠑ ⠑ ⠠ ⠉ ⠠ ⠁ ⠠ ⠙']
|
||||||
|
# See http://www.tiresias.org/research/reports/braille_cell.htm for examples
|
||||||
|
# of braille cell geometry.
|
||||||
|
horizontal_interdot = 2.5
|
||||||
|
vertical_interdot = 2.5
|
||||||
|
horizontal_intercell = 6
|
||||||
|
vertical_interline = 10
|
||||||
|
dot_height = 0.5
|
||||||
|
dot_diameter = 1.3
|
||||||
|
|
||||||
|
base_thickness = 1.5
|
||||||
|
|
||||||
|
# End of configuration.
|
||||||
|
BrailleCellGeometry = namedtuple('BrailleCellGeometry',
|
||||||
|
('horizontal_interdot',
|
||||||
|
'vertical_interdot',
|
||||||
|
'intercell',
|
||||||
|
'interline',
|
||||||
|
'dot_height',
|
||||||
|
'dot_diameter'))
|
||||||
|
|
||||||
|
|
||||||
|
class Point(object):
|
||||||
|
def __init__(self, x, y):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
return Point(self.x + other.x, self.y + other.y)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return 2
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
return (self.x, self.y)[index]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '({}, {})'.format(self.x, self.y)
|
||||||
|
|
||||||
|
|
||||||
|
def brailleToPoints(text, cell_geometry):
|
||||||
|
# Unicode bit pattern (cf. https://en.wikipedia.org/wiki/Braille_Patterns).
|
||||||
|
mask1 = 0b00000001
|
||||||
|
mask2 = 0b00000010
|
||||||
|
mask3 = 0b00000100
|
||||||
|
mask4 = 0b00001000
|
||||||
|
mask5 = 0b00010000
|
||||||
|
mask6 = 0b00100000
|
||||||
|
mask7 = 0b01000000
|
||||||
|
mask8 = 0b10000000
|
||||||
|
masks = (mask1, mask2, mask3, mask4, mask5, mask6, mask7, mask8)
|
||||||
|
|
||||||
|
# Corresponding dot position
|
||||||
|
w = cell_geometry.horizontal_interdot
|
||||||
|
h = cell_geometry.vertical_interdot
|
||||||
|
pos1 = Point(0, 2 * h)
|
||||||
|
pos2 = Point(0, h)
|
||||||
|
pos3 = Point(0, 0)
|
||||||
|
pos4 = Point(w, 2 * h)
|
||||||
|
pos5 = Point(w, h)
|
||||||
|
pos6 = Point(w, 0)
|
||||||
|
pos7 = Point(0, -h)
|
||||||
|
pos8 = Point(w, -h)
|
||||||
|
pos = (pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8)
|
||||||
|
|
||||||
|
# Braille blank pattern (u'\u2800').
|
||||||
|
blank = '⠀'
|
||||||
|
points = []
|
||||||
|
# Position of dot1 along the x-axis (horizontal).
|
||||||
|
character_origin = 0
|
||||||
|
for c in text:
|
||||||
|
for m, p in zip(masks, pos):
|
||||||
|
delta_to_blank = ord(c) - ord(blank)
|
||||||
|
if (m & delta_to_blank):
|
||||||
|
points.append(p + Point(character_origin, 0))
|
||||||
|
character_origin += cell_geometry.intercell
|
||||||
|
return points
|
||||||
|
|
||||||
|
|
||||||
|
def get_plate_height(text_lines, cell_geometry):
|
||||||
|
# cell_geometry.vertical_interdot is also used as space between base
|
||||||
|
# borders and characters.
|
||||||
|
return (2 * cell_geometry.vertical_interdot +
|
||||||
|
2 * cell_geometry.vertical_interdot +
|
||||||
|
(len(text_lines) - 1) * cell_geometry.interline)
|
||||||
|
|
||||||
|
|
||||||
|
def get_plate_width(text_lines, cell_geometry):
|
||||||
|
# cell_geometry.horizontal_interdot is also used as space between base
|
||||||
|
# borders and characters.
|
||||||
|
max_len = max([len(t) for t in text_lines])
|
||||||
|
return (2 * cell_geometry.horizontal_interdot +
|
||||||
|
cell_geometry.horizontal_interdot +
|
||||||
|
(max_len - 1) * cell_geometry.intercell)
|
||||||
|
|
||||||
|
|
||||||
|
def get_cylinder_radius(cell_geometry):
|
||||||
|
"""Return the radius the cylinder should have
|
||||||
|
|
||||||
|
The cylinder have the same radius as the half-sphere make the dots (the
|
||||||
|
hidden and the shown part of the dots).
|
||||||
|
The radius is such that the spherical cap with diameter
|
||||||
|
cell_geometry.dot_diameter has a height of cell_geometry.dot_height.
|
||||||
|
"""
|
||||||
|
h = cell_geometry.dot_height
|
||||||
|
r = cell_geometry.dot_diameter / 2
|
||||||
|
return (r ** 2 + h ** 2) / 2 / h
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_plate_thickness(plate_thickness, cell_geometry):
|
||||||
|
"""Return the height on which the half spheres will sit"""
|
||||||
|
return (plate_thickness +
|
||||||
|
get_cylinder_radius(cell_geometry) -
|
||||||
|
cell_geometry.dot_height)
|
||||||
|
|
||||||
|
|
||||||
|
def make_base(text_lines, cell_geometry, plate_thickness):
|
||||||
|
base_width = get_plate_width(text_lines, cell_geometry)
|
||||||
|
base_height = get_plate_height(text_lines, cell_geometry)
|
||||||
|
base_thickness = get_base_plate_thickness(plate_thickness, cell_geometry)
|
||||||
|
base = cq.Workplane('XY').box(base_width, base_height, base_thickness,
|
||||||
|
centered=(False, False, False))
|
||||||
|
return base
|
||||||
|
|
||||||
|
|
||||||
|
def make_embossed_plate(text_lines, cell_geometry):
|
||||||
|
"""Make an embossed plate with dots as spherical caps
|
||||||
|
|
||||||
|
Method:
|
||||||
|
- make a thin plate on which sit cylinders
|
||||||
|
- fillet the upper edge of the cylinders so to get pseudo half-spheres
|
||||||
|
- make the union with a thicker plate so that only the sphere caps stay
|
||||||
|
"visible".
|
||||||
|
"""
|
||||||
|
base = make_base(text_lines, cell_geometry, base_thickness)
|
||||||
|
|
||||||
|
dot_pos = []
|
||||||
|
base_width = get_plate_width(text_lines, cell_geometry)
|
||||||
|
base_height = get_plate_height(text_lines, cell_geometry)
|
||||||
|
y = base_height - 3 * cell_geometry.vertical_interdot
|
||||||
|
line_start_pos = Point(cell_geometry.horizontal_interdot, y)
|
||||||
|
for text in text_lines:
|
||||||
|
dots = brailleToPoints(text, cell_geometry)
|
||||||
|
dots = [p + line_start_pos for p in dots]
|
||||||
|
dot_pos += dots
|
||||||
|
line_start_pos += Point(0, -cell_geometry.interline)
|
||||||
|
|
||||||
|
r = get_cylinder_radius(cell_geometry)
|
||||||
|
base = base.faces('>Z').vertices('<XY').workplane() \
|
||||||
|
.pushPoints(dot_pos).circle(r) \
|
||||||
|
.extrude(r)
|
||||||
|
# Make a fillet almost the same radius to get a pseudo spherical cap.
|
||||||
|
base = base.faces('>Z').edges() \
|
||||||
|
.fillet(r - 0.001)
|
||||||
|
hidding_box = cq.Workplane('XY').box(
|
||||||
|
base_width, base_height, base_thickness, centered=(False, False, False))
|
||||||
|
result = hidding_box.union(base)
|
||||||
|
return result
|
||||||
|
|
||||||
|
_cell_geometry = BrailleCellGeometry(
|
||||||
|
horizontal_interdot,
|
||||||
|
vertical_interdot,
|
||||||
|
horizontal_intercell,
|
||||||
|
vertical_interline,
|
||||||
|
dot_height,
|
||||||
|
dot_diameter)
|
||||||
|
|
||||||
|
if base_thickness < get_cylinder_radius(_cell_geometry):
|
||||||
|
raise ValueError('Base thickness should be at least {}'.format(dot_height))
|
||||||
|
|
||||||
|
show(make_embossed_plate(text_lines, _cell_geometry))
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
"""Adds all of the commands that are used for the menus of the CadQuery module"""
|
"""Adds all of the commands that are used for the menus of the CadQuery module"""
|
||||||
# (c) 2014-2015 Jeremy Wright LGPL v3
|
# (c) 2014-2015 Jeremy Wright LGPL v3
|
||||||
|
|
||||||
|
@ -160,7 +161,7 @@ class CadQueryExecuteScript:
|
||||||
|
|
||||||
#Save our code to a tempfile and render it
|
#Save our code to a tempfile and render it
|
||||||
tempFile = tempfile.NamedTemporaryFile(delete=False)
|
tempFile = tempfile.NamedTemporaryFile(delete=False)
|
||||||
tempFile.write(cqCodePane.toPlainText())
|
tempFile.write(cqCodePane.toPlainText().encode('utf-8'))
|
||||||
tempFile.close()
|
tempFile.close()
|
||||||
FreeCAD.Console.PrintMessage("\r\n")
|
FreeCAD.Console.PrintMessage("\r\n")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user