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): """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))