def attach(self,vobj): '''Setup the scene sub-graph of the view provider''' 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() textdrawstyle = coin.SoDrawStyle() textdrawstyle.style = coin.SoDrawStyle.FILLED self.textpos = coin.SoTransform() self.font = coin.SoFont() self.text2d = coin.SoText2() self.text3d = coin.SoAsciiText() self.text2d.string = self.text3d.string = "Label" # need to init with something, otherwise, crash! self.text2d.justification = coin.SoText2.RIGHT self.text3d.justification = coin.SoAsciiText.RIGHT self.fcoords = coin.SoCoordinate3() self.frame = coin.SoType.fromName("SoBrepEdgeSet").createInstance() self.lineswitch = coin.SoSwitch() switchnode = coin.SoSeparator() switchnode.addChild(self.line) switchnode.addChild(self.arrow) self.lineswitch.addChild(switchnode) self.lineswitch.whichChild = 0 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.font) self.node2d.addChild(self.text2d) self.node2d.addChild(self.fcoords) self.node2d.addChild(self.frame) 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.font) self.node3d.addChild(self.text3d) 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,"ArrowSize") self.onChanged(vobj,"Line")
def makeLabels(self): label_strings = ["X", "Y", "Z"] colors = [0xFF0000FF, 0x00FF00FF, 0x0000FFFF] self.label_texts = [] self.label_translations = [] # frame translation self.label_translations.append(coin.SoTranslation()) # axis translation self.label_translations.append(coin.SoTranslation()) self.labels = [] for i in range(3): label_group = coin.SoSeparator() label_group.addChild(self.label_translations[0]) frame_axis_color = coin.SoPackedColor() frame_axis_color.orderedRGBA.setValue(colors[i]) label_group.addChild(frame_axis_color) self.label_texts.append(coin.SoText2()) self.label_texts[i].string.setValues(0, 3, ["", label_strings[i], ""]) self.label_texts[i].justification.setValue( self.label_texts[i].CENTER) self.label_texts[i].spacing.setValue(0.45) label_group.addChild(self.label_texts[i]) self.labels.append(coin.SoSwitch()) self.labels[i].addChild(label_group) return self.labels
def displaytext(self, pos, color=(1, 1, 1), text=["aaa", "bbb"]): textpos = coin.SoTransform() p = pos textpos.translation.setValue(p.x + 10, p.y + 10, p.z + 10) font = coin.SoFont() font.size = 20 text2d = coin.SoText2() text3d = coin.SoAsciiText() text2d.string.setValues([l.encode("utf8") for l in text if l]) text3d.string.setValues([l.encode("utf8") for l in text if l]) myMaterial = SoMaterial() myMaterial.diffuseColor.set1Value(0, SbColor(*color)) try: sg = self._sg except: sg = SoSeparator() self._sg = sg root = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph() root.addChild(sg) node2d = SoSeparator() node2d.addChild(textpos) node2d.addChild(myMaterial) node2d.addChild(font) node2d.addChild(text2d) #node2d.addChild(text3d) sg.addChild(node2d)
def attach(self,vobj): '''Setup the scene sub-graph of the view provider''' self.mattext = coin.SoMaterial() textdrawstyle = coin.SoDrawStyle() textdrawstyle.style = coin.SoDrawStyle.FILLED self.trans = coin.SoTransform() self.font = coin.SoFont() self.text2d = coin.SoAsciiText() self.text3d = coin.SoText2() self.text2d.string = self.text3d.string = "Label" # need to init with something, otherwise, crash! self.text2d.justification = coin.SoAsciiText.LEFT self.text3d.justification = coin.SoText2.LEFT self.node2d = coin.SoGroup() self.node2d.addChild(self.trans) self.node2d.addChild(self.mattext) self.node2d.addChild(textdrawstyle) self.node2d.addChild(self.font) self.node2d.addChild(self.text2d) self.node3d = coin.SoGroup() self.node3d.addChild(self.trans) self.node3d.addChild(self.mattext) self.node3d.addChild(textdrawstyle) self.node3d.addChild(self.font) self.node3d.addChild(self.text3d) vobj.addDisplayMode(self.node2d,"2D text") vobj.addDisplayMode(self.node3d,"3D text") self.onChanged(vobj,"TextColor") self.onChanged(vobj,"FontSize") self.onChanged(vobj,"FontName") self.onChanged(vobj,"Justification") self.onChanged(vobj,"LineSpacing")
def makeLabels(self): """ Method which makes Coin3D labels to be displayed in the FreeCAD View. Frame labels for axes X, Y and Z are made. The labels have the same color as the axes. Returns: A SoSwitch with colored text label to be shown in the FreeCAD View. """ label_strings = ["X", "Y", "Z"] colors = [0xFF0000FF, 0x00FF00FF, 0x0000FFFF] self.label_texts = [] self.label_translations = [] # frame translation self.label_translations.append(coin.SoTranslation()) # axis translation self.label_translations.append(coin.SoTranslation()) self.labels = [] for i in range(3): label_group = coin.SoSeparator() label_group.addChild(self.label_translations[0]) frame_axis_color = coin.SoPackedColor() frame_axis_color.orderedRGBA.setValue(colors[i]) label_group.addChild(frame_axis_color) self.label_texts.append(coin.SoText2()) self.label_texts[i].string.setValues( 0, 3, ["", label_strings[i], ""]) self.label_texts[i].justification.setValue( self.label_texts[i].CENTER) self.label_texts[i].spacing.setValue(0.45) label_group.addChild(self.label_texts[i]) self.labels.append(coin.SoSwitch()) self.labels[i].addChild(label_group) return self.labels
def data(self, datarr): if not ((len(self._data) == len(datarr[0])) & (len(self._data) == len(datarr[1]))): # lengths of the 2 arrays are different. Wipe the Separator and populate it. self.nodeList = [] self._data = [] self.textSep.removeAllChildren() for i in range(min(len(datarr[0]),len(datarr[1]))): sep = coin.SoSeparator() textpos = coin.SoTransform() textpos.translation.setValue([datarr[0][i][0],datarr[0][i][1],datarr[0][i][2]]) text = coin.SoText2() field = [""]*self.offset + [datarr[1][i]] text.string.setValues(0,len(field),field) sep.addChild(textpos) sep.addChild(text) self.textSep.addChild(sep) self.nodeList.append((textpos,text)) self._data.append((datarr[0][i],datarr[1][i])) else: for i in range(min(len(datarr[0]),len(datarr[1]))): print(range(min(len(datarr[0]),len(datarr[1])))) print(self.nodeList[i][0]) self.nodeList[i][0].translation.setValue([datarr[0][i][0],datarr[0][i][1],datarr[0][i][2]]) field = [""]*self.offset + [datarr[1][i]] self.nodeList[i][1].string.setValues(0,len(field),field) self._data[i] = (datarr[0][i],datarr[1][i])
def __init__(self, points, sh=None): super(MarkerOnEdge, self).__init__(points, True) self._shape = None self._sublink = None self._tangent = None self._text_type = 0 self._text_translate = coin.SoTranslation() self._text_font = coin.SoFont() self._text_font.name = "Arial:Bold" self._text_font.size = 13.0 self._text = coin.SoText2() self._text_switch = coin.SoSwitch() self._text_switch.whichChild = coin.SO_SWITCH_ALL self._text_switch.addChild(self._text_translate) self._text_switch.addChild(self._text_font) self._text_switch.addChild(self._text) #self.on_drag_start.append(self.add_text) #self.on_drag_release.append(self.remove_text) self.on_drag.append(self.update_text) self.update_text() self.addChild(self._text_switch) if isinstance(sh, Part.Shape): self.snap_shape = sh elif isinstance(sh, (tuple, list)): self.sublink = sh
def attach(self, vobj): '''Setup the scene sub-graph of the view provider''' from pivy import coin self.Object = vobj.Object self.color = coin.SoBaseColor() if hasattr(vobj, "LineColor"): self.color.rgb.setValue(vobj.LineColor[0], vobj.LineColor[1], vobj.LineColor[2]) self.font = coin.SoFont() self.font3d = coin.SoFont() self.text = coin.SoAsciiText() self.text3d = coin.SoText2() self.text.string = "d" # some versions of coin crash if string is not set self.text3d.string = "d" self.text.justification = self.text3d.justification = coin.SoAsciiText.CENTER self.textpos = coin.SoTransform() label = coin.SoSeparator() label.addChild(self.textpos) label.addChild(self.color) label.addChild(self.font) label.addChild(self.text) label3d = coin.SoSeparator() label3d.addChild(self.textpos) label3d.addChild(self.color) label3d.addChild(self.font3d) label3d.addChild(self.text3d) self.coord1 = coin.SoCoordinate3() self.trans1 = coin.SoTransform() self.coord2 = coin.SoCoordinate3() self.trans2 = coin.SoTransform() self.marks = coin.SoSeparator() self.drawstyle = coin.SoDrawStyle() self.coords = coin.SoCoordinate3() self.arc = coin.SoType.fromName("SoBrepEdgeSet").createInstance() self.node = coin.SoGroup() self.node.addChild(self.color) self.node.addChild(self.drawstyle) self.node.addChild(self.coords) self.node.addChild(self.arc) self.node.addChild(self.marks) self.node.addChild(label) self.node3d = coin.SoGroup() self.node3d.addChild(self.color) self.node3d.addChild(self.drawstyle) self.node3d.addChild(self.coords) self.node3d.addChild(self.arc) self.node3d.addChild(self.marks) self.node3d.addChild(label3d) vobj.addDisplayMode(self.node, "2D") vobj.addDisplayMode(self.node3d, "3D") self.updateData(vobj.Object, None) self.onChanged(vobj, "FontSize") self.onChanged(vobj, "FontName") self.onChanged(vobj, "ArrowType") self.onChanged(vobj, "LineColor") # backwards compatibility self.ScaleMultiplier = 1.00
def makeBubbles(self): import Part def getNode(): # make sure we already have the complete node built r = self.ViewObject.RootNode if r.getChildren().getLength() > 2: if r.getChild(2).getChildren().getLength() > 0: if r.getChild(2).getChild(0).getChildren().getLength() > 0: return self.ViewObject.RootNode.getChild(2).getChild( 0).getChild(0) return None rn = getNode() if rn: if self.bubbles: rn.removeChild(self.bubbles) self.bubbles = None self.bubbles = coin.SoSeparator() isep = coin.SoSeparator() self.bubblestyle = coin.SoDrawStyle() self.bubblestyle.linePattern = 0xffff self.bubbles.addChild(self.bubblestyle) for i in range(len(self.ViewObject.Object.Distances)): invpl = self.ViewObject.Object.Placement.inverse() verts = self.ViewObject.Object.Shape.Edges[i].Vertexes p1 = invpl.multVec(verts[0].Point) p2 = invpl.multVec(verts[1].Point) dv = p2.sub(p1) dv.normalize() rad = self.ViewObject.BubbleSize center = p2.add(dv.scale(rad, rad, rad)) ts = Part.makeCircle(rad, center).writeInventor() cin = coin.SoInput() cin.setBuffer(ts) cob = coin.SoDB.readAll(cin) co = cob.getChild(1).getChild(0).getChild(2) li = cob.getChild(1).getChild(0).getChild(3) self.bubbles.addChild(co) self.bubbles.addChild(li) st = coin.SoSeparator() tr = coin.SoTransform() tr.translation.setValue( (center.x, center.y - rad / 4, center.z)) fo = coin.SoFont() fo.name = "Arial,Sans" fo.size = rad * 100 tx = coin.SoText2() tx.justification = coin.SoText2.CENTER tx.string = self.getNumber(i) st.addChild(tr) st.addChild(fo) st.addChild(tx) isep.addChild(st) self.bubbles.addChild(isep) rn.addChild(self.bubbles)
def __init__(self, view, coneHeight=5): self.view = view self.tsze = coneHeight self.cam = coin.SoOrthographicCamera() self.cam.aspectRatio = 1 self.cam.viewportMapping = coin.SoCamera.LEAVE_ALONE self.pos = coin.SoTranslation() self.mat = coin.SoMaterial() self.mat.diffuseColor = coin.SbColor(0.9, 0.0, 0.9) self.mat.transparency = 0 self.fnt = coin.SoFont() self.txt = coin.SoText2() self.txt.string = 'setValues' self.txt.justification = coin.SoText2.LEFT self.sep = coin.SoSeparator() self.sep.addChild(self.cam) self.sep.addChild(self.pos) self.sep.addChild(self.mat) self.sep.addChild(self.fnt) self.sep.addChild(self.txt) self.tTrf = coin.SoTransform() self.tTrf.translation.setValue((0, -self.tsze / 2, 0)) self.tTrf.center.setValue((0, self.tsze / 2, 0)) self.tTrf.rotation.setValue(coin.SbVec3f((1, 0, 0)), -math.pi / 2) self.tPos = coin.SoTranslation() self.tMat = coin.SoMaterial() self.tMat.diffuseColor = coin.SbColor(0.4, 0.4, 0.4) self.tMat.transparency = 0.8 self.tool = coin.SoCone() self.tool.height.setValue(self.tsze) self.tool.bottomRadius.setValue(self.tsze / 4) self.tSep = coin.SoSeparator() self.tSep.addChild(self.tPos) self.tSep.addChild(self.tTrf) self.tSep.addChild(self.tMat) self.tSep.addChild(self.tool) self.viewer = self.view.getViewer() self.render = self.viewer.getSoRenderManager() self.sup = None self.updatePreferences() self.setPosition(0, 0, 0, 0, 0, 0, False, False)
def __init__(self, sim): self.sim = sim # Scene axis label length = 1 self.r = coin.SoSeparator() st = coin.SoDrawStyle() st.lineWidth = 3 self.r.addChild(st) data = {'x': (1, 0, 0), 'y': (0, 1, 0), 'z': (0, 0, 1)} #text_ref = coin.SoText2() #self.r.addChild(text_ref) #text_ref.string = 'Tracer rendering' for k in data: vx, vy, vz = data[k] vec = (length * vx, length * vy, length * vz) s1 = coin.SoSeparator() la = coin.SoLabel() la.label = k s1.addChild(la) tr1 = coin.SoTranslation() tr1.translation = vec s1.addChild(tr1) self.r.addChild(s1) s2 = coin.SoSeparator() tr2 = coin.SoTransform() tr2.translation.setValue(data[k]) s2.addChild(tr2) matxt = coin.SoMaterial() matxt.diffuseColor = data[k] s2.addChild(matxt) txaxis = coin.SoText2() txaxis.string = k s2.addChild(txaxis) self.r.addChild(s2) ma = coin.SoMaterial() ma.diffuseColor = data[k] self.r.addChild(ma) co = coin.SoCoordinate3() co.point.setValues(0, 2, [(0, 0, 0), vec]) self.r.addChild(co) ls = coin.SoLineSet() ls.numVertices.setValues(0, 1, [2]) self.r.addChild(ls)
def __init__(self, color = (0.,0.,0.), font = 'sans', size = 16, trans = (0,0,0), text = ''): super(text2dNode, self).__init__() self.fontNode = coin.SoFont() self.transNode = coin.SoTransform() self.textNode = coin.SoText2() self.addChild(self.fontNode) self.addChild(self.transNode) self.addChild(self.textNode) self.color = color self.font = font self.size = size self.trans = trans self.text = text
def __init__(self, parent, dynamic=False): super(CustomText, self).__init__(parent.points, dynamic) #self._text_offset = FreeCAD.Vector(0,0,0) self._text_translate = coin.SoTranslation() self._text_font = coin.SoFont() self._text_font.name = "Arial:Bold" self._text_font.size = 13.0 self._text = coin.SoText2() self._text_switch = coin.SoSwitch() self._text_switch.addChild(self._text_translate) self._text_switch.addChild(self._text_font) self._text_switch.addChild(self._text) self.addChild(self._text_switch) self.parent = parent self.parent.on_drag.append(self.translate) self.translate()
def Activated(self): self.states = [ 'selecting_face', 'choosing_drafting_tools', 'drawing', 'extruding', 'finalizing' ] self.state = self.states[0] # Coin Separator for text helping user during the command textSep = coin.SoSeparator() cam = coin.SoOrthographicCamera() cam.aspectRatio = 1 cam.viewportMapping = coin.SoCamera.LEAVE_ALONE trans = coin.SoTranslation() trans.translation = (-0.98, 0.85, 0) myFont = coin.SoFont() myFont.name = "Arial" size = 50 myFont.size.setValue(size) self.SoText2 = coin.SoText2() self.SoText2.string.setValues( 0, 2, ["Sélectionner une face d'un composant", ""]) color = coin.SoBaseColor() color.rgb = (0, 0, 0) textSep.addChild(cam) textSep.addChild(trans) textSep.addChild(color) textSep.addChild(myFont) textSep.addChild(self.SoText2) activeDoc = Gui.ActiveDocument view = activeDoc.ActiveView self.sg = view.getSceneGraph() viewer = view.getViewer() self.render = viewer.getSoRenderManager() self.sup = self.render.addSuperimposition(textSep) self.sg.touch() # Timer to check what the user is doing self.machining_timer = QtCore.QTimer() self.machining_timer.setInterval(200) self.machining_timer.timeout.connect(self.check) self.start()
def __init__(self, points, sh=None): super(MarkerOnShape, self).__init__(points, True) self._shape = None self._sublink = None self._tangent = None self._text_translate = coin.SoTranslation() self._text = coin.SoText2() self._text_switch = coin.SoSwitch() self._text_switch.addChild(self._text_translate) self._text_switch.addChild(self._text) self.on_drag_start.append(self.add_text) self.on_drag_release.append(self.remove_text) self.addChild(self._text_switch) if isinstance(sh, Part.Shape): self.snap_shape = sh elif isinstance(sh, (tuple, list)): self.sublink = sh
def Activated(self, index=0): if index == 1: debug("GeomInfo activated") self.stack = [] # install the function in resident mode FreeCADGui.Selection.addObserver(self) self.active = True self.textSep = coin.SoSeparator() self.cam = coin.SoOrthographicCamera() self.cam.aspectRatio = 1 self.cam.viewportMapping = coin.SoCamera.LEAVE_ALONE self.trans = coin.SoTranslation() self.trans.translation = (-0.98, 0.90, 0) self.myFont = coin.SoFont() self.myFont.name = "FreeMono,FreeSans,sans" size = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/Mod/Curves").GetInt( 'GeomInfoFontSize', 14) print(size) self.myFont.size.setValue(size) self.SoText2 = coin.SoText2() self.SoText2.string = "" # "Nothing Selected\r2nd line" self.color = coin.SoBaseColor() self.color.rgb = (0, 0, 0) self.textSep.addChild(self.cam) self.textSep.addChild(self.trans) self.textSep.addChild(self.color) self.textSep.addChild(self.myFont) self.textSep.addChild(self.SoText2) self.addHUD() self.Active = True self.viz = False self.getTopo() elif (index == 0) and self.Active: debug("GeomInfo off") self.removeHUD() self.Active = False FreeCADGui.Selection.removeObserver(self)
def __init__(self,pl=None, sizeFont=30, color=(1.0,0.6,0.0), text='TEXT'): import FreeCAD, FreeCADGui self.node=coin.SoSeparator() self.color=coin.SoBaseColor() self.color.rgb=color self.node.addChild(self.color) self.transform=coin.SoTransform() self.node.addChild(self.transform) self.font=coin.SoFont() self.node.addChild(self.font) self.font.size=sizeFont self.text=coin.SoText2() self.text.string=text self.node.addChild(self.text) self.sg=FreeCADGui.ActiveDocument.ActiveView.getSceneGraph() self.sg.addChild(self.node) if not pl: pl=FreeCAD.Placement() self.moveto(pl)
def __init__(self): super(textArea, self).__init__() self.trans = coin.SoTranslation() self.trans.translation = (-0.98,0.95,0) self.font = coin.SoFont() self.font.name = "osiFont,FreeSans,sans" self.font.size.setValue(16.0) self.str = coin.SoText2() self.str.string = "" self.color = coin.SoBaseColor() self.color.rgb = (0,0,0) self.addChild(self.trans) self.addChild(self.color) self.addChild(self.font) self.addChild(self.str)
def attach(self, vobj): """Set up the scene sub-graph of the view provider.""" # Main attributes of the Coin scenegraph self.mattext = coin.SoMaterial() self.trans = coin.SoTransform() self.font = coin.SoFont() self.text2d = coin.SoText2() # Faces the camera always self.text3d = coin.SoAsciiText() # Can be oriented in 3D space textdrawstyle = coin.SoDrawStyle() textdrawstyle.style = coin.SoDrawStyle.FILLED # The text string needs to be initialized to something, # otherwise it may crash self.text2d.string = self.text3d.string = "Label" self.text2d.justification = coin.SoText2.LEFT self.text3d.justification = coin.SoAsciiText.LEFT self.node2d = coin.SoGroup() self.node2d.addChild(self.trans) self.node2d.addChild(self.mattext) self.node2d.addChild(textdrawstyle) self.node2d.addChild(self.font) self.node2d.addChild(self.text2d) self.node3d = coin.SoGroup() self.node3d.addChild(self.trans) self.node3d.addChild(self.mattext) self.node3d.addChild(textdrawstyle) self.node3d.addChild(self.font) self.node3d.addChild(self.text3d) vobj.addDisplayMode(self.node2d, "2D text") vobj.addDisplayMode(self.node3d, "3D text") self.onChanged(vobj, "TextColor") self.onChanged(vobj, "FontSize") self.onChanged(vobj, "FontName") self.onChanged(vobj, "Justification") self.onChanged(vobj, "LineSpacing") self.onChanged(vobj, "ScaleMultiplier") self.Object = vobj.Object
def __init__(self, view): self.view = view self.pos = coin.SoTranslation() self.mat = coin.SoMaterial() self.mat.diffuseColor = coin.SbColor( MachinekitPreferences.hudFontColorUnhomed()) self.mat.transparency = 0 self.fnt = coin.SoFont() self.txt = coin.SoText2() self.txt.string = 'setValues' self.txt.justification = coin.SoText2.LEFT self.sep = coin.SoSeparator() self.sep.addChild(self.pos) self.sep.addChild(self.mat) self.sep.addChild(self.fnt) self.sep.addChild(self.txt)
def _update_grid(self, grid_x, grid_y, drag_release=False): self.grid.removeAllChildren() x_points_lower = [[x, grid_y[0], -0.001] for x in grid_x] x_points_upper = [[x, grid_y[-1], -0.001] for x in grid_x] y_points_lower = [[grid_x[0], y, -0.001] for y in grid_y] y_points_upper = [[grid_x[-1], y, -0.001] for y in grid_y] for l in zip(x_points_lower, x_points_upper): self.grid += [pp.Line(l, color='grey').object] for l in zip(y_points_lower, y_points_upper): self.grid += [pp.Line(l, color='grey').object] for l in y_points_upper: color = coin.SoMaterial() color.diffuseColor = [0, 0, 0] textsep = coin.SoSeparator() text = coin.SoText2() trans = coin.SoTranslation() trans.translation = l text.string = self.text_repr(l[1] * self.value_scale) textsep += [color, trans, text] self.grid += [textsep] interpolation = self.spline.interpolation(50) if drag_release: for i in self.back: color = coin.SoMaterial() color.diffuseColor = [0, 0, 0] textsep = coin.SoSeparator() scale = coin.SoScale() text = coin.SoAsciiText() trans = coin.SoTranslation() rot = coin.SoRotationXYZ() rot.axis = coin.SoRotationXYZ.Z rot.angle.setValue(np.pi / 2) scale.scaleFactor = (self.text_scale, self.text_scale, self.text_scale) trans.translation = (i[0], i[1], 0.001) text.string = self.text_repr( interpolation(i[0]) * self.value_scale * self.scale[1]) textsep += [color, trans, scale, rot, text] self.grid += [textsep]
def attach(self, vobj): '''Setup the scene sub-graph of the view provider''' self.Object = vobj.Object self.color = coin.SoBaseColor() self.font = coin.SoFont() self.font3d = coin.SoFont() self.text = coin.SoAsciiText() self.text3d = coin.SoText2() self.text.string = "d" # some versions of coin crash if string is not set self.text3d.string = "d" self.textpos = coin.SoTransform() self.text.justification = self.text3d.justification = coin.SoAsciiText.CENTER label = coin.SoSeparator() label.addChild(self.textpos) label.addChild(self.color) label.addChild(self.font) label.addChild(self.text) label3d = coin.SoSeparator() label3d.addChild(self.textpos) label3d.addChild(self.color) label3d.addChild(self.font3d) label3d.addChild(self.text3d) self.coord1 = coin.SoCoordinate3() self.trans1 = coin.SoTransform() self.coord2 = coin.SoCoordinate3() self.trans2 = coin.SoTransform() self.transDimOvershoot1 = coin.SoTransform() self.transDimOvershoot2 = coin.SoTransform() self.transExtOvershoot1 = coin.SoTransform() self.transExtOvershoot2 = coin.SoTransform() self.marks = coin.SoSeparator() self.marksDimOvershoot = coin.SoSeparator() self.marksExtOvershoot = coin.SoSeparator() self.drawstyle = coin.SoDrawStyle() self.line = coin.SoType.fromName("SoBrepEdgeSet").createInstance() self.coords = coin.SoCoordinate3() self.node = coin.SoGroup() self.node.addChild(self.color) self.node.addChild(self.drawstyle) self.lineswitch2 = coin.SoSwitch() self.lineswitch2.whichChild = -3 self.node.addChild(self.lineswitch2) self.lineswitch2.addChild(self.coords) self.lineswitch2.addChild(self.line) self.lineswitch2.addChild(self.marks) self.lineswitch2.addChild(self.marksDimOvershoot) self.lineswitch2.addChild(self.marksExtOvershoot) self.node.addChild(label) self.node3d = coin.SoGroup() self.node3d.addChild(self.color) self.node3d.addChild(self.drawstyle) self.lineswitch3 = coin.SoSwitch() self.lineswitch3.whichChild = -3 self.node3d.addChild(self.lineswitch3) self.lineswitch3.addChild(self.coords) self.lineswitch3.addChild(self.line) self.lineswitch3.addChild(self.marks) self.lineswitch3.addChild(self.marksDimOvershoot) self.lineswitch3.addChild(self.marksExtOvershoot) self.node3d.addChild(label3d) vobj.addDisplayMode(self.node, "2D") vobj.addDisplayMode(self.node3d, "3D") self.updateData(vobj.Object, "Start") self.onChanged(vobj, "FontSize") self.onChanged(vobj, "FontName") self.onChanged(vobj, "ArrowType") self.onChanged(vobj, "LineColor") self.onChanged(vobj, "DimOvershoot") self.onChanged(vobj, "ExtOvershoot")
def makeSolarDiagram(longitude, latitude, scale=1, complete=False): """makeSolarDiagram(longitude,latitude,[scale,complete]): returns a solar diagram as a pivy node. If complete is True, the 12 months are drawn""" from subprocess import call py3_failed = call(["python3", "-c", "import Pysolar"]) if py3_failed: try: import Pysolar except: print( "Pysolar is not installed. Unable to generate solar diagrams") return None else: from subprocess import check_output from pivy import coin if not scale: return None def toNode(shape): "builds a pivy node from a simple linear shape" from pivy import coin buf = shape.writeInventor(2, 0.01) buf = buf.replace("\n", "") pts = re.findall("point \[(.*?)\]", buf)[0] pts = pts.split(",") pc = [] for p in pts: v = p.strip().split() pc.append([float(v[0]), float(v[1]), float(v[2])]) coords = coin.SoCoordinate3() coords.point.setValues(0, len(pc), pc) line = coin.SoLineSet() line.numVertices.setValue(-1) item = coin.SoSeparator() item.addChild(coords) item.addChild(line) return item circles = [] sunpaths = [] hourpaths = [] circlepos = [] hourpos = [] # build the base circle + number positions import Part for i in range(1, 9): circles.append(Part.makeCircle(scale * (i / 8.0))) for ad in range(0, 360, 15): a = math.radians(ad) p1 = FreeCAD.Vector(math.cos(a) * scale, math.sin(a) * scale, 0) p2 = FreeCAD.Vector( math.cos(a) * scale * 0.125, math.sin(a) * scale * 0.125, 0) p3 = FreeCAD.Vector( math.cos(a) * scale * 1.08, math.sin(a) * scale * 1.08, 0) circles.append(Part.LineSegment(p1, p2).toShape()) circlepos.append((ad, p3)) # build the sun curves at solstices and equinoxe year = datetime.datetime.now().year hpts = [[] for i in range(24)] m = [(6, 21), (7, 21), (8, 21), (9, 21), (10, 21), (11, 21), (12, 21)] if complete: m.extend([(1, 21), (2, 21), (3, 21), (4, 21), (5, 21)]) for i, d in enumerate(m): pts = [] for h in range(24): if not py3_failed: dt = "datetime.datetime(%s, %s, %s, %s)" % (year, d[0], d[1], h) alt_call = "python3 -c 'import datetime,Pysolar; print (Pysolar.solar.get_altitude_fast(%s, %s, %s))'" % ( latitude, longitude, dt) alt = math.radians( float(check_output(alt_call, shell=True).strip())) az_call = "python3 -c 'import datetime,Pysolar; print (Pysolar.solar.get_azimuth(%s, %s, %s))'" % ( latitude, longitude, dt) az = float( re.search('.+$', check_output(az_call, shell=True)).group(0)) else: dt = datetime.datetime(year, d[0], d[1], h) alt = math.radians( Pysolar.solar.GetAltitudeFast(latitude, longitude, dt)) az = Pysolar.solar.GetAzimuth(latitude, longitude, dt) az = -90 + az # pysolar's zero is south if az < 0: az = 360 + az az = math.radians(az) zc = math.sin(alt) * scale ic = math.cos(alt) * scale xc = math.cos(az) * ic yc = math.sin(az) * ic p = FreeCAD.Vector(xc, yc, zc) pts.append(p) hpts[h].append(p) if i in [0, 6]: ep = FreeCAD.Vector(p) ep.multiply(1.08) if ep.z >= 0: if h == 12: if i == 0: h = "SUMMER" else: h = "WINTER" if latitude < 0: if h == "SUMMER": h = "WINTER" else: h = "SUMMER" hourpos.append((h, ep)) if i < 7: sunpaths.append(Part.makePolygon(pts)) for h in hpts: if complete: h.append(h[0]) hourpaths.append(Part.makePolygon(h)) # cut underground lines sz = 2.1 * scale cube = Part.makeBox(sz, sz, sz) cube.translate(FreeCAD.Vector(-sz / 2, -sz / 2, -sz)) sunpaths = [sp.cut(cube) for sp in sunpaths] hourpaths = [hp.cut(cube) for hp in hourpaths] # build nodes ts = 0.005 * scale # text scale mastersep = coin.SoSeparator() circlesep = coin.SoSeparator() numsep = coin.SoSeparator() pathsep = coin.SoSeparator() hoursep = coin.SoSeparator() hournumsep = coin.SoSeparator() mastersep.addChild(circlesep) mastersep.addChild(numsep) mastersep.addChild(pathsep) mastersep.addChild(hoursep) for item in circles: circlesep.addChild(toNode(item)) for item in sunpaths: for w in item.Edges: pathsep.addChild(toNode(w)) for item in hourpaths: for w in item.Edges: hoursep.addChild(toNode(w)) for p in circlepos: text = coin.SoText2() s = p[0] - 90 s = -s if s > 360: s = s - 360 if s < 0: s = 360 + s if s == 0: s = "N" elif s == 90: s = "E" elif s == 180: s = "S" elif s == 270: s = "W" else: s = str(s) text.string = s text.justification = coin.SoText2.CENTER coords = coin.SoTransform() coords.translation.setValue([p[1].x, p[1].y, p[1].z]) coords.scaleFactor.setValue([ts, ts, ts]) item = coin.SoSeparator() item.addChild(coords) item.addChild(text) numsep.addChild(item) for p in hourpos: text = coin.SoText2() s = str(p[0]) text.string = s text.justification = coin.SoText2.CENTER coords = coin.SoTransform() coords.translation.setValue([p[1].x, p[1].y, p[1].z]) coords.scaleFactor.setValue([ts, ts, ts]) item = coin.SoSeparator() item.addChild(coords) item.addChild(text) numsep.addChild(item) return mastersep
def makeSolarDiagram(longitude, latitude, scale=1, complete=False, tz=None): """makeSolarDiagram(longitude,latitude,[scale,complete,tz]): returns a solar diagram as a pivy node. If complete is True, the 12 months are drawn. Tz is the timezone related to UTC (ex: -3 = UTC-3)""" oldversion = False ladybug = False try: import ladybug from ladybug import location from ladybug import sunpath except Exception: # TODO - remove pysolar dependency # FreeCAD.Console.PrintWarning("Ladybug module not found, using pysolar instead. Warning, this will be deprecated in the future\n") ladybug = False try: import pysolar except Exception: try: import Pysolar as pysolar except Exception: FreeCAD.Console.PrintError( "The pysolar module was not found. Unable to generate solar diagrams\n" ) return None else: oldversion = True if tz: tz = datetime.timezone(datetime.timedelta(hours=-3)) else: tz = datetime.timezone.utc else: loc = ladybug.location.Location(latitude=latitude, longitude=longitude, time_zone=tz) sunpath = ladybug.sunpath.Sunpath.from_location(loc) from pivy import coin if not scale: return None circles = [] sunpaths = [] hourpaths = [] circlepos = [] hourpos = [] # build the base circle + number positions import Part for i in range(1, 9): circles.append(Part.makeCircle(scale * (i / 8.0))) for ad in range(0, 360, 15): a = math.radians(ad) p1 = FreeCAD.Vector(math.cos(a) * scale, math.sin(a) * scale, 0) p2 = FreeCAD.Vector( math.cos(a) * scale * 0.125, math.sin(a) * scale * 0.125, 0) p3 = FreeCAD.Vector( math.cos(a) * scale * 1.08, math.sin(a) * scale * 1.08, 0) circles.append(Part.LineSegment(p1, p2).toShape()) circlepos.append((ad, p3)) # build the sun curves at solstices and equinoxe year = datetime.datetime.now().year hpts = [[] for i in range(24)] m = [(6, 21), (7, 21), (8, 21), (9, 21), (10, 21), (11, 21), (12, 21)] if complete: m.extend([(1, 21), (2, 21), (3, 21), (4, 21), (5, 21)]) for i, d in enumerate(m): pts = [] for h in range(24): if ladybug: sun = sunpath.calculate_sun(month=d[0], day=d[1], hour=h) alt = math.radians(sun.altitude) az = 90 + sun.azimuth elif oldversion: dt = datetime.datetime(year, d[0], d[1], h) alt = math.radians( pysolar.solar.GetAltitudeFast(latitude, longitude, dt)) az = pysolar.solar.GetAzimuth(latitude, longitude, dt) az = -90 + az # pysolar's zero is south, ours is X direction else: dt = datetime.datetime(year, d[0], d[1], h, tzinfo=tz) alt = math.radians( pysolar.solar.get_altitude_fast(latitude, longitude, dt)) az = pysolar.solar.get_azimuth(latitude, longitude, dt) az = 90 + az # pysolar's zero is north, ours is X direction if az < 0: az = 360 + az az = math.radians(az) zc = math.sin(alt) * scale ic = math.cos(alt) * scale xc = math.cos(az) * ic yc = math.sin(az) * ic p = FreeCAD.Vector(xc, yc, zc) pts.append(p) hpts[h].append(p) if i in [0, 6]: ep = FreeCAD.Vector(p) ep.multiply(1.08) if ep.z >= 0: if not oldversion: h = 24 - h # not sure why this is needed now... But it is. if h == 12: if i == 0: h = "SUMMER" else: h = "WINTER" if latitude < 0: if h == "SUMMER": h = "WINTER" else: h = "SUMMER" hourpos.append((h, ep)) if i < 7: sunpaths.append(Part.makePolygon(pts)) for h in hpts: if complete: h.append(h[0]) hourpaths.append(Part.makePolygon(h)) # cut underground lines sz = 2.1 * scale cube = Part.makeBox(sz, sz, sz) cube.translate(FreeCAD.Vector(-sz / 2, -sz / 2, -sz)) sunpaths = [sp.cut(cube) for sp in sunpaths] hourpaths = [hp.cut(cube) for hp in hourpaths] # build nodes ts = 0.005 * scale # text scale mastersep = coin.SoSeparator() circlesep = coin.SoSeparator() numsep = coin.SoSeparator() pathsep = coin.SoSeparator() hoursep = coin.SoSeparator() hournumsep = coin.SoSeparator() mastersep.addChild(circlesep) mastersep.addChild(numsep) mastersep.addChild(pathsep) mastersep.addChild(hoursep) for item in circles: circlesep.addChild(toNode(item)) for item in sunpaths: for w in item.Edges: pathsep.addChild(toNode(w)) for item in hourpaths: for w in item.Edges: hoursep.addChild(toNode(w)) for p in circlepos: text = coin.SoText2() s = p[0] - 90 s = -s if s > 360: s = s - 360 if s < 0: s = 360 + s if s == 0: s = "N" elif s == 90: s = "E" elif s == 180: s = "S" elif s == 270: s = "W" else: s = str(s) text.string = s text.justification = coin.SoText2.CENTER coords = coin.SoTransform() coords.translation.setValue([p[1].x, p[1].y, p[1].z]) coords.scaleFactor.setValue([ts, ts, ts]) item = coin.SoSeparator() item.addChild(coords) item.addChild(text) numsep.addChild(item) for p in hourpos: text = coin.SoText2() s = str(p[0]) text.string = s text.justification = coin.SoText2.CENTER coords = coin.SoTransform() coords.translation.setValue([p[1].x, p[1].y, p[1].z]) coords.scaleFactor.setValue([ts, ts, ts]) item = coin.SoSeparator() item.addChild(coords) item.addChild(text) numsep.addChild(item) return mastersep
def __init__(self, layout=0): node = Gui.ActiveDocument.ActiveView.getSceneGraph() bb = coin.SoVRMLBillboard() b = coin.SoSphere() t = coin.SoTransform() t.translation.setValue(FreeCAD.Vector(0, 0, 10)) mat = coin.SoMaterial() # mat.diffuseColor.setValue([1.,0.,1.]) mat.emissiveColor.setValue([1., 1., 0.]) ssa = coin.SoSeparator() ssa.addChild(t) ssa.addChild(bb) node.addChild(ssa) if layout == 0: vertices = [ (30, 20, 0), (30, 50, 0), (0, 50, 0), (0, 0, 0), ] if layout == 1: vertices = [ (30, 80, 0), (0, 80, 0), (0, 0, 0), ] if layout == 2: vertices = [(60, 80, 0), (0, 80, 0), (0, 0, 0), (60, 0, 0)] vc = len(vertices) numvertices = (vc, vc) myVertexProperty = coin.SoVertexProperty() myVertexProperty.vertex.setValues(0, vc, vertices) # Define the FaceSet myFaceSet = coin.SoFaceSet() myFaceSet.vertexProperty = myVertexProperty myFaceSet.numVertices.setValues(0, 1, numvertices) ss = coin.SoSeparator() bb.addChild(ss) africaSep = coin.SoSeparator() africaTranslate = coin.SoTranslation() font = coin.SoFont() font.size = 20 africaText = coin.SoText2() africaTranslate.translation = (2., 40.0, 1.) # africaText.string = "AFRICA" africaText.string.setValues( ["Station", "", "Road 66", "AB - CD", "EF"]) bb.addChild(africaSep) textmat = coin.SoMaterial() textmat.diffuseColor.setValue([0., 0., 0.]) # mat.emissiveColor.setValue([1.,1.,0.]) africaSep.addChild(font) africaSep.addChild(textmat) africaSep.addChild(africaTranslate) africaSep.addChild(africaText) ss.addChild(mat) ss.addChild(myFaceSet) ss.addChild(b) self.placement = t self.material = mat self.face = ss self.parentN = node self.billboard = ssa self.text = africaText
def setTolerance(self, tol): self.calc.expression.set1Value(0, "ta=%f" % tol) trans = coin.SoTranslation() trans.translation = (2.0, 0, 0) color = coin.SoBaseColor() color.rgb = (0, 0, 0) cube = coin.SoCube() # One text node in each child of the Switch no = coin.SoText2() no.string = "View is not orthogonal to any plane" xy = coin.SoText2() xy.string = "View is orthogonal to a plane" # -------------- orthoSwitch = orthoToggleSwitch("Grid") orthoSwitch.view_0.addChild(no) orthoSwitch.view_1.addChild(xy) import FreeCADGui sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
def Activated(self, index=0): if index == 1: debug("GeomInfo activated") #self.activeDoc = FreeCADGui.ActiveDocument #self.view = self.activeDoc.ActiveView self.stack = [] FreeCADGui.Selection.addObserver( self) # installe la fonction en mode resident #FreeCADGui.Selection.addObserver(self.getTopo) self.active = True #self.sg = self.view.getSceneGraph() self.textSep = coin.SoSeparator() self.cam = coin.SoOrthographicCamera() self.cam.aspectRatio = 1 self.cam.viewportMapping = coin.SoCamera.LEAVE_ALONE self.trans = coin.SoTranslation() self.trans.translation = (-0.98, 0.90, 0) self.myFont = coin.SoFont() self.myFont.name = "FreeMono,FreeSans,sans" self.myFont.size.setValue(14.0) #self.trans = coin.SoTranslation() self.SoText2 = coin.SoText2() #self.trans.translation.setValue(.25,.0,1.25) self.SoText2.string = "" #"Nothing Selected\r2nd line" self.color = coin.SoBaseColor() self.color.rgb = (0, 0, 0) self.textSep.addChild(self.cam) self.textSep.addChild(self.trans) self.textSep.addChild(self.color) self.textSep.addChild(self.myFont) #self.textSep.addChild(self.trans) self.textSep.addChild(self.SoText2) #self.Active = False #self.sg.addChild(self.textSep) #self.viewer=self.view.getViewer() #self.render=self.viewer.getSoRenderManager() #self.sup = self.render.addSuperimposition(self.textSep) #self.sg.touch() #self.cam2 = coin.SoPerspectiveCamera() #self.sg.addChild(self.cam2) #self.sensor = coin.SoFieldSensor(self.updateCB, None) #self.sensor.setData(self.sensor) #self.sensor.setPriority(0) self.addHUD() self.Active = True self.viz = False self.getTopo() elif (index == 0) and self.Active: debug("GeomInfo off") self.removeHUD() self.Active = False FreeCADGui.Selection.removeObserver(self)
def onChanged(self, vobj, prop): if prop == "LineColor": l = vobj.LineColor self.mat.diffuseColor.setValue([l[0], l[1], l[2]]) elif prop == "DrawStyle": if vobj.DrawStyle == "Solid": self.linestyle.linePattern = 0xffff elif vobj.DrawStyle == "Dashed": self.linestyle.linePattern = 0xf00f elif vobj.DrawStyle == "Dotted": self.linestyle.linePattern = 0x0f0f else: self.linestyle.linePattern = 0xff88 elif prop == "LineWidth": self.linestyle.lineWidth = vobj.LineWidth elif prop == "BubbleSize": if hasattr(self, "bubbleset"): if self.bubbles: self.bubbleset.removeChild(self.bubbles) self.bubbles = None if vobj.Object.Shape: if vobj.Object.Shape.Edges: self.bubbles = coin.SoSeparator() self.bubblestyle = coin.SoDrawStyle() self.bubblestyle.linePattern = 0xffff self.bubbles.addChild(self.bubblestyle) import Part, Draft self.bubbletexts = [] for i in range(len(vobj.Object.Shape.Edges)): verts = vobj.Object.Shape.Edges[i].Vertexes p1 = verts[0].Point p2 = verts[1].Point dv = p2.sub(p1) dv.normalize() rad = vobj.BubbleSize center = p2.add(dv.scale(rad, rad, rad)) buf = Part.makeCircle(rad, center).writeInventor() try: cin = coin.SoInput() cin.setBuffer(buf) cob = coin.SoDB.readAll(cin) except: import re # workaround for pivy SoInput.setBuffer() bug buf = buf.replace("\n", "") pts = re.findall("point \[(.*?)\]", buf)[0] pts = pts.split(",") pc = [] for p in pts: v = p.strip().split() pc.append([ float(v[0]), float(v[1]), float(v[2]) ]) coords = coin.SoCoordinate3() coords.point.setValues(0, len(pc), pc) line = coin.SoLineSet() line.numVertices.setValue(-1) else: coords = cob.getChild(1).getChild(0).getChild( 2) line = cob.getChild(1).getChild(0).getChild(3) self.bubbles.addChild(coords) self.bubbles.addChild(line) st = coin.SoSeparator() tr = coin.SoTransform() tr.translation.setValue( (center.x, center.y - rad / 4, center.z)) fo = coin.SoFont() fo.name = Draft.getParam("textfont", "Arial,Sans") fo.size = rad * 100 tx = coin.SoText2() tx.justification = coin.SoText2.CENTER self.bubbletexts.append(tx) st.addChild(tr) st.addChild(fo) st.addChild(tx) self.bubbles.addChild(st) self.bubbleset.addChild(self.bubbles) self.onChanged(vobj, "NumberingStyle") elif prop == "NumberingStyle": if hasattr(self, "bubbletexts"): chars = "abcdefghijklmnopqrstuvwxyz" roman = (('M', 1000), ('CM', 900), ('D', 500), ('CD', 400), ('C', 100), ('XC', 90), ('L', 50), ('XL', 40), ('X', 10), ('IX', 9), ('V', 5), ('IV', 4), ('I', 1)) num = 0 for t in self.bubbletexts: if vobj.NumberingStyle == "1,2,3": t.string = str(num + 1) elif vobj.NumberingStyle == "01,02,03": t.string = str(num + 1).zfill(2) elif vobj.NumberingStyle == "001,002,003": t.string = str(num + 1).zfill(3) elif vobj.NumberingStyle == "A,B,C": result = "" base = num / 26 if base: result += chars[base].upper() remainder = num % 26 result += chars[remainder].upper() t.string = result elif vobj.NumberingStyle == "a,b,c": result = "" base = num / 26 if base: result += chars[base] remainder = num % 26 result += chars[remainder] t.string = result elif vobj.NumberingStyle == "I,II,III": result = "" num += 1 for numeral, integer in roman: while num >= integer: result += numeral num -= integer t.string = result elif vobj.NumberingStyle == "L0,L1,L2": t.string = "L" + str(num) num += 1
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")
def makeSolarDiagram(longitude, latitude, scale=1, complete=False, tz=None): """makeSolarDiagram(longitude,latitude,[scale,complete,tz]): returns a solar diagram as a pivy node. If complete is True, the 12 months are drawn. Tz is the timezone related to UTC (ex: -3 = UTC-3)""" oldversion = False try: import pysolar except: try: import Pysolar as pysolar except: FreeCAD.Console.PrintError( "The pysolar module was not found. Unable to generate solar diagrams\n" ) return None else: oldversion = True from pivy import coin if not scale: return None if tz: tz = datetime.timezone(datetime.timedelta(hours=-3)) else: tz = datetime.timezone.utc def toNode(shape): "builds a pivy node from a simple linear shape" from pivy import coin buf = shape.writeInventor(2, 0.01) buf = buf.replace("\n", "") pts = re.findall("point \[(.*?)\]", buf)[0] pts = pts.split(",") pc = [] for p in pts: v = p.strip().split() pc.append([float(v[0]), float(v[1]), float(v[2])]) coords = coin.SoCoordinate3() coords.point.setValues(0, len(pc), pc) line = coin.SoLineSet() line.numVertices.setValue(-1) item = coin.SoSeparator() item.addChild(coords) item.addChild(line) return item circles = [] sunpaths = [] hourpaths = [] circlepos = [] hourpos = [] # build the base circle + number positions import Part for i in range(1, 9): circles.append(Part.makeCircle(scale * (i / 8.0))) for ad in range(0, 360, 15): a = math.radians(ad) p1 = FreeCAD.Vector(math.cos(a) * scale, math.sin(a) * scale, 0) p2 = FreeCAD.Vector( math.cos(a) * scale * 0.125, math.sin(a) * scale * 0.125, 0) p3 = FreeCAD.Vector( math.cos(a) * scale * 1.08, math.sin(a) * scale * 1.08, 0) circles.append(Part.LineSegment(p1, p2).toShape()) circlepos.append((ad, p3)) # build the sun curves at solstices and equinoxe year = datetime.datetime.now().year hpts = [[] for i in range(24)] m = [(6, 21), (7, 21), (8, 21), (9, 21), (10, 21), (11, 21), (12, 21)] if complete: m.extend([(1, 21), (2, 21), (3, 21), (4, 21), (5, 21)]) for i, d in enumerate(m): pts = [] for h in range(24): if oldversion: dt = datetime.datetime(year, d[0], d[1], h) alt = math.radians( pysolar.solar.GetAltitudeFast(latitude, longitude, dt)) az = pysolar.solar.GetAzimuth(latitude, longitude, dt) az = -90 + az # pysolar's zero is south, ours is X direction else: dt = datetime.datetime(year, d[0], d[1], h, tzinfo=tz) alt = math.radians( pysolar.solar.get_altitude_fast(latitude, longitude, dt)) az = pysolar.solar.get_azimuth(latitude, longitude, dt) az = 90 + az # pysolar's zero is north, ours is X direction if az < 0: az = 360 + az az = math.radians(az) zc = math.sin(alt) * scale ic = math.cos(alt) * scale xc = math.cos(az) * ic yc = math.sin(az) * ic p = FreeCAD.Vector(xc, yc, zc) pts.append(p) hpts[h].append(p) if i in [0, 6]: ep = FreeCAD.Vector(p) ep.multiply(1.08) if ep.z >= 0: if not oldversion: h = 24 - h # not sure why this is needed now... But it is. if h == 12: if i == 0: h = "SUMMER" else: h = "WINTER" if latitude < 0: if h == "SUMMER": h = "WINTER" else: h = "SUMMER" hourpos.append((h, ep)) if i < 7: sunpaths.append(Part.makePolygon(pts)) for h in hpts: if complete: h.append(h[0]) hourpaths.append(Part.makePolygon(h)) # cut underground lines sz = 2.1 * scale cube = Part.makeBox(sz, sz, sz) cube.translate(FreeCAD.Vector(-sz / 2, -sz / 2, -sz)) sunpaths = [sp.cut(cube) for sp in sunpaths] hourpaths = [hp.cut(cube) for hp in hourpaths] # build nodes ts = 0.005 * scale # text scale mastersep = coin.SoSeparator() circlesep = coin.SoSeparator() numsep = coin.SoSeparator() pathsep = coin.SoSeparator() hoursep = coin.SoSeparator() hournumsep = coin.SoSeparator() mastersep.addChild(circlesep) mastersep.addChild(numsep) mastersep.addChild(pathsep) mastersep.addChild(hoursep) for item in circles: circlesep.addChild(toNode(item)) for item in sunpaths: for w in item.Edges: pathsep.addChild(toNode(w)) for item in hourpaths: for w in item.Edges: hoursep.addChild(toNode(w)) for p in circlepos: text = coin.SoText2() s = p[0] - 90 s = -s if s > 360: s = s - 360 if s < 0: s = 360 + s if s == 0: s = "N" elif s == 90: s = "E" elif s == 180: s = "S" elif s == 270: s = "W" else: s = str(s) text.string = s text.justification = coin.SoText2.CENTER coords = coin.SoTransform() coords.translation.setValue([p[1].x, p[1].y, p[1].z]) coords.scaleFactor.setValue([ts, ts, ts]) item = coin.SoSeparator() item.addChild(coords) item.addChild(text) numsep.addChild(item) for p in hourpos: text = coin.SoText2() s = str(p[0]) text.string = s text.justification = coin.SoText2.CENTER coords = coin.SoTransform() coords.translation.setValue([p[1].x, p[1].y, p[1].z]) coords.scaleFactor.setValue([ts, ts, ts]) item = coin.SoSeparator() item.addChild(coords) item.addChild(text) numsep.addChild(item) return mastersep