def recompute(self): import Part if self.circle: self.sep.removeChild(self.circle) self.circle = None if self.endangle < self.startangle: c = Part.makeCircle(1, Vector(0, 0, 0), FreeCAD.DraftWorkingPlane.axis, self.endangle, self.startangle) else: c = Part.makeCircle(1, Vector(0, 0, 0), FreeCAD.DraftWorkingPlane.axis, self.startangle, self.endangle) buf = c.writeInventor(2, 0.01) ivin = coin.SoInput() ivin.setBuffer(buf) ivob = coin.SoDB.readAll(ivin) # In case reading from buffer failed if ivob and ivob.getNumChildren() > 1: self.circle = ivob.getChild(1).getChild(0) self.circle.removeChild(self.circle.getChild(0)) self.circle.removeChild(self.circle.getChild(0)) self.sep.addChild(self.circle) else: FreeCAD.Console.PrintWarning( "arcTracker.recompute() failed to read-in Inventor string\n")
def recompute(self): if (len(self.points) >= 2): if self.bspline: self.sep.removeChild(self.bspline) self.bspline = None c = Part.BSplineCurve() # DNC: allows to close the curve by placing ends close to each other if ( len(self.points) >= 3 ) and ( (self.points[0] - self.points[-1]).Length < Draft.tolerance() ): # YVH: Added a try to bypass some hazardous situations try: c.interpolate(self.points[:-1], True) except: pass elif self.points: try: c.interpolate(self.points, False) except: pass c = c.toShape() buf=c.writeInventor(2,0.01) #fp=open("spline.iv","w") #fp.write(buf) #fp.close() ivin = coin.SoInput() ivin.setBuffer(buf) ivob = coin.SoDB.readAll(ivin) # In case reading from buffer failed if ivob and ivob.getNumChildren() > 1: self.bspline = ivob.getChild(1).getChild(0) self.bspline.removeChild(self.bspline.getChild(0)) self.bspline.removeChild(self.bspline.getChild(0)) self.sep.addChild(self.bspline) else: FreeCAD.Console.PrintWarning("bsplineTracker.recompute() failed to read-in Inventor string\n")
def embedLight(scene,lightdir): """embedLight(scene,lightdir): embeds a given coin node inside a shadow group with directional light with the given direction (x,y,z) tuple. Returns the final coin node""" from pivy import coin # buggy - no SoShadowGroup in pivy? #sgroup = coin.SoShadowGroup() #sgroup.quality = 1 #sgroup.precision = 1 #slight = SoShadowDirectionalLight() #slight.direction = lightdir #slight.intensity = 20.0 buf = """ #Inventor V2.1 ascii ShadowGroup { quality 1 precision 1 ShadowDirectionalLight { direction """+str(lightdir[0])+" "+str(lightdir[1])+" "+str(lightdir[2])+""" intensity 200.0 # enable this to reduce the shadow view distance # maxShadowDistance 200 } }""" inp = coin.SoInput() inp.setBuffer(buf) sgroup = coin.SoDB.readAll(inp) sgroup.addChild(scene) return sgroup
def buildScene(objects,colors=None): """buildScene(objects,colors=None): builds a coin node from a given list of FreeCAD objects. Optional colors argument can be a dictionary of objName:ShapeColorTuple or obj:DiffuseColorList pairs.""" from pivy import coin root = coin.SoSeparator() for o in objects: buf = None if hasattr(o,'Shape') and o.Shape and (not o.Shape.isNull()): # writeInventor of shapes needs tessellation values buf = o.Shape.writeInventor(2,0.01) elif o.isDerivedFrom("Mesh::Feature"): buf = o.Mesh.writeInventor() if buf: # 3 lines below are the standard way to produce a coin node from a string # Part and Mesh objects always have a containing SoSeparator inp = coin.SoInput() inp.setBuffer(buf) node = coin.SoDB.readAll(inp) if colors: if o.Name in colors: # insert a material node at 1st position, before the geometry color = colors[o.Name] if isinstance(color,list): # DiffuseColor, not supported here color = color[0] color = color[:3] mat = coin.SoMaterial() mat.diffuseColor = color node.insertChild(mat,0) root.addChild(node) return root
def rootNode(shape, mode=2, deviation=0.3, angle=0.4): buf = shape.writeInventor(mode, deviation, angle) from pivy import coin inp = coin.SoInput() inp.setBuffer(buf) node = coin.SoDB.readAll(inp) return node
def recompute(self): """ Recompute geometry based on current points """ if not self.points: return if len(self.points) <= 1: return if self.wire: self.sep.removeChild(self.wire) wire = Part.makePolygon(self.points) buf = wire.writeInventor(2, 0.01) try: ivin = coin.SoInput() ivin.setBuffer(buf) ivob = coin.SoDB.readAll(ivin) except: import re buf = buf.replace('\n', '') pts = re.findall(r'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) self.wire = coin.SoSeparator() self.wire.addChild(coords) self.sep.addChild(self.wire) else: if ivob and ivob.getNumChildren() > 1: self.wire = ivob.getChild(1).getChild(0) self.wire.removeChild(self.wire.getChild(0)) self.wire.removeChild(self.wire.getChild(0)) self.sep.addChild(self.wire) else: App.Console.PrintWarning(""" AlignmentTracker.recompute() failed to read Inventor string\n """)
def recompute(self): if (len(self.points) >= 2): if self.bezcurve: self.sep.removeChild(self.bezcurve) self.bezcurve = None ### c = Part.BSplineCurve() #!!!!!!!!!!!!!!! c = Part.BezierCurve() # DNC: allows to close the curve by placing ends close to each other if (len(self.points) >= 3) and ( (self.points[0] - self.points[-1]).Length < Draft.tolerance()): # YVH: Added a try to bypass some hazardous situations try: ### c.interpolate(self.points[:-1], True) #!!!!!!!!!!!! c.setPoles(self.points[:-1]) except Part.OCCError: pass elif self.points: try: ### c.interpolate(self.points, False) #!!!!!!! c.setPoles(self.points) except Part.OCCError: pass c = c.toShape() #???? c = Part.Edge(c)?, c = Part.Wire(c)?? buf = c.writeInventor(2, 0.01) #fp=open("spline.iv","w") #fp.write(buf) #fp.close() try: ivin = coin.SoInput() ivin.setBuffer(buf) ivob = coin.SoDB.readAll(ivin) except: # workaround for pivy SoInput.setBuffer() bug import re 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) self.bezcurve = coin.SoSeparator() self.bezcurve.addChild(coords) self.bezcurve.addChild(line) self.sep.addChild(self.bezcurve) else: if ivob and ivob.getNumChildren() > 1: self.bezcurve = ivob.getChild(1).getChild(0) self.bezcurve.removeChild(self.bezcurve.getChild(0)) self.bezcurve.removeChild(self.bezcurve.getChild(0)) self.sep.addChild(self.bezcurve) else: FreeCAD.Console.PrintWarning( "bezcurveTracker.recompute() failed to read-in Inventor string\n" )
def recompute(self): """Recompute the tracker.""" if self.bezcurve: for seg in self.bezcurve: self.sep.removeChild(seg) seg = None self.bezcurve = [] if (len(self.points) >= 2): if self.degree: poles = self.points[1:] segpoleslst = [poles[x:x+self.degree] for x in range(0, len(poles), (self.degree or 1))] else: segpoleslst = [self.points] startpoint = self.points[0] for segpoles in segpoleslst: c = Part.BezierCurve() # last segment may have lower degree c.increase(len(segpoles)) c.setPoles([startpoint] + segpoles) c = c.toShape() startpoint = segpoles[-1] buf = c.writeInventor(2, 0.01) # fp=open("spline.iv", "w") # fp.write(buf) # fp.close() try: ivin = coin.SoInput() ivin.setBuffer(buf) ivob = coin.SoDB.readAll(ivin) except Exception: # 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) bezcurveseg = coin.SoSeparator() bezcurveseg.addChild(coords) bezcurveseg.addChild(line) self.sep.addChild(bezcurveseg) else: if ivob and ivob.getNumChildren() > 1: bezcurveseg = ivob.getChild(1).getChild(0) bezcurveseg.removeChild(bezcurveseg.getChild(0)) bezcurveseg.removeChild(bezcurveseg.getChild(0)) self.sep.addChild(bezcurveseg) else: FreeCAD.Console.PrintWarning("bezcurveTracker.recompute() failed to read-in Inventor string\n") self.bezcurve.append(bezcurveseg)
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 openiv(filename): """openiv(filename): opens an .iv file and returns a coin node from it""" f = open(filename, "r") buf = f.read() f.close() inp = coin.SoInput() inp.setBuffer(buf) node = coin.SoDB.readAll(inp) return node
def getCoinNode(shape): import tempfile iv = shape.writeInventor() temp = tempfile.NamedTemporaryFile() temp.write(shape.writeInventor()) temp.seek(0) inp = coin.SoInput() #openFile(str(filename.toLatin1())) inp.openFile(temp.name) root = coin.SoDB.readAll(inp) temp.close() return(root)
def getNodeLight(self, shape): "extract a lighter version directly from a shape" sep = coin.SoSeparator() try: inputstr = coin.SoInput() inputstr.setBuffer(shape.writeInventor()) coinobj = coin.SoDB.readAll(inputstr) # only add wireframe or full node? sep.addChild(coinobj.getChildren()[1]) # sep.addChild(coinobj) except: pass return sep
def getCoinCamera(camerastring): """getCoinCamera(camerastring): Returns a coin camera node from a string""" if camerastring: inp = coin.SoInput() inp.setBuffer(camerastring) node = coin.SoDB.readAll(inp) # this produces a SoSeparator containing the camera for child in node.getChildren(): if ("SoOrthographicCamera" in str(child)) or ("SoPerspectiveCamera" in str(child)): return child print("unnable to build a camera node from string:",camerastring) return None
def loadInventor(self, obj): "loads an openinventor file and replace the root node of this object" # check inventor contents ivstring = self.getInventorString(obj) if not ivstring: FreeCAD.Console.PrintWarning( "Unable to get lightWeight node for object referenced in " + obj.Label + "\n") return from pivy import coin inputnode = coin.SoInput() inputnode.setBuffer(ivstring) lwnode = coin.SoDB.readAll(inputnode) if not isinstance(lwnode, coin.SoSeparator): FreeCAD.Console.PrintError( "Invalid lightWeight node for object referenced in " + obj.Label + "\n") return if lwnode.getNumChildren() < 2: FreeCAD.Console.PrintError( "Invalid lightWeight node for object referenced in " + obj.Label + "\n") return flatlines = lwnode shaded = lwnode.getChild(0) wireframe = lwnode.getChild(1) # check node contents rootnode = obj.ViewObject.RootNode if rootnode.getNumChildren() < 3: FreeCAD.Console.PrintError("Invalid root node in " + obj.Label + "\n") return switch = rootnode.getChild(2) if switch.getNumChildren() != 4: FreeCAD.Console.PrintError("Invalid root node in " + obj.Label + "\n") return # keep a copy of the original nodes self.orig_flatlines = switch.getChild(0).copy() self.orig_shaded = switch.getChild(1).copy() self.orig_wireframe = switch.getChild(2).copy() # replace root node of object switch.replaceChild(0, flatlines) switch.replaceChild(1, shaded) switch.replaceChild(2, wireframe)
def makeSnapshotWithoutGui(): from pivy import coin # create a test geometry and create an IV representation as string box = Part.makeCone(10, 8, 10) iv = box.writeInventor() # load it into a buffer inp = coin.SoInput() try: inp.setBuffer(iv) except Exception: tempPath = tempfile.gettempdir() fileName = tempPath + os.sep + "cone.iv" file = open(fileName, "w") file.write(iv) file.close() inp.openFile(fileName) # and create a scenegraph data = coin.SoDB.readAll(inp) base = coin.SoBaseColor() base.rgb.setValue(0.6, 0.7, 1.0) data.insertChild(base, 0) # add light and camera so that the rendered geometry is visible root = coin.SoSeparator() light = coin.SoDirectionalLight() cam = coin.SoOrthographicCamera() root.addChild(cam) root.addChild(light) root.addChild(data) # do the rendering now axo = coin.SbRotation(-0.353553, -0.146447, -0.353553, -0.853553) viewport = coin.SbViewportRegion(400, 400) cam.orientation.setValue(axo) cam.viewAll(root, viewport) off = coin.SoOffscreenRenderer(viewport) root.ref() off.render(root) root.unref() # export the image, PS is always available off.writeToPostScript("crystal.ps") # Other formats are only available if simage package is installed if off.isWriteSupported("PNG"): print("Save as PNG") off.writeToFile("crystal.png", "PNG")
def getNodeLight(self,shape): "extract a lighter version directly from a shape" # error-prone sep = coin.SoSeparator() try: inputstr = coin.SoInput() inputstr.setBuffer(shape.writeInventor()) coinobj = coin.SoDB.readAll(inputstr) # only add wireframe or full node? sep.addChild(coinobj.getChildren()[1]) # sep.addChild(coinobj) except: print("ghostTracker: Error retrieving coin node (light)") return sep
def recompute(self): if self.circle: self.sep.removeChild(self.circle) self.circle = None c = Part.makeCircle(1, Vector(0, 0, 0), plane.axis) buf = c.writeInventor(2, 0.01) ivin = coin.SoInput() ivin.setBuffer(buf) ivob = coin.SoDB.readAll(ivin) # In case reading from buffer failed if ivob and ivob.getNumChildren() > 1: self.circle = ivob.getChild(1).getChild(0) self.circle.removeChild(self.circle.getChild(0))# 材料属性 self.circle.removeChild(self.circle.getChild(0))# 绘制属性 self.sep.addChild(self.circle) # 留下的有coin.SoCoordinate3和coin.SoLineSet else: FreeCAD.Console.PrintWarning("arcTracker.recompute() failed to read-in Inventor string\n")
def recompute(self): """Recompute the tracker.""" import Part if self.circle: self.sep.removeChild(self.circle) self.circle = None if (self.endangle < self.startangle) or not self.autoinvert: c = Part.makeCircle(1, Vector(0, 0, 0), self.normal, self.endangle, self.startangle) else: c = Part.makeCircle(1, Vector(0, 0, 0), self.normal, self.startangle, self.endangle) buf = c.writeInventor(2, 0.01) try: ivin = coin.SoInput() ivin.setBuffer(buf) ivob = coin.SoDB.readAll(ivin) except Exception: # 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) self.circle = coin.SoSeparator() self.circle.addChild(coords) self.circle.addChild(line) self.sep.addChild(self.circle) else: if ivob and ivob.getNumChildren() > 1: self.circle = ivob.getChild(1).getChild(0) self.circle.removeChild(self.circle.getChild(0)) self.circle.removeChild(self.circle.getChild(0)) self.sep.addChild(self.circle) else: FreeCAD.Console.PrintWarning( "arcTracker.recompute() failed to read-in Inventor string\n" )
def __init__(self, sel): self.trans = coin.SoTransform() self.trans.translation.setValue([0, 0, 0]) self.children = [self.trans] self.ivsep = coin.SoSeparator() try: if isinstance(sel, Part.Shape): ivin = coin.SoInput() ivin.setBuffer(sel.writeInventor()) ivob = coin.SoDB.readAll(ivin) self.ivsep.addChild(ivob.getChildren()[1]) else: if not isinstance(sel, list): sel = [sel] for obj in sel: self.ivsep.addChild(obj.ViewObject.RootNode.copy()) except: print "draft: Couldn't create ghost" self.children.append(self.ivsep) Tracker.__init__(self, children=self.children)
def setToolShape(self, shape): '''Takes the actual shape of the tool and copies it into the 3d view. Should the tool in question be a legacy tool without a shape the tool is stylized by the traditional inverted cone.''' if self.tool: self.sep.removeChild(self.tool) if shape and MachinekitPreferences.hudToolShowShape(): buf = shape.writeInventor() cin = coin.SoInput() cin.setBuffer(buf) self.tool = coin.SoDB.readAll(cin) # the shape is correct, but we need to adjust the offset self.trf.translation.setValue((0, 0, -shape.BoundBox.ZMin)) self.trf.center.setValue((0, 0, 0)) self.trf.rotation.setValue(coin.SbVec3f((0, 0, 0)), 0) else: self.tool = coin.SoCone() self.tool.height.setValue(self.tsze) self.tool.bottomRadius.setValue(self.tsze / 4) # we need to flip and translate the cone so it sits on it's top self.trf.translation.setValue((0, -self.tsze / 2, 0)) self.trf.center.setValue((0, self.tsze / 2, 0)) self.trf.rotation.setValue(coin.SbVec3f((1, 0, 0)), -math.pi / 2) self.sep.addChild(self.tool)
def _dropEvent(self, event): mimedata = event.mimeData() input = coin.SoInput() if mimedata.hasUrls(): url = mimedata.urls().takeFirst() if url.scheme().isEmpty() or url.scheme().toLower() == QtCore.QString("file"): # attempt to open file if not input.openFile(url.toLocalFile().toLatin1().constData()): return elif mimedata.hasText(): # FIXME 2007-11-09 preng: dropping text buffer does not work on Windows Vista. bytes = mimedata.text().toUtf8() input.setBuffer(bytes.constData(), bytes.size()) if not input.isValidBuffer(): return # attempt to import it root = coin.SoDB.readAll(input) if not root: return # get QuarterWidget and set new scenegraph quarterwidget = self.manager.getWidget() quarterwidget.setSceneGraph(root) quarterwidget.updateGL()
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 in ["BubbleSize", "BubblePosition", "FontName", "FontSize"]: 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 = [] pos = ["Start"] if hasattr(vobj, "BubblePosition"): if vobj.BubblePosition == "Both": pos = ["Start", "End"] elif vobj.BubblePosition == "None": pos = [] else: pos = [vobj.BubblePosition] for i in range(len(vobj.Object.Shape.Edges)): for p in pos: verts = vobj.Object.Shape.Edges[i].Vertexes if p == "Start": p1 = verts[0].Point p2 = verts[1].Point else: p1 = verts[1].Point p2 = verts[0].Point dv = p2.sub(p1) dv.normalize() if hasattr(vobj.BubbleSize, "Value"): rad = vobj.BubbleSize.Value / 2 else: rad = vobj.BubbleSize / 2 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() fs = rad * 1.5 if hasattr(vobj, "FontSize"): fs = vobj.FontSize.Value tr.translation.setValue( (center.x, center.y - fs / 2.5, center.z)) fo = coin.SoFont() fn = Draft.getParam("textfont", "Arial,Sans") if hasattr(vobj, "FontName"): if vobj.FontName: try: fn = str(vobj.FontName) except: pass fo.name = fn fo.size = fs tx = coin.SoAsciiText() 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") if prop in ["FontName", "FontSize"]: self.onChanged(vobj, "ShowLabel") elif prop in ["NumberingStyle", "StartNumber"]: 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 if hasattr(vobj, "StartNumber"): if vobj.StartNumber > 1: num = vobj.StartNumber - 1 alt = False for t in self.bubbletexts: if hasattr(vobj, "NumberingStyle"): 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 = "" n = num n += 1 for numeral, integer in roman: while n >= integer: result += numeral n -= integer t.string = result elif vobj.NumberingStyle == "L0,L1,L2": t.string = "L" + str(num) else: t.string = str(num + 1) num += 1 if hasattr(vobj, "BubblePosition"): if vobj.BubblePosition == "Both": if not alt: num -= 1 alt = not alt elif prop in ["ShowLabel", "LabelOffset"]: if hasattr(self, "labels"): if self.labels: self.labelset.removeChild(self.labels) self.labels = None if hasattr(vobj, "ShowLabel") and hasattr(vobj.Object, "Labels"): if vobj.ShowLabel: self.labels = coin.SoSeparator() for i in range(len(vobj.Object.Shape.Edges)): if len(vobj.Object.Labels) > i: if vobj.Object.Labels[i]: import Draft vert = vobj.Object.Shape.Edges[i].Vertexes[ 0].Point if hasattr(vobj, "LabelOffset"): pl = FreeCAD.Placement(vobj.LabelOffset) pl.Base = vert.add(pl.Base) st = coin.SoSeparator() tr = coin.SoTransform() fo = coin.SoFont() tx = coin.SoAsciiText() tx.justification = coin.SoText2.LEFT t = vobj.Object.Labels[i] if isinstance(t, unicode): t = t.encode("utf8") tx.string.setValue(t) if hasattr(vobj, "FontSize"): fs = vobj.FontSize.Value elif hasattr(vobj.BubbleSize, "Value"): fs = vobj.BubbleSize.Value * 0.75 else: fs = vobj.BubbleSize * 0.75 tr.translation.setValue(tuple(pl.Base)) tr.rotation.setValue(pl.Rotation.Q) fn = Draft.getParam("textfont", "Arial,Sans") if hasattr(vobj, "FontName"): if vobj.FontName: try: fn = str(vobj.FontName) except: pass fo.name = fn fo.size = fs st.addChild(tr) st.addChild(fo) st.addChild(tx) self.labels.addChild(st) self.labelset.addChild(self.labels)
def onChanged(self, vobj, prop): if prop == "LineColor": if hasattr(vobj, "LineColor"): l = vobj.LineColor self.mat.diffuseColor.setValue([l[0], l[1], l[2]]) elif prop == "DrawStyle": if hasattr(vobj, "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": if hasattr(vobj, "LineWidth"): self.linestyle.lineWidth = vobj.LineWidth elif prop in ["BubbleSize", "BubblePosition", "FontName", "FontSize"]: 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) self.bubbletexts = [] self.bubbledata = [] pos = ["Start"] if hasattr(vobj, "BubblePosition"): if vobj.BubblePosition in [ "Both", "Arrow left", "Arrow right", "Bar left", "Bar right" ]: pos = ["Start", "End"] elif vobj.BubblePosition == "None": pos = [] else: pos = [vobj.BubblePosition] for i in range(len(vobj.Object.Distances)): for p in pos: if hasattr( vobj.Object, "Limit") and vobj.Object.Limit.Value: verts = [ vobj.Object.Placement.inverse( ).multVec(vobj.Object.Shape.Edges[i]. Vertexes[0].Point), vobj.Object.Placement.inverse(). multVec(vobj.Object.Shape.Edges[ i + 1].Vertexes[0].Point) ] else: verts = [ vobj.Object.Placement.inverse( ).multVec(v.Point) for v in vobj.Object.Shape.Edges[i].Vertexes ] arrow = None if p == "Start": p1 = verts[0] p2 = verts[1] if vobj.BubblePosition.endswith("left"): arrow = True elif vobj.BubblePosition.endswith("right"): arrow = False else: p1 = verts[1] p2 = verts[0] if vobj.BubblePosition.endswith("left"): arrow = False elif vobj.BubblePosition.endswith("right"): arrow = True dv = p2.sub(p1) dv.normalize() if hasattr(vobj.BubbleSize, "Value"): rad = vobj.BubbleSize.Value / 2 else: rad = vobj.BubbleSize / 2 center = p2.add(Vector(dv).multiply(rad)) normal = vobj.Object.Placement.Rotation.multVec( Vector(0, 0, 1)) chord = dv.cross(normal) if arrow: p3 = p2.add( Vector(chord).multiply(rad / 2).negative()) if vobj.BubblePosition.startswith("Arrow"): p4 = p3.add( Vector(dv).multiply(rad * 2).negative()) p5 = p2.add( Vector(dv).multiply( rad).negative()).add( Vector(chord).multiply( rad * 1.5).negative()) pts = [ tuple(p3), tuple(p5), tuple(p4), tuple(p3) ] center = p5.add( Vector(chord).multiply(rad * 2.5)) else: p4 = p3.add( Vector(dv).multiply(rad / 2).negative()) p5 = p4.add( Vector(chord).multiply( rad * 1.5).negative()) p6 = p5.add( Vector(dv).multiply(rad / 2)) pts = [ tuple(p3), tuple(p6), tuple(p5), tuple(p4), tuple(p3) ] center = p5.add( Vector(chord).multiply(rad * 3)) coords = coin.SoCoordinate3() coords.point.setValues(0, len(pts), pts) line = coin.SoFaceSet() line.numVertices.setValue(-1) cir = Part.makePolygon(pts) cir.Placement = vobj.Object.Placement self.bubbledata.append(cir) elif arrow == False: p3 = p2.add( Vector(chord).multiply(rad / 2)) if vobj.BubblePosition.startswith("Arrow"): p4 = p3.add( Vector(dv).multiply(rad * 2).negative()) p5 = p2.add( Vector(dv).multiply( rad).negative()).add( Vector(chord).multiply( rad * 1.5)) pts = [ tuple(p3), tuple(p4), tuple(p5), tuple(p3) ] center = p5.add( Vector(chord).multiply( rad * 2.5).negative()) else: p4 = p3.add( Vector(dv).multiply(rad / 2).negative()) p5 = p4.add( Vector(chord).multiply(rad * 1.5)) p6 = p5.add( Vector(dv).multiply(rad / 2)) pts = [ tuple(p3), tuple(p4), tuple(p5), tuple(p6), tuple(p3) ] center = p5.add( Vector(chord).multiply( rad * 3).negative()) coords = coin.SoCoordinate3() coords.point.setValues(0, len(pts), pts) line = coin.SoFaceSet() line.numVertices.setValue(-1) cir = Part.makePolygon(pts) cir.Placement = vobj.Object.Placement self.bubbledata.append(cir) else: cir = Part.makeCircle(rad, center) buf = cir.writeInventor() try: cin = coin.SoInput() cin.setBuffer(buf) cob = coin.SoDB.readAll(cin) except Exception: # workaround for pivy SoInput.setBuffer() bug buf = buf.replace("\n", "") pts = re.findall( "point \[(.*?)\]", buf)[0] pts = pts.split(",") pc = [] for point in pts: v = point.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) cir.Placement = vobj.Object.Placement self.bubbledata.append(cir) self.bubbles.addChild(coords) self.bubbles.addChild(line) st = coin.SoSeparator() tr = coin.SoTransform() fs = rad * 1.5 if hasattr(vobj, "FontSize"): fs = vobj.FontSize.Value txpos = FreeCAD.Vector(center.x, center.y - fs / 2.5, center.z) tr.translation.setValue(tuple(txpos)) fo = coin.SoFont() fn = Draft.getParam("textfont", "Arial,Sans") if hasattr(vobj, "FontName"): if vobj.FontName: try: fn = str(vobj.FontName) except Exception: pass fo.name = fn fo.size = fs tx = coin.SoAsciiText() tx.justification = coin.SoText2.CENTER self.bubbletexts.append( (tx, vobj.Object.Placement.multVec(center))) st.addChild(tr) st.addChild(fo) st.addChild(tx) self.bubbles.addChild(st) self.bubbleset.addChild(self.bubbles) self.onChanged(vobj, "NumberingStyle") if prop in ["FontName", "FontSize"]: self.onChanged(vobj, "ShowLabel") elif prop in ["NumberingStyle", "StartNumber"]: if hasattr(self, "bubbletexts"): num = 0 if hasattr(vobj, "StartNumber"): if vobj.StartNumber > 1: num = vobj.StartNumber - 1 alt = False for t in self.bubbletexts: t[0].string = self.getNumber(vobj, num) num += 1 if hasattr(vobj, "BubblePosition"): if vobj.BubblePosition in [ "Both", "Arrow left", "Arrow right", "Bar left", "Bar right" ]: if not alt: num -= 1 alt = not alt elif prop in ["ShowLabel", "LabelOffset"]: if hasattr(self, "labels"): if self.labels: self.labelset.removeChild(self.labels) self.labels = None if hasattr(vobj, "ShowLabel") and hasattr(vobj.Object, "Labels"): if vobj.ShowLabel: self.labels = coin.SoSeparator() if hasattr(vobj.Object, "Limit") and vobj.Object.Limit.Value: n = len(vobj.Object.Shape.Edges) / 2 else: n = len(vobj.Object.Shape.Edges) for i in range(n): if len(vobj.Object.Labels) > i: if vobj.Object.Labels[i]: vert = vobj.Object.Shape.Edges[i].Vertexes[ 0].Point if hasattr(vobj, "LabelOffset"): pl = FreeCAD.Placement(vobj.LabelOffset) pl.Base = vert.add(pl.Base) st = coin.SoSeparator() tr = coin.SoTransform() fo = coin.SoFont() tx = coin.SoAsciiText() tx.justification = coin.SoText2.LEFT t = vobj.Object.Labels[i] if six.PY2 and isinstance(t, six.text_type): t = t.encode("utf8") tx.string.setValue(t) if hasattr(vobj, "FontSize"): fs = vobj.FontSize.Value elif hasattr(vobj.BubbleSize, "Value"): fs = vobj.BubbleSize.Value * 0.75 else: fs = vobj.BubbleSize * 0.75 tr.translation.setValue(tuple(pl.Base)) tr.rotation.setValue(pl.Rotation.Q) fn = Draft.getParam("textfont", "Arial,Sans") if hasattr(vobj, "FontName"): if vobj.FontName: try: fn = str(vobj.FontName) except Exception: pass fo.name = fn fo.size = fs st.addChild(tr) st.addChild(fo) st.addChild(tx) self.labels.addChild(st) self.labelset.addChild(self.labels)
# Make an empty scene and add our node to it scene = SoSeparator() scene.addChild(iv) # Create a viewer in which to see our scene graph. viewer = SoGuiExaminerViewer(myWindow) # Put our scene into viewer, change the title viewer.setSceneGraph(scene) viewer.setTitle("FreeCAD Object Viewer") viewer.show() SoGui.show(myWindow) # Display main window SoGui.mainLoop() # Main Coin event loop doc = FreeCAD.newDocument() c = None for i in range(10, 1, -1): c_new = Cube(i, i, 1) if c: c = c.attachment('top') + c_new.attachment('bottom') else: c = c_new from pivy import coin inp = coin.SoInput() inp.setBuffer(c) myNode=coin.SoDB.readAll(inp) myViewer(FreeCADGui.activeDocument().getObject().toString())
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