From 21ba33df01624aa5f8a6668d3cb1b25fdff27c27 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Wed, 18 May 2016 14:32:33 -0300 Subject: [PATCH] Draft: Allow to scale imported DXF files - fixes #2557 --- src/Mod/Draft/App/DraftDxf.cpp | 48 ++++++++++------ src/Mod/Draft/App/DraftDxf.h | 7 ++- src/Mod/Draft/Resources/ui/preferences-dxf.ui | 53 ++++++++++++++++- src/Mod/Draft/importDXF.py | 57 +++++++++++-------- 4 files changed, 122 insertions(+), 43 deletions(-) diff --git a/src/Mod/Draft/App/DraftDxf.cpp b/src/Mod/Draft/App/DraftDxf.cpp index 9a75bf8e5..2d4909f63 100644 --- a/src/Mod/Draft/App/DraftDxf.cpp +++ b/src/Mod/Draft/App/DraftDxf.cpp @@ -26,8 +26,7 @@ #endif #include "DraftDxf.h" - -#include + #include #include #include @@ -51,19 +50,34 @@ using namespace DraftUtils; + DraftDxfRead::DraftDxfRead(std::string filepath, App::Document *pcDoc) : CDxfRead(filepath.c_str()) { document = pcDoc; ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Draft"); optionGroupLayers = hGrp->GetBool("groupLayers",false); optionImportAnnotations = hGrp->GetBool("dxftext",false); + optionScaling = hGrp->GetFloat("dxfScaling",1.0); } +gp_Pnt DraftDxfRead::makePoint(const double* p) +{ + double sp1(p[0]); + double sp2(p[1]); + double sp3(p[2]); + if (optionScaling != 1.0) { + sp1 = sp1 * optionScaling; + sp2 = sp2 * optionScaling; + sp3 = sp3 * optionScaling; + } + return gp_Pnt(sp1,sp2,sp3); +} + void DraftDxfRead::OnReadLine(const double* s, const double* e, bool hidden) { - gp_Pnt p0(s[0], s[1], s[2]); - gp_Pnt p1(e[0], e[1], e[2]); + gp_Pnt p0 = makePoint(s); + gp_Pnt p1 = makePoint(e); if (p0.IsEqual(p1,0.00000001)) return; BRepBuilderAPI_MakeEdge makeEdge(p0, p1); @@ -74,7 +88,7 @@ void DraftDxfRead::OnReadLine(const double* s, const double* e, bool hidden) void DraftDxfRead::OnReadPoint(const double* s) { - BRepBuilderAPI_MakeVertex makeVertex(gp_Pnt(s[0], s[1], s[2])); + BRepBuilderAPI_MakeVertex makeVertex(makePoint(s)); TopoDS_Vertex vertex = makeVertex.Vertex(); AddObject(new Part::TopoShape(vertex)); } @@ -82,12 +96,12 @@ void DraftDxfRead::OnReadPoint(const double* s) void DraftDxfRead::OnReadArc(const double* s, const double* e, const double* c, bool dir, bool hidden) { - gp_Pnt p0(s[0], s[1], s[2]); - gp_Pnt p1(e[0], e[1], e[2]); + gp_Pnt p0 = makePoint(s); + gp_Pnt p1 = makePoint(e); gp_Dir up(0, 0, 1); if (!dir) up = -up; - gp_Pnt pc(c[0], c[1], c[2]); + gp_Pnt pc = makePoint(c); gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc)); BRepBuilderAPI_MakeEdge makeEdge(circle, p0, p1); TopoDS_Edge edge = makeEdge.Edge(); @@ -97,11 +111,11 @@ void DraftDxfRead::OnReadArc(const double* s, const double* e, const double* c, void DraftDxfRead::OnReadCircle(const double* s, const double* c, bool dir, bool hidden) { - gp_Pnt p0(s[0], s[1], s[2]); + gp_Pnt p0 = makePoint(s); gp_Dir up(0, 0, 1); if (!dir) up = -up; - gp_Pnt pc(c[0], c[1], c[2]); + gp_Pnt pc = makePoint(c); gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc)); BRepBuilderAPI_MakeEdge makeEdge(circle); TopoDS_Edge edge = makeEdge.Edge(); @@ -120,8 +134,8 @@ void DraftDxfRead::OnReadEllipse(const double* c, double major_radius, double mi gp_Dir up(0, 0, 1); if(!dir) up = -up; - gp_Pnt pc(c[0], c[1], c[2]); - gp_Elips ellipse(gp_Ax2(pc, up), major_radius, minor_radius); + gp_Pnt pc = makePoint(c); + gp_Elips ellipse(gp_Ax2(pc, up), major_radius * optionScaling, minor_radius * optionScaling); ellipse.Rotate(gp_Ax1(pc,up),rotation); BRepBuilderAPI_MakeEdge makeEdge(ellipse); TopoDS_Edge edge = makeEdge.Edge(); @@ -132,7 +146,7 @@ void DraftDxfRead::OnReadEllipse(const double* c, double major_radius, double mi void DraftDxfRead::OnReadText(const double *point, const double height, const char* text) { if (optionImportAnnotations) { - Base::Vector3d pt(point[0],point[1],point[2]); + Base::Vector3d pt(point[0] * optionScaling, point[1] * optionScaling, point[2] * optionScaling); if(LayerName().substr(0, 6) != "BLOCKS") { App::Annotation *pcFeature = (App::Annotation *)document->addObject("App::Annotation", "Text"); pcFeature->LabelText.setValue(Deformat(text)); @@ -166,7 +180,7 @@ void DraftDxfRead::OnReadInsert(const double* point, const double* scale, const Base::Matrix4D mat; mat.scale(scale[0],scale[1],scale[2]); mat.rotZ(rotation); - mat.move(point[0],point[1],point[2]); + mat.move(point[0]*optionScaling,point[1]*optionScaling,point[2]*optionScaling); pcomp->transformShape(mat,true); AddObject(pcomp); } @@ -179,9 +193,9 @@ void DraftDxfRead::OnReadDimension(const double* s, const double* e, const doubl { if (optionImportAnnotations) { Base::Interpreter().runString("import Draft"); - Base::Interpreter().runStringArg("p1=FreeCAD.Vector(%f,%f,%f)",s[0],s[1],s[2]); - Base::Interpreter().runStringArg("p2=FreeCAD.Vector(%f,%f,%f)",e[0],e[1],e[2]); - Base::Interpreter().runStringArg("p3=FreeCAD.Vector(%f,%f,%f)",point[0],point[1],point[2]); + Base::Interpreter().runStringArg("p1=FreeCAD.Vector(%f,%f,%f)",s[0]*optionScaling,s[1]*optionScaling,s[2]*optionScaling); + Base::Interpreter().runStringArg("p2=FreeCAD.Vector(%f,%f,%f)",e[0]*optionScaling,e[1]*optionScaling,e[2]*optionScaling); + Base::Interpreter().runStringArg("p3=FreeCAD.Vector(%f,%f,%f)",point[0]*optionScaling,point[1]*optionScaling,point[2]*optionScaling); Base::Interpreter().runString("Draft.makeDimension(p1,p2,p3)"); } } diff --git a/src/Mod/Draft/App/DraftDxf.h b/src/Mod/Draft/App/DraftDxf.h index e4f50b19b..ed461a126 100644 --- a/src/Mod/Draft/App/DraftDxf.h +++ b/src/Mod/Draft/App/DraftDxf.h @@ -25,7 +25,8 @@ #include "dxf.h" #include -#include +#include +#include namespace DraftUtils { @@ -50,10 +51,14 @@ namespace DraftUtils void AddObject(Part::TopoShape *shape); //Called by OnRead functions to add Part objects std::string Deformat(const char* text); // Removes DXF formating from texts + private: + gp_Pnt makePoint(const double* p); + protected: App::Document *document; bool optionGroupLayers; bool optionImportAnnotations; + double optionScaling; std::map > layers; }; } diff --git a/src/Mod/Draft/Resources/ui/preferences-dxf.ui b/src/Mod/Draft/Resources/ui/preferences-dxf.ui index d3321bcf5..835b2cc77 100644 --- a/src/Mod/Draft/Resources/ui/preferences-dxf.ui +++ b/src/Mod/Draft/Resources/ui/preferences-dxf.ui @@ -7,7 +7,7 @@ 0 0 506 - 611 + 647 @@ -234,6 +234,57 @@ + + + + + + + + + Scale factor to apply to imported files + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Scale factor to apply to DXF files on import. +The factor is the conversion between the unit of your DXF file and millimeters. +Ex: for files in millimeters: 1, in centimeters: 10, in meters: 1000, in inches: 25.4, in feet: 304.8 + + + 4 + + + 99999.990000000005239 + + + 1.000000000000000 + + + dxfScaling + + + Mod/Draft + + + + + diff --git a/src/Mod/Draft/importDXF.py b/src/Mod/Draft/importDXF.py index 72bbe9392..115396dd5 100644 --- a/src/Mod/Draft/importDXF.py +++ b/src/Mod/Draft/importDXF.py @@ -364,8 +364,16 @@ def formatObject(obj,dxfobj=None): obj.ViewObject.LineColor = dxfDefaultColor def vec(pt): - "returns a rounded Vector from a dxf point" - return FreeCAD.Vector(round(pt[0],prec()),round(pt[1],prec()),round(pt[2],prec())) + "returns a rounded and scaled Vector from a dxf point, or rounded and scaled value" + if isinstance(pt,float) or isinstance(pt,int): + v = round(pt,prec()) + if dxfScaling != 1: + v = v * dxfScaling + else: + v = FreeCAD.Vector(round(pt[0],prec()),round(pt[1],prec()),round(pt[2],prec())) + if dxfScaling != 1: + v.multiply(dxfScaling) + return v def drawLine(line,forceShape=False): "returns a Part shape from a dxf line" @@ -462,7 +470,7 @@ def drawArc(arc,forceShape=False): lastangle=round(arc.end_angle,prec()) circle=Part.Circle() circle.Center=v - circle.Radius=round(arc.radius,prec()) + circle.Radius=vec(arc.radius) try: if (dxfCreateDraft or dxfCreateSketch) and (not forceShape): pl = FreeCAD.Placement() @@ -478,7 +486,7 @@ def drawCircle(circle,forceShape=False): "returns a Part shape from a dxf circle" v = vec(circle.loc) curve = Part.Circle() - curve.Radius = round(circle.radius,prec()) + curve.Radius = vec(circle.radius) curve.Center = v try: if (dxfCreateDraft or dxfCreateSketch) and (not forceShape): @@ -643,7 +651,7 @@ def drawSplineOld(spline,forceShape=False): cp.append(dline[1]) elif dline[0] == 30: cp.append(dline[1]) - pt = Vector(cp[0],cp[1],cp[2]) + pt = vec(cp) if verts: if pt != verts[-1]: verts.append(pt) @@ -698,11 +706,11 @@ non-parametric curve""" else: y=0.0 dataremain = dataremain[1:] - vec = FreeCAD.Vector(x,y,z) + v = vec([x,y,z]) if groupnumber == 10: - controlpoints.append(vec) + controlpoints.append(v) elif groupnumber == 11: - fitpoints.append(vec) + fitpoints.append(v) else: dataremain = dataremain[1:] #print groupnumber #debug @@ -843,7 +851,7 @@ def drawInsert(insert,num=None,clone=False): tsf.move(pos) tsf.rotateZ(rot) sc = insert.scale - sc = FreeCAD.Vector(sc[0],sc[1],0) + sc = vec([sc[0],sc[1],0]) newob.Placement = FreeCAD.Placement(tsf) newob.Scale = sc return newob @@ -921,13 +929,13 @@ def addText(text,attrib=False): if attrib: lay = locateLayer(rawValue(text,8)) val = rawValue(text,1) - pos = FreeCAD.Vector(rawValue(text,10),rawValue(text,20),rawValue(text,30)) - hgt = rawValue(text,40) + pos = vec([rawValue(text,10),rawValue(text,20),rawValue(text,30)]) + hgt = vec(rawValue(text,40)) else: lay = locateLayer(text.layer) val = text.value - pos = FreeCAD.Vector(text.loc[0],text.loc[1],text.loc[2]) - hgt = text.height + pos = vec(text.loc) + hgt = vec(text.height) if val: if attrib: newob = doc.addObject("App::Annotation","Attribute") @@ -951,7 +959,7 @@ def addText(text,attrib=False): xv = Vector(1,0,0) ax = Vector(0,0,1) if rx or ry or rz: - xv = Vector(rx,ry,rz) + xv = vec([rx,ry,rz]) if not DraftVecUtils.isNull(xv): ax = (xv.cross(Vector(1,0,0))).negative() if DraftVecUtils.isNull(ax): @@ -1317,9 +1325,9 @@ def processdxf(document,filename,getShapes=False): warn(dim) else: lay=locateLayer(layer) - pt = FreeCAD.Vector(x1,y1,z1) - p1 = FreeCAD.Vector(x2,y2,z2) - p2 = FreeCAD.Vector(x3,y3,z3) + pt = vec([x1,y1,z1]) + p1 = vec([x2,y2,z2]) + p2 = vec([x3,y3,z3]) if align >= 128: align -= 128 elif align >= 64: @@ -1328,9 +1336,9 @@ def processdxf(document,filename,getShapes=False): align -= 32 if align == 0: if angle in [0,180]: - p2 = FreeCAD.Vector(x3,y2,z2) + p2 = vec([x3,y2,z2]) elif angle in [90,270]: - p2 = FreeCAD.Vector(x2,y3,z2) + p2 = vec([x2,y3,z2]) newob = doc.addObject("App::FeaturePython","Dimension") lay.addObject(newob) _Dimension(newob) @@ -1345,7 +1353,7 @@ def processdxf(document,filename,getShapes=False): if dxfUseStandardSize and draftui: newob.ViewObject.FontSize = draftui.fontsize else: - st = rawValue(dim,3) + st = vec(rawValue(dim,3)) size = getdimheight(st) or 1 newob.ViewObject.FontSize = float(size)*TEXTSCALING else: @@ -1357,9 +1365,9 @@ def processdxf(document,filename,getShapes=False): points = drawing.entities.get_type("point") if points: FreeCAD.Console.PrintMessage("drawing "+str(len(points))+" points...\n") for point in points: - x = rawValue(point,10) - y = rawValue(point,20) - z = rawValue(point,30) + x = vec(rawValue(point,10)) + y = vec(rawValue(point,20)) + z = vec(rawValue(point,30)) lay = rawValue(point,8) if dxfImportLayouts or (not rawValue(point,67)): if dxfMakeBlocks: @@ -2016,7 +2024,7 @@ def readPreferences(): global dxfCreatePart, dxfCreateDraft, dxfCreateSketch, dxfDiscretizeCurves, dxfStarBlocks global dxfMakeBlocks, dxfJoin, dxfRenderPolylineWidth, dxfImportTexts, dxfImportLayouts global dxfImportPoints, dxfImportHatches, dxfUseStandardSize, dxfGetColors, dxfUseDraftVisGroups - global dxfFillMode, dxfBrightBackground, dxfDefaultColor, dxfUseLegacyImporter, dxfExportBlocks + global dxfFillMode, dxfBrightBackground, dxfDefaultColor, dxfUseLegacyImporter, dxfExportBlocks, dxfScaling dxfCreatePart = p.GetBool("dxfCreatePart",True) dxfCreateDraft = p.GetBool("dxfCreateDraft",False) dxfCreateSketch = p.GetBool("dxfCreateSketch",False) @@ -2037,3 +2045,4 @@ def readPreferences(): dxfBrightBackground = isBrightBackground() dxfDefaultColor = getColor() dxfExportBlocks = p.GetBool("dxfExportBlocks",True) + dxfScaling = p.GetFloat("dxfScaling",1.0)