Merge pull request #20072 from Roy-043/Draft-Implement-Dim-Auto-Flip-Text
Draft: Implement Dim Auto Flip Text
This commit is contained in:
@@ -36,9 +36,12 @@ This includes linear dimensions, radial dimensions, and angular dimensions.
|
||||
import math
|
||||
|
||||
import FreeCAD as App
|
||||
import DraftVecUtils
|
||||
import WorkingPlane
|
||||
|
||||
from draftgeoutils import edges
|
||||
from draftutils import gui_utils
|
||||
from draftutils import params
|
||||
from draftutils import utils
|
||||
from draftutils.messages import _wrn, _err
|
||||
from draftutils.translate import translate
|
||||
@@ -51,6 +54,51 @@ if App.GuiUp:
|
||||
ViewProviderAngularDimension)
|
||||
|
||||
|
||||
def _get_flip_text_lin(p1, p2, wp, normal):
|
||||
# for linear, radial dimensions
|
||||
if not params.get_param("DimAutoFlipText"):
|
||||
return False
|
||||
p1 = wp.project_point(p1)
|
||||
p2 = wp.project_point(p2)
|
||||
ang = DraftVecUtils.angle(wp.u, p2.sub(p1), normal)
|
||||
tol = 1e-4 # high tolerance
|
||||
if math.isclose(ang, 0, abs_tol=tol):
|
||||
return False
|
||||
if math.isclose(ang, math.pi, abs_tol=tol):
|
||||
return True
|
||||
if math.isclose(ang, math.pi/2, abs_tol=tol):
|
||||
return False
|
||||
if math.isclose(ang, -math.pi/2, abs_tol=tol):
|
||||
return True
|
||||
# 90-180 (in that quadrant + 1st point closest to the origin):
|
||||
if math.pi/2 < ang < math.pi:
|
||||
return True
|
||||
# 180-270:
|
||||
if -math.pi < ang < -math.pi/2:
|
||||
return True
|
||||
# 0-90 and 270-360:
|
||||
return False
|
||||
|
||||
|
||||
def _get_flip_text_ang(cen, sta, end, normal):
|
||||
# for angular dimensions
|
||||
if not params.get_param("DimAutoFlipText"):
|
||||
return False
|
||||
import Part
|
||||
circle = Part.makeCircle(1, cen, normal, sta, end)
|
||||
mid = edges.findMidpoint(circle)
|
||||
wp = WorkingPlane.get_working_plane(update=False)
|
||||
ang = DraftVecUtils.angle(wp.u, mid.sub(cen), normal)
|
||||
tol = 1e-4 # high tolerance
|
||||
if math.isclose(ang, 0, abs_tol=tol):
|
||||
return True
|
||||
if math.isclose(ang, math.pi, abs_tol=tol):
|
||||
return False
|
||||
if ang > 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def make_dimension(p1, p2, p3=None, p4=None):
|
||||
"""Create one of three types of dimension objects.
|
||||
|
||||
@@ -77,13 +125,24 @@ def make_dimension(p1, p2, p3=None, p4=None):
|
||||
_err("No active document. Aborting")
|
||||
return None
|
||||
|
||||
new_obj = App.ActiveDocument.addObject("App::FeaturePython",
|
||||
"Dimension")
|
||||
new_obj = App.ActiveDocument.addObject("App::FeaturePython", "Dimension")
|
||||
LinearDimension(new_obj)
|
||||
|
||||
if App.GuiUp:
|
||||
ViewProviderLinearDimension(new_obj.ViewObject)
|
||||
|
||||
wp = WorkingPlane.get_working_plane(update=False)
|
||||
normal = wp.axis
|
||||
flip_text = False
|
||||
|
||||
if App.GuiUp:
|
||||
# invert the normal if we are viewing it from the back
|
||||
vnorm = gui_utils.get3DView().getViewDirection()
|
||||
if vnorm.getAngle(normal) < math.pi/2:
|
||||
normal = normal.negative()
|
||||
|
||||
new_obj.Normal = normal
|
||||
|
||||
if isinstance(p1, App.Vector) and isinstance(p2, App.Vector):
|
||||
# Measure a straight distance between p1 and p2
|
||||
new_obj.Start = p1
|
||||
@@ -93,6 +152,9 @@ def make_dimension(p1, p2, p3=None, p4=None):
|
||||
p3.multiply(0.5)
|
||||
p3 = p1.add(p3)
|
||||
|
||||
if App.GuiUp:
|
||||
flip_text = _get_flip_text_lin(p1, p2, wp, normal)
|
||||
|
||||
elif isinstance(p2, int) and isinstance(p3, int):
|
||||
# p1 is an object, and measure the distance between vertices p2 and p3
|
||||
# of this object
|
||||
@@ -103,21 +165,18 @@ def make_dimension(p1, p2, p3=None, p4=None):
|
||||
new_obj.LinkedGeometry = linked
|
||||
new_obj.Support = p1
|
||||
|
||||
# p4, and now p3, is the point through which the dimension line
|
||||
# will go through
|
||||
v1 = p1.Shape.Vertexes[idx[0]].Point
|
||||
v2 = p1.Shape.Vertexes[idx[1]].Point
|
||||
# p4, and now p3, is the point through which the dimension line will pass
|
||||
p3 = p4
|
||||
if not p3:
|
||||
# When used from the GUI command, this will never run
|
||||
# because p4 will always be assigned to a vector,
|
||||
# so p3 will never be `None`.
|
||||
# Moreover, `new_obj.Base` doesn't exist, and certainly `Shape`
|
||||
# doesn't exist, so if this ever runs it will be an error.
|
||||
v1 = new_obj.Base.Shape.Vertexes[idx[0]].Point
|
||||
v2 = new_obj.Base.Shape.Vertexes[idx[1]].Point
|
||||
p3 = v2.sub(v1)
|
||||
p3.multiply(0.5)
|
||||
p3 = v1.add(p3)
|
||||
|
||||
if App.GuiUp:
|
||||
flip_text = _get_flip_text_lin(v1, v2, wp, normal)
|
||||
|
||||
elif isinstance(p3, str):
|
||||
# If the original p3 is a string, we are measuring a circular arc
|
||||
# p2 should be an integer number starting from 0
|
||||
@@ -137,29 +196,22 @@ def make_dimension(p1, p2, p3=None, p4=None):
|
||||
new_obj.LinkedGeometry = linked
|
||||
new_obj.Support = p1
|
||||
|
||||
# p4, and now p3, is the point through which the dimension line
|
||||
# will go through
|
||||
cen = p1.Shape.Edges[p2].Curve.Center
|
||||
# p4, and now p3, is the point through which the dimension line will pass
|
||||
p3 = p4
|
||||
if not p3:
|
||||
p3 = p1.Shape.Edges[p2].Curve.Center.add(App.Vector(1, 0, 0))
|
||||
p3 = cen.add(App.Vector(1, 0, 0))
|
||||
|
||||
if App.GuiUp:
|
||||
flip_text = _get_flip_text_lin(cen, p3, wp, normal)
|
||||
|
||||
# This p3 is the point through which the dimension line will pass,
|
||||
# but this may not be the original p3, it could have been p4
|
||||
# depending on the first three parameter values
|
||||
new_obj.Dimline = p3
|
||||
|
||||
normal = WorkingPlane.get_working_plane(update=False).axis
|
||||
|
||||
if App.GuiUp:
|
||||
# invert the normal if we are viewing it from the back
|
||||
vnorm = gui_utils.get3DView().getViewDirection()
|
||||
|
||||
if vnorm.getAngle(normal) < math.pi/2:
|
||||
normal = normal.negative()
|
||||
|
||||
new_obj.Normal = normal
|
||||
|
||||
if App.GuiUp:
|
||||
new_obj.ViewObject.FlipText = flip_text
|
||||
gui_utils.format_object(new_obj)
|
||||
gui_utils.select(new_obj)
|
||||
|
||||
@@ -577,15 +629,9 @@ def make_angular_dimension(center=App.Vector(0, 0, 0),
|
||||
if not normal:
|
||||
normal = WorkingPlane.get_working_plane(update=False).axis
|
||||
|
||||
new_obj = App.ActiveDocument.addObject("App::FeaturePython",
|
||||
"Dimension")
|
||||
new_obj = App.ActiveDocument.addObject("App::FeaturePython", "Dimension")
|
||||
AngularDimension(new_obj)
|
||||
|
||||
new_obj.Center = center
|
||||
new_obj.FirstAngle = angles[0]
|
||||
new_obj.LastAngle = angles[1]
|
||||
new_obj.Dimline = dim_line
|
||||
|
||||
if App.GuiUp:
|
||||
ViewProviderAngularDimension(new_obj.ViewObject)
|
||||
|
||||
@@ -596,9 +642,14 @@ def make_angular_dimension(center=App.Vector(0, 0, 0),
|
||||
if vnorm.getAngle(normal) < math.pi/2:
|
||||
normal = normal.negative()
|
||||
|
||||
new_obj.Center = center
|
||||
new_obj.FirstAngle = angles[0]
|
||||
new_obj.LastAngle = angles[1]
|
||||
new_obj.Dimline = dim_line
|
||||
new_obj.Normal = normal
|
||||
|
||||
if App.GuiUp:
|
||||
new_obj.ViewObject.FlipText = _get_flip_text_ang(center, angles[0], angles[1], normal)
|
||||
gui_utils.format_object(new_obj)
|
||||
gui_utils.select(new_obj)
|
||||
|
||||
|
||||
@@ -388,6 +388,7 @@ def _get_param_dictionary():
|
||||
"DefaultDisplayMode": ("int", 0),
|
||||
"DefaultDrawStyle": ("int", 0),
|
||||
"DefaultPrintColor": ("unsigned", 255),
|
||||
"DimAutoFlipText": ("bool", True),
|
||||
"Draft_array_fuse": ("bool", False),
|
||||
"Draft_array_Link": ("bool", True),
|
||||
"FilletRadius": ("float", 100.0),
|
||||
|
||||
@@ -376,7 +376,7 @@ class ViewProviderLinearDimension(ViewProviderDimensionBase):
|
||||
vobj = obj.ViewObject
|
||||
|
||||
if prop == "Diameter":
|
||||
if hasattr(vobj, "Override") and vobj.Override:
|
||||
if getattr(vobj, "Override", False):
|
||||
if obj.Diameter:
|
||||
vobj.Override = vobj.Override.replace("R $dim", "Ø $dim")
|
||||
else:
|
||||
@@ -503,7 +503,7 @@ class ViewProviderLinearDimension(ViewProviderDimensionBase):
|
||||
else:
|
||||
self.trot = (0, 0, 0, 1)
|
||||
|
||||
if hasattr(vobj, "FlipArrows") and vobj.FlipArrows:
|
||||
if getattr(vobj, "FlipArrows", False):
|
||||
u = u.negative()
|
||||
|
||||
v2 = norm.cross(u)
|
||||
@@ -535,7 +535,7 @@ class ViewProviderLinearDimension(ViewProviderDimensionBase):
|
||||
else:
|
||||
offset = DraftVecUtils.scaleTo(v1, 0.05)
|
||||
|
||||
if hasattr(vobj, "FlipText") and vobj.FlipText:
|
||||
if getattr(vobj, "FlipText", False):
|
||||
_rott = App.Rotation(self.trot[0], self.trot[1], self.trot[2], self.trot[3])
|
||||
self.trot = _rott.multiply(App.Rotation(App.Vector(0, 0, 1), 180)).Q
|
||||
offset = offset.negative()
|
||||
@@ -602,7 +602,7 @@ class ViewProviderLinearDimension(ViewProviderDimensionBase):
|
||||
None,
|
||||
'Length', show_unit, unit)
|
||||
|
||||
if hasattr(vobj, "Override") and vobj.Override:
|
||||
if getattr(vobj, "Override", False):
|
||||
self.string = vobj.Override.replace("$dim", self.string)
|
||||
|
||||
self.text_wld.string = utils.string_encode_coin(self.string)
|
||||
@@ -935,7 +935,7 @@ class ViewProviderAngularDimension(ViewProviderDimensionBase):
|
||||
obj.LastAngle.Value)
|
||||
self.p2 = self.circle.Vertexes[0].Point
|
||||
self.p3 = self.circle.Vertexes[-1].Point
|
||||
midp = DraftGeomUtils.findMidpoint(self.circle.Edges[0])
|
||||
midp = DraftGeomUtils.findMidpoint(self.circle)
|
||||
ray = midp - obj.Center
|
||||
|
||||
# Set text value
|
||||
@@ -1085,12 +1085,16 @@ class ViewProviderAngularDimension(ViewProviderDimensionBase):
|
||||
r = App.Placement(_plane_rot_3).Rotation
|
||||
offset = r.multVec(App.Vector(0, 1, 0))
|
||||
|
||||
if hasattr(vobj, "TextSpacing"):
|
||||
offset = DraftVecUtils.scaleTo(offset,
|
||||
vobj.TextSpacing.Value)
|
||||
if hasattr(vobj, "TextSpacing") and hasattr(vobj, "ScaleMultiplier"):
|
||||
ts = vobj.TextSpacing.Value * vobj.ScaleMultiplier
|
||||
offset = DraftVecUtils.scaleTo(offset, ts)
|
||||
else:
|
||||
offset = DraftVecUtils.scaleTo(offset, 0.05)
|
||||
|
||||
if getattr(vobj, "FlipText", False):
|
||||
r = r.multiply(App.Rotation(App.Vector(0, 0, 1), 180))
|
||||
offset = offset.negative()
|
||||
|
||||
if m == "Screen":
|
||||
offset = offset.negative()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user