Merge pull request #106 from CadQuery/adam-urbanczyk-text-rendering
Support for text rendering
This commit is contained in:
@ -2268,6 +2268,20 @@ class Workplane(CQ):
|
||||
r = baseSolid.fuse(obj)
|
||||
|
||||
return self.newObject([r])
|
||||
|
||||
def _cutFromBase(self, obj):
|
||||
"""
|
||||
Cuts the provided object from the base solid, if one can be found.
|
||||
:param obj:
|
||||
:return: a new object that represents the result of combining the base object with obj,
|
||||
or obj if one could not be found
|
||||
"""
|
||||
baseSolid = self.findSolid(searchParents=True)
|
||||
r = obj
|
||||
if baseSolid is not None:
|
||||
r = baseSolid.cut(obj)
|
||||
|
||||
return self.newObject([r])
|
||||
|
||||
def combine(self, clean=True):
|
||||
"""
|
||||
@ -2770,6 +2784,45 @@ class Workplane(CQ):
|
||||
raise AttributeError(
|
||||
"%s object doesn't support `clean()` method!" % obj.ShapeType())
|
||||
return self.newObject(cleanObjects)
|
||||
|
||||
def text(self, txt, fontsize, distance, cut=True, combine=False, clean=True,
|
||||
font="Arial", kind='regular'):
|
||||
"""
|
||||
Create a 3D text
|
||||
|
||||
:param str txt: text to be rendered
|
||||
:param distance: the distance to extrude, normal to the workplane plane
|
||||
:type distance: float, negative means opposite the normal direction
|
||||
:param float fontsize: size of the font
|
||||
:param boolean cut: True to cut the resulting solid from the parent solids if found.
|
||||
:param boolean combine: True to combine the resulting solid with parent solids if found.
|
||||
:param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
|
||||
:param str font: fontname (default: Arial)
|
||||
:param str kind: font type (default: Normal)
|
||||
:return: a CQ object with the resulting solid selected.
|
||||
|
||||
extrude always *adds* material to a part.
|
||||
|
||||
The returned object is always a CQ object, and depends on wither combine is True, and
|
||||
whether a context solid is already defined:
|
||||
|
||||
* if combine is False, the new value is pushed onto the stack.
|
||||
* if combine is true, the value is combined with the context solid if it exists,
|
||||
and the resulting solid becomes the new context solid.
|
||||
|
||||
"""
|
||||
r = Compound.makeText(txt,fontsize,distance,font=font,kind=kind,
|
||||
position=self.plane)
|
||||
|
||||
if cut:
|
||||
newS = self._cutFromBase(r)
|
||||
elif combine:
|
||||
newS = self._combineWithBase(r)
|
||||
else:
|
||||
newS = self.newObject([r])
|
||||
if clean:
|
||||
newS = newS.clean()
|
||||
return newS
|
||||
|
||||
def _repr_html_(self):
|
||||
"""
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from cadquery import Vector, BoundBox
|
||||
from cadquery import Vector, BoundBox, Plane
|
||||
|
||||
import OCC.Core.TopAbs as ta # Tolopolgy type enum
|
||||
import OCC.Core.GeomAbs as ga # Geometry type enum
|
||||
@ -106,6 +106,11 @@ from OCC.LocOpe import LocOpe_DPrism
|
||||
|
||||
from OCC.BRepCheck import BRepCheck_Analyzer
|
||||
|
||||
from OCC.Core.Addons import (text_to_brep,
|
||||
Font_FA_Regular,
|
||||
Font_FA_Italic,
|
||||
Font_FA_Bold)
|
||||
|
||||
from math import pi, sqrt
|
||||
|
||||
TOLERANCE = 1e-6
|
||||
@ -1451,6 +1456,24 @@ class Compound(Shape, Mixin3D):
|
||||
comp_builder.Add(comp, s.wrapped)
|
||||
|
||||
return cls(comp)
|
||||
|
||||
@classmethod
|
||||
def makeText(cls, text, size, height, font="Arial", kind='regular',
|
||||
position=Plane.XY()):
|
||||
"""
|
||||
Create a 3D text
|
||||
"""
|
||||
|
||||
font_kind = {'regular' : Font_FA_Regular,
|
||||
'bold' : Font_FA_Bold,
|
||||
'italic' : Font_FA_Italic}[kind]
|
||||
|
||||
text_flat = Shape(text_to_brep(text, font, font_kind, size, False))
|
||||
vecNormal = text_flat.Faces()[0].normalAt()*height
|
||||
|
||||
text_3d = BRepPrimAPI_MakePrism(text_flat.wrapped, vecNormal.wrapped)
|
||||
|
||||
return cls(text_3d.Shape()).transformShape(position.rG)
|
||||
|
||||
# TODO this is likely not needed if sing PythonOCC.Core.correclty but we will see
|
||||
|
||||
|
||||
@ -1800,3 +1800,27 @@ class TestCadQuery(BaseTest):
|
||||
|
||||
# The obj1 shape shall have the same volume as the obj2 shape.
|
||||
self.assertAlmostEqual(obj1.val().Volume(), obj2.val().Volume())
|
||||
|
||||
def testText(self):
|
||||
|
||||
box = Workplane("XY" ).box(4, 4, 0.5)
|
||||
|
||||
obj1 = box.faces('>Z').workplane().text('CQ 2.0',0.5,-.05,cut=True)
|
||||
|
||||
#combined object should have smaller volume
|
||||
self.assertGreater(box.val().Volume(),obj1.val().Volume())
|
||||
|
||||
obj2 = box.faces('>Z').workplane()\
|
||||
.text('CQ 2.0',0.5,.05,cut=False,combine=True)
|
||||
|
||||
#combined object should have bigger volume
|
||||
self.assertLess(box.val().Volume(),obj2.val().Volume())
|
||||
|
||||
#verify that the number of top faces is correct (NB: this is font specific)
|
||||
self.assertEqual(len(obj2.faces('>Z').vals()),5)
|
||||
|
||||
obj3 = box.faces('>Z').workplane()\
|
||||
.text('CQ 2.0',0.5,.05,cut=False,combine=False)
|
||||
|
||||
#verify that the number of solids is correct
|
||||
self.assertEqual(len(obj3.solids().vals()),5)
|
||||
Reference in New Issue
Block a user