def draw_dim_arrows(self, vobj): from pivy import coin if not hasattr(vobj, "ArrowType"): return # set scale symbol = utils.ARROW_TYPES.index(vobj.ArrowType) s = vobj.ArrowSize.Value * vobj.ScaleMultiplier self.trans1.scaleFactor.setValue((s, s, s)) self.trans2.scaleFactor.setValue((s, s, s)) # set new nodes self.marks = coin.SoSeparator() self.marks.addChild(self.color) s1 = coin.SoSeparator() if symbol == "Circle": s1.addChild(self.coord1) else: s1.addChild(self.trans1) s1.addChild(gui_utils.dim_symbol(symbol, invert=False)) self.marks.addChild(s1) s2 = coin.SoSeparator() if symbol == "Circle": s2.addChild(self.coord2) else: s2.addChild(self.trans2) s2.addChild(gui_utils.dim_symbol(symbol, invert=True)) self.marks.addChild(s2) self.node.insertChild(self.marks, 2) self.node3d.insertChild(self.marks, 2)
def update_arrow(self, obj, vobj): """Update the arrow tip of the line.""" if hasattr(self, "symbol"): if self.arrow.findChild(self.symbol) != -1: self.arrow.removeChild(self.symbol) s = utils.ARROW_TYPES.index(vobj.ArrowType) self.symbol = gui_utils.dim_symbol(s) self.arrow.addChild(self.symbol) prec = 10**(-utils.precision()) x_axis = App.Vector(1, 0, 0) target_dir = None # search in Points to get first point != to TargetPoint and use it # to get the target line direction for pnt in obj.Points[-2::-1]: if not pnt.isEqual(obj.Points[-1], prec): target_dir = pnt.sub(obj.Points[-1]) break if target_dir is None: target_dir = x_axis target_dir_xy = obj.Placement.Rotation.inverted() * target_dir angle = target_dir_xy.getAngle(x_axis) * App.Units.Radian axis = x_axis.cross(target_dir_xy) rot = App.Rotation(axis, angle) self.arrowpos.rotation.setValue((obj.Placement.Rotation * rot).Q) self.arrowpos.translation.setValue(obj.Points[-1])
def onChanged(self, vobj, prop): if prop in ["EndArrow", "ArrowSize", "ArrowType", "Visibility"]: rn = vobj.RootNode if hasattr(self, "pt") and hasattr(vobj, "EndArrow"): if vobj.EndArrow and vobj.Visibility: self.pt.removeChild(self.symbol) s = utils.ARROW_TYPES.index(vobj.ArrowType) self.symbol = gui_utils.dim_symbol(s) self.pt.addChild(self.symbol) self.updateData(vobj.Object, "Points") if hasattr(vobj, "ArrowSize"): s = vobj.ArrowSize else: s = utils.get_param("arrowsize", 0.1) self.coords.scaleFactor.setValue((s, s, s)) rn.addChild(self.pt) else: if self.symbol: if self.pt.findChild(self.symbol) != -1: self.pt.removeChild(self.symbol) if rn.findChild(self.pt) != -1: rn.removeChild(self.pt) if prop in ["LineColor"]: if hasattr(self, "pt"): self.pt[0].rgb.setValue(vobj.LineColor[0], vobj.LineColor[1], vobj.LineColor[2]) super(ViewProviderWire, self).onChanged(vobj, prop) return
def attach(self, vobj): self.Object = vobj.Object col = coin.SoBaseColor() col.rgb.setValue(vobj.LineColor[0],vobj.LineColor[1],vobj.LineColor[2]) self.coords = coin.SoTransform() self.pt = coin.SoSeparator() self.pt.addChild(col) self.pt.addChild(self.coords) self.symbol = gui_utils.dim_symbol() self.pt.addChild(self.symbol) super(ViewProviderWire, self).attach(vobj) self.onChanged(vobj,"EndArrow")
def draw_dim_arrows(self, vobj): """Draw dimension arrows.""" if not hasattr(vobj, "ArrowType"): return if self.p3.x < self.p2.x: inv = False else: inv = True # Set scale symbol = utils.ARROW_TYPES.index(vobj.ArrowType) s = vobj.ArrowSize.Value * vobj.ScaleMultiplier self.trans1.scaleFactor.setValue((s, s, s)) self.trans2.scaleFactor.setValue((s, s, s)) # Set new nodes self.marks = coin.SoSeparator() self.marks.addChild(self.color) s1 = coin.SoSeparator() if symbol == "Circle": s1.addChild(self.coord1) else: s1.addChild(self.trans1) s1.addChild(gui_utils.dim_symbol(symbol, invert=not inv)) self.marks.addChild(s1) s2 = coin.SoSeparator() if symbol == "Circle": s2.addChild(self.coord2) else: s2.addChild(self.trans2) s2.addChild(gui_utils.dim_symbol(symbol, invert=inv)) self.marks.addChild(s2) self.node.insertChild(self.marks, 2) self.node3d.insertChild(self.marks, 2)
def update_arrow(self, obj, vobj): """Update the arrow tip of the line.""" if hasattr(self, "symbol"): if self.arrow.findChild(self.symbol) != -1: self.arrow.removeChild(self.symbol) s = utils.ARROW_TYPES.index(vobj.ArrowType) self.symbol = gui_utils.dim_symbol(s) if vobj.ArrowType == "Circle": # TODO: fix behavior of the 'Circle' marker. # Instead of appearing at the tip of the line # the 'Circle' marker appears displaced and duplicated # a certain distance from the tip, which is the `TargetPoint`. # Somehow the translation is added to the position of the tip # resulting in a wrong value. # So the arrow position is reset; nevertheless, this doesn't # entirely fix the issue. coords2 = coin.SoCoordinate3() coords2.point.setValues([obj.Points[-1]]) self.arrow.addChild(coords2) self.arrowpos.translation.setValue((0, 0, 0)) else: self.arrowpos.translation.setValue(obj.Points[-1]) self.arrow.addChild(self.symbol) v1 = obj.Points[-2].sub(obj.Points[-1]) if not DraftVecUtils.isNull(v1): v1.normalize() v2 = App.Vector(0, 0, 1) if round(v2.getAngle(v1), 4) in [0, round(math.pi, 4)]: v2 = App.Vector(0, 1, 0) v3 = v1.cross(v2).negative() _rot_mat = DraftVecUtils.getPlaneRotation(v1, v3, v2) q = App.Placement(_rot_mat).Rotation.Q self.arrowpos.rotation.setValue((q[0], q[1], q[2], q[3]))
def onChanged(self,vobj,prop): if prop == "ScaleMultiplier": if not hasattr(vobj,"ScaleMultiplier"): return if hasattr(vobj,"TextSize") and hasattr(vobj,"TextAlignment"): self.update_label(vobj) if hasattr(vobj,"ArrowSize"): s = vobj.ArrowSize.Value * vobj.ScaleMultiplier if s: self.arrowpos.scaleFactor.setValue((s,s,s)) elif prop == "LineColor": if hasattr(vobj,"LineColor"): l = vobj.LineColor self.matline.diffuseColor.setValue([l[0],l[1],l[2]]) elif prop == "TextColor": if hasattr(vobj,"TextColor"): l = vobj.TextColor self.mattext.diffuseColor.setValue([l[0],l[1],l[2]]) elif prop == "LineWidth": if hasattr(vobj,"LineWidth"): self.drawstyle.lineWidth = vobj.LineWidth elif (prop == "TextFont"): if hasattr(vobj,"TextFont"): self.font.name = vobj.TextFont.encode("utf8") elif prop in ["TextSize","TextAlignment"] and hasattr(vobj,"ScaleMultiplier"): if hasattr(vobj,"TextSize") and hasattr(vobj,"TextAlignment"): self.update_label(vobj) elif prop == "Line": if hasattr(vobj,"Line"): if vobj.Line: self.lineswitch.whichChild = 0 else: self.lineswitch.whichChild = -1 elif prop == "ArrowType": if hasattr(vobj,"ArrowType"): if len(vobj.Object.Points) > 1: if hasattr(self,"symbol"): if self.arrow.findChild(self.symbol) != -1: self.arrow.removeChild(self.symbol) s = utils.ARROW_TYPES.index(vobj.ArrowType) self.symbol = gui_utils.dim_symbol(s) self.arrow.addChild(self.symbol) self.arrowpos.translation.setValue(vobj.Object.Points[-1]) v1 = vobj.Object.Points[-2].sub(vobj.Object.Points[-1]) if not DraftVecUtils.isNull(v1): v1.normalize() v2 = App.Vector(0,0,1) if round(v2.getAngle(v1),4) in [0,round(math.pi,4)]: v2 = App.Vector(0,1,0) v3 = v1.cross(v2).negative() q = App.Placement(DraftVecUtils.getPlaneRotation(v1,v3,v2)).Rotation.Q self.arrowpos.rotation.setValue((q[0],q[1],q[2],q[3])) elif prop == "ArrowSize": if hasattr(vobj,"ArrowSize") and hasattr(vobj,"ScaleMultiplier"): s = vobj.ArrowSize.Value * vobj.ScaleMultiplier if s: self.arrowpos.scaleFactor.setValue((s,s,s)) elif prop == "Frame": if hasattr(vobj,"Frame"): self.frame.coordIndex.deleteValues(0) if vobj.Frame == "Rectangle": tsize = self.getTextSize(vobj) pts = [] base = vobj.Object.Placement.Base.sub(App.Vector(self.textpos.translation.getValue().getValue())) pts.append(base.add(App.Vector(0,tsize[1]*3,0))) pts.append(pts[-1].add(App.Vector(-tsize[0]*6,0,0))) pts.append(pts[-1].add(App.Vector(0,-tsize[1]*6,0))) pts.append(pts[-1].add(App.Vector(tsize[0]*6,0,0))) pts.append(pts[0]) self.fcoords.point.setValues(pts) self.frame.coordIndex.setValues(0,len(pts),range(len(pts)))
def attach(self, vobj): """Set up the scene sub-graph of the viewprovider.""" # Attributes of the Coin scenegraph self.arrow = coin.SoSeparator() self.arrowpos = coin.SoTransform() self.arrow.addChild(self.arrowpos) self.matline = coin.SoMaterial() self.drawstyle = coin.SoDrawStyle() self.drawstyle.style = coin.SoDrawStyle.LINES self.lcoords = coin.SoCoordinate3() self.line = coin.SoType.fromName("SoBrepEdgeSet").createInstance() self.mattext = coin.SoMaterial() self.textpos = coin.SoTransform() self.font = coin.SoFont() self.text2d = coin.SoText2() # Faces the camera always self.text3d = coin.SoAsciiText() # Can be oriented in 3D space self.fcoords = coin.SoCoordinate3() self.frame = coin.SoType.fromName("SoBrepEdgeSet").createInstance() self.lineswitch = coin.SoSwitch() self.symbol = gui_utils.dim_symbol() textdrawstyle = coin.SoDrawStyle() textdrawstyle.style = coin.SoDrawStyle.FILLED # The text string needs to be initialized to something, # otherwise it crashes self.text2d.string = self.text3d.string = "Label" self.text2d.justification = coin.SoText2.RIGHT self.text3d.justification = coin.SoAsciiText.RIGHT self.font.name = utils.get_param("textfont") switchnode = coin.SoSeparator() switchnode.addChild(self.line) self.lineswitch.addChild(switchnode) self.lineswitch.whichChild = 0 self.node2dtxt = coin.SoGroup() self.node2dtxt.addChild(self.font) self.node2dtxt.addChild(self.text2d) self.node2d = coin.SoGroup() self.node2d.addChild(self.matline) self.node2d.addChild(self.arrow) self.node2d.addChild(self.drawstyle) self.node2d.addChild(self.lcoords) self.node2d.addChild(self.lineswitch) self.node2d.addChild(self.mattext) self.node2d.addChild(textdrawstyle) self.node2d.addChild(self.textpos) self.node2d.addChild(self.node2dtxt) self.node2d.addChild(self.matline) self.node2d.addChild(self.drawstyle) self.node2d.addChild(self.fcoords) self.node2d.addChild(self.frame) self.node3dtxt = coin.SoGroup() self.node3dtxt.addChild(self.font) self.node3dtxt.addChild(self.text3d) self.node3d = coin.SoGroup() self.node3d.addChild(self.matline) self.node3d.addChild(self.arrow) self.node3d.addChild(self.drawstyle) self.node3d.addChild(self.lcoords) self.node3d.addChild(self.lineswitch) self.node3d.addChild(self.mattext) self.node3d.addChild(textdrawstyle) self.node3d.addChild(self.textpos) self.node3d.addChild(self.node3dtxt) self.node3d.addChild(self.matline) self.node3d.addChild(self.drawstyle) self.node3d.addChild(self.fcoords) self.node3d.addChild(self.frame) vobj.addDisplayMode(self.node2d, "2D text") vobj.addDisplayMode(self.node3d, "3D text") self.onChanged(vobj, "LineColor") self.onChanged(vobj, "TextColor") self.onChanged(vobj, "LineWidth") self.onChanged(vobj, "ArrowSize") self.onChanged(vobj, "Line")