from math import pi from pivy import coin import Part def getPoint(pX,pY): render_manager = Gui.ActiveDocument.ActiveView.getViewer().getSoRenderManager() cam = render_manager.getCamera() ws = render_manager.getWindowSize().getValue() ar = 1.0 * ws[0] / ws[1] vol = cam.getViewVolume() line = coin.SbLine(*vol.projectPointToLine(coin.SbVec2f(pX*ar-0.5,pY))) normal = coin.SbVec3f(0,0,1) center = coin.SbVec3f(0,0,0) plane = coin.SbPlane(normal, center) point = plane.intersect(line) return(FreeCAD.Vector(point.getValue())) def draw_box(): #pts = [getPoint(-0.5,-0.5), getPoint(0.5,-0.5), getPoint(0.5,0.5), getPoint(-0.5,0.5), getPoint(-0.5,-0.5)] pts = [getPoint(0,0), getPoint(1,0), getPoint(1,1), getPoint(0,1), getPoint(0,0)] poly = Part.makePolygon(pts) Part.show(poly) class gridView(coin.SoSeparator): def __init__(self, name = "GridView"): super(gridView, self).__init__() self.setName(name) self._number_of_points = 50 self._center = (0,0) self._scale = 1.0 self._axis = 0 # 1=X 2=Y 3=Z self.transform = coin.SoTransform() self.coord = coin.SoCoordinate3() self.sep1 = coin.SoSeparator() self.sep1.setName("Snap_Points") self.sep2 = coin.SoSeparator() self.sep2.setName("Grid") self.sep3 = coin.SoSeparator() self.sep3.setName("Axis") self.addChild(self.transform) self.addChild(self.coord) self.addChild(self.sep1) self.addChild(self.sep2) self.addChild(self.sep3) ps = coin.SoPointSet() ds = coin.SoDrawStyle() ds.pointSize = 1 self.sep1.addChild(ds) self.sep1.addChild(ps) self.color1 = (0.82, 0.15, 0.15) # red (X) self.color2 = (0.40, 0.59, 0.20) # green (Y) self.color3 = (0.13, 0.49, 0.88) # blue (Z) @property def axis(self): return(self._axis) @axis.setter def axis(self, ax): if ax == 1: self.vector1color = self.color2 self.vector2color = self.color3 rot = coin.SoRotationXYZ() rot.axis = 1 # rotate around Y rot.angle = 0.5 * pi self.transform.rotation.setValue(rot.getRotation()) self._axis = 1 elif ax == 2: self.vector1color = self.color1 self.vector2color = self.color3 rot = coin.SoRotationXYZ() rot.axis = 0 # rotate around X rot.angle = 0.5 * pi self.transform.rotation.setValue(rot.getRotation()) self._axis = 2 elif ax == 3: self.vector1color = self.color1 self.vector2color = self.color2 rot = coin.SoRotationXYZ() self.transform.rotation.setValue(rot.getRotation()) self._axis = 3 else: self._axis = 0 @property def scale(self): return(self._scale) @scale.setter def scale(self, s): self._scale = s if s == 0: self._scale = 1.0 self.transform.scaleFactor.setValue(coin.SbVec3f(self._scale, self._scale, self._scale)) def build_lines(self): np = self._number_of_points n = 1 + 2 * np self.line_mat1 = coin.SoMaterial() ol = list() #[(0.2,0.2,0.2)] + [(0.6,0.6,0.6)] * 9 bind1 = coin.SoMaterialBinding() bind1.value = coin.SoMaterialBinding.PER_PART l1 = coin.SoIndexedLineSet() l1.coordIndex.setValue(0) ind = list() for i in range(2 * self._number_of_points + 1): if not i == self._number_of_points: ind.append((i * n)) ind.append(((i+1) * n)-1) ind.append(-1) if (i % 10) == 0: ol.append((0.2,0.2,0.2)) else: ol.append((0.4,0.4,0.4)) #print(ind) self.line_mat1.diffuseColor.setValues(0, len(ol), ol ) l1.coordIndex.setValues(0, len(ind), ind) l2 = coin.SoIndexedLineSet() l2.coordIndex.setValue(0) ind2 = list() for i in range(2 * self._number_of_points + 1): if not i == self._number_of_points: ind2.append(i) ind2.append(i+(n-1)*n) ind2.append(-1) #if (i % 10) == 0: #ol.append((0.2,0.2,0.2)) #else: #ol.append((0.4,0.4,0.4)) #print(ind) #self.line_mat1.diffuseColor.setValues(0, len(ol), ol ) l2.coordIndex.setValues(0, len(ind2), ind2) self.sep2.addChild(bind1) self.sep2.addChild(self.line_mat1) self.sep2.addChild(l1) self.sep2.addChild(l2) def build_points(self): pts = list() sc = 1. / self._number_of_points for i in range(-self._number_of_points, self._number_of_points + 1): for j in range(-self._number_of_points,self._number_of_points + 1): pts.append(coin.SbVec3f(sc * i, sc * j, 0)) self.coord.point.setValues(0, len(pts), pts) def build_axis(self): np = self._number_of_points n = 1 + 2 * np ds = coin.SoDrawStyle() ds.lineWidth = 2 self.sep3.addChild(ds) self.mat1 = coin.SoMaterial() #bind1 = coin.SoMaterialBinding() #bind1.value = coin.SoMaterialBinding.PER_PART ax = coin.SoIndexedLineSet() ax.coordIndex.setValue(0) ax.coordIndex.setValues(0, 3, [n*np, n*(np+1)-1, -1]) #self.sep3.addChild(bind1) self.sep3.addChild(self.mat1) self.sep3.addChild(ax) self.mat2 = coin.SoMaterial() #bind2 = coin.SoMaterialBinding() #bind2.value = coin.SoMaterialBinding.PER_PART ax2 = coin.SoIndexedLineSet() ax2.coordIndex.setValue(0) ax2.coordIndex.setValues(0, 3, [np, n*(n-1) + np, -1]) #self.sep3.addChild(bind2) self.sep3.addChild(self.mat2) self.sep3.addChild(ax2) class orthoToggleSwitch(coin.SoSwitch): def __init__(self, name = "ToggleSwitch", cam = None): super(orthoToggleSwitch, self).__init__() self.setName(name) self.vec = coin.SoTransformVec3f() self.vec.vector = coin.SbVec3f(0,0,-1) # switch with 4 nodes self.calc = coin.SoCalculator() self.calc.A.connectFrom(self.vec.direction) self.calc.expression.set1Value(0, "ta=0.0001") # tolerance self.calc.expression.set1Value(1, "tA=vec3f(0,0,1)") # XY plane normal self.calc.expression.set1Value(2, "tB=vec3f(0,1,0)") # XZ plane normal self.calc.expression.set1Value(3, "tC=vec3f(1,0,0)") # YZ plane normal self.calc.expression.set1Value(4, "oa=fabs(dot(A,tA))") # XY value self.calc.expression.set1Value(5, "ob=fabs(dot(A,tB))") # XZ value self.calc.expression.set1Value(6, "oc=fabs(dot(A,tC))") # YZ value self.calc.expression.set1Value(7, "tb=(oa>ob)?oa:ob") self.calc.expression.set1Value(8, "tc=(tb>oc)?tb:oc") # winning value self.calc.expression.set1Value(9, "tf=(oa==tc)&&((oa+ta)>1)?1:0") self.calc.expression.set1Value(10,"tg=(ob==tc)&&((ob+ta)>1)?2:0") self.calc.expression.set1Value(11,"th=(oc==tc)&&((oc+ta)>1)?3:0") self.calc.expression.set1Value(12,"od=tf+tg+th") # switch value # switch with 2 nodes self.calc2 = coin.SoCalculator() self.calc2.a.connectFrom(self.calc.od) self.calc2.expression.set1Value(0, "oa=(a>0)?1:0") # tolerance self.scaleEngine = coin.SoCalculator() #self.scaleEngine.a.connectFrom(cam.height) self.scaleEngine.expression.set1Value(0,"ta=floor(log10(a/10))") self.scaleEngine.expression.set1Value(1,"tb=pow(10,ta+2)") self.scaleEngine.expression.set1Value(2,"oA=vec3f(tb,tb,tb)") self.scaleEngine.expression.set1Value(3,"oa=0.01*a/tb") self.axis_color = coin.SoCalculator() self.axis_color.a.connectFrom(self.calc.od) self.axis_color.expression.set1Value(0, "tA=vec3f(0.82, 0.15, 0.15)") # red self.axis_color.expression.set1Value(1, "tB=vec3f(0.40, 0.59, 0.20)") # green self.axis_color.expression.set1Value(2, "tC=vec3f(0.13, 0.49, 0.88)") # blue self.axis_color.expression.set1Value(3, "tD=vec3f(0.00, 0.00, 0.00)") # black self.axis_color.expression.set1Value(4, "ta=(a==1)?1:0") self.axis_color.expression.set1Value(5, "tb=(a==2)?1:0") self.axis_color.expression.set1Value(6, "tc=(a==3)?1:0") self.axis_color.expression.set1Value(7, "oA=tD+tB*ta+tC*tb+tB*tc") self.axis_color.expression.set1Value(8, "oB=tD+tA*ta+tA*tb+tC*tc") self.view_0 = gridView("Not_Ortho") self.addChild(self.view_0) self.view_1 = gridView("Ortho") self.view_1.build_points() self.view_1.build_axis() self.view_1.build_lines() self.addChild(self.view_1) if cam: self.connectCamera(cam) else: self.whichChild = 0 def connectCamera(self, cam): self.vec.matrix.connectFrom(cam.orientation) self.whichChild.connectFrom(self.calc2.oa) self.scaleEngine.a.connectFrom(cam.height) self.view_1.transform.scaleFactor.connectFrom(self.scaleEngine.oA) self.view_1.mat1.diffuseColor.connectFrom(self.axis_color.oA) self.view_1.mat2.diffuseColor.connectFrom(self.axis_color.oB) def disconnect(self): self.whichChild = 0 class orthoViewSwitch(coin.SoSwitch): def __init__(self, name = "OrthoViewSwitch", cam = None): super(orthoViewSwitch, self).__init__() self.setName(name) self.vec = coin.SoTransformVec3f() self.vec.vector = coin.SbVec3f(0,0,-1) self.calc = coin.SoCalculator() self.calc.A.connectFrom(self.vec.direction) self.calc.expression.set1Value(0, "ta=0.00001") # tolerance self.calc.expression.set1Value(1, "tA=vec3f(0,0,1)") # XY plane normal self.calc.expression.set1Value(2, "tB=vec3f(0,1,0)") # XZ plane normal self.calc.expression.set1Value(3, "tC=vec3f(1,0,0)") # YZ plane normal self.calc.expression.set1Value(4, "oa=fabs(dot(A,tA))") # XY value self.calc.expression.set1Value(5, "ob=fabs(dot(A,tB))") # XZ value self.calc.expression.set1Value(6, "oc=fabs(dot(A,tC))") # YZ value self.calc.expression.set1Value(7, "tb=(oa>ob)?oa:ob") self.calc.expression.set1Value(8, "tc=(tb>oc)?tb:oc") # winning value self.calc.expression.set1Value(9, "tf=(oa==tc)&&((oa+ta)>1)?1:0") self.calc.expression.set1Value(10,"tg=(ob==tc)&&((ob+ta)>1)?2:0") self.calc.expression.set1Value(11,"th=(oc==tc)&&((oc+ta)>1)?3:0") self.calc.expression.set1Value(12,"od=tf+tg+th") # switch value self.view_0 = gridView("not_ortho_view") self.addChild(self.view_0) self.view_z = gridView("Z_view") self.addChild(self.view_z) self.view_y = gridView("Y_view") self.addChild(self.view_y) self.view_x = gridView("X_view") self.addChild(self.view_x) if cam: self.connectCamera(cam) else: self.whichChild = 0 def connectCamera(self, cam): self.vec.matrix.connectFrom(cam.orientation) self.whichChild.connectFrom(self.calc.od) def disconnect(self): self.whichChild = 0 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() #sg.addChild(cube) sg.addChild(color) sg.addChild(trans) sg.addChild(orthoSwitch) cam = FreeCADGui.ActiveDocument.ActiveView.getCameraNode() # Connect the switch to the camera orthoSwitch.connectCamera(cam) # adjust the detection tolerance #orthoSwitch.setTolerance(0.0001) #grid = gridView("grid") #sg.addChild(grid) #grid.build_points()