Import: Support DXF text rotation (#11001)

* Import: Support DXF text rotation - fixes #10882

- Reads and supports text rotation in builtin DXF import
- Makes the builtin DXF import produce Draft texts instead of App::Annotations
- Extends the arguments of Draft make_text()

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Yorik van Havre
2023-10-11 17:05:31 +02:00
committed by GitHub
parent fbc447ad4b
commit 55292e9041
5 changed files with 48 additions and 31 deletions

View File

@@ -41,7 +41,7 @@ if App.GuiUp:
from draftviewproviders.view_text import ViewProviderText
def make_text(string, placement=None, screen=False):
def make_text(string, placement=None, screen=False, height=None):
"""Create a Text object containing the given list of strings.
The current color and text height and font specified in preferences
@@ -66,6 +66,9 @@ def make_text(string, placement=None, screen=False):
If it is `True`, the text will always face perpendicularly
to the camera direction, that is, it will be flat on the screen.
height: float, optional
A height value for the text, in mm
Returns
-------
App::FeaturePython
@@ -122,15 +125,16 @@ def make_text(string, placement=None, screen=False):
if App.GuiUp:
ViewProviderText(new_obj.ViewObject)
h = utils.get_param("textheight", 2)
if not height: # zero or None
height = utils.get_param("textheight", 2)
new_obj.ViewObject.DisplayMode = "World"
if screen:
_msg("screen: {}".format(screen))
new_obj.ViewObject.DisplayMode = "Screen"
h = h * 10
height *= 10
new_obj.ViewObject.FontSize = h
new_obj.ViewObject.FontSize = height
new_obj.ViewObject.FontName = utils.get_param("textfont", "")
new_obj.ViewObject.LineSpacing = 1

View File

@@ -316,17 +316,21 @@ void ImpExpDxfRead::OnReadEllipse(const double* c,
}
void ImpExpDxfRead::OnReadText(const double* point, const double /*height*/, const char* text)
void ImpExpDxfRead::OnReadText(const double* point,
const double height,
const char* text,
const double rotation)
{
if (optionImportAnnotations) {
Base::Vector3d pt(point[0] * optionScaling,
point[1] * optionScaling,
point[2] * optionScaling);
if (LayerName().substr(0, 6) != "BLOCKS") {
App::Annotation* pcFeature =
static_cast<App::Annotation*>(document->addObject("App::Annotation", "Text"));
pcFeature->LabelText.setValue(Deformat(text));
pcFeature->Position.setValue(pt);
Base::Interpreter().runString("import Draft");
Base::Interpreter().runStringArg("p=FreeCAD.Vector(%f,%f,%f)",
point[0] * optionScaling,
point[1] * optionScaling,
point[2] * optionScaling);
Base::Interpreter().runString("a=FreeCAD.Vector(0,0,1)");
Base::Interpreter().runStringArg("pl=FreeCAD.Placement(p,a,%f)", rotation);
Base::Interpreter().runStringArg("Draft.make_text(\"%s\",pl, height=%f)", text, height);
}
// else std::cout << "skipped text in block: " << LayerName() << std::endl;
}

View File

@@ -43,7 +43,10 @@ public:
// CDxfRead's virtual functions
void OnReadLine(const double* s, const double* e, bool hidden) override;
void OnReadPoint(const double* s) override;
void OnReadText(const double* point, const double height, const char* text) override;
void OnReadText(const double* point,
const double height,
const char* text,
const double rotation) override;
void
OnReadArc(const double* s, const double* e, const double* c, bool dir, bool hidden) override;
void OnReadCircle(const double* s, const double* c, bool dir, bool hidden) override;

View File

@@ -2653,6 +2653,7 @@ bool CDxfRead::ReadText()
{
double c[3]; // coordinate
double height = 0.03082;
double rotation = 0.0;
std::string textPrefix;
memset(c, 0, sizeof(c));
@@ -2668,7 +2669,15 @@ bool CDxfRead::ReadText()
ss.imbue(std::locale("C"));
switch (n) {
case 0:
return false;
ResolveColorIndex();
{
const char* utfStr = (this->*stringToUTF8)(textPrefix.c_str());
OnReadText(c, height * 25.4 / 72.0, utfStr, rotation);
if (utfStr == m_str) {
delete utfStr;
}
}
return true;
case 8: // Layer name follows
get_line();
strcpy(m_layer_name, m_str);
@@ -2714,6 +2723,15 @@ bool CDxfRead::ReadText()
return false;
}
break;
case 50:
// text rotation
get_line();
ss.str(m_str);
ss >> rotation;
if (ss.fail()) {
return false;
}
break;
case 3:
// Additional text that goes before the type 1 text
// Note that if breaking the text into type-3 records splits a UFT-8 encoding we do
@@ -2724,23 +2742,9 @@ bool CDxfRead::ReadText()
break;
case 1:
// final text
// Note that we treat this as the end of the TEXT or MTEXT entity but this may cause
// us to miss other properties. Officially the entity ends at the start of the next
// entity, the BLKEND record that ends the containing BLOCK, or the ENDSEC record
// that ends the ENTITIES section. These are all code 0 records. Changing this would
// require either some sort of peek/pushback ability or the understanding that
// ReadText() and all the other Read... methods return having already read a code 0.
get_line();
textPrefix.append(m_str);
ResolveColorIndex();
{
const char* utfStr = (this->*stringToUTF8)(textPrefix.c_str());
OnReadText(c, height * 25.4 / 72.0, utfStr);
if (utfStr == m_str) {
delete utfStr;
}
}
return (true);
break;
case 62:
// color index

View File

@@ -392,8 +392,10 @@ public:
{}
ImportExport virtual void OnReadPoint(const double* /*s*/)
{}
ImportExport virtual void
OnReadText(const double* /*point*/, const double /*height*/, const char* /*text*/)
ImportExport virtual void OnReadText(const double* /*point*/,
const double /*height*/,
const char* /*text*/,
const double /*rotation*/)
{}
ImportExport virtual void OnReadArc(const double* /*s*/,
const double* /*e*/,