def updateData(self, obj, prop): if hasattr(self, "arc"): from pivy import coin import Part, DraftGeomUtils import DraftGui arcsegs = 24 # calculate the arc data if DraftVecUtils.isNull(obj.Normal): norm = App.Vector(0, 0, 1) else: norm = obj.Normal radius = (obj.Dimline.sub(obj.Center)).Length self.circle = Part.makeCircle(radius, obj.Center, norm, obj.FirstAngle.Value, obj.LastAngle.Value) self.p2 = self.circle.Vertexes[0].Point self.p3 = self.circle.Vertexes[-1].Point mp = DraftGeomUtils.findMidpoint(self.circle.Edges[0]) ray = mp.sub(obj.Center) # set text value if obj.LastAngle.Value > obj.FirstAngle.Value: a = obj.LastAngle.Value - obj.FirstAngle.Value else: a = (360 - obj.FirstAngle.Value) + obj.LastAngle.Value su = True if hasattr(obj.ViewObject, "ShowUnit"): su = obj.ViewObject.ShowUnit if hasattr(obj.ViewObject, "Decimals"): self.string = DraftGui.displayExternal(a, obj.ViewObject.Decimals, 'Angle', su) else: self.string = DraftGui.displayExternal(a, None, 'Angle', su) if obj.ViewObject.Override: self.string = obj.ViewObject.Override.replace("$dim",\ self.string) self.text.string = self.text3d.string = utils.string_encode_coin( self.string) # check display mode try: m = obj.ViewObject.DisplayMode except: # swallow all exceptions here since it always fails on first run (Displaymode enum no set yet) m = ["2D", "3D"][utils.get_param("dimstyle", 0)] # set the arc if m == "3D": # calculate the spacing of the text spacing = (len(self.string) * obj.ViewObject.FontSize.Value) / 8.0 pts1 = [] cut = None pts2 = [] for i in range(arcsegs + 1): p = self.circle.valueAt(self.circle.FirstParameter + ( (self.circle.LastParameter - self.circle.FirstParameter) / arcsegs) * i) if (p.sub(mp)).Length <= spacing: if cut is None: cut = i else: if cut is None: pts1.append([p.x, p.y, p.z]) else: pts2.append([p.x, p.y, p.z]) self.coords.point.setValues(pts1 + pts2) i1 = len(pts1) i2 = i1 + len(pts2) self.arc.coordIndex.setValues( 0, len(pts1) + len(pts2) + 1, list(range(len(pts1))) + [-1] + list(range(i1, i2))) if (len(pts1) >= 3) and (len(pts2) >= 3): self.circle1 = Part.Arc( App.Vector(pts1[0][0], pts1[0][1], pts1[0][2]), App.Vector(pts1[1][0], pts1[1][1], pts1[1][2]), App.Vector(pts1[-1][0], pts1[-1][1], pts1[-1][2])).toShape() self.circle2 = Part.Arc( App.Vector(pts2[0][0], pts2[0][1], pts2[0][2]), App.Vector(pts2[1][0], pts2[1][1], pts2[1][2]), App.Vector(pts2[-1][0], pts2[-1][1], pts2[-1][2])).toShape() else: pts = [] for i in range(arcsegs + 1): p = self.circle.valueAt(self.circle.FirstParameter + ( (self.circle.LastParameter - self.circle.FirstParameter) / arcsegs) * i) pts.append([p.x, p.y, p.z]) self.coords.point.setValues(pts) self.arc.coordIndex.setValues(0, arcsegs + 1, list(range(arcsegs + 1))) # set the arrow coords and rotation self.trans1.translation.setValue((self.p2.x, self.p2.y, self.p2.z)) self.coord1.point.setValue((self.p2.x, self.p2.y, self.p2.z)) self.trans2.translation.setValue((self.p3.x, self.p3.y, self.p3.z)) self.coord2.point.setValue((self.p3.x, self.p3.y, self.p3.z)) # calculate small chords to make arrows look better arrowlength = 4 * obj.ViewObject.ArrowSize.Value u1 = (self.circle.valueAt(self.circle.FirstParameter + arrowlength) ).sub(self.circle.valueAt( self.circle.FirstParameter)).normalize() u2 = (self.circle.valueAt(self.circle.LastParameter)).sub( self.circle.valueAt(self.circle.LastParameter - arrowlength)).normalize() if hasattr(obj.ViewObject, "FlipArrows"): if obj.ViewObject.FlipArrows: u1 = u1.negative() u2 = u2.negative() w2 = self.circle.Curve.Axis w1 = w2.negative() v1 = w1.cross(u1) v2 = w2.cross(u2) q1 = App.Placement(DraftVecUtils.getPlaneRotation(u1, v1, w1)).Rotation.Q q2 = App.Placement(DraftVecUtils.getPlaneRotation(u2, v2, w2)).Rotation.Q self.trans1.rotation.setValue((q1[0], q1[1], q1[2], q1[3])) self.trans2.rotation.setValue((q2[0], q2[1], q2[2], q2[3])) # setting text pos & rot self.tbase = mp if hasattr(obj.ViewObject, "TextPosition"): if not DraftVecUtils.isNull(obj.ViewObject.TextPosition): self.tbase = obj.ViewObject.TextPosition u3 = ray.cross(norm).normalize() v3 = norm.cross(u3) r = App.Placement(DraftVecUtils.getPlaneRotation(u3, v3, norm)).Rotation offset = r.multVec(App.Vector(0, 1, 0)) if hasattr(obj.ViewObject, "TextSpacing"): offset = DraftVecUtils.scaleTo( offset, obj.ViewObject.TextSpacing.Value) else: offset = DraftVecUtils.scaleTo(offset, 0.05) if m == "3D": offset = offset.negative() self.tbase = self.tbase.add(offset) q = r.Q self.textpos.translation.setValue( [self.tbase.x, self.tbase.y, self.tbase.z]) self.textpos.rotation = coin.SbRotation(q[0], q[1], q[2], q[3]) # set the angle property if round(obj.Angle, utils.precision()) != round( a, utils.precision()): obj.Angle = a
def updateData(self, obj, prop): """Execute when a property from the Proxy class is changed.""" if not hasattr(self, "arc"): return arcsegs = 24 vobj = obj.ViewObject # Determine the orientation of the text by using a normal direction. # Also calculate the arc data. if DraftVecUtils.isNull(obj.Normal): norm = App.Vector(0, 0, 1) else: norm = obj.Normal radius = (obj.Dimline - obj.Center).Length self.circle = Part.makeCircle(radius, obj.Center, norm, obj.FirstAngle.Value, obj.LastAngle.Value) self.p2 = self.circle.Vertexes[0].Point self.p3 = self.circle.Vertexes[-1].Point midp = DraftGeomUtils.findMidpoint(self.circle.Edges[0]) ray = midp - obj.Center # Set text value if obj.LastAngle.Value > obj.FirstAngle.Value: angle = obj.LastAngle.Value - obj.FirstAngle.Value else: angle = (360 - obj.FirstAngle.Value) + obj.LastAngle.Value show_unit = True if hasattr(vobj, "ShowUnit"): show_unit = vobj.ShowUnit if hasattr(vobj, "Decimals"): self.string = units.display_external(angle, vobj.Decimals, 'Angle', show_unit) else: self.string = units.display_external(angle, None, 'Angle', show_unit) if vobj.Override: self.string = vobj.Override.replace("$dim", self.string) self.text.string = utils.string_encode_coin(self.string) self.text3d.string = utils.string_encode_coin(self.string) # On first run the `DisplayMode` enumeration is not set, so we trap # the exception and set the display mode using the value # in the parameter database try: m = vobj.DisplayMode except AssertionError: m = ["2D", "3D"][utils.get_param("dimstyle", 0)] # Set the arc first = self.circle.FirstParameter last = self.circle.LastParameter if m == "3D": # Calculate the spacing of the text spacing = len(self.string) * vobj.FontSize.Value / 8.0 pts1 = [] cut = None pts2 = [] for i in range(arcsegs + 1): p = self.circle.valueAt(first + (last - first) / arcsegs * i) if (p - midp).Length <= spacing: if cut is None: cut = i else: if cut is None: pts1.append([p.x, p.y, p.z]) else: pts2.append([p.x, p.y, p.z]) self.coords.point.setValues(pts1 + pts2) pts1_num = len(pts1) pts2_num = len(pts2) i1 = pts1_num i2 = i1 + pts2_num self.arc.coordIndex.setValues( 0, pts1_num + pts2_num + 1, list(range(pts1_num)) + [-1] + list(range(i1, i2))) if pts1_num >= 3 and pts2_num >= 3: self.circle1 = Part.Arc( App.Vector(pts1[0][0], pts1[0][1], pts1[0][2]), App.Vector(pts1[1][0], pts1[1][1], pts1[1][2]), App.Vector(pts1[-1][0], pts1[-1][1], pts1[-1][2])).toShape() self.circle2 = Part.Arc( App.Vector(pts2[0][0], pts2[0][1], pts2[0][2]), App.Vector(pts2[1][0], pts2[1][1], pts2[1][2]), App.Vector(pts2[-1][0], pts2[-1][1], pts2[-1][2])).toShape() else: pts = [] for i in range(arcsegs + 1): p = self.circle.valueAt(first + (last - first) / arcsegs * i) pts.append([p.x, p.y, p.z]) self.coords.point.setValues(pts) self.arc.coordIndex.setValues(0, arcsegs + 1, list(range(arcsegs + 1))) # Set the arrow coords and rotation p2 = (self.p2.x, self.p2.y, self.p2.z) p3 = (self.p3.x, self.p3.y, self.p3.z) self.trans1.translation.setValue(p2) self.coord1.point.setValue(p2) self.trans2.translation.setValue(p3) self.coord2.point.setValue(p3) # Calculate small chords to make arrows look better arrowlength = 4 * vobj.ArrowSize.Value u1 = (self.circle.valueAt(first + arrowlength) - self.circle.valueAt(first)).normalize() u2 = (self.circle.valueAt(last) - self.circle.valueAt(last - arrowlength)).normalize() if hasattr(vobj, "FlipArrows") and vobj.FlipArrows: u1 = u1.negative() u2 = u2.negative() w2 = self.circle.Curve.Axis w1 = w2.negative() v1 = w1.cross(u1) v2 = w2.cross(u2) _plane_rot_1 = DraftVecUtils.getPlaneRotation(u1, v1, w1) _plane_rot_2 = DraftVecUtils.getPlaneRotation(u2, v2, w2) q1 = App.Placement(_plane_rot_1).Rotation.Q q2 = App.Placement(_plane_rot_2).Rotation.Q self.trans1.rotation.setValue((q1[0], q1[1], q1[2], q1[3])) self.trans2.rotation.setValue((q2[0], q2[1], q2[2], q2[3])) # Set text position and rotation self.tbase = midp if (hasattr(vobj, "TextPosition") and not DraftVecUtils.isNull(vobj.TextPosition)): self.tbase = vobj.TextPosition u3 = ray.cross(norm).normalize() v3 = norm.cross(u3) _plane_rot_3 = DraftVecUtils.getPlaneRotation(u3, v3, norm) 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) else: offset = DraftVecUtils.scaleTo(offset, 0.05) if m == "3D": offset = offset.negative() self.tbase = self.tbase.add(offset) q = r.Q self.textpos.translation.setValue( [self.tbase.x, self.tbase.y, self.tbase.z]) self.textpos.rotation = coin.SbRotation(q[0], q[1], q[2], q[3]) # Set the angle property _round_1 = round(obj.Angle, utils.precision()) _round_2 = round(angle, utils.precision()) if _round_1 != _round_2: obj.Angle = angle
def updateData(self, obj, prop): """called when the base object is changed""" import DraftGui if prop in ["Start", "End", "Dimline", "Direction"]: if obj.Start == obj.End: return if not hasattr(self, "node"): return import Part, DraftGeomUtils from pivy import coin # calculate the 4 points self.p1 = obj.Start self.p4 = obj.End base = None if hasattr(obj, "Direction"): if not DraftVecUtils.isNull(obj.Direction): v2 = self.p1.sub(obj.Dimline) v3 = self.p4.sub(obj.Dimline) v2 = DraftVecUtils.project(v2, obj.Direction) v3 = DraftVecUtils.project(v3, obj.Direction) self.p2 = obj.Dimline.add(v2) self.p3 = obj.Dimline.add(v3) if DraftVecUtils.equals(self.p2, self.p3): base = None proj = None else: base = Part.LineSegment(self.p2, self.p3).toShape() proj = DraftGeomUtils.findDistance(self.p1, base) if proj: proj = proj.negative() if not base: if DraftVecUtils.equals(self.p1, self.p4): base = None proj = None else: base = Part.LineSegment(self.p1, self.p4).toShape() proj = DraftGeomUtils.findDistance(obj.Dimline, base) if proj: self.p2 = self.p1.add(proj.negative()) self.p3 = self.p4.add(proj.negative()) else: self.p2 = self.p1 self.p3 = self.p4 if proj: if hasattr(obj.ViewObject, "ExtLines") and hasattr( obj.ViewObject, "ScaleMultiplier"): dmax = obj.ViewObject.ExtLines.Value * obj.ViewObject.ScaleMultiplier if dmax and (proj.Length > dmax): if (dmax > 0): self.p1 = self.p2.add( DraftVecUtils.scaleTo(proj, dmax)) self.p4 = self.p3.add( DraftVecUtils.scaleTo(proj, dmax)) else: rest = proj.Length + dmax self.p1 = self.p2.add( DraftVecUtils.scaleTo(proj, rest)) self.p4 = self.p3.add( DraftVecUtils.scaleTo(proj, rest)) else: proj = (self.p3.sub(self.p2)).cross(App.Vector(0, 0, 1)) # calculate the arrows positions self.trans1.translation.setValue((self.p2.x, self.p2.y, self.p2.z)) self.coord1.point.setValue((self.p2.x, self.p2.y, self.p2.z)) self.trans2.translation.setValue((self.p3.x, self.p3.y, self.p3.z)) self.coord2.point.setValue((self.p3.x, self.p3.y, self.p3.z)) # calculate dimension and extension lines overshoots positions self.transDimOvershoot1.translation.setValue( (self.p2.x, self.p2.y, self.p2.z)) self.transDimOvershoot2.translation.setValue( (self.p3.x, self.p3.y, self.p3.z)) self.transExtOvershoot1.translation.setValue( (self.p2.x, self.p2.y, self.p2.z)) self.transExtOvershoot2.translation.setValue( (self.p3.x, self.p3.y, self.p3.z)) # calculate the text position and orientation if hasattr(obj, "Normal"): if DraftVecUtils.isNull(obj.Normal): if proj: norm = (self.p3.sub(self.p2).cross(proj)).negative() else: norm = App.Vector(0, 0, 1) else: norm = App.Vector(obj.Normal) else: if proj: norm = (self.p3.sub(self.p2).cross(proj)).negative() else: norm = App.Vector(0, 0, 1) if not DraftVecUtils.isNull(norm): norm.normalize() u = self.p3.sub(self.p2) u.normalize() v1 = norm.cross(u) rot1 = App.Placement(DraftVecUtils.getPlaneRotation( u, v1, norm)).Rotation.Q self.transDimOvershoot1.rotation.setValue( (rot1[0], rot1[1], rot1[2], rot1[3])) self.transDimOvershoot2.rotation.setValue( (rot1[0], rot1[1], rot1[2], rot1[3])) if hasattr(obj.ViewObject, "FlipArrows"): if obj.ViewObject.FlipArrows: u = u.negative() v2 = norm.cross(u) rot2 = App.Placement(DraftVecUtils.getPlaneRotation( u, v2, norm)).Rotation.Q self.trans1.rotation.setValue((rot2[0], rot2[1], rot2[2], rot2[3])) self.trans2.rotation.setValue((rot2[0], rot2[1], rot2[2], rot2[3])) if self.p1 != self.p2: u3 = self.p1.sub(self.p2) u3.normalize() v3 = norm.cross(u3) rot3 = App.Placement( DraftVecUtils.getPlaneRotation(u3, v3, norm)).Rotation.Q self.transExtOvershoot1.rotation.setValue( (rot3[0], rot3[1], rot3[2], rot3[3])) self.transExtOvershoot2.rotation.setValue( (rot3[0], rot3[1], rot3[2], rot3[3])) if hasattr(obj.ViewObject, "TextSpacing") and hasattr( obj.ViewObject, "ScaleMultiplier"): ts = obj.ViewObject.TextSpacing.Value * obj.ViewObject.ScaleMultiplier offset = DraftVecUtils.scaleTo(v1, ts) else: offset = DraftVecUtils.scaleTo(v1, 0.05) rott = rot1 if hasattr(obj.ViewObject, "FlipText"): if obj.ViewObject.FlipText: rott = App.Rotation(*rott).multiply(App.Rotation( norm, 180)).Q offset = offset.negative() # setting text try: m = obj.ViewObject.DisplayMode except: # swallow all exceptions here since it always fails on first run (Displaymode enum no set yet) m = ["2D", "3D"][utils.get_param("dimstyle", 0)] if m == "3D": offset = offset.negative() self.tbase = (self.p2.add( (self.p3.sub(self.p2).multiply(0.5)))).add(offset) if hasattr(obj.ViewObject, "TextPosition"): if not DraftVecUtils.isNull(obj.ViewObject.TextPosition): self.tbase = obj.ViewObject.TextPosition self.textpos.translation.setValue( [self.tbase.x, self.tbase.y, self.tbase.z]) self.textpos.rotation = coin.SbRotation(rott[0], rott[1], rott[2], rott[3]) su = True if hasattr(obj.ViewObject, "ShowUnit"): su = obj.ViewObject.ShowUnit # set text value l = self.p3.sub(self.p2).Length unit = None if hasattr(obj.ViewObject, "UnitOverride"): unit = obj.ViewObject.UnitOverride # special representation if "Building US" scheme if App.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt( "UserSchema", 0) == 5: s = App.Units.Quantity(l, App.Units.Length).UserString self.string = s.replace("' ", "'- ") self.string = s.replace("+", " ") elif hasattr(obj.ViewObject, "Decimals"): self.string = DraftGui.displayExternal(l, obj.ViewObject.Decimals, 'Length', su, unit) else: self.string = DraftGui.displayExternal(l, None, 'Length', su, unit) if hasattr(obj.ViewObject, "Override"): if obj.ViewObject.Override: self.string = obj.ViewObject.Override.replace("$dim",\ self.string) self.text.string = self.text3d.string = utils.string_encode_coin( self.string) # set the lines if m == "3D": # calculate the spacing of the text textsize = (len(self.string) * obj.ViewObject.FontSize.Value) / 4.0 spacing = ((self.p3.sub(self.p2)).Length / 2.0) - textsize self.p2a = self.p2.add( DraftVecUtils.scaleTo(self.p3.sub(self.p2), spacing)) self.p2b = self.p3.add( DraftVecUtils.scaleTo(self.p2.sub(self.p3), spacing)) self.coords.point.setValues( [[self.p1.x, self.p1.y, self.p1.z], [self.p2.x, self.p2.y, self.p2.z], [self.p2a.x, self.p2a.y, self.p2a.z], [self.p2b.x, self.p2b.y, self.p2b.z], [self.p3.x, self.p3.y, self.p3.z], [self.p4.x, self.p4.y, self.p4.z]]) #self.line.numVertices.setValues([3,3]) self.line.coordIndex.setValues(0, 7, (0, 1, 2, -1, 3, 4, 5)) else: self.coords.point.setValues([[self.p1.x, self.p1.y, self.p1.z], [self.p2.x, self.p2.y, self.p2.z], [self.p3.x, self.p3.y, self.p3.z], [self.p4.x, self.p4.y, self.p4.z]]) #self.line.numVertices.setValue(4) self.line.coordIndex.setValues(0, 4, (0, 1, 2, 3))
def updateData(self, obj, prop): """Execute when a property from the Proxy class is changed. It only runs if `Start`, `End`, `Dimline`, or `Direction` changed. """ if prop not in ("Start", "End", "Dimline", "Direction"): return if obj.Start == obj.End: return if not hasattr(self, "node"): return vobj = obj.ViewObject # Calculate the 4 points # # | d | # ---p2-------------c----p3---- c # | | # | | # p1 p4 # # - `c` is the `Dimline`, a point that lies on the dimension line # or on its extension. # - The line itself between `p2` to `p3` is the `base`. # - The distance between `p2` (`base`) to `p1` is `proj`, an extension # line from the dimension to the measured object. # - If the `proj` distance is zero, `p1` and `p2` are the same point, # and same with `p3` and `p4`. # self.p1 = obj.Start self.p4 = obj.End base = None if (hasattr(obj, "Direction") and not DraftVecUtils.isNull(obj.Direction)): v2 = self.p1 - obj.Dimline v3 = self.p4 - obj.Dimline v2 = DraftVecUtils.project(v2, obj.Direction) v3 = DraftVecUtils.project(v3, obj.Direction) self.p2 = obj.Dimline + v2 self.p3 = obj.Dimline + v3 if DraftVecUtils.equals(self.p2, self.p3): base = None proj = None else: base = Part.LineSegment(self.p2, self.p3).toShape() proj = DraftGeomUtils.findDistance(self.p1, base) if proj: proj = proj.negative() if not base: if DraftVecUtils.equals(self.p1, self.p4): base = None proj = None else: base = Part.LineSegment(self.p1, self.p4).toShape() proj = DraftGeomUtils.findDistance(obj.Dimline, base) if proj: self.p2 = self.p1 + proj.negative() self.p3 = self.p4 + proj.negative() else: self.p2 = self.p1 self.p3 = self.p4 if proj: if hasattr(vobj, "ExtLines") and hasattr(vobj, "ScaleMultiplier"): # The scale multiplier also affects the value # of the extension line; this makes sure a maximum length # is used if the calculated value is larger than it. dmax = vobj.ExtLines.Value * vobj.ScaleMultiplier if dmax and proj.Length > dmax: if dmax > 0: self.p1 = self.p2 + DraftVecUtils.scaleTo(proj, dmax) self.p4 = self.p3 + DraftVecUtils.scaleTo(proj, dmax) else: rest = proj.Length + dmax self.p1 = self.p2 + DraftVecUtils.scaleTo(proj, rest) self.p4 = self.p3 + DraftVecUtils.scaleTo(proj, rest) else: proj = (self.p3 - self.p2).cross(App.Vector(0, 0, 1)) # Calculate the arrow positions p2 = (self.p2.x, self.p2.y, self.p2.z) p3 = (self.p3.x, self.p3.y, self.p3.z) self.trans1.translation.setValue(p2) self.coord1.point.setValue(p2) self.trans2.translation.setValue(p3) self.coord2.point.setValue(p3) # Calculate dimension and extension lines overshoots positions self.transDimOvershoot1.translation.setValue(p2) self.transDimOvershoot2.translation.setValue(p3) self.transExtOvershoot1.translation.setValue(p2) self.transExtOvershoot2.translation.setValue(p3) # Determine the orientation of the text by using a normal direction. # By default the value of +Z will be used, or a calculated value # from p2 and p3. So the text will lie on the XY plane # or a plane coplanar with p2 and p3. u = self.p3 - self.p2 u.normalize() if proj: _norm = u.cross(proj) norm = _norm.negative() else: norm = App.Vector(0, 0, 1) # If `Normal` exists and is different from the default `(0,0,0)`, # it will be used. if hasattr(obj, "Normal") and not DraftVecUtils.isNull(obj.Normal): norm = App.Vector(obj.Normal) if not DraftVecUtils.isNull(norm): norm.normalize() # Calculate the position of the arrows and extension lines v1 = norm.cross(u) _plane_rot = DraftVecUtils.getPlaneRotation(u, v1, norm) rot1 = App.Placement(_plane_rot).Rotation.Q self.transDimOvershoot1.rotation.setValue( (rot1[0], rot1[1], rot1[2], rot1[3])) self.transDimOvershoot2.rotation.setValue( (rot1[0], rot1[1], rot1[2], rot1[3])) if hasattr(vobj, "FlipArrows") and vobj.FlipArrows: u = u.negative() v2 = norm.cross(u) _plane_rot = DraftVecUtils.getPlaneRotation(u, v2, norm) rot2 = App.Placement(_plane_rot).Rotation.Q self.trans1.rotation.setValue((rot2[0], rot2[1], rot2[2], rot2[3])) self.trans2.rotation.setValue((rot2[0], rot2[1], rot2[2], rot2[3])) if self.p1 != self.p2: u3 = self.p1 - self.p2 u3.normalize() v3 = norm.cross(u3) _plane_rot = DraftVecUtils.getPlaneRotation(u3, v3, norm) rot3 = App.Placement(_plane_rot).Rotation.Q self.transExtOvershoot1.rotation.setValue( (rot3[0], rot3[1], rot3[2], rot3[3])) self.transExtOvershoot2.rotation.setValue( (rot3[0], rot3[1], rot3[2], rot3[3])) # Offset is the distance from the dimension line to the textual # element that displays the value of the measurement if hasattr(vobj, "TextSpacing") and hasattr(vobj, "ScaleMultiplier"): ts = vobj.TextSpacing.Value * vobj.ScaleMultiplier offset = DraftVecUtils.scaleTo(v1, ts) else: offset = DraftVecUtils.scaleTo(v1, 0.05) rott = rot1 if hasattr(vobj, "FlipText") and vobj.FlipText: _rott = App.Rotation(rott[0], rott[1], rott[2], rott[3]) rott = _rott.multiply(App.Rotation(norm, 180)).Q offset = offset.negative() # On first run the `DisplayMode` enumeration is not set, so we trap # the exception and set the display mode using the value # in the parameter database try: m = vobj.DisplayMode except AssertionError: m = ["2D", "3D"][utils.get_param("dimstyle", 0)] if m == "3D": offset = offset.negative() # The position of the text element in the dimension is provided # in absolute coordinates by the value of `TextPosition`, # if it is different from the default `(0,0,0)` if (hasattr(vobj, "TextPosition") and not DraftVecUtils.isNull(vobj.TextPosition)): self.tbase = vobj.TextPosition else: # Otherwise the position is calculated from the end points # of the dimension line, and the offset that depends # on `TextSpacing` center = self.p2 + (self.p3 - self.p2).multiply(0.5) self.tbase = center + offset self.textpos.translation.setValue( [self.tbase.x, self.tbase.y, self.tbase.z]) self.textpos.rotation = coin.SbRotation(rott[0], rott[1], rott[2], rott[3]) show_unit = True if hasattr(vobj, "ShowUnit"): show_unit = vobj.ShowUnit # Set text element showing the value of the dimension length = (self.p3 - self.p2).Length unit = None if hasattr(vobj, "UnitOverride"): unit = vobj.UnitOverride # Special representation if we use 'Building US' scheme u_params = App.ParamGet("User parameter:BaseApp/Preferences/Units") if u_params.GetInt("UserSchema", 0) == 5: s = App.Units.Quantity(length, App.Units.Length).UserString self.string = s.replace("' ", "'- ") # feet self.string = s.replace("+", " ") elif hasattr(vobj, "Decimals"): self.string = units.display_external(length, vobj.Decimals, 'Length', show_unit, unit) else: self.string = units.display_external(length, None, 'Length', show_unit, unit) if hasattr(vobj, "Override") and vobj.Override: self.string = vobj.Override.replace("$dim", self.string) self.text.string = utils.string_encode_coin(self.string) self.text3d.string = utils.string_encode_coin(self.string) # Set the lines if m == "3D": # Calculate the spacing of the text textsize = len(self.string) * vobj.FontSize.Value / 4.0 spacing = (self.p3 - self.p2).Length / 2.0 - textsize self.p2a = self.p2 + DraftVecUtils.scaleTo(self.p3 - self.p2, spacing) self.p2b = self.p3 + DraftVecUtils.scaleTo(self.p2 - self.p3, spacing) self.coords.point.setValues([[self.p1.x, self.p1.y, self.p1.z], [self.p2.x, self.p2.y, self.p2.z], [self.p2a.x, self.p2a.y, self.p2a.z], [self.p2b.x, self.p2b.y, self.p2b.z], [self.p3.x, self.p3.y, self.p3.z], [self.p4.x, self.p4.y, self.p4.z]]) # self.line.numVertices.setValues([3, 3]) self.line.coordIndex.setValues(0, 7, (0, 1, 2, -1, 3, 4, 5)) else: self.coords.point.setValues([[self.p1.x, self.p1.y, self.p1.z], [self.p2.x, self.p2.y, self.p2.z], [self.p3.x, self.p3.y, self.p3.z], [self.p4.x, self.p4.y, self.p4.z]]) # self.line.numVertices.setValue(4) self.line.coordIndex.setValues(0, 4, (0, 1, 2, 3))