def addAxisForDoc(self, DocName, xMin, xMax, yMin, yMax, title, texts, colors): # add coordinate axis import FreeCADGui from pivy import coin self.__axisNodes = [] node = coin.SoSeparator() try: sg = FreeCADGui.getDocument(DocName).ActiveView.getSceneGraph() except: raise from CoordinateAxis import addAxis2Scene sg.addChild(node) self.__axisNodes.append((sg, node)) addAxis2Scene(node, xMin, xMax, yMin, yMax, title, texts, colors)
def __init__(self, sel, dotted=False, scolor=None, swidth=None): self.trans = coin.SoTransform() self.trans.translation.setValue([0, 0, 0]) self.children = [self.trans] rootsep = coin.SoSeparator() if not isinstance(sel, list): sel = [sel] for obj in sel: rootsep.addChild(self.getNode(obj)) self.children.append(rootsep) Tracker.__init__(self, dotted, scolor, swidth, children=self.children, name="ghostTracker")
def __init__(self, points, dynamic=False, arrow_size=0.04, length=2): super(Arrow, self).__init__(points, dynamic) self.arrow_sep = coin.SoSeparator() self.arrow_rot = coin.SoRotation() self.arrow_scale = coin.SoScale() self.arrow_translate = coin.SoTranslation() self.arrow_scale.scaleFactor.setValue(arrow_size, arrow_size, arrow_size) self.cone = coin.SoCone() arrow_length = coin.SoScale() arrow_length.scaleFactor = (1, length, 1) arrow_origin = coin.SoTranslation() arrow_origin.translation = (0, -1, 0) self.arrow_sep += [self.arrow_translate, self.arrow_rot, self.arrow_scale] self.arrow_sep += [arrow_length, arrow_origin, self.cone] self += [self.arrow_sep] self.set_arrow_direction()
def __init__(self, point, colors): self.point = point self.color = colors self.sep = coin.SoSeparator() self.pos = coin.SoTranslation() self.pos.translation = (point.x, point.y, point.z) self.sphere = coin.SoSphere() self.scale = coin.SoType.fromName('SoShapeScale').createInstance() self.scale.setPart('shape', self.sphere) self.scale.scaleFactor.setValue(7) self.material = coin.SoMaterial() self.sep.addChild(self.pos) self.sep.addChild(self.material) self.sep.addChild(self.scale) self.enabled = True self.selected = False
def dim_dash(p1, p2, color, LineWidth): dash = coin.SoSeparator() v = coin.SoVertexProperty() v.vertex.set1Value(0, p1) v.vertex.set1Value(1, p2) line = coin.SoLineSet() line.vertexProperty = v style = coin.SoDrawStyle() style.lineWidth = LineWidth my_transparency = coin.SoMaterial() my_transparency.transparency.setValue(0.5) dash.addChild(style) dash.addChild(my_transparency) dash.addChild(color) dash.addChild(line) return dash
def getNodeFull(self,obj): """gets a coin node which is a full copy of the current representation""" sep = coin.SoSeparator() try: sep.addChild(obj.ViewObject.RootNode.copy()) # add Part container offset if hasattr(obj,"getGlobalPlacement"): if obj.Placement != obj.getGlobalPlacement(): if sep.getChild(0).getNumChildren() > 0: if isinstance(sep.getChild(0).getChild(0),coin.SoTransform): gpl = obj.getGlobalPlacement() sep.getChild(0).getChild(0).translation.setValue(tuple(gpl.Base)) sep.getChild(0).getChild(0).rotation.setValue(gpl.Rotation.Q) except: print("ghostTracker: Error retrieving coin node (full)") return sep
def attach(self,vobj): self.Object = vobj.Object self.clip = None from pivy import coin self.sep = coin.SoGroup() self.mat = coin.SoMaterial() self.sep.addChild(self.mat) self.dst = coin.SoDrawStyle() self.sep.addChild(self.dst) self.lco = coin.SoCoordinate3() self.sep.addChild(self.lco) lin = coin.SoType.fromName("SoBrepEdgeSet").createInstance() lin.coordIndex.setValues([0,1,-1,2,3,-1,4,5,-1]) self.sep.addChild(lin) self.bbox = coin.SoSwitch() self.bbox.whichChild = -1 bboxsep = coin.SoSeparator() self.bbox.addChild(bboxsep) drawstyle = coin.SoDrawStyle() drawstyle.style = coin.SoDrawStyle.LINES drawstyle.lineWidth = 3 drawstyle.linePattern = 0x0f0f # 0xaa bboxsep.addChild(drawstyle) self.bbco = coin.SoCoordinate3() bboxsep.addChild(self.bbco) lin = coin.SoIndexedLineSet() lin.coordIndex.setValues([0,1,2,3,0,-1,4,5,6,7,4,-1,0,4,-1,1,5,-1,2,6,-1,3,7,-1]) bboxsep.addChild(lin) self.sep.addChild(self.bbox) self.tra = coin.SoTransform() self.tra.rotation.setValue(FreeCAD.Rotation(0,0,90).Q) self.sep.addChild(self.tra) self.fon = coin.SoFont() self.sep.addChild(self.fon) self.txt = coin.SoAsciiText() self.txt.justification = coin.SoText2.LEFT self.txt.string.setValue("level") self.sep.addChild(self.txt) vobj.addDisplayMode(self.sep,"Default") self.onChanged(vobj,"ShapeColor") self.onChanged(vobj,"FontName") self.onChanged(vobj,"ShowLevel") self.onChanged(vobj,"FontSize") self.onChanged(vobj,"AutogroupBox") self.setProperties(vobj) return
def createAButton(self, _vector, _color, _rotation): color = coin.SoBaseColor() color.rgb = _color transform = coin.SoTransform() tempR = coin.SbVec3f() tempR.setValue(_rotation[0], _rotation[1], _rotation[2]) transform.rotation.setValue(tempR, math.radians(_rotation[3])) sphere = coin.SoSphere() sphere.radius = self.ButtonRadius transBar = coin.SoTranslation() transBar.translation.setValue(_vector) barLine = coin.SoSeparator() barLine.addChild(color) barLine.addChild(transBar) barLine.addChild(transform) barLine.addChild(sphere) return barLine
def get_scene_graph_transform(self): """ Create the Coin3D transform to translate and rotate this frame, in accordance with the self._rot and self._loc matrices held in this class. """ n = coin.SoSeparator() if N.any(self._loc != N.array((0, 0, 0))): tr = coin.SoTranslation() x, y, z = self._loc tr.translation = coin.SbVec3f((x, y, z)) #print "tr.translation = ",tr.translation.getValue().getValue() n.addChild(tr) if not N.all(N.equal(self._rot, N.eye(3))): m = self._rot # http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm tr = m[0, 0] + m[1, 1] + m[2, 2] if tr > 0: S = N.sqrt(tr + 1.0) * 2 qw = 0.25 * S qx = (m[2, 1] - m[1, 2]) / S qy = (m[0, 2] - m[2, 0]) / S qz = (m[1, 0] - m[0, 1]) / S elif m[0, 0] > m[1, 1] and m[0, 0] > m[2, 2]: S = N.sqrt(1.0 + m[0, 0] - m[1, 1] - m[2, 2]) * 2 qw = (m[2, 1] - m[1, 2]) / S qx = 0.25 * S qy = (m[0, 1] + m[1, 0]) / S qz = (m[0, 2] + m[2, 0]) / S elif m[1, 1] > m[2, 2]: S = N.sqrt(1.0 + m[1, 1] - m[0, 0] - m[2, 2]) * 2 qw = (m[0, 2] - m[2, 0]) / S qx = (m[0, 1] + m[1, 0]) / S qy = 0.25 * S qz = (m[1, 2] + m[2, 1]) / S else: S = N.sqrt(1.0 + m[2, 2] - m[0, 0] - m[1, 1]) * 2 qw = (m[1, 0] - m[0, 1]) / S qx = (m[0, 2] + m[2, 0]) / S qy = (m[1, 2] + m[2, 1]) / S qz = 0.25 * S ro = coin.SoRotation() ro.rotation = (qx, qy, qz, qw) n.addChild(ro) return n
def __init__(self, dotted=False, scolor=None, swidth=None, start=0, end=math.pi*2, normal=None): self.circle = None self.startangle = math.degrees(start) self.endangle = math.degrees(end) self.trans = coin.SoTransform() self.trans.translation.setValue([0, 0, 0]) self.sep = coin.SoSeparator() self.autoinvert = True if normal: self.normal = normal else: self.normal = FreeCAD.DraftWorkingPlane.axis self.basevector = self.getDeviation() self.recompute() Tracker.__init__(self, dotted, scolor, swidth, [self.trans, self.sep], name="arcTracker")
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 attach(self, vobj): self.Object = vobj.Object from pivy import coin sep = coin.SoSeparator() self.coords = coin.SoCoordinate3() sep.addChild(self.coords) self.coords.point.deleteValues(0) symbol = coin.SoMarkerSet() symbol.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_5_5 sep.addChild(symbol) rn = vobj.RootNode rn.addChild(sep) self.hiresgroup = coin.SoGroup() self.meshcolor = coin.SoBaseColor() self.hiresgroup.addChild(self.meshcolor) vobj.addDisplayMode(self.hiresgroup, "Mesh") ArchComponent.ViewProviderComponent.attach(self, vobj)
def main(): from pivy import sogui #from pivy import soqt as sogui win = sogui.SoGui.init() world = coin.SoSeparator() cube_lv = make_mother_daughter() world.addChild(cube_lv) view = sogui.SoGuiExaminerViewer(win) view.setSceneGraph(world) view.setTitle("Test") view.show() view.viewAll() sogui.SoGui.show(win) sogui.SoGui.mainLoop()
def __init__(self, view, coneHeight): self.view = view self.tsze = coneHeight self.trf = coin.SoTransform() self.pos = coin.SoTranslation() self.mat = coin.SoMaterial() self.mat.diffuseColor = coin.SbColor(0.4, 0.4, 0.4) self.mat.transparency = 0.8 self.sep = coin.SoSeparator() self.sep.addChild(self.pos) self.sep.addChild(self.trf) self.sep.addChild(self.mat) self.tool = None self.setToolShape(None)
def createExtensionSoSwitch(self, ext): sep = coin.SoSeparator() pos = coin.SoTranslation() mat = coin.SoMaterial() crd = coin.SoCoordinate3() fce = coin.SoFaceSet() hnt = coin.SoShapeHints() if not ext is None: try: wire = ext.getWire() except FreeCAD.Base.FreeCADError: wire = None if wire: if isinstance(wire, (list, tuple)): p0 = [p for p in wire[0].discretize(Deflection=0.02)] p1 = [p for p in wire[1].discretize(Deflection=0.02)] p2 = list(reversed(p1)) polygon = [(p.x, p.y, p.z) for p in (p0 + p2)] else: poly = [p for p in wire.discretize(Deflection=0.02)][:-1] polygon = [(p.x, p.y, p.z) for p in poly] crd.point.setValues(polygon) else: return None mat.diffuseColor = self.ColourDisabled mat.transparency = self.TransparencyDeselected hnt.faceType = coin.SoShapeHints.UNKNOWN_FACE_TYPE hnt.vertexOrdering = coin.SoShapeHints.CLOCKWISE sep.addChild(pos) sep.addChild(mat) sep.addChild(hnt) sep.addChild(crd) sep.addChild(fce) switch = coin.SoSwitch() switch.addChild(sep) switch.whichChild = coin.SO_SWITCH_NONE self.material = mat return switch
def __init__(self): """Initialize object.""" # Root node self.node = coin.SoSeparator() # Switch (visibility) self.switch = coin.SoSwitch() self.node.addChild(self.switch) # Transform (placement) self.transform = coin.SoTransform() self.switch.addChild(self.transform) # Display group (starting point for shape or light nodes) self.display_group = coin.SoGroup() self.switch.addChild(self.display_group) self.set_visibility(True)
def main(): app = QtWidgets.QApplication(sys.argv) viewer = quarter.QuarterWidget() # build a scene (sphere, cube) plane = coin.SbPlane(coin.SbVec3f(0, 0, 1), coin.SbVec3f(0, 0, 0)) root = coin.SoSeparator() myCallback = coin.SoCallback() cap = CapPlane(plane, root) myCallback.setCallback(myCallbackRoutine, cap) root += myCallback, coin.SoSphere() viewer.setSceneGraph(root) viewer.setBackgroundColor(coin.SbColor(.5, .5, .5)) viewer.setWindowTitle("GL stencil buffer") viewer.show() sys.exit(app.exec_())
def createABar(self, _vector, _color, _length, _rotation): color = coin.SoBaseColor() transform = coin.SoTransform() tempR = coin.SbVec3f() tempR.setValue(_rotation[0], _rotation[1], _rotation[2]) transform.rotation.setValue(tempR, math.radians(_rotation[3])) color.rgb = _color cylinder = coin.SoCylinder() cylinder.height = _length cylinder.radius = self.barRadius transBar = coin.SoTranslation() transBar.translation.setValue(_vector) barLine = coin.SoSeparator() barLine.addChild(color) barLine.addChild(transBar) barLine.addChild(transform) barLine.addChild(cylinder) return barLine
def attach(self, vobj): self.Object = vobj.Object from pivy import coin self.diagramsep = coin.SoSeparator() self.color = coin.SoBaseColor() self.coords = coin.SoTransform() self.diagramswitch = coin.SoSwitch() self.diagramswitch.whichChild = -1 self.diagramswitch.addChild(self.diagramsep) self.diagramsep.addChild(self.coords) self.diagramsep.addChild(self.color) vobj.Annotation.addChild(self.diagramswitch) self.compass = Compass() self.updateCompassVisibility(vobj) self.updateCompassScale(vobj) self.rotateCompass(vobj) vobj.Annotation.addChild(self.compass.rootNode)
def __init__(self, render_manager): super(InteractionSeparator, self).__init__() self.render_manager = render_manager self.objects = coin.SoSeparator() self.dynamic_objects = [] self.static_objects = [] self.over_object = None self.selected_objects = [] self.drag_objects = [] self.on_drag = [] self.on_drag_release = [] self.on_drag_start = [] self._direction = None self.events = coin.SoEventCallback() self += self.events, self.objects
def attach(self,vobj): self.Object = vobj.Object from pivy import coin tex = coin.SoTexture2() tex.image = Draft.loadTexture(Draft.svgpatterns()['simple'][1], 128) texcoords = coin.SoTextureCoordinatePlane() s = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetFloat("patternScale",0.01) texcoords.directionS.setValue(s,0,0) texcoords.directionT.setValue(0,s,0) self.fcoords = coin.SoCoordinate3() self.fset = coin.SoIndexedFaceSet() sep = coin.SoSeparator() sep.addChild(tex) sep.addChild(texcoords) sep.addChild(self.fcoords) sep.addChild(self.fset) vobj.RootNode.addChild(sep) ArchComponent.ViewProviderComponent.attach(self,vobj)
def sceneDrawPath(path, color=(0, 0, 1)): coPoint = coin.SoCoordinate3() pts = [] for pt in path: pts.append([pt[0], pt[1], topZ]) coPoint.point.setValues(0, len(pts), pts) ma = coin.SoBaseColor() ma.rgb = color li = coin.SoLineSet() li.numVertices.setValue(len(pts)) pathNode = coin.SoSeparator() pathNode.addChild(coPoint) pathNode.addChild(ma) pathNode.addChild(li) sceneGraph.addChild(pathNode) scenePathNodes.append(pathNode) #for scene cleanup afterwards
def onChanged(self, vobj, prop): ''' Update Object visuals when a view property changed. ''' labels = vobj.getPropertyByName("Labels") self.point_labels.removeAllChildren() if labels: if prop == "Labels" or prop == "Name" or prop == "NortingEasting"\ or prop == "Elevation" or prop == "Description": origin = geo_origin.get(vobj.Object.Points[0]) show_name = vobj.getPropertyByName("Name") show_ne = vobj.getPropertyByName("NortingEasting") show_z = vobj.getPropertyByName("Elevation") show_des = vobj.getPropertyByName("Description") for vector in vobj.Object.Points: font = coin.SoFont() font.size = 1000 point_label = coin.SoSeparator() location = coin.SoTranslation() text = coin.SoAsciiText() index = vobj.Object.Points.index(vector) labels =[] if show_name: labels.append(vobj.Object.PointNames[index]) if show_ne: labels.extend([str(round(vector.x/1000, 3)), str(round(vector.y/1000,3))]) if show_z: labels.append(str(round(vector.z/1000,3))) if show_des and vobj.Object.Descriptions: labels.append(vobj.Object.Descriptions[index]) location.translation = vector.sub(FreeCAD.Vector(origin.Origin.x, origin.Origin.y, 0)) text.string.setValues(labels) point_label.addChild(font) point_label.addChild(location) point_label.addChild(text) self.point_labels.addChild(point_label) if prop == "PointSize": size = vobj.getPropertyByName("PointSize") self.point_style.pointSize = size if prop == "PointColor": color = vobj.getPropertyByName("PointColor") self.color_mat.diffuseColor = (color[0],color[1],color[2])
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 viewer(scene=None,background=(1.0,1.0,1.0),lightdir=None): """viewer(scene=None,background=(1.0,1.0,1.0),lightdir=None): starts a standalone coin viewer with the contents of the given scene. You can give a background color, and optionally a light direction as a (x,y,z) tuple. In this case, a directional light will be added and shadows will be turned on. This might not work with some 3D drivers.""" # Initialize Coin. This returns a main window to use from pivy import coin from pivy import sogui win = sogui.SoGui.init() if win is None: print("Unable to create a SoGui window") return win.setBackgroundColor(coin.SbColor(background[0],background[1],background[2])) if not scene: # build a quick default scene mat = coin.SoMaterial() mat.diffuseColor = (1.0, 0.0, 0.0) # Make a scene containing a red cone scene = coin.SoSeparator() scene.addChild(mat) scene.addChild(coin.SoCone()) if lightdir: scene = embedLight(scene,lightdir) # ref the scene so it doesn't get garbage-collected scene.ref() # Create a viewer in which to see our scene graph viewer = sogui.SoGuiExaminerViewer(win) # Put our scene into viewer, change the title viewer.setSceneGraph(scene) viewer.setTitle("Coin viewer") viewer.show() sogui.SoGui.show(win) # Display main window sogui.SoGui.mainLoop() # Main Coin event loop
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 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
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 simple_poly_mesh(verts, poly, color=None): color = color or COLORS["grey"] _vertices = [list(v) for v in verts] _polygons = [] for pol in poly: _polygons += list(pol) + [-1] sep = coin.SoSeparator() vertex_property = coin.SoVertexProperty() face_set = coin.SoIndexedFaceSet() shape_hint = coin.SoShapeHints() shape_hint.vertexOrdering = coin.SoShapeHints.COUNTERCLOCKWISE shape_hint.creaseAngle = np.pi / 3 face_mat = coin.SoMaterial() face_mat.diffuseColor = color vertex_property.vertex.setValues(0, len(_vertices), _vertices) face_set.coordIndex.setValues(0, len(_polygons), list(_polygons)) vertex_property.materialBinding = coin.SoMaterialBinding.PER_VERTEX_INDEXED sep += [shape_hint, vertex_property, face_mat, face_set] return sep
def __init__(self, dotted=False, scolor=None, swidth=None, children=[], ontop=False): self.ontop = ontop color = coin.SoBaseColor() color.rgb = scolor or FreeCADGui.DDADockWidget.getDefaultColor("ui") drawstyle = coin.SoDrawStyle() if swidth: drawstyle.lineWidth = swidth if dotted: drawstyle.style = coin.SoDrawStyle.LINES drawstyle.lineWeight = 3 drawstyle.linePattern = 0x0f0f # 0xaa , 虚线的具体样式 node = coin.SoSeparator() for c in [drawstyle, color] + children: # openInventor的处理方式,前两决定后续children的样式 node.addChild(c) self.switch = coin.SoSwitch() # this is the on/off switch self.switch.addChild(node) self.switch.whichChild = -1 self.Visible = False todo.delay(self._insertSwitch, self.switch)