# Render the inline QC station views (run in the FreeCAD GUI after build_station.py). # exec(open(r"C:/dev/cnx_vinyl/docs/equipment/inline-qc-station/render_station.py", encoding="utf-8").read()) # Detail views are rendered from a temporary document holding the model clipped # to a box (Part common), because coin clip planes did not reach the render here. import os import FreeCAD as App import FreeCADGui as Gui import Part OUTDIR = r"C:/dev/cnx_vinyl/docs/equipment/inline-qc-station" doc = App.getDocument("InlineQCStation") _vp = App.ParamGet("User parameter:BaseApp/Preferences/View") _navi_before = _vp.GetBool("ShowNaviCube", True) _vp.SetBool("ShowNaviCube", False) _anim_before = _vp.GetBool("UseNavigationAnimations", True) _vp.SetBool("UseNavigationAnimations", False) _presel_before = _vp.GetBool("EnablePreselection", True) _vp.SetBool("EnablePreselection", False) Gui.Selection.clearPreselection() Gui.Selection.clearSelection() from pivy import coin def prep(d): Gui.setActiveDocument(d.Name) v = Gui.getDocument(d.Name).ActiveView try: v.setCameraType("Orthographic") except Exception: pass for m in ("setNavigationCubeVisible", "setCornerCrossVisible"): if hasattr(v, m): getattr(v, m)(False) return v def members(group): g = doc.getObject(group) return list(g.Group) if g else [] def show_all(): for o in doc.Objects: if o.TypeId == "Part::Feature": o.ViewObject.Visibility = True def hide(groups=(), names=()): for gname in groups: for o in members(gname): o.ViewObject.Visibility = False for n in names: o = doc.getObject(n) if o: o.ViewObject.Visibility = False def shoot(v, fname, orient, w=3200, h=2400): getattr(v, orient)() Gui.updateGui() v.fitAll() Gui.updateGui() # move the orthographic camera well back so no part sits behind the near plane c = v.getCameraNode() d = c.orientation.getValue().multVec(coin.SbVec3f(0, 0, -1)) c.position.setValue(c.position.getValue() - d * 8000) c.nearDistance.setValue(100) c.farDistance.setValue(32000) Gui.updateGui() path = os.path.join(OUTDIR, fname) v.saveImage(path, w, h, "White") print("saved", path) def clipped_doc(name, clipbox, skip_groups=()): skip = set() for gname in skip_groups: skip.update(o.Name for o in members(gname)) d = App.newDocument(name) for o in doc.Objects: if o.TypeId != "Part::Feature" or o.Name in skip: continue s = o.Shape.common(clipbox) if s.isNull() or s.Volume < 1e-3: continue n = d.addObject("Part::Feature", o.Name) n.Shape = s n.ViewObject.ShapeColor = o.ViewObject.ShapeColor n.ViewObject.Transparency = o.ViewObject.Transparency n.ViewObject.LineColor = o.ViewObject.LineColor d.recompute() return d view = prep(doc) enclosure_tops = ["PanelTop", "PanelFrontUpper", "PanelFrontLower", "GuardRejectFront", "GuardRejectTop", "DoorHandle"] # 1 open iso: front panels and lid off, the rest of the enclosure translucent show_all() hide(names=enclosure_tops) shoot(view, "inline-qc-station-iso.png", "viewIsometric") # 2 closed iso: as it stands in the hall show_all() for o in members("Enclosure"): o.ViewObject.Transparency = 15 if o.Name not in ("GuardRejectFront", "GuardRejectTop") else 70 shoot(view, "inline-qc-station-closed.png", "viewIsometric") for o in members("Enclosure"): o.ViewObject.Transparency = 55 if o.Name not in ("GuardRejectFront", "GuardRejectTop") else 75 # 3 front elevation without the front panels show_all() hide(names=enclosure_tops) shoot(view, "inline-qc-station-front.png", "viewFront") # 4 plan view without the lid and the top bridge show_all() hide(names=enclosure_tops + ["TopBeamF", "TopBeamB", "TopCrossLabel", "TopCrossLineScan", "TopCrossThermal", "TopCrossBacklight", "RejectBridgeCross", "RodlessCylinder", "PusherCarriage", "LabelCamTop", "LabelCamTopPost", "LabelCamTopPlate", "LineCamTop", "LineCamTopPost", "LineCamTopPlate", "LightHangerTop", "CoaxHangerTop", "CoaxLightTop", "CoaxLightTopFace", "BacklightForBottomCam", "BacklightForBottomCamFace", "BacklightBracketTop", "LabelRingTop", "LabelRingTopFace", "ThermalCam", "ThermalPost", "DarkFieldTopF", "DarkFieldTopB", "DarkFieldTopBracketF", "DarkFieldTopBracketB", "StackLight0", "StackLight1", "StackLight2", "StackLightPole", "HMI", "HMIArm"]) shoot(view, "inline-qc-station-top.png", "viewTop") show_all() hide(names=enclosure_tops) view.viewIsometric() view.fitAll() doc.save() # 5 inspection elevation: x 600..1120, everything in front of y = -150 cut away d5 = clipped_doc("QCDetailFront", Part.makeBox(520, 500, 1100, App.Vector(600, -150, 400)), skip_groups=("Enclosure", "Electrical", "Reject")) v5 = prep(d5) shoot(v5, "inline-qc-station-detail-front.png", "viewFront", w=2400, h=2400) App.closeDocument(d5.Name) # 6 inspection zone, 3/4 view: x 600..1120, z 400..1500 d6 = clipped_doc("QCDetailIso", Part.makeBox(520, 700, 1100, App.Vector(600, -350, 400)), skip_groups=("Enclosure", "Electrical", "Reject")) v6 = prep(d6) shoot(v6, "inline-qc-station-detail.png", "viewIsometric", w=2400, h=2400) App.closeDocument(d6.Name) Gui.setActiveDocument(doc.Name) _vp.SetBool("ShowNaviCube", _navi_before) _vp.SetBool("UseNavigationAnimations", _anim_before) _vp.SetBool("EnablePreselection", _presel_before) print("done")